UNPKG

@bimeister/pupakit.forms

Version:
260 lines 47.5 kB
import { DatePipe } from '@angular/common'; import { Directive, HostListener, Input, Optional, ViewChild } from '@angular/core'; import { NgControl } from '@angular/forms'; import { TimeDigitFormatPipe } from '@bimeister/pupakit.common'; import { filterNotNil, filterTruthy, isEmpty, isNil } from '@bimeister/utilities'; import { BehaviorSubject, combineLatest } from 'rxjs'; import { distinctUntilChanged, filter, map, take, withLatestFrom } from 'rxjs/operators'; import { DroppableComponent } from '../../../components/droppable/components/droppable/droppable.component'; import { dateClearTime } from '../../functions/date-clear-time.function'; import { getDaysInMonth } from '../../functions/get-days-in-month.function'; import '../../interfaces/parsed-date-data.interface'; import '../../types/input-value.type'; import { InputDateTimeHelper } from '../input-date-time-helper.class'; import { InputBase } from './input-base.abstract'; import * as i0 from "@angular/core"; import * as i1 from "@bimeister/pupakit.common"; import * as i2 from "@angular/common"; import * as i3 from "@angular/forms"; const DEFAULT_DATE = new Date(); const DEFAULT_CURRENT_DATE_WITH_CLEARED_TIME = dateClearTime(DEFAULT_DATE); const DATE_FORMAT = 'dd.MM.yyyy'; const MAX_HOURS = 23; const MAX_MINUTES = 59; const MAX_SECONDS = 59; const PLACEHOLDER_DATE = '00.00.0000'; const SIZE_PLACEHOLDER_DATE = PLACEHOLDER_DATE.length; const PLACEHOLDER_TIME = '00:00:00'; const SIZE_PLACEHOLDER_TIME = PLACEHOLDER_TIME.length; const MONTH_START_VALUE = 0; const MONTH_END_VALUE = 11; const HOUR_START_POSITION = 0; const HOUR_END_POSITION = 2; const MINUTES_START_POSITION = 3; const MINUTES_END_POSITION = 5; const SECONDS_START_POSITION = 6; const SECONDS_END_POSITION = 8; export class InputDateTimeBase extends InputBase { constructor(timeFormatPipe, datePipe, ngControl) { super(ngControl); this.timeFormatPipe = timeFormatPipe; this.datePipe = datePipe; this.isFixedSize = true; this.isFixedSize$ = new BehaviorSubject(true); this.isBackDating = true; this.isBackDating$ = new BehaviorSubject(true); this.availableEndDate = Infinity; this.availableEndDate$ = new BehaviorSubject(Infinity); this.isIconHovered$ = new BehaviorSubject(false); this.valueIsNotEmpty$ = this.value$.pipe(map((value) => !isEmpty(value))); this.dateToResetSwitcherEnabled$ = combineLatest([ this.isIconHovered$, this.valueIsNotEmpty$, this.withReset$, ]).pipe(map(([isIconHovered, valueIsNotEmpty, withReset]) => isIconHovered && valueIsNotEmpty && withReset)); this.hours$ = this.value$.pipe(map((value) => !isEmpty(value) && value.length >= HOUR_END_POSITION ? Number(value.slice(HOUR_START_POSITION, HOUR_END_POSITION)) : -1), filterNotNil(), filter((hours) => hours <= MAX_HOURS)); this.minutes$ = this.value$.pipe(map((value) => !isEmpty(value) && value.length >= MINUTES_END_POSITION ? Number(value.slice(MINUTES_START_POSITION, MINUTES_END_POSITION)) : -1), filterNotNil(), filter((minutes) => minutes <= MAX_MINUTES)); this.seconds$ = this.value$.pipe(map((value) => !isEmpty(value) && value.length === SECONDS_END_POSITION ? Number(value.slice(SECONDS_START_POSITION)) : -1), filterNotNil(), filter((minutes) => minutes <= MAX_SECONDS)); this.date$ = this.value$.pipe(filterNotNil(), distinctUntilChanged(), filter((value) => isEmpty(value) || value.length >= SIZE_PLACEHOLDER_DATE), map((value) => value.slice(0, SIZE_PLACEHOLDER_DATE)), map((value) => this.getParsedDate(value)), withLatestFrom(combineLatest([this.isBackDating$, this.availableEndDate$])), filter(([date, [isBackDating, availableEndDate]]) => !this.dateIsNotAvailable(date, isBackDating, availableEndDate)), map(([date, _]) => date)); this.rightIconWithCondition$ = combineLatest([ this.rightIcon$, this.dateToResetSwitcherEnabled$, ]).pipe(map(([rightIcon, dateToResetSwitcherEnabled]) => { if (dateToResetSwitcherEnabled) { return 'm-abort'; } return isEmpty(rightIcon) ? 'm-calendar' : rightIcon; })); } processWindowClick() { this.isFocused$.next(false); } handleContainerClick(event) { this.isDisabled$ .pipe(take(1), map((isDisabled) => isDisabled || this.droppableComponent.isOpened), filterTruthy()) .subscribe(() => event.stopPropagation()); } handleContainerStartEvents(event) { if (!this.droppableComponent.isOpened) { return; } event.stopPropagation(); } selectHours(hours) { this.value$.pipe(take(1)).subscribe((value) => { const parsedHours = InputDateTimeHelper.getUpdatedValueStringAfterSelectHours(hours, value); this.updateValue(parsedHours); }); } selectMinutes(minutes) { this.value$.pipe(take(1)).subscribe((value) => { const parsedMinutes = InputDateTimeHelper.getUpdatedValueStringAfterSelectMinutes(minutes, value); this.updateValue(parsedMinutes); }); } selectSeconds(seconds) { this.value$.pipe(take(1)).subscribe((value) => { const parsedSeconds = InputDateTimeHelper.getUpdatedValueStringAfterSelectSeconds(seconds, value); this.updateValue(parsedSeconds); }); } selectDateTimeHours(hours) { this.value$.pipe(take(1)).subscribe((value) => { const valueTime = isNil(value) ? '' : value.slice(SIZE_PLACEHOLDER_DATE).trim(); const parsedHours = InputDateTimeHelper.getUpdatedValueStringAfterSelectHours(hours, valueTime); const transformedHours = parsedHours.slice(0, SIZE_PLACEHOLDER_TIME); if (isNil(value) || value.length < SIZE_PLACEHOLDER_DATE) { const parsedDefaultDate = this.datePipe.transform(DEFAULT_DATE, DATE_FORMAT); this.updateValue(`${parsedDefaultDate} ${transformedHours}`); return; } const addedExistingValueInput = value.slice(0, SIZE_PLACEHOLDER_DATE); this.updateValue(`${addedExistingValueInput} ${transformedHours}`); }); } selectDateTimeMinutes(minutes) { this.value$.pipe(take(1)).subscribe((value) => { const valueTime = isNil(value) ? '' : value.slice(SIZE_PLACEHOLDER_DATE).trim(); const parsedMinutes = InputDateTimeHelper.getUpdatedValueStringAfterSelectMinutes(minutes, valueTime); const transformedMinutes = parsedMinutes.slice(0, SIZE_PLACEHOLDER_TIME); if (isNil(value) || value.length < SIZE_PLACEHOLDER_DATE) { const parsedDefaultDate = this.datePipe.transform(DEFAULT_DATE, DATE_FORMAT); this.updateValue(`${parsedDefaultDate} ${transformedMinutes}`); return; } const addedExistingValueInput = value.slice(0, SIZE_PLACEHOLDER_DATE); this.updateValue(`${addedExistingValueInput} ${transformedMinutes}`); }); } selectDateTimeSeconds(seconds) { this.value$.pipe(take(1)).subscribe((value) => { const valueTime = isNil(value) ? '' : value.slice(SIZE_PLACEHOLDER_DATE).trim(); const parsedSeconds = InputDateTimeHelper.getUpdatedValueStringAfterSelectSeconds(seconds, valueTime); const transformedSeconds = parsedSeconds.slice(0, SIZE_PLACEHOLDER_TIME); if (isNil(value) || value.length < SIZE_PLACEHOLDER_DATE) { const parsedDefaultDate = this.datePipe.transform(DEFAULT_DATE, DATE_FORMAT); this.updateValue(`${parsedDefaultDate} ${transformedSeconds}`); return; } const addedExistingValueInput = value.slice(0, SIZE_PLACEHOLDER_DATE); this.updateValue(`${addedExistingValueInput} ${transformedSeconds}`); }); } selectDate(selectedDate) { this.value$.pipe(take(1)).subscribe((value) => { const day = selectedDate.getDate(); const month = selectedDate.getMonth() + 1; const year = selectedDate.getFullYear(); const parsedDay = this.timeFormatPipe.transform(day); const parsedMonth = this.timeFormatPipe.transform(month); const dateInputString = `${parsedDay}.${parsedMonth}.${year}`; const addedExistingValueInput = isNil(value) ? '' : value.slice(SIZE_PLACEHOLDER_DATE); this.updateValue(`${dateInputString}${addedExistingValueInput}`); }); } selectRange(range) { const firstDate = range[0]; const secondDate = range[1]; const convertedFirstDate = this.datePipe.transform(firstDate, DATE_FORMAT); const convertedSecondDate = this.datePipe.transform(secondDate, DATE_FORMAT); const isRangeCorrect = firstDate <= secondDate; const updatedValue = isRangeCorrect ? `${convertedFirstDate} - ${convertedSecondDate}` : `${convertedSecondDate} - ${convertedFirstDate}`; this.updateValue(updatedValue); } getParsedDate(value) { const { day, month, year } = InputDateTimeHelper.getParsedDateData(value); const convertedYear = Number(year); const convertedMonth = Number(month) - 1; const convertedDay = Number(day); if (convertedMonth > MONTH_END_VALUE || convertedMonth < MONTH_START_VALUE) { return null; } const testDate = new Date(convertedYear, convertedMonth, 1); const daysInMonth = getDaysInMonth(testDate); if (convertedDay > daysInMonth) { return null; } const date = new Date(convertedYear, convertedMonth, convertedDay); return date; } ngOnChanges(changes) { this.processIsFixedSizeChange(changes?.isFixedSize); this.processIsBackDatingChange(changes?.isBackDating); this.processAvailableEndDateChange(changes?.availableEndDate); super.ngOnChanges(changes); } setValue(value) { const serializedValue = isNil(value) ? '' : String(value); this.value$.next(serializedValue); } handleFocusEvent(focusEvent) { focusEvent.stopPropagation(); this.emitFocusEvent(focusEvent); } handleIconHover(focusEvent, isHovered) { focusEvent.stopPropagation(); this.isIconHovered$.next(isHovered); } reset() { this.withReset$.pipe(take(1), filterTruthy()).subscribe(() => this.updateValue('')); this.inputElementRef.nativeElement.focus(); } clearInputValue() { combineLatest([this.isIconHovered$, this.valueIsNotEmpty$, this.isValid$]) .pipe(take(1), filter(([isIconHovered, valueIsNotEmpty, isValid]) => isIconHovered && valueIsNotEmpty && isValid)) .subscribe(() => this.updateValue('')); } dateIsNotAvailable(date, isBackDating, availableEndDate) { return (!isBackDating && date < DEFAULT_CURRENT_DATE_WITH_CLEARED_TIME) || date > availableEndDate; } processIsFixedSizeChange(change) { const updatedValue = change?.currentValue; if (isNil(updatedValue)) { return; } this.isFixedSize$.next(updatedValue); } processIsBackDatingChange(change) { const updatedValue = change?.currentValue; if (isNil(updatedValue)) { return; } this.isBackDating$.next(updatedValue); } processAvailableEndDateChange(change) { const updatedValue = change?.currentValue; if (isNil(updatedValue)) { return; } this.availableEndDate$.next(updatedValue); } } InputDateTimeBase.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: InputDateTimeBase, deps: [{ token: i1.TimeDigitFormatPipe }, { token: i2.DatePipe }, { token: i3.NgControl, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); InputDateTimeBase.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "14.2.12", type: InputDateTimeBase, inputs: { isFixedSize: "isFixedSize", isBackDating: "isBackDating", availableEndDate: "availableEndDate" }, host: { listeners: { "window:click": "processWindowClick()", "window:touchstart": "processWindowClick()" } }, viewQueries: [{ propertyName: "droppableComponent", first: true, predicate: ["droppable"], descendants: true, static: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: InputDateTimeBase, decorators: [{ type: Directive }], ctorParameters: function () { return [{ type: i1.TimeDigitFormatPipe }, { type: i2.DatePipe }, { type: i3.NgControl, decorators: [{ type: Optional }] }]; }, propDecorators: { droppableComponent: [{ type: ViewChild, args: ['droppable', { static: true }] }], isFixedSize: [{ type: Input }], isBackDating: [{ type: Input }], availableEndDate: [{ type: Input }], processWindowClick: [{ type: HostListener, args: ['window:click'] }, { type: HostListener, args: ['window:touchstart'] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5wdXQtZGF0ZS10aW1lLWJhc2UuYWJzdHJhY3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvZGVjbGFyYXRpb25zL2NsYXNzZXMvYWJzdHJhY3QvaW5wdXQtZGF0ZS10aW1lLWJhc2UuYWJzdHJhY3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzNDLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBYSxRQUFRLEVBQUUsU0FBUyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQy9GLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMzQyxPQUFPLEVBQXFDLG1CQUFtQixFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDbkcsT0FBTyxFQUFFLFlBQVksRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xGLE9BQU8sRUFBRSxlQUFlLEVBQUUsYUFBYSxFQUFjLE1BQU0sTUFBTSxDQUFDO0FBQ2xFLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxjQUFjLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUN6RixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSx3RUFBd0UsQ0FBQztBQUM1RyxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sMENBQTBDLENBQUM7QUFDekUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDRDQUE0QyxDQUFDO0FBQzVFLE9BQStCLDZDQUE2QyxDQUFDO0FBQzdFLE9BQTBCLDhCQUE4QixDQUFDO0FBQ3pELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGlDQUFpQyxDQUFDO0FBQ3RFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQzs7Ozs7QUFFbEQsTUFBTSxZQUFZLEdB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QUFZO3VCQUFDLG1CQUFtQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERhdGVQaXBlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IERpcmVjdGl2ZSwgSG9zdExpc3RlbmVyLCBJbnB1dCwgT25DaGFuZ2VzLCBPcHRpb25hbCwgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOZ0NvbnRyb2wgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBDb21wb25lbnRDaGFuZ2VzLCBDb21wb25lbnRDaGFuZ2UsIFRpbWVEaWdpdEZvcm1hdFBpcGUgfSBmcm9tICdAYmltZWlzdGVyL3B1cGFraXQuY29tbW9uJztcbmltcG9ydCB7IGZpbHRlck5vdE5pbCwgZmlsdGVyVHJ1dGh5LCBpc0VtcHR5LCBpc05pbCB9IGZyb20gJ0BiaW1laXN0ZXIvdXRpbGl0aWVzJztcbmltcG9ydCB7IEJlaGF2aW9yU3ViamVjdCwgY29tYmluZUxhdGVzdCwgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGlzdGluY3RVbnRpbENoYW5nZWQsIGZpbHRlciwgbWFwLCB0YWtlLCB3aXRoTGF0ZXN0RnJvbSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcbmltcG9ydCB7IERyb3BwYWJsZUNvbXBvbmVudCB9IGZyb20gJy4uLy4uLy4uL2NvbXBvbmVudHMvZHJvcHBhYmxlL2NvbXBvbmVudHMvZHJvcHBhYmxlL2Ryb3BwYWJsZS5jb21wb25lbnQnO1xuaW1wb3J0IHsgZGF0ZUNsZWFyVGltZSB9IGZyb20gJy4uLy4uL2Z1bmN0aW9ucy9kYXRlLWNsZWFyLXRpbWUuZnVuY3Rpb24nO1xuaW1wb3J0IHsgZ2V0RGF5c0luTW9udGggfSBmcm9tICcuLi8uLi9mdW5jdGlvbnMvZ2V0LWRheXMtaW4tbW9udGguZnVuY3Rpb24nO1xuaW1wb3J0IHsgUGFyc2VkRGF0ZURhdGEgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL3BhcnNlZC1kYXRlLWRhdGEuaW50ZXJmYWNlJztcbmltcG9ydCB7IFZhbHVlVHlwZSB9IGZyb20gJy4uLy4uL3R5cGVzL2lucHV0LXZhbHVlLnR5cGUnO1xuaW1wb3J0IHsgSW5wdXREYXRlVGltZUhlbHBlciB9IGZyb20gJy4uL2lucHV0LWRhdGUtdGltZS1oZWxwZXIuY2xhc3MnO1xuaW1wb3J0IHsgSW5wdXRCYXNlIH0gZnJvbSAnLi9pbnB1dC1iYXNlLmFic3RyYWN0JztcblxuY29uc3QgREVGQVVMVF9EQVRFOiBEYXRlID0gbmV3IERhdGUoKTtcbmNvbnN0IERFRkFVTFRfQ1VSUkVOVF9EQVRFX1dJVEhfQ0xFQVJFRF9USU1FOiBEYXRlID0gZGF0ZUNsZWFyVGltZShERUZBVUxUX0RBVEUpO1xuY29uc3QgREFURV9GT1JNQVQ6IHN0cmluZyA9ICdkZC5NTS55eXl5JztcblxuY29uc3QgTUFYX0hPVVJTOiBudW1iZXIgPSAyMztcbmNvbnN0IE1BWF9NSU5VVEVTOiBudW1iZXIgPSA1OTtcbmNvbnN0IE1BWF9TRUNPTkRTOiBudW1iZXIgPSA1OTtcblxuY29uc3QgUExBQ0VIT0xERVJfREFURTogc3RyaW5nID0gJzAwLjAwLjAwMDAnO1xuY29uc3QgU0laRV9QTEFDRUhPTERFUl9EQVRFOiBudW1iZXIgPSBQTEFDRUhPTERFUl9EQVRFLmxlbmd0aDtcblxuY29uc3QgUExBQ0VIT0xERVJfVElNRTogc3RyaW5nID0gJzAwOjAwOjAwJztcbmNvbnN0IFNJWkVfUExBQ0VIT0xERVJfVElNRTogbnVtYmVyID0gUExBQ0VIT0xERVJfVElNRS5sZW5ndGg7XG5cbmNvbnN0IE1PTlRIX1NUQVJUX1ZBTFVFOiBudW1iZXIgPSAwO1xuY29uc3QgTU9OVEhfRU5EX1ZBTFVFOiBudW1iZXIgPSAxMTtcblxuY29uc3QgSE9VUl9TVEFSVF9QT1NJVElPTjogbnVtYmVyID0gMDtcbmNvbnN0IEhPVVJfRU5EX1BPU0lUSU9OOiBudW1iZXIgPSAyO1xuXG5jb25zdCBNSU5VVEVTX1NUQVJUX1BPU0lUSU9OOiBudW1iZXIgPSAzO1xuY29uc3QgTUlOVVRFU19FTkRfUE9TSVRJT046IG51bWJlciA9IDU7XG5cbmNvbnN0IFNFQ09ORFNfU1RBUlRfUE9TSVRJT046IG51bWJlciA9IDY7XG5jb25zdCBTRUNPTkRTX0VORF9QT1NJVElPTjogbnVtYmVyID0gODtcblxuQERpcmVjdGl2ZSgpXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgSW5wdXREYXRlVGltZUJhc2UgZXh0ZW5kcyBJbnB1dEJhc2U8VmFsdWVUeXBlPiBpbXBsZW1lbnRzIE9uQ2hhbmdlcyB7XG4gIEBWaWV3Q2hpbGQoJ2Ryb3BwYWJsZScsIHsgc3RhdGljOiB0cnVlIH0pIHB1YmxpYyByZWFkb25seSBkcm9wcGFibGVDb21wb25lbnQ6IERyb3BwYWJsZUNvbXBvbmVudDtcblxuICBASW5wdXQoKSBwdWJsaWMgcmVhZG9ubHkgaXNGaXhlZFNpemU6IGJvb2xlYW4gPSB0cnVlO1xuICBwdWJsaWMgcmVhZG9ubHkgaXNGaXhlZFNpemUkOiBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KHRydWUpO1xuXG4gIEBJbnB1dCgpIHB1YmxpYyByZWFkb25seSBpc0JhY2tEYXRpbmc6IGJvb2xlYW4gPSB0cnVlO1xuICBwdWJsaWMgcmVhZG9ubHkgaXNCYWNrRGF0aW5nJDogQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPih0cnVlKTtcblxuICBASW5wdXQoKSBwdWJsaWMgcmVhZG9ubHkgYXZhaWxhYmxlRW5kRGF0ZTogRGF0ZSB8IG51bWJlciA9IEluZmluaXR5O1xuICBwdWJsaWMgcmVhZG9ubHkgYXZhaWxhYmxlRW5kRGF0ZSQ6IEJlaGF2aW9yU3ViamVjdDxEYXRlIHwgbnVtYmVyPiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8RGF0ZSB8IG51bWJlcj4oSW5maW5pdHkpO1xuXG4gIHB1YmxpYyByZWFkb25seSBpc0ljb25Ib3ZlcmVkJDogQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPihmYWxzZSk7XG4gIHB1YmxpYyByZWFkb25seSB2YWx1ZUlzTm90RW1wdHkkOiBPYnNlcnZhYmxlPGJvb2xlYW4+ID0gdGhpcy52YWx1ZSQucGlwZShtYXAoKHZhbHVlOiBzdHJpbmcpID0+ICFpc0VtcHR5KHZhbHVlKSkpO1xuICBwdWJsaWMgcmVhZG9ubHkgZGF0ZVRvUmVzZXRTd2l0Y2hlckVuYWJsZWQkOiBPYnNlcnZhYmxlPGJvb2xlYW4+ID0gY29tYmluZUxhdGVzdChbXG4gICAgdGhpcy5pc0ljb25Ib3ZlcmVkJCxcbiAgICB0aGlzLnZhbHVlSXNOb3RFbXB0eSQsXG4gICAgdGhpcy53aXRoUmVzZXQkLFxuICBdKS5waXBlKFxuICAgIG1hcChcbiAgICAgIChbaXNJY29uSG92ZXJlZCwgdmFsdWVJc05vdEVtcHR5LCB3aXRoUmVzZXRdOiBbYm9vbGVhbiwgYm9vbGVhbiwgYm9vbGVhbl0pID0+XG4gICAgICAgIGlzSWNvbkhvdmVyZWQgJiYgdmFsdWVJc05vdEVtcHR5ICYmIHdpdGhSZXNldFxuICAgIClcbiAgKTtcblxuICBwdWJsaWMgcmVhZG9ubHkgaG91cnMkOiBPYnNlcnZhYmxlPG51bWJlcj4gPSB0aGlzLnZhbHVlJC5waXBlKFxuICAgIG1hcCgodmFsdWU6IHN0cmluZykgPT5cbiAgICAgICFpc0VtcHR5KHZhbHVlKSAmJiB2YWx1ZS5sZW5ndGggPj0gSE9VUl9FTkRfUE9TSVRJT05cbiAgICAgICAgPyBOdW1iZXIodmFsdWUuc2xpY2UoSE9VUl9TVEFSVF9QT1NJVElPTiwgSE9VUl9FTkRfUE9TSVRJT04pKVxuICAgICAgICA6IC0xXG4gICAgKSxcbiAgICBmaWx0ZXJOb3ROaWwoKSxcbiAgICBmaWx0ZXIoKGhvdXJzOiBudW1iZXIpID0+IGhvdXJzIDw9IE1BWF9IT1VSUylcbiAgKTtcblxuICBwdWJsaWMgcmVhZG9ubHkgbWludXRlcyQ6IE9ic2VydmFibGU8bnVtYmVyPiA9IHRoaXMudmFsdWUkLnBpcGUoXG4gICAgbWFwKCh2YWx1ZTogc3RyaW5nKSA9PlxuICAgICAgIWlzRW1wdHkodmFsdWUpICYmIHZhbHVlLmxlbmd0aCA+PSBNSU5VVEVTX0VORF9QT1NJVElPTlxuICAgICAgICA/IE51bWJlcih2YWx1ZS5zbGljZShNSU5VVEVTX1NUQVJUX1BPU0lUSU9OLCBNSU5VVEVTX0VORF9QT1NJVElPTikpXG4gICAgICAgIDogLTFcbiAgICApLFxuICAgIGZpbHRlck5vdE5pbCgpLFxuICAgIGZpbHRlcigobWludXRlczogbnVtYmVyKSA9PiBtaW51dGVzIDw9IE1BWF9NSU5VVEVTKVxuICApO1xuXG4gIHB1YmxpYyByZWFkb25seSBzZWNvbmRzJDogT2JzZXJ2YWJsZTxudW1iZXI+ID0gdGhpcy52YWx1ZSQucGlwZShcbiAgICBtYXAoKHZhbHVlOiBzdHJpbmcpID0+XG4gICAgICAhaXNFbXB0eSh2YWx1ZSkgJiYgdmFsdWUubGVuZ3RoID09PSBTRUNPTkRTX0VORF9QT1NJVElPTiA/IE51bWJlcih2YWx1ZS5zbGljZShTRUNPTkRTX1NUQVJUX1BPU0lUSU9OKSkgOiAtMVxuICAgICksXG4gICAgZmlsdGVyTm90TmlsKCksXG4gICAgZmlsdGVyKChtaW51dGVzOiBudW1iZXIpID0+IG1pbnV0ZXMgPD0gTUFYX1NFQ09ORFMpXG4gICk7XG5cbiAgcHVibGljIHJlYWRvbmx5IGRhdGUkOiBPYnNlcnZhYmxlPERhdGU+ID0gdGhpcy52YWx1ZSQucGlwZShcbiAgICBmaWx0ZXJOb3ROaWwoKSxcbiAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxuICAgIGZpbHRlcigodmFsdWU6IHN0cmluZykgPT4gaXNFbXB0eSh2YWx1ZSkgfHwgdmFsdWUubGVuZ3RoID49IFNJWkVfUExBQ0VIT0xERVJfREFURSksXG4gICAgbWFwKCh2YWx1ZTogc3RyaW5nKSA9PiB2YWx1ZS5zbGljZSgwLCBTSVpFX1BMQUNFSE9MREVSX0RBVEUpKSxcbiAgICBtYXAoKHZhbHVlOiBzdHJpbmcpID0+IHRoaXMuZ2V0UGFyc2VkRGF0ZSh2YWx1ZSkpLFxuICAgIHdpdGhMYXRlc3RGcm9tKGNvbWJpbmVMYXRlc3QoW3RoaXMuaXNCYWNrRGF0aW5nJCwgdGhpcy5hdmFpbGFibGVFbmREYXRlJF0pKSxcbiAgICBmaWx0ZXIoXG4gICAgICAoW2RhdGUsIFtpc0JhY2tEYXRpbmcsIGF2YWlsYWJsZUVuZERhdGVdXTogW0RhdGUsIFtib29sZWFuLCBEYXRlXV0pID0+XG4gICAgICAgICF0aGlzLmRhdGVJc05vdEF2YWlsYWJsZShkYXRlLCBpc0JhY2tEYXRpbmcsIGF2YWlsYWJsZUVuZERhdGUpXG4gICAgKSxcbiAgICBtYXAoKFtkYXRlLCBfXTogW0RhdGUsIFtib29sZWFuLCBEYXRlXV0pID0+IGRhdGUpXG4gICk7XG5cbiAgcHVibGljIHJlYWRvbmx5IHJpZ2h0SWNvbldpdGhDb25kaXRpb24kOiBPYnNlcnZhYmxlPHN0cmluZz4gPSBjb21iaW5lTGF0ZXN0KFtcbiAgICB0aGlzLnJpZ2h0SWNvbiQsXG4gICAgdGhpcy5kYXRlVG9SZXNldFN3aXRjaGVyRW5hYmxlZCQsXG4gIF0pLnBpcGUoXG4gICAgbWFwKChbcmlnaHRJY29uLCBkYXRlVG9SZXNldFN3aXRjaGVyRW5hYmxlZF06IFtzdHJpbmcsIGJvb2xlYW5dKSA9PiB7XG4gICAgICBpZiAoZGF0ZVRvUmVzZXRTd2l0Y2hlckVuYWJsZWQpIHtcbiAgICAgICAgcmV0dXJuICdtLWFib3J0JztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGlzRW1wdHkocmlnaHRJY29uKSA/ICdtLWNhbGVuZGFyJyA6IHJpZ2h0SWNvbjtcbiAgICB9KVxuICApO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgdGltZUZvcm1hdFBpcGU6IFRpbWVEaWdpdEZvcm1hdFBpcGUsXG4gICAgcHVibGljIHJlYWRvbmx5IGRhdGVQaXBlOiBEYXRlUGlwZSxcbiAgICBAT3B0aW9uYWwoKSBuZ0NvbnRyb2w6IE5nQ29udHJvbFxuICApIHtcbiAgICBzdXBlcihuZ0NvbnRyb2wpO1xuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignd2luZG93OmNsaWNrJylcbiAgQEhvc3RMaXN0ZW5lcignd2luZG93OnRvdWNoc3RhcnQnKVxuICBwdWJsaWMgcHJvY2Vzc1dpbmRvd0NsaWNrKCk6IHZvaWQge1xuICAgIHRoaXMuaXNGb2N1c2VkJC5uZXh0KGZhbHNlKTtcbiAgfVxuXG4gIHB1YmxpYyBoYW5kbGVDb250YWluZXJDbGljayhldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICB0aGlzLmlzRGlzYWJsZWQkXG4gICAgICAucGlwZShcbiAgICAgICAgdGFrZSgxKSxcbiAgICAgICAgbWFwKChpc0Rpc2FibGVkOiBib29sZWFuKSA9PiBpc0Rpc2FibGVkIHx8IHRoaXMuZHJvcHBhYmxlQ29tcG9uZW50LmlzT3BlbmVkKSxcbiAgICAgICAgZmlsdGVyVHJ1dGh5KClcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4gZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCkpO1xuICB9XG5cbiAgcHVibGljIGhhbmRsZUNvbnRhaW5lclN0YXJ0RXZlbnRzKGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5kcm9wcGFibGVDb21wb25lbnQuaXNPcGVuZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIH1cblxuICBwdWJsaWMgc2VsZWN0SG91cnMoaG91cnM6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMudmFsdWUkLnBpcGUodGFrZSgxKSkuc3Vic2NyaWJlKCh2YWx1ZTogc3RyaW5nKSA9PiB7XG4gICAgICBjb25zdCBwYXJzZWRIb3Vyczogc3RyaW5nID0gSW5wdXREYXRlVGltZUhlbHBlci5nZXRVcGRhdGVkVmFsdWVTdHJpbmdBZnRlclNlbGVjdEhvdXJzKGhvdXJzLCB2YWx1ZSk7XG4gICAgICB0aGlzLnVwZGF0ZVZhbHVlKHBhcnNlZEhvdXJzKTtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBzZWxlY3RNaW51dGVzKG1pbnV0ZXM6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMudmFsdWUkLnBpcGUodGFrZSgxKSkuc3Vic2NyaWJlKCh2YWx1ZTogc3RyaW5nKSA9PiB7XG4gICAgICBjb25zdCBwYXJzZWRNaW51dGVzOiBzdHJpbmcgPSBJbnB1dERhdGVUaW1lSGVscGVyLmdldFVwZGF0ZWRWYWx1ZVN0cmluZ0FmdGVyU2VsZWN0TWludXRlcyhtaW51dGVzLCB2YWx1ZSk7XG4gICAgICB0aGlzLnVwZGF0ZVZhbHVlKHBhcnNlZE1pbnV0ZXMpO1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIHNlbGVjdFNlY29uZHMoc2Vjb25kczogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy52YWx1ZSQucGlwZSh0YWtlKDEpKS5zdWJzY3JpYmUoKHZhbHVlOiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IHBhcnNlZFNlY29uZHM6IHN0cmluZyA9IElucHV0RGF0ZVRpbWVIZWxwZXIuZ2V0VXBkYXRlZFZhbHVlU3RyaW5nQWZ0ZXJTZWxlY3RTZWNvbmRzKHNlY29uZHMsIHZhbHVlKTtcbiAgICAgIHRoaXMudXBkYXRlVmFsdWUocGFyc2VkU2Vjb25kcyk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgc2VsZWN0RGF0ZVRpbWVIb3Vycyhob3VyczogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy52YWx1ZSQucGlwZSh0YWtlKDEpKS5zdWJzY3JpYmUoKHZhbHVlOiBzdHJpbmcpID0+IHtcbiAgICAgIGNvbnN0IHZhbHVlVGltZTogc3RyaW5nID0gaXNOaWwodmFsdWUpID8gJycgOiB2YWx1ZS5zbGljZShTSVpFX1BMQUNFSE9MREVSX0RBVEUpLnRyaW0oKTtcblxuICAgICAgY29uc3QgcGFyc2VkSG91cnM6IHN0cmluZyA9IElucHV0RGF0ZVRpbWVIZWxwZXIuZ2V0VXBkYXRlZFZhbHVlU3RyaW5nQWZ0ZXJTZWxlY3RIb3Vycyhob3VycywgdmFsdWVUaW1lKTtcbiAgICAgIGNvbnN0IHRyYW5zZm9ybWVkSG91cnM6IHN0cmluZyA9IHBhcnNlZEhvdXJzLnNsaWNlKDAsIFNJWkVfUExBQ0VIT0xERVJfVElNRSk7XG5cbiAgICAgIGlmIChpc05pbCh2YWx1ZSkgfHwgdmFsdWUubGVuZ3RoIDwgU0laRV9QTEFDRUhPTERFUl9EQVRFKSB7XG4gICAgICAgIGNvbnN0IHBhcnNlZERlZmF1bHREYXRlOiBzdHJpbmcgPSB0aGlzLmRhdGVQaXBlLnRyYW5zZm9ybShERUZBVUxUX0RBVEUsIERBVEVfRk9STUFUKTtcbiAgICAgICAgdGhpcy51cGRhdGVWYWx1ZShgJHtwYXJzZWREZWZhdWx0RGF0ZX0gJHt0cmFuc2Zvcm1lZEhvdXJzfWApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGFkZGVkRXhpc3RpbmdWYWx1ZUlucHV0OiBzdHJpbmcgPSB2YWx1ZS5zbGljZSgwLCBTSVpFX1BMQUNFSE9MREVSX0RBVEUpO1xuXG4gICAgICB0aGlzLnVwZGF0ZVZhbHVlKGAke2FkZGVkRXhpc3RpbmdWYWx1ZUlucHV0fSAke3RyYW5zZm9ybWVkSG91cnN9YCk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgc2VsZWN0RGF0ZVRpbWVNaW51dGVzKG1pbnV0ZXM6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMudmFsdWUkLnBpcGUodGFrZSgxKSkuc3Vic2NyaWJlKCh2YWx1ZTogc3RyaW5nKSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZVRpbWU6IHN0cmluZyA9IGlzTmlsKHZhbHVlKSA/ICcnIDogdmFsdWUuc2xpY2UoU0laRV9QTEFDRUhPTERFUl9EQVRFKS50cmltKCk7XG5cbiAgICAgIGNvbnN0IHBhcnNlZE1pbnV0ZXM6IHN0cmluZyA9IElucHV0RGF0ZVRpbWVIZWxwZXIuZ2V0VXBkYXRlZFZhbHVlU3RyaW5nQWZ0ZXJTZWxlY3RNaW51dGVzKG1pbnV0ZXMsIHZhbHVlVGltZSk7XG4gICAgICBjb25zdCB0cmFuc2Zvcm1lZE1pbnV0ZXM6IHN0cmluZyA9IHBhcnNlZE1pbnV0ZXMuc2xpY2UoMCwgU0laRV9QTEFDRUhPTERFUl9USU1FKTtcblxuICAgICAgaWYgKGlzTmlsKHZhbHVlKSB8fCB2YWx1ZS5sZW5ndGggPCBTSVpFX1BMQUNFSE9MREVSX0RBVEUpIHtcbiAgICAgICAgY29uc3QgcGFyc2VkRGVmYXVsdERhdGU6IHN0cmluZyA9IHRoaXMuZGF0ZVBpcGUudHJhbnNmb3JtKERFRkFVTFRfREFURSwgREFURV9GT1JNQVQpO1xuICAgICAgICB0aGlzLnVwZGF0ZVZhbHVlKGAke3BhcnNlZERlZmF1bHREYXRlfSAke3RyYW5zZm9ybWVkTWludXRlc31gKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBhZGRlZEV4aXN0aW5nVmFsdWVJbnB1dDogc3RyaW5nID0gdmFsdWUuc2xpY2UoMCwgU0laRV9QTEFDRUhPTERFUl9EQVRFKTtcblxuICAgICAgdGhpcy51cGRhdGVWYWx1ZShgJHthZGRlZEV4aXN0aW5nVmFsdWVJbnB1dH0gJHt0cmFuc2Zvcm1lZE1pbnV0ZXN9YCk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgc2VsZWN0RGF0ZVRpbWVTZWNvbmRzKHNlY29uZHM6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMudmFsdWUkLnBpcGUodGFrZSgxKSkuc3Vic2NyaWJlKCh2YWx1ZTogc3RyaW5nKSA9PiB7XG4gICAgICBjb25zdCB2YWx1ZVRpbWU6IHN0cmluZyA9IGlzTmlsKHZhbHVlKSA/ICcnIDogdmFsdWUuc2xpY2UoU0laRV9QTEFDRUhPTERFUl9EQVRFKS50cmltKCk7XG5cbiAgICAgIGNvbnN0IHBhcnNlZFNlY29uZHM6IHN0cmluZyA9IElucHV0RGF0ZVRpbWVIZWxwZXIuZ2V0VXBkYXRlZFZhbHVlU3RyaW5nQWZ0ZXJTZWxlY3RTZWNvbmRzKHNlY29uZHMsIHZhbHVlVGltZSk7XG4gICAgICBjb25zdCB0cmFuc2Zvcm1lZFNlY29uZHM6IHN0cmluZyA9IHBhcnNlZFNlY29uZHMuc2xpY2UoMCwgU0laRV9QTEFDRUhPTERFUl9USU1FKTtcblxuICAgICAgaWYgKGlzTmlsKHZhbHVlKSB8fCB2YWx1ZS5sZW5ndGggPCBTSVpFX1BMQUNFSE9MREVSX0RBVEUpIHtcbiAgICAgICAgY29uc3QgcGFyc2VkRGVmYXVsdERhdGU6IHN0cmluZyA9IHRoaXMuZGF0ZVBpcGUudHJhbnNmb3JtKERFRkFVTFRfREFURSwgREFURV9GT1JNQVQpO1xuICAgICAgICB0aGlzLnVwZGF0ZVZhbHVlKGAke3BhcnNlZERlZmF1bHREYXRlfSAke3RyYW5zZm9ybWVkU2Vjb25kc31gKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBhZGRlZEV4aXN0aW5nVmFsdWVJbnB1dDogc3RyaW5nID0gdmFsdWUuc2xpY2UoMCwgU0laRV9QTEFDRUhPTERFUl9EQVRFKTtcblxuICAgICAgdGhpcy51cGRhdGVWYWx1ZShgJHthZGRlZEV4aXN0aW5nVmFsdWVJbnB1dH0gJHt0cmFuc2Zvcm1lZFNlY29uZHN9YCk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgc2VsZWN0RGF0ZShzZWxlY3RlZERhdGU6IERhdGUpOiB2b2lkIHtcbiAgICB0aGlzLnZhbHVlJC5waXBlKHRha2UoMSkpLnN1YnNjcmliZSgodmFsdWU6IHN0cmluZykgPT4ge1xuICAgICAgY29uc3QgZGF5OiBudW1iZXIgPSBzZWxlY3RlZERhdGUuZ2V0RGF0ZSgpO1xuICAgICAgY29uc3QgbW9udGg6IG51bWJlciA9IHNlbGVjdGVkRGF0ZS5nZXRNb250aCgpICsgMTtcbiAgICAgIGNvbnN0IHllYXI6IG51bWJlciA9IHNlbGVjdGVkRGF0ZS5nZXRGdWxsWWVhcigpO1xuXG4gICAgICBjb25zdCBwYXJzZWREYXk6IHN0cmluZyA9IHRoaXMudGltZUZvcm1hdFBpcGUudHJhbnNmb3JtKGRheSk7XG4gICAgICBjb25zdCBwYXJzZWRNb250aDogc3RyaW5nID0gdGhpcy50aW1lRm9ybWF0UGlwZS50cmFuc2Zvcm0obW9udGgpO1xuXG4gICAgICBjb25zdCBkYXRlSW5wdXRTdHJpbmc6IHN0cmluZyA9IGAke3BhcnNlZERheX0uJHtwYXJzZWRNb250aH0uJHt5ZWFyfWA7XG5cbiAgICAgIGNvbnN0IGFkZGVkRXhpc3RpbmdWYWx1ZUlucHV0OiBzdHJpbmcgPSBpc05pbCh2YWx1ZSkgPyAnJyA6IHZhbHVlLnNsaWNlKFNJWkVfUExBQ0VIT0xERVJfREFURSk7XG5cbiAgICAgIHRoaXMudXBkYXRlVmFsdWUoYCR7ZGF0ZUlucHV0U3RyaW5nfSR7YWRkZWRFeGlzdGluZ1ZhbHVlSW5wdXR9YCk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgc2VsZWN0UmFuZ2UocmFuZ2U6IFtEYXRlLCBEYXRlXSk6IHZvaWQge1xuICAgIGNvbnN0IGZpcnN0RGF0ZTogRGF0ZSA9IHJhbmdlWzBdO1xuICAgIGNvbnN0IHNlY29uZERhdGU6IERhdGUgPSByYW5nZVsxXTtcblxuICAgIGNvbnN0IGNvbnZlcnRlZEZpcnN0RGF0ZTogc3RyaW5nID0gdGhpcy5kYXRlUGlwZS50cmFuc2Zvcm0oZmlyc3REYXRlLCBEQVRFX0ZPUk1BVCk7XG4gICAgY29uc3QgY29udmVydGVkU2Vjb25kRGF0ZTogc3RyaW5nID0gdGhpcy5kYXRlUGlwZS50cmFuc2Zvcm0oc2Vjb25kRGF0ZSwgREFURV9GT1JNQVQpO1xuXG4gICAgY29uc3QgaXNSYW5nZUNvcnJlY3Q6IGJvb2xlYW4gPSBmaXJzdERhdGUgPD0gc2Vjb25kRGF0ZTtcbiAgICBjb25zdCB1cGRhdGVkVmFsdWU6IHN0cmluZyA9IGlzUmFuZ2VDb3JyZWN0XG4gICAgICA/IGAke2NvbnZlcnRlZEZpcnN0RGF0ZX0gLSAke2NvbnZlcnRlZFNlY29uZERhdGV9YFxuICAgICAgOiBgJHtjb252ZXJ0ZWRTZWNvbmREYXRlfSAtICR7Y29udmVydGVkRmlyc3REYXRlfWA7XG5cbiAgICB0aGlzLnVwZGF0ZVZhbHVlKHVwZGF0ZWRWYWx1ZSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0UGFyc2VkRGF0ZSh2YWx1ZTogc3RyaW5nKTogRGF0ZSB7XG4gICAgY29uc3QgeyBkYXksIG1vbnRoLCB5ZWFyIH06IFBhcnNlZERhdGVEYXRhID0gSW5wdXREYXRlVGltZUhlbHBlci5nZXRQYXJzZWREYXRlRGF0YSh2YWx1ZSk7XG4gICAgY29uc3QgY29udmVydGVkWWVhcjogbnVtYmVyID0gTnVtYmVyKHllYXIpO1xuICAgIGNvbnN0IGNvbnZlcnRlZE1vbnRoOiBudW1iZXIgPSBOdW1iZXIobW9udGgpIC0gMTtcbiAgICBjb25zdCBjb252ZXJ0ZWREYXk6IG51bWJlciA9IE51bWJlcihkYXkpO1xuXG4gICAgaWYgKGNvbnZlcnRlZE1vbnRoID4gTU9OVEhfRU5EX1ZBTFVFIHx8IGNvbnZlcnRlZE1vbnRoIDwgTU9OVEhfU1RBUlRfVkFMVUUpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IHRlc3REYXRlOiBEYXRlID0gbmV3IERhdGUoY29udmVydGVkWWVhciwgY29udmVydGVkTW9udGgsIDEpO1xuICAgIGNvbnN0IGRheXNJbk1vbnRoOiBudW1iZXIgPSBnZXREYXlzSW5Nb250aCh0ZXN0RGF0ZSk7XG5cbiAgICBpZiAoY29udmVydGVkRGF5ID4gZGF5c0luTW9udGgpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IGRhdGU6IERhdGUgPSBuZXcgRGF0ZShjb252ZXJ0ZWRZZWFyLCBjb252ZXJ0ZWRNb250aCwgY29udmVydGVkRGF5KTtcbiAgICByZXR1cm4gZGF0ZTtcbiAgfVxuXG4gIHB1YmxpYyBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiBDb21wb25lbnRDaGFuZ2VzPHRoaXM+KTogdm9pZCB7XG4gICAgdGhpcy5wcm9jZXNzSXNGaXhlZFNpemVDaGFuZ2UoY2hhbmdlcz8uaXNGaXhlZFNpemUpO1xuICAgIHRoaXMucHJvY2Vzc0lzQmFja0RhdGluZ0NoYW5nZShjaGFuZ2VzPy5pc0JhY2tEYXRpbmcpO1xuICAgIHRoaXMucHJvY2Vzc0F2YWlsYWJsZUVuZERhdGVDaGFuZ2UoY2hhbmdlcz8uYXZhaWxhYmxlRW5kRGF0ZSk7XG4gICAgc3VwZXIubmdPbkNoYW5nZXMoY2hhbmdlcyk7XG4gIH1cblxuICBwdWJsaWMgc2V0VmFsdWUodmFsdWU6IFZhbHVlVHlwZSk6IHZvaWQge1xuICAgIGNvbnN0IHNlcmlhbGl6ZWRWYWx1ZTogc3RyaW5nID0gaXNOaWwodmFsdWUpID8gJycgOiBTdHJpbmcodmFsdWUpO1xuICAgIHRoaXMudmFsdWUkLm5leHQoc2VyaWFsaXplZFZhbHVlKTtcbiAgfVxuXG4gIHB1YmxpYyBoYW5kbGVGb2N1c0V2ZW50KGZvY3VzRXZlbnQ6IEZvY3VzRXZlbnQpOiB2b2lkIHtcbiAgICBmb2N1c0V2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuZW1pdEZvY3VzRXZlbnQoZm9jdXNFdmVudCk7XG4gIH1cblxuICBwdWJsaWMgaGFuZGxlSWNvbkhvdmVyKGZvY3VzRXZlbnQ6IEZvY3VzRXZlbnQsIGlzSG92ZXJlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIGZvY3VzRXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy5pc0ljb25Ib3ZlcmVkJC5uZXh0KGlzSG92ZXJlZCk7XG4gIH1cblxuICBwdWJsaWMgcmVzZXQoKTogdm9pZCB7XG4gICAgdGhpcy53aXRoUmVzZXQkLnBpcGUodGFrZSgxKSwgZmlsdGVyVHJ1dGh5KCkpLnN1YnNjcmliZSgoKSA9PiB0aGlzLnVwZGF0ZVZhbHVlKCcnKSk7XG4gICAgdGhpcy5pbnB1dEVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICB9XG5cbiAgcHVibGljIGNsZWFySW5wdXRWYWx1ZSgpOiB2b2lkIHtcbiAgICBjb21iaW5lTGF0ZXN0KFt0aGlzLmlzSWNvbkhvdmVyZWQkLCB0aGlzLnZhbHVlSXNOb3RFbXB0eSQsIHRoaXMuaXNWYWxpZCRdKVxuICAgICAgLnBpcGUoXG4gICAgICAgIHRha2UoMSksXG4gICAgICAgIGZpbHRlcihcbiAgICAgICAgICAoW2lzSWNvbkhvdmVyZWQsIHZhbHVlSXNOb3RFbXB0eSwgaXNWYWxpZF06IFtib29sZWFuLCBib29sZWFuLCBib29sZWFuXSkgPT5cbiAgICAgICAgICAgIGlzSWNvbkhvdmVyZWQgJiYgdmFsdWVJc05vdEVtcHR5ICYmIGlzVmFsaWRcbiAgICAgICAgKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB0aGlzLnVwZGF0ZVZhbHVlKCcnKSk7XG4gIH1cblxuICBwdWJsaWMgZGF0ZUlzTm90QXZhaWxhYmxlKGRhdGU6IERhdGUsIGlzQmFja0RhdGluZzogYm9vbGVhbiwgYXZhaWxhYmxlRW5kRGF0ZTogRGF0ZSk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoIWlzQmFja0RhdGluZyAmJiBkYXRlIDwgREVGQVVMVF9DVVJSRU5UX0RBVEVfV0lUSF9DTEVBUkVEX1RJTUUpIHx8IGRhdGUgPiBhdmFpbGFibGVFbmREYXRlO1xuICB9XG5cbiAgcHJpdmF0ZSBwcm9jZXNzSXNGaXhlZFNpemVDaGFuZ2UoY2hhbmdlOiBDb21wb25lbnRDaGFuZ2U8dGhpcywgYm9vbGVhbj4pOiB2b2lkIHtcbiAgICBjb25zdCB1cGRhdGVkVmFsdWU6IGJvb2xlYW4gfCB1bmRlZmluZWQgPSBjaGFuZ2U/LmN1cnJlbnRWYWx1ZTtcblxuICAgIGlmIChpc05pbCh1cGRhdGVkVmFsdWUpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5pc0ZpeGVkU2l6ZSQubmV4dCh1cGRhdGVkVmFsdWUpO1xuICB9XG5cbiAgcHJpdmF0ZSBwcm9jZXNzSXNCYWNrRGF0aW5nQ2hhbmdlKGNoYW5nZTogQ29tcG9uZW50Q2hhbmdlPHRoaXMsIGJvb2xlYW4+KTogdm9pZCB7XG4gICAgY29uc3QgdXBkYXRlZFZhbHVlOiBib29sZWFuIHwgdW5kZWZpbmVkID0gY2hhbmdlPy5jdXJyZW50VmFsdWU7XG5cbiAgICBpZiAoaXNOaWwodXBkYXRlZFZhbHVlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmlzQmFja0RhdGluZyQubmV4dCh1cGRhdGVkVmFsdWUpO1xuICB9XG5cbiAgcHJpdmF0ZSBwcm9jZXNzQXZhaWxhYmxlRW5kRGF0ZUNoYW5nZShjaGFuZ2U6IENvbXBvbmVudENoYW5nZTx0aGlzLCBEYXRlIHwgbnVtYmVyPik6IHZvaWQge1xuICAgIGNvbnN0IHVwZGF0ZWRWYWx1ZTogRGF0ZSB8IG51bWJlciB8IHVuZGVmaW5lZCA9IGNoYW5nZT8uY3VycmVudFZhbHVlO1xuXG4gICAgaWYgKGlzTmlsKHVwZGF0ZWRWYWx1ZSkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5hdmFpbGFibGVFbmREYXRlJC5uZXh0KHVwZGF0ZWRWYWx1ZSk7XG4gIH1cbn1cbiJdfQ==