@nakedobjects/gemini
Version:
Single Page Application client for a Naked Objects application.
148 lines • 30.6 kB
JavaScript
import { Component, ViewChildren } from '@angular/core';
import * as Ro from '@nakedobjects/restful-objects';
import each from 'lodash-es/each';
import find from 'lodash-es/find';
import forEach from 'lodash-es/forEach';
import map from 'lodash-es/map';
import some from 'lodash-es/some';
import { createForm, safeUnsubscribe } from '../helpers-components';
import { PaneComponent } from '../pane/pane';
import { ParametersComponent } from '../parameters/parameters.component';
import * as i0 from "@angular/core";
import * as i1 from "@angular/router";
import * as i2 from "@nakedobjects/services";
import * as i3 from "@nakedobjects/view-models";
import * as i4 from "@angular/forms";
import * as i5 from "@angular/common";
import * as i6 from "../parameters/parameters.component";
import * as i7 from "../click.directive";
export class MultiLineDialogComponent extends PaneComponent {
viewModelFactory;
error;
formBuilder;
configService;
constructor(activatedRoute, urlManager, viewModelFactory, context, error, formBuilder, configService) {
super(activatedRoute, urlManager, context);
this.viewModelFactory = viewModelFactory;
this.error = error;
this.formBuilder = formBuilder;
this.configService = configService;
}
parmComponents;
sub;
dialog;
rowData;
form = (i) => {
const rowData = this.rowData[i];
return rowData.form;
};
get objectFriendlyName() {
return this.dialog.objectFriendlyName;
}
get objectTitle() {
return this.dialog.objectTitle;
}
get dialogTitle() {
return this.dialog.title;
}
get header() {
return this.dialog.header();
}
get rows() {
return this.dialog.dialogs;
}
parameters = (row) => row.parameters;
rowSubmitted = (row) => row.submitted;
rowTooltip = (row) => row.tooltip();
rowMessage = (row) => {
return row.getMessageOrSubmitted();
};
rowDisabled = (row) => {
return !row.clientValid() || row.submitted;
};
get count() {
return this.dialog.submittedCountMsg();
}
invokeAndAdd(index) {
const parms = this.rowData[index].parms;
forEach(parms, p => {
const newValue = this.rowData[index].form.value[p.id];
p.setValueFromControl(newValue);
});
const addedIndex = this.dialog.invokeAndAdd(index);
if (addedIndex) {
this.rowData.push(this.createForm(this.dialog.dialogs[addedIndex]));
}
}
close = () => {
this.urlManager.popUrlState();
};
createForm(dialog) {
return createForm(dialog, this.formBuilder);
}
setMultiLineDialog(holder, newDialogId, routeData, actionViewModel) {
const action = holder.actionMember(newDialogId);
this.context.getInvokableAction(action).
then(details => {
if (actionViewModel) {
actionViewModel.makeInvokable(details);
}
this.dialog = this.viewModelFactory.multiLineDialogViewModel(routeData, details, holder);
this.rowData = map(this.dialog.dialogs, d => this.createForm(d));
}).
catch((reject) => this.error.handleError(reject));
}
setup(routeData) {
if (routeData.menuId) {
this.context.getMenu(routeData.menuId)
.then((menu) => {
this.setMultiLineDialog(menu, routeData.dialogId, routeData);
})
.catch((reject) => {
this.error.handleError(reject);
});
}
else if (routeData.objectId) {
const oid = Ro.ObjectIdWrapper.fromObjectId(routeData.objectId, this.configService.config.keySeparator);
this.context.getObject(routeData.paneId, oid, routeData.interactionMode).
then((object) => {
const ovm = this.viewModelFactory.domainObjectViewModel(object, routeData, false);
const newDialogId = routeData.dialogId;
const lcaCollection = find(ovm.collections, c => c.hasMatchingLocallyContributedAction(newDialogId));
if (lcaCollection) {
const actionViewModel = find(lcaCollection.actions, a => a.actionRep.actionId() === newDialogId);
this.setMultiLineDialog(lcaCollection, newDialogId, routeData, actionViewModel);
}
else {
this.setMultiLineDialog(object, newDialogId, routeData);
}
}).
catch((reject) => {
this.error.handleError(reject);
});
}
}
focus(parms) {
if (parms && parms.length > 0) {
some(parms.toArray(), p => p.focus());
}
}
ngAfterViewInit() {
this.sub = this.parmComponents?.changes.subscribe(ql => this.focus(ql));
}
ngOnDestroy() {
safeUnsubscribe(this.sub);
each(this.rowData, rd => safeUnsubscribe(rd.sub));
super.ngOnDestroy();
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: MultiLineDialogComponent, deps: [{ token: i1.ActivatedRoute }, { token: i2.UrlManagerService }, { token: i3.ViewModelFactoryService }, { token: i2.ContextService }, { token: i2.ErrorService }, { token: i4.FormBuilder }, { token: i2.ConfigService }], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "18.2.9", type: MultiLineDialogComponent, selector: "nof-multi-line-dialog", viewQueries: [{ propertyName: "parmComponents", predicate: ParametersComponent, descendants: true }], usesInheritance: true, ngImport: i0, template: "<div id=\"pane1\" class=\"single\">\n <div *ngIf=\"dialog\" class=\"multilinedialog\">\n <div class=\"header\">\n <div class=\"type\">{{objectFriendlyName}}</div>\n <div class=\"title\" gemini-drag tabindex=\"0\">\n <div>{{objectTitle}}</div>\n <div>{{dialogTitle}}</div>\n </div>\n </div>\n <div class=\"columnHeader\" *ngFor=\"let column of header\">{{column}}</div>\n <div class=\"lineDialog\" *ngFor=\"let row of rows; let i = index \">\n <form *ngIf=\"!rowSubmitted(row)\" (ngSubmit)=\"invokeAndAdd(i)\" [formGroup]=\"form(i)\" autocomplete=\"off\">\n <nof-parameters class=\"parameters multilinedialog\" [parameters]=\"parameters(row)\" [parent]=\"row\" [form]=\"form(i)\"></nof-parameters> \n <input class=\"ok\" tabindex=\"0\" type=\"submit\" value=\"OK\" title=\"{{rowTooltip(row)}}\" [disabled]=\"rowDisabled(row)\" nofClick (leftClick)=\"invokeAndAdd(i)\" />\n <div class=\"co-validation\">{{rowMessage(row)}}</div>\n </form>\n <nof-parameters *ngIf=\"rowSubmitted(row)\" class=\"parameters\" [parameters]=\"parameters(row)\" [parent]=\"row\"></nof-parameters>\n <div *ngIf=\"rowSubmitted(row)\" class=\"co-validation\">{{rowMessage(row)}}</div>\n </div>\n <input class=\"close\" tabindex=\"0\" type=\"submit\" value=\"Close\" title=\"\" nofClick (leftClick)=\"close()\" />\n <div class=\"count\">{{count}}</div>\n </div>\n</div>\n", styles: [":host{overflow-y:auto;color:var(--default-text-color);font-size:var(--font-size-2);font-weight:var(--font-weight-1);display:block;margin-left:var(--space-5);padding-bottom:60px}viewTitle{display:inline-block}.title,.header .type{position:relative;font-weight:var(--font-weight-2);font-size:var(--font-size-4);line-height:38pt;margin-left:var(--space-1);padding-left:var(--space-3);padding-right:var(--space-3);margin-right:var(--space-5);margin-top:var(--space-1);display:block}.header .type{float:left;margin-right:var(--space-5);display:none}nof-parameters{display:inline-block}.columnHeader{display:inline-block;vertical-align:top;width:var(--field-value-width);padding-left:var(--space-4)}input.ok{font-size:var(--font-size-1);height:var(--field-value-height);margin-top:var(--space-1);margin-right:0;margin-left:var(--space-1);margin-bottom:var(--space-3);padding-top:var(--space-1);padding-bottom:0;padding-left:var(--space-1);padding-right:var(--space-1);vertical-align:top}input.close{float:left;margin-left:6px;margin-right:var(--space-4)}.count{display:inline-block;margin-top:var(--space-1)}.co-validation{display:inline-block}\n"], dependencies: [{ kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i6.ParametersComponent, selector: "nof-parameters", inputs: ["parent", "form", "parameters"] }, { kind: "directive", type: i7.ClickDirective, selector: "[nofClick]", outputs: ["leftClick", "rightClick"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.9", ngImport: i0, type: MultiLineDialogComponent, decorators: [{
type: Component,
args: [{ selector: 'nof-multi-line-dialog', template: "<div id=\"pane1\" class=\"single\">\n <div *ngIf=\"dialog\" class=\"multilinedialog\">\n <div class=\"header\">\n <div class=\"type\">{{objectFriendlyName}}</div>\n <div class=\"title\" gemini-drag tabindex=\"0\">\n <div>{{objectTitle}}</div>\n <div>{{dialogTitle}}</div>\n </div>\n </div>\n <div class=\"columnHeader\" *ngFor=\"let column of header\">{{column}}</div>\n <div class=\"lineDialog\" *ngFor=\"let row of rows; let i = index \">\n <form *ngIf=\"!rowSubmitted(row)\" (ngSubmit)=\"invokeAndAdd(i)\" [formGroup]=\"form(i)\" autocomplete=\"off\">\n <nof-parameters class=\"parameters multilinedialog\" [parameters]=\"parameters(row)\" [parent]=\"row\" [form]=\"form(i)\"></nof-parameters> \n <input class=\"ok\" tabindex=\"0\" type=\"submit\" value=\"OK\" title=\"{{rowTooltip(row)}}\" [disabled]=\"rowDisabled(row)\" nofClick (leftClick)=\"invokeAndAdd(i)\" />\n <div class=\"co-validation\">{{rowMessage(row)}}</div>\n </form>\n <nof-parameters *ngIf=\"rowSubmitted(row)\" class=\"parameters\" [parameters]=\"parameters(row)\" [parent]=\"row\"></nof-parameters>\n <div *ngIf=\"rowSubmitted(row)\" class=\"co-validation\">{{rowMessage(row)}}</div>\n </div>\n <input class=\"close\" tabindex=\"0\" type=\"submit\" value=\"Close\" title=\"\" nofClick (leftClick)=\"close()\" />\n <div class=\"count\">{{count}}</div>\n </div>\n</div>\n", styles: [":host{overflow-y:auto;color:var(--default-text-color);font-size:var(--font-size-2);font-weight:var(--font-weight-1);display:block;margin-left:var(--space-5);padding-bottom:60px}viewTitle{display:inline-block}.title,.header .type{position:relative;font-weight:var(--font-weight-2);font-size:var(--font-size-4);line-height:38pt;margin-left:var(--space-1);padding-left:var(--space-3);padding-right:var(--space-3);margin-right:var(--space-5);margin-top:var(--space-1);display:block}.header .type{float:left;margin-right:var(--space-5);display:none}nof-parameters{display:inline-block}.columnHeader{display:inline-block;vertical-align:top;width:var(--field-value-width);padding-left:var(--space-4)}input.ok{font-size:var(--font-size-1);height:var(--field-value-height);margin-top:var(--space-1);margin-right:0;margin-left:var(--space-1);margin-bottom:var(--space-3);padding-top:var(--space-1);padding-bottom:0;padding-left:var(--space-1);padding-right:var(--space-1);vertical-align:top}input.close{float:left;margin-left:6px;margin-right:var(--space-4)}.count{display:inline-block;margin-top:var(--space-1)}.co-validation{display:inline-block}\n"] }]
}], ctorParameters: () => [{ type: i1.ActivatedRoute }, { type: i2.UrlManagerService }, { type: i3.ViewModelFactoryService }, { type: i2.ContextService }, { type: i2.ErrorService }, { type: i4.FormBuilder }, { type: i2.ConfigService }], propDecorators: { parmComponents: [{
type: ViewChildren,
args: [ParametersComponent]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibXVsdGktbGluZS1kaWFsb2cuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vZ2VtaW5pL3NyYy9tdWx0aS1saW5lLWRpYWxvZy9tdWx0aS1saW5lLWRpYWxvZy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9nZW1pbmkvc3JjL211bHRpLWxpbmUtZGlhbG9nL211bHRpLWxpbmUtZGlhbG9nLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBaUIsU0FBUyxFQUF3QixZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHN0YsT0FBTyxLQUFLLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUlwRCxPQUFPLElBQUksTUFBTSxnQkFBZ0IsQ0FBQztBQUNsQyxPQUFPLElBQUksTUFBTSxnQkFBZ0IsQ0FBQztBQUNsQyxPQUFPLE9BQU8sTUFBTSxtQkFBbUIsQ0FBQztBQUN4QyxPQUFPLEdBQUcsTUFBTSxlQUFlLENBQUM7QUFDaEMsT0FBTyxJQUFJLE1BQU0sZ0JBQWdCLENBQUM7QUFFbEMsT0FBTyxFQUFFLFVBQVUsRUFBRSxlQUFlLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNwRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQzdDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLG9DQUFvQyxDQUFDOzs7Ozs7Ozs7QUFPekUsTUFBTSxPQUFPLHdCQUF5QixTQUFRLGFBQWE7SUFLbEM7SUFFQTtJQUNBO0lBQ0E7SUFQckIsWUFDSSxjQUE4QixFQUM5QixVQUE2QixFQUNaLGdCQUF5QyxFQUMxRCxPQUF1QixFQUNOLEtBQW1CLEVBQ25CLFdBQXdCLEVBQ3hCLGFBQTRCO1FBRTdDLEtBQUssQ0FBQyxjQUFjLEVBQUUsVUFBVSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBTjFCLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBeUI7UUFFekMsVUFBSyxHQUFMLEtBQUssQ0FBYztRQUNuQixnQkFBVyxHQUFYLFdBQVcsQ0FBYTtRQUN4QixrQkFBYSxHQUFiLGFBQWEsQ0FBZTtJQUdqRCxDQUFDO0lBR0QsY0FBYyxDQUFrQztJQUV4QyxHQUFHLENBQWlCO0lBQzVCLE1BQU0sQ0FBNEI7SUFFbEMsT0FBTyxDQUE2RztJQUVwSCxJQUFJLEdBQUcsQ0FBQyxDQUFTLEVBQUUsRUFBRTtRQUNqQixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2hDLE9BQU8sT0FBTyxDQUFDLElBQUksQ0FBQztJQUN4QixDQUFDLENBQUM7SUFFRixJQUFJLGtCQUFrQjtRQUNsQixPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsa0JBQWtCLENBQUM7SUFDMUMsQ0FBQztJQUVELElBQUksV0FBVztRQUNYLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxXQUFXLENBQUM7SUFDbkMsQ0FBQztJQUVELElBQUksV0FBVztRQUNYLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7SUFDN0IsQ0FBQztJQUVELElBQUksTUFBTTtRQUNOLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUNoQyxDQUFDO0lBRUQsSUFBSSxJQUFJO1FBQ0osT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQztJQUMvQixDQUFDO0lBRUQsVUFBVSxHQUFHLENBQUMsR0FBb0IsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQztJQUV0RCxZQUFZLEdBQUcsQ0FBQyxHQUFvQixFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDO0lBRXZELFVBQVUsR0FBRyxDQUFDLEdBQW9CLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUVyRCxVQUFVLEdBQUcsQ0FBQyxHQUFvQixFQUFFLEVBQUU7UUFDbEMsT0FBTyxHQUFHLENBQUMscUJBQXFCLEVBQUUsQ0FBQztJQUN2QyxDQUFDLENBQUM7SUFFRixXQUFXLEdBQUcsQ0FBQyxHQUFvQixFQUFFLEVBQUU7UUFDbkMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsSUFBSSxHQUFHLENBQUMsU0FBUyxDQUFDO0lBQy9DLENBQUMsQ0FBQztJQUVGLElBQUksS0FBSztRQUNMLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO0lBQzNDLENBQUM7SUFFRCxZQUFZLENBQUMsS0FBYTtRQUN0QixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssQ0FBQztRQUV4QyxPQUFPLENBQUMsS0FBSyxFQUNULENBQUMsQ0FBQyxFQUFFO1lBQ0EsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUN0RCxDQUFDLENBQUMsbUJBQW1CLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDcEMsQ0FBQyxDQUFDLENBQUM7UUFFUCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUVuRCxJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQ2IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDeEUsQ0FBQztJQUNMLENBQUM7SUFFRCxLQUFLLEdBQUcsR0FBRyxFQUFFO1FBQ1QsSUFBSSxDQUFDLFVBQVUsQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUNsQyxDQUFDLENBQUM7SUFFTSxVQUFVLENBQUMsTUFBdUI7UUFDdEMsT0FBTyxVQUFVLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztJQUNoRCxDQUFDO0lBRUQsa0JBQWtCLENBQUMsTUFBbUYsRUFDbEcsV0FBbUIsRUFDbkIsU0FBd0IsRUFDeEIsZUFBaUM7UUFFakMsTUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUUsQ0FBQztRQUNqRCxJQUFJLENBQUMsT0FBTyxDQUFDLGtCQUFrQixDQUFDLE1BQU0sQ0FBQztZQUNuQyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUU7WUFFWCxJQUFJLGVBQWUsRUFBRSxDQUFDO2dCQUNsQixlQUFlLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzNDLENBQUM7WUFFRCxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyx3QkFBd0IsQ0FBQyxTQUFTLEVBQUUsT0FBTyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ3pGLElBQUksQ0FBQyxPQUFPLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3JFLENBQUMsQ0FBQztZQUNGLEtBQUssQ0FBQyxDQUFDLE1BQW9CLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDeEUsQ0FBQztJQUVTLEtBQUssQ0FBQyxTQUF3QjtRQUNwQyxJQUFJLFNBQVMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNuQixJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDO2lCQUNqQyxJQUFJLENBQUMsQ0FBQyxJQUEyQixFQUFFLEVBQUU7Z0JBQ2xDLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLFFBQVMsRUFBRSxTQUFTLENBQUMsQ0FBQztZQUNsRSxDQUFDLENBQUM7aUJBQ0QsS0FBSyxDQUFDLENBQUMsTUFBb0IsRUFBRSxFQUFFO2dCQUM1QixJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUNuQyxDQUFDLENBQUMsQ0FBQztRQUNYLENBQUM7YUFBTSxJQUFJLFNBQVMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztZQUM1QixNQUFNLEdBQUcsR0FBRyxFQUFFLENBQUMsZUFBZSxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxDQUFDO1lBQ3hHLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsR0FBRyxFQUFFLFNBQVMsQ0FBQyxlQUFnQixDQUFDO2dCQUNyRSxJQUFJLENBQUMsQ0FBQyxNQUFxQyxFQUFFLEVBQUU7Z0JBRTNDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxxQkFBcUIsQ0FBQyxNQUFNLEVBQUUsU0FBUyxFQUFFLEtBQUssQ0FBQyxDQUFDO2dCQUNsRixNQUFNLFdBQVcsR0FBRyxTQUFTLENBQUMsUUFBUSxDQUFDO2dCQUV2QyxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxtQ0FBbUMsQ0FBQyxXQUFZLENBQUMsQ0FBQyxDQUFDO2dCQUV0RyxJQUFJLGFBQWEsRUFBRSxDQUFDO29CQUNoQixNQUFNLGVBQWUsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsUUFBUSxFQUFFLEtBQUssV0FBVyxDQUFDLENBQUM7b0JBQ2pHLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxhQUFhLEVBQUUsV0FBWSxFQUFFLFNBQVMsRUFBRSxlQUFlLENBQUMsQ0FBQztnQkFDckYsQ0FBQztxQkFBTSxDQUFDO29CQUNKLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNLEVBQUUsV0FBWSxFQUFFLFNBQVMsQ0FBQyxDQUFDO2dCQUM3RCxDQUFDO1lBRUwsQ0FBQyxDQUFDO2dCQUNGLEtBQUssQ0FBQyxDQUFDLE1BQW9CLEVBQUUsRUFBRTtnQkFDM0IsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDbkMsQ0FBQyxDQUFDLENBQUM7UUFDWCxDQUFDO0lBQ0wsQ0FBQztJQUVELEtBQUssQ0FBQyxLQUFxQztRQUN2QyxJQUFJLEtBQUssSUFBSSxLQUFLLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzVCLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUMxQyxDQUFDO0lBQ0wsQ0FBQztJQUVELGVBQWU7UUFDWCxJQUFJLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxjQUFjLEVBQUUsT0FBTyxDQUFDLFNBQVMsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUM1RSxDQUFDO0lBRVEsV0FBVztRQUNoQixlQUFlLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzFCLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsZUFBZSxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ2xELEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUN4QixDQUFDO3VHQTNKUSx3QkFBd0I7MkZBQXhCLHdCQUF3QixnR0FjbkIsbUJBQW1CLHVFQ3BDckMsK2hEQXVCQTs7MkZERGEsd0JBQXdCO2tCQUxwQyxTQUFTOytCQUNJLHVCQUF1Qjt1UUFtQmpDLGNBQWM7c0JBRGIsWUFBWTt1QkFBQyxtQkFBbUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBZnRlclZpZXdJbml0LCBDb21wb25lbnQsIE9uRGVzdHJveSwgUXVlcnlMaXN0LCBWaWV3Q2hpbGRyZW4gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1CdWlsZGVyLCBGb3JtR3JvdXAgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBBY3RpdmF0ZWRSb3V0ZSB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5pbXBvcnQgKiBhcyBSbyBmcm9tICdAbmFrZWRvYmplY3RzL3Jlc3RmdWwtb2JqZWN0cyc7XG5pbXBvcnQgeyBDb25maWdTZXJ2aWNlLCBDb250ZXh0U2VydmljZSwgRXJyb3JTZXJ2aWNlLCBFcnJvcldyYXBwZXIsIFBhbmVSb3V0ZURhdGEsIFVybE1hbmFnZXJTZXJ2aWNlIH0gZnJvbSAnQG5ha2Vkb2JqZWN0cy9zZXJ2aWNlcyc7XG5pbXBvcnQgeyBBY3Rpb25WaWV3TW9kZWwsIENvbGxlY3Rpb25WaWV3TW9kZWwsIERpYWxvZ1ZpZXdNb2RlbCwgTXVsdGlMaW5lRGlhbG9nVmlld01vZGVsLCBQYXJhbWV0ZXJWaWV3TW9kZWwsIFZpZXdNb2RlbEZhY3RvcnlTZXJ2aWNlIH0gZnJvbSAnQG5ha2Vkb2JqZWN0cy92aWV3LW1vZGVscyc7XG5pbXBvcnQgeyBEaWN0aW9uYXJ5IH0gZnJvbSAnbG9kYXNoJztcbmltcG9ydCBlYWNoIGZyb20gJ2xvZGFzaC1lcy9lYWNoJztcbmltcG9ydCBmaW5kIGZyb20gJ2xvZGFzaC1lcy9maW5kJztcbmltcG9ydCBmb3JFYWNoIGZyb20gJ2xvZGFzaC1lcy9mb3JFYWNoJztcbmltcG9ydCBtYXAgZnJvbSAnbG9kYXNoLWVzL21hcCc7XG5pbXBvcnQgc29tZSBmcm9tICdsb2Rhc2gtZXMvc29tZSc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb25MaWtlIGFzIElTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGNyZWF0ZUZvcm0sIHNhZmVVbnN1YnNjcmliZSB9IGZyb20gJy4uL2hlbHBlcnMtY29tcG9uZW50cyc7XG5pbXBvcnQgeyBQYW5lQ29tcG9uZW50IH0gZnJvbSAnLi4vcGFuZS9wYW5lJztcbmltcG9ydCB7IFBhcmFtZXRlcnNDb21wb25lbnQgfSBmcm9tICcuLi9wYXJhbWV0ZXJzL3BhcmFtZXRlcnMuY29tcG9uZW50JztcblxuQENvbXBvbmVudCh7XG4gICAgc2VsZWN0b3I6ICdub2YtbXVsdGktbGluZS1kaWFsb2cnLFxuICAgIHRlbXBsYXRlVXJsOiAnbXVsdGktbGluZS1kaWFsb2cuY29tcG9uZW50Lmh0bWwnLFxuICAgIHN0eWxlVXJsczogWydtdWx0aS1saW5lLWRpYWxvZy5jb21wb25lbnQuY3NzJ11cbn0pXG5leHBvcnQgY2xhc3MgTXVsdGlMaW5lRGlhbG9nQ29tcG9uZW50IGV4dGVuZHMgUGFuZUNvbXBvbmVudCBpbXBsZW1lbnRzIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveSB7XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgYWN0aXZhdGVkUm91dGU6IEFjdGl2YXRlZFJvdXRlLFxuICAgICAgICB1cmxNYW5hZ2VyOiBVcmxNYW5hZ2VyU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSB2aWV3TW9kZWxGYWN0b3J5OiBWaWV3TW9kZWxGYWN0b3J5U2VydmljZSxcbiAgICAgICAgY29udGV4dDogQ29udGV4dFNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgZXJyb3I6IEVycm9yU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSByZWFkb25seSBmb3JtQnVpbGRlcjogRm9ybUJ1aWxkZXIsXG4gICAgICAgIHByaXZhdGUgcmVhZG9ubHkgY29uZmlnU2VydmljZTogQ29uZmlnU2VydmljZVxuICAgICkge1xuICAgICAgICBzdXBlcihhY3RpdmF0ZWRSb3V0ZSwgdXJsTWFuYWdlciwgY29udGV4dCk7XG4gICAgfVxuXG4gICAgQFZpZXdDaGlsZHJlbihQYXJhbWV0ZXJzQ29tcG9uZW50KVxuICAgIHBhcm1Db21wb25lbnRzPzogUXVlcnlMaXN0PFBhcmFtZXRlcnNDb21wb25lbnQ+O1xuXG4gICAgcHJpdmF0ZSBzdWI/OiBJU3Vic2NyaXB0aW9uO1xuICAgIGRpYWxvZyE6IE11bHRpTGluZURpYWxvZ1ZpZXdNb2RlbDtcblxuICAgIHJvd0RhdGEhOiB7IGZvcm06IEZvcm1Hcm91cCwgZGlhbG9nOiBEaWFsb2dWaWV3TW9kZWwsIHBhcm1zOiBEaWN0aW9uYXJ5PFBhcmFtZXRlclZpZXdNb2RlbD4sIHN1YjogSVN1YnNjcmlwdGlvbiB9W107XG5cbiAgICBmb3JtID0gKGk6IG51bWJlcikgPT4ge1xuICAgICAgICBjb25zdCByb3dEYXRhID0gdGhpcy5yb3dEYXRhW2ldO1xuICAgICAgICByZXR1cm4gcm93RGF0YS5mb3JtO1xuICAgIH07XG5cbiAgICBnZXQgb2JqZWN0RnJpZW5kbHlOYW1lKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5kaWFsb2cub2JqZWN0RnJpZW5kbHlOYW1lO1xuICAgIH1cblxuICAgIGdldCBvYmplY3RUaXRsZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGlhbG9nLm9iamVjdFRpdGxlO1xuICAgIH1cblxuICAgIGdldCBkaWFsb2dUaXRsZSgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGlhbG9nLnRpdGxlO1xuICAgIH1cblxuICAgIGdldCBoZWFkZXIoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLmRpYWxvZy5oZWFkZXIoKTtcbiAgICB9XG5cbiAgICBnZXQgcm93cygpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGlhbG9nLmRpYWxvZ3M7XG4gICAgfVxuXG4gICAgcGFyYW1ldGVycyA9IChyb3c6IERpYWxvZ1ZpZXdNb2RlbCkgPT4gcm93LnBhcmFtZXRlcnM7XG5cbiAgICByb3dTdWJtaXR0ZWQgPSAocm93OiBEaWFsb2dWaWV3TW9kZWwpID0+IHJvdy5zdWJtaXR0ZWQ7XG5cbiAgICByb3dUb29sdGlwID0gKHJvdzogRGlhbG9nVmlld01vZGVsKSA9PiByb3cudG9vbHRpcCgpO1xuXG4gICAgcm93TWVzc2FnZSA9IChyb3c6IERpYWxvZ1ZpZXdNb2RlbCkgPT4ge1xuICAgICAgICByZXR1cm4gcm93LmdldE1lc3NhZ2VPclN1Ym1pdHRlZCgpO1xuICAgIH07XG5cbiAgICByb3dEaXNhYmxlZCA9IChyb3c6IERpYWxvZ1ZpZXdNb2RlbCkgPT4ge1xuICAgICAgICByZXR1cm4gIXJvdy5jbGllbnRWYWxpZCgpIHx8IHJvdy5zdWJtaXR0ZWQ7XG4gICAgfTtcblxuICAgIGdldCBjb3VudCgpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuZGlhbG9nLnN1Ym1pdHRlZENvdW50TXNnKCk7XG4gICAgfVxuXG4gICAgaW52b2tlQW5kQWRkKGluZGV4OiBudW1iZXIpIHtcbiAgICAgICAgY29uc3QgcGFybXMgPSB0aGlzLnJvd0RhdGFbaW5kZXhdLnBhcm1zO1xuXG4gICAgICAgIGZvckVhY2gocGFybXMsXG4gICAgICAgICAgICBwID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBuZXdWYWx1ZSA9IHRoaXMucm93RGF0YVtpbmRleF0uZm9ybS52YWx1ZVtwLmlkXTtcbiAgICAgICAgICAgICAgICBwLnNldFZhbHVlRnJvbUNvbnRyb2wobmV3VmFsdWUpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgY29uc3QgYWRkZWRJbmRleCA9IHRoaXMuZGlhbG9nLmludm9rZUFuZEFkZChpbmRleCk7XG5cbiAgICAgICAgaWYgKGFkZGVkSW5kZXgpIHtcbiAgICAgICAgICAgIHRoaXMucm93RGF0YS5wdXNoKHRoaXMuY3JlYXRlRm9ybSh0aGlzLmRpYWxvZy5kaWFsb2dzW2FkZGVkSW5kZXhdKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjbG9zZSA9ICgpID0+IHtcbiAgICAgICAgdGhpcy51cmxNYW5hZ2VyLnBvcFVybFN0YXRlKCk7XG4gICAgfTtcblxuICAgIHByaXZhdGUgY3JlYXRlRm9ybShkaWFsb2c6IERpYWxvZ1ZpZXdNb2RlbCkge1xuICAgICAgICByZXR1cm4gY3JlYXRlRm9ybShkaWFsb2csIHRoaXMuZm9ybUJ1aWxkZXIpO1xuICAgIH1cblxuICAgIHNldE11bHRpTGluZURpYWxvZyhob2xkZXI6IFJvLk1lbnVSZXByZXNlbnRhdGlvbiB8IFJvLkRvbWFpbk9iamVjdFJlcHJlc2VudGF0aW9uIHwgQ29sbGVjdGlvblZpZXdNb2RlbCxcbiAgICAgICAgbmV3RGlhbG9nSWQ6IHN0cmluZyxcbiAgICAgICAgcm91dGVEYXRhOiBQYW5lUm91dGVEYXRhLFxuICAgICAgICBhY3Rpb25WaWV3TW9kZWw/OiBBY3Rpb25WaWV3TW9kZWwpIHtcblxuICAgICAgICBjb25zdCBhY3Rpb24gPSBob2xkZXIuYWN0aW9uTWVtYmVyKG5ld0RpYWxvZ0lkKSE7XG4gICAgICAgIHRoaXMuY29udGV4dC5nZXRJbnZva2FibGVBY3Rpb24oYWN0aW9uKS5cbiAgICAgICAgICAgIHRoZW4oZGV0YWlscyA9PiB7XG5cbiAgICAgICAgICAgICAgICBpZiAoYWN0aW9uVmlld01vZGVsKSB7XG4gICAgICAgICAgICAgICAgICAgIGFjdGlvblZpZXdNb2RlbC5tYWtlSW52b2thYmxlKGRldGFpbHMpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHRoaXMuZGlhbG9nID0gdGhpcy52aWV3TW9kZWxGYWN0b3J5Lm11bHRpTGluZURpYWxvZ1ZpZXdNb2RlbChyb3V0ZURhdGEsIGRldGFpbHMsIGhvbGRlcik7XG4gICAgICAgICAgICAgICAgdGhpcy5yb3dEYXRhID0gbWFwKHRoaXMuZGlhbG9nLmRpYWxvZ3MsIGQgPT4gdGhpcy5jcmVhdGVGb3JtKGQpKTtcbiAgICAgICAgICAgIH0pLlxuICAgICAgICAgICAgY2F0Y2goKHJlamVjdDogRXJyb3JXcmFwcGVyKSA9PiB0aGlzLmVycm9yLmhhbmRsZUVycm9yKHJlamVjdCkpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBzZXR1cChyb3V0ZURhdGE6IFBhbmVSb3V0ZURhdGEpIHtcbiAgICAgICAgaWYgKHJvdXRlRGF0YS5tZW51SWQpIHtcbiAgICAgICAgICAgIHRoaXMuY29udGV4dC5nZXRNZW51KHJvdXRlRGF0YS5tZW51SWQpXG4gICAgICAgICAgICAgICAgLnRoZW4oKG1lbnU6IFJvLk1lbnVSZXByZXNlbnRhdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnNldE11bHRpTGluZURpYWxvZyhtZW51LCByb3V0ZURhdGEuZGlhbG9nSWQhLCByb3V0ZURhdGEpO1xuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgLmNhdGNoKChyZWplY3Q6IEVycm9yV3JhcHBlcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLmVycm9yLmhhbmRsZUVycm9yKHJlamVjdCk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSBpZiAocm91dGVEYXRhLm9iamVjdElkKSB7XG4gICAgICAgICAgICBjb25zdCBvaWQgPSBSby5PYmplY3RJZFdyYXBwZXIuZnJvbU9iamVjdElkKHJvdXRlRGF0YS5vYmplY3RJZCwgdGhpcy5jb25maWdTZXJ2aWNlLmNvbmZpZy5rZXlTZXBhcmF0b3IpO1xuICAgICAgICAgICAgdGhpcy5jb250ZXh0LmdldE9iamVjdChyb3V0ZURhdGEucGFuZUlkLCBvaWQsIHJvdXRlRGF0YS5pbnRlcmFjdGlvbk1vZGUhKS5cbiAgICAgICAgICAgICAgICB0aGVuKChvYmplY3Q6IFJvLkRvbWFpbk9iamVjdFJlcHJlc2VudGF0aW9uKSA9PiB7XG5cbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgb3ZtID0gdGhpcy52aWV3TW9kZWxGYWN0b3J5LmRvbWFpbk9iamVjdFZpZXdNb2RlbChvYmplY3QsIHJvdXRlRGF0YSwgZmFsc2UpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBuZXdEaWFsb2dJZCA9IHJvdXRlRGF0YS5kaWFsb2dJZDtcblxuICAgICAgICAgICAgICAgICAgICBjb25zdCBsY2FDb2xsZWN0aW9uID0gZmluZChvdm0uY29sbGVjdGlvbnMsIGMgPT4gYy5oYXNNYXRjaGluZ0xvY2FsbHlDb250cmlidXRlZEFjdGlvbihuZXdEaWFsb2dJZCEpKTtcblxuICAgICAgICAgICAgICAgICAgICBpZiAobGNhQ29sbGVjdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYWN0aW9uVmlld01vZGVsID0gZmluZChsY2FDb2xsZWN0aW9uLmFjdGlvbnMsIGEgPT4gYS5hY3Rpb25SZXAuYWN0aW9uSWQoKSA9PT0gbmV3RGlhbG9nSWQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5zZXRNdWx0aUxpbmVEaWFsb2cobGNhQ29sbGVjdGlvbiwgbmV3RGlhbG9nSWQhLCByb3V0ZURhdGEsIGFjdGlvblZpZXdNb2RlbCk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnNldE11bHRpTGluZURpYWxvZyhvYmplY3QsIG5ld0RpYWxvZ0lkISwgcm91dGVEYXRhKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgfSkuXG4gICAgICAgICAgICAgICAgY2F0Y2goKHJlamVjdDogRXJyb3JXcmFwcGVyKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXJyb3IuaGFuZGxlRXJyb3IocmVqZWN0KTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvY3VzKHBhcm1zOiBRdWVyeUxpc3Q8UGFyYW1ldGVyc0NvbXBvbmVudD4pIHtcbiAgICAgICAgaWYgKHBhcm1zICYmIHBhcm1zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHNvbWUocGFybXMudG9BcnJheSgpLCBwID0+IHAuZm9jdXMoKSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc3ViID0gdGhpcy5wYXJtQ29tcG9uZW50cz8uY2hhbmdlcy5zdWJzY3JpYmUocWwgPT4gdGhpcy5mb2N1cyhxbCkpO1xuICAgIH1cblxuICAgIG92ZXJyaWRlIG5nT25EZXN0cm95KCk6IHZvaWQge1xuICAgICAgICBzYWZlVW5zdWJzY3JpYmUodGhpcy5zdWIpO1xuICAgICAgICBlYWNoKHRoaXMucm93RGF0YSwgcmQgPT4gc2FmZVVuc3Vic2NyaWJlKHJkLnN1YikpO1xuICAgICAgICBzdXBlci5uZ09uRGVzdHJveSgpO1xuICAgIH1cbn1cbiIsIjxkaXYgaWQ9XCJwYW5lMVwiIGNsYXNzPVwic2luZ2xlXCI+XG4gICAgPGRpdiAgKm5nSWY9XCJkaWFsb2dcIiBjbGFzcz1cIm11bHRpbGluZWRpYWxvZ1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiaGVhZGVyXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidHlwZVwiPnt7b2JqZWN0RnJpZW5kbHlOYW1lfX08L2Rpdj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0aXRsZVwiIGdlbWluaS1kcmFnIHRhYmluZGV4PVwiMFwiPlxuICAgICAgICAgICAgICAgIDxkaXY+e3tvYmplY3RUaXRsZX19PC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdj57e2RpYWxvZ1RpdGxlfX08L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNvbHVtbkhlYWRlclwiICpuZ0Zvcj1cImxldCBjb2x1bW4gb2YgaGVhZGVyXCI+e3tjb2x1bW59fTwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwibGluZURpYWxvZ1wiICpuZ0Zvcj1cImxldCByb3cgb2Ygcm93czsgbGV0IGkgPSBpbmRleCBcIj5cbiAgICAgICAgICAgIDxmb3JtICpuZ0lmPVwiIXJvd1N1Ym1pdHRlZChyb3cpXCIgKG5nU3VibWl0KT1cImludm9rZUFuZEFkZChpKVwiIFtmb3JtR3JvdXBdPVwiZm9ybShpKVwiIGF1dG9jb21wbGV0ZT1cIm9mZlwiPlxuICAgICAgICAgICAgICAgIDxub2YtcGFyYW1ldGVycyAgY2xhc3M9XCJwYXJhbWV0ZXJzIG11bHRpbGluZWRpYWxvZ1wiIFtwYXJhbWV0ZXJzXT1cInBhcmFtZXRlcnMocm93KVwiIFtwYXJlbnRdPVwicm93XCIgW2Zvcm1dPVwiZm9ybShpKVwiPjwvbm9mLXBhcmFtZXRlcnM+ICAgICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwib2tcIiB0YWJpbmRleD1cIjBcIiB0eXBlPVwic3VibWl0XCIgdmFsdWU9XCJPS1wiIHRpdGxlPVwie3tyb3dUb29sdGlwKHJvdyl9fVwiIFtkaXNhYmxlZF09XCJyb3dEaXNhYmxlZChyb3cpXCIgbm9mQ2xpY2sgKGxlZnRDbGljayk9XCJpbnZva2VBbmRBZGQoaSlcIiAvPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjby12YWxpZGF0aW9uXCI+e3tyb3dNZXNzYWdlKHJvdyl9fTwvZGl2PlxuICAgICAgICAgICAgPC9mb3JtPlxuICAgICAgICAgICAgPG5vZi1wYXJhbWV0ZXJzICpuZ0lmPVwicm93U3VibWl0dGVkKHJvdylcIiBjbGFzcz1cInBhcmFtZXRlcnNcIiBbcGFyYW1ldGVyc109XCJwYXJhbWV0ZXJzKHJvdylcIiBbcGFyZW50XT1cInJvd1wiPjwvbm9mLXBhcmFtZXRlcnM+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwicm93U3VibWl0dGVkKHJvdylcIiBjbGFzcz1cImNvLXZhbGlkYXRpb25cIj57e3Jvd01lc3NhZ2Uocm93KX19PC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8aW5wdXQgY2xhc3M9XCJjbG9zZVwiIHRhYmluZGV4PVwiMFwiIHR5cGU9XCJzdWJtaXRcIiB2YWx1ZT1cIkNsb3NlXCIgdGl0bGU9XCJcIiBub2ZDbGljayAobGVmdENsaWNrKT1cImNsb3NlKClcIiAvPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY291bnRcIj57e2NvdW50fX08L2Rpdj5cbiAgICA8L2Rpdj5cbjwvZGl2PlxuIl19