ng-devui
Version:
DevUI components based on Angular
246 lines • 50.4 kB
JavaScript
import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, ViewChild } from '@angular/core';
import { I18nService } from 'ng-devui/i18n';
import { fromEvent, Subject } from 'rxjs';
import { debounceTime, takeUntil } from 'rxjs/operators';
import { DatepickerProService } from './../datepicker-pro.service';
import * as i0 from "@angular/core";
import * as i1 from "ng-devui/i18n";
import * as i2 from "./../datepicker-pro.service";
import * as i3 from "@angular/common";
import * as i4 from "@angular/cdk/scrolling";
export class MonthPanelComponent {
get curHoverDate() {
return this.pickerSrv.curHoverDate;
}
set curHoverDate(value) {
this.pickerSrv.curHoverDate = value;
}
get selectedRangeDate() {
return this.pickerSrv.curRangeDate;
}
set selectedRangeDate(dateList) {
this.pickerSrv.curRangeDate = dateList;
}
get currentDate() {
if (this.isRangeType) {
if (this.pickerSrv.currentActiveInput === 'start') {
return this.pickerSrv.curRangeDate[0];
}
else if (this.pickerSrv.currentActiveInput === 'end') {
return this.pickerSrv.curRangeDate[1];
}
}
else {
return this.pickerSrv.curDate;
}
}
set currentDate(value) {
if (this.isRangeType) {
if (this.pickerSrv.currentActiveInput === 'start') {
this.pickerSrv.curRangeDate[0] = value;
}
else if (this.pickerSrv.currentActiveInput === 'end') {
this.pickerSrv.curRangeDate[1] = value;
}
}
else {
this.pickerSrv.curDate = value;
}
}
constructor(i18n, pickerSrv, cdr) {
this.i18n = i18n;
this.pickerSrv = pickerSrv;
this.cdr = cdr;
this.isRangeType = false;
this.unsubscribe$ = new Subject();
this.yearList = [];
this.calenderItemSize = 186;
this.monthList = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[10, 11, 12]
];
}
ngOnInit() {
this.thisMonth = new Date();
this.initList();
this.initObservable();
this.setI18nText();
}
setI18nText() {
this.i18nText = this.i18n.getI18nText().datePickerPro;
this.i18nSubscription = this.i18n.langChange().subscribe((data) => {
this.i18nText = data.datePickerPro;
this.cdr.detectChanges();
});
}
initObservable() {
this.pickerSrv.toggleEvent.pipe(takeUntil(this.unsubscribe$)).subscribe(isOpen => {
if (isOpen) {
setTimeout(() => {
this.goToDate(this.currentDate || new Date());
});
}
if (!this.scrollListener) {
this.initScrollListener();
}
});
this.pickerSrv.updateDateValue.pipe(takeUntil(this.unsubscribe$)).subscribe(res => {
if (res.type === 'range') {
this.pickerSrv.curRangeDate = res.value;
}
else {
this.pickerSrv.curDate = res.value;
}
this.goToDate(this.currentDate || new Date());
this.cdr.detectChanges();
});
this.pickerSrv.activeInputChange.pipe(takeUntil(this.unsubscribe$)).subscribe(type => {
if (type === 'start') {
this.goToDate(this.selectedRangeDate[0] || this.selectedRangeDate[1] || new Date());
}
else {
this.goToDate(this.selectedRangeDate[1] || this.selectedRangeDate[0] || new Date());
}
});
}
initList() {
for (let yearIndex = this.pickerSrv.calendarRange[0]; yearIndex <= this.pickerSrv.calendarRange[1]; yearIndex++) {
this.yearList.push({
year: yearIndex,
active: false
});
}
}
initScrollListener() {
const scrollEle = this.scrollBodyCmp.getElementRef().nativeElement;
this.scrollListener = fromEvent(scrollEle, 'mousewheel').pipe(takeUntil(this.unsubscribe$), debounceTime(180) // 滚动动画时间180,延时保证计算位置的准确
).subscribe(() => {
const offsetY = this.scrollBodyCmp.measureScrollOffset();
// 当面板滚过一半更新面板
this.currentBodyIndex = Math.floor(offsetY / this.calenderItemSize) + (offsetY % this.calenderItemSize > 100 ? 1 : 0);
this.goToListByIndex(this.currentBodyIndex);
this.cdr.detectChanges();
});
}
goToDate(date, scrollBehavior = 'auto') {
if (date) {
const index = date.getFullYear() - this.pickerSrv.calendarRange[0];
this.currentBodyIndex = index;
this.scrollBodyCmp.scrollToIndex(index, scrollBehavior);
this.goToListByIndex(index);
}
}
goToListByIndex(index) {
const indexDelta = Math.abs(this.scrollListCmp.measureScrollOffset() / 30 - index);
this.scrollListCmp.scrollToIndex(index - 4, indexDelta < 12 ? 'smooth' : 'auto');
}
selectMonth(yearIndex, monthIndex) {
if (this.isDisable(yearIndex, monthIndex)) {
return;
}
this.currentDate = new Date(yearIndex, monthIndex - 1, 1);
if (this.isRangeType) {
this.pickerSrv.fixRangeDate();
}
// 非时间模式下选完开始日期跳转到结束日期
if (this.isRangeType) {
if (this.pickerSrv.currentActiveInput === 'start') {
this.pickerSrv.currentActiveInput = 'end';
}
else if (this.pickerSrv.currentActiveInput === 'end' && !this.selectedRangeDate[0]) {
this.pickerSrv.currentActiveInput = 'start';
}
else {
this.pickerSrv.closeDropdownEvent.next(false);
}
}
this.pickerSrv.selectedDateChange.next({
type: this.isRangeType ? 'range' : 'single',
value: this.isRangeType ? this.selectedRangeDate : this.currentDate
});
if (this.pickerSrv.closeAfterSelected) {
this.pickerSrv.closeDropdownEvent.next(false);
}
}
selectYear(yearIndex) {
const isScroll = (yearIndex - this.pickerSrv.calendarRange[0]) - this.currentBodyIndex < 7;
this.goToDate(new Date(yearIndex, 0, 1), isScroll ? 'smooth' : 'auto');
}
isSelected(yearIndex, monthIndex) {
return this.pickerSrv.isMonthActive(yearIndex, monthIndex - 1);
}
isThisMonth(yearIndex, monthIndex) {
return this.thisMonth.getFullYear() === yearIndex && this.thisMonth.getMonth() === monthIndex - 1;
}
isDateInRange(yearIndex, monthIndex) {
const date = new Date(yearIndex, monthIndex - 1, 1);
return this.pickerSrv.isDateInRange(date);
}
isDisable(yearIndex, monthIndex) {
const date = new Date(yearIndex, monthIndex - 1, 1);
return this.pickerSrv.maxDate.getTime() < date.getTime() || this.pickerSrv.minDate.getTime() > date.getTime();
}
isStartDate(yearIndex, monthIndex) {
if (!this.isRangeType) {
return false;
}
const date = new Date(yearIndex, monthIndex - 1, 1);
return this.pickerSrv.isStartDate(date);
}
isEndDate(yearIndex, monthIndex) {
if (!this.isRangeType) {
return false;
}
const date = new Date(yearIndex, monthIndex - 1, 1);
return this.pickerSrv.isEndDate(date);
}
isDateAbandon(yearIndex, monthIndex) {
if (!this.isRangeType || (!this.selectedRangeDate[0] || !this.selectedRangeDate[1])) {
return false;
}
const date = new Date(yearIndex, monthIndex - 1, 1);
return this.pickerSrv.isDateAbandon(date);
}
isDateInSelectRange(yearIndex, monthIndex) {
if (!this.isRangeType) {
return false;
}
const date = new Date(yearIndex, monthIndex - 1, 1);
return this.pickerSrv.isDateInSelectRange(date);
}
isActiveTypeDate(yearIndex, monthIndex) {
if (!this.isRangeType) {
return false;
}
const date = new Date(yearIndex, monthIndex - 1, 1);
return this.pickerSrv.isActiveInputTypeDate(date);
}
setHoverTarget(yearIndex, monthIndex) {
const date = new Date(yearIndex, monthIndex - 1, 1);
if (this.isRangeType && !this.isDisable(yearIndex, monthIndex)) {
this.curHoverDate = date;
}
}
ngOnDestroy() {
this.unsubscribe$.next();
this.unsubscribe$.complete();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MonthPanelComponent, deps: [{ token: i1.I18nService }, { token: i2.DatepickerProService }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.13", type: MonthPanelComponent, selector: "d-month-panel", inputs: { isRangeType: "isRangeType" }, viewQueries: [{ propertyName: "scrollBodyCmp", first: true, predicate: ["scrollBody"], descendants: true }, { propertyName: "scrollListCmp", first: true, predicate: ["scrollList"], descendants: true }], ngImport: i0, template: "<div class=\"devui-month-panel\">\n <cdk-virtual-scroll-viewport #scrollList [itemSize]=\"30\" class=\"devui-year-list\" minBufferPx=\"400\" maxBufferPx=\"600\">\n <div\n class=\"devui-year-list-item\"\n [ngClass]=\"{ 'title-active': index === currentBodyIndex }\"\n *cdkVirtualFor=\"let year of yearList; let index = index\"\n (click)=\"selectYear(year.year)\"\n >\n <p class=\"devui-year-title\">{{ year.year }}</p>\n </div>\n </cdk-virtual-scroll-viewport>\n <div class=\"devui-month-list-wrapper\">\n <cdk-virtual-scroll-viewport #scrollBody [itemSize]=\"calenderItemSize\" class=\"devui-month-list\" minBufferPx=\"400\" maxBufferPx=\"600\">\n <div *cdkVirtualFor=\"let year of yearList; let index = index\">\n <p class=\"devui-table-year-title\">{{ i18nText?.yearDisplay(year.year) }}</p>\n <table\n class=\"devui-month-table\"\n [ngClass]=\"{ 'devui-active-month': index === currentBodyIndex }\"\n (mouseleave)=\"curHoverDate = null\"\n >\n <tbody>\n <tr *ngFor=\"let season of monthList\">\n <td\n *ngFor=\"let month of season\"\n class=\"devui-month-item\"\n [ngClass]=\"{\n 'devui-table-month-selected': isSelected(year.year, month),\n 'devui-table-this-month': isThisMonth(year.year, month),\n 'devui-table-date-inrange': isDateInRange(year.year, month),\n 'devui-table-date-start': isStartDate(year.year, month),\n 'devui-table-date-end': isEndDate(year.year, month),\n 'devui-table-date-abandon-selected': isDateAbandon(year.year, month),\n 'devui-table-date-in-selected-range': isDateInSelectRange(year.year, month),\n 'devui-table-date-active-type': isActiveTypeDate(year.year, month)\n }\"\n >\n <span\n (mouseenter)=\"setHoverTarget(year.year, month)\"\n [ngClass]=\"{ 'devui-disabled': isDisable(year.year, month) }\"\n (click)=\"selectMonth(year.year, month)\"\n >\n {{ i18nText.monthsOfYear[month - 1] }}\n </span>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </cdk-virtual-scroll-viewport>\n </div>\n</div>\n", styles: [".devui-month-panel{height:300px;font-size:0}.devui-month-panel .devui-year-list{padding:8px 0;display:inline-block;width:80px;height:300px;overflow:auto;text-align:center;font-size:12px}.devui-month-panel .devui-year-list::-webkit-scrollbar{width:0!important}.devui-month-panel .devui-year-list-item{height:30px;line-height:30px;background-color:var(--devui-global-bg, #f5f5f5);cursor:pointer}.devui-month-panel .devui-year-list-item.title-active{background-color:var(--devui-base-bg, #ffffff)}.devui-month-panel .devui-year-list-item:hover:not(.title-active){background-color:var(--devui-list-item-selected-bg, #cedefd)}.devui-month-panel .devui-month-list-wrapper{padding:0 4px;display:inline-block}.devui-month-panel .devui-month-list{width:180px;height:295px;font-size:12px}.devui-month-panel .devui-month-list::-webkit-scrollbar{width:0!important}.devui-month-panel .devui-month-list .devui-table-year-title{text-align:start;line-height:26px;color:var(--devui-aide-text, #595959);padding-left:8px}.devui-month-panel .devui-month-list .devui-month-table{border-collapse:collapse}.devui-month-panel .devui-month-list .devui-month-item{width:60px;height:40px;padding:4px 0;box-sizing:border-box;text-align:center;cursor:pointer}.devui-month-panel .devui-month-list .devui-month-item:hover span:not(.devui-disabled){background-color:var(--devui-list-item-hover-bg, #f2f2f3)}.devui-month-panel .devui-month-list .devui-month-item span{display:block;line-height:32px;border-radius:var(--devui-border-radius-feedback, 4px)}.devui-month-panel .devui-month-list .devui-month-item span.devui-disabled{border-radius:0}.devui-month-panel .devui-month-list .devui-month-item.devui-table-this-month span{color:var(--devui-brand, #0a59f7)}.devui-month-panel .devui-month-list .devui-month-item.devui-table-month-selected span{background:var(--devui-list-item-active-bg, #cedefd);color:var(--devui-list-item-active-text, #000000)}.devui-month-panel .devui-month-list .devui-month-item.devui-table-month-selected span:hover{background-color:var(--devui-list-item-active-bg, #cedefd)}.devui-month-panel .devui-month-list .devui-month-item.devui-table-month-selected.devui-table-date-abandon-selected span{background:var(--devui-primary-disabled, #9dbdfc)}.devui-month-panel .devui-month-list .devui-month-item.devui-table-date-inrange:not(.devui-table-month-selected) span{background-color:var(--devui-list-item-hover-bg, #f2f2f3);border-radius:0}.devui-month-panel .devui-month-list .devui-month-item.devui-table-date-start:not(.devui-table-date-end) span{border-radius:var(--devui-border-radius-feedback, 4px) 0 0 var(--devui-border-radius-feedback, 4px)}.devui-month-panel .devui-month-list .devui-month-item.devui-table-date-end:not(.devui-table-date-start) span{border-radius:0 var(--devui-border-radius-feedback, 4px) var(--devui-border-radius-feedback, 4px) 0}.devui-month-panel .devui-month-list .devui-month-item.devui-table-date-in-selected-range:not(.devui-table-date-inrange):not(:hover) span{background-color:var(--devui-disabled-bg, #f3f3f3);border-radius:0}.devui-month-panel .devui-month-list .devui-month-item.devui-table-date-active-type:not(.devui-table-date-abandon-selected) span{animation:2s ease 0s infinite normal both breath-animation}@keyframes breath-animation{0%{box-shadow:0 0 0 var(--devui-list-item-active-bg, #cedefd)}50%{box-shadow:0 0 8px var(--devui-list-item-active-bg, #cedefd)}to{box-shadow:0 0 0 var(--devui-list-item-active-bg, #cedefd)}}\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: i4.CdkFixedSizeVirtualScroll, selector: "cdk-virtual-scroll-viewport[itemSize]", inputs: ["itemSize", "minBufferPx", "maxBufferPx"] }, { kind: "directive", type: i4.CdkVirtualForOf, selector: "[cdkVirtualFor][cdkVirtualForOf]", inputs: ["cdkVirtualForOf", "cdkVirtualForTrackBy", "cdkVirtualForTemplate", "cdkVirtualForTemplateCacheSize"] }, { kind: "component", type: i4.CdkVirtualScrollViewport, selector: "cdk-virtual-scroll-viewport", inputs: ["orientation", "appendOnly"], outputs: ["scrolledIndexChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: MonthPanelComponent, decorators: [{
type: Component,
args: [{ selector: 'd-month-panel', preserveWhitespaces: false, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"devui-month-panel\">\n <cdk-virtual-scroll-viewport #scrollList [itemSize]=\"30\" class=\"devui-year-list\" minBufferPx=\"400\" maxBufferPx=\"600\">\n <div\n class=\"devui-year-list-item\"\n [ngClass]=\"{ 'title-active': index === currentBodyIndex }\"\n *cdkVirtualFor=\"let year of yearList; let index = index\"\n (click)=\"selectYear(year.year)\"\n >\n <p class=\"devui-year-title\">{{ year.year }}</p>\n </div>\n </cdk-virtual-scroll-viewport>\n <div class=\"devui-month-list-wrapper\">\n <cdk-virtual-scroll-viewport #scrollBody [itemSize]=\"calenderItemSize\" class=\"devui-month-list\" minBufferPx=\"400\" maxBufferPx=\"600\">\n <div *cdkVirtualFor=\"let year of yearList; let index = index\">\n <p class=\"devui-table-year-title\">{{ i18nText?.yearDisplay(year.year) }}</p>\n <table\n class=\"devui-month-table\"\n [ngClass]=\"{ 'devui-active-month': index === currentBodyIndex }\"\n (mouseleave)=\"curHoverDate = null\"\n >\n <tbody>\n <tr *ngFor=\"let season of monthList\">\n <td\n *ngFor=\"let month of season\"\n class=\"devui-month-item\"\n [ngClass]=\"{\n 'devui-table-month-selected': isSelected(year.year, month),\n 'devui-table-this-month': isThisMonth(year.year, month),\n 'devui-table-date-inrange': isDateInRange(year.year, month),\n 'devui-table-date-start': isStartDate(year.year, month),\n 'devui-table-date-end': isEndDate(year.year, month),\n 'devui-table-date-abandon-selected': isDateAbandon(year.year, month),\n 'devui-table-date-in-selected-range': isDateInSelectRange(year.year, month),\n 'devui-table-date-active-type': isActiveTypeDate(year.year, month)\n }\"\n >\n <span\n (mouseenter)=\"setHoverTarget(year.year, month)\"\n [ngClass]=\"{ 'devui-disabled': isDisable(year.year, month) }\"\n (click)=\"selectMonth(year.year, month)\"\n >\n {{ i18nText.monthsOfYear[month - 1] }}\n </span>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </cdk-virtual-scroll-viewport>\n </div>\n</div>\n", styles: [".devui-month-panel{height:300px;font-size:0}.devui-month-panel .devui-year-list{padding:8px 0;display:inline-block;width:80px;height:300px;overflow:auto;text-align:center;font-size:12px}.devui-month-panel .devui-year-list::-webkit-scrollbar{width:0!important}.devui-month-panel .devui-year-list-item{height:30px;line-height:30px;background-color:var(--devui-global-bg, #f5f5f5);cursor:pointer}.devui-month-panel .devui-year-list-item.title-active{background-color:var(--devui-base-bg, #ffffff)}.devui-month-panel .devui-year-list-item:hover:not(.title-active){background-color:var(--devui-list-item-selected-bg, #cedefd)}.devui-month-panel .devui-month-list-wrapper{padding:0 4px;display:inline-block}.devui-month-panel .devui-month-list{width:180px;height:295px;font-size:12px}.devui-month-panel .devui-month-list::-webkit-scrollbar{width:0!important}.devui-month-panel .devui-month-list .devui-table-year-title{text-align:start;line-height:26px;color:var(--devui-aide-text, #595959);padding-left:8px}.devui-month-panel .devui-month-list .devui-month-table{border-collapse:collapse}.devui-month-panel .devui-month-list .devui-month-item{width:60px;height:40px;padding:4px 0;box-sizing:border-box;text-align:center;cursor:pointer}.devui-month-panel .devui-month-list .devui-month-item:hover span:not(.devui-disabled){background-color:var(--devui-list-item-hover-bg, #f2f2f3)}.devui-month-panel .devui-month-list .devui-month-item span{display:block;line-height:32px;border-radius:var(--devui-border-radius-feedback, 4px)}.devui-month-panel .devui-month-list .devui-month-item span.devui-disabled{border-radius:0}.devui-month-panel .devui-month-list .devui-month-item.devui-table-this-month span{color:var(--devui-brand, #0a59f7)}.devui-month-panel .devui-month-list .devui-month-item.devui-table-month-selected span{background:var(--devui-list-item-active-bg, #cedefd);color:var(--devui-list-item-active-text, #000000)}.devui-month-panel .devui-month-list .devui-month-item.devui-table-month-selected span:hover{background-color:var(--devui-list-item-active-bg, #cedefd)}.devui-month-panel .devui-month-list .devui-month-item.devui-table-month-selected.devui-table-date-abandon-selected span{background:var(--devui-primary-disabled, #9dbdfc)}.devui-month-panel .devui-month-list .devui-month-item.devui-table-date-inrange:not(.devui-table-month-selected) span{background-color:var(--devui-list-item-hover-bg, #f2f2f3);border-radius:0}.devui-month-panel .devui-month-list .devui-month-item.devui-table-date-start:not(.devui-table-date-end) span{border-radius:var(--devui-border-radius-feedback, 4px) 0 0 var(--devui-border-radius-feedback, 4px)}.devui-month-panel .devui-month-list .devui-month-item.devui-table-date-end:not(.devui-table-date-start) span{border-radius:0 var(--devui-border-radius-feedback, 4px) var(--devui-border-radius-feedback, 4px) 0}.devui-month-panel .devui-month-list .devui-month-item.devui-table-date-in-selected-range:not(.devui-table-date-inrange):not(:hover) span{background-color:var(--devui-disabled-bg, #f3f3f3);border-radius:0}.devui-month-panel .devui-month-list .devui-month-item.devui-table-date-active-type:not(.devui-table-date-abandon-selected) span{animation:2s ease 0s infinite normal both breath-animation}@keyframes breath-animation{0%{box-shadow:0 0 0 var(--devui-list-item-active-bg, #cedefd)}50%{box-shadow:0 0 8px var(--devui-list-item-active-bg, #cedefd)}to{box-shadow:0 0 0 var(--devui-list-item-active-bg, #cedefd)}}\n"] }]
}], ctorParameters: () => [{ type: i1.I18nService }, { type: i2.DatepickerProService }, { type: i0.ChangeDetectorRef }], propDecorators: { scrollBodyCmp: [{
type: ViewChild,
args: ['scrollBody']
}], scrollListCmp: [{
type: ViewChild,
args: ['scrollList']
}], isRangeType: [{
type: Input
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9udGgtcGFuZWwuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vZGV2dWkvZGF0ZXBpY2tlci1wcm8vbGliL21vbnRoLXBhbmVsLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uL2RldnVpL2RhdGVwaWNrZXItcHJvL2xpYi9tb250aC1wYW5lbC5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUNsRSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsS0FBSyxFQUdMLFNBQVMsRUFDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQWlCLFdBQVcsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUMzRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBZ0IsTUFBTSxNQUFNLENBQUM7QUFDeEQsT0FBTyxFQUFFLFlBQVksRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQzs7Ozs7O0FBU25FLE1BQU0sT0FBTyxtQkFBbUI7SUFxQjlCLElBQUksWUFBWTtRQUNkLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUM7SUFDckMsQ0FBQztJQUVELElBQUksWUFBWSxDQUFDLEtBQVc7UUFDMUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLEdBQUcsS0FBSyxDQUFDO0lBQ3RDLENBQUM7SUFFRCxJQUFJLGlCQUFpQjtRQUNuQixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDO0lBQ3JDLENBQUM7SUFFRCxJQUFJLGlCQUFpQixDQUFDLFFBQWdCO1FBQ3BDLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxHQUFHLFFBQVEsQ0FBQztJQUN6QyxDQUFDO0lBRUQsSUFBSSxXQUFXO1FBQ2IsSUFBSSxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDckIsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLGtCQUFrQixLQUFLLE9BQU8sRUFBRSxDQUFDO2dCQUNsRCxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3hDLENBQUM7aUJBQU0sSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLGtCQUFrQixLQUFLLEtBQUssRUFBRSxDQUFDO2dCQUN2RCxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3hDLENBQUM7UUFDSCxDQUFDO2FBQU0sQ0FBQztZQUNOLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUM7UUFDaEMsQ0FBQztJQUNILENBQUM7SUFFRCxJQUFJLFdBQVcsQ0FBQyxLQUFXO1FBQ3pCLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3JCLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxrQkFBa0IsS0FBSyxPQUFPLEVBQUUsQ0FBQztnQkFDbEQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDO1lBQ3pDLENBQUM7aUJBQU0sSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLGtCQUFrQixLQUFLLEtBQUssRUFBRSxDQUFDO2dCQUN2RCxJQUFJLENBQUMsU0FBUyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUM7WUFDekMsQ0FBQztRQUNILENBQUM7YUFBTSxDQUFDO1lBQ04sSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO1FBQ2pDLENBQUM7SUFDSCxDQUFDO0lBRUQsWUFDWSxJQUFpQixFQUNuQixTQUErQixFQUMvQixHQUFzQjtRQUZwQixTQUFJLEdBQUosSUFBSSxDQUFhO1FBQ25CLGNBQVMsR0FBVCxTQUFTLENBQXNCO1FBQy9CLFFBQUcsR0FBSCxHQUFHLENBQW1CO1FBN0R2QixnQkFBVyxHQUFHLEtBQUssQ0FBQztRQUU3QixpQkFBWSxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7UUFLbkMsYUFBUSxHQUFHLEVBQUUsQ0FBQztRQUNkLHFCQUFnQixHQUFHLEdBQUcsQ0FBQztRQUV2QixjQUFTLEdBQUc7WUFDVixDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ1QsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNULENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDVCxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDO1NBQ2IsQ0FBQztJQStDQyxDQUFDO0lBRUosUUFBUTtRQUNOLElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUM1QixJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDaEIsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNyQixDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxhQUFhLENBQUM7UUFDdEQsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUMsU0FBUyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUU7WUFDaEUsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDO1lBQ25DLElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDM0IsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsY0FBYztRQUNaLElBQUksQ0FBQyxTQUFTLENBQUMsV0FBVyxDQUFDLElBQUksQ0FDN0IsU0FBUyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FDN0IsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLEVBQUU7WUFDbkIsSUFBSSxNQUFNLEVBQUUsQ0FBQztnQkFDWCxVQUFVLENBQUMsR0FBRyxFQUFFO29CQUNkLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFdBQVcsSUFBSSxJQUFJLElBQUksRUFBRSxDQUFDLENBQUM7Z0JBQ2hELENBQUMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztZQUNELElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7Z0JBQ3pCLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1lBQzVCLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLElBQUksQ0FDakMsU0FBUyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FDN0IsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDaEIsSUFBSSxHQUFHLENBQUMsSUFBSSxLQUFLLE9BQU8sRUFBRSxDQUFDO2dCQUN6QixJQUFJLENBQUMsU0FBUyxDQUFDLFlBQVksR0FBRyxHQUFHLENBQUMsS0FBZSxDQUFDO1lBQ3BELENBQUM7aUJBQU0sQ0FBQztnQkFDTixJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sR0FBRyxHQUFHLENBQUMsS0FBYSxDQUFDO1lBQzdDLENBQUM7WUFDRCxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxXQUFXLElBQUksSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQzlDLElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDM0IsQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsU0FBUyxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FDbkMsU0FBUyxDQUFDLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FDN0IsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDakIsSUFBSSxJQUFJLEtBQUssT0FBTyxFQUFFLENBQUM7Z0JBQ3JCLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLElBQUksRUFBRSxDQUFDLENBQUM7WUFDdEYsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLElBQUksRUFBRSxDQUFDLENBQUM7WUFDdEYsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELFFBQVE7UUFDTixLQUFLLElBQUksU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxFQUFFLFNBQVMsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsRUFBRSxTQUFTLEVBQUUsRUFBRSxDQUFDO1lBQ2hILElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDO2dCQUNqQixJQUFJLEVBQUUsU0FBUztnQkFDZixNQUFNLEVBQUUsS0FBSzthQUNkLENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDO0lBRUQsa0JBQWtCO1FBQ2hCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsYUFBYSxFQUFFLENBQUMsYUFBYSxDQUFDO1FBQ25FLElBQUksQ0FBQyxjQUFjLEdBQUcsU0FBUyxDQUFDLFNBQVMsRUFBRSxZQUFZLENBQUMsQ0FBQyxJQUFJLENBQzNELFNBQVMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQzVCLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQyx3QkFBd0I7U0FDM0MsQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFO1lBQ2YsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBQ3pELGNBQWM7WUFDZCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN0SCxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQzVDLElBQUksQ0FBQyxHQUFHLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDM0IsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQsUUFBUSxDQUFDLElBQVUsRUFBRSxpQkFBb0MsTUFBTTtRQUM3RCxJQUFJLElBQUksRUFBRSxDQUFDO1lBQ1QsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFdBQVcsRUFBRSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ25FLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxLQUFLLENBQUM7WUFDOUIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLGNBQWMsQ0FBQyxDQUFDO1lBQ3hELElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDOUIsQ0FBQztJQUNILENBQUM7SUFFRCxlQUFlLENBQUMsS0FBSztRQUNuQixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsbUJBQW1CLEVBQUUsR0FBRyxFQUFFLEdBQUcsS0FBSyxDQUFDLENBQUM7UUFDbkYsSUFBSSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUMsS0FBSyxHQUFHLENBQUMsRUFBRSxVQUFVLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ25GLENBQUM7SUFFRCxXQUFXLENBQUMsU0FBaUIsRUFBRSxVQUFrQjtRQUMvQyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxFQUFFLFVBQVUsQ0FBQyxFQUFFLENBQUM7WUFDMUMsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxVQUFVLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBRTFELElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO1lBQ3JCLElBQUksQ0FBQyxTQUFTLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDaEMsQ0FBQztRQUVELHNCQUFzQjtRQUN0QixJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNyQixJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsa0JBQWtCLEtBQUssT0FBTyxFQUFFLENBQUM7Z0JBQ2xELElBQUksQ0FBQyxTQUFTLENBQUMsa0JBQWtCLEdBQUcsS0FBSyxDQUFDO1lBQzVDLENBQUM7aUJBQU0sSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLGtCQUFrQixLQUFLLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUNyRixJQUFJLENBQUMsU0FBUyxDQUFDLGtCQUFrQixHQUFHLE9BQU8sQ0FBQztZQUM5QyxDQUFDO2lCQUFNLENBQUM7Z0JBQ04sSUFBSSxDQUFDLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDaEQsQ0FBQztRQUNILENBQUM7UUFFRCxJQUFJLENBQUMsU0FBUyxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQztZQUNyQyxJQUFJLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxRQUFRO1lBQzNDLEtBQUssRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxXQUFXO1NBQ3BFLENBQUMsQ0FBQztRQUVILElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1lBQ3RDLElBQUksQ0FBQyxTQUFTLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2hELENBQUM7SUFDSCxDQUFDO0lBRUQsVUFBVSxDQUFDLFNBQWlCO1FBQzFCLE1BQU0sUUFBUSxHQUFHLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixHQUFHLENBQUMsQ0FBQztRQUMzRixJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3pFLENBQUM7SUFFRCxVQUFVLENBQUMsU0FBaUIsRUFBRSxVQUFrQjtRQUM5QyxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLFNBQVMsRUFBRSxVQUFVLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDakUsQ0FBQztJQUVELFdBQVcsQ0FBQyxTQUFpQixFQUFFLFVBQWtCO1FBQy9DLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLEVBQUUsS0FBSyxTQUFTLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLEVBQUUsS0FBSyxVQUFVLEdBQUcsQ0FBQyxDQUFDO0lBQ3BHLENBQUM7SUFFRCxhQUFhLENBQUMsU0FBaUIsRUFBRSxVQUFrQjtRQUNqRCxNQUFNLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsVUFBVSxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNwRCxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRCxTQUFTLENBQUMsU0FBaUIsRUFBRSxVQUFrQjtRQUM3QyxNQUFNLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsVUFBVSxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNwRCxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxHQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsR0FBSSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDbEgsQ0FBQztJQUVELFdBQVcsQ0FBQyxTQUFpQixFQUFFLFVBQWtCO1FBQy9DLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDdEIsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO1FBQ0QsTUFBTSxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLFVBQVUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDcEQsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQsU0FBUyxDQUFDLFNBQWlCLEVBQUUsVUFBa0I7UUFDN0MsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUN0QixPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7UUFDRCxNQUFNLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsVUFBVSxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNwRCxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3hDLENBQUM7SUFFRCxhQUFhLENBQUMsU0FBaUIsRUFBRSxVQUFrQjtRQUNqRCxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUNwRixPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7UUFDRCxNQUFNLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsVUFBVSxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNwRCxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRCxtQkFBbUIsQ0FBQyxTQUFpQixFQUFFLFVBQWtCO1FBQ3ZELElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDdEIsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO1FBRUQsTUFBTSxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLFVBQVUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFFcEQsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2xELENBQUM7SUFFRCxnQkFBZ0IsQ0FBQyxTQUFpQixFQUFFLFVBQWtCO1FBQ3BELElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDdEIsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO1FBRUQsTUFBTSxJQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFLFVBQVUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFFcEQsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3BELENBQUM7SUFFRCxjQUFjLENBQUMsU0FBaUIsRUFBRSxVQUFrQjtRQUNsRCxNQUFNLElBQUksR0FBRyxJQUFJLElBQUksQ0FBQyxTQUFTLEVBQUUsVUFBVSxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUNwRCxJQUFJLElBQUksQ0FBQyxXQUFXLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFNBQVMsRUFBRSxVQUFVLENBQUMsRUFBRSxDQUFDO1lBQy9ELElBQUksQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO1FBQzNCLENBQUM7SUFDSCxDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDekIsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUMvQixDQUFDOytHQXhRVSxtQkFBbUI7bUdBQW5CLG1CQUFtQix3U0N0QmhDLCszRUFtREE7OzRGRDdCYSxtQkFBbUI7a0JBUC9CLFNBQVM7K0JBQ0UsZUFBZSx1QkFHSixLQUFLLG1CQUNULHVCQUF1QixDQUFDLE1BQU07bUpBR3RCLGFBQWE7c0JBQXJDLFNBQVM7dUJBQUMsWUFBWTtnQkFDRSxhQUFhO3NCQUFyQyxTQUFTO3VCQUFDLFlBQVk7Z0JBQ2QsV0FBVztzQkFBbkIsS0FBSyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENka1ZpcnR1YWxTY3JvbGxWaWV3cG9ydCB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9zY3JvbGxpbmcnO1xuaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIElucHV0LFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgVmlld0NoaWxkXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgSTE4bkludGVyZmFjZSwgSTE4blNlcnZpY2UgfSBmcm9tICduZy1kZXZ1aS9pMThuJztcbmltcG9ydCB7IGZyb21FdmVudCwgU3ViamVjdCwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBkZWJvdW5jZVRpbWUsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IERhdGVwaWNrZXJQcm9TZXJ2aWNlIH0gZnJvbSAnLi8uLi9kYXRlcGlja2VyLXByby5zZXJ2aWNlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnZC1tb250aC1wYW5lbCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9tb250aC1wYW5lbC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL21vbnRoLXBhbmVsLmNvbXBvbmVudC5zY3NzJ10sXG4gIHByZXNlcnZlV2hpdGVzcGFjZXM6IGZhbHNlLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaFxufSlcbmV4cG9ydCBjbGFzcyBNb250aFBhbmVsQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICBAVmlld0NoaWxkKCdzY3JvbGxCb2R5Jykgc2Nyb2xsQm9keUNtcDogQ2RrVmlydHVhbFNjcm9sbFZpZXdwb3J0O1xuICBAVmlld0NoaWxkKCdzY3JvbGxMaXN0Jykgc2Nyb2xsTGlzdENtcDogQ2RrVmlydHVhbFNjcm9sbFZpZXdwb3J0O1xuICBASW5wdXQoKSBpc1JhbmdlVHlwZSA9IGZhbHNlO1xuXG4gIHVuc3Vic2NyaWJlJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIHNjcm9sbExpc3RlbmVyOiBTdWJzY3JpcHRpb247XG4gIGkxOG5UZXh0OiBJMThuSW50ZXJmYWNlWydkYXRlUGlja2VyUHJvJ107XG4gIGkxOG5TdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcblxuICB5ZWFyTGlzdCA9IFtdO1xuICBjYWxlbmRlckl0ZW1TaXplID0gMTg2O1xuICBjdXJyZW50Qm9keUluZGV4O1xuICBtb250aExpc3QgPSBbXG4gICAgWzEsIDIsIDNdLFxuICAgIFs0LCA1LCA2XSxcbiAgICBbNywgOCwgOV0sXG4gICAgWzEwLCAxMSwgMTJdXG4gIF07XG4gIHRoaXNNb250aDogRGF0ZTtcblxuICBnZXQgY3VySG92ZXJEYXRlKCkge1xuICAgIHJldHVybiB0aGlzLnBpY2tlclNydi5jdXJIb3ZlckRhdGU7XG4gIH1cblxuICBzZXQgY3VySG92ZXJEYXRlKHZhbHVlOiBEYXRlKSB7XG4gICAgdGhpcy5waWNrZXJTcnYuY3VySG92ZXJEYXRlID0gdmFsdWU7XG4gIH1cblxuICBnZXQgc2VsZWN0ZWRSYW5nZURhdGUoKTogRGF0ZVtdIHtcbiAgICByZXR1cm4gdGhpcy5waWNrZXJTcnYuY3VyUmFuZ2VEYXRlO1xuICB9XG5cbiAgc2V0IHNlbGVjdGVkUmFuZ2VEYXRlKGRhdGVMaXN0OiBEYXRlW10pIHtcbiAgICB0aGlzLnBpY2tlclNydi5jdXJSYW5nZURhdGUgPSBkYXRlTGlzdDtcbiAgfVxuXG4gIGdldCBjdXJyZW50RGF0ZSgpOiBEYXRlIHtcbiAgICBpZiAodGhpcy5pc1JhbmdlVHlwZSkge1xuICAgICAgaWYgKHRoaXMucGlja2VyU3J2LmN1cnJlbnRBY3RpdmVJbnB1dCA9PT0gJ3N0YXJ0Jykge1xuICAgICAgICByZXR1cm4gdGhpcy5waWNrZXJTcnYuY3VyUmFuZ2VEYXRlWzBdO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLnBpY2tlclNydi5jdXJyZW50QWN0aXZlSW5wdXQgPT09ICdlbmQnKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnBpY2tlclNydi5jdXJSYW5nZURhdGVbMV07XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB0aGlzLnBpY2tlclNydi5jdXJEYXRlO1xuICAgIH1cbiAgfVxuXG4gIHNldCBjdXJyZW50RGF0ZSh2YWx1ZTogRGF0ZSkge1xuICAgIGlmICh0aGlzLmlzUmFuZ2VUeXBlKSB7XG4gICAgICBpZiAodGhpcy5waWNrZXJTcnYuY3VycmVudEFjdGl2ZUlucHV0ID09PSAnc3RhcnQnKSB7XG4gICAgICAgIHRoaXMucGlja2VyU3J2LmN1clJhbmdlRGF0ZVswXSA9IHZhbHVlO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLnBpY2tlclNydi5jdXJyZW50QWN0aXZlSW5wdXQgPT09ICdlbmQnKSB7XG4gICAgICAgIHRoaXMucGlja2VyU3J2LmN1clJhbmdlRGF0ZVsxXSA9IHZhbHVlO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnBpY2tlclNydi5jdXJEYXRlID0gdmFsdWU7XG4gICAgfVxuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIGkxOG46IEkxOG5TZXJ2aWNlLFxuICAgIHByaXZhdGUgcGlja2VyU3J2OiBEYXRlcGlja2VyUHJvU2VydmljZSxcbiAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWZcbiAgKSB7fVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMudGhpc01vbnRoID0gbmV3IERhdGUoKTtcbiAgICB0aGlzLmluaXRMaXN0KCk7XG4gICAgdGhpcy5pbml0T2JzZXJ2YWJsZSgpO1xuICAgIHRoaXMuc2V0STE4blRleHQoKTtcbiAgfVxuXG4gIHNldEkxOG5UZXh0KCkge1xuICAgIHRoaXMuaTE4blRleHQgPSB0aGlzLmkxOG4uZ2V0STE4blRleHQoKS5kYXRlUGlja2VyUHJvO1xuICAgIHRoaXMuaTE4blN1YnNjcmlwdGlvbiA9IHRoaXMuaTE4bi5sYW5nQ2hhbmdlKCkuc3Vic2NyaWJlKChkYXRhKSA9PiB7XG4gICAgICB0aGlzLmkxOG5UZXh0ID0gZGF0YS5kYXRlUGlja2VyUHJvO1xuICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgIH0pO1xuICB9XG5cbiAgaW5pdE9ic2VydmFibGUoKSB7XG4gICAgdGhpcy5waWNrZXJTcnYudG9nZ2xlRXZlbnQucGlwZShcbiAgICAgIHRha2VVbnRpbCh0aGlzLnVuc3Vic2NyaWJlJCksXG4gICAgKS5zdWJzY3JpYmUoaXNPcGVuID0+IHtcbiAgICAgIGlmIChpc09wZW4pIHtcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgdGhpcy5nb1RvRGF0ZSh0aGlzLmN1cnJlbnREYXRlIHx8IG5ldyBEYXRlKCkpO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGlmICghdGhpcy5zY3JvbGxMaXN0ZW5lcikge1xuICAgICAgICB0aGlzLmluaXRTY3JvbGxMaXN0ZW5lcigpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdGhpcy5waWNrZXJTcnYudXBkYXRlRGF0ZVZhbHVlLnBpcGUoXG4gICAgICB0YWtlVW50aWwodGhpcy51bnN1YnNjcmliZSQpLFxuICAgICkuc3Vic2NyaWJlKHJlcyA9PiB7XG4gICAgICBpZiAocmVzLnR5cGUgPT09ICdyYW5nZScpIHtcbiAgICAgICAgdGhpcy5waWNrZXJTcnYuY3VyUmFuZ2VEYXRlID0gcmVzLnZhbHVlIGFzIERhdGVbXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucGlja2VyU3J2LmN1ckRhdGUgPSByZXMudmFsdWUgYXMgRGF0ZTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZ29Ub0RhdGUodGhpcy5jdXJyZW50RGF0ZSB8fCBuZXcgRGF0ZSgpKTtcbiAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICB9KTtcblxuICAgIHRoaXMucGlja2VyU3J2LmFjdGl2ZUlucHV0Q2hhbmdlLnBpcGUoXG4gICAgICB0YWtlVW50aWwodGhpcy51bnN1YnNjcmliZSQpXG4gICAgKS5zdWJzY3JpYmUodHlwZSA9PiB7XG4gICAgICBpZiAodHlwZSA9PT0gJ3N0YXJ0Jykge1xuICAgICAgICB0aGlzLmdvVG9EYXRlKHRoaXMuc2VsZWN0ZWRSYW5nZURhdGVbMF0gfHwgdGhpcy5zZWxlY3RlZFJhbmdlRGF0ZVsxXSB8fCBuZXcgRGF0ZSgpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuZ29Ub0RhdGUodGhpcy5zZWxlY3RlZFJhbmdlRGF0ZVsxXSB8fCB0aGlzLnNlbGVjdGVkUmFuZ2VEYXRlWzBdIHx8IG5ldyBEYXRlKCkpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgaW5pdExpc3QoKSB7XG4gICAgZm9yIChsZXQgeWVhckluZGV4ID0gdGhpcy5waWNrZXJTcnYuY2FsZW5kYXJSYW5nZVswXTsgeWVhckluZGV4IDw9IHRoaXMucGlja2VyU3J2LmNhbGVuZGFyUmFuZ2VbMV07IHllYXJJbmRleCsrKSB7XG4gICAgICB0aGlzLnllYXJMaXN0LnB1c2goe1xuICAgICAgICB5ZWFyOiB5ZWFySW5kZXgsXG4gICAgICAgIGFjdGl2ZTogZmFsc2VcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGluaXRTY3JvbGxMaXN0ZW5lcigpIHtcbiAgICBjb25zdCBzY3JvbGxFbGUgPSB0aGlzLnNjcm9sbEJvZHlDbXAuZ2V0RWxlbWVudFJlZigpLm5hdGl2ZUVsZW1lbnQ7XG4gICAgdGhpcy5zY3JvbGxMaXN0ZW5lciA9IGZyb21FdmVudChzY3JvbGxFbGUsICdtb3VzZXdoZWVsJykucGlwZShcbiAgICAgIHRha2VVbnRpbCh0aGlzLnVuc3Vic2NyaWJlJCksXG4gICAgICBkZWJvdW5jZVRpbWUoMTgwKSAvLyDmu5rliqjliqjnlLvml7bpl7QxODDvvIzlu7bml7bkv53or4HorqHnrpfkvY3nva7nmoTlh4bnoa5cbiAgICApLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICBjb25zdCBvZmZzZXRZID0gdGhpcy5zY3JvbGxCb2R5Q21wLm1lYXN1cmVTY3JvbGxPZmZzZXQoKTtcbiAgICAgIC8vIOW9k+mdouadv+a7mui/h+S4gOWNiuabtOaWsOmdouadv1xuICAgICAgdGhpcy5jdXJyZW50Qm9keUluZGV4ID0gTWF0aC5mbG9vcihvZmZzZXRZIC8gdGhpcy5jYWxlbmRlckl0ZW1TaXplKSArIChvZmZzZXRZICUgdGhpcy5jYWxlbmRlckl0ZW1TaXplID4gMTAwID8gMSA6IDApO1xuICAgICAgdGhpcy5nb1RvTGlzdEJ5SW5kZXgodGhpcy5jdXJyZW50Qm9keUluZGV4KTtcbiAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICB9KTtcbiAgfVxuXG4gIGdvVG9EYXRlKGRhdGU6IERhdGUsIHNjcm9sbEJlaGF2aW9yOiAnYXV0bycgfCAnc21vb3RoJyA9ICdhdXRvJykge1xuICAgIGlmIChkYXRlKSB7XG4gICAgICBjb25zdCBpbmRleCA9IGRhdGUuZ2V0RnVsbFllYXIoKSAtIHRoaXMucGlja2VyU3J2LmNhbGVuZGFyUmFuZ2VbMF07XG4gICAgICB0aGlzLmN1cnJlbnRCb2R5SW5kZXggPSBpbmRleDtcbiAgICAgIHRoaXMuc2Nyb2xsQm9keUNtcC5zY3JvbGxUb0luZGV4KGluZGV4LCBzY3JvbGxCZWhhdmlvcik7XG4gICAgICB0aGlzLmdvVG9MaXN0QnlJbmRleChpbmRleCk7XG4gICAgfVxuICB9XG5cbiAgZ29Ub0xpc3RCeUluZGV4KGluZGV4KSB7XG4gICAgY29uc3QgaW5kZXhEZWx0YSA9IE1hdGguYWJzKHRoaXMuc2Nyb2xsTGlzdENtcC5tZWFzdXJlU2Nyb2xsT2Zmc2V0KCkgLyAzMCAtIGluZGV4KTtcbiAgICB0aGlzLnNjcm9sbExpc3RDbXAuc2Nyb2xsVG9JbmRleChpbmRleCAtIDQsIGluZGV4RGVsdGEgPCAxMiA/ICdzbW9vdGgnIDogJ2F1dG8nKTtcbiAgfVxuXG4gIHNlbGVjdE1vbnRoKHllYXJJbmRleDogbnVtYmVyLCBtb250aEluZGV4OiBudW1iZXIpIHtcbiAgICBpZiAodGhpcy5pc0Rpc2FibGUoeWVhckluZGV4LCBtb250aEluZGV4KSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmN1cnJlbnREYXRlID0gbmV3IERhdGUoeWVhckluZGV4LCBtb250aEluZGV4IC0gMSwgMSk7XG5cbiAgICBpZiAodGhpcy5pc1JhbmdlVHlwZSkge1xuICAgICAgdGhpcy5waWNrZXJTcnYuZml4UmFuZ2VEYXRlKCk7XG4gICAgfVxuXG4gICAgLy8g6Z2e5pe26Ze05qih5byP5LiL6YCJ5a6M5byA5aeL5pel5pyf6Lez6L2s5Yiw57uT5p2f5pel5pyfXG4gICAgaWYgKHRoaXMuaXNSYW5nZVR5cGUpIHtcbiAgICAgIGlmICh0aGlzLnBpY2tlclNydi5jdXJyZW50QWN0aXZlSW5wdXQgPT09ICdzdGFydCcpIHtcbiAgICAgICAgdGhpcy5waWNrZXJTcnYuY3VycmVudEFjdGl2ZUlucHV0ID0gJ2VuZCc7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMucGlja2VyU3J2LmN1cnJlbnRBY3RpdmVJbnB1dCA9PT0gJ2VuZCcgJiYgIXRoaXMuc2VsZWN0ZWRSYW5nZURhdGVbMF0pIHtcbiAgICAgICAgdGhpcy5waWNrZXJTcnYuY3VycmVudEFjdGl2ZUlucHV0ID0gJ3N0YXJ0JztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMucGlja2VyU3J2LmNsb3NlRHJvcGRvd25FdmVudC5uZXh0KGZhbHNlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnBpY2tlclNydi5zZWxlY3RlZERhdGVDaGFuZ2UubmV4dCh7XG4gICAgICB0eXBlOiB0aGlzLmlzUmFuZ2VUeXBlID8gJ3JhbmdlJyA6ICdzaW5nbGUnLFxuICAgICAgdmFsdWU6IHRoaXMuaXNSYW5nZVR5cGUgPyB0aGlzLnNlbGVjdGVkUmFuZ2VEYXRlIDogdGhpcy5jdXJyZW50RGF0ZVxuICAgIH0pO1xuXG4gICAgaWYgKHRoaXMucGlja2VyU3J2LmNsb3NlQWZ0ZXJTZWxlY3RlZCkge1xuICAgICAgdGhpcy5waWNrZXJTcnYuY2xvc2VEcm9wZG93bkV2ZW50Lm5leHQoZmFsc2UpO1xuICAgIH1cbiAgfVxuXG4gIHNlbGVjdFllYXIoeWVhckluZGV4OiBudW1iZXIpIHtcbiAgICBjb25zdCBpc1Njcm9sbCA9ICh5ZWFySW5kZXggLSB0aGlzLnBpY2tlclNydi5jYWxlbmRhclJhbmdlWzBdKSAtIHRoaXMuY3VycmVudEJvZHlJbmRleCA8IDc7XG4gICAgdGhpcy5nb1RvRGF0ZShuZXcgRGF0ZSh5ZWFySW5kZXgsIDAsIDEpLCBpc1Njcm9sbCA/ICdzbW9vdGgnIDogJ2F1dG8nKTtcbiAgfVxuXG4gIGlzU2VsZWN0ZWQoeWVhckluZGV4OiBudW1iZXIsIG1vbnRoSW5kZXg6IG51bWJlcikge1xuICAgIHJldHVybiB0aGlzLnBpY2tlclNydi5pc01vbnRoQWN0aXZlKHllYXJJbmRleCwgbW9udGhJbmRleCAtIDEpO1xuICB9XG5cbiAgaXNUaGlzTW9udGgoeWVhckluZGV4OiBudW1iZXIsIG1vbnRoSW5kZXg6IG51bWJlcikge1xuICAgIHJldHVybiB0aGlzLnRoaXNNb250aC5nZXRGdWxsWWVhcigpID09PSB5ZWFySW5kZXggJiYgdGhpcy50aGlzTW9udGguZ2V0TW9udGgoKSA9PT0gbW9udGhJbmRleCAtIDE7XG4gIH1cblxuICBpc0RhdGVJblJhbmdlKHllYXJJbmRleDogbnVtYmVyLCBtb250aEluZGV4OiBudW1iZXIpIHtcbiAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoeWVhckluZGV4LCBtb250aEluZGV4IC0gMSwgMSk7XG4gICAgcmV0dXJuIHRoaXMucGlja2VyU3J2LmlzRGF0ZUluUmFuZ2UoZGF0ZSk7XG4gIH1cblxuICBpc0Rpc2FibGUoeWVhckluZGV4OiBudW1iZXIsIG1vbnRoSW5kZXg6IG51bWJlcikge1xuICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSh5ZWFySW5kZXgsIG1vbnRoSW5kZXggLSAxLCAxKTtcbiAgICByZXR1cm4gdGhpcy5waWNrZXJTcnYubWF4RGF0ZS5nZXRUaW1lKCkgPCAgZGF0ZS5nZXRUaW1lKCkgfHwgdGhpcy5waWNrZXJTcnYubWluRGF0ZS5nZXRUaW1lKCkgPiAgZGF0ZS5nZXRUaW1lKCk7XG4gIH1cblxuICBpc1N0YXJ0RGF0ZSh5ZWFySW5kZXg6IG51bWJlciwgbW9udGhJbmRleDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgaWYgKCF0aGlzLmlzUmFuZ2VUeXBlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSh5ZWFySW5kZXgsIG1vbnRoSW5kZXggLSAxLCAxKTtcbiAgICByZXR1cm4gdGhpcy5waWNrZXJTcnYuaXNTdGFydERhdGUoZGF0ZSk7XG4gIH1cblxuICBpc0VuZERhdGUoeWVhckluZGV4OiBudW1iZXIsIG1vbnRoSW5kZXg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIGlmICghdGhpcy5pc1JhbmdlVHlwZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoeWVhckluZGV4LCBtb250aEluZGV4IC0gMSwgMSk7XG4gICAgcmV0dXJuIHRoaXMucGlja2VyU3J2LmlzRW5kRGF0ZShkYXRlKTtcbiAgfVxuXG4gIGlzRGF0ZUFiYW5kb24oeWVhckluZGV4OiBudW1iZXIsIG1vbnRoSW5kZXg6IG51bWJlcikge1xuICAgIGlmICghdGhpcy5pc1JhbmdlVHlwZSB8fCAoIXRoaXMuc2VsZWN0ZWRSYW5nZURhdGVbMF0gfHwgIXRoaXMuc2VsZWN0ZWRSYW5nZURhdGVbMV0pKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSh5ZWFySW5kZXgsIG1vbnRoSW5kZXggLSAxLCAxKTtcbiAgICByZXR1cm4gdGhpcy5waWNrZXJTcnYuaXNEYXRlQWJhbmRvbihkYXRlKTtcbiAgfVxuXG4gIGlzRGF0ZUluU2VsZWN0UmFuZ2UoeWVhckluZGV4OiBudW1iZXIsIG1vbnRoSW5kZXg6IG51bWJlcikge1xuICAgIGlmICghdGhpcy5pc1JhbmdlVHlwZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IGRhdGUgPSBuZXcgRGF0ZSh5ZWFySW5kZXgsIG1vbnRoSW5kZXggLSAxLCAxKTtcblxuICAgIHJldHVybiB0aGlzLnBpY2tlclNydi5pc0RhdGVJblNlbGVjdFJhbmdlKGRhdGUpO1xuICB9XG5cbiAgaXNBY3RpdmVUeXBlRGF0ZSh5ZWFySW5kZXg6IG51bWJlciwgbW9udGhJbmRleDogbnVtYmVyKSB7XG4gICAgaWYgKCF0aGlzLmlzUmFuZ2VUeXBlKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgY29uc3QgZGF0ZSA9IG5ldyBEYXRlKHllYXJJbmRleCwgbW9udGhJbmRleCAtIDEsIDEpO1xuXG4gICAgcmV0dXJuIHRoaXMucGlja2VyU3J2LmlzQWN0aXZlSW5wdXRUeXBlRGF0ZShkYXRlKTtcbiAgfVxuXG4gIHNldEhvdmVyVGFyZ2V0KHllYXJJbmRleDogbnVtYmVyLCBtb250aEluZGV4OiBudW1iZXIpIHtcbiAgICBjb25zdCBkYXRlID0gbmV3IERhdGUoeWVhckluZGV4LCBtb250aEluZGV4IC0gMSwgMSk7XG4gICAgaWYgKHRoaXMuaXNSYW5nZVR5cGUgJiYgIXRoaXMuaXNEaXNhYmxlKHllYXJJbmRleCwgbW9udGhJbmRleCkpIHtcbiAgICAgIHRoaXMuY3VySG92ZXJEYXRlID0gZGF0ZTtcbiAgICB9XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLnVuc3Vic2NyaWJlJC5uZXh0KCk7XG4gICAgdGhpcy51bnN1YnNjcmliZSQuY29tcGxldGUoKTtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cImRldnVpLW1vbnRoLXBhbmVsXCI+XG4gIDxjZGstdmlydHVhbC1zY3JvbGwtdmlld3BvcnQgI3Njcm9sbExpc3QgW2l0ZW1TaXplXT1cIjMwXCIgY2xhc3M9XCJkZXZ1aS15ZWFyLWxpc3RcIiBtaW5CdWZmZXJQeD1cIjQwMFwiIG1heEJ1ZmZlclB4PVwiNjAwXCI+XG4gICAgPGRpdlxuICAgICAgY2xhc3M9XCJkZXZ1aS15ZWFyLWxpc3QtaXRlbVwiXG4gICAgICBbbmdDbGFzc109XCJ7ICd0aXRsZS1hY3RpdmUnOiBpbmRleCA9PT0gY3VycmVudEJvZHlJbmRleCB9XCJcbiAgICAgICpjZGtWaXJ0dWFsRm9yPVwibGV0IHllYXIgb2YgeWVhckxpc3Q7IGxldCBpbmRleCA9IGluZGV4XCJcbiAgICAgIChjbGljayk9XCJzZWxlY3RZZWFyKHllYXIueWVhcilcIlxuICAgID5cbiAgICAgIDxwIGNsYXNzPVwiZGV2dWkteWVhci10aXRsZVwiPnt7IHllYXIueWVhciB9fTwvcD5cbiAgICA8L2Rpdj5cbiAgPC9jZGstdmlydHVhbC1zY3JvbGwtdmlld3BvcnQ+XG4gIDxkaXYgY2xhc3M9XCJkZXZ1aS1tb250aC1saXN0LXdyYXBwZXJcIj5cbiAgICA8Y2RrLXZpcnR1YWwtc2Nyb2xsLXZpZXdwb3J0ICNzY3JvbGxCb2R5IFtpdGVtU2l6ZV09XCJjYWxlbmRlckl0ZW1TaXplXCIgY2xhc3M9XCJkZXZ1aS1tb250aC1saXN0XCIgbWluQnVmZmVyUHg9XCI0MDBcIiBtYXhCdWZmZXJQeD1cIjYwMFwiPlxuICAgICAgPGRpdiAqY2RrVmlydHVhbEZvcj1cImxldCB5ZWFyIG9mIHllYXJMaXN0OyBsZXQgaW5kZXggPSBpbmRleFwiPlxuICAgICAgICA8cCBjbGFzcz1cImRldnVpLXRhYmxlLXllYXItdGl0bGVcIj57eyBpMThuVGV4dD8ueWVhckRpc3BsYXkoeWVhci55ZWFyKSB9fTwvcD5cbiAgICAgICAgPHRhYmxlXG4gICAgICAgICAgY2xhc3M9XCJkZXZ1aS1tb250aC10YWJsZVwiXG4gICAgICAgICAgW25nQ2xhc3NdPVwieyAnZGV2dWktYWN0aXZlLW1vbnRoJzogaW5kZXggPT09IGN1cnJlbnRCb2R5SW5kZXggfVwiXG4gICAgICAgICAgKG1vdXNlbGVhdmUpPVwiY3VySG92ZXJEYXRlID0gbnVsbFwiXG4gICAgICAgID5cbiAgICAgICAgICA8dGJvZHk+XG4gICAgICAgICAgICA8dHIgKm5nRm9yPVwibGV0IHNlYXNvbiBvZiBtb250aExpc3RcIj5cbiAgICAgICAgICAgICAgPHRkXG4gICAgICAgICAgICAgICAgKm5nRm9yPVwibGV0IG1vbnRoIG9mIHNlYXNvblwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJkZXZ1aS1tb250aC1pdGVtXCJcbiAgICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7XG4gICAgICAgICAgICAgICAgICAnZGV2dWktdGFibGUtbW9udGgtc2VsZWN0ZWQnOiBpc1NlbGVjdGVkKHllYXIueWVhciwgbW9udGgpLFxuICAgICAgICAgICAgICAgICAgJ2RldnVpLXRhYmxlLXRoaXMtbW9udGgnOiBpc1RoaXNNb250aCh5ZWFyLnllYXIsIG1vbnRoKSxcbiAgICAgICAgICAgICAgICAgICdkZXZ1aS10YWJsZS1kYXRlLWlucmFuZ2UnOiBpc0RhdGVJblJhbmdlKHllYXIueWVhciwgbW9udGgpLFxuICAgICAgICAgICAgICAgICAgJ2RldnVpLXRhYmxlLWRhdGUtc3RhcnQnOiBpc1N0YXJ0RGF0ZSh5ZWFyLnllYXIsIG1vbnRoKSxcbiAgICAgICAgICAgICAgICAgICdkZXZ1aS10YWJsZS1kYXRlLWVuZCc6IGlzRW5kRGF0ZSh5ZWFyLnllYXIsIG1vbnRoKSxcbiAgICAgICAgICAgICAgICAgICdkZXZ1aS10YWJsZS1kYXRlLWFiYW5kb24tc2VsZWN0ZWQnOiBpc0RhdGVBYmFuZG9uKHllYXIueWVhciwgbW9udGgpLFxuICAgICAgICAgICAgICAgICAgJ2RldnVpLXRhYmxlLWRhdGUtaW4tc2VsZWN0ZWQtcmFuZ2UnOiBpc0RhdGVJblNlbGVjdFJhbmdlKHllYXIueWVhciwgbW9udGgpLFxuICAgICAgICAgICAgICAgICAgJ2RldnVpLXRhYmxlLWRhdGUtYWN0aXZlLXR5cGUnOiBpc0FjdGl2ZVR5cGVEYXRlKHllYXIueWVhciwgbW9udGgpXG4gICAgICAgICAgICAgICAgfVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICAgICAgKG1vdXNlZW50ZXIpPVwic2V0SG92ZXJUYXJnZXQoeWVhci55ZWFyLCBtb250aClcIlxuICAgICAgICAgICAgICAgICAgW25nQ2xhc3NdPVwieyAnZGV2dWktZGlzYWJsZWQnOiBpc0Rpc2FibGUoeWVhci55ZWFyLCBtb250aCkgfVwiXG4gICAgICAgICAgICAgICAgICAoY2xpY2spPVwic2VsZWN0TW9udGgoeWVhci55ZWFyLCBtb250aClcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIHt