UNPKG

ng2-datepicker

Version:

ng2-datepicker is simple and minimal Angular datepicker component. It is fully customizable.

253 lines 41.6 kB
import { Component, Input, HostListener, ElementRef, EventEmitter, Inject, ChangeDetectorRef } from '@angular/core'; import { DOCUMENT } from '@angular/common'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { SlimScrollOptions, SlimScrollEvent } from 'ngx-slimscroll'; import { mergeDatepickerOptions, defaultOptions } from './datepicker-options.interface'; import { eachDayOfInterval, startOfMonth, endOfMonth, getDate, getMonth, getYear, isToday, isSameDay, isSameMonth, isSameYear, isBefore, isAfter, getDay, subDays, setDay, format, addMonths, subMonths, setYear, addYears, subYears } from 'date-fns'; import { fromEvent, Subscription } from 'rxjs'; import { filter } from 'rxjs/operators'; export class DatepickerComponent { constructor(elementRef, ref, document) { this.elementRef = elementRef; this.ref = ref; this.options = Object.assign({}, defaultOptions); this.scrollOptions = new SlimScrollOptions(this.scrollBarOptions); this.isOpened = false; this.innerValue = new Date(); this.displayValue = ''; this.view = 'days'; this.date = new Date(); this.years = []; this.days = []; this.dayNames = []; this.scrollEvents = new EventEmitter(); this.sub = new Subscription(); this.onTouchedCallback = () => { }; this.onChangeCallback = () => { }; this.doc = document; } get value() { return this.innerValue; } set value(val) { this.innerValue = val; this.displayValue = format(this.innerValue, this.options.format, { locale: this.options.locale }); this.onChangeCallback(this.innerValue); } get title() { return format(this.date, this.options.formatTitle); } get scrollBarOptions() { return { barBackground: (this.options && this.options.scrollBarColor) || '#dfe3e9', gridBackground: 'transparent', barBorderRadius: '3', gridBorderRadius: '3', barWidth: '6', gridWidth: '6', barMargin: '0', gridMargin: '0' }; } ngOnInit() { this.view = 'days'; this.date = new Date(); this.init(); } ngOnChanges(changes) { if ('options' in changes) { this.options = mergeDatepickerOptions(this.options); this.scrollOptions = new SlimScrollOptions(this.scrollBarOptions); if (this.sub) { this.sub.unsubscribe(); } if (this.options.enableKeyboard) { this.sub = fromEvent(this.doc || document, 'keyup') .pipe(filter(() => this.isOpened)) .subscribe(e => { e.preventDefault(); e.stopPropagation(); switch (e.key) { case 'Down': case 'ArrowDown': this.prevYear(); break; case 'Up': case 'ArrowUp': this.nextYear(); break; case 'Left': case 'ArrowLeft': this.prevMonth(); break; case 'Right': case 'ArrowRight': this.nextMonth(); break; case 'Esc': case 'Escape': case 'Enter': this.isOpened = false; break; default: return; } }); } } } ngOnDestroy() { this.sub.unsubscribe(); } toggle() { this.isOpened = !this.isOpened; if (this.isOpened) { this.view = 'days'; this.date = this.value; this.initDays(); } } toggleView() { this.view = this.view === 'days' ? 'years' : 'days'; if (this.view === 'years') { this.ref.detectChanges(); this.scrollToYear(); } } nextMonth() { this.date = addMonths(this.date, 1); this.initDays(); } prevMonth() { this.date = subMonths(this.date, 1); this.initDays(); } nextYear() { this.date = addYears(this.date, 1); this.initDays(); } prevYear() { this.date = subYears(this.date, 1); this.initDays(); } setDate(i) { this.date = this.days[i].date; this.value = this.date; this.initDays(); this.isOpened = false; } setYear(i) { this.date = setYear(this.date, this.years[i].year); this.initDays(); this.initYears(); this.view = 'days'; } scrollToYear() { const parent = this.elementRef.nativeElement.querySelector('.main-calendar-years'); const el = this.elementRef.nativeElement.querySelector('.year-unit.is-selected'); const y = el.offsetTop - parent.clientHeight / 2 + el.clientHeight / 2; const event = new SlimScrollEvent({ type: 'scrollTo', y, duration: 100 }); this.scrollEvents.emit(event); } init() { this.initDayNames(); this.initDays(); this.initYears(); } initDays() { const date = this.date || new Date(); const [start, end] = [startOfMonth(date), endOfMonth(date)]; this.days = eachDayOfInterval({ start, end }).map((d) => this.generateDay(d)); const tmp = getDay(start) - this.options.firstCalendarDay; const prevDays = tmp < 0 ? 7 - this.options.firstCalendarDay : tmp; for (let i = 1; i <= prevDays; i++) { const d = subDays(start, i); this.days.unshift(this.generateDay(d, false)); } } initYears() { const range = this.options.maxYear - this.options.minYear + 1; this.years = Array.from(new Array(range), (_, i) => i + this.options.minYear).map(year => { return { year, isThisYear: year === getYear(this.date) }; }); } initDayNames() { this.dayNames = []; const start = this.options.firstCalendarDay; for (let i = start; i <= 6 + start; i++) { const date = setDay(new Date(), i); this.dayNames.push(format(date, this.options.formatDays, { locale: this.options.locale })); } } generateDay(date, inThisMonth = true) { return { date, day: getDate(date), month: getMonth(date), year: getYear(date), inThisMonth, isToday: isToday(date), isSelected: isSameDay(date, this.innerValue) && isSameMonth(date, this.innerValue) && isSameYear(date, this.innerValue), isSelectable: this.isDateSelectable(date) }; } isDateSelectable(date) { if (this.options.minDate && isBefore(date, this.options.minDate)) { return false; } if (this.options.maxDate && isAfter(date, this.options.maxDate)) { return false; } return true; } writeValue(val) { if (!val) { return; } this.innerValue = val; this.displayValue = format(this.innerValue, this.options.format, { locale: this.options.locale }); this.init(); } registerOnChange(fn) { this.onChangeCallback = fn; } registerOnTouched(fn) { this.onTouchedCallback = fn; } onBlur(e) { if (!this.isOpened) { return; } const input = this.elementRef.nativeElement.querySelector('.datepicker-container > input'); if (!input || e.target === input || input.contains(e.target)) { return; } const container = this.elementRef.nativeElement.querySelector('.datepicker-container > .calendar-container'); if (container && container !== e.target && !container.contains(e.target) && !e.target.classList.contains('year-unit')) { this.isOpened = false; } } } DatepickerComponent.decorators = [ { type: Component, args: [{ selector: 'ngx-datepicker', template: "<div class=\"datepicker-container\" [class]=\"options.calendarClass\">\n <input\n type=\"text\"\n [(ngModel)]=\"displayValue\"\n [class]=\"options.inputClass\"\n [placeholder]=\"options.placeholder\"\n readonly\n (click)=\"toggle()\"\n />\n\n <div class=\"calendar-container\" *ngIf=\"isOpened\">\n <div class=\"top-container\">\n <div class=\"month-year-container\">\n <span class=\"month-year-text\">\n <span (click)=\"toggleView()\">{{ title }}</span>\n </span>\n </div>\n <div class=\"controls\">\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"control prev-month\"\n width=\"8\"\n height=\"13\"\n (click)=\"prevMonth()\"\n *ngIf=\"view === 'days'\"\n >\n <path\n d=\"M7.575 1.131a1.063 1.063 0 00-1.502 0l-4.93 4.93c-.42.42-.42 1.099 0 1.518l4.93 4.93a1.063 1.063 0 001.503-1.503L3.388 6.82l4.186-4.186a1.063 1.063 0 000-1.503z\"\n />\n </svg>\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n class=\"control next-month\"\n width=\"8\"\n height=\"13\"\n (click)=\"nextMonth()\"\n *ngIf=\"view === 'days'\"\n >\n <path\n d=\"M1.14 1.131a1.063 1.063 0 011.502 0l4.93 4.93c.42.42.42 1.099 0 1.518l-4.93 4.93a1.063 1.063 0 01-1.503-1.503L5.327 6.82 1.14 2.634a1.063 1.063 0 010-1.503z\"\n />\n </svg>\n </div>\n </div>\n <div class=\"main-calendar-container is-days\" *ngIf=\"view === 'days'\">\n <div class=\"main-calendar-day-names\">\n <span class=\"day-name-unit\" *ngFor=\"let day of dayNames\">{{ day }}</span>\n </div>\n <div class=\"main-calendar-days\">\n <span\n class=\"day-unit\"\n *ngFor=\"let day of days; let i = index\"\n [ngClass]=\"{\n 'is-prev-month': !day.inThisMonth,\n 'is-today': day.isToday,\n 'is-selected': day.isSelected,\n 'is-disabled': !day.isSelectable\n }\"\n (click)=\"day.isSelectable && setDate(i)\"\n >{{ day.day }}</span\n >\n </div>\n </div>\n <div class=\"main-calendar-container is-years\" *ngIf=\"view === 'years'\">\n <div class=\"main-calendar-years\" slimScroll [options]=\"scrollOptions\" [scrollEvents]=\"scrollEvents\">\n <span\n class=\"year-unit\"\n *ngFor=\"let year of years; let i = index\"\n [ngClass]=\"{ 'is-selected': year.isThisYear }\"\n (click)=\"setYear(i)\"\n >{{ year.year }}</span\n >\n </div>\n </div>\n </div>\n</div>\n", providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: DatepickerComponent, multi: true }], styles: [".datepicker-container{position:relative;display:inline-block;box-sizing:border-box}.datepicker-container *{box-sizing:inherit}.datepicker-container input{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;cursor:pointer}.datepicker-container .is-hidden{display:none!important}.datepicker-container .calendar-container{position:absolute;width:320px;border-radius:4px;top:35px;left:0;z-index:10}.datepicker-container .calendar-container .top-container{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:100%;padding:20px;display:flex;justify-content:space-between;align-items:center}.datepicker-container .calendar-container .top-container .month-year-container{height:100%;display:flex;align-items:center;cursor:pointer;position:relative}.datepicker-container .calendar-container .top-container .month-year-container .month-year-text{font-size:16px;width:100%}.datepicker-container .calendar-container .top-container .controls{height:100%;display:flex;justify-content:flex-end;align-items:center}.datepicker-container .calendar-container .top-container .controls .control{cursor:pointer;margin-left:20px}.datepicker-container .calendar-container .main-calendar-container{width:100%;height:100%;font-size:12px;display:block}.datepicker-container .calendar-container .main-calendar-container .main-calendar-day-names{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;display:flex;align-items:center;height:35px;padding:0 10px}.datepicker-container .calendar-container .main-calendar-container .main-calendar-day-names .day-name-unit{width:calc(100% / 7);text-transform:uppercase;text-align:center}.datepicker-container .calendar-container .main-calendar-container .main-calendar-days,.datepicker-container .calendar-container .main-calendar-container .main-calendar-years{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;padding:10px;width:100%;overflow:hidden;text-align:left;display:inline-block}.datepicker-container .calendar-container .main-calendar-container .main-calendar-days.is-hidden,.datepicker-container .calendar-container .main-calendar-container .main-calendar-years.is-hidden{display:none}.datepicker-container .calendar-container .main-calendar-container .main-calendar-days .day-unit,.datepicker-container .calendar-container .main-calendar-container .main-calendar-days .year-unit,.datepicker-container .calendar-container .main-calendar-container .main-calendar-years .day-unit,.datepicker-container .calendar-container .main-calendar-container .main-calendar-years .year-unit{width:calc(100% / 7);display:inline-flex;align-items:center;justify-content:center;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;font-size:13px;border-radius:50%}.datepicker-container .calendar-container .main-calendar-container .main-calendar-days .day-unit:before,.datepicker-container .calendar-container .main-calendar-container .main-calendar-days .year-unit:before,.datepicker-container .calendar-container .main-calendar-container .main-calendar-years .day-unit:before,.datepicker-container .calendar-container .main-calendar-container .main-calendar-years .year-unit:before{content:\"\";float:left;padding-top:calc(100% - 5px)}.datepicker-container .calendar-container .main-calendar-container .main-calendar-days .day-unit.is-disabled,.datepicker-container .calendar-container .main-calendar-container .main-calendar-days .year-unit.is-disabled,.datepicker-container .calendar-container .main-calendar-container .main-calendar-years .day-unit.is-disabled,.datepicker-container .calendar-container .main-calendar-container .main-calendar-years .year-unit.is-disabled{cursor:not-allowed}.datepicker-container .calendar-container .main-calendar-container .main-calendar-days .day-unit.is-disabled:hover,.datepicker-container .calendar-container .main-calendar-container .main-calendar-days .year-unit.is-disabled:hover,.datepicker-container .calendar-container .main-calendar-container .main-calendar-years .day-unit.is-disabled:hover,.datepicker-container .calendar-container .main-calendar-container .main-calendar-years .year-unit.is-disabled:hover{background:transparent}.datepicker-container .calendar-container .main-calendar-container .main-calendar-years{display:block;padding:10px;height:275px}.datepicker-container .calendar-container .main-calendar-container .main-calendar-years .year-unit{width:calc(100% / 4);height:35px;border-radius:20px;margin:8px 0}.datepicker-container .calendar-container .main-calendar-container .main-calendar-years .year-unit:before{padding-top:0}.datepicker-default .calendar-container{background:#fff;border:1px solid #eaedf3;box-shadow:0 4px 12px rgba(0,0,0,.05);top:35px;left:0;font-weight:600}.datepicker-default .month-year-text{color:#010001}.datepicker-default .control path{fill:#aaa8ab}.datepicker-default .control:hover path{fill:#010001}.datepicker-default .main-calendar-day-names{border-bottom:1px solid #eaedf3}.datepicker-default .day-name-unit{color:#aaa8ab}.datepicker-default .day-unit,.datepicker-default .year-unit{color:#010001}.datepicker-default .day-unit.is-prev-month,.datepicker-default .year-unit.is-prev-month{color:#bbbabe}.datepicker-default .day-unit.is-today,.datepicker-default .year-unit.is-today{background:#edeef2}.datepicker-default .day-unit.is-selected,.datepicker-default .day-unit:hover,.datepicker-default .year-unit.is-selected,.datepicker-default .year-unit:hover{background:#010001;color:#fff}.datepicker-default .day-unit.is-disabled,.datepicker-default .year-unit.is-disabled{color:#aaa8ab}.datepicker-default .day-unit.is-disabled:hover,.datepicker-default .year-unit.is-disabled:hover{background:transparent}"] },] } ]; DatepickerComponent.ctorParameters = () => [ { type: ElementRef }, { type: ChangeDetectorRef }, { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] } ]; DatepickerComponent.propDecorators = { options: [{ type: Input }], scrollOptions: [{ type: Input }], isOpened: [{ type: Input }], onBlur: [{ type: HostListener, args: ['document:click', ['$event'],] }] }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZXBpY2tlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9kYXRlcGlja2VyL3NyYy9saWIvZGF0ZXBpY2tlci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFNBQVMsRUFFVCxLQUFLLEVBR0wsWUFBWSxFQUNaLFVBQVUsRUFDVixZQUFZLEVBRVosTUFBTSxFQUNOLGlCQUFpQixFQUNsQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUFFLGlCQUFpQixFQUF3QixNQUFNLGdCQUFnQixDQUFDO0FBQ3pFLE9BQU8sRUFBd0MsaUJBQWlCLEVBQUUsZUFBZSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDMUcsT0FBTyxFQUFxQixzQkFBc0IsRUFBRSxjQUFjLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUMzRyxPQUFPLEVBQ0wsaUJBQWlCLEVBQ2pCLFlBQVksRUFDWixVQUFVLEVBQ1YsT0FBTyxFQUNQLFFBQVEsRUFDUixPQUFPLEVBQ1AsT0FBTyxFQUNQLFNBQVMsRUFDVCxXQUFXLEVBQ1gsVUFBVSxFQUNWLFFBQVEsRUFDUixPQUFPLEVBQ1AsTUFBTSxFQUNOLE9BQU8sRUFDUCxNQUFNLEVBQ04sTUFBTSxFQUNOLFNBQVMsRUFDVCxTQUFTLEVBQ1QsT0FBTyxFQUNQLFFBQVEsRUFDUixRQUFRLEVBQ1QsTUFBTSxVQUFVLENBQUM7QUFDbEIsT0FBTyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDL0MsT0FBTyxFQUFFLE1BQU0sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBbUJ4QyxNQUFNLE9BQU8sbUJBQW1CO0lBMEI5QixZQUFtQixVQUFzQixFQUFVLEdBQXNCLEVBQW9CLFFBQWM7UUFBeEYsZUFBVSxHQUFWLFVBQVUsQ0FBWTtRQUFV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T0FBTztTQUNSO1FBRUQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLCtCQUErQixDQUFDLENBQUM7UUFDM0YsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsTUFBTSxLQUFLLEtBQUssSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsRUFBRTtZQUM1RCxPQUFPO1NBQ1I7UUFFRCxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsNkNBQTZDLENBQUMsQ0FBQztRQUM3RyxJQUNFLFNBQVM7WUFDVCxTQUFTLEtBQUssQ0FBQyxDQUFDLE1BQU07WUFDdEIsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUM7WUFDN0IsQ0FBRSxDQUFDLENBQUMsTUFBc0IsQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxFQUMxRDtZQUNBLElBQUksQ0FBQyxRQUFRLEdBQUcsS0FBSyxDQUFDO1NBQ3ZCO0lBQ0gsQ0FBQzs7O1lBN1FGLFNBQVMsU0FBQztnQkFDVCxRQUFRLEVBQUUsZ0JBQWdCO2dCQUMxQiwrb0ZBQTBDO2dCQUUxQyxTQUFTLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxXQUFXLEVBQUUsbUJBQW1CLEVBQUUsS0FBSyxFQUFFLElBQUksRUFBRSxDQUFDOzthQUMzRjs7O1lBcERDLFVBQVU7WUFJVixpQkFBaUI7NENBMkUyRCxNQUFNLFNBQUMsUUFBUTs7O3NCQXpCMUYsS0FBSzs0QkFDTCxLQUFLO3VCQUNMLEtBQUs7cUJBaVBMLFlBQVksU0FBQyxnQkFBZ0IsRUFBRSxDQUFDLFFBQVEsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgT25Jbml0LFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBTaW1wbGVDaGFuZ2VzLFxuICBIb3N0TGlzdGVuZXIsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgT25EZXN0cm95LFxuICBJbmplY3QsXG4gIENoYW5nZURldGVjdG9yUmVmXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgTkdfVkFMVUVfQUNDRVNTT1IsIENvbnRyb2xWYWx1ZUFjY2Vzc29yIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgSVNsaW1TY3JvbGxFdmVudCwgSVNsaW1TY3JvbGxPcHRpb25zLCBTbGltU2Nyb2xsT3B0aW9ucywgU2xpbVNjcm9sbEV2ZW50IH0gZnJvbSAnbmd4LXNsaW1zY3JvbGwnO1xuaW1wb3J0IHsgRGF0ZXBpY2tlck9wdGlvbnMsIG1lcmdlRGF0ZXBpY2tlck9wdGlvbnMsIGRlZmF1bHRPcHRpb25zIH0gZnJvbSAnLi9kYXRlcGlja2VyLW9wdGlvbnMuaW50ZXJmYWNlJztcbmltcG9ydCB7XG4gIGVhY2hEYXlPZkludGVydmFsLFxuICBzdGFydE9mTW9udGgsXG4gIGVuZE9mTW9udGgsXG4gIGdldERhdGUsXG4gIGdldE1vbnRoLFxuICBnZXRZZWFyLFxuICBpc1RvZGF5LFxuICBpc1NhbWVEYXksXG4gIGlzU2FtZU1vbnRoLFxuICBpc1NhbWVZZWFyLFxuICBpc0JlZm9yZSxcbiAgaXNBZnRlcixcbiAgZ2V0RGF5LFxuICBzdWJEYXlzLFxuICBzZXREYXksXG4gIGZvcm1hdCxcbiAgYWRkTW9udGhzLFxuICBzdWJNb250aHMsXG4gIHNldFllYXIsXG4gIGFkZFllYXJzLFxuICBzdWJZZWFyc1xufSBmcm9tICdkYXRlLWZucyc7XG5pbXBvcnQgeyBmcm9tRXZlbnQsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZmlsdGVyIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbnRlcmZhY2UgRGF5IHtcbiAgZGF0ZTogRGF0ZTtcbiAgZGF5OiBudW1iZXI7XG4gIG1vbnRoOiBudW1iZXI7XG4gIHllYXI6IG51bWJlcjtcbiAgaW5UaGlzTW9udGg6IGJvb2xlYW47XG4gIGlzVG9kYXk6IGJvb2xlYW47XG4gIGlzU2VsZWN0ZWQ6IGJvb2xlYW47XG4gIGlzU2VsZWN0YWJsZTogYm9vbGVhbjtcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmd4LWRhdGVwaWNrZXInLFxuICB0ZW1wbGF0ZVVybDogJy4vZGF0ZXBpY2tlci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2RhdGVwaWNrZXIuY29tcG9uZW50LnNhc3MnXSxcbiAgcHJvdmlkZXJzOiBbeyBwcm92aWRlOiBOR19WQUxVRV9BQ0NFU1NPUiwgdXNlRXhpc3Rpbmc6IERhdGVwaWNrZXJDb21wb25lbnQsIG11bHRpOiB0cnVlIH1dXG59KVxuZXhwb3J0IGNsYXNzIERhdGVwaWNrZXJDb21wb25lbnQgaW1wbGVtZW50cyBDb250cm9sVmFsdWVBY2Nlc3NvciwgT25Jbml0LCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG4gIEBJbnB1dCgpIG9wdGlvbnM6IERhdGVwaWNrZXJPcHRpb25zID0geyAuLi5kZWZhdWx0T3B0aW9ucyB9O1xuICBASW5wdXQoKSBzY3JvbGxPcHRpb25zOiBTbGltU2Nyb2xsT3B0aW9ucyA9IG5ldyBTbGltU2Nyb2xsT3B0aW9ucyh0aGlzLnNjcm9sbEJhck9wdGlvbnMpO1xuICBASW5wdXQoKSBpc09wZW5lZCA9IGZhbHNlO1xuXG4gIGlubmVyVmFsdWU6IERhdGUgPSBuZXcgRGF0ZSgpO1xuICBkaXNwbGF5VmFsdWUgPSAnJztcbiAgdmlldzogJ2RheXMnIHwgJ3llYXJzJyA9ICdkYXlzJztcbiAgZGF0ZTogRGF0ZSA9IG5ldyBEYXRlKCk7XG4gIHllYXJzOiB7IHllYXI6IG51bWJlcjsgaXNUaGlzWWVhcjogYm9vbGVhbiB9W10gPSBbXTtcbiAgZGF5czogRGF5W10gPSBbXTtcbiAgZGF5TmFtZXM6IHN0cmluZ1tdID0gW107XG4gIHNjcm9sbEV2ZW50cyA9IG5ldyBFdmVudEVtaXR0ZXI8SVNsaW1TY3JvbGxFdmVudD4oKTtcbiAgc3ViOiBTdWJzY3JpcHRpb24gPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG4gIHByaXZhdGUgZG9jPzogRG9jdW1lbnQ7XG5cbiAgZ2V0IHZhbHVlKCk6IERhdGUge1xuICAgIHJldHVybiB0aGlzLmlubmVyVmFsdWU7XG4gIH1cblxuICBzZXQgdmFsdWUodmFsOiBEYXRlKSB7XG4gICAgdGhpcy5pbm5lclZhbHVlID0gdmFsO1xuICAgIHRoaXMuZGlzcGxheVZhbHVlID0gZm9ybWF0KHRoaXMuaW5uZXJWYWx1ZSwgdGhpcy5vcHRpb25zLmZvcm1hdCBhcyBzdHJpbmcsIHsgbG9jYWxlOiB0aGlzLm9wdGlvbnMubG9jYWxlIH0pO1xuICAgIHRoaXMub25DaGFuZ2VDYWxsYmFjayh0aGlzLmlubmVyVmFsdWUpO1xuICB9XG5cbiAgY29uc3RydWN0b3IocHVibGljIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsIHByaXZhdGUgcmVmOiBDaGFuZ2VEZXRlY3RvclJlZiwgQEluamVjdChET0NVTUVOVCkgZG9jdW1lbnQ/OiBhbnkpIHtcbiAgICB0aGlzLmRvYyA9IGRvY3VtZW50IGFzIERvY3VtZW50O1xuICB9XG5cbiAgZ2V0IHRpdGxlKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGZvcm1hdCh0aGlzLmRhdGUsIHRoaXMub3B0aW9ucy5mb3JtYXRUaXRsZSBhcyBzdHJpbmcpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQgc2Nyb2xsQmFyT3B0aW9ucygpOiBJU2xpbVNjcm9sbE9wdGlvbnMge1xuICAgIHJldHVybiB7XG4gICAgICBiYXJCYWNrZ3JvdW5kOiAodGhpcy5vcHRpb25zICYmIHRoaXMub3B0aW9ucy5zY3JvbGxCYXJDb2xvcikgfHwgJyNkZmUzZTknLFxuICAgICAgZ3JpZEJhY2tncm91bmQ6ICd0cmFuc3BhcmVudCcsXG4gICAgICBiYXJCb3JkZXJSYWRpdXM6ICczJyxcbiAgICAgIGdyaWRCb3JkZXJSYWRpdXM6ICczJyxcbiAgICAgIGJhcldpZHRoOiAnNicsXG4gICAgICBncmlkV2lkdGg6ICc2JyxcbiAgICAgIGJhck1hcmdpbjogJzAnLFxuICAgICAgZ3JpZE1hcmdpbjogJzAnXG4gICAgfTtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMudmlldyA9ICdkYXlzJztcbiAgICB0aGlzLmRhdGUgPSBuZXcgRGF0ZSgpO1xuICAgIHRoaXMuaW5pdCgpO1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGlmICgnb3B0aW9ucycgaW4gY2hhbmdlcykge1xuICAgICAgdGhpcy5vcHRpb25zID0gbWVyZ2VEYXRlcGlja2VyT3B0aW9ucyh0aGlzLm9wdGlvbnMpO1xuICAgICAgdGhpcy5zY3JvbGxPcHRpb25zID0gbmV3IFNsaW1TY3JvbGxPcHRpb25zKHRoaXMuc2Nyb2xsQmFyT3B0aW9ucyk7XG5cbiAgICAgIGlmICh0aGlzLnN1Yikge1xuICAgICAgICB0aGlzLnN1Yi51bnN1YnNjcmliZSgpO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5vcHRpb25zLmVuYWJsZUtleWJvYXJkKSB7XG4gICAgICAgIHRoaXMuc3ViID0gZnJvbUV2ZW50PEtleWJvYXJkRXZlbnQ+KHRoaXMuZG9jIHx8IGRvY3VtZW50LCAna2V5dXAnKVxuICAgICAgICAgIC5waXBlKGZpbHRlcigoKSA9PiB0aGlzLmlzT3BlbmVkKSlcbiAgICAgICAgICAuc3Vic2NyaWJlKGUgPT4ge1xuICAgICAgICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgICAgICAgICAgc3dpdGNoIChlLmtleSkge1xuICAgICAgICAgICAgICBjYXNlICdEb3duJzpcbiAgICAgICAgICAgICAgY2FzZSAnQXJyb3dEb3duJzpcbiAgICAgICAgICAgICAgICB0aGlzLnByZXZZZWFyKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgJ1VwJzpcbiAgICAgICAgICAgICAgY2FzZSAnQXJyb3dVcCc6XG4gICAgICAgICAgICAgICAgdGhpcy5uZXh0WWVhcigpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBjYXNlICdMZWZ0JzpcbiAgICAgICAgICAgICAgY2FzZSAnQXJyb3dMZWZ0JzpcbiAgICAgICAgICAgICAgICB0aGlzLnByZXZNb250aCgpO1xuICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICBjYXNlICdSaWdodCc6XG4gICAgICAgICAgICAgIGNhc2UgJ0Fycm93UmlnaHQnOlxuICAgICAgICAgICAgICAgIHRoaXMubmV4dE1vbnRoKCk7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGNhc2UgJ0VzYyc6XG4gICAgICAgICAgICAgIGNhc2UgJ0VzY2FwZSc6XG4gICAgICAgICAgICAgIGNhc2UgJ0VudGVyJzpcbiAgICAgICAgICAgICAgICB0aGlzLmlzT3BlbmVkID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuc3ViLnVuc3Vic2NyaWJlKCk7XG4gIH1cblxuICB0b2dnbGUoKTogdm9pZCB7XG4gICAgdGhpcy5pc09wZW5lZCA9ICF0aGlzLmlzT3BlbmVkO1xuICAgIGlmICh0aGlzLmlzT3BlbmVkKSB7XG4gICAgICB0aGlzLnZpZXcgPSAnZGF5cyc7XG4gICAgICB0aGlzLmRhdGUgPSB0aGlzLnZhbHVlO1xuICAgICAgdGhpcy5pbml0RGF5cygpO1xuICAgIH1cbiAgfVxuXG4gIHRvZ2dsZVZpZXcoKTogdm9pZCB7XG4gICAgdGhpcy52aWV3ID0gdGhpcy52aWV3ID09PSAnZGF5cycgPyAneWVhcnMnIDogJ2RheXMnO1xuICAgIGlmICh0aGlzLnZpZXcgPT09ICd5ZWFycycpIHtcbiAgICAgIHRoaXMucmVmLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIHRoaXMuc2Nyb2xsVG9ZZWFyKCk7XG4gICAgfVxuICB9XG5cbiAgbmV4dE1vbnRoKCk6IHZvaWQge1xuICAgIHRoaXMuZGF0ZSA9IGFkZE1vbnRocyh0aGlzLmRhdGUsIDEpO1xuICAgIHRoaXMuaW5pdERheXMoKTtcbiAgfVxuXG4gIHByZXZNb250aCgpOiB2b2lkIHtcbiAgICB0aGlzLmRhdGUgPSBzdWJNb250aHModGhpcy5kYXRlLCAxKTtcbiAgICB0aGlzLmluaXREYXlzKCk7XG4gIH1cblxuICBuZXh0WWVhcigpOiB2b2lkIHtcbiAgICB0aGlzLmRhdGUgPSBhZGRZZWFycyh0aGlzLmRhdGUsIDEpO1xuICAgIHRoaXMuaW5pdERheXMoKTtcbiAgfVxuXG4gIHByZXZZZWFyKCk6IHZvaWQge1xuICAgIHRoaXMuZGF0ZSA9IHN1YlllYXJzKHRoaXMuZGF0ZSwgMSk7XG4gICAgdGhpcy5pbml0RGF5cygpO1xuICB9XG5cbiAgc2V0RGF0ZShpOiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLmRhdGUgPSB0aGlzLmRheXNbaV0uZGF0ZTtcbiAgICB0aGlzLnZhbHVlID0gdGhpcy5kYXRlO1xuICAgIHRoaXMuaW5pdERheXMoKTtcbiAgICB0aGlzLmlzT3BlbmVkID0gZmFsc2U7XG4gIH1cblxuICBzZXRZZWFyKGk6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuZGF0ZSA9IHNldFllYXIodGhpcy5kYXRlLCB0aGlzLnllYXJzW2ldLnllYXIpO1xuICAgIHRoaXMuaW5pdERheXMoKTtcbiAgICB0aGlzLmluaXRZZWFycygpO1xuICAgIHRoaXMudmlldyA9ICdkYXlzJztcbiAgfVxuXG4gIHByaXZhdGUgc2Nyb2xsVG9ZZWFyKCk6IHZvaWQge1xuICAgIGNvbnN0IHBhcmVudCA9IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy5tYWluLWNhbGVuZGFyLXllYXJzJyk7XG4gICAgY29uc3QgZWwgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCcueWVhci11bml0LmlzLXNlbGVjdGVkJyk7XG4gICAgY29uc3QgeSA9IGVsLm9mZnNldFRvcCAtIHBhcmVudC5jbGllbnRIZWlnaHQgLyAyICsgZWwuY2xpZW50SGVpZ2h0IC8gMjtcbiAgICBjb25zdCBldmVudCA9IG5ldyBTbGltU2Nyb2xsRXZlbnQoeyB0eXBlOiAnc2Nyb2xsVG8nLCB5LCBkdXJhdGlvbjogMTAwIH0pO1xuICAgIHRoaXMuc2Nyb2xsRXZlbnRzLmVtaXQoZXZlbnQpO1xuICB9XG5cbiAgcHJpdmF0ZSBpbml0KCk6IHZvaWQge1xuICAgIHRoaXMuaW5pdERheU5hbWVzKCk7XG4gICAgdGhpcy5pbml0RGF5cygpO1xuICAgIHRoaXMuaW5pdFllYXJzKCk7XG4gIH1cblxuICBwcml2YXRlIGluaXREYXlzKCk6IHZvaWQge1xuICAgIGNvbnN0IGRhdGUgPSB0aGlzLmRhdGUgfHwgbmV3IERhdGUoKTtcbiAgICBjb25zdCBbc3RhcnQsIGVuZF0gPSBbc3RhcnRPZk1vbnRoKGRhdGUpLCBlbmRPZk1vbnRoKGRhdGUpXTtcblxuICAgIHRoaXMuZGF5cyA9IGVhY2hEYXlPZkludGVydmFsKHsgc3RhcnQsIGVuZCB9KS5tYXAoKGQ6IERhdGUpID0+IHRoaXMuZ2VuZXJhdGVEYXkoZCkpO1xuXG4gICAgY29uc3QgdG1wID0gZ2V0RGF5KHN0YXJ0KSAtICh0aGlzLm9wdGlvbnMuZmlyc3RDYWxlbmRhckRheSBhcyBudW1iZXIpO1xuICAgIGNvbnN0IHByZXZEYXlzID0gdG1wIDwgMCA/IDcgLSAodGhpcy5vcHRpb25zLmZpcnN0Q2FsZW5kYXJEYXkgYXMgbnVtYmVyKSA6IHRtcDtcbiAgICBmb3IgKGxldCBpID0gMTsgaSA8PSBwcmV2RGF5czsgaSsrKSB7XG4gICAgICBjb25zdCBkID0gc3ViRGF5cyhzdGFydCwgaSk7XG4gICAgICB0aGlzLmRheXMudW5zaGlmdCh0aGlzLmdlbmVyYXRlRGF5KGQsIGZhbHNlKSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBpbml0WWVhcnMoKTogdm9pZCB7XG4gICAgY29uc3QgcmFuZ2UgPSAodGhpcy5vcHRpb25zLm1heFllYXIgYXMgbnVtYmVyKSAtICh0aGlzLm9wdGlvbnMubWluWWVhciBhcyBudW1iZXIpICsgMTtcbiAgICB0aGlzLnllYXJzID0gQXJyYXkuZnJvbShuZXcgQXJyYXkocmFuZ2UpLCAoXywgaSkgPT4gaSArICh0aGlzLm9wdGlvbnMubWluWWVhciBhcyBudW1iZXIpKS5tYXAoeWVhciA9PiB7XG4gICAgICByZXR1cm4geyB5ZWFyLCBpc1RoaXNZZWFyOiB5ZWFyID09PSBnZXRZZWFyKHRoaXMuZGF0ZSkgfTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgaW5pdERheU5hbWVzKCk6IHZvaWQge1xuICAgIHRoaXMuZGF5TmFtZXMgPSBbXTtcbiAgICBjb25zdCBzdGFydCA9IHRoaXMub3B0aW9ucy5maXJzdENhbGVuZGFyRGF5IGFzIG51bWJlcjtcbiAgICBmb3IgKGxldCBpID0gc3RhcnQ7IGkgPD0gNiArIHN0YXJ0OyBpKyspIHtcbiAgICAgIGNvbnN0IGRhdGUgPSBzZXREYXkobmV3IERhdGUoKSwgaSk7XG4gICAgICB0aGlzLmRheU5hbWVzLnB1c2goZm9ybWF0KGRhdGUsIHRoaXMub3B0aW9ucy5mb3JtYXREYXlzIGFzIHN0cmluZywgeyBsb2NhbGU6IHRoaXMub3B0aW9ucy5sb2NhbGUgfSkpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2VuZXJhdGVEYXkoZGF0ZTogRGF0ZSwgaW5UaGlzTW9udGg6IGJvb2xlYW4gPSB0cnVlKTogRGF5IHtcbiAgICByZXR1cm4ge1xuICAgICAgZGF0ZSxcbiAgICAgIGRheTogZ2V0RGF0ZShkYXRlKSxcbiAgICAgIG1vbnRoOiBnZXRNb250aChkYXRlKSxcbiAgICAgIHllYXI6IGdldFllYXIoZGF0ZSksXG4gICAgICBpblRoaXNNb250aCxcbiAgICAgIGlzVG9kYXk6IGlzVG9kYXkoZGF0ZSksXG4gICAgICBpc1NlbGVjdGVkOlxuICAgICAgICBpc1NhbWVEYXkoZGF0ZSwgdGhpcy5pbm5lclZhbHVlKSAmJiBpc1NhbWVNb250aChkYXRlLCB0aGlzLmlubmVyVmFsdWUpICYmIGlzU2FtZVllYXIoZGF0ZSwgdGhpcy5pbm5lclZhbHVlKSxcbiAgICAgIGlzU2VsZWN0YWJsZTogdGhpcy5pc0RhdGVTZWxlY3RhYmxlKGRhdGUpXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgaXNEYXRlU2VsZWN0YWJsZShkYXRlOiBEYXRlKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMub3B0aW9ucy5taW5EYXRlICYmIGlzQmVmb3JlKGRhdGUsIHRoaXMub3B0aW9ucy5taW5EYXRlKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm9wdGlvbnMubWF4RGF0ZSAmJiBpc0FmdGVyKGRhdGUsIHRoaXMub3B0aW9ucy5tYXhEYXRlKSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgd3JpdGVWYWx1ZSh2YWw6IERhdGUpOiB2b2lkIHtcbiAgICBpZiAoIXZhbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmlubmVyVmFsdWUgPSB2YWw7XG4gICAgdGhpcy5kaXNwbGF5VmFsdWUgPSBmb3JtYXQodGhpcy5pbm5lclZhbHVlLCB0aGlzLm9wdGlvbnMuZm9ybWF0IGFzIHN0cmluZywgeyBsb2NhbGU6IHRoaXMub3B0aW9ucy5sb2NhbGUgfSk7XG4gICAgdGhpcy5pbml0KCk7XG4gIH1cblxuICByZWdpc3Rlck9uQ2hhbmdlKGZuOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLm9uQ2hhbmdlQ2FsbGJhY2sgPSBmbjtcbiAgfVxuXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLm9uVG91Y2hlZENhbGxiYWNrID0gZm47XG4gIH1cblxuICBwcml2YXRlIG9uVG91Y2hlZENhbGxiYWNrOiAoKSA9PiB2b2lkID0gKCkgPT4ge307XG4gIHByaXZhdGUgb25DaGFuZ2VDYWxsYmFjazogKF86IGFueSkgPT4gdm9pZCA9ICgpID0+IHt9O1xuXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmNsaWNrJywgWyckZXZlbnQnXSkgb25CbHVyKGU6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaXNPcGVuZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBpbnB1dCA9IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3IoJy5kYXRlcGlja2VyLWNvbnRhaW5lciA+IGlucHV0Jyk7XG4gICAgaWYgKCFpbnB1dCB8fCBlLnRhcmdldCA9PT0gaW5wdXQgfHwgaW5wdXQuY29udGFpbnMoZS50YXJnZXQpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgY29udGFpbmVyID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignLmRhdGVwaWNrZXItY29udGFpbmVyID4gLmNhbGVuZGFyLWNvbnRhaW5lcicpO1xuICAgIGlmIChcbiAgICAgIGNvbnRhaW5lciAmJlxuICAgICAgY29udGFpbmVyICE9PSBlLnRhcmdldCAmJlxuICAgICAgIWNvbnRhaW5lci5jb250YWlucyhlLnRhcmdldCkgJiZcbiAgICAgICEoZS50YXJnZXQgYXMgSFRNTEVsZW1lbnQpLmNsYXNzTGlzdC5jb250YWlucygneWVhci11bml0JylcbiAgICApIHtcbiAgICAgIHRoaXMuaXNPcGVuZWQgPSBmYWxzZTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==