bways-report 0.1.5 → 0.1.6
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.
- package/README.md +75 -35
- package/esm2022/lib/core/services/index.mjs +2 -1
- package/esm2022/lib/core/services/report-data-discovery.service.mjs +135 -0
- package/esm2022/lib/core/tokens/reporting-config.token.mjs +1 -1
- package/esm2022/lib/core/utils/identifier-humanizer.mjs +15 -4
- package/esm2022/lib/data-access/adapters/http-lookup.adapter.mjs +17 -8
- package/esm2022/lib/features/designer/components/design-canvas/design-canvas.component.mjs +69 -11
- package/esm2022/lib/features/designer/components/property-editor/parameter-binding-editor.component.mjs +345 -213
- package/esm2022/lib/features/designer/components/property-editor/property-editor-action.component.mjs +39 -32
- package/esm2022/lib/features/designer/components/property-editor/property-editor-datasource.component.mjs +35 -3
- package/esm2022/lib/features/designer/components/property-editor/property-editor-grid.component.mjs +97 -5
- package/esm2022/lib/features/designer/components/property-editor/property-editor.component.mjs +112 -39
- package/esm2022/lib/features/designer/designer.component.mjs +3 -3
- package/esm2022/lib/features/designer/services/designer-state.service.mjs +62 -2
- package/esm2022/lib/features/runtime/report-grid-bridge.component.mjs +106 -14
- package/esm2022/lib/primitives/components/dropdown/rpt-dropdown.component.mjs +31 -5
- package/esm2022/lib/provide-reporting.mjs +20 -5
- package/fesm2022/bways-report.mjs +1620 -896
- package/fesm2022/bways-report.mjs.map +1 -1
- package/lib/core/services/index.d.ts +1 -0
- package/lib/core/services/report-data-discovery.service.d.ts +38 -0
- package/lib/core/tokens/reporting-config.token.d.ts +2 -0
- package/lib/data-access/adapters/http-lookup.adapter.d.ts +2 -1
- package/lib/features/designer/components/design-canvas/design-canvas.component.d.ts +5 -1
- package/lib/features/designer/components/property-editor/parameter-binding-editor.component.d.ts +5 -0
- package/lib/features/designer/components/property-editor/property-editor-action.component.d.ts +3 -0
- package/lib/features/designer/components/property-editor/property-editor-grid.component.d.ts +31 -1
- package/lib/features/designer/components/property-editor/property-editor.component.d.ts +19 -0
- package/lib/features/designer/services/designer-state.service.d.ts +12 -1
- package/lib/features/runtime/report-grid-bridge.component.d.ts +7 -58
- package/lib/primitives/components/dropdown/rpt-dropdown.component.d.ts +3 -0
- package/lib/provide-reporting.d.ts +6 -0
- package/package.json +1 -1
|
@@ -16,6 +16,8 @@ import * as i1 from "@angular/cdk/drag-drop";
|
|
|
16
16
|
import * as i2 from "@angular/forms";
|
|
17
17
|
export class DesignCanvasComponent {
|
|
18
18
|
designerState = inject(DesignerStateService);
|
|
19
|
+
gridFilterDebounceTimer = null;
|
|
20
|
+
pendingGridState = null;
|
|
19
21
|
templateService = inject(ReportTemplateService);
|
|
20
22
|
formBuilder = inject(DynamicFormBuilder);
|
|
21
23
|
executionService = inject(ReportExecutionService);
|
|
@@ -337,6 +339,12 @@ export class DesignCanvasComponent {
|
|
|
337
339
|
setTimeout(() => this.gridExecError.set(null), 4000);
|
|
338
340
|
}
|
|
339
341
|
}
|
|
342
|
+
ngOnDestroy() {
|
|
343
|
+
if (this.gridFilterDebounceTimer) {
|
|
344
|
+
clearTimeout(this.gridFilterDebounceTimer);
|
|
345
|
+
this.gridFilterDebounceTimer = null;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
340
348
|
onCanvasGridStateChange(state) {
|
|
341
349
|
if (!state || !this.definition().grid)
|
|
342
350
|
return;
|
|
@@ -346,34 +354,84 @@ export class DesignCanvasComponent {
|
|
|
346
354
|
const newSerialized = JSON.stringify(state ?? null);
|
|
347
355
|
if (currentSerialized === newSerialized)
|
|
348
356
|
return;
|
|
357
|
+
// Distinguish between true structural layout changes (groupModel, sortModel)
|
|
358
|
+
// vs interactive column data filtering (activeFilters, conditionFilters).
|
|
359
|
+
const currentGroup = JSON.stringify(currentGrid.options?.groupModel ?? []);
|
|
360
|
+
const newGroup = JSON.stringify(state.groupModel ?? []);
|
|
361
|
+
const currentSort = JSON.stringify(currentGrid.options?.sortModel ?? []);
|
|
362
|
+
const newSort = JSON.stringify(state.sortModel ?? []);
|
|
363
|
+
const isLayoutChange = currentGroup !== newGroup || currentSort !== newSort;
|
|
349
364
|
const updatedOptions = {
|
|
350
365
|
...(currentGrid.options || {}),
|
|
351
366
|
groupModel: state.groupModel ?? currentGrid.options?.groupModel,
|
|
352
367
|
sortModel: state.sortModel ?? currentGrid.options?.sortModel,
|
|
353
368
|
reportState: state,
|
|
354
369
|
};
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
370
|
+
if (isLayoutChange) {
|
|
371
|
+
// Clear any pending debounced filter update
|
|
372
|
+
if (this.gridFilterDebounceTimer) {
|
|
373
|
+
clearTimeout(this.gridFilterDebounceTimer);
|
|
374
|
+
this.gridFilterDebounceTimer = null;
|
|
375
|
+
}
|
|
376
|
+
this.pendingGridState = null;
|
|
377
|
+
// Grouping or sorting changed — update layout immediately and show visual indicator
|
|
378
|
+
this.designerState.updateGridSettings({
|
|
379
|
+
...currentGrid,
|
|
380
|
+
options: updatedOptions,
|
|
381
|
+
});
|
|
382
|
+
this.layoutJustUpdated.set(true);
|
|
383
|
+
setTimeout(() => this.layoutJustUpdated.set(false), 1200);
|
|
384
|
+
}
|
|
385
|
+
else {
|
|
386
|
+
// Pure column filter adjustment (activeFilters / conditionFilters).
|
|
387
|
+
// 1. Do NOT trigger the "Layout auto-persisted" indicator (filtering rows is not a layout change).
|
|
388
|
+
// 2. Debounce saving the state with skipHistory so typing or checking boxes
|
|
389
|
+
// does not flood undo history or interrupt column filter interaction.
|
|
390
|
+
this.pendingGridState = state;
|
|
391
|
+
if (this.gridFilterDebounceTimer) {
|
|
392
|
+
clearTimeout(this.gridFilterDebounceTimer);
|
|
393
|
+
}
|
|
394
|
+
this.gridFilterDebounceTimer = setTimeout(() => {
|
|
395
|
+
this.gridFilterDebounceTimer = null;
|
|
396
|
+
if (!this.pendingGridState || !this.definition().grid)
|
|
397
|
+
return;
|
|
398
|
+
const latestGrid = this.definition().grid;
|
|
399
|
+
const latestOptions = {
|
|
400
|
+
...(latestGrid.options || {}),
|
|
401
|
+
reportState: this.pendingGridState,
|
|
402
|
+
};
|
|
403
|
+
this.pendingGridState = null;
|
|
404
|
+
this.designerState.updateGridSettings({
|
|
405
|
+
...latestGrid,
|
|
406
|
+
options: latestOptions,
|
|
407
|
+
}, { skipHistory: true });
|
|
408
|
+
}, 1200);
|
|
409
|
+
}
|
|
361
410
|
}
|
|
362
411
|
onCanvasColumnDefsChange(defs) {
|
|
363
412
|
if (!Array.isArray(defs) || !this.definition().grid)
|
|
364
413
|
return;
|
|
365
414
|
const currentGrid = this.definition().grid;
|
|
415
|
+
let anyChanged = false;
|
|
366
416
|
const updatedCols = currentGrid.columns.map((c) => {
|
|
367
417
|
const match = defs.find((d) => d.field === c.field);
|
|
368
418
|
if (match) {
|
|
419
|
+
const newWidth = match.width ? `${match.width}px` : c.width;
|
|
420
|
+
const newVisible = match.hide !== true;
|
|
421
|
+
if (newWidth !== c.width || newVisible !== c.visible) {
|
|
422
|
+
anyChanged = true;
|
|
423
|
+
}
|
|
369
424
|
return {
|
|
370
425
|
...c,
|
|
371
|
-
width:
|
|
372
|
-
visible:
|
|
426
|
+
width: newWidth,
|
|
427
|
+
visible: newVisible,
|
|
373
428
|
};
|
|
374
429
|
}
|
|
375
430
|
return c;
|
|
376
431
|
});
|
|
432
|
+
// If no column widths or visibilities actually changed, do not trigger auto-persist
|
|
433
|
+
if (!anyChanged)
|
|
434
|
+
return;
|
|
377
435
|
this.designerState.updateGridSettings({
|
|
378
436
|
...currentGrid,
|
|
379
437
|
columns: updatedCols,
|
|
@@ -393,7 +451,7 @@ export class DesignCanvasComponent {
|
|
|
393
451
|
this.designerState.addComponent(type);
|
|
394
452
|
}
|
|
395
453
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DesignCanvasComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
396
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: DesignCanvasComponent, isStandalone: true, selector: "rpt-design-canvas", host: { listeners: { "document:keydown.escape": "onEscape()" } }, ngImport: i0, template: " <div class=\"canvas-wrapper\" (click)=\"onCanvasBackgroundClick($event)\">\n <!-- Canvas Status / Quick Controls -->\n <div class=\"canvas-toolbar\">\n <div class=\"canvas-info\">\n <span class=\"info-label\">Grid Layout:</span>\n <span class=\"info-value\">{{ totalColumns() }} Columns</span>\n <span class=\"info-divider\">\u2022</span>\n <span class=\"info-label\">Components:</span>\n <span class=\"info-value\">{{ components().length }}</span>\n <span class=\"info-divider\">\u2022</span>\n <span class=\"live-mode-badge\" title=\"Interactive canvas: Values typed here run live queries and test dropdowns.\">\n \u26A1 Live Interactive Mode\n </span>\n </div>\n\n <div class=\"canvas-actions\">\n @if (!definition().grid) {\n <button\n type=\"button\"\n class=\"canvas-action-btn btn-grid-add\"\n (click)=\"addResultGrid($event)\"\n title=\"Add a Result Grid to this report\"\n >\n <rpt-icon name=\"table\" [size]=\"14\" />\n <span>+ Add Grid</span>\n </button>\n } @else {\n <button\n type=\"button\"\n class=\"canvas-action-btn btn-grid-configured\"\n (click)=\"selectGridSettings($event)\"\n title=\"Configure Result Data Grid\"\n >\n <rpt-icon name=\"table\" [size]=\"14\" />\n <span>Grid ({{ definition().grid?.columns?.length ?? 0 }})</span>\n </button>\n }\n\n <button\n type=\"button\"\n class=\"canvas-action-btn\"\n (click)=\"selectReportSettings($event)\"\n title=\"Configure Page Layout & Grid Settings\"\n >\n <rpt-icon name=\"settings\" [size]=\"14\" />\n <span>Report Settings</span>\n </button>\n </div>\n </div>\n\n <!-- Canvas Drop Area -->\n <div class=\"canvas-scroll-area\">\n <div\n class=\"canvas-artboard\"\n [style.padding.px]=\"definition().layout.padding ?? 24\"\n >\n <!-- Report Header Preview -->\n <div class=\"canvas-report-header\">\n <h2 class=\"canvas-report-title\">{{ definition().name || 'Untitled Report' }}</h2>\n @if (definition().description) {\n <p class=\"canvas-report-desc\">{{ definition().description }}</p>\n }\n </div>\n\n <!-- Component Drop List Grid with 2D mixed orientation and data binding -->\n <div\n cdkDropList\n id=\"designer-canvas-drop-list\"\n class=\"canvas-grid\"\n cdkDropListOrientation=\"mixed\"\n [cdkDropListData]=\"sortedComponents()\"\n [style.grid-template-columns]=\"gridTemplateColumns()\"\n [style.gap.px]=\"definition().layout.gap ?? 16\"\n (cdkDropListDropped)=\"onDrop($event)\"\n >\n @for (comp of sortedComponents(); track comp.id; let idx = $index) {\n <div\n cdkDrag\n [cdkDragData]=\"comp\"\n [cdkDragDisabled]=\"isAnyResizing()\"\n class=\"canvas-component-card\"\n [class.is-selected]=\"isSelected(comp.id)\"\n [class.is-resizing]=\"resizingCompId() === comp.id\"\n [class.is-field-highlighted]=\"isFieldHighlighted(comp)\"\n [class.is-narrow]=\"getSpan(comp) <= 4\"\n [class.is-compact]=\"getSpan(comp) <= 2\"\n [style.grid-column]=\"getGridColumn(comp)\"\n [style.grid-row]=\"getGridRow(comp)\"\n [style.width]=\"comp.layout?.width || 'auto'\"\n [style.height]=\"getComponentHeight(comp)\"\n [style.min-height]=\"getComponentMinHeight(comp)\"\n (click)=\"onSelect(comp.id, $event)\"\n >\n <!-- Card Header with Drag Handle & Actions -->\n <div class=\"card-header\">\n <div class=\"card-title-group\" cdkDragHandle title=\"Drag to reorder\">\n <span class=\"drag-handle-dots\">\u22EE\u22EE</span>\n <rpt-icon [name]=\"getComponentIconName(comp.type)\" [size]=\"14\" />\n <span class=\"comp-title\" [title]=\"comp.label || comp.key || comp.type\">\n {{ comp.label || comp.key || comp.type }}\n </span>\n </div>\n\n <div class=\"card-actions\">\n <!-- Static span pill & new row / start col pill when not hovered / not selected -->\n @if (comp.layout?.column; as col) {\n <span class=\"new-row-pill-static\" title=\"Starts at Column {{ col }}\">Col {{ col }}</span>\n } @else if (comp.layout?.newRow) {\n <span class=\"new-row-pill-static\" title=\"Starts on separate row\">\u21B3 Row</span>\n }\n <span\n class=\"span-pill-static\"\n title=\"Column span: {{ getSpan(comp) }} of {{ totalColumns() }} columns\"\n >\n {{ getSpan(comp) }}/{{ totalColumns() }}\n </span>\n\n <!-- Quick Action Stepper & Buttons (revealed on hover or selection) -->\n <div class=\"card-quick-controls\">\n <button\n type=\"button\"\n class=\"card-action-btn\"\n [class.btn-active-toggle]=\"comp.layout?.newRow\"\n (click)=\"toggleNewRow(comp, $event)\"\n title=\"{{ comp.layout?.newRow ? 'Starts on new row (Click to place inline)' : 'Start on separate row (Row Break)' }}\"\n >\n <rpt-icon name=\"corner-down-right\" [size]=\"11\" />\n </button>\n\n <div class=\"span-control-group\" title=\"Adjust Column Span\">\n <button\n type=\"button\"\n class=\"span-btn\"\n [disabled]=\"getSpan(comp) <= 1\"\n (click)=\"adjustSpan(comp, -1, $event)\"\n title=\"Shrink Column Span\"\n >\n <rpt-icon name=\"minus\" [size]=\"9\" />\n </button>\n <span class=\"span-badge\" [title]=\"'Column span: ' + getSpan(comp) + ' of ' + totalColumns()\">\n <span class=\"span-num\">{{ getSpan(comp) }}</span><span class=\"span-total\">/{{ totalColumns() }}</span>\n </span>\n <button\n type=\"button\"\n class=\"span-btn\"\n [disabled]=\"getSpan(comp) >= totalColumns()\"\n (click)=\"adjustSpan(comp, 1, $event)\"\n title=\"Expand Column Span\"\n >\n <rpt-icon name=\"plus\" [size]=\"9\" />\n </button>\n </div>\n\n <button\n type=\"button\"\n class=\"card-action-btn\"\n (click)=\"onDuplicate(comp.id, $event)\"\n title=\"Duplicate component\"\n >\n <rpt-icon name=\"copy\" [size]=\"12\" />\n </button>\n <button\n type=\"button\"\n class=\"card-action-btn btn-delete\"\n (click)=\"onDelete(comp.id, $event)\"\n title=\"Remove component\"\n >\n <rpt-icon name=\"trash\" [size]=\"12\" />\n </button>\n </div>\n </div>\n </div>\n\n <!-- Card Body Visual Preview -->\n <div class=\"card-body\">\n\n @switch (comp.type) {\n @case ('input') {\n <div class=\"mock-input-field\" (click)=\"onControlInteract(comp, $event)\">\n <span class=\"mock-label\">{{ comp.label || 'Input' }}</span>\n @if (getCanvasControl(comp); as ctrl) {\n <input\n type=\"text\"\n class=\"canvas-active-input\"\n [placeholder]=\"comp.properties?.['placeholder'] || 'Enter text...'\"\n [formControl]=\"ctrl\"\n (focus)=\"onControlInteract(comp, $event)\"\n />\n } @else {\n <div class=\"mock-input-box\">{{ comp.properties?.['placeholder'] || 'Enter text...' }}</div>\n }\n </div>\n }\n @case ('dropdown') {\n <div class=\"canvas-live-control-wrapper\" (click)=\"onControlInteract(comp, $event)\">\n <rpt-dropdown\n [config]=\"comp\"\n [showStatus]=\"true\"\n [parentForm]=\"canvasForm()\"\n [control]=\"getCanvasControl(comp)\"\n />\n </div>\n }\n @case ('date') {\n <div class=\"mock-input-field\" (click)=\"onControlInteract(comp, $event)\">\n <span class=\"mock-label\">{{ comp.label || 'Date' }}</span>\n @if (getCanvasControl(comp); as ctrl) {\n <input\n type=\"date\"\n class=\"canvas-active-input\"\n [formControl]=\"ctrl\"\n (focus)=\"onControlInteract(comp, $event)\"\n />\n } @else {\n <div class=\"mock-select-box\">\n <span>YYYY-MM-DD</span>\n <rpt-icon name=\"calendar\" [size]=\"12\" />\n </div>\n }\n </div>\n }\n @case ('date-range') {\n <div class=\"canvas-live-control-wrapper\" (click)=\"onControlInteract(comp, $event)\">\n <rpt-date-range\n [config]=\"comp\"\n [control]=\"getCanvasControl(comp)\"\n />\n </div>\n }\n @case ('number') {\n <div class=\"mock-input-field\" (click)=\"onControlInteract(comp, $event)\">\n <span class=\"mock-label\">{{ comp.label || 'Number' }}</span>\n @if (getCanvasControl(comp); as ctrl) {\n <input\n type=\"number\"\n class=\"canvas-active-input\"\n [formControl]=\"ctrl\"\n (focus)=\"onControlInteract(comp, $event)\"\n />\n } @else {\n <div class=\"mock-input-box\">\n {{ comp.properties?.['prefix'] || '' }} 0.00 {{ comp.properties?.['suffix'] || '' }}\n </div>\n }\n </div>\n }\n @case ('checkbox') {\n <div class=\"mock-checkbox-field\" (click)=\"onControlInteract(comp, $event)\">\n @if (getCanvasControl(comp); as ctrl) {\n <label class=\"canvas-active-checkbox-lbl\">\n <input type=\"checkbox\" [formControl]=\"ctrl\" (focus)=\"onControlInteract(comp, $event)\" />\n <span class=\"mock-label\">{{ comp.label || 'Checkbox' }}</span>\n </label>\n } @else {\n <span class=\"mock-check-box\">\n <rpt-icon name=\"check\" [size]=\"10\" />\n </span>\n <span class=\"mock-label\">{{ comp.label || 'Checkbox' }}</span>\n }\n </div>\n }\n @case ('button') {\n <div class=\"mock-btn-wrapper\">\n <button\n type=\"button\"\n class=\"mock-btn\"\n [class]=\"'btn-' + (comp.properties?.['variant'] || 'primary')\"\n [class.mock-btn-full]=\"comp.properties?.['fullWidth'] === true || comp.layout?.width === '100%'\"\n [style.height]=\"getCustomBtnHeight(comp)\"\n [style.width]=\"getCustomBtnWidth(comp)\"\n (click)=\"onCanvasButtonClick(comp, $event)\"\n >\n @if (getCustomBtnIcon(comp); as btnIcon) {\n <rpt-icon [name]=\"btnIcon\" [size]=\"15\" />\n }\n <span>{{ comp.label || 'Button' }}</span>\n </button>\n </div>\n }\n @case ('kpi-card') {\n <div class=\"mock-kpi-field\">\n <div class=\"mock-kpi-header\">\n <span class=\"mock-label\">{{ comp.label || 'KPI Metric' }}</span>\n <rpt-icon name=\"kpi\" [size]=\"14\" />\n </div>\n <div class=\"mock-kpi-value\">{{ comp.properties?.['value'] || '$128,450' }}</div>\n <div class=\"mock-kpi-footer\">\n <span class=\"mock-kpi-trend\">+12.5%</span>\n <span class=\"mock-kpi-sub\">vs last period</span>\n </div>\n </div>\n }\n @case ('chart') {\n <div class=\"mock-chart-field\">\n <div class=\"mock-chart-header\">\n <span class=\"mock-label\">{{ comp.label || 'Quarterly Sales Revenue ($000)' }}</span>\n </div>\n <div class=\"mock-chart-bars\">\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 44%\"></div>\n <span class=\"mock-bar-lbl\">Q1 Jan-Mar</span>\n </div>\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 61%\"></div>\n <span class=\"mock-bar-lbl\">Q2 Apr-Jun</span>\n </div>\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 79%\"></div>\n <span class=\"mock-bar-lbl\">Q3 Jul-Sep</span>\n </div>\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 100%\"></div>\n <span class=\"mock-bar-lbl\">Q4 Oct-Dec</span>\n </div>\n </div>\n </div>\n }\n @default {\n <div class=\"mock-generic-box\">\n <span>{{ comp.type }}</span>\n </div>\n }\n }\n </div>\n\n <!-- Resizing Handles (East, South, South-East) -->\n <div\n class=\"resize-handle handle-e\"\n (pointerdown)=\"startResize($event, comp, 'e')\"\n (dblclick)=\"resetDimensions(comp, $event)\"\n title=\"Drag to resize column width \u2022 Double-click to reset\"\n ></div>\n <div\n class=\"resize-handle handle-s\"\n (pointerdown)=\"startResize($event, comp, 's')\"\n (dblclick)=\"resetDimensions(comp, $event)\"\n title=\"Drag to resize height \u2022 Double-click to reset\"\n ></div>\n <div\n class=\"resize-handle handle-se\"\n (pointerdown)=\"startResize($event, comp, 'se')\"\n (dblclick)=\"resetDimensions(comp, $event)\"\n title=\"Drag to resize width and height \u2022 Double-click to reset\"\n ></div>\n\n <!-- Resizing Dimension Ghost / Badge -->\n @if (resizingCompId() === comp.id) {\n <div class=\"resize-dimension-tooltip\">\n {{ resizingTooltip(comp) }}\n </div>\n }\n\n <!-- Drag placeholder with matched grid column span -->\n <div\n *cdkDragPlaceholder\n class=\"canvas-drag-placeholder\"\n [style.grid-column]=\"getGridColumn(comp)\"\n ></div>\n\n <!-- Drag preview -->\n <div *cdkDragPreview class=\"canvas-drag-preview\">\n <span class=\"drag-handle-dots\">\u22EE\u22EE</span>\n <rpt-icon [name]=\"getComponentIconName(comp.type)\" [size]=\"14\" />\n <span class=\"preview-title\">{{ comp.label || comp.key || comp.type }}</span>\n <span class=\"preview-span\">{{ getSpan(comp) }}/{{ totalColumns() }}</span>\n </div>\n </div>\n }\n\n @if (components().length === 0) {\n <div class=\"canvas-empty-state\" role=\"region\" aria-label=\"Empty canvas starter options\">\n <div class=\"empty-hero-badge\">\n <rpt-icon name=\"design\" [size]=\"28\" />\n </div>\n <h3 class=\"empty-hero-title\">Start Designing Your Custom Report</h3>\n <p class=\"empty-hero-desc\">\n Drag controls from the left component palette, or jumpstart your design with pre-configured enterprise blueprints.\n </p>\n\n <div class=\"empty-hero-actions\">\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-primary\"\n (click)=\"applyBlueprint('blueprint-audit-register')\"\n title=\"Load complete Audit Register blueprint with parameters and result grid\"\n >\n <rpt-icon name=\"table\" [size]=\"15\" />\n <span>Audit Register Blueprint</span>\n </button>\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-secondary\"\n (click)=\"applyBlueprint('blueprint-kpi-summary')\"\n title=\"Load Executive KPI summary blueprint\"\n >\n <rpt-icon name=\"chart-bar\" [size]=\"15\" />\n <span>KPI Summary Blueprint</span>\n </button>\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-outline\"\n (click)=\"addStarterComponent('date-range')\"\n title=\"Add a Date Range filter component\"\n >\n <rpt-icon name=\"calendar\" [size]=\"14\" />\n <span>+ Add Date Filter</span>\n </button>\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-outline\"\n (click)=\"addStarterComponent('button')\"\n title=\"Add an Execute Action button\"\n >\n <rpt-icon name=\"play\" [size]=\"14\" />\n <span>+ Add Run Button</span>\n </button>\n </div>\n </div>\n }\n </div>\n\n <!-- Live Result Grid Preview with Bways-Grid Features -->\n @if (definition().grid) {\n <div class=\"canvas-grid-box\">\n <div class=\"grid-preview-header\">\n <div style=\"display: flex; align-items: center; gap: 8px;\">\n <rpt-icon name=\"table\" [size]=\"15\" />\n <span class=\"grid-title\">Bways Grid ({{ definition().grid?.columns?.length ?? 0 }} columns)</span>\n @if (isExecutingGrid()) {\n <span class=\"grid-exec-badge is-loading\">Loading data from database...</span>\n } @else if (gridExecError()) {\n <span class=\"grid-exec-badge is-error\">{{ gridExecError() }}</span>\n } @else if (canvasGridData().length > 0) {\n <span class=\"grid-exec-badge is-success\">{{ canvasGridData().length }} rows loaded</span>\n }\n </div>\n <div style=\"display: flex; align-items: center; gap: 8px;\">\n <button\n type=\"button\"\n class=\"btn-canvas-run-grid\"\n (click)=\"executeCanvasReport($event)\"\n [disabled]=\"isExecutingGrid()\"\n title=\"Execute query and load data into Bways Grid\"\n >\n <rpt-icon name=\"play\" [size]=\"11\" />\n <span>{{ isExecutingGrid() ? 'Running...' : 'Run / Refresh Grid' }}</span>\n </button>\n <button\n type=\"button\"\n class=\"btn-canvas-edit-grid\"\n (click)=\"selectGridSettings($event)\"\n title=\"Configure columns and grid options\"\n >\n <rpt-icon name=\"settings\" [size]=\"11\" />\n <span>Configure</span>\n </button>\n <button\n type=\"button\"\n class=\"btn-remove-grid\"\n (click)=\"removeGrid($event)\"\n title=\"Remove Result Grid from this report\"\n >\n <rpt-icon name=\"trash\" [size]=\"13\" />\n </button>\n </div>\n </div>\n\n @if (getGridSummaryText(); as summary) {\n <div class=\"grid-layout-status-strip\">\n <div class=\"grid-status-info\">\n <rpt-icon name=\"table\" [size]=\"12\" />\n <span>{{ summary }}</span>\n </div>\n <div class=\"grid-status-sync\" [class.is-pulsing]=\"layoutJustUpdated()\">\n <rpt-icon name=\"check\" [size]=\"11\" />\n <span>Layout auto-persisted</span>\n </div>\n </div>\n }\n\n <!-- Live Bways Grid bridge -->\n <div class=\"canvas-live-grid-container\" (click)=\"$event.stopPropagation()\">\n <rpt-grid-bridge\n [gridDefinition]=\"definition().grid!\"\n [data]=\"canvasGridData()\"\n (gridStateChange)=\"onCanvasGridStateChange($event)\"\n (columnDefsChange)=\"onCanvasColumnDefsChange($event)\"\n />\n </div>\n </div>\n } @else {\n <div class=\"canvas-add-grid-banner\" (click)=\"addResultGrid($event)\">\n <div class=\"add-grid-icon\">\n <rpt-icon name=\"table\" [size]=\"20\" />\n </div>\n <div class=\"add-grid-text\">\n <span class=\"add-grid-title\">+ Add Result Data Grid</span>\n <span class=\"add-grid-sub\">Attach an interactive data table or UltraGrid to display report execution output</span>\n </div>\n <button type=\"button\" class=\"btn-banner-add\">Add Grid</button>\n </div>\n }\n </div>\n </div>\n </div>", styles: [":host{display:block;height:100%;background-color:#f1f5f9;font-family:var(--rpt-font-family, inherit);box-sizing:border-box}.canvas-wrapper{display:flex;flex-direction:column;height:100%}.canvas-toolbar{display:flex;align-items:center;justify-content:space-between;min-height:42px;height:42px;padding:0 24px;background:var(--rpt-color-surface, #ffffff);border-bottom:1px solid var(--rpt-color-border, #cbd5e1);box-sizing:border-box;gap:12px;overflow-x:auto;scrollbar-width:none;font-family:var(--rpt-font-family, inherit);flex-shrink:0}.canvas-toolbar::-webkit-scrollbar{display:none}.canvas-info{display:flex;align-items:center;gap:8px;font-family:var(--rpt-font-family, inherit);font-size:var(--rpt-font-size-sm, .75rem);color:var(--rpt-color-text-muted, #64748b);white-space:nowrap;line-height:1}.info-label{color:var(--rpt-color-text-muted, #64748b);font-weight:500;font-size:var(--rpt-font-size-sm, .75rem)}.info-value{font-weight:600;color:var(--rpt-color-text, #0f172a);font-size:var(--rpt-font-size-sm, .75rem)}.info-divider{color:var(--rpt-color-border, #cbd5e1);margin:0 2px}.live-mode-badge{display:inline-flex;align-items:center;gap:4px;font-family:var(--rpt-font-family, inherit);font-size:var(--rpt-font-size-xs, .7rem);font-weight:600;color:#047857;background:#ecfdf5;border:1px solid #a7f3d0;padding:2px 8px;border-radius:9999px;line-height:1}.canvas-actions{display:flex;align-items:center;gap:8px;white-space:nowrap}.canvas-action-btn{display:inline-flex;align-items:center;gap:6px;height:28px;padding:0 10px;font-family:var(--rpt-font-family, inherit);font-size:var(--rpt-font-size-sm, .75rem);font-weight:500;letter-spacing:-.01em;color:var(--rpt-color-text-secondary, #334155);background:var(--rpt-color-surface, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);cursor:pointer;line-height:1;white-space:nowrap;box-shadow:0 1px 2px #0000000a;transition:all var(--rpt-transition-speed, .15s) ease}.canvas-action-btn:hover{background:var(--rpt-color-surface-hover, #f8fafc);border-color:var(--rpt-color-border-hover, #94a3b8);color:var(--rpt-color-text, #0f172a);box-shadow:0 2px 4px #0000000f}.canvas-action-btn.btn-grid-configured{background:#eff6ff;border-color:#bfdbfe;color:#2563eb;font-weight:600}.canvas-action-btn.btn-grid-configured:hover{background:#dbeafe;color:#1d4ed8;border-color:#93c5fd}.canvas-action-btn.btn-grid-add{background:#f0fdf4;border-color:#bbf7d0;color:#16a34a;font-weight:600}.canvas-action-btn.btn-grid-add:hover{background:#dcfce7;color:#15803d;border-color:#86efac}.canvas-action-btn:active{transform:translateY(1px)}.canvas-scroll-area{flex:1;overflow-y:auto;padding:16px}.canvas-artboard{width:100%;max-width:1400px;margin:0 auto;background:#fff;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius-lg, 8px);box-shadow:0 4px 6px -1px #0000000d;min-height:480px;box-sizing:border-box}@media (max-width: 900px){.canvas-toolbar{min-height:36px;height:36px;padding:0 10px;gap:6px}.live-mode-badge{display:none}.canvas-info{font-size:.75rem;gap:5px}.canvas-action-btn{padding:0 8px;font-size:.725rem;height:28px;gap:4px}.canvas-scroll-area{padding:10px}.canvas-artboard{min-height:360px}}@media (max-width: 600px){.canvas-toolbar{padding:0 8px;gap:4px}.canvas-info .info-label,.canvas-action-btn span{display:none}.canvas-action-btn{padding:0 6px;min-width:28px;justify-content:center}}.canvas-report-header{margin-bottom:24px;padding-bottom:16px;border-bottom:1px solid var(--rpt-color-border, #e2e8f0)}.canvas-report-title{font-size:var(--rpt-font-size-xl, 1.5rem);font-weight:700;color:var(--rpt-color-text, #0f172a);margin:0 0 6px}.canvas-report-desc{font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text-muted, #64748b);margin:0}.canvas-grid{display:grid;width:100%;min-height:180px;align-items:start;border-radius:6px;transition:all var(--rpt-transition-speed, .15s) ease}.canvas-component-card{container-type:inline-size;background:#fff;border:1.5px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);box-shadow:var(--rpt-box-shadow, 0 1px 2px rgba(0, 0, 0, .05));box-sizing:border-box;transition:all var(--rpt-transition-speed, .15s) ease;cursor:pointer;position:relative;overflow:visible;display:flex;flex-direction:column;min-height:104px;z-index:1}.canvas-component-card:hover{border-color:var(--rpt-color-primary, #2563eb);box-shadow:0 4px 6px -1px #2563eb1a;z-index:2}.canvas-component-card.is-selected{border-color:var(--rpt-color-primary, #2563eb);box-shadow:0 0 0 2px #2563eb40;z-index:10}.canvas-component-card:focus-within,.canvas-component-card:has(.rpt-combobox-menu),.canvas-component-card:has(.is-open){z-index:100}.canvas-component-card.is-resizing{-webkit-user-select:none;user-select:none;border-color:var(--rpt-color-primary, #2563eb);box-shadow:0 0 0 2px #2563eb59;z-index:30;transition:none!important}.resize-handle{position:absolute;z-index:20;touch-action:none;opacity:0;pointer-events:none;transition:opacity .15s ease}.canvas-component-card.is-selected .resize-handle{opacity:1;pointer-events:auto}.resize-handle.handle-e{top:0;right:0;width:6px;height:100%;cursor:ew-resize;display:flex;align-items:center;justify-content:center}.resize-handle.handle-e:after{content:\"\";width:3px;height:24px;background:#cbd5e1;border-radius:2px;transition:background .15s ease}.resize-handle.handle-e:hover:after,.canvas-component-card.is-selected .resize-handle.handle-e:after{background:var(--rpt-color-primary, #2563eb)}.resize-handle.handle-s{bottom:0;left:0;height:6px;width:100%;cursor:ns-resize;display:flex;align-items:center;justify-content:center}.resize-handle.handle-s:after{content:\"\";height:3px;width:24px;background:#cbd5e1;border-radius:2px;transition:background .15s ease}.resize-handle.handle-s:hover:after,.canvas-component-card.is-selected .resize-handle.handle-s:after{background:var(--rpt-color-primary, #2563eb)}.resize-handle.handle-se{bottom:0;right:0;width:12px;height:12px;cursor:nwse-resize;display:flex;align-items:flex-end;justify-content:flex-end;padding:2px}.resize-handle.handle-se:after{content:\"\";width:5px;height:5px;border-right:2px solid #cbd5e1;border-bottom:2px solid #cbd5e1;transition:border-color .15s ease}.resize-handle.handle-se:hover:after,.canvas-component-card.is-selected .resize-handle.handle-se:after{border-color:var(--rpt-color-primary, #2563eb)}.resize-dimension-tooltip{position:absolute;top:38px;right:8px;background:#0f172ae6;color:#fff;font-size:.7rem;font-weight:600;padding:3px 8px;border-radius:4px;white-space:nowrap;pointer-events:none;z-index:50;box-shadow:0 2px 4px #0003}.card-header{display:flex;align-items:center;justify-content:space-between;gap:6px;padding:5px 8px;background:var(--rpt-color-surface, #f8fafc);border-bottom:1px solid var(--rpt-color-border, #e2e8f0);border-top-left-radius:var(--rpt-border-radius, 6px);border-top-right-radius:var(--rpt-border-radius, 6px);min-height:32px;box-sizing:border-box;overflow:hidden;position:relative}.canvas-component-card.is-selected .card-header{overflow:visible}.card-title-group{display:flex;align-items:center;gap:5px;cursor:grab;min-width:0;flex:1;overflow:hidden}.drag-handle-dots{color:var(--rpt-color-text-muted, #94a3b8);font-size:.85rem;letter-spacing:-2px;flex-shrink:0;-webkit-user-select:none;user-select:none}.comp-title{font-size:.75rem;font-weight:600;color:var(--rpt-color-text, #0f172a);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-webkit-user-select:none;user-select:none}.card-actions{display:flex;align-items:center;gap:4px;flex-shrink:0;margin-left:auto}.new-row-pill-static{font-size:.65rem;font-weight:600;color:#7c3aed;background:#f5f3ff;border:1px solid #ddd6fe;padding:1px 5px;border-radius:9999px;white-space:nowrap;line-height:1;flex-shrink:0}.span-pill-static{display:inline-flex;align-items:center;justify-content:center;font-size:.65rem;font-weight:600;color:var(--rpt-color-text-muted, #64748b);background:var(--rpt-color-surface, #f1f5f9);border:1px solid var(--rpt-color-border, #e2e8f0);padding:1px 6px;border-radius:9999px;line-height:1.2;white-space:nowrap;-webkit-user-select:none;user-select:none}.card-quick-controls{display:none;align-items:center;gap:3px;flex-shrink:0}.canvas-component-card:hover .span-pill-static,.canvas-component-card.is-selected .span-pill-static,.canvas-component-card:hover .new-row-pill-static,.canvas-component-card.is-selected .new-row-pill-static{display:none}.canvas-component-card:hover .card-quick-controls,.canvas-component-card.is-selected .card-quick-controls{display:inline-flex}.canvas-component-card.is-narrow .card-header{padding:4px 6px;gap:3px}.canvas-component-card.is-narrow:hover .comp-title,.canvas-component-card.is-narrow.is-selected .comp-title,.canvas-component-card.is-narrow:hover .drag-handle-dots,.canvas-component-card.is-narrow.is-selected .drag-handle-dots{display:none}.canvas-component-card.is-narrow .card-quick-controls{gap:2px}.canvas-component-card.is-narrow .span-control-group{height:18px}.canvas-component-card.is-narrow .span-btn{width:14px;height:16px}.canvas-component-card.is-narrow .span-badge{font-size:.6rem;padding:0 2px}.canvas-component-card.is-narrow .span-total{display:none}.canvas-component-card.is-narrow .card-action-btn{width:18px;height:18px}@container (max-width: 250px){.card-header{padding:4px 6px;gap:3px}.canvas-component-card:hover .comp-title,.canvas-component-card.is-selected .comp-title,.canvas-component-card:hover .drag-handle-dots,.canvas-component-card.is-selected .drag-handle-dots,.span-total{display:none}.card-quick-controls{gap:2px}.card-action-btn{width:18px;height:18px}.span-control-group{height:18px}.span-btn{width:14px;height:16px}.span-badge{font-size:.6rem;padding:0 2px}}@container (max-width: 160px){.canvas-component-card.is-selected .card-quick-controls{position:absolute;top:-30px;right:0;background:#fff;border:1.5px solid var(--rpt-color-primary, #2563eb);border-radius:6px;padding:2px 4px;gap:3px;box-shadow:0 4px 12px #2563eb2e,0 2px 4px #00000014;z-index:120;white-space:nowrap}}@media (max-width: 900px){.canvas-component-card:hover .comp-title,.canvas-component-card.is-selected .comp-title,.canvas-component-card:hover .drag-handle-dots,.canvas-component-card.is-selected .drag-handle-dots,.canvas-component-card .span-total{display:none}.canvas-component-card.is-selected .card-header{overflow:visible}.canvas-component-card.is-selected .card-quick-controls{position:absolute;top:-30px;right:0;background:#fff;border:1.5px solid var(--rpt-color-primary, #2563eb);border-radius:6px;padding:2px 4px;gap:3px;box-shadow:0 4px 12px #2563eb2e,0 2px 4px #00000014;z-index:120;white-space:nowrap}}.span-control-group{display:inline-flex;align-items:center;background:#fff;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:4px;height:20px;padding:0 1px;white-space:nowrap;flex-shrink:0}.span-btn{width:16px;height:18px;display:inline-flex;align-items:center;justify-content:center;border:none;background:transparent;padding:0;color:var(--rpt-color-text-muted, #64748b);cursor:pointer;border-radius:2px;transition:all .12s ease}.span-btn:hover:not(:disabled){background:var(--rpt-color-surface-hover, #f1f5f9);color:var(--rpt-color-primary, #2563eb)}.span-btn:disabled{opacity:.3;cursor:not-allowed}.span-badge{font-size:.65rem;font-weight:600;color:var(--rpt-color-text, #0f172a);padding:0 3px;white-space:nowrap;-webkit-user-select:none;user-select:none;line-height:1}.span-total{font-size:.6rem;color:var(--rpt-color-text-muted, #64748b);font-weight:500}.card-action-btn{width:20px;height:20px;border:none;background:transparent;border-radius:4px;display:inline-flex;align-items:center;justify-content:center;padding:0;cursor:pointer;color:var(--rpt-color-text-muted, #64748b);transition:all .12s ease;flex-shrink:0}.card-action-btn:hover{background:#e2e8f0;color:var(--rpt-color-text, #0f172a)}.card-action-btn.btn-active-toggle{background:#7c3aed;color:#fff;border-color:#7c3aed}.card-action-btn.btn-active-toggle:hover{background:#6d28d9;color:#fff}.btn-delete:hover{background:#fee2e2;color:#ef4444}.card-body{padding:8px 10px 14px;flex:1;display:flex;flex-direction:column;min-height:0;min-width:0;max-width:100%;box-sizing:border-box;overflow:visible}.mock-input-field{display:flex;flex-direction:column;gap:4px;flex:1;height:100%;min-height:0}.mock-label{font-size:.7rem;font-weight:600;color:var(--rpt-color-text-muted, #475569);flex-shrink:0}.mock-input-box,.mock-select-box{border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:6px;padding:6px 12px;font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text-muted, #94a3b8);background:#fff;flex:1;min-height:38px;height:100%;display:flex;align-items:center;justify-content:space-between;box-sizing:border-box}.mock-checkbox-field{display:flex;align-items:center;gap:6px;flex:1;height:100%;min-height:0;padding-top:14px}.mock-check-box{width:18px;height:18px;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:4px;display:flex;align-items:center;justify-content:center;font-size:.65rem;color:var(--rpt-color-primary, #2563eb);flex-shrink:0}.mock-btn-wrapper{display:flex;flex:1;height:100%;min-height:38px;align-items:center;justify-content:flex-start;width:100%;min-width:0;box-sizing:border-box}.mock-btn{border-radius:var(--rpt-border-radius, 6px);padding:0 16px;height:36px;font-size:var(--rpt-font-size-base, .875rem);font-weight:500;border:1px solid transparent;cursor:pointer;width:auto;max-width:100%;display:inline-flex;align-items:center;justify-content:center;gap:6px;box-sizing:border-box;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:all .15s ease}.mock-btn.mock-btn-full{width:100%}.canvas-component-card.is-narrow .mock-btn{padding:0 6px;font-size:.775rem;width:100%;height:34px}.mock-kpi-field{display:flex;flex-direction:column;justify-content:space-between;flex:1;height:100%;min-height:0}.mock-kpi-header{display:flex;align-items:center;justify-content:space-between}.mock-kpi-value{font-size:1.25rem;font-weight:700;color:var(--rpt-color-text, #0f172a);margin:2px 0}.mock-kpi-footer{display:flex;align-items:center;gap:6px;font-size:.65rem}.mock-kpi-trend{color:#16a34a;font-weight:600}.mock-kpi-sub{color:#64748b}.mock-chart-field{display:flex;flex-direction:column;flex:1;height:100%;min-height:140px}.mock-chart-bars{display:flex;align-items:flex-end;justify-content:space-around;gap:16px;flex:1;min-height:100px;padding-top:12px;box-sizing:border-box}.mock-chart-col{flex:1;display:flex;flex-direction:column;align-items:center;height:100%;min-width:60px;max-width:140px}.mock-chart-bar{width:38px;max-width:44px;margin:0 auto;background:var(--rpt-color-primary, #2563eb);border-radius:6px 6px 0 0;opacity:.85;min-height:10px;transition:height .2s ease}.mock-bar-lbl{font-size:.6875rem;color:#64748b;margin-top:6px;text-align:center;white-space:normal;line-height:1.2}.btn-primary{background:var(--rpt-color-primary, #2563eb);color:#fff}.btn-secondary{background:#f1f5f9;color:#0f172a;border:1px solid #cbd5e1}.btn-outline{background:transparent;color:#2563eb;border:1px solid #2563eb}.btn-danger{background:#ef4444;color:#fff}.mock-generic-box{border:1px dashed #cbd5e1;border-radius:4px;padding:8px;font-size:.75rem;text-align:center;color:#64748b}.canvas-drag-placeholder{background:#2563eb0f;border:2px dashed var(--rpt-color-primary, #2563eb);border-radius:6px;min-height:80px;box-sizing:border-box;transition:transform .15s ease}.canvas-drag-preview,::ng-deep .canvas-drag-preview{background:#fff;border:2px solid var(--rpt-color-primary, #2563eb);border-radius:6px;padding:8px 14px;display:inline-flex;align-items:center;gap:8px;font-family:var(--rpt-font-family, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif)!important;font-size:.8rem;font-weight:600;color:var(--rpt-color-text, #0f172a);box-shadow:0 12px 24px -4px #00000040;z-index:10000}.preview-title,::ng-deep .preview-title{font-family:inherit!important;max-width:160px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.preview-span,::ng-deep .preview-span{font-family:inherit!important;font-size:.65rem;font-weight:600;color:var(--rpt-color-primary, #2563eb);background:#eff6ff;border:1px solid #bfdbfe;padding:1px 6px;border-radius:9999px}.canvas-empty-state{grid-column:1 / -1;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:56px 28px;border:2px dashed var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius-xl, 12px);background:var(--rpt-color-surface, #ffffff);text-align:center;box-shadow:var(--rpt-box-shadow-xs, 0 1px 2px 0 rgba(0, 0, 0, .04));transition:border-color var(--rpt-transition-speed, .15s) ease}.canvas-empty-state:hover{border-color:var(--rpt-color-primary, #2563eb)}.empty-hero-badge{width:56px;height:56px;border-radius:var(--rpt-border-radius-xl, 12px);background:var(--rpt-color-primary-light, #eff6ff);color:var(--rpt-color-primary, #2563eb);display:flex;align-items:center;justify-content:center;margin-bottom:16px;box-shadow:0 2px 8px #2563eb1f}.empty-hero-title{font-size:var(--rpt-font-size-lg, 1.125rem);font-weight:700;color:var(--rpt-color-text, #0f172a);margin:0 0 8px;letter-spacing:-.01em}.empty-hero-desc{font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text-muted, #64748b);max-width:520px;line-height:1.5;margin:0 0 24px}.empty-hero-actions{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:10px}.empty-btn{display:inline-flex;align-items:center;gap:7px;padding:8px 16px;font-size:var(--rpt-font-size-sm, .75rem);font-weight:600;border-radius:var(--rpt-border-radius, 6px);cursor:pointer;transition:all var(--rpt-transition-speed, .15s) ease;font-family:inherit}.empty-btn-primary{background:var(--rpt-color-primary, #2563eb);color:#fff;border:1px solid var(--rpt-color-primary, #2563eb);box-shadow:0 1px 3px #2563eb33}.empty-btn-primary:hover{background:var(--rpt-color-primary-hover, #1d4ed8);border-color:var(--rpt-color-primary-hover, #1d4ed8);transform:translateY(-1px)}.empty-btn-secondary{background:#f8fafc;color:#334155;border:1px solid var(--rpt-color-border, #cbd5e1)}.empty-btn-secondary:hover{background:#f1f5f9;color:#0f172a;border-color:#94a3b8;transform:translateY(-1px)}.empty-btn-outline{background:#fff;color:var(--rpt-color-primary, #2563eb);border:1px solid #bfdbfe}.empty-btn-outline:hover{background:#eff6ff;border-color:var(--rpt-color-primary, #2563eb);transform:translateY(-1px)}.canvas-active-input{width:100%;height:32px;padding:4px 8px;font-size:.8125rem;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:4px;outline:none;box-sizing:border-box;background:#fff;color:#0f172a;transition:border-color .15s ease}.canvas-active-input:focus{border-color:var(--rpt-color-primary, #2563eb)}.canvas-active-checkbox-lbl{display:inline-flex;align-items:center;gap:6px;cursor:pointer}.canvas-live-control-wrapper{width:100%;max-width:100%;min-width:0;position:relative;z-index:1;box-sizing:border-box}.canvas-grid-box{margin-top:24px;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:8px;background:#fff;box-shadow:0 1px 3px #0000000d;overflow:hidden}.grid-preview-header{display:flex;align-items:center;justify-content:space-between;padding:10px 16px;background:var(--rpt-color-surface, #f8fafc);border-bottom:1px solid var(--rpt-color-border, #cbd5e1);font-size:.8rem;font-weight:600;color:var(--rpt-color-text, #0f172a)}.grid-title{font-weight:700}.grid-exec-badge{font-size:.6875rem;font-weight:600;padding:2px 8px;border-radius:10px}.grid-exec-badge.is-loading{background:#eff6ff;color:#2563eb}.grid-exec-badge.is-error{background:#fee2e2;color:#ef4444}.grid-exec-badge.is-success{background:#ecfdf5;color:#059669}.btn-canvas-run-grid{display:inline-flex;align-items:center;gap:5px;padding:4px 10px;font-size:.72rem;font-weight:600;color:#fff;background:var(--rpt-color-primary, #2563eb);border:none;border-radius:4px;cursor:pointer;transition:background .15s ease}.btn-canvas-run-grid:hover:not(:disabled){background:#1d4ed8}.btn-canvas-run-grid:disabled{opacity:.6;cursor:not-allowed}.btn-canvas-edit-grid{display:inline-flex;align-items:center;gap:4px;padding:4px 8px;font-size:.72rem;font-weight:500;color:#334155;background:#fff;border:1px solid #cbd5e1;border-radius:4px;cursor:pointer;transition:all .12s ease}.btn-canvas-edit-grid:hover{background:#f1f5f9}.canvas-live-grid-container{width:100%;min-height:480px;background:#fff}.live-mode-badge{display:inline-flex;align-items:center;gap:4px;font-size:.6875rem;font-weight:700;color:#047857;background:#ecfdf5;border:1px solid #a7f3d0;padding:1px 8px;border-radius:9999px}.canvas-component-card.is-field-highlighted{border-color:#f59e0b!important;box-shadow:0 0 0 3px #f59e0b59!important;animation:rpt-pulse-border 1s ease-in-out infinite alternate}@keyframes rpt-pulse-border{0%{box-shadow:0 0 0 2px #f59e0b40}to{box-shadow:0 0 0 5px #f59e0b80}}.grid-layout-status-strip{display:flex;align-items:center;justify-content:space-between;padding:6px 16px;background:#f1f5f9;border-bottom:1px solid var(--rpt-color-border, #cbd5e1);font-size:.6875rem;color:#475569}.grid-status-info{display:inline-flex;align-items:center;gap:6px;font-weight:600}.grid-status-sync{display:inline-flex;align-items:center;gap:4px;color:#059669;font-weight:600;transition:transform .2s ease}.grid-status-sync.is-pulsing{transform:scale(1.08);color:#047857}.canvas-actions{display:flex;align-items:center;gap:8px}.btn-grid-add{background:#f0fdf4;border-color:#bbf7d0;color:#16a34a}.btn-grid-add:hover{background:#dcfce7;border-color:#86efac;color:#15803d}.btn-remove-grid{display:inline-flex;align-items:center;justify-content:center;padding:4px;border:none;background:transparent;color:#94a3b8;border-radius:4px;cursor:pointer;transition:all .15s ease}.btn-remove-grid:hover{background:#fee2e2;color:#ef4444}.canvas-add-grid-banner{margin-top:24px;border:2px dashed #cbd5e1;border-radius:8px;background:#fff;padding:16px 20px;display:flex;align-items:center;gap:16px;cursor:pointer;transition:all .15s ease}.canvas-add-grid-banner:hover{border-color:#2563eb;background:#f8fafc;box-shadow:0 2px 8px #2563eb14}.add-grid-icon{width:40px;height:40px;border-radius:8px;background:#eff6ff;color:#2563eb;display:flex;align-items:center;justify-content:center;flex-shrink:0}.add-grid-text{display:flex;flex-direction:column;gap:2px;flex:1}.add-grid-title{font-size:.875rem;font-weight:600;color:#0f172a}.add-grid-sub{font-size:.75rem;color:#64748b}.btn-banner-add{padding:6px 14px;font-size:.75rem;font-weight:600;color:#2563eb;background:#eff6ff;border:1px solid #bfdbfe;border-radius:6px;cursor:pointer;white-space:nowrap;transition:all .15s ease}.canvas-add-grid-banner:hover .btn-banner-add{background:#2563eb;color:#fff;border-color:#2563eb}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i1.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: i1.CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "directive", type: i1.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.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: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: RptIconComponent, selector: "rpt-icon", inputs: ["name", "size", "color", "strokeWidth"] }, { kind: "component", type: RptDropdownComponent, selector: "rpt-dropdown", inputs: ["config", "control", "parentForm", "showStatus"] }, { kind: "component", type: RptDateRangeComponent, selector: "rpt-date-range", inputs: ["config", "control"] }, { kind: "component", type: ReportGridBridgeComponent, selector: "rpt-grid-bridge", inputs: ["gridDefinition", "data"], outputs: ["gridStateChange", "columnDefsChange", "rowClick", "selectionChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
454
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: DesignCanvasComponent, isStandalone: true, selector: "rpt-design-canvas", host: { listeners: { "document:keydown.escape": "onEscape()" } }, ngImport: i0, template: " <div class=\"canvas-wrapper\" (click)=\"onCanvasBackgroundClick($event)\">\n <!-- Canvas Status / Quick Controls -->\n <div class=\"canvas-toolbar\">\n <div class=\"canvas-info\">\n <span class=\"info-label\">Grid Layout:</span>\n <span class=\"info-value\">{{ totalColumns() }} Columns</span>\n <span class=\"info-divider\">\u2022</span>\n <span class=\"info-label\">Components:</span>\n <span class=\"info-value\">{{ components().length }}</span>\n <span class=\"info-divider\">\u2022</span>\n <span class=\"live-mode-badge\" title=\"Interactive canvas: Values typed here run live queries and test dropdowns.\">\n \u26A1 Live Interactive Mode\n </span>\n </div>\n\n <div class=\"canvas-actions\">\n @if (!definition().grid) {\n <button\n type=\"button\"\n class=\"canvas-action-btn btn-grid-add\"\n (click)=\"addResultGrid($event)\"\n title=\"Add a Result Grid to this report\"\n >\n <rpt-icon name=\"table\" [size]=\"14\" />\n <span>+ Add Grid</span>\n </button>\n } @else {\n <button\n type=\"button\"\n class=\"canvas-action-btn btn-grid-configured\"\n (click)=\"selectGridSettings($event)\"\n title=\"Configure Result Data Grid\"\n >\n <rpt-icon name=\"table\" [size]=\"14\" />\n <span>Grid ({{ definition().grid?.columns?.length ?? 0 }})</span>\n </button>\n }\n\n <button\n type=\"button\"\n class=\"canvas-action-btn\"\n (click)=\"selectReportSettings($event)\"\n title=\"Configure Page Layout & Grid Settings\"\n >\n <rpt-icon name=\"settings\" [size]=\"14\" />\n <span>Report Settings</span>\n </button>\n </div>\n </div>\n\n <!-- Canvas Drop Area -->\n <div class=\"canvas-scroll-area\">\n <div\n class=\"canvas-artboard\"\n [style.padding.px]=\"definition().layout.padding ?? 24\"\n >\n <!-- Report Header Preview -->\n <div class=\"canvas-report-header\">\n <h2 class=\"canvas-report-title\">{{ definition().name || 'Untitled Report' }}</h2>\n @if (definition().description) {\n <p class=\"canvas-report-desc\">{{ definition().description }}</p>\n }\n </div>\n\n <!-- Component Drop List Grid with 2D mixed orientation and data binding -->\n <div\n cdkDropList\n id=\"designer-canvas-drop-list\"\n class=\"canvas-grid\"\n cdkDropListOrientation=\"mixed\"\n [cdkDropListData]=\"sortedComponents()\"\n [style.grid-template-columns]=\"gridTemplateColumns()\"\n [style.gap.px]=\"definition().layout.gap ?? 16\"\n (cdkDropListDropped)=\"onDrop($event)\"\n >\n @for (comp of sortedComponents(); track comp.id; let idx = $index) {\n <div\n cdkDrag\n [cdkDragData]=\"comp\"\n [cdkDragDisabled]=\"isAnyResizing()\"\n class=\"canvas-component-card\"\n [class.is-selected]=\"isSelected(comp.id)\"\n [class.is-resizing]=\"resizingCompId() === comp.id\"\n [class.is-field-highlighted]=\"isFieldHighlighted(comp)\"\n [class.is-narrow]=\"getSpan(comp) <= 4\"\n [class.is-compact]=\"getSpan(comp) <= 2\"\n [style.grid-column]=\"getGridColumn(comp)\"\n [style.grid-row]=\"getGridRow(comp)\"\n [style.width]=\"comp.layout?.width || 'auto'\"\n [style.height]=\"getComponentHeight(comp)\"\n [style.min-height]=\"getComponentMinHeight(comp)\"\n (click)=\"onSelect(comp.id, $event)\"\n >\n <!-- Card Header with Drag Handle & Actions -->\n <div class=\"card-header\">\n <div class=\"card-title-group\" cdkDragHandle title=\"Drag to reorder\">\n <span class=\"drag-handle-dots\">\u22EE\u22EE</span>\n <rpt-icon [name]=\"getComponentIconName(comp.type)\" [size]=\"14\" />\n <span class=\"comp-title\" [title]=\"comp.label || comp.key || comp.type\">\n {{ comp.label || comp.key || comp.type }}\n </span>\n </div>\n\n <div class=\"card-actions\">\n <!-- Static span pill & new row / start col pill when not hovered / not selected -->\n @if (comp.layout?.column; as col) {\n <span class=\"new-row-pill-static\" title=\"Starts at Column {{ col }}\">Col {{ col }}</span>\n } @else if (comp.layout?.newRow) {\n <span class=\"new-row-pill-static\" title=\"Starts on separate row\">\u21B3 Row</span>\n }\n <span\n class=\"span-pill-static\"\n title=\"Column span: {{ getSpan(comp) }} of {{ totalColumns() }} columns\"\n >\n {{ getSpan(comp) }}/{{ totalColumns() }}\n </span>\n\n <!-- Quick Action Stepper & Buttons (revealed on hover or selection) -->\n <div class=\"card-quick-controls\">\n <button\n type=\"button\"\n class=\"card-action-btn\"\n [class.btn-active-toggle]=\"comp.layout?.newRow\"\n (click)=\"toggleNewRow(comp, $event)\"\n title=\"{{ comp.layout?.newRow ? 'Starts on new row (Click to place inline)' : 'Start on separate row (Row Break)' }}\"\n >\n <rpt-icon name=\"corner-down-right\" [size]=\"11\" />\n </button>\n\n <div class=\"span-control-group\" title=\"Adjust Column Span\">\n <button\n type=\"button\"\n class=\"span-btn\"\n [disabled]=\"getSpan(comp) <= 1\"\n (click)=\"adjustSpan(comp, -1, $event)\"\n title=\"Shrink Column Span\"\n >\n <rpt-icon name=\"minus\" [size]=\"9\" />\n </button>\n <span class=\"span-badge\" [title]=\"'Column span: ' + getSpan(comp) + ' of ' + totalColumns()\">\n <span class=\"span-num\">{{ getSpan(comp) }}</span><span class=\"span-total\">/{{ totalColumns() }}</span>\n </span>\n <button\n type=\"button\"\n class=\"span-btn\"\n [disabled]=\"getSpan(comp) >= totalColumns()\"\n (click)=\"adjustSpan(comp, 1, $event)\"\n title=\"Expand Column Span\"\n >\n <rpt-icon name=\"plus\" [size]=\"9\" />\n </button>\n </div>\n\n <button\n type=\"button\"\n class=\"card-action-btn\"\n (click)=\"onDuplicate(comp.id, $event)\"\n title=\"Duplicate component\"\n >\n <rpt-icon name=\"copy\" [size]=\"12\" />\n </button>\n <button\n type=\"button\"\n class=\"card-action-btn btn-delete\"\n (click)=\"onDelete(comp.id, $event)\"\n title=\"Remove component\"\n >\n <rpt-icon name=\"trash\" [size]=\"12\" />\n </button>\n </div>\n </div>\n </div>\n\n <!-- Card Body Visual Preview -->\n <div class=\"card-body\">\n\n @switch (comp.type) {\n @case ('input') {\n <div class=\"mock-input-field\" (click)=\"onControlInteract(comp, $event)\">\n <span class=\"mock-label\">{{ comp.label || 'Input' }}</span>\n @if (getCanvasControl(comp); as ctrl) {\n <input\n type=\"text\"\n class=\"canvas-active-input\"\n [placeholder]=\"comp.properties?.['placeholder'] || 'Enter text...'\"\n [formControl]=\"ctrl\"\n (focus)=\"onControlInteract(comp, $event)\"\n />\n } @else {\n <div class=\"mock-input-box\">{{ comp.properties?.['placeholder'] || 'Enter text...' }}</div>\n }\n </div>\n }\n @case ('dropdown') {\n <div class=\"canvas-live-control-wrapper\" (click)=\"onControlInteract(comp, $event)\">\n <rpt-dropdown\n [config]=\"comp\"\n [showStatus]=\"true\"\n [parentForm]=\"canvasForm()\"\n [control]=\"getCanvasControl(comp)\"\n />\n </div>\n }\n @case ('date') {\n <div class=\"mock-input-field\" (click)=\"onControlInteract(comp, $event)\">\n <span class=\"mock-label\">{{ comp.label || 'Date' }}</span>\n @if (getCanvasControl(comp); as ctrl) {\n <input\n type=\"date\"\n class=\"canvas-active-input\"\n [formControl]=\"ctrl\"\n (focus)=\"onControlInteract(comp, $event)\"\n />\n } @else {\n <div class=\"mock-select-box\">\n <span>YYYY-MM-DD</span>\n <rpt-icon name=\"calendar\" [size]=\"12\" />\n </div>\n }\n </div>\n }\n @case ('date-range') {\n <div class=\"canvas-live-control-wrapper\" (click)=\"onControlInteract(comp, $event)\">\n <rpt-date-range\n [config]=\"comp\"\n [control]=\"getCanvasControl(comp)\"\n />\n </div>\n }\n @case ('number') {\n <div class=\"mock-input-field\" (click)=\"onControlInteract(comp, $event)\">\n <span class=\"mock-label\">{{ comp.label || 'Number' }}</span>\n @if (getCanvasControl(comp); as ctrl) {\n <input\n type=\"number\"\n class=\"canvas-active-input\"\n [formControl]=\"ctrl\"\n (focus)=\"onControlInteract(comp, $event)\"\n />\n } @else {\n <div class=\"mock-input-box\">\n {{ comp.properties?.['prefix'] || '' }} 0.00 {{ comp.properties?.['suffix'] || '' }}\n </div>\n }\n </div>\n }\n @case ('checkbox') {\n <div class=\"mock-checkbox-field\" (click)=\"onControlInteract(comp, $event)\">\n @if (getCanvasControl(comp); as ctrl) {\n <label class=\"canvas-active-checkbox-lbl\">\n <input type=\"checkbox\" [formControl]=\"ctrl\" (focus)=\"onControlInteract(comp, $event)\" />\n <span class=\"mock-label\">{{ comp.label || 'Checkbox' }}</span>\n </label>\n } @else {\n <span class=\"mock-check-box\">\n <rpt-icon name=\"check\" [size]=\"10\" />\n </span>\n <span class=\"mock-label\">{{ comp.label || 'Checkbox' }}</span>\n }\n </div>\n }\n @case ('button') {\n <div class=\"mock-btn-wrapper\">\n <button\n type=\"button\"\n class=\"mock-btn\"\n [class]=\"'btn-' + (comp.properties?.['variant'] || 'primary')\"\n [class.mock-btn-full]=\"comp.properties?.['fullWidth'] === true || comp.layout?.width === '100%'\"\n [style.height]=\"getCustomBtnHeight(comp)\"\n [style.width]=\"getCustomBtnWidth(comp)\"\n (click)=\"onCanvasButtonClick(comp, $event)\"\n >\n @if (getCustomBtnIcon(comp); as btnIcon) {\n <rpt-icon [name]=\"btnIcon\" [size]=\"15\" />\n }\n <span>{{ comp.label || 'Button' }}</span>\n </button>\n </div>\n }\n @case ('kpi-card') {\n <div class=\"mock-kpi-field\">\n <div class=\"mock-kpi-header\">\n <span class=\"mock-label\">{{ comp.label || 'KPI Metric' }}</span>\n <rpt-icon name=\"kpi\" [size]=\"14\" />\n </div>\n <div class=\"mock-kpi-value\">{{ comp.properties?.['value'] || '$128,450' }}</div>\n <div class=\"mock-kpi-footer\">\n <span class=\"mock-kpi-trend\">+12.5%</span>\n <span class=\"mock-kpi-sub\">vs last period</span>\n </div>\n </div>\n }\n @case ('chart') {\n <div class=\"mock-chart-field\">\n <div class=\"mock-chart-header\">\n <span class=\"mock-label\">{{ comp.label || 'Quarterly Sales Revenue ($000)' }}</span>\n </div>\n <div class=\"mock-chart-bars\">\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 44%\"></div>\n <span class=\"mock-bar-lbl\">Q1 Jan-Mar</span>\n </div>\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 61%\"></div>\n <span class=\"mock-bar-lbl\">Q2 Apr-Jun</span>\n </div>\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 79%\"></div>\n <span class=\"mock-bar-lbl\">Q3 Jul-Sep</span>\n </div>\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 100%\"></div>\n <span class=\"mock-bar-lbl\">Q4 Oct-Dec</span>\n </div>\n </div>\n </div>\n }\n @default {\n <div class=\"mock-generic-box\">\n <span>{{ comp.type }}</span>\n </div>\n }\n }\n </div>\n\n <!-- Resizing Handles (East, South, South-East) -->\n <div\n class=\"resize-handle handle-e\"\n (pointerdown)=\"startResize($event, comp, 'e')\"\n (dblclick)=\"resetDimensions(comp, $event)\"\n title=\"Drag to resize column width \u2022 Double-click to reset\"\n ></div>\n <div\n class=\"resize-handle handle-s\"\n (pointerdown)=\"startResize($event, comp, 's')\"\n (dblclick)=\"resetDimensions(comp, $event)\"\n title=\"Drag to resize height \u2022 Double-click to reset\"\n ></div>\n <div\n class=\"resize-handle handle-se\"\n (pointerdown)=\"startResize($event, comp, 'se')\"\n (dblclick)=\"resetDimensions(comp, $event)\"\n title=\"Drag to resize width and height \u2022 Double-click to reset\"\n ></div>\n\n <!-- Resizing Dimension Ghost / Badge -->\n @if (resizingCompId() === comp.id) {\n <div class=\"resize-dimension-tooltip\">\n {{ resizingTooltip(comp) }}\n </div>\n }\n\n <!-- Drag placeholder with matched grid column span -->\n <div\n *cdkDragPlaceholder\n class=\"canvas-drag-placeholder\"\n [style.grid-column]=\"getGridColumn(comp)\"\n ></div>\n\n <!-- Drag preview -->\n <div *cdkDragPreview class=\"canvas-drag-preview\">\n <span class=\"drag-handle-dots\">\u22EE\u22EE</span>\n <rpt-icon [name]=\"getComponentIconName(comp.type)\" [size]=\"14\" />\n <span class=\"preview-title\">{{ comp.label || comp.key || comp.type }}</span>\n <span class=\"preview-span\">{{ getSpan(comp) }}/{{ totalColumns() }}</span>\n </div>\n </div>\n }\n\n @if (components().length === 0) {\n <div class=\"canvas-empty-state\" role=\"region\" aria-label=\"Empty canvas starter options\">\n <div class=\"empty-hero-badge\">\n <rpt-icon name=\"design\" [size]=\"28\" />\n </div>\n <h3 class=\"empty-hero-title\">Start Designing Your Custom Report</h3>\n <p class=\"empty-hero-desc\">\n Drag controls from the left component palette, or jumpstart your design with pre-configured enterprise blueprints.\n </p>\n\n <div class=\"empty-hero-actions\">\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-primary\"\n (click)=\"applyBlueprint('blueprint-audit-register')\"\n title=\"Load complete Audit Register blueprint with parameters and result grid\"\n >\n <rpt-icon name=\"table\" [size]=\"15\" />\n <span>Audit Register Blueprint</span>\n </button>\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-secondary\"\n (click)=\"applyBlueprint('blueprint-kpi-summary')\"\n title=\"Load Executive KPI summary blueprint\"\n >\n <rpt-icon name=\"chart-bar\" [size]=\"15\" />\n <span>KPI Summary Blueprint</span>\n </button>\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-outline\"\n (click)=\"addStarterComponent('date-range')\"\n title=\"Add a Date Range filter component\"\n >\n <rpt-icon name=\"calendar\" [size]=\"14\" />\n <span>+ Add Date Filter</span>\n </button>\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-outline\"\n (click)=\"addStarterComponent('button')\"\n title=\"Add an Execute Action button\"\n >\n <rpt-icon name=\"play\" [size]=\"14\" />\n <span>+ Add Run Button</span>\n </button>\n </div>\n </div>\n }\n </div>\n\n <!-- Live Result Grid Preview with Bways-Grid Features -->\n @if (definition().grid) {\n <div class=\"canvas-grid-box\">\n <div class=\"grid-preview-header\">\n <div style=\"display: flex; align-items: center; gap: 8px;\">\n <rpt-icon name=\"table\" [size]=\"15\" />\n <span class=\"grid-title\">Bways Grid ({{ definition().grid?.columns?.length ?? 0 }} columns)</span>\n @if (isExecutingGrid()) {\n <span class=\"grid-exec-badge is-loading\">Loading data from database...</span>\n } @else if (gridExecError()) {\n <span class=\"grid-exec-badge is-error\">{{ gridExecError() }}</span>\n } @else if (canvasGridData().length > 0) {\n <span class=\"grid-exec-badge is-success\">{{ canvasGridData().length }} rows loaded</span>\n }\n </div>\n <div style=\"display: flex; align-items: center; gap: 8px;\">\n <button\n type=\"button\"\n class=\"btn-canvas-run-grid\"\n (click)=\"executeCanvasReport($event)\"\n [disabled]=\"isExecutingGrid()\"\n title=\"Execute query and load data into Bways Grid\"\n >\n <rpt-icon name=\"play\" [size]=\"11\" />\n <span>{{ isExecutingGrid() ? 'Running...' : 'Run / Refresh Grid' }}</span>\n </button>\n <button\n type=\"button\"\n class=\"btn-canvas-edit-grid\"\n (click)=\"selectGridSettings($event)\"\n title=\"Configure columns and grid options\"\n >\n <rpt-icon name=\"settings\" [size]=\"11\" />\n <span>Configure</span>\n </button>\n <button\n type=\"button\"\n class=\"btn-remove-grid\"\n (click)=\"removeGrid($event)\"\n title=\"Remove Result Grid from this report\"\n >\n <rpt-icon name=\"trash\" [size]=\"13\" />\n </button>\n </div>\n </div>\n\n @if (getGridSummaryText(); as summary) {\n <div class=\"grid-layout-status-strip\">\n <div class=\"grid-status-info\">\n <rpt-icon name=\"table\" [size]=\"12\" />\n <span>{{ summary }}</span>\n </div>\n <div class=\"grid-status-sync\" [class.is-pulsing]=\"layoutJustUpdated()\">\n <rpt-icon name=\"check\" [size]=\"11\" />\n <span>Layout auto-persisted</span>\n </div>\n </div>\n }\n\n <!-- Live Bways Grid bridge -->\n <div class=\"canvas-live-grid-container\" (click)=\"$event.stopPropagation()\" style=\"position: relative; min-height: 250px;\">\n @if (isExecutingGrid()) {\n <div class=\"canvas-grid-loading-overlay\">\n <span class=\"status-dot dot-pulse\" style=\"width: 14px; height: 14px; color: #2563eb; background: #2563eb; border-radius: 50%;\"></span>\n <span class=\"grid-loading-title\">Executing stored procedure on SQL Server...</span>\n <span class=\"grid-loading-sub\">Calculating outstanding balances and ledger amounts. Please wait...</span>\n </div>\n }\n <rpt-grid-bridge\n [gridDefinition]=\"definition().grid!\"\n [data]=\"canvasGridData()\"\n (gridStateChange)=\"onCanvasGridStateChange($event)\"\n (columnDefsChange)=\"onCanvasColumnDefsChange($event)\"\n />\n </div>\n </div>\n } @else {\n <div class=\"canvas-add-grid-banner\" (click)=\"addResultGrid($event)\">\n <div class=\"add-grid-icon\">\n <rpt-icon name=\"table\" [size]=\"20\" />\n </div>\n <div class=\"add-grid-text\">\n <span class=\"add-grid-title\">+ Add Result Data Grid</span>\n <span class=\"add-grid-sub\">Attach an interactive data table or UltraGrid to display report execution output</span>\n </div>\n <button type=\"button\" class=\"btn-banner-add\">Add Grid</button>\n </div>\n }\n </div>\n </div>\n </div>", styles: [":host{display:block;height:100%;background-color:#f1f5f9;font-family:var(--rpt-font-family, inherit);box-sizing:border-box}.canvas-wrapper{display:flex;flex-direction:column;height:100%}.canvas-toolbar{display:flex;align-items:center;justify-content:space-between;min-height:42px;height:42px;padding:0 24px;background:var(--rpt-color-surface, #ffffff);border-bottom:1px solid var(--rpt-color-border, #cbd5e1);box-sizing:border-box;gap:12px;overflow-x:auto;scrollbar-width:none;font-family:var(--rpt-font-family, inherit);flex-shrink:0}.canvas-toolbar::-webkit-scrollbar{display:none}.canvas-info{display:flex;align-items:center;gap:8px;font-family:var(--rpt-font-family, inherit);font-size:var(--rpt-font-size-sm, .75rem);color:var(--rpt-color-text-muted, #64748b);white-space:nowrap;line-height:1}.info-label{color:var(--rpt-color-text-muted, #64748b);font-weight:500;font-size:var(--rpt-font-size-sm, .75rem)}.info-value{font-weight:600;color:var(--rpt-color-text, #0f172a);font-size:var(--rpt-font-size-sm, .75rem)}.info-divider{color:var(--rpt-color-border, #cbd5e1);margin:0 2px}.live-mode-badge{display:inline-flex;align-items:center;gap:4px;font-family:var(--rpt-font-family, inherit);font-size:var(--rpt-font-size-xs, .7rem);font-weight:600;color:#047857;background:#ecfdf5;border:1px solid #a7f3d0;padding:2px 8px;border-radius:9999px;line-height:1}.canvas-actions{display:flex;align-items:center;gap:8px;white-space:nowrap}.canvas-action-btn{display:inline-flex;align-items:center;gap:6px;height:28px;padding:0 10px;font-family:var(--rpt-font-family, inherit);font-size:var(--rpt-font-size-sm, .75rem);font-weight:500;letter-spacing:-.01em;color:var(--rpt-color-text-secondary, #334155);background:var(--rpt-color-surface, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);cursor:pointer;line-height:1;white-space:nowrap;box-shadow:0 1px 2px #0000000a;transition:all var(--rpt-transition-speed, .15s) ease}.canvas-action-btn:hover{background:var(--rpt-color-surface-hover, #f8fafc);border-color:var(--rpt-color-border-hover, #94a3b8);color:var(--rpt-color-text, #0f172a);box-shadow:0 2px 4px #0000000f}.canvas-action-btn.btn-grid-configured{background:#eff6ff;border-color:#bfdbfe;color:#2563eb;font-weight:600}.canvas-action-btn.btn-grid-configured:hover{background:#dbeafe;color:#1d4ed8;border-color:#93c5fd}.canvas-action-btn.btn-grid-add{background:#f0fdf4;border-color:#bbf7d0;color:#16a34a;font-weight:600}.canvas-action-btn.btn-grid-add:hover{background:#dcfce7;color:#15803d;border-color:#86efac}.canvas-action-btn:active{transform:translateY(1px)}.canvas-scroll-area{flex:1;overflow-y:auto;padding:16px}.canvas-artboard{width:100%;max-width:1400px;margin:0 auto;background:#fff;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius-lg, 8px);box-shadow:0 4px 6px -1px #0000000d;min-height:480px;box-sizing:border-box}@media (max-width: 900px){.canvas-toolbar{min-height:36px;height:36px;padding:0 10px;gap:6px}.live-mode-badge{display:none}.canvas-info{font-size:.75rem;gap:5px}.canvas-action-btn{padding:0 8px;font-size:.725rem;height:28px;gap:4px}.canvas-scroll-area{padding:10px}.canvas-artboard{min-height:360px}}@media (max-width: 600px){.canvas-toolbar{padding:0 8px;gap:4px}.canvas-info .info-label,.canvas-action-btn span{display:none}.canvas-action-btn{padding:0 6px;min-width:28px;justify-content:center}}.canvas-report-header{margin-bottom:24px;padding-bottom:16px;border-bottom:1px solid var(--rpt-color-border, #e2e8f0)}.canvas-report-title{font-size:var(--rpt-font-size-xl, 1.5rem);font-weight:700;color:var(--rpt-color-text, #0f172a);margin:0 0 6px}.canvas-report-desc{font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text-muted, #64748b);margin:0}.canvas-grid{display:grid;width:100%;min-height:180px;align-items:start;border-radius:6px;transition:all var(--rpt-transition-speed, .15s) ease}.canvas-component-card{container-type:inline-size;background:#fff;border:1.5px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);box-shadow:var(--rpt-box-shadow, 0 1px 2px rgba(0, 0, 0, .05));box-sizing:border-box;transition:all var(--rpt-transition-speed, .15s) ease;cursor:pointer;position:relative;overflow:visible;display:flex;flex-direction:column;min-height:104px;z-index:1}.canvas-component-card:hover{border-color:var(--rpt-color-primary, #2563eb);box-shadow:0 4px 6px -1px #2563eb1a;z-index:2}.canvas-component-card.is-selected{border-color:var(--rpt-color-primary, #2563eb);box-shadow:0 0 0 2px #2563eb40;z-index:10}.canvas-component-card:focus-within,.canvas-component-card:has(.rpt-combobox-menu),.canvas-component-card:has(.is-open){z-index:100}.canvas-component-card.is-resizing{-webkit-user-select:none;user-select:none;border-color:var(--rpt-color-primary, #2563eb);box-shadow:0 0 0 2px #2563eb59;z-index:30;transition:none!important}.resize-handle{position:absolute;z-index:20;touch-action:none;opacity:0;pointer-events:none;transition:opacity .15s ease}.canvas-component-card.is-selected .resize-handle{opacity:1;pointer-events:auto}.resize-handle.handle-e{top:0;right:0;width:6px;height:100%;cursor:ew-resize;display:flex;align-items:center;justify-content:center}.resize-handle.handle-e:after{content:\"\";width:3px;height:24px;background:#cbd5e1;border-radius:2px;transition:background .15s ease}.resize-handle.handle-e:hover:after,.canvas-component-card.is-selected .resize-handle.handle-e:after{background:var(--rpt-color-primary, #2563eb)}.resize-handle.handle-s{bottom:0;left:0;height:6px;width:100%;cursor:ns-resize;display:flex;align-items:center;justify-content:center}.resize-handle.handle-s:after{content:\"\";height:3px;width:24px;background:#cbd5e1;border-radius:2px;transition:background .15s ease}.resize-handle.handle-s:hover:after,.canvas-component-card.is-selected .resize-handle.handle-s:after{background:var(--rpt-color-primary, #2563eb)}.resize-handle.handle-se{bottom:0;right:0;width:12px;height:12px;cursor:nwse-resize;display:flex;align-items:flex-end;justify-content:flex-end;padding:2px}.resize-handle.handle-se:after{content:\"\";width:5px;height:5px;border-right:2px solid #cbd5e1;border-bottom:2px solid #cbd5e1;transition:border-color .15s ease}.resize-handle.handle-se:hover:after,.canvas-component-card.is-selected .resize-handle.handle-se:after{border-color:var(--rpt-color-primary, #2563eb)}.resize-dimension-tooltip{position:absolute;top:38px;right:8px;background:#0f172ae6;color:#fff;font-size:.7rem;font-weight:600;padding:3px 8px;border-radius:4px;white-space:nowrap;pointer-events:none;z-index:50;box-shadow:0 2px 4px #0003}.card-header{display:flex;align-items:center;justify-content:space-between;gap:6px;padding:5px 8px;background:var(--rpt-color-surface, #f8fafc);border-bottom:1px solid var(--rpt-color-border, #e2e8f0);border-top-left-radius:var(--rpt-border-radius, 6px);border-top-right-radius:var(--rpt-border-radius, 6px);min-height:32px;box-sizing:border-box;overflow:hidden;position:relative}.canvas-component-card.is-selected .card-header{overflow:visible}.card-title-group{display:flex;align-items:center;gap:5px;cursor:grab;min-width:0;flex:1;overflow:hidden}.drag-handle-dots{color:var(--rpt-color-text-muted, #94a3b8);font-size:.85rem;letter-spacing:-2px;flex-shrink:0;-webkit-user-select:none;user-select:none}.comp-title{font-size:.75rem;font-weight:600;color:var(--rpt-color-text, #0f172a);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-webkit-user-select:none;user-select:none}.card-actions{display:flex;align-items:center;gap:4px;flex-shrink:0;margin-left:auto}.new-row-pill-static{font-size:.65rem;font-weight:600;color:#7c3aed;background:#f5f3ff;border:1px solid #ddd6fe;padding:1px 5px;border-radius:9999px;white-space:nowrap;line-height:1;flex-shrink:0}.span-pill-static{display:inline-flex;align-items:center;justify-content:center;font-size:.65rem;font-weight:600;color:var(--rpt-color-text-muted, #64748b);background:var(--rpt-color-surface, #f1f5f9);border:1px solid var(--rpt-color-border, #e2e8f0);padding:1px 6px;border-radius:9999px;line-height:1.2;white-space:nowrap;-webkit-user-select:none;user-select:none}.card-quick-controls{display:none;align-items:center;gap:3px;flex-shrink:0}.canvas-component-card:hover .span-pill-static,.canvas-component-card.is-selected .span-pill-static,.canvas-component-card:hover .new-row-pill-static,.canvas-component-card.is-selected .new-row-pill-static{display:none}.canvas-component-card:hover .card-quick-controls,.canvas-component-card.is-selected .card-quick-controls{display:inline-flex}.canvas-component-card.is-narrow .card-header{padding:4px 6px;gap:3px}.canvas-component-card.is-narrow:hover .comp-title,.canvas-component-card.is-narrow.is-selected .comp-title,.canvas-component-card.is-narrow:hover .drag-handle-dots,.canvas-component-card.is-narrow.is-selected .drag-handle-dots{display:none}.canvas-component-card.is-narrow .card-quick-controls{gap:2px}.canvas-component-card.is-narrow .span-control-group{height:18px}.canvas-component-card.is-narrow .span-btn{width:14px;height:16px}.canvas-component-card.is-narrow .span-badge{font-size:.6rem;padding:0 2px}.canvas-component-card.is-narrow .span-total{display:none}.canvas-component-card.is-narrow .card-action-btn{width:18px;height:18px}@container (max-width: 250px){.card-header{padding:4px 6px;gap:3px}.canvas-component-card:hover .comp-title,.canvas-component-card.is-selected .comp-title,.canvas-component-card:hover .drag-handle-dots,.canvas-component-card.is-selected .drag-handle-dots,.span-total{display:none}.card-quick-controls{gap:2px}.card-action-btn{width:18px;height:18px}.span-control-group{height:18px}.span-btn{width:14px;height:16px}.span-badge{font-size:.6rem;padding:0 2px}}@container (max-width: 160px){.canvas-component-card.is-selected .card-quick-controls{position:absolute;top:-30px;right:0;background:#fff;border:1.5px solid var(--rpt-color-primary, #2563eb);border-radius:6px;padding:2px 4px;gap:3px;box-shadow:0 4px 12px #2563eb2e,0 2px 4px #00000014;z-index:120;white-space:nowrap}}@media (max-width: 900px){.canvas-component-card:hover .comp-title,.canvas-component-card.is-selected .comp-title,.canvas-component-card:hover .drag-handle-dots,.canvas-component-card.is-selected .drag-handle-dots,.canvas-component-card .span-total{display:none}.canvas-component-card.is-selected .card-header{overflow:visible}.canvas-component-card.is-selected .card-quick-controls{position:absolute;top:-30px;right:0;background:#fff;border:1.5px solid var(--rpt-color-primary, #2563eb);border-radius:6px;padding:2px 4px;gap:3px;box-shadow:0 4px 12px #2563eb2e,0 2px 4px #00000014;z-index:120;white-space:nowrap}}.span-control-group{display:inline-flex;align-items:center;background:#fff;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:4px;height:20px;padding:0 1px;white-space:nowrap;flex-shrink:0}.span-btn{width:16px;height:18px;display:inline-flex;align-items:center;justify-content:center;border:none;background:transparent;padding:0;color:var(--rpt-color-text-muted, #64748b);cursor:pointer;border-radius:2px;transition:all .12s ease}.span-btn:hover:not(:disabled){background:var(--rpt-color-surface-hover, #f1f5f9);color:var(--rpt-color-primary, #2563eb)}.span-btn:disabled{opacity:.3;cursor:not-allowed}.span-badge{font-size:.65rem;font-weight:600;color:var(--rpt-color-text, #0f172a);padding:0 3px;white-space:nowrap;-webkit-user-select:none;user-select:none;line-height:1}.span-total{font-size:.6rem;color:var(--rpt-color-text-muted, #64748b);font-weight:500}.card-action-btn{width:20px;height:20px;border:none;background:transparent;border-radius:4px;display:inline-flex;align-items:center;justify-content:center;padding:0;cursor:pointer;color:var(--rpt-color-text-muted, #64748b);transition:all .12s ease;flex-shrink:0}.card-action-btn:hover{background:#e2e8f0;color:var(--rpt-color-text, #0f172a)}.card-action-btn.btn-active-toggle{background:#7c3aed;color:#fff;border-color:#7c3aed}.card-action-btn.btn-active-toggle:hover{background:#6d28d9;color:#fff}.btn-delete:hover{background:#fee2e2;color:#ef4444}.card-body{padding:8px 10px 14px;flex:1;display:flex;flex-direction:column;min-height:0;min-width:0;max-width:100%;box-sizing:border-box;overflow:visible}.mock-input-field{display:flex;flex-direction:column;gap:4px;flex:1;height:100%;min-height:0}.mock-label{font-size:.7rem;font-weight:600;color:var(--rpt-color-text-muted, #475569);flex-shrink:0}.mock-input-box,.mock-select-box{border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:6px;padding:6px 12px;font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text-muted, #94a3b8);background:#fff;flex:1;min-height:38px;height:100%;display:flex;align-items:center;justify-content:space-between;box-sizing:border-box}.mock-checkbox-field{display:flex;align-items:center;gap:6px;flex:1;height:100%;min-height:0;padding-top:14px}.mock-check-box{width:18px;height:18px;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:4px;display:flex;align-items:center;justify-content:center;font-size:.65rem;color:var(--rpt-color-primary, #2563eb);flex-shrink:0}.mock-btn-wrapper{display:flex;flex:1;height:100%;min-height:38px;align-items:center;justify-content:flex-start;width:100%;min-width:0;box-sizing:border-box}.mock-btn{border-radius:var(--rpt-border-radius, 6px);padding:0 16px;height:36px;font-size:var(--rpt-font-size-base, .875rem);font-weight:500;border:1px solid transparent;cursor:pointer;width:auto;max-width:100%;display:inline-flex;align-items:center;justify-content:center;gap:6px;box-sizing:border-box;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:all .15s ease}.mock-btn.mock-btn-full{width:100%}.canvas-component-card.is-narrow .mock-btn{padding:0 6px;font-size:.775rem;width:100%;height:34px}.mock-kpi-field{display:flex;flex-direction:column;justify-content:space-between;flex:1;height:100%;min-height:0}.mock-kpi-header{display:flex;align-items:center;justify-content:space-between}.mock-kpi-value{font-size:1.25rem;font-weight:700;color:var(--rpt-color-text, #0f172a);margin:2px 0}.mock-kpi-footer{display:flex;align-items:center;gap:6px;font-size:.65rem}.mock-kpi-trend{color:#16a34a;font-weight:600}.mock-kpi-sub{color:#64748b}.mock-chart-field{display:flex;flex-direction:column;flex:1;height:100%;min-height:140px}.mock-chart-bars{display:flex;align-items:flex-end;justify-content:space-around;gap:16px;flex:1;min-height:100px;padding-top:12px;box-sizing:border-box}.mock-chart-col{flex:1;display:flex;flex-direction:column;align-items:center;height:100%;min-width:60px;max-width:140px}.mock-chart-bar{width:38px;max-width:44px;margin:0 auto;background:var(--rpt-color-primary, #2563eb);border-radius:6px 6px 0 0;opacity:.85;min-height:10px;transition:height .2s ease}.mock-bar-lbl{font-size:.6875rem;color:#64748b;margin-top:6px;text-align:center;white-space:normal;line-height:1.2}.btn-primary{background:var(--rpt-color-primary, #2563eb);color:#fff}.btn-secondary{background:#f1f5f9;color:#0f172a;border:1px solid #cbd5e1}.btn-outline{background:transparent;color:#2563eb;border:1px solid #2563eb}.btn-danger{background:#ef4444;color:#fff}.mock-generic-box{border:1px dashed #cbd5e1;border-radius:4px;padding:8px;font-size:.75rem;text-align:center;color:#64748b}.canvas-drag-placeholder{background:#2563eb0f;border:2px dashed var(--rpt-color-primary, #2563eb);border-radius:6px;min-height:80px;box-sizing:border-box;transition:transform .15s ease}.canvas-drag-preview,::ng-deep .canvas-drag-preview{background:#fff;border:2px solid var(--rpt-color-primary, #2563eb);border-radius:6px;padding:8px 14px;display:inline-flex;align-items:center;gap:8px;font-family:var(--rpt-font-family, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif)!important;font-size:.8rem;font-weight:600;color:var(--rpt-color-text, #0f172a);box-shadow:0 12px 24px -4px #00000040;z-index:10000}.preview-title,::ng-deep .preview-title{font-family:inherit!important;max-width:160px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.preview-span,::ng-deep .preview-span{font-family:inherit!important;font-size:.65rem;font-weight:600;color:var(--rpt-color-primary, #2563eb);background:#eff6ff;border:1px solid #bfdbfe;padding:1px 6px;border-radius:9999px}.canvas-empty-state{grid-column:1 / -1;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:56px 28px;border:2px dashed var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius-xl, 12px);background:var(--rpt-color-surface, #ffffff);text-align:center;box-shadow:var(--rpt-box-shadow-xs, 0 1px 2px 0 rgba(0, 0, 0, .04));transition:border-color var(--rpt-transition-speed, .15s) ease}.canvas-empty-state:hover{border-color:var(--rpt-color-primary, #2563eb)}.empty-hero-badge{width:56px;height:56px;border-radius:var(--rpt-border-radius-xl, 12px);background:var(--rpt-color-primary-light, #eff6ff);color:var(--rpt-color-primary, #2563eb);display:flex;align-items:center;justify-content:center;margin-bottom:16px;box-shadow:0 2px 8px #2563eb1f}.empty-hero-title{font-size:var(--rpt-font-size-lg, 1.125rem);font-weight:700;color:var(--rpt-color-text, #0f172a);margin:0 0 8px;letter-spacing:-.01em}.empty-hero-desc{font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text-muted, #64748b);max-width:520px;line-height:1.5;margin:0 0 24px}.empty-hero-actions{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:10px}.empty-btn{display:inline-flex;align-items:center;gap:7px;padding:8px 16px;font-size:var(--rpt-font-size-sm, .75rem);font-weight:600;border-radius:var(--rpt-border-radius, 6px);cursor:pointer;transition:all var(--rpt-transition-speed, .15s) ease;font-family:inherit}.empty-btn-primary{background:var(--rpt-color-primary, #2563eb);color:#fff;border:1px solid var(--rpt-color-primary, #2563eb);box-shadow:0 1px 3px #2563eb33}.empty-btn-primary:hover{background:var(--rpt-color-primary-hover, #1d4ed8);border-color:var(--rpt-color-primary-hover, #1d4ed8);transform:translateY(-1px)}.empty-btn-secondary{background:#f8fafc;color:#334155;border:1px solid var(--rpt-color-border, #cbd5e1)}.empty-btn-secondary:hover{background:#f1f5f9;color:#0f172a;border-color:#94a3b8;transform:translateY(-1px)}.empty-btn-outline{background:#fff;color:var(--rpt-color-primary, #2563eb);border:1px solid #bfdbfe}.empty-btn-outline:hover{background:#eff6ff;border-color:var(--rpt-color-primary, #2563eb);transform:translateY(-1px)}.canvas-active-input{width:100%;height:32px;padding:4px 8px;font-size:.8125rem;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:4px;outline:none;box-sizing:border-box;background:#fff;color:#0f172a;transition:border-color .15s ease}.canvas-active-input:focus{border-color:var(--rpt-color-primary, #2563eb)}.canvas-active-checkbox-lbl{display:inline-flex;align-items:center;gap:6px;cursor:pointer}.canvas-live-control-wrapper{width:100%;max-width:100%;min-width:0;position:relative;z-index:1;box-sizing:border-box}.canvas-grid-box{margin-top:24px;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:8px;background:#fff;box-shadow:0 1px 3px #0000000d;overflow:hidden}.grid-preview-header{display:flex;align-items:center;justify-content:space-between;padding:10px 16px;background:var(--rpt-color-surface, #f8fafc);border-bottom:1px solid var(--rpt-color-border, #cbd5e1);font-size:.8rem;font-weight:600;color:var(--rpt-color-text, #0f172a)}.grid-title{font-weight:700}.grid-exec-badge{font-size:.6875rem;font-weight:600;padding:2px 8px;border-radius:10px}.grid-exec-badge.is-loading{background:#eff6ff;color:#2563eb}.grid-exec-badge.is-error{background:#fee2e2;color:#ef4444}.grid-exec-badge.is-success{background:#ecfdf5;color:#059669}.btn-canvas-run-grid{display:inline-flex;align-items:center;gap:5px;padding:4px 10px;font-size:.72rem;font-weight:600;color:#fff;background:var(--rpt-color-primary, #2563eb);border:none;border-radius:4px;cursor:pointer;transition:background .15s ease}.btn-canvas-run-grid:hover:not(:disabled){background:#1d4ed8}.btn-canvas-run-grid:disabled{opacity:.6;cursor:not-allowed}.btn-canvas-edit-grid{display:inline-flex;align-items:center;gap:4px;padding:4px 8px;font-size:.72rem;font-weight:500;color:#334155;background:#fff;border:1px solid #cbd5e1;border-radius:4px;cursor:pointer;transition:all .12s ease}.btn-canvas-edit-grid:hover{background:#f1f5f9}.canvas-live-grid-container{width:100%;min-height:480px;background:#fff}.live-mode-badge{display:inline-flex;align-items:center;gap:4px;font-size:.6875rem;font-weight:700;color:#047857;background:#ecfdf5;border:1px solid #a7f3d0;padding:1px 8px;border-radius:9999px}.canvas-component-card.is-field-highlighted{border-color:#f59e0b!important;box-shadow:0 0 0 3px #f59e0b59!important;animation:rpt-pulse-border 1s ease-in-out infinite alternate}@keyframes rpt-pulse-border{0%{box-shadow:0 0 0 2px #f59e0b40}to{box-shadow:0 0 0 5px #f59e0b80}}.grid-layout-status-strip{display:flex;align-items:center;justify-content:space-between;padding:6px 16px;background:#f1f5f9;border-bottom:1px solid var(--rpt-color-border, #cbd5e1);font-size:.6875rem;color:#475569}.grid-status-info{display:inline-flex;align-items:center;gap:6px;font-weight:600}.grid-status-sync{display:inline-flex;align-items:center;gap:4px;color:#059669;font-weight:600;transition:transform .2s ease}.grid-status-sync.is-pulsing{transform:scale(1.08);color:#047857}.canvas-actions{display:flex;align-items:center;gap:8px}.btn-grid-add{background:#f0fdf4;border-color:#bbf7d0;color:#16a34a}.btn-grid-add:hover{background:#dcfce7;border-color:#86efac;color:#15803d}.btn-remove-grid{display:inline-flex;align-items:center;justify-content:center;padding:4px;border:none;background:transparent;color:#94a3b8;border-radius:4px;cursor:pointer;transition:all .15s ease}.btn-remove-grid:hover{background:#fee2e2;color:#ef4444}.canvas-add-grid-banner{margin-top:24px;border:2px dashed #cbd5e1;border-radius:8px;background:#fff;padding:16px 20px;display:flex;align-items:center;gap:16px;cursor:pointer;transition:all .15s ease}.canvas-add-grid-banner:hover{border-color:#2563eb;background:#f8fafc;box-shadow:0 2px 8px #2563eb14}.add-grid-icon{width:40px;height:40px;border-radius:8px;background:#eff6ff;color:#2563eb;display:flex;align-items:center;justify-content:center;flex-shrink:0}.add-grid-text{display:flex;flex-direction:column;gap:2px;flex:1}.add-grid-title{font-size:.875rem;font-weight:600;color:#0f172a}.add-grid-sub{font-size:.75rem;color:#64748b}.btn-banner-add{padding:6px 14px;font-size:.75rem;font-weight:600;color:#2563eb;background:#eff6ff;border:1px solid #bfdbfe;border-radius:6px;cursor:pointer;white-space:nowrap;transition:all .15s ease}.canvas-add-grid-banner:hover .btn-banner-add{background:#2563eb;color:#fff;border-color:#2563eb}.canvas-grid-loading-overlay{position:absolute;inset:0;background:#ffffffe6;backdrop-filter:blur(2px);z-index:10;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;font-family:inherit;border-radius:6px}.grid-loading-title{font-weight:600;font-size:.95rem;color:#1e293b}.grid-loading-sub{font-size:.8rem;color:#64748b}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: i1.CdkDragHandle, selector: "[cdkDragHandle]", inputs: ["cdkDragHandleDisabled"] }, { kind: "directive", type: i1.CdkDragPreview, selector: "ng-template[cdkDragPreview]", inputs: ["data", "matchSize"] }, { kind: "directive", type: i1.CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.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: i2.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { kind: "directive", type: i2.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: RptIconComponent, selector: "rpt-icon", inputs: ["name", "size", "color", "strokeWidth"] }, { kind: "component", type: RptDropdownComponent, selector: "rpt-dropdown", inputs: ["config", "control", "parentForm", "showStatus"] }, { kind: "component", type: RptDateRangeComponent, selector: "rpt-date-range", inputs: ["config", "control"] }, { kind: "component", type: ReportGridBridgeComponent, selector: "rpt-grid-bridge", inputs: ["gridDefinition", "data"], outputs: ["gridStateChange", "columnDefsChange", "rowClick", "selectionChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
397
455
|
}
|
|
398
456
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: DesignCanvasComponent, decorators: [{
|
|
399
457
|
type: Component,
|
|
@@ -405,9 +463,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
405
463
|
RptDropdownComponent,
|
|
406
464
|
RptDateRangeComponent,
|
|
407
465
|
ReportGridBridgeComponent,
|
|
408
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, template: " <div class=\"canvas-wrapper\" (click)=\"onCanvasBackgroundClick($event)\">\n <!-- Canvas Status / Quick Controls -->\n <div class=\"canvas-toolbar\">\n <div class=\"canvas-info\">\n <span class=\"info-label\">Grid Layout:</span>\n <span class=\"info-value\">{{ totalColumns() }} Columns</span>\n <span class=\"info-divider\">\u2022</span>\n <span class=\"info-label\">Components:</span>\n <span class=\"info-value\">{{ components().length }}</span>\n <span class=\"info-divider\">\u2022</span>\n <span class=\"live-mode-badge\" title=\"Interactive canvas: Values typed here run live queries and test dropdowns.\">\n \u26A1 Live Interactive Mode\n </span>\n </div>\n\n <div class=\"canvas-actions\">\n @if (!definition().grid) {\n <button\n type=\"button\"\n class=\"canvas-action-btn btn-grid-add\"\n (click)=\"addResultGrid($event)\"\n title=\"Add a Result Grid to this report\"\n >\n <rpt-icon name=\"table\" [size]=\"14\" />\n <span>+ Add Grid</span>\n </button>\n } @else {\n <button\n type=\"button\"\n class=\"canvas-action-btn btn-grid-configured\"\n (click)=\"selectGridSettings($event)\"\n title=\"Configure Result Data Grid\"\n >\n <rpt-icon name=\"table\" [size]=\"14\" />\n <span>Grid ({{ definition().grid?.columns?.length ?? 0 }})</span>\n </button>\n }\n\n <button\n type=\"button\"\n class=\"canvas-action-btn\"\n (click)=\"selectReportSettings($event)\"\n title=\"Configure Page Layout & Grid Settings\"\n >\n <rpt-icon name=\"settings\" [size]=\"14\" />\n <span>Report Settings</span>\n </button>\n </div>\n </div>\n\n <!-- Canvas Drop Area -->\n <div class=\"canvas-scroll-area\">\n <div\n class=\"canvas-artboard\"\n [style.padding.px]=\"definition().layout.padding ?? 24\"\n >\n <!-- Report Header Preview -->\n <div class=\"canvas-report-header\">\n <h2 class=\"canvas-report-title\">{{ definition().name || 'Untitled Report' }}</h2>\n @if (definition().description) {\n <p class=\"canvas-report-desc\">{{ definition().description }}</p>\n }\n </div>\n\n <!-- Component Drop List Grid with 2D mixed orientation and data binding -->\n <div\n cdkDropList\n id=\"designer-canvas-drop-list\"\n class=\"canvas-grid\"\n cdkDropListOrientation=\"mixed\"\n [cdkDropListData]=\"sortedComponents()\"\n [style.grid-template-columns]=\"gridTemplateColumns()\"\n [style.gap.px]=\"definition().layout.gap ?? 16\"\n (cdkDropListDropped)=\"onDrop($event)\"\n >\n @for (comp of sortedComponents(); track comp.id; let idx = $index) {\n <div\n cdkDrag\n [cdkDragData]=\"comp\"\n [cdkDragDisabled]=\"isAnyResizing()\"\n class=\"canvas-component-card\"\n [class.is-selected]=\"isSelected(comp.id)\"\n [class.is-resizing]=\"resizingCompId() === comp.id\"\n [class.is-field-highlighted]=\"isFieldHighlighted(comp)\"\n [class.is-narrow]=\"getSpan(comp) <= 4\"\n [class.is-compact]=\"getSpan(comp) <= 2\"\n [style.grid-column]=\"getGridColumn(comp)\"\n [style.grid-row]=\"getGridRow(comp)\"\n [style.width]=\"comp.layout?.width || 'auto'\"\n [style.height]=\"getComponentHeight(comp)\"\n [style.min-height]=\"getComponentMinHeight(comp)\"\n (click)=\"onSelect(comp.id, $event)\"\n >\n <!-- Card Header with Drag Handle & Actions -->\n <div class=\"card-header\">\n <div class=\"card-title-group\" cdkDragHandle title=\"Drag to reorder\">\n <span class=\"drag-handle-dots\">\u22EE\u22EE</span>\n <rpt-icon [name]=\"getComponentIconName(comp.type)\" [size]=\"14\" />\n <span class=\"comp-title\" [title]=\"comp.label || comp.key || comp.type\">\n {{ comp.label || comp.key || comp.type }}\n </span>\n </div>\n\n <div class=\"card-actions\">\n <!-- Static span pill & new row / start col pill when not hovered / not selected -->\n @if (comp.layout?.column; as col) {\n <span class=\"new-row-pill-static\" title=\"Starts at Column {{ col }}\">Col {{ col }}</span>\n } @else if (comp.layout?.newRow) {\n <span class=\"new-row-pill-static\" title=\"Starts on separate row\">\u21B3 Row</span>\n }\n <span\n class=\"span-pill-static\"\n title=\"Column span: {{ getSpan(comp) }} of {{ totalColumns() }} columns\"\n >\n {{ getSpan(comp) }}/{{ totalColumns() }}\n </span>\n\n <!-- Quick Action Stepper & Buttons (revealed on hover or selection) -->\n <div class=\"card-quick-controls\">\n <button\n type=\"button\"\n class=\"card-action-btn\"\n [class.btn-active-toggle]=\"comp.layout?.newRow\"\n (click)=\"toggleNewRow(comp, $event)\"\n title=\"{{ comp.layout?.newRow ? 'Starts on new row (Click to place inline)' : 'Start on separate row (Row Break)' }}\"\n >\n <rpt-icon name=\"corner-down-right\" [size]=\"11\" />\n </button>\n\n <div class=\"span-control-group\" title=\"Adjust Column Span\">\n <button\n type=\"button\"\n class=\"span-btn\"\n [disabled]=\"getSpan(comp) <= 1\"\n (click)=\"adjustSpan(comp, -1, $event)\"\n title=\"Shrink Column Span\"\n >\n <rpt-icon name=\"minus\" [size]=\"9\" />\n </button>\n <span class=\"span-badge\" [title]=\"'Column span: ' + getSpan(comp) + ' of ' + totalColumns()\">\n <span class=\"span-num\">{{ getSpan(comp) }}</span><span class=\"span-total\">/{{ totalColumns() }}</span>\n </span>\n <button\n type=\"button\"\n class=\"span-btn\"\n [disabled]=\"getSpan(comp) >= totalColumns()\"\n (click)=\"adjustSpan(comp, 1, $event)\"\n title=\"Expand Column Span\"\n >\n <rpt-icon name=\"plus\" [size]=\"9\" />\n </button>\n </div>\n\n <button\n type=\"button\"\n class=\"card-action-btn\"\n (click)=\"onDuplicate(comp.id, $event)\"\n title=\"Duplicate component\"\n >\n <rpt-icon name=\"copy\" [size]=\"12\" />\n </button>\n <button\n type=\"button\"\n class=\"card-action-btn btn-delete\"\n (click)=\"onDelete(comp.id, $event)\"\n title=\"Remove component\"\n >\n <rpt-icon name=\"trash\" [size]=\"12\" />\n </button>\n </div>\n </div>\n </div>\n\n <!-- Card Body Visual Preview -->\n <div class=\"card-body\">\n\n @switch (comp.type) {\n @case ('input') {\n <div class=\"mock-input-field\" (click)=\"onControlInteract(comp, $event)\">\n <span class=\"mock-label\">{{ comp.label || 'Input' }}</span>\n @if (getCanvasControl(comp); as ctrl) {\n <input\n type=\"text\"\n class=\"canvas-active-input\"\n [placeholder]=\"comp.properties?.['placeholder'] || 'Enter text...'\"\n [formControl]=\"ctrl\"\n (focus)=\"onControlInteract(comp, $event)\"\n />\n } @else {\n <div class=\"mock-input-box\">{{ comp.properties?.['placeholder'] || 'Enter text...' }}</div>\n }\n </div>\n }\n @case ('dropdown') {\n <div class=\"canvas-live-control-wrapper\" (click)=\"onControlInteract(comp, $event)\">\n <rpt-dropdown\n [config]=\"comp\"\n [showStatus]=\"true\"\n [parentForm]=\"canvasForm()\"\n [control]=\"getCanvasControl(comp)\"\n />\n </div>\n }\n @case ('date') {\n <div class=\"mock-input-field\" (click)=\"onControlInteract(comp, $event)\">\n <span class=\"mock-label\">{{ comp.label || 'Date' }}</span>\n @if (getCanvasControl(comp); as ctrl) {\n <input\n type=\"date\"\n class=\"canvas-active-input\"\n [formControl]=\"ctrl\"\n (focus)=\"onControlInteract(comp, $event)\"\n />\n } @else {\n <div class=\"mock-select-box\">\n <span>YYYY-MM-DD</span>\n <rpt-icon name=\"calendar\" [size]=\"12\" />\n </div>\n }\n </div>\n }\n @case ('date-range') {\n <div class=\"canvas-live-control-wrapper\" (click)=\"onControlInteract(comp, $event)\">\n <rpt-date-range\n [config]=\"comp\"\n [control]=\"getCanvasControl(comp)\"\n />\n </div>\n }\n @case ('number') {\n <div class=\"mock-input-field\" (click)=\"onControlInteract(comp, $event)\">\n <span class=\"mock-label\">{{ comp.label || 'Number' }}</span>\n @if (getCanvasControl(comp); as ctrl) {\n <input\n type=\"number\"\n class=\"canvas-active-input\"\n [formControl]=\"ctrl\"\n (focus)=\"onControlInteract(comp, $event)\"\n />\n } @else {\n <div class=\"mock-input-box\">\n {{ comp.properties?.['prefix'] || '' }} 0.00 {{ comp.properties?.['suffix'] || '' }}\n </div>\n }\n </div>\n }\n @case ('checkbox') {\n <div class=\"mock-checkbox-field\" (click)=\"onControlInteract(comp, $event)\">\n @if (getCanvasControl(comp); as ctrl) {\n <label class=\"canvas-active-checkbox-lbl\">\n <input type=\"checkbox\" [formControl]=\"ctrl\" (focus)=\"onControlInteract(comp, $event)\" />\n <span class=\"mock-label\">{{ comp.label || 'Checkbox' }}</span>\n </label>\n } @else {\n <span class=\"mock-check-box\">\n <rpt-icon name=\"check\" [size]=\"10\" />\n </span>\n <span class=\"mock-label\">{{ comp.label || 'Checkbox' }}</span>\n }\n </div>\n }\n @case ('button') {\n <div class=\"mock-btn-wrapper\">\n <button\n type=\"button\"\n class=\"mock-btn\"\n [class]=\"'btn-' + (comp.properties?.['variant'] || 'primary')\"\n [class.mock-btn-full]=\"comp.properties?.['fullWidth'] === true || comp.layout?.width === '100%'\"\n [style.height]=\"getCustomBtnHeight(comp)\"\n [style.width]=\"getCustomBtnWidth(comp)\"\n (click)=\"onCanvasButtonClick(comp, $event)\"\n >\n @if (getCustomBtnIcon(comp); as btnIcon) {\n <rpt-icon [name]=\"btnIcon\" [size]=\"15\" />\n }\n <span>{{ comp.label || 'Button' }}</span>\n </button>\n </div>\n }\n @case ('kpi-card') {\n <div class=\"mock-kpi-field\">\n <div class=\"mock-kpi-header\">\n <span class=\"mock-label\">{{ comp.label || 'KPI Metric' }}</span>\n <rpt-icon name=\"kpi\" [size]=\"14\" />\n </div>\n <div class=\"mock-kpi-value\">{{ comp.properties?.['value'] || '$128,450' }}</div>\n <div class=\"mock-kpi-footer\">\n <span class=\"mock-kpi-trend\">+12.5%</span>\n <span class=\"mock-kpi-sub\">vs last period</span>\n </div>\n </div>\n }\n @case ('chart') {\n <div class=\"mock-chart-field\">\n <div class=\"mock-chart-header\">\n <span class=\"mock-label\">{{ comp.label || 'Quarterly Sales Revenue ($000)' }}</span>\n </div>\n <div class=\"mock-chart-bars\">\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 44%\"></div>\n <span class=\"mock-bar-lbl\">Q1 Jan-Mar</span>\n </div>\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 61%\"></div>\n <span class=\"mock-bar-lbl\">Q2 Apr-Jun</span>\n </div>\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 79%\"></div>\n <span class=\"mock-bar-lbl\">Q3 Jul-Sep</span>\n </div>\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 100%\"></div>\n <span class=\"mock-bar-lbl\">Q4 Oct-Dec</span>\n </div>\n </div>\n </div>\n }\n @default {\n <div class=\"mock-generic-box\">\n <span>{{ comp.type }}</span>\n </div>\n }\n }\n </div>\n\n <!-- Resizing Handles (East, South, South-East) -->\n <div\n class=\"resize-handle handle-e\"\n (pointerdown)=\"startResize($event, comp, 'e')\"\n (dblclick)=\"resetDimensions(comp, $event)\"\n title=\"Drag to resize column width \u2022 Double-click to reset\"\n ></div>\n <div\n class=\"resize-handle handle-s\"\n (pointerdown)=\"startResize($event, comp, 's')\"\n (dblclick)=\"resetDimensions(comp, $event)\"\n title=\"Drag to resize height \u2022 Double-click to reset\"\n ></div>\n <div\n class=\"resize-handle handle-se\"\n (pointerdown)=\"startResize($event, comp, 'se')\"\n (dblclick)=\"resetDimensions(comp, $event)\"\n title=\"Drag to resize width and height \u2022 Double-click to reset\"\n ></div>\n\n <!-- Resizing Dimension Ghost / Badge -->\n @if (resizingCompId() === comp.id) {\n <div class=\"resize-dimension-tooltip\">\n {{ resizingTooltip(comp) }}\n </div>\n }\n\n <!-- Drag placeholder with matched grid column span -->\n <div\n *cdkDragPlaceholder\n class=\"canvas-drag-placeholder\"\n [style.grid-column]=\"getGridColumn(comp)\"\n ></div>\n\n <!-- Drag preview -->\n <div *cdkDragPreview class=\"canvas-drag-preview\">\n <span class=\"drag-handle-dots\">\u22EE\u22EE</span>\n <rpt-icon [name]=\"getComponentIconName(comp.type)\" [size]=\"14\" />\n <span class=\"preview-title\">{{ comp.label || comp.key || comp.type }}</span>\n <span class=\"preview-span\">{{ getSpan(comp) }}/{{ totalColumns() }}</span>\n </div>\n </div>\n }\n\n @if (components().length === 0) {\n <div class=\"canvas-empty-state\" role=\"region\" aria-label=\"Empty canvas starter options\">\n <div class=\"empty-hero-badge\">\n <rpt-icon name=\"design\" [size]=\"28\" />\n </div>\n <h3 class=\"empty-hero-title\">Start Designing Your Custom Report</h3>\n <p class=\"empty-hero-desc\">\n Drag controls from the left component palette, or jumpstart your design with pre-configured enterprise blueprints.\n </p>\n\n <div class=\"empty-hero-actions\">\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-primary\"\n (click)=\"applyBlueprint('blueprint-audit-register')\"\n title=\"Load complete Audit Register blueprint with parameters and result grid\"\n >\n <rpt-icon name=\"table\" [size]=\"15\" />\n <span>Audit Register Blueprint</span>\n </button>\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-secondary\"\n (click)=\"applyBlueprint('blueprint-kpi-summary')\"\n title=\"Load Executive KPI summary blueprint\"\n >\n <rpt-icon name=\"chart-bar\" [size]=\"15\" />\n <span>KPI Summary Blueprint</span>\n </button>\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-outline\"\n (click)=\"addStarterComponent('date-range')\"\n title=\"Add a Date Range filter component\"\n >\n <rpt-icon name=\"calendar\" [size]=\"14\" />\n <span>+ Add Date Filter</span>\n </button>\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-outline\"\n (click)=\"addStarterComponent('button')\"\n title=\"Add an Execute Action button\"\n >\n <rpt-icon name=\"play\" [size]=\"14\" />\n <span>+ Add Run Button</span>\n </button>\n </div>\n </div>\n }\n </div>\n\n <!-- Live Result Grid Preview with Bways-Grid Features -->\n @if (definition().grid) {\n <div class=\"canvas-grid-box\">\n <div class=\"grid-preview-header\">\n <div style=\"display: flex; align-items: center; gap: 8px;\">\n <rpt-icon name=\"table\" [size]=\"15\" />\n <span class=\"grid-title\">Bways Grid ({{ definition().grid?.columns?.length ?? 0 }} columns)</span>\n @if (isExecutingGrid()) {\n <span class=\"grid-exec-badge is-loading\">Loading data from database...</span>\n } @else if (gridExecError()) {\n <span class=\"grid-exec-badge is-error\">{{ gridExecError() }}</span>\n } @else if (canvasGridData().length > 0) {\n <span class=\"grid-exec-badge is-success\">{{ canvasGridData().length }} rows loaded</span>\n }\n </div>\n <div style=\"display: flex; align-items: center; gap: 8px;\">\n <button\n type=\"button\"\n class=\"btn-canvas-run-grid\"\n (click)=\"executeCanvasReport($event)\"\n [disabled]=\"isExecutingGrid()\"\n title=\"Execute query and load data into Bways Grid\"\n >\n <rpt-icon name=\"play\" [size]=\"11\" />\n <span>{{ isExecutingGrid() ? 'Running...' : 'Run / Refresh Grid' }}</span>\n </button>\n <button\n type=\"button\"\n class=\"btn-canvas-edit-grid\"\n (click)=\"selectGridSettings($event)\"\n title=\"Configure columns and grid options\"\n >\n <rpt-icon name=\"settings\" [size]=\"11\" />\n <span>Configure</span>\n </button>\n <button\n type=\"button\"\n class=\"btn-remove-grid\"\n (click)=\"removeGrid($event)\"\n title=\"Remove Result Grid from this report\"\n >\n <rpt-icon name=\"trash\" [size]=\"13\" />\n </button>\n </div>\n </div>\n\n @if (getGridSummaryText(); as summary) {\n <div class=\"grid-layout-status-strip\">\n <div class=\"grid-status-info\">\n <rpt-icon name=\"table\" [size]=\"12\" />\n <span>{{ summary }}</span>\n </div>\n <div class=\"grid-status-sync\" [class.is-pulsing]=\"layoutJustUpdated()\">\n <rpt-icon name=\"check\" [size]=\"11\" />\n <span>Layout auto-persisted</span>\n </div>\n </div>\n }\n\n <!-- Live Bways Grid bridge -->\n <div class=\"canvas-live-grid-container\" (click)=\"$event.stopPropagation()\">\n <rpt-grid-bridge\n [gridDefinition]=\"definition().grid!\"\n [data]=\"canvasGridData()\"\n (gridStateChange)=\"onCanvasGridStateChange($event)\"\n (columnDefsChange)=\"onCanvasColumnDefsChange($event)\"\n />\n </div>\n </div>\n } @else {\n <div class=\"canvas-add-grid-banner\" (click)=\"addResultGrid($event)\">\n <div class=\"add-grid-icon\">\n <rpt-icon name=\"table\" [size]=\"20\" />\n </div>\n <div class=\"add-grid-text\">\n <span class=\"add-grid-title\">+ Add Result Data Grid</span>\n <span class=\"add-grid-sub\">Attach an interactive data table or UltraGrid to display report execution output</span>\n </div>\n <button type=\"button\" class=\"btn-banner-add\">Add Grid</button>\n </div>\n }\n </div>\n </div>\n </div>", styles: [":host{display:block;height:100%;background-color:#f1f5f9;font-family:var(--rpt-font-family, inherit);box-sizing:border-box}.canvas-wrapper{display:flex;flex-direction:column;height:100%}.canvas-toolbar{display:flex;align-items:center;justify-content:space-between;min-height:42px;height:42px;padding:0 24px;background:var(--rpt-color-surface, #ffffff);border-bottom:1px solid var(--rpt-color-border, #cbd5e1);box-sizing:border-box;gap:12px;overflow-x:auto;scrollbar-width:none;font-family:var(--rpt-font-family, inherit);flex-shrink:0}.canvas-toolbar::-webkit-scrollbar{display:none}.canvas-info{display:flex;align-items:center;gap:8px;font-family:var(--rpt-font-family, inherit);font-size:var(--rpt-font-size-sm, .75rem);color:var(--rpt-color-text-muted, #64748b);white-space:nowrap;line-height:1}.info-label{color:var(--rpt-color-text-muted, #64748b);font-weight:500;font-size:var(--rpt-font-size-sm, .75rem)}.info-value{font-weight:600;color:var(--rpt-color-text, #0f172a);font-size:var(--rpt-font-size-sm, .75rem)}.info-divider{color:var(--rpt-color-border, #cbd5e1);margin:0 2px}.live-mode-badge{display:inline-flex;align-items:center;gap:4px;font-family:var(--rpt-font-family, inherit);font-size:var(--rpt-font-size-xs, .7rem);font-weight:600;color:#047857;background:#ecfdf5;border:1px solid #a7f3d0;padding:2px 8px;border-radius:9999px;line-height:1}.canvas-actions{display:flex;align-items:center;gap:8px;white-space:nowrap}.canvas-action-btn{display:inline-flex;align-items:center;gap:6px;height:28px;padding:0 10px;font-family:var(--rpt-font-family, inherit);font-size:var(--rpt-font-size-sm, .75rem);font-weight:500;letter-spacing:-.01em;color:var(--rpt-color-text-secondary, #334155);background:var(--rpt-color-surface, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);cursor:pointer;line-height:1;white-space:nowrap;box-shadow:0 1px 2px #0000000a;transition:all var(--rpt-transition-speed, .15s) ease}.canvas-action-btn:hover{background:var(--rpt-color-surface-hover, #f8fafc);border-color:var(--rpt-color-border-hover, #94a3b8);color:var(--rpt-color-text, #0f172a);box-shadow:0 2px 4px #0000000f}.canvas-action-btn.btn-grid-configured{background:#eff6ff;border-color:#bfdbfe;color:#2563eb;font-weight:600}.canvas-action-btn.btn-grid-configured:hover{background:#dbeafe;color:#1d4ed8;border-color:#93c5fd}.canvas-action-btn.btn-grid-add{background:#f0fdf4;border-color:#bbf7d0;color:#16a34a;font-weight:600}.canvas-action-btn.btn-grid-add:hover{background:#dcfce7;color:#15803d;border-color:#86efac}.canvas-action-btn:active{transform:translateY(1px)}.canvas-scroll-area{flex:1;overflow-y:auto;padding:16px}.canvas-artboard{width:100%;max-width:1400px;margin:0 auto;background:#fff;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius-lg, 8px);box-shadow:0 4px 6px -1px #0000000d;min-height:480px;box-sizing:border-box}@media (max-width: 900px){.canvas-toolbar{min-height:36px;height:36px;padding:0 10px;gap:6px}.live-mode-badge{display:none}.canvas-info{font-size:.75rem;gap:5px}.canvas-action-btn{padding:0 8px;font-size:.725rem;height:28px;gap:4px}.canvas-scroll-area{padding:10px}.canvas-artboard{min-height:360px}}@media (max-width: 600px){.canvas-toolbar{padding:0 8px;gap:4px}.canvas-info .info-label,.canvas-action-btn span{display:none}.canvas-action-btn{padding:0 6px;min-width:28px;justify-content:center}}.canvas-report-header{margin-bottom:24px;padding-bottom:16px;border-bottom:1px solid var(--rpt-color-border, #e2e8f0)}.canvas-report-title{font-size:var(--rpt-font-size-xl, 1.5rem);font-weight:700;color:var(--rpt-color-text, #0f172a);margin:0 0 6px}.canvas-report-desc{font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text-muted, #64748b);margin:0}.canvas-grid{display:grid;width:100%;min-height:180px;align-items:start;border-radius:6px;transition:all var(--rpt-transition-speed, .15s) ease}.canvas-component-card{container-type:inline-size;background:#fff;border:1.5px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);box-shadow:var(--rpt-box-shadow, 0 1px 2px rgba(0, 0, 0, .05));box-sizing:border-box;transition:all var(--rpt-transition-speed, .15s) ease;cursor:pointer;position:relative;overflow:visible;display:flex;flex-direction:column;min-height:104px;z-index:1}.canvas-component-card:hover{border-color:var(--rpt-color-primary, #2563eb);box-shadow:0 4px 6px -1px #2563eb1a;z-index:2}.canvas-component-card.is-selected{border-color:var(--rpt-color-primary, #2563eb);box-shadow:0 0 0 2px #2563eb40;z-index:10}.canvas-component-card:focus-within,.canvas-component-card:has(.rpt-combobox-menu),.canvas-component-card:has(.is-open){z-index:100}.canvas-component-card.is-resizing{-webkit-user-select:none;user-select:none;border-color:var(--rpt-color-primary, #2563eb);box-shadow:0 0 0 2px #2563eb59;z-index:30;transition:none!important}.resize-handle{position:absolute;z-index:20;touch-action:none;opacity:0;pointer-events:none;transition:opacity .15s ease}.canvas-component-card.is-selected .resize-handle{opacity:1;pointer-events:auto}.resize-handle.handle-e{top:0;right:0;width:6px;height:100%;cursor:ew-resize;display:flex;align-items:center;justify-content:center}.resize-handle.handle-e:after{content:\"\";width:3px;height:24px;background:#cbd5e1;border-radius:2px;transition:background .15s ease}.resize-handle.handle-e:hover:after,.canvas-component-card.is-selected .resize-handle.handle-e:after{background:var(--rpt-color-primary, #2563eb)}.resize-handle.handle-s{bottom:0;left:0;height:6px;width:100%;cursor:ns-resize;display:flex;align-items:center;justify-content:center}.resize-handle.handle-s:after{content:\"\";height:3px;width:24px;background:#cbd5e1;border-radius:2px;transition:background .15s ease}.resize-handle.handle-s:hover:after,.canvas-component-card.is-selected .resize-handle.handle-s:after{background:var(--rpt-color-primary, #2563eb)}.resize-handle.handle-se{bottom:0;right:0;width:12px;height:12px;cursor:nwse-resize;display:flex;align-items:flex-end;justify-content:flex-end;padding:2px}.resize-handle.handle-se:after{content:\"\";width:5px;height:5px;border-right:2px solid #cbd5e1;border-bottom:2px solid #cbd5e1;transition:border-color .15s ease}.resize-handle.handle-se:hover:after,.canvas-component-card.is-selected .resize-handle.handle-se:after{border-color:var(--rpt-color-primary, #2563eb)}.resize-dimension-tooltip{position:absolute;top:38px;right:8px;background:#0f172ae6;color:#fff;font-size:.7rem;font-weight:600;padding:3px 8px;border-radius:4px;white-space:nowrap;pointer-events:none;z-index:50;box-shadow:0 2px 4px #0003}.card-header{display:flex;align-items:center;justify-content:space-between;gap:6px;padding:5px 8px;background:var(--rpt-color-surface, #f8fafc);border-bottom:1px solid var(--rpt-color-border, #e2e8f0);border-top-left-radius:var(--rpt-border-radius, 6px);border-top-right-radius:var(--rpt-border-radius, 6px);min-height:32px;box-sizing:border-box;overflow:hidden;position:relative}.canvas-component-card.is-selected .card-header{overflow:visible}.card-title-group{display:flex;align-items:center;gap:5px;cursor:grab;min-width:0;flex:1;overflow:hidden}.drag-handle-dots{color:var(--rpt-color-text-muted, #94a3b8);font-size:.85rem;letter-spacing:-2px;flex-shrink:0;-webkit-user-select:none;user-select:none}.comp-title{font-size:.75rem;font-weight:600;color:var(--rpt-color-text, #0f172a);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-webkit-user-select:none;user-select:none}.card-actions{display:flex;align-items:center;gap:4px;flex-shrink:0;margin-left:auto}.new-row-pill-static{font-size:.65rem;font-weight:600;color:#7c3aed;background:#f5f3ff;border:1px solid #ddd6fe;padding:1px 5px;border-radius:9999px;white-space:nowrap;line-height:1;flex-shrink:0}.span-pill-static{display:inline-flex;align-items:center;justify-content:center;font-size:.65rem;font-weight:600;color:var(--rpt-color-text-muted, #64748b);background:var(--rpt-color-surface, #f1f5f9);border:1px solid var(--rpt-color-border, #e2e8f0);padding:1px 6px;border-radius:9999px;line-height:1.2;white-space:nowrap;-webkit-user-select:none;user-select:none}.card-quick-controls{display:none;align-items:center;gap:3px;flex-shrink:0}.canvas-component-card:hover .span-pill-static,.canvas-component-card.is-selected .span-pill-static,.canvas-component-card:hover .new-row-pill-static,.canvas-component-card.is-selected .new-row-pill-static{display:none}.canvas-component-card:hover .card-quick-controls,.canvas-component-card.is-selected .card-quick-controls{display:inline-flex}.canvas-component-card.is-narrow .card-header{padding:4px 6px;gap:3px}.canvas-component-card.is-narrow:hover .comp-title,.canvas-component-card.is-narrow.is-selected .comp-title,.canvas-component-card.is-narrow:hover .drag-handle-dots,.canvas-component-card.is-narrow.is-selected .drag-handle-dots{display:none}.canvas-component-card.is-narrow .card-quick-controls{gap:2px}.canvas-component-card.is-narrow .span-control-group{height:18px}.canvas-component-card.is-narrow .span-btn{width:14px;height:16px}.canvas-component-card.is-narrow .span-badge{font-size:.6rem;padding:0 2px}.canvas-component-card.is-narrow .span-total{display:none}.canvas-component-card.is-narrow .card-action-btn{width:18px;height:18px}@container (max-width: 250px){.card-header{padding:4px 6px;gap:3px}.canvas-component-card:hover .comp-title,.canvas-component-card.is-selected .comp-title,.canvas-component-card:hover .drag-handle-dots,.canvas-component-card.is-selected .drag-handle-dots,.span-total{display:none}.card-quick-controls{gap:2px}.card-action-btn{width:18px;height:18px}.span-control-group{height:18px}.span-btn{width:14px;height:16px}.span-badge{font-size:.6rem;padding:0 2px}}@container (max-width: 160px){.canvas-component-card.is-selected .card-quick-controls{position:absolute;top:-30px;right:0;background:#fff;border:1.5px solid var(--rpt-color-primary, #2563eb);border-radius:6px;padding:2px 4px;gap:3px;box-shadow:0 4px 12px #2563eb2e,0 2px 4px #00000014;z-index:120;white-space:nowrap}}@media (max-width: 900px){.canvas-component-card:hover .comp-title,.canvas-component-card.is-selected .comp-title,.canvas-component-card:hover .drag-handle-dots,.canvas-component-card.is-selected .drag-handle-dots,.canvas-component-card .span-total{display:none}.canvas-component-card.is-selected .card-header{overflow:visible}.canvas-component-card.is-selected .card-quick-controls{position:absolute;top:-30px;right:0;background:#fff;border:1.5px solid var(--rpt-color-primary, #2563eb);border-radius:6px;padding:2px 4px;gap:3px;box-shadow:0 4px 12px #2563eb2e,0 2px 4px #00000014;z-index:120;white-space:nowrap}}.span-control-group{display:inline-flex;align-items:center;background:#fff;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:4px;height:20px;padding:0 1px;white-space:nowrap;flex-shrink:0}.span-btn{width:16px;height:18px;display:inline-flex;align-items:center;justify-content:center;border:none;background:transparent;padding:0;color:var(--rpt-color-text-muted, #64748b);cursor:pointer;border-radius:2px;transition:all .12s ease}.span-btn:hover:not(:disabled){background:var(--rpt-color-surface-hover, #f1f5f9);color:var(--rpt-color-primary, #2563eb)}.span-btn:disabled{opacity:.3;cursor:not-allowed}.span-badge{font-size:.65rem;font-weight:600;color:var(--rpt-color-text, #0f172a);padding:0 3px;white-space:nowrap;-webkit-user-select:none;user-select:none;line-height:1}.span-total{font-size:.6rem;color:var(--rpt-color-text-muted, #64748b);font-weight:500}.card-action-btn{width:20px;height:20px;border:none;background:transparent;border-radius:4px;display:inline-flex;align-items:center;justify-content:center;padding:0;cursor:pointer;color:var(--rpt-color-text-muted, #64748b);transition:all .12s ease;flex-shrink:0}.card-action-btn:hover{background:#e2e8f0;color:var(--rpt-color-text, #0f172a)}.card-action-btn.btn-active-toggle{background:#7c3aed;color:#fff;border-color:#7c3aed}.card-action-btn.btn-active-toggle:hover{background:#6d28d9;color:#fff}.btn-delete:hover{background:#fee2e2;color:#ef4444}.card-body{padding:8px 10px 14px;flex:1;display:flex;flex-direction:column;min-height:0;min-width:0;max-width:100%;box-sizing:border-box;overflow:visible}.mock-input-field{display:flex;flex-direction:column;gap:4px;flex:1;height:100%;min-height:0}.mock-label{font-size:.7rem;font-weight:600;color:var(--rpt-color-text-muted, #475569);flex-shrink:0}.mock-input-box,.mock-select-box{border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:6px;padding:6px 12px;font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text-muted, #94a3b8);background:#fff;flex:1;min-height:38px;height:100%;display:flex;align-items:center;justify-content:space-between;box-sizing:border-box}.mock-checkbox-field{display:flex;align-items:center;gap:6px;flex:1;height:100%;min-height:0;padding-top:14px}.mock-check-box{width:18px;height:18px;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:4px;display:flex;align-items:center;justify-content:center;font-size:.65rem;color:var(--rpt-color-primary, #2563eb);flex-shrink:0}.mock-btn-wrapper{display:flex;flex:1;height:100%;min-height:38px;align-items:center;justify-content:flex-start;width:100%;min-width:0;box-sizing:border-box}.mock-btn{border-radius:var(--rpt-border-radius, 6px);padding:0 16px;height:36px;font-size:var(--rpt-font-size-base, .875rem);font-weight:500;border:1px solid transparent;cursor:pointer;width:auto;max-width:100%;display:inline-flex;align-items:center;justify-content:center;gap:6px;box-sizing:border-box;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:all .15s ease}.mock-btn.mock-btn-full{width:100%}.canvas-component-card.is-narrow .mock-btn{padding:0 6px;font-size:.775rem;width:100%;height:34px}.mock-kpi-field{display:flex;flex-direction:column;justify-content:space-between;flex:1;height:100%;min-height:0}.mock-kpi-header{display:flex;align-items:center;justify-content:space-between}.mock-kpi-value{font-size:1.25rem;font-weight:700;color:var(--rpt-color-text, #0f172a);margin:2px 0}.mock-kpi-footer{display:flex;align-items:center;gap:6px;font-size:.65rem}.mock-kpi-trend{color:#16a34a;font-weight:600}.mock-kpi-sub{color:#64748b}.mock-chart-field{display:flex;flex-direction:column;flex:1;height:100%;min-height:140px}.mock-chart-bars{display:flex;align-items:flex-end;justify-content:space-around;gap:16px;flex:1;min-height:100px;padding-top:12px;box-sizing:border-box}.mock-chart-col{flex:1;display:flex;flex-direction:column;align-items:center;height:100%;min-width:60px;max-width:140px}.mock-chart-bar{width:38px;max-width:44px;margin:0 auto;background:var(--rpt-color-primary, #2563eb);border-radius:6px 6px 0 0;opacity:.85;min-height:10px;transition:height .2s ease}.mock-bar-lbl{font-size:.6875rem;color:#64748b;margin-top:6px;text-align:center;white-space:normal;line-height:1.2}.btn-primary{background:var(--rpt-color-primary, #2563eb);color:#fff}.btn-secondary{background:#f1f5f9;color:#0f172a;border:1px solid #cbd5e1}.btn-outline{background:transparent;color:#2563eb;border:1px solid #2563eb}.btn-danger{background:#ef4444;color:#fff}.mock-generic-box{border:1px dashed #cbd5e1;border-radius:4px;padding:8px;font-size:.75rem;text-align:center;color:#64748b}.canvas-drag-placeholder{background:#2563eb0f;border:2px dashed var(--rpt-color-primary, #2563eb);border-radius:6px;min-height:80px;box-sizing:border-box;transition:transform .15s ease}.canvas-drag-preview,::ng-deep .canvas-drag-preview{background:#fff;border:2px solid var(--rpt-color-primary, #2563eb);border-radius:6px;padding:8px 14px;display:inline-flex;align-items:center;gap:8px;font-family:var(--rpt-font-family, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif)!important;font-size:.8rem;font-weight:600;color:var(--rpt-color-text, #0f172a);box-shadow:0 12px 24px -4px #00000040;z-index:10000}.preview-title,::ng-deep .preview-title{font-family:inherit!important;max-width:160px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.preview-span,::ng-deep .preview-span{font-family:inherit!important;font-size:.65rem;font-weight:600;color:var(--rpt-color-primary, #2563eb);background:#eff6ff;border:1px solid #bfdbfe;padding:1px 6px;border-radius:9999px}.canvas-empty-state{grid-column:1 / -1;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:56px 28px;border:2px dashed var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius-xl, 12px);background:var(--rpt-color-surface, #ffffff);text-align:center;box-shadow:var(--rpt-box-shadow-xs, 0 1px 2px 0 rgba(0, 0, 0, .04));transition:border-color var(--rpt-transition-speed, .15s) ease}.canvas-empty-state:hover{border-color:var(--rpt-color-primary, #2563eb)}.empty-hero-badge{width:56px;height:56px;border-radius:var(--rpt-border-radius-xl, 12px);background:var(--rpt-color-primary-light, #eff6ff);color:var(--rpt-color-primary, #2563eb);display:flex;align-items:center;justify-content:center;margin-bottom:16px;box-shadow:0 2px 8px #2563eb1f}.empty-hero-title{font-size:var(--rpt-font-size-lg, 1.125rem);font-weight:700;color:var(--rpt-color-text, #0f172a);margin:0 0 8px;letter-spacing:-.01em}.empty-hero-desc{font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text-muted, #64748b);max-width:520px;line-height:1.5;margin:0 0 24px}.empty-hero-actions{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:10px}.empty-btn{display:inline-flex;align-items:center;gap:7px;padding:8px 16px;font-size:var(--rpt-font-size-sm, .75rem);font-weight:600;border-radius:var(--rpt-border-radius, 6px);cursor:pointer;transition:all var(--rpt-transition-speed, .15s) ease;font-family:inherit}.empty-btn-primary{background:var(--rpt-color-primary, #2563eb);color:#fff;border:1px solid var(--rpt-color-primary, #2563eb);box-shadow:0 1px 3px #2563eb33}.empty-btn-primary:hover{background:var(--rpt-color-primary-hover, #1d4ed8);border-color:var(--rpt-color-primary-hover, #1d4ed8);transform:translateY(-1px)}.empty-btn-secondary{background:#f8fafc;color:#334155;border:1px solid var(--rpt-color-border, #cbd5e1)}.empty-btn-secondary:hover{background:#f1f5f9;color:#0f172a;border-color:#94a3b8;transform:translateY(-1px)}.empty-btn-outline{background:#fff;color:var(--rpt-color-primary, #2563eb);border:1px solid #bfdbfe}.empty-btn-outline:hover{background:#eff6ff;border-color:var(--rpt-color-primary, #2563eb);transform:translateY(-1px)}.canvas-active-input{width:100%;height:32px;padding:4px 8px;font-size:.8125rem;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:4px;outline:none;box-sizing:border-box;background:#fff;color:#0f172a;transition:border-color .15s ease}.canvas-active-input:focus{border-color:var(--rpt-color-primary, #2563eb)}.canvas-active-checkbox-lbl{display:inline-flex;align-items:center;gap:6px;cursor:pointer}.canvas-live-control-wrapper{width:100%;max-width:100%;min-width:0;position:relative;z-index:1;box-sizing:border-box}.canvas-grid-box{margin-top:24px;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:8px;background:#fff;box-shadow:0 1px 3px #0000000d;overflow:hidden}.grid-preview-header{display:flex;align-items:center;justify-content:space-between;padding:10px 16px;background:var(--rpt-color-surface, #f8fafc);border-bottom:1px solid var(--rpt-color-border, #cbd5e1);font-size:.8rem;font-weight:600;color:var(--rpt-color-text, #0f172a)}.grid-title{font-weight:700}.grid-exec-badge{font-size:.6875rem;font-weight:600;padding:2px 8px;border-radius:10px}.grid-exec-badge.is-loading{background:#eff6ff;color:#2563eb}.grid-exec-badge.is-error{background:#fee2e2;color:#ef4444}.grid-exec-badge.is-success{background:#ecfdf5;color:#059669}.btn-canvas-run-grid{display:inline-flex;align-items:center;gap:5px;padding:4px 10px;font-size:.72rem;font-weight:600;color:#fff;background:var(--rpt-color-primary, #2563eb);border:none;border-radius:4px;cursor:pointer;transition:background .15s ease}.btn-canvas-run-grid:hover:not(:disabled){background:#1d4ed8}.btn-canvas-run-grid:disabled{opacity:.6;cursor:not-allowed}.btn-canvas-edit-grid{display:inline-flex;align-items:center;gap:4px;padding:4px 8px;font-size:.72rem;font-weight:500;color:#334155;background:#fff;border:1px solid #cbd5e1;border-radius:4px;cursor:pointer;transition:all .12s ease}.btn-canvas-edit-grid:hover{background:#f1f5f9}.canvas-live-grid-container{width:100%;min-height:480px;background:#fff}.live-mode-badge{display:inline-flex;align-items:center;gap:4px;font-size:.6875rem;font-weight:700;color:#047857;background:#ecfdf5;border:1px solid #a7f3d0;padding:1px 8px;border-radius:9999px}.canvas-component-card.is-field-highlighted{border-color:#f59e0b!important;box-shadow:0 0 0 3px #f59e0b59!important;animation:rpt-pulse-border 1s ease-in-out infinite alternate}@keyframes rpt-pulse-border{0%{box-shadow:0 0 0 2px #f59e0b40}to{box-shadow:0 0 0 5px #f59e0b80}}.grid-layout-status-strip{display:flex;align-items:center;justify-content:space-between;padding:6px 16px;background:#f1f5f9;border-bottom:1px solid var(--rpt-color-border, #cbd5e1);font-size:.6875rem;color:#475569}.grid-status-info{display:inline-flex;align-items:center;gap:6px;font-weight:600}.grid-status-sync{display:inline-flex;align-items:center;gap:4px;color:#059669;font-weight:600;transition:transform .2s ease}.grid-status-sync.is-pulsing{transform:scale(1.08);color:#047857}.canvas-actions{display:flex;align-items:center;gap:8px}.btn-grid-add{background:#f0fdf4;border-color:#bbf7d0;color:#16a34a}.btn-grid-add:hover{background:#dcfce7;border-color:#86efac;color:#15803d}.btn-remove-grid{display:inline-flex;align-items:center;justify-content:center;padding:4px;border:none;background:transparent;color:#94a3b8;border-radius:4px;cursor:pointer;transition:all .15s ease}.btn-remove-grid:hover{background:#fee2e2;color:#ef4444}.canvas-add-grid-banner{margin-top:24px;border:2px dashed #cbd5e1;border-radius:8px;background:#fff;padding:16px 20px;display:flex;align-items:center;gap:16px;cursor:pointer;transition:all .15s ease}.canvas-add-grid-banner:hover{border-color:#2563eb;background:#f8fafc;box-shadow:0 2px 8px #2563eb14}.add-grid-icon{width:40px;height:40px;border-radius:8px;background:#eff6ff;color:#2563eb;display:flex;align-items:center;justify-content:center;flex-shrink:0}.add-grid-text{display:flex;flex-direction:column;gap:2px;flex:1}.add-grid-title{font-size:.875rem;font-weight:600;color:#0f172a}.add-grid-sub{font-size:.75rem;color:#64748b}.btn-banner-add{padding:6px 14px;font-size:.75rem;font-weight:600;color:#2563eb;background:#eff6ff;border:1px solid #bfdbfe;border-radius:6px;cursor:pointer;white-space:nowrap;transition:all .15s ease}.canvas-add-grid-banner:hover .btn-banner-add{background:#2563eb;color:#fff;border-color:#2563eb}\n"] }]
|
|
466
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: " <div class=\"canvas-wrapper\" (click)=\"onCanvasBackgroundClick($event)\">\n <!-- Canvas Status / Quick Controls -->\n <div class=\"canvas-toolbar\">\n <div class=\"canvas-info\">\n <span class=\"info-label\">Grid Layout:</span>\n <span class=\"info-value\">{{ totalColumns() }} Columns</span>\n <span class=\"info-divider\">\u2022</span>\n <span class=\"info-label\">Components:</span>\n <span class=\"info-value\">{{ components().length }}</span>\n <span class=\"info-divider\">\u2022</span>\n <span class=\"live-mode-badge\" title=\"Interactive canvas: Values typed here run live queries and test dropdowns.\">\n \u26A1 Live Interactive Mode\n </span>\n </div>\n\n <div class=\"canvas-actions\">\n @if (!definition().grid) {\n <button\n type=\"button\"\n class=\"canvas-action-btn btn-grid-add\"\n (click)=\"addResultGrid($event)\"\n title=\"Add a Result Grid to this report\"\n >\n <rpt-icon name=\"table\" [size]=\"14\" />\n <span>+ Add Grid</span>\n </button>\n } @else {\n <button\n type=\"button\"\n class=\"canvas-action-btn btn-grid-configured\"\n (click)=\"selectGridSettings($event)\"\n title=\"Configure Result Data Grid\"\n >\n <rpt-icon name=\"table\" [size]=\"14\" />\n <span>Grid ({{ definition().grid?.columns?.length ?? 0 }})</span>\n </button>\n }\n\n <button\n type=\"button\"\n class=\"canvas-action-btn\"\n (click)=\"selectReportSettings($event)\"\n title=\"Configure Page Layout & Grid Settings\"\n >\n <rpt-icon name=\"settings\" [size]=\"14\" />\n <span>Report Settings</span>\n </button>\n </div>\n </div>\n\n <!-- Canvas Drop Area -->\n <div class=\"canvas-scroll-area\">\n <div\n class=\"canvas-artboard\"\n [style.padding.px]=\"definition().layout.padding ?? 24\"\n >\n <!-- Report Header Preview -->\n <div class=\"canvas-report-header\">\n <h2 class=\"canvas-report-title\">{{ definition().name || 'Untitled Report' }}</h2>\n @if (definition().description) {\n <p class=\"canvas-report-desc\">{{ definition().description }}</p>\n }\n </div>\n\n <!-- Component Drop List Grid with 2D mixed orientation and data binding -->\n <div\n cdkDropList\n id=\"designer-canvas-drop-list\"\n class=\"canvas-grid\"\n cdkDropListOrientation=\"mixed\"\n [cdkDropListData]=\"sortedComponents()\"\n [style.grid-template-columns]=\"gridTemplateColumns()\"\n [style.gap.px]=\"definition().layout.gap ?? 16\"\n (cdkDropListDropped)=\"onDrop($event)\"\n >\n @for (comp of sortedComponents(); track comp.id; let idx = $index) {\n <div\n cdkDrag\n [cdkDragData]=\"comp\"\n [cdkDragDisabled]=\"isAnyResizing()\"\n class=\"canvas-component-card\"\n [class.is-selected]=\"isSelected(comp.id)\"\n [class.is-resizing]=\"resizingCompId() === comp.id\"\n [class.is-field-highlighted]=\"isFieldHighlighted(comp)\"\n [class.is-narrow]=\"getSpan(comp) <= 4\"\n [class.is-compact]=\"getSpan(comp) <= 2\"\n [style.grid-column]=\"getGridColumn(comp)\"\n [style.grid-row]=\"getGridRow(comp)\"\n [style.width]=\"comp.layout?.width || 'auto'\"\n [style.height]=\"getComponentHeight(comp)\"\n [style.min-height]=\"getComponentMinHeight(comp)\"\n (click)=\"onSelect(comp.id, $event)\"\n >\n <!-- Card Header with Drag Handle & Actions -->\n <div class=\"card-header\">\n <div class=\"card-title-group\" cdkDragHandle title=\"Drag to reorder\">\n <span class=\"drag-handle-dots\">\u22EE\u22EE</span>\n <rpt-icon [name]=\"getComponentIconName(comp.type)\" [size]=\"14\" />\n <span class=\"comp-title\" [title]=\"comp.label || comp.key || comp.type\">\n {{ comp.label || comp.key || comp.type }}\n </span>\n </div>\n\n <div class=\"card-actions\">\n <!-- Static span pill & new row / start col pill when not hovered / not selected -->\n @if (comp.layout?.column; as col) {\n <span class=\"new-row-pill-static\" title=\"Starts at Column {{ col }}\">Col {{ col }}</span>\n } @else if (comp.layout?.newRow) {\n <span class=\"new-row-pill-static\" title=\"Starts on separate row\">\u21B3 Row</span>\n }\n <span\n class=\"span-pill-static\"\n title=\"Column span: {{ getSpan(comp) }} of {{ totalColumns() }} columns\"\n >\n {{ getSpan(comp) }}/{{ totalColumns() }}\n </span>\n\n <!-- Quick Action Stepper & Buttons (revealed on hover or selection) -->\n <div class=\"card-quick-controls\">\n <button\n type=\"button\"\n class=\"card-action-btn\"\n [class.btn-active-toggle]=\"comp.layout?.newRow\"\n (click)=\"toggleNewRow(comp, $event)\"\n title=\"{{ comp.layout?.newRow ? 'Starts on new row (Click to place inline)' : 'Start on separate row (Row Break)' }}\"\n >\n <rpt-icon name=\"corner-down-right\" [size]=\"11\" />\n </button>\n\n <div class=\"span-control-group\" title=\"Adjust Column Span\">\n <button\n type=\"button\"\n class=\"span-btn\"\n [disabled]=\"getSpan(comp) <= 1\"\n (click)=\"adjustSpan(comp, -1, $event)\"\n title=\"Shrink Column Span\"\n >\n <rpt-icon name=\"minus\" [size]=\"9\" />\n </button>\n <span class=\"span-badge\" [title]=\"'Column span: ' + getSpan(comp) + ' of ' + totalColumns()\">\n <span class=\"span-num\">{{ getSpan(comp) }}</span><span class=\"span-total\">/{{ totalColumns() }}</span>\n </span>\n <button\n type=\"button\"\n class=\"span-btn\"\n [disabled]=\"getSpan(comp) >= totalColumns()\"\n (click)=\"adjustSpan(comp, 1, $event)\"\n title=\"Expand Column Span\"\n >\n <rpt-icon name=\"plus\" [size]=\"9\" />\n </button>\n </div>\n\n <button\n type=\"button\"\n class=\"card-action-btn\"\n (click)=\"onDuplicate(comp.id, $event)\"\n title=\"Duplicate component\"\n >\n <rpt-icon name=\"copy\" [size]=\"12\" />\n </button>\n <button\n type=\"button\"\n class=\"card-action-btn btn-delete\"\n (click)=\"onDelete(comp.id, $event)\"\n title=\"Remove component\"\n >\n <rpt-icon name=\"trash\" [size]=\"12\" />\n </button>\n </div>\n </div>\n </div>\n\n <!-- Card Body Visual Preview -->\n <div class=\"card-body\">\n\n @switch (comp.type) {\n @case ('input') {\n <div class=\"mock-input-field\" (click)=\"onControlInteract(comp, $event)\">\n <span class=\"mock-label\">{{ comp.label || 'Input' }}</span>\n @if (getCanvasControl(comp); as ctrl) {\n <input\n type=\"text\"\n class=\"canvas-active-input\"\n [placeholder]=\"comp.properties?.['placeholder'] || 'Enter text...'\"\n [formControl]=\"ctrl\"\n (focus)=\"onControlInteract(comp, $event)\"\n />\n } @else {\n <div class=\"mock-input-box\">{{ comp.properties?.['placeholder'] || 'Enter text...' }}</div>\n }\n </div>\n }\n @case ('dropdown') {\n <div class=\"canvas-live-control-wrapper\" (click)=\"onControlInteract(comp, $event)\">\n <rpt-dropdown\n [config]=\"comp\"\n [showStatus]=\"true\"\n [parentForm]=\"canvasForm()\"\n [control]=\"getCanvasControl(comp)\"\n />\n </div>\n }\n @case ('date') {\n <div class=\"mock-input-field\" (click)=\"onControlInteract(comp, $event)\">\n <span class=\"mock-label\">{{ comp.label || 'Date' }}</span>\n @if (getCanvasControl(comp); as ctrl) {\n <input\n type=\"date\"\n class=\"canvas-active-input\"\n [formControl]=\"ctrl\"\n (focus)=\"onControlInteract(comp, $event)\"\n />\n } @else {\n <div class=\"mock-select-box\">\n <span>YYYY-MM-DD</span>\n <rpt-icon name=\"calendar\" [size]=\"12\" />\n </div>\n }\n </div>\n }\n @case ('date-range') {\n <div class=\"canvas-live-control-wrapper\" (click)=\"onControlInteract(comp, $event)\">\n <rpt-date-range\n [config]=\"comp\"\n [control]=\"getCanvasControl(comp)\"\n />\n </div>\n }\n @case ('number') {\n <div class=\"mock-input-field\" (click)=\"onControlInteract(comp, $event)\">\n <span class=\"mock-label\">{{ comp.label || 'Number' }}</span>\n @if (getCanvasControl(comp); as ctrl) {\n <input\n type=\"number\"\n class=\"canvas-active-input\"\n [formControl]=\"ctrl\"\n (focus)=\"onControlInteract(comp, $event)\"\n />\n } @else {\n <div class=\"mock-input-box\">\n {{ comp.properties?.['prefix'] || '' }} 0.00 {{ comp.properties?.['suffix'] || '' }}\n </div>\n }\n </div>\n }\n @case ('checkbox') {\n <div class=\"mock-checkbox-field\" (click)=\"onControlInteract(comp, $event)\">\n @if (getCanvasControl(comp); as ctrl) {\n <label class=\"canvas-active-checkbox-lbl\">\n <input type=\"checkbox\" [formControl]=\"ctrl\" (focus)=\"onControlInteract(comp, $event)\" />\n <span class=\"mock-label\">{{ comp.label || 'Checkbox' }}</span>\n </label>\n } @else {\n <span class=\"mock-check-box\">\n <rpt-icon name=\"check\" [size]=\"10\" />\n </span>\n <span class=\"mock-label\">{{ comp.label || 'Checkbox' }}</span>\n }\n </div>\n }\n @case ('button') {\n <div class=\"mock-btn-wrapper\">\n <button\n type=\"button\"\n class=\"mock-btn\"\n [class]=\"'btn-' + (comp.properties?.['variant'] || 'primary')\"\n [class.mock-btn-full]=\"comp.properties?.['fullWidth'] === true || comp.layout?.width === '100%'\"\n [style.height]=\"getCustomBtnHeight(comp)\"\n [style.width]=\"getCustomBtnWidth(comp)\"\n (click)=\"onCanvasButtonClick(comp, $event)\"\n >\n @if (getCustomBtnIcon(comp); as btnIcon) {\n <rpt-icon [name]=\"btnIcon\" [size]=\"15\" />\n }\n <span>{{ comp.label || 'Button' }}</span>\n </button>\n </div>\n }\n @case ('kpi-card') {\n <div class=\"mock-kpi-field\">\n <div class=\"mock-kpi-header\">\n <span class=\"mock-label\">{{ comp.label || 'KPI Metric' }}</span>\n <rpt-icon name=\"kpi\" [size]=\"14\" />\n </div>\n <div class=\"mock-kpi-value\">{{ comp.properties?.['value'] || '$128,450' }}</div>\n <div class=\"mock-kpi-footer\">\n <span class=\"mock-kpi-trend\">+12.5%</span>\n <span class=\"mock-kpi-sub\">vs last period</span>\n </div>\n </div>\n }\n @case ('chart') {\n <div class=\"mock-chart-field\">\n <div class=\"mock-chart-header\">\n <span class=\"mock-label\">{{ comp.label || 'Quarterly Sales Revenue ($000)' }}</span>\n </div>\n <div class=\"mock-chart-bars\">\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 44%\"></div>\n <span class=\"mock-bar-lbl\">Q1 Jan-Mar</span>\n </div>\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 61%\"></div>\n <span class=\"mock-bar-lbl\">Q2 Apr-Jun</span>\n </div>\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 79%\"></div>\n <span class=\"mock-bar-lbl\">Q3 Jul-Sep</span>\n </div>\n <div class=\"mock-chart-col\">\n <div class=\"mock-chart-bar\" style=\"height: 100%\"></div>\n <span class=\"mock-bar-lbl\">Q4 Oct-Dec</span>\n </div>\n </div>\n </div>\n }\n @default {\n <div class=\"mock-generic-box\">\n <span>{{ comp.type }}</span>\n </div>\n }\n }\n </div>\n\n <!-- Resizing Handles (East, South, South-East) -->\n <div\n class=\"resize-handle handle-e\"\n (pointerdown)=\"startResize($event, comp, 'e')\"\n (dblclick)=\"resetDimensions(comp, $event)\"\n title=\"Drag to resize column width \u2022 Double-click to reset\"\n ></div>\n <div\n class=\"resize-handle handle-s\"\n (pointerdown)=\"startResize($event, comp, 's')\"\n (dblclick)=\"resetDimensions(comp, $event)\"\n title=\"Drag to resize height \u2022 Double-click to reset\"\n ></div>\n <div\n class=\"resize-handle handle-se\"\n (pointerdown)=\"startResize($event, comp, 'se')\"\n (dblclick)=\"resetDimensions(comp, $event)\"\n title=\"Drag to resize width and height \u2022 Double-click to reset\"\n ></div>\n\n <!-- Resizing Dimension Ghost / Badge -->\n @if (resizingCompId() === comp.id) {\n <div class=\"resize-dimension-tooltip\">\n {{ resizingTooltip(comp) }}\n </div>\n }\n\n <!-- Drag placeholder with matched grid column span -->\n <div\n *cdkDragPlaceholder\n class=\"canvas-drag-placeholder\"\n [style.grid-column]=\"getGridColumn(comp)\"\n ></div>\n\n <!-- Drag preview -->\n <div *cdkDragPreview class=\"canvas-drag-preview\">\n <span class=\"drag-handle-dots\">\u22EE\u22EE</span>\n <rpt-icon [name]=\"getComponentIconName(comp.type)\" [size]=\"14\" />\n <span class=\"preview-title\">{{ comp.label || comp.key || comp.type }}</span>\n <span class=\"preview-span\">{{ getSpan(comp) }}/{{ totalColumns() }}</span>\n </div>\n </div>\n }\n\n @if (components().length === 0) {\n <div class=\"canvas-empty-state\" role=\"region\" aria-label=\"Empty canvas starter options\">\n <div class=\"empty-hero-badge\">\n <rpt-icon name=\"design\" [size]=\"28\" />\n </div>\n <h3 class=\"empty-hero-title\">Start Designing Your Custom Report</h3>\n <p class=\"empty-hero-desc\">\n Drag controls from the left component palette, or jumpstart your design with pre-configured enterprise blueprints.\n </p>\n\n <div class=\"empty-hero-actions\">\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-primary\"\n (click)=\"applyBlueprint('blueprint-audit-register')\"\n title=\"Load complete Audit Register blueprint with parameters and result grid\"\n >\n <rpt-icon name=\"table\" [size]=\"15\" />\n <span>Audit Register Blueprint</span>\n </button>\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-secondary\"\n (click)=\"applyBlueprint('blueprint-kpi-summary')\"\n title=\"Load Executive KPI summary blueprint\"\n >\n <rpt-icon name=\"chart-bar\" [size]=\"15\" />\n <span>KPI Summary Blueprint</span>\n </button>\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-outline\"\n (click)=\"addStarterComponent('date-range')\"\n title=\"Add a Date Range filter component\"\n >\n <rpt-icon name=\"calendar\" [size]=\"14\" />\n <span>+ Add Date Filter</span>\n </button>\n <button\n type=\"button\"\n class=\"empty-btn empty-btn-outline\"\n (click)=\"addStarterComponent('button')\"\n title=\"Add an Execute Action button\"\n >\n <rpt-icon name=\"play\" [size]=\"14\" />\n <span>+ Add Run Button</span>\n </button>\n </div>\n </div>\n }\n </div>\n\n <!-- Live Result Grid Preview with Bways-Grid Features -->\n @if (definition().grid) {\n <div class=\"canvas-grid-box\">\n <div class=\"grid-preview-header\">\n <div style=\"display: flex; align-items: center; gap: 8px;\">\n <rpt-icon name=\"table\" [size]=\"15\" />\n <span class=\"grid-title\">Bways Grid ({{ definition().grid?.columns?.length ?? 0 }} columns)</span>\n @if (isExecutingGrid()) {\n <span class=\"grid-exec-badge is-loading\">Loading data from database...</span>\n } @else if (gridExecError()) {\n <span class=\"grid-exec-badge is-error\">{{ gridExecError() }}</span>\n } @else if (canvasGridData().length > 0) {\n <span class=\"grid-exec-badge is-success\">{{ canvasGridData().length }} rows loaded</span>\n }\n </div>\n <div style=\"display: flex; align-items: center; gap: 8px;\">\n <button\n type=\"button\"\n class=\"btn-canvas-run-grid\"\n (click)=\"executeCanvasReport($event)\"\n [disabled]=\"isExecutingGrid()\"\n title=\"Execute query and load data into Bways Grid\"\n >\n <rpt-icon name=\"play\" [size]=\"11\" />\n <span>{{ isExecutingGrid() ? 'Running...' : 'Run / Refresh Grid' }}</span>\n </button>\n <button\n type=\"button\"\n class=\"btn-canvas-edit-grid\"\n (click)=\"selectGridSettings($event)\"\n title=\"Configure columns and grid options\"\n >\n <rpt-icon name=\"settings\" [size]=\"11\" />\n <span>Configure</span>\n </button>\n <button\n type=\"button\"\n class=\"btn-remove-grid\"\n (click)=\"removeGrid($event)\"\n title=\"Remove Result Grid from this report\"\n >\n <rpt-icon name=\"trash\" [size]=\"13\" />\n </button>\n </div>\n </div>\n\n @if (getGridSummaryText(); as summary) {\n <div class=\"grid-layout-status-strip\">\n <div class=\"grid-status-info\">\n <rpt-icon name=\"table\" [size]=\"12\" />\n <span>{{ summary }}</span>\n </div>\n <div class=\"grid-status-sync\" [class.is-pulsing]=\"layoutJustUpdated()\">\n <rpt-icon name=\"check\" [size]=\"11\" />\n <span>Layout auto-persisted</span>\n </div>\n </div>\n }\n\n <!-- Live Bways Grid bridge -->\n <div class=\"canvas-live-grid-container\" (click)=\"$event.stopPropagation()\" style=\"position: relative; min-height: 250px;\">\n @if (isExecutingGrid()) {\n <div class=\"canvas-grid-loading-overlay\">\n <span class=\"status-dot dot-pulse\" style=\"width: 14px; height: 14px; color: #2563eb; background: #2563eb; border-radius: 50%;\"></span>\n <span class=\"grid-loading-title\">Executing stored procedure on SQL Server...</span>\n <span class=\"grid-loading-sub\">Calculating outstanding balances and ledger amounts. Please wait...</span>\n </div>\n }\n <rpt-grid-bridge\n [gridDefinition]=\"definition().grid!\"\n [data]=\"canvasGridData()\"\n (gridStateChange)=\"onCanvasGridStateChange($event)\"\n (columnDefsChange)=\"onCanvasColumnDefsChange($event)\"\n />\n </div>\n </div>\n } @else {\n <div class=\"canvas-add-grid-banner\" (click)=\"addResultGrid($event)\">\n <div class=\"add-grid-icon\">\n <rpt-icon name=\"table\" [size]=\"20\" />\n </div>\n <div class=\"add-grid-text\">\n <span class=\"add-grid-title\">+ Add Result Data Grid</span>\n <span class=\"add-grid-sub\">Attach an interactive data table or UltraGrid to display report execution output</span>\n </div>\n <button type=\"button\" class=\"btn-banner-add\">Add Grid</button>\n </div>\n }\n </div>\n </div>\n </div>", styles: [":host{display:block;height:100%;background-color:#f1f5f9;font-family:var(--rpt-font-family, inherit);box-sizing:border-box}.canvas-wrapper{display:flex;flex-direction:column;height:100%}.canvas-toolbar{display:flex;align-items:center;justify-content:space-between;min-height:42px;height:42px;padding:0 24px;background:var(--rpt-color-surface, #ffffff);border-bottom:1px solid var(--rpt-color-border, #cbd5e1);box-sizing:border-box;gap:12px;overflow-x:auto;scrollbar-width:none;font-family:var(--rpt-font-family, inherit);flex-shrink:0}.canvas-toolbar::-webkit-scrollbar{display:none}.canvas-info{display:flex;align-items:center;gap:8px;font-family:var(--rpt-font-family, inherit);font-size:var(--rpt-font-size-sm, .75rem);color:var(--rpt-color-text-muted, #64748b);white-space:nowrap;line-height:1}.info-label{color:var(--rpt-color-text-muted, #64748b);font-weight:500;font-size:var(--rpt-font-size-sm, .75rem)}.info-value{font-weight:600;color:var(--rpt-color-text, #0f172a);font-size:var(--rpt-font-size-sm, .75rem)}.info-divider{color:var(--rpt-color-border, #cbd5e1);margin:0 2px}.live-mode-badge{display:inline-flex;align-items:center;gap:4px;font-family:var(--rpt-font-family, inherit);font-size:var(--rpt-font-size-xs, .7rem);font-weight:600;color:#047857;background:#ecfdf5;border:1px solid #a7f3d0;padding:2px 8px;border-radius:9999px;line-height:1}.canvas-actions{display:flex;align-items:center;gap:8px;white-space:nowrap}.canvas-action-btn{display:inline-flex;align-items:center;gap:6px;height:28px;padding:0 10px;font-family:var(--rpt-font-family, inherit);font-size:var(--rpt-font-size-sm, .75rem);font-weight:500;letter-spacing:-.01em;color:var(--rpt-color-text-secondary, #334155);background:var(--rpt-color-surface, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);cursor:pointer;line-height:1;white-space:nowrap;box-shadow:0 1px 2px #0000000a;transition:all var(--rpt-transition-speed, .15s) ease}.canvas-action-btn:hover{background:var(--rpt-color-surface-hover, #f8fafc);border-color:var(--rpt-color-border-hover, #94a3b8);color:var(--rpt-color-text, #0f172a);box-shadow:0 2px 4px #0000000f}.canvas-action-btn.btn-grid-configured{background:#eff6ff;border-color:#bfdbfe;color:#2563eb;font-weight:600}.canvas-action-btn.btn-grid-configured:hover{background:#dbeafe;color:#1d4ed8;border-color:#93c5fd}.canvas-action-btn.btn-grid-add{background:#f0fdf4;border-color:#bbf7d0;color:#16a34a;font-weight:600}.canvas-action-btn.btn-grid-add:hover{background:#dcfce7;color:#15803d;border-color:#86efac}.canvas-action-btn:active{transform:translateY(1px)}.canvas-scroll-area{flex:1;overflow-y:auto;padding:16px}.canvas-artboard{width:100%;max-width:1400px;margin:0 auto;background:#fff;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius-lg, 8px);box-shadow:0 4px 6px -1px #0000000d;min-height:480px;box-sizing:border-box}@media (max-width: 900px){.canvas-toolbar{min-height:36px;height:36px;padding:0 10px;gap:6px}.live-mode-badge{display:none}.canvas-info{font-size:.75rem;gap:5px}.canvas-action-btn{padding:0 8px;font-size:.725rem;height:28px;gap:4px}.canvas-scroll-area{padding:10px}.canvas-artboard{min-height:360px}}@media (max-width: 600px){.canvas-toolbar{padding:0 8px;gap:4px}.canvas-info .info-label,.canvas-action-btn span{display:none}.canvas-action-btn{padding:0 6px;min-width:28px;justify-content:center}}.canvas-report-header{margin-bottom:24px;padding-bottom:16px;border-bottom:1px solid var(--rpt-color-border, #e2e8f0)}.canvas-report-title{font-size:var(--rpt-font-size-xl, 1.5rem);font-weight:700;color:var(--rpt-color-text, #0f172a);margin:0 0 6px}.canvas-report-desc{font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text-muted, #64748b);margin:0}.canvas-grid{display:grid;width:100%;min-height:180px;align-items:start;border-radius:6px;transition:all var(--rpt-transition-speed, .15s) ease}.canvas-component-card{container-type:inline-size;background:#fff;border:1.5px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);box-shadow:var(--rpt-box-shadow, 0 1px 2px rgba(0, 0, 0, .05));box-sizing:border-box;transition:all var(--rpt-transition-speed, .15s) ease;cursor:pointer;position:relative;overflow:visible;display:flex;flex-direction:column;min-height:104px;z-index:1}.canvas-component-card:hover{border-color:var(--rpt-color-primary, #2563eb);box-shadow:0 4px 6px -1px #2563eb1a;z-index:2}.canvas-component-card.is-selected{border-color:var(--rpt-color-primary, #2563eb);box-shadow:0 0 0 2px #2563eb40;z-index:10}.canvas-component-card:focus-within,.canvas-component-card:has(.rpt-combobox-menu),.canvas-component-card:has(.is-open){z-index:100}.canvas-component-card.is-resizing{-webkit-user-select:none;user-select:none;border-color:var(--rpt-color-primary, #2563eb);box-shadow:0 0 0 2px #2563eb59;z-index:30;transition:none!important}.resize-handle{position:absolute;z-index:20;touch-action:none;opacity:0;pointer-events:none;transition:opacity .15s ease}.canvas-component-card.is-selected .resize-handle{opacity:1;pointer-events:auto}.resize-handle.handle-e{top:0;right:0;width:6px;height:100%;cursor:ew-resize;display:flex;align-items:center;justify-content:center}.resize-handle.handle-e:after{content:\"\";width:3px;height:24px;background:#cbd5e1;border-radius:2px;transition:background .15s ease}.resize-handle.handle-e:hover:after,.canvas-component-card.is-selected .resize-handle.handle-e:after{background:var(--rpt-color-primary, #2563eb)}.resize-handle.handle-s{bottom:0;left:0;height:6px;width:100%;cursor:ns-resize;display:flex;align-items:center;justify-content:center}.resize-handle.handle-s:after{content:\"\";height:3px;width:24px;background:#cbd5e1;border-radius:2px;transition:background .15s ease}.resize-handle.handle-s:hover:after,.canvas-component-card.is-selected .resize-handle.handle-s:after{background:var(--rpt-color-primary, #2563eb)}.resize-handle.handle-se{bottom:0;right:0;width:12px;height:12px;cursor:nwse-resize;display:flex;align-items:flex-end;justify-content:flex-end;padding:2px}.resize-handle.handle-se:after{content:\"\";width:5px;height:5px;border-right:2px solid #cbd5e1;border-bottom:2px solid #cbd5e1;transition:border-color .15s ease}.resize-handle.handle-se:hover:after,.canvas-component-card.is-selected .resize-handle.handle-se:after{border-color:var(--rpt-color-primary, #2563eb)}.resize-dimension-tooltip{position:absolute;top:38px;right:8px;background:#0f172ae6;color:#fff;font-size:.7rem;font-weight:600;padding:3px 8px;border-radius:4px;white-space:nowrap;pointer-events:none;z-index:50;box-shadow:0 2px 4px #0003}.card-header{display:flex;align-items:center;justify-content:space-between;gap:6px;padding:5px 8px;background:var(--rpt-color-surface, #f8fafc);border-bottom:1px solid var(--rpt-color-border, #e2e8f0);border-top-left-radius:var(--rpt-border-radius, 6px);border-top-right-radius:var(--rpt-border-radius, 6px);min-height:32px;box-sizing:border-box;overflow:hidden;position:relative}.canvas-component-card.is-selected .card-header{overflow:visible}.card-title-group{display:flex;align-items:center;gap:5px;cursor:grab;min-width:0;flex:1;overflow:hidden}.drag-handle-dots{color:var(--rpt-color-text-muted, #94a3b8);font-size:.85rem;letter-spacing:-2px;flex-shrink:0;-webkit-user-select:none;user-select:none}.comp-title{font-size:.75rem;font-weight:600;color:var(--rpt-color-text, #0f172a);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;-webkit-user-select:none;user-select:none}.card-actions{display:flex;align-items:center;gap:4px;flex-shrink:0;margin-left:auto}.new-row-pill-static{font-size:.65rem;font-weight:600;color:#7c3aed;background:#f5f3ff;border:1px solid #ddd6fe;padding:1px 5px;border-radius:9999px;white-space:nowrap;line-height:1;flex-shrink:0}.span-pill-static{display:inline-flex;align-items:center;justify-content:center;font-size:.65rem;font-weight:600;color:var(--rpt-color-text-muted, #64748b);background:var(--rpt-color-surface, #f1f5f9);border:1px solid var(--rpt-color-border, #e2e8f0);padding:1px 6px;border-radius:9999px;line-height:1.2;white-space:nowrap;-webkit-user-select:none;user-select:none}.card-quick-controls{display:none;align-items:center;gap:3px;flex-shrink:0}.canvas-component-card:hover .span-pill-static,.canvas-component-card.is-selected .span-pill-static,.canvas-component-card:hover .new-row-pill-static,.canvas-component-card.is-selected .new-row-pill-static{display:none}.canvas-component-card:hover .card-quick-controls,.canvas-component-card.is-selected .card-quick-controls{display:inline-flex}.canvas-component-card.is-narrow .card-header{padding:4px 6px;gap:3px}.canvas-component-card.is-narrow:hover .comp-title,.canvas-component-card.is-narrow.is-selected .comp-title,.canvas-component-card.is-narrow:hover .drag-handle-dots,.canvas-component-card.is-narrow.is-selected .drag-handle-dots{display:none}.canvas-component-card.is-narrow .card-quick-controls{gap:2px}.canvas-component-card.is-narrow .span-control-group{height:18px}.canvas-component-card.is-narrow .span-btn{width:14px;height:16px}.canvas-component-card.is-narrow .span-badge{font-size:.6rem;padding:0 2px}.canvas-component-card.is-narrow .span-total{display:none}.canvas-component-card.is-narrow .card-action-btn{width:18px;height:18px}@container (max-width: 250px){.card-header{padding:4px 6px;gap:3px}.canvas-component-card:hover .comp-title,.canvas-component-card.is-selected .comp-title,.canvas-component-card:hover .drag-handle-dots,.canvas-component-card.is-selected .drag-handle-dots,.span-total{display:none}.card-quick-controls{gap:2px}.card-action-btn{width:18px;height:18px}.span-control-group{height:18px}.span-btn{width:14px;height:16px}.span-badge{font-size:.6rem;padding:0 2px}}@container (max-width: 160px){.canvas-component-card.is-selected .card-quick-controls{position:absolute;top:-30px;right:0;background:#fff;border:1.5px solid var(--rpt-color-primary, #2563eb);border-radius:6px;padding:2px 4px;gap:3px;box-shadow:0 4px 12px #2563eb2e,0 2px 4px #00000014;z-index:120;white-space:nowrap}}@media (max-width: 900px){.canvas-component-card:hover .comp-title,.canvas-component-card.is-selected .comp-title,.canvas-component-card:hover .drag-handle-dots,.canvas-component-card.is-selected .drag-handle-dots,.canvas-component-card .span-total{display:none}.canvas-component-card.is-selected .card-header{overflow:visible}.canvas-component-card.is-selected .card-quick-controls{position:absolute;top:-30px;right:0;background:#fff;border:1.5px solid var(--rpt-color-primary, #2563eb);border-radius:6px;padding:2px 4px;gap:3px;box-shadow:0 4px 12px #2563eb2e,0 2px 4px #00000014;z-index:120;white-space:nowrap}}.span-control-group{display:inline-flex;align-items:center;background:#fff;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:4px;height:20px;padding:0 1px;white-space:nowrap;flex-shrink:0}.span-btn{width:16px;height:18px;display:inline-flex;align-items:center;justify-content:center;border:none;background:transparent;padding:0;color:var(--rpt-color-text-muted, #64748b);cursor:pointer;border-radius:2px;transition:all .12s ease}.span-btn:hover:not(:disabled){background:var(--rpt-color-surface-hover, #f1f5f9);color:var(--rpt-color-primary, #2563eb)}.span-btn:disabled{opacity:.3;cursor:not-allowed}.span-badge{font-size:.65rem;font-weight:600;color:var(--rpt-color-text, #0f172a);padding:0 3px;white-space:nowrap;-webkit-user-select:none;user-select:none;line-height:1}.span-total{font-size:.6rem;color:var(--rpt-color-text-muted, #64748b);font-weight:500}.card-action-btn{width:20px;height:20px;border:none;background:transparent;border-radius:4px;display:inline-flex;align-items:center;justify-content:center;padding:0;cursor:pointer;color:var(--rpt-color-text-muted, #64748b);transition:all .12s ease;flex-shrink:0}.card-action-btn:hover{background:#e2e8f0;color:var(--rpt-color-text, #0f172a)}.card-action-btn.btn-active-toggle{background:#7c3aed;color:#fff;border-color:#7c3aed}.card-action-btn.btn-active-toggle:hover{background:#6d28d9;color:#fff}.btn-delete:hover{background:#fee2e2;color:#ef4444}.card-body{padding:8px 10px 14px;flex:1;display:flex;flex-direction:column;min-height:0;min-width:0;max-width:100%;box-sizing:border-box;overflow:visible}.mock-input-field{display:flex;flex-direction:column;gap:4px;flex:1;height:100%;min-height:0}.mock-label{font-size:.7rem;font-weight:600;color:var(--rpt-color-text-muted, #475569);flex-shrink:0}.mock-input-box,.mock-select-box{border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:6px;padding:6px 12px;font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text-muted, #94a3b8);background:#fff;flex:1;min-height:38px;height:100%;display:flex;align-items:center;justify-content:space-between;box-sizing:border-box}.mock-checkbox-field{display:flex;align-items:center;gap:6px;flex:1;height:100%;min-height:0;padding-top:14px}.mock-check-box{width:18px;height:18px;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:4px;display:flex;align-items:center;justify-content:center;font-size:.65rem;color:var(--rpt-color-primary, #2563eb);flex-shrink:0}.mock-btn-wrapper{display:flex;flex:1;height:100%;min-height:38px;align-items:center;justify-content:flex-start;width:100%;min-width:0;box-sizing:border-box}.mock-btn{border-radius:var(--rpt-border-radius, 6px);padding:0 16px;height:36px;font-size:var(--rpt-font-size-base, .875rem);font-weight:500;border:1px solid transparent;cursor:pointer;width:auto;max-width:100%;display:inline-flex;align-items:center;justify-content:center;gap:6px;box-sizing:border-box;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:all .15s ease}.mock-btn.mock-btn-full{width:100%}.canvas-component-card.is-narrow .mock-btn{padding:0 6px;font-size:.775rem;width:100%;height:34px}.mock-kpi-field{display:flex;flex-direction:column;justify-content:space-between;flex:1;height:100%;min-height:0}.mock-kpi-header{display:flex;align-items:center;justify-content:space-between}.mock-kpi-value{font-size:1.25rem;font-weight:700;color:var(--rpt-color-text, #0f172a);margin:2px 0}.mock-kpi-footer{display:flex;align-items:center;gap:6px;font-size:.65rem}.mock-kpi-trend{color:#16a34a;font-weight:600}.mock-kpi-sub{color:#64748b}.mock-chart-field{display:flex;flex-direction:column;flex:1;height:100%;min-height:140px}.mock-chart-bars{display:flex;align-items:flex-end;justify-content:space-around;gap:16px;flex:1;min-height:100px;padding-top:12px;box-sizing:border-box}.mock-chart-col{flex:1;display:flex;flex-direction:column;align-items:center;height:100%;min-width:60px;max-width:140px}.mock-chart-bar{width:38px;max-width:44px;margin:0 auto;background:var(--rpt-color-primary, #2563eb);border-radius:6px 6px 0 0;opacity:.85;min-height:10px;transition:height .2s ease}.mock-bar-lbl{font-size:.6875rem;color:#64748b;margin-top:6px;text-align:center;white-space:normal;line-height:1.2}.btn-primary{background:var(--rpt-color-primary, #2563eb);color:#fff}.btn-secondary{background:#f1f5f9;color:#0f172a;border:1px solid #cbd5e1}.btn-outline{background:transparent;color:#2563eb;border:1px solid #2563eb}.btn-danger{background:#ef4444;color:#fff}.mock-generic-box{border:1px dashed #cbd5e1;border-radius:4px;padding:8px;font-size:.75rem;text-align:center;color:#64748b}.canvas-drag-placeholder{background:#2563eb0f;border:2px dashed var(--rpt-color-primary, #2563eb);border-radius:6px;min-height:80px;box-sizing:border-box;transition:transform .15s ease}.canvas-drag-preview,::ng-deep .canvas-drag-preview{background:#fff;border:2px solid var(--rpt-color-primary, #2563eb);border-radius:6px;padding:8px 14px;display:inline-flex;align-items:center;gap:8px;font-family:var(--rpt-font-family, system-ui, -apple-system, BlinkMacSystemFont, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif)!important;font-size:.8rem;font-weight:600;color:var(--rpt-color-text, #0f172a);box-shadow:0 12px 24px -4px #00000040;z-index:10000}.preview-title,::ng-deep .preview-title{font-family:inherit!important;max-width:160px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.preview-span,::ng-deep .preview-span{font-family:inherit!important;font-size:.65rem;font-weight:600;color:var(--rpt-color-primary, #2563eb);background:#eff6ff;border:1px solid #bfdbfe;padding:1px 6px;border-radius:9999px}.canvas-empty-state{grid-column:1 / -1;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:56px 28px;border:2px dashed var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius-xl, 12px);background:var(--rpt-color-surface, #ffffff);text-align:center;box-shadow:var(--rpt-box-shadow-xs, 0 1px 2px 0 rgba(0, 0, 0, .04));transition:border-color var(--rpt-transition-speed, .15s) ease}.canvas-empty-state:hover{border-color:var(--rpt-color-primary, #2563eb)}.empty-hero-badge{width:56px;height:56px;border-radius:var(--rpt-border-radius-xl, 12px);background:var(--rpt-color-primary-light, #eff6ff);color:var(--rpt-color-primary, #2563eb);display:flex;align-items:center;justify-content:center;margin-bottom:16px;box-shadow:0 2px 8px #2563eb1f}.empty-hero-title{font-size:var(--rpt-font-size-lg, 1.125rem);font-weight:700;color:var(--rpt-color-text, #0f172a);margin:0 0 8px;letter-spacing:-.01em}.empty-hero-desc{font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text-muted, #64748b);max-width:520px;line-height:1.5;margin:0 0 24px}.empty-hero-actions{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:10px}.empty-btn{display:inline-flex;align-items:center;gap:7px;padding:8px 16px;font-size:var(--rpt-font-size-sm, .75rem);font-weight:600;border-radius:var(--rpt-border-radius, 6px);cursor:pointer;transition:all var(--rpt-transition-speed, .15s) ease;font-family:inherit}.empty-btn-primary{background:var(--rpt-color-primary, #2563eb);color:#fff;border:1px solid var(--rpt-color-primary, #2563eb);box-shadow:0 1px 3px #2563eb33}.empty-btn-primary:hover{background:var(--rpt-color-primary-hover, #1d4ed8);border-color:var(--rpt-color-primary-hover, #1d4ed8);transform:translateY(-1px)}.empty-btn-secondary{background:#f8fafc;color:#334155;border:1px solid var(--rpt-color-border, #cbd5e1)}.empty-btn-secondary:hover{background:#f1f5f9;color:#0f172a;border-color:#94a3b8;transform:translateY(-1px)}.empty-btn-outline{background:#fff;color:var(--rpt-color-primary, #2563eb);border:1px solid #bfdbfe}.empty-btn-outline:hover{background:#eff6ff;border-color:var(--rpt-color-primary, #2563eb);transform:translateY(-1px)}.canvas-active-input{width:100%;height:32px;padding:4px 8px;font-size:.8125rem;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:4px;outline:none;box-sizing:border-box;background:#fff;color:#0f172a;transition:border-color .15s ease}.canvas-active-input:focus{border-color:var(--rpt-color-primary, #2563eb)}.canvas-active-checkbox-lbl{display:inline-flex;align-items:center;gap:6px;cursor:pointer}.canvas-live-control-wrapper{width:100%;max-width:100%;min-width:0;position:relative;z-index:1;box-sizing:border-box}.canvas-grid-box{margin-top:24px;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:8px;background:#fff;box-shadow:0 1px 3px #0000000d;overflow:hidden}.grid-preview-header{display:flex;align-items:center;justify-content:space-between;padding:10px 16px;background:var(--rpt-color-surface, #f8fafc);border-bottom:1px solid var(--rpt-color-border, #cbd5e1);font-size:.8rem;font-weight:600;color:var(--rpt-color-text, #0f172a)}.grid-title{font-weight:700}.grid-exec-badge{font-size:.6875rem;font-weight:600;padding:2px 8px;border-radius:10px}.grid-exec-badge.is-loading{background:#eff6ff;color:#2563eb}.grid-exec-badge.is-error{background:#fee2e2;color:#ef4444}.grid-exec-badge.is-success{background:#ecfdf5;color:#059669}.btn-canvas-run-grid{display:inline-flex;align-items:center;gap:5px;padding:4px 10px;font-size:.72rem;font-weight:600;color:#fff;background:var(--rpt-color-primary, #2563eb);border:none;border-radius:4px;cursor:pointer;transition:background .15s ease}.btn-canvas-run-grid:hover:not(:disabled){background:#1d4ed8}.btn-canvas-run-grid:disabled{opacity:.6;cursor:not-allowed}.btn-canvas-edit-grid{display:inline-flex;align-items:center;gap:4px;padding:4px 8px;font-size:.72rem;font-weight:500;color:#334155;background:#fff;border:1px solid #cbd5e1;border-radius:4px;cursor:pointer;transition:all .12s ease}.btn-canvas-edit-grid:hover{background:#f1f5f9}.canvas-live-grid-container{width:100%;min-height:480px;background:#fff}.live-mode-badge{display:inline-flex;align-items:center;gap:4px;font-size:.6875rem;font-weight:700;color:#047857;background:#ecfdf5;border:1px solid #a7f3d0;padding:1px 8px;border-radius:9999px}.canvas-component-card.is-field-highlighted{border-color:#f59e0b!important;box-shadow:0 0 0 3px #f59e0b59!important;animation:rpt-pulse-border 1s ease-in-out infinite alternate}@keyframes rpt-pulse-border{0%{box-shadow:0 0 0 2px #f59e0b40}to{box-shadow:0 0 0 5px #f59e0b80}}.grid-layout-status-strip{display:flex;align-items:center;justify-content:space-between;padding:6px 16px;background:#f1f5f9;border-bottom:1px solid var(--rpt-color-border, #cbd5e1);font-size:.6875rem;color:#475569}.grid-status-info{display:inline-flex;align-items:center;gap:6px;font-weight:600}.grid-status-sync{display:inline-flex;align-items:center;gap:4px;color:#059669;font-weight:600;transition:transform .2s ease}.grid-status-sync.is-pulsing{transform:scale(1.08);color:#047857}.canvas-actions{display:flex;align-items:center;gap:8px}.btn-grid-add{background:#f0fdf4;border-color:#bbf7d0;color:#16a34a}.btn-grid-add:hover{background:#dcfce7;border-color:#86efac;color:#15803d}.btn-remove-grid{display:inline-flex;align-items:center;justify-content:center;padding:4px;border:none;background:transparent;color:#94a3b8;border-radius:4px;cursor:pointer;transition:all .15s ease}.btn-remove-grid:hover{background:#fee2e2;color:#ef4444}.canvas-add-grid-banner{margin-top:24px;border:2px dashed #cbd5e1;border-radius:8px;background:#fff;padding:16px 20px;display:flex;align-items:center;gap:16px;cursor:pointer;transition:all .15s ease}.canvas-add-grid-banner:hover{border-color:#2563eb;background:#f8fafc;box-shadow:0 2px 8px #2563eb14}.add-grid-icon{width:40px;height:40px;border-radius:8px;background:#eff6ff;color:#2563eb;display:flex;align-items:center;justify-content:center;flex-shrink:0}.add-grid-text{display:flex;flex-direction:column;gap:2px;flex:1}.add-grid-title{font-size:.875rem;font-weight:600;color:#0f172a}.add-grid-sub{font-size:.75rem;color:#64748b}.btn-banner-add{padding:6px 14px;font-size:.75rem;font-weight:600;color:#2563eb;background:#eff6ff;border:1px solid #bfdbfe;border-radius:6px;cursor:pointer;white-space:nowrap;transition:all .15s ease}.canvas-add-grid-banner:hover .btn-banner-add{background:#2563eb;color:#fff;border-color:#2563eb}.canvas-grid-loading-overlay{position:absolute;inset:0;background:#ffffffe6;backdrop-filter:blur(2px);z-index:10;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;font-family:inherit;border-radius:6px}.grid-loading-title{font-weight:600;font-size:.95rem;color:#1e293b}.grid-loading-sub{font-size:.8rem;color:#64748b}\n"] }]
|
|
409
467
|
}], propDecorators: { onEscape: [{
|
|
410
468
|
type: HostListener,
|
|
411
469
|
args: ['document:keydown.escape']
|
|
412
470
|
}] } });
|
|
413
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVzaWduLWNhbnZhcy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9id2F5cy1yZXBvcnQvc3JjL2xpYi9mZWF0dXJlcy9kZXNpZ25lci9jb21wb25lbnRzL2Rlc2lnbi1jYW52YXMvZGVzaWduLWNhbnZhcy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9id2F5cy1yZXBvcnQvc3JjL2xpYi9mZWF0dXJlcy9kZXNpZ25lci9jb21wb25lbnRzL2Rlc2lnbi1jYW52YXMvZGVzaWduLWNhbnZhcy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxRQUFRLEVBQ1IsWUFBWSxFQUNaLE1BQU0sRUFDTixNQUFNLEdBRVAsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0UsT0FBTyxFQU9MLGNBQWMsR0FDZixNQUFNLHdCQUF3QixDQUFDO0FBQ2hDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQzdFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBSS9FLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDJEQUEyRCxDQUFDO0FBQzdGLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLG1FQUFtRSxDQUFDO0FBQ3pHLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHVFQUF1RSxDQUFDO0FBQzlHLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLCtDQUErQyxDQUFDO0FBQzFGLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFN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O3NCQURQLFlBQVk7dUJBQUMseUJBQXlCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgY29tcHV0ZWQsXG4gIEhvc3RMaXN0ZW5lcixcbiAgaW5qZWN0LFxuICBzaWduYWwsXG4gIHVudHJhY2tlZCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgUmVhY3RpdmVGb3Jtc01vZHVsZSwgRm9ybUNvbnRyb2wsIEZvcm1Hcm91cCB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7XG4gIENka0RyYWcsXG4gIENka0RyYWdEcm9wLFxuICBDZGtEcmFnSGFuZGxlLFxuICBDZGtEcmFnUGxhY2Vob2xkZXIsXG4gIENka0RyYWdQcmV2aWV3LFxuICBDZGtEcm9wTGlzdCxcbiAgRHJhZ0Ryb3BNb2R1bGUsXG59IGZyb20gJ0Bhbmd1bGFyL2Nkay9kcmFnLWRyb3AnO1xuaW1wb3J0IHsgRGVzaWduZXJTdGF0ZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9kZXNpZ25lci1zdGF0ZS5zZXJ2aWNlJztcbmltcG9ydCB7IFJlcG9ydFRlbXBsYXRlU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3JlcG9ydC10ZW1wbGF0ZS5zZXJ2aWNlJztcbmltcG9ydCB7IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24gfSBmcm9tICcuLi8uLi8uLi8uLi9jb3JlL21vZGVscy9yZXBvcnQtY29tcG9uZW50Lm1vZGVsJztcbmltcG9ydCB7IENvbXBvbmVudExheW91dERlZmluaXRpb24gfSBmcm9tICcuLi8uLi8uLi8uLi9jb3JlL21vZGVscy9yZXBvcnQtbGF5b3V0Lm1vZGVsJztcbmltcG9ydCB7IFJlcG9ydEdyaWREZWZpbml0aW9uIH0gZnJvbSAnLi4vLi4vLi4vLi4vY29yZS9tb2RlbHMvcmVwb3J0LWdyaWQubW9kZWwnO1xuaW1wb3J0IHsgUnB0SWNvbkNvbXBvbmVudCB9IGZyb20gJy4uLy4uLy4uLy4uL3ByaW1pdGl2ZXMvY29tcG9uZW50cy9pY29uL3JwdC1pY29uLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBScHREcm9wZG93bkNvbXBvbmVudCB9IGZyb20gJy4uLy4uLy4uLy4uL3ByaW1pdGl2ZXMvY29tcG9uZW50cy9kcm9wZG93bi9ycHQtZHJvcGRvd24uY29tcG9uZW50JztcbmltcG9ydCB7IFJwdERhdGVSYW5nZUNvbXBvbmVudCB9IGZyb20gJy4uLy4uLy4uLy4uL3ByaW1pdGl2ZXMvY29tcG9uZW50cy9kYXRlLXJhbmdlL3JwdC1kYXRlLXJhbmdlLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBSZXBvcnRHcmlkQnJpZGdlQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vLi4vcnVudGltZS9yZXBvcnQtZ3JpZC1icmlkZ2UuY29tcG9uZW50JztcbmltcG9ydCB7IER5bmFtaWNGb3JtQnVpbGRlciB9IGZyb20gJy4uLy4uLy4uLy4uL2NvcmUvc2VydmljZXMvZHluYW1pYy1mb3JtLWJ1aWxkZXIuc2VydmljZSc7XG5pbXBvcnQgeyBSZXBvcnRFeGVjdXRpb25TZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vcnVudGltZS9yZXBvcnQtZXhlY3V0aW9uLnNlcnZpY2UnO1xuaW1wb3J0IHtcbiAgY2FsY3VsYXRlR3JpZENvbHVtbixcbiAgY2FsY3VsYXRlR3JpZFJvdyxcbiAgY2FsY3VsYXRlU25hcHBlZEhlaWdodCxcbiAgY2FsY3VsYXRlU25hcHBlZFNwYW4sXG4gIENBTlZBU19DQVJEX09WRVJIRUFELFxuICBnZXRDb21wb25lbnRJY29uTmFtZSxcbiAgZ2V0Q29tcG9uZW50TmF0dXJhbE1pbkhlaWdodCxcbiAgcmVzb2x2ZUNhbnZhc0NhcmRIZWlnaHQsXG4gIHJlc29sdmVDYW52YXNDYXJkTWluSGVpZ2h0LFxuICByZXNvbHZlQ29tcG9uZW50U3Bhbixcbn0gZnJvbSAnLi4vLi4vdXRpbGl0aWVzL2NhbnZhcy1sYXlvdXQudXRpbCc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3JwdC1kZXNpZ24tY2FudmFzJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZSxcbiAgICBEcmFnRHJvcE1vZHVsZSxcbiAgICBSZWFjdGl2ZUZvcm1zTW9kdWxlLFxuICAgIFJwdEljb25Db21wb25lbnQsXG4gICAgUnB0RHJvcGRvd25Db21wb25lbnQsXG4gICAgUnB0RGF0ZVJhbmdlQ29tcG9uZW50LFxuICAgIFJlcG9ydEdyaWRCcmlkZ2VDb21wb25lbnQsXG4gIF0sXG5cbiAgdGVtcGxhdGVVcmw6ICcuL2Rlc2lnbi1jYW52YXMuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybDogJy4vZGVzaWduLWNhbnZhcy5jb21wb25lbnQuY3NzJyxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIERlc2lnbkNhbnZhc0NvbXBvbmVudCB7XG4gIHByaXZhdGUgcmVhZG9ubHkgZGVzaWduZXJTdGF0ZSA9IGluamVjdChEZXNpZ25lclN0YXRlU2VydmljZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgdGVtcGxhdGVTZXJ2aWNlID0gaW5qZWN0KFJlcG9ydFRlbXBsYXRlU2VydmljZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgZm9ybUJ1aWxkZXIgPSBpbmplY3QoRHluYW1pY0Zvcm1CdWlsZGVyKTtcbiAgcHJpdmF0ZSByZWFkb25seSBleGVjdXRpb25TZXJ2aWNlID0gaW5qZWN0KFJlcG9ydEV4ZWN1dGlvblNlcnZpY2UpO1xuXG4gIHJlYWRvbmx5IGRlZmluaXRpb24gPSB0aGlzLmRlc2lnbmVyU3RhdGUuZGVmaW5pdGlvbjtcbiAgcmVhZG9ubHkgY29tcG9uZW50cyA9IGNvbXB1dGVkKCgpID0+IHRoaXMuZGVmaW5pdGlvbigpLmNvbXBvbmVudHMpO1xuICByZWFkb25seSBzZWxlY3RlZElkID0gdGhpcy5kZXNpZ25lclN0YXRlLnNlbGVjdGVkQ29tcG9uZW50SWQ7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfc3RhYmxlQ2FudmFzRm9ybSA9IG5ldyBGb3JtR3JvdXAoe30pO1xuICByZWFkb25seSBjYW52YXNGb3JtID0gY29tcHV0ZWQ8Rm9ybUdyb3VwPigoKSA9PiB7XG4gICAgY29uc3QgY29tcHMgPSB0aGlzLmNvbXBvbmVudHMoKTtcbiAgICBjb25zdCBjdXJyZW50S2V5cyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gICAgZm9yIChjb25zdCBjb21wIG9mIGNvbXBzKSB7XG4gICAgICBpZiAoIWNvbXAua2V5KSBjb250aW51ZTtcbiAgICAgIGN1cnJlbnRLZXlzLmFkZChjb21wLmtleSk7XG5cbiAgICAgIGlmICghdGhpcy5fc3RhYmxlQ2FudmFzRm9ybS5jb250YWlucyhjb21wLmtleSkpIHtcbiAgICAgICAgY29uc3QgZGVmYXVsdFZhbCA9IGNvbXAucHJvcGVydGllcz8uWydkZWZhdWx0VmFsdWUnXSA/PyAoY29tcC50eXBlID09PSAnY2hlY2tib3gnID8gZmFsc2UgOiAnJyk7XG4gICAgICAgIHRoaXMuX3N0YWJsZUNhbnZhc0Zvcm0uYWRkQ29udHJvbChjb21wLmtleSwgbmV3IEZvcm1Db250cm9sKGRlZmF1bHRWYWwpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGV4aXN0aW5nS2V5IG9mIE9iamVjdC5rZXlzKHRoaXMuX3N0YWJsZUNhbnZhc0Zvcm0uY29udHJvbHMpKSB7XG4gICAgICBpZiAoIWN1cnJlbnRLZXlzLmhhcyhleGlzdGluZ0tleSkpIHtcbiAgICAgICAgdGhpcy5fc3RhYmxlQ2FudmFzRm9ybS5yZW1vdmVDb250cm9sKGV4aXN0aW5nS2V5KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fc3RhYmxlQ2FudmFzRm9ybTtcbiAgfSk7XG5cbiAgZ2V0Q2FudmFzQ29udHJvbChjb21wOiBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uKTogRm9ybUNvbnRyb2wgfCBudWxsIHtcbiAgICBpZiAoIWNvbXAua2V5KSByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4gKHRoaXMuY2FudmFzRm9ybSgpLmdldChjb21wLmtleSkgYXMgRm9ybUNvbnRyb2wpID8/IG51bGw7XG4gIH1cblxuICByZWFkb25seSBoaWdobGlnaHRlZEZpZWxkS2V5cyA9IHNpZ25hbDxTZXQ8c3RyaW5nPj4obmV3IFNldCgpKTtcbiAgcmVhZG9ubHkgbGF5b3V0SnVzdFVwZGF0ZWQgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuXG4gIGlzRmllbGRIaWdobGlnaHRlZChjb21wOiBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhY29tcC5rZXkgJiYgdGhpcy5oaWdobGlnaHRlZEZpZWxkS2V5cygpLmhhcyhjb21wLmtleS50b0xvd2VyQ2FzZSgpKTtcbiAgfVxuXG4gIG9uQ29udHJvbEludGVyYWN0KGNvbXA6IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24sIGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5zZWxlY3RDb21wb25lbnQoY29tcC5pZCk7XG4gIH1cblxuICBnZXRHcmlkU3VtbWFyeVRleHQoKTogc3RyaW5nIHtcbiAgICBjb25zdCBncmlkID0gdGhpcy5kZWZpbml0aW9uKCkuZ3JpZDtcbiAgICBpZiAoIWdyaWQpIHJldHVybiAnJztcbiAgICBjb25zdCBwYXJ0czogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCBncm91cHMgPSBncmlkLm9wdGlvbnM/Lmdyb3VwTW9kZWw7XG4gICAgaWYgKGdyb3VwcyAmJiBncm91cHMubGVuZ3RoID4gMCkge1xuICAgICAgcGFydHMucHVzaChgR3JvdXBlZCBieTogJHtncm91cHMuam9pbignLCAnKX1gKTtcbiAgICB9XG4gICAgY29uc3QgY29scyA9IGdyaWQuY29sdW1ucz8uZmlsdGVyKChjKSA9PiBjLnZpc2libGUgIT09IGZhbHNlKSA/PyBbXTtcbiAgICBwYXJ0cy5wdXNoKGAke2NvbHMubGVuZ3RofSB2aXNpYmxlIGNvbHVtbnNgKTtcbiAgICByZXR1cm4gcGFydHMuam9pbignIOKAoiAnKTtcbiAgfVxuXG4gIGhpZ2hsaWdodE1pc3NpbmdGaWVsZHMoZmllbGRzOiBzdHJpbmdbXSk6IHZvaWQge1xuICAgIGNvbnN0IGtleXMgPSBuZXcgU2V0KGZpZWxkcy5tYXAoKGYpID0+IGYudG9Mb3dlckNhc2UoKSkpO1xuICAgIHRoaXMuaGlnaGxpZ2h0ZWRGaWVsZEtleXMuc2V0KGtleXMpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5oaWdobGlnaHRlZEZpZWxkS2V5cy5zZXQobmV3IFNldCgpKTtcbiAgICB9LCAyODAwKTtcbiAgfVxuXG4gIHJlYWRvbmx5IGNhbnZhc0dyaWREYXRhID0gc2lnbmFsPHVua25vd25bXT4oW10pO1xuICByZWFkb25seSBpc0V4ZWN1dGluZ0dyaWQgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICByZWFkb25seSBncmlkRXhlY0Vycm9yID0gc2lnbmFsPHN0cmluZyB8IG51bGw+KG51bGwpO1xuXG4gIHJlYWRvbmx5IHRvdGFsQ29sdW1ucyA9IGNvbXB1dGVkKCgpID0+IHRoaXMuZGVmaW5pdGlvbigpLmxheW91dC5jb2x1bW5zIHx8IDEyKTtcblxuICByZWFkb25seSBncmlkVGVtcGxhdGVDb2x1bW5zID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIHJldHVybiBgcmVwZWF0KCR7dGhpcy50b3RhbENvbHVtbnMoKX0sIG1pbm1heCgwLCAxZnIpKWA7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IHNvcnRlZENvbXBvbmVudHMgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgcmV0dXJuIFsuLi50aGlzLmNvbXBvbmVudHMoKV0uc29ydCgoYSwgYikgPT4gKGEub3JkZXIgPz8gMCkgLSAoYi5vcmRlciA/PyAwKSk7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IHJlc2l6aW5nQ29tcElkID0gc2lnbmFsPHN0cmluZyB8IG51bGw+KG51bGwpO1xuICByZWFkb25seSByZXNpemluZ1NwYW4gPSBzaWduYWw8bnVtYmVyIHwgbnVsbD4obnVsbCk7XG4gIHJlYWRvbmx5IHJlc2l6aW5nSGVpZ2h0ID0gc2lnbmFsPG51bWJlciB8IG51bGw+KG51bGwpO1xuICByZWFkb25seSBpc0FueVJlc2l6aW5nID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5yZXNpemluZ0NvbXBJZCgpICE9PSBudWxsKTtcblxuICBpc1NlbGVjdGVkKGlkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3RlZElkKCkgPT09IGlkO1xuICB9XG5cbiAgZ2V0U3Bhbihjb21wOiBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uKTogbnVtYmVyIHtcbiAgICByZXR1cm4gcmVzb2x2ZUNvbXBvbmVudFNwYW4oXG4gICAgICBjb21wLFxuICAgICAgdGhpcy50b3RhbENvbHVtbnMoKSxcbiAgICAgIHRoaXMucmVzaXppbmdDb21wSWQoKSA9PT0gY29tcC5pZCA/IHRoaXMucmVzaXppbmdTcGFuKCkgOiBudWxsXG4gICAgKTtcbiAgfVxuXG4gIGdldEdyaWRDb2x1bW4oY29tcDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbik6IHN0cmluZyB7XG4gICAgcmV0dXJuIGNhbGN1bGF0ZUdyaWRDb2x1bW4oY29tcCwgdGhpcy50b3RhbENvbHVtbnMoKSwgdGhpcy5nZXRTcGFuKGNvbXApKTtcbiAgfVxuXG4gIHRvZ2dsZU5ld1Jvdyhjb21wOiBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uLCBldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGNvbnN0IGN1cnJlbnQgPSAhIWNvbXAubGF5b3V0Py5uZXdSb3c7XG4gICAgdGhpcy5kZXNpZ25lclN0YXRlLnVwZGF0ZUNvbXBvbmVudExheW91dChjb21wLmlkLCB7IG5ld1JvdzogIWN1cnJlbnQgfSk7XG4gIH1cblxuICBnZXRHcmlkUm93KGNvbXA6IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24pOiBzdHJpbmcge1xuICAgIHJldHVybiBjYWxjdWxhdGVHcmlkUm93KGNvbXApO1xuICB9XG5cbiAgZ2V0Q29tcG9uZW50SGVpZ2h0KGNvbXA6IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24pOiBzdHJpbmcge1xuICAgIHJldHVybiByZXNvbHZlQ2FudmFzQ2FyZEhlaWdodChcbiAgICAgIGNvbXAsXG4gICAgICB0aGlzLnJlc2l6aW5nQ29tcElkKCkgPT09IGNvbXAuaWQgPyB0aGlzLnJlc2l6aW5nSGVpZ2h0KCkgOiBudWxsXG4gICAgKTtcbiAgfVxuXG4gIGdldENvbXBvbmVudE1pbkhlaWdodChjb21wOiBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uKTogc3RyaW5nIHtcbiAgICByZXR1cm4gcmVzb2x2ZUNhbnZhc0NhcmRNaW5IZWlnaHQoXG4gICAgICBjb21wLFxuICAgICAgdGhpcy5yZXNpemluZ0NvbXBJZCgpID09PSBjb21wLmlkID8gdGhpcy5yZXNpemluZ0hlaWdodCgpIDogbnVsbFxuICAgICk7XG4gIH1cblxuICBnZXRDdXN0b21CdG5IZWlnaHQoY29tcDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbik6IHN0cmluZyB8IG51bGwge1xuICAgIGNvbnN0IGggPSBjb21wLmxheW91dD8uaGVpZ2h0O1xuICAgIHJldHVybiBoICYmIGggIT09ICdhdXRvJyA/IGggOiBudWxsO1xuICB9XG5cbiAgZ2V0Q3VzdG9tQnRuV2lkdGgoY29tcDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbik6IHN0cmluZyB8IG51bGwge1xuICAgIGNvbnN0IHcgPSBjb21wLmxheW91dD8ud2lkdGg7XG4gICAgcmV0dXJuIHcgJiYgdyAhPT0gJ2F1dG8nID8gdyA6IG51bGw7XG4gIH1cblxuICBnZXRDdXN0b21CdG5JY29uKGNvbXA6IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24pOiBzdHJpbmcge1xuICAgIHJldHVybiAoY29tcC5wcm9wZXJ0aWVzPy5bJ2ljb24nXSBhcyBzdHJpbmcpIHx8ICcnO1xuICB9XG5cbiAgcmVzaXppbmdUb29sdGlwKGNvbXA6IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24pOiBzdHJpbmcge1xuICAgIGNvbnN0IHNwYW4gPSB0aGlzLmdldFNwYW4oY29tcCk7XG4gICAgY29uc3QgaGVpZ2h0ID0gdGhpcy5yZXNpemluZ0hlaWdodCgpID8/IChjb21wLmxheW91dD8uaGVpZ2h0ID8gcGFyc2VJbnQoY29tcC5sYXlvdXQuaGVpZ2h0LCAxMCkgOiA1OCk7XG4gICAgcmV0dXJuIGAke3NwYW59IGNvbHMgw5cgJHtoZWlnaHR9cHhgO1xuICB9XG5cbiAgcmVhZG9ubHkgZ2V0Q29tcG9uZW50SWNvbk5hbWUgPSBnZXRDb21wb25lbnRJY29uTmFtZTtcblxuICBvblNlbGVjdChpZDogc3RyaW5nLCBldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmlzQW55UmVzaXppbmcoKSkgcmV0dXJuO1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5zZWxlY3RDb21wb25lbnQoaWQpO1xuICB9XG5cbiAgYWRqdXN0U3Bhbihjb21wOiBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uLCBkZWx0YTogbnVtYmVyLCBldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLmdldFNwYW4oY29tcCk7XG4gICAgY29uc3QgbmV4dCA9IE1hdGgubWF4KDEsIE1hdGgubWluKHRoaXMudG90YWxDb2x1bW5zKCksIGN1cnJlbnQgKyBkZWx0YSkpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS51cGRhdGVDb21wb25lbnRMYXlvdXQoY29tcC5pZCwgeyBjb2x1bW5TcGFuOiBuZXh0IH0pO1xuICB9XG5cbiAgb25EdXBsaWNhdGUoaWQ6IHN0cmluZywgZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLmRlc2lnbmVyU3RhdGUuZHVwbGljYXRlQ29tcG9uZW50KGlkKTtcbiAgfVxuXG4gIG9uRGVsZXRlKGlkOiBzdHJpbmcsIGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy5kZXNpZ25lclN0YXRlLnJlbW92ZUNvbXBvbmVudChpZCk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDprZXlkb3duLmVzY2FwZScpXG4gIG9uRXNjYXBlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnNlbGVjdGVkSWQoKSkge1xuICAgICAgdGhpcy5kZXNpZ25lclN0YXRlLnNlbGVjdENvbXBvbmVudChudWxsKTtcbiAgICB9XG4gIH1cblxuICBvbkNhbnZhc0JhY2tncm91bmRDbGljayhldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmlzQW55UmVzaXppbmcoKSkgcmV0dXJuO1xuICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudDtcbiAgICBpZiAoXG4gICAgICB0YXJnZXQuY2xvc2VzdCgnLmNhbnZhcy1jb21wb25lbnQtY2FyZCcpIHx8XG4gICAgICB0YXJnZXQuY2xvc2VzdCgnLmNhbnZhcy1hY3Rpb24tYnRuJykgfHxcbiAgICAgIHRhcmdldC5jbG9zZXN0KCcuY2FudmFzLWdyaWQtcHJldmlldy1ib3gnKVxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmRlc2lnbmVyU3RhdGUuc2VsZWN0Q29tcG9uZW50KG51bGwpO1xuICB9XG5cbiAgc2VsZWN0UmVwb3J0U2V0dGluZ3MoZXZlbnQ/OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQ/LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5zZWxlY3RDb21wb25lbnQobnVsbCk7XG4gICAgdGhpcy5kZXNpZ25lclN0YXRlLnNldEFjdGl2ZVRhYigncmVwb3J0Jyk7XG4gIH1cblxuICBzZWxlY3RHcmlkU2V0dGluZ3MoZXZlbnQ/OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQ/LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5zZWxlY3RDb21wb25lbnQobnVsbCk7XG4gICAgdGhpcy5kZXNpZ25lclN0YXRlLnNldEFjdGl2ZVRhYignZ3JpZCcpO1xuICB9XG5cbiAgc3RhcnRSZXNpemUoZXZlbnQ6IFBvaW50ZXJFdmVudCwgY29tcDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbiwgZGlyZWN0aW9uOiAnZScgfCAncycgfCAnc2UnKTogdm9pZCB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5zZWxlY3RDb21wb25lbnQoY29tcC5pZCk7XG5cbiAgICBjb25zdCBoYW5kbGUgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgaGFuZGxlLnNldFBvaW50ZXJDYXB0dXJlKGV2ZW50LnBvaW50ZXJJZCk7XG5cbiAgICBjb25zdCBjYXJkID0gaGFuZGxlLmNsb3Nlc3QoJy5jYW52YXMtY29tcG9uZW50LWNhcmQnKSBhcyBIVE1MRWxlbWVudDtcbiAgICBjb25zdCBncmlkID0gaGFuZGxlLmNsb3Nlc3QoJy5jYW52YXMtZ3JpZCcpIGFzIEhUTUxFbGVtZW50O1xuICAgIGlmICghY2FyZCB8fCAhZ3JpZCkgcmV0dXJuO1xuXG4gICAgY29uc3Qgc3RhcnRYID0gZXZlbnQuY2xpZW50WDtcbiAgICBjb25zdCBzdGFydFkgPSBldmVudC5jbGllbnRZO1xuICAgIGNvbnN0IHN0YXJ0U3BhbiA9IGNvbXAubGF5b3V0Py5jb2x1bW5TcGFuID8/IChjb21wLnR5cGUgPT09ICdidXR0b24nID8gMiA6IDQpO1xuICAgIGNvbnN0IGV4aXN0aW5nQ29tcEhlaWdodCA9IGNvbXAubGF5b3V0Py5oZWlnaHQgPyBwYXJzZUludChjb21wLmxheW91dC5oZWlnaHQsIDEwKSA6IG51bGw7XG4gICAgY29uc3Qgc3RhcnRIZWlnaHQgPSBleGlzdGluZ0NvbXBIZWlnaHQgPz8gTWF0aC5tYXgoMzgsIGNhcmQub2Zmc2V0SGVpZ2h0IC0gQ0FOVkFTX0NBUkRfT1ZFUkhFQUQpO1xuICAgIGNvbnN0IHRvdGFsQ29scyA9IHRoaXMudG90YWxDb2x1bW5zKCk7XG4gICAgY29uc3QgZ2FwID0gdGhpcy5kZWZpbml0aW9uKCkubGF5b3V0LmdhcCA/PyAxNjtcbiAgICBjb25zdCBjb2xXaWR0aCA9IChncmlkLm9mZnNldFdpZHRoIC0gKHRvdGFsQ29scyAtIDEpICogZ2FwKSAvIHRvdGFsQ29scztcblxuICAgIHRoaXMucmVzaXppbmdDb21wSWQuc2V0KGNvbXAuaWQpO1xuICAgIHRoaXMucmVzaXppbmdTcGFuLnNldChzdGFydFNwYW4pO1xuICAgIHRoaXMucmVzaXppbmdIZWlnaHQuc2V0KHN0YXJ0SGVpZ2h0KTtcblxuICAgIGxldCBjdXJyZW50U3BhbiA9IHN0YXJ0U3BhbjtcbiAgICBsZXQgY3VycmVudEhlaWdodCA9IHN0YXJ0SGVpZ2h0O1xuXG4gICAgY29uc3Qgb25Qb2ludGVyTW92ZSA9IChtb3ZlRXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgICAgaWYgKGRpcmVjdGlvbiA9PT0gJ2UnIHx8IGRpcmVjdGlvbiA9PT0gJ3NlJykge1xuICAgICAgICBjb25zdCBkZWx0YVggPSBtb3ZlRXZlbnQuY2xpZW50WCAtIHN0YXJ0WDtcbiAgICAgICAgY3VycmVudFNwYW4gPSBjYWxjdWxhdGVTbmFwcGVkU3BhbihkZWx0YVgsIHN0YXJ0U3BhbiwgY29sV2lkdGgsIGdhcCwgdG90YWxDb2xzKTtcbiAgICAgICAgdGhpcy5yZXNpemluZ1NwYW4uc2V0KGN1cnJlbnRTcGFuKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGRpcmVjdGlvbiA9PT0gJ3MnIHx8IGRpcmVjdGlvbiA9PT0gJ3NlJykge1xuICAgICAgICBjb25zdCBkZWx0YVkgPSBtb3ZlRXZlbnQuY2xpZW50WSAtIHN0YXJ0WTtcbiAgICAgICAgY29uc3QgbmF0dXJhbE1pbiA9IE1hdGgubWF4KDM4LCBnZXRDb21wb25lbnROYXR1cmFsTWluSGVpZ2h0KGNvbXAudHlwZSkpO1xuICAgICAgICBjdXJyZW50SGVpZ2h0ID0gY2FsY3VsYXRlU25hcHBlZEhlaWdodChkZWx0YVksIHN0YXJ0SGVpZ2h0LCBuYXR1cmFsTWluKTtcbiAgICAgICAgdGhpcy5yZXNpemluZ0hlaWdodC5zZXQoY3VycmVudEhlaWdodCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGNvbnN0IG9uUG9pbnRlclVwID0gKHVwRXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaGFuZGxlLnJlbGVhc2VQb2ludGVyQ2FwdHVyZSh1cEV2ZW50LnBvaW50ZXJJZCk7XG4gICAgICB9IGNhdGNoIHt9XG5cbiAgICAgIGhhbmRsZS5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVybW92ZScsIG9uUG9pbnRlck1vdmUpO1xuICAgICAgaGFuZGxlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJ1cCcsIG9uUG9pbnRlclVwKTtcbiAgICAgIGhhbmRsZS5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVyY2FuY2VsJywgb25Qb2ludGVyVXApO1xuXG4gICAgICBjb25zdCBsYXlvdXRDaGFuZ2VzOiBQYXJ0aWFsPENvbXBvbmVudExheW91dERlZmluaXRpb24+ID0ge307XG4gICAgICBpZiAoZGlyZWN0aW9uID09PSAnZScgfHwgZGlyZWN0aW9uID09PSAnc2UnKSB7XG4gICAgICAgIGxheW91dENoYW5nZXMuY29sdW1uU3BhbiA9IGN1cnJlbnRTcGFuO1xuICAgICAgfVxuICAgICAgY29uc3QgZGVsdGFZID0gTWF0aC5hYnModXBFdmVudC5jbGllbnRZIC0gc3RhcnRZKTtcbiAgICAgIGlmIChkaXJlY3Rpb24gPT09ICdzJyB8fCAoZGlyZWN0aW9uID09PSAnc2UnICYmIGRlbHRhWSA+IDgpKSB7XG4gICAgICAgIGxheW91dENoYW5nZXMuaGVpZ2h0ID0gYCR7Y3VycmVudEhlaWdodH1weGA7XG4gICAgICAgIGxheW91dENoYW5nZXMubWluSGVpZ2h0ID0gYCR7Y3VycmVudEhlaWdodH1weGA7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuZGVzaWduZXJTdGF0ZS51cGRhdGVDb21wb25lbnRMYXlvdXQoY29tcC5pZCwgbGF5b3V0Q2hhbmdlcyk7XG5cbiAgICAgIHRoaXMucmVzaXppbmdDb21wSWQuc2V0KG51bGwpO1xuICAgICAgdGhpcy5yZXNpemluZ1NwYW4uc2V0KG51bGwpO1xuICAgICAgdGhpcy5yZXNpemluZ0hlaWdodC5zZXQobnVsbCk7XG4gICAgfTtcblxuICAgIGhhbmRsZS5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVybW92ZScsIG9uUG9pbnRlck1vdmUpO1xuICAgIGhhbmRsZS5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVydXAnLCBvblBvaW50ZXJVcCk7XG4gICAgaGFuZGxlLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJjYW5jZWwnLCBvblBvaW50ZXJVcCk7XG4gIH1cblxuICByZXNldERpbWVuc2lvbnMoY29tcDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbiwgZXZlbnQ/OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKGV2ZW50KSB7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICAgIGNvbnN0IGRlZmF1bHRTcGFuID0gY29tcC50eXBlID09PSAnYnV0dG9uJyA/IDIgOiA0O1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS51cGRhdGVDb21wb25lbnRMYXlvdXQoY29tcC5pZCwge1xuICAgICAgY29sdW1uU3BhbjogZGVmYXVsdFNwYW4sXG4gICAgICBoZWlnaHQ6IHVuZGVmaW5lZCxcbiAgICAgIG1pbkhlaWdodDogdW5kZWZpbmVkLFxuICAgICAgd2lkdGg6IHVuZGVmaW5lZCxcbiAgICB9KTtcbiAgfVxuXG4gIG9uRHJvcChldmVudDogQ2RrRHJhZ0Ryb3A8UmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbltdLCB1bmtub3duLCB1bmtub3duPik6IHZvaWQge1xuICAgIGlmICh0aGlzLmlzQW55UmVzaXppbmcoKSkgcmV0dXJuO1xuXG4gICAgaWYgKGV2ZW50LnByZXZpb3VzQ29udGFpbmVyID09PSBldmVudC5jb250YWluZXIpIHtcbiAgICAgIC8vIFJlb3JkZXJpbmcgd2l0aGluIGNhbnZhc1xuICAgICAgdGhpcy5kZXNpZ25lclN0YXRlLm1vdmVDb21wb25lbnQoZXZlbnQucHJldmlvdXNJbmRleCwgZXZlbnQuY3VycmVudEluZGV4KTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gRHJhZ2dlZCBmcm9tIHBhbGV0dGUgaW50byBjYW52YXNcbiAgICAgIGNvbnN0IHJhd0RhdGEgPSBldmVudC5pdGVtLmRhdGEgYXMgc3RyaW5nIHwgeyB0eXBlPzogc3RyaW5nIH0gfCB1bmRlZmluZWQ7XG4gICAgICBjb25zdCBjb21wb25lbnRUeXBlID0gdHlwZW9mIHJhd0RhdGEgPT09ICdzdHJpbmcnID8gcmF3RGF0YSA6IHJhd0RhdGE/LnR5cGU7XG4gICAgICBpZiAoY29tcG9uZW50VHlwZSkge1xuICAgICAgICB0aGlzLmRlc2lnbmVyU3RhdGUuYWRkQ29tcG9uZW50KGNvbXBvbmVudFR5cGUsIGV2ZW50LmN1cnJlbnRJbmRleCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgYWRkUmVzdWx0R3JpZChldmVudD86IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudD8uc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgY29uc3QgZXhpc3RpbmdEcyA9IHRoaXMuZGVmaW5pdGlvbigpLmRhdGFTb3VyY2VzWzBdO1xuICAgIGNvbnN0IGRlZmF1bHRHcmlkOiBSZXBvcnRHcmlkRGVmaW5pdGlvbiA9IHtcbiAgICAgIGRhdGFTb3VyY2VJZDogZXhpc3RpbmdEcz8uaWQgPz8gJ2RlZmF1bHQnLFxuICAgICAgY29sdW1uczogW1xuICAgICAgICB7IGZpZWxkOiAnaWQnLCBsYWJlbDogJ0lEJywgZGF0YVR5cGU6ICdudW1iZXInLCB2aXNpYmxlOiB0cnVlLCBzb3J0YWJsZTogdHJ1ZSB9LFxuICAgICAgICB7IGZpZWxkOiAnbmFtZScsIGxhYmVsOiAnTmFtZScsIGRhdGFUeXBlOiAnc3RyaW5nJywgdmlzaWJsZTogdHJ1ZSwgc29ydGFibGU6IHRydWUgfSxcbiAgICAgIF0sXG4gICAgICBvcHRpb25zOiB7XG4gICAgICAgIHBhZ2luYXRpb246IHRydWUsXG4gICAgICAgIHBhZ2VTaXplOiAyNSxcbiAgICAgICAgc2hvd1Jvd051bWJlcnM6IHRydWUsXG4gICAgICAgIHNob3dGb290ZXI6IHRydWUsXG4gICAgICAgIHNpZGVCYXI6IHRydWUsXG4gICAgICAgIGdsb2JhbFNlYXJjaDogdHJ1ZSxcbiAgICAgICAgc3RhdHVzQmFyOiB0cnVlLFxuICAgICAgfSxcbiAgICB9O1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS51cGRhdGVHcmlkU2V0dGluZ3MoZGVmYXVsdEdyaWQpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5zZWxlY3RDb21wb25lbnQobnVsbCk7XG4gICAgdGhpcy5kZXNpZ25lclN0YXRlLnNldEFjdGl2ZVRhYignZ3JpZCcpO1xuICB9XG5cbiAgZXhlY3V0ZUNhbnZhc1JlcG9ydChldmVudD86IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoZXZlbnQpIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGlmICghdGhpcy5kZWZpbml0aW9uKCkuZ3JpZCkge1xuICAgICAgdGhpcy5hZGRSZXN1bHRHcmlkKCk7XG4gICAgfVxuXG4gICAgY29uc3QgZm9ybVZhbHVlcyA9IHRoaXMuY2FudmFzRm9ybSgpLmdldFJhd1ZhbHVlKCk7XG4gICAgY29uc3QgbWlzc2luZyA9IHRoaXMuZXhlY3V0aW9uU2VydmljZS5nZXRNaXNzaW5nRmllbGRzKHRoaXMuZGVmaW5pdGlvbigpLCBmb3JtVmFsdWVzKTtcbiAgICBpZiAobWlzc2luZy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLmdyaWRFeGVjRXJyb3Iuc2V0KCdNaXNzaW5nIHJlcXVpcmVkIGZpbHRlciB2YWx1ZXM6ICcgKyBtaXNzaW5nLmpvaW4oJywgJykgKyAnLiBQbGVhc2UgZW50ZXIgdmFsdWVzIGFib3ZlIHRvIHJ1bi4nKTtcbiAgICAgIHRoaXMuaGlnaGxpZ2h0TWlzc2luZ0ZpZWxkcyhtaXNzaW5nKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmlzRXhlY3V0aW5nR3JpZC5zZXQodHJ1ZSk7XG4gICAgdGhpcy5ncmlkRXhlY0Vycm9yLnNldChudWxsKTtcblxuICAgIHRoaXMuZXhlY3V0aW9uU2VydmljZS5leGVjdXRlKHRoaXMuZGVmaW5pdGlvbigpLCBmb3JtVmFsdWVzKS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKHJvd3M6IHVua25vd25bXSkgPT4ge1xuICAgICAgICB0aGlzLmNhbnZhc0dyaWREYXRhLnNldChyb3dzIHx8IFtdKTtcbiAgICAgICAgdGhpcy5pc0V4ZWN1dGluZ0dyaWQuc2V0KGZhbHNlKTtcbiAgICAgIH0sXG4gICAgICBlcnJvcjogKGVycjogdW5rbm93bikgPT4ge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdbRGVzaWduQ2FudmFzXSBRdWVyeSBleGVjdXRpb24gZXJyb3I6JywgZXJyKTtcbiAgICAgICAgY29uc3QgbXNnID0gZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpO1xuICAgICAgICB0aGlzLmdyaWRFeGVjRXJyb3Iuc2V0KG1zZyB8fCAnRXhlY3V0aW9uIGZhaWxlZCcpO1xuICAgICAgICB0aGlzLmlzRXhlY3V0aW5nR3JpZC5zZXQoZmFsc2UpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIG9uQ2FudmFzQnV0dG9uQ2xpY2soY29tcDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbiwgZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBjb25zdCBhY3Rpb24gPSAoY29tcC5wcm9wZXJ0aWVzPy5bJ2FjdGlvbiddIGFzIHN0cmluZykgfHwgJ2V4ZWN1dGUtcmVwb3J0JztcbiAgICBpZiAoYWN0aW9uID09PSAnZXhlY3V0ZS1yZXBvcnQnKSB7XG4gICAgICB0aGlzLmV4ZWN1dGVDYW52YXNSZXBvcnQoKTtcbiAgICB9IGVsc2UgaWYgKGFjdGlvbiA9PT0gJ3Jlc2V0Jykge1xuICAgICAgdGhpcy5jYW52YXNGb3JtKCkucmVzZXQoKTtcbiAgICAgIHRoaXMuY2FudmFzR3JpZERhdGEuc2V0KFtdKTtcbiAgICB9IGVsc2UgaWYgKGFjdGlvbiA9PT0gJ2V4cG9ydCcpIHtcbiAgICAgIHRoaXMuZ3JpZEV4ZWNFcnJvci5zZXQoJ/CfkqEgRXhwb3J0IGFjdGlvbiBpcyBjb25maWd1cmVkLiBSdW4gdGhlIHJlcG9ydCBhbmQgc3dpdGNoIHRvIFJ1bnRpbWUgdmlldyB0byBkb3dubG9hZCBmaWxlcy4nKTtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5ncmlkRXhlY0Vycm9yLnNldChudWxsKSwgNDAwMCk7XG4gICAgfSBlbHNlIGlmIChhY3Rpb24gPT09ICdwcmludC1yZXBvcnQnKSB7XG4gICAgICB0aGlzLmdyaWRFeGVjRXJyb3Iuc2V0KCfwn5KhIFByaW50IFJlcG9ydCBhY3Rpb24gaXMgY29uZmlndXJlZC4gU3dpdGNoIHRvIFJ1bnRpbWUgdmlldyB0byBzdWJtaXQgdG8gcHJpbnQgc2VydmljZS4nKTtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5ncmlkRXhlY0Vycm9yLnNldChudWxsKSwgNDAwMCk7XG4gICAgfVxuICB9XG5cbiAgb25DYW52YXNHcmlkU3RhdGVDaGFuZ2Uoc3RhdGU6IGFueSk6IHZvaWQge1xuICAgIGlmICghc3RhdGUgfHwgIXRoaXMuZGVmaW5pdGlvbigpLmdyaWQpIHJldHVybjtcbiAgICBjb25zdCBjdXJyZW50R3JpZCA9IHRoaXMuZGVmaW5pdGlvbigpLmdyaWQhO1xuXG4gICAgLy8gQXZvaWQgZGlydHkgY2h1cm4gYW5kIGV2ZW50IGxvb3BzIGlmIHN0YXRlIGhhcyBub3QgY2hhbmdlZFxuICAgIGNvbnN0IGN1cnJlbnRTZXJpYWxpemVkID0gSlNPTi5zdHJpbmdpZnkoY3VycmVudEdyaWQub3B0aW9ucz8ucmVwb3J0U3RhdGUgPz8gbnVsbCk7XG4gICAgY29uc3QgbmV3U2VyaWFsaXplZCA9IEpTT04uc3RyaW5naWZ5KHN0YXRlID8/IG51bGwpO1xuICAgIGlmIChjdXJyZW50U2VyaWFsaXplZCA9PT0gbmV3U2VyaWFsaXplZCkgcmV0dXJuO1xuXG4gICAgY29uc3QgdXBkYXRlZE9wdGlvbnMgPSB7XG4gICAgICAuLi4oY3VycmVudEdyaWQub3B0aW9ucyB8fCB7fSksXG4gICAgICBncm91cE1vZGVsOiBzdGF0ZS5ncm91cE1vZGVsID8/IGN1cnJlbnRHcmlkLm9wdGlvbnM/Lmdyb3VwTW9kZWwsXG4gICAgICBzb3J0TW9kZWw6IHN0YXRlLnNvcnRNb2RlbCA/PyBjdXJyZW50R3JpZC5vcHRpb25zPy5zb3J0TW9kZWwsXG4gICAgICByZXBvcnRTdGF0ZTogc3RhdGUsXG4gICAgfTtcbiAgICB0aGlzLmRlc2lnbmVyU3RhdGUudXBkYXRlR3JpZFNldHRpbmdzKHtcbiAgICAgIC4uLmN1cnJlbnRHcmlkLFxuICAgICAgb3B0aW9uczogdXBkYXRlZE9wdGlvbnMsXG4gICAgfSk7XG4gICAgdGhpcy5sYXlvdXRKdXN0VXBkYXRlZC5zZXQodHJ1ZSk7XG4gICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLmxheW91dEp1c3RVcGRhdGVkLnNldChmYWxzZSksIDEyMDApO1xuICB9XG5cbiAgb25DYW52YXNDb2x1bW5EZWZzQ2hhbmdlKGRlZnM6IGFueVtdKTogdm9pZCB7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KGRlZnMpIHx8ICF0aGlzLmRlZmluaXRpb24oKS5ncmlkKSByZXR1cm47XG4gICAgY29uc3QgY3VycmVudEdyaWQgPSB0aGlzLmRlZmluaXRpb24oKS5ncmlkITtcbiAgICBjb25zdCB1cGRhdGVkQ29scyA9IGN1cnJlbnRHcmlkLmNvbHVtbnMubWFwKChjKSA9PiB7XG4gICAgICBjb25zdCBtYXRjaCA9IGRlZnMuZmluZCgoZDogYW55KSA9PiBkLmZpZWxkID09PSBjLmZpZWxkKTtcbiAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLmMsXG4gICAgICAgICAgd2lkdGg6IG1hdGNoLndpZHRoID8gYCR7bWF0Y2gud2lkdGh9cHhgIDogYy53aWR0aCxcbiAgICAgICAgICB2aXNpYmxlOiBtYXRjaC5oaWRlICE9PSB0cnVlLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgcmV0dXJuIGM7XG4gICAgfSk7XG4gICAgdGhpcy5kZXNpZ25lclN0YXRlLnVwZGF0ZUdyaWRTZXR0aW5ncyh7XG4gICAgICAuLi5jdXJyZW50R3JpZCxcbiAgICAgIGNvbHVtbnM6IHVwZGF0ZWRDb2xzLFxuICAgIH0pO1xuICAgIHRoaXMubGF5b3V0SnVzdFVwZGF0ZWQuc2V0KHRydWUpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5sYXlvdXRKdXN0VXBkYXRlZC5zZXQoZmFsc2UpLCAxMjAwKTtcbiAgfVxuXG4gIHJlbW92ZUdyaWQoZXZlbnQ/OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQ/LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS51cGRhdGVHcmlkU2V0dGluZ3ModW5kZWZpbmVkKTtcbiAgfVxuXG4gIGFwcGx5Qmx1ZXByaW50KGJsdWVwcmludElkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBuZXdEZWYgPSB0aGlzLnRlbXBsYXRlU2VydmljZS5pbnN0YW50aWF0ZVRlbXBsYXRlKGJsdWVwcmludElkKTtcbiAgICB0aGlzLmRlc2lnbmVyU3RhdGUubG9hZERlZmluaXRpb24obmV3RGVmKTtcbiAgfVxuXG4gIGFkZFN0YXJ0ZXJDb21wb25lbnQodHlwZTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5kZXNpZ25lclN0YXRlLmFkZENvbXBvbmVudCh0eXBlKTtcbiAgfVxufVxuIiwiICAgIDxkaXYgY2xhc3M9XCJjYW52YXMtd3JhcHBlclwiIChjbGljayk9XCJvbkNhbnZhc0JhY2tncm91bmRDbGljaygkZXZlbnQpXCI+XG4gICAgICA8IS0tIENhbnZhcyBTdGF0dXMgLyBRdWljayBDb250cm9scyAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJjYW52YXMtdG9vbGJhclwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY2FudmFzLWluZm9cIj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImluZm8tbGFiZWxcIj5HcmlkIExheW91dDo8L3NwYW4+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJpbmZvLXZhbHVlXCI+e3sgdG90YWxDb2x1bW5zKCkgfX0gQ29sdW1uczwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImluZm8tZGl2aWRlclwiPuKAojwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImluZm8tbGFiZWxcIj5Db21wb25lbnRzOjwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImluZm8tdmFsdWVcIj57eyBjb21wb25lbnRzKCkubGVuZ3RoIH19PC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaW5mby1kaXZpZGVyXCI+4oCiPC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwibGl2ZS1tb2RlLWJhZGdlXCIgdGl0bGU9XCJJbnRlcmFjdGl2ZSBjYW52YXM6IFZhbHVlcyB0eXBlZCBoZXJlIHJ1biBsaXZlIHF1ZXJpZXMgYW5kIHRlc3QgZHJvcGRvd25zLlwiPlxuICAgICAgICAgICAg4pqhIExpdmUgSW50ZXJhY3RpdmUgTW9kZVxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNhbnZhcy1hY3Rpb25zXCI+XG4gICAgICAgICAgQGlmICghZGVmaW5pdGlvbigpLmdyaWQpIHtcbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgIGNsYXNzPVwiY2FudmFzLWFjdGlvbi1idG4gYnRuLWdyaWQtYWRkXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cImFkZFJlc3VsdEdyaWQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgIHRpdGxlPVwiQWRkIGEgUmVzdWx0IEdyaWQgdG8gdGhpcyByZXBvcnRcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cInRhYmxlXCIgW3NpemVdPVwiMTRcIiAvPlxuICAgICAgICAgICAgICA8c3Bhbj4rIEFkZCBHcmlkPC9zcGFuPlxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICBjbGFzcz1cImNhbnZhcy1hY3Rpb24tYnRuIGJ0bi1ncmlkLWNvbmZpZ3VyZWRcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwic2VsZWN0R3JpZFNldHRpbmdzKCRldmVudClcIlxuICAgICAgICAgICAgICB0aXRsZT1cIkNvbmZpZ3VyZSBSZXN1bHQgRGF0YSBHcmlkXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJ0YWJsZVwiIFtzaXplXT1cIjE0XCIgLz5cbiAgICAgICAgICAgICAgPHNwYW4+R3JpZCAoe3sgZGVmaW5pdGlvbigpLmdyaWQ/LmNvbHVtbnM/Lmxlbmd0aCA/PyAwIH19KTwvc3Bhbj5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIH1cblxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgY2xhc3M9XCJjYW52YXMtYWN0aW9uLWJ0blwiXG4gICAgICAgICAgICAoY2xpY2spPVwic2VsZWN0UmVwb3J0U2V0dGluZ3MoJGV2ZW50KVwiXG4gICAgICAgICAgICB0aXRsZT1cIkNvbmZpZ3VyZSBQYWdlIExheW91dCAmIEdyaWQgU2V0dGluZ3NcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwic2V0dGluZ3NcIiBbc2l6ZV09XCIxNFwiIC8+XG4gICAgICAgICAgICA8c3Bhbj5SZXBvcnQgU2V0dGluZ3M8L3NwYW4+XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gQ2FudmFzIERyb3AgQXJlYSAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJjYW52YXMtc2Nyb2xsLWFyZWFcIj5cbiAgICAgICAgPGRpdlxuICAgICAgICAgIGNsYXNzPVwiY2FudmFzLWFydGJvYXJkXCJcbiAgICAgICAgICBbc3R5bGUucGFkZGluZy5weF09XCJkZWZpbml0aW9uKCkubGF5b3V0LnBhZGRpbmcgPz8gMjRcIlxuICAgICAgICA+XG4gICAgICAgICAgPCEtLSBSZXBvcnQgSGVhZGVyIFByZXZpZXcgLS0+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImNhbnZhcy1yZXBvcnQtaGVhZGVyXCI+XG4gICAgICAgICAgICA8aDIgY2xhc3M9XCJjYW52YXMtcmVwb3J0LXRpdGxlXCI+e3sgZGVmaW5pdGlvbigpLm5hbWUgfHwgJ1VudGl0bGVkIFJlcG9ydCcgfX08L2gyPlxuICAgICAgICAgICAgQGlmIChkZWZpbml0aW9uKCkuZGVzY3JpcHRpb24pIHtcbiAgICAgICAgICAgICAgPHAgY2xhc3M9XCJjYW52YXMtcmVwb3J0LWRlc2NcIj57eyBkZWZpbml0aW9uKCkuZGVzY3JpcHRpb24gfX08L3A+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8IS0tIENvbXBvbmVudCBEcm9wIExpc3QgR3JpZCB3aXRoIDJEIG1peGVkIG9yaWVudGF0aW9uIGFuZCBkYXRhIGJpbmRpbmcgLS0+XG4gICAgICAgICAgPGRpdlxuICAgICAgICAgICAgY2RrRHJvcExpc3RcbiAgICAgICAgICAgIGlkPVwiZGVzaWduZXItY2FudmFzLWRyb3AtbGlzdFwiXG4gICAgICAgICAgICBjbGFzcz1cImNhbnZhcy1ncmlkXCJcbiAgICAgICAgICAgIGNka0Ryb3BMaXN0T3JpZW50YXRpb249XCJtaXhlZFwiXG4gICAgICAgICAgICBbY2RrRHJvcExpc3REYXRhXT1cInNvcnRlZENvbXBvbmVudHMoKVwiXG4gICAgICAgICAgICBbc3R5bGUuZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zXT1cImdyaWRUZW1wbGF0ZUNvbHVtbnMoKVwiXG4gICAgICAgICAgICBbc3R5bGUuZ2FwLnB4XT1cImRlZmluaXRpb24oKS5sYXlvdXQuZ2FwID8/IDE2XCJcbiAgICAgICAgICAgIChjZGtEcm9wTGlzdERyb3BwZWQpPVwib25Ecm9wKCRldmVudClcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIEBmb3IgKGNvbXAgb2Ygc29ydGVkQ29tcG9uZW50cygpOyB0cmFjayBjb21wLmlkOyBsZXQgaWR4ID0gJGluZGV4KSB7XG4gICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICBjZGtEcmFnXG4gICAgICAgICAgICAgICAgW2Nka0RyYWdEYXRhXT1cImNvbXBcIlxuICAgICAgICAgICAgICAgIFtjZGtEcmFnRGlzYWJsZWRdPVwiaXNBbnlSZXNpemluZygpXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cImNhbnZhcy1jb21wb25lbnQtY2FyZFwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLmlzLXNlbGVjdGVkXT1cImlzU2VsZWN0ZWQoY29tcC5pZClcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1yZXNpemluZ109XCJyZXNpemluZ0NvbXBJZCgpID09PSBjb21wLmlkXCJcbiAgICAgICAgICAgICAgICBbY2xhc3MuaXMtZmllbGQtaGlnaGxpZ2h0ZWRdPVwiaXNGaWVsZEhpZ2hsaWdodGVkKGNvbXApXCJcbiAgICAgICAgICAgICAgICBbY2xhc3MuaXMtbmFycm93XT1cImdldFNwYW4oY29tcCkgPD0gNFwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLmlzLWNvbXBhY3RdPVwiZ2V0U3Bhbihjb21wKSA8PSAyXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUuZ3JpZC1jb2x1bW5dPVwiZ2V0R3JpZENvbHVtbihjb21wKVwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLmdyaWQtcm93XT1cImdldEdyaWRSb3coY29tcClcIlxuICAgICAgICAgICAgICAgIFtzdHlsZS53aWR0aF09XCJjb21wLmxheW91dD8ud2lkdGggfHwgJ2F1dG8nXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUuaGVpZ2h0XT1cImdldENvbXBvbmVudEhlaWdodChjb21wKVwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLm1pbi1oZWlnaHRdPVwiZ2V0Q29tcG9uZW50TWluSGVpZ2h0KGNvbXApXCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwib25TZWxlY3QoY29tcC5pZCwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8IS0tIENhcmQgSGVhZGVyIHdpdGggRHJhZyBIYW5kbGUgJiBBY3Rpb25zIC0tPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYXJkLWhlYWRlclwiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQtdGl0bGUtZ3JvdXBcIiBjZGtEcmFnSGFuZGxlIHRpdGxlPVwiRHJhZyB0byByZW9yZGVyXCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZHJhZy1oYW5kbGUtZG90c1wiPuKLruKLrjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIFtuYW1lXT1cImdldENvbXBvbmVudEljb25OYW1lKGNvbXAudHlwZSlcIiBbc2l6ZV09XCIxNFwiIC8+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY29tcC10aXRsZVwiIFt0aXRsZV09XCJjb21wLmxhYmVsIHx8IGNvbXAua2V5IHx8IGNvbXAudHlwZVwiPlxuICAgICAgICAgICAgICAgICAgICAgIHt7IGNvbXAubGFiZWwgfHwgY29tcC5rZXkgfHwgY29tcC50eXBlIH19XG4gICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FyZC1hY3Rpb25zXCI+XG4gICAgICAgICAgICAgICAgICAgIDwhLS0gU3RhdGljIHNwYW4gcGlsbCAmIG5ldyByb3cgLyBzdGFydCBjb2wgcGlsbCB3aGVuIG5vdCBob3ZlcmVkIC8gbm90IHNlbGVjdGVkIC0tPlxuICAgICAgICAgICAgICAgICAgICBAaWYgKGNvbXAubGF5b3V0Py5jb2x1bW47IGFzIGNvbCkge1xuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibmV3LXJvdy1waWxsLXN0YXRpY1wiIHRpdGxlPVwiU3RhcnRzIGF0IENvbHVtbiB7eyBjb2wgfX1cIj5Db2wge3sgY29sIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICB9IEBlbHNlIGlmIChjb21wLmxheW91dD8ubmV3Um93KSB7XG4gICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJuZXctcm93LXBpbGwtc3RhdGljXCIgdGl0bGU9XCJTdGFydHMgb24gc2VwYXJhdGUgcm93XCI+4oazIFJvdzwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwic3Bhbi1waWxsLXN0YXRpY1wiXG4gICAgICAgICAgICAgICAgICAgICAgdGl0bGU9XCJDb2x1bW4gc3Bhbjoge3sgZ2V0U3Bhbihjb21wKSB9fSBvZiB7eyB0b3RhbENvbHVtbnMoKSB9fSBjb2x1bW5zXCJcbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgIHt7IGdldFNwYW4oY29tcCkgfX0ve3sgdG90YWxDb2x1bW5zKCkgfX1cbiAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gUXVpY2sgQWN0aW9uIFN0ZXBwZXIgJiBCdXR0b25zIChyZXZlYWxlZCBvbiBob3ZlciBvciBzZWxlY3Rpb24pIC0tPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FyZC1xdWljay1jb250cm9sc1wiPlxuICAgICAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjYXJkLWFjdGlvbi1idG5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmJ0bi1hY3RpdmUtdG9nZ2xlXT1cImNvbXAubGF5b3V0Py5uZXdSb3dcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInRvZ2dsZU5ld1Jvdyhjb21wLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlPVwie3sgY29tcC5sYXlvdXQ/Lm5ld1JvdyA/ICdTdGFydHMgb24gbmV3IHJvdyAoQ2xpY2sgdG8gcGxhY2UgaW5saW5lKScgOiAnU3RhcnQgb24gc2VwYXJhdGUgcm93IChSb3cgQnJlYWspJyB9fVwiXG4gICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJjb3JuZXItZG93bi1yaWdodFwiIFtzaXplXT1cIjExXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cblxuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzcGFuLWNvbnRyb2wtZ3JvdXBcIiB0aXRsZT1cIkFkanVzdCBDb2x1bW4gU3BhblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJzcGFuLWJ0blwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJnZXRTcGFuKGNvbXApIDw9IDFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYWRqdXN0U3Bhbihjb21wLCAtMSwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlPVwiU2hyaW5rIENvbHVtbiBTcGFuXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJtaW51c1wiIFtzaXplXT1cIjlcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNwYW4tYmFkZ2VcIiBbdGl0bGVdPVwiJ0NvbHVtbiBzcGFuOiAnICsgZ2V0U3Bhbihjb21wKSArICcgb2YgJyArIHRvdGFsQ29sdW1ucygpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3Bhbi1udW1cIj57eyBnZXRTcGFuKGNvbXApIH19PC9zcGFuPjxzcGFuIGNsYXNzPVwic3Bhbi10b3RhbFwiPi97eyB0b3RhbENvbHVtbnMoKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwic3Bhbi1idG5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiZ2V0U3Bhbihjb21wKSA+PSB0b3RhbENvbHVtbnMoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJhZGp1c3RTcGFuKGNvbXAsIDEsICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIkV4cGFuZCBDb2x1bW4gU3BhblwiXG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwicGx1c1wiIFtzaXplXT1cIjlcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY2FyZC1hY3Rpb24tYnRuXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJvbkR1cGxpY2F0ZShjb21wLmlkLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlPVwiRHVwbGljYXRlIGNvbXBvbmVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJjb3B5XCIgW3NpemVdPVwiMTJcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjYXJkLWFjdGlvbi1idG4gYnRuLWRlbGV0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwib25EZWxldGUoY29tcC5pZCwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIlJlbW92ZSBjb21wb25lbnRcIlxuICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwidHJhc2hcIiBbc2l6ZV09XCIxMlwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8IS0tIENhcmQgQm9keSBWaXN1YWwgUHJldmlldyAtLT5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FyZC1ib2R5XCI+XG5cbiAgICAgICAgICAgICAgICAgIEBzd2l0Y2ggKGNvbXAudHlwZSkge1xuICAgICAgICAgICAgICAgICAgICBAY2FzZSAoJ2lucHV0Jykge1xuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2NrLWlucHV0LWZpZWxkXCIgKGNsaWNrKT1cIm9uQ29udHJvbEludGVyYWN0KGNvbXAsICRldmVudClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibW9jay1sYWJlbFwiPnt7IGNvbXAubGFiZWwgfHwgJ0lucHV0JyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoZ2V0Q2FudmFzQ29udHJvbChjb21wKTsgYXMgY3RybCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjYW52YXMtYWN0aXZlLWlucHV0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiY29tcC5wcm9wZXJ0aWVzPy5bJ3BsYWNlaG9sZGVyJ10gfHwgJ0VudGVyIHRleHQuLi4nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwiY3RybFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZvY3VzKT1cIm9uQ29udHJvbEludGVyYWN0KGNvbXAsICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2NrLWlucHV0LWJveFwiPnt7IGNvbXAucHJvcGVydGllcz8uWydwbGFjZWhvbGRlciddIHx8ICdFbnRlciB0ZXh0Li4uJyB9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEBjYXNlICgnZHJvcGRvd24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhbnZhcy1saXZlLWNvbnRyb2wtd3JhcHBlclwiIChjbGljayk9XCJvbkNvbnRyb2xJbnRlcmFjdChjb21wLCAkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8cnB0LWRyb3Bkb3duXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtjb25maWddPVwiY29tcFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93U3RhdHVzXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbcGFyZW50Rm9ybV09XCJjYW52YXNGb3JtKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbY29udHJvbF09XCJnZXRDYW52YXNDb250cm9sKGNvbXApXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGNhc2UgKCdkYXRlJykge1xuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2NrLWlucHV0LWZpZWxkXCIgKGNsaWNrKT1cIm9uQ29udHJvbEludGVyYWN0KGNvbXAsICRldmVudClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibW9jay1sYWJlbFwiPnt7IGNvbXAubGFiZWwgfHwgJ0RhdGUnIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChnZXRDYW52YXNDb250cm9sKGNvbXApOyBhcyBjdHJsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJkYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNhbnZhcy1hY3RpdmUtaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJjdHJsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZm9jdXMpPVwib25Db250cm9sSW50ZXJhY3QoY29tcCwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2stc2VsZWN0LWJveFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPllZWVktTU0tREQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJjYWxlbmRhclwiIFtzaXplXT1cIjEyXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGNhc2UgKCdkYXRlLXJhbmdlJykge1xuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYW52YXMtbGl2ZS1jb250cm9sLXdyYXBwZXJcIiAoY2xpY2spPVwib25Db250cm9sSW50ZXJhY3QoY29tcCwgJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHJwdC1kYXRlLXJhbmdlXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtjb25maWddPVwiY29tcFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtjb250cm9sXT1cImdldENhbnZhc0NvbnRyb2woY29tcClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBAY2FzZSAoJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1pbnB1dC1maWVsZFwiIChjbGljayk9XCJvbkNvbnRyb2xJbnRlcmFjdChjb21wLCAkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1vY2stbGFiZWxcIj57eyBjb21wLmxhYmVsIHx8ICdOdW1iZXInIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChnZXRDYW52YXNDb250cm9sKGNvbXApOyBhcyBjdHJsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJudW1iZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY2FudmFzLWFjdGl2ZS1pbnB1dFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Zvcm1Db250cm9sXT1cImN0cmxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmb2N1cyk9XCJvbkNvbnRyb2xJbnRlcmFjdChjb21wLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1pbnB1dC1ib3hcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBjb21wLnByb3BlcnRpZXM/LlsncHJlZml4J10gfHwgJycgfX0gMC4wMCB7eyBjb21wLnByb3BlcnRpZXM/Llsnc3VmZml4J10gfHwgJycgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGNhc2UgKCdjaGVja2JveCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1jaGVja2JveC1maWVsZFwiIChjbGljayk9XCJvbkNvbnRyb2xJbnRlcmFjdChjb21wLCAkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBAaWYgKGdldENhbnZhc0NvbnRyb2woY29tcCk7IGFzIGN0cmwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY2FudmFzLWFjdGl2ZS1jaGVja2JveC1sYmxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgW2Zvcm1Db250cm9sXT1cImN0cmxcIiAoZm9jdXMpPVwib25Db250cm9sSW50ZXJhY3QoY29tcCwgJGV2ZW50KVwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtb2NrLWxhYmVsXCI+e3sgY29tcC5sYWJlbCB8fCAnQ2hlY2tib3gnIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibW9jay1jaGVjay1ib3hcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cImNoZWNrXCIgW3NpemVdPVwiMTBcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibW9jay1sYWJlbFwiPnt7IGNvbXAubGFiZWwgfHwgJ0NoZWNrYm94JyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBAY2FzZSAoJ2J1dHRvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1idG4td3JhcHBlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJtb2NrLWJ0blwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzc109XCInYnRuLScgKyAoY29tcC5wcm9wZXJ0aWVzPy5bJ3ZhcmlhbnQnXSB8fCAncHJpbWFyeScpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLm1vY2stYnRuLWZ1bGxdPVwiY29tcC5wcm9wZXJ0aWVzPy5bJ2Z1bGxXaWR0aCddID09PSB0cnVlIHx8IGNvbXAubGF5b3V0Py53aWR0aCA9PT0gJzEwMCUnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlLmhlaWdodF09XCJnZXRDdXN0b21CdG5IZWlnaHQoY29tcClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiZ2V0Q3VzdG9tQnRuV2lkdGgoY29tcClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwib25DYW52YXNCdXR0b25DbGljayhjb21wLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChnZXRDdXN0b21CdG5JY29uKGNvbXApOyBhcyBidG5JY29uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIFtuYW1lXT1cImJ0bkljb25cIiBbc2l6ZV09XCIxNVwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+e3sgY29tcC5sYWJlbCB8fCAnQnV0dG9uJyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEBjYXNlICgna3BpLWNhcmQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2sta3BpLWZpZWxkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1rcGktaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibW9jay1sYWJlbFwiPnt7IGNvbXAubGFiZWwgfHwgJ0tQSSBNZXRyaWMnIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cImtwaVwiIFtzaXplXT1cIjE0XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2sta3BpLXZhbHVlXCI+e3sgY29tcC5wcm9wZXJ0aWVzPy5bJ3ZhbHVlJ10gfHwgJyQxMjgsNDUwJyB9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2sta3BpLWZvb3RlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1vY2sta3BpLXRyZW5kXCI+KzEyLjUlPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1vY2sta3BpLXN1YlwiPnZzIGxhc3QgcGVyaW9kPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGNhc2UgKCdjaGFydCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1jaGFydC1maWVsZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2stY2hhcnQtaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibW9jay1sYWJlbFwiPnt7IGNvbXAubGFiZWwgfHwgJ1F1YXJ0ZXJseSBTYWxlcyBSZXZlbnVlICgkMDAwKScgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2NrLWNoYXJ0LWJhcnNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2stY2hhcnQtY29sXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2stY2hhcnQtYmFyXCIgc3R5bGU9XCJoZWlnaHQ6IDQ0JVwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibW9jay1iYXItbGJsXCI+UTEgSmFuLU1hcjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2NrLWNoYXJ0LWNvbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2NrLWNoYXJ0LWJhclwiIHN0eWxlPVwiaGVpZ2h0OiA2MSVcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1vY2stYmFyLWxibFwiPlEyIEFwci1KdW48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1jaGFydC1jb2xcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1jaGFydC1iYXJcIiBzdHlsZT1cImhlaWdodDogNzklXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtb2NrLWJhci1sYmxcIj5RMyBKdWwtU2VwPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2stY2hhcnQtY29sXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2stY2hhcnQtYmFyXCIgc3R5bGU9XCJoZWlnaHQ6IDEwMCVcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1vY2stYmFyLWxibFwiPlE0IE9jdC1EZWM8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGRlZmF1bHQge1xuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2NrLWdlbmVyaWMtYm94XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj57eyBjb21wLnR5cGUgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDwhLS0gUmVzaXppbmcgSGFuZGxlcyAoRWFzdCwgU291dGgsIFNvdXRoLUVhc3QpIC0tPlxuICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwicmVzaXplLWhhbmRsZSBoYW5kbGUtZVwiXG4gICAgICAgICAgICAgICAgICAocG9pbnRlcmRvd24pPVwic3RhcnRSZXNpemUoJGV2ZW50LCBjb21wLCAnZScpXCJcbiAgICAgICAgICAgICAgICAgIChkYmxjbGljayk9XCJyZXNldERpbWVuc2lvbnMoY29tcCwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICB0aXRsZT1cIkRyYWcgdG8gcmVzaXplIGNvbHVtbiB3aWR0aCDigKIgRG91YmxlLWNsaWNrIHRvIHJlc2V0XCJcbiAgICAgICAgICAgICAgICA+PC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJyZXNpemUtaGFuZGxlIGhhbmRsZS1zXCJcbiAgICAgICAgICAgICAgICAgIChwb2ludGVyZG93bik9XCJzdGFydFJlc2l6ZSgkZXZlbnQsIGNvbXAsICdzJylcIlxuICAgICAgICAgICAgICAgICAgKGRibGNsaWNrKT1cInJlc2V0RGltZW5zaW9ucyhjb21wLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgIHRpdGxlPVwiRHJhZyB0byByZXNpemUgaGVpZ2h0IOKAoiBEb3VibGUtY2xpY2sgdG8gcmVzZXRcIlxuICAgICAgICAgICAgICAgID48L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICBjbGFzcz1cInJlc2l6ZS1oYW5kbGUgaGFuZGxlLXNlXCJcbiAgICAgICAgICAgICAgICAgIChwb2ludGVyZG93bik9XCJzdGFydFJlc2l6ZSgkZXZlbnQsIGNvbXAsICdzZScpXCJcbiAgICAgICAgICAgICAgICAgIChkYmxjbGljayk9XCJyZXNldERpbWVuc2lvbnMoY29tcCwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICB0aXRsZT1cIkRyYWcgdG8gcmVzaXplIHdpZHRoIGFuZCBoZWlnaHQg4oCiIERvdWJsZS1jbGljayB0byByZXNldFwiXG4gICAgICAgICAgICAgICAgPjwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPCEtLSBSZXNpemluZyBEaW1lbnNpb24gR2hvc3QgLyBCYWRnZSAtLT5cbiAgICAgICAgICAgICAgICBAaWYgKHJlc2l6aW5nQ29tcElkKCkgPT09IGNvbXAuaWQpIHtcbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZXNpemUtZGltZW5zaW9uLXRvb2x0aXBcIj5cbiAgICAgICAgICAgICAgICAgICAge3sgcmVzaXppbmdUb29sdGlwKGNvbXApIH19XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICA8IS0tIERyYWcgcGxhY2Vob2xkZXIgd2l0aCBtYXRjaGVkIGdyaWQgY29sdW1uIHNwYW4gLS0+XG4gICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgKmNka0RyYWdQbGFjZWhvbGRlclxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjYW52YXMtZHJhZy1wbGFjZWhvbGRlclwiXG4gICAgICAgICAgICAgICAgICBbc3R5bGUuZ3JpZC1jb2x1bW5dPVwiZ2V0R3JpZENvbHVtbihjb21wKVwiXG4gICAgICAgICAgICAgICAgPjwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPCEtLSBEcmFnIHByZXZpZXcgLS0+XG4gICAgICAgICAgICAgICAgPGRpdiAqY2RrRHJhZ1ByZXZpZXcgY2xhc3M9XCJjYW52YXMtZHJhZy1wcmV2aWV3XCI+XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRyYWctaGFuZGxlLWRvdHNcIj7ii67ii648L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8cnB0LWljb24gW25hbWVdPVwiZ2V0Q29tcG9uZW50SWNvbk5hbWUoY29tcC50eXBlKVwiIFtzaXplXT1cIjE0XCIgLz5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicHJldmlldy10aXRsZVwiPnt7IGNvbXAubGFiZWwgfHwgY29tcC5rZXkgfHwgY29tcC50eXBlIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJwcmV2aWV3LXNwYW5cIj57eyBnZXRTcGFuKGNvbXApIH19L3t7IHRvdGFsQ29sdW1ucygpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgQGlmIChjb21wb25lbnRzKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYW52YXMtZW1wdHktc3RhdGVcIiByb2xlPVwicmVnaW9uXCIgYXJpYS1sYWJlbD1cIkVtcHR5IGNhbnZhcyBzdGFydGVyIG9wdGlvbnNcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZW1wdHktaGVyby1iYWRnZVwiPlxuICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJkZXNpZ25cIiBbc2l6ZV09XCIyOFwiIC8+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwiZW1wdHktaGVyby10aXRsZVwiPlN0YXJ0IERlc2lnbmluZyBZb3VyIEN1c3RvbSBSZXBvcnQ8L2gzPlxuICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwiZW1wdHktaGVyby1kZXNjXCI+XG4gICAgICAgICAgICAgICAgICBEcmFnIGNvbnRyb2xzIGZyb20gdGhlIGxlZnQgY29tcG9uZW50IHBhbGV0dGUsIG9yIGp1bXBzdGFydCB5b3VyIGRlc2lnbiB3aXRoIHByZS1jb25maWd1cmVkIGVudGVycHJpc2UgYmx1ZXByaW50cy5cbiAgICAgICAgICAgICAgICA8L3A+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZW1wdHktaGVyby1hY3Rpb25zXCI+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImVtcHR5LWJ0biBlbXB0eS1idG4tcHJpbWFyeVwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJhcHBseUJsdWVwcmludCgnYmx1ZXByaW50LWF1ZGl0LXJlZ2lzdGVyJylcIlxuICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIkxvYWQgY29tcGxldGUgQXVkaXQgUmVnaXN0ZXIgYmx1ZXByaW50IHdpdGggcGFyYW1ldGVycyBhbmQgcmVzdWx0IGdyaWRcIlxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cInRhYmxlXCIgW3NpemVdPVwiMTVcIiAvPlxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj5BdWRpdCBSZWdpc3RlciBCbHVlcHJpbnQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZW1wdHktYnRuIGVtcHR5LWJ0bi1zZWNvbmRhcnlcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYXBwbHlCbHVlcHJpbnQoJ2JsdWVwcmludC1rcGktc3VtbWFyeScpXCJcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU9XCJMb2FkIEV4ZWN1dGl2ZSBLUEkgc3VtbWFyeSBibHVlcHJpbnRcIlxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cImNoYXJ0LWJhclwiIFtzaXplXT1cIjE1XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+S1BJIFN1bW1hcnkgQmx1ZXByaW50PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImVtcHR5LWJ0biBlbXB0eS1idG4tb3V0bGluZVwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJhZGRTdGFydGVyQ29tcG9uZW50KCdkYXRlLXJhbmdlJylcIlxuICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIkFkZCBhIERhdGUgUmFuZ2UgZmlsdGVyIGNvbXBvbmVudFwiXG4gICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwiY2FsZW5kYXJcIiBbc2l6ZV09XCIxNFwiIC8+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuPisgQWRkIERhdGUgRmlsdGVyPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImVtcHR5LWJ0biBlbXB0eS1idG4tb3V0bGluZVwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJhZGRTdGFydGVyQ29tcG9uZW50KCdidXR0b24nKVwiXG4gICAgICAgICAgICAgICAgICAgIHRpdGxlPVwiQWRkIGFuIEV4ZWN1dGUgQWN0aW9uIGJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwicGxheVwiIFtzaXplXT1cIjE0XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+KyBBZGQgUnVuIEJ1dHRvbjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDwhLS0gTGl2ZSBSZXN1bHQgR3JpZCBQcmV2aWV3IHdpdGggQndheXMtR3JpZCBGZWF0dXJlcyAtLT5cbiAgICAgICAgICBAaWYgKGRlZmluaXRpb24oKS5ncmlkKSB7XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FudmFzLWdyaWQtYm94XCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJncmlkLXByZXZpZXctaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogOHB4O1wiPlxuICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJ0YWJsZVwiIFtzaXplXT1cIjE1XCIgLz5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZ3JpZC10aXRsZVwiPkJ3YXlzIEdyaWQgKHt7IGRlZmluaXRpb24oKS5ncmlkPy5jb2x1bW5zPy5sZW5ndGggPz8gMCB9fSBjb2x1bW5zKTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIEBpZiAoaXNFeGVjdXRpbmdHcmlkKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJncmlkLWV4ZWMtYmFkZ2UgaXMtbG9hZGluZ1wiPkxvYWRpbmcgZGF0YSBmcm9tIGRhdGFiYXNlLi4uPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgfSBAZWxzZSBpZiAoZ3JpZEV4ZWNFcnJvcigpKSB7XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZ3JpZC1leGVjLWJhZGdlIGlzLWVycm9yXCI+e3sgZ3JpZEV4ZWNFcnJvcigpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgfSBAZWxzZSBpZiAoY2FudmFzR3JpZERhdGEoKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZ3JpZC1leGVjLWJhZGdlIGlzLXN1Y2Nlc3NcIj57eyBjYW52YXNHcmlkRGF0YSgpLmxlbmd0aCB9fSByb3dzIGxvYWRlZDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiA4cHg7XCI+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImJ0bi1jYW52YXMtcnVuLWdyaWRcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiZXhlY3V0ZUNhbnZhc1JlcG9ydCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImlzRXhlY3V0aW5nR3JpZCgpXCJcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU9XCJFeGVjdXRlIHF1ZXJ5IGFuZCBsb2FkIGRhdGEgaW50byBCd2F5cyBHcmlkXCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJwbGF5XCIgW3NpemVdPVwiMTFcIiAvPlxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj57eyBpc0V4ZWN1dGluZ0dyaWQoKSA/ICdSdW5uaW5nLi4uJyA6ICdSdW4gLyBSZWZyZXNoIEdyaWQnIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImJ0bi1jYW52YXMtZWRpdC1ncmlkXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInNlbGVjdEdyaWRTZXR0aW5ncygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU9XCJDb25maWd1cmUgY29sdW1ucyBhbmQgZ3JpZCBvcHRpb25zXCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJzZXR0aW5nc1wiIFtzaXplXT1cIjExXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+Q29uZmlndXJlPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImJ0bi1yZW1vdmUtZ3JpZFwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJyZW1vdmVHcmlkKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIlJlbW92ZSBSZXN1bHQgR3JpZCBmcm9tIHRoaXMgcmVwb3J0XCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJ0cmFzaFwiIFtzaXplXT1cIjEzXCIgLz5cbiAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICBAaWYgKGdldEdyaWRTdW1tYXJ5VGV4dCgpOyBhcyBzdW1tYXJ5KSB7XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImdyaWQtbGF5b3V0LXN0YXR1cy1zdHJpcFwiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImdyaWQtc3RhdHVzLWluZm9cIj5cbiAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJ0YWJsZVwiIFtzaXplXT1cIjEyXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+e3sgc3VtbWFyeSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImdyaWQtc3RhdHVzLXN5bmNcIiBbY2xhc3MuaXMtcHVsc2luZ109XCJsYXlvdXRKdXN0VXBkYXRlZCgpXCI+XG4gICAgICAgICAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwiY2hlY2tcIiBbc2l6ZV09XCIxMVwiIC8+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuPkxheW91dCBhdXRvLXBlcnNpc3RlZDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgPCEtLSBMaXZlIEJ3YXlzIEdyaWQgYnJpZGdlIC0tPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FudmFzLWxpdmUtZ3JpZC1jb250YWluZXJcIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgICAgICAgICAgICAgPHJwdC1ncmlkLWJyaWRnZVxuICAgICAgICAgICAgICAgICAgW2dyaWREZWZpbml0aW9uXT1cImRlZmluaXRpb24oKS5ncmlkIVwiXG4gICAgICAgICAgICAgICAgICBbZGF0YV09XCJjYW52YXNHcmlkRGF0YSgpXCJcbiAgICAgICAgICAgICAgICAgIChncmlkU3RhdGVDaGFuZ2UpPVwib25DYW52YXNHcmlkU3RhdGVDaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAoY29sdW1uRGVmc0NoYW5nZSk9XCJvbkNhbnZhc0NvbHVtbkRlZnNDaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYW52YXMtYWRkLWdyaWQtYmFubmVyXCIgKGNsaWNrKT1cImFkZFJlc3VsdEdyaWQoJGV2ZW50KVwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWRkLWdyaWQtaWNvblwiPlxuICAgICAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwidGFibGVcIiBbc2l6ZV09XCIyMFwiIC8+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYWRkLWdyaWQtdGV4dFwiPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYWRkLWdyaWQtdGl0bGVcIj4rIEFkZCBSZXN1bHQgRGF0YSBHcmlkPC9zcGFuPlxuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYWRkLWdyaWQtc3ViXCI+QXR0YWNoIGFuIGludGVyYWN0aXZlIGRhdGEgdGFibGUgb3IgVWx0cmFHcmlkIHRvIGRpc3BsYXkgcmVwb3J0IGV4ZWN1dGlvbiBvdXRwdXQ8L3NwYW4+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImJ0bi1iYW5uZXItYWRkXCI+QWRkIEdyaWQ8L2J1dHRvbj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIH1cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj4iXX0=
|
|
471
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVzaWduLWNhbnZhcy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9id2F5cy1yZXBvcnQvc3JjL2xpYi9mZWF0dXJlcy9kZXNpZ25lci9jb21wb25lbnRzL2Rlc2lnbi1jYW52YXMvZGVzaWduLWNhbnZhcy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9id2F5cy1yZXBvcnQvc3JjL2xpYi9mZWF0dXJlcy9kZXNpZ25lci9jb21wb25lbnRzL2Rlc2lnbi1jYW52YXMvZGVzaWduLWNhbnZhcy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxRQUFRLEVBQ1IsWUFBWSxFQUNaLE1BQU0sRUFFTixNQUFNLEdBRVAsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0UsT0FBTyxFQU9MLGNBQWMsR0FDZixNQUFNLHdCQUF3QixDQUFDO0FBQ2hDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQzdFLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBSS9FLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDJEQUEyRCxDQUFDO0FBQzdGLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLG1FQUFtRSxDQUFDO0FBQ3pHLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHVFQUF1RSxDQUFDO0FBQzlHLE9BQU8sRUFBRSx5QkFBeUIsRUFBRSxNQUFNLCtDQUErQyxDQUFDO0FBQzFGLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFN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QUMxQixtQkFJZ0IsdUJBQXVCLENBQUMsTUFBTTs4QkFxTC9DLFFBQVE7c0JBRFAsWUFBWTt1QkFBQyx5QkFBeUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ29tcG9uZW50LFxuICBjb21wdXRlZCxcbiAgSG9zdExpc3RlbmVyLFxuICBpbmplY3QsXG4gIE9uRGVzdHJveSxcbiAgc2lnbmFsLFxuICB1bnRyYWNrZWQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IFJlYWN0aXZlRm9ybXNNb2R1bGUsIEZvcm1Db250cm9sLCBGb3JtR3JvdXAgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQge1xuICBDZGtEcmFnLFxuICBDZGtEcmFnRHJvcCxcbiAgQ2RrRHJhZ0hhbmRsZSxcbiAgQ2RrRHJhZ1BsYWNlaG9sZGVyLFxuICBDZGtEcmFnUHJldmlldyxcbiAgQ2RrRHJvcExpc3QsXG4gIERyYWdEcm9wTW9kdWxlLFxufSBmcm9tICdAYW5ndWxhci9jZGsvZHJhZy1kcm9wJztcbmltcG9ydCB7IERlc2lnbmVyU3RhdGVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvZGVzaWduZXItc3RhdGUuc2VydmljZSc7XG5pbXBvcnQgeyBSZXBvcnRUZW1wbGF0ZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9yZXBvcnQtdGVtcGxhdGUuc2VydmljZSc7XG5pbXBvcnQgeyBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uIH0gZnJvbSAnLi4vLi4vLi4vLi4vY29yZS9tb2RlbHMvcmVwb3J0LWNvbXBvbmVudC5tb2RlbCc7XG5pbXBvcnQgeyBDb21wb25lbnRMYXlvdXREZWZpbml0aW9uIH0gZnJvbSAnLi4vLi4vLi4vLi4vY29yZS9tb2RlbHMvcmVwb3J0LWxheW91dC5tb2RlbCc7XG5pbXBvcnQgeyBSZXBvcnRHcmlkRGVmaW5pdGlvbiB9IGZyb20gJy4uLy4uLy4uLy4uL2NvcmUvbW9kZWxzL3JlcG9ydC1ncmlkLm1vZGVsJztcbmltcG9ydCB7IFJwdEljb25Db21wb25lbnQgfSBmcm9tICcuLi8uLi8uLi8uLi9wcmltaXRpdmVzL2NvbXBvbmVudHMvaWNvbi9ycHQtaWNvbi5jb21wb25lbnQnO1xuaW1wb3J0IHsgUnB0RHJvcGRvd25Db21wb25lbnQgfSBmcm9tICcuLi8uLi8uLi8uLi9wcmltaXRpdmVzL2NvbXBvbmVudHMvZHJvcGRvd24vcnB0LWRyb3Bkb3duLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBScHREYXRlUmFuZ2VDb21wb25lbnQgfSBmcm9tICcuLi8uLi8uLi8uLi9wcmltaXRpdmVzL2NvbXBvbmVudHMvZGF0ZS1yYW5nZS9ycHQtZGF0ZS1yYW5nZS5jb21wb25lbnQnO1xuaW1wb3J0IHsgUmVwb3J0R3JpZEJyaWRnZUNvbXBvbmVudCB9IGZyb20gJy4uLy4uLy4uL3J1bnRpbWUvcmVwb3J0LWdyaWQtYnJpZGdlLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBEeW5hbWljRm9ybUJ1aWxkZXIgfSBmcm9tICcuLi8uLi8uLi8uLi9jb3JlL3NlcnZpY2VzL2R5bmFtaWMtZm9ybS1idWlsZGVyLnNlcnZpY2UnO1xuaW1wb3J0IHsgUmVwb3J0RXhlY3V0aW9uU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3J1bnRpbWUvcmVwb3J0LWV4ZWN1dGlvbi5zZXJ2aWNlJztcbmltcG9ydCB7XG4gIGNhbGN1bGF0ZUdyaWRDb2x1bW4sXG4gIGNhbGN1bGF0ZUdyaWRSb3csXG4gIGNhbGN1bGF0ZVNuYXBwZWRIZWlnaHQsXG4gIGNhbGN1bGF0ZVNuYXBwZWRTcGFuLFxuICBDQU5WQVNfQ0FSRF9PVkVSSEVBRCxcbiAgZ2V0Q29tcG9uZW50SWNvbk5hbWUsXG4gIGdldENvbXBvbmVudE5hdHVyYWxNaW5IZWlnaHQsXG4gIHJlc29sdmVDYW52YXNDYXJkSGVpZ2h0LFxuICByZXNvbHZlQ2FudmFzQ2FyZE1pbkhlaWdodCxcbiAgcmVzb2x2ZUNvbXBvbmVudFNwYW4sXG59IGZyb20gJy4uLy4uL3V0aWxpdGllcy9jYW52YXMtbGF5b3V0LnV0aWwnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdycHQtZGVzaWduLWNhbnZhcycsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBDb21tb25Nb2R1bGUsXG4gICAgRHJhZ0Ryb3BNb2R1bGUsXG4gICAgUmVhY3RpdmVGb3Jtc01vZHVsZSxcbiAgICBScHRJY29uQ29tcG9uZW50LFxuICAgIFJwdERyb3Bkb3duQ29tcG9uZW50LFxuICAgIFJwdERhdGVSYW5nZUNvbXBvbmVudCxcbiAgICBSZXBvcnRHcmlkQnJpZGdlQ29tcG9uZW50LFxuICBdLFxuXG4gIHRlbXBsYXRlVXJsOiAnLi9kZXNpZ24tY2FudmFzLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmw6ICcuL2Rlc2lnbi1jYW52YXMuY29tcG9uZW50LmNzcycsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBEZXNpZ25DYW52YXNDb21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICBwcml2YXRlIHJlYWRvbmx5IGRlc2lnbmVyU3RhdGUgPSBpbmplY3QoRGVzaWduZXJTdGF0ZVNlcnZpY2UpO1xuICBwcml2YXRlIGdyaWRGaWx0ZXJEZWJvdW5jZVRpbWVyOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PiB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHBlbmRpbmdHcmlkU3RhdGU6IGFueSA9IG51bGw7XG4gIHByaXZhdGUgcmVhZG9ubHkgdGVtcGxhdGVTZXJ2aWNlID0gaW5qZWN0KFJlcG9ydFRlbXBsYXRlU2VydmljZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgZm9ybUJ1aWxkZXIgPSBpbmplY3QoRHluYW1pY0Zvcm1CdWlsZGVyKTtcbiAgcHJpdmF0ZSByZWFkb25seSBleGVjdXRpb25TZXJ2aWNlID0gaW5qZWN0KFJlcG9ydEV4ZWN1dGlvblNlcnZpY2UpO1xuXG4gIHJlYWRvbmx5IGRlZmluaXRpb24gPSB0aGlzLmRlc2lnbmVyU3RhdGUuZGVmaW5pdGlvbjtcbiAgcmVhZG9ubHkgY29tcG9uZW50cyA9IGNvbXB1dGVkKCgpID0+IHRoaXMuZGVmaW5pdGlvbigpLmNvbXBvbmVudHMpO1xuICByZWFkb25seSBzZWxlY3RlZElkID0gdGhpcy5kZXNpZ25lclN0YXRlLnNlbGVjdGVkQ29tcG9uZW50SWQ7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfc3RhYmxlQ2FudmFzRm9ybSA9IG5ldyBGb3JtR3JvdXAoe30pO1xuICByZWFkb25seSBjYW52YXNGb3JtID0gY29tcHV0ZWQ8Rm9ybUdyb3VwPigoKSA9PiB7XG4gICAgY29uc3QgY29tcHMgPSB0aGlzLmNvbXBvbmVudHMoKTtcbiAgICBjb25zdCBjdXJyZW50S2V5cyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gICAgZm9yIChjb25zdCBjb21wIG9mIGNvbXBzKSB7XG4gICAgICBpZiAoIWNvbXAua2V5KSBjb250aW51ZTtcbiAgICAgIGN1cnJlbnRLZXlzLmFkZChjb21wLmtleSk7XG5cbiAgICAgIGlmICghdGhpcy5fc3RhYmxlQ2FudmFzRm9ybS5jb250YWlucyhjb21wLmtleSkpIHtcbiAgICAgICAgY29uc3QgZGVmYXVsdFZhbCA9IGNvbXAucHJvcGVydGllcz8uWydkZWZhdWx0VmFsdWUnXSA/PyAoY29tcC50eXBlID09PSAnY2hlY2tib3gnID8gZmFsc2UgOiAnJyk7XG4gICAgICAgIHRoaXMuX3N0YWJsZUNhbnZhc0Zvcm0uYWRkQ29udHJvbChjb21wLmtleSwgbmV3IEZvcm1Db250cm9sKGRlZmF1bHRWYWwpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGV4aXN0aW5nS2V5IG9mIE9iamVjdC5rZXlzKHRoaXMuX3N0YWJsZUNhbnZhc0Zvcm0uY29udHJvbHMpKSB7XG4gICAgICBpZiAoIWN1cnJlbnRLZXlzLmhhcyhleGlzdGluZ0tleSkpIHtcbiAgICAgICAgdGhpcy5fc3RhYmxlQ2FudmFzRm9ybS5yZW1vdmVDb250cm9sKGV4aXN0aW5nS2V5KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fc3RhYmxlQ2FudmFzRm9ybTtcbiAgfSk7XG5cbiAgZ2V0Q2FudmFzQ29udHJvbChjb21wOiBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uKTogRm9ybUNvbnRyb2wgfCBudWxsIHtcbiAgICBpZiAoIWNvbXAua2V5KSByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4gKHRoaXMuY2FudmFzRm9ybSgpLmdldChjb21wLmtleSkgYXMgRm9ybUNvbnRyb2wpID8/IG51bGw7XG4gIH1cblxuICByZWFkb25seSBoaWdobGlnaHRlZEZpZWxkS2V5cyA9IHNpZ25hbDxTZXQ8c3RyaW5nPj4obmV3IFNldCgpKTtcbiAgcmVhZG9ubHkgbGF5b3V0SnVzdFVwZGF0ZWQgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuXG4gIGlzRmllbGRIaWdobGlnaHRlZChjb21wOiBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICEhY29tcC5rZXkgJiYgdGhpcy5oaWdobGlnaHRlZEZpZWxkS2V5cygpLmhhcyhjb21wLmtleS50b0xvd2VyQ2FzZSgpKTtcbiAgfVxuXG4gIG9uQ29udHJvbEludGVyYWN0KGNvbXA6IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24sIGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5zZWxlY3RDb21wb25lbnQoY29tcC5pZCk7XG4gIH1cblxuICBnZXRHcmlkU3VtbWFyeVRleHQoKTogc3RyaW5nIHtcbiAgICBjb25zdCBncmlkID0gdGhpcy5kZWZpbml0aW9uKCkuZ3JpZDtcbiAgICBpZiAoIWdyaWQpIHJldHVybiAnJztcbiAgICBjb25zdCBwYXJ0czogc3RyaW5nW10gPSBbXTtcbiAgICBjb25zdCBncm91cHMgPSBncmlkLm9wdGlvbnM/Lmdyb3VwTW9kZWw7XG4gICAgaWYgKGdyb3VwcyAmJiBncm91cHMubGVuZ3RoID4gMCkge1xuICAgICAgcGFydHMucHVzaChgR3JvdXBlZCBieTogJHtncm91cHMuam9pbignLCAnKX1gKTtcbiAgICB9XG4gICAgY29uc3QgY29scyA9IGdyaWQuY29sdW1ucz8uZmlsdGVyKChjKSA9PiBjLnZpc2libGUgIT09IGZhbHNlKSA/PyBbXTtcbiAgICBwYXJ0cy5wdXNoKGAke2NvbHMubGVuZ3RofSB2aXNpYmxlIGNvbHVtbnNgKTtcbiAgICByZXR1cm4gcGFydHMuam9pbignIOKAoiAnKTtcbiAgfVxuXG4gIGhpZ2hsaWdodE1pc3NpbmdGaWVsZHMoZmllbGRzOiBzdHJpbmdbXSk6IHZvaWQge1xuICAgIGNvbnN0IGtleXMgPSBuZXcgU2V0KGZpZWxkcy5tYXAoKGYpID0+IGYudG9Mb3dlckNhc2UoKSkpO1xuICAgIHRoaXMuaGlnaGxpZ2h0ZWRGaWVsZEtleXMuc2V0KGtleXMpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgdGhpcy5oaWdobGlnaHRlZEZpZWxkS2V5cy5zZXQobmV3IFNldCgpKTtcbiAgICB9LCAyODAwKTtcbiAgfVxuXG4gIHJlYWRvbmx5IGNhbnZhc0dyaWREYXRhID0gc2lnbmFsPHVua25vd25bXT4oW10pO1xuICByZWFkb25seSBpc0V4ZWN1dGluZ0dyaWQgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICByZWFkb25seSBncmlkRXhlY0Vycm9yID0gc2lnbmFsPHN0cmluZyB8IG51bGw+KG51bGwpO1xuXG4gIHJlYWRvbmx5IHRvdGFsQ29sdW1ucyA9IGNvbXB1dGVkKCgpID0+IHRoaXMuZGVmaW5pdGlvbigpLmxheW91dC5jb2x1bW5zIHx8IDEyKTtcblxuICByZWFkb25seSBncmlkVGVtcGxhdGVDb2x1bW5zID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIHJldHVybiBgcmVwZWF0KCR7dGhpcy50b3RhbENvbHVtbnMoKX0sIG1pbm1heCgwLCAxZnIpKWA7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IHNvcnRlZENvbXBvbmVudHMgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgcmV0dXJuIFsuLi50aGlzLmNvbXBvbmVudHMoKV0uc29ydCgoYSwgYikgPT4gKGEub3JkZXIgPz8gMCkgLSAoYi5vcmRlciA/PyAwKSk7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IHJlc2l6aW5nQ29tcElkID0gc2lnbmFsPHN0cmluZyB8IG51bGw+KG51bGwpO1xuICByZWFkb25seSByZXNpemluZ1NwYW4gPSBzaWduYWw8bnVtYmVyIHwgbnVsbD4obnVsbCk7XG4gIHJlYWRvbmx5IHJlc2l6aW5nSGVpZ2h0ID0gc2lnbmFsPG51bWJlciB8IG51bGw+KG51bGwpO1xuICByZWFkb25seSBpc0FueVJlc2l6aW5nID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5yZXNpemluZ0NvbXBJZCgpICE9PSBudWxsKTtcblxuICBpc1NlbGVjdGVkKGlkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3RlZElkKCkgPT09IGlkO1xuICB9XG5cbiAgZ2V0U3Bhbihjb21wOiBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uKTogbnVtYmVyIHtcbiAgICByZXR1cm4gcmVzb2x2ZUNvbXBvbmVudFNwYW4oXG4gICAgICBjb21wLFxuICAgICAgdGhpcy50b3RhbENvbHVtbnMoKSxcbiAgICAgIHRoaXMucmVzaXppbmdDb21wSWQoKSA9PT0gY29tcC5pZCA/IHRoaXMucmVzaXppbmdTcGFuKCkgOiBudWxsXG4gICAgKTtcbiAgfVxuXG4gIGdldEdyaWRDb2x1bW4oY29tcDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbik6IHN0cmluZyB7XG4gICAgcmV0dXJuIGNhbGN1bGF0ZUdyaWRDb2x1bW4oY29tcCwgdGhpcy50b3RhbENvbHVtbnMoKSwgdGhpcy5nZXRTcGFuKGNvbXApKTtcbiAgfVxuXG4gIHRvZ2dsZU5ld1Jvdyhjb21wOiBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uLCBldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGNvbnN0IGN1cnJlbnQgPSAhIWNvbXAubGF5b3V0Py5uZXdSb3c7XG4gICAgdGhpcy5kZXNpZ25lclN0YXRlLnVwZGF0ZUNvbXBvbmVudExheW91dChjb21wLmlkLCB7IG5ld1JvdzogIWN1cnJlbnQgfSk7XG4gIH1cblxuICBnZXRHcmlkUm93KGNvbXA6IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24pOiBzdHJpbmcge1xuICAgIHJldHVybiBjYWxjdWxhdGVHcmlkUm93KGNvbXApO1xuICB9XG5cbiAgZ2V0Q29tcG9uZW50SGVpZ2h0KGNvbXA6IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24pOiBzdHJpbmcge1xuICAgIHJldHVybiByZXNvbHZlQ2FudmFzQ2FyZEhlaWdodChcbiAgICAgIGNvbXAsXG4gICAgICB0aGlzLnJlc2l6aW5nQ29tcElkKCkgPT09IGNvbXAuaWQgPyB0aGlzLnJlc2l6aW5nSGVpZ2h0KCkgOiBudWxsXG4gICAgKTtcbiAgfVxuXG4gIGdldENvbXBvbmVudE1pbkhlaWdodChjb21wOiBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uKTogc3RyaW5nIHtcbiAgICByZXR1cm4gcmVzb2x2ZUNhbnZhc0NhcmRNaW5IZWlnaHQoXG4gICAgICBjb21wLFxuICAgICAgdGhpcy5yZXNpemluZ0NvbXBJZCgpID09PSBjb21wLmlkID8gdGhpcy5yZXNpemluZ0hlaWdodCgpIDogbnVsbFxuICAgICk7XG4gIH1cblxuICBnZXRDdXN0b21CdG5IZWlnaHQoY29tcDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbik6IHN0cmluZyB8IG51bGwge1xuICAgIGNvbnN0IGggPSBjb21wLmxheW91dD8uaGVpZ2h0O1xuICAgIHJldHVybiBoICYmIGggIT09ICdhdXRvJyA/IGggOiBudWxsO1xuICB9XG5cbiAgZ2V0Q3VzdG9tQnRuV2lkdGgoY29tcDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbik6IHN0cmluZyB8IG51bGwge1xuICAgIGNvbnN0IHcgPSBjb21wLmxheW91dD8ud2lkdGg7XG4gICAgcmV0dXJuIHcgJiYgdyAhPT0gJ2F1dG8nID8gdyA6IG51bGw7XG4gIH1cblxuICBnZXRDdXN0b21CdG5JY29uKGNvbXA6IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24pOiBzdHJpbmcge1xuICAgIHJldHVybiAoY29tcC5wcm9wZXJ0aWVzPy5bJ2ljb24nXSBhcyBzdHJpbmcpIHx8ICcnO1xuICB9XG5cbiAgcmVzaXppbmdUb29sdGlwKGNvbXA6IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24pOiBzdHJpbmcge1xuICAgIGNvbnN0IHNwYW4gPSB0aGlzLmdldFNwYW4oY29tcCk7XG4gICAgY29uc3QgaGVpZ2h0ID0gdGhpcy5yZXNpemluZ0hlaWdodCgpID8/IChjb21wLmxheW91dD8uaGVpZ2h0ID8gcGFyc2VJbnQoY29tcC5sYXlvdXQuaGVpZ2h0LCAxMCkgOiA1OCk7XG4gICAgcmV0dXJuIGAke3NwYW59IGNvbHMgw5cgJHtoZWlnaHR9cHhgO1xuICB9XG5cbiAgcmVhZG9ubHkgZ2V0Q29tcG9uZW50SWNvbk5hbWUgPSBnZXRDb21wb25lbnRJY29uTmFtZTtcblxuICBvblNlbGVjdChpZDogc3RyaW5nLCBldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmlzQW55UmVzaXppbmcoKSkgcmV0dXJuO1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5zZWxlY3RDb21wb25lbnQoaWQpO1xuICB9XG5cbiAgYWRqdXN0U3Bhbihjb21wOiBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uLCBkZWx0YTogbnVtYmVyLCBldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLmdldFNwYW4oY29tcCk7XG4gICAgY29uc3QgbmV4dCA9IE1hdGgubWF4KDEsIE1hdGgubWluKHRoaXMudG90YWxDb2x1bW5zKCksIGN1cnJlbnQgKyBkZWx0YSkpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS51cGRhdGVDb21wb25lbnRMYXlvdXQoY29tcC5pZCwgeyBjb2x1bW5TcGFuOiBuZXh0IH0pO1xuICB9XG5cbiAgb25EdXBsaWNhdGUoaWQ6IHN0cmluZywgZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLmRlc2lnbmVyU3RhdGUuZHVwbGljYXRlQ29tcG9uZW50KGlkKTtcbiAgfVxuXG4gIG9uRGVsZXRlKGlkOiBzdHJpbmcsIGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy5kZXNpZ25lclN0YXRlLnJlbW92ZUNvbXBvbmVudChpZCk7XG4gIH1cblxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDprZXlkb3duLmVzY2FwZScpXG4gIG9uRXNjYXBlKCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnNlbGVjdGVkSWQoKSkge1xuICAgICAgdGhpcy5kZXNpZ25lclN0YXRlLnNlbGVjdENvbXBvbmVudChudWxsKTtcbiAgICB9XG4gIH1cblxuICBvbkNhbnZhc0JhY2tncm91bmRDbGljayhldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGlmICh0aGlzLmlzQW55UmVzaXppbmcoKSkgcmV0dXJuO1xuICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudDtcbiAgICBpZiAoXG4gICAgICB0YXJnZXQuY2xvc2VzdCgnLmNhbnZhcy1jb21wb25lbnQtY2FyZCcpIHx8XG4gICAgICB0YXJnZXQuY2xvc2VzdCgnLmNhbnZhcy1hY3Rpb24tYnRuJykgfHxcbiAgICAgIHRhcmdldC5jbG9zZXN0KCcuY2FudmFzLWdyaWQtcHJldmlldy1ib3gnKVxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmRlc2lnbmVyU3RhdGUuc2VsZWN0Q29tcG9uZW50KG51bGwpO1xuICB9XG5cbiAgc2VsZWN0UmVwb3J0U2V0dGluZ3MoZXZlbnQ/OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQ/LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5zZWxlY3RDb21wb25lbnQobnVsbCk7XG4gICAgdGhpcy5kZXNpZ25lclN0YXRlLnNldEFjdGl2ZVRhYigncmVwb3J0Jyk7XG4gIH1cblxuICBzZWxlY3RHcmlkU2V0dGluZ3MoZXZlbnQ/OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQ/LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5zZWxlY3RDb21wb25lbnQobnVsbCk7XG4gICAgdGhpcy5kZXNpZ25lclN0YXRlLnNldEFjdGl2ZVRhYignZ3JpZCcpO1xuICB9XG5cbiAgc3RhcnRSZXNpemUoZXZlbnQ6IFBvaW50ZXJFdmVudCwgY29tcDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbiwgZGlyZWN0aW9uOiAnZScgfCAncycgfCAnc2UnKTogdm9pZCB7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblxuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5zZWxlY3RDb21wb25lbnQoY29tcC5pZCk7XG5cbiAgICBjb25zdCBoYW5kbGUgPSBldmVudC50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgaGFuZGxlLnNldFBvaW50ZXJDYXB0dXJlKGV2ZW50LnBvaW50ZXJJZCk7XG5cbiAgICBjb25zdCBjYXJkID0gaGFuZGxlLmNsb3Nlc3QoJy5jYW52YXMtY29tcG9uZW50LWNhcmQnKSBhcyBIVE1MRWxlbWVudDtcbiAgICBjb25zdCBncmlkID0gaGFuZGxlLmNsb3Nlc3QoJy5jYW52YXMtZ3JpZCcpIGFzIEhUTUxFbGVtZW50O1xuICAgIGlmICghY2FyZCB8fCAhZ3JpZCkgcmV0dXJuO1xuXG4gICAgY29uc3Qgc3RhcnRYID0gZXZlbnQuY2xpZW50WDtcbiAgICBjb25zdCBzdGFydFkgPSBldmVudC5jbGllbnRZO1xuICAgIGNvbnN0IHN0YXJ0U3BhbiA9IGNvbXAubGF5b3V0Py5jb2x1bW5TcGFuID8/IChjb21wLnR5cGUgPT09ICdidXR0b24nID8gMiA6IDQpO1xuICAgIGNvbnN0IGV4aXN0aW5nQ29tcEhlaWdodCA9IGNvbXAubGF5b3V0Py5oZWlnaHQgPyBwYXJzZUludChjb21wLmxheW91dC5oZWlnaHQsIDEwKSA6IG51bGw7XG4gICAgY29uc3Qgc3RhcnRIZWlnaHQgPSBleGlzdGluZ0NvbXBIZWlnaHQgPz8gTWF0aC5tYXgoMzgsIGNhcmQub2Zmc2V0SGVpZ2h0IC0gQ0FOVkFTX0NBUkRfT1ZFUkhFQUQpO1xuICAgIGNvbnN0IHRvdGFsQ29scyA9IHRoaXMudG90YWxDb2x1bW5zKCk7XG4gICAgY29uc3QgZ2FwID0gdGhpcy5kZWZpbml0aW9uKCkubGF5b3V0LmdhcCA/PyAxNjtcbiAgICBjb25zdCBjb2xXaWR0aCA9IChncmlkLm9mZnNldFdpZHRoIC0gKHRvdGFsQ29scyAtIDEpICogZ2FwKSAvIHRvdGFsQ29scztcblxuICAgIHRoaXMucmVzaXppbmdDb21wSWQuc2V0KGNvbXAuaWQpO1xuICAgIHRoaXMucmVzaXppbmdTcGFuLnNldChzdGFydFNwYW4pO1xuICAgIHRoaXMucmVzaXppbmdIZWlnaHQuc2V0KHN0YXJ0SGVpZ2h0KTtcblxuICAgIGxldCBjdXJyZW50U3BhbiA9IHN0YXJ0U3BhbjtcbiAgICBsZXQgY3VycmVudEhlaWdodCA9IHN0YXJ0SGVpZ2h0O1xuXG4gICAgY29uc3Qgb25Qb2ludGVyTW92ZSA9IChtb3ZlRXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgICAgaWYgKGRpcmVjdGlvbiA9PT0gJ2UnIHx8IGRpcmVjdGlvbiA9PT0gJ3NlJykge1xuICAgICAgICBjb25zdCBkZWx0YVggPSBtb3ZlRXZlbnQuY2xpZW50WCAtIHN0YXJ0WDtcbiAgICAgICAgY3VycmVudFNwYW4gPSBjYWxjdWxhdGVTbmFwcGVkU3BhbihkZWx0YVgsIHN0YXJ0U3BhbiwgY29sV2lkdGgsIGdhcCwgdG90YWxDb2xzKTtcbiAgICAgICAgdGhpcy5yZXNpemluZ1NwYW4uc2V0KGN1cnJlbnRTcGFuKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGRpcmVjdGlvbiA9PT0gJ3MnIHx8IGRpcmVjdGlvbiA9PT0gJ3NlJykge1xuICAgICAgICBjb25zdCBkZWx0YVkgPSBtb3ZlRXZlbnQuY2xpZW50WSAtIHN0YXJ0WTtcbiAgICAgICAgY29uc3QgbmF0dXJhbE1pbiA9IE1hdGgubWF4KDM4LCBnZXRDb21wb25lbnROYXR1cmFsTWluSGVpZ2h0KGNvbXAudHlwZSkpO1xuICAgICAgICBjdXJyZW50SGVpZ2h0ID0gY2FsY3VsYXRlU25hcHBlZEhlaWdodChkZWx0YVksIHN0YXJ0SGVpZ2h0LCBuYXR1cmFsTWluKTtcbiAgICAgICAgdGhpcy5yZXNpemluZ0hlaWdodC5zZXQoY3VycmVudEhlaWdodCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGNvbnN0IG9uUG9pbnRlclVwID0gKHVwRXZlbnQ6IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgaGFuZGxlLnJlbGVhc2VQb2ludGVyQ2FwdHVyZSh1cEV2ZW50LnBvaW50ZXJJZCk7XG4gICAgICB9IGNhdGNoIHt9XG5cbiAgICAgIGhhbmRsZS5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVybW92ZScsIG9uUG9pbnRlck1vdmUpO1xuICAgICAgaGFuZGxlLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJ1cCcsIG9uUG9pbnRlclVwKTtcbiAgICAgIGhhbmRsZS5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVyY2FuY2VsJywgb25Qb2ludGVyVXApO1xuXG4gICAgICBjb25zdCBsYXlvdXRDaGFuZ2VzOiBQYXJ0aWFsPENvbXBvbmVudExheW91dERlZmluaXRpb24+ID0ge307XG4gICAgICBpZiAoZGlyZWN0aW9uID09PSAnZScgfHwgZGlyZWN0aW9uID09PSAnc2UnKSB7XG4gICAgICAgIGxheW91dENoYW5nZXMuY29sdW1uU3BhbiA9IGN1cnJlbnRTcGFuO1xuICAgICAgfVxuICAgICAgY29uc3QgZGVsdGFZID0gTWF0aC5hYnModXBFdmVudC5jbGllbnRZIC0gc3RhcnRZKTtcbiAgICAgIGlmIChkaXJlY3Rpb24gPT09ICdzJyB8fCAoZGlyZWN0aW9uID09PSAnc2UnICYmIGRlbHRhWSA+IDgpKSB7XG4gICAgICAgIGxheW91dENoYW5nZXMuaGVpZ2h0ID0gYCR7Y3VycmVudEhlaWdodH1weGA7XG4gICAgICAgIGxheW91dENoYW5nZXMubWluSGVpZ2h0ID0gYCR7Y3VycmVudEhlaWdodH1weGA7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuZGVzaWduZXJTdGF0ZS51cGRhdGVDb21wb25lbnRMYXlvdXQoY29tcC5pZCwgbGF5b3V0Q2hhbmdlcyk7XG5cbiAgICAgIHRoaXMucmVzaXppbmdDb21wSWQuc2V0KG51bGwpO1xuICAgICAgdGhpcy5yZXNpemluZ1NwYW4uc2V0KG51bGwpO1xuICAgICAgdGhpcy5yZXNpemluZ0hlaWdodC5zZXQobnVsbCk7XG4gICAgfTtcblxuICAgIGhhbmRsZS5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVybW92ZScsIG9uUG9pbnRlck1vdmUpO1xuICAgIGhhbmRsZS5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVydXAnLCBvblBvaW50ZXJVcCk7XG4gICAgaGFuZGxlLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJjYW5jZWwnLCBvblBvaW50ZXJVcCk7XG4gIH1cblxuICByZXNldERpbWVuc2lvbnMoY29tcDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbiwgZXZlbnQ/OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKGV2ZW50KSB7XG4gICAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuICAgIGNvbnN0IGRlZmF1bHRTcGFuID0gY29tcC50eXBlID09PSAnYnV0dG9uJyA/IDIgOiA0O1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS51cGRhdGVDb21wb25lbnRMYXlvdXQoY29tcC5pZCwge1xuICAgICAgY29sdW1uU3BhbjogZGVmYXVsdFNwYW4sXG4gICAgICBoZWlnaHQ6IHVuZGVmaW5lZCxcbiAgICAgIG1pbkhlaWdodDogdW5kZWZpbmVkLFxuICAgICAgd2lkdGg6IHVuZGVmaW5lZCxcbiAgICB9KTtcbiAgfVxuXG4gIG9uRHJvcChldmVudDogQ2RrRHJhZ0Ryb3A8UmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbltdLCB1bmtub3duLCB1bmtub3duPik6IHZvaWQge1xuICAgIGlmICh0aGlzLmlzQW55UmVzaXppbmcoKSkgcmV0dXJuO1xuXG4gICAgaWYgKGV2ZW50LnByZXZpb3VzQ29udGFpbmVyID09PSBldmVudC5jb250YWluZXIpIHtcbiAgICAgIC8vIFJlb3JkZXJpbmcgd2l0aGluIGNhbnZhc1xuICAgICAgdGhpcy5kZXNpZ25lclN0YXRlLm1vdmVDb21wb25lbnQoZXZlbnQucHJldmlvdXNJbmRleCwgZXZlbnQuY3VycmVudEluZGV4KTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gRHJhZ2dlZCBmcm9tIHBhbGV0dGUgaW50byBjYW52YXNcbiAgICAgIGNvbnN0IHJhd0RhdGEgPSBldmVudC5pdGVtLmRhdGEgYXMgc3RyaW5nIHwgeyB0eXBlPzogc3RyaW5nIH0gfCB1bmRlZmluZWQ7XG4gICAgICBjb25zdCBjb21wb25lbnRUeXBlID0gdHlwZW9mIHJhd0RhdGEgPT09ICdzdHJpbmcnID8gcmF3RGF0YSA6IHJhd0RhdGE/LnR5cGU7XG4gICAgICBpZiAoY29tcG9uZW50VHlwZSkge1xuICAgICAgICB0aGlzLmRlc2lnbmVyU3RhdGUuYWRkQ29tcG9uZW50KGNvbXBvbmVudFR5cGUsIGV2ZW50LmN1cnJlbnRJbmRleCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgYWRkUmVzdWx0R3JpZChldmVudD86IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudD8uc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgY29uc3QgZXhpc3RpbmdEcyA9IHRoaXMuZGVmaW5pdGlvbigpLmRhdGFTb3VyY2VzWzBdO1xuICAgIGNvbnN0IGRlZmF1bHRHcmlkOiBSZXBvcnRHcmlkRGVmaW5pdGlvbiA9IHtcbiAgICAgIGRhdGFTb3VyY2VJZDogZXhpc3RpbmdEcz8uaWQgPz8gJ2RlZmF1bHQnLFxuICAgICAgY29sdW1uczogW1xuICAgICAgICB7IGZpZWxkOiAnaWQnLCBsYWJlbDogJ0lEJywgZGF0YVR5cGU6ICdudW1iZXInLCB2aXNpYmxlOiB0cnVlLCBzb3J0YWJsZTogdHJ1ZSB9LFxuICAgICAgICB7IGZpZWxkOiAnbmFtZScsIGxhYmVsOiAnTmFtZScsIGRhdGFUeXBlOiAnc3RyaW5nJywgdmlzaWJsZTogdHJ1ZSwgc29ydGFibGU6IHRydWUgfSxcbiAgICAgIF0sXG4gICAgICBvcHRpb25zOiB7XG4gICAgICAgIHBhZ2luYXRpb246IHRydWUsXG4gICAgICAgIHBhZ2VTaXplOiAyNSxcbiAgICAgICAgc2hvd1Jvd051bWJlcnM6IHRydWUsXG4gICAgICAgIHNob3dGb290ZXI6IHRydWUsXG4gICAgICAgIHNpZGVCYXI6IHRydWUsXG4gICAgICAgIGdsb2JhbFNlYXJjaDogdHJ1ZSxcbiAgICAgICAgc3RhdHVzQmFyOiB0cnVlLFxuICAgICAgfSxcbiAgICB9O1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS51cGRhdGVHcmlkU2V0dGluZ3MoZGVmYXVsdEdyaWQpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5zZWxlY3RDb21wb25lbnQobnVsbCk7XG4gICAgdGhpcy5kZXNpZ25lclN0YXRlLnNldEFjdGl2ZVRhYignZ3JpZCcpO1xuICB9XG5cbiAgZXhlY3V0ZUNhbnZhc1JlcG9ydChldmVudD86IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoZXZlbnQpIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGlmICghdGhpcy5kZWZpbml0aW9uKCkuZ3JpZCkge1xuICAgICAgdGhpcy5hZGRSZXN1bHRHcmlkKCk7XG4gICAgfVxuXG4gICAgY29uc3QgZm9ybVZhbHVlcyA9IHRoaXMuY2FudmFzRm9ybSgpLmdldFJhd1ZhbHVlKCk7XG4gICAgY29uc3QgbWlzc2luZyA9IHRoaXMuZXhlY3V0aW9uU2VydmljZS5nZXRNaXNzaW5nRmllbGRzKHRoaXMuZGVmaW5pdGlvbigpLCBmb3JtVmFsdWVzKTtcbiAgICBpZiAobWlzc2luZy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLmdyaWRFeGVjRXJyb3Iuc2V0KCdNaXNzaW5nIHJlcXVpcmVkIGZpbHRlciB2YWx1ZXM6ICcgKyBtaXNzaW5nLmpvaW4oJywgJykgKyAnLiBQbGVhc2UgZW50ZXIgdmFsdWVzIGFib3ZlIHRvIHJ1bi4nKTtcbiAgICAgIHRoaXMuaGlnaGxpZ2h0TWlzc2luZ0ZpZWxkcyhtaXNzaW5nKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmlzRXhlY3V0aW5nR3JpZC5zZXQodHJ1ZSk7XG4gICAgdGhpcy5ncmlkRXhlY0Vycm9yLnNldChudWxsKTtcblxuICAgIHRoaXMuZXhlY3V0aW9uU2VydmljZS5leGVjdXRlKHRoaXMuZGVmaW5pdGlvbigpLCBmb3JtVmFsdWVzKS5zdWJzY3JpYmUoe1xuICAgICAgbmV4dDogKHJvd3M6IHVua25vd25bXSkgPT4ge1xuICAgICAgICB0aGlzLmNhbnZhc0dyaWREYXRhLnNldChyb3dzIHx8IFtdKTtcbiAgICAgICAgdGhpcy5pc0V4ZWN1dGluZ0dyaWQuc2V0KGZhbHNlKTtcbiAgICAgIH0sXG4gICAgICBlcnJvcjogKGVycjogdW5rbm93bikgPT4ge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdbRGVzaWduQ2FudmFzXSBRdWVyeSBleGVjdXRpb24gZXJyb3I6JywgZXJyKTtcbiAgICAgICAgY29uc3QgbXNnID0gZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IFN0cmluZyhlcnIpO1xuICAgICAgICB0aGlzLmdyaWRFeGVjRXJyb3Iuc2V0KG1zZyB8fCAnRXhlY3V0aW9uIGZhaWxlZCcpO1xuICAgICAgICB0aGlzLmlzRXhlY3V0aW5nR3JpZC5zZXQoZmFsc2UpO1xuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIG9uQ2FudmFzQnV0dG9uQ2xpY2soY29tcDogUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbiwgZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICBjb25zdCBhY3Rpb24gPSAoY29tcC5wcm9wZXJ0aWVzPy5bJ2FjdGlvbiddIGFzIHN0cmluZykgfHwgJ2V4ZWN1dGUtcmVwb3J0JztcbiAgICBpZiAoYWN0aW9uID09PSAnZXhlY3V0ZS1yZXBvcnQnKSB7XG4gICAgICB0aGlzLmV4ZWN1dGVDYW52YXNSZXBvcnQoKTtcbiAgICB9IGVsc2UgaWYgKGFjdGlvbiA9PT0gJ3Jlc2V0Jykge1xuICAgICAgdGhpcy5jYW52YXNGb3JtKCkucmVzZXQoKTtcbiAgICAgIHRoaXMuY2FudmFzR3JpZERhdGEuc2V0KFtdKTtcbiAgICB9IGVsc2UgaWYgKGFjdGlvbiA9PT0gJ2V4cG9ydCcpIHtcbiAgICAgIHRoaXMuZ3JpZEV4ZWNFcnJvci5zZXQoJ/CfkqEgRXhwb3J0IGFjdGlvbiBpcyBjb25maWd1cmVkLiBSdW4gdGhlIHJlcG9ydCBhbmQgc3dpdGNoIHRvIFJ1bnRpbWUgdmlldyB0byBkb3dubG9hZCBmaWxlcy4nKTtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5ncmlkRXhlY0Vycm9yLnNldChudWxsKSwgNDAwMCk7XG4gICAgfSBlbHNlIGlmIChhY3Rpb24gPT09ICdwcmludC1yZXBvcnQnKSB7XG4gICAgICB0aGlzLmdyaWRFeGVjRXJyb3Iuc2V0KCfwn5KhIFByaW50IFJlcG9ydCBhY3Rpb24gaXMgY29uZmlndXJlZC4gU3dpdGNoIHRvIFJ1bnRpbWUgdmlldyB0byBzdWJtaXQgdG8gcHJpbnQgc2VydmljZS4nKTtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5ncmlkRXhlY0Vycm9yLnNldChudWxsKSwgNDAwMCk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZ3JpZEZpbHRlckRlYm91bmNlVGltZXIpIHtcbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLmdyaWRGaWx0ZXJEZWJvdW5jZVRpbWVyKTtcbiAgICAgIHRoaXMuZ3JpZEZpbHRlckRlYm91bmNlVGltZXIgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIG9uQ2FudmFzR3JpZFN0YXRlQ2hhbmdlKHN0YXRlOiBhbnkpOiB2b2lkIHtcbiAgICBpZiAoIXN0YXRlIHx8ICF0aGlzLmRlZmluaXRpb24oKS5ncmlkKSByZXR1cm47XG4gICAgY29uc3QgY3VycmVudEdyaWQgPSB0aGlzLmRlZmluaXRpb24oKS5ncmlkITtcblxuICAgIC8vIEF2b2lkIGRpcnR5IGNodXJuIGFuZCBldmVudCBsb29wcyBpZiBzdGF0ZSBoYXMgbm90IGNoYW5nZWRcbiAgICBjb25zdCBjdXJyZW50U2VyaWFsaXplZCA9IEpTT04uc3RyaW5naWZ5KGN1cnJlbnRHcmlkLm9wdGlvbnM/LnJlcG9ydFN0YXRlID8/IG51bGwpO1xuICAgIGNvbnN0IG5ld1NlcmlhbGl6ZWQgPSBKU09OLnN0cmluZ2lmeShzdGF0ZSA/PyBudWxsKTtcbiAgICBpZiAoY3VycmVudFNlcmlhbGl6ZWQgPT09IG5ld1NlcmlhbGl6ZWQpIHJldHVybjtcblxuICAgIC8vIERpc3Rpbmd1aXNoIGJldHdlZW4gdHJ1ZSBzdHJ1Y3R1cmFsIGxheW91dCBjaGFuZ2VzIChncm91cE1vZGVsLCBzb3J0TW9kZWwpXG4gICAgLy8gdnMgaW50ZXJhY3RpdmUgY29sdW1uIGRhdGEgZmlsdGVyaW5nIChhY3RpdmVGaWx0ZXJzLCBjb25kaXRpb25GaWx0ZXJzKS5cbiAgICBjb25zdCBjdXJyZW50R3JvdXAgPSBKU09OLnN0cmluZ2lmeShjdXJyZW50R3JpZC5vcHRpb25zPy5ncm91cE1vZGVsID8/IFtdKTtcbiAgICBjb25zdCBuZXdHcm91cCA9IEpTT04uc3RyaW5naWZ5KHN0YXRlLmdyb3VwTW9kZWwgPz8gW10pO1xuICAgIGNvbnN0IGN1cnJlbnRTb3J0ID0gSlNPTi5zdHJpbmdpZnkoY3VycmVudEdyaWQub3B0aW9ucz8uc29ydE1vZGVsID8/IFtdKTtcbiAgICBjb25zdCBuZXdTb3J0ID0gSlNPTi5zdHJpbmdpZnkoc3RhdGUuc29ydE1vZGVsID8/IFtdKTtcbiAgICBjb25zdCBpc0xheW91dENoYW5nZSA9IGN1cnJlbnRHcm91cCAhPT0gbmV3R3JvdXAgfHwgY3VycmVudFNvcnQgIT09IG5ld1NvcnQ7XG5cbiAgICBjb25zdCB1cGRhdGVkT3B0aW9ucyA9IHtcbiAgICAgIC4uLihjdXJyZW50R3JpZC5vcHRpb25zIHx8IHt9KSxcbiAgICAgIGdyb3VwTW9kZWw6IHN0YXRlLmdyb3VwTW9kZWwgPz8gY3VycmVudEdyaWQub3B0aW9ucz8uZ3JvdXBNb2RlbCxcbiAgICAgIHNvcnRNb2RlbDogc3RhdGUuc29ydE1vZGVsID8/IGN1cnJlbnRHcmlkLm9wdGlvbnM/LnNvcnRNb2RlbCxcbiAgICAgIHJlcG9ydFN0YXRlOiBzdGF0ZSxcbiAgICB9O1xuXG4gICAgaWYgKGlzTGF5b3V0Q2hhbmdlKSB7XG4gICAgICAvLyBDbGVhciBhbnkgcGVuZGluZyBkZWJvdW5jZWQgZmlsdGVyIHVwZGF0ZVxuICAgICAgaWYgKHRoaXMuZ3JpZEZpbHRlckRlYm91bmNlVGltZXIpIHtcbiAgICAgICAgY2xlYXJUaW1lb3V0KHRoaXMuZ3JpZEZpbHRlckRlYm91bmNlVGltZXIpO1xuICAgICAgICB0aGlzLmdyaWRGaWx0ZXJEZWJvdW5jZVRpbWVyID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIHRoaXMucGVuZGluZ0dyaWRTdGF0ZSA9IG51bGw7XG5cbiAgICAgIC8vIEdyb3VwaW5nIG9yIHNvcnRpbmcgY2hhbmdlZCDigJQgdXBkYXRlIGxheW91dCBpbW1lZGlhdGVseSBhbmQgc2hvdyB2aXN1YWwgaW5kaWNhdG9yXG4gICAgICB0aGlzLmRlc2lnbmVyU3RhdGUudXBkYXRlR3JpZFNldHRpbmdzKHtcbiAgICAgICAgLi4uY3VycmVudEdyaWQsXG4gICAgICAgIG9wdGlvbnM6IHVwZGF0ZWRPcHRpb25zLFxuICAgICAgfSk7XG4gICAgICB0aGlzLmxheW91dEp1c3RVcGRhdGVkLnNldCh0cnVlKTtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5sYXlvdXRKdXN0VXBkYXRlZC5zZXQoZmFsc2UpLCAxMjAwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gUHVyZSBjb2x1bW4gZmlsdGVyIGFkanVzdG1lbnQgKGFjdGl2ZUZpbHRlcnMgLyBjb25kaXRpb25GaWx0ZXJzKS5cbiAgICAgIC8vIDEuIERvIE5PVCB0cmlnZ2VyIHRoZSBcIkxheW91dCBhdXRvLXBlcnNpc3RlZFwiIGluZGljYXRvciAoZmlsdGVyaW5nIHJvd3MgaXMgbm90IGEgbGF5b3V0IGNoYW5nZSkuXG4gICAgICAvLyAyLiBEZWJvdW5jZSBzYXZpbmcgdGhlIHN0YXRlIHdpdGggc2tpcEhpc3Rvcnkgc28gdHlwaW5nIG9yIGNoZWNraW5nIGJveGVzXG4gICAgICAvLyAgICBkb2VzIG5vdCBmbG9vZCB1bmRvIGhpc3Rvcnkgb3IgaW50ZXJydXB0IGNvbHVtbiBmaWx0ZXIgaW50ZXJhY3Rpb24uXG4gICAgICB0aGlzLnBlbmRpbmdHcmlkU3RhdGUgPSBzdGF0ZTtcbiAgICAgIGlmICh0aGlzLmdyaWRGaWx0ZXJEZWJvdW5jZVRpbWVyKSB7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aGlzLmdyaWRGaWx0ZXJEZWJvdW5jZVRpbWVyKTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZ3JpZEZpbHRlckRlYm91bmNlVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5ncmlkRmlsdGVyRGVib3VuY2VUaW1lciA9IG51bGw7XG4gICAgICAgIGlmICghdGhpcy5wZW5kaW5nR3JpZFN0YXRlIHx8ICF0aGlzLmRlZmluaXRpb24oKS5ncmlkKSByZXR1cm47XG4gICAgICAgIGNvbnN0IGxhdGVzdEdyaWQgPSB0aGlzLmRlZmluaXRpb24oKS5ncmlkITtcbiAgICAgICAgY29uc3QgbGF0ZXN0T3B0aW9ucyA9IHtcbiAgICAgICAgICAuLi4obGF0ZXN0R3JpZC5vcHRpb25zIHx8IHt9KSxcbiAgICAgICAgICByZXBvcnRTdGF0ZTogdGhpcy5wZW5kaW5nR3JpZFN0YXRlLFxuICAgICAgICB9O1xuICAgICAgICB0aGlzLnBlbmRpbmdHcmlkU3RhdGUgPSBudWxsO1xuICAgICAgICB0aGlzLmRlc2lnbmVyU3RhdGUudXBkYXRlR3JpZFNldHRpbmdzKFxuICAgICAgICAgIHtcbiAgICAgICAgICAgIC4uLmxhdGVzdEdyaWQsXG4gICAgICAgICAgICBvcHRpb25zOiBsYXRlc3RPcHRpb25zLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgeyBza2lwSGlzdG9yeTogdHJ1ZSB9XG4gICAgICAgICk7XG4gICAgICB9LCAxMjAwKTtcbiAgICB9XG4gIH1cblxuICBvbkNhbnZhc0NvbHVtbkRlZnNDaGFuZ2UoZGVmczogYW55W10pOiB2b2lkIHtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoZGVmcykgfHwgIXRoaXMuZGVmaW5pdGlvbigpLmdyaWQpIHJldHVybjtcbiAgICBjb25zdCBjdXJyZW50R3JpZCA9IHRoaXMuZGVmaW5pdGlvbigpLmdyaWQhO1xuICAgIGxldCBhbnlDaGFuZ2VkID0gZmFsc2U7XG5cbiAgICBjb25zdCB1cGRhdGVkQ29scyA9IGN1cnJlbnRHcmlkLmNvbHVtbnMubWFwKChjKSA9PiB7XG4gICAgICBjb25zdCBtYXRjaCA9IGRlZnMuZmluZCgoZDogYW55KSA9PiBkLmZpZWxkID09PSBjLmZpZWxkKTtcbiAgICAgIGlmIChtYXRjaCkge1xuICAgICAgICBjb25zdCBuZXdXaWR0aCA9IG1hdGNoLndpZHRoID8gYCR7bWF0Y2gud2lkdGh9cHhgIDogYy53aWR0aDtcbiAgICAgICAgY29uc3QgbmV3VmlzaWJsZSA9IG1hdGNoLmhpZGUgIT09IHRydWU7XG4gICAgICAgIGlmIChuZXdXaWR0aCAhPT0gYy53aWR0aCB8fCBuZXdWaXNpYmxlICE9PSBjLnZpc2libGUpIHtcbiAgICAgICAgICBhbnlDaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIC4uLmMsXG4gICAgICAgICAgd2lkdGg6IG5ld1dpZHRoLFxuICAgICAgICAgIHZpc2libGU6IG5ld1Zpc2libGUsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgICByZXR1cm4gYztcbiAgICB9KTtcblxuICAgIC8vIElmIG5vIGNvbHVtbiB3aWR0aHMgb3IgdmlzaWJpbGl0aWVzIGFjdHVhbGx5IGNoYW5nZWQsIGRvIG5vdCB0cmlnZ2VyIGF1dG8tcGVyc2lzdFxuICAgIGlmICghYW55Q2hhbmdlZCkgcmV0dXJuO1xuXG4gICAgdGhpcy5kZXNpZ25lclN0YXRlLnVwZGF0ZUdyaWRTZXR0aW5ncyh7XG4gICAgICAuLi5jdXJyZW50R3JpZCxcbiAgICAgIGNvbHVtbnM6IHVwZGF0ZWRDb2xzLFxuICAgIH0pO1xuICAgIHRoaXMubGF5b3V0SnVzdFVwZGF0ZWQuc2V0KHRydWUpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5sYXlvdXRKdXN0VXBkYXRlZC5zZXQoZmFsc2UpLCAxMjAwKTtcbiAgfVxuXG4gIHJlbW92ZUdyaWQoZXZlbnQ/OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQ/LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuZGVzaWduZXJTdGF0ZS51cGRhdGVHcmlkU2V0dGluZ3ModW5kZWZpbmVkKTtcbiAgfVxuXG4gIGFwcGx5Qmx1ZXByaW50KGJsdWVwcmludElkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBuZXdEZWYgPSB0aGlzLnRlbXBsYXRlU2VydmljZS5pbnN0YW50aWF0ZVRlbXBsYXRlKGJsdWVwcmludElkKTtcbiAgICB0aGlzLmRlc2lnbmVyU3RhdGUubG9hZERlZmluaXRpb24obmV3RGVmKTtcbiAgfVxuXG4gIGFkZFN0YXJ0ZXJDb21wb25lbnQodHlwZTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5kZXNpZ25lclN0YXRlLmFkZENvbXBvbmVudCh0eXBlKTtcbiAgfVxufVxuIiwiICAgIDxkaXYgY2xhc3M9XCJjYW52YXMtd3JhcHBlclwiIChjbGljayk9XCJvbkNhbnZhc0JhY2tncm91bmRDbGljaygkZXZlbnQpXCI+XG4gICAgICA8IS0tIENhbnZhcyBTdGF0dXMgLyBRdWljayBDb250cm9scyAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJjYW52YXMtdG9vbGJhclwiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwiY2FudmFzLWluZm9cIj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImluZm8tbGFiZWxcIj5HcmlkIExheW91dDo8L3NwYW4+XG4gICAgICAgICAgPHNwYW4gY2xhc3M9XCJpbmZvLXZhbHVlXCI+e3sgdG90YWxDb2x1bW5zKCkgfX0gQ29sdW1uczwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImluZm8tZGl2aWRlclwiPuKAojwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImluZm8tbGFiZWxcIj5Db21wb25lbnRzOjwvc3Bhbj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImluZm8tdmFsdWVcIj57eyBjb21wb25lbnRzKCkubGVuZ3RoIH19PC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwiaW5mby1kaXZpZGVyXCI+4oCiPC9zcGFuPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwibGl2ZS1tb2RlLWJhZGdlXCIgdGl0bGU9XCJJbnRlcmFjdGl2ZSBjYW52YXM6IFZhbHVlcyB0eXBlZCBoZXJlIHJ1biBsaXZlIHF1ZXJpZXMgYW5kIHRlc3QgZHJvcGRvd25zLlwiPlxuICAgICAgICAgICAg4pqhIExpdmUgSW50ZXJhY3RpdmUgTW9kZVxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPGRpdiBjbGFzcz1cImNhbnZhcy1hY3Rpb25zXCI+XG4gICAgICAgICAgQGlmICghZGVmaW5pdGlvbigpLmdyaWQpIHtcbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgIGNsYXNzPVwiY2FudmFzLWFjdGlvbi1idG4gYnRuLWdyaWQtYWRkXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cImFkZFJlc3VsdEdyaWQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgIHRpdGxlPVwiQWRkIGEgUmVzdWx0IEdyaWQgdG8gdGhpcyByZXBvcnRcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cInRhYmxlXCIgW3NpemVdPVwiMTRcIiAvPlxuICAgICAgICAgICAgICA8c3Bhbj4rIEFkZCBHcmlkPC9zcGFuPlxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICBjbGFzcz1cImNhbnZhcy1hY3Rpb24tYnRuIGJ0bi1ncmlkLWNvbmZpZ3VyZWRcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwic2VsZWN0R3JpZFNldHRpbmdzKCRldmVudClcIlxuICAgICAgICAgICAgICB0aXRsZT1cIkNvbmZpZ3VyZSBSZXN1bHQgRGF0YSBHcmlkXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJ0YWJsZVwiIFtzaXplXT1cIjE0XCIgLz5cbiAgICAgICAgICAgICAgPHNwYW4+R3JpZCAoe3sgZGVmaW5pdGlvbigpLmdyaWQ/LmNvbHVtbnM/Lmxlbmd0aCA/PyAwIH19KTwvc3Bhbj5cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIH1cblxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgY2xhc3M9XCJjYW52YXMtYWN0aW9uLWJ0blwiXG4gICAgICAgICAgICAoY2xpY2spPVwic2VsZWN0UmVwb3J0U2V0dGluZ3MoJGV2ZW50KVwiXG4gICAgICAgICAgICB0aXRsZT1cIkNvbmZpZ3VyZSBQYWdlIExheW91dCAmIEdyaWQgU2V0dGluZ3NcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwic2V0dGluZ3NcIiBbc2l6ZV09XCIxNFwiIC8+XG4gICAgICAgICAgICA8c3Bhbj5SZXBvcnQgU2V0dGluZ3M8L3NwYW4+XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gQ2FudmFzIERyb3AgQXJlYSAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJjYW52YXMtc2Nyb2xsLWFyZWFcIj5cbiAgICAgICAgPGRpdlxuICAgICAgICAgIGNsYXNzPVwiY2FudmFzLWFydGJvYXJkXCJcbiAgICAgICAgICBbc3R5bGUucGFkZGluZy5weF09XCJkZWZpbml0aW9uKCkubGF5b3V0LnBhZGRpbmcgPz8gMjRcIlxuICAgICAgICA+XG4gICAgICAgICAgPCEtLSBSZXBvcnQgSGVhZGVyIFByZXZpZXcgLS0+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImNhbnZhcy1yZXBvcnQtaGVhZGVyXCI+XG4gICAgICAgICAgICA8aDIgY2xhc3M9XCJjYW52YXMtcmVwb3J0LXRpdGxlXCI+e3sgZGVmaW5pdGlvbigpLm5hbWUgfHwgJ1VudGl0bGVkIFJlcG9ydCcgfX08L2gyPlxuICAgICAgICAgICAgQGlmIChkZWZpbml0aW9uKCkuZGVzY3JpcHRpb24pIHtcbiAgICAgICAgICAgICAgPHAgY2xhc3M9XCJjYW52YXMtcmVwb3J0LWRlc2NcIj57eyBkZWZpbml0aW9uKCkuZGVzY3JpcHRpb24gfX08L3A+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8IS0tIENvbXBvbmVudCBEcm9wIExpc3QgR3JpZCB3aXRoIDJEIG1peGVkIG9yaWVudGF0aW9uIGFuZCBkYXRhIGJpbmRpbmcgLS0+XG4gICAgICAgICAgPGRpdlxuICAgICAgICAgICAgY2RrRHJvcExpc3RcbiAgICAgICAgICAgIGlkPVwiZGVzaWduZXItY2FudmFzLWRyb3AtbGlzdFwiXG4gICAgICAgICAgICBjbGFzcz1cImNhbnZhcy1ncmlkXCJcbiAgICAgICAgICAgIGNka0Ryb3BMaXN0T3JpZW50YXRpb249XCJtaXhlZFwiXG4gICAgICAgICAgICBbY2RrRHJvcExpc3REYXRhXT1cInNvcnRlZENvbXBvbmVudHMoKVwiXG4gICAgICAgICAgICBbc3R5bGUuZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zXT1cImdyaWRUZW1wbGF0ZUNvbHVtbnMoKVwiXG4gICAgICAgICAgICBbc3R5bGUuZ2FwLnB4XT1cImRlZmluaXRpb24oKS5sYXlvdXQuZ2FwID8/IDE2XCJcbiAgICAgICAgICAgIChjZGtEcm9wTGlzdERyb3BwZWQpPVwib25Ecm9wKCRldmVudClcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIEBmb3IgKGNvbXAgb2Ygc29ydGVkQ29tcG9uZW50cygpOyB0cmFjayBjb21wLmlkOyBsZXQgaWR4ID0gJGluZGV4KSB7XG4gICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICBjZGtEcmFnXG4gICAgICAgICAgICAgICAgW2Nka0RyYWdEYXRhXT1cImNvbXBcIlxuICAgICAgICAgICAgICAgIFtjZGtEcmFnRGlzYWJsZWRdPVwiaXNBbnlSZXNpemluZygpXCJcbiAgICAgICAgICAgICAgICBjbGFzcz1cImNhbnZhcy1jb21wb25lbnQtY2FyZFwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLmlzLXNlbGVjdGVkXT1cImlzU2VsZWN0ZWQoY29tcC5pZClcIlxuICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1yZXNpemluZ109XCJyZXNpemluZ0NvbXBJZCgpID09PSBjb21wLmlkXCJcbiAgICAgICAgICAgICAgICBbY2xhc3MuaXMtZmllbGQtaGlnaGxpZ2h0ZWRdPVwiaXNGaWVsZEhpZ2hsaWdodGVkKGNvbXApXCJcbiAgICAgICAgICAgICAgICBbY2xhc3MuaXMtbmFycm93XT1cImdldFNwYW4oY29tcCkgPD0gNFwiXG4gICAgICAgICAgICAgICAgW2NsYXNzLmlzLWNvbXBhY3RdPVwiZ2V0U3Bhbihjb21wKSA8PSAyXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUuZ3JpZC1jb2x1bW5dPVwiZ2V0R3JpZENvbHVtbihjb21wKVwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLmdyaWQtcm93XT1cImdldEdyaWRSb3coY29tcClcIlxuICAgICAgICAgICAgICAgIFtzdHlsZS53aWR0aF09XCJjb21wLmxheW91dD8ud2lkdGggfHwgJ2F1dG8nXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUuaGVpZ2h0XT1cImdldENvbXBvbmVudEhlaWdodChjb21wKVwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLm1pbi1oZWlnaHRdPVwiZ2V0Q29tcG9uZW50TWluSGVpZ2h0KGNvbXApXCJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwib25TZWxlY3QoY29tcC5pZCwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8IS0tIENhcmQgSGVhZGVyIHdpdGggRHJhZyBIYW5kbGUgJiBBY3Rpb25zIC0tPlxuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYXJkLWhlYWRlclwiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhcmQtdGl0bGUtZ3JvdXBcIiBjZGtEcmFnSGFuZGxlIHRpdGxlPVwiRHJhZyB0byByZW9yZGVyXCI+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZHJhZy1oYW5kbGUtZG90c1wiPuKLruKLrjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIFtuYW1lXT1cImdldENvbXBvbmVudEljb25OYW1lKGNvbXAudHlwZSlcIiBbc2l6ZV09XCIxNFwiIC8+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiY29tcC10aXRsZVwiIFt0aXRsZV09XCJjb21wLmxhYmVsIHx8IGNvbXAua2V5IHx8IGNvbXAudHlwZVwiPlxuICAgICAgICAgICAgICAgICAgICAgIHt7IGNvbXAubGFiZWwgfHwgY29tcC5rZXkgfHwgY29tcC50eXBlIH19XG4gICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FyZC1hY3Rpb25zXCI+XG4gICAgICAgICAgICAgICAgICAgIDwhLS0gU3RhdGljIHNwYW4gcGlsbCAmIG5ldyByb3cgLyBzdGFydCBjb2wgcGlsbCB3aGVuIG5vdCBob3ZlcmVkIC8gbm90IHNlbGVjdGVkIC0tPlxuICAgICAgICAgICAgICAgICAgICBAaWYgKGNvbXAubGF5b3V0Py5jb2x1bW47IGFzIGNvbCkge1xuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibmV3LXJvdy1waWxsLXN0YXRpY1wiIHRpdGxlPVwiU3RhcnRzIGF0IENvbHVtbiB7eyBjb2wgfX1cIj5Db2wge3sgY29sIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICB9IEBlbHNlIGlmIChjb21wLmxheW91dD8ubmV3Um93KSB7XG4gICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJuZXctcm93LXBpbGwtc3RhdGljXCIgdGl0bGU9XCJTdGFydHMgb24gc2VwYXJhdGUgcm93XCI+4oazIFJvdzwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwic3Bhbi1waWxsLXN0YXRpY1wiXG4gICAgICAgICAgICAgICAgICAgICAgdGl0bGU9XCJDb2x1bW4gc3Bhbjoge3sgZ2V0U3Bhbihjb21wKSB9fSBvZiB7eyB0b3RhbENvbHVtbnMoKSB9fSBjb2x1bW5zXCJcbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgIHt7IGdldFNwYW4oY29tcCkgfX0ve3sgdG90YWxDb2x1bW5zKCkgfX1cbiAgICAgICAgICAgICAgICAgICAgPC9zcGFuPlxuXG4gICAgICAgICAgICAgICAgICAgIDwhLS0gUXVpY2sgQWN0aW9uIFN0ZXBwZXIgJiBCdXR0b25zIChyZXZlYWxlZCBvbiBob3ZlciBvciBzZWxlY3Rpb24pIC0tPlxuICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FyZC1xdWljay1jb250cm9sc1wiPlxuICAgICAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjYXJkLWFjdGlvbi1idG5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmJ0bi1hY3RpdmUtdG9nZ2xlXT1cImNvbXAubGF5b3V0Py5uZXdSb3dcIlxuICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInRvZ2dsZU5ld1Jvdyhjb21wLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlPVwie3sgY29tcC5sYXlvdXQ/Lm5ld1JvdyA/ICdTdGFydHMgb24gbmV3IHJvdyAoQ2xpY2sgdG8gcGxhY2UgaW5saW5lKScgOiAnU3RhcnQgb24gc2VwYXJhdGUgcm93IChSb3cgQnJlYWspJyB9fVwiXG4gICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJjb3JuZXItZG93bi1yaWdodFwiIFtzaXplXT1cIjExXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cblxuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzcGFuLWNvbnRyb2wtZ3JvdXBcIiB0aXRsZT1cIkFkanVzdCBDb2x1bW4gU3BhblwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJzcGFuLWJ0blwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJnZXRTcGFuKGNvbXApIDw9IDFcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYWRqdXN0U3Bhbihjb21wLCAtMSwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlPVwiU2hyaW5rIENvbHVtbiBTcGFuXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJtaW51c1wiIFtzaXplXT1cIjlcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInNwYW4tYmFkZ2VcIiBbdGl0bGVdPVwiJ0NvbHVtbiBzcGFuOiAnICsgZ2V0U3Bhbihjb21wKSArICcgb2YgJyArIHRvdGFsQ29sdW1ucygpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3Bhbi1udW1cIj57eyBnZXRTcGFuKGNvbXApIH19PC9zcGFuPjxzcGFuIGNsYXNzPVwic3Bhbi10b3RhbFwiPi97eyB0b3RhbENvbHVtbnMoKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwic3Bhbi1idG5cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiZ2V0U3Bhbihjb21wKSA+PSB0b3RhbENvbHVtbnMoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJhZGp1c3RTcGFuKGNvbXAsIDEsICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIkV4cGFuZCBDb2x1bW4gU3BhblwiXG4gICAgICAgICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwicGx1c1wiIFtzaXplXT1cIjlcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY2FyZC1hY3Rpb24tYnRuXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJvbkR1cGxpY2F0ZShjb21wLmlkLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlPVwiRHVwbGljYXRlIGNvbXBvbmVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJjb3B5XCIgW3NpemVdPVwiMTJcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjYXJkLWFjdGlvbi1idG4gYnRuLWRlbGV0ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwib25EZWxldGUoY29tcC5pZCwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIlJlbW92ZSBjb21wb25lbnRcIlxuICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwidHJhc2hcIiBbc2l6ZV09XCIxMlwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgICAgICA8IS0tIENhcmQgQm9keSBWaXN1YWwgUHJldmlldyAtLT5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FyZC1ib2R5XCI+XG5cbiAgICAgICAgICAgICAgICAgIEBzd2l0Y2ggKGNvbXAudHlwZSkge1xuICAgICAgICAgICAgICAgICAgICBAY2FzZSAoJ2lucHV0Jykge1xuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2NrLWlucHV0LWZpZWxkXCIgKGNsaWNrKT1cIm9uQ29udHJvbEludGVyYWN0KGNvbXAsICRldmVudClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibW9jay1sYWJlbFwiPnt7IGNvbXAubGFiZWwgfHwgJ0lucHV0JyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoZ2V0Q2FudmFzQ29udHJvbChjb21wKTsgYXMgY3RybCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjYW52YXMtYWN0aXZlLWlucHV0XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGxhY2Vob2xkZXJdPVwiY29tcC5wcm9wZXJ0aWVzPy5bJ3BsYWNlaG9sZGVyJ10gfHwgJ0VudGVyIHRleHQuLi4nXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwiY3RybFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKGZvY3VzKT1cIm9uQ29udHJvbEludGVyYWN0KGNvbXAsICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2NrLWlucHV0LWJveFwiPnt7IGNvbXAucHJvcGVydGllcz8uWydwbGFjZWhvbGRlciddIHx8ICdFbnRlciB0ZXh0Li4uJyB9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEBjYXNlICgnZHJvcGRvd24nKSB7XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhbnZhcy1saXZlLWNvbnRyb2wtd3JhcHBlclwiIChjbGljayk9XCJvbkNvbnRyb2xJbnRlcmFjdChjb21wLCAkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8cnB0LWRyb3Bkb3duXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtjb25maWddPVwiY29tcFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtzaG93U3RhdHVzXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbcGFyZW50Rm9ybV09XCJjYW52YXNGb3JtKClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbY29udHJvbF09XCJnZXRDYW52YXNDb250cm9sKGNvbXApXCJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGNhc2UgKCdkYXRlJykge1xuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2NrLWlucHV0LWZpZWxkXCIgKGNsaWNrKT1cIm9uQ29udHJvbEludGVyYWN0KGNvbXAsICRldmVudClcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibW9jay1sYWJlbFwiPnt7IGNvbXAubGFiZWwgfHwgJ0RhdGUnIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChnZXRDYW52YXNDb250cm9sKGNvbXApOyBhcyBjdHJsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJkYXRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImNhbnZhcy1hY3RpdmUtaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJjdHJsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZm9jdXMpPVwib25Db250cm9sSW50ZXJhY3QoY29tcCwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2stc2VsZWN0LWJveFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuPllZWVktTU0tREQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJjYWxlbmRhclwiIFtzaXplXT1cIjEyXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGNhc2UgKCdkYXRlLXJhbmdlJykge1xuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYW52YXMtbGl2ZS1jb250cm9sLXdyYXBwZXJcIiAoY2xpY2spPVwib25Db250cm9sSW50ZXJhY3QoY29tcCwgJGV2ZW50KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHJwdC1kYXRlLXJhbmdlXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtjb25maWddPVwiY29tcFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtjb250cm9sXT1cImdldENhbnZhc0NvbnRyb2woY29tcClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBAY2FzZSAoJ251bWJlcicpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1pbnB1dC1maWVsZFwiIChjbGljayk9XCJvbkNvbnRyb2xJbnRlcmFjdChjb21wLCAkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1vY2stbGFiZWxcIj57eyBjb21wLmxhYmVsIHx8ICdOdW1iZXInIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChnZXRDYW52YXNDb250cm9sKGNvbXApOyBhcyBjdHJsKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJudW1iZXJcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY2FudmFzLWFjdGl2ZS1pbnB1dFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Zvcm1Db250cm9sXT1cImN0cmxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmb2N1cyk9XCJvbkNvbnRyb2xJbnRlcmFjdChjb21wLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1pbnB1dC1ib3hcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBjb21wLnByb3BlcnRpZXM/LlsncHJlZml4J10gfHwgJycgfX0gMC4wMCB7eyBjb21wLnByb3BlcnRpZXM/Llsnc3VmZml4J10gfHwgJycgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGNhc2UgKCdjaGVja2JveCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1jaGVja2JveC1maWVsZFwiIChjbGljayk9XCJvbkNvbnRyb2xJbnRlcmFjdChjb21wLCAkZXZlbnQpXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBAaWYgKGdldENhbnZhc0NvbnRyb2woY29tcCk7IGFzIGN0cmwpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiY2FudmFzLWFjdGl2ZS1jaGVja2JveC1sYmxcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8aW5wdXQgdHlwZT1cImNoZWNrYm94XCIgW2Zvcm1Db250cm9sXT1cImN0cmxcIiAoZm9jdXMpPVwib25Db250cm9sSW50ZXJhY3QoY29tcCwgJGV2ZW50KVwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtb2NrLWxhYmVsXCI+e3sgY29tcC5sYWJlbCB8fCAnQ2hlY2tib3gnIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibW9jay1jaGVjay1ib3hcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cImNoZWNrXCIgW3NpemVdPVwiMTBcIiAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibW9jay1sYWJlbFwiPnt7IGNvbXAubGFiZWwgfHwgJ0NoZWNrYm94JyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBAY2FzZSAoJ2J1dHRvbicpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1idG4td3JhcHBlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJtb2NrLWJ0blwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtjbGFzc109XCInYnRuLScgKyAoY29tcC5wcm9wZXJ0aWVzPy5bJ3ZhcmlhbnQnXSB8fCAncHJpbWFyeScpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2NsYXNzLm1vY2stYnRuLWZ1bGxdPVwiY29tcC5wcm9wZXJ0aWVzPy5bJ2Z1bGxXaWR0aCddID09PSB0cnVlIHx8IGNvbXAubGF5b3V0Py53aWR0aCA9PT0gJzEwMCUnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW3N0eWxlLmhlaWdodF09XCJnZXRDdXN0b21CdG5IZWlnaHQoY29tcClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGhdPVwiZ2V0Q3VzdG9tQnRuV2lkdGgoY29tcClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwib25DYW52YXNCdXR0b25DbGljayhjb21wLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChnZXRDdXN0b21CdG5JY29uKGNvbXApOyBhcyBidG5JY29uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIFtuYW1lXT1cImJ0bkljb25cIiBbc2l6ZV09XCIxNVwiIC8+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4+e3sgY29tcC5sYWJlbCB8fCAnQnV0dG9uJyB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEBjYXNlICgna3BpLWNhcmQnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2sta3BpLWZpZWxkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1rcGktaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibW9jay1sYWJlbFwiPnt7IGNvbXAubGFiZWwgfHwgJ0tQSSBNZXRyaWMnIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cImtwaVwiIFtzaXplXT1cIjE0XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2sta3BpLXZhbHVlXCI+e3sgY29tcC5wcm9wZXJ0aWVzPy5bJ3ZhbHVlJ10gfHwgJyQxMjgsNDUwJyB9fTwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2sta3BpLWZvb3RlclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1vY2sta3BpLXRyZW5kXCI+KzEyLjUlPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1vY2sta3BpLXN1YlwiPnZzIGxhc3QgcGVyaW9kPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGNhc2UgKCdjaGFydCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1jaGFydC1maWVsZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2stY2hhcnQtaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibW9jay1sYWJlbFwiPnt7IGNvbXAubGFiZWwgfHwgJ1F1YXJ0ZXJseSBTYWxlcyBSZXZlbnVlICgkMDAwKScgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2NrLWNoYXJ0LWJhcnNcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2stY2hhcnQtY29sXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2stY2hhcnQtYmFyXCIgc3R5bGU9XCJoZWlnaHQ6IDQ0JVwiPjwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwibW9jay1iYXItbGJsXCI+UTEgSmFuLU1hcjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2NrLWNoYXJ0LWNvbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2NrLWNoYXJ0LWJhclwiIHN0eWxlPVwiaGVpZ2h0OiA2MSVcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1vY2stYmFyLWxibFwiPlEyIEFwci1KdW48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1jaGFydC1jb2xcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibW9jay1jaGFydC1iYXJcIiBzdHlsZT1cImhlaWdodDogNzklXCI+PC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJtb2NrLWJhci1sYmxcIj5RMyBKdWwtU2VwPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2stY2hhcnQtY29sXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIm1vY2stY2hhcnQtYmFyXCIgc3R5bGU9XCJoZWlnaHQ6IDEwMCVcIj48L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm1vY2stYmFyLWxibFwiPlE0IE9jdC1EZWM8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGRlZmF1bHQge1xuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJtb2NrLWdlbmVyaWMtYm94XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj57eyBjb21wLnR5cGUgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICAgIDwhLS0gUmVzaXppbmcgSGFuZGxlcyAoRWFzdCwgU291dGgsIFNvdXRoLUVhc3QpIC0tPlxuICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwicmVzaXplLWhhbmRsZSBoYW5kbGUtZVwiXG4gICAgICAgICAgICAgICAgICAocG9pbnRlcmRvd24pPVwic3RhcnRSZXNpemUoJGV2ZW50LCBjb21wLCAnZScpXCJcbiAgICAgICAgICAgICAgICAgIChkYmxjbGljayk9XCJyZXNldERpbWVuc2lvbnMoY29tcCwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICB0aXRsZT1cIkRyYWcgdG8gcmVzaXplIGNvbHVtbiB3aWR0aCDigKIgRG91YmxlLWNsaWNrIHRvIHJlc2V0XCJcbiAgICAgICAgICAgICAgICA+PC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJyZXNpemUtaGFuZGxlIGhhbmRsZS1zXCJcbiAgICAgICAgICAgICAgICAgIChwb2ludGVyZG93bik9XCJzdGFydFJlc2l6ZSgkZXZlbnQsIGNvbXAsICdzJylcIlxuICAgICAgICAgICAgICAgICAgKGRibGNsaWNrKT1cInJlc2V0RGltZW5zaW9ucyhjb21wLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgIHRpdGxlPVwiRHJhZyB0byByZXNpemUgaGVpZ2h0IOKAoiBEb3VibGUtY2xpY2sgdG8gcmVzZXRcIlxuICAgICAgICAgICAgICAgID48L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICBjbGFzcz1cInJlc2l6ZS1oYW5kbGUgaGFuZGxlLXNlXCJcbiAgICAgICAgICAgICAgICAgIChwb2ludGVyZG93bik9XCJzdGFydFJlc2l6ZSgkZXZlbnQsIGNvbXAsICdzZScpXCJcbiAgICAgICAgICAgICAgICAgIChkYmxjbGljayk9XCJyZXNldERpbWVuc2lvbnMoY29tcCwgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICB0aXRsZT1cIkRyYWcgdG8gcmVzaXplIHdpZHRoIGFuZCBoZWlnaHQg4oCiIERvdWJsZS1jbGljayB0byByZXNldFwiXG4gICAgICAgICAgICAgICAgPjwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPCEtLSBSZXNpemluZyBEaW1lbnNpb24gR2hvc3QgLyBCYWRnZSAtLT5cbiAgICAgICAgICAgICAgICBAaWYgKHJlc2l6aW5nQ29tcElkKCkgPT09IGNvbXAuaWQpIHtcbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJyZXNpemUtZGltZW5zaW9uLXRvb2x0aXBcIj5cbiAgICAgICAgICAgICAgICAgICAge3sgcmVzaXppbmdUb29sdGlwKGNvbXApIH19XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICA8IS0tIERyYWcgcGxhY2Vob2xkZXIgd2l0aCBtYXRjaGVkIGdyaWQgY29sdW1uIHNwYW4gLS0+XG4gICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgKmNka0RyYWdQbGFjZWhvbGRlclxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjYW52YXMtZHJhZy1wbGFjZWhvbGRlclwiXG4gICAgICAgICAgICAgICAgICBbc3R5bGUuZ3JpZC1jb2x1bW5dPVwiZ2V0R3JpZENvbHVtbihjb21wKVwiXG4gICAgICAgICAgICAgICAgPjwvZGl2PlxuXG4gICAgICAgICAgICAgICAgPCEtLSBEcmFnIHByZXZpZXcgLS0+XG4gICAgICAgICAgICAgICAgPGRpdiAqY2RrRHJhZ1ByZXZpZXcgY2xhc3M9XCJjYW52YXMtZHJhZy1wcmV2aWV3XCI+XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImRyYWctaGFuZGxlLWRvdHNcIj7ii67ii648L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8cnB0LWljb24gW25hbWVdPVwiZ2V0Q29tcG9uZW50SWNvbk5hbWUoY29tcC50eXBlKVwiIFtzaXplXT1cIjE0XCIgLz5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwicHJldmlldy10aXRsZVwiPnt7IGNvbXAubGFiZWwgfHwgY29tcC5rZXkgfHwgY29tcC50eXBlIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJwcmV2aWV3LXNwYW5cIj57eyBnZXRTcGFuKGNvbXApIH19L3t7IHRvdGFsQ29sdW1ucygpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgQGlmIChjb21wb25lbnRzKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYW52YXMtZW1wdHktc3RhdGVcIiByb2xlPVwicmVnaW9uXCIgYXJpYS1sYWJlbD1cIkVtcHR5IGNhbnZhcyBzdGFydGVyIG9wdGlvbnNcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZW1wdHktaGVyby1iYWRnZVwiPlxuICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJkZXNpZ25cIiBbc2l6ZV09XCIyOFwiIC8+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGgzIGNsYXNzPVwiZW1wdHktaGVyby10aXRsZVwiPlN0YXJ0IERlc2lnbmluZyBZb3VyIEN1c3RvbSBSZXBvcnQ8L2gzPlxuICAgICAgICAgICAgICAgIDxwIGNsYXNzPVwiZW1wdHktaGVyby1kZXNjXCI+XG4gICAgICAgICAgICAgICAgICBEcmFnIGNvbnRyb2xzIGZyb20gdGhlIGxlZnQgY29tcG9uZW50IHBhbGV0dGUsIG9yIGp1bXBzdGFydCB5b3VyIGRlc2lnbiB3aXRoIHByZS1jb25maWd1cmVkIGVudGVycHJpc2UgYmx1ZXByaW50cy5cbiAgICAgICAgICAgICAgICA8L3A+XG5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZW1wdHktaGVyby1hY3Rpb25zXCI+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImVtcHR5LWJ0biBlbXB0eS1idG4tcHJpbWFyeVwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJhcHBseUJsdWVwcmludCgnYmx1ZXByaW50LWF1ZGl0LXJlZ2lzdGVyJylcIlxuICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIkxvYWQgY29tcGxldGUgQXVkaXQgUmVnaXN0ZXIgYmx1ZXByaW50IHdpdGggcGFyYW1ldGVycyBhbmQgcmVzdWx0IGdyaWRcIlxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cInRhYmxlXCIgW3NpemVdPVwiMTVcIiAvPlxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj5BdWRpdCBSZWdpc3RlciBCbHVlcHJpbnQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiZW1wdHktYnRuIGVtcHR5LWJ0bi1zZWNvbmRhcnlcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYXBwbHlCbHVlcHJpbnQoJ2JsdWVwcmludC1rcGktc3VtbWFyeScpXCJcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU9XCJMb2FkIEV4ZWN1dGl2ZSBLUEkgc3VtbWFyeSBibHVlcHJpbnRcIlxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cImNoYXJ0LWJhclwiIFtzaXplXT1cIjE1XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+S1BJIFN1bW1hcnkgQmx1ZXByaW50PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImVtcHR5LWJ0biBlbXB0eS1idG4tb3V0bGluZVwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJhZGRTdGFydGVyQ29tcG9uZW50KCdkYXRlLXJhbmdlJylcIlxuICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIkFkZCBhIERhdGUgUmFuZ2UgZmlsdGVyIGNvbXBvbmVudFwiXG4gICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwiY2FsZW5kYXJcIiBbc2l6ZV09XCIxNFwiIC8+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuPisgQWRkIERhdGUgRmlsdGVyPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImVtcHR5LWJ0biBlbXB0eS1idG4tb3V0bGluZVwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJhZGRTdGFydGVyQ29tcG9uZW50KCdidXR0b24nKVwiXG4gICAgICAgICAgICAgICAgICAgIHRpdGxlPVwiQWRkIGFuIEV4ZWN1dGUgQWN0aW9uIGJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwicGxheVwiIFtzaXplXT1cIjE0XCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+KyBBZGQgUnVuIEJ1dHRvbjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgIDwhLS0gTGl2ZSBSZXN1bHQgR3JpZCBQcmV2aWV3IHdpdGggQndheXMtR3JpZCBGZWF0dXJlcyAtLT5cbiAgICAgICAgICBAaWYgKGRlZmluaXRpb24oKS5ncmlkKSB7XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FudmFzLWdyaWQtYm94XCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJncmlkLXByZXZpZXctaGVhZGVyXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBzdHlsZT1cImRpc3BsYXk6IGZsZXg7IGFsaWduLWl0ZW1zOiBjZW50ZXI7IGdhcDogOHB4O1wiPlxuICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJ0YWJsZVwiIFtzaXplXT1cIjE1XCIgLz5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZ3JpZC10aXRsZVwiPkJ3YXlzIEdyaWQgKHt7IGRlZmluaXRpb24oKS5ncmlkPy5jb2x1bW5zPy5sZW5ndGggPz8gMCB9fSBjb2x1bW5zKTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIEBpZiAoaXNFeGVjdXRpbmdHcmlkKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJncmlkLWV4ZWMtYmFkZ2UgaXMtbG9hZGluZ1wiPkxvYWRpbmcgZGF0YSBmcm9tIGRhdGFiYXNlLi4uPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgfSBAZWxzZSBpZiAoZ3JpZEV4ZWNFcnJvcigpKSB7XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZ3JpZC1leGVjLWJhZGdlIGlzLWVycm9yXCI+e3sgZ3JpZEV4ZWNFcnJvcigpIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgfSBAZWxzZSBpZiAoY2FudmFzR3JpZERhdGEoKS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZ3JpZC1leGVjLWJhZGdlIGlzLXN1Y2Nlc3NcIj57eyBjYW52YXNHcmlkRGF0YSgpLmxlbmd0aCB9fSByb3dzIGxvYWRlZDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IHN0eWxlPVwiZGlzcGxheTogZmxleDsgYWxpZ24taXRlbXM6IGNlbnRlcjsgZ2FwOiA4cHg7XCI+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImJ0bi1jYW52YXMtcnVuLWdyaWRcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiZXhlY3V0ZUNhbnZhc1JlcG9ydCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImlzRXhlY3V0aW5nR3JpZCgpXCJcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU9XCJFeGVjdXRlIHF1ZXJ5IGFuZCBsb2FkIGRhdGEgaW50byBCd2F5cyBHcmlkXCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJwbGF5XCIgW3NpemVdPVwiMTFcIiAvPlxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj57eyBpc0V4ZWN1dGluZ0dyaWQoKSA/ICdSdW5uaW5nLi4uJyA6ICdSdW4gLyBSZWZyZXNoIEdyaWQnIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImJ0bi1jYW52YXMtZWRpdC1ncmlkXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInNlbGVjdEdyaWRTZXR0aW5ncygkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgdGl0bGU9XCJDb25maWd1cmUgY29sdW1ucyBhbmQgZ3JpZCBvcHRpb25zXCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJzZXR0aW5nc1wiIFtzaXplXT1cIjExXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+Q29uZmlndXJlPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImJ0bi1yZW1vdmUtZ3JpZFwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJyZW1vdmVHcmlkKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIlJlbW92ZSBSZXN1bHQgR3JpZCBmcm9tIHRoaXMgcmVwb3J0XCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJ0cmFzaFwiIFtzaXplXT1cIjEzXCIgLz5cbiAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8L2Rpdj5cblxuICAgICAgICAgICAgICBAaWYgKGdldEdyaWRTdW1tYXJ5VGV4dCgpOyBhcyBzdW1tYXJ5KSB7XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImdyaWQtbGF5b3V0LXN0YXR1cy1zdHJpcFwiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImdyaWQtc3RhdHVzLWluZm9cIj5cbiAgICAgICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJ0YWJsZVwiIFtzaXplXT1cIjEyXCIgLz5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+e3sgc3VtbWFyeSB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImdyaWQtc3RhdHVzLXN5bmNcIiBbY2xhc3MuaXMtcHVsc2luZ109XCJsYXlvdXRKdXN0VXBkYXRlZCgpXCI+XG4gICAgICAgICAgICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwiY2hlY2tcIiBbc2l6ZV09XCIxMVwiIC8+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuPkxheW91dCBhdXRvLXBlcnNpc3RlZDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgPCEtLSBMaXZlIEJ3YXlzIEdyaWQgYnJpZGdlIC0tPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY2FudmFzLWxpdmUtZ3JpZC1jb250YWluZXJcIiAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCIgc3R5bGU9XCJwb3NpdGlvbjogcmVsYXRpdmU7IG1pbi1oZWlnaHQ6IDI1MHB4O1wiPlxuICAgICAgICAgICAgICAgIEBpZiAoaXNFeGVjdXRpbmdHcmlkKCkpIHtcbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjYW52YXMtZ3JpZC1sb2FkaW5nLW92ZXJsYXlcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0dXMtZG90IGRvdC1wdWxzZVwiIHN0eWxlPVwid2lkdGg6IDE0cHg7IGhlaWdodDogMTRweDsgY29sb3I6ICMyNTYzZWI7IGJhY2tncm91bmQ6ICMyNTYzZWI7IGJvcmRlci1yYWRpdXM6IDUwJTtcIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZ3JpZC1sb2FkaW5nLXRpdGxlXCI+RXhlY3V0aW5nIHN0b3JlZCBwcm9jZWR1cmUgb24gU1FMIFNlcnZlci4uLjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJncmlkLWxvYWRpbmctc3ViXCI+Q2FsY3VsYXRpbmcgb3V0c3RhbmRpbmcgYmFsYW5jZXMgYW5kIGxlZGdlciBhbW91bnRzLiBQbGVhc2Ugd2FpdC4uLjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA8cnB0LWdyaWQtYnJpZGdlXG4gICAgICAgICAgICAgICAgICBbZ3JpZERlZmluaXRpb25dPVwiZGVmaW5pdGlvbigpLmdyaWQhXCJcbiAgICAgICAgICAgICAgICAgIFtkYXRhXT1cImNhbnZhc0dyaWREYXRhKClcIlxuICAgICAgICAgICAgICAgICAgKGdyaWRTdGF0ZUNoYW5nZSk9XCJvbkNhbnZhc0dyaWRTdGF0ZUNoYW5nZSgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgIChjb2x1bW5EZWZzQ2hhbmdlKT1cIm9uQ2FudmFzQ29sdW1uRGVmc0NoYW5nZSgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNhbnZhcy1hZGQtZ3JpZC1iYW5uZXJcIiAoY2xpY2spPVwiYWRkUmVzdWx0R3JpZCgkZXZlbnQpXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhZGQtZ3JpZC1pY29uXCI+XG4gICAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJ0YWJsZVwiIFtzaXplXT1cIjIwXCIgLz5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJhZGQtZ3JpZC10ZXh0XCI+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJhZGQtZ3JpZC10aXRsZVwiPisgQWRkIFJlc3VsdCBEYXRhIEdyaWQ8L3NwYW4+XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJhZGQtZ3JpZC1zdWJcIj5BdHRhY2ggYW4gaW50ZXJhY3RpdmUgZGF0YSB0YWJsZSBvciBVbHRyYUdyaWQgdG8gZGlzcGxheSByZXBvcnQgZXhlY3V0aW9uIG91dHB1dDwvc3Bhbj5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuLWJhbm5lci1hZGRcIj5BZGQgR3JpZDwvYnV0dG9uPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgfVxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PiJdfQ==
|