UNPKG

materialize-angular

Version:
468 lines 36.9 kB
/** * @fileoverview added by tsickle * Generated from: app/completed-components/calendar/calendar.component.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * @license * Copyright Workylab. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://raw.githubusercontent.com/workylab/materialize-angular/master/LICENSE */ import { Component, ElementRef, EventEmitter, Input, Output, ViewChild } from '@angular/core'; import { config } from '../../config'; import { days } from '../../fixtures/calendar-week-days'; import { months } from '../../fixtures/calendar-months'; var CalendarComponent = /** @class */ (function () { function CalendarComponent() { this.className = CalendarComponent.defaultProps.className; this.date = CalendarComponent.defaultProps.date; this.displayOtherMonthDays = CalendarComponent.defaultProps.displayOtherMonthDays; this.prefix = config.components.prefix; this.selectYearAnimationDuration = 150; this.scrollToActiveYear = this.scrollToActiveYear.bind(this); this.onSelectDayEmitter = new EventEmitter(); this.dayLabels = this.getDayLabels(days); this.monthLabels = this.getMonthLabels(months); } /** * @return {?} */ CalendarComponent.prototype.ngOnInit = /** * @return {?} */ function () { this.init(); }; /** * @return {?} */ CalendarComponent.prototype.ngOnChanges = /** * @return {?} */ function () { this.init(); }; /** * @return {?} */ CalendarComponent.prototype.init = /** * @return {?} */ function () { /** @type {?} */ var dateExists = (typeof this.date !== 'undefined' && this.date !== null); /** @type {?} */ var openDate = dateExists ? this.date : new Date(); /** @type {?} */ var isToday = this.isTodayDate(openDate); /** @type {?} */ var month = openDate.getMonth(); /** @type {?} */ var year = openDate.getFullYear(); this.weeks = this.fillWeeks(month, year); this.years = this.fillYears(year); this.selectedDate = this.createDateModel(openDate, false, isToday, dateExists); }; /** * @param {?} dayLabels * @return {?} */ CalendarComponent.prototype.getDayLabels = /** * @param {?} dayLabels * @return {?} */ function (dayLabels) { return [ dayLabels.sunday, dayLabels.monday, dayLabels.tuesday, dayLabels.wednesday, dayLabels.thursday, dayLabels.friday, dayLabels.saturday ]; }; /** * @param {?} monthLabels * @return {?} */ CalendarComponent.prototype.getMonthLabels = /** * @param {?} monthLabels * @return {?} */ function (monthLabels) { return [ monthLabels.january, monthLabels.february, monthLabels.march, monthLabels.april, monthLabels.may, monthLabels.june, monthLabels.july, monthLabels.august, monthLabels.september, monthLabels.october, monthLabels.november, monthLabels.december ]; }; /** * @param {?} date * @param {?} isOutOfMonth * @param {?} isToday * @param {?} showSelected * @return {?} */ CalendarComponent.prototype.createDateModel = /** * @param {?} date * @param {?} isOutOfMonth * @param {?} isToday * @param {?} showSelected * @return {?} */ function (date, isOutOfMonth, isToday, showSelected) { /** @type {?} */ var weekDay = date.getDay(); /** @type {?} */ var month = date.getMonth(); /** @type {?} */ var dateModel = { ISODate: this.generateISODate(date), date: date, dayLabel: this.dayLabels[weekDay], isOutOfMonth: isOutOfMonth, isToday: isToday, monthLabel: this.monthLabels[month], showSelected: showSelected }; return dateModel; }; /** * @param {?} day * @param {?} month * @param {?} year * @return {?} */ CalendarComponent.prototype.createDateObject = /** * @param {?} day * @param {?} month * @param {?} year * @return {?} */ function (day, month, year) { /** @type {?} */ var date = new Date(); date.setDate(day); date.setMonth(month); date.setFullYear(year); return date; }; /** * @param {?} currentYear * @return {?} */ CalendarComponent.prototype.fillYears = /** * @param {?} currentYear * @return {?} */ function (currentYear) { /** @type {?} */ var firstYear = currentYear - 100; /** @type {?} */ var lastYear = currentYear + 100; /** @type {?} */ var years = []; for (var i = firstYear; i <= lastYear; i++) { years.push(i); } return years; }; /** * @param {?} month * @param {?} year * @return {?} */ CalendarComponent.prototype.fillWeeks = /** * @param {?} month * @param {?} year * @return {?} */ function (month, year) { this.selectedMonth = { label: this.monthLabels[month], number: month, year: year }; /** @type {?} */ var finalMonthDay = this.createDateObject(0, month, year); /** @type {?} */ var weeks = []; /** @type {?} */ var initMonthDate = new Date(year, month, 1); /** @type {?} */ var day = 0 - initMonthDate.getDay(); /** @type {?} */ var daysInWeek = []; while (initMonthDate.getDay() !== 0 || finalMonthDay >= initMonthDate) { ++day; initMonthDate = new Date(year, month, day); daysInWeek.push(this.createDayDate(initMonthDate, day, finalMonthDay)); if (daysInWeek.length === 7) { weeks.push(daysInWeek); daysInWeek = []; } } return weeks; }; /** * @param {?} date * @return {?} */ CalendarComponent.prototype.isTodayDate = /** * @param {?} date * @return {?} */ function (date) { /** @type {?} */ var ISOCurrentDate = this.generateISODate(new Date()); /** @type {?} */ var ISODate = this.generateISODate(date); /** @type {?} */ var isToday = (ISODate === ISOCurrentDate); return isToday; }; /** * @param {?} date * @param {?} dayNumber * @param {?} finalMonthDay * @return {?} */ CalendarComponent.prototype.createDayDate = /** * @param {?} date * @param {?} dayNumber * @param {?} finalMonthDay * @return {?} */ function (date, dayNumber, finalMonthDay) { /** @type {?} */ var isToday = this.isTodayDate(date); /** @type {?} */ var isOutOfMonth = (dayNumber <= 0 || date > finalMonthDay); return this.createDateModel(date, isOutOfMonth, isToday, true); }; /** * @return {?} */ CalendarComponent.prototype.showPrevMonth = /** * @return {?} */ function () { /** @type {?} */ var month = this.selectedMonth.number; /** @type {?} */ var year = this.selectedMonth.year; /** @type {?} */ var prevMonth = month >= 1 ? month - 1 : 11; /** @type {?} */ var prevYear = month < 1 ? year - 1 : year; this.weeks = this.fillWeeks(prevMonth, prevYear); }; /** * @return {?} */ CalendarComponent.prototype.showNextMonth = /** * @return {?} */ function () { /** @type {?} */ var month = this.selectedMonth.number; /** @type {?} */ var year = this.selectedMonth.year; /** @type {?} */ var nextMonth = month < 11 ? month + 1 : 0; /** @type {?} */ var nextYear = month >= 11 ? year + 1 : year; this.weeks = this.fillWeeks(nextMonth, nextYear); }; /** * @param {?} date * @return {?} */ CalendarComponent.prototype.generateISODate = /** * @param {?} date * @return {?} */ function (date) { /** @type {?} */ var day = date.getDate(); /** @type {?} */ var month = date.getMonth() + 1; /** @type {?} */ var year = date.getFullYear(); /** @type {?} */ var dayString = day > 9 ? day : "0" + day; /** @type {?} */ var monthString = month > 9 ? month : "0" + month; return year + "-" + monthString + "-" + dayString; }; /** * @param {?} date * @return {?} */ CalendarComponent.prototype.onSelectDay = /** * @param {?} date * @return {?} */ function (date) { if (date.isOutOfMonth) { return; } this.selectedDate = date; this.onSelectDayEmitter.emit(this.selectedDate); }; /** * @param {?} year * @return {?} */ CalendarComponent.prototype.onSelectYear = /** * @param {?} year * @return {?} */ function (year) { var _this = this; setTimeout((/** * @return {?} */ function () { /** @type {?} */ var day = _this.selectedDate.date.getDate(); /** @type {?} */ var month = _this.selectedDate.date.getMonth(); _this.date = _this.createDateObject(day, month, year); _this.showYears = false; _this.selectedDate = _this.createDateModel(_this.date, false, true, true); _this.weeks = _this.fillWeeks(month, year); }), this.selectYearAnimationDuration); }; /** * @return {?} */ CalendarComponent.prototype.displayYears = /** * @return {?} */ function () { this.showYears = true; setTimeout(this.scrollToActiveYear, 0); }; /** * @return {?} */ CalendarComponent.prototype.scrollToActiveYear = /** * @return {?} */ function () { var nativeElement = this.yearsContainerRef.nativeElement; /** @type {?} */ var activeYear = nativeElement.querySelector('.selected'); if (activeYear) { /** @type {?} */ var top_1 = this.getScrollCenter(nativeElement, activeYear); nativeElement.scrollTop = top_1; } }; /** * @param {?} container * @param {?} internalElement * @return {?} */ CalendarComponent.prototype.getScrollCenter = /** * @param {?} container * @param {?} internalElement * @return {?} */ function (container, internalElement) { /** @type {?} */ var yearTop = internalElement.offsetTop; /** @type {?} */ var yearMiddleHeight = internalElement.offsetHeight / 2; /** @type {?} */ var containerTop = container.offsetTop; /** @type {?} */ var containerMiddleHeight = container.offsetHeight / 2; /** @type {?} */ var elementRelativeTop = (yearTop - containerTop) - (containerMiddleHeight - yearMiddleHeight); if (elementRelativeTop < 0) { return 0; } return elementRelativeTop; }; CalendarComponent.defaultProps = { className: '', date: new Date(), displayOtherMonthDays: true }; CalendarComponent.decorators = [ { type: Component, args: [{ selector: config.components.prefix + "-calendar }", template: "<div [ngClass]=\"[prefix + '-calendar', className]\">\n <div [ngClass]=\"prefix + '-calendar-header'\">\n <div [ngClass]=\"prefix + '-calendar-year'\">\n <materialize-button (onClick)=\"displayYears()\">{{ selectedMonth.year }}</materialize-button>\n </div>\n <div [ngClass]=\"prefix + '-calendar-date'\">\n <materialize-button (onClick)=\"showYears = false\">\n {{ selectedDate.dayLabel.shortName }}, {{ selectedDate.monthLabel.shortName }} {{ selectedDate.date.getDate() }}\n </materialize-button>\n </div>\n </div>\n\n <div [ngClass]=\"prefix + '-calendar-body'\">\n <ng-container *ngIf=\"!showYears\">\n <div [ngClass]=\"prefix + '-calendar-controls'\">\n <div [ngClass]=\"prefix + '-calendar-control'\" materializeRipple (click)=\"showPrevMonth()\">\n <materialize-icon>chevron_left</materialize-icon>\n </div>\n <div [ngClass]=\"prefix + '-calendar-month'\">\n {{ selectedMonth.label.shortName }} {{ selectedMonth.year }}\n </div>\n <div [ngClass]=\"prefix + '-calendar-control'\" materializeRipple (click)=\"showNextMonth()\">\n <materialize-icon>chevron_right</materialize-icon>\n </div>\n </div>\n \n <table [ngClass]=\"prefix + '-calendar-table'\">\n <thead>\n <tr>\n <td [ngClass]=\"prefix + '-calendar-day-name'\" *ngFor=\"let day of dayLabels\">{{ day.shortestName }}</td>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let week of weeks\">\n <td *ngFor=\"let day of week\">\n <div [ngClass]=\"prefix + '-calendar-day'\"\n (click)=\"onSelectDay(day)\"\n *ngIf=\"!day.isOutOfMonth || displayOtherMonthDays\"\n \n [class.current]=\"day.isToday\"\n [class.selected]=\"selectedDate.showSelected && selectedDate.ISODate === day.ISODate\"\n [class.disabled]=\"day.isOutOfMonth\"\n \n materializeRipple\n [rippleDuration]=\"800\"\n >\n {{ day.date.getDate() }}\n </div>\n </td>\n </tr>\n </tbody>\n </table>\n </ng-container>\n \n <div [ngClass]=\"prefix + '-calendar-years'\" #yearsContainer>\n <ng-container *ngIf=\"showYears\">\n <div [ngClass]=\"prefix + '-calendar-year-option'\"\n *ngFor=\"let year of years\"\n\n (click)=\"onSelectYear(year)\"\n [class.selected]=\"year === selectedMonth.year\"\n\n materializeRipple\n [rippleDuration]=\"selectYearAnimationDuration\"\n >\n {{ year }}\n </div>\n </ng-container>\n </div>\n </div>\n</div>\n" }] } ]; /** @nocollapse */ CalendarComponent.ctorParameters = function () { return []; }; CalendarComponent.propDecorators = { yearsContainerRef: [{ type: ViewChild, args: ['yearsContainer', { static: false },] }], onSelectDayEmitter: [{ type: Output, args: ['onSelectDay',] }], className: [{ type: Input }], date: [{ type: Input }], displayOtherMonthDays: [{ type: Input }] }; return CalendarComponent; }()); export { CalendarComponent }; if (false) { /** @type {?} */ CalendarComponent.defaultProps; /** @type {?} */ CalendarComponent.prototype.yearsContainerRef; /** @type {?} */ CalendarComponent.prototype.onSelectDayEmitter; /** @type {?} */ CalendarComponent.prototype.className; /** @type {?} */ CalendarComponent.prototype.date; /** @type {?} */ CalendarComponent.prototype.displayOtherMonthDays; /** @type {?} */ CalendarComponent.prototype.prefix; /** @type {?} */ CalendarComponent.prototype.dayLabels; /** @type {?} */ CalendarComponent.prototype.monthLabels; /** @type {?} */ CalendarComponent.prototype.selectedDate; /** @type {?} */ CalendarComponent.prototype.selectedMonth; /** @type {?} */ CalendarComponent.prototype.showYears; /** @type {?} */ CalendarComponent.prototype.weeks; /** @type {?} */ CalendarComponent.prototype.years; /** @type {?} */ CalendarComponent.prototype.selectYearAnimationDuration; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2FsZW5kYXIuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbWF0ZXJpYWxpemUtYW5ndWxhci8iLCJzb3VyY2VzIjpbImFwcC9jb21wbGV0ZWQtY29tcG9uZW50cy9jYWxlbmRhci9jYWxlbmRhci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBU0EsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBcUIsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNqSCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3RDLE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxtQ0FBbUMsQ0FBQztBQUN6RCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFFeEQ7SUErQkU7UUFoQlMsY0FBUyxHQUFXLGlCQUFpQixDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUM7UUFDN0QsU0FBSSxHQUFTLGlCQUFpQixDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUM7UUFDakQsMEJBQXFCLEdBQVksaUJBQWlCLENBQUMsWUFBWSxDQUFDLHFCQUFxQixDQUFDO1FBRXhGLFdBQU0sR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQztRQVVsQyxnQ0FBMkIsR0FBRyxHQUFHLENBQUM7UUFHdkMsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFN0QsSUFBSSxDQUFDLGtCQUFrQixHQUFHLElBQUksWUFBWSxFQUFhLENBQUM7UUFFeEQsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3pDLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNqRCxDQUFDOzs7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QW1DOztJQUNuQyx3Q0FBcUM7O0lBQ3JDLHlDQUErQjs7SUFDL0IsMENBQWlDOztJQUNqQyxzQ0FBMEI7O0lBQzFCLGtDQUFzQzs7SUFDdEMsa0NBQTRCOztJQUU1Qix3REFBeUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgV29ya3lsYWIuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL3dvcmt5bGFiL21hdGVyaWFsaXplLWFuZ3VsYXIvbWFzdGVyL0xJQ0VOU0VcbiAqL1xuXG5pbXBvcnQgeyBDYWxlbmRhck1vZGVsLCBEYXRlTGFiZWwsIERhdGVNb2RlbCwgRGF5TGFiZWxzLCBNb250aExhYmVscywgTW9udGhNb2RlbCB9IGZyb20gJy4vY2FsZW5kYXIubW9kZWwnO1xuaW1wb3J0IHsgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIElucHV0LCBPbkNoYW5nZXMsIE9uSW5pdCwgT3V0cHV0LCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IGNvbmZpZyB9IGZyb20gJy4uLy4uL2NvbmZpZyc7XG5pbXBvcnQgeyBkYXlzIH0gZnJvbSAnLi4vLi4vZml4dHVyZXMvY2FsZW5kYXItd2Vlay1kYXlzJztcbmltcG9ydCB7IG1vbnRocyB9IGZyb20gJy4uLy4uL2ZpeHR1cmVzL2NhbGVuZGFyLW1vbnRocyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogYCR7IGNvbmZpZy5jb21wb25lbnRzLnByZWZpeCB9LWNhbGVuZGFyIH1gLFxuICB0ZW1wbGF0ZVVybDogJy4vY2FsZW5kYXIuY29tcG9uZW50Lmh0bWwnXG59KVxuZXhwb3J0IGNsYXNzIENhbGVuZGFyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMge1xuICBzdGF0aWMgcmVhZG9ubHkgZGVmYXVsdFByb3BzOiBDYWxlbmRhck1vZGVsID0ge1xuICAgIGNsYXNzTmFtZTogJycsXG4gICAgZGF0ZTogbmV3IERhdGUoKSxcbiAgICBkaXNwbGF5T3RoZXJNb250aERheXM6IHRydWVcbiAgfTtcblxuICBAVmlld0NoaWxkKCd5ZWFyc0NvbnRhaW5lcicsIHsgc3RhdGljOiBmYWxzZSB9KSB5ZWFyc0NvbnRhaW5lclJlZjogRWxlbWVudFJlZjtcblxuICBAT3V0cHV0KCdvblNlbGVjdERheScpIG9uU2VsZWN0RGF5RW1pdHRlcjogRXZlbnRFbWl0dGVyPERhdGVNb2RlbD47XG5cbiAgQElucHV0KCkgY2xhc3NOYW1lOiBzdHJpbmcgPSBDYWxlbmRhckNvbXBvbmVudC5kZWZhdWx0UHJvcHMuY2xhc3NOYW1lO1xuICBASW5wdXQoKSBkYXRlOiBEYXRlID0gQ2FsZW5kYXJDb21wb25lbnQuZGVmYXVsdFByb3BzLmRhdGU7XG4gIEBJbnB1dCgpIGRpc3BsYXlPdGhlck1vbnRoRGF5czogYm9vbGVhbiA9IENhbGVuZGFyQ29tcG9uZW50LmRlZmF1bHRQcm9wcy5kaXNwbGF5T3RoZXJNb250aERheXM7XG5cbiAgcHVibGljIHByZWZpeCA9IGNvbmZpZy5jb21wb25lbnRzLnByZWZpeDtcblxuICBwdWJsaWMgZGF5TGFiZWxzOiBBcnJheTxEYXRlTGFiZWw+O1xuICBwdWJsaWMgbW9udGhMYWJlbHM6IEFycmF5PERhdGVMYWJlbD47XG4gIHB1YmxpYyBzZWxlY3RlZERhdGU6IERhdGVNb2RlbDtcbiAgcHVibGljIHNlbGVjdGVkTW9udGg6IE1vbnRoTW9kZWw7XG4gIHB1YmxpYyBzaG93WWVhcnM6IGJvb2xlYW47XG4gIHB1YmxpYyB3ZWVrczogQXJyYXk8QXJyYXk8RGF0ZU1vZGVsPj47XG4gIHB1YmxpYyB5ZWFyczogQXJyYXk8bnVtYmVyPjtcblxuICBwdWJsaWMgc2VsZWN0WWVhckFuaW1hdGlvbkR1cmF0aW9uID0gMTUwO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHRoaXMuc2Nyb2xsVG9BY3RpdmVZZWFyID0gdGhpcy5zY3JvbGxUb0FjdGl2ZVllYXIuYmluZCh0aGlzKTtcblxuICAgIHRoaXMub25TZWxlY3REYXlFbWl0dGVyID0gbmV3IEV2ZW50RW1pdHRlcjxEYXRlTW9kZWw+KCk7XG5cbiAgICB0aGlzLmRheUxhYmVscyA9IHRoaXMuZ2V0RGF5TGFiZWxzKGRheXMpO1xuICAgIHRoaXMubW9udGhMYWJlbHMgPSB0aGlzLmdldE1vbnRoTGFiZWxzKG1vbnRocyk7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmluaXQoKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKCkge1xuICAgIHRoaXMuaW5pdCgpO1xuICB9XG5cbiAgaW5pdCgpIHtcbiAgICBjb25zdCBkYXRlRXhpc3RzID0gKHR5cGVvZiB0aGlzLmRhdGUgIT09ICd1bmRlZmluZWQnICYmIHRoaXMuZGF0ZSAhPT0gbnVsbCk7XG4gICAgY29uc3Qgb3BlbkRhdGUgPSBkYXRlRXhpc3RzID8gdGhpcy5kYXRlIDogbmV3IERhdGUoKTtcbiAgICBjb25zdCBpc1RvZGF5ID0gdGhpcy5pc1RvZGF5RGF0ZShvcGVuRGF0ZSk7XG4gICAgY29uc3QgbW9udGggPSBvcGVuRGF0ZS5nZXRNb250aCgpO1xuICAgIGNvbnN0IHllYXIgPSBvcGVuRGF0ZS5nZXRGdWxsWWVhcigpO1xuXG4gICAgdGhpcy53ZWVrcyA9IHRoaXMuZmlsbFdlZWtzKG1vbnRoLCB5ZWFyKTtcbiAgICB0aGlzLnllYXJzID0gdGhpcy5maWxsWWVhcnMoeWVhcik7XG5cbiAgICB0aGlzLnNlbGVjdGVkRGF0ZSA9IHRoaXMuY3JlYXRlRGF0ZU1vZGVsKG9wZW5EYXRlLCBmYWxzZSwgaXNUb2RheSwgZGF0ZUV4aXN0cyk7XG4gIH1cblxuICBnZXREYXlMYWJlbHMoZGF5TGFiZWxzOiBEYXlMYWJlbHMpOiBBcnJheTxEYXRlTGFiZWw+IHtcbiAgICByZXR1cm4gW1xuICAgICAgZGF5TGFiZWxzLnN1bmRheSxcbiAgICAgIGRheUxhYmVscy5tb25kYXksXG4gICAgICBkYXlMYWJlbHMudHVlc2RheSxcbiAgICAgIGRheUxhYmVscy53ZWRuZXNkYXksXG4gICAgICBkYXlMYWJlbHMudGh1cnNkYXksXG4gICAgICBkYXlMYWJlbHMuZnJpZGF5LFxuICAgICAgZGF5TGFiZWxzLnNhdHVyZGF5XG4gICAgXTtcbiAgfVxuXG4gIGdldE1vbnRoTGFiZWxzKG1vbnRoTGFiZWxzOiBNb250aExhYmVscyk6IEFycmF5PERhdGVMYWJlbD4ge1xuICAgIHJldHVybiBbXG4gICAgICBtb250aExhYmVscy5qYW51YXJ5LFxuICAgICAgbW9udGhMYWJlbHMuZmVicnVhcnksXG4gICAgICBtb250aExhYmVscy5tYXJjaCxcbiAgICAgIG1vbnRoTGFiZWxzLmFwcmlsLFxuICAgICAgbW9udGhMYWJlbHMubWF5LFxuICAgICAgbW9udGhMYWJlbHMuanVuZSxcbiAgICAgIG1vbnRoTGFiZWxzLmp1bHksXG4gICAgICBtb250aExhYmVscy5hdWd1c3QsXG4gICAgICBtb250aExhYmVscy5zZXB0ZW1iZXIsXG4gICAgICBtb250aExhYmVscy5vY3RvYmVyLFxuICAgICAgbW9udGhMYWJlbHMubm92ZW1iZXIsXG4gICAgICBtb250aExhYmVscy5kZWNlbWJlclxuICAgIF07XG4gIH1cblxuICBjcmVhdGVEYXRlTW9kZWwoZGF0ZTogRGF0ZSwgaXNPdXRPZk1vbnRoOiBib29sZWFuLCBpc1RvZGF5OiBib29sZWFuLCBzaG93U2VsZWN0ZWQ6IGJvb2xlYW4pOiBEYXRlTW9kZWwge1xuICAgIGNvbnN0IHdlZWtEYXkgPSBkYXRlLmdldERheSgpO1xuICAgIGNvbnN0IG1vbnRoID0gZGF0ZS5nZXRNb250aCgpO1xuXG4gICAgY29uc3QgZGF0ZU1vZGVsOiBEYXRlTW9kZWwgPSB7XG4gICAgICBJU09EYXRlOiB0aGlzLmdlbmVyYXRlSVNPRGF0ZShkYXRlKSxcbiAgICAgIGRhdGU6IGRhdGUsXG4gICAgICBkYXlMYWJlbDogdGhpcy5kYXlMYWJlbHNbd2Vla0RheV0sXG4gICAgICBpc091dE9mTW9udGg6IGlzT3V0T2ZNb250aCxcbiAgICAgIGlzVG9kYXk6IGlzVG9kYXksXG4gICAgICBtb250aExhYmVsOiB0aGlzLm1vbnRoTGFiZWxzW21vbnRoXSxcbiAgICAgIHNob3dTZWxlY3RlZDogc2hvd1NlbGVjdGVkXG4gICAgfTtcblxuICAgIHJldHVybiBkYXRlTW9kZWw7XG4gIH1cblxuICBjcmVhdGVEYXRlT2JqZWN0KGRheTogbnVtYmVyLCBtb250aDogbnVtYmVyLCB5ZWFyOiBudW1iZXIpOiBEYXRlIHtcbiAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoKTtcblxuICAgIGRhdGUuc2V0RGF0ZShkYXkpO1xuICAgIGRhdGUuc2V0TW9udGgobW9udGgpO1xuICAgIGRhdGUuc2V0RnVsbFllYXIoeWVhcik7XG5cbiAgICByZXR1cm4gZGF0ZTtcbiAgfVxuXG4gIGZpbGxZZWFycyhjdXJyZW50WWVhcjogbnVtYmVyKTogQXJyYXk8bnVtYmVyPiB7XG4gICAgY29uc3QgZmlyc3RZZWFyID0gY3VycmVudFllYXIgLSAxMDA7XG4gICAgY29uc3QgbGFzdFllYXIgPSBjdXJyZW50WWVhciArIDEwMDtcbiAgICBjb25zdCB5ZWFycyA9IFtdO1xuXG4gICAgZm9yIChsZXQgaSA9IGZpcnN0WWVhcjsgaSA8PSBsYXN0WWVhcjsgaSsrKSB7XG4gICAgICB5ZWFycy5wdXNoKGkpO1xuICAgIH1cblxuICAgIHJldHVybiB5ZWFycztcbiAgfVxuXG4gIGZpbGxXZWVrcyhtb250aDogbnVtYmVyLCB5ZWFyOiBudW1iZXIpIHtcbiAgICB0aGlzLnNlbGVjdGVkTW9udGggPSB7XG4gICAgICBsYWJlbDogdGhpcy5tb250aExhYmVsc1ttb250aF0sXG4gICAgICBudW1iZXI6IG1vbnRoLFxuICAgICAgeWVhcjogeWVhclxuICAgIH07XG5cbiAgICBjb25zdCBmaW5hbE1vbnRoRGF5ID0gdGhpcy5jcmVhdGVEYXRlT2JqZWN0KDAsIG1vbnRoLCB5ZWFyKTtcbiAgICBjb25zdCB3ZWVrcyA9IFtdO1xuXG4gICAgbGV0IGluaXRNb250aERhdGUgPSBuZXcgRGF0ZSh5ZWFyLCBtb250aCwgMSk7XG4gICAgbGV0IGRheSA9IDAgLSBpbml0TW9udGhEYXRlLmdldERheSgpO1xuICAgIGxldCBkYXlzSW5XZWVrID0gW107XG5cbiAgICB3aGlsZSAoaW5pdE1vbnRoRGF0ZS5nZXREYXkoKSAhPT0gMCB8fCBmaW5hbE1vbnRoRGF5ID49IGluaXRNb250aERhdGUpIHtcbiAgICAgICsrZGF5O1xuXG4gICAgICBpbml0TW9udGhEYXRlID0gbmV3IERhdGUoeWVhciwgbW9udGgsIGRheSk7XG5cbiAgICAgIGRheXNJbldlZWsucHVzaCh0aGlzLmNyZWF0ZURheURhdGUoaW5pdE1vbnRoRGF0ZSwgZGF5LCBmaW5hbE1vbnRoRGF5KSk7XG5cbiAgICAgIGlmIChkYXlzSW5XZWVrLmxlbmd0aCA9PT0gNykge1xuICAgICAgICB3ZWVrcy5wdXNoKGRheXNJbldlZWspO1xuICAgICAgICBkYXlzSW5XZWVrID0gW107XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHdlZWtzO1xuICB9XG5cbiAgaXNUb2RheURhdGUoZGF0ZTogRGF0ZSkge1xuICAgIGNvbnN0IElTT0N1cnJlbnREYXRlID0gdGhpcy5nZW5lcmF0ZUlTT0RhdGUobmV3IERhdGUoKSk7XG4gICAgY29uc3QgSVNPRGF0ZSA9IHRoaXMuZ2VuZXJhdGVJU09EYXRlKGRhdGUpO1xuICAgIGNvbnN0IGlzVG9kYXkgPSAoSVNPRGF0ZSA9PT0gSVNPQ3VycmVudERhdGUpO1xuXG4gICAgcmV0dXJuIGlzVG9kYXk7XG4gIH1cblxuICBjcmVhdGVEYXlEYXRlKGRhdGU6IERhdGUsIGRheU51bWJlcjogbnVtYmVyLCBmaW5hbE1vbnRoRGF5OiBEYXRlKTogRGF0ZU1vZGVsIHtcbiAgICBjb25zdCBpc1RvZGF5ID0gdGhpcy5pc1RvZGF5RGF0ZShkYXRlKTtcbiAgICBjb25zdCBpc091dE9mTW9udGggPSAoZGF5TnVtYmVyIDw9IDAgfHwgZGF0ZSA+IGZpbmFsTW9udGhEYXkpO1xuXG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlRGF0ZU1vZGVsKGRhdGUsIGlzT3V0T2ZNb250aCwgaXNUb2RheSwgdHJ1ZSk7XG4gIH1cblxuICBzaG93UHJldk1vbnRoKCkge1xuICAgIGNvbnN0IG1vbnRoID0gdGhpcy5zZWxlY3RlZE1vbnRoLm51bWJlcjtcbiAgICBjb25zdCB5ZWFyID0gdGhpcy5zZWxlY3RlZE1vbnRoLnllYXI7XG5cbiAgICBjb25zdCBwcmV2TW9udGggPSBtb250aCA+PSAxXG4gICAgICA/IG1vbnRoIC0gMVxuICAgICAgOiAxMTtcblxuICAgIGNvbnN0IHByZXZZZWFyID0gbW9udGggPCAxXG4gICAgICA/IHllYXIgLSAxXG4gICAgICA6IHllYXI7XG5cbiAgICB0aGlzLndlZWtzID0gdGhpcy5maWxsV2Vla3MocHJldk1vbnRoLCBwcmV2WWVhcik7XG4gIH1cblxuICBzaG93TmV4dE1vbnRoKCkge1xuICAgIGNvbnN0IG1vbnRoID0gdGhpcy5zZWxlY3RlZE1vbnRoLm51bWJlcjtcbiAgICBjb25zdCB5ZWFyID0gdGhpcy5zZWxlY3RlZE1vbnRoLnllYXI7XG5cbiAgICBjb25zdCBuZXh0TW9udGggPSBtb250aCA8IDExXG4gICAgICA/IG1vbnRoICsgMVxuICAgICAgOiAwO1xuXG4gICAgY29uc3QgbmV4dFllYXIgPSBtb250aCA+PSAxMVxuICAgICAgPyB5ZWFyICsgMVxuICAgICAgOiB5ZWFyO1xuXG4gICAgdGhpcy53ZWVrcyA9IHRoaXMuZmlsbFdlZWtzKG5leHRNb250aCwgbmV4dFllYXIpO1xuICB9XG5cbiAgZ2VuZXJhdGVJU09EYXRlKGRhdGU6IERhdGUpIHtcbiAgICBjb25zdCBkYXkgPSBkYXRlLmdldERhdGUoKTtcbiAgICBjb25zdCBtb250aCA9IGRhdGUuZ2V0TW9udGgoKSArIDE7XG4gICAgY29uc3QgeWVhciA9IGRhdGUuZ2V0RnVsbFllYXIoKTtcblxuICAgIGNvbnN0IGRheVN0cmluZyA9IGRheSA+IDlcbiAgICAgID8gZGF5XG4gICAgICA6IGAwJHsgZGF5IH1gO1xuXG4gICAgY29uc3QgbW9udGhTdHJpbmcgPSBtb250aCA+IDlcbiAgICAgID8gbW9udGhcbiAgICAgIDogYDAkeyBtb250aCB9YDtcblxuICAgIHJldHVybiBgJHsgeWVhciB9LSR7IG1vbnRoU3RyaW5nIH0tJHsgZGF5U3RyaW5nIH1gO1xuICB9XG5cbiAgb25TZWxlY3REYXkoZGF0ZTogRGF0ZU1vZGVsKSB7XG4gICAgaWYgKGRhdGUuaXNPdXRPZk1vbnRoKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zZWxlY3RlZERhdGUgPSBkYXRlO1xuICAgIHRoaXMub25TZWxlY3REYXlFbWl0dGVyLmVtaXQodGhpcy5zZWxlY3RlZERhdGUpO1xuICB9XG5cbiAgb25TZWxlY3RZZWFyKHllYXI6IG51bWJlcikge1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgY29uc3QgZGF5ID0gdGhpcy5zZWxlY3RlZERhdGUuZGF0ZS5nZXREYXRlKCk7XG4gICAgICBjb25zdCBtb250aCA9IHRoaXMuc2VsZWN0ZWREYXRlLmRhdGUuZ2V0TW9udGgoKTtcblxuICAgICAgdGhpcy5kYXRlID0gdGhpcy5jcmVhdGVEYXRlT2JqZWN0KGRheSwgbW9udGgsIHllYXIpO1xuICAgICAgdGhpcy5zaG93WWVhcnMgPSBmYWxzZTtcbiAgICAgIHRoaXMuc2VsZWN0ZWREYXRlID0gdGhpcy5jcmVhdGVEYXRlTW9kZWwodGhpcy5kYXRlLCBmYWxzZSwgdHJ1ZSwgdHJ1ZSk7XG5cbiAgICAgIHRoaXMud2Vla3MgPSB0aGlzLmZpbGxXZWVrcyhtb250aCwgeWVhcik7XG4gICAgfSwgdGhpcy5zZWxlY3RZZWFyQW5pbWF0aW9uRHVyYXRpb24pO1xuICB9XG5cbiAgZGlzcGxheVllYXJzKCkge1xuICAgIHRoaXMuc2hvd1llYXJzID0gdHJ1ZTtcblxuICAgIHNldFRpbWVvdXQodGhpcy5zY3JvbGxUb0FjdGl2ZVllYXIsIDApO1xuICB9XG5cbiAgc2Nyb2xsVG9BY3RpdmVZZWFyKCkge1xuICAgIGNvbnN0IHsgbmF0aXZlRWxlbWVudCB9ID0gdGhpcy55ZWFyc0NvbnRhaW5lclJlZjtcbiAgICBjb25zdCBhY3RpdmVZZWFyOiBIVE1MRWxlbWVudCA9IG5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignLnNlbGVjdGVkJyk7XG5cbiAgICBpZiAoYWN0aXZlWWVhcikge1xuICAgICAgY29uc3QgdG9wID0gdGhpcy5nZXRTY3JvbGxDZW50ZXIobmF0aXZlRWxlbWVudCwgYWN0aXZlWWVhcik7XG5cbiAgICAgIG5hdGl2ZUVsZW1lbnQuc2Nyb2xsVG9wID0gdG9wO1xuICAgIH1cbiAgfVxuXG4gIGdldFNjcm9sbENlbnRlcihjb250YWluZXI6IEhUTUxFbGVtZW50LCBpbnRlcm5hbEVsZW1lbnQ6IEhUTUxFbGVtZW50KTogbnVtYmVyIHtcbiAgICBjb25zdCB5ZWFyVG9wID0gaW50ZXJuYWxFbGVtZW50Lm9mZnNldFRvcDtcbiAgICBjb25zdCB5ZWFyTWlkZGxlSGVpZ2h0ID0gaW50ZXJuYWxFbGVtZW50Lm9mZnNldEhlaWdodCAvIDI7XG5cbiAgICBjb25zdCBjb250YWluZXJUb3AgPSBjb250YWluZXIub2Zmc2V0VG9wO1xuICAgIGNvbnN0IGNvbnRhaW5lck1pZGRsZUhlaWdodCA9IGNvbnRhaW5lci5vZmZzZXRIZWlnaHQgLyAyO1xuXG4gICAgY29uc3QgZWxlbWVudFJlbGF0aXZlVG9wID0gKHllYXJUb3AgLSBjb250YWluZXJUb3ApIC0gKGNvbnRhaW5lck1pZGRsZUhlaWdodCAtIHllYXJNaWRkbGVIZWlnaHQpO1xuXG4gICAgaWYgKGVsZW1lbnRSZWxhdGl2ZVRvcCA8IDApIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cblxuICAgIHJldHVybiBlbGVtZW50UmVsYXRpdmVUb3A7XG4gIH1cbn1cbiJdfQ==