3febf9f2c12a34eafb1a75664ea6ba1f045dfd988792c7871899809f4ed3c347.json 137 KB

1
  1. {"ast":null,"code":"import { __decorate, __param } from 'tslib';\nimport { Platform, PlatformModule } from '@angular/cdk/platform';\nimport { InjectionToken, inject, LOCALE_ID, Optional, Inject, Injectable, NgModule, ɵɵdefineInjectable, EventEmitter, ElementRef, NgZone, Input, Output, Component, ViewEncapsulation, ChangeDetectionStrategy, ChangeDetectorRef, ViewChild, forwardRef, ViewContainerRef, Directive, Attribute, ContentChild } from '@angular/core';\nimport { Subject, Subscription, merge, of } from 'rxjs';\nimport { A11yModule } from '@angular/cdk/a11y';\nimport { Overlay, OverlayConfig, OverlayModule } from '@angular/cdk/overlay';\nimport { ComponentPortal, PortalModule } from '@angular/cdk/portal';\nimport { DOCUMENT, CommonModule } from '@angular/common';\nimport { MatButtonModule } from '@angular/material/button';\nimport { MatDialog, MatDialogModule } from '@angular/material/dialog';\nimport { SPACE, ENTER, PAGE_DOWN, PAGE_UP, END, HOME, DOWN_ARROW, UP_ARROW, RIGHT_ARROW, LEFT_ARROW, ESCAPE } from '@angular/cdk/keycodes';\nimport { Directionality } from '@angular/cdk/bidi';\nimport { take, filter } from 'rxjs/operators';\nimport { coerceBooleanProperty } from '@angular/cdk/coercion';\nimport { mixinColor } from '@angular/material/core';\nimport { trigger, state, style, transition, animate } from '@angular/animations';\nimport { NG_VALUE_ACCESSOR, NG_VALIDATORS, Validators } from '@angular/forms';\nimport { MatFormField } from '@angular/material/form-field';\nimport { MAT_INPUT_VALUE_ACCESSOR } from '@angular/material/input';\n\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n/** InjectionToken for datepicker that can be used to override default locale code. */\nconst MAT_DATE_LOCALE = new InjectionToken('MAT_DATE_LOCALE', {\n providedIn: 'root',\n factory: MAT_DATE_LOCALE_FACTORY\n});\n/** @docs-private */\nfunction MAT_DATE_LOCALE_FACTORY() {\n return inject(LOCALE_ID);\n}\n/**\n * No longer needed since MAT_DATE_LOCALE has been changed to a scoped injectable.\n * If you are importing and providing this in your code you can simply remove it.\n * @deprecated\n * @breaking-change 8.0.0\n */\nconst MAT_DATE_LOCALE_PROVIDER = {\n provide: MAT_DATE_LOCALE,\n useExisting: LOCALE_ID\n};\n/** Adapts type `D` to be usable as a date by cdk-based components that work with dates. */\nclass DateAdapter {\n constructor() {\n this._localeChanges = new Subject();\n }\n /** A stream that emits when the locale changes. */\n get localeChanges() {\n return this._localeChanges;\n }\n /**\n * Attempts to deserialize a value to a valid date object. This is different from parsing in that\n * deserialize should only accept non-ambiguous, locale-independent formats (e.g. a ISO 8601\n * string). The default implementation does not allow any deserialization, it simply checks that\n * the given value is already a valid date object or null. The `<sat-datepicker>` will call this\n * method on all of its `@Input()` properties that accept dates. It is therefore possible to\n * support passing values from your backend directly to these properties by overriding this method\n * to also deserialize the format used by your backend.\n * @param value The value to be deserialized into a date object.\n * @returns The deserialized date object, either a valid date, null if the value can be\n * deserialized into a null date (e.g. the empty string), or an invalid date.\n */\n deserialize(value) {\n if (value == null || this.isDateInstance(value) && this.isValid(value)) {\n return value;\n }\n return this.invalid();\n }\n /**\n * Sets the locale used for all dates.\n * @param locale The new locale.\n */\n setLocale(locale) {\n this.locale = locale;\n this._localeChanges.next();\n }\n /**\n * Compares two dates.\n * @param first The first date to compare.\n * @param second The second date to compare.\n * @returns 0 if the dates are equal, a number less than 0 if the first date is earlier,\n * a number greater than 0 if the first date is later.\n */\n compareDate(first, second) {\n return this.getYear(first) - this.getYear(second) || this.getMonth(first) - this.getMonth(second) || this.getDate(first) - this.getDate(second);\n }\n /**\n * Checks if two dates are equal.\n * @param first The first date to check.\n * @param second The second date to check.\n * @returns Whether the two dates are equal.\n * Null dates are considered equal to other null dates.\n */\n sameDate(first, second) {\n if (first && second) {\n let firstValid = this.isValid(first);\n let secondValid = this.isValid(second);\n if (firstValid && secondValid) {\n return !this.compareDate(first, second);\n }\n return firstValid == secondValid;\n }\n return first == second;\n }\n /**\n * Clamp the given date between min and max dates.\n * @param date The date to clamp.\n * @param min The minimum value to allow. If null or omitted no min is enforced.\n * @param max The maximum value to allow. If null or omitted no max is enforced.\n * @returns `min` if `date` is less than `min`, `max` if date is greater than `max`,\n * otherwise `date`.\n */\n clampDate(date, min, max) {\n if (min && this.compareDate(date, min) < 0) {\n return min;\n }\n if (max && this.compareDate(date, max) > 0) {\n return max;\n }\n return date;\n }\n}\n\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nconst MAT_DATE_FORMATS = new InjectionToken('mat-date-formats');\n\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n// TODO(mmalerba): Remove when we no longer support safari 9.\n/** Whether the browser supports the Intl API. */\nlet SUPPORTS_INTL_API;\n// We need a try/catch around the reference to `Intl`, because accessing it in some cases can\n// cause IE to throw. These cases are tied to particular versions of Windows and can happen if\n// the consumer is providing a polyfilled `Map`. See:\n// https://github.com/Microsoft/ChakraCore/issues/3189\n// https://github.com/angular/components/issues/15687\ntry {\n SUPPORTS_INTL_API = typeof Intl != 'undefined';\n} catch (_a) {\n SUPPORTS_INTL_API = false;\n}\n/** The default month names to use if Intl API is not available. */\nconst DEFAULT_MONTH_NAMES = {\n 'long': ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],\n 'short': ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],\n 'narrow': ['J', 'F', 'M', 'A', 'M', 'J', 'J', 'A', 'S', 'O', 'N', 'D']\n};\nconst ɵ0 = i => String(i + 1);\n/** The default date names to use if Intl API is not available. */\nconst DEFAULT_DATE_NAMES = range(31, ɵ0);\n/** The default day of the week names to use if Intl API is not available. */\nconst DEFAULT_DAY_OF_WEEK_NAMES = {\n 'long': ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],\n 'short': ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],\n 'narrow': ['S', 'M', 'T', 'W', 'T', 'F', 'S']\n};\n/** First day of week according locale.\n * Taken form moment.js source code https://github.com/moment/moment/tree/develop/src/locale\n */\nconst FIRST_DAY_OF_WEEK = {\n af: 1,\n ar: 6,\n 'ar-ly': 6,\n 'ar-ma': 6,\n 'ar-tn': 1,\n az: 1,\n be: 1,\n bg: 1,\n bm: 1,\n br: 1,\n bs: 1,\n ca: 1,\n cs: 1,\n cv: 1,\n cy: 1,\n da: 1,\n de: 1,\n 'de-at': 1,\n 'de-ch': 1,\n el: 1,\n 'en-au': 1,\n 'en-gb': 1,\n 'en-ie': 1,\n 'en-nz': 1,\n eo: 1,\n es: 1,\n 'es-do': 1,\n et: 1,\n eu: 1,\n fa: 6,\n fi: 1,\n fo: 1,\n fr: 1,\n 'fr-ch': 1,\n fy: 1,\n gd: 1,\n gl: 1,\n 'gom-latn': 1,\n hr: 1,\n hu: 1,\n 'hy-am': 1,\n id: 1,\n is: 1,\n it: 1,\n jv: 1,\n ka: 1,\n kk: 1,\n km: 1,\n ky: 1,\n lb: 1,\n lt: 1,\n lv: 1,\n me: 1,\n mi: 1,\n mk: 1,\n ms: 1,\n 'ms-my': 1,\n mt: 1,\n my: 1,\n nb: 1,\n nl: 1,\n 'nl-be': 1,\n nn: 1,\n pl: 1,\n pt: 1,\n 'pt-BR': 0,\n ro: 1,\n ru: 1,\n sd: 1,\n se: 1,\n sk: 1,\n sl: 1,\n sq: 1,\n sr: 1,\n 'sr-cyrl': 1,\n ss: 1,\n sv: 1,\n sw: 1,\n 'tet': 1,\n tg: 1,\n 'tl-ph': 1,\n 'tlh': 1,\n tr: 1,\n 'tzl': 1,\n 'tzm': 6,\n 'tzm-latn': 6,\n 'ug-cn': 1,\n uk: 1,\n ur: 1,\n uz: 1,\n 'uz-latn': 1,\n vi: 1,\n 'x-pseudo': 1,\n yo: 1,\n 'zh-cn': 1\n};\n/**\n * Matches strings that have the form of a valid RFC 3339 string\n * (https://tools.ietf.org/html/rfc3339). Note that the string may not actually be a valid date\n * because the regex will match strings an with out of bounds month, date, etc.\n */\nconst ISO_8601_REGEX = /^\\d{4}-\\d{2}-\\d{2}(?:T\\d{2}:\\d{2}:\\d{2}(?:\\.\\d+)?(?:Z|(?:(?:\\+|-)\\d{2}:\\d{2}))?)?$/;\n/** Creates an array and fills it with values. */\nfunction range(length, valueFunction) {\n const valuesArray = Array(length);\n for (let i = 0; i < length; i++) {\n valuesArray[i] = valueFunction(i);\n }\n return valuesArray;\n}\n/** Adapts the native JS Date for use with cdk-based components that work with dates. */\nlet NativeDateAdapter = /*#__PURE__*/(() => {\n let NativeDateAdapter = class NativeDateAdapter extends DateAdapter {\n constructor(matDateLocale, platform) {\n super();\n /**\n * Whether to use `timeZone: 'utc'` with `Intl.DateTimeFormat` when formatting dates.\n * Without this `Intl.DateTimeFormat` sometimes chooses the wrong timeZone, which can throw off\n * the result. (e.g. in the en-US locale `new Date(1800, 7, 14).toLocaleDateString()`\n * will produce `'8/13/1800'`.\n *\n * TODO(mmalerba): drop this variable. It's not being used in the code right now. We're now\n * getting the string representation of a Date object from it's utc representation. We're keeping\n * it here for sometime, just for precaution, in case we decide to revert some of these changes\n * though.\n */\n this.useUtcForDisplay = true;\n super.setLocale(matDateLocale);\n // IE does its own time zone correction, so we disable this on IE.\n this.useUtcForDisplay = !platform.TRIDENT;\n this._clampDate = platform.TRIDENT || platform.EDGE;\n }\n getYear(date) {\n return date.getFullYear();\n }\n getMonth(date) {\n return date.getMonth();\n }\n getDate(date) {\n return date.getDate();\n }\n getDayOfWeek(date) {\n return date.getDay();\n }\n getMonthNames(style) {\n if (SUPPORTS_INTL_API) {\n const dtf = new Intl.DateTimeFormat(this.locale, {\n month: style,\n timeZone: 'utc'\n });\n return range(12, i => this._stripDirectionalityCharacters(this._format(dtf, new Date(2017, i, 1))));\n }\n return DEFAULT_MONTH_NAMES[style];\n }\n getDateNames() {\n if (SUPPORTS_INTL_API) {\n const dtf = new Intl.DateTimeFormat(this.locale, {\n day: 'numeric',\n timeZone: 'utc'\n });\n return range(31, i => this._stripDirectionalityCharacters(this._format(dtf, new Date(2017, 0, i + 1))));\n }\n return DEFAULT_DATE_NAMES;\n }\n getDayOfWeekNames(style) {\n if (SUPPORTS_INTL_API) {\n const dtf = new Intl.DateTimeFormat(this.locale, {\n weekday: style,\n timeZone: 'utc'\n });\n return range(7, i => this._stripDirectionalityCharacters(this._format(dtf, new Date(2017, 0, i + 1))));\n }\n return DEFAULT_DAY_OF_WEEK_NAMES[style];\n }\n getYearName(date) {\n if (SUPPORTS_INTL_API) {\n const dtf = new Intl.DateTimeFormat(this.locale, {\n year: 'numeric',\n timeZone: 'utc'\n });\n return this._stripDirectionalityCharacters(this._format(dtf, date));\n }\n return String(this.getYear(date));\n }\n getFirstDayOfWeek() {\n // We can't tell using native JS Date what the first day of the week is.\n // Sometimes people use excess language definition, e.g. ru-RU,\n // so we use fallback to two-letter language code\n const locale = this.locale.toLowerCase();\n return FIRST_DAY_OF_WEEK[locale] || FIRST_DAY_OF_WEEK[locale.substr(0, 2)] || 0;\n }\n getNumDaysInMonth(date) {\n return this.getDate(this._createDateWithOverflow(this.getYear(date), this.getMonth(date) + 1, 0));\n }\n clone(date) {\n return new Date(date.getTime());\n }\n createDate(year, month, date) {\n // Check for invalid month and date (except upper bound on date which we have to check after\n // creating the Date).\n if (month < 0 || month > 11) {\n throw Error(`Invalid month index \"${month}\". Month index has to be between 0 and 11.`);\n }\n if (date < 1) {\n throw Error(`Invalid date \"${date}\". Date has to be greater than 0.`);\n }\n let result = this._createDateWithOverflow(year, month, date);\n // Check that the date wasn't above the upper bound for the month, causing the month to overflow\n if (result.getMonth() != month) {\n throw Error(`Invalid date \"${date}\" for month with index \"${month}\".`);\n }\n return result;\n }\n today() {\n return new Date();\n }\n parse(value) {\n // We have no way using the native JS Date to set the parse format or locale, so we ignore these\n // parameters.\n if (typeof value == 'number') {\n return new Date(value);\n }\n return value ? new Date(Date.parse(value)) : null;\n }\n format(date, displayFormat) {\n if (!this.isValid(date)) {\n throw Error('NativeDateAdapter: Cannot format invalid date.');\n }\n if (SUPPORTS_INTL_API) {\n // On IE and Edge the i18n API will throw a hard error that can crash the entire app\n // if we attempt to format a date whose year is less than 1 or greater than 9999.\n if (this._clampDate && (date.getFullYear() < 1 || date.getFullYear() > 9999)) {\n date = this.clone(date);\n date.setFullYear(Math.max(1, Math.min(9999, date.getFullYear())));\n }\n displayFormat = Object.assign({}, displayFormat, {\n timeZone: 'utc'\n });\n const dtf = new Intl.DateTimeFormat(this.locale, displayFormat);\n return this._stripDirectionalityCharacters(this._format(dtf, date));\n }\n return this._stripDirectionalityCharacters(date.toDateString());\n }\n addCalendarYears(date, years) {\n return this.addCalendarMonths(date, years * 12);\n }\n addCalendarMonths(date, months) {\n let newDate = this._createDateWithOverflow(this.getYear(date), this.getMonth(date) + months, this.getDate(date));\n // It's possible to wind up in the wrong month if the original month has more days than the new\n // month. In this case we want to go to the last day of the desired month.\n // Note: the additional + 12 % 12 ensures we end up with a positive number, since JS % doesn't\n // guarantee this.\n if (this.getMonth(newDate) != ((this.getMonth(date) + months) % 12 + 12) % 12) {\n newDate = this._createDateWithOverflow(this.getYear(newDate), this.getMonth(newDate), 0);\n }\n return newDate;\n }\n addCalendarDays(date, days) {\n return this._createDateWithOverflow(this.getYear(date), this.getMonth(date), this.getDate(date) + days);\n }\n toIso8601(date) {\n return [date.getUTCFullYear(), this._2digit(date.getUTCMonth() + 1), this._2digit(date.getUTCDate())].join('-');\n }\n /**\n * Returns the given value if given a valid Date or null. Deserializes valid ISO 8601 strings\n * (https://www.ietf.org/rfc/rfc3339.txt) into valid Dates and empty string into null. Returns an\n * invalid date for all other values.\n */\n deserialize(value) {\n if (typeof value === 'string') {\n if (!value) {\n return null;\n }\n // The `Date` constructor accepts formats other than ISO 8601, so we need to make sure the\n // string is the right format first.\n if (ISO_8601_REGEX.test(value)) {\n let date = new Date(value);\n if (this.isValid(date)) {\n return date;\n }\n }\n }\n return super.deserialize(value);\n }\n isDateInstance(obj) {\n return obj instanceof Date;\n }\n isValid(date) {\n return !isNaN(date.getTime());\n }\n invalid() {\n return new Date(NaN);\n }\n /** Creates a date but allows the month and date to overflow. */\n _createDateWithOverflow(year, month, date) {\n const result = new Date(year, month, date);\n // We need to correct for the fact that JS native Date treats years in range [0, 99] as\n // abbreviations for 19xx.\n if (year >= 0 && year < 100) {\n result.setFullYear(this.getYear(result) - 1900);\n }\n return result;\n }\n /**\n * Pads a number to make it two digits.\n * @param n The number to pad.\n * @returns The padded number.\n */\n _2digit(n) {\n return ('00' + n).slice(-2);\n }\n /**\n * Strip out unicode LTR and RTL characters. Edge and IE insert these into formatted dates while\n * other browsers do not. We remove them to make output consistent and because they interfere with\n * date parsing.\n * @param str The string to strip direction characters from.\n * @returns The stripped string.\n */\n _stripDirectionalityCharacters(str) {\n return str.replace(/[\\u200e\\u200f]/g, '');\n }\n /**\n * When converting Date object to string, javascript built-in functions may return wrong\n * results because it applies its internal DST rules. The DST rules around the world change\n * very frequently, and the current valid rule is not always valid in previous years though.\n * We work around this problem building a new Date object which has its internal UTC\n * representation with the local date and time.\n * @param dtf Intl.DateTimeFormat object, containg the desired string format. It must have\n * timeZone set to 'utc' to work fine.\n * @param date Date from which we want to get the string representation according to dtf\n * @returns A Date object with its UTC representation based on the passed in date info\n */\n _format(dtf, date) {\n const d = new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), date.getMilliseconds()));\n return dtf.format(d);\n }\n };\n NativeDateAdapter = __decorate([Injectable(), __param(0, Optional()), __param(0, Inject(MAT_DATE_LOCALE))], NativeDateAdapter);\n\n /**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n return NativeDateAdapter;\n})();\nconst MAT_NATIVE_DATE_FORMATS = {\n parse: {\n dateInput: null\n },\n display: {\n dateInput: {\n year: 'numeric',\n month: 'numeric',\n day: 'numeric'\n },\n monthYearLabel: {\n year: 'numeric',\n month: 'short'\n },\n dateA11yLabel: {\n year: 'numeric',\n month: 'long',\n day: 'numeric'\n },\n monthYearA11yLabel: {\n year: 'numeric',\n month: 'long'\n }\n }\n};\n\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\nlet NativeDateModule = /*#__PURE__*/(() => {\n let NativeDateModule = class NativeDateModule {};\n NativeDateModule = __decorate([NgModule({\n imports: [PlatformModule],\n providers: [{\n provide: DateAdapter,\n useClass: NativeDateAdapter\n }]\n })], NativeDateModule);\n return NativeDateModule;\n})();\nconst ɵ0$1 = MAT_NATIVE_DATE_FORMATS;\nlet SatNativeDateModule = /*#__PURE__*/(() => {\n let SatNativeDateModule = class SatNativeDateModule {};\n SatNativeDateModule = __decorate([NgModule({\n imports: [NativeDateModule],\n providers: [{\n provide: MAT_DATE_FORMATS,\n useValue: ɵ0$1\n }]\n })], SatNativeDateModule);\n\n /**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n /** @docs-private */\n return SatNativeDateModule;\n})();\nfunction createMissingDateImplError(provider) {\n return Error(`SatDatepicker: No provider found for ${provider}. You must import one of the following ` + `modules at your application root: SatNativeDateModule, MatMomentDateModule, or provide a ` + `custom implementation.`);\n}\n\n/** Datepicker data that requires internationalization. */\nlet SatDatepickerIntl = class SatDatepickerIntl {\n /** Datepicker data that requires internationalization. */\n constructor() {\n /**\n * Stream that emits whenever the labels here are changed. Use this to notify\n * components if the labels have changed after initialization.\n */\n this.changes = new Subject();\n /** A label for the calendar popup (used by screen readers). */\n this.calendarLabel = 'Calendar';\n /** A label for the button used to open the calendar popup (used by screen readers). */\n this.openCalendarLabel = 'Open calendar';\n /** A label for the previous month button (used by screen readers). */\n this.prevMonthLabel = 'Previous month';\n /** A label for the next month button (used by screen readers). */\n this.nextMonthLabel = 'Next month';\n /** A label for the previous year button (used by screen readers). */\n this.prevYearLabel = 'Previous year';\n /** A label for the next year button (used by screen readers). */\n this.nextYearLabel = 'Next year';\n /** A label for the previous multi-year button (used by screen readers). */\n this.prevMultiYearLabel = 'Previous 20 years';\n /** A label for the next multi-year button (used by screen readers). */\n this.nextMultiYearLabel = 'Next 20 years';\n /** A label for the 'switch to month view' button (used by screen readers). */\n this.switchToMonthViewLabel = 'Choose date';\n /** A label for the 'switch to year view' button (used by screen readers). */\n this.switchToMultiYearViewLabel = 'Choose month and year';\n }\n};\nSatDatepickerIntl.ngInjectableDef = ɵɵdefineInjectable({\n factory: function SatDatepickerIntl_Factory() {\n return new SatDatepickerIntl();\n },\n token: SatDatepickerIntl,\n providedIn: \"root\"\n});\nSatDatepickerIntl = __decorate([Injectable({\n providedIn: 'root'\n})], SatDatepickerIntl);\n\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n/**\n * An internal class that represents the data corresponding to a single calendar cell.\n * @docs-private\n */\nclass SatCalendarCell {\n constructor(value, displayValue, ariaLabel, enabled, cssClasses) {\n this.value = value;\n this.displayValue = displayValue;\n this.ariaLabel = ariaLabel;\n this.enabled = enabled;\n this.cssClasses = cssClasses;\n }\n}\n/**\n * An internal component used to display calendar data in a table.\n * @docs-private\n */\nlet SatCalendarBody = /*#__PURE__*/(() => {\n let SatCalendarBody = class SatCalendarBody {\n constructor(_elementRef, _ngZone) {\n this._elementRef = _elementRef;\n this._ngZone = _ngZone;\n /** Enables datepicker MouseOver effect on range mode */\n this.rangeHoverEffect = true;\n /** Whether to use date range selection behaviour.*/\n this.rangeMode = false;\n /** The number of columns in the table. */\n this.numCols = 7;\n /** The cell number of the active cell in the table. */\n this.activeCell = 0;\n /**\n * The aspect ratio (width / height) to use for the cells in the table. This aspect ratio will be\n * maintained even as the table resizes.\n */\n this.cellAspectRatio = 1;\n /** Emits when a new value is selected. */\n this.selectedValueChange = new EventEmitter();\n }\n _cellClicked(cell) {\n if (cell.enabled) {\n this.selectedValueChange.emit(cell.value);\n }\n }\n _mouseOverCell(cell) {\n if (this.rangeHoverEffect) this._cellOver = cell.value;\n }\n ngOnChanges(changes) {\n const columnChanges = changes['numCols'];\n const {\n rows,\n numCols\n } = this;\n if (changes['rows'] || columnChanges) {\n this._firstRowOffset = rows && rows.length && rows[0].length ? numCols - rows[0].length : 0;\n }\n if (changes['cellAspectRatio'] || columnChanges || !this._cellPadding) {\n this._cellPadding = `${50 * this.cellAspectRatio / numCols}%`;\n }\n if (columnChanges || !this._cellWidth) {\n this._cellWidth = `${100 / numCols}%`;\n }\n if (changes.activeCell) {\n this._cellOver = this.activeCell + 1;\n }\n }\n _isActiveCell(rowIndex, colIndex) {\n let cellNumber = rowIndex * this.numCols + colIndex;\n // Account for the fact that the first row may not have as many cells.\n if (rowIndex) {\n cellNumber -= this._firstRowOffset;\n }\n return cellNumber == this.activeCell;\n }\n /** Whenever to mark cell as semi-selected (inside dates interval). */\n _isSemiSelected(date) {\n if (!this.rangeMode) {\n return false;\n }\n if (this.rangeFull) {\n return true;\n }\n /** Do not mark start and end of interval. */\n if (date === this.begin || date === this.end) {\n return false;\n }\n if (this.begin && !this.end) {\n return date > this.begin;\n }\n if (this.end && !this.begin) {\n return date < this.end;\n }\n return date > this.begin && date < this.end;\n }\n /** Whenever to mark cell as semi-selected before the second date is selected (between the begin cell and the hovered cell). */\n _isBetweenOverAndBegin(date) {\n if (!this._cellOver || !this.rangeMode || !this.beginSelected) {\n return false;\n }\n if (this.isBeforeSelected && !this.begin) {\n return date > this._cellOver;\n }\n if (this._cellOver > this.begin) {\n return date > this.begin && date < this._cellOver;\n }\n if (this._cellOver < this.begin) {\n return date < this.begin && date > this._cellOver;\n }\n return false;\n }\n /** Whenever to mark cell as begin of the range. */\n _isBegin(date) {\n if (this.rangeMode && this.beginSelected && this._cellOver) {\n if (this.isBeforeSelected && !this.begin) {\n return this._cellOver === date;\n } else {\n return this.begin === date && !(this._cellOver < this.begin) || this._cellOver === date && this._cellOver < this.begin;\n }\n }\n return this.begin === date;\n }\n /** Whenever to mark cell as end of the range. */\n _isEnd(date) {\n if (this.rangeMode && this.beginSelected && this._cellOver) {\n if (this.isBeforeSelected && !this.begin) {\n return false;\n } else {\n return this.end === date && !(this._cellOver > this.begin) || this._cellOver === date && this._cellOver > this.begin;\n }\n }\n return this.end === date;\n }\n /** Focuses the active cell after the microtask queue is empty. */\n _focusActiveCell() {\n this._ngZone.runOutsideAngular(() => {\n this._ngZone.onStable.asObservable().pipe(take(1)).subscribe(() => {\n const activeCell = this._elementRef.nativeElement.querySelector('.mat-calendar-body-active');\n if (activeCell) {\n activeCell.focus();\n }\n });\n });\n }\n /** Whenever to highlight the target cell when selecting the second date in range mode */\n _previewCellOver(date) {\n return this._cellOver === date && this.rangeMode && this.beginSelected;\n }\n };\n __decorate([Input()], SatCalendarBody.prototype, \"label\", void 0);\n __decorate([Input()], SatCalendarBody.prototype, \"rangeHoverEffect\", void 0);\n __decorate([Input()], SatCalendarBody.prototype, \"rows\", void 0);\n __decorate([Input()], SatCalendarBody.prototype, \"todayValue\", void 0);\n __decorate([Input()], SatCalendarBody.prototype, \"selectedValue\", void 0);\n __decorate([Input()], SatCalendarBody.prototype, \"begin\", void 0);\n __decorate([Input()], SatCalendarBody.prototype, \"end\", void 0);\n __decorate([Input()], SatCalendarBody.prototype, \"beginSelected\", void 0);\n __decorate([Input()], SatCalendarBody.prototype, \"isBeforeSelected\", void 0);\n __decorate([Input()], SatCalendarBody.prototype, \"rangeFull\", void 0);\n __decorate([Input()], SatCalendarBody.prototype, \"rangeMode\", void 0);\n __decorate([Input()], SatCalendarBody.prototype, \"labelMinRequiredCells\", void 0);\n __decorate([Input()], SatCalendarBody.prototype, \"numCols\", void 0);\n __decorate([Input()], SatCalendarBody.prototype, \"activeCell\", void 0);\n __decorate([Input()], SatCalendarBody.prototype, \"cellAspectRatio\", void 0);\n __decorate([Output()], SatCalendarBody.prototype, \"selectedValueChange\", void 0);\n SatCalendarBody = __decorate([Component({\n moduleId: module.id,\n selector: '[sat-calendar-body]',\n template: \"<!--\\n If there's not enough space in the first row, create a separate label row. We mark this row as\\n aria-hidden because we don't want it to be read out as one of the weeks in the month.\\n-->\\n<tr *ngIf=\\\"_firstRowOffset < labelMinRequiredCells\\\" aria-hidden=\\\"true\\\">\\n <td class=\\\"mat-calendar-body-label\\\"\\n [attr.colspan]=\\\"numCols\\\"\\n [style.paddingTop]=\\\"_cellPadding\\\"\\n [style.paddingBottom]=\\\"_cellPadding\\\">\\n {{label}}\\n </td>\\n</tr>\\n\\n<!-- Create the first row separately so we can include a special spacer cell. -->\\n<tr *ngFor=\\\"let row of rows; let rowIndex = index\\\" role=\\\"row\\\">\\n <!--\\n We mark this cell as aria-hidden so it doesn't get read out as one of the days in the week.\\n The aspect ratio of the table cells is maintained by setting the top and bottom padding as a\\n percentage of the width (a variant of the trick described here:\\n https://www.w3schools.com/howto/howto_css_aspect_ratio.asp).\\n -->\\n <td *ngIf=\\\"rowIndex === 0 && _firstRowOffset\\\"\\n aria-hidden=\\\"true\\\"\\n class=\\\"mat-calendar-body-label\\\"\\n [attr.colspan]=\\\"_firstRowOffset\\\"\\n [style.paddingTop]=\\\"_cellPadding\\\"\\n [style.paddingBottom]=\\\"_cellPadding\\\">\\n {{_firstRowOffset >= labelMinRequiredCells ? label : ''}}\\n </td>\\n <td *ngFor=\\\"let item of row; let colIndex = index\\\"\\n role=\\\"gridcell\\\"\\n class=\\\"mat-calendar-body-cell\\\"\\n [ngClass]=\\\"item.cssClasses\\\"\\n [tabindex]=\\\"_isActiveCell(rowIndex, colIndex) ? 0 : -1\\\"\\n [class.mat-calendar-body-disabled]=\\\"!item.enabled\\\"\\n [class.mat-calendar-body-active]=\\\"_isActiveCell(rowIndex, colIndex)\\\"\\n [class.mat-calendar-body-begin-range]=\\\"_isBegin(item.value)\\\"\\n [class.mat-calendar-body-end-range]=\\\"_isEnd(item.value)\\\"\\n [class.mat-calendar-cell-semi-selected]=\\\"_isSemiSelected(item.value) || _isBetweenOverAndBegin(item.value)\\\"\\n [class.mat-calendar-cell-over]=\\\"_previewCellOver(item.value)\\\"\\n [attr.aria-label]=\\\"item.ariaLabel\\\"\\n [attr.aria-disabled]=\\\"!item.enabled || null\\\"\\n [attr.aria-selected]=\\\"selectedValue === item.value\\\"\\n (click)=\\\"_cellClicked(item)\\\"\\n (mouseover)=\\\"_mouseOverCell(item)\\\"\\n [style.width]=\\\"_cellWidth\\\"\\n [style.paddingTop]=\\\"_cellPadding\\\"\\n [style.paddingBottom]=\\\"_cellPadding\\\">\\n <div class=\\\"mat-calendar-body-cell-content\\\"\\n [class.mat-calendar-body-selected]=\\\"begin === item.value || end === item.value || selectedValue === item.value\\\"\\n [class.mat-calendar-body-semi-selected]=\\\"_isSemiSelected(item.value)\\\"\\n [class.mat-calendar-body-today]=\\\"todayValue === item.value\\\">\\n {{item.displayValue}}\\n </div>\\n </td>\\n</tr>\\n\",\n host: {\n 'class': 'mat-calendar-body',\n 'role': 'grid',\n 'aria-readonly': 'true'\n },\n exportAs: 'matCalendarBody',\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n 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}\"]\n })], SatCalendarBody);\n\n /**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n return SatCalendarBody;\n})();\nconst DAYS_PER_WEEK = 7;\n/**\n * An internal component used to display a single month in the datepicker.\n * @docs-private\n */\nlet SatMonthView = /*#__PURE__*/(() => {\n let SatMonthView = class SatMonthView {\n constructor(_changeDetectorRef, _dateFormats, _dateAdapter, _dir) {\n this._changeDetectorRef = _changeDetectorRef;\n this._dateFormats = _dateFormats;\n this._dateAdapter = _dateAdapter;\n this._dir = _dir;\n /** Allow selecting range of dates. */\n this.rangeMode = false;\n /** Enables datepicker MouseOver effect on range mode */\n this.rangeHoverEffect = true;\n /** Enables datepicker closing after selection */\n this.closeAfterSelection = true;\n /** Whenever full month is inside dates interval. */\n this._rangeFull = false;\n /** Emits when a new date is selected. */\n this.selectedChange = new EventEmitter();\n /** Emits when any date is selected. */\n this._userSelection = new EventEmitter();\n /** Emits when any date is activated. */\n this.activeDateChange = new EventEmitter();\n if (!this._dateAdapter) {\n throw createMissingDateImplError('DateAdapter');\n }\n if (!this._dateFormats) {\n throw createMissingDateImplError('MAT_DATE_FORMATS');\n }\n this._activeDate = this._dateAdapter.today();\n }\n /** Current start of interval. */\n get beginDate() {\n return this._beginDate;\n }\n set beginDate(value) {\n this._beginDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value));\n this.updateRangeSpecificValues();\n }\n /** Current end of interval. */\n get endDate() {\n return this._endDate;\n }\n set endDate(value) {\n this._endDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value));\n this.updateRangeSpecificValues();\n }\n /** Whenever user already selected start of dates interval. */\n set beginDateSelected(value) {\n this._beginDateSelected = value;\n }\n /**\n * The date to display in this month view (everything other than the month and year is ignored).\n */\n get activeDate() {\n return this._activeDate;\n }\n set activeDate(value) {\n const oldActiveDate = this._activeDate;\n const validDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value)) || this._dateAdapter.today();\n this._activeDate = this._dateAdapter.clampDate(validDate, this.minDate, this.maxDate);\n if (!this._hasSameMonthAndYear(oldActiveDate, this._activeDate)) {\n this._init();\n }\n }\n /** The currently selected date. */\n get selected() {\n return this._selected;\n }\n set selected(value) {\n this._selected = this._getValidDateOrNull(this._dateAdapter.deserialize(value));\n this._selectedDate = this._getDateInCurrentMonth(this._selected);\n }\n /** The minimum selectable date. */\n get minDate() {\n return this._minDate;\n }\n set minDate(value) {\n this._minDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n /** The maximum selectable date. */\n get maxDate() {\n return this._maxDate;\n }\n set maxDate(value) {\n this._maxDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n ngAfterContentInit() {\n this._init();\n }\n /** Handles when a new date is selected. */\n _dateSelected(date) {\n if (this.rangeMode) {\n const selectedYear = this._dateAdapter.getYear(this.activeDate);\n const selectedMonth = this._dateAdapter.getMonth(this.activeDate);\n const selectedDate = this._dateAdapter.createDate(selectedYear, selectedMonth, date);\n if (!this._beginDateSelected) {\n // At first click emit the same start and end of interval\n this._beginDateSelected = selectedDate;\n this.selectedChange.emit(selectedDate);\n } else {\n this._beginDateSelected = null;\n this.selectedChange.emit(selectedDate);\n this._userSelection.emit();\n }\n this._createWeekCells();\n this.activeDate = selectedDate;\n this._focusActiveCell();\n } else if (this._selectedDate != date) {\n const selectedYear = this._dateAdapter.getYear(this.activeDate);\n const selectedMonth = this._dateAdapter.getMonth(this.activeDate);\n const selectedDate = this._dateAdapter.createDate(selectedYear, selectedMonth, date);\n this.selectedChange.emit(selectedDate);\n this._userSelection.emit();\n this._createWeekCells();\n }\n }\n /** Handles keydown events on the calendar body when calendar is in month view. */\n _handleCalendarBodyKeydown(event) {\n // TODO(mmalerba): We currently allow keyboard navigation to disabled dates, but just prevent\n // disabled ones from being selected. This may not be ideal, we should look into whether\n // navigation should skip over disabled dates, and if so, how to implement that efficiently.\n const oldActiveDate = this._activeDate;\n const isRtl = this._isRtl();\n switch (event.keyCode) {\n case LEFT_ARROW:\n this.activeDate = this._dateAdapter.addCalendarDays(this._activeDate, isRtl ? 1 : -1);\n break;\n case RIGHT_ARROW:\n this.activeDate = this._dateAdapter.addCalendarDays(this._activeDate, isRtl ? -1 : 1);\n break;\n case UP_ARROW:\n this.activeDate = this._dateAdapter.addCalendarDays(this._activeDate, -7);\n break;\n case DOWN_ARROW:\n this.activeDate = this._dateAdapter.addCalendarDays(this._activeDate, 7);\n break;\n case HOME:\n this.activeDate = this._dateAdapter.addCalendarDays(this._activeDate, 1 - this._dateAdapter.getDate(this._activeDate));\n break;\n case END:\n this.activeDate = this._dateAdapter.addCalendarDays(this._activeDate, this._dateAdapter.getNumDaysInMonth(this._activeDate) - this._dateAdapter.getDate(this._activeDate));\n break;\n case PAGE_UP:\n this.activeDate = event.altKey ? this._dateAdapter.addCalendarYears(this._activeDate, -1) : this._dateAdapter.addCalendarMonths(this._activeDate, -1);\n break;\n case PAGE_DOWN:\n this.activeDate = event.altKey ? this._dateAdapter.addCalendarYears(this._activeDate, 1) : this._dateAdapter.addCalendarMonths(this._activeDate, 1);\n break;\n case ENTER:\n case SPACE:\n if (!this.dateFilter || this.dateFilter(this._activeDate)) {\n this._dateSelected(this._dateAdapter.getDate(this._activeDate));\n if (!this._beginDateSelected) {\n this._userSelection.emit();\n }\n if (this._beginDateSelected || !this.closeAfterSelection) {\n this._focusActiveCell();\n }\n // Prevent unexpected default actions such as form submission.\n event.preventDefault();\n }\n return;\n default:\n // Don't prevent default or focus active cell on keys that we don't explicitly handle.\n return;\n }\n if (this._dateAdapter.compareDate(oldActiveDate, this.activeDate)) {\n this.activeDateChange.emit(this.activeDate);\n }\n this._focusActiveCell();\n // Prevent unexpected default actions such as form submission.\n event.preventDefault();\n }\n /** Initializes this month view. */\n _init() {\n this.updateRangeSpecificValues();\n this._selectedDate = this._getDateInCurrentMonth(this.selected);\n this._todayDate = this._getDateInCurrentMonth(this._dateAdapter.today());\n this._monthLabel = this._dateAdapter.getMonthNames('short')[this._dateAdapter.getMonth(this.activeDate)].toLocaleUpperCase();\n let firstOfMonth = this._dateAdapter.createDate(this._dateAdapter.getYear(this.activeDate), this._dateAdapter.getMonth(this.activeDate), 1);\n this._firstWeekOffset = (DAYS_PER_WEEK + this._dateAdapter.getDayOfWeek(firstOfMonth) - this._dateAdapter.getFirstDayOfWeek()) % DAYS_PER_WEEK;\n this._initWeekdays();\n this._createWeekCells();\n this._changeDetectorRef.markForCheck();\n }\n /** Focuses the active cell after the microtask queue is empty. */\n _focusActiveCell() {\n this._matCalendarBody._focusActiveCell();\n }\n /** Initializes the weekdays. */\n _initWeekdays() {\n const firstDayOfWeek = this._dateAdapter.getFirstDayOfWeek();\n const narrowWeekdays = this._dateAdapter.getDayOfWeekNames('narrow');\n const longWeekdays = this._dateAdapter.getDayOfWeekNames('long');\n // Rotate the labels for days of the week based on the configured first day of the week.\n let weekdays = longWeekdays.map((long, i) => {\n return {\n long,\n narrow: narrowWeekdays[i]\n };\n });\n this._weekdays = weekdays.slice(firstDayOfWeek).concat(weekdays.slice(0, firstDayOfWeek));\n }\n /** Creates SatCalendarCells for the dates in this month. */\n _createWeekCells() {\n const daysInMonth = this._dateAdapter.getNumDaysInMonth(this.activeDate);\n const dateNames = this._dateAdapter.getDateNames();\n this._weeks = [[]];\n for (let i = 0, cell = this._firstWeekOffset; i < daysInMonth; i++, cell++) {\n if (cell == DAYS_PER_WEEK) {\n this._weeks.push([]);\n cell = 0;\n }\n const date = this._dateAdapter.createDate(this._dateAdapter.getYear(this.activeDate), this._dateAdapter.getMonth(this.activeDate), i + 1);\n const enabled = this._shouldEnableDate(date);\n const ariaLabel = this._dateAdapter.format(date, this._dateFormats.display.dateA11yLabel);\n const cellClasses = this.dateClass ? this.dateClass(date) : undefined;\n this._weeks[this._weeks.length - 1].push(new SatCalendarCell(i + 1, dateNames[i], ariaLabel, enabled, cellClasses));\n }\n }\n /** Date filter for the month */\n _shouldEnableDate(date) {\n 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);\n }\n /**\n * Gets the date in this month that the given Date falls on.\n * Returns null if the given Date is in another month.\n */\n _getDateInCurrentMonth(date) {\n return date && this._hasSameMonthAndYear(date, this.activeDate) ? this._dateAdapter.getDate(date) : null;\n }\n /** Checks whether the 2 dates are non-null and fall within the same month of the same year. */\n _hasSameMonthAndYear(d1, d2) {\n return !!(d1 && d2 && this._dateAdapter.getMonth(d1) == this._dateAdapter.getMonth(d2) && this._dateAdapter.getYear(d1) == this._dateAdapter.getYear(d2));\n }\n /**\n * @param obj The object to check.\n * @returns The given object if it is both a date instance and valid, otherwise null.\n */\n _getValidDateOrNull(obj) {\n return this._dateAdapter.isDateInstance(obj) && this._dateAdapter.isValid(obj) ? obj : null;\n }\n /** Determines whether the user has the RTL layout direction. */\n _isRtl() {\n return this._dir && this._dir.value === 'rtl';\n }\n /** Updates range full parameter on each begin or end of interval update.\n * Necessary to display calendar-body correctly\n */\n updateRangeSpecificValues() {\n if (this.rangeMode) {\n this._beginDateNumber = this._getDateInCurrentMonth(this._beginDate);\n this._endDateNumber = this._getDateInCurrentMonth(this._endDate);\n this._rangeFull = this.beginDate && this.endDate && !this._beginDateNumber && !this._endDateNumber && this._dateAdapter.compareDate(this.beginDate, this.activeDate) <= 0 && this._dateAdapter.compareDate(this.activeDate, this.endDate) <= 0;\n } else {\n this._beginDateNumber = this._endDateNumber = null;\n this._rangeFull = false;\n }\n }\n };\n __decorate([Input()], SatMonthView.prototype, \"beginDate\", null);\n __decorate([Input()], SatMonthView.prototype, \"endDate\", null);\n __decorate([Input()], SatMonthView.prototype, \"rangeMode\", void 0);\n __decorate([Input()], SatMonthView.prototype, \"rangeHoverEffect\", void 0);\n __decorate([Input()], SatMonthView.prototype, \"closeAfterSelection\", void 0);\n __decorate([Input()], SatMonthView.prototype, \"beginDateSelected\", null);\n __decorate([Input()], SatMonthView.prototype, \"activeDate\", null);\n __decorate([Input()], SatMonthView.prototype, \"selected\", null);\n __decorate([Input()], SatMonthView.prototype, \"minDate\", null);\n __decorate([Input()], SatMonthView.prototype, \"maxDate\", null);\n __decorate([Input()], SatMonthView.prototype, \"dateFilter\", void 0);\n __decorate([Input()], SatMonthView.prototype, \"dateClass\", void 0);\n __decorate([Output()], SatMonthView.prototype, \"selectedChange\", void 0);\n __decorate([Output()], SatMonthView.prototype, \"_userSelection\", void 0);\n __decorate([Output()], SatMonthView.prototype, \"activeDateChange\", void 0);\n __decorate([ViewChild(SatCalendarBody, {\n static: false\n })], SatMonthView.prototype, \"_matCalendarBody\", void 0);\n SatMonthView = __decorate([Component({\n moduleId: module.id,\n selector: 'sat-month-view',\n template: \"<table class=\\\"mat-calendar-table\\\">\\n <thead class=\\\"mat-calendar-table-header\\\">\\n <tr><th *ngFor=\\\"let day of _weekdays\\\" [attr.aria-label]=\\\"day.long\\\">{{day.narrow}}</th></tr>\\n <tr><th class=\\\"mat-calendar-table-header-divider\\\" colspan=\\\"7\\\" aria-hidden=\\\"true\\\"></th></tr>\\n </thead>\\n <tbody sat-calendar-body\\n [label]=\\\"_monthLabel\\\"\\n [rows]=\\\"_weeks\\\"\\n [todayValue]=\\\"_todayDate\\\"\\n [selectedValue]=\\\"_selectedDate\\\"\\n [begin]=\\\"_beginDateNumber\\\"\\n [end]=\\\"_endDateNumber\\\"\\n [beginSelected]=\\\"_beginDateSelected\\\"\\n [isBeforeSelected]=\\\"_beginDateSelected && _dateAdapter.compareDate(activeDate, _beginDateSelected) < 0\\\"\\n [rangeFull]=\\\"_rangeFull\\\"\\n [rangeMode]=\\\"rangeMode\\\"\\n [rangeHoverEffect]=\\\"rangeHoverEffect\\\"\\n [labelMinRequiredCells]=\\\"3\\\"\\n [activeCell]=\\\"_dateAdapter.getDate(activeDate) - 1\\\"\\n (selectedValueChange)=\\\"_dateSelected($event)\\\"\\n (keydown)=\\\"_handleCalendarBodyKeydown($event)\\\">\\n </tbody>\\n</table>\\n\",\n exportAs: 'matMonthView',\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush\n }), __param(1, Optional()), __param(1, Inject(MAT_DATE_FORMATS)), __param(2, Optional()), __param(3, Optional())], SatMonthView);\n\n /**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n return SatMonthView;\n})();\nconst yearsPerPage = 24;\nconst yearsPerRow = 4;\n/**\n * An internal component used to display a year selector in the datepicker.\n * @docs-private\n */\nlet SatMultiYearView = /*#__PURE__*/(() => {\n let SatMultiYearView = class SatMultiYearView {\n constructor(_changeDetectorRef, _dateAdapter, _dir) {\n this._changeDetectorRef = _changeDetectorRef;\n this._dateAdapter = _dateAdapter;\n this._dir = _dir;\n /** Emits when a new year is selected. */\n this.selectedChange = new EventEmitter();\n /** Emits the selected year. This doesn't imply a change on the selected date */\n this.yearSelected = new EventEmitter();\n /** Emits when any date is activated. */\n this.activeDateChange = new EventEmitter();\n if (!this._dateAdapter) {\n throw createMissingDateImplError('DateAdapter');\n }\n this._activeDate = this._dateAdapter.today();\n }\n /** The date to display in this multi-year view (everything other than the year is ignored). */\n get activeDate() {\n return this._activeDate;\n }\n set activeDate(value) {\n let oldActiveDate = this._activeDate;\n const validDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value)) || this._dateAdapter.today();\n this._activeDate = this._dateAdapter.clampDate(validDate, this.minDate, this.maxDate);\n if (!isSameMultiYearView(this._dateAdapter, oldActiveDate, this._activeDate, this.minDate, this.maxDate)) {\n this._init();\n }\n }\n /** The currently selected date. */\n get selected() {\n return this._selected;\n }\n set selected(value) {\n this._selected = this._getValidDateOrNull(this._dateAdapter.deserialize(value));\n this._selectedYear = this._selected && this._dateAdapter.getYear(this._selected);\n }\n /** The minimum selectable date. */\n get minDate() {\n return this._minDate;\n }\n set minDate(value) {\n this._minDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n /** The maximum selectable date. */\n get maxDate() {\n return this._maxDate;\n }\n set maxDate(value) {\n this._maxDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n ngAfterContentInit() {\n this._init();\n }\n /** Initializes this multi-year view. */\n _init() {\n this._todayYear = this._dateAdapter.getYear(this._dateAdapter.today());\n // We want a range years such that we maximize the number of\n // enabled dates visible at once. This prevents issues where the minimum year\n // is the last item of a page OR the maximum year is the first item of a page.\n // The offset from the active year to the \"slot\" for the starting year is the\n // *actual* first rendered year in the multi-year view.\n const activeYear = this._dateAdapter.getYear(this._activeDate);\n const minYearOfPage = activeYear - getActiveOffset(this._dateAdapter, this.activeDate, this.minDate, this.maxDate);\n this._years = [];\n for (let i = 0, row = []; i < yearsPerPage; i++) {\n row.push(minYearOfPage + i);\n if (row.length == yearsPerRow) {\n this._years.push(row.map(year => this._createCellForYear(year)));\n row = [];\n }\n }\n this._changeDetectorRef.markForCheck();\n }\n /** Handles when a new year is selected. */\n _yearSelected(year) {\n this.yearSelected.emit(this._dateAdapter.createDate(year, 0, 1));\n let month = this._dateAdapter.getMonth(this.activeDate);\n let daysInMonth = this._dateAdapter.getNumDaysInMonth(this._dateAdapter.createDate(year, month, 1));\n this.selectedChange.emit(this._dateAdapter.createDate(year, month, Math.min(this._dateAdapter.getDate(this.activeDate), daysInMonth)));\n }\n /** Handles keydown events on the calendar body when calendar is in multi-year view. */\n _handleCalendarBodyKeydown(event) {\n const oldActiveDate = this._activeDate;\n const isRtl = this._isRtl();\n switch (event.keyCode) {\n case LEFT_ARROW:\n this.activeDate = this._dateAdapter.addCalendarYears(this._activeDate, isRtl ? 1 : -1);\n break;\n case RIGHT_ARROW:\n this.activeDate = this._dateAdapter.addCalendarYears(this._activeDate, isRtl ? -1 : 1);\n break;\n case UP_ARROW:\n this.activeDate = this._dateAdapter.addCalendarYears(this._activeDate, -yearsPerRow);\n break;\n case DOWN_ARROW:\n this.activeDate = this._dateAdapter.addCalendarYears(this._activeDate, yearsPerRow);\n break;\n case HOME:\n this.activeDate = this._dateAdapter.addCalendarYears(this._activeDate, -getActiveOffset(this._dateAdapter, this.activeDate, this.minDate, this.maxDate));\n break;\n case END:\n this.activeDate = this._dateAdapter.addCalendarYears(this._activeDate, yearsPerPage - getActiveOffset(this._dateAdapter, this.activeDate, this.minDate, this.maxDate) - 1);\n break;\n case PAGE_UP:\n this.activeDate = this._dateAdapter.addCalendarYears(this._activeDate, event.altKey ? -yearsPerPage * 10 : -yearsPerPage);\n break;\n case PAGE_DOWN:\n this.activeDate = this._dateAdapter.addCalendarYears(this._activeDate, event.altKey ? yearsPerPage * 10 : yearsPerPage);\n break;\n case ENTER:\n case SPACE:\n this._yearSelected(this._dateAdapter.getYear(this._activeDate));\n break;\n default:\n // Don't prevent default or focus active cell on keys that we don't explicitly handle.\n return;\n }\n if (this._dateAdapter.compareDate(oldActiveDate, this.activeDate)) {\n this.activeDateChange.emit(this.activeDate);\n }\n this._focusActiveCell();\n // Prevent unexpected default actions such as form submission.\n event.preventDefault();\n }\n _getActiveCell() {\n return getActiveOffset(this._dateAdapter, this.activeDate, this.minDate, this.maxDate);\n }\n /** Focuses the active cell after the microtask queue is empty. */\n _focusActiveCell() {\n this._matCalendarBody._focusActiveCell();\n }\n /** Creates an SatCalendarCell for the given year. */\n _createCellForYear(year) {\n let yearName = this._dateAdapter.getYearName(this._dateAdapter.createDate(year, 0, 1));\n return new SatCalendarCell(year, yearName, yearName, this._shouldEnableYear(year));\n }\n /** Whether the given year is enabled. */\n _shouldEnableYear(year) {\n // disable if the year is greater than maxDate lower than minDate\n if (year === undefined || year === null || this.maxDate && year > this._dateAdapter.getYear(this.maxDate) || this.minDate && year < this._dateAdapter.getYear(this.minDate)) {\n return false;\n }\n // enable if it reaches here and there's no filter defined\n if (!this.dateFilter) {\n return true;\n }\n const firstOfYear = this._dateAdapter.createDate(year, 0, 1);\n // If any date in the year is enabled count the year as enabled.\n for (let date = firstOfYear; this._dateAdapter.getYear(date) == year; date = this._dateAdapter.addCalendarDays(date, 1)) {\n if (this.dateFilter(date)) {\n return true;\n }\n }\n return false;\n }\n /**\n * @param obj The object to check.\n * @returns The given object if it is both a date instance and valid, otherwise null.\n */\n _getValidDateOrNull(obj) {\n return this._dateAdapter.isDateInstance(obj) && this._dateAdapter.isValid(obj) ? obj : null;\n }\n /** Determines whether the user has the RTL layout direction. */\n _isRtl() {\n return this._dir && this._dir.value === 'rtl';\n }\n };\n __decorate([Input()], SatMultiYearView.prototype, \"activeDate\", null);\n __decorate([Input()], SatMultiYearView.prototype, \"selected\", null);\n __decorate([Input()], SatMultiYearView.prototype, \"minDate\", null);\n __decorate([Input()], SatMultiYearView.prototype, \"maxDate\", null);\n __decorate([Input()], SatMultiYearView.prototype, \"dateFilter\", void 0);\n __decorate([Output()], SatMultiYearView.prototype, \"selectedChange\", void 0);\n __decorate([Output()], SatMultiYearView.prototype, \"yearSelected\", void 0);\n __decorate([Output()], SatMultiYearView.prototype, \"activeDateChange\", void 0);\n __decorate([ViewChild(SatCalendarBody, {\n static: false\n })], SatMultiYearView.prototype, \"_matCalendarBody\", void 0);\n SatMultiYearView = __decorate([Component({\n moduleId: module.id,\n selector: 'sat-multi-year-view',\n template: \"<table class=\\\"mat-calendar-table\\\" role=\\\"presentation\\\">\\n <thead class=\\\"mat-calendar-table-header\\\">\\n <tr><th class=\\\"mat-calendar-table-header-divider\\\" colspan=\\\"4\\\"></th></tr>\\n </thead>\\n <tbody sat-calendar-body\\n [rows]=\\\"_years\\\"\\n [todayValue]=\\\"_todayYear\\\"\\n [selectedValue]=\\\"_selectedYear\\\"\\n [numCols]=\\\"4\\\"\\n [cellAspectRatio]=\\\"4 / 7\\\"\\n [activeCell]=\\\"_getActiveCell()\\\"\\n (selectedValueChange)=\\\"_yearSelected($event)\\\"\\n (keydown)=\\\"_handleCalendarBodyKeydown($event)\\\">\\n </tbody>\\n</table>\\n\",\n exportAs: 'matMultiYearView',\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush\n }), __param(1, Optional()), __param(2, Optional())], SatMultiYearView);\n return SatMultiYearView;\n})();\nfunction isSameMultiYearView(dateAdapter, date1, date2, minDate, maxDate) {\n const year1 = dateAdapter.getYear(date1);\n const year2 = dateAdapter.getYear(date2);\n const startingYear = getStartingYear(dateAdapter, minDate, maxDate);\n return Math.floor((year1 - startingYear) / yearsPerPage) === Math.floor((year2 - startingYear) / yearsPerPage);\n}\n/**\n * When the multi-year view is first opened, the active year will be in view.\n * So we compute how many years are between the active year and the *slot* where our\n * \"startingYear\" will render when paged into view.\n */\nfunction getActiveOffset(dateAdapter, activeDate, minDate, maxDate) {\n const activeYear = dateAdapter.getYear(activeDate);\n return euclideanModulo(activeYear - getStartingYear(dateAdapter, minDate, maxDate), yearsPerPage);\n}\n/**\n * We pick a \"starting\" year such that either the maximum year would be at the end\n * or the minimum year would be at the beginning of a page.\n */\nfunction getStartingYear(dateAdapter, minDate, maxDate) {\n let startingYear = 0;\n if (maxDate) {\n const maxYear = dateAdapter.getYear(maxDate);\n startingYear = maxYear - yearsPerPage + 1;\n } else if (minDate) {\n startingYear = dateAdapter.getYear(minDate);\n }\n return startingYear;\n}\n/** Gets remainder that is non-negative, even if first number is negative */\nfunction euclideanModulo(a, b) {\n return (a % b + b) % b;\n}\n\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n/**\n * An internal component used to display a single year in the datepicker.\n * @docs-private\n */\nlet SatYearView = /*#__PURE__*/(() => {\n let SatYearView = class SatYearView {\n constructor(_changeDetectorRef, _dateFormats, _dateAdapter, _dir) {\n this._changeDetectorRef = _changeDetectorRef;\n this._dateFormats = _dateFormats;\n this._dateAdapter = _dateAdapter;\n this._dir = _dir;\n /** Emits when a new month is selected. */\n this.selectedChange = new EventEmitter();\n /** Emits the selected month. This doesn't imply a change on the selected date */\n this.monthSelected = new EventEmitter();\n /** Emits when any date is activated. */\n this.activeDateChange = new EventEmitter();\n if (!this._dateAdapter) {\n throw createMissingDateImplError('DateAdapter');\n }\n if (!this._dateFormats) {\n throw createMissingDateImplError('MAT_DATE_FORMATS');\n }\n this._activeDate = this._dateAdapter.today();\n }\n /** The date to display in this year view (everything other than the year is ignored). */\n get activeDate() {\n return this._activeDate;\n }\n set activeDate(value) {\n let oldActiveDate = this._activeDate;\n const validDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value)) || this._dateAdapter.today();\n this._activeDate = this._dateAdapter.clampDate(validDate, this.minDate, this.maxDate);\n if (this._dateAdapter.getYear(oldActiveDate) !== this._dateAdapter.getYear(this._activeDate)) {\n this._init();\n }\n }\n /** The currently selected date. */\n get selected() {\n return this._selected;\n }\n set selected(value) {\n this._selected = this._getValidDateOrNull(this._dateAdapter.deserialize(value));\n this._selectedMonth = this._getMonthInCurrentYear(this._selected);\n }\n /** The minimum selectable date. */\n get minDate() {\n return this._minDate;\n }\n set minDate(value) {\n this._minDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n /** The maximum selectable date. */\n get maxDate() {\n return this._maxDate;\n }\n set maxDate(value) {\n this._maxDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n ngAfterContentInit() {\n this._init();\n }\n /** Handles when a new month is selected. */\n _monthSelected(month) {\n const normalizedDate = this._dateAdapter.createDate(this._dateAdapter.getYear(this.activeDate), month, 1);\n this.monthSelected.emit(normalizedDate);\n const daysInMonth = this._dateAdapter.getNumDaysInMonth(normalizedDate);\n this.selectedChange.emit(this._dateAdapter.createDate(this._dateAdapter.getYear(this.activeDate), month, Math.min(this._dateAdapter.getDate(this.activeDate), daysInMonth)));\n }\n /** Handles keydown events on the calendar body when calendar is in year view. */\n _handleCalendarBodyKeydown(event) {\n // TODO(mmalerba): We currently allow keyboard navigation to disabled dates, but just prevent\n // disabled ones from being selected. This may not be ideal, we should look into whether\n // navigation should skip over disabled dates, and if so, how to implement that efficiently.\n const oldActiveDate = this._activeDate;\n const isRtl = this._isRtl();\n switch (event.keyCode) {\n case LEFT_ARROW:\n this.activeDate = this._dateAdapter.addCalendarMonths(this._activeDate, isRtl ? 1 : -1);\n break;\n case RIGHT_ARROW:\n this.activeDate = this._dateAdapter.addCalendarMonths(this._activeDate, isRtl ? -1 : 1);\n break;\n case UP_ARROW:\n this.activeDate = this._dateAdapter.addCalendarMonths(this._activeDate, -4);\n break;\n case DOWN_ARROW:\n this.activeDate = this._dateAdapter.addCalendarMonths(this._activeDate, 4);\n break;\n case HOME:\n this.activeDate = this._dateAdapter.addCalendarMonths(this._activeDate, -this._dateAdapter.getMonth(this._activeDate));\n break;\n case END:\n this.activeDate = this._dateAdapter.addCalendarMonths(this._activeDate, 11 - this._dateAdapter.getMonth(this._activeDate));\n break;\n case PAGE_UP:\n this.activeDate = this._dateAdapter.addCalendarYears(this._activeDate, event.altKey ? -10 : -1);\n break;\n case PAGE_DOWN:\n this.activeDate = this._dateAdapter.addCalendarYears(this._activeDate, event.altKey ? 10 : 1);\n break;\n case ENTER:\n case SPACE:\n this._monthSelected(this._dateAdapter.getMonth(this._activeDate));\n break;\n default:\n // Don't prevent default or focus active cell on keys that we don't explicitly handle.\n return;\n }\n if (this._dateAdapter.compareDate(oldActiveDate, this.activeDate)) {\n this.activeDateChange.emit(this.activeDate);\n }\n this._focusActiveCell();\n // Prevent unexpected default actions such as form submission.\n event.preventDefault();\n }\n /** Initializes this year view. */\n _init() {\n this._selectedMonth = this._getMonthInCurrentYear(this.selected);\n this._todayMonth = this._getMonthInCurrentYear(this._dateAdapter.today());\n this._yearLabel = this._dateAdapter.getYearName(this.activeDate);\n let monthNames = this._dateAdapter.getMonthNames('short');\n // First row of months only contains 5 elements so we can fit the year label on the same row.\n this._months = [[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11]].map(row => row.map(month => this._createCellForMonth(month, monthNames[month])));\n this._changeDetectorRef.markForCheck();\n }\n /** Focuses the active cell after the microtask queue is empty. */\n _focusActiveCell() {\n this._matCalendarBody._focusActiveCell();\n }\n /**\n * Gets the month in this year that the given Date falls on.\n * Returns null if the given Date is in another year.\n */\n _getMonthInCurrentYear(date) {\n return date && this._dateAdapter.getYear(date) == this._dateAdapter.getYear(this.activeDate) ? this._dateAdapter.getMonth(date) : null;\n }\n /** Creates an SatCalendarCell for the given month. */\n _createCellForMonth(month, monthName) {\n let ariaLabel = this._dateAdapter.format(this._dateAdapter.createDate(this._dateAdapter.getYear(this.activeDate), month, 1), this._dateFormats.display.monthYearA11yLabel);\n return new SatCalendarCell(month, monthName.toLocaleUpperCase(), ariaLabel, this._shouldEnableMonth(month));\n }\n /** Whether the given month is enabled. */\n _shouldEnableMonth(month) {\n const activeYear = this._dateAdapter.getYear(this.activeDate);\n if (month === undefined || month === null || this._isYearAndMonthAfterMaxDate(activeYear, month) || this._isYearAndMonthBeforeMinDate(activeYear, month)) {\n return false;\n }\n if (!this.dateFilter) {\n return true;\n }\n const firstOfMonth = this._dateAdapter.createDate(activeYear, month, 1);\n // If any date in the month is enabled count the month as enabled.\n for (let date = firstOfMonth; this._dateAdapter.getMonth(date) == month; date = this._dateAdapter.addCalendarDays(date, 1)) {\n if (this.dateFilter(date)) {\n return true;\n }\n }\n return false;\n }\n /**\n * Tests whether the combination month/year is after this.maxDate, considering\n * just the month and year of this.maxDate\n */\n _isYearAndMonthAfterMaxDate(year, month) {\n if (this.maxDate) {\n const maxYear = this._dateAdapter.getYear(this.maxDate);\n const maxMonth = this._dateAdapter.getMonth(this.maxDate);\n return year > maxYear || year === maxYear && month > maxMonth;\n }\n return false;\n }\n /**\n * Tests whether the combination month/year is before this.minDate, considering\n * just the month and year of this.minDate\n */\n _isYearAndMonthBeforeMinDate(year, month) {\n if (this.minDate) {\n const minYear = this._dateAdapter.getYear(this.minDate);\n const minMonth = this._dateAdapter.getMonth(this.minDate);\n return year < minYear || year === minYear && month < minMonth;\n }\n return false;\n }\n /**\n * @param obj The object to check.\n * @returns The given object if it is both a date instance and valid, otherwise null.\n */\n _getValidDateOrNull(obj) {\n return this._dateAdapter.isDateInstance(obj) && this._dateAdapter.isValid(obj) ? obj : null;\n }\n /** Determines whether the user has the RTL layout direction. */\n _isRtl() {\n return this._dir && this._dir.value === 'rtl';\n }\n };\n __decorate([Input()], SatYearView.prototype, \"activeDate\", null);\n __decorate([Input()], SatYearView.prototype, \"selected\", null);\n __decorate([Input()], SatYearView.prototype, \"minDate\", null);\n __decorate([Input()], SatYearView.prototype, \"maxDate\", null);\n __decorate([Input()], SatYearView.prototype, \"dateFilter\", void 0);\n __decorate([Output()], SatYearView.prototype, \"selectedChange\", void 0);\n __decorate([Output()], SatYearView.prototype, \"monthSelected\", void 0);\n __decorate([Output()], SatYearView.prototype, \"activeDateChange\", void 0);\n __decorate([ViewChild(SatCalendarBody, {\n static: false\n })], SatYearView.prototype, \"_matCalendarBody\", void 0);\n SatYearView = __decorate([Component({\n moduleId: module.id,\n selector: 'sat-year-view',\n template: \"<table class=\\\"mat-calendar-table\\\" role=\\\"presentation\\\">\\n <thead class=\\\"mat-calendar-table-header\\\">\\n <tr><th class=\\\"mat-calendar-table-header-divider\\\" colspan=\\\"4\\\"></th></tr>\\n </thead>\\n <tbody sat-calendar-body\\n [label]=\\\"_yearLabel\\\"\\n [rows]=\\\"_months\\\"\\n [todayValue]=\\\"_todayMonth\\\"\\n [selectedValue]=\\\"_selectedMonth\\\"\\n [labelMinRequiredCells]=\\\"2\\\"\\n [numCols]=\\\"4\\\"\\n [cellAspectRatio]=\\\"4 / 7\\\"\\n [activeCell]=\\\"_dateAdapter.getMonth(activeDate)\\\"\\n (selectedValueChange)=\\\"_monthSelected($event)\\\"\\n (keydown)=\\\"_handleCalendarBodyKeydown($event)\\\">\\n </tbody>\\n</table>\\n\",\n exportAs: 'matYearView',\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush\n }), __param(1, Optional()), __param(1, Inject(MAT_DATE_FORMATS)), __param(2, Optional()), __param(3, Optional())], SatYearView);\n\n /**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n /** Default header for SatCalendar */\n return SatYearView;\n})();\nlet SatCalendarHeader = /*#__PURE__*/(() => {\n let SatCalendarHeader = class SatCalendarHeader {\n constructor(_intl, calendar, _dateAdapter, _dateFormats, changeDetectorRef) {\n this._intl = _intl;\n this.calendar = calendar;\n this._dateAdapter = _dateAdapter;\n this._dateFormats = _dateFormats;\n this.calendar.stateChanges.subscribe(() => changeDetectorRef.markForCheck());\n }\n /** The label for the current calendar view. */\n get periodButtonText() {\n if (this.calendar.currentView == 'month') {\n return this._dateAdapter.format(this.calendar.activeDate, this._dateFormats.display.monthYearLabel).toLocaleUpperCase();\n }\n if (this.calendar.currentView == 'year') {\n return this._dateAdapter.getYearName(this.calendar.activeDate);\n }\n // The offset from the active year to the \"slot\" for the starting year is the\n // *actual* first rendered year in the multi-year view, and the last year is\n // just yearsPerPage - 1 away.\n const activeYear = this._dateAdapter.getYear(this.calendar.activeDate);\n const minYearOfPage = activeYear - getActiveOffset(this._dateAdapter, this.calendar.activeDate, this.calendar.minDate, this.calendar.maxDate);\n const maxYearOfPage = minYearOfPage + yearsPerPage - 1;\n return `${minYearOfPage} \\u2013 ${maxYearOfPage}`;\n }\n get periodButtonLabel() {\n return this.calendar.currentView == 'month' ? this._intl.switchToMultiYearViewLabel : this._intl.switchToMonthViewLabel;\n }\n /** The label for the previous button. */\n get prevButtonLabel() {\n return {\n 'month': this._intl.prevMonthLabel,\n 'year': this._intl.prevYearLabel,\n 'multi-year': this._intl.prevMultiYearLabel\n }[this.calendar.currentView];\n }\n /** The label for the next button. */\n get nextButtonLabel() {\n return {\n 'month': this._intl.nextMonthLabel,\n 'year': this._intl.nextYearLabel,\n 'multi-year': this._intl.nextMultiYearLabel\n }[this.calendar.currentView];\n }\n /** Handles user clicks on the period label.\n * Option`calendar.orderPeriodLabel` sort the label period views.\n * - Default [multi-year]: multi-year then back to month\n * - Month [month]: month > year > multi-year\n */\n currentPeriodClicked() {\n const mouthFirstOrder = ['month', 'year', 'multi-year'];\n const defaultOrder = ['month', 'multi-year', 'month'];\n const orderPeriod = this.calendar.orderPeriodLabel === 'month' ? mouthFirstOrder : defaultOrder;\n switch (this.calendar.currentView) {\n case 'month':\n this.calendar.currentView = orderPeriod[1];\n break;\n case 'year':\n this.calendar.currentView = orderPeriod[2];\n break;\n default:\n this.calendar.currentView = orderPeriod[0];\n break;\n }\n }\n /** Handles user clicks on the previous button. */\n previousClicked() {\n this.calendar.activeDate = this.calendar.currentView == 'month' ? this._dateAdapter.addCalendarMonths(this.calendar.activeDate, -1) : this._dateAdapter.addCalendarYears(this.calendar.activeDate, this.calendar.currentView == 'year' ? -1 : -yearsPerPage);\n }\n /** Handles user clicks on the next button. */\n nextClicked() {\n this.calendar.activeDate = this.calendar.currentView == 'month' ? this._dateAdapter.addCalendarMonths(this.calendar.activeDate, 1) : this._dateAdapter.addCalendarYears(this.calendar.activeDate, this.calendar.currentView == 'year' ? 1 : yearsPerPage);\n }\n /** Whether the previous period button is enabled. */\n previousEnabled() {\n if (!this.calendar.minDate) {\n return true;\n }\n return !this.calendar.minDate || !this._isSameView(this.calendar.activeDate, this.calendar.minDate);\n }\n /** Whether the next period button is enabled. */\n nextEnabled() {\n return !this.calendar.maxDate || !this._isSameView(this.calendar.activeDate, this.calendar.maxDate);\n }\n /** Whether the two dates represent the same view in the current view mode (month or year). */\n _isSameView(date1, date2) {\n if (this.calendar.currentView == 'month') {\n return this._dateAdapter.getYear(date1) == this._dateAdapter.getYear(date2) && this._dateAdapter.getMonth(date1) == this._dateAdapter.getMonth(date2);\n }\n if (this.calendar.currentView == 'year') {\n return this._dateAdapter.getYear(date1) == this._dateAdapter.getYear(date2);\n }\n // Otherwise we are in 'multi-year' view.\n return isSameMultiYearView(this._dateAdapter, date1, date2, this.calendar.minDate, this.calendar.maxDate);\n }\n };\n SatCalendarHeader = __decorate([Component({\n moduleId: module.id,\n selector: 'sat-calendar-header',\n template: \"<div class=\\\"mat-calendar-header\\\">\\n <div class=\\\"mat-calendar-controls\\\">\\n <button mat-button type=\\\"button\\\" class=\\\"mat-calendar-period-button\\\"\\n (click)=\\\"currentPeriodClicked()\\\" [attr.aria-label]=\\\"periodButtonLabel\\\"\\n cdkAriaLive=\\\"polite\\\">\\n {{periodButtonText}}\\n <div class=\\\"mat-calendar-arrow\\\"\\n [class.mat-calendar-invert]=\\\"calendar.currentView != 'month'\\\"></div>\\n </button>\\n\\n <div class=\\\"mat-calendar-spacer\\\"></div>\\n\\n <ng-content></ng-content>\\n\\n <button mat-icon-button type=\\\"button\\\" class=\\\"mat-calendar-previous-button\\\"\\n [disabled]=\\\"!previousEnabled()\\\" (click)=\\\"previousClicked()\\\"\\n [attr.aria-label]=\\\"prevButtonLabel\\\">\\n </button>\\n\\n <button mat-icon-button type=\\\"button\\\" class=\\\"mat-calendar-next-button\\\"\\n [disabled]=\\\"!nextEnabled()\\\" (click)=\\\"nextClicked()\\\"\\n [attr.aria-label]=\\\"nextButtonLabel\\\">\\n </button>\\n </div>\\n</div>\\n\",\n exportAs: 'matCalendarHeader',\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush\n }), __param(1, Inject(forwardRef(() => SatCalendar))), __param(2, Optional()), __param(3, Optional()), __param(3, Inject(MAT_DATE_FORMATS))], SatCalendarHeader);\n /** Default footer for SatCalendar */\n return SatCalendarHeader;\n})();\nlet SatCalendarFooter = /*#__PURE__*/(() => {\n let SatCalendarFooter = class SatCalendarFooter {};\n SatCalendarFooter = __decorate([Component({\n moduleId: module.id,\n selector: 'sat-calendar-footer',\n template: \"\",\n exportAs: 'matCalendarFooter',\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush\n })], SatCalendarFooter);\n /**\n * A calendar that is used as part of the datepicker.\n * @docs-private\n */\n return SatCalendarFooter;\n})();\nlet SatCalendar = /*#__PURE__*/(() => {\n let SatCalendar = class SatCalendar {\n constructor(_intl, _dateAdapter, _dateFormats, _changeDetectorRef) {\n this._dateAdapter = _dateAdapter;\n this._dateFormats = _dateFormats;\n this._changeDetectorRef = _changeDetectorRef;\n /** Whenever datepicker is for selecting range of dates. */\n this.rangeMode = false;\n /** Enables datepicker MouseOver effect on range mode */\n this.rangeHoverEffect = true;\n /** Enables datepicker closing after selection */\n this.closeAfterSelection = true;\n /** Emits when new pair of dates selected. */\n this.dateRangesChange = new EventEmitter();\n /** Whenever user already selected start of dates interval. */\n this.beginDateSelected = false;\n /** Emits when a new start date has been selected in range mode. */\n this.beginDateSelectedChange = new EventEmitter();\n /**\n * Used for scheduling that focus should be moved to the active cell on the next tick.\n * We need to schedule it, rather than do it immediately, because we have to wait\n * for Angular to re-evaluate the view children.\n */\n this._moveFocusOnNextTick = false;\n /** Whether the calendar should be started in month or year view. */\n this.startView = 'month';\n /** Order the views when clicking on period label button */\n this.orderPeriodLabel = 'multi-year';\n /** Emits when the currently selected date changes. */\n this.selectedChange = new EventEmitter();\n /**\n * Emits the year chosen in multiyear view.\n * This doesn't imply a change on the selected date.\n */\n this.yearSelected = new EventEmitter();\n /**\n * Emits the month chosen in year view.\n * This doesn't imply a change on the selected date.\n */\n this.monthSelected = new EventEmitter();\n /** Emits when any date is selected. */\n this._userSelection = new EventEmitter();\n /**\n * Emits whenever there is a state change that the header may need to respond to.\n */\n this.stateChanges = new Subject();\n if (!this._dateAdapter) {\n throw createMissingDateImplError('DateAdapter');\n }\n if (!this._dateFormats) {\n throw createMissingDateImplError('MAT_DATE_FORMATS');\n }\n this._intlChanges = _intl.changes.subscribe(() => {\n _changeDetectorRef.markForCheck();\n this.stateChanges.next();\n });\n }\n /** Beginning of date range. */\n get beginDate() {\n return this._beginDate;\n }\n set beginDate(value) {\n this._beginDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n /** Date range end. */\n get endDate() {\n return this._endDate;\n }\n set endDate(value) {\n this._endDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n /** A date representing the period (month or year) to start the calendar in. */\n get startAt() {\n return this._startAt;\n }\n set startAt(value) {\n this._startAt = this._getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n /** The currently selected date. */\n get selected() {\n return this._selected;\n }\n set selected(value) {\n this._selected = this._getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n /** The minimum selectable date. */\n get minDate() {\n return this._minDate;\n }\n set minDate(value) {\n this._minDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n /** The maximum selectable date. */\n get maxDate() {\n return this._maxDate;\n }\n set maxDate(value) {\n this._maxDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n /**\n * The current active date. This determines which time period is shown and which date is\n * highlighted when using keyboard navigation.\n */\n get activeDate() {\n return this._clampedActiveDate;\n }\n set activeDate(value) {\n this._clampedActiveDate = this._dateAdapter.clampDate(value, this.minDate, this.maxDate);\n this.stateChanges.next();\n this._changeDetectorRef.markForCheck();\n }\n /** Whether the calendar is in month view. */\n get currentView() {\n return this._currentView;\n }\n set currentView(value) {\n this._currentView = value;\n this._moveFocusOnNextTick = true;\n this._changeDetectorRef.markForCheck();\n }\n ngAfterContentInit() {\n this._calendarHeaderPortal = new ComponentPortal(this.headerComponent || SatCalendarHeader);\n this._calendarFooterPortal = new ComponentPortal(this.footerComponent || SatCalendarFooter);\n this.activeDate = this.startAt || this._dateAdapter.today();\n // Assign to the private property since we don't want to move focus on init.\n this._currentView = this.startView;\n }\n ngAfterViewChecked() {\n if (this._moveFocusOnNextTick) {\n this._moveFocusOnNextTick = false;\n this.focusActiveCell();\n }\n }\n ngOnDestroy() {\n this._intlChanges.unsubscribe();\n this.stateChanges.complete();\n }\n ngOnChanges(changes) {\n const change = changes['minDate'] || changes['maxDate'] || changes['dateFilter'];\n if (change && !change.firstChange) {\n const view = this._getCurrentViewComponent();\n if (view) {\n // We need to `detectChanges` manually here, because the `minDate`, `maxDate` etc. are\n // passed down to the view via data bindings which won't be up-to-date when we call `_init`.\n this._changeDetectorRef.detectChanges();\n view._init();\n }\n }\n this.stateChanges.next();\n }\n focusActiveCell() {\n this._getCurrentViewComponent()._focusActiveCell();\n }\n /** Updates today's date after an update of the active date */\n updateTodaysDate() {\n let view = this.currentView == 'month' ? this.monthView : this.currentView == 'year' ? this.yearView : this.multiYearView;\n view.ngAfterContentInit();\n }\n /** Handles date selection in the month view. */\n _dateSelected(date) {\n if (this.rangeMode) {\n if (!this.beginDateSelected) {\n this.beginDateSelected = date;\n this.beginDate = date;\n this.endDate = date;\n this.beginDateSelectedChange.emit(date);\n } else {\n this.beginDateSelected = false;\n if (this._dateAdapter.compareDate(this.beginDate, date) <= 0) {\n this.endDate = date;\n } else {\n this.endDate = this.beginDate;\n this.beginDate = date;\n }\n this.dateRangesChange.emit({\n begin: this.beginDate,\n end: this.endDate\n });\n }\n } else if (!this._dateAdapter.sameDate(date, this.selected)) {\n this.selectedChange.emit(date);\n }\n }\n /** Handles year selection in the multiyear view. */\n _yearSelectedInMultiYearView(normalizedYear) {\n this.yearSelected.emit(normalizedYear);\n }\n /** Handles month selection in the year view. */\n _monthSelectedInYearView(normalizedMonth) {\n this.monthSelected.emit(normalizedMonth);\n }\n _userSelected() {\n this._userSelection.emit();\n }\n /** Handles year/month selection in the multi-year/year views. */\n _goToDateInView(date, view) {\n this.activeDate = date;\n this.currentView = view;\n }\n /**\n * @param obj The object to check.\n * @returns The given object if it is both a date instance and valid, otherwise null.\n */\n _getValidDateOrNull(obj) {\n return this._dateAdapter.isDateInstance(obj) && this._dateAdapter.isValid(obj) ? obj : null;\n }\n /** Returns the component instance that corresponds to the current calendar view. */\n _getCurrentViewComponent() {\n return this.monthView || this.yearView || this.multiYearView;\n }\n };\n __decorate([Input()], SatCalendar.prototype, \"beginDate\", null);\n __decorate([Input()], SatCalendar.prototype, \"endDate\", null);\n __decorate([Input()], SatCalendar.prototype, \"rangeMode\", void 0);\n __decorate([Input()], SatCalendar.prototype, \"rangeHoverEffect\", void 0);\n __decorate([Input()], SatCalendar.prototype, \"closeAfterSelection\", void 0);\n __decorate([Output()], SatCalendar.prototype, \"dateRangesChange\", void 0);\n __decorate([Output()], SatCalendar.prototype, \"beginDateSelectedChange\", void 0);\n __decorate([Input()], SatCalendar.prototype, \"headerComponent\", void 0);\n __decorate([Input()], SatCalendar.prototype, \"footerComponent\", void 0);\n __decorate([Input()], SatCalendar.prototype, \"startAt\", null);\n __decorate([Input()], SatCalendar.prototype, \"startView\", void 0);\n __decorate([Input()], SatCalendar.prototype, \"selected\", null);\n __decorate([Input()], SatCalendar.prototype, \"minDate\", null);\n __decorate([Input()], SatCalendar.prototype, \"maxDate\", null);\n __decorate([Input()], SatCalendar.prototype, \"dateFilter\", void 0);\n __decorate([Input()], SatCalendar.prototype, \"dateClass\", void 0);\n __decorate([Input()], SatCalendar.prototype, \"orderPeriodLabel\", void 0);\n __decorate([Output()], SatCalendar.prototype, \"selectedChange\", void 0);\n __decorate([Output()], SatCalendar.prototype, \"yearSelected\", void 0);\n __decorate([Output()], SatCalendar.prototype, \"monthSelected\", void 0);\n __decorate([Output()], SatCalendar.prototype, \"_userSelection\", void 0);\n __decorate([ViewChild(SatMonthView, {\n static: false\n })], SatCalendar.prototype, \"monthView\", void 0);\n __decorate([ViewChild(SatYearView, {\n static: false\n })], SatCalendar.prototype, \"yearView\", void 0);\n __decorate([ViewChild(SatMultiYearView, {\n static: false\n })], SatCalendar.prototype, \"multiYearView\", void 0);\n SatCalendar = __decorate([Component({\n moduleId: module.id,\n selector: 'sat-calendar',\n template: \"\\n<ng-template [cdkPortalOutlet]=\\\"_calendarHeaderPortal\\\"></ng-template>\\n\\n<div class=\\\"mat-calendar-content\\\" [ngSwitch]=\\\"currentView\\\" cdkMonitorSubtreeFocus tabindex=\\\"-1\\\">\\n <sat-month-view\\n *ngSwitchCase=\\\"'month'\\\"\\n [(activeDate)]=\\\"activeDate\\\"\\n [selected]=\\\"selected\\\"\\n [beginDate]=\\\"beginDate\\\"\\n [endDate]=\\\"endDate\\\"\\n [rangeMode]=\\\"rangeMode\\\"\\n [closeAfterSelection]=\\\"closeAfterSelection\\\"\\n [rangeHoverEffect]=\\\"rangeHoverEffect\\\"\\n [dateFilter]=\\\"dateFilter\\\"\\n [maxDate]=\\\"maxDate\\\"\\n [minDate]=\\\"minDate\\\"\\n [dateClass]=\\\"dateClass\\\"\\n [beginDateSelected]=\\\"beginDateSelected\\\"\\n (selectedChange)=\\\"_dateSelected($event)\\\"\\n (_userSelection)=\\\"_userSelected()\\\">\\n </sat-month-view>\\n\\n <sat-year-view\\n *ngSwitchCase=\\\"'year'\\\"\\n [(activeDate)]=\\\"activeDate\\\"\\n [selected]=\\\"selected\\\"\\n [dateFilter]=\\\"dateFilter\\\"\\n [maxDate]=\\\"maxDate\\\"\\n [minDate]=\\\"minDate\\\"\\n (monthSelected)=\\\"_monthSelectedInYearView($event)\\\"\\n (selectedChange)=\\\"_goToDateInView($event, 'month')\\\">\\n </sat-year-view>\\n\\n <sat-multi-year-view\\n *ngSwitchCase=\\\"'multi-year'\\\"\\n [(activeDate)]=\\\"activeDate\\\"\\n [selected]=\\\"selected\\\"\\n [dateFilter]=\\\"dateFilter\\\"\\n [maxDate]=\\\"maxDate\\\"\\n [minDate]=\\\"minDate\\\"\\n (yearSelected)=\\\"_yearSelectedInMultiYearView($event)\\\"\\n (selectedChange)=\\\"_goToDateInView($event, 'year')\\\">\\n </sat-multi-year-view>\\n</div>\\n\\n<ng-template [cdkPortalOutlet]=\\\"_calendarFooterPortal\\\"></ng-template>\\n\",\n host: {\n 'class': 'mat-calendar'\n },\n exportAs: 'matCalendar',\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [\".mat-calendar{display:block}.mat-calendar-header{padding:8px 8px 0}.mat-calendar-content{padding:0 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}.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}\"]\n }), __param(1, Optional()), __param(2, Optional()), __param(2, Inject(MAT_DATE_FORMATS))], SatCalendar);\n\n /**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n /**\n * Animations used by the Material datepicker.\n * @docs-private\n */\n return SatCalendar;\n})();\nconst matDatepickerAnimations = {\n /** Transforms the height of the datepicker's calendar. */\n transformPanel: trigger('transformPanel', [state('void', style({\n opacity: 0,\n transform: 'scale(1, 0.8)'\n })), transition('void => enter', animate('120ms cubic-bezier(0, 0, 0.2, 1)', style({\n opacity: 1,\n transform: 'scale(1, 1)'\n }))), transition('* => void', animate('100ms linear', style({\n opacity: 0\n })))]),\n /** Fades in the content of the calendar. */\n fadeInCalendar: trigger('fadeInCalendar', [state('void', style({\n opacity: 0\n })), state('enter', style({\n opacity: 1\n })),\n // TODO(crisbeto): this animation should be removed since it isn't quite on spec, but we\n // need to keep it until #12440 gets in, otherwise the exit animation will look glitchy.\n transition('void => *', animate('120ms 100ms cubic-bezier(0.55, 0, 0.55, 0.2)'))])\n};\n\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n/** Used to generate a unique ID for each datepicker instance. */\nlet datepickerUid = 0;\n/** Injection token that determines the scroll handling while the calendar is open. */\nconst MAT_DATEPICKER_SCROLL_STRATEGY = new InjectionToken('sat-datepicker-scroll-strategy');\n/** @docs-private */\nfunction MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY(overlay) {\n return () => overlay.scrollStrategies.reposition();\n}\n/** @docs-private */\nconst MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY_PROVIDER = {\n provide: MAT_DATEPICKER_SCROLL_STRATEGY,\n deps: [Overlay],\n useFactory: MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY\n};\n// Boilerplate for applying mixins to SatDatepickerContent.\n/** @docs-private */\nclass SatDatepickerContentBase {\n constructor(_elementRef) {\n this._elementRef = _elementRef;\n }\n}\nconst _SatDatepickerContentMixinBase = mixinColor(SatDatepickerContentBase);\n/**\n * Component used as the content for the datepicker dialog and popup. We use this instead of using\n * SatCalendar directly as the content so we can control the initial focus. This also gives us a\n * place to put additional features of the popup that are not part of the calendar itself in the\n * future. (e.g. confirmation buttons).\n * @docs-private\n */\nlet SatDatepickerContent = /*#__PURE__*/(() => {\n let SatDatepickerContent = class SatDatepickerContent extends _SatDatepickerContentMixinBase {\n constructor(elementRef) {\n super(elementRef);\n }\n ngAfterViewInit() {\n this._calendar.focusActiveCell();\n }\n close() {\n if (this.datepicker.closeAfterSelection) {\n this.datepicker.close();\n }\n }\n };\n __decorate([ViewChild(SatCalendar, {\n static: false\n })], SatDatepickerContent.prototype, \"_calendar\", void 0);\n SatDatepickerContent = __decorate([Component({\n moduleId: module.id,\n selector: 'sat-datepicker-content',\n template: \"<sat-calendar cdkTrapFocus\\n [id]=\\\"datepicker.id\\\"\\n [ngClass]=\\\"datepicker.panelClass\\\"\\n [startAt]=\\\"datepicker.startAt\\\"\\n [startView]=\\\"datepicker.startView\\\"\\n [minDate]=\\\"datepicker._minDate\\\"\\n [maxDate]=\\\"datepicker._maxDate\\\"\\n [dateFilter]=\\\"datepicker._dateFilter\\\"\\n [rangeHoverEffect]=\\\"datepicker.rangeHoverEffect\\\"\\n [headerComponent]=\\\"datepicker.calendarHeaderComponent\\\"\\n [footerComponent]=\\\"datepicker.calendarFooterComponent\\\"\\n [selected]=\\\"datepicker._selected\\\"\\n [dateClass]=\\\"datepicker.dateClass\\\"\\n [@fadeInCalendar]=\\\"'enter'\\\"\\n (selectedChange)=\\\"datepicker.select($event)\\\"\\n (yearSelected)=\\\"datepicker._selectYear($event)\\\"\\n (monthSelected)=\\\"datepicker._selectMonth($event)\\\"\\n [beginDate]=\\\"datepicker._beginDate\\\"\\n [endDate]=\\\"datepicker._endDate\\\"\\n [rangeMode]=\\\"datepicker.rangeMode\\\"\\n [closeAfterSelection]=\\\"datepicker.closeAfterSelection\\\"\\n [orderPeriodLabel]=\\\"datepicker.orderPeriodLabel\\\"\\n (dateRangesChange)=\\\"datepicker._selectRange($event)\\\"\\n (beginDateSelectedChange)=\\\"datepicker.setBeginDateSelected($event)\\\"\\n (_userSelection)=\\\"close()\\\">\\n</sat-calendar>\\n\",\n host: {\n 'class': 'mat-datepicker-content',\n '[@transformPanel]': '\"enter\"',\n '[class.mat-datepicker-content-touch]': 'datepicker.touchUi'\n },\n animations: [matDatepickerAnimations.transformPanel, matDatepickerAnimations.fadeInCalendar],\n exportAs: 'matDatepickerContent',\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n inputs: ['color'],\n 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-datepicker-content .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}}\"]\n })], SatDatepickerContent);\n // TODO(mmalerba): We use a component instead of a directive here so the user can use implicit\n // template reference variables (e.g. #d vs #d=\"matDatepicker\"). We can change this to a directive\n // if angular adds support for `exportAs: '$implicit'` on directives.\n /** Component responsible for managing the datepicker popup/dialog. */\n return SatDatepickerContent;\n})();\nlet SatDatepicker = /*#__PURE__*/(() => {\n let SatDatepicker = class SatDatepicker {\n constructor(_dialog, _overlay, _ngZone, _viewContainerRef, scrollStrategy, _dateAdapter, _dir, _document) {\n this._dialog = _dialog;\n this._overlay = _overlay;\n this._ngZone = _ngZone;\n this._viewContainerRef = _viewContainerRef;\n this._dateAdapter = _dateAdapter;\n this._dir = _dir;\n this._document = _document;\n /** The view that the calendar should start in. */\n this.startView = 'month';\n this._touchUi = false;\n /**\n * Emits selected year in multiyear view.\n * This doesn't imply a change on the selected date.\n */\n this.yearSelected = new EventEmitter();\n /**\n * Emits selected month in year view.\n * This doesn't imply a change on the selected date.\n */\n this.monthSelected = new EventEmitter();\n /** Emits when the datepicker has been opened. */\n this.openedStream = new EventEmitter();\n /** Emits when the datepicker has been closed. */\n this.closedStream = new EventEmitter();\n /** Enables datepicker closing after selection */\n this.closeAfterSelection = true;\n /** Enables datepicker MouseOver effect on range mode */\n this.rangeHoverEffect = true;\n /** In range mod, enable datepicker to select the first date selected as a one-day-range,\n * if the user closes the picker before selecting another date\n */\n this.selectFirstDateOnClose = false;\n /** Order the views when clicking on period label button */\n this.orderPeriodLabel = 'multi-year';\n this._opened = false;\n /** The id for the datepicker calendar. */\n this.id = `sat-datepicker-${datepickerUid++}`;\n this._validSelected = null;\n /** The element that was focused before the datepicker was opened. */\n this._focusedElementBeforeOpen = null;\n /** Subscription to value changes in the associated input element. */\n this._inputSubscription = Subscription.EMPTY;\n /** Emits when the datepicker is disabled. */\n this._disabledChange = new Subject();\n /** Emits new selected date when selected date changes. */\n this._selectedChanged = new Subject();\n if (!this._dateAdapter) {\n throw createMissingDateImplError('DateAdapter');\n }\n this._scrollStrategy = scrollStrategy;\n }\n /** Whenever datepicker is for selecting range of dates. */\n get rangeMode() {\n return this._rangeMode;\n }\n set rangeMode(mode) {\n this._rangeMode = mode;\n if (this.rangeMode) {\n this._validSelected = null;\n } else {\n this._beginDate = this._endDate = null;\n }\n }\n /** Start of dates interval. */\n get beginDate() {\n return this._beginDate;\n }\n set beginDate(value) {\n this._validSelected = null;\n this._beginDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n /** End of dates interval. */\n get endDate() {\n return this._endDate;\n }\n set endDate(value) {\n this._validSelected = null;\n this._endDate = this._getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n /** The date to open the calendar to initially. */\n get startAt() {\n // If an explicit startAt is set we start there, otherwise we start at whatever the currently\n // selected value is.\n if (this.rangeMode) {\n return this._startAt || (this._datepickerInput && this._datepickerInput.value ? this._datepickerInput.value.begin : null);\n }\n return this._startAt || (this._datepickerInput ? this._datepickerInput.value : null);\n }\n set startAt(value) {\n this._startAt = this._getValidDateOrNull(this._dateAdapter.deserialize(value));\n }\n /** Color palette to use on the datepicker's calendar. */\n get color() {\n return this._color || (this._datepickerInput ? this._datepickerInput._getThemePalette() : undefined);\n }\n set color(value) {\n this._color = value;\n }\n /**\n * Whether the calendar UI is in touch mode. In touch mode the calendar opens in a dialog rather\n * than a popup and elements have more padding to allow for bigger touch targets.\n */\n get touchUi() {\n return this._touchUi;\n }\n set touchUi(value) {\n this._touchUi = coerceBooleanProperty(value);\n }\n /** Whether the datepicker pop-up should be disabled. */\n get disabled() {\n return this._disabled === undefined && this._datepickerInput ? this._datepickerInput.disabled : !!this._disabled;\n }\n set disabled(value) {\n const newValue = coerceBooleanProperty(value);\n if (newValue !== this._disabled) {\n this._disabled = newValue;\n this._disabledChange.next(newValue);\n }\n }\n /** Whether the calendar is open. */\n get opened() {\n return this._opened;\n }\n set opened(value) {\n value ? this.open() : this.close();\n }\n /** The currently selected date. */\n get _selected() {\n return this._validSelected;\n }\n set _selected(value) {\n this._validSelected = value;\n }\n /** The minimum selectable date. */\n get _minDate() {\n return this._datepickerInput && this._datepickerInput.min;\n }\n /** The maximum selectable date. */\n get _maxDate() {\n return this._datepickerInput && this._datepickerInput.max;\n }\n get _dateFilter() {\n return this._datepickerInput && this._datepickerInput._dateFilter;\n }\n ngOnDestroy() {\n this.close();\n this._inputSubscription.unsubscribe();\n this._disabledChange.complete();\n if (this._popupRef) {\n this._popupRef.dispose();\n this._popupComponentRef = null;\n }\n }\n /** Selects the given date */\n select(date) {\n let oldValue = this._selected;\n this._selected = date;\n if (!this._dateAdapter.sameDate(oldValue, this._selected)) {\n this._selectedChanged.next(date);\n }\n }\n /** Selects the given date range */\n _selectRange(dates) {\n this._beginDateSelected = null;\n if (!this._dateAdapter.sameDate(dates.begin, this.beginDate) || !this._dateAdapter.sameDate(dates.end, this.endDate)) {\n this._selectedChanged.next(dates);\n }\n this._beginDate = dates.begin;\n this._endDate = dates.end;\n }\n /** Emits the selected year in multiyear view */\n _selectYear(normalizedYear) {\n this.yearSelected.emit(normalizedYear);\n }\n /** Emits selected month in year view */\n _selectMonth(normalizedMonth) {\n this.monthSelected.emit(normalizedMonth);\n }\n /**\n * Register an input with this datepicker.\n * @param input The datepicker input to register with this datepicker.\n */\n _registerInput(input) {\n if (this._datepickerInput) {\n throw Error('A SatDatepicker can only be associated with a single input.');\n }\n this._datepickerInput = input;\n this._inputSubscription = this._datepickerInput._valueChange.subscribe(value => {\n if (value === null) {\n this.beginDate = this.endDate = this._selected = null;\n return;\n }\n if (value && value.hasOwnProperty('begin') && value.hasOwnProperty('end')) {\n value = value;\n if (value.begin && value.end && this._dateAdapter.compareDate(value.begin, value.end) <= 0) {\n this.beginDate = value.begin;\n this.endDate = value.end;\n } else {\n this.beginDate = this.endDate = null;\n }\n } else {\n this._selected = value;\n }\n });\n }\n /** Open the calendar. */\n open() {\n if (this._opened || this.disabled) {\n return;\n }\n if (!this._datepickerInput) {\n throw Error('Attempted to open an SatDatepicker with no associated input.');\n }\n if (this._document) {\n this._focusedElementBeforeOpen = this._document.activeElement;\n }\n this.touchUi ? this._openAsDialog() : this._openAsPopup();\n this._opened = true;\n this.openedStream.emit();\n }\n /** Close the calendar. */\n close() {\n if (!this._opened) {\n return;\n }\n if (this._popupRef && this._popupRef.hasAttached()) {\n this._popupRef.detach();\n }\n if (this._dialogRef) {\n this._dialogRef.close();\n this._dialogRef = null;\n }\n if (this._calendarPortal && this._calendarPortal.isAttached) {\n this._calendarPortal.detach();\n }\n if (this._beginDateSelected && this.selectFirstDateOnClose) {\n this._selectRange({\n begin: this._beginDateSelected,\n end: this._beginDateSelected\n });\n }\n const completeClose = () => {\n // The `_opened` could've been reset already if\n // we got two events in quick succession.\n if (this._opened) {\n this._opened = false;\n this.closedStream.emit();\n this._focusedElementBeforeOpen = null;\n }\n };\n if (this._focusedElementBeforeOpen && typeof this._focusedElementBeforeOpen.focus === 'function') {\n // Because IE moves focus asynchronously, we can't count on it being restored before we've\n // marked the datepicker as closed. If the event fires out of sequence and the element that\n // we're refocusing opens the datepicker on focus, the user could be stuck with not being\n // able to close the calendar at all. We work around it by making the logic, that marks\n // the datepicker as closed, async as well.\n this._focusedElementBeforeOpen.focus();\n setTimeout(completeClose);\n } else {\n completeClose();\n }\n }\n setBeginDateSelected(date) {\n this._beginDateSelected = date;\n }\n /** Open the calendar as a dialog. */\n _openAsDialog() {\n // Usually this would be handled by `open` which ensures that we can only have one overlay\n // open at a time, however since we reset the variables in async handlers some overlays\n // may slip through if the user opens and closes multiple times in quick succession (e.g.\n // by holding down the enter key).\n if (this._dialogRef) {\n this._dialogRef.close();\n }\n this._dialogRef = this._dialog.open(SatDatepickerContent, {\n direction: this._dir ? this._dir.value : 'ltr',\n viewContainerRef: this._viewContainerRef,\n panelClass: 'mat-datepicker-dialog'\n });\n this._dialogRef.afterClosed().subscribe(() => this.close());\n this._dialogRef.componentInstance.datepicker = this;\n this._setColor();\n }\n /** Open the calendar as a popup. */\n _openAsPopup() {\n if (!this._calendarPortal) {\n this._calendarPortal = new ComponentPortal(SatDatepickerContent, this._viewContainerRef);\n }\n if (!this._popupRef) {\n this._createPopup();\n }\n if (!this._popupRef.hasAttached()) {\n this._popupComponentRef = this._popupRef.attach(this._calendarPortal);\n this._popupComponentRef.instance.datepicker = this;\n this._setColor();\n // Update the position once the calendar has rendered.\n this._ngZone.onStable.asObservable().pipe(take(1)).subscribe(() => {\n this._popupRef.updatePosition();\n });\n }\n }\n /** Create the popup. */\n _createPopup() {\n const overlayConfig = new OverlayConfig({\n positionStrategy: this._createPopupPositionStrategy(),\n hasBackdrop: true,\n backdropClass: 'mat-overlay-transparent-backdrop',\n direction: this._dir,\n scrollStrategy: this._scrollStrategy(),\n panelClass: 'mat-datepicker-popup'\n });\n this._popupRef = this._overlay.create(overlayConfig);\n this._popupRef.overlayElement.setAttribute('role', 'dialog');\n merge(this._popupRef.backdropClick(), this._popupRef.detachments(), this._popupRef.keydownEvents().pipe(filter(event => {\n // Closing on alt + up is only valid when there's an input associated with the datepicker.\n return event.keyCode === ESCAPE || this._datepickerInput && event.altKey && event.keyCode === UP_ARROW;\n }))).subscribe(event => {\n if (event) {\n event.preventDefault();\n }\n this.close();\n });\n }\n /** Create the popup PositionStrategy. */\n _createPopupPositionStrategy() {\n return this._overlay.position().flexibleConnectedTo(this._datepickerInput.getConnectedOverlayOrigin()).withTransformOriginOn('.mat-datepicker-content').withFlexibleDimensions(false).withViewportMargin(8).withLockedPosition().withPositions([{\n originX: 'start',\n originY: 'bottom',\n overlayX: 'start',\n overlayY: 'top'\n }, {\n originX: 'start',\n originY: 'top',\n overlayX: 'start',\n overlayY: 'bottom'\n }, {\n originX: 'end',\n originY: 'bottom',\n overlayX: 'end',\n overlayY: 'top'\n }, {\n originX: 'end',\n originY: 'top',\n overlayX: 'end',\n overlayY: 'bottom'\n }]);\n }\n /**\n * @param obj The object to check.\n * @returns The given object if it is both a date instance and valid, otherwise null.\n */\n _getValidDateOrNull(obj) {\n return this._dateAdapter.isDateInstance(obj) && this._dateAdapter.isValid(obj) ? obj : null;\n }\n /** Passes the current theme color along to the calendar overlay. */\n _setColor() {\n const color = this.color;\n if (this._popupComponentRef) {\n this._popupComponentRef.instance.color = color;\n }\n if (this._dialogRef) {\n this._dialogRef.componentInstance.color = color;\n }\n }\n };\n __decorate([Input()], SatDatepicker.prototype, \"rangeMode\", null);\n __decorate([Input()], SatDatepicker.prototype, \"beginDate\", null);\n __decorate([Input()], SatDatepicker.prototype, \"endDate\", null);\n __decorate([Input()], SatDatepicker.prototype, \"calendarHeaderComponent\", void 0);\n __decorate([Input()], SatDatepicker.prototype, \"calendarFooterComponent\", void 0);\n __decorate([Input()], SatDatepicker.prototype, \"startAt\", null);\n __decorate([Input()], SatDatepicker.prototype, \"startView\", void 0);\n __decorate([Input()], SatDatepicker.prototype, \"color\", null);\n __decorate([Input()], SatDatepicker.prototype, \"touchUi\", null);\n __decorate([Input()], SatDatepicker.prototype, \"disabled\", null);\n __decorate([Output()], SatDatepicker.prototype, \"yearSelected\", void 0);\n __decorate([Output()], SatDatepicker.prototype, \"monthSelected\", void 0);\n __decorate([Input()], SatDatepicker.prototype, \"panelClass\", void 0);\n __decorate([Input()], SatDatepicker.prototype, \"dateClass\", void 0);\n __decorate([Output('opened')], SatDatepicker.prototype, \"openedStream\", void 0);\n __decorate([Output('closed')], SatDatepicker.prototype, \"closedStream\", void 0);\n __decorate([Input()], SatDatepicker.prototype, \"closeAfterSelection\", void 0);\n __decorate([Input()], SatDatepicker.prototype, \"rangeHoverEffect\", void 0);\n __decorate([Input()], SatDatepicker.prototype, \"selectFirstDateOnClose\", void 0);\n __decorate([Input()], SatDatepicker.prototype, \"orderPeriodLabel\", void 0);\n __decorate([Input()], SatDatepicker.prototype, \"opened\", null);\n SatDatepicker = __decorate([Component({\n moduleId: module.id,\n selector: 'sat-datepicker',\n template: '',\n exportAs: 'matDatepicker',\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None\n }), __param(4, Inject(MAT_DATEPICKER_SCROLL_STRATEGY)), __param(5, Optional()), __param(6, Optional()), __param(7, Optional()), __param(7, Inject(DOCUMENT))], SatDatepicker);\n\n /**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n return SatDatepicker;\n})();\nvar SatDatepickerInput_1;\n/** @docs-private */\nconst MAT_DATEPICKER_VALUE_ACCESSOR = {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => SatDatepickerInput),\n multi: true\n};\n/** @docs-private */\nconst MAT_DATEPICKER_VALIDATORS = {\n provide: NG_VALIDATORS,\n useExisting: forwardRef(() => SatDatepickerInput),\n multi: true\n};\n/**\n * An event used for datepicker input and change events. We don't always have access to a native\n * input or change event because the event may have been triggered by the user clicking on the\n * calendar popup. For consistency, we always use SatDatepickerInputEvent instead.\n */\nclass SatDatepickerInputEvent {\n constructor( /** Reference to the datepicker input component that emitted the event. */\n target, /** Reference to the native input element associated with the datepicker input. */\n targetElement) {\n this.target = target;\n this.targetElement = targetElement;\n this.value = this.target.value;\n }\n}\n/** Directive used to connect an input to a SatDatepicker. */\nlet SatDatepickerInput = SatDatepickerInput_1 = class SatDatepickerInput {\n constructor(_elementRef, _dateAdapter, _dateFormats, _formField) {\n this._elementRef = _elementRef;\n this._dateAdapter = _dateAdapter;\n this._dateFormats = _dateFormats;\n this._formField = _formField;\n /** Emits when a `change` event is fired on this `<input>`. */\n this.dateChange = new EventEmitter();\n /** Emits when an `input` event is fired on this `<input>`. */\n this.dateInput = new EventEmitter();\n /** Emits when the value changes (either due to user input or programmatic change). */\n this._valueChange = new EventEmitter();\n /** Emits when the disabled state has changed */\n this._disabledChange = new EventEmitter();\n this._onTouched = () => {};\n this._cvaOnChange = () => {};\n this._validatorOnChange = () => {};\n this._datepickerSubscription = Subscription.EMPTY;\n this._localeSubscription = Subscription.EMPTY;\n /** The form control validator for whether the input parses. */\n this._parseValidator = () => {\n return this._lastValueValid ? null : {\n 'matDatepickerParse': {\n 'text': this._elementRef.nativeElement.value\n }\n };\n };\n /** The form control validator for the min date. */\n this._minValidator = control => {\n if (this._datepicker.rangeMode && control.value) {\n const beginDate = this._getValidDateOrNull(this._dateAdapter.deserialize(control.value.begin));\n const endDate = this._getValidDateOrNull(this._dateAdapter.deserialize(control.value.end));\n if (this.min) {\n if (beginDate && this._dateAdapter.compareDate(this.min, beginDate) > 0) {\n return {\n 'matDatepickerMin': {\n 'min': this.min,\n 'actual': beginDate\n }\n };\n }\n if (endDate && this._dateAdapter.compareDate(this.min, endDate) > 0) {\n return {\n 'matDatepickerMin': {\n 'min': this.min,\n 'actual': endDate\n }\n };\n }\n }\n return null;\n }\n const controlValue = this._getValidDateOrNull(this._dateAdapter.deserialize(control.value));\n return !this.min || !controlValue || this._dateAdapter.compareDate(this.min, controlValue) <= 0 ? null : {\n 'matDatepickerMin': {\n 'min': this.min,\n 'actual': controlValue\n }\n };\n };\n /** The form control validator for the max date. */\n this._maxValidator = control => {\n if (this._datepicker.rangeMode && control.value) {\n const beginDate = this._getValidDateOrNull(this._dateAdapter.deserialize(control.value.begin));\n const endDate = this._getValidDateOrNull(this._dateAdapter.deserialize(control.value.end));\n if (this.max) {\n if (beginDate && this._dateAdapter.compareDate(this.max, beginDate) < 0) {\n return {\n 'matDatepickerMax': {\n 'max': this.max,\n 'actual': beginDate\n }\n };\n }\n if (endDate && this._dateAdapter.compareDate(this.max, endDate) < 0) {\n return {\n 'matDatepickerMax': {\n 'max': this.max,\n 'actual': endDate\n }\n };\n }\n }\n return null;\n }\n const controlValue = this._getValidDateOrNull(this._dateAdapter.deserialize(control.value));\n return !this.max || !controlValue || this._dateAdapter.compareDate(this.max, controlValue) >= 0 ? null : {\n 'matDatepickerMax': {\n 'max': this.max,\n 'actual': controlValue\n }\n };\n };\n /** The form control validator for the date filter. */\n this._filterValidator = control => {\n if (this._datepicker.rangeMode && control.value) {\n const beginDate = this._getValidDateOrNull(this._dateAdapter.deserialize(control.value.begin));\n const endDate = this._getValidDateOrNull(this._dateAdapter.deserialize(control.value.end));\n return !this._dateFilter || !beginDate && !endDate || this._dateFilter(beginDate) && this._dateFilter(endDate) ? null : {\n 'matDatepickerFilter': true\n };\n }\n const controlValue = this._getValidDateOrNull(this._dateAdapter.deserialize(control.value));\n return !this._dateFilter || !controlValue || this._dateFilter(controlValue) ? null : {\n 'matDatepickerFilter': true\n };\n };\n /** The form control validator for the date filter. */\n this._rangeValidator = control => {\n if (this._datepicker.rangeMode && control.value) {\n const beginDate = this._getValidDateOrNull(this._dateAdapter.deserialize(control.value.begin));\n const endDate = this._getValidDateOrNull(this._dateAdapter.deserialize(control.value.end));\n return !beginDate || !endDate || this._dateAdapter.compareDate(beginDate, endDate) <= 0 ? null : {\n 'matDatepickerRange': true\n };\n }\n return null;\n };\n /** The combined form control validator for this input. */\n this._validator = Validators.compose([this._parseValidator, this._minValidator, this._maxValidator, this._filterValidator, this._rangeValidator]);\n /** Whether the last value set on the input was valid. */\n this._lastValueValid = false;\n if (!this._dateAdapter) {\n throw createMissingDateImplError('DateAdapter');\n }\n if (!this._dateFormats) {\n throw createMissingDateImplError('MAT_DATE_FORMATS');\n }\n // Update the displayed date when the locale changes.\n this._localeSubscription = _dateAdapter.localeChanges.subscribe(() => {\n this.value = this.value;\n });\n }\n /** The datepicker that this input is associated with. */\n set satDatepicker(value) {\n if (!value) {\n return;\n }\n this._datepicker = value;\n this._datepicker._registerInput(this);\n this._datepickerSubscription.unsubscribe();\n this._datepickerSubscription = this._datepicker._selectedChanged.subscribe(selected => {\n this.value = selected;\n this._cvaOnChange(selected);\n this._onTouched();\n this.dateInput.emit(new SatDatepickerInputEvent(this, this._elementRef.nativeElement));\n this.dateChange.emit(new SatDatepickerInputEvent(this, this._elementRef.nativeElement));\n });\n }\n /** Function that can be used to filter out dates within the datepicker. */\n set matDatepickerFilter(value) {\n this._dateFilter = value;\n this._validatorOnChange();\n }\n /** The value of the input. */\n get value() {\n return this._value;\n }\n set value(value) {\n if (value && value.hasOwnProperty('begin') && value.hasOwnProperty('end')) {\n /** Range mode */\n const rangeValue = value;\n rangeValue.begin = this._dateAdapter.deserialize(rangeValue.begin);\n rangeValue.end = this._dateAdapter.deserialize(rangeValue.end);\n this._lastValueValid = !rangeValue.begin || !rangeValue.end || this._dateAdapter.isValid(rangeValue.begin) && this._dateAdapter.isValid(rangeValue.end);\n rangeValue.begin = this._getValidDateOrNull(rangeValue.begin);\n rangeValue.end = this._getValidDateOrNull(rangeValue.end);\n let oldDate = this.value;\n this._elementRef.nativeElement.value = rangeValue && rangeValue.begin && rangeValue.end ? this._dateAdapter.format(rangeValue.begin, this._dateFormats.display.dateInput) + ' - ' + this._dateAdapter.format(rangeValue.end, this._dateFormats.display.dateInput) : '';\n if (oldDate == null && rangeValue != null || oldDate != null && rangeValue == null || !this._dateAdapter.sameDate(oldDate.begin, rangeValue.begin) || !this._dateAdapter.sameDate(oldDate.end, rangeValue.end)) {\n if (rangeValue.end && rangeValue.begin && this._dateAdapter.compareDate(rangeValue.begin, rangeValue.end) > 0) {\n // if begin > end\n value = null;\n }\n this._value = value;\n this._valueChange.emit(value);\n }\n } else {\n /** Not range mode */\n value = this._dateAdapter.deserialize(value);\n this._lastValueValid = !value || this._dateAdapter.isValid(value);\n value = this._getValidDateOrNull(value);\n let oldDate = this.value;\n this._value = value;\n this._elementRef.nativeElement.value = value ? this._dateAdapter.format(value, this._dateFormats.display.dateInput) : '';\n if (!this._dateAdapter.sameDate(oldDate, value)) {\n this._valueChange.emit(value);\n }\n }\n }\n /** The minimum valid date. */\n get min() {\n return this._min;\n }\n set min(value) {\n this._min = this._getValidDateOrNull(this._dateAdapter.deserialize(value));\n this._validatorOnChange();\n }\n /** The maximum valid date. */\n get max() {\n return this._max;\n }\n set max(value) {\n this._max = this._getValidDateOrNull(this._dateAdapter.deserialize(value));\n this._validatorOnChange();\n }\n /** Whether the datepicker-input is disabled. */\n get disabled() {\n return !!this._disabled;\n }\n set disabled(value) {\n const newValue = coerceBooleanProperty(value);\n const element = this._elementRef.nativeElement;\n if (this._disabled !== newValue) {\n this._disabled = newValue;\n this._disabledChange.emit(newValue);\n }\n // We need to null check the `blur` method, because it's undefined during SSR.\n if (newValue && element.blur) {\n // Normally, native input elements automatically blur if they turn disabled. This behavior\n // is problematic, because it would mean that it triggers another change detection cycle,\n // which then causes a changed after checked error if the input element was focused before.\n element.blur();\n }\n }\n ngOnDestroy() {\n this._datepickerSubscription.unsubscribe();\n this._localeSubscription.unsubscribe();\n this._valueChange.complete();\n this._disabledChange.complete();\n }\n /** @docs-private */\n registerOnValidatorChange(fn) {\n this._validatorOnChange = fn;\n }\n /** @docs-private */\n validate(c) {\n return this._validator ? this._validator(c) : null;\n }\n /**\n * @deprecated\n * @breaking-change 8.0.0 Use `getConnectedOverlayOrigin` instead\n */\n getPopupConnectionElementRef() {\n return this.getConnectedOverlayOrigin();\n }\n /**\n * Gets the element that the datepicker popup should be connected to.\n * @return The element to connect the popup to.\n */\n getConnectedOverlayOrigin() {\n return this._formField ? this._formField.getConnectedOverlayOrigin() : this._elementRef;\n }\n // Implemented as part of ControlValueAccessor\n writeValue(value) {\n this.value = value;\n }\n // Implemented as part of ControlValueAccessor.\n registerOnChange(fn) {\n this._cvaOnChange = fn;\n }\n // Implemented as part of ControlValueAccessor.\n registerOnTouched(fn) {\n this._onTouched = fn;\n }\n // Implemented as part of ControlValueAccessor.\n setDisabledState(isDisabled) {\n this.disabled = isDisabled;\n }\n _onKeydown(event) {\n const isAltDownArrow = event.altKey && event.keyCode === DOWN_ARROW;\n if (this._datepicker && isAltDownArrow && !this._elementRef.nativeElement.readOnly) {\n this._datepicker.open();\n event.preventDefault();\n }\n }\n _onInput(value) {\n let date = null;\n if (this._datepicker.rangeMode) {\n const parts = value.split('-');\n if (parts.length > 1) {\n const position = Math.floor(parts.length / 2);\n const beginDateString = parts.slice(0, position).join('-');\n const endDateString = parts.slice(position).join('-');\n let beginDate = this._dateAdapter.parse(beginDateString, this._dateFormats.parse.dateInput);\n let endDate = this._dateAdapter.parse(endDateString, this._dateFormats.parse.dateInput);\n this._lastValueValid = !beginDate || !endDate || this._dateAdapter.isValid(beginDate) && this._dateAdapter.isValid(endDate);\n beginDate = this._getValidDateOrNull(beginDate);\n endDate = this._getValidDateOrNull(endDate);\n if (beginDate && endDate) {\n date = {\n begin: beginDate,\n end: endDate\n };\n }\n }\n } else {\n date = this._dateAdapter.parse(value, this._dateFormats.parse.dateInput);\n this._lastValueValid = !date || this._dateAdapter.isValid(date);\n date = this._getValidDateOrNull(date);\n }\n this._value = date;\n this._cvaOnChange(date);\n this._valueChange.emit(date);\n this.dateInput.emit(new SatDatepickerInputEvent(this, this._elementRef.nativeElement));\n }\n _onChange() {\n this.dateChange.emit(new SatDatepickerInputEvent(this, this._elementRef.nativeElement));\n }\n /** Returns the palette used by the input's form field, if any. */\n _getThemePalette() {\n return this._formField ? this._formField.color : undefined;\n }\n /** Handles blur events on the input. */\n _onBlur() {\n // Reformat the input only if we have a valid value.\n if (this.value) {\n this._formatValue(this.value);\n }\n this._onTouched();\n }\n /** Formats a value and sets it on the input element. */\n _formatValue(value) {\n if (value && value.hasOwnProperty('begin') && value.hasOwnProperty('end')) {\n value = value;\n this._elementRef.nativeElement.value = value && value.begin && value.end ? this._dateAdapter.format(value.begin, this._dateFormats.display.dateInput) + ' - ' + this._dateAdapter.format(value.end, this._dateFormats.display.dateInput) : '';\n } else {\n value = value;\n this._elementRef.nativeElement.value = value ? this._dateAdapter.format(value, this._dateFormats.display.dateInput) : '';\n }\n }\n /**\n * @param obj The object to check.\n * @returns The given object if it is both a date instance and valid, otherwise null.\n */\n _getValidDateOrNull(obj) {\n return this._dateAdapter.isDateInstance(obj) && this._dateAdapter.isValid(obj) ? obj : null;\n }\n};\nSatDatepickerInput.ctorParameters = () => [{\n type: ElementRef\n}, {\n type: DateAdapter,\n decorators: [{\n type: Optional\n }]\n}, {\n type: undefined,\n decorators: [{\n type: Optional\n }, {\n type: Inject,\n args: [MAT_DATE_FORMATS]\n }]\n}, {\n type: MatFormField,\n decorators: [{\n type: Optional\n }]\n}];\n__decorate([Input()], SatDatepickerInput.prototype, \"satDatepicker\", null);\n__decorate([Input()], SatDatepickerInput.prototype, \"matDatepickerFilter\", null);\n__decorate([Input()], SatDatepickerInput.prototype, \"value\", null);\n__decorate([Input()], SatDatepickerInput.prototype, \"min\", null);\n__decorate([Input()], SatDatepickerInput.prototype, \"max\", null);\n__decorate([Input()], SatDatepickerInput.prototype, \"disabled\", null);\n__decorate([Output()], SatDatepickerInput.prototype, \"dateChange\", void 0);\n__decorate([Output()], SatDatepickerInput.prototype, \"dateInput\", void 0);\nSatDatepickerInput = SatDatepickerInput_1 = __decorate([Directive({\n selector: 'input[satDatepicker]',\n providers: [MAT_DATEPICKER_VALUE_ACCESSOR, MAT_DATEPICKER_VALIDATORS, {\n provide: MAT_INPUT_VALUE_ACCESSOR,\n useExisting: SatDatepickerInput_1\n }],\n host: {\n '[attr.aria-haspopup]': '_datepicker ? \"dialog\" : null',\n '[attr.aria-owns]': '(_datepicker?.opened && _datepicker.id) || null',\n '[attr.min]': 'min ? _dateAdapter.toIso8601(min) : null',\n '[attr.max]': 'max ? _dateAdapter.toIso8601(max) : null',\n '[disabled]': 'disabled',\n '(input)': '_onInput($event.target.value)',\n '(change)': '_onChange()',\n '(blur)': '_onBlur()',\n '(keydown)': '_onKeydown($event)'\n },\n exportAs: 'matDatepickerInput'\n}), __param(1, Optional()), __param(2, Optional()), __param(2, Inject(MAT_DATE_FORMATS)), __param(3, Optional())], SatDatepickerInput);\n\n/**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n/** Can be used to override the icon of a `matDatepickerToggle`. */\nlet SatDatepickerToggleIcon = /*#__PURE__*/(() => {\n let SatDatepickerToggleIcon = class SatDatepickerToggleIcon {};\n SatDatepickerToggleIcon = __decorate([Directive({\n selector: '[matDatepickerToggleIcon]'\n })], SatDatepickerToggleIcon);\n return SatDatepickerToggleIcon;\n})();\nlet SatDatepickerToggle = /*#__PURE__*/(() => {\n let SatDatepickerToggle = class SatDatepickerToggle {\n constructor(_intl, _changeDetectorRef, defaultTabIndex) {\n this._intl = _intl;\n this._changeDetectorRef = _changeDetectorRef;\n this._stateChanges = Subscription.EMPTY;\n const parsedTabIndex = Number(defaultTabIndex);\n this.tabIndex = parsedTabIndex || parsedTabIndex === 0 ? parsedTabIndex : null;\n }\n /** Whether the toggle button is disabled. */\n get disabled() {\n if (this._disabled === undefined && this.datepicker) {\n return this.datepicker.disabled;\n }\n return !!this._disabled;\n }\n set disabled(value) {\n this._disabled = coerceBooleanProperty(value);\n }\n ngOnChanges(changes) {\n if (changes['datepicker']) {\n this._watchStateChanges();\n }\n }\n ngOnDestroy() {\n this._stateChanges.unsubscribe();\n }\n ngAfterContentInit() {\n this._watchStateChanges();\n }\n _open(event) {\n if (this.datepicker && !this.disabled) {\n this.datepicker.open();\n event.stopPropagation();\n }\n }\n _watchStateChanges() {\n const datepickerDisabled = this.datepicker ? this.datepicker._disabledChange : of();\n const inputDisabled = this.datepicker && this.datepicker._datepickerInput ? this.datepicker._datepickerInput._disabledChange : of();\n const datepickerToggled = this.datepicker ? merge(this.datepicker.openedStream, this.datepicker.closedStream) : of();\n this._stateChanges.unsubscribe();\n this._stateChanges = merge(this._intl.changes, datepickerDisabled, inputDisabled, datepickerToggled).subscribe(() => this._changeDetectorRef.markForCheck());\n }\n };\n __decorate([Input('for')], SatDatepickerToggle.prototype, \"datepicker\", void 0);\n __decorate([Input()], SatDatepickerToggle.prototype, \"tabIndex\", void 0);\n __decorate([Input()], SatDatepickerToggle.prototype, \"disabled\", null);\n __decorate([Input()], SatDatepickerToggle.prototype, \"disableRipple\", void 0);\n __decorate([ContentChild(SatDatepickerToggleIcon, {\n static: false\n })], SatDatepickerToggle.prototype, \"_customIcon\", void 0);\n __decorate([ViewChild('button', {\n static: false\n })], SatDatepickerToggle.prototype, \"_button\", void 0);\n SatDatepickerToggle = __decorate([Component({\n moduleId: module.id,\n selector: 'sat-datepicker-toggle',\n template: \"<button\\n #button\\n mat-icon-button\\n type=\\\"button\\\"\\n [attr.aria-haspopup]=\\\"datepicker ? 'dialog' : null\\\"\\n [attr.aria-label]=\\\"_intl.openCalendarLabel\\\"\\n [attr.tabindex]=\\\"disabled ? -1 : tabIndex\\\"\\n [disabled]=\\\"disabled\\\"\\n [disableRipple]=\\\"disableRipple\\\"\\n (click)=\\\"_open($event)\\\">\\n\\n <svg\\n *ngIf=\\\"!_customIcon\\\"\\n class=\\\"mat-datepicker-toggle-default-icon\\\"\\n viewBox=\\\"0 0 24 24\\\"\\n width=\\\"24px\\\"\\n height=\\\"24px\\\"\\n fill=\\\"currentColor\\\"\\n focusable=\\\"false\\\">\\n <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\\\"/>\\n </svg>\\n\\n <ng-content select=\\\"[matDatepickerToggleIcon]\\\"></ng-content>\\n</button>\\n\",\n host: {\n 'class': 'mat-datepicker-toggle',\n // Always set the tabindex to -1 so that it doesn't overlap with any custom tabindex the\n // consumer may have provided, while still being able to receive focus.\n '[attr.tabindex]': '-1',\n '[class.mat-datepicker-toggle-active]': 'datepicker && datepicker.opened',\n '[class.mat-accent]': 'datepicker && datepicker.color === \"accent\"',\n '[class.mat-warn]': 'datepicker && datepicker.color === \"warn\"',\n '(focus)': '_button.focus()'\n },\n exportAs: 'matDatepickerToggle',\n encapsulation: ViewEncapsulation.None,\n changeDetection: ChangeDetectionStrategy.OnPush,\n styles: [\".mat-form-field-appearance-legacy .mat-form-field-prefix .mat-datepicker-toggle-default-icon,.mat-form-field-appearance-legacy .mat-form-field-suffix .mat-datepicker-toggle-default-icon{width:1em}.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-prefix .mat-datepicker-toggle-default-icon,.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-suffix .mat-datepicker-toggle-default-icon{display:block;width:1.5em;height:1.5em}.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-prefix .mat-icon-button .mat-datepicker-toggle-default-icon,.mat-form-field:not(.mat-form-field-appearance-legacy) .mat-form-field-suffix .mat-icon-button .mat-datepicker-toggle-default-icon{margin:auto}\"]\n }), __param(2, Attribute('tabindex'))], SatDatepickerToggle);\n\n /**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n return SatDatepickerToggle;\n})();\nlet SatDatepickerModule = /*#__PURE__*/(() => {\n let SatDatepickerModule = class SatDatepickerModule {};\n SatDatepickerModule = __decorate([NgModule({\n imports: [CommonModule, MatButtonModule, MatDialogModule, OverlayModule, A11yModule, PortalModule],\n exports: [SatCalendar, SatCalendarBody, SatDatepicker, SatDatepickerContent, SatDatepickerInput, SatDatepickerToggle, SatDatepickerToggleIcon, SatMonthView, SatYearView, SatMultiYearView, SatCalendarHeader, SatCalendarFooter],\n declarations: [SatCalendar, SatCalendarBody, SatDatepicker, SatDatepickerContent, SatDatepickerInput, SatDatepickerToggle, SatDatepickerToggleIcon, SatMonthView, SatYearView, SatMultiYearView, SatCalendarHeader, SatCalendarFooter],\n providers: [SatDatepickerIntl, MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY_PROVIDER],\n entryComponents: [SatDatepickerContent, SatCalendarHeader, SatCalendarFooter]\n })], SatDatepickerModule);\n\n /**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n /**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n /**\n * @license\n * Copyright Google LLC All Rights Reserved.\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://angular.io/license\n */\n\n /**\n * Generated bundle index. Do not edit.\n */\n return SatDatepickerModule;\n})();\nexport { DateAdapter, MAT_DATEPICKER_SCROLL_STRATEGY, MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY, MAT_DATEPICKER_SCROLL_STRATEGY_FACTORY_PROVIDER, MAT_DATEPICKER_VALIDATORS, MAT_DATEPICKER_VALUE_ACCESSOR, MAT_DATE_FORMATS, MAT_DATE_LOCALE, MAT_DATE_LOCALE_FACTORY, MAT_DATE_LOCALE_PROVIDER, MAT_NATIVE_DATE_FORMATS, NativeDateAdapter, NativeDateModule, SatCalendar, SatCalendarBody, SatCalendarCell, SatCalendarFooter, SatCalendarHeader, SatDatepicker, SatDatepickerContent, SatDatepickerInput, SatDatepickerInputEvent, SatDatepickerIntl, SatDatepickerModule, SatDatepickerToggle, SatDatepickerToggleIcon, SatMonthView, SatMultiYearView, SatNativeDateModule, SatYearView, matDatepickerAnimations, yearsPerPage, yearsPerRow, ɵ0$1 as ɵ0 };\n//# sourceMappingURL=saturn-datepicker.js.map","map":null,"metadata":{},"sourceType":"module","externalDependencies":[]}