ngx-jalali-date-picker
Version:
This is a configurable date-picker build for Angular applications. Supports latest (Angular 18) version. This date-picker is based on ng2-date-piker and ngx-jalali-date-picker date pickers.
276 lines • 52.3 kB
JavaScript
import { ECalendarMode } from '../common/types/calendar-mode-enum';
import { ChangeDetectionStrategy, Component, EventEmitter, forwardRef, HostBinding, Input, Output, ViewEncapsulation } from '@angular/core';
import { DayCalendarService } from './day-calendar.service';
import moment from 'jalali-moment';
import { NG_VALIDATORS, NG_VALUE_ACCESSOR } from '@angular/forms';
import * as i0 from "@angular/core";
import * as i1 from "./day-calendar.service";
import * as i2 from "../common/services/utils/utils.service";
import * as i3 from "@angular/common";
import * as i4 from "../month-calendar/month-calendar.component";
import * as i5 from "../calendar-nav/calendar-nav.component";
export class DayCalendarComponent {
set selected(selected) {
this._selected = selected;
this.onChangeCallback(this.processOnChangeCallback(selected));
}
get selected() {
return this._selected;
}
set currentDateView(current) {
this._currentDateView = current.clone();
this.weeks = this.dayCalendarService
.generateMonthArray(this.componentConfig, this._currentDateView, this.selected);
this.navLabel = this.dayCalendarService.getHeaderLabel(this.componentConfig, this._currentDateView);
this.showLeftNav = this.dayCalendarService.shouldShowLeft(this.componentConfig.min, this.currentDateView);
this.showRightNav = this.dayCalendarService.shouldShowRight(this.componentConfig.max, this.currentDateView);
}
get currentDateView() {
return this._currentDateView;
}
constructor(dayCalendarService, utilsService, cd) {
this.dayCalendarService = dayCalendarService;
this.utilsService = utilsService;
this.cd = cd;
this.onSelect = new EventEmitter();
this.onMonthSelect = new EventEmitter();
this.onNavHeaderBtnClick = new EventEmitter();
this.onGoToCurrent = new EventEmitter();
this.onLeftNav = new EventEmitter();
this.onRightNav = new EventEmitter();
this.CalendarMode = ECalendarMode;
this.isInited = false;
this.currentCalendarMode = ECalendarMode.Day;
this._shouldShowCurrent = true;
this.api = {
moveCalendarsBy: this.moveCalendarsBy.bind(this),
moveCalendarTo: this.moveCalendarTo.bind(this),
toggleCalendarMode: this.toggleCalendarMode.bind(this)
};
}
ngOnInit() {
this.isInited = true;
this.init();
this.initValidators();
}
init() {
this.componentConfig = this.dayCalendarService.getConfig(this.config);
this.selected = this.selected || [];
this.currentDateView = this.displayDate
? this.utilsService.convertToMoment(this.displayDate, this.componentConfig.format, this.componentConfig.locale).clone()
: this.utilsService
.getDefaultDisplayDate(this.currentDateView, this.selected, this.componentConfig.allowMultiSelect, this.componentConfig.min, this.componentConfig.locale);
this.weekdays = this.dayCalendarService
.generateWeekdays(this.componentConfig.firstDayOfWeek, this.componentConfig.locale);
this.inputValueType = this.utilsService.getInputType(this.inputValue, this.componentConfig.allowMultiSelect);
this.monthCalendarConfig = this.dayCalendarService.getMonthCalendarConfig(this.componentConfig);
this._shouldShowCurrent = this.shouldShowCurrent();
}
isFarsi() {
return this.componentConfig.locale === 'fa';
}
ngOnChanges(changes) {
if (this.isInited) {
const { minDate, maxDate, config } = changes;
this.handleConfigChange(config);
this.init();
if (minDate || maxDate) {
this.initValidators();
}
}
}
writeValue(value) {
if (value === this.inputValue
|| (this.inputValue
&& (moment.isMoment(this.inputValue)) && this.inputValue.isSame(value))) {
return;
}
this.inputValue = value;
if (value) {
this.selected = this.utilsService
.convertToMomentArray(value, this.componentConfig.format, this.componentConfig.allowMultiSelect, this.componentConfig.locale);
this.inputValueType = this.utilsService
.getInputType(this.inputValue, this.componentConfig.allowMultiSelect);
}
else {
this.selected = [];
}
this.weeks = this.dayCalendarService
.generateMonthArray(this.componentConfig, this.currentDateView, this.selected);
this.cd.markForCheck();
}
registerOnChange(fn) {
this.onChangeCallback = fn;
}
onChangeCallback(_) {
}
;
registerOnTouched(fn) {
}
validate(formControl) {
if (this.minDate || this.maxDate) {
return this.validateFn(formControl.value);
}
else {
return () => null;
}
}
processOnChangeCallback(value) {
return this.utilsService.convertFromMomentArray(this.componentConfig.format, value, this.componentConfig.returnedValueType || this.inputValueType, this.componentConfig.locale);
}
initValidators() {
this.validateFn = this.utilsService.createValidator({ minDate: this.minDate, maxDate: this.maxDate }, this.componentConfig.format, 'day', this.componentConfig.locale);
this.onChangeCallback(this.processOnChangeCallback(this.selected));
}
dayClicked(day) {
if (day.selected && !this.componentConfig.unSelectOnClick) {
return;
}
this.selected = this.utilsService
.updateSelected(this.componentConfig.allowMultiSelect, this.selected, day);
this.weeks = this.dayCalendarService
.generateMonthArray(this.componentConfig, this.currentDateView, this.selected);
this.onSelect.emit(day);
}
getDayBtnText(day) {
return this.dayCalendarService.getDayBtnText(this.componentConfig, day.date);
}
getDayBtnCssClass(day) {
const cssClasses = {
'dp-selected': day.selected,
'dp-current-month': day.currentMonth,
'dp-prev-month': day.prevMonth,
'dp-next-month': day.nextMonth,
'dp-current-day': day.currentDay
};
const customCssClass = this.dayCalendarService.getDayBtnCssClass(this.componentConfig, day.date);
if (customCssClass) {
cssClasses[customCssClass] = true;
}
return cssClasses;
}
onLeftNavClick() {
const from = this.currentDateView.clone();
this.moveCalendarsBy(this.currentDateView, -1, 'month');
const to = this.currentDateView.clone();
this.onLeftNav.emit({ from, to });
}
onRightNavClick() {
const from = this.currentDateView.clone();
this.moveCalendarsBy(this.currentDateView, 1, 'month');
const to = this.currentDateView.clone();
this.onRightNav.emit({ from, to });
}
onMonthCalendarLeftClick(change) {
this.onLeftNav.emit(change);
}
onMonthCalendarRightClick(change) {
this.onRightNav.emit(change);
}
onMonthCalendarSecondaryLeftClick(change) {
this.onRightNav.emit(change);
}
onMonthCalendarSecondaryRightClick(change) {
this.onLeftNav.emit(change);
}
getWeekdayName(weekday) {
if (this.componentConfig.weekDayFormatter) {
return this.componentConfig.weekDayFormatter(weekday.day());
}
return weekday.format(this.componentConfig.weekDayFormat);
}
toggleCalendarMode(mode) {
if (this.currentCalendarMode !== mode) {
this.currentCalendarMode = mode;
this.onNavHeaderBtnClick.emit(mode);
}
this.cd.markForCheck();
}
monthSelected(month) {
this.currentDateView = month.date.clone();
this.currentCalendarMode = ECalendarMode.Day;
this.onMonthSelect.emit(month);
}
moveCalendarsBy(current, amount, granularity = 'month') {
this.currentDateView = current.clone().add(amount, granularity);
this.cd.markForCheck();
}
moveCalendarTo(to) {
if (to) {
this.currentDateView = this.utilsService.convertToMoment(to, this.componentConfig.format, this.componentConfig.locale);
}
this.cd.markForCheck();
}
shouldShowCurrent() {
return this.utilsService.shouldShowCurrent(this.componentConfig.showGoToCurrent, 'day', this.componentConfig.min, this.componentConfig.max);
}
goToCurrent() {
this.currentDateView = moment().locale(this.componentConfig.locale);
this.onGoToCurrent.emit();
}
handleConfigChange(config) {
if (config) {
const prevConf = this.dayCalendarService.getConfig(config.previousValue);
const currentConf = this.dayCalendarService.getConfig(config.currentValue);
if (this.utilsService.shouldResetCurrentView(prevConf, currentConf)) {
this._currentDateView = null;
}
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DayCalendarComponent, deps: [{ token: i1.DayCalendarService }, { token: i2.UtilsService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: DayCalendarComponent, selector: "dp-day-calendar", inputs: { config: "config", displayDate: "displayDate", minDate: "minDate", maxDate: "maxDate", theme: "theme" }, outputs: { onSelect: "onSelect", onMonthSelect: "onMonthSelect", onNavHeaderBtnClick: "onNavHeaderBtnClick", onGoToCurrent: "onGoToCurrent", onLeftNav: "onLeftNav", onRightNav: "onRightNav" }, host: { properties: { "class": "this.theme" } }, providers: [
DayCalendarService,
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DayCalendarComponent),
multi: true
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => DayCalendarComponent),
multi: true
}
], usesOnChanges: true, ngImport: i0, template: "<div class=\"dp-day-calendar-container\" *ngIf=\"currentCalendarMode === CalendarMode.Day\">\n <dp-calendar-nav\n [label]=\"navLabel\"\n [showLeftNav]=\"showLeftNav\"\n [showRightNav]=\"showRightNav\"\n [isLabelClickable]=\"componentConfig.enableMonthSelector\"\n [showGoToCurrent]=\"_shouldShowCurrent\"\n [theme]=\"theme\"\n (onLeftNav)=\"onLeftNavClick()\"\n (onRightNav)=\"onRightNavClick()\"\n (onLabelClick)=\"toggleCalendarMode(CalendarMode.Month)\"\n (onGoToCurrent)=\"goToCurrent()\">\n </dp-calendar-nav>\n\n <div class=\"dp-calendar-wrapper\"\n [ngClass]=\"{'dp-hide-near-month': !componentConfig.showNearMonthDays,'rtl':isFarsi()}\">\n <div class=\"dp-weekdays\">\n <span class=\"dp-calendar-weekday\"\n *ngFor=\"let weekday of weekdays\"\n [innerText]=\"getWeekdayName(weekday)\">\n </span>\n </div>\n <div class=\"dp-calendar-week\" *ngFor=\"let week of weeks\">\n <span class=\"dp-week-number\"\n *ngIf=\"componentConfig.showWeekNumbers\"\n [innerText]=\"week[0].date.isoWeek()\">\n </span>\n <button type=\"button\"\n class=\"dp-calendar-day\"\n *ngFor=\"let day of week\"\n [attr.data-date]=\"day.date.format(componentConfig.format)\"\n (click)=\"dayClicked(day)\"\n [disabled]=\"day.disabled\"\n [ngClass]=\"getDayBtnCssClass(day)\"\n [innerText]=\"getDayBtnText(day)\">\n </button>\n </div>\n </div>\n</div>\n\n<dp-month-calendar\n *ngIf=\"currentCalendarMode === CalendarMode.Month\"\n [config]=\"monthCalendarConfig\"\n [displayDate]=\"_currentDateView\"\n [theme]=\"theme\"\n (onSelect)=\"monthSelected($event)\"\n (onNavHeaderBtnClick)=\"toggleCalendarMode(CalendarMode.Day)\"\n (onLeftNav)=\"onMonthCalendarLeftClick($event)\"\n (onRightNav)=\"onMonthCalendarRightClick($event)\"\n (onLeftSecondaryNav)=\"onMonthCalendarSecondaryLeftClick($event)\"\n (onRightSecondaryNav)=\"onMonthCalendarSecondaryRightClick($event)\">\n</dp-month-calendar>\n", styles: ["dp-day-calendar{display:inline-block}dp-day-calendar .dp-day-calendar-container{background:#fff}dp-day-calendar .dp-calendar-wrapper{box-sizing:border-box;border:1px solid #000000}dp-day-calendar .dp-calendar-wrapper .dp-calendar-weekday:first-child{border-left:none}dp-day-calendar .dp-weekdays{font-size:15px;margin-bottom:5px}dp-day-calendar .dp-calendar-weekday{box-sizing:border-box;display:inline-block;width:30px;text-align:center;border-left:1px solid #000000;border-bottom:1px solid #000000}dp-day-calendar .dp-calendar-day{box-sizing:border-box;width:30px;height:30px;cursor:pointer}dp-day-calendar .dp-selected{background:#106cc8;color:#fff}dp-day-calendar .dp-prev-month,dp-day-calendar .dp-next-month{opacity:.5}dp-day-calendar .dp-hide-near-month .dp-prev-month,dp-day-calendar .dp-hide-near-month .dp-next-month{visibility:hidden}dp-day-calendar .dp-week-number{position:absolute;font-size:9px}dp-day-calendar.dp-material .dp-calendar-weekday{height:25px;width:30px;line-height:25px;color:#7a7a7a;border:none;font-size:.75rem;opacity:.6}dp-day-calendar.dp-material .dp-calendar-wrapper{border:1px solid #E0E0E0}dp-day-calendar.dp-material .dp-calendar-weekday:last-child{color:red}dp-day-calendar.dp-material .dp-calendar-wrapper{padding:20px}dp-day-calendar.dp-material .dp-calendar-wrapper.rtl{direction:rtl}dp-day-calendar.dp-material .dp-calendar-month,dp-day-calendar.dp-material .dp-calendar-day{box-sizing:border-box;background:#fff;border-radius:0%;transition:border-radius .1s ease;border:none;outline:none;padding:0}dp-day-calendar.dp-material .dp-calendar-month:hover,dp-day-calendar.dp-material .dp-calendar-day:hover{background:#e0e0e0;border-radius:50%}dp-day-calendar.dp-material .dp-selected{border-radius:50%;background:#106cc8;color:#fff}dp-day-calendar.dp-material .dp-selected:hover{background:#106cc8}dp-day-calendar.dp-material .dp-current-day{border-radius:50%;border:1px solid #106CC8}\n"], dependencies: [{ kind: "directive", type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i4.MonthCalendarComponent, selector: "dp-month-calendar", inputs: ["config", "displayDate", "minDate", "maxDate", "theme"], outputs: ["onSelect", "onNavHeaderBtnClick", "onGoToCurrent", "onLeftNav", "onRightNav", "onLeftSecondaryNav", "onRightSecondaryNav"] }, { kind: "component", type: i5.CalendarNavComponent, selector: "dp-calendar-nav", inputs: ["label", "isLabelClickable", "showLeftNav", "showLeftSecondaryNav", "showRightNav", "showRightSecondaryNav", "leftNavDisabled", "leftSecondaryNavDisabled", "rightNavDisabled", "rightSecondaryNavDisabled", "showGoToCurrent", "theme"], outputs: ["onLeftNav", "onLeftSecondaryNav", "onRightNav", "onRightSecondaryNav", "onLabelClick", "onGoToCurrent"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: DayCalendarComponent, decorators: [{
type: Component,
args: [{ selector: 'dp-day-calendar', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, providers: [
DayCalendarService,
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => DayCalendarComponent),
multi: true
},
{
provide: NG_VALIDATORS,
useExisting: forwardRef(() => DayCalendarComponent),
multi: true
}
], template: "<div class=\"dp-day-calendar-container\" *ngIf=\"currentCalendarMode === CalendarMode.Day\">\n <dp-calendar-nav\n [label]=\"navLabel\"\n [showLeftNav]=\"showLeftNav\"\n [showRightNav]=\"showRightNav\"\n [isLabelClickable]=\"componentConfig.enableMonthSelector\"\n [showGoToCurrent]=\"_shouldShowCurrent\"\n [theme]=\"theme\"\n (onLeftNav)=\"onLeftNavClick()\"\n (onRightNav)=\"onRightNavClick()\"\n (onLabelClick)=\"toggleCalendarMode(CalendarMode.Month)\"\n (onGoToCurrent)=\"goToCurrent()\">\n </dp-calendar-nav>\n\n <div class=\"dp-calendar-wrapper\"\n [ngClass]=\"{'dp-hide-near-month': !componentConfig.showNearMonthDays,'rtl':isFarsi()}\">\n <div class=\"dp-weekdays\">\n <span class=\"dp-calendar-weekday\"\n *ngFor=\"let weekday of weekdays\"\n [innerText]=\"getWeekdayName(weekday)\">\n </span>\n </div>\n <div class=\"dp-calendar-week\" *ngFor=\"let week of weeks\">\n <span class=\"dp-week-number\"\n *ngIf=\"componentConfig.showWeekNumbers\"\n [innerText]=\"week[0].date.isoWeek()\">\n </span>\n <button type=\"button\"\n class=\"dp-calendar-day\"\n *ngFor=\"let day of week\"\n [attr.data-date]=\"day.date.format(componentConfig.format)\"\n (click)=\"dayClicked(day)\"\n [disabled]=\"day.disabled\"\n [ngClass]=\"getDayBtnCssClass(day)\"\n [innerText]=\"getDayBtnText(day)\">\n </button>\n </div>\n </div>\n</div>\n\n<dp-month-calendar\n *ngIf=\"currentCalendarMode === CalendarMode.Month\"\n [config]=\"monthCalendarConfig\"\n [displayDate]=\"_currentDateView\"\n [theme]=\"theme\"\n (onSelect)=\"monthSelected($event)\"\n (onNavHeaderBtnClick)=\"toggleCalendarMode(CalendarMode.Day)\"\n (onLeftNav)=\"onMonthCalendarLeftClick($event)\"\n (onRightNav)=\"onMonthCalendarRightClick($event)\"\n (onLeftSecondaryNav)=\"onMonthCalendarSecondaryLeftClick($event)\"\n (onRightSecondaryNav)=\"onMonthCalendarSecondaryRightClick($event)\">\n</dp-month-calendar>\n", styles: ["dp-day-calendar{display:inline-block}dp-day-calendar .dp-day-calendar-container{background:#fff}dp-day-calendar .dp-calendar-wrapper{box-sizing:border-box;border:1px solid #000000}dp-day-calendar .dp-calendar-wrapper .dp-calendar-weekday:first-child{border-left:none}dp-day-calendar .dp-weekdays{font-size:15px;margin-bottom:5px}dp-day-calendar .dp-calendar-weekday{box-sizing:border-box;display:inline-block;width:30px;text-align:center;border-left:1px solid #000000;border-bottom:1px solid #000000}dp-day-calendar .dp-calendar-day{box-sizing:border-box;width:30px;height:30px;cursor:pointer}dp-day-calendar .dp-selected{background:#106cc8;color:#fff}dp-day-calendar .dp-prev-month,dp-day-calendar .dp-next-month{opacity:.5}dp-day-calendar .dp-hide-near-month .dp-prev-month,dp-day-calendar .dp-hide-near-month .dp-next-month{visibility:hidden}dp-day-calendar .dp-week-number{position:absolute;font-size:9px}dp-day-calendar.dp-material .dp-calendar-weekday{height:25px;width:30px;line-height:25px;color:#7a7a7a;border:none;font-size:.75rem;opacity:.6}dp-day-calendar.dp-material .dp-calendar-wrapper{border:1px solid #E0E0E0}dp-day-calendar.dp-material .dp-calendar-weekday:last-child{color:red}dp-day-calendar.dp-material .dp-calendar-wrapper{padding:20px}dp-day-calendar.dp-material .dp-calendar-wrapper.rtl{direction:rtl}dp-day-calendar.dp-material .dp-calendar-month,dp-day-calendar.dp-material .dp-calendar-day{box-sizing:border-box;background:#fff;border-radius:0%;transition:border-radius .1s ease;border:none;outline:none;padding:0}dp-day-calendar.dp-material .dp-calendar-month:hover,dp-day-calendar.dp-material .dp-calendar-day:hover{background:#e0e0e0;border-radius:50%}dp-day-calendar.dp-material .dp-selected{border-radius:50%;background:#106cc8;color:#fff}dp-day-calendar.dp-material .dp-selected:hover{background:#106cc8}dp-day-calendar.dp-material .dp-current-day{border-radius:50%;border:1px solid #106CC8}\n"] }]
}], ctorParameters: () => [{ type: i1.DayCalendarService }, { type: i2.UtilsService }, { type: i0.ChangeDetectorRef }], propDecorators: { config: [{
type: Input
}], displayDate: [{
type: Input
}], minDate: [{
type: Input
}], maxDate: [{
type: Input
}], theme: [{
type: HostBinding,
args: ['class']
}, {
type: Input
}], onSelect: [{
type: Output
}], onMonthSelect: [{
type: Output
}], onNavHeaderBtnClick: [{
type: Output
}], onGoToCurrent: [{
type: Output
}], onLeftNav: [{
type: Output
}], onRightNav: [{
type: Output
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF5LWNhbGVuZGFyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1qYWxhbGktZGF0ZS1waWNrZXIvc3JjL2xpYi9kYXktY2FsZW5kYXIvZGF5LWNhbGVuZGFyLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1qYWxhbGktZGF0ZS1waWNrZXIvc3JjL2xpYi9kYXktY2FsZW5kYXIvZGF5LWNhbGVuZGFyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLE9BQU8sRUFBQyxhQUFhLEVBQUMsTUFBTSxvQ0FBb0MsQ0FBQztBQUNqRSxPQUFPLEVBQ0wsdUJBQXVCLEVBRXZCLFNBQVMsRUFDVCxZQUFZLEVBQ1osVUFBVSxFQUNWLFdBQVcsRUFDWCxLQUFLLEVBR0wsTUFBTSxFQUdOLGlCQUFpQixFQUNsQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUMsa0JBQWtCLEVBQUMsTUFBTSx3QkFBd0IsQ0FBQztBQUMxRCxPQUFPLE1BQU0sTUFBTSxlQUFlLENBQUM7QUFJbkMsT0FBTyxFQUdMLGFBQWEsRUFDYixpQkFBaUIsRUFHbEIsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7OztBQTRCeEIsTUFBTSxPQUFPLG9CQUFvQjtJQXNDL0IsSUFBSSxRQUFRLENBQUMsUUFBa0I7UUFDN0IsSUFBSSxDQUFDLFNBQVMsR0FBRyxRQUFRLENBQUM7UUFDMUIsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0lBQ2hFLENBQUM7SUFFRCxJQUFJLFFBQVE7UUFDVixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUM7SUFDeEIsQ0FBQztJQUVELElBQUksZUFBZSxDQUFDLE9BQWU7UUFDakMsSUFBSSxDQUFDLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUN4QyxJ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Z0JBQ25ELEtBQUssRUFBRSxJQUFJO2FBQ1o7U0FDRiwrQ0N4REgsMmxFQW9EQTs7NEZETWEsb0JBQW9CO2tCQXBCaEMsU0FBUzsrQkFDRSxpQkFBaUIsaUJBR1osaUJBQWlCLENBQUMsSUFBSSxtQkFDcEIsdUJBQXVCLENBQUMsTUFBTSxhQUNwQzt3QkFDVCxrQkFBa0I7d0JBQ2xCOzRCQUNFLE9BQU8sRUFBRSxpQkFBaUI7NEJBQzFCLFdBQVcsRUFBRSxVQUFVLENBQUMsR0FBRyxFQUFFLHFCQUFxQixDQUFDOzRCQUNuRCxLQUFLLEVBQUUsSUFBSTt5QkFDWjt3QkFDRDs0QkFDRSxPQUFPLEVBQUUsYUFBYTs0QkFDdEIsV0FBVyxFQUFFLFVBQVUsQ0FBQyxHQUFHLEVBQUUscUJBQXFCLENBQUM7NEJBQ25ELEtBQUssRUFBRSxJQUFJO3lCQUNaO3FCQUNGO2tKQUlRLE1BQU07c0JBQWQsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLE9BQU87c0JBQWYsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ3lCLEtBQUs7c0JBQW5DLFdBQVc7dUJBQUMsT0FBTzs7c0JBQUcsS0FBSztnQkFFbEIsUUFBUTtzQkFBakIsTUFBTTtnQkFDRyxhQUFhO3NCQUF0QixNQUFNO2dCQUNHLG1CQUFtQjtzQkFBNUIsTUFBTTtnQkFDRyxhQUFhO3NCQUF0QixNQUFNO2dCQUNHLFNBQVM7c0JBQWxCLE1BQU07Z0JBQ0csVUFBVTtzQkFBbkIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7RUNhbGVuZGFyVmFsdWV9IGZyb20gJy4uL2NvbW1vbi90eXBlcy9jYWxlbmRhci12YWx1ZS1lbnVtJztcbmltcG9ydCB7U2luZ2xlQ2FsZW5kYXJWYWx1ZX0gZnJvbSAnLi4vY29tbW9uL3R5cGVzL3NpbmdsZS1jYWxlbmRhci12YWx1ZSc7XG5pbXBvcnQge0VDYWxlbmRhck1vZGV9IGZyb20gJy4uL2NvbW1vbi90eXBlcy9jYWxlbmRhci1tb2RlLWVudW0nO1xuaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIEV2ZW50RW1pdHRlcixcbiAgZm9yd2FyZFJlZixcbiAgSG9zdEJpbmRpbmcsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE9uSW5pdCxcbiAgT3V0cHV0LFxuICBTaW1wbGVDaGFuZ2UsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFZpZXdFbmNhcHN1bGF0aW9uXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtEYXlDYWxlbmRhclNlcnZpY2V9IGZyb20gJy4vZGF5LWNhbGVuZGFyLnNlcnZpY2UnO1xuaW1wb3J0IG1vbWVudCBmcm9tICdqYWxhbGktbW9tZW50JztcbmltcG9ydCB7TW9tZW50LCBNb21lbnRJbnB1dCwgdW5pdE9mVGltZX0gZnJvbSAnamFsYWxpLW1vbWVudCc7XG5pbXBvcnQge0lEYXlDYWxlbmRhckNvbmZpZywgSURheUNhbGVuZGFyQ29uZmlnSW50ZXJuYWx9IGZyb20gJy4vZGF5LWNhbGVuZGFyLWNvbmZpZy5tb2RlbCc7XG5pbXBvcnQge0lEYXl9IGZyb20gJy4vZGF5Lm1vZGVsJztcbmltcG9ydCB7XG4gIENvbnRyb2xWYWx1ZUFjY2Vzc29yLFxuICBGb3JtQ29udHJvbCxcbiAgTkdfVkFMSURBVE9SUyxcbiAgTkdfVkFMVUVfQUNDRVNTT1IsXG4gIFZhbGlkYXRpb25FcnJvcnMsXG4gIFZhbGlkYXRvclxufSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQge0NhbGVuZGFyVmFsdWV9IGZyb20gJy4uL2NvbW1vbi90eXBlcy9jYWxlbmRhci12YWx1ZSc7XG5pbXBvcnQge1V0aWxzU2VydmljZX0gZnJvbSAnLi4vY29tbW9uL3NlcnZpY2VzL3V0aWxzL3V0aWxzLnNlcnZpY2UnO1xuaW1wb3J0IHtJTW9udGhDYWxlbmRhckNvbmZpZ30gZnJvbSAnLi4vbW9udGgtY2FsZW5kYXIvbW9udGgtY2FsZW5kYXItY29uZmlnJztcbmltcG9ydCB7SU1vbnRofSBmcm9tICcuLi9tb250aC1jYWxlbmRhci9tb250aC5tb2RlbCc7XG5pbXBvcnQge0RhdGVWYWxpZGF0b3J9IGZyb20gJy4uL2NvbW1vbi90eXBlcy92YWxpZGF0b3IudHlwZSc7XG5pbXBvcnQge0lOYXZFdmVudH0gZnJvbSAnLi4vY29tbW9uL21vZGVscy9uYXZpZ2F0aW9uLWV2ZW50Lm1vZGVsJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnZHAtZGF5LWNhbGVuZGFyJyxcbiAgdGVtcGxhdGVVcmw6ICdkYXktY2FsZW5kYXIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnZGF5LWNhbGVuZGFyLmNvbXBvbmVudC5sZXNzJ10sXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBwcm92aWRlcnM6IFtcbiAgICBEYXlDYWxlbmRhclNlcnZpY2UsXG4gICAge1xuICAgICAgcHJvdmlkZTogTkdfVkFMVUVfQUNDRVNTT1IsXG4gICAgICB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBEYXlDYWxlbmRhckNvbXBvbmVudCksXG4gICAgICBtdWx0aTogdHJ1ZVxuICAgIH0sXG4gICAge1xuICAgICAgcHJvdmlkZTogTkdfVkFMSURBVE9SUyxcbiAgICAgIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IERheUNhbGVuZGFyQ29tcG9uZW50KSxcbiAgICAgIG11bHRpOiB0cnVlXG4gICAgfVxuICBdXG59KVxuZXhwb3J0IGNsYXNzIERheUNhbGVuZGFyQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIENvbnRyb2xWYWx1ZUFjY2Vzc29yLCBWYWxpZGF0b3Ige1xuXG4gIEBJbnB1dCgpIGNvbmZpZzogSURheUNhbGVuZGFyQ29uZmlnO1xuICBASW5wdXQoKSBkaXNwbGF5RGF0ZTogU2luZ2xlQ2FsZW5kYXJWYWx1ZTtcbiAgQElucHV0KCkgbWluRGF0ZTogTW9tZW50O1xuICBASW5wdXQoKSBtYXhEYXRlOiBNb21lbnQ7XG4gIEBIb3N0QmluZGluZygnY2xhc3MnKSBASW5wdXQoKSB0aGVtZTogc3RyaW5nO1xuXG4gIEBPdXRwdXQoKSBvblNlbGVjdDogRXZlbnRFbWl0dGVyPElEYXk+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgb25Nb250aFNlbGVjdDogRXZlbnRFbWl0dGVyPElNb250aD4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBvbk5hdkhlYWRlckJ0bkNsaWNrOiBFdmVudEVtaXR0ZXI8RUNhbGVuZGFyTW9kZT4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBvbkdvVG9DdXJyZW50OiBFdmVudEVtaXR0ZXI8dm9pZD4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBvbkxlZnROYXY6IEV2ZW50RW1pdHRlcjxJTmF2RXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgb25SaWdodE5hdjogRXZlbnRFbWl0dGVyPElOYXZFdmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG5cbiAgQ2FsZW5kYXJNb2RlID0gRUNhbGVuZGFyTW9kZTtcbiAgaXNJbml0ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcbiAgY29tcG9uZW50Q29uZmlnOiBJRGF5Q2FsZW5kYXJDb25maWdJbnRlcm5hbDtcbiAgX3NlbGVjdGVkOiBNb21lbnRbXTtcbiAgd2Vla3M6IElEYXlbXVtdO1xuICB3ZWVrZGF5czogTW9tZW50W107XG4gIF9jdXJyZW50RGF0ZVZpZXc6IE1vbWVudDtcbiAgaW5wdXRWYWx1ZTogQ2FsZW5kYXJWYWx1ZTtcbiAgaW5wdXRWYWx1ZVR5cGU6IEVDYWxlbmRhclZhbHVlO1xuICB2YWxpZGF0ZUZuOiBEYXRlVmFsaWRhdG9yO1xuICBjdXJyZW50Q2FsZW5kYXJNb2RlOiBFQ2FsZW5kYXJNb2RlID0gRUNhbGVuZGFyTW9kZS5EYXk7XG4gIG1vbnRoQ2FsZW5kYXJDb25maWc6IElNb250aENhbGVuZGFyQ29uZmlnO1xuICBfc2hvdWxkU2hvd0N1cnJlbnQ6IGJvb2xlYW4gPSB0cnVlO1xuICBuYXZMYWJlbDogc3RyaW5nO1xuICBzaG93TGVmdE5hdjogYm9vbGVhbjtcbiAgc2hvd1JpZ2h0TmF2OiBib29sZWFuO1xuXG4gIGFwaSA9IHtcbiAgICBtb3ZlQ2FsZW5kYXJzQnk6IHRoaXMubW92ZUNhbGVuZGFyc0J5LmJpbmQodGhpcyksXG4gICAgbW92ZUNhbGVuZGFyVG86IHRoaXMubW92ZUNhbGVuZGFyVG8uYmluZCh0aGlzKSxcbiAgICB0b2dnbGVDYWxlbmRhck1vZGU6IHRoaXMudG9nZ2xlQ2FsZW5kYXJNb2RlLmJpbmQodGhpcylcbiAgfTtcblxuICBzZXQgc2VsZWN0ZWQoc2VsZWN0ZWQ6IE1vbWVudFtdKSB7XG4gICAgdGhpcy5fc2VsZWN0ZWQgPSBzZWxlY3RlZDtcbiAgICB0aGlzLm9uQ2hhbmdlQ2FsbGJhY2sodGhpcy5wcm9jZXNzT25DaGFuZ2VDYWxsYmFjayhzZWxlY3RlZCkpO1xuICB9XG5cbiAgZ2V0IHNlbGVjdGVkKCk6IE1vbWVudFtdIHtcbiAgICByZXR1cm4gdGhpcy5fc2VsZWN0ZWQ7XG4gIH1cblxuICBzZXQgY3VycmVudERhdGVWaWV3KGN1cnJlbnQ6IE1vbWVudCkge1xuICAgIHRoaXMuX2N1cnJlbnREYXRlVmlldyA9IGN1cnJlbnQuY2xvbmUoKTtcbiAgICB0aGlzLndlZWtzID0gdGhpcy5kYXlDYWxlbmRhclNlcnZpY2VcbiAgICAgIC5nZW5lcmF0ZU1vbnRoQXJyYXkodGhpcy5jb21wb25lbnRDb25maWcsIHRoaXMuX2N1cnJlbnREYXRlVmlldywgdGhpcy5zZWxlY3RlZCk7XG4gICAgdGhpcy5uYXZMYWJlbCA9IHRoaXMuZGF5Q2FsZW5kYXJTZXJ2aWNlLmdldEhlYWRlckxhYmVsKHRoaXMuY29tcG9uZW50Q29uZmlnLCB0aGlzLl9jdXJyZW50RGF0ZVZpZXcpO1xuICAgIHRoaXMuc2hvd0xlZnROYXYgPSB0aGlzLmRheUNhbGVuZGFyU2VydmljZS5zaG91bGRTaG93TGVmdCh0aGlzLmNvbXBvbmVudENvbmZpZy5taW4sIHRoaXMuY3VycmVudERhdGVWaWV3KTtcbiAgICB0aGlzLnNob3dSaWdodE5hdiA9IHRoaXMuZGF5Q2FsZW5kYXJTZXJ2aWNlLnNob3VsZFNob3dSaWdodCh0aGlzLmNvbXBvbmVudENvbmZpZy5tYXgsIHRoaXMuY3VycmVudERhdGVWaWV3KTtcbiAgfVxuXG4gIGdldCBjdXJyZW50RGF0ZVZpZXcoKTogTW9tZW50IHtcbiAgICByZXR1cm4gdGhpcy5fY3VycmVudERhdGVWaWV3O1xuICB9XG5cbiAgY29uc3RydWN0b3IocHVibGljIHJlYWRvbmx5IGRheUNhbGVuZGFyU2VydmljZTogRGF5Q2FsZW5kYXJTZXJ2aWNlLFxuICAgICAgICAgICAgICBwdWJsaWMgcmVhZG9ubHkgdXRpbHNTZXJ2aWNlOiBVdGlsc1NlcnZpY2UsXG4gICAgICAgICAgICAgIHB1YmxpYyByZWFkb25seSBjZDogQ2hhbmdlRGV0ZWN0b3JSZWYpIHtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuaXNJbml0ZWQgPSB0cnVlO1xuICAgIHRoaXMuaW5pdCgpO1xuICAgIHRoaXMuaW5pdFZhbGlkYXRvcnMoKTtcbiAgfVxuXG4gIGluaXQoKSB7XG4gICAgdGhpcy5jb21wb25lbnRDb25maWcgPSB0aGlzLmRheUNhbGVuZGFyU2VydmljZS5nZXRDb25maWcodGhpcy5jb25maWcpO1xuICAgIHRoaXMuc2VsZWN0ZWQgPSB0aGlzLnNlbGVjdGVkIHx8IFtdO1xuICAgIHRoaXMuY3VycmVudERhdGVWaWV3ID0gdGhpcy5kaXNwbGF5RGF0ZVxuICAgICAgPyB0aGlzLnV0aWxzU2VydmljZS5jb252ZXJ0VG9Nb21lbnQodGhpcy5kaXNwbGF5RGF0ZSwgdGhpcy5jb21wb25lbnRDb25maWcuZm9ybWF0LCB0aGlzLmNvbXBvbmVudENvbmZpZy5sb2NhbGUpLmNsb25lKClcbiAgICAgIDogdGhpcy51dGlsc1NlcnZpY2VcbiAgICAgICAgLmdldERlZmF1bHREaXNwbGF5RGF0ZShcbiAgICAgICAgICB0aGlzLmN1cnJlbnREYXRlVmlldyxcbiAgICAgICAgICB0aGlzLnNlbGVjdGVkLFxuICAgICAgICAgIHRoaXMuY29tcG9uZW50Q29uZmlnLmFsbG93TXVsdGlTZWxlY3QsXG4gICAgICAgICAgdGhpcy5jb21wb25lbnRDb25maWcubWluLFxuICAgICAgICAgIHRoaXMuY29tcG9uZW50Q29uZmlnLmxvY2FsZVxuICAgICAgICApO1xuICAgIHRoaXMud2Vla2RheXMgPSB0aGlzLmRheUNhbGVuZGFyU2VydmljZVxuICAgICAgLmdlbmVyYXRlV2Vla2RheXModGhpcy5jb21wb25lbnRDb25maWcuZmlyc3REYXlPZldlZWssIHRoaXMuY29tcG9uZW50Q29uZmlnLmxvY2FsZSk7XG4gICAgdGhpcy5pbnB1dFZhbHVlVHlwZSA9IHRoaXMudXRpbHNTZXJ2aWNlLmdldElucHV0VHlwZSh0aGlzLmlucHV0VmFsdWUsIHRoaXMuY29tcG9uZW50Q29uZmlnLmFsbG93TXVsdGlTZWxlY3QpO1xuICAgIHRoaXMubW9udGhDYWxlbmRhckNvbmZpZyA9IHRoaXMuZGF5Q2FsZW5kYXJTZXJ2aWNlLmdldE1vbnRoQ2FsZW5kYXJDb25maWcodGhpcy5jb21wb25lbnRDb25maWcpO1xuICAgIHRoaXMuX3Nob3VsZFNob3dDdXJyZW50ID0gdGhpcy5zaG91bGRTaG93Q3VycmVudCgpO1xuICB9XG4gIGlzRmFyc2koKSB7XG4gICAgcmV0dXJuIHRoaXMuY29tcG9uZW50Q29uZmlnLmxvY2FsZSA9PT0gJ2ZhJztcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcbiAgICBpZiAodGhpcy5pc0luaXRlZCkge1xuICAgICAgY29uc3Qge21pbkRhdGUsIG1heERhdGUsIGNvbmZpZ30gPSBjaGFuZ2VzO1xuXG4gICAgICB0aGlzLmhhbmRsZUNvbmZpZ0NoYW5nZShjb25maWcpO1xuICAgICAgdGhpcy5pbml0KCk7XG5cbiAgICAgIGlmIChtaW5EYXRlIHx8IG1heERhdGUpIHtcbiAgICAgICAgdGhpcy5pbml0VmFsaWRhdG9ycygpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHdyaXRlVmFsdWUodmFsdWU6IENhbGVuZGFyVmFsdWUpOiB2b2lkIHtcbiAgICBpZiAodmFsdWUgPT09IHRoaXMuaW5wdXRWYWx1ZVxuICAgICAgfHwgKHRoaXMuaW5wdXRWYWx1ZVxuICAgICAgICYmIChtb21lbnQuaXNNb21lbnQodGhpcy5pbnB1dFZhbHVlKSkgJiYgKHRoaXMuaW5wdXRWYWx1ZSBhcyBNb21lbnQpLmlzU2FtZSg8TW9tZW50SW5wdXQ+dmFsdWUpKVxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuaW5wdXRWYWx1ZSA9IHZhbHVlO1xuXG4gICAgaWYgKHZhbHVlKSB7XG4gICAgICB0aGlzLnNlbGVjdGVkID0gdGhpcy51dGlsc1NlcnZpY2VcbiAgICAgICAgLmNvbnZlcnRUb01vbWVudEFycmF5KHZhbHVlLCB0aGlzLmNvbXBvbmVudENvbmZpZy5mb3JtYXQsIHRoaXMuY29tcG9uZW50Q29uZmlnLmFsbG93TXVsdGlTZWxlY3QsIHRoaXMuY29tcG9uZW50Q29uZmlnLmxvY2FsZSk7XG4gICAgICB0aGlzLmlucHV0VmFsdWVUeXBlID0gdGhpcy51dGlsc1NlcnZpY2VcbiAgICAgICAgLmdldElucHV0VHlwZSh0aGlzLmlucHV0VmFsdWUsIHRoaXMuY29tcG9uZW50Q29uZmlnLmFsbG93TXVsdGlTZWxlY3QpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNlbGVjdGVkID0gW107XG4gICAgfVxuXG4gICAgdGhpcy53ZWVrcyA9IHRoaXMuZGF5Q2FsZW5kYXJTZXJ2aWNlXG4gICAgICAuZ2VuZXJhdGVNb250aEFycmF5KHRoaXMuY29tcG9uZW50Q29uZmlnLCB0aGlzLmN1cnJlbnREYXRlVmlldywgdGhpcy5zZWxlY3RlZCk7XG5cbiAgICB0aGlzLmNkLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgcmVnaXN0ZXJPbkNoYW5nZShmbjogYW55KTogdm9pZCB7XG4gICAgdGhpcy5vbkNoYW5nZUNhbGxiYWNrID0gZm47XG4gIH1cblxuICBvbkNoYW5nZUNhbGxiYWNrKF86IGFueSkge1xuICB9O1xuXG4gIHJlZ2lzdGVyT25Ub3VjaGVkKGZuOiBhbnkpOiB2b2lkIHtcbiAgfVxuXG4gIHZhbGlkYXRlKGZvcm1Db250cm9sOiBGb3JtQ29udHJvbCk6IFZhbGlkYXRpb25FcnJvcnMgfCBhbnkge1xuICAgIGlmICh0aGlzLm1pbkRhdGUgfHwgdGhpcy5tYXhEYXRlKSB7XG4gICAgICByZXR1cm4gdGhpcy52YWxpZGF0ZUZuKGZvcm1Db250cm9sLnZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuICgpID0+IG51bGw7XG4gICAgfVxuICB9XG5cbiAgcHJvY2Vzc09uQ2hhbmdlQ2FsbGJhY2sodmFsdWU6IE1vbWVudFtdKTogQ2FsZW5kYXJWYWx1ZSB7XG4gICAgcmV0dXJuIHRoaXMudXRpbHNTZXJ2aWNlLmNvbnZlcnRGcm9tTW9tZW50QXJyYXkoXG4gICAgICB0aGlzLmNvbXBvbmVudENvbmZpZy5mb3JtYXQsXG4gICAgICB2YWx1ZSxcbiAgICAgIHRoaXMuY29tcG9uZW50Q29uZmlnLnJldHVybmVkVmFsdWVUeXBlIHx8IHRoaXMuaW5wdXRWYWx1ZVR5cGUsXG4gICAgICB0aGlzLmNvbXBvbmVudENvbmZpZy5sb2NhbGVcbiAgICApO1xuICB9XG5cbiAgaW5pdFZhbGlkYXRvcnMoKSB7XG4gICAgdGhpcy52YWxpZGF0ZUZuID0gdGhpcy51dGlsc1NlcnZpY2UuY3JlYXRlVmFsaWRhdG9yKFxuICAgICAge21pbkRhdGU6IHRoaXMubWluRGF0ZSwgbWF4RGF0ZTogdGhpcy5tYXhEYXRlfSxcbiAgICAgIHRoaXMuY29tcG9uZW50Q29uZmlnLmZvcm1hdCxcbiAgICAgICdkYXknLFxuICAgICAgdGhpcy5jb21wb25lbnRDb25maWcubG9jYWxlXG4gICAgKTtcblxuICAgIHRoaXMub25DaGFuZ2VDYWxsYmFjayh0aGlzLnByb2Nlc3NPbkNoYW5nZUNhbGxiYWNrKHRoaXMuc2VsZWN0ZWQpKTtcbiAgfVxuXG4gIGRheUNsaWNrZWQoZGF5OiBJRGF5KSB7XG4gICAgaWYgKGRheS5zZWxlY3RlZCAmJiAhdGhpcy5jb21wb25lbnRDb25maWcudW5TZWxlY3RPbkNsaWNrKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5zZWxlY3RlZCA9IHRoaXMudXRpbHNTZXJ2aWNlXG4gICAgICAudXBkYXRlU2VsZWN0ZWQodGhpcy5jb21wb25lbnRDb25maWcuYWxsb3dNdWx0aVNlbGVjdCwgdGhpcy5zZWxlY3RlZCwgZGF5KTtcbiAgICB0aGlzLndlZWtzID0gdGhpcy5kYXlDYWxlbmRhclNlcnZpY2VcbiAgICAgIC5nZW5lcmF0ZU1vbnRoQXJyYXkodGhpcy5jb21wb25lbnRDb25maWcsIHRoaXMuY3VycmVudERhdGVWaWV3LCB0aGlzLnNlbGVjdGVkKTtcbiAgICB0aGlzLm9uU2VsZWN0LmVtaXQoZGF5KTtcbiAgfVxuXG4gIGdldERheUJ0blRleHQoZGF5OiBJRGF5KTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5kYXlDYWxlbmRhclNlcnZpY2UuZ2V0RGF5QnRuVGV4dCh0aGlzLmNvbXBvbmVudENvbmZpZywgZGF5LmRhdGUpO1xuICB9XG5cbiAgZ2V0RGF5QnRuQ3NzQ2xhc3MoZGF5OiBJRGF5KToge1trbGFzczogc3RyaW5nXTogYm9vbGVhbn0ge1xuICAgIGNvbnN0IGNzc0NsYXNzZXM6IHtba2xhc3M6IHN0cmluZ106IGJvb2xlYW59ID0ge1xuICAgICAgJ2RwLXNlbGVjdGVkJzogZGF5LnNlbGVjdGVkLFxuICAgICAgJ2RwLWN1cnJlbnQtbW9udGgnOiBkYXkuY3VycmVudE1vbnRoLFxuICAgICAgJ2RwLXByZXYtbW9udGgnOiBkYXkucHJldk1vbnRoLFxuICAgICAgJ2RwLW5leHQtbW9udGgnOiBkYXkubmV4dE1vbnRoLFxuICAgICAgJ2RwLWN1cnJlbnQtZGF5JzogZGF5LmN1cnJlbnREYXlcbiAgICB9O1xuICAgIGNvbnN0IGN1c3RvbUNzc0NsYXNzOiBzdHJpbmcgPSB0aGlzLmRheUNhbGVuZGFyU2VydmljZS5nZXREYXlCdG5Dc3NDbGFzcyh0aGlzLmNvbXBvbmVudENvbmZpZywgZGF5LmRhdGUpO1xuICAgIGlmIChjdXN0b21Dc3NDbGFzcykge1xuICAgICAgY3NzQ2xhc3Nlc1tjdXN0b21Dc3NDbGFzc10gPSB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiBjc3NDbGFzc2VzO1xuICB9XG5cbiAgb25MZWZ0TmF2Q2xpY2soKSB7XG4gICAgY29uc3QgZnJvbSA9IHRoaXMuY3VycmVudERhdGVWaWV3LmNsb25lKCk7XG4gICAgdGhpcy5tb3ZlQ2FsZW5kYXJzQnkodGhpcy5jdXJyZW50RGF0ZVZpZXcsIC0xLCAnbW9udGgnKTtcbiAgICBjb25zdCB0byA9IHRoaXMuY3VycmVudERhdGVWaWV3LmNsb25lKCk7XG4gICAgdGhpcy5vbkxlZnROYXYuZW1pdCh7ZnJvbSwgdG99KTtcbiAgfVxuXG4gIG9uUmlnaHROYXZDbGljaygpIHtcbiAgICBjb25zdCBmcm9tID0gdGhpcy5jdXJyZW50RGF0ZVZpZXcuY2xvbmUoKTtcbiAgICB0aGlzLm1vdmVDYWxlbmRhcnNCeSh0aGlzLmN1cnJlbnREYXRlVmlldywgMSwgJ21vbnRoJyk7XG4gICAgY29uc3QgdG8gPSB0aGlzLmN1cnJlbnREYXRlVmlldy5jbG9uZSgpO1xuICAgIHRoaXMub25SaWdodE5hdi5lbWl0KHtmcm9tLCB0b30pO1xuICB9XG5cbiAgb25Nb250aENhbGVuZGFyTGVmdENsaWNrKGNoYW5nZTogSU5hdkV2ZW50KSB7XG4gICAgdGhpcy5vbkxlZnROYXYuZW1pdChjaGFuZ2UpO1xuICB9XG5cbiAgb25Nb250aENhbGVuZGFyUmlnaHRDbGljayhjaGFuZ2U6IElOYXZFdmVudCkge1xuICAgIHRoaXMub25SaWdodE5hdi5lbWl0KGNoYW5nZSk7XG4gIH1cblxuICBvbk1vbnRoQ2FsZW5kYXJTZWNvbmRhcnlMZWZ0Q2xpY2soY2hhbmdlOiBJTmF2RXZlbnQpIHtcbiAgICB0aGlzLm9uUmlnaHROYXYuZW1pdChjaGFuZ2UpO1xuICB9XG5cbiAgb25Nb250aENhbGVuZGFyU2Vjb25kYXJ5UmlnaHRDbGljayhjaGFuZ2U6IElOYXZFdmVudCkge1xuICAgIHRoaXMub25MZWZ0TmF2LmVtaXQoY2hhbmdlKTtcbiAgfVxuXG4gIGdldFdlZWtkYXlOYW1lKHdlZWtkYXk6IE1vbWVudCk6IHN0cmluZyB7XG4gICAgaWYgKHRoaXMuY29tcG9uZW50Q29uZmlnLndlZWtEYXlGb3JtYXR0ZXIpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbXBvbmVudENvbmZpZy53ZWVrRGF5Rm9ybWF0dGVyKHdlZWtkYXkuZGF5KCkpO1xuICAgIH1cblxuICAgIHJldHVybiB3ZWVrZGF5LmZvcm1hdCh0aGlzLmNvbXBvbmVudENvbmZpZy53ZWVrRGF5Rm9ybWF0KTtcbiAgfVxuXG4gIHRvZ2dsZUNhbGVuZGFyTW9kZShtb2RlOiBFQ2FsZW5kYXJNb2RlKSB7XG4gICAgaWYgKHRoaXMuY3VycmVudENhbGVuZGFyTW9kZSAhPT0gbW9kZSkge1xuICAgICAgdGhpcy5jdXJyZW50Q2FsZW5kYXJNb2RlID0gbW9kZTtcbiAgICAgIHRoaXMub25OYXZIZWFkZXJCdG5DbGljay5lbWl0KG1vZGUpO1xuICAgIH1cblxuICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBtb250aFNlbGVjdGVkKG1vbnRoOiBJTW9udGgpIHtcbiAgICB0aGlzLmN1cnJlbnREYXRlVmlldyA9IG1vbnRoLmRhdGUuY2xvbmUoKTtcbiAgICB0aGlzLmN1cnJlbnRDYWxlbmRhck1vZGUgPSBFQ2FsZW5kYXJNb2RlLkRheTtcbiAgICB0aGlzLm9uTW9udGhTZWxlY3QuZW1pdChtb250aCk7XG4gIH1cblxuICBtb3ZlQ2FsZW5kYXJzQnkoY3VycmVudDogTW9tZW50LCBhbW91bnQ6IG51bWJlciwgZ3JhbnVsYXJpdHk6IHVuaXRPZlRpbWUuQmFzZSA9ICdtb250aCcpIHtcbiAgICB0aGlzLmN1cnJlbnREYXRlVmlldyA9IGN1cnJlbnQuY2xvbmUoKS5hZGQoYW1vdW50LCBncmFudWxhcml0eSk7XG4gICAgdGhpcy5jZC5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIG1vdmVDYWxlbmRhclRvKHRvOiBTaW5nbGVDYWxlbmRhclZhbHVlKSB7XG4gICAgaWYgKHRvKSB7XG4gICAgICB0aGlzLmN1cnJlbnREYXRlVmlldyA9IHRoaXMudXRpbHNTZXJ2aWNlLmNvbnZlcnRUb01vbWVudCh0bywgdGhpcy5jb21wb25lbnRDb25maWcuZm9ybWF0LCB0aGlzLmNvbXBvbmVudENvbmZpZy5sb2NhbGUpO1xuICAgIH1cblxuICAgIHRoaXMuY2QubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICBzaG91bGRTaG93Q3VycmVudCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy51dGlsc1NlcnZpY2Uuc2hvdWxkU2hvd0N1cnJlbnQoXG4gICAgICB0aGlzLmNvbXBvbmVudENvbmZpZy5zaG93R29Ub0N1cnJlbnQsXG4gICAgICAnZGF5JyxcbiAgICAgIHRoaXMuY29tcG9uZW50Q29uZmlnLm1pbixcbiAgICAgIHRoaXMuY29tcG9uZW50Q29uZmlnLm1heFxuICAgICk7XG4gIH1cblxuICBnb1RvQ3VycmVudCgpIHtcbiAgICB0aGlzLmN1cnJlbnREYXRlVmlldyA9IG1vbWVudCgpLmxvY2FsZSh0aGlzLmNvbXBvbmVudENvbmZpZy5sb2NhbGUpO1xuICAgIHRoaXMub25Hb1RvQ3VycmVudC5lbWl0KCk7XG4gIH1cblxuICBoYW5kbGVDb25maWdDaGFuZ2UoY29uZmlnOiBTaW1wbGVDaGFuZ2UpIHtcbiAgICBpZiAoY29uZmlnKSB7XG4gICAgICBjb25zdCBwcmV2Q29uZjogSURheUNhbGVuZGFyQ29uZmlnSW50ZXJuYWwgPSB0aGlzLmRheUNhbGVuZGFyU2VydmljZS5nZXRDb25maWcoY29uZmlnLnByZXZpb3VzVmFsdWUpO1xuICAgICAgY29uc3QgY3VycmVudENvbmY6IElEYXlDYWxlbmRhckNvbmZpZ0ludGVybmFsID0gdGhpcy5kYXlDYWxlbmRhclNlcnZpY2UuZ2V0Q29uZmlnKGNvbmZpZy5jdXJyZW50VmFsdWUpO1xuXG4gICAgICBpZiAodGhpcy51dGlsc1NlcnZpY2Uuc2hvdWxkUmVzZXRDdXJyZW50VmlldyhwcmV2Q29uZiwgY3VycmVudENvbmYpKSB7XG4gICAgICAgIHRoaXMuX2N1cnJlbnREYXRlVmlldyA9IG51bGw7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwiZHAtZGF5LWNhbGVuZGFyLWNvbnRhaW5lclwiICpuZ0lmPVwiY3VycmVudENhbGVuZGFyTW9kZSA9PT0gIENhbGVuZGFyTW9kZS5EYXlcIj5cbiAgPGRwLWNhbGVuZGFyLW5hdlxuICAgICAgW2xhYmVsXT1cIm5hdkxhYmVsXCJcbiAgICAgIFtzaG93TGVmdE5hdl09XCJzaG93TGVmdE5hdlwiXG4gICAgICBbc2hvd1JpZ2h0TmF2XT1cInNob3dSaWdodE5hdlwiXG4gICAgICBbaXNMYWJlbENsaWNrYWJsZV09XCJjb21wb25lbnRDb25maWcuZW5hYmxlTW9udGhTZWxlY3RvclwiXG4gICAgICBbc2hvd0dvVG9DdXJyZW50XT1cIl9zaG91bGRTaG93Q3VycmVudFwiXG4gICAgICBbdGhlbWVdPVwidGhlbWVcIlxuICAgICAgKG9uTGVmdE5hdik9XCJvbkxlZnROYXZDbGljaygpXCJcbiAgICAgIChvblJpZ2h0TmF2KT1cIm9uUmlnaHROYXZDbGljaygpXCJcbiAgICAgIChvbkxhYmVsQ2xpY2spPVwidG9nZ2xlQ2FsZW5kYXJNb2RlKENhbGVuZGFyTW9kZS5Nb250aClcIlxuICAgICAgKG9uR29Ub0N1cnJlbnQpPVwiZ29Ub0N1cnJlbnQoKVwiPlxuICA8L2RwLWNhbGVuZGFyLW5hdj5cblxuICA8ZGl2IGNsYXNzPVwiZHAtY2FsZW5kYXItd3JhcHBlclwiXG4gICAgICAgW25nQ2xhc3NdPVwieydkcC1oaWRlLW5lYXItbW9udGgnOiAhY29tcG9uZW50Q29uZmlnLnNob3dOZWFyTW9udGhEYXlzLCdydGwnOmlzRmFyc2koKX1cIj5cbiAgICA8ZGl2IGNsYXNzPVwiZHAtd2Vla2RheXNcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwiZHAtY2FsZW5kYXItd2Vla2RheVwiXG4gICAgICAgICAgICAqbmdGb3I9XCJsZXQgd2Vla2RheSBvZiB3ZWVrZGF5c1wiXG4gICAgICAgICAgICBbaW5uZXJUZXh0XT1cImdldFdlZWtkYXlOYW1lKHdlZWtkYXkpXCI+XG4gICAgICA8L3NwYW4+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cImRwLWNhbGVuZGFyLXdlZWtcIiAqbmdGb3I9XCJsZXQgd2VlayBvZiB3ZWVrc1wiPlxuICAgICAgPHNwYW4gY2xhc3M9XCJkcC13ZWVrLW51bWJlclwiXG4gICAgICAgICAgICAqbmdJZj1cImNvbXBvbmVudENvbmZpZy5zaG93V2Vla051bWJlcnNcIlxuICAgICAgICAgICAgW2lubmVyVGV4dF09XCJ3ZWVrWzBdLmRhdGUuaXNvV2VlaygpXCI+XG4gICAgICA8L3NwYW4+XG4gICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICBjbGFzcz1cImRwLWNhbGVuZGFyLWRheVwiXG4gICAgICAgICAgICAgICpuZ0Zvcj1cImxldCBkYXkgb2Ygd2Vla1wiXG4gICAgICAgICAgICAgIFthdHRyLmRhdGEtZGF0ZV09XCJkYXkuZGF0ZS5mb3JtYXQoY29tcG9uZW50Q29uZmlnLmZvcm1hdClcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwiZGF5Q2xpY2tlZChkYXkpXCJcbiAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImRheS5kaXNhYmxlZFwiXG4gICAgICAgICAgICAgIFtuZ0NsYXNzXT1cImdldERheUJ0bkNzc0NsYXNzKGRheSlcIlxuICAgICAgICAgICAgICBbaW5uZXJUZXh0XT1cImdldERheUJ0blRleHQoZGF5KVwiPlxuICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9kaXY+XG5cbjxkcC1tb250aC1jYWxlbmRhclxuICAgICpuZ0lmPVwiY3VycmVudENhbGVuZGFyTW9kZSA9PT0gIENhbGVuZGFyTW9kZS5Nb250aFwiXG4gICAgW2NvbmZpZ109XCJtb250aENhbGVuZGFyQ29uZmlnXCJcbiAgICBbZGlzcGxheURhdGVdPVwiX2N1cnJlbnREYXRlVmlld1wiXG4gICAgW3RoZW1lXT1cInRoZW1lXCJcbiAgICAob25TZWxlY3QpPVwibW9udGhTZWxlY3RlZCgkZXZlbnQpXCJcbiAgICAob25OYXZIZWFkZXJCdG5DbGljayk9XCJ0b2dnbGVDYWxlbmRhck1vZGUoQ2FsZW5kYXJNb2RlLkRheSlcIlxuICAgIChvbkxlZnROYXYpPVwib25Nb250aENhbGVuZGFyTGVmdENsaWNrKCRldmVudClcIlxuICAgIChvblJpZ2h0TmF2KT1cIm9uTW9udGhDYWxlbmRhclJpZ2h0Q2xpY2soJGV2ZW50KVwiXG4gICAgKG9uTGVmdFNlY29uZGFyeU5hdik9XCJvbk1vbnRoQ2FsZW5kYXJTZWNvbmRhcnlMZWZ0Q2xpY2soJGV2ZW50KVwiXG4gICAgKG9uUmlnaHRTZWNvbmRhcnlOYXYpPVwib25Nb250aENhbGVuZGFyU2Vjb25kYXJ5UmlnaHRDbGljaygkZXZlbnQpXCI+XG48L2RwLW1vbnRoLWNhbGVuZGFyPlxuIl19