ontimize-web-ngx
Version:
Ontimize Web framework using Angular 15
282 lines • 48.8 kB
JavaScript
import { __decorate, __metadata } from "tslib";
import { Component, ElementRef, EventEmitter, forwardRef, Inject, Injector, Optional, ViewChild } from '@angular/core';
import { UntypedFormControl } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { MatInput } from '@angular/material/input';
import { BooleanInputConverter, NumberInputConverter } from '../../../decorators/input-converter';
import { OntimizeServiceProvider } from '../../../services/factories';
import { Util } from '../../../util/util';
import { OFormComponent } from '../../form/o-form.component';
import { OValueChangeEvent } from '../../o-value-change-event.class';
import { OFormServiceComponent } from '../o-form-service-component.class';
import { OListPickerDialogComponent } from './o-list-picker-dialog.component';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "@angular/flex-layout/flex";
import * as i3 from "@angular/forms";
import * as i4 from "../../../directives/o-mat-error.directive";
import * as i5 from "@angular/material/button";
import * as i6 from "@angular/material/icon";
import * as i7 from "@angular/material/input";
import * as i8 from "@angular/material/form-field";
import * as i9 from "@angular/material/tooltip";
import * as i10 from "../../contextmenu/o-context-menu.directive";
import * as i11 from "../../contextmenu/o-context-menu.component";
import * as i12 from "../../contextmenu/context-menu-item/o-context-menu-item.component";
import * as i13 from "../../../pipes/o-translate.pipe";
import * as i14 from "../../form/o-form.component";
export const DEFAULT_INPUTS_O_LIST_PICKER = [
'filter',
'dialogWidth : dialog-width',
'dialogHeight : dialog-height',
'queryRows: query-rows',
'textInputEnabled: text-input-enabled',
'dialogDisableClose: dialog-disable-close',
'dialogClass: dialog-class'
];
export const DEFAULT_OUTPUTS_O_LIST_PICKER = [
'onDialogAccept',
'onDialogCancel'
];
export class OListPickerComponent extends OFormServiceComponent {
constructor(form, elRef, injector) {
super(form, elRef, injector);
this.onDialogAccept = new EventEmitter();
this.onDialogCancel = new EventEmitter();
this.textInputEnabled = true;
this.dialogDisableClose = false;
this.filter = true;
this.dialogHeight = '55%';
this.blurDelay = 200;
this.blurPrevent = false;
this.matDialog = this.injector.get(MatDialog);
this.stateCtrl = new UntypedFormControl();
this.clearButton = true;
}
ngOnInit() {
this.initialize();
if (!Util.isDefined(this.stateCtrl.value)) {
this.setStateCtrlValue();
}
}
ngOnChanges(changes) {
super.ngOnChanges(changes);
if (typeof (changes.staticData) !== 'undefined') {
this.cacheQueried = true;
this.setDataArray(changes.staticData.currentValue);
}
}
createFormControl(cfg, validators) {
this._fControl = super.createFormControl(cfg, validators);
this._fControl.fControlChildren = [this.stateCtrl];
return this._fControl;
}
ensureOFormValue(value) {
super.ensureOFormValue(value);
this.syncDataIndex(false);
}
setEnabled(value) {
super.setEnabled(value);
if (this.stateCtrl && this.hasEnabledPermission() || this.hasVisiblePermission()) {
value ? this.stateCtrl.enable() : this.stateCtrl.disable();
}
}
ngAfterViewInit() {
super.ngAfterViewInit();
if (this.queryOnInit) {
this.queryData();
}
else if (this.queryOnBind) {
this.syncDataIndex();
}
}
getDescriptionValue() {
if (!Util.isDefined(this.descriptionColArray) || !Util.isDefined(this._currentIndex)) {
return '';
}
if (Util.isDefined(this.renderer)) {
return this.renderer.getListPickerValue(this.dataArray[this._currentIndex]);
}
else {
return this.getOptionDescriptionValue(this.dataArray[this._currentIndex]);
}
}
onClickClear(e) {
e.preventDefault();
e.stopPropagation();
if (!this.isReadOnly && this.enabled) {
clearTimeout(this.blurTimer);
this.blurPrevent = true;
this.setValue(undefined);
}
}
onClickInput(e) {
if (!this.textInputEnabled) {
this.onClickListpicker(e);
}
}
onClickListpicker(e) {
e.preventDefault();
e.stopPropagation();
if (!this.isReadOnly && this.enabled) {
clearTimeout(this.blurTimer);
this.openDialog();
}
}
onDialogClose(evt) {
this.dialogRef = null;
this.visibleInputValue = undefined;
if (evt instanceof Object && typeof evt[this.valueColumn] !== 'undefined') {
const self = this;
window.setTimeout(() => {
self.setValue(evt[self.valueColumn], { changeType: OValueChangeEvent.USER_CHANGE });
if (self._fControl) {
self._fControl.markAsTouched();
self._fControl.markAsDirty();
}
self.onDialogAccept.emit();
}, 0);
}
else {
this.onDialogCancel.emit();
}
}
innerOnBlur(evt) {
if (!this.isReadOnly && this.enabled) {
const self = this;
this.blurTimer = setTimeout(() => {
if (!self.blurPrevent) {
self._fControl.markAsTouched();
self.onBlur.emit(evt);
if (self.visibleInputValue !== undefined && self.visibleInputValue.length > 0) {
self.openDialog();
}
else if (self.visibleInputValue !== undefined) {
self.setValue(undefined);
self.visibleInputValue = undefined;
}
else {
self._fControl.markAsTouched();
}
}
self.blurPrevent = false;
}, this.blurDelay);
}
}
onVisibleInputChange(event) {
this.visibleInputValue = event.target.value;
}
onKeydownEnter(val) {
clearTimeout(this.blurTimer);
this.blurPrevent = true;
this.visibleInputValue = val;
this.openDialog();
}
openDialog() {
const cfg = {
role: 'dialog',
disableClose: this.dialogDisableClose,
panelClass: ['cdk-overlay-list-picker', 'o-dialog-class', this.dialogClass],
data: {
data: this.getDialogDataArray(this.dataArray),
filter: this.filter,
searchVal: this.visibleInputValue,
menuColumns: this.visibleColumns,
visibleColumns: this.visibleColArray,
queryRows: this.queryRows,
renderer: this.renderer
}
};
if (this.dialogWidth !== undefined) {
cfg.width = this.dialogWidth;
}
if (this.dialogHeight !== undefined) {
cfg.height = this.dialogHeight;
}
this.dialogRef = this.matDialog.open(OListPickerDialogComponent, cfg);
this.dialogRef.afterClosed().subscribe(result => this.onDialogClose(result));
}
getDialogDataArray(dataArray) {
const result = [];
dataArray.forEach((item, itemIndex) => {
const newItem = Object.assign({}, item);
if (!this.renderer) {
newItem._parsedVisibleColumnText = this.getVisibleColumnText(item);
}
newItem._parsedIndex = itemIndex;
result.push(newItem);
});
return result;
}
getVisibleColumnText(item) {
let element = '';
this.visibleColArray.forEach((visibleCol, index) => {
element += item[visibleCol];
if ((index + 1) < this.visibleColArray.length) {
element += this.separator;
}
});
return element;
}
registerRenderer(renderer) {
this.renderer = renderer;
this.renderer.initialize();
}
setStateCtrlValue() {
let descriptionValue = this.getDescriptionValue();
if (typeof descriptionValue === 'string' && descriptionValue.length === 0) {
descriptionValue = null;
}
this.stateCtrl.setValue(descriptionValue);
}
syncDataIndex(queryIfNotFound) {
super.syncDataIndex(queryIfNotFound);
this.setStateCtrlValue();
}
selectValue() {
const inputEl = document.getElementById('desc_' + this.oattr);
if (inputEl) {
inputEl.select();
}
}
}
OListPickerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: OListPickerComponent, deps: [{ token: forwardRef(() => OFormComponent), optional: true }, { token: i0.ElementRef }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Component });
OListPickerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.10", type: OListPickerComponent, selector: "o-list-picker", inputs: { filter: "filter", dialogWidth: ["dialog-width", "dialogWidth"], dialogHeight: ["dialog-height", "dialogHeight"], queryRows: ["query-rows", "queryRows"], textInputEnabled: ["text-input-enabled", "textInputEnabled"], dialogDisableClose: ["dialog-disable-close", "dialogDisableClose"], dialogClass: ["dialog-class", "dialogClass"] }, outputs: { onDialogAccept: "onDialogAccept", onDialogCancel: "onDialogCancel" }, providers: [
OntimizeServiceProvider,
{ provide: OFormServiceComponent, useExisting: forwardRef(() => OListPickerComponent) }
], viewQueries: [{ propertyName: "inputModel", first: true, predicate: ["inputModel"], descendants: true }, { propertyName: "visibleInput", first: true, predicate: ["visibleInput"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<div (click)=\"onClickInput($event)\" fxLayout=\"row\" fxLayoutAlign=\"space-between center\" [formGroup]=\"getFormGroup()\"\n [matTooltip]=\"tooltip\" [matTooltipClass]=\"tooltipClass\" [matTooltipPosition]=\"tooltipPosition\"\n [matTooltipShowDelay]=\"tooltipShowDelay\" [matTooltipHideDelay]=\"tooltipHideDelay\"\n class=\"custom-error o-list-picker-content\" [oContextMenu]=\"oContextMenu\">\n <input #inputModel class=\"input-model\" type=\"text\" [id]=\"getAttribute()\" [formControlName]=\"getAttribute()\">\n\n <mat-form-field [appearance]=\"appearance\" [floatLabel]=\"floatLabel\" [class.custom-width]=\"hasCustomWidth\"\n [hideRequiredMarker]=\"hideRequiredMarker\" class=\"icon-field\" #innerInputContainer fxFlexFill [subscriptSizing]=\"subscriptSizing\">\n <mat-label *ngIf=\"labelVisible\">{{ olabel | oTranslate }}</mat-label>\n\n <input #visibleInput matInput type=\"text\" [attr.id]=\"'desc_' + getAttribute()\" [id]=\"'desc_' + getAttribute()\"\n [formControl]=\"stateCtrl\" [placeholder]=\"placeHolder\"\n (input)=\"onVisibleInputChange($event)\" (focus)=\"innerOnFocus($event)\" (blur)=\"innerOnBlur($event)\"\n [readonly]=\"isReadOnly || !textInputEnabled\" [required]=\"isRequired\"\n (keydown.enter)=\"onKeydownEnter(visibleInput.value)\" (change)=\"onChangeEvent($event)\">\n\n <button type=\"button\" [disabled]=\"isReadOnly || !enabled\" [class.read-only]=\"isReadOnly\" matSuffix mat-icon-button\n (click)=\"onClickListpicker($event)\">\n <mat-icon svgIcon=\"ontimize:search\"></mat-icon>\n </button>\n\n <button type=\"button\" [disabled]=\"isReadOnly || !enabled\" [class.read-only]=\"isReadOnly\" matSuffix mat-icon-button\n (click)=\"onClickClearValue($event)\" *ngIf=\"showClearButton\">\n <mat-icon svgIcon=\"ontimize:clear\"></mat-icon>\n </button>\n\n <mat-error *oMatError=\"hasError('required')\">\n {{ 'FORM_VALIDATION.REQUIRED' | oTranslate }}\n </mat-error>\n <mat-error *ngFor=\"let oError of getActiveOErrors()\">\n {{ oError.text | oTranslate }}\n </mat-error>\n </mat-form-field>\n\n <o-context-menu *ngIf=\"!this.isReadOnly && this.enabled\">\n <o-context-menu-item attr=\"refresh\" label=\"FORM_SERVICE_COMPONENT.REFRESH\" svg-icon=\"ontimize:autorenew\" (execute)=\"refresh()\">\n </o-context-menu-item>\n </o-context-menu>\n</div>\n", styles: [".o-list-picker-content .input-model{display:none!important}.o-list-picker-content .mat-mdc-button.mat-disabled{cursor:default}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.DefaultLayoutDirective, selector: " [fxLayout], [fxLayout.xs], [fxLayout.sm], [fxLayout.md], [fxLayout.lg], [fxLayout.xl], [fxLayout.lt-sm], [fxLayout.lt-md], [fxLayout.lt-lg], [fxLayout.lt-xl], [fxLayout.gt-xs], [fxLayout.gt-sm], [fxLayout.gt-md], [fxLayout.gt-lg]", inputs: ["fxLayout", "fxLayout.xs", "fxLayout.sm", "fxLayout.md", "fxLayout.lg", "fxLayout.xl", "fxLayout.lt-sm", "fxLayout.lt-md", "fxLayout.lt-lg", "fxLayout.lt-xl", "fxLayout.gt-xs", "fxLayout.gt-sm", "fxLayout.gt-md", "fxLayout.gt-lg"] }, { kind: "directive", type: i2.DefaultLayoutAlignDirective, selector: " [fxLayoutAlign], [fxLayoutAlign.xs], [fxLayoutAlign.sm], [fxLayoutAlign.md], [fxLayoutAlign.lg], [fxLayoutAlign.xl], [fxLayoutAlign.lt-sm], [fxLayoutAlign.lt-md], [fxLayoutAlign.lt-lg], [fxLayoutAlign.lt-xl], [fxLayoutAlign.gt-xs], [fxLayoutAlign.gt-sm], [fxLayoutAlign.gt-md], [fxLayoutAlign.gt-lg]", inputs: ["fxLayoutAlign", "fxLayoutAlign.xs", "fxLayoutAlign.sm", "fxLayoutAlign.md", "fxLayoutAlign.lg", "fxLayoutAlign.xl", "fxLayoutAlign.lt-sm", "fxLayoutAlign.lt-md", "fxLayoutAlign.lt-lg", "fxLayoutAlign.lt-xl", "fxLayoutAlign.gt-xs", "fxLayoutAlign.gt-sm", "fxLayoutAlign.gt-md", "fxLayoutAlign.gt-lg"] }, { kind: "directive", type: i2.FlexFillDirective, selector: "[fxFill], [fxFlexFill]" }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i3.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i3.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i3.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: i4.OMatErrorDirective, selector: "[oMatError]", inputs: ["oMatError"] }, { kind: "component", type: i5.MatIconButton, selector: "button[mat-icon-button]", inputs: ["disabled", "disableRipple", "color"], exportAs: ["matButton"] }, { kind: "component", type: i6.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: i7.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i8.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i8.MatLabel, selector: "mat-label" }, { kind: "directive", type: i8.MatError, selector: "mat-error, [matError]", inputs: ["id"] }, { kind: "directive", type: i8.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i9.MatTooltip, selector: "[matTooltip]", exportAs: ["matTooltip"] }, { kind: "directive", type: i10.OContextMenuDirective, selector: "[oContextMenu]", inputs: ["oContextMenu", "oContextMenuData"] }, { kind: "component", type: i11.OContextMenuComponent, selector: "o-context-menu", outputs: ["onShow", "onClose"] }, { kind: "component", type: i12.OContextMenuItemComponent, selector: "o-context-menu-item", outputs: ["execute"] }, { kind: "pipe", type: i13.OTranslatePipe, name: "oTranslate" }] });
__decorate([
BooleanInputConverter(),
__metadata("design:type", Boolean)
], OListPickerComponent.prototype, "textInputEnabled", void 0);
__decorate([
BooleanInputConverter(),
__metadata("design:type", Boolean)
], OListPickerComponent.prototype, "dialogDisableClose", void 0);
__decorate([
BooleanInputConverter(),
__metadata("design:type", Boolean)
], OListPickerComponent.prototype, "filter", void 0);
__decorate([
NumberInputConverter(),
__metadata("design:type", Number)
], OListPickerComponent.prototype, "queryRows", void 0);
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: OListPickerComponent, decorators: [{
type: Component,
args: [{ selector: 'o-list-picker', providers: [
OntimizeServiceProvider,
{ provide: OFormServiceComponent, useExisting: forwardRef(() => OListPickerComponent) }
], inputs: DEFAULT_INPUTS_O_LIST_PICKER, outputs: DEFAULT_OUTPUTS_O_LIST_PICKER, template: "<div (click)=\"onClickInput($event)\" fxLayout=\"row\" fxLayoutAlign=\"space-between center\" [formGroup]=\"getFormGroup()\"\n [matTooltip]=\"tooltip\" [matTooltipClass]=\"tooltipClass\" [matTooltipPosition]=\"tooltipPosition\"\n [matTooltipShowDelay]=\"tooltipShowDelay\" [matTooltipHideDelay]=\"tooltipHideDelay\"\n class=\"custom-error o-list-picker-content\" [oContextMenu]=\"oContextMenu\">\n <input #inputModel class=\"input-model\" type=\"text\" [id]=\"getAttribute()\" [formControlName]=\"getAttribute()\">\n\n <mat-form-field [appearance]=\"appearance\" [floatLabel]=\"floatLabel\" [class.custom-width]=\"hasCustomWidth\"\n [hideRequiredMarker]=\"hideRequiredMarker\" class=\"icon-field\" #innerInputContainer fxFlexFill [subscriptSizing]=\"subscriptSizing\">\n <mat-label *ngIf=\"labelVisible\">{{ olabel | oTranslate }}</mat-label>\n\n <input #visibleInput matInput type=\"text\" [attr.id]=\"'desc_' + getAttribute()\" [id]=\"'desc_' + getAttribute()\"\n [formControl]=\"stateCtrl\" [placeholder]=\"placeHolder\"\n (input)=\"onVisibleInputChange($event)\" (focus)=\"innerOnFocus($event)\" (blur)=\"innerOnBlur($event)\"\n [readonly]=\"isReadOnly || !textInputEnabled\" [required]=\"isRequired\"\n (keydown.enter)=\"onKeydownEnter(visibleInput.value)\" (change)=\"onChangeEvent($event)\">\n\n <button type=\"button\" [disabled]=\"isReadOnly || !enabled\" [class.read-only]=\"isReadOnly\" matSuffix mat-icon-button\n (click)=\"onClickListpicker($event)\">\n <mat-icon svgIcon=\"ontimize:search\"></mat-icon>\n </button>\n\n <button type=\"button\" [disabled]=\"isReadOnly || !enabled\" [class.read-only]=\"isReadOnly\" matSuffix mat-icon-button\n (click)=\"onClickClearValue($event)\" *ngIf=\"showClearButton\">\n <mat-icon svgIcon=\"ontimize:clear\"></mat-icon>\n </button>\n\n <mat-error *oMatError=\"hasError('required')\">\n {{ 'FORM_VALIDATION.REQUIRED' | oTranslate }}\n </mat-error>\n <mat-error *ngFor=\"let oError of getActiveOErrors()\">\n {{ oError.text | oTranslate }}\n </mat-error>\n </mat-form-field>\n\n <o-context-menu *ngIf=\"!this.isReadOnly && this.enabled\">\n <o-context-menu-item attr=\"refresh\" label=\"FORM_SERVICE_COMPONENT.REFRESH\" svg-icon=\"ontimize:autorenew\" (execute)=\"refresh()\">\n </o-context-menu-item>\n </o-context-menu>\n</div>\n", styles: [".o-list-picker-content .input-model{display:none!important}.o-list-picker-content .mat-mdc-button.mat-disabled{cursor:default}\n"] }]
}], ctorParameters: function () { return [{ type: i14.OFormComponent, decorators: [{
type: Optional
}, {
type: Inject,
args: [forwardRef(() => OFormComponent)]
}] }, { type: i0.ElementRef }, { type: i0.Injector }]; }, propDecorators: { textInputEnabled: [], dialogDisableClose: [], filter: [], queryRows: [], inputModel: [{
type: ViewChild,
args: ['inputModel']
}], visibleInput: [{
type: ViewChild,
args: ['visibleInput']
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiby1saXN0LXBpY2tlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9vbnRpbWl6ZS13ZWItbmd4L3NyYy9saWIvY29tcG9uZW50cy9pbnB1dC9saXN0cGlja2VyL28tbGlzdC1waWNrZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvb250aW1pemUtd2ViLW5neC9zcmMvbGliL2NvbXBvbmVudHMvaW5wdXQvbGlzdHBpY2tlci9vLWxpc3QtcGlja2VyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBRUwsU0FBUyxFQUNULFVBQVUsRUFDVixZQUFZLEVBQ1osVUFBVSxFQUNWLE1BQU0sRUFDTixRQUFRLEVBR1IsUUFBUSxFQUVSLFNBQVMsRUFDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNwRCxPQUFPLEVBQUUsU0FBUyxFQUFpQyxNQUFNLDBCQUEwQixDQUFDO0FBQ3BGLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUVuRCxPQUFPLEVBQUUscUJBQXFCLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUNsRyxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUN0RSxPQUFPLEVBQUUsSUFBSSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDMUMsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzdELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLGtDQUFrQyxDQUFDO0FBRXJFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLG1DQUFtQyxDQUFDO0FBRTFFLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLGtDQUFrQyxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7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QUFHLEVBQUUsQ0FBQyxjQUFjLENBQUM7NEZBMUIvQyxnQkFBZ0IsTUFFaEIsa0JBQWtCLE1BRWYsTUFBTSxNQUtOLFNBQVMsTUFRZ0IsVUFBVTtzQkFBNUMsU0FBUzt1QkFBQyxZQUFZO2dCQUNjLFlBQVk7c0JBQWhELFNBQVM7dUJBQUMsY0FBYyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBmb3J3YXJkUmVmLFxuICBJbmplY3QsXG4gIEluamVjdG9yLFxuICBPbkNoYW5nZXMsXG4gIE9uSW5pdCxcbiAgT3B0aW9uYWwsXG4gIFNpbXBsZUNoYW5nZSxcbiAgVmlld0NoaWxkXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgVW50eXBlZEZvcm1Db250cm9sIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgTWF0RGlhbG9nLCBNYXREaWFsb2dDb25maWcsIE1hdERpYWxvZ1JlZiB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2RpYWxvZyc7XG5pbXBvcnQgeyBNYXRJbnB1dCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2lucHV0JztcblxuaW1wb3J0IHsgQm9vbGVhbklucHV0Q29udmVydGVyLCBOdW1iZXJJbnB1dENvbnZlcnRlciB9IGZyb20gJy4uLy4uLy4uL2RlY29yYXRvcnMvaW5wdXQtY29udmVydGVyJztcbmltcG9ydCB7IE9udGltaXplU2VydmljZVByb3ZpZGVyIH0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvZmFjdG9yaWVzJztcbmltcG9ydCB7IFV0aWwgfSBmcm9tICcuLi8uLi8uLi91dGlsL3V0aWwnO1xuaW1wb3J0IHsgT0Zvcm1Db21wb25lbnQgfSBmcm9tICcuLi8uLi9mb3JtL28tZm9ybS5jb21wb25lbnQnO1xuaW1wb3J0IHsgT1ZhbHVlQ2hhbmdlRXZlbnQgfSBmcm9tICcuLi8uLi9vLXZhbHVlLWNoYW5nZS1ldmVudC5jbGFzcyc7XG5pbXBvcnQgeyBPRm9ybUNvbnRyb2wgfSBmcm9tICcuLi9vLWZvcm0tY29udHJvbC5jbGFzcyc7XG5pbXBvcnQgeyBPRm9ybVNlcnZpY2VDb21wb25lbnQgfSBmcm9tICcuLi9vLWZvcm0tc2VydmljZS1jb21wb25lbnQuY2xhc3MnO1xuaW1wb3J0IHsgT0xpc3RQaWNrZXJDdXN0b21SZW5kZXJlciB9IGZyb20gJy4vbGlzdHBpY2tlci1yZW5kZXJlci9vLWxpc3QtcGlja2VyLXJlbmRlcmVyLmNsYXNzJztcbmltcG9ydCB7IE9MaXN0UGlja2VyRGlhbG9nQ29tcG9uZW50IH0gZnJvbSAnLi9vLWxpc3QtcGlja2VyLWRpYWxvZy5jb21wb25lbnQnO1xuXG5leHBvcnQgY29uc3QgREVGQVVMVF9JTlBVVFNfT19MSVNUX1BJQ0tFUiA9IFtcbiAgJ2ZpbHRlcicsXG4gICdkaWFsb2dXaWR0aCA6IGRpYWxvZy13aWR0aCcsXG4gICdkaWFsb2dIZWlnaHQgOiBkaWFsb2ctaGVpZ2h0JyxcbiAgJ3F1ZXJ5Um93czogcXVlcnktcm93cycsXG4gICd0ZXh0SW5wdXRFbmFibGVkOiB0ZXh0LWlucHV0LWVuYWJsZWQnLFxuICAnZGlhbG9nRGlzYWJsZUNsb3NlOiBkaWFsb2ctZGlzYWJsZS1jbG9zZScsXG4gICdkaWFsb2dDbGFzczogZGlhbG9nLWNsYXNzJ1xuXTtcblxuZXhwb3J0IGNvbnN0IERFRkFVTFRfT1VUUFVUU19PX0xJU1RfUElDS0VSID0gW1xuICAnb25EaWFsb2dBY2NlcHQnLFxuICAnb25EaWFsb2dDYW5jZWwnXG5dO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdvLWxpc3QtcGlja2VyJyxcbiAgdGVtcGxhdGVVcmw6ICcuL28tbGlzdC1waWNrZXIuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9vLWxpc3QtcGlja2VyLmNvbXBvbmVudC5zY3NzJ10sXG4gIHByb3ZpZGVyczogW1xuICAgIE9udGltaXplU2VydmljZVByb3ZpZGVyLFxuICAgIHsgcHJvdmlkZTogT0Zvcm1TZXJ2aWNlQ29tcG9uZW50LCB1c2VFeGlzdGluZzogZm9yd2FyZFJlZigoKSA9PiBPTGlzdFBpY2tlckNvbXBvbmVudCkgfVxuICBdLFxuICBpbnB1dHM6IERFRkFVTFRfSU5QVVRTX09fTElTVF9QSUNLRVIsXG4gIG91dHB1dHM6IERFRkFVTFRfT1VUUFVUU19PX0xJU1RfUElDS0VSXG59KVxuZXhwb3J0IGNsYXNzIE9MaXN0UGlja2VyQ29tcG9uZW50IGV4dGVuZHMgT0Zvcm1TZXJ2aWNlQ29tcG9uZW50IGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25DaGFuZ2VzLCBPbkluaXQge1xuXG4gIC8qIE91dHB1dHMgKi9cbiAgcHVibGljIG9uRGlhbG9nQWNjZXB0OiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgcHVibGljIG9uRGlhbG9nQ2FuY2VsOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgLyogRW5kIG91dHB1dHMgKi9cblxuICBwdWJsaWMgc3RhdGVDdHJsOiBVbnR5cGVkRm9ybUNvbnRyb2w7XG5cbiAgLyogSW5wdXRzICovXG4gIEBCb29sZWFuSW5wdXRDb252ZXJ0ZXIoKVxuICBwdWJsaWMgdGV4dElucHV0RW5hYmxlZDogYm9vbGVhbiA9IHRydWU7XG4gIEBCb29sZWFuSW5wdXRDb252ZXJ0ZXIoKVxuICBwdWJsaWMgZGlhbG9nRGlzYWJsZUNsb3NlOiBib29sZWFuID0gZmFsc2U7XG4gIEBCb29sZWFuSW5wdXRDb252ZXJ0ZXIoKVxuICBwcm90ZWN0ZWQgZmlsdGVyOiBib29sZWFuID0gdHJ1ZTtcbiAgcHJvdGVjdGVkIGRpYWxvZ1dpZHRoOiBzdHJpbmc7XG4gIHByb3RlY3RlZCBkaWFsb2dIZWlnaHQ6IHN0cmluZyA9ICc1NSUnO1xuICBwcm90ZWN0ZWQgZGlhbG9nQ2xhc3M6IHN0cmluZztcbiAgQE51bWJlcklucHV0Q29udmVydGVyKClcbiAgcHJvdGVjdGVkIHF1ZXJ5Um93czogbnVtYmVyO1xuXG5cbiAgcHVibGljIHJlbmRlcmVyOiBPTGlzdFBpY2tlckN1c3RvbVJlbmRlcmVyO1xuXG4gIHByb3RlY3RlZCBtYXREaWFsb2c6IE1hdERpYWxvZztcbiAgcHJvdGVjdGVkIGRpYWxvZ1JlZjogTWF0RGlhbG9nUmVmPE9MaXN0UGlja2VyRGlhbG9nQ29tcG9uZW50PjtcblxuICBAVmlld0NoaWxkKCdpbnB1dE1vZGVsJykgcHJvdGVjdGVkIGlucHV0TW9kZWw6IE1hdElucHV0O1xuICBAVmlld0NoaWxkKCd2aXNpYmxlSW5wdXQnKSBwcm90ZWN0ZWQgdmlzaWJsZUlucHV0OiBFbGVtZW50UmVmO1xuICBwcm90ZWN0ZWQgdmlzaWJsZUlucHV0VmFsdWU6IGFueTtcblxuICBwcm90ZWN0ZWQgYmx1clRpbWVyO1xuICBwcm90ZWN0ZWQgYmx1ckRlbGF5ID0gMjAwO1xuICBwcm90ZWN0ZWQgYmx1clByZXZlbnQgPSBmYWxzZTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KGZvcndhcmRSZWYoKCkgPT4gT0Zvcm1Db21wb25lbnQpKSBmb3JtOiBPRm9ybUNvbXBvbmVudCxcbiAgICBlbFJlZjogRWxlbWVudFJlZixcbiAgICBpbmplY3RvcjogSW5qZWN0b3IpIHtcbiAgICBzdXBlcihmb3JtLCBlbFJlZiwgaW5qZWN0b3IpO1xuICAgIHRoaXMubWF0RGlhbG9nID0gdGhpcy5pbmplY3Rvci5nZXQ8TWF0RGlhbG9nPihNYXREaWFsb2cpO1xuICAgIHRoaXMuc3RhdGVDdHJsID0gbmV3IFVudHlwZWRGb3JtQ29udHJvbCgpO1xuXG4gICAgLyogb3ZlcndyaXR0ZSBjbGVhckJ1dHRvbiB0byB0cnVlICovXG4gICAgdGhpcy5jbGVhckJ1dHRvbiA9IHRydWU7XG4gIH1cblxuICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5pbml0aWFsaXplKCk7XG4gICAgLy8gRW5zdXJpbmcgdmFsdWUgaW4gdGhlIHN0YXRlQ3RybFxuICAgIC8vIChqdXN0IGluIGNhc2UgaXQgd2FzIGNyZWF0ZWQgd2l0aCBhIGVtcHR5IHZhbHVlIGJlZm9yZSB0aGUgZkNvbnRyb2wgZGF0YSBpbml0aWFsaXphdGlvbilcbiAgICBpZiAoIVV0aWwuaXNEZWZpbmVkKHRoaXMuc3RhdGVDdHJsLnZhbHVlKSkge1xuICAgICAgdGhpcy5zZXRTdGF0ZUN0cmxWYWx1ZSgpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBuZ09uQ2hhbmdlcyhjaGFuZ2VzOiB7IFtwcm9wTmFtZTogc3RyaW5nXTogU2ltcGxlQ2hhbmdlIH0pOiB2b2lkIHtcbiAgICBzdXBlci5uZ09uQ2hhbmdlcyhjaGFuZ2VzKTtcbiAgICBpZiAodHlwZW9mIChjaGFuZ2VzLnN0YXRpY0RhdGEpICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhpcy5jYWNoZVF1ZXJpZWQgPSB0cnVlO1xuICAgICAgdGhpcy5zZXREYXRhQXJyYXkoY2hhbmdlcy5zdGF0aWNEYXRhLmN1cnJlbnRWYWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGNyZWF0ZUZvcm1Db250cm9sKGNmZz8sIHZhbGlkYXRvcnM/KTogT0Zvcm1Db250cm9sIHtcbiAgICB0aGlzLl9mQ29udHJvbCA9IHN1cGVyLmNyZWF0ZUZvcm1Db250cm9sKGNmZywgdmFsaWRhdG9ycyk7XG4gICAgdGhpcy5fZkNvbnRyb2wuZkNvbnRyb2xDaGlsZHJlbiA9IFt0aGlzLnN0YXRlQ3RybF07XG4gICAgcmV0dXJuIHRoaXMuX2ZDb250cm9sO1xuICB9XG5cbiAgcHVibGljIGVuc3VyZU9Gb3JtVmFsdWUodmFsdWU6IGFueSk6IHZvaWQge1xuICAgIHN1cGVyLmVuc3VyZU9Gb3JtVmFsdWUodmFsdWUpO1xuICAgIC8vIFRoaXMgY2FsbCBtYWtlIHRoZSBjb21wb25lbnQgcXVlcnlpbmcgaXRzIGRhdGEgbXVsdGlwbGUgdGltZXMsIGJ1dCBnZXR0aW5nIGRlc2NyaXB0aW9uIHZhbHVlIGlzIG5lZWRlZFxuICAgIHRoaXMuc3luY0RhdGFJbmRleChmYWxzZSk7XG4gIH1cblxuICBwdWJsaWMgc2V0RW5hYmxlZCh2YWx1ZTogYm9vbGVhbik6IHZvaWQge1xuICAgIHN1cGVyLnNldEVuYWJsZWQodmFsdWUpO1xuICAgIGlmICh0aGlzLnN0YXRlQ3RybCAmJiB0aGlzLmhhc0VuYWJsZWRQZXJtaXNzaW9uKCkgfHwgdGhpcy5oYXNWaXNpYmxlUGVybWlzc2lvbigpKSB7XG4gICAgICB2YWx1ZSA/IHRoaXMuc3RhdGVDdHJsLmVuYWJsZSgpIDogdGhpcy5zdGF0ZUN0cmwuZGlzYWJsZSgpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgc3VwZXIubmdBZnRlclZpZXdJbml0KCk7XG4gICAgaWYgKHRoaXMucXVlcnlPbkluaXQpIHtcbiAgICAgIHRoaXMucXVlcnlEYXRhKCk7XG4gICAgfSBlbHNlIGlmICh0aGlzLnF1ZXJ5T25CaW5kKSB7XG4gICAgICAvLyBUT0RPIGRvIGl0IGJldHRlci4gV2hlbiBjaGFuZ2luZyB0YWJzIGl0IGlzIG5lY2Vzc2FyeSB0byBpbnZva2UgbmV3IHF1ZXJ5XG4gICAgICB0aGlzLnN5bmNEYXRhSW5kZXgoKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgZ2V0RGVzY3JpcHRpb25WYWx1ZSgpOiBzdHJpbmcge1xuICAgIGlmICghVXRpbC5pc0RlZmluZWQodGhpcy5kZXNjcmlwdGlvbkNvbEFycmF5KSB8fCAhVXRpbC5pc0RlZmluZWQodGhpcy5fY3VycmVudEluZGV4KSkge1xuICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgICBpZiAoVXRpbC5pc0RlZmluZWQodGhpcy5yZW5kZXJlcikpIHtcbiAgICAgIHJldHVybiB0aGlzLnJlbmRlcmVyLmdldExpc3RQaWNrZXJWYWx1ZSh0aGlzLmRhdGFBcnJheVt0aGlzLl9jdXJyZW50SW5kZXhdKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHRoaXMuZ2V0T3B0aW9uRGVzY3JpcHRpb25WYWx1ZSh0aGlzLmRhdGFBcnJheVt0aGlzLl9jdXJyZW50SW5kZXhdKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgb25DbGlja0NsZWFyKGU6IEV2ZW50KTogdm9pZCB7XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgaWYgKCF0aGlzLmlzUmVhZE9ubHkgJiYgdGhpcy5lbmFibGVkKSB7XG4gICAgICBjbGVhclRpbWVvdXQodGhpcy5ibHVyVGltZXIpO1xuICAgICAgdGhpcy5ibHVyUHJldmVudCA9IHRydWU7XG4gICAgICB0aGlzLnNldFZhbHVlKHVuZGVmaW5lZCk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIG9uQ2xpY2tJbnB1dChlOiBFdmVudCk6IHZvaWQge1xuICAgIGlmICghdGhpcy50ZXh0SW5wdXRFbmFibGVkKSB7XG4gICAgICB0aGlzLm9uQ2xpY2tMaXN0cGlja2VyKGUpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBvbkNsaWNrTGlzdHBpY2tlcihlOiBFdmVudCk6IHZvaWQge1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGlmICghdGhpcy5pc1JlYWRPbmx5ICYmIHRoaXMuZW5hYmxlZCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuYmx1clRpbWVyKTtcbiAgICAgIHRoaXMub3BlbkRpYWxvZygpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBvbkRpYWxvZ0Nsb3NlKGV2dDogYW55KTogdm9pZCB7XG4gICAgdGhpcy5kaWFsb2dSZWYgPSBudWxsO1xuICAgIHRoaXMudmlzaWJsZUlucHV0VmFsdWUgPSB1bmRlZmluZWQ7XG4gICAgaWYgKGV2dCBpbnN0YW5jZW9mIE9iamVjdCAmJiB0eXBlb2YgZXZ0W3RoaXMudmFsdWVDb2x1bW5dICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgICB3aW5kb3cuc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgIHNlbGYuc2V0VmFsdWUoZXZ0W3NlbGYudmFsdWVDb2x1bW5dLCB7IGNoYW5nZVR5cGU6IE9WYWx1ZUNoYW5nZUV2ZW50LlVTRVJfQ0hBTkdFIH0pO1xuICAgICAgICBpZiAoc2VsZi5fZkNvbnRyb2wpIHtcbiAgICAgICAgICBzZWxmLl9mQ29udHJvbC5tYXJrQXNUb3VjaGVkKCk7XG4gICAgICAgICAgc2VsZi5fZkNvbnRyb2wubWFya0FzRGlydHkoKTtcbiAgICAgICAgfVxuICAgICAgICBzZWxmLm9uRGlhbG9nQWNjZXB0LmVtaXQoKTtcbiAgICAgIH0sIDApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm9uRGlhbG9nQ2FuY2VsLmVtaXQoKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgaW5uZXJPbkJsdXIoZXZ0OiBhbnkpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaXNSZWFkT25seSAmJiB0aGlzLmVuYWJsZWQpIHtcbiAgICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuICAgICAgdGhpcy5ibHVyVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgaWYgKCFzZWxmLmJsdXJQcmV2ZW50KSB7XG4gICAgICAgICAgc2VsZi5fZkNvbnRyb2wubWFya0FzVG91Y2hlZCgpO1xuICAgICAgICAgIHNlbGYub25CbHVyLmVtaXQoZXZ0KTtcbiAgICAgICAgICBpZiAoc2VsZi52aXNpYmxlSW5wdXRWYWx1ZSAhPT0gdW5kZWZpbmVkICYmIHNlbGYudmlzaWJsZUlucHV0VmFsdWUubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgc2VsZi5vcGVuRGlhbG9nKCk7XG4gICAgICAgICAgfSBlbHNlIGlmIChzZWxmLnZpc2libGVJbnB1dFZhbHVlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHNlbGYuc2V0VmFsdWUodW5kZWZpbmVkKTtcbiAgICAgICAgICAgIHNlbGYudmlzaWJsZUlucHV0VmFsdWUgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHNlbGYuX2ZDb250cm9sLm1hcmtBc1RvdWNoZWQoKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgc2VsZi5ibHVyUHJldmVudCA9IGZhbHNlO1xuICAgICAgfSwgdGhpcy5ibHVyRGVsYXkpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBvblZpc2libGVJbnB1dENoYW5nZShldmVudDogYW55KTogdm9pZCB7XG4gICAgdGhpcy52aXNpYmxlSW5wdXRWYWx1ZSA9IGV2ZW50LnRhcmdldC52YWx1ZTtcbiAgfVxuXG4gIHB1YmxpYyBvbktleWRvd25FbnRlcih2YWw6IGFueSk6IHZvaWQge1xuICAgIGNsZWFyVGltZW91dCh0aGlzLmJsdXJUaW1lcik7XG4gICAgdGhpcy5ibHVyUHJldmVudCA9IHRydWU7XG4gICAgdGhpcy52aXNpYmxlSW5wdXRWYWx1ZSA9IHZhbDtcbiAgICB0aGlzLm9wZW5EaWFsb2coKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvcGVuRGlhbG9nKCk6IHZvaWQge1xuICAgIGNvbnN0IGNmZzogTWF0RGlhbG9nQ29uZmlnID0ge1xuICAgICAgcm9sZTogJ2RpYWxvZycsXG4gICAgICBkaXNhYmxlQ2xvc2U6IHRoaXMuZGlhbG9nRGlzYWJsZUNsb3NlLFxuICAgICAgcGFuZWxDbGFzczogWydjZGstb3ZlcmxheS1saXN0LXBpY2tlcicsICdvLWRpYWxvZy1jbGFzcycsIHRoaXMuZGlhbG9nQ2xhc3NdLFxuICAgICAgZGF0YToge1xuICAgICAgICBkYXRhOiB0aGlzLmdldERpYWxvZ0RhdGFBcnJheSh0aGlzLmRhdGFBcnJheSksXG4gICAgICAgIGZpbHRlcjogdGhpcy5maWx0ZXIsXG4gICAgICAgIHNlYXJjaFZhbDogdGhpcy52aXNpYmxlSW5wdXRWYWx1ZSxcbiAgICAgICAgbWVudUNvbHVtbnM6IHRoaXMudmlzaWJsZUNvbHVtbnMsIC8vIFRPRE86IGltcHJvdmUgdGhpcywgdGhpcyBpcyBwYXNzZWQgdG8gYG8tc2VhcmNoLWlucHV0YCBvZiB0aGUgZGlhbG9nXG4gICAgICAgIHZpc2libGVDb2x1bW5zOiB0aGlzLnZpc2libGVDb2xBcnJheSxcbiAgICAgICAgcXVlcnlSb3dzOiB0aGlzLnF1ZXJ5Um93cyxcbiAgICAgICAgcmVuZGVyZXI6IHRoaXMucmVuZGVyZXJcbiAgICAgIH1cbiAgICB9O1xuICAgIGlmICh0aGlzLmRpYWxvZ1dpZHRoICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGNmZy53aWR0aCA9IHRoaXMuZGlhbG9nV2lkdGg7XG4gICAgfVxuICAgIGlmICh0aGlzLmRpYWxvZ0hlaWdodCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBjZmcuaGVpZ2h0ID0gdGhpcy5kaWFsb2dIZWlnaHQ7XG4gICAgfVxuICAgIHRoaXMuZGlhbG9nUmVmID0gdGhpcy5tYXREaWFsb2cub3BlbihPTGlzdFBpY2tlckRpYWxvZ0NvbXBvbmVudCwgY2ZnKTtcblxuICAgIHRoaXMuZGlhbG9nUmVmLmFmdGVyQ2xvc2VkKCkuc3Vic2NyaWJlKHJlc3VsdCA9PiB0aGlzLm9uRGlhbG9nQ2xvc2UocmVzdWx0KSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0RGlhbG9nRGF0YUFycmF5KGRhdGFBcnJheTogYW55W10pOiBhbnlbXSB7XG4gICAgY29uc3QgcmVzdWx0OiBhbnlbXSA9IFtdO1xuICAgIGRhdGFBcnJheS5mb3JFYWNoKChpdGVtLCBpdGVtSW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IG5ld0l0ZW0gPSBPYmplY3QuYXNzaWduKHt9LCBpdGVtKTtcbiAgICAgIGlmICghdGhpcy5yZW5kZXJlcikge1xuICAgICAgICBuZXdJdGVtLl9wYXJzZWRWaXNpYmxlQ29sdW1uVGV4dCA9IHRoaXMuZ2V0VmlzaWJsZUNvbHVtblRleHQoaXRlbSk7XG4gICAgICB9XG4gICAgICBuZXdJdGVtLl9wYXJzZWRJbmRleCA9IGl0ZW1JbmRleDtcbiAgICAgIHJlc3VsdC5wdXNoKG5ld0l0ZW0pO1xuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0VmlzaWJsZUNvbHVtblRleHQoaXRlbTogYW55KSB7XG4gICAgbGV0IGVsZW1lbnQgPSAnJztcbiAgICB0aGlzLnZpc2libGVDb2xBcnJheS5mb3JFYWNoKCh2aXNpYmxlQ29sLCBpbmRleCkgPT4ge1xuICAgICAgZWxlbWVudCArPSBpdGVtW3Zpc2libGVDb2xdO1xuICAgICAgaWYgKChpbmRleCArIDEpIDwgdGhpcy52aXNpYmxlQ29sQXJyYXkubGVuZ3RoKSB7XG4gICAgICAgIGVsZW1lbnQgKz0gdGhpcy5zZXBhcmF0b3I7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH1cblxuXG4gIHB1YmxpYyByZWdpc3RlclJlbmRlcmVyKHJlbmRlcmVyOiBhbnkpIHtcbiAgICB0aGlzLnJlbmRlcmVyID0gcmVuZGVyZXI7XG4gICAgdGhpcy5yZW5kZXJlci5pbml0aWFsaXplKCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc2V0U3RhdGVDdHJsVmFsdWUoKSB7XG4gICAgbGV0IGRlc2NyaXB0aW9uVmFsdWUgPSB0aGlzLmdldERlc2NyaXB0aW9uVmFsdWUoKTtcbiAgICBpZiAodHlwZW9mIGRlc2NyaXB0aW9uVmFsdWUgPT09ICdzdHJpbmcnICYmIGRlc2NyaXB0aW9uVmFsdWUubGVuZ3RoID09PSAwKSB7XG4gICAgICBkZXNjcmlwdGlvblZhbHVlID0gbnVsbDtcbiAgICB9XG4gICAgdGhpcy5zdGF0ZUN0cmwuc2V0VmFsdWUoZGVzY3JpcHRpb25WYWx1ZSk7XG4gIH1cblxuICBzeW5jRGF0YUluZGV4KHF1ZXJ5SWZOb3RGb3VuZD86IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBzdXBlci5zeW5jRGF0YUluZGV4KHF1ZXJ5SWZOb3RGb3VuZCk7XG4gICAgdGhpcy5zZXRTdGF0ZUN0cmxWYWx1ZSgpO1xuICB9XG5cbiAgcHVibGljIHNlbGVjdFZhbHVlKCkge1xuICAgIGNvbnN0IGlucHV0RWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgnZGVzY18nICsgdGhpcy5vYXR0cik7XG4gICAgaWYgKGlucHV0RWwpIHtcbiAgICAgIChpbnB1dEVsIGFzIEhUTUxJbnB1dEVsZW1lbnQpLnNlbGVjdCgpO1xuICAgIH1cbiAgfVxuXG59XG4iLCI8ZGl2IChjbGljayk9XCJvbkNsaWNrSW5wdXQoJGV2ZW50KVwiIGZ4TGF5b3V0PVwicm93XCIgZnhMYXlvdXRBbGlnbj1cInNwYWNlLWJldHdlZW4gY2VudGVyXCIgW2Zvcm1Hcm91cF09XCJnZXRGb3JtR3JvdXAoKVwiXG4gIFttYXRUb29sdGlwXT1cInRvb2x0aXBcIiBbbWF0VG9vbHRpcENsYXNzXT1cInRvb2x0aXBDbGFzc1wiIFttYXRUb29sdGlwUG9zaXRpb25dPVwidG9vbHRpcFBvc2l0aW9uXCJcbiAgW21hdFRvb2x0aXBTaG93RGVsYXldPVwidG9vbHRpcFNob3dEZWxheVwiIFttYXRUb29sdGlwSGlkZURlbGF5XT1cInRvb2x0aXBIaWRlRGVsYXlcIlxuICBjbGFzcz1cImN1c3RvbS1lcnJvciBvLWxpc3QtcGlja2VyLWNvbnRlbnRcIiBbb0NvbnRleHRNZW51XT1cIm9Db250ZXh0TWVudVwiPlxuICA8aW5wdXQgI2lucHV0TW9kZWwgY2xhc3M9XCJpbnB1dC1tb2RlbFwiIHR5cGU9XCJ0ZXh0XCIgW2lkXT1cImdldEF0dHJpYnV0ZSgpXCIgW2Zvcm1Db250cm9sTmFtZV09XCJnZXRBdHRyaWJ1dGUoKVwiPlxuXG4gIDxtYXQtZm9ybS1maWVsZCBbYXBwZWFyYW5jZV09XCJhcHBlYXJhbmNlXCIgW2Zsb2F0TGFiZWxdPVwiZmxvYXRMYWJlbFwiIFtjbGFzcy5jdXN0b20td2lkdGhdPVwiaGFzQ3VzdG9tV2lkdGhcIlxuICAgIFtoaWRlUmVxdWlyZWRNYXJrZXJdPVwiaGlkZVJlcXVpcmVkTWFya2VyXCIgY2xhc3M9XCJpY29uLWZpZWxkXCIgI2lubmVySW5wdXRDb250YWluZXIgZnhGbGV4RmlsbCBbc3Vic2NyaXB0U2l6aW5nXT1cInN1YnNjcmlwdFNpemluZ1wiPlxuICAgIDxtYXQtbGFiZWwgKm5nSWY9XCJsYWJlbFZpc2libGVcIj57eyBvbGFiZWwgfCBvVHJhbnNsYXRlIH19PC9tYXQtbGFiZWw+XG5cbiAgICA8aW5wdXQgI3Zpc2libGVJbnB1dCBtYXRJbnB1dCB0eXBlPVwidGV4dFwiIFthdHRyLmlkXT1cIidkZXNjXycgKyBnZXRBdHRyaWJ1dGUoKVwiIFtpZF09XCInZGVzY18nICsgZ2V0QXR0cmlidXRlKClcIlxuICAgICAgW2Zvcm1Db250cm9sXT1cInN0YXRlQ3RybFwiIFtwbGFjZWhvbGRlcl09XCJwbGFjZUhvbGRlclwiXG4gICAgICAoaW5wdXQpPVwib25WaXNpYmxlSW5wdXRDaGFuZ2UoJGV2ZW50KVwiIChmb2N1cyk9XCJpbm5lck9uRm9jdXMoJGV2ZW50KVwiIChibHVyKT1cImlubmVyT25CbHVyKCRldmVudClcIlxuICAgICAgW3JlYWRvbmx5XT1cImlzUmVhZE9ubHkgfHwgIXRleHRJbnB1dEVuYWJsZWRcIiBbcmVxdWlyZWRdPVwiaXNSZXF1aXJlZFwiXG4gICAgICAoa2V5ZG93bi5lbnRlcik9XCJvbktleWRvd25FbnRlcih2aXNpYmxlSW5wdXQudmFsdWUpXCIgKGNoYW5nZSk9XCJvbkNoYW5nZUV2ZW50KCRldmVudClcIj5cblxuICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIFtkaXNhYmxlZF09XCJpc1JlYWRPbmx5IHx8ICFlbmFibGVkXCIgW2NsYXNzLnJlYWQtb25seV09XCJpc1JlYWRPbmx5XCIgbWF0U3VmZml4IG1hdC1pY29uLWJ1dHRvblxuICAgICAgKGNsaWNrKT1cIm9uQ2xpY2tMaXN0cGlja2VyKCRldmVudClcIj5cbiAgICAgIDxtYXQtaWNvbiBzdmdJY29uPVwib250aW1pemU6c2VhcmNoXCI+PC9tYXQtaWNvbj5cbiAgICA8L2J1dHRvbj5cblxuICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIFtkaXNhYmxlZF09XCJpc1JlYWRPbmx5IHx8ICFlbmFibGVkXCIgW2NsYXNzLnJlYWQtb25seV09XCJpc1JlYWRPbmx5XCIgbWF0U3VmZml4IG1hdC1pY29uLWJ1dHRvblxuICAgICAgKGNsaWNrKT1cIm9uQ2xpY2tDbGVhclZhbHVlKCRldmVudClcIiAqbmdJZj1cInNob3dDbGVhckJ1dHRvblwiPlxuICAgICAgPG1hdC1pY29uIHN2Z0ljb249XCJvbnRpbWl6ZTpjbGVhclwiPjwvbWF0LWljb24+XG4gICAgPC9idXR0b24+XG5cbiAgICA8bWF0LWVycm9yICpvTWF0RXJyb3I9XCJoYXNFcnJvcigncmVxdWlyZWQnKVwiPlxuICAgICAge3sgJ0ZPUk1fVkFMSURBVElPTi5SRVFVSVJFRCcgfCBvVHJhbnNsYXRlIH19XG4gICAgPC9tYXQtZXJyb3I+XG4gICAgPG1hdC1lcnJvciAqbmdGb3I9XCJsZXQgb0Vycm9yIG9mIGdldEFjdGl2ZU9FcnJvcnMoKVwiPlxuICAgICAge3sgb0Vycm9yLnRleHQgfCBvVHJhbnNsYXRlIH19XG4gICAgPC9tYXQtZXJyb3I+XG4gIDwvbWF0LWZvcm0tZmllbGQ+XG5cbiAgPG8tY29udGV4dC1tZW51ICpuZ0lmPVwiIXRoaXMuaXNSZWFkT25seSAmJiB0aGlzLmVuYWJsZWRcIj5cbiAgICA8by1jb250ZXh0LW1lbnUtaXRlbSBhdHRyPVwicmVmcmVzaFwiIGxhYmVsPVwiRk9STV9TRVJWSUNFX0NPTVBPTkVOVC5SRUZSRVNIXCIgc3ZnLWljb249XCJvbnRpbWl6ZTphdXRvcmVuZXdcIiAoZXhlY3V0ZSk9XCJyZWZyZXNoKClcIj5cbiAgICA8L28tY29udGV4dC1tZW51LWl0ZW0+XG4gIDwvby1jb250ZXh0LW1lbnU+XG48L2Rpdj5cbiJdfQ==