UNPKG

kwikid-forms

Version:

KwikID's JSON Configuration based Forms Renderer and Builder

241 lines 43.7 kB
import { __decorate } from "tslib"; import { Component, EventEmitter, Input, Output } from "@angular/core"; import { checkObjectKeyExists, checkObjectPathExists, 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.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; this.loading = true; this.setSelectedForm((_b = (_a = this.activeFormConfig) === null || _a === void 0 ? void 0 : _a.key) !== null && _b !== void 0 ? _b : ""); 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; const verifyChange = (key) => { return checkObjectKeyExists(changes, key) && !changes[key].firstChange; }; if (verifyChange("showFormFields")) { this.showFormFields = changes.showFormFields.currentValue; } if (verifyChange("stepConfig")) { this.stepConfig = 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 : ""); } } triggerLogs(eventType, logs) { this.getLogs.emit(formatEventLogs(eventType, this.stepConfig, logs)); } formatStepConfig(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()); return stepConfig; } filterHiddenForms(formsList) { return formsList.filter((form) => { if (checkObjectKeyExists(form, "hidden")) { return !form.hidden; } return false; }); } setFormTitles(formsList) { return formsList .map((form) => { if (form.type === EFormType.HTML) { return form; // No modification, just return } if (checkObjectPathExists(form, "props.title")) { form.props.title = updateLanguage(form.props.title, getLanguage()); } 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", 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 }}&nbsp;<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 }], 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybXMtbGlzdC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9rd2lraWQtZm9ybXMvc3JjL2xpYi9yZW5kZXJlci9mb3Jtcy1saXN0L2Zvcm1zLWxpc3QuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMva3dpa2lkLWZvcm1zL3NyYy9saWIvcmVuZGVyZXIvZm9ybXMtbGlzdC9mb3Jtcy1saXN0LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULFlBQVksRUFDWixLQUFLLEVBR0wsTUFBTSxFQUVQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFDTCxvQkFBb0IsRUFDcEIscUJBQXFCLEVBQ3JCLE1BQU0sRUFDTixXQUFXLEVBQ1gsU0FBUyxFQUNULFlBQVksRUFDWixvQkFBb0IsRUFDckIsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQ0wsV0FBVyxFQUNYLGNBQWMsRUFDZixNQUFNLDZDQUE2QyxDQUFDO0FBQ3JELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDekQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHFCQUFxQixDQUFDOzs7OztBQU90RCxNQUFNLE9BQU8sd0JBQXdCO0lBTHJDO1FBT0UsbUJBQWMsR0FBUSxFQUFFLENBQUM7UUFHekIsZUFBVSxHQUFRLEVBQUUsQ0FBQztRQUdyQixlQUFVLEdBQVEsRUFBRSxDQUFDO1FBR3JCLHFCQUFnQixHQUFRLEVBQUUsQ0FBQztRQUczQixjQUFTLEdBQVUsRUFBRSxDQUFDO1FBR3RCLHVCQUFrQixHQUFVLEVBQUUsQ0FBQztRQUcvQixpQkFBWSxHQUFHLEtBQUssQ0FBQztRQUdyQixrQkFBYSxHQUFHLEtBQUssQ0FBQztR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O3dFQWdCVDtBQUdEO0lBREMsU0FBUzswRUF1QlQ7QUFHRDtJQURDLFNBQVM7bUVBVVQ7NEZBdFBVLHdCQUF3QjtrQkFMcEMsU0FBUzttQkFBQztvQkFDVCxRQUFRLEVBQUUsbUJBQW1CO29CQUM3QixXQUFXLEVBQUUsNkJBQTZCO29CQUMxQyxTQUFTLEVBQUUsQ0FBQyw2QkFBNkIsRUFBRSxnQkFBZ0IsQ0FBQztpQkFDN0Q7OEJBR0MsY0FBYztzQkFEYixLQUFLO2dCQUlOLFVBQVU7c0JBRFQsS0FBSztnQkFJTixVQUFVO3NCQURULEtBQUs7Z0JBSU4sZ0JBQWdCO3NCQURmLEtBQUs7Z0JBSU4sU0FBUztzQkFEUixLQUFLO2dCQUlOLGtCQUFrQjtzQkFEakIsS0FBSztnQkFJTixZQUFZO3NCQURYLEtBQUs7Z0JBSU4sYUFBYTtzQkFEWixLQUFLO2dCQUlOLE9BQU87c0JBRE4sTUFBTTtnQkFJUCxvQkFBb0I7c0JBRG5CLE1BQU07Z0JBSVAsb0JBQW9CO3NCQURuQixNQUFNO2dCQUlQLGtCQUFrQjtzQkFEakIsTUFBTTtnQkFtQ1AsV0FBVyxNQWtDWCxXQUFXLE1BS1gsZ0JBQWdCLE1BMkNoQixpQkFBaUIsTUFVakIsYUFBYSxNQW1CYixtQkFBbUIsTUFjbkIsd0JBQXdCLE1Ba0J4QiwwQkFBMEIsTUF5QjFCLG1CQUFtQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgRXZlbnRFbWl0dGVyLFxuICBJbnB1dCxcbiAgT25DaGFuZ2VzLFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlc1xufSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHtcbiAgY2hlY2tPYmplY3RLZXlFeGlzdHMsXG4gIGNoZWNrT2JqZWN0UGF0aEV4aXN0cyxcbiAgaXNOdWxsLFxuICBpc1VuZGVmaW5lZCxcbiAgbG9nTWV0aG9kLFxuICBtZXJnZU9iamVjdHMsXG4gIHNldFZhbHVlVG9PYmplY3RQYXRoXG59IGZyb20gXCJrd2lraWQtdG9vbGtpdFwiO1xuaW1wb3J0IHtcbiAgZ2V0TGFuZ3VhZ2UsXG4gIHVwZGF0ZUxhbmd1YWdlXG59IGZyb20gXCIuLi9jb25maWctY29udmVydGVyL2NvbmZpZy1jb252ZXJ0ZXIuaGVscGVyXCI7XG5pbXBvcnQgeyBFRm9ybVR5cGUgfSBmcm9tIFwiLi4vcmVuZGVyZXIuZGVmaW5pdGlvbnNcIjtcbmltcG9ydCB7IEVMb2dFdmVudFR5cGUgfSBmcm9tIFwiLi9mb3Jtcy1saXN0LmRlZmluaXRpb25zXCI7XG5pbXBvcnQgeyBmb3JtYXRFdmVudExvZ3MgfSBmcm9tIFwiLi9mb3Jtcy1saXN0LmhlbHBlclwiO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6IFwia3dpa2lkLWZvcm1zLWxpc3RcIixcbiAgdGVtcGxhdGVVcmw6IFwiLi9mb3Jtcy1saXN0LmNvbXBvbmVudC5odG1sXCIsXG4gIHN0eWxlVXJsczogW1wiLi9mb3Jtcy1saXN0LmNvbXBvbmVudC5zY3NzXCIsIFwiLi4vc2hhcmVkLnNjc3NcIl1cbn0pXG5leHBvcnQgY2xhc3MgS3dpa0lERm9ybXNMaXN0Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMge1xuICBASW5wdXQoKVxuICBzaG93Rm9ybUZpZWxkczogYW55ID0ge307XG5cbiAgQElucHV0KClcbiAgdXNlckNvbmZpZzogYW55ID0ge307XG5cbiAgQElucHV0KClcbiAgc3RlcENvbmZpZzogYW55ID0ge307XG5cbiAgQElucHV0KClcbiAgYWN0aXZlRm9ybUNvbmZpZzogYW55ID0ge307XG5cbiAgQElucHV0KClcbiAgZm9ybXNMaXN0OiBhbnlbXSA9IFtdO1xuXG4gIEBJbnB1dCgpXG4gIGZvcm1zTGlzdENvbXBsZXRlZDogYW55W10gPSBbXTtcblxuICBASW5wdXQoKVxuICBpc01vYmlsZVZpZXcgPSBmYWxzZTtcblxuICBASW5wdXQoKVxuICBpc1Vuc2F2ZWREYXRhID0gZmFsc2U7XG5cbiAgQE91dHB1dCgpXG4gIGdldExvZ3M6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG5cbiAgQE91dHB1dCgpXG4gIG9uQ2xpY2tTZXRBY3RpdmVGb3JtOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuXG4gIEBPdXRwdXQoKVxuICBvbkNsaWNrSGlkZUZvcm1zTGlzdDogRXZlbnRFbWl0dGVyPGFueT4gPSBuZXcgRXZlbnRFbWl0dGVyPGFueT4oKTtcblxuICBAT3V0cHV0KClcbiAgb25DbGlja1N1Ym1pdEZvcm1zID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG5cbiAgc2VsZWN0ZWRGb3JtID0gXCJcIjtcblxuICBzZXRTZWxlY3RlZEZvcm0oc2VsZWN0ZWRGb3JtOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnNlbGVjdGVkRm9ybSA9IHNlbGVjdGVkRm9ybTtcbiAgfVxuXG4gIGZvcm1zTGlzdExlbmd0aCA9IDA7XG5cbiAgaXNBbGxGb3Jtc0NvbXBsZXRlZCA9IHRydWU7XG5cbiAgbG9hZGluZyA9IGZhbHNlO1xuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMubG9hZGluZyA9IHRydWU7XG5cbiAgICB0aGlzLnNldFNlbGVjdGVkRm9ybSh0aGlzLmFjdGl2ZUZvcm1Db25maWc/LmtleSA/PyBcIlwiKTtcblxuICAgIHRoaXMuc3RlcENvbmZpZyA9IHRoaXMuZm9ybWF0U3RlcENvbmZpZyh0aGlzLnN0ZXBDb25maWcpO1xuXG4gICAgdGhpcy50cmlnZ2VyTG9ncyhFTG9nRXZlbnRUeXBlLkZPUk1fX1NURVBfQ09ORklHX0xPQURfU1VDQ0VTUywge30pO1xuXG4gICAgdGhpcy5mb3Jtc0xpc3QgPSB0aGlzLmZpbHRlckhpZGRlbkZvcm1zKHRoaXMuZm9ybXNMaXN0KTtcbiAgICB0aGlzLmZvcm1zTGlzdCA9IHRoaXMuc2V0Rm9ybVRpdGxlcyh0aGlzLmZvcm1zTGlzdCk7XG4gICAgdGhpcy5mb3Jtc0xpc3RMZW5ndGggPSB0aGlzLmZpbmRGb3Jtc0xpc3RMZW5ndGgodGhpcy5mb3Jtc0xpc3QpO1xuICAgIHRoaXMuaXNBbGxGb3Jtc0NvbXBsZXRlZCA9IHRoaXMuY2hlY2tJc0FsbEZvcm1zQ29tcGxldGVkKHRoaXMuZm9ybXNMaXN0KTtcblxuICAgIHRoaXMudHJpZ2dlckxvZ3MoRUxvZ0V2ZW50VHlwZS5GT1JNX19MSVNUX0xPQURfU1VDQ0VTUywge30pO1xuXG4gICAgdGhpcy5sb2FkaW5nID0gZmFsc2U7XG4gIH1cblxuICBAbG9nTWV0aG9kXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBjb25zdCB2ZXJpZnlDaGFuZ2UgPSAoa2V5OiBzdHJpbmcpID0+IHtcbiAgICAgIHJldHVybiBjaGVja09iamVjdEtleUV4aXN0cyhjaGFuZ2VzLCBrZXkpICYmICFjaGFuZ2VzW2tleV0uZmlyc3RDaGFuZ2U7XG4gICAgfTtcbiAgICBpZiAodmVyaWZ5Q2hhbmdlKFwic2hvd0Zvcm1GaWVsZHNcIikpIHtcbiAgICAgIHRoaXMuc2hvd0Zvcm1GaWVsZHMgPSBjaGFuZ2VzLnNob3dGb3JtRmllbGRzLmN1cnJlbnRWYWx1ZTtcbiAgICB9XG4gICAgaWYgKHZlcmlmeUNoYW5nZShcInN0ZXBDb25maWdcIikpIHtcbiAgICAgIHRoaXMuc3RlcENvbmZpZyA9IGNoYW5nZXMuc3RlcENvbmZpZy5jdXJyZW50VmFsdWU7XG4gICAgfVxuICAgIGlmICh2ZXJpZnlDaGFuZ2UoXCJpc1Vuc2F2ZWREYXRhXCIpKSB7XG4gICAgICB0aGlzLmlzVW5zYXZlZERhdGEgPSBjaGFuZ2VzLmlzVW5zYXZlZERhdGEuY3VycmVudFZhbHVlO1xuICAgIH1cbiAgICBpZiAodmVyaWZ5Q2hhbmdlKFwiZm9ybXNMaXN0XCIpKSB7XG4gICAgICB0aGlzLmZvcm1zTGlzdCA9IHRoaXMuZmlsdGVySGlkZGVuRm9ybXModGhpcy5mb3Jtc0xpc3QpO1xuICAgICAgdGhpcy5mb3Jtc0xpc3QgPSB0aGlzLnNldEZvcm1UaXRsZXModGhpcy5mb3Jtc0xpc3QpO1xuICAgICAgdGhpcy5mb3Jtc0xpc3RMZW5ndGggPSB0aGlzLmZpbmRGb3Jtc0xpc3RMZW5ndGgodGhpcy5mb3Jtc0xpc3QpO1xuICAgICAgdGhpcy5pc0FsbEZvcm1zQ29tcGxldGVkID0gdGhpcy5jaGVja0lzQWxsRm9ybXNDb21wbGV0ZWQodGhpcy5mb3Jtc0xpc3QpO1xuICAgIH1cbiAgICBpZiAodmVyaWZ5Q2hhbmdlKFwiaXNNb2JpbGVWaWV3XCIpKSB7XG4gICAgICB0aGlzLmlzTW9iaWxlVmlldyA9IGNoYW5nZXMuaXNNb2JpbGVWaWV3LmN1cnJlbnRWYWx1ZTtcblxuICAgICAgaWYgKCF0aGlzLmlzTW9iaWxlVmlldykge1xuICAgICAgICB0aGlzLnNldFNlbGVjdGVkRm9ybShcIlwiKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHZlcmlmeUNoYW5nZShcImFjdGl2ZUZvcm1Db25maWdcIikpIHtcbiAgICAgIHRoaXMuYWN0aXZlRm9ybUNvbmZpZyA9IGNoYW5nZXMuYWN0aXZlRm9ybUNvbmZpZy5jdXJyZW50VmFsdWU7XG5cbiAgICAgIHRoaXMuc2V0U2VsZWN0ZWRGb3JtKHRoaXMuYWN0aXZlRm9ybUNvbmZpZz8ua2V5ID8/IFwiXCIpO1xuICAgIH1cbiAgfVxuXG4gIEBsb2dNZXRob2RcbiAgdHJpZ2dlckxvZ3MoZXZlbnRUeXBlOiBFTG9nRXZlbnRUeXBlLCBsb2dzOiBhbnkpIHtcbiAgICB0aGlzLmdldExvZ3MuZW1pdChmb3JtYXRFdmVudExvZ3MoZXZlbnRUeXBlLCB0aGlzLnN0ZXBDb25maWcsIGxvZ3MpKTtcbiAgfVxuXG4gIEBsb2dNZXRob2RcbiAgZm9ybWF0U3RlcENvbmZpZyhzdGVwQ29uZmlnOiBhbnkpOiBhbnkge1xuICAgIGxldCBzdGVwQ29uZmlnUHJvcGVydGllcyA9IHtcbiAgICAgIGZvcm1MaXN0UHJvcGVydGllczoge1xuICAgICAgICBmb290ZXI6IHtcbiAgICAgICAgICBzdWJtaXRGb3JtQnV0dG9uOiB7XG4gICAgICAgICAgICBoaWRkZW46IGZhbHNlLFxuICAgICAgICAgICAgbGFiZWw6IFwiU3VibWl0XCJcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgaWYgKGlzTnVsbChzdGVwQ29uZmlnKSB8fCBpc1VuZGVmaW5lZChzdGVwQ29uZmlnKSkge1xuICAgICAgc3RlcENvbmZpZyA9IHNldFZhbHVlVG9PYmplY3RQYXRoKHt9LCBcInByb3BzXCIsIHN0ZXBDb25maWdQcm9wZXJ0aWVzKTtcbiAgICB9IGVsc2UgaWYgKGNoZWNrT2JqZWN0S2V5RXhpc3RzKHN0ZXBDb25maWcsIFwicHJvcHNcIikpIHtcbiAgICAgIHN0ZXBDb25maWdQcm9wZXJ0aWVzID0gbWVyZ2VPYmplY3RzKFxuICAgICAgICBzdGVwQ29uZmlnUHJvcGVydGllcyxcbiAgICAgICAgc3RlcENvbmZpZy5wcm9wc1xuICAgICAgKTtcblxuICAgICAgc3RlcENvbmZpZyA9IHNldFZhbHVlVG9PYmplY3RQYXRoKFxuICAgICAgICBzdGVwQ29uZmlnLFxuICAgICAgICBcInByb3BzXCIsXG4gICAgICAgIHN0ZXBDb25maWdQcm9wZXJ0aWVzXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdGVwQ29uZmlnID0gc2V0VmFsdWVUb09iamVjdFBhdGgoXG4gICAgICAgIHN0ZXBDb25maWcsXG4gICAgICAgIFwicHJvcHNcIixcbiAgICAgICAgc3RlcENvbmZpZ1Byb3BlcnRpZXNcbiAgICAgICk7XG4gICAgfVxuXG4gICAgc3RlcENvbmZpZy5wcm9wcy5mb3JtTGlzdFByb3BlcnRpZXMuZm9vdGVyLnN1Ym1pdEZvcm1CdXR0b24ubGFiZWwgPVxuICAgICAgdXBkYXRlTGFuZ3VhZ2UoXG4gICAgICAgIHN0ZXBDb25maWcucHJvcHMuZm9ybUxpc3RQcm9wZXJ0aWVzLmZvb3Rlci5zdWJtaXRGb3JtQnV0dG9uLmxhYmVsLFxuICAgICAgICBnZXRMYW5ndWFnZSgpXG4gICAgICApO1xuXG4gICAgcmV0dXJuIHN0ZXBDb25maWc7XG4gIH1cblxuICBAbG9nTWV0aG9kXG4gIGZpbHRlckhpZGRlbkZvcm1zKGZvcm1zTGlzdDogYW55W10pOiBhbnlbXSB7XG4gICAgcmV0dXJuIGZvcm1zTGlzdC5maWx0ZXIoKGZvcm0pID0+IHtcbiAgICAgIGlmIChjaGVja09iamVjdEtleUV4aXN0cyhmb3JtLCBcImhpZGRlblwiKSkge1xuICAgICAgICByZXR1cm4gIWZvcm0uaGlkZGVuO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0pO1xuICB9XG5cbiAgQGxvZ01ldGhvZFxuICBzZXRGb3JtVGl0bGVzKGZvcm1zTGlzdDogYW55W10pOiBhbnlbXSB7XG4gICAgcmV0dXJuIGZvcm1zTGlzdFxuICAgICAgLm1hcCgoZm9ybSkgPT4ge1xuICAgICAgICBpZiAoZm9ybS50eXBlID09PSBFRm9ybVR5cGUuSFRNTCkge1xuICAgICAgICAgIHJldHVybiBmb3JtOyAvLyBObyBtb2RpZmljYXRpb24sIGp1c3QgcmV0dXJuXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNoZWNrT2JqZWN0UGF0aEV4aXN0cyhmb3JtLCBcInByb3BzLnRpdGxlXCIpKSB7XG4gICAgICAgICAgZm9ybS5wcm9wcy50aXRsZSA9IHVwZGF0ZUxhbmd1YWdlKGZvcm0ucHJvcHMudGl0bGUsIGdldExhbmd1YWdlKCkpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmb3JtOyAvLyBSZXR1cm4gdGhlIGZvcm0gcmVnYXJkbGVzcyBvZiBtb2RpZmljYXRpb25cbiAgICAgIH0pXG4gICAgICAuZmlsdGVyKFxuICAgICAgICAoZm9ybSkgPT5cbiAgICAgICAgICBmb3JtLnR5cGUgPT09IEVGb3JtVHlwZS5IVE1MIHx8XG4gICAgICAgICAgY2hlY2tPYmplY3RQYXRoRXhpc3RzKGZvcm0sIFwicHJvcHMudGl0bGVcIilcbiAgICAgICk7XG4gIH1cblxuICBAbG9nTWV0aG9kXG4gIGZpbmRGb3Jtc0xpc3RMZW5ndGgoZm9ybXNMaXN0OiBhbnlbXSk6IG51bWJlciB7XG4gICAgcmV0dXJuIGZvcm1zTGlzdC5maWx0ZXIoKGZvcm0pID0+IHtcbiAgICAgIGlmIChjaGVja09iamVjdEtleUV4aXN0cyhmb3JtLCBcInR5cGVcIikpIHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICBmb3JtLnR5cGUgIT09IEVGb3JtVHlwZS5IVE1MICYmXG4gICAgICAgICAgY2hlY2tPYmplY3RLZXlFeGlzdHMoZm9ybSwgXCJoaWRkZW5cIikgJiZcbiAgICAgICAgICAhZm9ybS5oaWRkZW5cbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBjaGVja09iamVjdEtleUV4aXN0cyhmb3JtLCBcImhpZGRlblwiKSAmJiAhZm9ybS5oaWRkZW47XG4gICAgfSkubGVuZ3RoO1xuICB9XG5cbiAgQGxvZ01ldGhvZFxuICBjaGVja0lzQWxsRm9ybXNDb21wbGV0ZWQoZm9ybXNMaXN0OiBhbnlbXSk6IGJvb2xlYW4ge1xuICAgIGxldCBpc0FsbEZvcm1zQ29tcGxldGVkID0gdHJ1ZTtcblxuICAgIGZvciAoY29uc3QgZm9ybSBvZiBmb3Jtc0xpc3QpIHtcbiAgICAgIGlmIChjaGVja09iamVjdEtleUV4aXN0cyhmb3JtLCBcInR5cGVcIikpIHtcbiAgICAgICAgaWYgKGZvcm0udHlwZSAhPT0gRUZvcm1UeXBlLkhUTUwpIHtcbiAgICAgICAgICBpZiAoZm9ybS5zdGF0dXMgIT09IFwiY29tcGxldGVkXCIpIHtcbiAgICAgICAgICAgIGlzQWxsRm9ybXNDb21wbGV0ZWQgPSBmYWxzZTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBpc0FsbEZvcm1zQ29tcGxldGVkO1xuICB9XG5cbiAgQGxvZ01ldGhvZFxuICBoYW5kbGVPbkNsaWNrU2V0QWN0aXZlRm9ybShzZWxlY3RlZEZvcm06IHN0cmluZykge1xuICAgIGlmIChcbiAgICAgIHRoaXMuaXNNb2JpbGVWaWV3IHx8XG4gICAgICAoIXRoaXMuaXNNb2JpbGVWaWV3ICYmIHRoaXMuc2VsZWN0ZWRGb3JtICE9PSBzZWxlY3RlZEZvcm0pIHx8XG4gICAgICAodGhpcy5pc0FsbEZvcm1zQ29tcGxldGVkICYmICF0aGlzLnNob3dGb3JtRmllbGRzKVxuICAgICkge1xuICAgICAgaWYgKFxuICAgICAgICB0aGlzLmFjdGl2ZUZvcm1Db25maWc/LnByb3BlcnRpZXM/LmlzVW5zYXZlZERhdGFBbGVydEVuYWJsZWQgJiZcbiAgICAgICAgdGhpcy5pc1Vuc2F2ZWREYXRhICYmXG4gICAgICAgICF3aW5kb3cuY29uZmlybShcIllvdSBoYXZlIHVuc2F2ZWQgZGF0YS4gUHJvY2VlZD9cIilcbiAgICAgICkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICB0aGlzLnRyaWdnZXJMb2dzKEVMb2dFdmVudFR5cGUuRk9STV9fRk9STV9PUEVOX0JVVFRPTl9DTElDSywge1xuICAgICAgICBmb3JtX2tleTogc2VsZWN0ZWRGb3JtLFxuICAgICAgICBmb3JtX2xhYmVsOlxuICAgICAgICAgIHRoaXMuYWN0aXZlRm9ybUNvbmZpZz8udGl0bGUgPz8gdGhpcy5hY3RpdmVGb3JtQ29uZmlnPy5wcm9wcz8udGl0bGVcbiAgICAgIH0pO1xuXG4gICAgICB0aGlzLnNlbGVjdGVkRm9ybSA9IHNlbGVjdGVkRm9ybTtcbiAgICAgIHRoaXMub25DbGlja1NldEFjdGl2ZUZvcm0uZW1pdChzZWxlY3RlZEZvcm0pO1xuICAgIH1cbiAgfVxuXG4gIEBsb2dNZXRob2RcbiAgaGFuZGxlT25TdWJtaXRGb3JtcyhlOiBhbnkpIHtcbiAgICAvKipcbiAgICAgKiBQT1NUIEFDVElPTlNcbiAgICAgKiAxLiBBUEkgQ2FsbHMuXG4gICAgICogMi4gUHJldmlldyBvZiBhbGwgZmlsbGVkIGRhdGEuXG4gICAgICogMy4gVVJMIFJlZGlyZWN0aW9uIG9yIG5ldyBvcGVuaW5nIG9mIFVSTCBpbiBleHRlcm5hbCB0YWIuXG4gICAgICovXG5cbiAgICB0aGlzLm9uQ2xpY2tTdWJtaXRGb3Jtcy5lbWl0KGUpO1xuICB9XG59XG4iLCI8ZGl2XG4gIGlkPVwic2lkZWJhci1jb250YWluZXJcIlxuICAqbmdJZj1cIiFsb2FkaW5nXCJcbj5cbiAgPGRpdiBpZD1cInNpZGViYXJcIj5cbiAgICA8ZGl2IG5nQ2xhc3M9XCJrd2lraWQtZm9ybS1oZWFkZXJcIj5cbiAgICAgIDxkaXYgaWQ9XCJ1Zi1oZWFkZXJcIj5cbiAgICAgICAgPGRpdiBpZD1cInVmLWhlYWRlci1sb2dvLWNvbnRhaW5lclwiPlxuICAgICAgICAgIDxpbWdcbiAgICAgICAgICAgIGlkPVwidWYtaGVhZGVyLWxvZ29cIlxuICAgICAgICAgICAgc3JjPVwie3sgdGhpcy51c2VyQ29uZmlnLnRoZW1lLmNsaWVudExvZ28gfX1cIlxuICAgICAgICAgICAgW25nQ2xhc3NdPVwiJ2xhcmdlLWljb24nXCJcbiAgICAgICAgICAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgICAgPGhyIC8+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBpZD1cInVmLXByb2dyZXNzXCI+XG4gICAgICA8ZGl2IGlkPVwidWYtcHJvZ3Jlc3Mtc3RlcHNcIj5cbiAgICAgICAge3sgdGhpcy5mb3Jtc0xpc3RDb21wbGV0ZWQubGVuZ3RoIH19IC8ge3sgdGhpcy5mb3Jtc0xpc3RMZW5ndGggfX0gU3RlcHNcbiAgICAgICAgQ29tcGxldGVkXG4gICAgICA8L2Rpdj5cbiAgICAgIDxrd2lrdWktcHJvZ3Jlc3Mtc2VnbWVudGVkXG4gICAgICAgIFttYXhdPVwidGhpcy5mb3Jtc0xpc3RMZW5ndGhcIlxuICAgICAgICBzaXplPVwibVwiXG4gICAgICAgIFt2YWx1ZV09XCJ0aGlzLmZvcm1zTGlzdENvbXBsZXRlZC5sZW5ndGhcIlxuICAgICAgPjwva3dpa3VpLXByb2dyZXNzLXNlZ21lbnRlZD5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGlkPVwidWYtc2VjdGlvbnMtY29udGFpbmVyXCI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBmb3JtIG9mIGZvcm1zTGlzdDsgbGV0IGkgPSBpbmRleFwiPlxuICAgICAgICA8bmctY29udGFpbmVyIFtuZ1N3aXRjaF09XCJmb3JtLnR5cGVcIj5cbiAgICAgICAgICA8IS0tIEhUTUwgQ29udGVudCAtLT5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInSFRNTCdcIj5cbiAgICAgICAgICAgIDxkaXYgW2lubmVySHRtbF09XCJmb3JtLnByb3BzLmh0bWxDb250ZW50IHwga3dpa3VpU2FmZUh0bWxcIj48L2Rpdj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8IS0tIFR5cGUgRk9STSAtLT5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ1N3aXRjaENhc2U9XCInRk9STSdcIj5cbiAgICAgICAgICAgIDxuZy1jb250YWluZXJcbiAgICAgICAgICAgICAgW25nVGVtcGxhdGVPdXRsZXRdPVwiRk9STV9CVVRUT05cIlxuICAgICAgICAgICAgICBbbmdUZW1wbGF0ZU91dGxldENvbnRleHRdPVwie1xuICAgICAgICAgICAgICAgIGZvcm06IGZvcm0sXG4gICAgICAgICAgICAgICAgYWN0aXZlRm9ybUNvbmZpZzogYWN0aXZlRm9ybUNvbmZpZ1xuICAgICAgICAgICAgICB9XCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgaWQ9XCJzdWJtaXQtc2lkZWJhci1idG4tY29udGFpbmVyXCI+XG4gICAgICA8a3dpa3VpLWJ1dHRvblxuICAgICAgICAqbmdJZj1cIlxuICAgICAgICAgICFzdGVwQ29uZmlnLnByb3BzLmZvcm1MaXN0UHJvcGVydGllcy5mb290ZXIuc3VibWl0Rm9ybUJ1dHRvbi5oaWRkZW5cbiAgICAgICAgXCJcbiAgICAgICAgbGFiZWw9XCJ7e1xuICAgICAgICAgIHN0ZXBDb25maWcucHJvcHMuZm9ybUxpc3RQcm9wZXJ0aWVzLmZvb3Rlci5zdWJtaXRGb3JtQnV0dG9uLmxhYmVsXG4gICAgICAgIH19XCJcbiAgICAgICAgdHlwZT1cInN1Ym1pdFwiXG4gICAgICAgIHN0eWxlcz1cIndpZHRoOiAxMDAlXCJcbiAgICAgICAgKG9uQ2xpY2spPVwiaGFuZGxlT25TdWJtaXRGb3JtcygkZXZlbnQpXCJcbiAgICAgID48L2t3aWt1aS1idXR0b24+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9kaXY+XG5cbjxuZy10ZW1wbGF0ZVxuICAjRk9STV9CVVRUT05cbiAgbGV0LWZvcm09XCJmb3JtXCJcbiAgbGV0LWFjdGl2ZUZvcm1Db25maWc9XCJhY3RpdmVGb3JtQ29uZmlnXCJcbj5cbiAgPGRpdlxuICAgIFtjbGFzc109XCIndWYtc2VjdGlvbi1pdGVtJ1wiXG4gICAgW2NsYXNzLmNvbXBsZXRlZF09XCJmb3JtLnN0YXR1cyA9PT0gJ2NvbXBsZXRlZCcgJiYgIWZvcm0uZGlzYWJsZWRcIlxuICAgIFtjbGFzcy5lZGl0XT1cImZvcm0uc3RhdHVzID09PSAnZWRpdGFibGUnICYmICFmb3JtLmRpc2FibGVkXCJcbiAgICBbY2xhc3MubG9ja2VkXT1cImZvcm0uc3RhdHVzID09PSAnbG9ja2VkJyAmJiBmb3JtLmRpc2FibGVkXCJcbiAgICBbY2xhc3MuYWN0aXZlXT1cIlxuICAgICAgYWN0aXZlRm9ybUNvbmZpZyAhPT0gdW5kZWZpbmVkICYmIGZvcm0ua2V5ID09PSBhY3RpdmVGb3JtQ29uZmlnLmtleVxuICAgIFwiXG4gICAgKGNsaWNrKT1cIlxuICAgICAgZm9ybS5zdGF0dXMgPT09ICdsb2NrZWQnICYmIGZvcm0uZGlzYWJsZWRcbiAgICAgICAgPyB1bmRlZmluZWRcbiAgICAgICAgOiBoYW5kbGVPbkNsaWNrU2V0QWN0aXZlRm9ybShmb3JtLmtleSlcbiAgICBcIlxuICA+XG4gICAgPGRpdiBjbGFzcz1cInVmLWZvcm0tc2VjdGlvbi1jYXJkLXRpdGxlXCI+XG4gICAgICB7eyBmb3JtLnByb3BzLnRpdGxlIH19Jm5ic3A7PHNwYW4gKm5nSWY9XCJmb3JtPy5yZXF1aXJlZFwiPio8L3NwYW4+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cInVmLWZvcm0tc2VjdGlvbi1jYXJkLXN0YXR1c1wiPlxuICAgICAgPGRpdlxuICAgICAgICAqbmdJZj1cImZvcm0uc3RhdHVzID09PSAnY29tcGxldGVkJyAmJiAhZm9ybS5kaXNhYmxlZFwiXG4gICAgICAgIGNsYXNzPVwidWYtZm9ybS1zZWN0aW9uLWNhcmQtc3RhdHVzLWltZyBjb21wbGV0ZWRcIlxuICAgICAgPlxuICAgICAgICA8dHVpLXN2ZyBzcmM9XCJ0dWlJY29uQ2hlY2tMYXJnZVwiPjwvdHVpLXN2Zz5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdlxuICAgICAgICAqbmdJZj1cImZvcm0uc3RhdHVzICE9PSAnY29tcGxldGVkJyAmJiAhZm9ybS5kaXNhYmxlZFwiXG4gICAgICAgIGNsYXNzPVwidWYtZm9ybS1zZWN0aW9uLWNhcmQtc3RhdHVzLWltZyBlZGl0XCJcbiAgICAgID5cbiAgICAgICAgPHR1aS1zdmcgc3JjPVwidHVpSWNvbkVkaXRcIj48L3R1aS1zdmc+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXZcbiAgICAgICAgKm5nSWY9XCJmb3JtLnN0YXR1cyAhPT0gJ2NvbXBsZXRlZCcgJiYgZm9ybS5kaXNhYmxlZFwiXG4gICAgICAgIGNsYXNzPVwidWYtZm9ybS1zZWN0aW9uLWNhcmQtc3RhdHVzLWltZyBsb2NrZWRcIlxuICAgICAgPlxuICAgICAgICA8dHVpLXN2ZyBzcmM9XCJ0dWlJY29uTG9ja1wiPjwvdHVpLXN2Zz5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvbmctdGVtcGxhdGU+XG4iXX0=