tango-app-ui-store-builder 1.2.16 → 1.2.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/esm2022/lib/components/plano-configurations/plano-configurations.component.mjs +18 -7
  2. package/esm2022/lib/components/plano-tools/allow-edit/allow-edit.component.mjs +4 -3
  3. package/esm2022/lib/components/plano-tools/cad-files/cad-files.component.mjs +5 -4
  4. package/esm2022/lib/components/plano-tools/cad-render/cad-render.component.mjs +4 -3
  5. package/esm2022/lib/components/plano-tools/delete-floor/delete-floor.component.mjs +4 -3
  6. package/esm2022/lib/components/plano-tools/delete-task/delete-task.component.mjs +4 -3
  7. package/esm2022/lib/components/plano-tools/layout-touchup/layout-touchup.component.mjs +134 -0
  8. package/esm2022/lib/components/plano-tools/layout-touchup/touchup-editor/touchup-editor.component.mjs +5103 -0
  9. package/esm2022/lib/components/plano-tools/modify-fixture-numbers/modify-fixture-numbers.component.mjs +4 -3
  10. package/esm2022/lib/components/plano-tools/move-bucket/move-bucket.component.mjs +4 -3
  11. package/esm2022/lib/components/plano-tools/plano-data-export/plano-data-export.component.mjs +4 -3
  12. package/esm2022/lib/components/plano-tools/plano-migrate/plano-migrate.component.mjs +4 -3
  13. package/esm2022/lib/components/plano-tools/store-exports/store-exports.component.mjs +4 -3
  14. package/esm2022/lib/components/plano-tools/swap-template/swap-template.component.mjs +4 -3
  15. package/esm2022/lib/components/plano-tools/tool-page-header/tool-page-header.component.mjs +22 -0
  16. package/esm2022/lib/components/plano-tools/tools-parent/tools-parent.component.mjs +27 -8
  17. package/esm2022/lib/services/store-builder.service.mjs +10 -1
  18. package/esm2022/lib/tango-store-builder-routing.module.mjs +25 -55
  19. package/esm2022/lib/tango-store-builder.module.mjs +10 -1
  20. package/fesm2022/tango-app-ui-store-builder.mjs +5620 -390
  21. package/fesm2022/tango-app-ui-store-builder.mjs.map +1 -1
  22. package/lib/components/manage-plano/rollout-table/rollout-table.component.d.ts +4 -4
  23. package/lib/components/manage-plano/verification-table/verification-table.component.d.ts +5 -5
  24. package/lib/components/plano-configurations/plano-configurations.component.d.ts +9 -1
  25. package/lib/components/plano-tools/layout-touchup/layout-touchup.component.d.ts +50 -0
  26. package/lib/components/plano-tools/layout-touchup/touchup-editor/touchup-editor.component.d.ts +331 -0
  27. package/lib/components/plano-tools/tool-page-header/tool-page-header.component.d.ts +8 -0
  28. package/lib/components/plano-tools/tools-parent/tools-parent.component.d.ts +4 -2
  29. package/lib/services/store-builder.service.d.ts +10 -0
  30. package/lib/tango-store-builder.module.d.ts +61 -58
  31. package/package.json +1 -1
@@ -7,6 +7,7 @@ import * as i3 from "@angular/forms";
7
7
  import * as i4 from "tango-app-ui-shared";
8
8
  import * as i5 from "@ng-bootstrap/ng-bootstrap";
9
9
  import * as i6 from "../../collection-update-ai/components/store-select/store-select.component";
10
+ import * as i7 from "../tool-page-header/tool-page-header.component";
10
11
  const OUTPUT_COLUMN_ORDER = [
11
12
  { key: 'storeName', label: 'Store Name' },
12
13
  { key: 'fixtureCategory', label: 'Fixture Category' },
@@ -369,10 +370,10 @@ export class PlanoDataExportComponent {
369
370
  this.destroy$.complete();
370
371
  }
371
372
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PlanoDataExportComponent, deps: [{ token: i1.StoreBuilderService }, { token: i2.GlobalStateService }], target: i0.ɵɵFactoryTarget.Component });
372
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: PlanoDataExportComponent, selector: "lib-plano-data-export", ngImport: i0, template: "<section class=\"plano-data-export p-3\">\r\n <div class=\"card p-4 mb-3\">\r\n <h5 class=\"mb-1\">Plano Data Export</h5>\r\n <p class=\"text-muted small mb-3\">\r\n Build a query against planogram fixtures, preview results, and export as Excel.\r\n </p>\r\n\r\n @if (isLoadingSchema) {\r\n <div class=\"text-muted small\">Loading query schema...</div>\r\n }\r\n\r\n <!-- Stores -->\r\n <div class=\"block mb-3\">\r\n <div class=\"block-title\">Stores</div>\r\n <lib-store-select\r\n [options]=\"storeOptions\"\r\n [initialSelected]=\"initialStores\"\r\n (selectedChange)=\"onStoresSelected($event)\">\r\n </lib-store-select>\r\n </div>\r\n\r\n <!-- Match Criteria -->\r\n <div class=\"block mb-3\">\r\n <div class=\"d-flex align-items-center justify-content-between mb-2\">\r\n <div class=\"block-title mb-0\">Match Criteria</div>\r\n <div class=\"d-flex align-items-center gap-3\">\r\n <div class=\"form-check form-check-inline mb-0\">\r\n <input class=\"form-check-input\" type=\"radio\" id=\"combAnd\"\r\n name=\"combinator\" value=\"AND\" [(ngModel)]=\"filterCombinator\">\r\n <label class=\"form-check-label\" for=\"combAnd\">Match all (AND)</label>\r\n </div>\r\n <div class=\"form-check form-check-inline mb-0\">\r\n <input class=\"form-check-input\" type=\"radio\" id=\"combOr\"\r\n name=\"combinator\" value=\"OR\" [(ngModel)]=\"filterCombinator\">\r\n <label class=\"form-check-label\" for=\"combOr\">Match any (OR)</label>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n @if (!filters.length) {\r\n <div class=\"text-muted small mb-2\">\r\n No criteria \u2014 query will return every fixture for the selected stores.\r\n </div>\r\n }\r\n\r\n @for (row of filters; track $index) {\r\n <div class=\"filter-row d-flex gap-2 mb-2 align-items-center\">\r\n <select class=\"form-select form-select-sm filter-field\"\r\n [(ngModel)]=\"row.field\"\r\n (change)=\"onFilterFieldChange($index)\">\r\n @for (f of filterableFields; track f.key) {\r\n <option [value]=\"f.key\">{{ f.label }}</option>\r\n }\r\n </select>\r\n\r\n <select class=\"form-select form-select-sm filter-op\"\r\n [(ngModel)]=\"row.operator\">\r\n @for (op of operatorsForField(row.field); track op.key) {\r\n <option [value]=\"op.key\">{{ op.label }}</option>\r\n }\r\n </select>\r\n\r\n <input\r\n class=\"form-control form-control-sm filter-value\"\r\n [placeholder]=\"isValueDisabledFor(row.operator) ? '\u2014' : 'value'\"\r\n [disabled]=\"isValueDisabledFor(row.operator)\"\r\n [(ngModel)]=\"row.value\">\r\n\r\n <button class=\"btn btn-sm btn-outline-danger\" (click)=\"removeFilter($index)\"\r\n title=\"Remove\">\u00D7</button>\r\n </div>\r\n }\r\n\r\n <button class=\"btn btn-sm btn-outline-primary\" (click)=\"addFilter()\"\r\n [disabled]=\"!filterableFields.length\">\r\n + Add Criterion\r\n </button>\r\n </div>\r\n\r\n <!-- Selection Mode -->\r\n <div class=\"block mb-3\">\r\n <div class=\"block-title\">Fixture Selection</div>\r\n <div class=\"d-flex flex-wrap align-items-center gap-3\">\r\n <div class=\"form-check mb-0\">\r\n <input class=\"form-check-input\" type=\"radio\" id=\"selAll\"\r\n name=\"selectionMode\" value=\"all\" [(ngModel)]=\"selectionMode\">\r\n <label class=\"form-check-label\" for=\"selAll\">All matching fixtures</label>\r\n </div>\r\n <div class=\"form-check mb-0\">\r\n <input class=\"form-check-input\" type=\"radio\" id=\"selFirstN\"\r\n name=\"selectionMode\" value=\"firstN\" [(ngModel)]=\"selectionMode\">\r\n <label class=\"form-check-label\" for=\"selFirstN\">First</label>\r\n </div>\r\n <input\r\n type=\"number\"\r\n min=\"1\"\r\n class=\"form-control form-control-sm count-input\"\r\n [(ngModel)]=\"limitPerStore\"\r\n [disabled]=\"selectionMode !== 'firstN'\">\r\n <span class=\"text-muted small\">matching from entrance, per store</span>\r\n </div>\r\n\r\n <div class=\"form-check mt-2\">\r\n <input class=\"form-check-input\" type=\"checkbox\" id=\"incNotFound\"\r\n [(ngModel)]=\"includeNotFoundRows\">\r\n <label class=\"form-check-label\" for=\"incNotFound\">\r\n Include empty rows for stores with no matches\r\n </label>\r\n </div>\r\n </div>\r\n\r\n <!-- Output Columns -->\r\n <div class=\"block mb-3\">\r\n <div class=\"d-flex align-items-center justify-content-between mb-2\">\r\n <div class=\"block-title mb-0\">Output Columns</div>\r\n <div class=\"d-flex gap-2\">\r\n <button class=\"btn btn-sm btn-link p-0\" (click)=\"selectAllColumns()\">\r\n Select all\r\n </button>\r\n <button class=\"btn btn-sm btn-link p-0\" (click)=\"clearAllColumns()\">\r\n Clear\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"column-grid\">\r\n @for (col of outputColumns; track col.key) {\r\n <label class=\"column-item\">\r\n <input type=\"checkbox\" class=\"form-check-input me-2\"\r\n [(ngModel)]=\"col.selected\">\r\n {{ col.label }}\r\n </label>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Action Buttons -->\r\n <div class=\"d-flex gap-2\">\r\n <button\r\n class=\"btn btn-primary\"\r\n (click)=\"onRun()\"\r\n [disabled]=\"isRunning || isLoadingSchema || selectedStores.length === 0\">\r\n {{ isRunning ? 'Running...' : 'Run Query' }}\r\n </button>\r\n <button\r\n class=\"btn btn-success\"\r\n (click)=\"onExport()\"\r\n [disabled]=\"!result || !result.rows.length\">\r\n Export to Excel\r\n </button>\r\n </div>\r\n\r\n @if (message) {\r\n <div\r\n class=\"mt-3 alert\"\r\n [class.alert-success]=\"messageType === 'success'\"\r\n [class.alert-danger]=\"messageType === 'error'\">\r\n {{ message }}\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- VM Placement Export by VM Name -->\r\n <div class=\"card p-4 mb-3\">\r\n <h5 class=\"mb-1\">VM Placement Export by VM Name</h5>\r\n <p class=\"text-muted small mb-3\">\r\n Find every fixture (in the selected stores) that contains any VM whose\r\n <code>vmName</code> matches the regex, and export one row per VM placement\r\n with fixture details and shelf/zone coordinates.\r\n </p>\r\n\r\n <div class=\"block mb-3\">\r\n <div class=\"block-title\">Stores</div>\r\n <lib-store-select\r\n [options]=\"storeOptions\"\r\n [initialSelected]=\"vmInitialStores\"\r\n (selectedChange)=\"onVmStoresSelected($event)\">\r\n </lib-store-select>\r\n </div>\r\n\r\n <div class=\"block mb-3\">\r\n <div class=\"block-title\">VM Name (regex)</div>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"e.g. Zodiac, ^Hiphop, Leatherite\"\r\n [(ngModel)]=\"vmNameRegex\">\r\n <small class=\"text-muted\">Case-insensitive. Matched against the <code>planoVmDetails.vmName</code> field.</small>\r\n </div>\r\n\r\n <div class=\"d-flex gap-2\">\r\n <button\r\n class=\"btn btn-primary\"\r\n (click)=\"onVmRun()\"\r\n [disabled]=\"isVmRunning || vmSelectedStores.length === 0 || !vmNameRegex.trim()\">\r\n {{ isVmRunning ? 'Running...' : 'Run Query' }}\r\n </button>\r\n <button\r\n class=\"btn btn-success\"\r\n (click)=\"onVmExport()\"\r\n [disabled]=\"!vmResult || !vmResult.rows.length\">\r\n Export to Excel\r\n </button>\r\n </div>\r\n\r\n @if (vmMessage) {\r\n <div\r\n class=\"mt-3 alert\"\r\n [class.alert-success]=\"vmMessageType === 'success'\"\r\n [class.alert-danger]=\"vmMessageType === 'error'\">\r\n {{ vmMessage }}\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (vmResult) {\r\n <div class=\"card p-4 mb-3\">\r\n <div class=\"d-flex align-items-center justify-content-between mb-3\">\r\n <div>\r\n <h6 class=\"mb-0\">VM Placement Results</h6>\r\n <small class=\"text-muted\">\r\n {{ vmTotalRows }} row(s)\r\n @if (vmTotalRows) {\r\n \u00B7 showing {{ vmPageStart }}\u2013{{ vmPageEnd }}\r\n }\r\n </small>\r\n </div>\r\n </div>\r\n\r\n @if (!vmResult.rows.length) {\r\n <div class=\"text-muted\">No VM placements found for the given stores and vmName.</div>\r\n } @else {\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-sm table-bordered\">\r\n <thead>\r\n <tr>\r\n @for (col of vmResultColumns; track col) {\r\n <th>{{ col }}</th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (row of vmPagedRows; track $index) {\r\n <tr>\r\n @for (col of vmResultColumns; track col) {\r\n <td\r\n [ngbTooltip]=\"row[col]?.toString() ? row[col] : null\"\r\n container=\"body\"\r\n placement=\"top\"\r\n [openDelay]=\"300\">\r\n {{ row[col] }}\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <lib-pagination\r\n [itemsPerPage]=\"vmPageSize\"\r\n [currentPage]=\"vmCurrentPage\"\r\n [totalItems]=\"vmTotalRows\"\r\n [pageSize]=\"vmPageSize\"\r\n [paginationSizes]=\"paginationSizes\"\r\n [directionLinks]=\"true\"\r\n (pageChange)=\"onVmPageChange($event)\"\r\n (pageSizeChange)=\"onVmPageSizeChange($event)\">\r\n </lib-pagination>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Result Preview -->\r\n @if (result) {\r\n <div class=\"card p-4\">\r\n <div class=\"d-flex align-items-center justify-content-between mb-3\">\r\n <div>\r\n <h6 class=\"mb-0\">Results</h6>\r\n <small class=\"text-muted\">\r\n {{ totalRows }} row(s)\r\n @if (totalRows) {\r\n \u00B7 showing {{ pageStart }}\u2013{{ pageEnd }}\r\n }\r\n </small>\r\n </div>\r\n </div>\r\n\r\n @if (!result.rows.length) {\r\n <div class=\"text-muted\">No data found for the given query.</div>\r\n } @else {\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-sm table-bordered\">\r\n <thead>\r\n <tr>\r\n @for (col of resultColumns; track col.key) {\r\n <th>{{ col.label }}</th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (row of pagedRows; track $index) {\r\n <tr [class.row-not-found]=\"row['__notFound']\">\r\n @for (col of resultColumns; track col.key) {\r\n <td\r\n [ngbTooltip]=\"row[col.label]?.toString() ? row[col.label] : null\"\r\n container=\"body\"\r\n placement=\"top\"\r\n [openDelay]=\"300\">\r\n {{ row[col.label] }}\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <lib-pagination\r\n [itemsPerPage]=\"pageSize\"\r\n [currentPage]=\"currentPage\"\r\n [totalItems]=\"totalRows\"\r\n [pageSize]=\"pageSize\"\r\n [paginationSizes]=\"paginationSizes\"\r\n [directionLinks]=\"true\"\r\n (pageChange)=\"onPageChange($event)\"\r\n (pageSizeChange)=\"onPageSizeChange($event)\">\r\n </lib-pagination>\r\n }\r\n </div>\r\n }\r\n</section>\r\n", styles: [".plano-data-export .card{border:1px solid #e0e0e0}.plano-data-export .block{border:1px solid #e9ecef;border-radius:6px;padding:12px 14px;background:#fafbfc}.plano-data-export .block-title{font-weight:600;font-size:.95rem;color:#344054}.plano-data-export .filter-row .filter-field{flex:0 0 220px}.plano-data-export .filter-row .filter-op{flex:0 0 200px}.plano-data-export .filter-row .filter-value{flex:1 1 auto;min-width:120px}.plano-data-export .count-input{width:80px}.plano-data-export .column-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:6px 14px}.plano-data-export .column-item{display:flex;align-items:center;cursor:pointer;-webkit-user-select:none;user-select:none;font-size:.92rem;margin-bottom:0}.plano-data-export .table th{white-space:nowrap;background:#f8f9fa;position:sticky;top:0;z-index:1}.plano-data-export .table td{max-width:240px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:default}.plano-data-export .row-not-found td{color:#98a2b3;font-style:italic}.plano-data-export .table-responsive{max-height:480px;overflow:auto}\n"], dependencies: [{ kind: "directive", type: i3.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.PaginationComponent, selector: "lib-pagination", inputs: ["collection", "itemsPerPage", "currentPage", "totalItems", "directionLinks", "pageSize", "paginationSizes"], outputs: ["pageChange", "pageSizeChange"] }, { kind: "directive", type: i5.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "tooltipContext", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }, { kind: "component", type: i6.StoreSelectComponent, selector: "lib-store-select", inputs: ["options", "initialSelected", "singleSelect"], outputs: ["selectedChange"] }] });
373
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.3.12", type: PlanoDataExportComponent, selector: "lib-plano-data-export", ngImport: i0, template: "<section class=\"plano-data-export p-3\">\r\n <lib-tool-page-header\r\n title=\"Data Export\"\r\n description=\"Build a query against planogram fixtures, preview results, and export as Excel.\"\r\n ></lib-tool-page-header>\r\n <div class=\"card p-4 mb-3\">\r\n\r\n @if (isLoadingSchema) {\r\n <div class=\"text-muted small\">Loading query schema...</div>\r\n }\r\n\r\n <!-- Stores -->\r\n <div class=\"block mb-3\">\r\n <div class=\"block-title\">Stores</div>\r\n <lib-store-select\r\n [options]=\"storeOptions\"\r\n [initialSelected]=\"initialStores\"\r\n (selectedChange)=\"onStoresSelected($event)\">\r\n </lib-store-select>\r\n </div>\r\n\r\n <!-- Match Criteria -->\r\n <div class=\"block mb-3\">\r\n <div class=\"d-flex align-items-center justify-content-between mb-2\">\r\n <div class=\"block-title mb-0\">Match Criteria</div>\r\n <div class=\"d-flex align-items-center gap-3\">\r\n <div class=\"form-check form-check-inline mb-0\">\r\n <input class=\"form-check-input\" type=\"radio\" id=\"combAnd\"\r\n name=\"combinator\" value=\"AND\" [(ngModel)]=\"filterCombinator\">\r\n <label class=\"form-check-label\" for=\"combAnd\">Match all (AND)</label>\r\n </div>\r\n <div class=\"form-check form-check-inline mb-0\">\r\n <input class=\"form-check-input\" type=\"radio\" id=\"combOr\"\r\n name=\"combinator\" value=\"OR\" [(ngModel)]=\"filterCombinator\">\r\n <label class=\"form-check-label\" for=\"combOr\">Match any (OR)</label>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n @if (!filters.length) {\r\n <div class=\"text-muted small mb-2\">\r\n No criteria \u2014 query will return every fixture for the selected stores.\r\n </div>\r\n }\r\n\r\n @for (row of filters; track $index) {\r\n <div class=\"filter-row d-flex gap-2 mb-2 align-items-center\">\r\n <select class=\"form-select form-select-sm filter-field\"\r\n [(ngModel)]=\"row.field\"\r\n (change)=\"onFilterFieldChange($index)\">\r\n @for (f of filterableFields; track f.key) {\r\n <option [value]=\"f.key\">{{ f.label }}</option>\r\n }\r\n </select>\r\n\r\n <select class=\"form-select form-select-sm filter-op\"\r\n [(ngModel)]=\"row.operator\">\r\n @for (op of operatorsForField(row.field); track op.key) {\r\n <option [value]=\"op.key\">{{ op.label }}</option>\r\n }\r\n </select>\r\n\r\n <input\r\n class=\"form-control form-control-sm filter-value\"\r\n [placeholder]=\"isValueDisabledFor(row.operator) ? '\u2014' : 'value'\"\r\n [disabled]=\"isValueDisabledFor(row.operator)\"\r\n [(ngModel)]=\"row.value\">\r\n\r\n <button class=\"btn btn-sm btn-outline-danger\" (click)=\"removeFilter($index)\"\r\n title=\"Remove\">\u00D7</button>\r\n </div>\r\n }\r\n\r\n <button class=\"btn btn-sm btn-outline-primary\" (click)=\"addFilter()\"\r\n [disabled]=\"!filterableFields.length\">\r\n + Add Criterion\r\n </button>\r\n </div>\r\n\r\n <!-- Selection Mode -->\r\n <div class=\"block mb-3\">\r\n <div class=\"block-title\">Fixture Selection</div>\r\n <div class=\"d-flex flex-wrap align-items-center gap-3\">\r\n <div class=\"form-check mb-0\">\r\n <input class=\"form-check-input\" type=\"radio\" id=\"selAll\"\r\n name=\"selectionMode\" value=\"all\" [(ngModel)]=\"selectionMode\">\r\n <label class=\"form-check-label\" for=\"selAll\">All matching fixtures</label>\r\n </div>\r\n <div class=\"form-check mb-0\">\r\n <input class=\"form-check-input\" type=\"radio\" id=\"selFirstN\"\r\n name=\"selectionMode\" value=\"firstN\" [(ngModel)]=\"selectionMode\">\r\n <label class=\"form-check-label\" for=\"selFirstN\">First</label>\r\n </div>\r\n <input\r\n type=\"number\"\r\n min=\"1\"\r\n class=\"form-control form-control-sm count-input\"\r\n [(ngModel)]=\"limitPerStore\"\r\n [disabled]=\"selectionMode !== 'firstN'\">\r\n <span class=\"text-muted small\">matching from entrance, per store</span>\r\n </div>\r\n\r\n <div class=\"form-check mt-2\">\r\n <input class=\"form-check-input\" type=\"checkbox\" id=\"incNotFound\"\r\n [(ngModel)]=\"includeNotFoundRows\">\r\n <label class=\"form-check-label\" for=\"incNotFound\">\r\n Include empty rows for stores with no matches\r\n </label>\r\n </div>\r\n </div>\r\n\r\n <!-- Output Columns -->\r\n <div class=\"block mb-3\">\r\n <div class=\"d-flex align-items-center justify-content-between mb-2\">\r\n <div class=\"block-title mb-0\">Output Columns</div>\r\n <div class=\"d-flex gap-2\">\r\n <button class=\"btn btn-sm btn-link p-0\" (click)=\"selectAllColumns()\">\r\n Select all\r\n </button>\r\n <button class=\"btn btn-sm btn-link p-0\" (click)=\"clearAllColumns()\">\r\n Clear\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"column-grid\">\r\n @for (col of outputColumns; track col.key) {\r\n <label class=\"column-item\">\r\n <input type=\"checkbox\" class=\"form-check-input me-2\"\r\n [(ngModel)]=\"col.selected\">\r\n {{ col.label }}\r\n </label>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Action Buttons -->\r\n <div class=\"d-flex gap-2\">\r\n <button\r\n class=\"btn btn-primary\"\r\n (click)=\"onRun()\"\r\n [disabled]=\"isRunning || isLoadingSchema || selectedStores.length === 0\">\r\n {{ isRunning ? 'Running...' : 'Run Query' }}\r\n </button>\r\n <button\r\n class=\"btn btn-success\"\r\n (click)=\"onExport()\"\r\n [disabled]=\"!result || !result.rows.length\">\r\n Export to Excel\r\n </button>\r\n </div>\r\n\r\n @if (message) {\r\n <div\r\n class=\"mt-3 alert\"\r\n [class.alert-success]=\"messageType === 'success'\"\r\n [class.alert-danger]=\"messageType === 'error'\">\r\n {{ message }}\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- VM Placement Export by VM Name -->\r\n <div class=\"card p-4 mb-3\">\r\n <h5 class=\"mb-1\">VM Placement Export by VM Name</h5>\r\n <p class=\"text-muted small mb-3\">\r\n Find every fixture (in the selected stores) that contains any VM whose\r\n <code>vmName</code> matches the regex, and export one row per VM placement\r\n with fixture details and shelf/zone coordinates.\r\n </p>\r\n\r\n <div class=\"block mb-3\">\r\n <div class=\"block-title\">Stores</div>\r\n <lib-store-select\r\n [options]=\"storeOptions\"\r\n [initialSelected]=\"vmInitialStores\"\r\n (selectedChange)=\"onVmStoresSelected($event)\">\r\n </lib-store-select>\r\n </div>\r\n\r\n <div class=\"block mb-3\">\r\n <div class=\"block-title\">VM Name (regex)</div>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"e.g. Zodiac, ^Hiphop, Leatherite\"\r\n [(ngModel)]=\"vmNameRegex\">\r\n <small class=\"text-muted\">Case-insensitive. Matched against the <code>planoVmDetails.vmName</code> field.</small>\r\n </div>\r\n\r\n <div class=\"d-flex gap-2\">\r\n <button\r\n class=\"btn btn-primary\"\r\n (click)=\"onVmRun()\"\r\n [disabled]=\"isVmRunning || vmSelectedStores.length === 0 || !vmNameRegex.trim()\">\r\n {{ isVmRunning ? 'Running...' : 'Run Query' }}\r\n </button>\r\n <button\r\n class=\"btn btn-success\"\r\n (click)=\"onVmExport()\"\r\n [disabled]=\"!vmResult || !vmResult.rows.length\">\r\n Export to Excel\r\n </button>\r\n </div>\r\n\r\n @if (vmMessage) {\r\n <div\r\n class=\"mt-3 alert\"\r\n [class.alert-success]=\"vmMessageType === 'success'\"\r\n [class.alert-danger]=\"vmMessageType === 'error'\">\r\n {{ vmMessage }}\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (vmResult) {\r\n <div class=\"card p-4 mb-3\">\r\n <div class=\"d-flex align-items-center justify-content-between mb-3\">\r\n <div>\r\n <h6 class=\"mb-0\">VM Placement Results</h6>\r\n <small class=\"text-muted\">\r\n {{ vmTotalRows }} row(s)\r\n @if (vmTotalRows) {\r\n \u00B7 showing {{ vmPageStart }}\u2013{{ vmPageEnd }}\r\n }\r\n </small>\r\n </div>\r\n </div>\r\n\r\n @if (!vmResult.rows.length) {\r\n <div class=\"text-muted\">No VM placements found for the given stores and vmName.</div>\r\n } @else {\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-sm table-bordered\">\r\n <thead>\r\n <tr>\r\n @for (col of vmResultColumns; track col) {\r\n <th>{{ col }}</th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (row of vmPagedRows; track $index) {\r\n <tr>\r\n @for (col of vmResultColumns; track col) {\r\n <td\r\n [ngbTooltip]=\"row[col]?.toString() ? row[col] : null\"\r\n container=\"body\"\r\n placement=\"top\"\r\n [openDelay]=\"300\">\r\n {{ row[col] }}\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <lib-pagination\r\n [itemsPerPage]=\"vmPageSize\"\r\n [currentPage]=\"vmCurrentPage\"\r\n [totalItems]=\"vmTotalRows\"\r\n [pageSize]=\"vmPageSize\"\r\n [paginationSizes]=\"paginationSizes\"\r\n [directionLinks]=\"true\"\r\n (pageChange)=\"onVmPageChange($event)\"\r\n (pageSizeChange)=\"onVmPageSizeChange($event)\">\r\n </lib-pagination>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Result Preview -->\r\n @if (result) {\r\n <div class=\"card p-4\">\r\n <div class=\"d-flex align-items-center justify-content-between mb-3\">\r\n <div>\r\n <h6 class=\"mb-0\">Results</h6>\r\n <small class=\"text-muted\">\r\n {{ totalRows }} row(s)\r\n @if (totalRows) {\r\n \u00B7 showing {{ pageStart }}\u2013{{ pageEnd }}\r\n }\r\n </small>\r\n </div>\r\n </div>\r\n\r\n @if (!result.rows.length) {\r\n <div class=\"text-muted\">No data found for the given query.</div>\r\n } @else {\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-sm table-bordered\">\r\n <thead>\r\n <tr>\r\n @for (col of resultColumns; track col.key) {\r\n <th>{{ col.label }}</th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (row of pagedRows; track $index) {\r\n <tr [class.row-not-found]=\"row['__notFound']\">\r\n @for (col of resultColumns; track col.key) {\r\n <td\r\n [ngbTooltip]=\"row[col.label]?.toString() ? row[col.label] : null\"\r\n container=\"body\"\r\n placement=\"top\"\r\n [openDelay]=\"300\">\r\n {{ row[col.label] }}\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <lib-pagination\r\n [itemsPerPage]=\"pageSize\"\r\n [currentPage]=\"currentPage\"\r\n [totalItems]=\"totalRows\"\r\n [pageSize]=\"pageSize\"\r\n [paginationSizes]=\"paginationSizes\"\r\n [directionLinks]=\"true\"\r\n (pageChange)=\"onPageChange($event)\"\r\n (pageSizeChange)=\"onPageSizeChange($event)\">\r\n </lib-pagination>\r\n }\r\n </div>\r\n }\r\n</section>\r\n", styles: [".plano-data-export .card{border:1px solid #e0e0e0}.plano-data-export .block{border:1px solid #e9ecef;border-radius:6px;padding:12px 14px;background:#fafbfc}.plano-data-export .block-title{font-weight:600;font-size:.95rem;color:#344054}.plano-data-export .filter-row .filter-field{flex:0 0 220px}.plano-data-export .filter-row .filter-op{flex:0 0 200px}.plano-data-export .filter-row .filter-value{flex:1 1 auto;min-width:120px}.plano-data-export .count-input{width:80px}.plano-data-export .column-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:6px 14px}.plano-data-export .column-item{display:flex;align-items:center;cursor:pointer;-webkit-user-select:none;user-select:none;font-size:.92rem;margin-bottom:0}.plano-data-export .table th{white-space:nowrap;background:#f8f9fa;position:sticky;top:0;z-index:1}.plano-data-export .table td{max-width:240px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:default}.plano-data-export .row-not-found td{color:#98a2b3;font-style:italic}.plano-data-export .table-responsive{max-height:480px;overflow:auto}\n"], dependencies: [{ kind: "directive", type: i3.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i3.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i3.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i3.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i3.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i3.RadioControlValueAccessor, selector: "input[type=radio][formControlName],input[type=radio][formControl],input[type=radio][ngModel]", inputs: ["name", "formControlName", "value"] }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i4.PaginationComponent, selector: "lib-pagination", inputs: ["collection", "itemsPerPage", "currentPage", "totalItems", "directionLinks", "pageSize", "paginationSizes"], outputs: ["pageChange", "pageSizeChange"] }, { kind: "directive", type: i5.NgbTooltip, selector: "[ngbTooltip]", inputs: ["animation", "autoClose", "placement", "popperOptions", "triggers", "positionTarget", "container", "disableTooltip", "tooltipClass", "tooltipContext", "openDelay", "closeDelay", "ngbTooltip"], outputs: ["shown", "hidden"], exportAs: ["ngbTooltip"] }, { kind: "component", type: i6.StoreSelectComponent, selector: "lib-store-select", inputs: ["options", "initialSelected", "singleSelect"], outputs: ["selectedChange"] }, { kind: "component", type: i7.ToolPageHeaderComponent, selector: "lib-tool-page-header", inputs: ["title", "description", "backLink"] }] });
373
374
  }
374
375
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: PlanoDataExportComponent, decorators: [{
375
376
  type: Component,
376
- args: [{ selector: 'lib-plano-data-export', template: "<section class=\"plano-data-export p-3\">\r\n <div class=\"card p-4 mb-3\">\r\n <h5 class=\"mb-1\">Plano Data Export</h5>\r\n <p class=\"text-muted small mb-3\">\r\n Build a query against planogram fixtures, preview results, and export as Excel.\r\n </p>\r\n\r\n @if (isLoadingSchema) {\r\n <div class=\"text-muted small\">Loading query schema...</div>\r\n }\r\n\r\n <!-- Stores -->\r\n <div class=\"block mb-3\">\r\n <div class=\"block-title\">Stores</div>\r\n <lib-store-select\r\n [options]=\"storeOptions\"\r\n [initialSelected]=\"initialStores\"\r\n (selectedChange)=\"onStoresSelected($event)\">\r\n </lib-store-select>\r\n </div>\r\n\r\n <!-- Match Criteria -->\r\n <div class=\"block mb-3\">\r\n <div class=\"d-flex align-items-center justify-content-between mb-2\">\r\n <div class=\"block-title mb-0\">Match Criteria</div>\r\n <div class=\"d-flex align-items-center gap-3\">\r\n <div class=\"form-check form-check-inline mb-0\">\r\n <input class=\"form-check-input\" type=\"radio\" id=\"combAnd\"\r\n name=\"combinator\" value=\"AND\" [(ngModel)]=\"filterCombinator\">\r\n <label class=\"form-check-label\" for=\"combAnd\">Match all (AND)</label>\r\n </div>\r\n <div class=\"form-check form-check-inline mb-0\">\r\n <input class=\"form-check-input\" type=\"radio\" id=\"combOr\"\r\n name=\"combinator\" value=\"OR\" [(ngModel)]=\"filterCombinator\">\r\n <label class=\"form-check-label\" for=\"combOr\">Match any (OR)</label>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n @if (!filters.length) {\r\n <div class=\"text-muted small mb-2\">\r\n No criteria \u2014 query will return every fixture for the selected stores.\r\n </div>\r\n }\r\n\r\n @for (row of filters; track $index) {\r\n <div class=\"filter-row d-flex gap-2 mb-2 align-items-center\">\r\n <select class=\"form-select form-select-sm filter-field\"\r\n [(ngModel)]=\"row.field\"\r\n (change)=\"onFilterFieldChange($index)\">\r\n @for (f of filterableFields; track f.key) {\r\n <option [value]=\"f.key\">{{ f.label }}</option>\r\n }\r\n </select>\r\n\r\n <select class=\"form-select form-select-sm filter-op\"\r\n [(ngModel)]=\"row.operator\">\r\n @for (op of operatorsForField(row.field); track op.key) {\r\n <option [value]=\"op.key\">{{ op.label }}</option>\r\n }\r\n </select>\r\n\r\n <input\r\n class=\"form-control form-control-sm filter-value\"\r\n [placeholder]=\"isValueDisabledFor(row.operator) ? '\u2014' : 'value'\"\r\n [disabled]=\"isValueDisabledFor(row.operator)\"\r\n [(ngModel)]=\"row.value\">\r\n\r\n <button class=\"btn btn-sm btn-outline-danger\" (click)=\"removeFilter($index)\"\r\n title=\"Remove\">\u00D7</button>\r\n </div>\r\n }\r\n\r\n <button class=\"btn btn-sm btn-outline-primary\" (click)=\"addFilter()\"\r\n [disabled]=\"!filterableFields.length\">\r\n + Add Criterion\r\n </button>\r\n </div>\r\n\r\n <!-- Selection Mode -->\r\n <div class=\"block mb-3\">\r\n <div class=\"block-title\">Fixture Selection</div>\r\n <div class=\"d-flex flex-wrap align-items-center gap-3\">\r\n <div class=\"form-check mb-0\">\r\n <input class=\"form-check-input\" type=\"radio\" id=\"selAll\"\r\n name=\"selectionMode\" value=\"all\" [(ngModel)]=\"selectionMode\">\r\n <label class=\"form-check-label\" for=\"selAll\">All matching fixtures</label>\r\n </div>\r\n <div class=\"form-check mb-0\">\r\n <input class=\"form-check-input\" type=\"radio\" id=\"selFirstN\"\r\n name=\"selectionMode\" value=\"firstN\" [(ngModel)]=\"selectionMode\">\r\n <label class=\"form-check-label\" for=\"selFirstN\">First</label>\r\n </div>\r\n <input\r\n type=\"number\"\r\n min=\"1\"\r\n class=\"form-control form-control-sm count-input\"\r\n [(ngModel)]=\"limitPerStore\"\r\n [disabled]=\"selectionMode !== 'firstN'\">\r\n <span class=\"text-muted small\">matching from entrance, per store</span>\r\n </div>\r\n\r\n <div class=\"form-check mt-2\">\r\n <input class=\"form-check-input\" type=\"checkbox\" id=\"incNotFound\"\r\n [(ngModel)]=\"includeNotFoundRows\">\r\n <label class=\"form-check-label\" for=\"incNotFound\">\r\n Include empty rows for stores with no matches\r\n </label>\r\n </div>\r\n </div>\r\n\r\n <!-- Output Columns -->\r\n <div class=\"block mb-3\">\r\n <div class=\"d-flex align-items-center justify-content-between mb-2\">\r\n <div class=\"block-title mb-0\">Output Columns</div>\r\n <div class=\"d-flex gap-2\">\r\n <button class=\"btn btn-sm btn-link p-0\" (click)=\"selectAllColumns()\">\r\n Select all\r\n </button>\r\n <button class=\"btn btn-sm btn-link p-0\" (click)=\"clearAllColumns()\">\r\n Clear\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"column-grid\">\r\n @for (col of outputColumns; track col.key) {\r\n <label class=\"column-item\">\r\n <input type=\"checkbox\" class=\"form-check-input me-2\"\r\n [(ngModel)]=\"col.selected\">\r\n {{ col.label }}\r\n </label>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Action Buttons -->\r\n <div class=\"d-flex gap-2\">\r\n <button\r\n class=\"btn btn-primary\"\r\n (click)=\"onRun()\"\r\n [disabled]=\"isRunning || isLoadingSchema || selectedStores.length === 0\">\r\n {{ isRunning ? 'Running...' : 'Run Query' }}\r\n </button>\r\n <button\r\n class=\"btn btn-success\"\r\n (click)=\"onExport()\"\r\n [disabled]=\"!result || !result.rows.length\">\r\n Export to Excel\r\n </button>\r\n </div>\r\n\r\n @if (message) {\r\n <div\r\n class=\"mt-3 alert\"\r\n [class.alert-success]=\"messageType === 'success'\"\r\n [class.alert-danger]=\"messageType === 'error'\">\r\n {{ message }}\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- VM Placement Export by VM Name -->\r\n <div class=\"card p-4 mb-3\">\r\n <h5 class=\"mb-1\">VM Placement Export by VM Name</h5>\r\n <p class=\"text-muted small mb-3\">\r\n Find every fixture (in the selected stores) that contains any VM whose\r\n <code>vmName</code> matches the regex, and export one row per VM placement\r\n with fixture details and shelf/zone coordinates.\r\n </p>\r\n\r\n <div class=\"block mb-3\">\r\n <div class=\"block-title\">Stores</div>\r\n <lib-store-select\r\n [options]=\"storeOptions\"\r\n [initialSelected]=\"vmInitialStores\"\r\n (selectedChange)=\"onVmStoresSelected($event)\">\r\n </lib-store-select>\r\n </div>\r\n\r\n <div class=\"block mb-3\">\r\n <div class=\"block-title\">VM Name (regex)</div>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"e.g. Zodiac, ^Hiphop, Leatherite\"\r\n [(ngModel)]=\"vmNameRegex\">\r\n <small class=\"text-muted\">Case-insensitive. Matched against the <code>planoVmDetails.vmName</code> field.</small>\r\n </div>\r\n\r\n <div class=\"d-flex gap-2\">\r\n <button\r\n class=\"btn btn-primary\"\r\n (click)=\"onVmRun()\"\r\n [disabled]=\"isVmRunning || vmSelectedStores.length === 0 || !vmNameRegex.trim()\">\r\n {{ isVmRunning ? 'Running...' : 'Run Query' }}\r\n </button>\r\n <button\r\n class=\"btn btn-success\"\r\n (click)=\"onVmExport()\"\r\n [disabled]=\"!vmResult || !vmResult.rows.length\">\r\n Export to Excel\r\n </button>\r\n </div>\r\n\r\n @if (vmMessage) {\r\n <div\r\n class=\"mt-3 alert\"\r\n [class.alert-success]=\"vmMessageType === 'success'\"\r\n [class.alert-danger]=\"vmMessageType === 'error'\">\r\n {{ vmMessage }}\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (vmResult) {\r\n <div class=\"card p-4 mb-3\">\r\n <div class=\"d-flex align-items-center justify-content-between mb-3\">\r\n <div>\r\n <h6 class=\"mb-0\">VM Placement Results</h6>\r\n <small class=\"text-muted\">\r\n {{ vmTotalRows }} row(s)\r\n @if (vmTotalRows) {\r\n \u00B7 showing {{ vmPageStart }}\u2013{{ vmPageEnd }}\r\n }\r\n </small>\r\n </div>\r\n </div>\r\n\r\n @if (!vmResult.rows.length) {\r\n <div class=\"text-muted\">No VM placements found for the given stores and vmName.</div>\r\n } @else {\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-sm table-bordered\">\r\n <thead>\r\n <tr>\r\n @for (col of vmResultColumns; track col) {\r\n <th>{{ col }}</th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (row of vmPagedRows; track $index) {\r\n <tr>\r\n @for (col of vmResultColumns; track col) {\r\n <td\r\n [ngbTooltip]=\"row[col]?.toString() ? row[col] : null\"\r\n container=\"body\"\r\n placement=\"top\"\r\n [openDelay]=\"300\">\r\n {{ row[col] }}\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <lib-pagination\r\n [itemsPerPage]=\"vmPageSize\"\r\n [currentPage]=\"vmCurrentPage\"\r\n [totalItems]=\"vmTotalRows\"\r\n [pageSize]=\"vmPageSize\"\r\n [paginationSizes]=\"paginationSizes\"\r\n [directionLinks]=\"true\"\r\n (pageChange)=\"onVmPageChange($event)\"\r\n (pageSizeChange)=\"onVmPageSizeChange($event)\">\r\n </lib-pagination>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Result Preview -->\r\n @if (result) {\r\n <div class=\"card p-4\">\r\n <div class=\"d-flex align-items-center justify-content-between mb-3\">\r\n <div>\r\n <h6 class=\"mb-0\">Results</h6>\r\n <small class=\"text-muted\">\r\n {{ totalRows }} row(s)\r\n @if (totalRows) {\r\n \u00B7 showing {{ pageStart }}\u2013{{ pageEnd }}\r\n }\r\n </small>\r\n </div>\r\n </div>\r\n\r\n @if (!result.rows.length) {\r\n <div class=\"text-muted\">No data found for the given query.</div>\r\n } @else {\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-sm table-bordered\">\r\n <thead>\r\n <tr>\r\n @for (col of resultColumns; track col.key) {\r\n <th>{{ col.label }}</th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (row of pagedRows; track $index) {\r\n <tr [class.row-not-found]=\"row['__notFound']\">\r\n @for (col of resultColumns; track col.key) {\r\n <td\r\n [ngbTooltip]=\"row[col.label]?.toString() ? row[col.label] : null\"\r\n container=\"body\"\r\n placement=\"top\"\r\n [openDelay]=\"300\">\r\n {{ row[col.label] }}\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <lib-pagination\r\n [itemsPerPage]=\"pageSize\"\r\n [currentPage]=\"currentPage\"\r\n [totalItems]=\"totalRows\"\r\n [pageSize]=\"pageSize\"\r\n [paginationSizes]=\"paginationSizes\"\r\n [directionLinks]=\"true\"\r\n (pageChange)=\"onPageChange($event)\"\r\n (pageSizeChange)=\"onPageSizeChange($event)\">\r\n </lib-pagination>\r\n }\r\n </div>\r\n }\r\n</section>\r\n", styles: [".plano-data-export .card{border:1px solid #e0e0e0}.plano-data-export .block{border:1px solid #e9ecef;border-radius:6px;padding:12px 14px;background:#fafbfc}.plano-data-export .block-title{font-weight:600;font-size:.95rem;color:#344054}.plano-data-export .filter-row .filter-field{flex:0 0 220px}.plano-data-export .filter-row .filter-op{flex:0 0 200px}.plano-data-export .filter-row .filter-value{flex:1 1 auto;min-width:120px}.plano-data-export .count-input{width:80px}.plano-data-export .column-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:6px 14px}.plano-data-export .column-item{display:flex;align-items:center;cursor:pointer;-webkit-user-select:none;user-select:none;font-size:.92rem;margin-bottom:0}.plano-data-export .table th{white-space:nowrap;background:#f8f9fa;position:sticky;top:0;z-index:1}.plano-data-export .table td{max-width:240px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:default}.plano-data-export .row-not-found td{color:#98a2b3;font-style:italic}.plano-data-export .table-responsive{max-height:480px;overflow:auto}\n"] }]
377
+ args: [{ selector: 'lib-plano-data-export', template: "<section class=\"plano-data-export p-3\">\r\n <lib-tool-page-header\r\n title=\"Data Export\"\r\n description=\"Build a query against planogram fixtures, preview results, and export as Excel.\"\r\n ></lib-tool-page-header>\r\n <div class=\"card p-4 mb-3\">\r\n\r\n @if (isLoadingSchema) {\r\n <div class=\"text-muted small\">Loading query schema...</div>\r\n }\r\n\r\n <!-- Stores -->\r\n <div class=\"block mb-3\">\r\n <div class=\"block-title\">Stores</div>\r\n <lib-store-select\r\n [options]=\"storeOptions\"\r\n [initialSelected]=\"initialStores\"\r\n (selectedChange)=\"onStoresSelected($event)\">\r\n </lib-store-select>\r\n </div>\r\n\r\n <!-- Match Criteria -->\r\n <div class=\"block mb-3\">\r\n <div class=\"d-flex align-items-center justify-content-between mb-2\">\r\n <div class=\"block-title mb-0\">Match Criteria</div>\r\n <div class=\"d-flex align-items-center gap-3\">\r\n <div class=\"form-check form-check-inline mb-0\">\r\n <input class=\"form-check-input\" type=\"radio\" id=\"combAnd\"\r\n name=\"combinator\" value=\"AND\" [(ngModel)]=\"filterCombinator\">\r\n <label class=\"form-check-label\" for=\"combAnd\">Match all (AND)</label>\r\n </div>\r\n <div class=\"form-check form-check-inline mb-0\">\r\n <input class=\"form-check-input\" type=\"radio\" id=\"combOr\"\r\n name=\"combinator\" value=\"OR\" [(ngModel)]=\"filterCombinator\">\r\n <label class=\"form-check-label\" for=\"combOr\">Match any (OR)</label>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n @if (!filters.length) {\r\n <div class=\"text-muted small mb-2\">\r\n No criteria \u2014 query will return every fixture for the selected stores.\r\n </div>\r\n }\r\n\r\n @for (row of filters; track $index) {\r\n <div class=\"filter-row d-flex gap-2 mb-2 align-items-center\">\r\n <select class=\"form-select form-select-sm filter-field\"\r\n [(ngModel)]=\"row.field\"\r\n (change)=\"onFilterFieldChange($index)\">\r\n @for (f of filterableFields; track f.key) {\r\n <option [value]=\"f.key\">{{ f.label }}</option>\r\n }\r\n </select>\r\n\r\n <select class=\"form-select form-select-sm filter-op\"\r\n [(ngModel)]=\"row.operator\">\r\n @for (op of operatorsForField(row.field); track op.key) {\r\n <option [value]=\"op.key\">{{ op.label }}</option>\r\n }\r\n </select>\r\n\r\n <input\r\n class=\"form-control form-control-sm filter-value\"\r\n [placeholder]=\"isValueDisabledFor(row.operator) ? '\u2014' : 'value'\"\r\n [disabled]=\"isValueDisabledFor(row.operator)\"\r\n [(ngModel)]=\"row.value\">\r\n\r\n <button class=\"btn btn-sm btn-outline-danger\" (click)=\"removeFilter($index)\"\r\n title=\"Remove\">\u00D7</button>\r\n </div>\r\n }\r\n\r\n <button class=\"btn btn-sm btn-outline-primary\" (click)=\"addFilter()\"\r\n [disabled]=\"!filterableFields.length\">\r\n + Add Criterion\r\n </button>\r\n </div>\r\n\r\n <!-- Selection Mode -->\r\n <div class=\"block mb-3\">\r\n <div class=\"block-title\">Fixture Selection</div>\r\n <div class=\"d-flex flex-wrap align-items-center gap-3\">\r\n <div class=\"form-check mb-0\">\r\n <input class=\"form-check-input\" type=\"radio\" id=\"selAll\"\r\n name=\"selectionMode\" value=\"all\" [(ngModel)]=\"selectionMode\">\r\n <label class=\"form-check-label\" for=\"selAll\">All matching fixtures</label>\r\n </div>\r\n <div class=\"form-check mb-0\">\r\n <input class=\"form-check-input\" type=\"radio\" id=\"selFirstN\"\r\n name=\"selectionMode\" value=\"firstN\" [(ngModel)]=\"selectionMode\">\r\n <label class=\"form-check-label\" for=\"selFirstN\">First</label>\r\n </div>\r\n <input\r\n type=\"number\"\r\n min=\"1\"\r\n class=\"form-control form-control-sm count-input\"\r\n [(ngModel)]=\"limitPerStore\"\r\n [disabled]=\"selectionMode !== 'firstN'\">\r\n <span class=\"text-muted small\">matching from entrance, per store</span>\r\n </div>\r\n\r\n <div class=\"form-check mt-2\">\r\n <input class=\"form-check-input\" type=\"checkbox\" id=\"incNotFound\"\r\n [(ngModel)]=\"includeNotFoundRows\">\r\n <label class=\"form-check-label\" for=\"incNotFound\">\r\n Include empty rows for stores with no matches\r\n </label>\r\n </div>\r\n </div>\r\n\r\n <!-- Output Columns -->\r\n <div class=\"block mb-3\">\r\n <div class=\"d-flex align-items-center justify-content-between mb-2\">\r\n <div class=\"block-title mb-0\">Output Columns</div>\r\n <div class=\"d-flex gap-2\">\r\n <button class=\"btn btn-sm btn-link p-0\" (click)=\"selectAllColumns()\">\r\n Select all\r\n </button>\r\n <button class=\"btn btn-sm btn-link p-0\" (click)=\"clearAllColumns()\">\r\n Clear\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"column-grid\">\r\n @for (col of outputColumns; track col.key) {\r\n <label class=\"column-item\">\r\n <input type=\"checkbox\" class=\"form-check-input me-2\"\r\n [(ngModel)]=\"col.selected\">\r\n {{ col.label }}\r\n </label>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Action Buttons -->\r\n <div class=\"d-flex gap-2\">\r\n <button\r\n class=\"btn btn-primary\"\r\n (click)=\"onRun()\"\r\n [disabled]=\"isRunning || isLoadingSchema || selectedStores.length === 0\">\r\n {{ isRunning ? 'Running...' : 'Run Query' }}\r\n </button>\r\n <button\r\n class=\"btn btn-success\"\r\n (click)=\"onExport()\"\r\n [disabled]=\"!result || !result.rows.length\">\r\n Export to Excel\r\n </button>\r\n </div>\r\n\r\n @if (message) {\r\n <div\r\n class=\"mt-3 alert\"\r\n [class.alert-success]=\"messageType === 'success'\"\r\n [class.alert-danger]=\"messageType === 'error'\">\r\n {{ message }}\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- VM Placement Export by VM Name -->\r\n <div class=\"card p-4 mb-3\">\r\n <h5 class=\"mb-1\">VM Placement Export by VM Name</h5>\r\n <p class=\"text-muted small mb-3\">\r\n Find every fixture (in the selected stores) that contains any VM whose\r\n <code>vmName</code> matches the regex, and export one row per VM placement\r\n with fixture details and shelf/zone coordinates.\r\n </p>\r\n\r\n <div class=\"block mb-3\">\r\n <div class=\"block-title\">Stores</div>\r\n <lib-store-select\r\n [options]=\"storeOptions\"\r\n [initialSelected]=\"vmInitialStores\"\r\n (selectedChange)=\"onVmStoresSelected($event)\">\r\n </lib-store-select>\r\n </div>\r\n\r\n <div class=\"block mb-3\">\r\n <div class=\"block-title\">VM Name (regex)</div>\r\n <input\r\n class=\"form-control form-control-sm\"\r\n placeholder=\"e.g. Zodiac, ^Hiphop, Leatherite\"\r\n [(ngModel)]=\"vmNameRegex\">\r\n <small class=\"text-muted\">Case-insensitive. Matched against the <code>planoVmDetails.vmName</code> field.</small>\r\n </div>\r\n\r\n <div class=\"d-flex gap-2\">\r\n <button\r\n class=\"btn btn-primary\"\r\n (click)=\"onVmRun()\"\r\n [disabled]=\"isVmRunning || vmSelectedStores.length === 0 || !vmNameRegex.trim()\">\r\n {{ isVmRunning ? 'Running...' : 'Run Query' }}\r\n </button>\r\n <button\r\n class=\"btn btn-success\"\r\n (click)=\"onVmExport()\"\r\n [disabled]=\"!vmResult || !vmResult.rows.length\">\r\n Export to Excel\r\n </button>\r\n </div>\r\n\r\n @if (vmMessage) {\r\n <div\r\n class=\"mt-3 alert\"\r\n [class.alert-success]=\"vmMessageType === 'success'\"\r\n [class.alert-danger]=\"vmMessageType === 'error'\">\r\n {{ vmMessage }}\r\n </div>\r\n }\r\n </div>\r\n\r\n @if (vmResult) {\r\n <div class=\"card p-4 mb-3\">\r\n <div class=\"d-flex align-items-center justify-content-between mb-3\">\r\n <div>\r\n <h6 class=\"mb-0\">VM Placement Results</h6>\r\n <small class=\"text-muted\">\r\n {{ vmTotalRows }} row(s)\r\n @if (vmTotalRows) {\r\n \u00B7 showing {{ vmPageStart }}\u2013{{ vmPageEnd }}\r\n }\r\n </small>\r\n </div>\r\n </div>\r\n\r\n @if (!vmResult.rows.length) {\r\n <div class=\"text-muted\">No VM placements found for the given stores and vmName.</div>\r\n } @else {\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-sm table-bordered\">\r\n <thead>\r\n <tr>\r\n @for (col of vmResultColumns; track col) {\r\n <th>{{ col }}</th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (row of vmPagedRows; track $index) {\r\n <tr>\r\n @for (col of vmResultColumns; track col) {\r\n <td\r\n [ngbTooltip]=\"row[col]?.toString() ? row[col] : null\"\r\n container=\"body\"\r\n placement=\"top\"\r\n [openDelay]=\"300\">\r\n {{ row[col] }}\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <lib-pagination\r\n [itemsPerPage]=\"vmPageSize\"\r\n [currentPage]=\"vmCurrentPage\"\r\n [totalItems]=\"vmTotalRows\"\r\n [pageSize]=\"vmPageSize\"\r\n [paginationSizes]=\"paginationSizes\"\r\n [directionLinks]=\"true\"\r\n (pageChange)=\"onVmPageChange($event)\"\r\n (pageSizeChange)=\"onVmPageSizeChange($event)\">\r\n </lib-pagination>\r\n }\r\n </div>\r\n }\r\n\r\n <!-- Result Preview -->\r\n @if (result) {\r\n <div class=\"card p-4\">\r\n <div class=\"d-flex align-items-center justify-content-between mb-3\">\r\n <div>\r\n <h6 class=\"mb-0\">Results</h6>\r\n <small class=\"text-muted\">\r\n {{ totalRows }} row(s)\r\n @if (totalRows) {\r\n \u00B7 showing {{ pageStart }}\u2013{{ pageEnd }}\r\n }\r\n </small>\r\n </div>\r\n </div>\r\n\r\n @if (!result.rows.length) {\r\n <div class=\"text-muted\">No data found for the given query.</div>\r\n } @else {\r\n <div class=\"table-responsive\">\r\n <table class=\"table table-sm table-bordered\">\r\n <thead>\r\n <tr>\r\n @for (col of resultColumns; track col.key) {\r\n <th>{{ col.label }}</th>\r\n }\r\n </tr>\r\n </thead>\r\n <tbody>\r\n @for (row of pagedRows; track $index) {\r\n <tr [class.row-not-found]=\"row['__notFound']\">\r\n @for (col of resultColumns; track col.key) {\r\n <td\r\n [ngbTooltip]=\"row[col.label]?.toString() ? row[col.label] : null\"\r\n container=\"body\"\r\n placement=\"top\"\r\n [openDelay]=\"300\">\r\n {{ row[col.label] }}\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n </table>\r\n </div>\r\n\r\n <lib-pagination\r\n [itemsPerPage]=\"pageSize\"\r\n [currentPage]=\"currentPage\"\r\n [totalItems]=\"totalRows\"\r\n [pageSize]=\"pageSize\"\r\n [paginationSizes]=\"paginationSizes\"\r\n [directionLinks]=\"true\"\r\n (pageChange)=\"onPageChange($event)\"\r\n (pageSizeChange)=\"onPageSizeChange($event)\">\r\n </lib-pagination>\r\n }\r\n </div>\r\n }\r\n</section>\r\n", styles: [".plano-data-export .card{border:1px solid #e0e0e0}.plano-data-export .block{border:1px solid #e9ecef;border-radius:6px;padding:12px 14px;background:#fafbfc}.plano-data-export .block-title{font-weight:600;font-size:.95rem;color:#344054}.plano-data-export .filter-row .filter-field{flex:0 0 220px}.plano-data-export .filter-row .filter-op{flex:0 0 200px}.plano-data-export .filter-row .filter-value{flex:1 1 auto;min-width:120px}.plano-data-export .count-input{width:80px}.plano-data-export .column-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(200px,1fr));gap:6px 14px}.plano-data-export .column-item{display:flex;align-items:center;cursor:pointer;-webkit-user-select:none;user-select:none;font-size:.92rem;margin-bottom:0}.plano-data-export .table th{white-space:nowrap;background:#f8f9fa;position:sticky;top:0;z-index:1}.plano-data-export .table td{max-width:240px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;cursor:default}.plano-data-export .row-not-found td{color:#98a2b3;font-style:italic}.plano-data-export .table-responsive{max-height:480px;overflow:auto}\n"] }]
377
378
  }], ctorParameters: () => [{ type: i1.StoreBuilderService }, { type: i2.GlobalStateService }] });
378
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGxhbm8tZGF0YS1leHBvcnQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdGFuZ28tc3RvcmUtYnVpbGRlci9zcmMvbGliL2NvbXBvbmVudHMvcGxhbm8tdG9vbHMvcGxhbm8tZGF0YS1leHBvcnQvcGxhbm8tZGF0YS1leHBvcnQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdGFuZ28tc3RvcmUtYnVpbGRlci9zcmMvbGliL2NvbXBvbmVudHMvcGxhbm8tdG9vbHMvcGxhbm8tZGF0YS1leHBvcnQvcGxhbm8tZGF0YS1leHBvcnQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBcUIsTUFBTSxlQUFlLENBQUM7QUFHN0QsT0FBTyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLE1BQU0sQ0FBQzs7Ozs7Ozs7QUF5Q3RGLE1BQU0sbUJBQW1CLEdBQXFDO0lBQzVELEVBQUUsR0FBRyxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFO0lBQ3pDLEVBQUUsR0FBRyxFQUFFLGlCQUFpQixFQUFFLEtBQUssRUFBRSxrQkFBa0IsRUFBRTtJQUNyRCxFQUFFLEdBQUcsRUFBRSxjQUFjLEVBQUUsS0FBSyxFQUFFLGVBQWUsRUFBRTtJQUMvQyxFQUFFLEdBQUcsRUFBRSxlQUFlLEVBQUUsS0FBSyxFQUFFLGdCQUFnQixFQUFFO0lBQ2pELEVBQUUsR0FBRyxFQUFFLGFBQWEsRUFBRSxLQUFLLEVBQUUsY0FBYyxFQUFFO0lBQzdDLEVBQUUsR0FBRyxFQUFFLGFBQWEsRUFBRSxLQUFLLEVBQUUsY0FBYyxFQUFFO0lBQzdDLEVBQUUsR0FBRyxFQUFFLGFBQWEsRUFBRSxLQUFLLEVBQUUsY0FBYyxFQUFFO0lBQzdDLEVBQUUs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LCBPbkluaXQsIE9uRGVzdHJveSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBTdG9yZUJ1aWxkZXJTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vc2VydmljZXMvc3RvcmUtYnVpbGRlci5zZXJ2aWNlJztcclxuaW1wb3J0IHsgR2xvYmFsU3RhdGVTZXJ2aWNlIH0gZnJvbSAndGFuZ28tYXBwLXVpLWdsb2JhbCc7XHJcbmltcG9ydCB7IFN1YmplY3QsIHRha2VVbnRpbCwgZGVib3VuY2VUaW1lLCBmaWx0ZXIsIGRpc3RpbmN0VW50aWxDaGFuZ2VkIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IFN0b3JlT3B0aW9uIH0gZnJvbSAnLi4vLi4vY29sbGVjdGlvbi11cGRhdGUtYWkvY29tcG9uZW50cy9zdG9yZS1zZWxlY3Qvc3RvcmUtc2VsZWN0LmNvbXBvbmVudCc7XHJcblxyXG5pbnRlcmZhY2UgRmllbGREZWYge1xyXG4gIGtleTogc3RyaW5nO1xyXG4gIGxhYmVsOiBzdHJpbmc7XHJcbiAgdHlwZTogJ3N0cmluZycgfCAnbnVtYmVyJyB8ICdhcnJheU9mU3RyaW5ncyc7XHJcbiAgZmlsdGVyYWJsZTogYm9vbGVhbjtcclxuICBvdXRwdXQ6IGJvb2xlYW47XHJcbn1cclxuXHJcbmludGVyZmFjZSBPcGVyYXRvckRlZiB7XHJcbiAga2V5OiBzdHJpbmc7XHJcbiAgbGFiZWw6IHN0cmluZztcclxufVxyXG5cclxuaW50ZXJmYWNlIEZpbHRlclJvdyB7XHJcbiAgZmllbGQ6IHN0cmluZztcclxuICBvcGVyYXRvcjogc3RyaW5nO1xyXG4gIHZhbHVlOiBzdHJpbmc7XHJcbn1cclxuXHJcbmludGVyZmFjZSBDb2x1bW5TZWxlY3Rpb24ge1xyXG4gIGtleTogc3RyaW5nO1xyXG4gIGxhYmVsOiBzdHJpbmc7XHJcbiAgc2VsZWN0ZWQ6IGJvb2xlYW47XHJcbn1cclxuXHJcbmludGVyZmFjZSBRdWVyeVJlc3VsdCB7XHJcbiAgY29sdW1uczogc3RyaW5nW107XHJcbiAgcm93czogUmVjb3JkPHN0cmluZywgYW55PltdO1xyXG4gIHRvdGFsUm93czogbnVtYmVyO1xyXG59XHJcblxyXG5pbnRlcmZhY2UgVm1QbGFjZW1lbnRSZXN1bHQge1xyXG4gIGNvbHVtbnM6IHN0cmluZ1tdO1xyXG4gIHJvd3M6IFJlY29yZDxzdHJpbmcsIGFueT5bXTtcclxuICB0b3RhbFJvd3M6IG51bWJlcjtcclxuICBtYXRjaGVkVm1Db3VudDogbnVtYmVyO1xyXG59XHJcblxyXG5jb25zdCBPVVRQVVRfQ09MVU1OX09SREVSOiB7IGtleTogc3RyaW5nOyBsYWJlbDogc3RyaW5nIH1bXSA9IFtcclxuICB7IGtleTogJ3N0b3JlTmFtZScsIGxhYmVsOiAnU3RvcmUgTmFtZScgfSxcclxuICB7IGtleTogJ2ZpeHR1cmVDYXRlZ29yeScsIGxhYmVsOiAnRml4dHVyZSBDYXRlZ29yeScgfSxcclxuICB7IGtleTogJ2ZpeHR1cmVXaWR0aCcsIGxhYmVsOiAnRml4dHVyZSBXaWR0aCcgfSxcclxuICB7IGtleTogJ2ZpeHR1cmVOdW1iZXInLCBsYWJlbDogJ0ZpeHR1cmUgTnVtYmVyJyB9LFxyXG4gIHsga2V5OiAnZml4dHVyZU5hbWUnLCBsYWJlbDogJ0ZpeHR1cmUgTmFtZScgfSxcclxuICB7IGtleTogJ2ZpeHR1cmVUeXBlJywgbGFiZWw6ICdGaXh0dXJlIFR5cGUnIH0sXHJcbiAgeyBrZXk6ICdoZWFkZXJMYWJlbCcsIGxhYmVsOiAnSGVhZGVyIExhYmVsJyB9LFxyXG4gIHsga2V5OiAndGVtcGxhdGVHcm91cE5hbWUnLCBsYWJlbDogJ1RlbXBsYXRlIEdyb3VwIE5hbWUnIH0sXHJcbiAgeyBrZXk6ICd3YWxsTnVtYmVyJywgbGFiZWw6ICdXYWxsIE51bWJlcicgfSxcclxuICB7IGtleTogJ3dhbGxGaXh0dXJlTnVtYmVyJywgbGFiZWw6ICdXYWxsIEZpeHR1cmUgTnVtYmVyJyB9LFxyXG4gIHsga2V5OiAndm1OYW1lcycsIGxhYmVsOiAnVk0gTmFtZXMnIH0sXHJcbiAgeyBrZXk6ICd2bUNvdW50JywgbGFiZWw6ICdWTSBDb3VudCcgfSxcclxuICB7IGtleTogJ3Byb2R1Y3RQaWRzJywgbGFiZWw6ICdQcm9kdWN0IFBJRHMnIH0sXHJcbiAgeyBrZXk6ICdwb3NpdGlvbicsIGxhYmVsOiAnUG9zaXRpb24nIH0sXHJcbiAgeyBrZXk6ICdwb3NpdGlvbkxhYmVsJywgbGFiZWw6ICdQb3NpdGlvbiBMYWJlbCcgfSxcclxuICB7IGtleTogJ3N0YW5kYXJkQ2FwYWNpdHknLCBsYWJlbDogJ1N0YW5kYXJkIENhcGFjaXR5JyB9LFxyXG5dO1xyXG5cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICdsaWItcGxhbm8tZGF0YS1leHBvcnQnLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9wbGFuby1kYXRhLWV4cG9ydC5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmw6ICcuL3BsYW5vLWRhdGEtZXhwb3J0LmNvbXBvbmVudC5zY3NzJyxcclxufSlcclxuZXhwb3J0IGNsYXNzIFBsYW5vRGF0YUV4cG9ydENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcclxuICBjbGllbnRJZDogc3RyaW5nO1xyXG4gIHN0b3JlT3B0aW9uczogU3RvcmVPcHRpb25bXSA9IFtdO1xyXG4gIGluaXRpYWxTdG9yZXM6IFN0b3JlT3B0aW9uW10gPSBbXTtcclxuICBzZWxlY3RlZFN0b3JlczogU3RvcmVPcHRpb25bXSA9IFtdO1xyXG5cclxuICBmaWVsZHM6IEZpZWxkRGVmW10gPSBbXTtcclxuICBvcGVyYXRvcnNCeVR5cGU6IFJlY29yZDxzdHJpbmcsIE9wZXJhdG9yRGVmW10+ID0ge307XHJcbiAgaXNMb2FkaW5nU2NoZW1hOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIGZpbHRlcnM6IEZpbHRlclJvd1tdID0gW107XHJcbiAgZmlsdGVyQ29tYmluYXRvcjogJ0FORCcgfCAnT1InID0gJ0FORCc7XHJcblxyXG4gIHNlbGVjdGlvbk1vZGU6ICdhbGwnIHwgJ2ZpcnN0TicgPSAnZmlyc3ROJztcclxuICBsaW1pdFBlclN0b3JlOiBudW1iZXIgPSAxO1xyXG5cclxuICBvdXRwdXRDb2x1bW5zOiBDb2x1bW5TZWxlY3Rpb25bXSA9IFtdO1xyXG5cclxuICBpbmNsdWRlTm90Rm91bmRSb3dzOiBib29sZWFuID0gdHJ1ZTtcclxuXHJcbiAgaXNSdW5uaW5nOiBib29sZWFuID0gZmFsc2U7XHJcbiAgcmVzdWx0OiBRdWVyeVJlc3VsdCB8IG51bGwgPSBudWxsO1xyXG4gIHJlc3VsdENvbHVtbnM6IHsga2V5OiBzdHJpbmc7IGxhYmVsOiBzdHJpbmcgfVtdID0gW107XHJcblxyXG4gIG1lc3NhZ2U6IHN0cmluZyA9ICcnO1xyXG4gIG1lc3NhZ2VUeXBlOiAnc3VjY2VzcycgfCAnZXJyb3InID0gJ3N1Y2Nlc3MnO1xyXG5cclxuICBwYWdpbmF0aW9uU2l6ZXM6IG51bWJlcltdID0gWzI1LCA1MCwgMTAwLCAyMDBdO1xyXG4gIHBhZ2VTaXplOiBudW1iZXIgPSA1MDtcclxuICBjdXJyZW50UGFnZTogbnVtYmVyID0gMTtcclxuXHJcbiAgLy8gVk0gUGxhY2VtZW50IEV4cG9ydCBieSBWTSBOYW1lXHJcbiAgdm1TZWxlY3RlZFN0b3JlczogU3RvcmVPcHRpb25bXSA9IFtdO1xyXG4gIHZtSW5pdGlhbFN0b3JlczogU3RvcmVPcHRpb25bXSA9IFtdO1xyXG4gIHZtTmFtZVJlZ2V4OiBzdHJpbmcgPSAnJztcclxuICBpc1ZtUnVubmluZzogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIHZtUmVzdWx0OiBWbVBsYWNlbWVudFJlc3VsdCB8IG51bGwgPSBudWxsO1xyXG4gIHZtUmVzdWx0Q29sdW1uczogc3RyaW5nW10gPSBbXTtcclxuICB2bVBhZ2VTaXplOiBudW1iZXIgPSA1MDtcclxuICB2bUN1cnJlbnRQYWdlOiBudW1iZXIgPSAxO1xyXG4gIHZtTWVzc2FnZTogc3RyaW5nID0gJyc7XHJcbiAgdm1NZXNzYWdlVHlwZTogJ3N1Y2Nlc3MnIHwgJ2Vycm9yJyA9ICdzdWNjZXNzJztcclxuXHJcbiAgcHJpdmF0ZSByZWFkb25seSBkZXN0cm95JCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJpdmF0ZSBzYnM6IFN0b3JlQnVpbGRlclNlcnZpY2UsXHJcbiAgICBwcml2YXRlIGdzOiBHbG9iYWxTdGF0ZVNlcnZpY2UsXHJcbiAgKSB7fVxyXG5cclxuICBuZ09uSW5pdCgpOiB2b2lkIHtcclxuICAgIHRoaXMuZ3MuZGF0YVJhbmdlVmFsdWVcclxuICAgICAgLnBpcGUoXHJcbiAgICAgICAgdGFrZVVudGlsKHRoaXMuZGVzdHJveSQpLFxyXG4gICAgICAgIGRlYm91bmNlVGltZSgyMDApLFxyXG4gICAgICAgIGZpbHRlcigoZGF0YSkgPT4gISFkYXRhKSxcclxuICAgICAgICBkaXN0aW5jdFVudGlsQ2hhbmdlZCgpLFxyXG4gICAgICApXHJcbiAgICAgIC5zdWJzY3JpYmUoKGRhdGE6IGFueSkgPT4ge1xyXG4gICAgICAgIGlmIChkYXRhPy5jbGllbnQpIHtcclxuICAgICAgICAgIHRoaXMuY2xpZW50SWQgPSBkYXRhLmNsaWVudDtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgbGV0IGhlYWRlckRhdGEgPSBKU09OLnBhcnNlKFxyXG4gICAgICAgICAgICBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSgnaGVhZGVyLWZpbHRlcnMnKSBhcyBzdHJpbmcsXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgICAgdGhpcy5jbGllbnRJZCA9IGhlYWRlckRhdGE/LmNsaWVudDtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5sb2FkU3RvcmVzKCk7XHJcbiAgICAgIH0pO1xyXG5cclxuICAgIHRoaXMubG9hZFNjaGVtYSgpO1xyXG4gIH1cclxuXHJcbiAgbG9hZFN0b3JlcygpIHtcclxuICAgIHRoaXMuc2JzLmdldFN0b3JlT3JDbHVzdGVyTGlzdCh7IHNlYXJjaE1vZGU6ICdzdG9yZScgfSkuc3Vic2NyaWJlKChyZXM6IGFueSkgPT4ge1xyXG4gICAgICBpZiAocmVzPy5kYXRhKSB7XHJcbiAgICAgICAgdGhpcy5zdG9yZU9wdGlvbnMgPSByZXMuZGF0YTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBsb2FkU2NoZW1hKCkge1xyXG4gICAgdGhpcy5pc0xvYWRpbmdTY2hlbWEgPSB0cnVlO1xyXG4gICAgdGhpcy5zYnMuZ2V0UGxhbm9EYXRhU2NoZW1hKCkuc3Vic2NyaWJlKHtcclxuICAgICAgbmV4dDogKHJlczogYW55KSA9PiB7XHJcbiAgICAgICAgdGhpcy5maWVsZHMgPSByZXM/LmRhdGE/LmZpZWxkcyB8fCBbXTtcclxuICAgICAgICB0aGlzLm9wZXJhdG9yc0J5VHlwZSA9IHJlcz8uZGF0YT8ub3BlcmF0b3JzQnlUeXBlIHx8IHt9O1xyXG5cclxuICAgICAgICBsZXQgb3V0cHV0RmllbGRzID0gdGhpcy5maWVsZHMuZmlsdGVyKChmKSA9PiBmLm91dHB1dCk7XHJcbiAgICAgICAgbGV0IGJ5S2V5ID0gbmV3IE1hcChvdXRwdXRGaWVsZHMubWFwKChmKSA9PiBbZi5rZXksIGZdKSk7XHJcblxyXG4gICAgICAgIGxldCBvcmRlcmVkOiB7IGtleTogc3RyaW5nOyBsYWJlbDogc3RyaW5nIH1bXSA9IFtdO1xyXG4gICAgICAgIGZvciAobGV0IGVudHJ5IG9mIE9VVFBVVF9DT0xVTU5fT1JERVIpIHtcclxuICAgICAgICAgIGxldCBmID0gYnlLZXkuZ2V0KGVudHJ5LmtleSk7XHJcbiAgICAgICAgICBvcmRlcmVkLnB1c2goe1xyXG4gICAgICAgICAgICBrZXk6IGVudHJ5LmtleSxcclxuICAgICAgICAgICAgbGFiZWw6IGY/LmxhYmVsIHx8IGVudHJ5LmxhYmVsLFxyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgICBieUtleS5kZWxldGUoZW50cnkua2V5KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZm9yIChsZXQgZiBvZiBieUtleS52YWx1ZXMoKSkgb3JkZXJlZC5wdXNoKHsga2V5OiBmLmtleSwgbGFiZWw6IGYubGFiZWwgfSk7XHJcblxyXG4gICAgICAgIHRoaXMub3V0cHV0Q29sdW1ucyA9IG9yZGVyZWQubWFwKChmKSA9PiAoe1xyXG4gICAgICAgICAga2V5OiBmLmtleSxcclxuICAgICAgICAgIGxhYmVsOiBmLmxhYmVsLFxyXG4gICAgICAgICAgc2VsZWN0ZWQ6IHRoaXMuZGVmYXVsdFNlbGVjdGVkKGYua2V5KSxcclxuICAgICAgICB9KSk7XHJcbiAgICAgICAgdGhpcy5pc0xvYWRpbmdTY2hlbWEgPSBmYWxzZTtcclxuICAgICAgfSxcclxuICAgICAgZXJyb3I6ICgpID0+IHtcclxuICAgICAgICB0aGlzLmZpZWxkcyA9IFtdO1xyXG4gICAgICAgIHRoaXMub3BlcmF0b3JzQnlUeXBlID0ge307XHJcbiAgICAgICAgdGhpcy5vdXRwdXRDb2x1bW5zID0gW107XHJcbiAgICAgICAgdGhpcy5pc0xvYWRpbmdTY2hlbWEgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLnNob3dNZXNzYWdlKCdGYWlsZWQgdG8gbG9hZCBxdWVyeSBzY2hlbWEuJywgJ2Vycm9yJyk7XHJcbiAgICAgIH0sXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZGVmYXVsdFNlbGVjdGVkKGtleTogc3RyaW5nKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gW1xyXG4gICAgICAnc3RvcmVOYW1lJyxcclxuICAgICAgJ2ZpeHR1cmVDYXRlZ29yeScsXHJcbiAgICAgICdmaXh0dXJlV2lkdGgnLFxyXG4gICAgICAnZml4dHVyZU51bWJlcicsXHJcbiAgICAgICdmaXh0dXJlVHlwZScsXHJcbiAgICAgICdoZWFkZXJMYWJlbCcsXHJcbiAgICAgICd3YWxsTnVtYmVyJyxcclxuICAgICAgJ3dhbGxGaXh0dXJlTnVtYmVyJyxcclxuICAgICAgJ3ZtTmFtZXMnLFxyXG4gICAgICAncG9zaXRpb25MYWJlbCcsXHJcbiAgICAgICdzdGFuZGFyZENhcGFjaXR5JyxcclxuICAgIF0uaW5jbHVkZXMoa2V5KTtcclxuICB9XHJcblxyXG4gIGdldCBmaWx0ZXJhYmxlRmllbGRzKCk6IEZpZWxkRGVmW10ge1xyXG4gICAgcmV0dXJuIHRoaXMuZmllbGRzLmZpbHRlcigoZikgPT4gZi5maWx0ZXJhYmxlKTtcclxuICB9XHJcblxyXG4gIG9wZXJhdG9yc0ZvckZpZWxkKGZpZWxkS2V5OiBzdHJpbmcpOiBPcGVyYXRvckRlZltdIHtcclxuICAgIGxldCBmID0gdGhpcy5maWVsZHMuZmluZCgoeCkgPT4geC5rZXkgPT09IGZpZWxkS2V5KTtcclxuICAgIGlmICghZikgcmV0dXJuIFtdO1xyXG4gICAgcmV0dXJuIHRoaXMub3BlcmF0b3JzQnlUeXBlW2YudHlwZV0gfHwgW107XHJcbiAgfVxyXG5cclxuICBpc1ZhbHVlRGlzYWJsZWRGb3Iob3BlcmF0b3I6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIG9wZXJhdG9yID09PSAnZXhpc3RzJyB8fCBvcGVyYXRvciA9PT0gJ25vdEV4aXN0cyc7XHJcbiAgfVxyXG5cclxuICBvblN0b3Jlc1NlbGVjdGVkKHN0b3JlczogU3RvcmVPcHRpb25bXSkge1xyXG4gICAgdGhpcy5zZWxlY3RlZFN0b3JlcyA9IHN0b3JlcztcclxuICB9XHJcblxyXG4gIGFkZEZpbHRlcigpIHtcclxuICAgIGxldCBmaXJzdEZpZWxkID0gdGhpcy5maWx0ZXJhYmxlRmllbGRzWzBdO1xyXG4gICAgaWYgKCFmaXJzdEZpZWxkKSByZXR1cm47XHJcbiAgICBsZXQgZmlyc3RPcCA9IHRoaXMub3BlcmF0b3JzQnlUeXBlW2ZpcnN0RmllbGQudHlwZV0/LlswXTtcclxuICAgIHRoaXMuZmlsdGVycy5wdXNoKHtcclxuICAgICAgZmllbGQ6IGZpcnN0RmllbGQua2V5LFxyXG4gICAgICBvcGVyYXRvcjogZmlyc3RPcD8ua2V5IHx8ICdlcXVhbHMnLFxyXG4gICAgICB2YWx1ZTogJycsXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHJlbW92ZUZpbHRlcihpZHg6IG51bWJlcikge1xyXG4gICAgdGhpcy5maWx0ZXJzLnNwbGljZShpZHgsIDEpO1xyXG4gIH1cclxuXHJcbiAgb25GaWx0ZXJGaWVsZENoYW5nZShpZHg6IG51bWJlcikge1xyXG4gICAgbGV0IHJvdyA9IHRoaXMuZmlsdGVyc1tpZHhdO1xyXG4gICAgbGV0IGFsbG93ZWQgPSB0aGlzLm9wZXJhdG9yc0ZvckZpZWxkKHJvdy5maWVsZCk7XHJcbiAgICBpZiAoIWFsbG93ZWQuZmluZCgob3ApID0+IG9wLmtleSA9PT0gcm93Lm9wZXJhdG9yKSkge1xyXG4gICAgICByb3cub3BlcmF0b3IgPSBhbGxvd2VkWzBdPy5rZXkgfHwgJ2VxdWFscyc7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBzZWxlY3RBbGxDb2x1bW5zKCkge1xyXG4gICAgdGhpcy5vdXRwdXRDb2x1bW5zLmZvckVhY2goKGMpID0+IChjLnNlbGVjdGVkID0gdHJ1ZSkpO1xyXG4gIH1cclxuXHJcbiAgY2xlYXJBbGxDb2x1bW5zKCkge1xyXG4gICAgdGhpcy5vdXRwdXRDb2x1bW5zLmZvckVhY2goKGMpID0+IChjLnNlbGVjdGVkID0gZmFsc2UpKTtcclxuICB9XHJcblxyXG4gIGdldCBzZWxlY3RlZENvbHVtbnMoKTogQ29sdW1uU2VsZWN0aW9uW10ge1xyXG4gICAgcmV0dXJuIHRoaXMub3V0cHV0Q29sdW1ucy5maWx0ZXIoKGMpID0+IGMuc2VsZWN0ZWQpO1xyXG4gIH1cclxuXHJcbiAgZ2V0IHRvdGFsUm93cygpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMucmVzdWx0Py5yb3dzLmxlbmd0aCB8fCAwO1xyXG4gIH1cclxuXHJcbiAgZ2V0IHBhZ2VkUm93cygpOiBSZWNvcmQ8c3RyaW5nLCBhbnk+W10ge1xyXG4gICAgaWYgKCF0aGlzLnJlc3VsdCkgcmV0dXJuIFtdO1xyXG4gICAgbGV0IHN0YXJ0ID0gKHRoaXMuY3VycmVudFBhZ2UgLSAxKSAqIHRoaXMucGFnZVNpemU7XHJcbiAgICByZXR1cm4gdGhpcy5yZXN1bHQucm93cy5zbGljZShzdGFydCwgc3RhcnQgKyB0aGlzLnBhZ2VTaXplKTtcclxuICB9XHJcblxyXG4gIGdldCBwYWdlU3RhcnQoKTogbnVtYmVyIHtcclxuICAgIGlmICghdGhpcy50b3RhbFJvd3MpIHJldHVybiAwO1xyXG4gICAgcmV0dXJuICh0aGlzLmN1cnJlbnRQYWdlIC0gMSkgKiB0aGlzLnBhZ2VTaXplICsgMTtcclxuICB9XHJcblxyXG4gIGdldCBwYWdlRW5kKCk6IG51bWJlciB7XHJcbiAgICByZXR1cm4gTWF0aC5taW4odGhpcy5jdXJyZW50UGFnZSAqIHRoaXMucGFnZVNpemUsIHRoaXMudG90YWxSb3dzKTtcclxuICB9XHJcblxyXG4gIG9uUGFnZUNoYW5nZShwYWdlOiBudW1iZXIpIHtcclxuICAgIHRoaXMuY3VycmVudFBhZ2UgPSBOdW1iZXIocGFnZSkgfHwgMTtcclxuICB9XHJcblxyXG4gIG9uUGFnZVNpemVDaGFuZ2Uoc2l6ZTogbnVtYmVyKSB7XHJcbiAgICB0aGlzLnBhZ2VTaXplID0gTnVtYmVyKHNpemUpIHx8IDUwO1xyXG4gICAgdGhpcy5jdXJyZW50UGFnZSA9IDE7XHJcbiAgfVxyXG5cclxuICBvblJ1bigpIHtcclxuICAgIGlmICh0aGlzLnNlbGVjdGVkU3RvcmVzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICB0aGlzLnNob3dNZXNzYWdlKCdQbGVhc2Ugc2VsZWN0IGF0IGxlYXN0IG9uZSBzdG9yZS4nLCAnZXJyb3InKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRDb2x1bW5zLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICB0aGlzLnNob3dNZXNzYWdlKCdQbGVhc2Ugc2VsZWN0IGF0IGxlYXN0IG9uZSBvdXRwdXQgY29sdW1uLicsICdlcnJvcicpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5zZWxlY3Rpb25Nb2RlID09PSAnZmlyc3ROJykge1xyXG4gICAgICBsZXQgbiA9IE51bWJlcih0aGlzLmxpbWl0UGVyU3RvcmUpO1xyXG4gICAgICBpZiAoIU51bWJlci5pc0Zpbml0ZShuKSB8fCBuIDwgMSkge1xyXG4gICAgICAgIHRoaXMuc2hvd01lc3NhZ2UoXHJcbiAgICAgICAgICAnTnVtYmVyIG9mIGZpeHR1cmVzIHBlciBzdG9yZSBtdXN0IGJlIGEgcG9zaXRpdmUgaW50ZWdlci4nLFxyXG4gICAgICAgICAgJ2Vycm9yJyxcclxuICAgICAgICApO1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGxldCBjb2x1bW5zU25hcHNob3QgPSB0aGlzLnNlbGVjdGVkQ29sdW1ucy5tYXAoKGMpID0+ICh7XHJcbiAgICAgIGtleTogYy5rZXksXHJcbiAgICAgIGxhYmVsOiBjLmxhYmVsLFxyXG4gICAgfSkpO1xyXG5cclxuICAgIGxldCBwYXlsb2FkID0ge1xyXG4gICAgICBjbGllbnRJZDogdGhpcy5jbGllbnRJZCxcclxuICAgICAgc3RvcmVOYW1lczogdGhpcy5zZWxlY3RlZFN0b3Jlcy5tYXAoKHMpID0+IHMubGFiZWwpLFxyXG4gICAgICBmaWx0ZXJzOiB0aGlzLmZpbHRlcnNcclxuICAgICAgICAuZmlsdGVyKChmKSA9PiBmLmZpZWxkICYmIGYub3BlcmF0b3IpXHJcbiAgICAgICAgLm1hcCgoZikgPT4gKHtcclxuICAgICAgICAgIGZpZWxkOiBmLmZpZWxkLFxyXG4gICAgICAgICAgb3BlcmF0b3I6IGYub3BlcmF0b3IsXHJcbiAgICAgICAgICB2YWx1ZTogdGhpcy5pc1ZhbHVlRGlzYWJsZWRGb3IoZi5vcGVyYXRvcikgPyAnJyA6IGYudmFsdWUsXHJcbiAgICAgICAgfSkpLFxyXG4gICAgICBmaWx0ZXJDb21iaW5hdG9yOiB0aGlzLmZpbHRlckNvbWJpbmF0b3IsXHJcbiAgICAgIHNlbGVjdGlvbk1vZGU6IHRoaXMuc2VsZWN0aW9uTW9kZSxcclxuICAgICAgbGltaXRQZXJTdG9yZTpcclxuICAgICAgICB0aGlzLnNlbGVjdGlvbk1vZGUgPT09ICdmaXJzdE4nID8gTnVtYmVyKHRoaXMubGltaXRQZXJTdG9yZSkgOiB1bmRlZmluZWQsXHJcbiAgICAgIGNvbHVtbnM6IGNvbHVtbnNTbmFwc2hvdCxcclxuICAgICAgaW5jbHVkZU5vdEZvdW5kUm93czogdGhpcy5pbmNsdWRlTm90Rm91bmRSb3dzLFxyXG4gICAgfTtcclxuXHJcbiAgICB0aGlzLmlzUnVubmluZyA9IHRydWU7XHJcbiAgICB0aGlzLnJlc3VsdCA9IG51bGw7XHJcbiAgICB0aGlzLnJlc3VsdENvbHVtbnMgPSBjb2x1bW5zU25hcHNob3Q7XHJcbiAgICB0aGlzLmN1cnJlbnRQYWdlID0gMTtcclxuICAgIHRoaXMuc2JzLnJ1blBsYW5vRGF0YVF1ZXJ5KHBheWxvYWQpLnN1YnNjcmliZSh7XHJcbiAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xyXG4gICAgICAgIHRoaXMucmVzdWx0ID0gcmVzPy5kYXRhIHx8IG51bGw7XHJcbiAgICAgICAgdGhpcy5pc1J1bm5pbmcgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLmN1cnJlbnRQYWdlID0gMTtcclxuICAgICAgICBpZiAodGhpcy5yZXN1bHQpIHtcclxuICAgICAgICAgIHRoaXMuc2hvd01lc3NhZ2UoYEZvdW5kICR7dGhpcy5yZXN1bHQudG90YWxSb3dzfSByb3cocykuYCwgJ3N1Y2Nlc3MnKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0sXHJcbiAgICAgIGVycm9yOiAoZXJyOiBhbnkpID0+IHtcclxuICAgICAgICB0aGlzLnNob3dNZXNzYWdlKFxyXG4gICAgICAgICAgZXJyPy5lcnJvcj8ubWVzc2FnZSB8fCAnRmFpbGVkIHRvIHJ1biBxdWVyeS4nLFxyXG4gICAgICAgICAgJ2Vycm9yJyxcclxuICAgICAgICApO1xyXG4gICAgICAgIHRoaXMuaXNSdW5uaW5nID0gZmFsc2U7XHJcbiAgICAgIH0sXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIG9uRXhwb3J0KCkge1xyXG4gICAgaWYgKCF0aGlzLnJlc3VsdCB8fCAhdGhpcy5yZXN1bHQucm93cy5sZW5ndGgpIHtcclxuICAgICAgdGhpcy5zaG93TWVzc2FnZSgnTm8gZGF0YSB0byBleHBvcnQuIFJ1biB0aGUgcXVlcnkgZmlyc3QuJywgJ2Vycm9yJyk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGxldCBjbGVhbmVkID0gdGhpcy5yZXN1bHQucm93cy5tYXAoKHIpID0+IHtcclxuICAgICAgbGV0IGNvcHk6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcclxuICAgICAgZm9yIChsZXQgY29sIG9mIHRoaXMucmVzdWx0Q29sdW1ucykgY29weVtjb2wubGFiZWxdID0gcltjb2wubGFiZWxdID8/ICcnO1xyXG4gICAgICByZXR1cm4gY29weTtcclxuICAgIH0pO1xyXG4gICAgbGV0IGZpbGVOYW1lID0gYHBsYW5vX2RhdGFfZXhwb3J0XyR7RGF0ZS5ub3coKX1gO1xyXG4gICAgdGhpcy5zYnMuZXhwb3J0QXNFeGNlbEZpbGUoY2xlYW5lZCwgZmlsZU5hbWUpO1xyXG4gIH1cclxuXHJcbiAgc2hvd01lc3NhZ2UobXNnOiBzdHJpbmcsIHR5cGU6ICdzdWNjZXNzJyB8ICdlcnJvcicpIHtcclxuICAgIHRoaXMubWVzc2FnZSA9IG1zZztcclxuICAgIHRoaXMubWVzc2FnZVR5cGUgPSB0eXBlO1xyXG4gICAgc2V0VGltZW91dCgoKSA9PiAodGhpcy5tZXNzYWdlID0gJycpLCA1MDAwKTtcclxuICB9XHJcblxyXG4gIC8vIC0tLS0tLS0tLS0gVk0gUGxhY2VtZW50IEV4cG9ydCAtLS0tLS0tLS0tXHJcblxyXG4gIG9uVm1TdG9yZXNTZWxlY3RlZChzdG9yZXM6IFN0b3JlT3B0aW9uW10pIHtcclxuICAgIHRoaXMudm1TZWxlY3RlZFN0b3JlcyA9IHN0b3JlcztcclxuICB9XHJcblxyXG4gIGdldCB2bVRvdGFsUm93cygpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIHRoaXMudm1SZXN1bHQ/LnJvd3MubGVuZ3RoIHx8IDA7XHJcbiAgfVxyXG5cclxuICBnZXQgdm1QYWdlZFJvd3MoKTogUmVjb3JkPHN0cmluZywgYW55PltdIHtcclxuICAgIGlmICghdGhpcy52bVJlc3VsdCkgcmV0dXJuIFtdO1xyXG4gICAgbGV0IHN0YXJ0ID0gKHRoaXMudm1DdXJyZW50UGFnZSAtIDEpICogdGhpcy52bVBhZ2VTaXplO1xyXG4gICAgcmV0dXJuIHRoaXMudm1SZXN1bHQucm93cy5zbGljZShzdGFydCwgc3RhcnQgKyB0aGlzLnZtUGFnZVNpemUpO1xyXG4gIH1cclxuXHJcbiAgZ2V0IHZtUGFnZVN0YXJ0KCk6IG51bWJlciB7XHJcbiAgICBpZiAoIXRoaXMudm1Ub3RhbFJvd3MpIHJldHVybiAwO1xyXG4gICAgcmV0dXJuICh0aGlzLnZtQ3VycmVudFBhZ2UgLSAxKSAqIHRoaXMudm1QYWdlU2l6ZSArIDE7XHJcbiAgfVxyXG5cclxuICBnZXQgdm1QYWdlRW5kKCk6IG51bWJlciB7XHJcbiAgICByZXR1cm4gTWF0aC5taW4odGhpcy52bUN1cnJlbnRQYWdlICogdGhpcy52bVBhZ2VTaXplLCB0aGlzLnZtVG90YWxSb3dzKTtcclxuICB9XHJcblxyXG4gIG9uVm1QYWdlQ2hhbmdlKHBhZ2U6IG51bWJlcikge1xyXG4gICAgdGhpcy52bUN1cnJlbnRQYWdlID0gTnVtYmVyKHBhZ2UpIHx8IDE7XHJcbiAgfVxyXG5cclxuICBvblZtUGFnZVNpemVDaGFuZ2Uoc2l6ZTogbnVtYmVyKSB7XHJcbiAgICB0aGlzLnZtUGFnZVNpemUgPSBOdW1iZXIoc2l6ZSkgfHwgNTA7XHJcbiAgICB0aGlzLnZtQ3VycmVudFBhZ2UgPSAxO1xyXG4gIH1cclxuXHJcbiAgb25WbVJ1bigpIHtcclxuICAgIGlmICh0aGlzLnZtU2VsZWN0ZWRTdG9yZXMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgIHRoaXMuc2hvd1ZtTWVzc2FnZSgnUGxlYXNlIHNlbGVjdCBhdCBsZWFzdCBvbmUgc3RvcmUuJywgJ2Vycm9yJyk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGlmICghdGhpcy52bU5hbWVSZWdleCB8fCAhdGhpcy52bU5hbWVSZWdleC50cmltKCkpIHtcclxuICAgICAgdGhpcy5zaG93Vm1NZXNzYWdlKCdQbGVhc2UgZW50ZXIgYSBWTSBuYW1lIChyZWdleCkuJywgJ2Vycm9yJyk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBsZXQgcGF5bG9hZCA9IHtcclxuICAgICAgY2xpZW50SWQ6IHRoaXMuY2xpZW50SWQsXHJcbiAgICAgIHN0b3JlTmFtZXM6IHRoaXMudm1TZWxlY3RlZFN0b3Jlcy5tYXAoKHMpID0+IHMubGFiZWwpLFxyXG4gICAgICB2bU5hbWU6IHRoaXMudm1OYW1lUmVnZXgudHJpbSgpLFxyXG4gICAgfTtcclxuXHJcbiAgICB0aGlzLmlzVm1SdW5uaW5nID0gdHJ1ZTtcclxuICAgIHRoaXMudm1SZXN1bHQgPSBudWxsO1xyXG4gICAgdGhpcy52bUN1cnJlbnRQYWdlID0gMTtcclxuICAgIHRoaXMuc2JzLnJ1blZtUGxhY2VtZW50UXVlcnkocGF5bG9hZCkuc3Vic2NyaWJlKHtcclxuICAgICAgbmV4dDogKHJlczogYW55KSA9PiB7XHJcbiAgICAgICAgdGhpcy52bVJlc3VsdCA9IHJlcz8uZGF0YSB8fCBudWxsO1xyXG4gICAgICAgIHRoaXMudm1SZXN1bHRDb2x1bW5zID0gdGhpcy52bVJlc3VsdD8uY29sdW1ucyB8fCBbXTtcclxuICAgICAgICB0aGlzLmlzVm1SdW5uaW5nID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy52bUN1cnJlbnRQYWdlID0gMTtcclxuICAgICAgICBpZiAodGhpcy52bVJlc3VsdCkge1xyXG4gICAgICAgICAgdGhpcy5zaG93Vm1NZXNzYWdlKFxyXG4gICAgICAgICAgICBgTWF0Y2hlZCAke3RoaXMudm1SZXN1bHQubWF0Y2hlZFZtQ291bnR9IFZNKHMpOyBmb3VuZCAke3RoaXMudm1SZXN1bHQudG90YWxSb3dzfSBwbGFjZW1lbnQgcm93KHMpLmAsXHJcbiAgICAgICAgICAgICdzdWNjZXNzJyxcclxuICAgICAgICAgICk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9LFxyXG4gICAgICBlcnJvcjogKGVycjogYW55KSA9PiB7XHJcbiAgICAgICAgdGhpcy5zaG93Vm1NZXNzYWdlKFxyXG4gICAgICAgICAgZXJyPy5lcnJvcj8ubWVzc2FnZSB8fCAnRmFpbGVkIHRvIHJ1biBWTSBwbGFjZW1lbnQgcXVlcnkuJyxcclxuICAgICAgICAgICdlcnJvcicsXHJcbiAgICAgICAgKTtcclxuICAgICAgICB0aGlzLmlzVm1SdW5uaW5nID0gZmFsc2U7XHJcbiAgICAgIH0sXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIG9uVm1FeHBvcnQoKSB7XHJcbiAgICBpZiAoIXRoaXMudm1SZXN1bHQgfHwgIXRoaXMudm1SZXN1bHQucm93cy5sZW5ndGgpIHtcclxuICAgICAgdGhpcy5zaG93Vm1NZXNzYWdlKCdObyBkYXRhIHRvIGV4cG9ydC4gUnVuIHRoZSBxdWVyeSBmaXJzdC4nLCAnZXJyb3InKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgbGV0IGNsZWFuZWQgPSB0aGlzLnZtUmVzdWx0LnJvd3MubWFwKChyKSA9PiB7XHJcbiAgICAgIGxldCBjb3B5OiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XHJcbiAgICAgIGZvciAobGV0IGNvbCBvZiB0aGlzLnZtUmVzdWx0Q29sdW1ucykgY29weVtjb2xdID0gcltjb2xdID8/ICcnO1xyXG4gICAgICByZXR1cm4gY29weTtcclxuICAgIH0pO1xyXG4gICAgbGV0IHNhZmVOYW1lID0gKHRoaXMudm1OYW1lUmVnZXggfHwgJ3ZtJylcclxuICAgICAgLnRyaW0oKVxyXG4gICAgICAucmVwbGFjZSgvW15hLXowLTldKy9naSwgJ18nKVxyXG4gICAgICAudG9Mb3dlckNhc2UoKTtcclxuICAgIGxldCBmaWxlTmFtZSA9IGB2bV9wbGFjZW1lbnRfJHtzYWZlTmFtZX1fJHtEYXRlLm5vdygpfWA7XHJcbiAgICB0aGlzLnNicy5leHBvcnRBc0V4Y2VsRmlsZShjbGVhbmVkLCBmaWxlTmFtZSk7XHJcbiAgfVxyXG5cclxuICBzaG93Vm1NZXNzYWdlKG1zZzogc3RyaW5nLCB0eXBlOiAnc3VjY2VzcycgfCAnZXJyb3InKSB7XHJcbiAgICB0aGlzLnZtTWVzc2FnZSA9IG1zZztcclxuICAgIHRoaXMudm1NZXNzYWdlVHlwZSA9IHR5cGU7XHJcbiAgICBzZXRUaW1lb3V0KCgpID0+ICh0aGlzLnZtTWVzc2FnZSA9ICcnKSwgNTAwMCk7XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuICAgIHRoaXMuZGVzdHJveSQubmV4dCgpO1xyXG4gICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xyXG4gIH1cclxufVxyXG4iLCI8c2VjdGlvbiBjbGFzcz1cInBsYW5vLWRhdGEtZXhwb3J0IHAtM1wiPlxyXG4gIDxkaXYgY2xhc3M9XCJjYXJkIHAtNCBtYi0zXCI+XHJcbiAgICA8aDUgY2xhc3M9XCJtYi0xXCI+UGxhbm8gRGF0YSBFeHBvcnQ8L2g1PlxyXG4gICAgPHAgY2xhc3M9XCJ0ZXh0LW11dGVkIHNtYWxsIG1iLTNcIj5cclxuICAgICAgQnVpbGQgYSBxdWVyeSBhZ2FpbnN0IHBsYW5vZ3JhbSBmaXh0dXJlcywgcHJldmlldyByZXN1bHRzLCBhbmQgZXhwb3J0IGFzIEV4Y2VsLlxyXG4gICAgPC9wPlxyXG5cclxuICAgIEBpZiAoaXNMb2FkaW5nU2NoZW1hKSB7XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW11dGVkIHNtYWxsXCI+TG9hZGluZyBxdWVyeSBzY2hlbWEuLi48L2Rpdj5cclxuICAgIH1cclxuXHJcbiAgICA8IS0tIFN0b3JlcyAtLT5cclxuICAgIDxkaXYgY2xhc3M9XCJibG9jayBtYi0zXCI+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJibG9jay10aXRsZVwiPlN0b3JlczwvZGl2PlxyXG4gICAgICA8bGliLXN0b3JlLXNlbGVjdFxyXG4gICAgICAgIFtvcHRpb25zXT1cInN0b3JlT3B0aW9uc1wiXHJcbiAgICAgICAgW2luaXRpYWxTZWxlY3RlZF09XCJpbml0aWFsU3RvcmVzXCJcclxuICAgICAgICAoc2VsZWN0ZWRDaGFuZ2UpPVwib25TdG9yZXNTZWxlY3RlZCgkZXZlbnQpXCI+XHJcbiAgICAgIDwvbGliLXN0b3JlLXNlbGVjdD5cclxuICAgIDwvZGl2PlxyXG5cclxuICAgIDwhLS0gTWF0Y2ggQ3JpdGVyaWEgLS0+XHJcbiAgICA8ZGl2IGNsYXNzPVwiYmxvY2sgbWItM1wiPlxyXG4gICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBtYi0yXCI+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cImJsb2NrLXRpdGxlIG1iLTBcIj5NYXRjaCBDcml0ZXJpYTwvZGl2PlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGdhcC0zXCI+XHJcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1jaGVjayBmb3JtLWNoZWNrLWlubGluZSBtYi0wXCI+XHJcbiAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIiB0eXBlPVwicmFkaW9cIiBpZD1cImNvbWJBbmRcIlxyXG4gICAgICAgICAgICAgIG5hbWU9XCJjb21iaW5hdG9yXCIgdmFsdWU9XCJBTkRcIiBbKG5nTW9kZWwpXT1cImZpbHRlckNvbWJpbmF0b3JcIj5cclxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1jaGVjay1sYWJlbFwiIGZvcj1cImNvbWJBbmRcIj5NYXRjaCBhbGwgKEFORCk8L2xhYmVsPlxyXG4gICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1jaGVjayBmb3JtLWNoZWNrLWlubGluZSBtYi0wXCI+XHJcbiAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIiB0eXBlPVwicmFkaW9cIiBpZD1cImNvbWJPclwiXHJcbiAgICAgICAgICAgICAgbmFtZT1cImNvbWJpbmF0b3JcIiB2YWx1ZT1cIk9SXCIgWyhuZ01vZGVsKV09XCJmaWx0ZXJDb21iaW5hdG9yXCI+XHJcbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tY2hlY2stbGFiZWxcIiBmb3I9XCJjb21iT3JcIj5NYXRjaCBhbnkgKE9SKTwvbGFiZWw+XHJcbiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgPC9kaXY+XHJcblxyXG4gICAgICBAaWYgKCFmaWx0ZXJzLmxlbmd0aCkge1xyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW11dGVkIHNtYWxsIG1iLTJcIj5cclxuICAgICAgICAgIE5vIGNyaXRlcmlhIOKAlCBxdWVyeSB3aWxsIHJldHVybiBldmVyeSBmaXh0dXJlIGZvciB0aGUgc2VsZWN0ZWQgc3RvcmVzLlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICB9XHJcblxyXG4gICAgICBAZm9yIChyb3cgb2YgZmlsdGVyczsgdHJhY2sgJGluZGV4KSB7XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cImZpbHRlci1yb3cgZC1mbGV4IGdhcC0yIG1iLTIgYWxpZ24taXRlbXMtY2VudGVyXCI+XHJcbiAgICAgICAgICA8c2VsZWN0IGNsYXNzPVwiZm9ybS1zZWxlY3QgZm9ybS1zZWxlY3Qtc20gZmlsdGVyLWZpZWxkXCJcclxuICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJyb3cuZmllbGRcIlxyXG4gICAgICAgICAgICAoY2hhbmdlKT1cIm9uRmlsdGVyRmllbGRDaGFuZ2UoJGluZGV4KVwiPlxyXG4gICAgICAgICAgICBAZm9yIChmIG9mIGZpbHRlcmFibGVGaWVsZHM7IHRyYWNrIGYua2V5KSB7XHJcbiAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwiZi5rZXlcIj57eyBmLmxhYmVsIH19PC9vcHRpb24+XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIDwvc2VsZWN0PlxyXG5cclxuICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJmb3JtLXNlbGVjdCBmb3JtLXNlbGVjdC1zbSBmaWx0ZXItb3BcIlxyXG4gICAgICAgICAgICBbKG5nTW9kZWwpXT1cInJvdy5vcGVyYXRvclwiPlxyXG4gICAgICAgICAgICBAZm9yIChvcCBvZiBvcGVyYXRvcnNGb3JGaWVsZChyb3cuZmllbGQpOyB0cmFjayBvcC5rZXkpIHtcclxuICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCJvcC5rZXlcIj57eyBvcC5sYWJlbCB9fTwvb3B0aW9uPlxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICA8L3NlbGVjdD5cclxuXHJcbiAgICAgICAgICA8aW5wdXRcclxuICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZm9ybS1jb250cm9sLXNtIGZpbHRlci12YWx1ZVwiXHJcbiAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJpc1ZhbHVlRGlzYWJsZWRGb3Iocm93Lm9wZXJhdG9yKSA/ICfigJQnIDogJ3ZhbHVlJ1wiXHJcbiAgICAgICAgICAgIFtkaXNhYmxlZF09XCJpc1ZhbHVlRGlzYWJsZWRGb3Iocm93Lm9wZXJhdG9yKVwiXHJcbiAgICAgICAgICAgIFsobmdNb2RlbCldPVwicm93LnZhbHVlXCI+XHJcblxyXG4gICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc20gYnRuLW91dGxpbmUtZGFuZ2VyXCIgKGNsaWNrKT1cInJlbW92ZUZpbHRlcigkaW5kZXgpXCJcclxuICAgICAgICAgICAgdGl0bGU9XCJSZW1vdmVcIj7DlzwvYnV0dG9uPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICB9XHJcblxyXG4gICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zbSBidG4tb3V0bGluZS1wcmltYXJ5XCIgKGNsaWNrKT1cImFkZEZpbHRlcigpXCJcclxuICAgICAgICBbZGlzYWJsZWRdPVwiIWZpbHRlcmFibGVGaWVsZHMubGVuZ3RoXCI+XHJcbiAgICAgICAgKyBBZGQgQ3JpdGVyaW9uXHJcbiAgICAgIDwvYnV0dG9uPlxyXG4gICAgPC9kaXY+XHJcblxyXG4gICAgPCEtLSBTZWxlY3Rpb24gTW9kZSAtLT5cclxuICAgIDxkaXYgY2xhc3M9XCJibG9jayBtYi0zXCI+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJibG9jay10aXRsZVwiPkZpeHR1cmUgU2VsZWN0aW9uPC9kaXY+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZmxleC13cmFwIGFsaWduLWl0ZW1zLWNlbnRlciBnYXAtM1wiPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWNoZWNrIG1iLTBcIj5cclxuICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIiB0eXBlPVwicmFkaW9cIiBpZD1cInNlbEFsbFwiXHJcbiAgICAgICAgICAgIG5hbWU9XCJzZWxlY3Rpb25Nb2RlXCIgdmFsdWU9XCJhbGxcIiBbKG5nTW9kZWwpXT1cInNlbGVjdGlvbk1vZGVcIj5cclxuICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tY2hlY2stbGFiZWxcIiBmb3I9XCJzZWxBbGxcIj5BbGwgbWF0Y2hpbmcgZml4dHVyZXM8L2xhYmVsPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWNoZWNrIG1iLTBcIj5cclxuICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIiB0eXBlPVwicmFkaW9cIiBpZD1cInNlbEZpcnN0TlwiXHJcbiAgICAgICAgICAgIG5hbWU9XCJzZWxlY3Rpb25Nb2RlXCIgdmFsdWU9XCJmaXJzdE5cIiBbKG5nTW9kZWwpXT1cInNlbGVjdGlvbk1vZGVcIj5cclxuICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tY2hlY2stbGFiZWxcIiBmb3I9XCJzZWxGaXJzdE5cIj5GaXJzdDwvbGFiZWw+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPGlucHV0XHJcbiAgICAgICAgICB0eXBlPVwibnVtYmVyXCJcclxuICAgICAgICAgIG1pbj1cIjFcIlxyXG4gICAgICAgICAgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZm9ybS1jb250cm9sLXNtIGNvdW50LWlucHV0XCJcclxuICAgICAgICAgIFsobmdNb2RlbCldPVwibGltaXRQZXJTdG9yZVwiXHJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwic2VsZWN0aW9uTW9kZSAhPT0gJ2ZpcnN0TidcIj5cclxuICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtbXV0ZWQgc21hbGxcIj5tYXRjaGluZyBmcm9tIGVudHJhbmNlLCBwZXIgc3RvcmU8L3NwYW4+XHJcbiAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgPGRpdiBjbGFzcz1cImZvcm0tY2hlY2sgbXQtMlwiPlxyXG4gICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIiB0eXBlPVwiY2hlY2tib3hcIiBpZD1cImluY05vdEZvdW5kXCJcclxuICAgICAgICAgIFsobmdNb2RlbCldPVwiaW5jbHVkZU5vdEZvdW5kUm93c1wiPlxyXG4gICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tY2hlY2stbGFiZWxcIiBmb3I9XCJpbmNOb3RGb3VuZFwiPlxyXG4gICAgICAgICAgSW5jbHVkZSBlbXB0eSByb3dzIGZvciBzdG9yZXMgd2l0aCBubyBtYXRjaGVzXHJcbiAgICAgICAgPC9sYWJlbD5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgICA8IS0tIE91dHB1dCBDb2x1bW5zIC0tPlxyXG4gICAgPGRpdiBjbGFzcz1cImJsb2NrIG1iLTNcIj5cclxuICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWJldHdlZW4gbWItMlwiPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJibG9jay10aXRsZSBtYi0wXCI+T3V0cHV0IENvbHVtbnM8L2Rpdj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGdhcC0yXCI+XHJcbiAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zbSBidG4tbGluayBwLTBcIiAoY2xpY2spPVwic2VsZWN0QWxsQ29sdW1ucygpXCI+XHJcbiAgICAgICAgICAgIFNlbGVjdCBhbGxcclxuICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc20gYnRuLWxpbmsgcC0wXCIgKGNsaWNrKT1cImNsZWFyQWxsQ29sdW1ucygpXCI+XHJcbiAgICAgICAgICAgIENsZWFyXHJcbiAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgPC9kaXY+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJjb2x1bW4tZ3JpZFwiPlxyXG4gICAgICAgIEBmb3IgKGNvbCBvZiBvdXRwdXRDb2x1bW5zOyB0cmFjayBjb2wua2V5KSB7XHJcbiAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjb2x1bW4taXRlbVwiPlxyXG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0IG1lLTJcIlxyXG4gICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiY29sLnNlbGVjdGVkXCI+XHJcbiAgICAgICAgICAgIHt7IGNvbC5sYWJlbCB9fVxyXG4gICAgICAgICAgPC9sYWJlbD5cclxuICAgICAgICB9XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcblxyXG4gICAgPCEtLSBBY3Rpb24gQnV0dG9ucyAtLT5cclxuICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZ2FwLTJcIj5cclxuICAgICAgPGJ1dHRvblxyXG4gICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5XCJcclxuICAgICAgICAoY2xpY2spPVwib25SdW4oKVwiXHJcbiAgICAgICAgW2Rpc2FibGVkXT1cImlzUnVubmluZyB8fCBpc0xvYWRpbmdTY2hlbWEgfHwgc2VsZWN0ZWRTdG9yZXMubGVuZ3RoID09PSAwXCI+XHJcbiAgICAgICAge3sgaXNSdW5uaW5nID8gJ1J1bm5pbmcuLi4nIDogJ1J1biBRdWVyeScgfX1cclxuICAgICAgPC9idXR0b24+XHJcbiAgICAgIDxidXR0b25cclxuICAgICAgICBjbGFzcz1cImJ0biBidG4tc3VjY2Vzc1wiXHJcbiAgICAgICAgKGNsaWNrKT1cIm9uRXhwb3J0KClcIlxyXG4gICAgICAgIFtkaXNhYmxlZF09XCIhcmVzdWx0IHx8ICFyZXN1bHQucm93cy5sZW5ndGhcIj5cclxuICAgICAgICBFeHBvcnQgdG8gRXhjZWxcclxuICAgICAgPC9idXR0b24+XHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgICBAaWYgKG1lc3NhZ2UpIHtcclxuICAgICAgPGRpdlxyXG4gICAgICAgIGNsYXNzPVwibXQtMyBhbGVydFwiXHJcbiAgICAgICAgW2NsYXNzLmFsZXJ0LXN1Y2Nlc3NdPVwibWVzc2FnZVR5cGUgPT09ICdzdWNjZXNzJ1wiXHJcbiAgICAgICAgW2NsYXNzLmFsZXJ0LWRhbmdlcl09XCJtZXNzYWdlVHlwZSA9PT0gJ2Vycm9yJ1wiPlxyXG4gICAgICAgIHt7IG1lc3NhZ2UgfX1cclxuICAgICAgPC9kaXY+XHJcbiAgICB9XHJcbiAgPC9kaXY+XHJcblxyXG4gIDwhLS0gVk0gUGxhY2VtZW50IEV4cG9ydCBieSBWTSBOYW1lIC0tPlxyXG4gIDxkaXYgY2xhc3M9XCJjYXJkIHAtNCBtYi0zXCI+XHJcbiAgICA8aDUgY2xhc3M9XCJtYi0xXCI+Vk0gUGxhY2VtZW50IEV4cG9ydCBieSBWTSBOYW1lPC9oNT5cclxuICAgIDxwIGNsYXNzPVwidGV4dC1tdXRlZCBzbWFsbCBtYi0zXCI+XHJcbiAgICAgIEZpbmQgZXZlcnkgZml4dHVyZSAoaW4gdGhlIHNlbGVjdGVkIHN0b3JlcykgdGhhdCBjb250YWlucyBhbnkgVk0gd2hvc2VcclxuICAgICAgPGNvZGU+dm1OYW1lPC9jb2RlPiBtYXRjaGVzIHRoZSByZWdleCwgYW5kIGV4cG9ydCBvbmUgcm93IHBlciBWTSBwbGFjZW1lbnRcclxuICAgICAgd2l0aCBmaXh0dXJlIGRldGFpbHMgYW5kIHNoZWxmL3pvbmUgY29vcmRpbmF0ZXMuXHJcbiAgICA8L3A+XHJcblxyXG4gICAgPGRpdiBjbGFzcz1cImJsb2NrIG1iLTNcIj5cclxuICAgICAgPGRpdiBjbGFzcz1cImJsb2NrLXRpdGxlXCI+U3RvcmVzPC9kaXY+XHJcbiAgICAgIDxsaWItc3RvcmUtc2VsZWN0XHJcbiAgICAgICAgW29wdGlvbnNdPVwic3RvcmVPcHRpb25zXCJcclxuICAgICAgICBbaW5pdGlhbFNlbGVjdGVkXT1cInZtSW5pdGlhbFN0b3Jlc1wiXHJcbiAgICAgICAgKHNlbGVjdGVkQ2hhbmdlKT1cIm9uVm1TdG9yZXNTZWxlY3RlZCgkZXZlbnQpXCI+XHJcbiAgICAgIDwvbGliLXN0b3JlLXNlbGVjdD5cclxuICAgIDwvZGl2PlxyXG5cclxuICAgIDxkaXYgY2xhc3M9XCJibG9jayBtYi0zXCI+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJibG9jay10aXRsZVwiPlZNIE5hbWUgKHJlZ2V4KTwvZGl2PlxyXG4gICAgICA8aW5wdXRcclxuICAgICAgICBjbGFzcz1cImZvcm0tY29udHJvbCBmb3JtLWNvbnRyb2wtc21cIlxyXG4gICAgICAgIHBsYWNlaG9sZGVyPVwiZS5nLiBab2RpYWMsIF5IaXBob3AsIExlYXRoZXJpdGVcIlxyXG4gICAgICAgIFsobmdNb2RlbCldPVwidm1OYW1lUmVnZXhcIj5cclxuICAgICAgPHNtYWxsIGNsYXNzPVwidGV4dC1tdXRlZFwiPkNhc2UtaW5zZW5zaXRpdmUuIE1hdGNoZWQgYWdhaW5zdCB0aGUgPGNvZGU+cGxhbm9WbURldGFpbHMudm1OYW1lPC9jb2RlPiBmaWVsZC48L3NtYWxsPlxyXG4gICAgPC9kaXY+XHJcblxyXG4gICAgPGRpdiBjbGFzcz1cImQtZmxleCBnYXAtMlwiPlxyXG4gICAgICA8YnV0dG9uXHJcbiAgICAgICAgY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIlxyXG4gICAgICAgIChjbGljayk9XCJvblZtUnVuKClcIlxyXG4gICAgICAgIFtkaXNhYmxlZF09XCJpc1ZtUnVubmluZyB8fCB2bVNlbGVjdGVkU3RvcmVzLmxlbmd0aCA9PT0gMCB8fCAhdm1OYW1lUmVnZXgudHJpbSgpXCI+XHJcbiAgICAgICAge3sgaXNWbVJ1bm5pbmcgPyAnUnVubmluZy4uLicgOiAnUnVuIFF1ZXJ5JyB9fVxyXG4gICAgICA8L2J1dHRvbj5cclxuICAgICAgPGJ1dHRvblxyXG4gICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1zdWNjZXNzXCJcclxuICAgICAgICAoY2xpY2spPVwib25WbUV4cG9ydCgpXCJcclxuICAgICAgICBbZGlzYWJsZWRdPVwiIXZtUmVzdWx0IHx8ICF2bVJlc3VsdC5yb3dzLmxlbmd0aFwiPlxyXG4gICAgICAgIEV4cG9ydCB0byBFeGNlbFxyXG4gICAgICA8L2J1dHRvbj5cclxuICAgIDwvZGl2PlxyXG5cclxuICAgIEBpZiAodm1NZXNzYWdlKSB7XHJcbiAgICAgIDxkaXZcclxuICAgICAgICBjbGFzcz1cIm10LTMgYWxlcnRcIlxyXG4gICAgICAgIFtjbGFzcy5hbGVydC1zdWNjZXNzXT1cInZtTWVzc2FnZVR5cGUgPT09ICdzdWNjZXNzJ1wiXHJcbiAgICAgICAgW2NsYXNzLmFsZXJ0LWRhbmdlcl09XCJ2bU1lc3NhZ2VUeXBlID09PSAnZXJyb3InXCI+XHJcbiAgICAgICAge3sgdm1NZXNzYWdlIH19XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgfVxyXG4gIDwvZGl2PlxyXG5cclxuICBAaWYgKHZtUmVzdWx0KSB7XHJcbiAgICA8ZGl2IGNsYXNzPVwiY2FyZCBwLTQgbWItM1wiPlxyXG4gICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBtYi0zXCI+XHJcbiAgICAgICAgPGRpdj5cclxuICAgICAgICAgIDxoNiBjbGFzcz1cIm1iLTBcIj5WTSBQbGFjZW1lbnQgUmVzdWx0czwvaDY+XHJcbiAgICAgICAgICA8c21hbGwgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+XHJcbiAgICAgICAgICAgIHt7IHZtVG90YWxSb3dzIH19IHJvdyhzKVxyXG4gICAgICAgICAgICBAaWYgKHZtVG90YWxSb3dzKSB7XHJcbiAgICAgICAgICAgICAgwrcgc2hvd2luZyB7eyB2bVBhZ2VTdGFydCB9feKAk3t7IHZtUGFnZUVuZCB9fVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICA8L3NtYWxsPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICA8L2Rpdj5cclxuXHJcbiAgICAgIEBpZiAoIXZtUmVzdWx0LnJvd3MubGVuZ3RoKSB7XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbXV0ZWRcIj5ObyBWTSBwbGFjZW1lbnRzIGZvdW5kIGZvciB0aGUgZ2l2ZW4gc3RvcmVzIGFuZCB2bU5hbWUuPC9kaXY+XHJcbiAgICAgIH0gQGVsc2Uge1xyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0YWJsZS1yZXNwb25zaXZlXCI+XHJcbiAgICAgICAgICA8dGFibGUgY2xhc3M9XCJ0YWJsZSB0YWJsZS1zbSB0YWJsZS1ib3JkZXJlZFwiPlxyXG4gICAgICAgICAgICA8dGhlYWQ+XHJcbiAgICAgICAgICAgICAgPHRyPlxyXG4gICAgICAgICAgICAgICAgQGZvciAoY29sIG9mIHZtUmVzdWx0Q29sdW1uczsgdHJhY2sgY29sKSB7XHJcbiAgICAgICAgICAgICAgICAgIDx0aD57eyBjb2wgfX08L3RoPlxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgICAgIDwvdGhlYWQ+XHJcbiAgICAgICAgICAgIDx0Ym9keT5cclxuICAgICAgICAgICAgICBAZm9yIChyb3cgb2Ygdm1QYWdlZFJvd3M7IHRyYWNrICRpbmRleCkge1xyXG4gICAgICAgICAgICAgICAgPHRyPlxyXG4gICAgICAgICAgICAgICAgICBAZm9yIChjb2wgb2Ygdm1SZXN1bHRDb2x1bW5zOyB0cmFjayBjb2wpIHtcclxuICAgICAgICAgICAgICAgICAgICA8dGRcclxuICAgICAgICAgICAgICAgICAgICAgIFtuZ2JUb29sdGlwXT1cInJvd1tjb2xdPy50b1N0cmluZygpID8gcm93W2NvbF0gOiBudWxsXCJcclxuICAgICAgICAgICAgICAgICAgICAgIGNvbnRhaW5lcj1cImJvZHlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgcGxhY2VtZW50PVwidG9wXCJcclxuICAgICAgICAgICAgICAgICAgICAgIFtvcGVuRGVsYXldPVwiMzAwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICB7eyByb3dbY29sXSB9fVxyXG4gICAgICAgICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICA8L3Rib2R5PlxyXG4gICAgICAgICAgPC90YWJsZT5cclxuICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgPGxpYi1wYWdpbmF0aW9uXHJcbiAgICAgICAgICBbaXRlbXNQZXJQYWdlXT1cInZtUGFnZVNpemVcIlxyXG4gICAgICAgICAgW2N1cnJlbnRQYWdlXT1cInZtQ3VycmVudFBhZ2VcIlxyXG4gICAgICAgICAgW3RvdGFsSXRlbXNdPVwidm1Ub3RhbFJvd3NcIlxyXG4gICAgICAgICAgW3BhZ2VTaXplXT1cInZtUGFnZVNpemVcIlxyXG4gICAgICAgICAgW3BhZ2luYXRpb25TaXplc109XCJwYWdpbmF0aW9uU2l6ZXNcIlxyXG4gICAgICAgICAgW2RpcmVjdGlvbkxpbmtzXT1cInRydWVcIlxyXG4gICAgICAgICAgKHBhZ2VDaGFuZ2UpPVwib25WbVBhZ2VDaGFuZ2UoJGV2ZW50KVwiXHJcbiAgICAgICAgICAocGFnZVNpemVDaGFuZ2UpPVwib25WbVBhZ2VTaXplQ2hhbmdlKCRldmVudClcIj5cclxuICAgICAgICA8L2xpYi1wYWdpbmF0aW9uPlxyXG4gICAgICB9XHJcbiAgICA8L2Rpdj5cclxuICB9XHJcblxyXG4gIDwhLS0gUmVzdWx0IFByZXZpZXcgLS0+XHJcbiAgQGlmIChyZXN1bHQpIHtcclxuICAgIDxkaXYgY2xhc3M9XCJjYXJkIHAtNFwiPlxyXG4gICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBtYi0zXCI+XHJcbiAgICAgICAgPGRpdj5cclxuICAgICAgICAgIDxoNiBjbGFzcz1cIm1iLTBcIj5SZXN1bHRzPC9oNj5cclxuICAgICAgICAgIDxzbWFsbCBjbGFzcz1cInRleHQtbXV0ZWRcIj5cclxuICAgICAgICAgICAge3sgdG90YWxSb3dzIH19IHJvdyhzKVxyXG4gICAgICAgICAgICBAaWYgKHRvdGFsUm93cykge1xyXG4gICAgICAgICAgICAgIMK3IHNob3dpbmcge3sgcGFnZVN0YXJ0IH194oCTe3sgcGFnZUVuZCB9fVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICA8L3NtYWxsPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICA8L2Rpdj5cclxuXHJcbiAgICAgIEBpZiAoIXJlc3VsdC5yb3dzLmxlbmd0aCkge1xyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+Tm8gZGF0YSBmb3VuZCBmb3IgdGhlIGdpdmVuIHF1ZXJ5LjwvZGl2PlxyXG4gICAgICB9IEBlbHNlIHtcclxuICAgICAgICA8ZGl2IGNsYXNzPVwidGFibGUtcmVzcG9uc2l2ZVwiPlxyXG4gICAgICAgICAgPHRhYmxlIGNsYXNzPVwidGFibGUgdGFibGUtc20gdGFibGUtYm9yZGVyZWRcIj5cclxuICAgICAgICAgICAgPHRoZWFkPlxyXG4gICAgICAgICAgICAgIDx0cj5cclxuICAgICAgICAgICAgICAgIEBmb3IgKGNvbCBvZiByZXN1bHRDb2x1bW5zOyB0cmFjayBjb2wua2V5KSB7XHJcbiAgICAgICAgICAgICAgICAgIDx0aD57eyBjb2wubGFiZWwgfX08L3RoPlxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgICAgIDwvdGhlYWQ+XHJcbiAgICAgICAgICAgIDx0Ym9keT5cclxuICAgICAgICAgICAgICBAZm9yIChyb3cgb2YgcGFnZWRSb3dzOyB0cmFjayAkaW5kZXgpIHtcclxuICAgICAgICAgICAgICAgIDx0ciBbY2xhc3Mucm93LW5vdC1mb3VuZF09XCJyb3dbJ19fbm90Rm91bmQnXVwiPlxyXG4gICAgICAgICAgICAgICAgICBAZm9yIChjb2wgb2YgcmVzdWx0Q29sdW1uczsgdHJhY2sgY29sLmtleSkge1xyXG4gICAgICAgICAgICAgICAgICAgIDx0ZFxyXG4gICAgICAgICAgICAgICAgICAgICAgW25nYlRvb2x0aXBdPVwicm93W2NvbC5sYWJlbF0/LnRvU3RyaW5nKCkgPyByb3dbY29sLmxhYmVsXSA6IG51bGxcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyPVwiYm9keVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICBwbGFjZW1lbnQ9XCJ0b3BcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgW29wZW5EZWxheV09XCIzMDBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgIHt7IHJvd1tjb2wubGFiZWxdIH19XHJcbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgPC90cj5cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIDwvdGJvZHk+XHJcbiAgICAgICAgICA8L3RhYmxlPlxyXG4gICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICA8bGliLXBhZ2luYXRpb25cclxuICAgICAgICAgIFtpdGVtc1BlclBhZ2VdPVwicGFnZVNpemVcIlxyXG4gICAgICAgICAgW2N1cnJlbnRQYWdlXT1cImN1cnJlbnRQYWdlXCJcclxuICAgICAgICAgIFt0b3RhbEl0ZW1zXT1cInRvdGFsUm93c1wiXHJcbiAgICAgICAgICBbcGFnZVNpemVdPVwicGFnZVNpemVcIlxyXG4gICAgICAgICAgW3BhZ2luYXRpb25TaXplc109XCJwYWdpbmF0aW9uU2l6ZXNcIlxyXG4gICAgICAgICAgW2RpcmVjdGlvbkxpbmtzXT1cInRydWVcIlxyXG4gICAgICAgICAgKHBhZ2VDaGFuZ2UpPVwib25QYWdlQ2hhbmdlKCRldmVudClcIlxyXG4gICAgICAgICAgKHBhZ2VTaXplQ2hhbmdlKT1cIm9uUGFnZVNpemVDaGFuZ2UoJGV2ZW50KVwiPlxyXG4gICAgICAgIDwvbGliLXBhZ2luYXRpb24+XHJcbiAgICAgIH1cclxuICAgIDwvZGl2PlxyXG4gIH1cclxuPC9zZWN0aW9uPlxyXG4iXX0=
379
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGxhbm8tZGF0YS1leHBvcnQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdGFuZ28tc3RvcmUtYnVpbGRlci9zcmMvbGliL2NvbXBvbmVudHMvcGxhbm8tdG9vbHMvcGxhbm8tZGF0YS1leHBvcnQvcGxhbm8tZGF0YS1leHBvcnQuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvdGFuZ28tc3RvcmUtYnVpbGRlci9zcmMvbGliL2NvbXBvbmVudHMvcGxhbm8tdG9vbHMvcGxhbm8tZGF0YS1leHBvcnQvcGxhbm8tZGF0YS1leHBvcnQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBcUIsTUFBTSxlQUFlLENBQUM7QUFHN0QsT0FBTyxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLE1BQU0sQ0FBQzs7Ozs7Ozs7O0FBeUN0RixNQUFNLG1CQUFtQixHQUFxQztJQUM1RCxFQUFFLEdBQUcsRUFBRSxXQUFXLEVBQUUsS0FBSyxFQUFFLFlBQVksRUFBRTtJQUN6QyxFQUFFLEdBQUcsRUFBRSxpQkFBaUIsRUFBRSxLQUFLLEVBQUUsa0JBQWtCLEVBQUU7SUFDckQsRUFBRSxHQUFHLEVBQUUsY0FBYyxFQUFFLEtBQUssRUFBRSxlQUFlLEVBQUU7SUFDL0MsRUFBRSxHQUFHLEVBQUUsZUFBZSxFQUFFLEtBQUssRUFBRSxnQkFBZ0IsRUFBRTtJQUNqRCxFQUFFLEdBQUcsRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFFLGNBQWMsRUFBRTtJQUM3QyxFQUFFLEdBQUcsRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFFLGNBQWMsRUFBRTtJQUM3QyxFQUFFLEdBQUcsRUFBRSxhQUFhLEVBQUUsS0FBSyxFQUFFLGNBQWMsRUFBRTtJQUM3QyxFQUFF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dCwgT25Jbml0LCBPbkRlc3Ryb3kgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgU3RvcmVCdWlsZGVyU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL3N0b3JlLWJ1aWxkZXIuc2VydmljZSc7XHJcbmltcG9ydCB7IEdsb2JhbFN0YXRlU2VydmljZSB9IGZyb20gJ3RhbmdvLWFwcC11aS1nbG9iYWwnO1xyXG5pbXBvcnQgeyBTdWJqZWN0LCB0YWtlVW50aWwsIGRlYm91bmNlVGltZSwgZmlsdGVyLCBkaXN0aW5jdFVudGlsQ2hhbmdlZCB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyBTdG9yZU9wdGlvbiB9IGZyb20gJy4uLy4uL2NvbGxlY3Rpb24tdXBkYXRlLWFpL2NvbXBvbmVudHMvc3RvcmUtc2VsZWN0L3N0b3JlLXNlbGVjdC5jb21wb25lbnQnO1xyXG5cclxuaW50ZXJmYWNlIEZpZWxkRGVmIHtcclxuICBrZXk6IHN0cmluZztcclxuICBsYWJlbDogc3RyaW5nO1xyXG4gIHR5cGU6ICdzdHJpbmcnIHwgJ251bWJlcicgfCAnYXJyYXlPZlN0cmluZ3MnO1xyXG4gIGZpbHRlcmFibGU6IGJvb2xlYW47XHJcbiAgb3V0cHV0OiBib29sZWFuO1xyXG59XHJcblxyXG5pbnRlcmZhY2UgT3BlcmF0b3JEZWYge1xyXG4gIGtleTogc3RyaW5nO1xyXG4gIGxhYmVsOiBzdHJpbmc7XHJcbn1cclxuXHJcbmludGVyZmFjZSBGaWx0ZXJSb3cge1xyXG4gIGZpZWxkOiBzdHJpbmc7XHJcbiAgb3BlcmF0b3I6IHN0cmluZztcclxuICB2YWx1ZTogc3RyaW5nO1xyXG59XHJcblxyXG5pbnRlcmZhY2UgQ29sdW1uU2VsZWN0aW9uIHtcclxuICBrZXk6IHN0cmluZztcclxuICBsYWJlbDogc3RyaW5nO1xyXG4gIHNlbGVjdGVkOiBib29sZWFuO1xyXG59XHJcblxyXG5pbnRlcmZhY2UgUXVlcnlSZXN1bHQge1xyXG4gIGNvbHVtbnM6IHN0cmluZ1tdO1xyXG4gIHJvd3M6IFJlY29yZDxzdHJpbmcsIGFueT5bXTtcclxuICB0b3RhbFJvd3M6IG51bWJlcjtcclxufVxyXG5cclxuaW50ZXJmYWNlIFZtUGxhY2VtZW50UmVzdWx0IHtcclxuICBjb2x1bW5zOiBzdHJpbmdbXTtcclxuICByb3dzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+W107XHJcbiAgdG90YWxSb3dzOiBudW1iZXI7XHJcbiAgbWF0Y2hlZFZtQ291bnQ6IG51bWJlcjtcclxufVxyXG5cclxuY29uc3QgT1VUUFVUX0NPTFVNTl9PUkRFUjogeyBrZXk6IHN0cmluZzsgbGFiZWw6IHN0cmluZyB9W10gPSBbXHJcbiAgeyBrZXk6ICdzdG9yZU5hbWUnLCBsYWJlbDogJ1N0b3JlIE5hbWUnIH0sXHJcbiAgeyBrZXk6ICdmaXh0dXJlQ2F0ZWdvcnknLCBsYWJlbDogJ0ZpeHR1cmUgQ2F0ZWdvcnknIH0sXHJcbiAgeyBrZXk6ICdmaXh0dXJlV2lkdGgnLCBsYWJlbDogJ0ZpeHR1cmUgV2lkdGgnIH0sXHJcbiAgeyBrZXk6ICdmaXh0dXJlTnVtYmVyJywgbGFiZWw6ICdGaXh0dXJlIE51bWJlcicgfSxcclxuICB7IGtleTogJ2ZpeHR1cmVOYW1lJywgbGFiZWw6ICdGaXh0dXJlIE5hbWUnIH0sXHJcbiAgeyBrZXk6ICdmaXh0dXJlVHlwZScsIGxhYmVsOiAnRml4dHVyZSBUeXBlJyB9LFxyXG4gIHsga2V5OiAnaGVhZGVyTGFiZWwnLCBsYWJlbDogJ0hlYWRlciBMYWJlbCcgfSxcclxuICB7IGtleTogJ3RlbXBsYXRlR3JvdXBOYW1lJywgbGFiZWw6ICdUZW1wbGF0ZSBHcm91cCBOYW1lJyB9LFxyXG4gIHsga2V5OiAnd2FsbE51bWJlcicsIGxhYmVsOiAnV2FsbCBOdW1iZXInIH0sXHJcbiAgeyBrZXk6ICd3YWxsRml4dHVyZU51bWJlcicsIGxhYmVsOiAnV2FsbCBGaXh0dXJlIE51bWJlcicgfSxcclxuICB7IGtleTogJ3ZtTmFtZXMnLCBsYWJlbDogJ1ZNIE5hbWVzJyB9LFxyXG4gIHsga2V5OiAndm1Db3VudCcsIGxhYmVsOiAnVk0gQ291bnQnIH0sXHJcbiAgeyBrZXk6ICdwcm9kdWN0UGlkcycsIGxhYmVsOiAnUHJvZHVjdCBQSURzJyB9LFxyXG4gIHsga2V5OiAncG9zaXRpb24nLCBsYWJlbDogJ1Bvc2l0aW9uJyB9LFxyXG4gIHsga2V5OiAncG9zaXRpb25MYWJlbCcsIGxhYmVsOiAnUG9zaXRpb24gTGFiZWwnIH0sXHJcbiAgeyBrZXk6ICdzdGFuZGFyZENhcGFjaXR5JywgbGFiZWw6ICdTdGFuZGFyZCBDYXBhY2l0eScgfSxcclxuXTtcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnbGliLXBsYW5vLWRhdGEtZXhwb3J0JyxcclxuICB0ZW1wbGF0ZVVybDogJy4vcGxhbm8tZGF0YS1leHBvcnQuY29tcG9uZW50Lmh0bWwnLFxyXG4gIHN0eWxlVXJsOiAnLi9wbGFuby1kYXRhLWV4cG9ydC5jb21wb25lbnQuc2NzcycsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBQbGFub0RhdGFFeHBvcnRDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uRGVzdHJveSB7XHJcbiAgY2xpZW50SWQ6IHN0cmluZztcclxuICBzdG9yZU9wdGlvbnM6IFN0b3JlT3B0aW9uW10gPSBbXTtcclxuICBpbml0aWFsU3RvcmVzOiBTdG9yZU9wdGlvbltdID0gW107XHJcbiAgc2VsZWN0ZWRTdG9yZXM6IFN0b3JlT3B0aW9uW10gPSBbXTtcclxuXHJcbiAgZmllbGRzOiBGaWVsZERlZltdID0gW107XHJcbiAgb3BlcmF0b3JzQnlUeXBlOiBSZWNvcmQ8c3RyaW5nLCBPcGVyYXRvckRlZltdPiA9IHt9O1xyXG4gIGlzTG9hZGluZ1NjaGVtYTogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICBmaWx0ZXJzOiBGaWx0ZXJSb3dbXSA9IFtdO1xyXG4gIGZpbHRlckNvbWJpbmF0b3I6ICdBTkQnIHwgJ09SJyA9ICdBTkQnO1xyXG5cclxuICBzZWxlY3Rpb25Nb2RlOiAnYWxsJyB8ICdmaXJzdE4nID0gJ2ZpcnN0Tic7XHJcbiAgbGltaXRQZXJTdG9yZTogbnVtYmVyID0gMTtcclxuXHJcbiAgb3V0cHV0Q29sdW1uczogQ29sdW1uU2VsZWN0aW9uW10gPSBbXTtcclxuXHJcbiAgaW5jbHVkZU5vdEZvdW5kUm93czogYm9vbGVhbiA9IHRydWU7XHJcblxyXG4gIGlzUnVubmluZzogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIHJlc3VsdDogUXVlcnlSZXN1bHQgfCBudWxsID0gbnVsbDtcclxuICByZXN1bHRDb2x1bW5zOiB7IGtleTogc3RyaW5nOyBsYWJlbDogc3RyaW5nIH1bXSA9IFtdO1xyXG5cclxuICBtZXNzYWdlOiBzdHJpbmcgPSAnJztcclxuICBtZXNzYWdlVHlwZTogJ3N1Y2Nlc3MnIHwgJ2Vycm9yJyA9ICdzdWNjZXNzJztcclxuXHJcbiAgcGFnaW5hdGlvblNpemVzOiBudW1iZXJbXSA9IFsyNSwgNTAsIDEwMCwgMjAwXTtcclxuICBwYWdlU2l6ZTogbnVtYmVyID0gNTA7XHJcbiAgY3VycmVudFBhZ2U6IG51bWJlciA9IDE7XHJcblxyXG4gIC8vIFZNIFBsYWNlbWVudCBFeHBvcnQgYnkgVk0gTmFtZVxyXG4gIHZtU2VsZWN0ZWRTdG9yZXM6IFN0b3JlT3B0aW9uW10gPSBbXTtcclxuICB2bUluaXRpYWxTdG9yZXM6IFN0b3JlT3B0aW9uW10gPSBbXTtcclxuICB2bU5hbWVSZWdleDogc3RyaW5nID0gJyc7XHJcbiAgaXNWbVJ1bm5pbmc6IGJvb2xlYW4gPSBmYWxzZTtcclxuICB2bVJlc3VsdDogVm1QbGFjZW1lbnRSZXN1bHQgfCBudWxsID0gbnVsbDtcclxuICB2bVJlc3VsdENvbHVtbnM6IHN0cmluZ1tdID0gW107XHJcbiAgdm1QYWdlU2l6ZTogbnVtYmVyID0gNTA7XHJcbiAgdm1DdXJyZW50UGFnZTogbnVtYmVyID0gMTtcclxuICB2bU1lc3NhZ2U6IHN0cmluZyA9ICcnO1xyXG4gIHZtTWVzc2FnZVR5cGU6ICdzdWNjZXNzJyB8ICdlcnJvcicgPSAnc3VjY2Vzcyc7XHJcblxyXG4gIHByaXZhdGUgcmVhZG9ubHkgZGVzdHJveSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgc2JzOiBTdG9yZUJ1aWxkZXJTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBnczogR2xvYmFsU3RhdGVTZXJ2aWNlLFxyXG4gICkge31cclxuXHJcbiAgbmdPbkluaXQoKTogdm9pZCB7XHJcbiAgICB0aGlzLmdzLmRhdGFSYW5nZVZhbHVlXHJcbiAgICAgIC5waXBlKFxyXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLmRlc3Ryb3kkKSxcclxuICAgICAgICBkZWJvdW5jZVRpbWUoMjAwKSxcclxuICAgICAgICBmaWx0ZXIoKGRhdGEpID0+ICEhZGF0YSksXHJcbiAgICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcclxuICAgICAgKVxyXG4gICAgICAuc3Vic2NyaWJlKChkYXRhOiBhbnkpID0+IHtcclxuICAgICAgICBpZiAoZGF0YT8uY2xpZW50KSB7XHJcbiAgICAgICAgICB0aGlzLmNsaWVudElkID0gZGF0YS5jbGllbnQ7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIGxldCBoZWFkZXJEYXRhID0gSlNPTi5wYXJzZShcclxuICAgICAgICAgICAgbG9jYWxTdG9yYWdlLmdldEl0ZW0oJ2hlYWRlci1maWx0ZXJzJykgYXMgc3RyaW5nLFxyXG4gICAgICAgICAgKTtcclxuICAgICAgICAgIHRoaXMuY2xpZW50SWQgPSBoZWFkZXJEYXRhPy5jbGllbnQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMubG9hZFN0b3JlcygpO1xyXG4gICAgICB9KTtcclxuXHJcbiAgICB0aGlzLmxvYWRTY2hlbWEoKTtcclxuICB9XHJcblxyXG4gIGxvYWRTdG9yZXMoKSB7XHJcbiAgICB0aGlzLnNicy5nZXRTdG9yZU9yQ2x1c3Rlckxpc3QoeyBzZWFyY2hNb2RlOiAnc3RvcmUnIH0pLnN1YnNjcmliZSgocmVzOiBhbnkpID0+IHtcclxuICAgICAgaWYgKHJlcz8uZGF0YSkge1xyXG4gICAgICAgIHRoaXMuc3RvcmVPcHRpb25zID0gcmVzLmRhdGE7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgbG9hZFNjaGVtYSgpIHtcclxuICAgIHRoaXMuaXNMb2FkaW5nU2NoZW1hID0gdHJ1ZTtcclxuICAgIHRoaXMuc2JzLmdldFBsYW5vRGF0YVNjaGVtYSgpLnN1YnNjcmliZSh7XHJcbiAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xyXG4gICAgICAgIHRoaXMuZmllbGRzID0gcmVzPy5kYXRhPy5maWVsZHMgfHwgW107XHJcbiAgICAgICAgdGhpcy5vcGVyYXRvcnNCeVR5cGUgPSByZXM/LmRhdGE/Lm9wZXJhdG9yc0J5VHlwZSB8fCB7fTtcclxuXHJcbiAgICAgICAgbGV0IG91dHB1dEZpZWxkcyA9IHRoaXMuZmllbGRzLmZpbHRlcigoZikgPT4gZi5vdXRwdXQpO1xyXG4gICAgICAgIGxldCBieUtleSA9IG5ldyBNYXAob3V0cHV0RmllbGRzLm1hcCgoZikgPT4gW2Yua2V5LCBmXSkpO1xyXG5cclxuICAgICAgICBsZXQgb3JkZXJlZDogeyBrZXk6IHN0cmluZzsgbGFiZWw6IHN0cmluZyB9W10gPSBbXTtcclxuICAgICAgICBmb3IgKGxldCBlbnRyeSBvZiBPVVRQVVRfQ09MVU1OX09SREVSKSB7XHJcbiAgICAgICAgICBsZXQgZiA9IGJ5S2V5LmdldChlbnRyeS5rZXkpO1xyXG4gICAgICAgICAgb3JkZXJlZC5wdXNoKHtcclxuICAgICAgICAgICAga2V5OiBlbnRyeS5rZXksXHJcbiAgICAgICAgICAgIGxhYmVsOiBmPy5sYWJlbCB8fCBlbnRyeS5sYWJlbCxcclxuICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgYnlLZXkuZGVsZXRlKGVudHJ5LmtleSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZvciAobGV0IGYgb2YgYnlLZXkudmFsdWVzKCkpIG9yZGVyZWQucHVzaCh7IGtleTogZi5rZXksIGxhYmVsOiBmLmxhYmVsIH0pO1xyXG5cclxuICAgICAgICB0aGlzLm91dHB1dENvbHVtbnMgPSBvcmRlcmVkLm1hcCgoZikgPT4gKHtcclxuICAgICAgICAgIGtleTogZi5rZXksXHJcbiAgICAgICAgICBsYWJlbDogZi5sYWJlbCxcclxuICAgICAgICAgIHNlbGVjdGVkOiB0aGlzLmRlZmF1bHRTZWxlY3RlZChmLmtleSksXHJcbiAgICAgICAgfSkpO1xyXG4gICAgICAgIHRoaXMuaXNMb2FkaW5nU2NoZW1hID0gZmFsc2U7XHJcbiAgICAgIH0sXHJcbiAgICAgIGVycm9yOiAoKSA9PiB7XHJcbiAgICAgICAgdGhpcy5maWVsZHMgPSBbXTtcclxuICAgICAgICB0aGlzLm9wZXJhdG9yc0J5VHlwZSA9IHt9O1xyXG4gICAgICAgIHRoaXMub3V0cHV0Q29sdW1ucyA9IFtdO1xyXG4gICAgICAgIHRoaXMuaXNMb2FkaW5nU2NoZW1hID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5zaG93TWVzc2FnZSgnRmFpbGVkIHRvIGxvYWQgcXVlcnkgc2NoZW1hLicsICdlcnJvcicpO1xyXG4gICAgICB9LFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGRlZmF1bHRTZWxlY3RlZChrZXk6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIFtcclxuICAgICAgJ3N0b3JlTmFtZScsXHJcbiAgICAgICdmaXh0dXJlQ2F0ZWdvcnknLFxyXG4gICAgICAnZml4dHVyZVdpZHRoJyxcclxuICAgICAgJ2ZpeHR1cmVOdW1iZXInLFxyXG4gICAgICAnZml4dHVyZVR5cGUnLFxyXG4gICAgICAnaGVhZGVyTGFiZWwnLFxyXG4gICAgICAnd2FsbE51bWJlcicsXHJcbiAgICAgICd3YWxsRml4dHVyZU51bWJlcicsXHJcbiAgICAgICd2bU5hbWVzJyxcclxuICAgICAgJ3Bvc2l0aW9uTGFiZWwnLFxyXG4gICAgICAnc3RhbmRhcmRDYXBhY2l0eScsXHJcbiAgICBdLmluY2x1ZGVzKGtleSk7XHJcbiAgfVxyXG5cclxuICBnZXQgZmlsdGVyYWJsZUZpZWxkcygpOiBGaWVsZERlZltdIHtcclxuICAgIHJldHVybiB0aGlzLmZpZWxkcy5maWx0ZXIoKGYpID0+IGYuZmlsdGVyYWJsZSk7XHJcbiAgfVxyXG5cclxuICBvcGVyYXRvcnNGb3JGaWVsZChmaWVsZEtleTogc3RyaW5nKTogT3BlcmF0b3JEZWZbXSB7XHJcbiAgICBsZXQgZiA9IHRoaXMuZmllbGRzLmZpbmQoKHgpID0+IHgua2V5ID09PSBmaWVsZEtleSk7XHJcbiAgICBpZiAoIWYpIHJldHVybiBbXTtcclxuICAgIHJldHVybiB0aGlzLm9wZXJhdG9yc0J5VHlwZVtmLnR5cGVdIHx8IFtdO1xyXG4gIH1cclxuXHJcbiAgaXNWYWx1ZURpc2FibGVkRm9yKG9wZXJhdG9yOiBzdHJpbmcpOiBib29sZWFuIHtcclxuICAgIHJldHVybiBvcGVyYXRvciA9PT0gJ2V4aXN0cycgfHwgb3BlcmF0b3IgPT09ICdub3RFeGlzdHMnO1xyXG4gIH1cclxuXHJcbiAgb25TdG9yZXNTZWxlY3RlZChzdG9yZXM6IFN0b3JlT3B0aW9uW10pIHtcclxuICAgIHRoaXMuc2VsZWN0ZWRTdG9yZXMgPSBzdG9yZXM7XHJcbiAgfVxyXG5cclxuICBhZGRGaWx0ZXIoKSB7XHJcbiAgICBsZXQgZmlyc3RGaWVsZCA9IHRoaXMuZmlsdGVyYWJsZUZpZWxkc1swXTtcclxuICAgIGlmICghZmlyc3RGaWVsZCkgcmV0dXJuO1xyXG4gICAgbGV0IGZpcnN0T3AgPSB0aGlzLm9wZXJhdG9yc0J5VHlwZVtmaXJzdEZpZWxkLnR5cGVdPy5bMF07XHJcbiAgICB0aGlzLmZpbHRlcnMucHVzaCh7XHJcbiAgICAgIGZpZWxkOiBmaXJzdEZpZWxkLmtleSxcclxuICAgICAgb3BlcmF0b3I6IGZpcnN0T3A/LmtleSB8fCAnZXF1YWxzJyxcclxuICAgICAgdmFsdWU6ICcnLFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICByZW1vdmVGaWx0ZXIoaWR4OiBudW1iZXIpIHtcclxuICAgIHRoaXMuZmlsdGVycy5zcGxpY2UoaWR4LCAxKTtcclxuICB9XHJcblxyXG4gIG9uRmlsdGVyRmllbGRDaGFuZ2UoaWR4OiBudW1iZXIpIHtcclxuICAgIGxldCByb3cgPSB0aGlzLmZpbHRlcnNbaWR4XTtcclxuICAgIGxldCBhbGxvd2VkID0gdGhpcy5vcGVyYXRvcnNGb3JGaWVsZChyb3cuZmllbGQpO1xyXG4gICAgaWYgKCFhbGxvd2VkLmZpbmQoKG9wKSA9PiBvcC5rZXkgPT09IHJvdy5vcGVyYXRvcikpIHtcclxuICAgICAgcm93Lm9wZXJhdG9yID0gYWxsb3dlZFswXT8ua2V5IHx8ICdlcXVhbHMnO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgc2VsZWN0QWxsQ29sdW1ucygpIHtcclxuICAgIHRoaXMub3V0cHV0Q29sdW1ucy5mb3JFYWNoKChjKSA9PiAoYy5zZWxlY3RlZCA9IHRydWUpKTtcclxuICB9XHJcblxyXG4gIGNsZWFyQWxsQ29sdW1ucygpIHtcclxuICAgIHRoaXMub3V0cHV0Q29sdW1ucy5mb3JFYWNoKChjKSA9PiAoYy5zZWxlY3RlZCA9IGZhbHNlKSk7XHJcbiAgfVxyXG5cclxuICBnZXQgc2VsZWN0ZWRDb2x1bW5zKCk6IENvbHVtblNlbGVjdGlvbltdIHtcclxuICAgIHJldHVybiB0aGlzLm91dHB1dENvbHVtbnMuZmlsdGVyKChjKSA9PiBjLnNlbGVjdGVkKTtcclxuICB9XHJcblxyXG4gIGdldCB0b3RhbFJvd3MoKTogbnVtYmVyIHtcclxuICAgIHJldHVybiB0aGlzLnJlc3VsdD8ucm93cy5sZW5ndGggfHwgMDtcclxuICB9XHJcblxyXG4gIGdldCBwYWdlZFJvd3MoKTogUmVjb3JkPHN0cmluZywgYW55PltdIHtcclxuICAgIGlmICghdGhpcy5yZXN1bHQpIHJldHVybiBbXTtcclxuICAgIGxldCBzdGFydCA9ICh0aGlzLmN1cnJlbnRQYWdlIC0gMSkgKiB0aGlzLnBhZ2VTaXplO1xyXG4gICAgcmV0dXJuIHRoaXMucmVzdWx0LnJvd3Muc2xpY2Uoc3RhcnQsIHN0YXJ0ICsgdGhpcy5wYWdlU2l6ZSk7XHJcbiAgfVxyXG5cclxuICBnZXQgcGFnZVN0YXJ0KCk6IG51bWJlciB7XHJcbiAgICBpZiAoIXRoaXMudG90YWxSb3dzKSByZXR1cm4gMDtcclxuICAgIHJldHVybiAodGhpcy5jdXJyZW50UGFnZSAtIDEpICogdGhpcy5wYWdlU2l6ZSArIDE7XHJcbiAgfVxyXG5cclxuICBnZXQgcGFnZUVuZCgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIE1hdGgubWluKHRoaXMuY3VycmVudFBhZ2UgKiB0aGlzLnBhZ2VTaXplLCB0aGlzLnRvdGFsUm93cyk7XHJcbiAgfVxyXG5cclxuICBvblBhZ2VDaGFuZ2UocGFnZTogbnVtYmVyKSB7XHJcbiAgICB0aGlzLmN1cnJlbnRQYWdlID0gTnVtYmVyKHBhZ2UpIHx8IDE7XHJcbiAgfVxyXG5cclxuICBvblBhZ2VTaXplQ2hhbmdlKHNpemU6IG51bWJlcikge1xyXG4gICAgdGhpcy5wYWdlU2l6ZSA9IE51bWJlcihzaXplKSB8fCA1MDtcclxuICAgIHRoaXMuY3VycmVudFBhZ2UgPSAxO1xyXG4gIH1cclxuXHJcbiAgb25SdW4oKSB7XHJcbiAgICBpZiAodGhpcy5zZWxlY3RlZFN0b3Jlcy5sZW5ndGggPT09IDApIHtcclxuICAgICAgdGhpcy5zaG93TWVzc2FnZSgnUGxlYXNlIHNlbGVjdCBhdCBsZWFzdCBvbmUgc3RvcmUuJywgJ2Vycm9yJyk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGlmICh0aGlzLnNlbGVjdGVkQ29sdW1ucy5sZW5ndGggPT09IDApIHtcclxuICAgICAgdGhpcy5zaG93TWVzc2FnZSgnUGxlYXNlIHNlbGVjdCBhdCBsZWFzdCBvbmUgb3V0cHV0IGNvbHVtbi4nLCAnZXJyb3InKTtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMuc2VsZWN0aW9uTW9kZSA9PT0gJ2ZpcnN0TicpIHtcclxuICAgICAgbGV0IG4gPSBOdW1iZXIodGhpcy5saW1pdFBlclN0b3JlKTtcclxuICAgICAgaWYgKCFOdW1iZXIuaXNGaW5pdGUobikgfHwgbiA8IDEpIHtcclxuICAgICAgICB0aGlzLnNob3dNZXNzYWdlKFxyXG4gICAgICAgICAgJ051bWJlciBvZiBmaXh0dXJlcyBwZXIgc3RvcmUgbXVzdCBiZSBhIHBvc2l0aXZlIGludGVnZXIuJyxcclxuICAgICAgICAgICdlcnJvcicsXHJcbiAgICAgICAgKTtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBsZXQgY29sdW1uc1NuYXBzaG90ID0gdGhpcy5zZWxlY3RlZENvbHVtbnMubWFwKChjKSA9PiAoe1xyXG4gICAgICBrZXk6IGMua2V5LFxyXG4gICAgICBsYWJlbDogYy5sYWJlbCxcclxuICAgIH0pKTtcclxuXHJcbiAgICBsZXQgcGF5bG9hZCA9IHtcclxuICAgICAgY2xpZW50SWQ6IHRoaXMuY2xpZW50SWQsXHJcbiAgICAgIHN0b3JlTmFtZXM6IHRoaXMuc2VsZWN0ZWRTdG9yZXMubWFwKChzKSA9PiBzLmxhYmVsKSxcclxuICAgICAgZmlsdGVyczogdGhpcy5maWx0ZXJzXHJcbiAgICAgICAgLmZpbHRlcigoZikgPT4gZi5maWVsZCAmJiBmLm9wZXJhdG9yKVxyXG4gICAgICAgIC5tYXAoKGYpID0+ICh7XHJcbiAgICAgICAgICBmaWVsZDogZi5maWVsZCxcclxuICAgICAgICAgIG9wZXJhdG9yOiBmLm9wZXJhdG9yLFxyXG4gICAgICAgICAgdmFsdWU6IHRoaXMuaXNWYWx1ZURpc2FibGVkRm9yKGYub3BlcmF0b3IpID8gJycgOiBmLnZhbHVlLFxyXG4gICAgICAgIH0pKSxcclxuICAgICAgZmlsdGVyQ29tYmluYXRvcjogdGhpcy5maWx0ZXJDb21iaW5hdG9yLFxyXG4gICAgICBzZWxlY3Rpb25Nb2RlOiB0aGlzLnNlbGVjdGlvbk1vZGUsXHJcbiAgICAgIGxpbWl0UGVyU3RvcmU6XHJcbiAgICAgICAgdGhpcy5zZWxlY3Rpb25Nb2RlID09PSAnZmlyc3ROJyA/IE51bWJlcih0aGlzLmxpbWl0UGVyU3RvcmUpIDogdW5kZWZpbmVkLFxyXG4gICAgICBjb2x1bW5zOiBjb2x1bW5zU25hcHNob3QsXHJcbiAgICAgIGluY2x1ZGVOb3RGb3VuZFJvd3M6IHRoaXMuaW5jbHVkZU5vdEZvdW5kUm93cyxcclxuICAgIH07XHJcblxyXG4gICAgdGhpcy5pc1J1bm5pbmcgPSB0cnVlO1xyXG4gICAgdGhpcy5yZXN1bHQgPSBudWxsO1xyXG4gICAgdGhpcy5yZXN1bHRDb2x1bW5zID0gY29sdW1uc1NuYXBzaG90O1xyXG4gICAgdGhpcy5jdXJyZW50UGFnZSA9IDE7XHJcbiAgICB0aGlzLnNicy5ydW5QbGFub0RhdGFRdWVyeShwYXlsb2FkKS5zdWJzY3JpYmUoe1xyXG4gICAgICBuZXh0OiAocmVzOiBhbnkpID0+IHtcclxuICAgICAgICB0aGlzLnJlc3VsdCA9IHJlcz8uZGF0YSB8fCBudWxsO1xyXG4gICAgICAgIHRoaXMuaXNSdW5uaW5nID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5jdXJyZW50UGFnZSA9IDE7XHJcbiAgICAgICAgaWYgKHRoaXMucmVzdWx0KSB7XHJcbiAgICAgICAgICB0aGlzLnNob3dNZXNzYWdlKGBGb3VuZCAke3RoaXMucmVzdWx0LnRvdGFsUm93c30gcm93KHMpLmAsICdzdWNjZXNzJyk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9LFxyXG4gICAgICBlcnJvcjogKGVycjogYW55KSA9PiB7XHJcbiAgICAgICAgdGhpcy5zaG93TWVzc2FnZShcclxuICAgICAgICAgIGVycj8uZXJyb3I/Lm1lc3NhZ2UgfHwgJ0ZhaWxlZCB0byBydW4gcXVlcnkuJyxcclxuICAgICAgICAgICdlcnJvcicsXHJcbiAgICAgICAgKTtcclxuICAgICAgICB0aGlzLmlzUnVubmluZyA9IGZhbHNlO1xyXG4gICAgICB9LFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBvbkV4cG9ydCgpIHtcclxuICAgIGlmICghdGhpcy5yZXN1bHQgfHwgIXRoaXMucmVzdWx0LnJvd3MubGVuZ3RoKSB7XHJcbiAgICAgIHRoaXMuc2hvd01lc3NhZ2UoJ05vIGRhdGEgdG8gZXhwb3J0LiBSdW4gdGhlIHF1ZXJ5IGZpcnN0LicsICdlcnJvcicpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBsZXQgY2xlYW5lZCA9IHRoaXMucmVzdWx0LnJvd3MubWFwKChyKSA9PiB7XHJcbiAgICAgIGxldCBjb3B5OiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XHJcbiAgICAgIGZvciAobGV0IGNvbCBvZiB0aGlzLnJlc3VsdENvbHVtbnMpIGNvcHlbY29sLmxhYmVsXSA9IHJbY29sLmxhYmVsXSA/PyAnJztcclxuICAgICAgcmV0dXJuIGNvcHk7XHJcbiAgICB9KTtcclxuICAgIGxldCBmaWxlTmFtZSA9IGBwbGFub19kYXRhX2V4cG9ydF8ke0RhdGUubm93KCl9YDtcclxuICAgIHRoaXMuc2JzLmV4cG9ydEFzRXhjZWxGaWxlKGNsZWFuZWQsIGZpbGVOYW1lKTtcclxuICB9XHJcblxyXG4gIHNob3dNZXNzYWdlKG1zZzogc3RyaW5nLCB0eXBlOiAnc3VjY2VzcycgfCAnZXJyb3InKSB7XHJcbiAgICB0aGlzLm1lc3NhZ2UgPSBtc2c7XHJcbiAgICB0aGlzLm1lc3NhZ2VUeXBlID0gdHlwZTtcclxuICAgIHNldFRpbWVvdXQoKCkgPT4gKHRoaXMubWVzc2FnZSA9ICcnKSwgNTAwMCk7XHJcbiAgfVxyXG5cclxuICAvLyAtLS0tLS0tLS0tIFZNIFBsYWNlbWVudCBFeHBvcnQgLS0tLS0tLS0tLVxyXG5cclxuICBvblZtU3RvcmVzU2VsZWN0ZWQoc3RvcmVzOiBTdG9yZU9wdGlvbltdKSB7XHJcbiAgICB0aGlzLnZtU2VsZWN0ZWRTdG9yZXMgPSBzdG9yZXM7XHJcbiAgfVxyXG5cclxuICBnZXQgdm1Ub3RhbFJvd3MoKTogbnVtYmVyIHtcclxuICAgIHJldHVybiB0aGlzLnZtUmVzdWx0Py5yb3dzLmxlbmd0aCB8fCAwO1xyXG4gIH1cclxuXHJcbiAgZ2V0IHZtUGFnZWRSb3dzKCk6IFJlY29yZDxzdHJpbmcsIGFueT5bXSB7XHJcbiAgICBpZiAoIXRoaXMudm1SZXN1bHQpIHJldHVybiBbXTtcclxuICAgIGxldCBzdGFydCA9ICh0aGlzLnZtQ3VycmVudFBhZ2UgLSAxKSAqIHRoaXMudm1QYWdlU2l6ZTtcclxuICAgIHJldHVybiB0aGlzLnZtUmVzdWx0LnJvd3Muc2xpY2Uoc3RhcnQsIHN0YXJ0ICsgdGhpcy52bVBhZ2VTaXplKTtcclxuICB9XHJcblxyXG4gIGdldCB2bVBhZ2VTdGFydCgpOiBudW1iZXIge1xyXG4gICAgaWYgKCF0aGlzLnZtVG90YWxSb3dzKSByZXR1cm4gMDtcclxuICAgIHJldHVybiAodGhpcy52bUN1cnJlbnRQYWdlIC0gMSkgKiB0aGlzLnZtUGFnZVNpemUgKyAxO1xyXG4gIH1cclxuXHJcbiAgZ2V0IHZtUGFnZUVuZCgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIE1hdGgubWluKHRoaXMudm1DdXJyZW50UGFnZSAqIHRoaXMudm1QYWdlU2l6ZSwgdGhpcy52bVRvdGFsUm93cyk7XHJcbiAgfVxyXG5cclxuICBvblZtUGFnZUNoYW5nZShwYWdlOiBudW1iZXIpIHtcclxuICAgIHRoaXMudm1DdXJyZW50UGFnZSA9IE51bWJlcihwYWdlKSB8fCAxO1xyXG4gIH1cclxuXHJcbiAgb25WbVBhZ2VTaXplQ2hhbmdlKHNpemU6IG51bWJlcikge1xyXG4gICAgdGhpcy52bVBhZ2VTaXplID0gTnVtYmVyKHNpemUpIHx8IDUwO1xyXG4gICAgdGhpcy52bUN1cnJlbnRQYWdlID0gMTtcclxuICB9XHJcblxyXG4gIG9uVm1SdW4oKSB7XHJcbiAgICBpZiAodGhpcy52bVNlbGVjdGVkU3RvcmVzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICB0aGlzLnNob3dWbU1lc3NhZ2UoJ1BsZWFzZSBzZWxlY3QgYXQgbGVhc3Qgb25lIHN0b3JlLicsICdlcnJvcicpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcbiAgICBpZiAoIXRoaXMudm1OYW1lUmVnZXggfHwgIXRoaXMudm1OYW1lUmVnZXgudHJpbSgpKSB7XHJcbiAgICAgIHRoaXMuc2hvd1ZtTWVzc2FnZSgnUGxlYXNlIGVudGVyIGEgVk0gbmFtZSAocmVnZXgpLicsICdlcnJvcicpO1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IHBheWxvYWQgPSB7XHJcbiAgICAgIGNsaWVudElkOiB0aGlzLmNsaWVudElkLFxyXG4gICAgICBzdG9yZU5hbWVzOiB0aGlzLnZtU2VsZWN0ZWRTdG9yZXMubWFwKChzKSA9PiBzLmxhYmVsKSxcclxuICAgICAgdm1OYW1lOiB0aGlzLnZtTmFtZVJlZ2V4LnRyaW0oKSxcclxuICAgIH07XHJcblxyXG4gICAgdGhpcy5pc1ZtUnVubmluZyA9IHRydWU7XHJcbiAgICB0aGlzLnZtUmVzdWx0ID0gbnVsbDtcclxuICAgIHRoaXMudm1DdXJyZW50UGFnZSA9IDE7XHJcbiAgICB0aGlzLnNicy5ydW5WbVBsYWNlbWVudFF1ZXJ5KHBheWxvYWQpLnN1YnNjcmliZSh7XHJcbiAgICAgIG5leHQ6IChyZXM6IGFueSkgPT4ge1xyXG4gICAgICAgIHRoaXMudm1SZXN1bHQgPSByZXM/LmRhdGEgfHwgbnVsbDtcclxuICAgICAgICB0aGlzLnZtUmVzdWx0Q29sdW1ucyA9IHRoaXMudm1SZXN1bHQ/LmNvbHVtbnMgfHwgW107XHJcbiAgICAgICAgdGhpcy5pc1ZtUnVubmluZyA9IGZhbHNlO1xyXG4gICAgICAgIHRoaXMudm1DdXJyZW50UGFnZSA9IDE7XHJcbiAgICAgICAgaWYgKHRoaXMudm1SZXN1bHQpIHtcclxuICAgICAgICAgIHRoaXMuc2hvd1ZtTWVzc2FnZShcclxuICAgICAgICAgICAgYE1hdGNoZWQgJHt0aGlzLnZtUmVzdWx0Lm1hdGNoZWRWbUNvdW50fSBWTShzKTsgZm91bmQgJHt0aGlzLnZtUmVzdWx0LnRvdGFsUm93c30gcGxhY2VtZW50IHJvdyhzKS5gLFxyXG4gICAgICAgICAgICAnc3VjY2VzcycsXHJcbiAgICAgICAgICApO1xyXG4gICAgICAgIH1cclxuICAgICAgfSxcclxuICAgICAgZXJyb3I6IChlcnI6IGFueSkgPT4ge1xyXG4gICAgICAgIHRoaXMuc2hvd1ZtTWVzc2FnZShcclxuICAgICAgICAgIGVycj8uZXJyb3I/Lm1lc3NhZ2UgfHwgJ0ZhaWxlZCB0byBydW4gVk0gcGxhY2VtZW50IHF1ZXJ5LicsXHJcbiAgICAgICAgICAnZXJyb3InLFxyXG4gICAgICAgICk7XHJcbiAgICAgICAgdGhpcy5pc1ZtUnVubmluZyA9IGZhbHNlO1xyXG4gICAgICB9LFxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBvblZtRXhwb3J0KCkge1xyXG4gICAgaWYgKCF0aGlzLnZtUmVzdWx0IHx8ICF0aGlzLnZtUmVzdWx0LnJvd3MubGVuZ3RoKSB7XHJcbiAgICAgIHRoaXMuc2hvd1ZtTWVzc2FnZSgnTm8gZGF0YSB0byBleHBvcnQuIFJ1biB0aGUgcXVlcnkgZmlyc3QuJywgJ2Vycm9yJyk7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuICAgIGxldCBjbGVhbmVkID0gdGhpcy52bVJlc3VsdC5yb3dzLm1hcCgocikgPT4ge1xyXG4gICAgICBsZXQgY29weTogUmVjb3JkPHN0cmluZywgYW55PiA9IHt9O1xyXG4gICAgICBmb3IgKGxldCBjb2wgb2YgdGhpcy52bVJlc3VsdENvbHVtbnMpIGNvcHlbY29sXSA9IHJbY29sXSA/PyAnJztcclxuICAgICAgcmV0dXJuIGNvcHk7XHJcbiAgICB9KTtcclxuICAgIGxldCBzYWZlTmFtZSA9ICh0aGlzLnZtTmFtZVJlZ2V4IHx8ICd2bScpXHJcbiAgICAgIC50cmltKClcclxuICAgICAgLnJlcGxhY2UoL1teYS16MC05XSsvZ2ksICdfJylcclxuICAgICAgLnRvTG93ZXJDYXNlKCk7XHJcbiAgICBsZXQgZmlsZU5hbWUgPSBgdm1fcGxhY2VtZW50XyR7c2FmZU5hbWV9XyR7RGF0ZS5ub3coKX1gO1xyXG4gICAgdGhpcy5zYnMuZXhwb3J0QXNFeGNlbEZpbGUoY2xlYW5lZCwgZmlsZU5hbWUpO1xyXG4gIH1cclxuXHJcbiAgc2hvd1ZtTWVzc2FnZShtc2c6IHN0cmluZywgdHlwZTogJ3N1Y2Nlc3MnIHwgJ2Vycm9yJykge1xyXG4gICAgdGhpcy52bU1lc3NhZ2UgPSBtc2c7XHJcbiAgICB0aGlzLnZtTWVzc2FnZVR5cGUgPSB0eXBlO1xyXG4gICAgc2V0VGltZW91dCgoKSA9PiAodGhpcy52bU1lc3NhZ2UgPSAnJyksIDUwMDApO1xyXG4gIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XHJcbiAgICB0aGlzLmRlc3Ryb3kkLm5leHQoKTtcclxuICAgIHRoaXMuZGVzdHJveSQuY29tcGxldGUoKTtcclxuICB9XHJcbn1cclxuIiwiPHNlY3Rpb24gY2xhc3M9XCJwbGFuby1kYXRhLWV4cG9ydCBwLTNcIj5cclxuICA8bGliLXRvb2wtcGFnZS1oZWFkZXJcclxuICAgIHRpdGxlPVwiRGF0YSBFeHBvcnRcIlxyXG4gICAgZGVzY3JpcHRpb249XCJCdWlsZCBhIHF1ZXJ5IGFnYWluc3QgcGxhbm9ncmFtIGZpeHR1cmVzLCBwcmV2aWV3IHJlc3VsdHMsIGFuZCBleHBvcnQgYXMgRXhjZWwuXCJcclxuICA+PC9saWItdG9vbC1wYWdlLWhlYWRlcj5cclxuICA8ZGl2IGNsYXNzPVwiY2FyZCBwLTQgbWItM1wiPlxyXG5cclxuICAgIEBpZiAoaXNMb2FkaW5nU2NoZW1hKSB7XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW11dGVkIHNtYWxsXCI+TG9hZGluZyBxdWVyeSBzY2hlbWEuLi48L2Rpdj5cclxuICAgIH1cclxuXHJcbiAgICA8IS0tIFN0b3JlcyAtLT5cclxuICAgIDxkaXYgY2xhc3M9XCJibG9jayBtYi0zXCI+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJibG9jay10aXRsZVwiPlN0b3JlczwvZGl2PlxyXG4gICAgICA8bGliLXN0b3JlLXNlbGVjdFxyXG4gICAgICAgIFtvcHRpb25zXT1cInN0b3JlT3B0aW9uc1wiXHJcbiAgICAgICAgW2luaXRpYWxTZWxlY3RlZF09XCJpbml0aWFsU3RvcmVzXCJcclxuICAgICAgICAoc2VsZWN0ZWRDaGFuZ2UpPVwib25TdG9yZXNTZWxlY3RlZCgkZXZlbnQpXCI+XHJcbiAgICAgIDwvbGliLXN0b3JlLXNlbGVjdD5cclxuICAgIDwvZGl2PlxyXG5cclxuICAgIDwhLS0gTWF0Y2ggQ3JpdGVyaWEgLS0+XHJcbiAgICA8ZGl2IGNsYXNzPVwiYmxvY2sgbWItM1wiPlxyXG4gICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBtYi0yXCI+XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cImJsb2NrLXRpdGxlIG1iLTBcIj5NYXRjaCBDcml0ZXJpYTwvZGl2PlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyIGdhcC0zXCI+XHJcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1jaGVjayBmb3JtLWNoZWNrLWlubGluZSBtYi0wXCI+XHJcbiAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIiB0eXBlPVwicmFkaW9cIiBpZD1cImNvbWJBbmRcIlxyXG4gICAgICAgICAgICAgIG5hbWU9XCJjb21iaW5hdG9yXCIgdmFsdWU9XCJBTkRcIiBbKG5nTW9kZWwpXT1cImZpbHRlckNvbWJpbmF0b3JcIj5cclxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZm9ybS1jaGVjay1sYWJlbFwiIGZvcj1cImNvbWJBbmRcIj5NYXRjaCBhbGwgKEFORCk8L2xhYmVsPlxyXG4gICAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZm9ybS1jaGVjayBmb3JtLWNoZWNrLWlubGluZSBtYi0wXCI+XHJcbiAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIiB0eXBlPVwicmFkaW9cIiBpZD1cImNvbWJPclwiXHJcbiAgICAgICAgICAgICAgbmFtZT1cImNvbWJpbmF0b3JcIiB2YWx1ZT1cIk9SXCIgWyhuZ01vZGVsKV09XCJmaWx0ZXJDb21iaW5hdG9yXCI+XHJcbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tY2hlY2stbGFiZWxcIiBmb3I9XCJjb21iT3JcIj5NYXRjaCBhbnkgKE9SKTwvbGFiZWw+XHJcbiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgPC9kaXY+XHJcblxyXG4gICAgICBAaWYgKCFmaWx0ZXJzLmxlbmd0aCkge1xyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW11dGVkIHNtYWxsIG1iLTJcIj5cclxuICAgICAgICAgIE5vIGNyaXRlcmlhIOKAlCBxdWVyeSB3aWxsIHJldHVybiBldmVyeSBmaXh0dXJlIGZvciB0aGUgc2VsZWN0ZWQgc3RvcmVzLlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICB9XHJcblxyXG4gICAgICBAZm9yIChyb3cgb2YgZmlsdGVyczsgdHJhY2sgJGluZGV4KSB7XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cImZpbHRlci1yb3cgZC1mbGV4IGdhcC0yIG1iLTIgYWxpZ24taXRlbXMtY2VudGVyXCI+XHJcbiAgICAgICAgICA8c2VsZWN0IGNsYXNzPVwiZm9ybS1zZWxlY3QgZm9ybS1zZWxlY3Qtc20gZmlsdGVyLWZpZWxkXCJcclxuICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJyb3cuZmllbGRcIlxyXG4gICAgICAgICAgICAoY2hhbmdlKT1cIm9uRmlsdGVyRmllbGRDaGFuZ2UoJGluZGV4KVwiPlxyXG4gICAgICAgICAgICBAZm9yIChmIG9mIGZpbHRlcmFibGVGaWVsZHM7IHRyYWNrIGYua2V5KSB7XHJcbiAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwiZi5rZXlcIj57eyBmLmxhYmVsIH19PC9vcHRpb24+XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIDwvc2VsZWN0PlxyXG5cclxuICAgICAgICAgIDxzZWxlY3QgY2xhc3M9XCJmb3JtLXNlbGVjdCBmb3JtLXNlbGVjdC1zbSBmaWx0ZXItb3BcIlxyXG4gICAgICAgICAgICBbKG5nTW9kZWwpXT1cInJvdy5vcGVyYXRvclwiPlxyXG4gICAgICAgICAgICBAZm9yIChvcCBvZiBvcGVyYXRvcnNGb3JGaWVsZChyb3cuZmllbGQpOyB0cmFjayBvcC5rZXkpIHtcclxuICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCJvcC5rZXlcIj57eyBvcC5sYWJlbCB9fTwvb3B0aW9uPlxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICA8L3NlbGVjdD5cclxuXHJcbiAgICAgICAgICA8aW5wdXRcclxuICAgICAgICAgICAgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZm9ybS1jb250cm9sLXNtIGZpbHRlci12YWx1ZVwiXHJcbiAgICAgICAgICAgIFtwbGFjZWhvbGRlcl09XCJpc1ZhbHVlRGlzYWJsZWRGb3Iocm93Lm9wZXJhdG9yKSA/ICfigJQnIDogJ3ZhbHVlJ1wiXHJcbiAgICAgICAgICAgIFtkaXNhYmxlZF09XCJpc1ZhbHVlRGlzYWJsZWRGb3Iocm93Lm9wZXJhdG9yKVwiXHJcbiAgICAgICAgICAgIFsobmdNb2RlbCldPVwicm93LnZhbHVlXCI+XHJcblxyXG4gICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc20gYnRuLW91dGxpbmUtZGFuZ2VyXCIgKGNsaWNrKT1cInJlbW92ZUZpbHRlcigkaW5kZXgpXCJcclxuICAgICAgICAgICAgdGl0bGU9XCJSZW1vdmVcIj7DlzwvYnV0dG9uPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICB9XHJcblxyXG4gICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zbSBidG4tb3V0bGluZS1wcmltYXJ5XCIgKGNsaWNrKT1cImFkZEZpbHRlcigpXCJcclxuICAgICAgICBbZGlzYWJsZWRdPVwiIWZpbHRlcmFibGVGaWVsZHMubGVuZ3RoXCI+XHJcbiAgICAgICAgKyBBZGQgQ3JpdGVyaW9uXHJcbiAgICAgIDwvYnV0dG9uPlxyXG4gICAgPC9kaXY+XHJcblxyXG4gICAgPCEtLSBTZWxlY3Rpb24gTW9kZSAtLT5cclxuICAgIDxkaXYgY2xhc3M9XCJibG9jayBtYi0zXCI+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJibG9jay10aXRsZVwiPkZpeHR1cmUgU2VsZWN0aW9uPC9kaXY+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZmxleC13cmFwIGFsaWduLWl0ZW1zLWNlbnRlciBnYXAtM1wiPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWNoZWNrIG1iLTBcIj5cclxuICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIiB0eXBlPVwicmFkaW9cIiBpZD1cInNlbEFsbFwiXHJcbiAgICAgICAgICAgIG5hbWU9XCJzZWxlY3Rpb25Nb2RlXCIgdmFsdWU9XCJhbGxcIiBbKG5nTW9kZWwpXT1cInNlbGVjdGlvbk1vZGVcIj5cclxuICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tY2hlY2stbGFiZWxcIiBmb3I9XCJzZWxBbGxcIj5BbGwgbWF0Y2hpbmcgZml4dHVyZXM8L2xhYmVsPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJmb3JtLWNoZWNrIG1iLTBcIj5cclxuICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIiB0eXBlPVwicmFkaW9cIiBpZD1cInNlbEZpcnN0TlwiXHJcbiAgICAgICAgICAgIG5hbWU9XCJzZWxlY3Rpb25Nb2RlXCIgdmFsdWU9XCJmaXJzdE5cIiBbKG5nTW9kZWwpXT1cInNlbGVjdGlvbk1vZGVcIj5cclxuICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tY2hlY2stbGFiZWxcIiBmb3I9XCJzZWxGaXJzdE5cIj5GaXJzdDwvbGFiZWw+XHJcbiAgICAgICAgPC9kaXY+XHJcbiAgICAgICAgPGlucHV0XHJcbiAgICAgICAgICB0eXBlPVwibnVtYmVyXCJcclxuICAgICAgICAgIG1pbj1cIjFcIlxyXG4gICAgICAgICAgY2xhc3M9XCJmb3JtLWNvbnRyb2wgZm9ybS1jb250cm9sLXNtIGNvdW50LWlucHV0XCJcclxuICAgICAgICAgIFsobmdNb2RlbCldPVwibGltaXRQZXJTdG9yZVwiXHJcbiAgICAgICAgICBbZGlzYWJsZWRdPVwic2VsZWN0aW9uTW9kZSAhPT0gJ2ZpcnN0TidcIj5cclxuICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtbXV0ZWQgc21hbGxcIj5tYXRjaGluZyBmcm9tIGVudHJhbmNlLCBwZXIgc3RvcmU8L3NwYW4+XHJcbiAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgPGRpdiBjbGFzcz1cImZvcm0tY2hlY2sgbXQtMlwiPlxyXG4gICAgICAgIDxpbnB1dCBjbGFzcz1cImZvcm0tY2hlY2staW5wdXRcIiB0eXBlPVwiY2hlY2tib3hcIiBpZD1cImluY05vdEZvdW5kXCJcclxuICAgICAgICAgIFsobmdNb2RlbCldPVwiaW5jbHVkZU5vdEZvdW5kUm93c1wiPlxyXG4gICAgICAgIDxsYWJlbCBjbGFzcz1cImZvcm0tY2hlY2stbGFiZWxcIiBmb3I9XCJpbmNOb3RGb3VuZFwiPlxyXG4gICAgICAgICAgSW5jbHVkZSBlbXB0eSByb3dzIGZvciBzdG9yZXMgd2l0aCBubyBtYXRjaGVzXHJcbiAgICAgICAgPC9sYWJlbD5cclxuICAgICAgPC9kaXY+XHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgICA8IS0tIE91dHB1dCBDb2x1bW5zIC0tPlxyXG4gICAgPGRpdiBjbGFzcz1cImJsb2NrIG1iLTNcIj5cclxuICAgICAgPGRpdiBjbGFzcz1cImQtZmxleCBhbGlnbi1pdGVtcy1jZW50ZXIganVzdGlmeS1jb250ZW50LWJldHdlZW4gbWItMlwiPlxyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJibG9jay10aXRsZSBtYi0wXCI+T3V0cHV0IENvbHVtbnM8L2Rpdj5cclxuICAgICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGdhcC0yXCI+XHJcbiAgICAgICAgICA8YnV0dG9uIGNsYXNzPVwiYnRuIGJ0bi1zbSBidG4tbGluayBwLTBcIiAoY2xpY2spPVwic2VsZWN0QWxsQ29sdW1ucygpXCI+XHJcbiAgICAgICAgICAgIFNlbGVjdCBhbGxcclxuICAgICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ0biBidG4tc20gYnRuLWxpbmsgcC0wXCIgKGNsaWNrKT1cImNsZWFyQWxsQ29sdW1ucygpXCI+XHJcbiAgICAgICAgICAgIENsZWFyXHJcbiAgICAgICAgICA8L2J1dHRvbj5cclxuICAgICAgICA8L2Rpdj5cclxuICAgICAgPC9kaXY+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJjb2x1bW4tZ3JpZFwiPlxyXG4gICAgICAgIEBmb3IgKGNvbCBvZiBvdXRwdXRDb2x1bW5zOyB0cmFjayBjb2wua2V5KSB7XHJcbiAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJjb2x1bW4taXRlbVwiPlxyXG4gICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgY2xhc3M9XCJmb3JtLWNoZWNrLWlucHV0IG1lLTJcIlxyXG4gICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiY29sLnNlbGVjdGVkXCI+XHJcbiAgICAgICAgICAgIHt7IGNvbC5sYWJlbCB9fVxyXG4gICAgICAgICAgPC9sYWJlbD5cclxuICAgICAgICB9XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgPC9kaXY+XHJcblxyXG4gICAgPCEtLSBBY3Rpb24gQnV0dG9ucyAtLT5cclxuICAgIDxkaXYgY2xhc3M9XCJkLWZsZXggZ2FwLTJcIj5cclxuICAgICAgPGJ1dHRvblxyXG4gICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5XCJcclxuICAgICAgICAoY2xpY2spPVwib25SdW4oKVwiXHJcbiAgICAgICAgW2Rpc2FibGVkXT1cImlzUnVubmluZyB8fCBpc0xvYWRpbmdTY2hlbWEgfHwgc2VsZWN0ZWRTdG9yZXMubGVuZ3RoID09PSAwXCI+XHJcbiAgICAgICAge3sgaXNSdW5uaW5nID8gJ1J1bm5pbmcuLi4nIDogJ1J1biBRdWVyeScgfX1cclxuICAgICAgPC9idXR0b24+XHJcbiAgICAgIDxidXR0b25cclxuICAgICAgICBjbGFzcz1cImJ0biBidG4tc3VjY2Vzc1wiXHJcbiAgICAgICAgKGNsaWNrKT1cIm9uRXhwb3J0KClcIlxyXG4gICAgICAgIFtkaXNhYmxlZF09XCIhcmVzdWx0IHx8ICFyZXN1bHQucm93cy5sZW5ndGhcIj5cclxuICAgICAgICBFeHBvcnQgdG8gRXhjZWxcclxuICAgICAgPC9idXR0b24+XHJcbiAgICA8L2Rpdj5cclxuXHJcbiAgICBAaWYgKG1lc3NhZ2UpIHtcclxuICAgICAgPGRpdlxyXG4gICAgICAgIGNsYXNzPVwibXQtMyBhbGVydFwiXHJcbiAgICAgICAgW2NsYXNzLmFsZXJ0LXN1Y2Nlc3NdPVwibWVzc2FnZVR5cGUgPT09ICdzdWNjZXNzJ1wiXHJcbiAgICAgICAgW2NsYXNzLmFsZXJ0LWRhbmdlcl09XCJtZXNzYWdlVHlwZSA9PT0gJ2Vycm9yJ1wiPlxyXG4gICAgICAgIHt7IG1lc3NhZ2UgfX1cclxuICAgICAgPC9kaXY+XHJcbiAgICB9XHJcbiAgPC9kaXY+XHJcblxyXG4gIDwhLS0gVk0gUGxhY2VtZW50IEV4cG9ydCBieSBWTSBOYW1lIC0tPlxyXG4gIDxkaXYgY2xhc3M9XCJjYXJkIHAtNCBtYi0zXCI+XHJcbiAgICA8aDUgY2xhc3M9XCJtYi0xXCI+Vk0gUGxhY2VtZW50IEV4cG9ydCBieSBWTSBOYW1lPC9oNT5cclxuICAgIDxwIGNsYXNzPVwidGV4dC1tdXRlZCBzbWFsbCBtYi0zXCI+XHJcbiAgICAgIEZpbmQgZXZlcnkgZml4dHVyZSAoaW4gdGhlIHNlbGVjdGVkIHN0b3JlcykgdGhhdCBjb250YWlucyBhbnkgVk0gd2hvc2VcclxuICAgICAgPGNvZGU+dm1OYW1lPC9jb2RlPiBtYXRjaGVzIHRoZSByZWdleCwgYW5kIGV4cG9ydCBvbmUgcm93IHBlciBWTSBwbGFjZW1lbnRcclxuICAgICAgd2l0aCBmaXh0dXJlIGRldGFpbHMgYW5kIHNoZWxmL3pvbmUgY29vcmRpbmF0ZXMuXHJcbiAgICA8L3A+XHJcblxyXG4gICAgPGRpdiBjbGFzcz1cImJsb2NrIG1iLTNcIj5cclxuICAgICAgPGRpdiBjbGFzcz1cImJsb2NrLXRpdGxlXCI+U3RvcmVzPC9kaXY+XHJcbiAgICAgIDxsaWItc3RvcmUtc2VsZWN0XHJcbiAgICAgICAgW29wdGlvbnNdPVwic3RvcmVPcHRpb25zXCJcclxuICAgICAgICBbaW5pdGlhbFNlbGVjdGVkXT1cInZtSW5pdGlhbFN0b3Jlc1wiXHJcbiAgICAgICAgKHNlbGVjdGVkQ2hhbmdlKT1cIm9uVm1TdG9yZXNTZWxlY3RlZCgkZXZlbnQpXCI+XHJcbiAgICAgIDwvbGliLXN0b3JlLXNlbGVjdD5cclxuICAgIDwvZGl2PlxyXG5cclxuICAgIDxkaXYgY2xhc3M9XCJibG9jayBtYi0zXCI+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJibG9jay10aXRsZVwiPlZNIE5hbWUgKHJlZ2V4KTwvZGl2PlxyXG4gICAgICA8aW5wdXRcclxuICAgICAgICBjbGFzcz1cImZvcm0tY29udHJvbCBmb3JtLWNvbnRyb2wtc21cIlxyXG4gICAgICAgIHBsYWNlaG9sZGVyPVwiZS5nLiBab2RpYWMsIF5IaXBob3AsIExlYXRoZXJpdGVcIlxyXG4gICAgICAgIFsobmdNb2RlbCldPVwidm1OYW1lUmVnZXhcIj5cclxuICAgICAgPHNtYWxsIGNsYXNzPVwidGV4dC1tdXRlZFwiPkNhc2UtaW5zZW5zaXRpdmUuIE1hdGNoZWQgYWdhaW5zdCB0aGUgPGNvZGU+cGxhbm9WbURldGFpbHMudm1OYW1lPC9jb2RlPiBmaWVsZC48L3NtYWxsPlxyXG4gICAgPC9kaXY+XHJcblxyXG4gICAgPGRpdiBjbGFzcz1cImQtZmxleCBnYXAtMlwiPlxyXG4gICAgICA8YnV0dG9uXHJcbiAgICAgICAgY2xhc3M9XCJidG4gYnRuLXByaW1hcnlcIlxyXG4gICAgICAgIChjbGljayk9XCJvblZtUnVuKClcIlxyXG4gICAgICAgIFtkaXNhYmxlZF09XCJpc1ZtUnVubmluZyB8fCB2bVNlbGVjdGVkU3RvcmVzLmxlbmd0aCA9PT0gMCB8fCAhdm1OYW1lUmVnZXgudHJpbSgpXCI+XHJcbiAgICAgICAge3sgaXNWbVJ1bm5pbmcgPyAnUnVubmluZy4uLicgOiAnUnVuIFF1ZXJ5JyB9fVxyXG4gICAgICA8L2J1dHRvbj5cclxuICAgICAgPGJ1dHRvblxyXG4gICAgICAgIGNsYXNzPVwiYnRuIGJ0bi1zdWNjZXNzXCJcclxuICAgICAgICAoY2xpY2spPVwib25WbUV4cG9ydCgpXCJcclxuICAgICAgICBbZGlzYWJsZWRdPVwiIXZtUmVzdWx0IHx8ICF2bVJlc3VsdC5yb3dzLmxlbmd0aFwiPlxyXG4gICAgICAgIEV4cG9ydCB0byBFeGNlbFxyXG4gICAgICA8L2J1dHRvbj5cclxuICAgIDwvZGl2PlxyXG5cclxuICAgIEBpZiAodm1NZXNzYWdlKSB7XHJcbiAgICAgIDxkaXZcclxuICAgICAgICBjbGFzcz1cIm10LTMgYWxlcnRcIlxyXG4gICAgICAgIFtjbGFzcy5hbGVydC1zdWNjZXNzXT1cInZtTWVzc2FnZVR5cGUgPT09ICdzdWNjZXNzJ1wiXHJcbiAgICAgICAgW2NsYXNzLmFsZXJ0LWRhbmdlcl09XCJ2bU1lc3NhZ2VUeXBlID09PSAnZXJyb3InXCI+XHJcbiAgICAgICAge3sgdm1NZXNzYWdlIH19XHJcbiAgICAgIDwvZGl2PlxyXG4gICAgfVxyXG4gIDwvZGl2PlxyXG5cclxuICBAaWYgKHZtUmVzdWx0KSB7XHJcbiAgICA8ZGl2IGNsYXNzPVwiY2FyZCBwLTQgbWItM1wiPlxyXG4gICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBtYi0zXCI+XHJcbiAgICAgICAgPGRpdj5cclxuICAgICAgICAgIDxoNiBjbGFzcz1cIm1iLTBcIj5WTSBQbGFjZW1lbnQgUmVzdWx0czwvaDY+XHJcbiAgICAgICAgICA8c21hbGwgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+XHJcbiAgICAgICAgICAgIHt7IHZtVG90YWxSb3dzIH19IHJvdyhzKVxyXG4gICAgICAgICAgICBAaWYgKHZtVG90YWxSb3dzKSB7XHJcbiAgICAgICAgICAgICAgwrcgc2hvd2luZyB7eyB2bVBhZ2VTdGFydCB9feKAk3t7IHZtUGFnZUVuZCB9fVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICA8L3NtYWxsPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICA8L2Rpdj5cclxuXHJcbiAgICAgIEBpZiAoIXZtUmVzdWx0LnJvd3MubGVuZ3RoKSB7XHJcbiAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbXV0ZWRcIj5ObyBWTSBwbGFjZW1lbnRzIGZvdW5kIGZvciB0aGUgZ2l2ZW4gc3RvcmVzIGFuZCB2bU5hbWUuPC9kaXY+XHJcbiAgICAgIH0gQGVsc2Uge1xyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0YWJsZS1yZXNwb25zaXZlXCI+XHJcbiAgICAgICAgICA8dGFibGUgY2xhc3M9XCJ0YWJsZSB0YWJsZS1zbSB0YWJsZS1ib3JkZXJlZFwiPlxyXG4gICAgICAgICAgICA8dGhlYWQ+XHJcbiAgICAgICAgICAgICAgPHRyPlxyXG4gICAgICAgICAgICAgICAgQGZvciAoY29sIG9mIHZtUmVzdWx0Q29sdW1uczsgdHJhY2sgY29sKSB7XHJcbiAgICAgICAgICAgICAgICAgIDx0aD57eyBjb2wgfX08L3RoPlxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgICAgIDwvdGhlYWQ+XHJcbiAgICAgICAgICAgIDx0Ym9keT5cclxuICAgICAgICAgICAgICBAZm9yIChyb3cgb2Ygdm1QYWdlZFJvd3M7IHRyYWNrICRpbmRleCkge1xyXG4gICAgICAgICAgICAgICAgPHRyPlxyXG4gICAgICAgICAgICAgICAgICBAZm9yIChjb2wgb2Ygdm1SZXN1bHRDb2x1bW5zOyB0cmFjayBjb2wpIHtcclxuICAgICAgICAgICAgICAgICAgICA8dGRcclxuICAgICAgICAgICAgICAgICAgICAgIFtuZ2JUb29sdGlwXT1cInJvd1tjb2xdPy50b1N0cmluZygpID8gcm93W2NvbF0gOiBudWxsXCJcclxuICAgICAgICAgICAgICAgICAgICAgIGNvbnRhaW5lcj1cImJvZHlcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgcGxhY2VtZW50PVwidG9wXCJcclxuICAgICAgICAgICAgICAgICAgICAgIFtvcGVuRGVsYXldPVwiMzAwXCI+XHJcbiAgICAgICAgICAgICAgICAgICAgICB7eyByb3dbY29sXSB9fVxyXG4gICAgICAgICAgICAgICAgICAgIDwvdGQ+XHJcbiAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICA8L3Rib2R5PlxyXG4gICAgICAgICAgPC90YWJsZT5cclxuICAgICAgICA8L2Rpdj5cclxuXHJcbiAgICAgICAgPGxpYi1wYWdpbmF0aW9uXHJcbiAgICAgICAgICBbaXRlbXNQZXJQYWdlXT1cInZtUGFnZVNpemVcIlxyXG4gICAgICAgICAgW2N1cnJlbnRQYWdlXT1cInZtQ3VycmVudFBhZ2VcIlxyXG4gICAgICAgICAgW3RvdGFsSXRlbXNdPVwidm1Ub3RhbFJvd3NcIlxyXG4gICAgICAgICAgW3BhZ2VTaXplXT1cInZtUGFnZVNpemVcIlxyXG4gICAgICAgICAgW3BhZ2luYXRpb25TaXplc109XCJwYWdpbmF0aW9uU2l6ZXNcIlxyXG4gICAgICAgICAgW2RpcmVjdGlvbkxpbmtzXT1cInRydWVcIlxyXG4gICAgICAgICAgKHBhZ2VDaGFuZ2UpPVwib25WbVBhZ2VDaGFuZ2UoJGV2ZW50KVwiXHJcbiAgICAgICAgICAocGFnZVNpemVDaGFuZ2UpPVwib25WbVBhZ2VTaXplQ2hhbmdlKCRldmVudClcIj5cclxuICAgICAgICA8L2xpYi1wYWdpbmF0aW9uPlxyXG4gICAgICB9XHJcbiAgICA8L2Rpdj5cclxuICB9XHJcblxyXG4gIDwhLS0gUmVzdWx0IFByZXZpZXcgLS0+XHJcbiAgQGlmIChyZXN1bHQpIHtcclxuICAgIDxkaXYgY2xhc3M9XCJjYXJkIHAtNFwiPlxyXG4gICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtYmV0d2VlbiBtYi0zXCI+XHJcbiAgICAgICAgPGRpdj5cclxuICAgICAgICAgIDxoNiBjbGFzcz1cIm1iLTBcIj5SZXN1bHRzPC9oNj5cclxuICAgICAgICAgIDxzbWFsbCBjbGFzcz1cInRleHQtbXV0ZWRcIj5cclxuICAgICAgICAgICAge3sgdG90YWxSb3dzIH19IHJvdyhzKVxyXG4gICAgICAgICAgICBAaWYgKHRvdGFsUm93cykge1xyXG4gICAgICAgICAgICAgIMK3IHNob3dpbmcge3sgcGFnZVN0YXJ0IH194oCTe3sgcGFnZUVuZCB9fVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICA8L3NtYWxsPlxyXG4gICAgICAgIDwvZGl2PlxyXG4gICAgICA8L2Rpdj5cclxuXHJcbiAgICAgIEBpZiAoIXJlc3VsdC5yb3dzLmxlbmd0aCkge1xyXG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LW11dGVkXCI+Tm8gZGF0YSBmb3VuZCBmb3IgdGhlIGdpdmVuIHF1ZXJ5LjwvZGl2PlxyXG4gICAgICB9IEBlbHNlIHtcclxuICAgICAgICA8ZGl2IGNsYXNzPVwidGFibGUtcmVzcG9uc2l2ZVwiPlxyXG4gICAgICAgICAgPHRhYmxlIGNsYXNzPVwidGFibGUgdGFibGUtc20gdGFibGUtYm9yZGVyZWRcIj5cclxuICAgICAgICAgICAgPHRoZWFkPlxyXG4gICAgICAgICAgICAgIDx0cj5cclxuICAgICAgICAgICAgICAgIEBmb3IgKGNvbCBvZiByZXN1bHRDb2x1bW5zOyB0cmFjayBjb2wua2V5KSB7XHJcbiAgICAgICAgICAgICAgICAgIDx0aD57eyBjb2wubGFiZWwgfX08L3RoPlxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIDwvdHI+XHJcbiAgICAgICAgICAgIDwvdGhlYWQ+XHJcbiAgICAgICAgICAgIDx0Ym9keT5cclxuICAgICAgICAgICAgICBAZm9yIChyb3cgb2YgcGFnZWRSb3dzOyB0cmFjayAkaW5kZXgpIHtcclxuICAgICAgICAgICAgICAgIDx0ciBbY2xhc3Mucm93LW5vdC1mb3VuZF09XCJyb3dbJ19fbm90Rm91bmQnXVwiPlxyXG4gICAgICAgICAgICAgICAgICBAZm9yIChjb2wgb2YgcmVzdWx0Q29sdW1uczsgdHJhY2sgY29sLmtleSkge1xyXG4gICAgICAgICAgICAgICAgICAgIDx0ZFxyXG4gICAgICAgICAgICAgICAgICAgICAgW25nYlRvb2x0aXBdPVwicm93W2NvbC5sYWJlbF0/LnRvU3RyaW5nKCkgPyByb3dbY29sLmxhYmVsXSA6IG51bGxcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgY29udGFpbmVyPVwiYm9keVwiXHJcbiAgICAgICAgICAgICAgICAgICAgICBwbGFjZW1lbnQ9XCJ0b3BcIlxyXG4gICAgICAgICAgICAgICAgICAgICAgW29wZW5EZWxheV09XCIzMDBcIj5cclxuICAgICAgICAgICAgICAgICAgICAgIHt7IHJvd1tjb2wubGFiZWxdIH19XHJcbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cclxuICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgPC90cj5cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIDwvdGJvZHk+XHJcbiAgICAgICAgICA8L3RhYmxlPlxyXG4gICAgICAgIDwvZGl2PlxyXG5cclxuICAgICAgICA8bGliLXBhZ2luYXRpb25cclxuICAgICAgICAgIFtpdGVtc1BlclBhZ2VdPVwicGFnZVNpemVcIlxyXG4gICAgICAgICAgW2N1cnJlbnRQYWdlXT1cImN1cnJlbnRQYWdlXCJcclxuICAgICAgICAgIFt0b3RhbEl0ZW1zXT1cInRvdGFsUm93c1wiXHJcbiAgICAgICAgICBbcGFnZVNpemVdPVwicGFnZVNpemVcIlxyXG4gICAgICAgICAgW3BhZ2luYXRpb25TaXplc109XCJwYWdpbmF0aW9uU2l6ZXNcIlxyXG4gICAgICAgICAgW2RpcmVjdGlvbkxpbmtzXT1cInRydWVcIlxyXG4gICAgICAgICAgKHBhZ2VDaGFuZ2UpPVwib25QYWdlQ2hhbmdlKCRldmVudClcIlxyXG4gICAgICAgICAgKHBhZ2VTaXplQ2hhbmdlKT1cIm9uUGFnZVNpemVDaGFuZ2UoJGV2ZW50KVwiPlxyXG4gICAgICAgIDwvbGliLXBhZ2luYXRpb24+XHJcbiAgICAgIH1cclxuICAgIDwvZGl2PlxyXG4gIH1cclxuPC9zZWN0aW9uPlxyXG4iXX0=