kwikid-forms
Version:
KwikID's JSON Configuration based Forms Renderer and Builder
257 lines • 46.2 kB
JavaScript
import { __decorate } from "tslib";
import { Component, EventEmitter, Input, Output } from "@angular/core";
import { checkObjectKeyExists, checkObjectPathExists, getObjectDeepCopy, isNull, isUndefined, logMethod, mergeObjects, setValueToObjectPath } from "kwikid-toolkit";
import { getLanguage, updateLanguage } from "../config-converter/config-converter.helper";
import { EFormType } from "../renderer.definitions";
import { ELogEventType } from "./forms-list.definitions";
import { formatEventLogs } from "./forms-list.helper";
import * as i0 from "@angular/core";
import * as i1 from "kwikui";
import * as i2 from "@taiga-ui/core";
import * as i3 from "@angular/common";
export class KwikIDFormsListComponent {
constructor() {
this.showFormFields = {};
this.userConfig = {};
this.stepConfig = {};
this.activeFormConfig = {};
this.formsList = [];
this.reduxData = {};
this.formsListCompleted = [];
this.isMobileView = false;
this.isUnsavedData = false;
this.getLogs = new EventEmitter();
this.onClickSetActiveForm = new EventEmitter();
this.onClickHideFormsList = new EventEmitter();
this.onClickSubmitForms = new EventEmitter();
this.selectedForm = "";
this.formsListLength = 0;
this.isAllFormsCompleted = true;
this.loading = false;
}
setSelectedForm(selectedForm) {
this.selectedForm = selectedForm;
}
ngOnInit() {
var _a, _b, _c;
this.reduxData = (_a = this.reduxData) !== null && _a !== void 0 ? _a : {};
this.loading = true;
this.setSelectedForm((_c = (_b = this.activeFormConfig) === null || _b === void 0 ? void 0 : _b.key) !== null && _c !== void 0 ? _c : "");
this.stepConfig = this.formatStepConfig(this.stepConfig);
this.triggerLogs(ELogEventType.FORM__STEP_CONFIG_LOAD_SUCCESS, {});
this.formsList = this.filterHiddenForms(this.formsList);
this.formsList = this.setFormTitles(this.formsList);
this.formsListLength = this.findFormsListLength(this.formsList);
this.isAllFormsCompleted = this.checkIsAllFormsCompleted(this.formsList);
this.triggerLogs(ELogEventType.FORM__LIST_LOAD_SUCCESS, {});
this.loading = false;
}
ngOnChanges(changes) {
var _a, _b, _c;
const verifyChange = (key) => {
return checkObjectKeyExists(changes, key) && !changes[key].firstChange;
};
if (verifyChange("showFormFields")) {
this.showFormFields = changes.showFormFields.currentValue;
}
if (verifyChange("stepConfig")) {
this.stepConfig = this.formatStepConfig(changes.stepConfig.currentValue);
}
if (verifyChange("isUnsavedData")) {
this.isUnsavedData = changes.isUnsavedData.currentValue;
}
if (verifyChange("formsList")) {
this.formsList = this.filterHiddenForms(this.formsList);
this.formsList = this.setFormTitles(this.formsList);
this.formsListLength = this.findFormsListLength(this.formsList);
this.isAllFormsCompleted = this.checkIsAllFormsCompleted(this.formsList);
}
if (verifyChange("isMobileView")) {
this.isMobileView = changes.isMobileView.currentValue;
if (!this.isMobileView) {
this.setSelectedForm("");
}
}
if (verifyChange("activeFormConfig")) {
this.activeFormConfig = changes.activeFormConfig.currentValue;
this.setSelectedForm((_b = (_a = this.activeFormConfig) === null || _a === void 0 ? void 0 : _a.key) !== null && _b !== void 0 ? _b : "");
}
if (checkObjectKeyExists(changes, "reduxData")) {
this.reduxData = (_c = changes.reduxData.currentValue) !== null && _c !== void 0 ? _c : {};
}
if (checkObjectKeyExists(changes, "userConfig")) {
this.userConfig = changes.userConfig.currentValue;
}
}
triggerLogs(eventType, logs) {
this.getLogs.emit(formatEventLogs(eventType, this.stepConfig, logs));
}
formatStepConfig(stepConfig) {
var _a;
stepConfig =
stepConfig && typeof stepConfig === "object"
? getObjectDeepCopy(stepConfig)
: stepConfig;
let stepConfigProperties = {
formListProperties: {
footer: {
submitFormButton: {
hidden: false,
label: "Submit"
}
}
}
};
if (isNull(stepConfig) || isUndefined(stepConfig)) {
stepConfig = setValueToObjectPath({}, "props", stepConfigProperties);
}
else if (checkObjectKeyExists(stepConfig, "props")) {
stepConfigProperties = mergeObjects(stepConfigProperties, stepConfig.props);
stepConfig = setValueToObjectPath(stepConfig, "props", stepConfigProperties);
}
else {
stepConfig = setValueToObjectPath(stepConfig, "props", stepConfigProperties);
}
stepConfig.props.formListProperties.footer.submitFormButton.label =
updateLanguage(stepConfig.props.formListProperties.footer.submitFormButton.label, getLanguage((_a = this.reduxData) !== null && _a !== void 0 ? _a : {}, this.userConfig));
return stepConfig;
}
filterHiddenForms(formsList) {
return formsList.filter((form) => {
if (checkObjectKeyExists(form, "hidden")) {
return !form.hidden;
}
return false;
});
}
setFormTitles(formsList) {
return formsList
.map((form) => {
var _a;
if (form.type === EFormType.HTML) {
return form; // No modification, just return
}
if (checkObjectPathExists(form, "props.title")) {
form.props.title = updateLanguage(form.props.title, getLanguage((_a = this.reduxData) !== null && _a !== void 0 ? _a : {}, this.userConfig));
}
return form; // Return the form regardless of modification
})
.filter((form) => form.type === EFormType.HTML ||
checkObjectPathExists(form, "props.title"));
}
findFormsListLength(formsList) {
return formsList.filter((form) => {
if (checkObjectKeyExists(form, "type")) {
return (form.type !== EFormType.HTML &&
checkObjectKeyExists(form, "hidden") &&
!form.hidden);
}
return checkObjectKeyExists(form, "hidden") && !form.hidden;
}).length;
}
checkIsAllFormsCompleted(formsList) {
let isAllFormsCompleted = true;
for (const form of formsList) {
if (checkObjectKeyExists(form, "type")) {
if (form.type !== EFormType.HTML) {
if (form.status !== "completed") {
isAllFormsCompleted = false;
break;
}
}
}
}
return isAllFormsCompleted;
}
handleOnClickSetActiveForm(selectedForm) {
var _a, _b, _c, _d, _e, _f;
if (this.isMobileView ||
(!this.isMobileView && this.selectedForm !== selectedForm) ||
(this.isAllFormsCompleted && !this.showFormFields)) {
if (((_b = (_a = this.activeFormConfig) === null || _a === void 0 ? void 0 : _a.properties) === null || _b === void 0 ? void 0 : _b.isUnsavedDataAlertEnabled) &&
this.isUnsavedData &&
!window.confirm("You have unsaved data. Proceed?")) {
return;
}
this.triggerLogs(ELogEventType.FORM__FORM_OPEN_BUTTON_CLICK, {
form_key: selectedForm,
form_label: (_d = (_c = this.activeFormConfig) === null || _c === void 0 ? void 0 : _c.title) !== null && _d !== void 0 ? _d : (_f = (_e = this.activeFormConfig) === null || _e === void 0 ? void 0 : _e.props) === null || _f === void 0 ? void 0 : _f.title
});
this.selectedForm = selectedForm;
this.onClickSetActiveForm.emit(selectedForm);
}
}
handleOnSubmitForms(e) {
/**
* POST ACTIONS
* 1. API Calls.
* 2. Preview of all filled data.
* 3. URL Redirection or new opening of URL in external tab.
*/
this.onClickSubmitForms.emit(e);
}
}
/** @nocollapse */ KwikIDFormsListComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: KwikIDFormsListComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
/** @nocollapse */ KwikIDFormsListComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.2.17", type: KwikIDFormsListComponent, selector: "kwikid-forms-list", inputs: { showFormFields: "showFormFields", userConfig: "userConfig", stepConfig: "stepConfig", activeFormConfig: "activeFormConfig", formsList: "formsList", reduxData: "reduxData", formsListCompleted: "formsListCompleted", isMobileView: "isMobileView", isUnsavedData: "isUnsavedData" }, outputs: { getLogs: "getLogs", onClickSetActiveForm: "onClickSetActiveForm", onClickHideFormsList: "onClickHideFormsList", onClickSubmitForms: "onClickSubmitForms" }, usesOnChanges: true, ngImport: i0, template: "<div\n id=\"sidebar-container\"\n *ngIf=\"!loading\"\n>\n <div id=\"sidebar\">\n <div ngClass=\"kwikid-form-header\">\n <div id=\"uf-header\">\n <div id=\"uf-header-logo-container\">\n <img\n id=\"uf-header-logo\"\n src=\"{{ this.userConfig.theme.clientLogo }}\"\n [ngClass]=\"'large-icon'\"\n />\n </div>\n </div>\n <hr />\n </div>\n <div id=\"uf-progress\">\n <div id=\"uf-progress-steps\">\n {{ this.formsListCompleted.length }} / {{ this.formsListLength }} Steps\n Completed\n </div>\n <kwikui-progress-segmented\n [max]=\"this.formsListLength\"\n size=\"m\"\n [value]=\"this.formsListCompleted.length\"\n ></kwikui-progress-segmented>\n </div>\n <div id=\"uf-sections-container\">\n <ng-container *ngFor=\"let form of formsList; let i = index\">\n <ng-container [ngSwitch]=\"form.type\">\n <!-- HTML Content -->\n <ng-container *ngSwitchCase=\"'HTML'\">\n <div [innerHtml]=\"form.props.htmlContent | kwikuiSafeHtml\"></div>\n </ng-container>\n <!-- Type FORM -->\n <ng-container *ngSwitchCase=\"'FORM'\">\n <ng-container\n [ngTemplateOutlet]=\"FORM_BUTTON\"\n [ngTemplateOutletContext]=\"{\n form: form,\n activeFormConfig: activeFormConfig\n }\"\n >\n </ng-container>\n </ng-container>\n </ng-container>\n </ng-container>\n </div>\n <div id=\"submit-sidebar-btn-container\">\n <kwikui-button\n *ngIf=\"\n !stepConfig.props.formListProperties.footer.submitFormButton.hidden\n \"\n label=\"{{\n stepConfig.props.formListProperties.footer.submitFormButton.label\n }}\"\n type=\"submit\"\n styles=\"width: 100%\"\n (onClick)=\"handleOnSubmitForms($event)\"\n ></kwikui-button>\n </div>\n </div>\n</div>\n\n<ng-template\n #FORM_BUTTON\n let-form=\"form\"\n let-activeFormConfig=\"activeFormConfig\"\n>\n <div\n [class]=\"'uf-section-item'\"\n [class.completed]=\"form.status === 'completed' && !form.disabled\"\n [class.edit]=\"form.status === 'editable' && !form.disabled\"\n [class.locked]=\"form.status === 'locked' && form.disabled\"\n [class.active]=\"\n activeFormConfig !== undefined && form.key === activeFormConfig.key\n \"\n (click)=\"\n form.status === 'locked' && form.disabled\n ? undefined\n : handleOnClickSetActiveForm(form.key)\n \"\n >\n <div class=\"uf-form-section-card-title\">\n {{ form.props.title }} <span *ngIf=\"form?.required\">*</span>\n </div>\n <div class=\"uf-form-section-card-status\">\n <div\n *ngIf=\"form.status === 'completed' && !form.disabled\"\n class=\"uf-form-section-card-status-img completed\"\n >\n <tui-svg src=\"tuiIconCheckLarge\"></tui-svg>\n </div>\n <div\n *ngIf=\"form.status !== 'completed' && !form.disabled\"\n class=\"uf-form-section-card-status-img edit\"\n >\n <tui-svg src=\"tuiIconEdit\"></tui-svg>\n </div>\n <div\n *ngIf=\"form.status !== 'completed' && form.disabled\"\n class=\"uf-form-section-card-status-img locked\"\n >\n <tui-svg src=\"tuiIconLock\"></tui-svg>\n </div>\n </div>\n </div>\n</ng-template>\n", styles: ["#sidebar-container{width:100%;height:100%;margin:0 auto;display:flex;flex-direction:column;justify-content:flex-start;align-items:stretch;align-content:center}#sidebar{width:100%;height:100%;display:flex;flex-direction:column;align-content:center;justify-content:flex-start;align-items:stretch}.uf-section-item{width:100%;display:flex;flex-direction:row;align-items:center;justify-content:space-between;align-content:center;padding:1rem;cursor:pointer;box-shadow:0 1px 3px -1px var(--tui-base-05);border-radius:.5rem;background-color:var(--tui-base-02);position:relative}.uf-section-item>*:not(:last-child){margin-right:1rem}.uf-section-item:hover{box-shadow:0 1px 3px -1px var(--tui-base-08)}#submit-sidebar-btn-container{width:100%;bottom:0px;z-index:1;padding:1rem;display:flex;flex-direction:row;align-content:center;justify-content:center;align-items:center}#submit-sidebar-btn-container>*:not(:last-child){margin-right:1rem}#submit-sidebar-btn-container *{flex-grow:1}#uf-sections-container{display:flex;flex-direction:column;height:100%;padding:1rem;overflow-y:auto}#uf-sections-container>*:not(:last-child){margin-bottom:1rem}.uf-form-section-card{display:flex;flex-direction:row;align-content:center;justify-content:space-between;align-items:center;border:none;border-radius:8px;background-color:#e9e9e9;height:-moz-fit-content;height:fit-content;min-height:60px;padding:10px 15px;width:100%;max-width:350px;margin:0 auto}.uf-form-section-card>*:not(:last-child){margin-right:.5rem}.uf-section-item.locked{-webkit-user-select:none;user-select:none;cursor:not-allowed}.uf-form-section-card .uf-form-section-card-title{font-size:1.2em;text-align:left;line-height:1.25em}.uf-form-section-card .uf-form-section-card-status{width:30px;height:30px;display:flex;flex-direction:row;align-content:center;justify-content:center;align-items:center}.uf-form-section-card .uf-form-section-card-status .uf-form-section-card-status-img{width:30px;height:30px;display:flex;flex-direction:row;align-content:center;justify-content:center;align-items:center;border-radius:100%;color:#fff;font-weight:bold}.uf-form-section-card-status-img.completed{background-color:var(--tui-success-fill);padding:.25rem;border-radius:50%;color:#fff}.uf-form-section-card-status-img.edit{background-color:var(--tui-error-fill);padding:.25rem;border-radius:50%;color:#fff}.uf-form-section-card-status-img.locked{background-color:var(--tui-neutral-fill);padding:.25rem;border-radius:50%;color:#fff}#uf-progress{display:flex;padding:1rem;flex-direction:column;align-content:center;justify-content:center;align-items:stretch}#uf-progress>*:not(:last-child){margin-bottom:.5rem}#uf-progress-steps{font-size:1em;text-align:right;color:#3d3d3d}.uf-form-section-card-title{font-size:1em;font-weight:bold;color:#000}@media screen and (max-width: 600px){#sidebar-container{max-width:unset}}.kwikid-form-header{height:70px;z-index:6}.kwikid-form-header hr{width:calc(100% - 1rem);margin-left:auto;margin-right:auto}#uf-header{display:flex;flex-direction:row;align-content:center;align-items:center;justify-content:flex-start;padding:10px 20px;width:100%;max-width:calc(400px + 50vw + 2rem);margin:0 auto;height:70px;z-index:1}#uf-header>*:not(:last-child){margin-right:1rem}#uf-header #uf-header-goback-container{display:none}#uf-header #uf-header-goback-container:hover{border-radius:50%;background-color:#d3d3d3}#uf-header #uf-header-goback-container #uf-header-goback{width:100%;height:auto}#uf-header #uf-header-logo-container{display:flex;flex-direction:row;align-content:center;justify-content:center;align-items:center}#uf-header #uf-header-logo-container #uf-header-logo.small-icon{width:100%;height:50px}#uf-header #uf-header-logo-container #uf-header-logo.large-icon{width:100%;height:50px}#uf-header #uf-header-title-container{display:flex;flex-direction:column;justify-content:center;align-items:flex-start}#uf-header #uf-header-title-container>*:not(:last-child){margin-bottom:.5rem}#uf-header #uf-header-title-container #uf-header-title{font-size:1.4em;color:#121212}#uf-header #uf-header-title-container #uf-header-subtitle{font-size:1.2em;color:#121212}\n", "::-webkit-scrollbar{width:8px}::-webkit-scrollbar-track{border-radius:10px}::-webkit-scrollbar-thumb{background:lightgray;border-radius:10px}::-webkit-scrollbar-thumb:hover{background:gray}\n"], components: [{ type: i1.KwikUIProgressSegmentedComponent, selector: "kwikui-progress-segmented", inputs: ["colors", "id", "max", "size", "value"] }, { type: i1.KwikUIButtonComponent, selector: "kwikui-button", inputs: ["appearance", "class", "disabled", "icon", "iconRight", "id", "label", "shape", "showLoader", "size", "styles", "type", "pseudoHover"], outputs: ["onClick"] }, { type: i2.TuiSvgComponent, selector: "tui-svg", inputs: ["src"] }], directives: [{ type: i3.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i3.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { type: i3.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i3.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { type: i3.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }, { type: i3.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet"] }], pipes: { "kwikuiSafeHtml": i1.KwikUISafeHtmlPipe } });
__decorate([
logMethod
], KwikIDFormsListComponent.prototype, "ngOnChanges", null);
__decorate([
logMethod
], KwikIDFormsListComponent.prototype, "triggerLogs", null);
__decorate([
logMethod
], KwikIDFormsListComponent.prototype, "formatStepConfig", null);
__decorate([
logMethod
], KwikIDFormsListComponent.prototype, "filterHiddenForms", null);
__decorate([
logMethod
], KwikIDFormsListComponent.prototype, "setFormTitles", null);
__decorate([
logMethod
], KwikIDFormsListComponent.prototype, "findFormsListLength", null);
__decorate([
logMethod
], KwikIDFormsListComponent.prototype, "checkIsAllFormsCompleted", null);
__decorate([
logMethod
], KwikIDFormsListComponent.prototype, "handleOnClickSetActiveForm", null);
__decorate([
logMethod
], KwikIDFormsListComponent.prototype, "handleOnSubmitForms", null);
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.2.17", ngImport: i0, type: KwikIDFormsListComponent, decorators: [{
type: Component,
args: [{
selector: "kwikid-forms-list",
templateUrl: "./forms-list.component.html",
styleUrls: ["./forms-list.component.scss", "../shared.scss"]
}]
}], propDecorators: { showFormFields: [{
type: Input
}], userConfig: [{
type: Input
}], stepConfig: [{
type: Input
}], activeFormConfig: [{
type: Input
}], formsList: [{
type: Input
}], reduxData: [{
type: Input
}], formsListCompleted: [{
type: Input
}], isMobileView: [{
type: Input
}], isUnsavedData: [{
type: Input
}], getLogs: [{
type: Output
}], onClickSetActiveForm: [{
type: Output
}], onClickHideFormsList: [{
type: Output
}], onClickSubmitForms: [{
type: Output
}], ngOnChanges: [], triggerLogs: [], formatStepConfig: [], filterHiddenForms: [], setFormTitles: [], findFormsListLength: [], checkIsAllFormsCompleted: [], handleOnClickSetActiveForm: [], handleOnSubmitForms: [] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybXMtbGlzdC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9rd2lraWQtZm9ybXMvc3JjL2xpYi9yZW5kZXJlci9mb3Jtcy1saXN0L2Zvcm1zLWxpc3QuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMva3dpa2lkLWZvcm1zL3NyYy9saWIvcmVuZGVyZXIvZm9ybXMtbGlzdC9mb3Jtcy1saXN0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULFlBQVksRUFDWixLQUFLLEVBR0wsTUFBTSxFQUVQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFDTCxvQkFBb0IsRUFDcEIscUJBQXFCLEVBQ3JCLGlCQUFpQixFQUNqQixNQUFNLEVBQ04sV0FBVyxFQUNYLFNBQVMsRUFDVCxZQUFZLEVBQ1osb0JBQW9CLEVBQ3JCLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEIsT0FBTyxFQUNMLFdBQVcsRUFDWCxjQUFjLEVBQ2YsTUFBTSw2Q0FBNkMsQ0FBQztBQUNyRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDcEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3pELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQzs7Ozs7QUFPdEQsTUFBTSxPQUFPLHdCQUF3QjtJQUxyQztRQU9FLG1CQUFjLEdBQVEsRUFBRSxDQUFDO1FBR3pCLGVBQVUsR0FBUSxFQUFFLENBQUM7UUFHckIsZUFBVSxHQUFRLEVBQUUsQ0FBQztRQUdyQixxQkFBZ0IsR0FBUSxFQUFFLENBQUM7UUFHM0IsY0FBUyxHQUFVLEVBQUUsQ0FBQztRQUd0QixjQUFTLEdBQVEsRUFBRSxDQUFDO1FBR3BCLHVCQUFrQixHQUFVLEVBQUUsQ0FBQztRQUcvQixpQkFBWSxHQUFH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QURSLEtBQUs7Z0JBSU4sa0JBQWtCO3NCQURqQixLQUFLO2dCQUlOLFlBQVk7c0JBRFgsS0FBSztnQkFJTixhQUFhO3NCQURaLEtBQUs7Z0JBSU4sT0FBTztzQkFETixNQUFNO2dCQUlQLG9CQUFvQjtzQkFEbkIsTUFBTTtnQkFJUCxvQkFBb0I7c0JBRG5CLE1BQU07Z0JBSVAsa0JBQWtCO3NCQURqQixNQUFNO2dCQXFDUCxXQUFXLE1Bd0NYLFdBQVcsTUFLWCxnQkFBZ0IsTUFnRGhCLGlCQUFpQixNQVVqQixhQUFhLE1Bc0JiLG1CQUFtQixNQWNuQix3QkFBd0IsTUFrQnhCLDBCQUEwQixNQXlCMUIsbUJBQW1CIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ29tcG9uZW50LFxuICBFdmVudEVtaXR0ZXIsXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE9uSW5pdCxcbiAgT3V0cHV0LFxuICBTaW1wbGVDaGFuZ2VzXG59IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQge1xuICBjaGVja09iamVjdEtleUV4aXN0cyxcbiAgY2hlY2tPYmplY3RQYXRoRXhpc3RzLFxuICBnZXRPYmplY3REZWVwQ29weSxcbiAgaXNOdWxsLFxuICBpc1VuZGVmaW5lZCxcbiAgbG9nTWV0aG9kLFxuICBtZXJnZU9iamVjdHMsXG4gIHNldFZhbHVlVG9PYmplY3RQYXRoXG59IGZyb20gXCJrd2lraWQtdG9vbGtpdFwiO1xuaW1wb3J0IHtcbiAgZ2V0TGFuZ3VhZ2UsXG4gIHVwZGF0ZUxhbmd1YWdlXG59IGZyb20gXCIuLi9jb25maWctY29udmVydGVyL2NvbmZpZy1jb252ZXJ0ZXIuaGVscGVyXCI7XG5pbXBvcnQgeyBFRm9ybVR5cGUgfSBmcm9tIFwiLi4vcmVuZGVyZXIuZGVmaW5pdGlvbnNcIjtcbmltcG9ydCB7IEVMb2dFdmVudFR5cGUgfSBmcm9tIFwiLi9mb3Jtcy1saXN0LmRlZmluaXRpb25zXCI7XG5pbXBvcnQgeyBmb3JtYXRFdmVudExvZ3MgfSBmcm9tIFwiLi9mb3Jtcy1saXN0LmhlbHBlclwiO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6IFwia3dpa2lkLWZvcm1zLWxpc3RcIixcbiAgdGVtcGxhdGVVcmw6IFwiLi9mb3Jtcy1saXN0LmNvbXBvbmVudC5odG1sXCIsXG4gIHN0eWxlVXJsczogW1wiLi9mb3Jtcy1saXN0LmNvbXBvbmVudC5zY3NzXCIsIFwiLi4vc2hhcmVkLnNjc3NcIl1cbn0pXG5leHBvcnQgY2xhc3MgS3dpa0lERm9ybXNMaXN0Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMge1xuICBASW5wdXQoKVxuICBzaG93Rm9ybUZpZWxkczogYW55ID0ge307XG5cbiAgQElucHV0KClcbiAgdXNlckNvbmZpZzogYW55ID0ge307XG5cbiAgQElucHV0KClcbiAgc3RlcENvbmZpZzogYW55ID0ge307XG5cbiAgQElucHV0KClcbiAgYWN0aXZlRm9ybUNvbmZpZzogYW55ID0ge307XG5cbiAgQElucHV0KClcbiAgZm9ybXNMaXN0OiBhbnlbXSA9IFtdO1xuXG4gIEBJbnB1dCgpXG4gIHJlZHV4RGF0YTogYW55ID0ge307XG5cbiAgQElucHV0KClcbiAgZm9ybXNMaXN0Q29tcGxldGVkOiBhbnlbXSA9IFtdO1xuXG4gIEBJbnB1dCgpXG4gIGlzTW9iaWxlVmlldyA9IGZhbHNlO1xuXG4gIEBJbnB1dCgpXG4gIGlzVW5zYXZlZERhdGEgPSBmYWxzZTtcblxuICBAT3V0cHV0KClcbiAgZ2V0TG9nczogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICBAT3V0cHV0KClcbiAgb25DbGlja1NldEFjdGl2ZUZvcm06IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG5cbiAgQE91dHB1dCgpXG4gIG9uQ2xpY2tIaWRlRm9ybXNMaXN0OiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuXG4gIEBPdXRwdXQoKVxuICBvbkNsaWNrU3VibWl0Rm9ybXMgPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICBzZWxlY3RlZEZvcm0gPSBcIlwiO1xuXG4gIHNldFNlbGVjdGVkRm9ybShzZWxlY3RlZEZvcm06IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuc2VsZWN0ZWRGb3JtID0gc2VsZWN0ZWRGb3JtO1xuICB9XG5cbiAgZm9ybXNMaXN0TGVuZ3RoID0gMDtcblxuICBpc0FsbEZvcm1zQ29tcGxldGVkID0gdHJ1ZTtcblxuICBsb2FkaW5nID0gZmFsc2U7XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgdGhpcy5yZWR1eERhdGEgPSB0aGlzLnJlZHV4RGF0YSA/PyB7fTtcblxuICAgIHRoaXMubG9hZGluZyA9IHRydWU7XG5cbiAgICB0aGlzLnNldFNlbGVjdGVkRm9ybSh0aGlzLmFjdGl2ZUZvcm1Db25maWc/LmtleSA/PyBcIlwiKTtcblxuICAgIHRoaXMuc3RlcENvbmZpZyA9IHRoaXMuZm9ybWF0U3RlcENvbmZpZyh0aGlzLnN0ZXBDb25maWcpO1xuXG4gICAgdGhpcy50cmlnZ2VyTG9ncyhFTG9nRXZlbnRUeXBlLkZPUk1fX1NURVBfQ09ORklHX0xPQURfU1VDQ0VTUywge30pO1xuXG4gICAgdGhpcy5mb3Jtc0xpc3QgPSB0aGlzLmZpbHRlckhpZGRlbkZvcm1zKHRoaXMuZm9ybXNMaXN0KTtcbiAgICB0aGlzLmZvcm1zTGlzdCA9IHRoaXMuc2V0Rm9ybVRpdGxlcyh0aGlzLmZvcm1zTGlzdCk7XG4gICAgdGhpcy5mb3Jtc0xpc3RMZW5ndGggPSB0aGlzLmZpbmRGb3Jtc0xpc3RMZW5ndGgodGhpcy5mb3Jtc0xpc3QpO1xuICAgIHRoaXMuaXNBbGxGb3Jtc0NvbXBsZXRlZCA9IHRoaXMuY2hlY2tJc0FsbEZvcm1zQ29tcGxldGVkKHRoaXMuZm9ybXNMaXN0KTtcblxuICAgIHRoaXMudHJpZ2dlckxvZ3MoRUxvZ0V2ZW50VHlwZS5GT1JNX19MSVNUX0xPQURfU1VDQ0VTUywge30pO1xuXG4gICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gIH1cblxuICBAbG9nTWV0aG9kXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBjb25zdCB2ZXJpZnlDaGFuZ2UgPSAoa2V5OiBzdHJpbmcpID0+IHtcbiAgICAgIHJldHVybiBjaGVja09iamVjdEtleUV4aXN0cyhjaGFuZ2VzLCBrZXkpICYmICFjaGFuZ2VzW2tleV0uZmlyc3RDaGFuZ2U7XG4gICAgfTtcbiAgICBpZiAodmVyaWZ5Q2hhbmdlKFwic2hvd0Zvcm1GaWVsZHNcIikpIHtcbiAgICAgIHRoaXMuc2hvd0Zvcm1GaWVsZHMgPSBjaGFuZ2VzLnNob3dGb3JtRmllbGRzLmN1cnJlbnRWYWx1ZTtcbiAgICB9XG4gICAgaWYgKHZlcmlmeUNoYW5nZShcInN0ZXBDb25maWdcIikpIHtcbiAgICAgIHRoaXMuc3RlcENvbmZpZyA9IHRoaXMuZm9ybWF0U3RlcENvbmZpZyhjaGFuZ2VzLnN0ZXBDb25maWcuY3VycmVudFZhbHVlKTtcbiAgICB9XG4gICAgaWYgKHZlcmlmeUNoYW5nZShcImlzVW5zYXZlZERhdGFcIikpIHtcbiAgICAgIHRoaXMuaXNVbnNhdmVkRGF0YSA9IGNoYW5nZXMuaXNVbnNhdmVkRGF0YS5jdXJyZW50VmFsdWU7XG4gICAgfVxuICAgIGlmICh2ZXJpZnlDaGFuZ2UoXCJmb3Jtc0xpc3RcIikpIHtcbiAgICAgIHRoaXMuZm9ybXNMaXN0ID0gdGhpcy5maWx0ZXJIaWRkZW5Gb3Jtcyh0aGlzLmZvcm1zTGlzdCk7XG4gICAgICB0aGlzLmZvcm1zTGlzdCA9IHRoaXMuc2V0Rm9ybVRpdGxlcyh0aGlzLmZvcm1zTGlzdCk7XG4gICAgICB0aGlzLmZvcm1zTGlzdExlbmd0aCA9IHRoaXMuZmluZEZvcm1zTGlzdExlbmd0aCh0aGlzLmZvcm1zTGlzdCk7XG4gICAgICB0aGlzLmlzQWxsRm9ybXNDb21wbGV0ZWQgPSB0aGlzLmNoZWNrSXNBbGxGb3Jtc0NvbXBsZXRlZCh0aGlzLmZvcm1zTGlzdCk7XG4gICAgfVxuICAgIGlmICh2ZXJpZnlDaGFuZ2UoXCJpc01vYmlsZVZpZXdcIikpIHtcbiAgICAgIHRoaXMuaXNNb2JpbGVWaWV3ID0gY2hhbmdlcy5pc01vYmlsZVZpZXcuY3VycmVudFZhbHVlO1xuXG4gICAgICBpZiAoIXRoaXMuaXNNb2JpbGVWaWV3KSB7XG4gICAgICAgIHRoaXMuc2V0U2VsZWN0ZWRGb3JtKFwiXCIpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodmVyaWZ5Q2hhbmdlKFwiYWN0aXZlRm9ybUNvbmZpZ1wiKSkge1xuICAgICAgdGhpcy5hY3RpdmVGb3JtQ29uZmlnID0gY2hhbmdlcy5hY3RpdmVGb3JtQ29uZmlnLmN1cnJlbnRWYWx1ZTtcblxuICAgICAgdGhpcy5zZXRTZWxlY3RlZEZvcm0odGhpcy5hY3RpdmVGb3JtQ29uZmlnPy5rZXkgPz8gXCJcIik7XG4gICAgfVxuICAgIGlmIChjaGVja09iamVjdEtleUV4aXN0cyhjaGFuZ2VzLCBcInJlZHV4RGF0YVwiKSkge1xuICAgICAgdGhpcy5yZWR1eERhdGEgPSBjaGFuZ2VzLnJlZHV4RGF0YS5jdXJyZW50VmFsdWUgPz8ge307XG4gICAgfVxuICAgIGlmIChjaGVja09iamVjdEtleUV4aXN0cyhjaGFuZ2VzLCBcInVzZXJDb25maWdcIikpIHtcbiAgICAgIHRoaXMudXNlckNvbmZpZyA9IGNoYW5nZXMudXNlckNvbmZpZy5jdXJyZW50VmFsdWU7XG4gICAgfVxuICB9XG5cbiAgQGxvZ01ldGhvZFxuICB0cmlnZ2VyTG9ncyhldmVudFR5cGU6IEVMb2dFdmVudFR5cGUsIGxvZ3M6IGFueSkge1xuICAgIHRoaXMuZ2V0TG9ncy5lbWl0KGZvcm1hdEV2ZW50TG9ncyhldmVudFR5cGUsIHRoaXMuc3RlcENvbmZpZywgbG9ncykpO1xuICB9XG5cbiAgQGxvZ01ldGhvZFxuICBmb3JtYXRTdGVwQ29uZmlnKHN0ZXBDb25maWc6IGFueSk6IGFueSB7XG4gICAgc3RlcENvbmZpZyA9XG4gICAgICBzdGVwQ29uZmlnICYmIHR5cGVvZiBzdGVwQ29uZmlnID09PSBcIm9iamVjdFwiXG4gICAgICAgID8gZ2V0T2JqZWN0RGVlcENvcHkoc3RlcENvbmZpZylcbiAgICAgICAgOiBzdGVwQ29uZmlnO1xuXG4gICAgbGV0IHN0ZXBDb25maWdQcm9wZXJ0aWVzID0ge1xuICAgICAgZm9ybUxpc3RQcm9wZXJ0aWVzOiB7XG4gICAgICAgIGZvb3Rlcjoge1xuICAgICAgICAgIHN1Ym1pdEZvcm1CdXR0b246IHtcbiAgICAgICAgICAgIGhpZGRlbjogZmFsc2UsXG4gICAgICAgICAgICBsYWJlbDogXCJTdWJtaXRcIlxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICBpZiAoaXNOdWxsKHN0ZXBDb25maWcpIHx8IGlzVW5kZWZpbmVkKHN0ZXBDb25maWcpKSB7XG4gICAgICBzdGVwQ29uZmlnID0gc2V0VmFsdWVUb09iamVjdFBhdGgoe30sIFwicHJvcHNcIiwgc3RlcENvbmZpZ1Byb3BlcnRpZXMpO1xuICAgIH0gZWxzZSBpZiAoY2hlY2tPYmplY3RLZXlFeGlzdHMoc3RlcENvbmZpZywgXCJwcm9wc1wiKSkge1xuICAgICAgc3RlcENvbmZpZ1Byb3BlcnRpZXMgPSBtZXJnZU9iamVjdHMoXG4gICAgICAgIHN0ZXBDb25maWdQcm9wZXJ0aWVzLFxuICAgICAgICBzdGVwQ29uZmlnLnByb3BzXG4gICAgICApO1xuXG4gICAgICBzdGVwQ29uZmlnID0gc2V0VmFsdWVUb09iamVjdFBhdGgoXG4gICAgICAgIHN0ZXBDb25maWcsXG4gICAgICAgIFwicHJvcHNcIixcbiAgICAgICAgc3RlcENvbmZpZ1Byb3BlcnRpZXNcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ZXBDb25maWcgPSBzZXRWYWx1ZVRvT2JqZWN0UGF0aChcbiAgICAgICAgc3RlcENvbmZpZyxcbiAgICAgICAgXCJwcm9wc1wiLFxuICAgICAgICBzdGVwQ29uZmlnUHJvcGVydGllc1xuICAgICAgKTtcbiAgICB9XG5cbiAgICBzdGVwQ29uZmlnLnByb3BzLmZvcm1MaXN0UHJvcGVydGllcy5mb290ZXIuc3VibWl0Rm9ybUJ1dHRvbi5sYWJlbCA9XG4gICAgICB1cGRhdGVMYW5ndWFnZShcbiAgICAgICAgc3RlcENvbmZpZy5wcm9wcy5mb3JtTGlzdFByb3BlcnRpZXMuZm9vdGVyLnN1Ym1pdEZvcm1CdXR0b24ubGFiZWwsXG4gICAgICAgIGdldExhbmd1YWdlKHRoaXMucmVkdXhEYXRhID8/IHt9LCB0aGlzLnVzZXJDb25maWcpXG4gICAgICApO1xuXG4gICAgcmV0dXJuIHN0ZXBDb25maWc7XG4gIH1cblxuICBAbG9nTWV0aG9kXG4gIGZpbHRlckhpZGRlbkZvcm1zKGZvcm1zTGlzdDogYW55W10pOiBhbnlbXSB7XG4gICAgcmV0dXJuIGZvcm1zTGlzdC5maWx0ZXIoKGZvcm0pID0+IHtcbiAgICAgIGlmIChjaGVja09iamVjdEtleUV4aXN0cyhmb3JtLCBcImhpZGRlblwiKSkge1xuICAgICAgICByZXR1cm4gIWZvcm0uaGlkZGVuO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0pO1xuICB9XG5cbiAgQGxvZ01ldGhvZFxuICBzZXRGb3JtVGl0bGVzKGZvcm1zTGlzdDogYW55W10pOiBhbnlbXSB7XG4gICAgcmV0dXJuIGZvcm1zTGlzdFxuICAgICAgLm1hcCgoZm9ybSkgPT4ge1xuICAgICAgICBpZiAoZm9ybS50eXBlID09PSBFRm9ybVR5cGUuSFRNTCkge1xuICAgICAgICAgIHJldHVybiBmb3JtOyAvLyBObyBtb2RpZmljYXRpb24sIGp1c3QgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNoZWNrT2JqZWN0UGF0aEV4aXN0cyhmb3JtLCBcInByb3BzLnRpdGxlXCIpKSB7XG4gICAgICAgICAgZm9ybS5wcm9wcy50aXRsZSA9IHVwZGF0ZUxhbmd1YWdlKFxuICAgICAgICAgICAgZm9ybS5wcm9wcy50aXRsZSxcbiAgICAgICAgICAgIGdldExhbmd1YWdlKHRoaXMucmVkdXhEYXRhID8/IHt9LCB0aGlzLnVzZXJDb25maWcpXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZm9ybTsgLy8gUmV0dXJuIHRoZSBmb3JtIHJlZ2FyZGxlc3Mgb2YgbW9kaWZpY2F0aW9uXG4gICAgICB9KVxuICAgICAgLmZpbHRlcihcbiAgICAgICAgKGZvcm0pID0+XG4gICAgICAgICAgZm9ybS50eXBlID09PSBFRm9ybVR5cGUuSFRNTCB8fFxuICAgICAgICAgIGNoZWNrT2JqZWN0UGF0aEV4aXN0cyhmb3JtLCBcInByb3BzLnRpdGxlXCIpXG4gICAgICApO1xuICB9XG5cbiAgQGxvZ01ldGhvZFxuICBmaW5kRm9ybXNMaXN0TGVuZ3RoKGZvcm1zTGlzdDogYW55W10pOiBudW1iZXIge1xuICAgIHJldHVybiBmb3Jtc0xpc3QuZmlsdGVyKChmb3JtKSA9PiB7XG4gICAgICBpZiAoY2hlY2tPYmplY3RLZXlFeGlzdHMoZm9ybSwgXCJ0eXBlXCIpKSB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgZm9ybS50eXBlICE9PSBFRm9ybVR5cGUuSFRNTCAmJlxuICAgICAgICAgIGNoZWNrT2JqZWN0S2V5RXhpc3RzKGZvcm0sIFwiaGlkZGVuXCIpICYmXG4gICAgICAgICAgIWZvcm0uaGlkZGVuXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4gY2hlY2tPYmplY3RLZXlFeGlzdHMoZm9ybSwgXCJoaWRkZW5cIikgJiYgIWZvcm0uaGlkZGVuO1xuICAgIH0pLmxlbmd0aDtcbiAgfVxuXG4gIEBsb2dNZXRob2RcbiAgY2hlY2tJc0FsbEZvcm1zQ29tcGxldGVkKGZvcm1zTGlzdDogYW55W10pOiBib29sZWFuIHtcbiAgICBsZXQgaXNBbGxGb3Jtc0NvbXBsZXRlZCA9IHRydWU7XG5cbiAgICBmb3IgKGNvbnN0IGZvcm0gb2YgZm9ybXNMaXN0KSB7XG4gICAgICBpZiAoY2hlY2tPYmplY3RLZXlFeGlzdHMoZm9ybSwgXCJ0eXBlXCIpKSB7XG4gICAgICAgIGlmIChmb3JtLnR5cGUgIT09IEVGb3JtVHlwZS5IVE1MKSB7XG4gICAgICAgICAgaWYgKGZvcm0uc3RhdHVzICE9PSBcImNvbXBsZXRlZFwiKSB7XG4gICAgICAgICAgICBpc0FsbEZvcm1zQ29tcGxldGVkID0gZmFsc2U7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gaXNBbGxGb3Jtc0NvbXBsZXRlZDtcbiAgfVxuXG4gIEBsb2dNZXRob2RcbiAgaGFuZGxlT25DbGlja1NldEFjdGl2ZUZvcm0oc2VsZWN0ZWRGb3JtOiBzdHJpbmcpIHtcbiAgICBpZiAoXG4gICAgICB0aGlzLmlzTW9iaWxlVmlldyB8fFxuICAgICAgKCF0aGlzLmlzTW9iaWxlVmlldyAmJiB0aGlzLnNlbGVjdGVkRm9ybSAhPT0gc2VsZWN0ZWRGb3JtKSB8fFxuICAgICAgKHRoaXMuaXNBbGxGb3Jtc0NvbXBsZXRlZCAmJiAhdGhpcy5zaG93Rm9ybUZpZWxkcylcbiAgICApIHtcbiAgICAgIGlmIChcbiAgICAgICAgdGhpcy5hY3RpdmVGb3JtQ29uZmlnPy5wcm9wZXJ0aWVzPy5pc1Vuc2F2ZWREYXRhQWxlcnRFbmFibGVkICYmXG4gICAgICAgIHRoaXMuaXNVbnNhdmVkRGF0YSAmJlxuICAgICAgICAhd2luZG93LmNvbmZpcm0oXCJZb3UgaGF2ZSB1bnNhdmVkIGRhdGEuIFByb2NlZWQ/XCIpXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGhpcy50cmlnZ2VyTG9ncyhFTG9nRXZlbnRUeXBlLkZPUk1fX0ZPUk1fT1BFTl9CVVRUT05fQ0xJQ0ssIHtcbiAgICAgICAgZm9ybV9rZXk6IHNlbGVjdGVkRm9ybSxcbiAgICAgICAgZm9ybV9sYWJlbDpcbiAgICAgICAgICB0aGlzLmFjdGl2ZUZvcm1Db25maWc/LnRpdGxlID8/IHRoaXMuYWN0aXZlRm9ybUNvbmZpZz8ucHJvcHM/LnRpdGxlXG4gICAgICB9KTtcblxuICAgICAgdGhpcy5zZWxlY3RlZEZvcm0gPSBzZWxlY3RlZEZvcm07XG4gICAgICB0aGlzLm9uQ2xpY2tTZXRBY3RpdmVGb3JtLmVtaXQoc2VsZWN0ZWRGb3JtKTtcbiAgICB9XG4gIH1cblxuICBAbG9nTWV0aG9kXG4gIGhhbmRsZU9uU3VibWl0Rm9ybXMoZTogYW55KSB7XG4gICAgLyoqXG4gICAgICogUE9TVCBBQ1RJT05TXG4gICAgICogMS4gQVBJIENhbGxzLlxuICAgICAqIDIuIFByZXZpZXcgb2YgYWxsIGZpbGxlZCBkYXRhLlxuICAgICAqIDMuIFVSTCBSZWRpcmVjdGlvbiBvciBuZXcgb3BlbmluZyBvZiBVUkwgaW4gZXh0ZXJuYWwgdGFiLlxuICAgICAqL1xuXG4gICAgdGhpcy5vbkNsaWNrU3VibWl0Rm9ybXMuZW1pdChlKTtcbiAgfVxufVxuIiwiPGRpdlxuICBpZD1cInNpZGViYXItY29udGFpbmVyXCJcbiAgKm5nSWY9XCIhbG9hZGluZ1wiXG4+XG4gIDxkaXYgaWQ9XCJzaWRlYmFyXCI+XG4gICAgPGRpdiBuZ0NsYXNzPVwia3dpa2lkLWZvcm0taGVhZGVyXCI+XG4gICAgICA8ZGl2IGlkPVwidWYtaGVhZGVyXCI+XG4gICAgICAgIDxkaXYgaWQ9XCJ1Zi1oZWFkZXItbG9nby1jb250YWluZXJcIj5cbiAgICAgICAgICA8aW1nXG4gICAgICAgICAgICBpZD1cInVmLWhlYWRlci1sb2dvXCJcbiAgICAgICAgICAgIHNyYz1cInt7IHRoaXMudXNlckNvbmZpZy50aGVtZS5jbGllbnRMb2dvIH19XCJcbiAgICAgICAgICAgIFtuZ0NsYXNzXT1cIidsYXJnZS1pY29uJ1wiXG4gICAgICAgICAgLz5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxociAvPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgaWQ9XCJ1Zi1wcm9ncmVzc1wiPlxuICAgICAgPGRpdiBpZD1cInVmLXByb2dyZXNzLXN0ZXBzXCI+XG4gICAgICAgIHt7IHRoaXMuZm9ybXNMaXN0Q29tcGxldGVkLmxlbmd0aCB9fSAvIHt7IHRoaXMuZm9ybXNMaXN0TGVuZ3RoIH19IFN0ZXBzXG4gICAgICAgIENvbXBsZXRlZFxuICAgICAgPC9kaXY+XG4gICAgICA8a3dpa3VpLXByb2dyZXNzLXNlZ21lbnRlZFxuICAgICAgICBbbWF4XT1cInRoaXMuZm9ybXNMaXN0TGVuZ3RoXCJcbiAgICAgICAgc2l6ZT1cIm1cIlxuICAgICAgICBbdmFsdWVdPVwidGhpcy5mb3Jtc0xpc3RDb21wbGV0ZWQubGVuZ3RoXCJcbiAgICAgID48L2t3aWt1aS1wcm9ncmVzcy1zZWdtZW50ZWQ+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBpZD1cInVmLXNlY3Rpb25zLWNvbnRhaW5lclwiPlxuICAgICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgZm9ybSBvZiBmb3Jtc0xpc3Q7IGxldCBpID0gaW5kZXhcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciBbbmdTd2l0Y2hdPVwiZm9ybS50eXBlXCI+XG4gICAgICAgICAgPCEtLSBIVE1MIENvbnRlbnQgLS0+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ0hUTUwnXCI+XG4gICAgICAgICAgICA8ZGl2IFtpbm5lckh0bWxdPVwiZm9ybS5wcm9wcy5odG1sQ29udGVudCB8IGt3aWt1aVNhZmVIdG1sXCI+PC9kaXY+XG4gICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgPCEtLSBUeXBlIEZPUk0gLS0+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdTd2l0Y2hDYXNlPVwiJ0ZPUk0nXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyXG4gICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cIkZPUk1fQlVUVE9OXCJcbiAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRDb250ZXh0XT1cIntcbiAgICAgICAgICAgICAgICBmb3JtOiBmb3JtLFxuICAgICAgICAgICAgICAgIGFjdGl2ZUZvcm1Db25maWc6IGFjdGl2ZUZvcm1Db25maWdcbiAgICAgICAgICAgICAgfVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGlkPVwic3VibWl0LXNpZGViYXItYnRuLWNvbnRhaW5lclwiPlxuICAgICAgPGt3aWt1aS1idXR0b25cbiAgICAgICAgKm5nSWY9XCJcbiAgICAgICAgICAhc3RlcENvbmZpZy5wcm9wcy5mb3JtTGlzdFByb3BlcnRpZXMuZm9vdGVyLnN1Ym1pdEZvcm1CdXR0b24uaGlkZGVuXG4gICAgICAgIFwiXG4gICAgICAgIGxhYmVsPVwie3tcbiAgICAgICAgICBzdGVwQ29uZmlnLnByb3BzLmZvcm1MaXN0UHJvcGVydGllcy5mb290ZXIuc3VibWl0Rm9ybUJ1dHRvbi5sYWJlbFxuICAgICAgICB9fVwiXG4gICAgICAgIHR5cGU9XCJzdWJtaXRcIlxuICAgICAgICBzdHlsZXM9XCJ3aWR0aDogMTAwJVwiXG4gICAgICAgIChvbkNsaWNrKT1cImhhbmRsZU9uU3VibWl0Rm9ybXMoJGV2ZW50KVwiXG4gICAgICA+PC9rd2lrdWktYnV0dG9uPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PlxuXG48bmctdGVtcGxhdGVcbiAgI0ZPUk1fQlVUVE9OXG4gIGxldC1mb3JtPVwiZm9ybVwiXG4gIGxldC1hY3RpdmVGb3JtQ29uZmlnPVwiYWN0aXZlRm9ybUNvbmZpZ1wiXG4+XG4gIDxkaXZcbiAgICBbY2xhc3NdPVwiJ3VmLXNlY3Rpb24taXRlbSdcIlxuICAgIFtjbGFzcy5jb21wbGV0ZWRdPVwiZm9ybS5zdGF0dXMgPT09ICdjb21wbGV0ZWQnICYmICFmb3JtLmRpc2FibGVkXCJcbiAgICBbY2xhc3MuZWRpdF09XCJmb3JtLnN0YXR1cyA9PT0gJ2VkaXRhYmxlJyAmJiAhZm9ybS5kaXNhYmxlZFwiXG4gICAgW2NsYXNzLmxvY2tlZF09XCJmb3JtLnN0YXR1cyA9PT0gJ2xvY2tlZCcgJiYgZm9ybS5kaXNhYmxlZFwiXG4gICAgW2NsYXNzLmFjdGl2ZV09XCJcbiAgICAgIGFjdGl2ZUZvcm1Db25maWcgIT09IHVuZGVmaW5lZCAmJiBmb3JtLmtleSA9PT0gYWN0aXZlRm9ybUNvbmZpZy5rZXlcbiAgICBcIlxuICAgIChjbGljayk9XCJcbiAgICAgIGZvcm0uc3RhdHVzID09PSAnbG9ja2VkJyAmJiBmb3JtLmRpc2FibGVkXG4gICAgICAgID8gdW5kZWZpbmVkXG4gICAgICAgIDogaGFuZGxlT25DbGlja1NldEFjdGl2ZUZvcm0oZm9ybS5rZXkpXG4gICAgXCJcbiAgPlxuICAgIDxkaXYgY2xhc3M9XCJ1Zi1mb3JtLXNlY3Rpb24tY2FyZC10aXRsZVwiPlxuICAgICAge3sgZm9ybS5wcm9wcy50aXRsZSB9fSZuYnNwOzxzcGFuICpuZ0lmPVwiZm9ybT8ucmVxdWlyZWRcIj4qPC9zcGFuPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJ1Zi1mb3JtLXNlY3Rpb24tY2FyZC1zdGF0dXNcIj5cbiAgICAgIDxkaXZcbiAgICAgICAgKm5nSWY9XCJmb3JtLnN0YXR1cyA9PT0gJ2NvbXBsZXRlZCcgJiYgIWZvcm0uZGlzYWJsZWRcIlxuICAgICAgICBjbGFzcz1cInVmLWZvcm0tc2VjdGlvbi1jYXJkLXN0YXR1cy1pbWcgY29tcGxldGVkXCJcbiAgICAgID5cbiAgICAgICAgPHR1aS1zdmcgc3JjPVwidHVpSWNvbkNoZWNrTGFyZ2VcIj48L3R1aS1zdmc+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXZcbiAgICAgICAgKm5nSWY9XCJmb3JtLnN0YXR1cyAhPT0gJ2NvbXBsZXRlZCcgJiYgIWZvcm0uZGlzYWJsZWRcIlxuICAgICAgICBjbGFzcz1cInVmLWZvcm0tc2VjdGlvbi1jYXJkLXN0YXR1cy1pbWcgZWRpdFwiXG4gICAgICA+XG4gICAgICAgIDx0dWktc3ZnIHNyYz1cInR1aUljb25FZGl0XCI+PC90dWktc3ZnPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2XG4gICAgICAgICpuZ0lmPVwiZm9ybS5zdGF0dXMgIT09ICdjb21wbGV0ZWQnICYmIGZvcm0uZGlzYWJsZWRcIlxuICAgICAgICBjbGFzcz1cInVmLWZvcm0tc2VjdGlvbi1jYXJkLXN0YXR1cy1pbWcgbG9ja2VkXCJcbiAgICAgID5cbiAgICAgICAgPHR1aS1zdmcgc3JjPVwidHVpSWNvbkxvY2tcIj48L3R1aS1zdmc+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L25nLXRlbXBsYXRlPlxuIl19