stimulsoft-forms
Version:
Stimulsoft PDF Forms
459 lines (455 loc) • 39.1 kB
JavaScript
import { Component, Input, ViewChild } from "@angular/core";
import { StiTableElement } from "../../../../../elements/StiTableElement";
import { RotateAnimation } from "../../../../animations/animations";
import * as i0 from "@angular/core";
import * as i1 from "../../../../../services/model.service";
import * as i2 from "../../../../../services/sti-helper.service";
import * as i3 from "../../../../../services/theme.service";
import * as i4 from "../../../../../services/sti-localization.service";
import * as i5 from "../../../../../services/sti-column-draggable.service";
import * as i6 from "../../../../../services/mouse.service";
import * as i7 from "@angular/common";
import * as i8 from "../table-column-editor/table-column-editor.component";
export class StiTableColumnsEditorComponent {
getMaxWidth() {
return this.model.propertyGridWidth - 20;
}
get disabled() {
return this.property.property != "columns" &&
this.model?.selectedComponent?.element instanceof StiTableElement &&
this.model?.selectedComponent?.element.columns.length == 0
? true
: false;
}
constructor(model, helper, theme, loc, draggableService, mouseService) {
this.model = model;
this.helper = helper;
this.theme = theme;
this.loc = loc;
this.draggableService = draggableService;
this.mouseService = mouseService;
this.arrayOfStates = [];
this.minWidth = 40;
this.isDrag = false;
}
ngOnInit() {
if (this.items.length != this.arrayOfStates.length) {
this.items.forEach(() => {
this.arrayOfStates.push("default");
});
this.model.currentContentEditableItem.subscribe((index) => this.refreshState(index));
}
}
get items() {
return this.helper.getProperty(this.model.selectedComponent.element, this.property.property);
}
onHeaderClick(event, item) {
event.preventDefault();
this.draggableService.startX = event["offsetX"];
this.draggableService.startY = event["offsetY"];
this.draggableService.containerWidth = this.booleanButton?.nativeElement.offsetWidth;
this.draggableService.onHeaderClick(event, item, this.items);
}
refreshState(index) {
if (this.arrayOfStates.length != this.items.length) {
this.arrayOfStates = [];
this.items.forEach(() => {
this.arrayOfStates.push("default");
});
}
this.arrayOfStates.forEach((state, i) => {
if (i != index) {
this.arrayOfStates[i] = "default";
}
else {
this.arrayOfStates[i] = "rotated";
}
});
}
changeState(i) {
if (!this.isDrag) {
this.arrayOfStates[i] = this.arrayOfStates[i] == "default" ? "rotated" : "default";
}
}
addItem(event, element) {
if (this.model.selectedComponent.element instanceof StiTableElement) {
if (this.property.property == "columns") {
this.model.selectedComponent.element.addColumnLikeLast();
this.model.showColumnPreview(this.items.length - 1);
}
else {
this.helper.addTotalMenuItems = null;
this.model.toggleTieredMenu(element);
}
}
}
deleteItem(i) {
this.items.splice(i, 1);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: StiTableColumnsEditorComponent, deps: [{ token: i1.StiModelService }, { token: i2.StiHelperService }, { token: i3.StiThemeService }, { token: i4.StiLocalizationService }, { token: i5.StiColumnDraggableService }, { token: i6.StiMouseService }], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: StiTableColumnsEditorComponent, selector: "sti-table-columns-editor", inputs: { property: "property" }, viewQueries: [{ propertyName: "booleanButton", first: true, predicate: ["booleanButton"], descendants: true }], ngImport: i0, template: `
<table class="sti-clear drop-area" [style]="{ width: '100%' }">
<tr *ngIf="draggableService.isDragging && !draggableService.fromTable">
<td [style]="{ height: '3px', width: '100%' }" (mousemove)="draggableService.insertIndex = 0">
<div
class="drag-preview"
[style.margin-bottom]="'-5px'"
[style.height.px]="draggableService.insertIndex == 0 ? 6 : 0"
>
<div class="middle-part" *ngIf="draggableService.insertIndex == 0"></div>
</div>
</td>
</tr>
<tr *ngFor="let item of items; index as i">
<td
colspan="7"
*ngIf="(!draggableService.fromTable && draggableService.item != item) || draggableService.fromTable"
>
<div
#booleanButton
class="boolean-button"
[style.max-width.px]="getMaxWidth()"
(click)="changeState(i)"
(mouseover)="overIndex = i"
(mouseleave)="overIndex = null"
(mousedown)="onHeaderClick($event, item)"
(mousemove)="!draggableService.fromTable ? (draggableService.insertIndex = i + 1) : return"
>
<div class="arrow" [@rotatedState]="arrayOfStates[i]">
<span class="select-button"><i class="pi pi-chevron-right"></i></span>
</div>
<div class="content">
{{
this.property.property == "columns"
? item.label
? item.label
: "Column " + (i + 1)
: item.header
? item.header
: "Total Field " + (i + 1)
}}
</div>
<div class="delete" *ngIf="draggableService.insertIndex == -1">
<div class="delete-button" (click)="deleteItem(i)" *ngIf="overIndex == i">
<img [src]="model.getImage('images.Ribbon.Delete.png')" />
</div>
</div>
</div>
<sti-table-column-editor
[column]="item"
[state]="arrayOfStates[i] == 'default' ? false : true"
[index]="i"
[expression]="item?.calculationAlgorithm?.expression"
></sti-table-column-editor>
<div
class="drag-preview"
[style.height.px]="!draggableService.fromTable && draggableService.insertIndex == i + 1 ? 6 : 0"
>
<div class="middle-part" *ngIf="!draggableService.fromTable && draggableService.insertIndex == i + 1"></div>
</div>
</td>
</tr>
<tr [style.text-align]="'start'">
<td>
<button #addButton class="add-button" [disabled]="disabled" (click)="addItem($event, addButton)">
<!--addItem()-->
{{
this.property.property == "columns"
? loc.get2("FormDictionaryDesigner", "ColumnNew")
: loc.get2("FormDictionaryDesigner", "NewItem")
}}
</button>
</td>
</tr>
</table>
<style>
.middle-part {
position: absolute;
width: 100%;
left: 0;
top: 50%;
border-bottom: 3px solid rgb(198, 198, 198);
}
tr {
padding: 3px 0px 3px 0px;
}
i {
width: 10px;
height: 10px;
}
.arrow {
width: 20px;
text-align: center;
cursor: default;
-webkit-touch-callout: none;
-webkit-user-select: none;
}
.content {
cursor: default;
-webkit-touch-callout: none;
-webkit-user-select: none;
flex: 1;
overflow: hidden;
}
.delete {
width: 45px;
display: flex;
height: 100%;
}
.delete-button {
width: 22px;
height: 100%;
border-radius: 3px;
background-color: var(--hover-color);
display: flex;
align-items: center;
justify-content: center;
}
.delete-button img {
height: 16px;
width: 16px;
}
.delete-button:hover {
background-color: var(--columnDeleteHover-color);
}
.delete-button:active {
background-color: var(--hover-color);
}
.boolean-button {
width: 100%;
height: 22px;
margin-top: 2px;
display: flex;
flex-direction: row;
color: var(--text-color);
background-color: var(--hover-color);
border-top: 2px solid var(--toolbarResizerBorder-color);
}
.drag-preview {
width: 100%;
margin-bottom: -3px;
background-color: transparent;
position: relative;
transition: height 50ms ease-in-out;
}
.add-button {
min-width: 100px;
min-height: 22px;
padding: 3px 6px;
margin-top: 5px;
text-decoration: none;
font-weight: 600;
font-size: 12px;
color: var(--text-color);
text-align: center;
justify-content: center;
background-color: var(--input-color);
border-top: 2px solid var(--toolbarResizerBorder-color);
border-left: 1px solid var(--toolbarResizerBorder-color);
border-right: 1px solid var(--toolbarResizerBorder-color);
border-bottom: 1px solid var(--toolbarResizerBorder-color);
border-radius: 3px;
}
.add-button:not([disabled]):hover {
background-color: var(--hover-color);
}
.add-button[disabled] {
opacity: 0.7;
pointer-events: none;
background-color: var(--hover-color);
}
.add-button:active {
background-color: var(--active-color);
}
</style>
`, isInline: true, styles: ["\n .middle-part {\n position: absolute;\n width: 100%;\n left: 0;\n top: 50%;\n border-bottom: 3px solid rgb(198, 198, 198);\n }\n tr {\n padding: 3px 0px 3px 0px;\n }\n i {\n width: 10px;\n height: 10px;\n }\n .arrow {\n width: 20px;\n text-align: center;\n cursor: default;\n -webkit-touch-callout: none;\n -webkit-user-select: none;\n }\n .content {\n cursor: default;\n -webkit-touch-callout: none;\n -webkit-user-select: none;\n flex: 1;\n overflow: hidden;\n }\n .delete {\n width: 45px;\n display: flex;\n height: 100%;\n }\n .delete-button {\n width: 22px;\n height: 100%;\n border-radius: 3px;\n background-color: var(--hover-color);\n display: flex;\n align-items: center;\n justify-content: center;\n }\n .delete-button img {\n height: 16px;\n width: 16px;\n }\n .delete-button:hover {\n background-color: var(--columnDeleteHover-color);\n }\n .delete-button:active {\n background-color: var(--hover-color);\n }\n .boolean-button {\n width: 100%;\n height: 22px;\n margin-top: 2px;\n display: flex;\n flex-direction: row;\n color: var(--text-color);\n background-color: var(--hover-color);\n border-top: 2px solid var(--toolbarResizerBorder-color);\n }\n\n .drag-preview {\n width: 100%;\n margin-bottom: -3px;\n background-color: transparent;\n position: relative;\n transition: height 50ms ease-in-out;\n }\n .add-button {\n min-width: 100px;\n min-height: 22px;\n padding: 3px 6px;\n margin-top: 5px;\n text-decoration: none;\n font-weight: 600;\n font-size: 12px;\n color: var(--text-color);\n text-align: center;\n justify-content: center;\n background-color: var(--input-color);\n border-top: 2px solid var(--toolbarResizerBorder-color);\n border-left: 1px solid var(--toolbarResizerBorder-color);\n border-right: 1px solid var(--toolbarResizerBorder-color);\n border-bottom: 1px solid var(--toolbarResizerBorder-color);\n border-radius: 3px;\n }\n .add-button:not([disabled]):hover {\n background-color: var(--hover-color);\n }\n .add-button[disabled] {\n opacity: 0.7;\n pointer-events: none;\n background-color: var(--hover-color);\n }\n .add-button:active {\n background-color: var(--active-color);\n }\n "], dependencies: [{ kind: "directive", type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i8.StiTableColumnEditorComponent, selector: "sti-table-column-editor", inputs: ["column", "state", "index", "expression"] }], animations: [RotateAnimation] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: StiTableColumnsEditorComponent, decorators: [{
type: Component,
args: [{
selector: "sti-table-columns-editor",
template: `
<table class="sti-clear drop-area" [style]="{ width: '100%' }">
<tr *ngIf="draggableService.isDragging && !draggableService.fromTable">
<td [style]="{ height: '3px', width: '100%' }" (mousemove)="draggableService.insertIndex = 0">
<div
class="drag-preview"
[style.margin-bottom]="'-5px'"
[style.height.px]="draggableService.insertIndex == 0 ? 6 : 0"
>
<div class="middle-part" *ngIf="draggableService.insertIndex == 0"></div>
</div>
</td>
</tr>
<tr *ngFor="let item of items; index as i">
<td
colspan="7"
*ngIf="(!draggableService.fromTable && draggableService.item != item) || draggableService.fromTable"
>
<div
#booleanButton
class="boolean-button"
[style.max-width.px]="getMaxWidth()"
(click)="changeState(i)"
(mouseover)="overIndex = i"
(mouseleave)="overIndex = null"
(mousedown)="onHeaderClick($event, item)"
(mousemove)="!draggableService.fromTable ? (draggableService.insertIndex = i + 1) : return"
>
<div class="arrow" [@rotatedState]="arrayOfStates[i]">
<span class="select-button"><i class="pi pi-chevron-right"></i></span>
</div>
<div class="content">
{{
this.property.property == "columns"
? item.label
? item.label
: "Column " + (i + 1)
: item.header
? item.header
: "Total Field " + (i + 1)
}}
</div>
<div class="delete" *ngIf="draggableService.insertIndex == -1">
<div class="delete-button" (click)="deleteItem(i)" *ngIf="overIndex == i">
<img [src]="model.getImage('images.Ribbon.Delete.png')" />
</div>
</div>
</div>
<sti-table-column-editor
[column]="item"
[state]="arrayOfStates[i] == 'default' ? false : true"
[index]="i"
[expression]="item?.calculationAlgorithm?.expression"
></sti-table-column-editor>
<div
class="drag-preview"
[style.height.px]="!draggableService.fromTable && draggableService.insertIndex == i + 1 ? 6 : 0"
>
<div class="middle-part" *ngIf="!draggableService.fromTable && draggableService.insertIndex == i + 1"></div>
</div>
</td>
</tr>
<tr [style.text-align]="'start'">
<td>
<button #addButton class="add-button" [disabled]="disabled" (click)="addItem($event, addButton)">
<!--addItem()-->
{{
this.property.property == "columns"
? loc.get2("FormDictionaryDesigner", "ColumnNew")
: loc.get2("FormDictionaryDesigner", "NewItem")
}}
</button>
</td>
</tr>
</table>
<style>
.middle-part {
position: absolute;
width: 100%;
left: 0;
top: 50%;
border-bottom: 3px solid rgb(198, 198, 198);
}
tr {
padding: 3px 0px 3px 0px;
}
i {
width: 10px;
height: 10px;
}
.arrow {
width: 20px;
text-align: center;
cursor: default;
-webkit-touch-callout: none;
-webkit-user-select: none;
}
.content {
cursor: default;
-webkit-touch-callout: none;
-webkit-user-select: none;
flex: 1;
overflow: hidden;
}
.delete {
width: 45px;
display: flex;
height: 100%;
}
.delete-button {
width: 22px;
height: 100%;
border-radius: 3px;
background-color: var(--hover-color);
display: flex;
align-items: center;
justify-content: center;
}
.delete-button img {
height: 16px;
width: 16px;
}
.delete-button:hover {
background-color: var(--columnDeleteHover-color);
}
.delete-button:active {
background-color: var(--hover-color);
}
.boolean-button {
width: 100%;
height: 22px;
margin-top: 2px;
display: flex;
flex-direction: row;
color: var(--text-color);
background-color: var(--hover-color);
border-top: 2px solid var(--toolbarResizerBorder-color);
}
.drag-preview {
width: 100%;
margin-bottom: -3px;
background-color: transparent;
position: relative;
transition: height 50ms ease-in-out;
}
.add-button {
min-width: 100px;
min-height: 22px;
padding: 3px 6px;
margin-top: 5px;
text-decoration: none;
font-weight: 600;
font-size: 12px;
color: var(--text-color);
text-align: center;
justify-content: center;
background-color: var(--input-color);
border-top: 2px solid var(--toolbarResizerBorder-color);
border-left: 1px solid var(--toolbarResizerBorder-color);
border-right: 1px solid var(--toolbarResizerBorder-color);
border-bottom: 1px solid var(--toolbarResizerBorder-color);
border-radius: 3px;
}
.add-button:not([disabled]):hover {
background-color: var(--hover-color);
}
.add-button[disabled] {
opacity: 0.7;
pointer-events: none;
background-color: var(--hover-color);
}
.add-button:active {
background-color: var(--active-color);
}
</style>
`,
animations: [RotateAnimation],
}]
}], ctorParameters: () => [{ type: i1.StiModelService }, { type: i2.StiHelperService }, { type: i3.StiThemeService }, { type: i4.StiLocalizationService }, { type: i5.StiColumnDraggableService }, { type: i6.StiMouseService }], propDecorators: { property: [{
type: Input
}], booleanButton: [{
type: ViewChild,
args: ["booleanButton"]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUtY29sdW1ucy1lZGl0b3IuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvc3RpbXVsc29mdC1mb3Jtcy9zcmMvbGliL2NvbXBvbmVudHMvcHJvcGVydHlHcmlkL2VkaXRvcnMvdGFibGUvdGFibGUtY29sdW1ucy1lZGl0b3IvdGFibGUtY29sdW1ucy1lZGl0b3IuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQWMsS0FBSyxFQUFVLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNoRixPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFVMUUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLG1DQUFtQyxDQUFDOzs7Ozs7Ozs7O0FBd0xwRSxNQUFNLE9BQU8sOEJBQThCO0lBSWxDLFdBQVc7UUFDaEIsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLGlCQUFpQixHQUFHLEVBQUUsQ0FBQztJQUMzQyxDQUFDO0lBTUQsSUFBVyxRQUFRO1FBQ2pCLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLElBQUksU0FBUztZQUN4QyxJQUFJLENBQUMsS0FBSyxFQUFFLGlCQUFpQixFQUFFLE9BQU8sWUFBWSxlQUFlO1lBQ2pFLElBQUksQ0FBQyxLQUFLLEVBQUUsaUJBQWlCLEVBQUUsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLElBQUksQ0FBQztZQUMxRCxDQUFDLENBQUMsSUFBSTtZQUNOLENBQUMsQ0FBQyxLQUFLLENBQUM7SUFDWixDQUFDO0lBR0QsWUFDUyxLQUFzQixFQUN0QixNQUF3QixFQUN4QixLQUFzQixFQUN0QixHQUEyQixFQUMzQixnQkFBMkMsRUFDM0MsWUFBOEI7UUFMOUIsVUFBSyxHQUFMLEtBQUssQ0FBaUI7UUFDdEIsV0FBTSxHQUFOLE1BQU0sQ0FBa0I7UUFDeEIsVUFB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Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWlMVDtvQkFDRCxVQUFVLEVBQUUsQ0FBQyxlQUFlLENBQUM7aUJBQzlCOzRQQUdVLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ3NCLGFBQWE7c0JBQXhDLFNBQVM7dUJBQUMsZUFBZSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgRWxlbWVudFJlZiwgSW5wdXQsIE9uSW5pdCwgVmlld0NoaWxkIH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcclxuaW1wb3J0IHsgU3RpVGFibGVFbGVtZW50IH0gZnJvbSBcIi4uLy4uLy4uLy4uLy4uL2VsZW1lbnRzL1N0aVRhYmxlRWxlbWVudFwiO1xyXG5pbXBvcnQgeyBTdGlUb3RhbHNGaWVsZEl0ZW0gfSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vZWxlbWVudHMvdGFibGUvU3RpVG90YWxzRmllbGRJdGVtXCI7XHJcbmltcG9ydCB7IFN0aU1vZGVsU2VydmljZSB9IGZyb20gXCIuLi8uLi8uLi8uLi8uLi9zZXJ2aWNlcy9tb2RlbC5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IFN0aU1vdXNlU2VydmljZSB9IGZyb20gXCIuLi8uLi8uLi8uLi8uLi9zZXJ2aWNlcy9tb3VzZS5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IFN0aUVkaXRvclByb3BlcnR5IH0gZnJvbSBcIi4uLy4uLy4uLy4uLy4uL3NlcnZpY2VzL29iamVjdHNcIjtcclxuaW1wb3J0IHsgU3RpQ29sdW1uRHJhZ2dhYmxlU2VydmljZSB9IGZyb20gXCIuLi8uLi8uLi8uLi8uLi9zZXJ2aWNlcy9zdGktY29sdW1uLWRyYWdnYWJsZS5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IFN0aUhlbHBlclNlcnZpY2UgfSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vc2VydmljZXMvc3RpLWhlbHBlci5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IFN0aUxvY2FsaXphdGlvblNlcnZpY2UgfSBmcm9tIFwiLi4vLi4vLi4vLi4vLi4vc2VydmljZXMvc3RpLWxvY2FsaXphdGlvbi5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IFN0aVRoZW1lU2VydmljZSB9IGZyb20gXCIuLi8uLi8uLi8uLi8uLi9zZXJ2aWNlcy90aGVtZS5zZXJ2aWNlXCI7XHJcbmltcG9ydCB7IE1lbnUsIE1lbnVNb2R1bGUgfSBmcm9tIFwicHJpbWVuZy9tZW51XCI7XHJcbmltcG9ydCB7IFJvdGF0ZUFuaW1hdGlvbiB9IGZyb20gXCIuLi8uLi8uLi8uLi9hbmltYXRpb25zL2FuaW1hdGlvbnNcIjtcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiBcInN0aS10YWJsZS1jb2x1bW5zLWVkaXRvclwiLFxyXG4gIHRlbXBsYXRlOiBgXHJcbiAgICA8dGFibGUgY2xhc3M9XCJzdGktY2xlYXIgZHJvcC1hcmVhXCIgW3N0eWxlXT1cInsgd2lkdGg6ICcxMDAlJyB9XCI+XHJcbiAgICAgIDx0ciAqbmdJZj1cImRyYWdnYWJsZVNlcnZpY2UuaXNEcmFnZ2luZyAmJiAhZHJhZ2dhYmxlU2VydmljZS5mcm9tVGFibGVcIj5cclxuICAgICAgICA8dGQgW3N0eWxlXT1cInsgaGVpZ2h0OiAnM3B4Jywgd2lkdGg6ICcxMDAlJyB9XCIgKG1vdXNlbW92ZSk9XCJkcmFnZ2FibGVTZXJ2aWNlLmluc2VydEluZGV4ID0gMFwiPlxyXG4gICAgICAgICAgPGRpdlxyXG4gICAgICAgICAgICBjbGFzcz1cImRyYWctcHJldmlld1wiXHJcbiAgICAgICAgICAgIFtzdHlsZS5tYXJnaW4tYm90dG9tXT1cIictNXB4J1wiXHJcbiAgICAgICAgICAgIFtzdHlsZS5oZWlnaHQucHhdPVwiZHJhZ2dhYmxlU2VydmljZS5pbnNlcnRJbmRleCA9PSAwID8gNiA6IDBcIlxyXG4gICAgICAgICAgPlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwibWlkZGxlLXBhcnRcIiAqbmdJZj1cImRyYWdnYWJsZVNlcnZpY2UuaW5zZXJ0SW5kZXggPT0gMFwiPjwvZGl2PlxyXG4gICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC90ZD5cclxuICAgICAgPC90cj5cclxuXHJcbiAgICAgIDx0ciAqbmdGb3I9XCJsZXQgaXRlbSBvZiBpdGVtczsgaW5kZXggYXMgaVwiPlxyXG4gICAgICAgIDx0ZFxyXG4gICAgICAgICAgY29sc3Bhbj1cIjdcIlxyXG4gICAgICAgICAgKm5nSWY9XCIoIWRyYWdnYWJsZVNlcnZpY2UuZnJvbVRhYmxlICYmIGRyYWdnYWJsZVNlcnZpY2UuaXRlbSAhPSBpdGVtKSB8fCBkcmFnZ2FibGVTZXJ2aWNlLmZyb21UYWJsZVwiXHJcbiAgICAgICAgPlxyXG4gICAgICAgICAgPGRpdlxyXG4gICAgICAgICAgICAjYm9vbGVhbkJ1dHRvblxyXG4gICAgICAgICAgICBjbGFzcz1cImJvb2xlYW4tYnV0dG9uXCJcclxuICAgICAgICAgICAgW3N0eWxlLm1heC13aWR0aC5weF09XCJnZXRNYXhXaWR0aCgpXCJcclxuICAgICAgICAgICAgKGNsaWNrKT1cImNoYW5nZVN0YXRlKGkpXCJcclxuICAgICAgICAgICAgKG1vdXNlb3Zlcik9XCJvdmVySW5kZXggPSBpXCJcclxuICAgICAgICAgICAgKG1vdXNlbGVhdmUpPVwib3ZlckluZGV4ID0gbnVsbFwiXHJcbiAgICAgICAgICAgIChtb3VzZWRvd24pPVwib25IZWFkZXJDbGljaygkZXZlbnQsIGl0ZW0pXCJcclxuICAgICAgICAgICAgKG1vdXNlbW92ZSk9XCIhZHJhZ2dhYmxlU2VydmljZS5mcm9tVGFibGUgPyAoZHJhZ2dhYmxlU2VydmljZS5pbnNlcnRJbmRleCA9IGkgKyAxKSA6IHJldHVyblwiXHJcbiAgICAgICAgICA+XHJcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhcnJvd1wiIFtAcm90YXRlZFN0YXRlXT1cImFycmF5T2ZTdGF0ZXNbaV1cIj5cclxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNlbGVjdC1idXR0b25cIj48aSBjbGFzcz1cInBpIHBpLWNoZXZyb24tcmlnaHRcIj48L2k+PC9zcGFuPlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbnRlbnRcIj5cclxuICAgICAgICAgICAgICB7e1xyXG4gICAgICAgICAgICAgICAgdGhpcy5wcm9wZXJ0eS5wcm9wZXJ0eSA9PSBcImNvbHVtbnNcIlxyXG4gICAgICAgICAgICAgICAgICA/IGl0ZW0ubGFiZWxcclxuICAgICAgICAgICAgICAgICAgICA/IGl0ZW0ubGFiZWxcclxuICAgICAgICAgICAgICAgICAgICA6IFwiQ29sdW1uIFwiICsgKGkgKyAxKVxyXG4gICAgICAgICAgICAgICAgICA6IGl0ZW0uaGVhZGVyXHJcbiAgICAgICAgICAgICAgICAgID8gaXRlbS5oZWFkZXJcclxuICAgICAgICAgICAgICAgICAgOiBcIlRvdGFsIEZpZWxkIFwiICsgKGkgKyAxKVxyXG4gICAgICAgICAgICAgIH19XHJcbiAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGVsZXRlXCIgKm5nSWY9XCJkcmFnZ2FibGVTZXJ2aWNlLmluc2VydEluZGV4ID09IC0xXCI+XHJcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRlbGV0ZS1idXR0b25cIiAoY2xpY2spPVwiZGVsZXRlSXRlbShpKVwiICpuZ0lmPVwib3ZlckluZGV4ID09IGlcIj5cclxuICAgICAgICAgICAgICAgIDxpbWcgW3NyY109XCJtb2RlbC5nZXRJbWFnZSgnaW1hZ2VzLlJpYmJvbi5EZWxldGUucG5nJylcIiAvPlxyXG4gICAgICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgICAgPHN0aS10YWJsZS1jb2x1bW4tZWRpdG9yXHJcbiAgICAgICAgICAgIFtjb2x1bW5dPVwiaXRlbVwiXHJcbiAgICAgICAgICAgIFtzdGF0ZV09XCJhcnJheU9mU3RhdGVzW2ldID09ICdkZWZhdWx0JyA/IGZhbHNlIDogdHJ1ZVwiXHJcbiAgICAgICAgICAgIFtpbmRleF09XCJpXCJcclxuICAgICAgICAgICAgW2V4cHJlc3Npb25dPVwiaXRlbT8uY2FsY3VsYXRpb25BbGdvcml0aG0/LmV4cHJlc3Npb25cIlxyXG4gICAgICAgICAgPjwvc3RpLXRhYmxlLWNvbHVtbi1lZGl0b3I+XHJcbiAgICAgICAgICA8ZGl2XHJcbiAgICAgICAgICAgIGNsYXNzPVwiZHJhZy1wcmV2aWV3XCJcclxuICAgICAgICAgICAgW3N0eWxlLmhlaWdodC5weF09XCIhZHJhZ2dhYmxlU2VydmljZS5mcm9tVGFibGUgJiYgZHJhZ2dhYmxlU2VydmljZS5pbnNlcnRJbmRleCA9PSBpICsgMSA/IDYgOiAwXCJcclxuICAgICAgICAgID5cclxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1pZGRsZS1wYXJ0XCIgKm5nSWY9XCIhZHJhZ2dhYmxlU2VydmljZS5mcm9tVGFibGUgJiYgZHJhZ2dhYmxlU2VydmljZS5pbnNlcnRJbmRleCA9PSBpICsgMVwiPjwvZGl2PlxyXG4gICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPC90ZD5cclxuICAgICAgPC90cj5cclxuICAgICAgPHRyIFtzdHlsZS50ZXh0LWFsaWduXT1cIidzdGFydCdcIj5cclxuICAgICAgICA8dGQ+XHJcbiAgICAgICAgICA8YnV0dG9uICNhZGRCdXR0b24gY2xhc3M9XCJhZGQtYnV0dG9uXCIgW2Rpc2FibGVkXT1cImRpc2FibGVkXCIgKGNsaWNrKT1cImFkZEl0ZW0oJGV2ZW50LCBhZGRCdXR0b24pXCI+XHJcbiAgICAgICAgICAgIDwhLS1hZGRJdGVtKCktLT5cclxuICAgICAgICAgICAge3tcclxuICAgICAgICAgICAgICB0aGlzLnByb3BlcnR5LnByb3BlcnR5ID09IFwiY29sdW1uc1wiXHJcbiAgICAgICAgICAgICAgICA/IGxvYy5nZXQyKFwiRm9ybURpY3Rpb25hcnlEZXNpZ25lclwiLCBcIkNvbHVtbk5ld1wiKVxyXG4gICAgICAgICAgICAgICAgOiBsb2MuZ2V0MihcIkZvcm1EaWN0aW9uYXJ5RGVzaWduZXJcIiwgXCJOZXdJdGVtXCIpXHJcbiAgICAgICAgICAgIH19XHJcbiAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICA8L3RkPlxyXG4gICAgICA8L3RyPlxyXG4gICAgPC90YWJsZT5cclxuICAgIDxzdHlsZT5cclxuICAgICAgLm1pZGRsZS1wYXJ0IHtcclxuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XHJcbiAgICAgICAgd2lkdGg6IDEwMCU7XHJcbiAgICAgICAgbGVmdDogMDtcclxuICAgICAgICB0b3A6IDUwJTtcclxuICAgICAgICBib3JkZXItYm90dG9tOiAzcHggc29saWQgcmdiKDE5OCwgMTk4LCAxOTgpO1xyXG4gICAgICB9XHJcbiAgICAgIHRyIHtcclxuICAgICAgICBwYWRkaW5nOiAzcHggMHB4IDNweCAwcHg7XHJcbiAgICAgIH1cclxuICAgICAgaSB7XHJcbiAgICAgICAgd2lkdGg6IDEwcHg7XHJcbiAgICAgICAgaGVpZ2h0OiAxMHB4O1xyXG4gICAgICB9XHJcbiAgICAgIC5hcnJvdyB7XHJcbiAgICAgICAgd2lkdGg6IDIwcHg7XHJcbiAgICAgICAgdGV4dC1hbGlnbjogY2VudGVyO1xyXG4gICAgICAgIGN1cnNvcjogZGVmYXVsdDtcclxuICAgICAgICAtd2Via2l0LXRvdWNoLWNhbGxvdXQ6IG5vbmU7XHJcbiAgICAgICAgLXdlYmtpdC11c2VyLXNlbGVjdDogbm9uZTtcclxuICAgICAgfVxyXG4gICAgICAuY29udGVudCB7XHJcbiAgICAgICAgY3Vyc29yOiBkZWZhdWx0O1xyXG4gICAgICAgIC13ZWJraXQtdG91Y2gtY2FsbG91dDogbm9uZTtcclxuICAgICAgICAtd2Via2l0LXVzZXItc2VsZWN0OiBub25lO1xyXG4gICAgICAgIGZsZXg6IDE7XHJcbiAgICAgICAgb3ZlcmZsb3c6IGhpZGRlbjtcclxuICAgICAgfVxyXG4gICAgICAuZGVsZXRlIHtcclxuICAgICAgICB3aWR0aDogNDVweDtcclxuICAgICAgICBkaXNwbGF5OiBmbGV4O1xyXG4gICAgICAgIGhlaWdodDogMTAwJTtcclxuICAgICAgfVxyXG4gICAgICAuZGVsZXRlLWJ1dHRvbiB7XHJcbiAgICAgICAgd2lkdGg6IDIycHg7XHJcbiAgICAgICAgaGVpZ2h0OiAxMDAlO1xyXG4gICAgICAgIGJvcmRlci1yYWRpdXM6IDNweDtcclxuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1ob3Zlci1jb2xvcik7XHJcbiAgICAgICAgZGlzcGxheTogZmxleDtcclxuICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xyXG4gICAgICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xyXG4gICAgICB9XHJcbiAgICAgIC5kZWxldGUtYnV0dG9uIGltZyB7XHJcbiAgICAgICAgaGVpZ2h0OiAxNnB4O1xyXG4gICAgICAgIHdpZHRoOiAxNnB4O1xyXG4gICAgICB9XHJcbiAgICAgIC5kZWxldGUtYnV0dG9uOmhvdmVyIHtcclxuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1jb2x1bW5EZWxldGVIb3Zlci1jb2xvcik7XHJcbiAgICAgIH1cclxuICAgICAgLmRlbGV0ZS1idXR0b246YWN0aXZlIHtcclxuICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiB2YXIoLS1ob3Zlci1jb2xvcik7XHJcbiAgICAgIH1cclxuICAgICAgLmJvb2xlYW4tYnV0dG9uIHtcclxuICAgICAgICB3aWR0aDogMTAwJTtcclxuICAgICAgICBoZWlnaHQ6IDIycHg7XHJcbiAgICAgICAgbWFyZ2luLXRvcDogMnB4O1xyXG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XHJcbiAgICAgICAgZmxleC1kaXJlY3Rpb246IHJvdztcclxuICAgICAgICBjb2xvcjogdmFyKC0tdGV4dC1jb2xvcik7XHJcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0taG92ZXItY29sb3IpO1xyXG4gICAgICAgIGJvcmRlci10b3A6IDJweCBzb2xpZCB2YXIoLS10b29sYmFyUmVzaXplckJvcmRlci1jb2xvcik7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC5kcmFnLXByZXZpZXcge1xyXG4gICAgICAgIHdpZHRoOiAxMDAlO1xyXG4gICAgICAgIG1hcmdpbi1ib3R0b206IC0zcHg7XHJcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogdHJhbnNwYXJlbnQ7XHJcbiAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xyXG4gICAgICAgIHRyYW5zaXRpb246IGhlaWdodCA1MG1zIGVhc2UtaW4tb3V0O1xyXG4gICAgICB9XHJcbiAgICAgIC5hZGQtYnV0dG9uIHtcclxuICAgICAgICBtaW4td2lkdGg6IDEwMHB4O1xyXG4gICAgICAgIG1pbi1oZWlnaHQ6IDIycHg7XHJcbiAgICAgICAgcGFkZGluZzogM3B4IDZweDtcclxuICAgICAgICBtYXJnaW4tdG9wOiA1cHg7XHJcbiAgICAgICAgdGV4dC1kZWNvcmF0aW9uOiBub25lO1xyXG4gICAgICAgIGZvbnQtd2VpZ2h0OiA2MDA7XHJcbiAgICAgICAgZm9udC1zaXplOiAxMnB4O1xyXG4gICAgICAgIGNvbG9yOiB2YXIoLS10ZXh0LWNvbG9yKTtcclxuICAgICAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XHJcbiAgICAgICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XHJcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0taW5wdXQtY29sb3IpO1xyXG4gICAgICAgIGJvcmRlci10b3A6IDJweCBzb2xpZCB2YXIoLS10b29sYmFyUmVzaXplckJvcmRlci1jb2xvcik7XHJcbiAgICAgICAgYm9yZGVyLWxlZnQ6IDFweCBzb2xpZCB2YXIoLS10b29sYmFyUmVzaXplckJvcmRlci1jb2xvcik7XHJcbiAgICAgICAgYm9yZGVyLXJpZ2h0OiAxcHggc29saWQgdmFyKC0tdG9vbGJhclJlc2l6ZXJCb3JkZXItY29sb3IpO1xyXG4gICAgICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCB2YXIoLS10b29sYmFyUmVzaXplckJvcmRlci1jb2xvcik7XHJcbiAgICAgICAgYm9yZGVyLXJhZGl1czogM3B4O1xyXG4gICAgICB9XHJcbiAgICAgIC5hZGQtYnV0dG9uOm5vdChbZGlzYWJsZWRdKTpob3ZlciB7XHJcbiAgICAgICAgYmFja2dyb3VuZC1jb2xvcjogdmFyKC0taG92ZXItY29sb3IpO1xyXG4gICAgICB9XHJcbiAgICAgIC5hZGQtYnV0dG9uW2Rpc2FibGVkXSB7XHJcbiAgICAgICAgb3BhY2l0eTogMC43O1xyXG4gICAgICAgIHBvaW50ZXItZXZlbnRzOiBub25lO1xyXG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWhvdmVyLWNvbG9yKTtcclxuICAgICAgfVxyXG4gICAgICAuYWRkLWJ1dHRvbjphY3RpdmUge1xyXG4gICAgICAgIGJhY2tncm91bmQtY29sb3I6IHZhcigtLWFjdGl2ZS1jb2xvcik7XHJcbiAgICAgIH1cclxuICAgIDwvc3R5bGU+XHJcbiAgYCxcclxuICBhbmltYXRpb25zOiBbUm90YXRlQW5pbWF0aW9uXSxcclxufSlcclxuZXhwb3J0IGNsYXNzIFN0aVRhYmxlQ29sdW1uc0VkaXRvckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcbiAgcHVibGljIG92ZXJJbmRleDtcclxuICBASW5wdXQoKSBwcm9wZXJ0eTogU3RpRWRpdG9yUHJvcGVydHk7XHJcbiAgQFZpZXdDaGlsZChcImJvb2xlYW5CdXR0b25cIikgYm9vbGVhbkJ1dHRvbjogRWxlbWVudFJlZjtcclxuICBwdWJsaWMgZ2V0TWF4V2lkdGgoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5tb2RlbC5wcm9wZXJ0eUdyaWRXaWR0aCAtIDIwO1xyXG4gIH1cclxuICBhcnJheU9mU3RhdGVzID0gW107XHJcbiAgcHVibGljIHdpZHRoRGlmZmVyZW5jZTogbnVtYmVyO1xyXG4gIHB1YmxpYyBtaW5XaWR0aDogbnVtYmVyID0gNDA7XHJcbiAgcHVibGljIGlzRHJhZzogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICBwdWJsaWMgZ2V0IGRpc2FibGVkKCkge1xyXG4gICAgcmV0dXJuIHRoaXMucHJvcGVydHkucHJvcGVydHkgIT0gXCJjb2x1bW5zXCIgJiZcclxuICAgICAgdGhpcy5tb2RlbD8uc2VsZWN0ZWRDb21wb25lbnQ/LmVsZW1lbnQgaW5zdGFuY2VvZiBTdGlUYWJsZUVsZW1lbnQgJiZcclxuICAgICAgdGhpcy5tb2RlbD8uc2VsZWN0ZWRDb21wb25lbnQ/LmVsZW1lbnQuY29sdW1ucy5sZW5ndGggPT0gMFxyXG4gICAgICA/IHRydWVcclxuICAgICAgOiBmYWxzZTtcclxuICB9XHJcbiAgcHVibGljIGRyYWdnYWJsZUl0ZW06IG51bWJlcjtcclxuXHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwdWJsaWMgbW9kZWw6IFN0aU1vZGVsU2VydmljZSxcclxuICAgIHB1YmxpYyBoZWxwZXI6IFN0aUhlbHBlclNlcnZpY2UsXHJcbiAgICBwdWJsaWMgdGhlbWU6IFN0aVRoZW1lU2VydmljZSxcclxuICAgIHB1YmxpYyBsb2M6IFN0aUxvY2FsaXphdGlvblNlcnZpY2UsXHJcbiAgICBwdWJsaWMgZHJhZ2dhYmxlU2VydmljZTogU3RpQ29sdW1uRHJhZ2dhYmxlU2VydmljZSxcclxuICAgIHB1YmxpYyBtb3VzZVNlcnZpY2U/OiBTdGlNb3VzZVNlcnZpY2VcclxuICApIHsgfVxyXG4gIG5nT25Jbml0KCk6IHZvaWQge1xyXG4gICAgaWYgKHRoaXMuaXRlbXMubGVuZ3RoICE9IHRoaXMuYXJyYXlPZlN0YXRlcy5sZW5ndGgpIHtcclxuICAgICAgdGhpcy5pdGVtcy5mb3JFYWNoKCgpID0+IHtcclxuICAgICAgICB0aGlzLmFycmF5T2ZTdGF0ZXMucHVzaChcImRlZmF1bHRcIik7XHJcbiAgICAgIH0pO1xyXG4gICAgICB0aGlzLm1vZGVsLmN1cnJlbnRDb250ZW50RWRpdGFibGVJdGVtLnN1YnNjcmliZSgoaW5kZXgpID0+IHRoaXMucmVmcmVzaFN0YXRlKGluZGV4KSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgZ2V0IGl0ZW1zKCk6IGFueVtdIHtcclxuICAgIHJldHVybiB0aGlzLmhlbHBlci5nZXRQcm9wZXJ0eSh0aGlzLm1vZGVsLnNlbGVjdGVkQ29tcG9uZW50LmVsZW1lbnQsIHRoaXMucHJvcGVydHkucHJvcGVydHkpO1xyXG4gIH1cclxuXHJcbiAgb25IZWFkZXJDbGljayhldmVudDogTW91c2VFdmVudCwgaXRlbTogYW55KSB7XHJcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xyXG4gICAgdGhpcy5kcmFnZ2FibGVTZXJ2aWNlLnN0YXJ0WCA9IGV2ZW50W1wib2Zmc2V0WFwiXTtcclxuICAgIHRoaXMuZHJhZ2dhYmxlU2VydmljZS5zdGFydFkgPSBldmVudFtcIm9mZnNldFlcIl07XHJcbiAgICB0aGlzLmRyYWdnYWJsZVNlcnZpY2UuY29udGFpbmVyV2lkdGggPSB0aGlzLmJvb2xlYW5CdXR0b24/Lm5hdGl2ZUVsZW1lbnQub2Zmc2V0V2lkdGg7XHJcbiAgICB0aGlzLmRyYWdnYWJsZVNlcnZpY2Uub25IZWFkZXJDbGljayhldmVudCwgaXRlbSwgdGhpcy5pdGVtcyk7XHJcbiAgfVxyXG5cclxuICByZWZyZXNoU3RhdGUoaW5kZXgpIHtcclxuICAgIGlmICh0aGlzLmFycmF5T2ZTdGF0ZXMubGVuZ3RoICE9IHRoaXMuaXRlbXMubGVuZ3RoKSB7XHJcbiAgICAgIHRoaXMuYXJyYXlPZlN0YXRlcyA9IFtdO1xyXG4gICAgICB0aGlzLml0ZW1zLmZvckVhY2goKCkgPT4ge1xyXG4gICAgICAgIHRoaXMuYXJyYXlPZlN0YXRlcy5wdXNoKFwiZGVmYXVsdFwiKTtcclxuICAgICAgfSk7XHJcbiAgICB9XHJcbiAgICB0aGlzLmFycmF5T2ZTdGF0ZXMuZm9yRWFjaCgoc3RhdGUsIGkpID0+IHtcclxuICAgICAgaWYgKGkgIT0gaW5kZXgpIHtcclxuICAgICAgICB0aGlzLmFycmF5T2ZTdGF0ZXNbaV0gPSBcImRlZmF1bHRcIjtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLmFycmF5T2ZTdGF0ZXNbaV0gPSBcInJvdGF0ZWRcIjtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG4gIGNoYW5nZVN0YXRlKGkpIHtcclxuICAgIGlmICghdGhpcy5pc0RyYWcpIHtcclxuICAgICAgdGhpcy5hcnJheU9mU3RhdGVzW2ldID0gdGhpcy5hcnJheU9mU3RhdGVzW2ldID09IFwiZGVmYXVsdFwiID8gXCJyb3RhdGVkXCIgOiBcImRlZmF1bHRcIjtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGFkZEl0ZW0oZXZlbnQsIGVsZW1lbnQpIHtcclxuICAgIGlmICh0aGlzLm1vZGVsLnNlbGVjdGVkQ29tcG9uZW50LmVsZW1lbnQgaW5zdGFuY2VvZiBTdGlUYWJsZUVsZW1lbnQpIHtcclxuICAgICAgaWYgKHRoaXMucHJvcGVydHkucHJvcGVydHkgPT0gXCJjb2x1bW5zXCIpIHtcclxuICAgICAgICB0aGlzLm1vZGVsLnNlbGVjdGVkQ29tcG9uZW50LmVsZW1lbnQuYWRkQ29sdW1uTGlrZUxhc3QoKTtcclxuICAgICAgICB0aGlzLm1vZGVsLnNob3dDb2x1bW5QcmV2aWV3KHRoaXMuaXRlbXMubGVuZ3RoIC0gMSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhpcy5oZWxwZXIuYWRkVG90YWxNZW51SXRlbXMgPSBudWxsO1xyXG4gICAgICAgIHRoaXMubW9kZWwudG9nZ2xlVGllcmVkTWVudShlbGVtZW50KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuICBkZWxldGVJdGVtKGkpIHtcclxuICAgIHRoaXMuaXRlbXMuc3BsaWNlKGksIDEpO1xyXG4gIH1cclxufVxyXG4iXX0=