bways-report 0.1.0
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/LICENSE +26 -0
- package/README.md +477 -0
- package/esm2022/bways-report.mjs +5 -0
- package/esm2022/lib/core/errors/index.mjs +2 -0
- package/esm2022/lib/core/errors/reporting-errors.mjs +65 -0
- package/esm2022/lib/core/index.mjs +8 -0
- package/esm2022/lib/core/models/component-event.model.mjs +8 -0
- package/esm2022/lib/core/models/index.mjs +5 -0
- package/esm2022/lib/core/models/report-component.model.mjs +10 -0
- package/esm2022/lib/core/models/report-datasource.model.mjs +9 -0
- package/esm2022/lib/core/models/report-definition.model.mjs +13 -0
- package/esm2022/lib/core/models/report-grid.model.mjs +10 -0
- package/esm2022/lib/core/models/report-layout.model.mjs +9 -0
- package/esm2022/lib/core/models/report-parameter.model.mjs +9 -0
- package/esm2022/lib/core/models/validation.model.mjs +8 -0
- package/esm2022/lib/core/registry/component-category.mjs +8 -0
- package/esm2022/lib/core/registry/component-registry.mjs +90 -0
- package/esm2022/lib/core/registry/index.mjs +2 -0
- package/esm2022/lib/core/registry/property-definition.model.mjs +10 -0
- package/esm2022/lib/core/services/dynamic-form-builder.service.mjs +55 -0
- package/esm2022/lib/core/services/index.mjs +3 -0
- package/esm2022/lib/core/services/report-session-context.service.mjs +314 -0
- package/esm2022/lib/core/tokens/index.mjs +3 -0
- package/esm2022/lib/core/tokens/reporting-config.token.mjs +26 -0
- package/esm2022/lib/core/tokens/session-context.token.mjs +18 -0
- package/esm2022/lib/core/utilities/id-generator.mjs +17 -0
- package/esm2022/lib/core/utilities/index.mjs +3 -0
- package/esm2022/lib/core/utilities/schema-migration.mjs +38 -0
- package/esm2022/lib/core/utils/identifier-humanizer.mjs +88 -0
- package/esm2022/lib/core/validation/index.mjs +2 -0
- package/esm2022/lib/core/validation/validation-factory.mjs +70 -0
- package/esm2022/lib/data-access/adapters/http-lookup.adapter.mjs +107 -0
- package/esm2022/lib/data-access/adapters/http-schema-discovery.adapter.mjs +119 -0
- package/esm2022/lib/data-access/adapters/index.mjs +3 -0
- package/esm2022/lib/data-access/contracts/data-source.contract.mjs +28 -0
- package/esm2022/lib/data-access/contracts/index.mjs +7 -0
- package/esm2022/lib/data-access/contracts/lookup.contract.mjs +6 -0
- package/esm2022/lib/data-access/contracts/master-data.provider.mjs +24 -0
- package/esm2022/lib/data-access/contracts/report-persistence.contract.mjs +25 -0
- package/esm2022/lib/data-access/contracts/schema-discovery.contract.mjs +7 -0
- package/esm2022/lib/data-access/contracts/translation.contract.mjs +9 -0
- package/esm2022/lib/data-access/index.mjs +3 -0
- package/esm2022/lib/features/designer/components/component-palette/component-palette.component.mjs +542 -0
- package/esm2022/lib/features/designer/components/design-canvas/design-canvas.component.mjs +843 -0
- package/esm2022/lib/features/designer/components/property-editor/parameter-binding-editor.component.mjs +556 -0
- package/esm2022/lib/features/designer/components/property-editor/property-editor-datasource.component.mjs +845 -0
- package/esm2022/lib/features/designer/components/property-editor/property-editor-general.component.mjs +185 -0
- package/esm2022/lib/features/designer/components/property-editor/property-editor-grid.component.mjs +452 -0
- package/esm2022/lib/features/designer/components/property-editor/property-editor-layout.component.mjs +350 -0
- package/esm2022/lib/features/designer/components/property-editor/property-editor-report.component.mjs +175 -0
- package/esm2022/lib/features/designer/components/property-editor/property-editor-validation.component.mjs +137 -0
- package/esm2022/lib/features/designer/components/property-editor/property-editor.component.mjs +608 -0
- package/esm2022/lib/features/designer/components/toolbar/designer-toolbar.component.mjs +225 -0
- package/esm2022/lib/features/designer/designer.component.mjs +285 -0
- package/esm2022/lib/features/designer/index.mjs +7 -0
- package/esm2022/lib/features/designer/services/designer-state.service.mjs +310 -0
- package/esm2022/lib/features/designer/services/index.mjs +2 -0
- package/esm2022/lib/features/designer/utilities/canvas-layout.util.mjs +124 -0
- package/esm2022/lib/features/export/index.mjs +2 -0
- package/esm2022/lib/features/export/models/export.models.mjs +2 -0
- package/esm2022/lib/features/export/services/report-export.service.mjs +107 -0
- package/esm2022/lib/features/index.mjs +6 -0
- package/esm2022/lib/features/persistence/index.mjs +2 -0
- package/esm2022/lib/features/persistence/services/index.mjs +4 -0
- package/esm2022/lib/features/persistence/services/report-store.service.mjs +183 -0
- package/esm2022/lib/features/persistence/services/report-versioning.service.mjs +81 -0
- package/esm2022/lib/features/persistence/services/schema-validator.service.mjs +102 -0
- package/esm2022/lib/features/routing/components/routed-report-designer.component.mjs +156 -0
- package/esm2022/lib/features/routing/components/routed-report-runtime.component.mjs +163 -0
- package/esm2022/lib/features/routing/index.mjs +6 -0
- package/esm2022/lib/features/routing/models/report-route.models.mjs +2 -0
- package/esm2022/lib/features/routing/report-routes.mjs +49 -0
- package/esm2022/lib/features/routing/resolvers/report.resolver.mjs +22 -0
- package/esm2022/lib/features/routing/services/report-menu.service.mjs +77 -0
- package/esm2022/lib/features/runtime/dynamic-renderer.component.mjs +222 -0
- package/esm2022/lib/features/runtime/index.mjs +4 -0
- package/esm2022/lib/features/runtime/report-grid-bridge.component.mjs +409 -0
- package/esm2022/lib/features/runtime/report-runtime.component.mjs +147 -0
- package/esm2022/lib/primitives/components/button/rpt-button.component.mjs +88 -0
- package/esm2022/lib/primitives/components/chart-bridge/report-chart-bridge.component.mjs +361 -0
- package/esm2022/lib/primitives/components/checkbox/rpt-checkbox.component.mjs +86 -0
- package/esm2022/lib/primitives/components/date/rpt-date.component.mjs +91 -0
- package/esm2022/lib/primitives/components/dropdown/rpt-dropdown.component.mjs +204 -0
- package/esm2022/lib/primitives/components/icon/rpt-icon.component.mjs +476 -0
- package/esm2022/lib/primitives/components/index.mjs +10 -0
- package/esm2022/lib/primitives/components/input/rpt-input.component.mjs +88 -0
- package/esm2022/lib/primitives/components/kpi-card/rpt-kpi-card.component.mjs +197 -0
- package/esm2022/lib/primitives/components/number/rpt-number.component.mjs +110 -0
- package/esm2022/lib/primitives/index.mjs +3 -0
- package/esm2022/lib/primitives/register-builtins.mjs +328 -0
- package/esm2022/lib/provide-reporting.mjs +92 -0
- package/esm2022/public-api.mjs +9 -0
- package/fesm2022/bways-report.mjs +10360 -0
- package/fesm2022/bways-report.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/core/errors/index.d.ts +1 -0
- package/lib/core/errors/reporting-errors.d.ts +42 -0
- package/lib/core/index.d.ts +7 -0
- package/lib/core/models/component-event.model.d.ts +37 -0
- package/lib/core/models/index.d.ts +11 -0
- package/lib/core/models/report-component.model.d.ts +95 -0
- package/lib/core/models/report-datasource.model.d.ts +39 -0
- package/lib/core/models/report-definition.model.d.ts +100 -0
- package/lib/core/models/report-grid.model.d.ts +73 -0
- package/lib/core/models/report-layout.model.d.ts +43 -0
- package/lib/core/models/report-parameter.model.d.ts +22 -0
- package/lib/core/models/validation.model.d.ts +30 -0
- package/lib/core/registry/component-category.d.ts +16 -0
- package/lib/core/registry/component-registry.d.ts +101 -0
- package/lib/core/registry/index.d.ts +4 -0
- package/lib/core/registry/property-definition.model.d.ts +38 -0
- package/lib/core/services/dynamic-form-builder.service.d.ts +30 -0
- package/lib/core/services/index.d.ts +3 -0
- package/lib/core/services/report-session-context.service.d.ts +87 -0
- package/lib/core/tokens/index.d.ts +4 -0
- package/lib/core/tokens/reporting-config.token.d.ts +42 -0
- package/lib/core/tokens/session-context.token.d.ts +36 -0
- package/lib/core/utilities/id-generator.d.ts +9 -0
- package/lib/core/utilities/index.d.ts +3 -0
- package/lib/core/utilities/schema-migration.d.ts +10 -0
- package/lib/core/utils/identifier-humanizer.d.ts +22 -0
- package/lib/core/validation/index.d.ts +1 -0
- package/lib/core/validation/validation-factory.d.ts +31 -0
- package/lib/data-access/adapters/http-lookup.adapter.d.ts +19 -0
- package/lib/data-access/adapters/http-schema-discovery.adapter.d.ts +20 -0
- package/lib/data-access/adapters/index.d.ts +2 -0
- package/lib/data-access/contracts/data-source.contract.d.ts +37 -0
- package/lib/data-access/contracts/index.d.ts +9 -0
- package/lib/data-access/contracts/lookup.contract.d.ts +32 -0
- package/lib/data-access/contracts/master-data.provider.d.ts +54 -0
- package/lib/data-access/contracts/report-persistence.contract.d.ts +36 -0
- package/lib/data-access/contracts/schema-discovery.contract.d.ts +52 -0
- package/lib/data-access/contracts/translation.contract.d.ts +16 -0
- package/lib/data-access/index.d.ts +2 -0
- package/lib/features/designer/components/component-palette/component-palette.component.d.ts +39 -0
- package/lib/features/designer/components/design-canvas/design-canvas.component.d.ts +42 -0
- package/lib/features/designer/components/property-editor/parameter-binding-editor.component.d.ts +36 -0
- package/lib/features/designer/components/property-editor/property-editor-datasource.component.d.ts +68 -0
- package/lib/features/designer/components/property-editor/property-editor-general.component.d.ts +20 -0
- package/lib/features/designer/components/property-editor/property-editor-grid.component.d.ts +20 -0
- package/lib/features/designer/components/property-editor/property-editor-layout.component.d.ts +18 -0
- package/lib/features/designer/components/property-editor/property-editor-report.component.d.ts +15 -0
- package/lib/features/designer/components/property-editor/property-editor-validation.component.d.ts +12 -0
- package/lib/features/designer/components/property-editor/property-editor.component.d.ts +44 -0
- package/lib/features/designer/components/toolbar/designer-toolbar.component.d.ts +18 -0
- package/lib/features/designer/designer.component.d.ts +36 -0
- package/lib/features/designer/index.d.ts +7 -0
- package/lib/features/designer/services/designer-state.service.d.ts +103 -0
- package/lib/features/designer/services/index.d.ts +2 -0
- package/lib/features/designer/utilities/canvas-layout.util.d.ts +55 -0
- package/lib/features/export/index.d.ts +2 -0
- package/lib/features/export/models/export.models.d.ts +16 -0
- package/lib/features/export/services/report-export.service.d.ts +27 -0
- package/lib/features/index.d.ts +5 -0
- package/lib/features/persistence/index.d.ts +1 -0
- package/lib/features/persistence/services/index.d.ts +5 -0
- package/lib/features/persistence/services/report-store.service.d.ts +53 -0
- package/lib/features/persistence/services/report-versioning.service.d.ts +29 -0
- package/lib/features/persistence/services/schema-validator.service.d.ts +34 -0
- package/lib/features/routing/components/routed-report-designer.component.d.ts +18 -0
- package/lib/features/routing/components/routed-report-runtime.component.d.ts +18 -0
- package/lib/features/routing/index.d.ts +6 -0
- package/lib/features/routing/models/report-route.models.d.ts +41 -0
- package/lib/features/routing/report-routes.d.ts +16 -0
- package/lib/features/routing/resolvers/report.resolver.d.ts +7 -0
- package/lib/features/routing/services/report-menu.service.d.ts +30 -0
- package/lib/features/runtime/dynamic-renderer.component.d.ts +30 -0
- package/lib/features/runtime/index.d.ts +3 -0
- package/lib/features/runtime/report-grid-bridge.component.d.ts +94 -0
- package/lib/features/runtime/report-runtime.component.d.ts +26 -0
- package/lib/primitives/components/button/rpt-button.component.d.ts +19 -0
- package/lib/primitives/components/chart-bridge/report-chart-bridge.component.d.ts +45 -0
- package/lib/primitives/components/checkbox/rpt-checkbox.component.d.ts +14 -0
- package/lib/primitives/components/date/rpt-date.component.d.ts +17 -0
- package/lib/primitives/components/dropdown/rpt-dropdown.component.d.ts +32 -0
- package/lib/primitives/components/icon/rpt-icon.component.d.ts +41 -0
- package/lib/primitives/components/index.d.ts +12 -0
- package/lib/primitives/components/input/rpt-input.component.d.ts +16 -0
- package/lib/primitives/components/kpi-card/rpt-kpi-card.component.d.ts +43 -0
- package/lib/primitives/components/number/rpt-number.component.d.ts +20 -0
- package/lib/primitives/index.d.ts +2 -0
- package/lib/primitives/register-builtins.d.ts +11 -0
- package/lib/provide-reporting.d.ts +75 -0
- package/package.json +55 -0
- package/public-api.d.ts +5 -0
|
@@ -0,0 +1,845 @@
|
|
|
1
|
+
import { ChangeDetectionStrategy, Component, computed, effect, inject, input, output, signal, } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { FormsModule } from '@angular/forms';
|
|
4
|
+
import { ReportSchemaDiscoveryAdapter, } from '../../../../data-access/contracts/schema-discovery.contract';
|
|
5
|
+
import { detectDefaultDisplayField, detectDefaultValueField, humanizeIdentifier, } from '../../../../core/utils/identifier-humanizer';
|
|
6
|
+
import { RptIconComponent } from '../../../../primitives/components/icon/rpt-icon.component';
|
|
7
|
+
import { ParameterBindingEditorComponent } from './parameter-binding-editor.component';
|
|
8
|
+
import * as i0 from "@angular/core";
|
|
9
|
+
import * as i1 from "@angular/forms";
|
|
10
|
+
export class PropertyEditorDatasourceComponent {
|
|
11
|
+
discoveryAdapter = inject(ReportSchemaDiscoveryAdapter, { optional: true });
|
|
12
|
+
comp = input.required();
|
|
13
|
+
allComponents = input([]);
|
|
14
|
+
updateDataSource = output();
|
|
15
|
+
updateProperty = output();
|
|
16
|
+
isAdvancedMode = signal(false);
|
|
17
|
+
allEntities = signal([]);
|
|
18
|
+
entityColumns = signal([]);
|
|
19
|
+
procedureParameters = signal([]);
|
|
20
|
+
currentSourceType = computed(() => {
|
|
21
|
+
const ds = this.comp().dataSource;
|
|
22
|
+
if (ds?.sourceType)
|
|
23
|
+
return ds.sourceType;
|
|
24
|
+
if (ds?.entityName)
|
|
25
|
+
return 'table';
|
|
26
|
+
return 'static';
|
|
27
|
+
});
|
|
28
|
+
selectedEntity = computed(() => this.comp().dataSource?.entityName || '');
|
|
29
|
+
selectedValueField = computed(() => this.comp().dataSource?.valueField || '');
|
|
30
|
+
selectedDisplayField = computed(() => this.comp().dataSource?.displayField || '');
|
|
31
|
+
selectedDependsOn = computed(() => this.comp().dataSource?.dependsOn?.[0] || '');
|
|
32
|
+
availableTables = computed(() => {
|
|
33
|
+
return this.allEntities()
|
|
34
|
+
.filter((e) => e.type === 'table' || e.type === 'view')
|
|
35
|
+
.map((e) => ({
|
|
36
|
+
...e,
|
|
37
|
+
displayName: e.friendlyName || humanizeIdentifier(e.name),
|
|
38
|
+
}));
|
|
39
|
+
});
|
|
40
|
+
availableProcedures = computed(() => {
|
|
41
|
+
return this.allEntities()
|
|
42
|
+
.filter((e) => e.type === 'stored_procedure')
|
|
43
|
+
.map((e) => ({
|
|
44
|
+
...e,
|
|
45
|
+
displayName: e.friendlyName || humanizeIdentifier(e.name),
|
|
46
|
+
}));
|
|
47
|
+
});
|
|
48
|
+
availableParentFields = computed(() => {
|
|
49
|
+
return this.allComponents().filter((c) => c.id !== this.comp().id);
|
|
50
|
+
});
|
|
51
|
+
staticOptions = computed(() => {
|
|
52
|
+
const opts = this.comp().properties?.['options'];
|
|
53
|
+
if (Array.isArray(opts)) {
|
|
54
|
+
return opts.map((o) => ({ key: String(o.key ?? o.value ?? ''), label: String(o.label ?? '') }));
|
|
55
|
+
}
|
|
56
|
+
return [
|
|
57
|
+
{ key: '1', label: 'Option 1' },
|
|
58
|
+
{ key: '2', label: 'Option 2' },
|
|
59
|
+
];
|
|
60
|
+
});
|
|
61
|
+
constructor() {
|
|
62
|
+
effect(() => {
|
|
63
|
+
const entity = this.selectedEntity();
|
|
64
|
+
const type = this.currentSourceType();
|
|
65
|
+
if (entity && (type === 'table' || type === 'procedure')) {
|
|
66
|
+
this.loadEntityDetails(entity, type);
|
|
67
|
+
}
|
|
68
|
+
}, { allowSignalWrites: true });
|
|
69
|
+
}
|
|
70
|
+
ngOnInit() {
|
|
71
|
+
this.loadEntities();
|
|
72
|
+
}
|
|
73
|
+
loadEntities() {
|
|
74
|
+
if (!this.discoveryAdapter)
|
|
75
|
+
return;
|
|
76
|
+
this.discoveryAdapter.getEntities().subscribe({
|
|
77
|
+
next: (entities) => {
|
|
78
|
+
this.allEntities.set(entities);
|
|
79
|
+
},
|
|
80
|
+
error: (err) => console.error('[PropertyEditorDatasource] Failed to load entities:', err),
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
loadEntityDetails(entityName, type) {
|
|
84
|
+
if (!this.discoveryAdapter)
|
|
85
|
+
return;
|
|
86
|
+
const dbType = type === 'procedure' ? 'stored_procedure' : 'table';
|
|
87
|
+
this.discoveryAdapter.getColumns(entityName, 'dbo', dbType).subscribe({
|
|
88
|
+
next: (cols) => {
|
|
89
|
+
this.entityColumns.set(cols);
|
|
90
|
+
// Auto-detect default valueField and displayField if not yet set
|
|
91
|
+
const currentVal = this.selectedValueField();
|
|
92
|
+
const currentDisp = this.selectedDisplayField();
|
|
93
|
+
const suggestedVal = detectDefaultValueField(cols);
|
|
94
|
+
const suggestedDisp = detectDefaultDisplayField(cols);
|
|
95
|
+
if (!currentVal || !currentDisp) {
|
|
96
|
+
this.updateDataSource.emit({
|
|
97
|
+
...(this.comp().dataSource ?? { displayField: '', valueField: '' }),
|
|
98
|
+
sourceType: type,
|
|
99
|
+
entityName,
|
|
100
|
+
valueField: currentVal || suggestedVal || cols[0]?.field || '',
|
|
101
|
+
displayField: currentDisp || suggestedDisp || cols[1]?.field || cols[0]?.field || '',
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
error: (err) => console.error(`[PropertyEditorDatasource] Failed to load columns for ${entityName}:`, err),
|
|
106
|
+
});
|
|
107
|
+
if (type === 'procedure') {
|
|
108
|
+
this.discoveryAdapter.getParameters(entityName, 'dbo').subscribe({
|
|
109
|
+
next: (params) => this.procedureParameters.set(params),
|
|
110
|
+
error: (err) => console.error(`[PropertyEditorDatasource] Failed to load params for ${entityName}:`, err),
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
setSourceType(type) {
|
|
115
|
+
if (type === 'static') {
|
|
116
|
+
this.updateDataSource.emit({
|
|
117
|
+
sourceType: 'static',
|
|
118
|
+
displayField: '',
|
|
119
|
+
valueField: '',
|
|
120
|
+
});
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
const firstEntity = type === 'table' ? this.availableTables()[0]?.name : this.availableProcedures()[0]?.name;
|
|
124
|
+
this.updateDataSource.emit({
|
|
125
|
+
sourceType: type,
|
|
126
|
+
entityName: firstEntity || '',
|
|
127
|
+
schema: 'dbo',
|
|
128
|
+
displayField: '',
|
|
129
|
+
valueField: '',
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
onEntitySelected(entityName) {
|
|
133
|
+
this.updateDataSource.emit({
|
|
134
|
+
...(this.comp().dataSource ?? { displayField: '', valueField: '' }),
|
|
135
|
+
sourceType: this.currentSourceType(),
|
|
136
|
+
entityName,
|
|
137
|
+
schema: 'dbo',
|
|
138
|
+
valueField: '',
|
|
139
|
+
displayField: '',
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
onValueFieldChanged(valueField) {
|
|
143
|
+
this.updateDataSource.emit({
|
|
144
|
+
...(this.comp().dataSource ?? { displayField: '', valueField: '' }),
|
|
145
|
+
valueField,
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
onDisplayFieldChanged(displayField) {
|
|
149
|
+
this.updateDataSource.emit({
|
|
150
|
+
...(this.comp().dataSource ?? { displayField: '', valueField: '' }),
|
|
151
|
+
displayField,
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
onDependsOnChanged(parentKey) {
|
|
155
|
+
this.updateDataSource.emit({
|
|
156
|
+
...(this.comp().dataSource ?? { displayField: '', valueField: '' }),
|
|
157
|
+
dependsOn: parentKey ? [parentKey] : [],
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
getParamValue(paramName) {
|
|
161
|
+
return this.comp().dataSource?.parameterMappings?.[paramName] ?? '';
|
|
162
|
+
}
|
|
163
|
+
setParamValue(paramName, value) {
|
|
164
|
+
const existing = this.comp().dataSource?.parameterMappings ?? {};
|
|
165
|
+
this.updateDataSource.emit({
|
|
166
|
+
...(this.comp().dataSource ?? { displayField: '', valueField: '' }),
|
|
167
|
+
parameterMappings: {
|
|
168
|
+
...existing,
|
|
169
|
+
[paramName]: value,
|
|
170
|
+
},
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
onParamLinkedFieldChange(evt) {
|
|
174
|
+
const currentDependsOn = [...(this.comp().dataSource?.dependsOn ?? [])];
|
|
175
|
+
if (evt.isLinked && evt.fieldKey) {
|
|
176
|
+
if (!currentDependsOn.includes(evt.fieldKey)) {
|
|
177
|
+
currentDependsOn.push(evt.fieldKey);
|
|
178
|
+
this.updateDataSource.emit({
|
|
179
|
+
...(this.comp().dataSource ?? { displayField: '', valueField: '' }),
|
|
180
|
+
dependsOn: currentDependsOn,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
addStaticOption() {
|
|
186
|
+
const current = [...this.staticOptions()];
|
|
187
|
+
const nextIdx = current.length + 1;
|
|
188
|
+
current.push({ key: String(nextIdx), label: `Option ${nextIdx}` });
|
|
189
|
+
this.updateProperty.emit({ key: 'options', value: current });
|
|
190
|
+
}
|
|
191
|
+
updateStaticOption(index, field, val) {
|
|
192
|
+
const current = [...this.staticOptions()];
|
|
193
|
+
if (current[index]) {
|
|
194
|
+
current[index] = { ...current[index], [field]: val };
|
|
195
|
+
this.updateProperty.emit({ key: 'options', value: current });
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
removeStaticOption(index) {
|
|
199
|
+
const current = this.staticOptions().filter((_, i) => i !== index);
|
|
200
|
+
this.updateProperty.emit({ key: 'options', value: current });
|
|
201
|
+
}
|
|
202
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PropertyEditorDatasourceComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
203
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: PropertyEditorDatasourceComponent, isStandalone: true, selector: "rpt-property-editor-datasource", inputs: { comp: { classPropertyName: "comp", publicName: "comp", isSignal: true, isRequired: true, transformFunction: null }, allComponents: { classPropertyName: "allComponents", publicName: "allComponents", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { updateDataSource: "updateDataSource", updateProperty: "updateProperty" }, ngImport: i0, template: `
|
|
204
|
+
<div class="property-group">
|
|
205
|
+
<!-- 1. Header with Simple / Advanced Mode Toggle -->
|
|
206
|
+
<div class="datasource-header-bar">
|
|
207
|
+
<div class="group-title">Options Data Source</div>
|
|
208
|
+
<div class="mode-toggle-pill">
|
|
209
|
+
<button
|
|
210
|
+
type="button"
|
|
211
|
+
class="pill-btn"
|
|
212
|
+
[class.active]="!isAdvancedMode()"
|
|
213
|
+
(click)="isAdvancedMode.set(false)"
|
|
214
|
+
title="Simplified view for business users with friendly names"
|
|
215
|
+
>
|
|
216
|
+
Simple
|
|
217
|
+
</button>
|
|
218
|
+
<button
|
|
219
|
+
type="button"
|
|
220
|
+
class="pill-btn"
|
|
221
|
+
[class.active]="isAdvancedMode()"
|
|
222
|
+
(click)="isAdvancedMode.set(true)"
|
|
223
|
+
title="Technical view with SQL types and expressions"
|
|
224
|
+
>
|
|
225
|
+
Advanced
|
|
226
|
+
</button>
|
|
227
|
+
</div>
|
|
228
|
+
</div>
|
|
229
|
+
|
|
230
|
+
<!-- 2. Source Type Segmented Switcher -->
|
|
231
|
+
<div class="source-type-switcher">
|
|
232
|
+
<button
|
|
233
|
+
type="button"
|
|
234
|
+
class="source-tab-btn"
|
|
235
|
+
[class.active]="currentSourceType() === 'table'"
|
|
236
|
+
(click)="setSourceType('table')"
|
|
237
|
+
>
|
|
238
|
+
<rpt-icon name="table" [size]="12" />
|
|
239
|
+
<span>{{ isAdvancedMode() ? 'Table / View' : 'Database Table' }}</span>
|
|
240
|
+
</button>
|
|
241
|
+
<button
|
|
242
|
+
type="button"
|
|
243
|
+
class="source-tab-btn"
|
|
244
|
+
[class.active]="currentSourceType() === 'procedure'"
|
|
245
|
+
(click)="setSourceType('procedure')"
|
|
246
|
+
>
|
|
247
|
+
<rpt-icon name="code" [size]="12" />
|
|
248
|
+
<span>{{ isAdvancedMode() ? 'Stored Proc' : 'Data Query' }}</span>
|
|
249
|
+
</button>
|
|
250
|
+
<button
|
|
251
|
+
type="button"
|
|
252
|
+
class="source-tab-btn"
|
|
253
|
+
[class.active]="currentSourceType() === 'static'"
|
|
254
|
+
(click)="setSourceType('static')"
|
|
255
|
+
>
|
|
256
|
+
<rpt-icon name="edit" [size]="12" />
|
|
257
|
+
<span>Static List</span>
|
|
258
|
+
</button>
|
|
259
|
+
</div>
|
|
260
|
+
|
|
261
|
+
<!-- 3A. DATABASE TABLE / VIEW CONFIGURATION -->
|
|
262
|
+
@if (currentSourceType() === 'table') {
|
|
263
|
+
<div class="field-row">
|
|
264
|
+
<div class="field-label-row">
|
|
265
|
+
<label class="field-label">
|
|
266
|
+
{{ isAdvancedMode() ? 'Database Table / View' : 'Select Data Source' }}
|
|
267
|
+
</label>
|
|
268
|
+
<button
|
|
269
|
+
type="button"
|
|
270
|
+
class="btn-refresh-entities"
|
|
271
|
+
(click)="loadEntities()"
|
|
272
|
+
title="Refresh available tables from backend"
|
|
273
|
+
>
|
|
274
|
+
<rpt-icon name="refresh" [size]="11" />
|
|
275
|
+
<span>Refresh</span>
|
|
276
|
+
</button>
|
|
277
|
+
</div>
|
|
278
|
+
<select
|
|
279
|
+
class="field-select"
|
|
280
|
+
[ngModel]="selectedEntity()"
|
|
281
|
+
(ngModelChange)="onEntitySelected($event)"
|
|
282
|
+
>
|
|
283
|
+
<option value="">-- Choose Data Table --</option>
|
|
284
|
+
@for (tbl of availableTables(); track tbl.name) {
|
|
285
|
+
<option [value]="tbl.name">
|
|
286
|
+
@if (isAdvancedMode()) {
|
|
287
|
+
{{ tbl.schema }}.{{ tbl.name }} ({{ tbl.type }})
|
|
288
|
+
} @else {
|
|
289
|
+
{{ tbl.displayName }}{{ tbl.category ? ' • ' + tbl.category : '' }}
|
|
290
|
+
}
|
|
291
|
+
</option>
|
|
292
|
+
}
|
|
293
|
+
</select>
|
|
294
|
+
</div>
|
|
295
|
+
|
|
296
|
+
@if (selectedEntity()) {
|
|
297
|
+
<!-- Display Field (Visible text) -->
|
|
298
|
+
<div class="field-row">
|
|
299
|
+
<div class="field-label-row">
|
|
300
|
+
<label class="field-label">
|
|
301
|
+
{{ isAdvancedMode() ? 'Display Field (Visible Text)' : 'Text Shown in Dropdown' }}
|
|
302
|
+
</label>
|
|
303
|
+
@if (!isAdvancedMode()) {
|
|
304
|
+
<span class="auto-badge" title="Auto-detected column for text label">Auto-detected</span>
|
|
305
|
+
}
|
|
306
|
+
</div>
|
|
307
|
+
<select
|
|
308
|
+
class="field-select"
|
|
309
|
+
[ngModel]="selectedDisplayField()"
|
|
310
|
+
(ngModelChange)="onDisplayFieldChanged($event)"
|
|
311
|
+
>
|
|
312
|
+
<option value="">-- Select Display Column --</option>
|
|
313
|
+
@for (col of entityColumns(); track col.field) {
|
|
314
|
+
<option [value]="col.field">
|
|
315
|
+
{{ col.label }} {{ isAdvancedMode() ? '(' + col.dataType + ')' : '' }}
|
|
316
|
+
</option>
|
|
317
|
+
}
|
|
318
|
+
</select>
|
|
319
|
+
</div>
|
|
320
|
+
|
|
321
|
+
<!-- Value Field (Stored key) -->
|
|
322
|
+
<div class="field-row">
|
|
323
|
+
<div class="field-label-row">
|
|
324
|
+
<label class="field-label">
|
|
325
|
+
{{ isAdvancedMode() ? 'Value Field (Stored Key)' : 'Internal Value / Key' }}
|
|
326
|
+
</label>
|
|
327
|
+
@if (!isAdvancedMode()) {
|
|
328
|
+
<span class="auto-badge" title="Auto-detected column for primary ID">Auto-detected</span>
|
|
329
|
+
}
|
|
330
|
+
</div>
|
|
331
|
+
<select
|
|
332
|
+
class="field-select"
|
|
333
|
+
[ngModel]="selectedValueField()"
|
|
334
|
+
(ngModelChange)="onValueFieldChanged($event)"
|
|
335
|
+
>
|
|
336
|
+
<option value="">-- Select Key Column --</option>
|
|
337
|
+
@for (col of entityColumns(); track col.field) {
|
|
338
|
+
<option [value]="col.field">
|
|
339
|
+
{{ col.label }} {{ isAdvancedMode() ? '(' + col.dataType + ')' : '' }}
|
|
340
|
+
</option>
|
|
341
|
+
}
|
|
342
|
+
</select>
|
|
343
|
+
</div>
|
|
344
|
+
|
|
345
|
+
<!-- Cascading Dropdown Dependency -->
|
|
346
|
+
<div class="field-row">
|
|
347
|
+
<label class="field-label">
|
|
348
|
+
{{ isAdvancedMode() ? 'Dependent On (Cascading Parent Field)' : 'Filter by Another Field' }}
|
|
349
|
+
</label>
|
|
350
|
+
<select
|
|
351
|
+
class="field-select"
|
|
352
|
+
[ngModel]="selectedDependsOn()"
|
|
353
|
+
(ngModelChange)="onDependsOnChanged($event)"
|
|
354
|
+
>
|
|
355
|
+
<option value="">-- None (Independent) --</option>
|
|
356
|
+
@for (other of availableParentFields(); track other.key || other.id) {
|
|
357
|
+
<option [value]="other.key || other.id">{{ other.label || other.key }}</option>
|
|
358
|
+
}
|
|
359
|
+
</select>
|
|
360
|
+
<span class="field-hint">
|
|
361
|
+
{{ isAdvancedMode() ? 'Automatically re-queries options when parent field changes.' : 'Only loads options when the selected field changes.' }}
|
|
362
|
+
</span>
|
|
363
|
+
</div>
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
<!-- 3B. STORED PROCEDURE CONFIGURATION -->
|
|
368
|
+
@if (currentSourceType() === 'procedure') {
|
|
369
|
+
<div class="field-row">
|
|
370
|
+
<div class="field-label-row">
|
|
371
|
+
<label class="field-label">
|
|
372
|
+
{{ isAdvancedMode() ? 'Stored Procedure' : 'Select Data Procedure' }}
|
|
373
|
+
</label>
|
|
374
|
+
<button
|
|
375
|
+
type="button"
|
|
376
|
+
class="btn-refresh-entities"
|
|
377
|
+
(click)="loadEntities()"
|
|
378
|
+
title="Refresh available procedures from backend"
|
|
379
|
+
>
|
|
380
|
+
<rpt-icon name="refresh" [size]="11" />
|
|
381
|
+
<span>Refresh</span>
|
|
382
|
+
</button>
|
|
383
|
+
</div>
|
|
384
|
+
<select
|
|
385
|
+
class="field-select"
|
|
386
|
+
[ngModel]="selectedEntity()"
|
|
387
|
+
(ngModelChange)="onEntitySelected($event)"
|
|
388
|
+
>
|
|
389
|
+
<option value="">-- Choose Data Query / SP --</option>
|
|
390
|
+
@for (sp of availableProcedures(); track sp.name) {
|
|
391
|
+
<option [value]="sp.name">
|
|
392
|
+
@if (isAdvancedMode()) {
|
|
393
|
+
{{ sp.schema }}.{{ sp.name }}
|
|
394
|
+
} @else {
|
|
395
|
+
{{ sp.displayName }}{{ sp.category ? ' • ' + sp.category : '' }}
|
|
396
|
+
}
|
|
397
|
+
</option>
|
|
398
|
+
}
|
|
399
|
+
</select>
|
|
400
|
+
</div>
|
|
401
|
+
|
|
402
|
+
@if (selectedEntity()) {
|
|
403
|
+
<!-- Visual Parameter Linkers -->
|
|
404
|
+
@if (procedureParameters().length > 0) {
|
|
405
|
+
<div class="sp-params-group">
|
|
406
|
+
<div class="params-header-row">
|
|
407
|
+
<label class="field-label">
|
|
408
|
+
{{ isAdvancedMode() ? 'Procedure Input Parameters' : 'Filter Inputs & Parameters' }}
|
|
409
|
+
</label>
|
|
410
|
+
@if (!isAdvancedMode()) {
|
|
411
|
+
<span class="params-hint">Link to canvas controls or set fixed values</span>
|
|
412
|
+
}
|
|
413
|
+
</div>
|
|
414
|
+
|
|
415
|
+
@for (param of procedureParameters(); track param.name) {
|
|
416
|
+
<rpt-parameter-binding-editor
|
|
417
|
+
[param]="param"
|
|
418
|
+
[currentValue]="getParamValue(param.name)"
|
|
419
|
+
[allComponents]="allComponents()"
|
|
420
|
+
[currentComponentId]="comp().id"
|
|
421
|
+
[isAdvancedMode]="isAdvancedMode()"
|
|
422
|
+
(valueChange)="setParamValue(param.name, $event)"
|
|
423
|
+
(linkedFieldChange)="onParamLinkedFieldChange($event)"
|
|
424
|
+
/>
|
|
425
|
+
}
|
|
426
|
+
</div>
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
<!-- Display Field (Visible text) -->
|
|
430
|
+
<div class="field-row">
|
|
431
|
+
<div class="field-label-row">
|
|
432
|
+
<label class="field-label">
|
|
433
|
+
{{ isAdvancedMode() ? 'Display Field (from SP result)' : 'Text Shown in Dropdown' }}
|
|
434
|
+
</label>
|
|
435
|
+
@if (!isAdvancedMode()) {
|
|
436
|
+
<span class="auto-badge">Auto-detected</span>
|
|
437
|
+
}
|
|
438
|
+
</div>
|
|
439
|
+
<select
|
|
440
|
+
class="field-select"
|
|
441
|
+
[ngModel]="selectedDisplayField()"
|
|
442
|
+
(ngModelChange)="onDisplayFieldChanged($event)"
|
|
443
|
+
>
|
|
444
|
+
<option value="">-- Select Display Column --</option>
|
|
445
|
+
@for (col of entityColumns(); track col.field) {
|
|
446
|
+
<option [value]="col.field">
|
|
447
|
+
{{ col.label }} {{ isAdvancedMode() ? '(' + col.dataType + ')' : '' }}
|
|
448
|
+
</option>
|
|
449
|
+
}
|
|
450
|
+
</select>
|
|
451
|
+
</div>
|
|
452
|
+
|
|
453
|
+
<!-- Value Field (Stored key) -->
|
|
454
|
+
<div class="field-row">
|
|
455
|
+
<div class="field-label-row">
|
|
456
|
+
<label class="field-label">
|
|
457
|
+
{{ isAdvancedMode() ? 'Value Field (from SP result)' : 'Internal Value / Key' }}
|
|
458
|
+
</label>
|
|
459
|
+
@if (!isAdvancedMode()) {
|
|
460
|
+
<span class="auto-badge">Auto-detected</span>
|
|
461
|
+
}
|
|
462
|
+
</div>
|
|
463
|
+
<select
|
|
464
|
+
class="field-select"
|
|
465
|
+
[ngModel]="selectedValueField()"
|
|
466
|
+
(ngModelChange)="onValueFieldChanged($event)"
|
|
467
|
+
>
|
|
468
|
+
<option value="">-- Select Key Column --</option>
|
|
469
|
+
@for (col of entityColumns(); track col.field) {
|
|
470
|
+
<option [value]="col.field">
|
|
471
|
+
{{ col.label }} {{ isAdvancedMode() ? '(' + col.dataType + ')' : '' }}
|
|
472
|
+
</option>
|
|
473
|
+
}
|
|
474
|
+
</select>
|
|
475
|
+
</div>
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
<!-- 3C. STATIC OPTIONS EDITOR -->
|
|
480
|
+
@if (currentSourceType() === 'static') {
|
|
481
|
+
<div class="static-options-wrapper">
|
|
482
|
+
<div class="static-options-header">
|
|
483
|
+
<span class="field-label">Static Options</span>
|
|
484
|
+
<button type="button" class="btn-add-option" (click)="addStaticOption()">
|
|
485
|
+
<rpt-icon name="plus" [size]="11" />
|
|
486
|
+
<span>Add Option</span>
|
|
487
|
+
</button>
|
|
488
|
+
</div>
|
|
489
|
+
|
|
490
|
+
<div class="static-options-list">
|
|
491
|
+
@for (opt of staticOptions(); track $index) {
|
|
492
|
+
<div class="static-option-row">
|
|
493
|
+
<input
|
|
494
|
+
type="text"
|
|
495
|
+
class="field-input opt-key"
|
|
496
|
+
placeholder="Key"
|
|
497
|
+
[ngModel]="opt.key"
|
|
498
|
+
(ngModelChange)="updateStaticOption($index, 'key', $event)"
|
|
499
|
+
/>
|
|
500
|
+
<input
|
|
501
|
+
type="text"
|
|
502
|
+
class="field-input opt-label"
|
|
503
|
+
placeholder="Label"
|
|
504
|
+
[ngModel]="opt.label"
|
|
505
|
+
(ngModelChange)="updateStaticOption($index, 'label', $event)"
|
|
506
|
+
/>
|
|
507
|
+
<button
|
|
508
|
+
type="button"
|
|
509
|
+
class="btn-remove-option"
|
|
510
|
+
(click)="removeStaticOption($index)"
|
|
511
|
+
title="Remove option"
|
|
512
|
+
>
|
|
513
|
+
<rpt-icon name="trash" [size]="12" />
|
|
514
|
+
</button>
|
|
515
|
+
</div>
|
|
516
|
+
}
|
|
517
|
+
</div>
|
|
518
|
+
</div>
|
|
519
|
+
}
|
|
520
|
+
</div>
|
|
521
|
+
`, isInline: true, styles: [".property-group{display:flex;flex-direction:column;gap:12px}.group-title{font-size:.7rem;font-weight:700;color:var(--rpt-color-text-muted, #64748b);text-transform:uppercase;letter-spacing:.05em;border-bottom:1px solid var(--rpt-color-border, #e2e8f0);padding-bottom:4px}.field-row{display:flex;flex-direction:column;gap:4px}.field-label-row{display:flex;align-items:center;justify-content:space-between}.field-badge-val{font-size:.65rem;font-weight:600;color:var(--rpt-color-primary, #2563eb);background:#eff6ff;border:1px solid #bfdbfe;padding:1px 6px;border-radius:9999px}.field-label{font-size:.7rem;font-weight:600;color:var(--rpt-color-text, #0f172a)}.field-input,.field-select,.field-textarea{width:100%;box-sizing:border-box;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius-sm, 4px);padding:6px 10px;font-size:var(--rpt-font-size-sm, .75rem);color:var(--rpt-color-text, #0f172a);background:#fff;outline:none;transition:all var(--rpt-transition-speed, .15s) ease}.field-select{appearance:none;-webkit-appearance:none;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E\");background-repeat:no-repeat;background-position:right 10px center;background-size:13px 13px;padding-right:28px;cursor:pointer}.field-input:focus,.field-select:focus,.field-textarea:focus{border-color:var(--rpt-color-primary, #2563eb);box-shadow:var(--rpt-box-shadow-focus, 0 0 0 3px rgba(37, 99, 235, .25))}.checkbox-toggle{display:inline-flex;align-items:center;gap:8px;font-size:.75rem;font-weight:500;color:var(--rpt-color-text, #0f172a);cursor:pointer}.preset-pill-group{display:flex;flex-wrap:wrap;gap:4px;margin-top:4px}.preset-pill{background:#f1f5f9;border:1px solid #e2e8f0;border-radius:4px;padding:2px 8px;font-size:.65rem;font-weight:600;color:#475569;cursor:pointer;transition:all .12s ease}.preset-pill:hover{background:#e2e8f0;color:#0f172a;border-color:#cbd5e1}.preset-pill-active{background:var(--rpt-color-primary, #2563eb)!important;color:#fff!important;border-color:var(--rpt-color-primary, #2563eb)!important}.preset-pill-reset{color:var(--rpt-color-primary, #2563eb);background:#eff6ff;border-color:#bfdbfe}.preset-pill-reset:hover{background:#dbeafe;color:#1d4ed8;border-color:#93c5fd}\n", ".datasource-header-bar{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}.mode-toggle-pill{display:inline-flex;background:#e2e8f0;border-radius:12px;padding:2px;gap:2px}.pill-btn{border:none;background:transparent;padding:2px 8px;font-size:.65rem;font-weight:500;color:#64748b;border-radius:10px;cursor:pointer;transition:all .12s ease}.pill-btn:hover{color:#0f172a}.pill-btn.active{background:#fff;color:var(--rpt-color-primary, #2563eb);font-weight:700;box-shadow:0 1px 2px #00000014}.source-type-switcher{display:flex;background:#f1f5f9;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:6px;padding:2px;gap:2px;margin-bottom:6px}.source-tab-btn{flex:1;display:inline-flex;align-items:center;justify-content:center;gap:5px;padding:6px 4px;font-size:.7rem;font-weight:600;color:var(--rpt-color-text-muted, #64748b);background:transparent;border:none;border-radius:4px;cursor:pointer;transition:all .12s ease}.source-tab-btn:hover{color:var(--rpt-color-text, #0f172a)}.source-tab-btn.active{background:#fff;color:var(--rpt-color-primary, #2563eb);box-shadow:0 1px 2px #0000000d}.btn-refresh-entities{display:inline-flex;align-items:center;gap:4px;border:none;background:transparent;color:var(--rpt-color-primary, #2563eb);font-size:.65rem;font-weight:600;cursor:pointer;padding:0}.btn-refresh-entities:hover{text-decoration:underline}.auto-badge{font-size:.62rem;font-weight:600;background:#dcfce7;color:#166534;padding:1px 5px;border-radius:4px}.field-hint{font-size:.65rem;color:var(--rpt-color-text-muted, #94a3b8);margin-top:2px}.sp-params-group{display:flex;flex-direction:column;gap:6px;background:#f8fafc;padding:8px;border-radius:6px;border:1px solid #e2e8f0;margin-bottom:6px}.params-header-row{display:flex;align-items:center;justify-content:space-between}.params-hint{font-size:.64rem;color:#64748b;font-style:italic}.static-options-wrapper{display:flex;flex-direction:column;gap:8px}.static-options-header{display:flex;align-items:center;justify-content:space-between}.btn-add-option{display:inline-flex;align-items:center;gap:4px;border:1px solid var(--rpt-color-border, #cbd5e1);background:#fff;border-radius:4px;padding:3px 8px;font-size:.65rem;font-weight:600;color:var(--rpt-color-primary, #2563eb);cursor:pointer;transition:all .12s ease}.btn-add-option:hover{background:#eff6ff}.static-options-list{display:flex;flex-direction:column;gap:6px}.static-option-row{display:flex;align-items:center;gap:6px}.opt-key{flex:1}.opt-label{flex:1.5}.btn-remove-option{width:24px;height:24px;border:none;background:transparent;color:#94a3b8;border-radius:4px;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;padding:0;transition:all .12s ease}.btn-remove-option:hover{background:#fee2e2;color:#ef4444}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.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: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: RptIconComponent, selector: "rpt-icon", inputs: ["name", "size", "color", "strokeWidth"] }, { kind: "component", type: ParameterBindingEditorComponent, selector: "rpt-parameter-binding-editor", inputs: ["param", "currentValue", "allComponents", "currentComponentId", "isAdvancedMode"], outputs: ["valueChange", "linkedFieldChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
522
|
+
}
|
|
523
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PropertyEditorDatasourceComponent, decorators: [{
|
|
524
|
+
type: Component,
|
|
525
|
+
args: [{ selector: 'rpt-property-editor-datasource', standalone: true, imports: [CommonModule, FormsModule, RptIconComponent, ParameterBindingEditorComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
526
|
+
<div class="property-group">
|
|
527
|
+
<!-- 1. Header with Simple / Advanced Mode Toggle -->
|
|
528
|
+
<div class="datasource-header-bar">
|
|
529
|
+
<div class="group-title">Options Data Source</div>
|
|
530
|
+
<div class="mode-toggle-pill">
|
|
531
|
+
<button
|
|
532
|
+
type="button"
|
|
533
|
+
class="pill-btn"
|
|
534
|
+
[class.active]="!isAdvancedMode()"
|
|
535
|
+
(click)="isAdvancedMode.set(false)"
|
|
536
|
+
title="Simplified view for business users with friendly names"
|
|
537
|
+
>
|
|
538
|
+
Simple
|
|
539
|
+
</button>
|
|
540
|
+
<button
|
|
541
|
+
type="button"
|
|
542
|
+
class="pill-btn"
|
|
543
|
+
[class.active]="isAdvancedMode()"
|
|
544
|
+
(click)="isAdvancedMode.set(true)"
|
|
545
|
+
title="Technical view with SQL types and expressions"
|
|
546
|
+
>
|
|
547
|
+
Advanced
|
|
548
|
+
</button>
|
|
549
|
+
</div>
|
|
550
|
+
</div>
|
|
551
|
+
|
|
552
|
+
<!-- 2. Source Type Segmented Switcher -->
|
|
553
|
+
<div class="source-type-switcher">
|
|
554
|
+
<button
|
|
555
|
+
type="button"
|
|
556
|
+
class="source-tab-btn"
|
|
557
|
+
[class.active]="currentSourceType() === 'table'"
|
|
558
|
+
(click)="setSourceType('table')"
|
|
559
|
+
>
|
|
560
|
+
<rpt-icon name="table" [size]="12" />
|
|
561
|
+
<span>{{ isAdvancedMode() ? 'Table / View' : 'Database Table' }}</span>
|
|
562
|
+
</button>
|
|
563
|
+
<button
|
|
564
|
+
type="button"
|
|
565
|
+
class="source-tab-btn"
|
|
566
|
+
[class.active]="currentSourceType() === 'procedure'"
|
|
567
|
+
(click)="setSourceType('procedure')"
|
|
568
|
+
>
|
|
569
|
+
<rpt-icon name="code" [size]="12" />
|
|
570
|
+
<span>{{ isAdvancedMode() ? 'Stored Proc' : 'Data Query' }}</span>
|
|
571
|
+
</button>
|
|
572
|
+
<button
|
|
573
|
+
type="button"
|
|
574
|
+
class="source-tab-btn"
|
|
575
|
+
[class.active]="currentSourceType() === 'static'"
|
|
576
|
+
(click)="setSourceType('static')"
|
|
577
|
+
>
|
|
578
|
+
<rpt-icon name="edit" [size]="12" />
|
|
579
|
+
<span>Static List</span>
|
|
580
|
+
</button>
|
|
581
|
+
</div>
|
|
582
|
+
|
|
583
|
+
<!-- 3A. DATABASE TABLE / VIEW CONFIGURATION -->
|
|
584
|
+
@if (currentSourceType() === 'table') {
|
|
585
|
+
<div class="field-row">
|
|
586
|
+
<div class="field-label-row">
|
|
587
|
+
<label class="field-label">
|
|
588
|
+
{{ isAdvancedMode() ? 'Database Table / View' : 'Select Data Source' }}
|
|
589
|
+
</label>
|
|
590
|
+
<button
|
|
591
|
+
type="button"
|
|
592
|
+
class="btn-refresh-entities"
|
|
593
|
+
(click)="loadEntities()"
|
|
594
|
+
title="Refresh available tables from backend"
|
|
595
|
+
>
|
|
596
|
+
<rpt-icon name="refresh" [size]="11" />
|
|
597
|
+
<span>Refresh</span>
|
|
598
|
+
</button>
|
|
599
|
+
</div>
|
|
600
|
+
<select
|
|
601
|
+
class="field-select"
|
|
602
|
+
[ngModel]="selectedEntity()"
|
|
603
|
+
(ngModelChange)="onEntitySelected($event)"
|
|
604
|
+
>
|
|
605
|
+
<option value="">-- Choose Data Table --</option>
|
|
606
|
+
@for (tbl of availableTables(); track tbl.name) {
|
|
607
|
+
<option [value]="tbl.name">
|
|
608
|
+
@if (isAdvancedMode()) {
|
|
609
|
+
{{ tbl.schema }}.{{ tbl.name }} ({{ tbl.type }})
|
|
610
|
+
} @else {
|
|
611
|
+
{{ tbl.displayName }}{{ tbl.category ? ' • ' + tbl.category : '' }}
|
|
612
|
+
}
|
|
613
|
+
</option>
|
|
614
|
+
}
|
|
615
|
+
</select>
|
|
616
|
+
</div>
|
|
617
|
+
|
|
618
|
+
@if (selectedEntity()) {
|
|
619
|
+
<!-- Display Field (Visible text) -->
|
|
620
|
+
<div class="field-row">
|
|
621
|
+
<div class="field-label-row">
|
|
622
|
+
<label class="field-label">
|
|
623
|
+
{{ isAdvancedMode() ? 'Display Field (Visible Text)' : 'Text Shown in Dropdown' }}
|
|
624
|
+
</label>
|
|
625
|
+
@if (!isAdvancedMode()) {
|
|
626
|
+
<span class="auto-badge" title="Auto-detected column for text label">Auto-detected</span>
|
|
627
|
+
}
|
|
628
|
+
</div>
|
|
629
|
+
<select
|
|
630
|
+
class="field-select"
|
|
631
|
+
[ngModel]="selectedDisplayField()"
|
|
632
|
+
(ngModelChange)="onDisplayFieldChanged($event)"
|
|
633
|
+
>
|
|
634
|
+
<option value="">-- Select Display Column --</option>
|
|
635
|
+
@for (col of entityColumns(); track col.field) {
|
|
636
|
+
<option [value]="col.field">
|
|
637
|
+
{{ col.label }} {{ isAdvancedMode() ? '(' + col.dataType + ')' : '' }}
|
|
638
|
+
</option>
|
|
639
|
+
}
|
|
640
|
+
</select>
|
|
641
|
+
</div>
|
|
642
|
+
|
|
643
|
+
<!-- Value Field (Stored key) -->
|
|
644
|
+
<div class="field-row">
|
|
645
|
+
<div class="field-label-row">
|
|
646
|
+
<label class="field-label">
|
|
647
|
+
{{ isAdvancedMode() ? 'Value Field (Stored Key)' : 'Internal Value / Key' }}
|
|
648
|
+
</label>
|
|
649
|
+
@if (!isAdvancedMode()) {
|
|
650
|
+
<span class="auto-badge" title="Auto-detected column for primary ID">Auto-detected</span>
|
|
651
|
+
}
|
|
652
|
+
</div>
|
|
653
|
+
<select
|
|
654
|
+
class="field-select"
|
|
655
|
+
[ngModel]="selectedValueField()"
|
|
656
|
+
(ngModelChange)="onValueFieldChanged($event)"
|
|
657
|
+
>
|
|
658
|
+
<option value="">-- Select Key Column --</option>
|
|
659
|
+
@for (col of entityColumns(); track col.field) {
|
|
660
|
+
<option [value]="col.field">
|
|
661
|
+
{{ col.label }} {{ isAdvancedMode() ? '(' + col.dataType + ')' : '' }}
|
|
662
|
+
</option>
|
|
663
|
+
}
|
|
664
|
+
</select>
|
|
665
|
+
</div>
|
|
666
|
+
|
|
667
|
+
<!-- Cascading Dropdown Dependency -->
|
|
668
|
+
<div class="field-row">
|
|
669
|
+
<label class="field-label">
|
|
670
|
+
{{ isAdvancedMode() ? 'Dependent On (Cascading Parent Field)' : 'Filter by Another Field' }}
|
|
671
|
+
</label>
|
|
672
|
+
<select
|
|
673
|
+
class="field-select"
|
|
674
|
+
[ngModel]="selectedDependsOn()"
|
|
675
|
+
(ngModelChange)="onDependsOnChanged($event)"
|
|
676
|
+
>
|
|
677
|
+
<option value="">-- None (Independent) --</option>
|
|
678
|
+
@for (other of availableParentFields(); track other.key || other.id) {
|
|
679
|
+
<option [value]="other.key || other.id">{{ other.label || other.key }}</option>
|
|
680
|
+
}
|
|
681
|
+
</select>
|
|
682
|
+
<span class="field-hint">
|
|
683
|
+
{{ isAdvancedMode() ? 'Automatically re-queries options when parent field changes.' : 'Only loads options when the selected field changes.' }}
|
|
684
|
+
</span>
|
|
685
|
+
</div>
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
<!-- 3B. STORED PROCEDURE CONFIGURATION -->
|
|
690
|
+
@if (currentSourceType() === 'procedure') {
|
|
691
|
+
<div class="field-row">
|
|
692
|
+
<div class="field-label-row">
|
|
693
|
+
<label class="field-label">
|
|
694
|
+
{{ isAdvancedMode() ? 'Stored Procedure' : 'Select Data Procedure' }}
|
|
695
|
+
</label>
|
|
696
|
+
<button
|
|
697
|
+
type="button"
|
|
698
|
+
class="btn-refresh-entities"
|
|
699
|
+
(click)="loadEntities()"
|
|
700
|
+
title="Refresh available procedures from backend"
|
|
701
|
+
>
|
|
702
|
+
<rpt-icon name="refresh" [size]="11" />
|
|
703
|
+
<span>Refresh</span>
|
|
704
|
+
</button>
|
|
705
|
+
</div>
|
|
706
|
+
<select
|
|
707
|
+
class="field-select"
|
|
708
|
+
[ngModel]="selectedEntity()"
|
|
709
|
+
(ngModelChange)="onEntitySelected($event)"
|
|
710
|
+
>
|
|
711
|
+
<option value="">-- Choose Data Query / SP --</option>
|
|
712
|
+
@for (sp of availableProcedures(); track sp.name) {
|
|
713
|
+
<option [value]="sp.name">
|
|
714
|
+
@if (isAdvancedMode()) {
|
|
715
|
+
{{ sp.schema }}.{{ sp.name }}
|
|
716
|
+
} @else {
|
|
717
|
+
{{ sp.displayName }}{{ sp.category ? ' • ' + sp.category : '' }}
|
|
718
|
+
}
|
|
719
|
+
</option>
|
|
720
|
+
}
|
|
721
|
+
</select>
|
|
722
|
+
</div>
|
|
723
|
+
|
|
724
|
+
@if (selectedEntity()) {
|
|
725
|
+
<!-- Visual Parameter Linkers -->
|
|
726
|
+
@if (procedureParameters().length > 0) {
|
|
727
|
+
<div class="sp-params-group">
|
|
728
|
+
<div class="params-header-row">
|
|
729
|
+
<label class="field-label">
|
|
730
|
+
{{ isAdvancedMode() ? 'Procedure Input Parameters' : 'Filter Inputs & Parameters' }}
|
|
731
|
+
</label>
|
|
732
|
+
@if (!isAdvancedMode()) {
|
|
733
|
+
<span class="params-hint">Link to canvas controls or set fixed values</span>
|
|
734
|
+
}
|
|
735
|
+
</div>
|
|
736
|
+
|
|
737
|
+
@for (param of procedureParameters(); track param.name) {
|
|
738
|
+
<rpt-parameter-binding-editor
|
|
739
|
+
[param]="param"
|
|
740
|
+
[currentValue]="getParamValue(param.name)"
|
|
741
|
+
[allComponents]="allComponents()"
|
|
742
|
+
[currentComponentId]="comp().id"
|
|
743
|
+
[isAdvancedMode]="isAdvancedMode()"
|
|
744
|
+
(valueChange)="setParamValue(param.name, $event)"
|
|
745
|
+
(linkedFieldChange)="onParamLinkedFieldChange($event)"
|
|
746
|
+
/>
|
|
747
|
+
}
|
|
748
|
+
</div>
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
<!-- Display Field (Visible text) -->
|
|
752
|
+
<div class="field-row">
|
|
753
|
+
<div class="field-label-row">
|
|
754
|
+
<label class="field-label">
|
|
755
|
+
{{ isAdvancedMode() ? 'Display Field (from SP result)' : 'Text Shown in Dropdown' }}
|
|
756
|
+
</label>
|
|
757
|
+
@if (!isAdvancedMode()) {
|
|
758
|
+
<span class="auto-badge">Auto-detected</span>
|
|
759
|
+
}
|
|
760
|
+
</div>
|
|
761
|
+
<select
|
|
762
|
+
class="field-select"
|
|
763
|
+
[ngModel]="selectedDisplayField()"
|
|
764
|
+
(ngModelChange)="onDisplayFieldChanged($event)"
|
|
765
|
+
>
|
|
766
|
+
<option value="">-- Select Display Column --</option>
|
|
767
|
+
@for (col of entityColumns(); track col.field) {
|
|
768
|
+
<option [value]="col.field">
|
|
769
|
+
{{ col.label }} {{ isAdvancedMode() ? '(' + col.dataType + ')' : '' }}
|
|
770
|
+
</option>
|
|
771
|
+
}
|
|
772
|
+
</select>
|
|
773
|
+
</div>
|
|
774
|
+
|
|
775
|
+
<!-- Value Field (Stored key) -->
|
|
776
|
+
<div class="field-row">
|
|
777
|
+
<div class="field-label-row">
|
|
778
|
+
<label class="field-label">
|
|
779
|
+
{{ isAdvancedMode() ? 'Value Field (from SP result)' : 'Internal Value / Key' }}
|
|
780
|
+
</label>
|
|
781
|
+
@if (!isAdvancedMode()) {
|
|
782
|
+
<span class="auto-badge">Auto-detected</span>
|
|
783
|
+
}
|
|
784
|
+
</div>
|
|
785
|
+
<select
|
|
786
|
+
class="field-select"
|
|
787
|
+
[ngModel]="selectedValueField()"
|
|
788
|
+
(ngModelChange)="onValueFieldChanged($event)"
|
|
789
|
+
>
|
|
790
|
+
<option value="">-- Select Key Column --</option>
|
|
791
|
+
@for (col of entityColumns(); track col.field) {
|
|
792
|
+
<option [value]="col.field">
|
|
793
|
+
{{ col.label }} {{ isAdvancedMode() ? '(' + col.dataType + ')' : '' }}
|
|
794
|
+
</option>
|
|
795
|
+
}
|
|
796
|
+
</select>
|
|
797
|
+
</div>
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
<!-- 3C. STATIC OPTIONS EDITOR -->
|
|
802
|
+
@if (currentSourceType() === 'static') {
|
|
803
|
+
<div class="static-options-wrapper">
|
|
804
|
+
<div class="static-options-header">
|
|
805
|
+
<span class="field-label">Static Options</span>
|
|
806
|
+
<button type="button" class="btn-add-option" (click)="addStaticOption()">
|
|
807
|
+
<rpt-icon name="plus" [size]="11" />
|
|
808
|
+
<span>Add Option</span>
|
|
809
|
+
</button>
|
|
810
|
+
</div>
|
|
811
|
+
|
|
812
|
+
<div class="static-options-list">
|
|
813
|
+
@for (opt of staticOptions(); track $index) {
|
|
814
|
+
<div class="static-option-row">
|
|
815
|
+
<input
|
|
816
|
+
type="text"
|
|
817
|
+
class="field-input opt-key"
|
|
818
|
+
placeholder="Key"
|
|
819
|
+
[ngModel]="opt.key"
|
|
820
|
+
(ngModelChange)="updateStaticOption($index, 'key', $event)"
|
|
821
|
+
/>
|
|
822
|
+
<input
|
|
823
|
+
type="text"
|
|
824
|
+
class="field-input opt-label"
|
|
825
|
+
placeholder="Label"
|
|
826
|
+
[ngModel]="opt.label"
|
|
827
|
+
(ngModelChange)="updateStaticOption($index, 'label', $event)"
|
|
828
|
+
/>
|
|
829
|
+
<button
|
|
830
|
+
type="button"
|
|
831
|
+
class="btn-remove-option"
|
|
832
|
+
(click)="removeStaticOption($index)"
|
|
833
|
+
title="Remove option"
|
|
834
|
+
>
|
|
835
|
+
<rpt-icon name="trash" [size]="12" />
|
|
836
|
+
</button>
|
|
837
|
+
</div>
|
|
838
|
+
}
|
|
839
|
+
</div>
|
|
840
|
+
</div>
|
|
841
|
+
}
|
|
842
|
+
</div>
|
|
843
|
+
`, styles: [".property-group{display:flex;flex-direction:column;gap:12px}.group-title{font-size:.7rem;font-weight:700;color:var(--rpt-color-text-muted, #64748b);text-transform:uppercase;letter-spacing:.05em;border-bottom:1px solid var(--rpt-color-border, #e2e8f0);padding-bottom:4px}.field-row{display:flex;flex-direction:column;gap:4px}.field-label-row{display:flex;align-items:center;justify-content:space-between}.field-badge-val{font-size:.65rem;font-weight:600;color:var(--rpt-color-primary, #2563eb);background:#eff6ff;border:1px solid #bfdbfe;padding:1px 6px;border-radius:9999px}.field-label{font-size:.7rem;font-weight:600;color:var(--rpt-color-text, #0f172a)}.field-input,.field-select,.field-textarea{width:100%;box-sizing:border-box;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius-sm, 4px);padding:6px 10px;font-size:var(--rpt-font-size-sm, .75rem);color:var(--rpt-color-text, #0f172a);background:#fff;outline:none;transition:all var(--rpt-transition-speed, .15s) ease}.field-select{appearance:none;-webkit-appearance:none;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E\");background-repeat:no-repeat;background-position:right 10px center;background-size:13px 13px;padding-right:28px;cursor:pointer}.field-input:focus,.field-select:focus,.field-textarea:focus{border-color:var(--rpt-color-primary, #2563eb);box-shadow:var(--rpt-box-shadow-focus, 0 0 0 3px rgba(37, 99, 235, .25))}.checkbox-toggle{display:inline-flex;align-items:center;gap:8px;font-size:.75rem;font-weight:500;color:var(--rpt-color-text, #0f172a);cursor:pointer}.preset-pill-group{display:flex;flex-wrap:wrap;gap:4px;margin-top:4px}.preset-pill{background:#f1f5f9;border:1px solid #e2e8f0;border-radius:4px;padding:2px 8px;font-size:.65rem;font-weight:600;color:#475569;cursor:pointer;transition:all .12s ease}.preset-pill:hover{background:#e2e8f0;color:#0f172a;border-color:#cbd5e1}.preset-pill-active{background:var(--rpt-color-primary, #2563eb)!important;color:#fff!important;border-color:var(--rpt-color-primary, #2563eb)!important}.preset-pill-reset{color:var(--rpt-color-primary, #2563eb);background:#eff6ff;border-color:#bfdbfe}.preset-pill-reset:hover{background:#dbeafe;color:#1d4ed8;border-color:#93c5fd}\n", ".datasource-header-bar{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}.mode-toggle-pill{display:inline-flex;background:#e2e8f0;border-radius:12px;padding:2px;gap:2px}.pill-btn{border:none;background:transparent;padding:2px 8px;font-size:.65rem;font-weight:500;color:#64748b;border-radius:10px;cursor:pointer;transition:all .12s ease}.pill-btn:hover{color:#0f172a}.pill-btn.active{background:#fff;color:var(--rpt-color-primary, #2563eb);font-weight:700;box-shadow:0 1px 2px #00000014}.source-type-switcher{display:flex;background:#f1f5f9;border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:6px;padding:2px;gap:2px;margin-bottom:6px}.source-tab-btn{flex:1;display:inline-flex;align-items:center;justify-content:center;gap:5px;padding:6px 4px;font-size:.7rem;font-weight:600;color:var(--rpt-color-text-muted, #64748b);background:transparent;border:none;border-radius:4px;cursor:pointer;transition:all .12s ease}.source-tab-btn:hover{color:var(--rpt-color-text, #0f172a)}.source-tab-btn.active{background:#fff;color:var(--rpt-color-primary, #2563eb);box-shadow:0 1px 2px #0000000d}.btn-refresh-entities{display:inline-flex;align-items:center;gap:4px;border:none;background:transparent;color:var(--rpt-color-primary, #2563eb);font-size:.65rem;font-weight:600;cursor:pointer;padding:0}.btn-refresh-entities:hover{text-decoration:underline}.auto-badge{font-size:.62rem;font-weight:600;background:#dcfce7;color:#166534;padding:1px 5px;border-radius:4px}.field-hint{font-size:.65rem;color:var(--rpt-color-text-muted, #94a3b8);margin-top:2px}.sp-params-group{display:flex;flex-direction:column;gap:6px;background:#f8fafc;padding:8px;border-radius:6px;border:1px solid #e2e8f0;margin-bottom:6px}.params-header-row{display:flex;align-items:center;justify-content:space-between}.params-hint{font-size:.64rem;color:#64748b;font-style:italic}.static-options-wrapper{display:flex;flex-direction:column;gap:8px}.static-options-header{display:flex;align-items:center;justify-content:space-between}.btn-add-option{display:inline-flex;align-items:center;gap:4px;border:1px solid var(--rpt-color-border, #cbd5e1);background:#fff;border-radius:4px;padding:3px 8px;font-size:.65rem;font-weight:600;color:var(--rpt-color-primary, #2563eb);cursor:pointer;transition:all .12s ease}.btn-add-option:hover{background:#eff6ff}.static-options-list{display:flex;flex-direction:column;gap:6px}.static-option-row{display:flex;align-items:center;gap:6px}.opt-key{flex:1}.opt-label{flex:1.5}.btn-remove-option{width:24px;height:24px;border:none;background:transparent;color:#94a3b8;border-radius:4px;display:inline-flex;align-items:center;justify-content:center;cursor:pointer;flex-shrink:0;padding:0;transition:all .12s ease}.btn-remove-option:hover{background:#fee2e2;color:#ef4444}\n"] }]
|
|
844
|
+
}], ctorParameters: () => [] });
|
|
845
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvcGVydHktZWRpdG9yLWRhdGFzb3VyY2UuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYndheXMtcmVwb3J0L3NyYy9saWIvZmVhdHVyZXMvZGVzaWduZXIvY29tcG9uZW50cy9wcm9wZXJ0eS1lZGl0b3IvcHJvcGVydHktZWRpdG9yLWRhdGFzb3VyY2UuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsU0FBUyxFQUNULFFBQVEsRUFDUixNQUFNLEVBQ04sTUFBTSxFQUNOLEtBQUssRUFFTCxNQUFNLEVBQ04sTUFBTSxHQUNQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFNN0MsT0FBTyxFQUlMLDRCQUE0QixHQUM3QixNQUFNLDZEQUE2RCxDQUFDO0FBQ3JFLE9BQU8sRUFDTCx5QkFBeUIsRUFDekIsdUJBQXVCLEVBQ3ZCLGtCQUFrQixHQUNuQixNQUFNLDZDQUE2QyxDQUFDO0FBQ3JELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDJEQUEyRCxDQUFDO0FBQzdGLE9BQU8sRUFBRSwrQkFBK0IsRUFBRSxNQUFNLHNDQUFzQyxDQUFDOzs7QUErZnZGLE1BQU0sT0FBTyxpQ0FBaUM7SUFDM0IsZ0JBQWdCLEdBQUcsTUFBTSxDQUFDLDRCQUE0QixFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFFcEYsSUFBSSxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQTZCLENBQUM7SUFDbkQsYUFBYSxHQUFHLEtBQUssQ0FBOEIsRUFBRSxDQUFDLENBQUM7SUFFdkQsZ0JBQWdCLEdBQUcsTUFBTSxFQUFpQyxDQUFDO0lBQzNELGNBQWMsR0FBRyxNQUFN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Z0NBQUUsZ0JBQWdCLHVHQUFFLCtCQUErQjs7NEZBcWYzRSxpQ0FBaUM7a0JBeGY3QyxTQUFTOytCQUNFLGdDQUFnQyxjQUM5QixJQUFJLFdBQ1AsQ0FBQyxZQUFZLEVBQUUsV0FBVyxFQUFFLGdCQUFnQixFQUFFLCtCQUErQixDQUFDLG1CQUN0RSx1QkFBdUIsQ0FBQyxNQUFNLFlBRXJDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E4VFQiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ29tcG9uZW50LFxuICBjb21wdXRlZCxcbiAgZWZmZWN0LFxuICBpbmplY3QsXG4gIGlucHV0LFxuICBPbkluaXQsXG4gIG91dHB1dCxcbiAgc2lnbmFsLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7XG4gIENvbXBvbmVudERhdGFTb3VyY2VEZWZpbml0aW9uLFxuICBEcm9wZG93blNvdXJjZVR5cGUsXG4gIFJlcG9ydENvbXBvbmVudERlZmluaXRpb24sXG59IGZyb20gJy4uLy4uLy4uLy4uL2NvcmUvbW9kZWxzL3JlcG9ydC1jb21wb25lbnQubW9kZWwnO1xuaW1wb3J0IHtcbiAgRGF0YWJhc2VFbnRpdHlNZXRhZGF0YSxcbiAgRW50aXR5Q29sdW1uTWV0YWRhdGEsXG4gIFByb2NlZHVyZVBhcmFtZXRlck1ldGFkYXRhLFxuICBSZXBvcnRTY2hlbWFEaXNjb3ZlcnlBZGFwdGVyLFxufSBmcm9tICcuLi8uLi8uLi8uLi9kYXRhLWFjY2Vzcy9jb250cmFjdHMvc2NoZW1hLWRpc2NvdmVyeS5jb250cmFjdCc7XG5pbXBvcnQge1xuICBkZXRlY3REZWZhdWx0RGlzcGxheUZpZWxkLFxuICBkZXRlY3REZWZhdWx0VmFsdWVGaWVsZCxcbiAgaHVtYW5pemVJZGVudGlmaWVyLFxufSBmcm9tICcuLi8uLi8uLi8uLi9jb3JlL3V0aWxzL2lkZW50aWZpZXItaHVtYW5pemVyJztcbmltcG9ydCB7IFJwdEljb25Db21wb25lbnQgfSBmcm9tICcuLi8uLi8uLi8uLi9wcmltaXRpdmVzL2NvbXBvbmVudHMvaWNvbi9ycHQtaWNvbi5jb21wb25lbnQnO1xuaW1wb3J0IHsgUGFyYW1ldGVyQmluZGluZ0VkaXRvckNvbXBvbmVudCB9IGZyb20gJy4vcGFyYW1ldGVyLWJpbmRpbmctZWRpdG9yLmNvbXBvbmVudCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3RhdGljT3B0aW9uSXRlbSB7XG4gIGtleTogc3RyaW5nO1xuICBsYWJlbDogc3RyaW5nO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdycHQtcHJvcGVydHktZWRpdG9yLWRhdGFzb3VyY2UnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBGb3Jtc01vZHVsZSwgUnB0SWNvbkNvbXBvbmVudCwgUGFyYW1ldGVyQmluZGluZ0VkaXRvckNvbXBvbmVudF0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBzdHlsZVVybHM6IFsnLi9wcm9wZXJ0eS1lZGl0b3IuY29tbW9uLmNzcyddLFxuICB0ZW1wbGF0ZTogYFxuICAgIDxkaXYgY2xhc3M9XCJwcm9wZXJ0eS1ncm91cFwiPlxuICAgICAgPCEtLSAxLiBIZWFkZXIgd2l0aCBTaW1wbGUgLyBBZHZhbmNlZCBNb2RlIFRvZ2dsZSAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJkYXRhc291cmNlLWhlYWRlci1iYXJcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cImdyb3VwLXRpdGxlXCI+T3B0aW9ucyBEYXRhIFNvdXJjZTwvZGl2PlxuICAgICAgICA8ZGl2IGNsYXNzPVwibW9kZS10b2dnbGUtcGlsbFwiPlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgY2xhc3M9XCJwaWxsLWJ0blwiXG4gICAgICAgICAgICBbY2xhc3MuYWN0aXZlXT1cIiFpc0FkdmFuY2VkTW9kZSgpXCJcbiAgICAgICAgICAgIChjbGljayk9XCJpc0FkdmFuY2VkTW9kZS5zZXQoZmFsc2UpXCJcbiAgICAgICAgICAgIHRpdGxlPVwiU2ltcGxpZmllZCB2aWV3IGZvciBidXNpbmVzcyB1c2VycyB3aXRoIGZyaWVuZGx5IG5hbWVzXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICBTaW1wbGVcbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGNsYXNzPVwicGlsbC1idG5cIlxuICAgICAgICAgICAgW2NsYXNzLmFjdGl2ZV09XCJpc0FkdmFuY2VkTW9kZSgpXCJcbiAgICAgICAgICAgIChjbGljayk9XCJpc0FkdmFuY2VkTW9kZS5zZXQodHJ1ZSlcIlxuICAgICAgICAgICAgdGl0bGU9XCJUZWNobmljYWwgdmlldyB3aXRoIFNRTCB0eXBlcyBhbmQgZXhwcmVzc2lvbnNcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIEFkdmFuY2VkXG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gMi4gU291cmNlIFR5cGUgU2VnbWVudGVkIFN3aXRjaGVyIC0tPlxuICAgICAgPGRpdiBjbGFzcz1cInNvdXJjZS10eXBlLXN3aXRjaGVyXCI+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICBjbGFzcz1cInNvdXJjZS10YWItYnRuXCJcbiAgICAgICAgICBbY2xhc3MuYWN0aXZlXT1cImN1cnJlbnRTb3VyY2VUeXBlKCkgPT09ICd0YWJsZSdcIlxuICAgICAgICAgIChjbGljayk9XCJzZXRTb3VyY2VUeXBlKCd0YWJsZScpXCJcbiAgICAgICAgPlxuICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwidGFibGVcIiBbc2l6ZV09XCIxMlwiIC8+XG4gICAgICAgICAgPHNwYW4+e3sgaXNBZHZhbmNlZE1vZGUoKSA/ICdUYWJsZSAvIFZpZXcnIDogJ0RhdGFiYXNlIFRhYmxlJyB9fTwvc3Bhbj5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICBjbGFzcz1cInNvdXJjZS10YWItYnRuXCJcbiAgICAgICAgICBbY2xhc3MuYWN0aXZlXT1cImN1cnJlbnRTb3VyY2VUeXBlKCkgPT09ICdwcm9jZWR1cmUnXCJcbiAgICAgICAgICAoY2xpY2spPVwic2V0U291cmNlVHlwZSgncHJvY2VkdXJlJylcIlxuICAgICAgICA+XG4gICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJjb2RlXCIgW3NpemVdPVwiMTJcIiAvPlxuICAgICAgICAgIDxzcGFuPnt7IGlzQWR2YW5jZWRNb2RlKCkgPyAnU3RvcmVkIFByb2MnIDogJ0RhdGEgUXVlcnknIH19PC9zcGFuPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgIGNsYXNzPVwic291cmNlLXRhYi1idG5cIlxuICAgICAgICAgIFtjbGFzcy5hY3RpdmVdPVwiY3VycmVudFNvdXJjZVR5cGUoKSA9PT0gJ3N0YXRpYydcIlxuICAgICAgICAgIChjbGljayk9XCJzZXRTb3VyY2VUeXBlKCdzdGF0aWMnKVwiXG4gICAgICAgID5cbiAgICAgICAgICA8cnB0LWljb24gbmFtZT1cImVkaXRcIiBbc2l6ZV09XCIxMlwiIC8+XG4gICAgICAgICAgPHNwYW4+U3RhdGljIExpc3Q8L3NwYW4+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9kaXY+XG5cbiAgICAgIDwhLS0gM0EuIERBVEFCQVNFIFRBQkxFIC8gVklFVyBDT05GSUdVUkFUSU9OIC0tPlxuICAgICAgQGlmIChjdXJyZW50U291cmNlVHlwZSgpID09PSAndGFibGUnKSB7XG4gICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC1yb3dcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtbGFiZWwtcm93XCI+XG4gICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmaWVsZC1sYWJlbFwiPlxuICAgICAgICAgICAgICB7eyBpc0FkdmFuY2VkTW9kZSgpID8gJ0RhdGFiYXNlIFRhYmxlIC8gVmlldycgOiAnU2VsZWN0IERhdGEgU291cmNlJyB9fVxuICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgIGNsYXNzPVwiYnRuLXJlZnJlc2gtZW50aXRpZXNcIlxuICAgICAgICAgICAgICAoY2xpY2spPVwibG9hZEVudGl0aWVzKClcIlxuICAgICAgICAgICAgICB0aXRsZT1cIlJlZnJlc2ggYXZhaWxhYmxlIHRhYmxlcyBmcm9tIGJhY2tlbmRcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cInJlZnJlc2hcIiBbc2l6ZV09XCIxMVwiIC8+XG4gICAgICAgICAgICAgIDxzcGFuPlJlZnJlc2g8L3NwYW4+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8c2VsZWN0XG4gICAgICAgICAgICBjbGFzcz1cImZpZWxkLXNlbGVjdFwiXG4gICAgICAgICAgICBbbmdNb2RlbF09XCJzZWxlY3RlZEVudGl0eSgpXCJcbiAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIm9uRW50aXR5U2VsZWN0ZWQoJGV2ZW50KVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPi0tIENob29zZSBEYXRhIFRhYmxlIC0tPC9vcHRpb24+XG4gICAgICAgICAgICBAZm9yICh0Ymwgb2YgYXZhaWxhYmxlVGFibGVzKCk7IHRyYWNrIHRibC5uYW1lKSB7XG4gICAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cInRibC5uYW1lXCI+XG4gICAgICAgICAgICAgICAgQGlmIChpc0FkdmFuY2VkTW9kZSgpKSB7XG4gICAgICAgICAgICAgICAgICB7eyB0Ymwuc2NoZW1hIH19Lnt7IHRibC5uYW1lIH19ICh7eyB0YmwudHlwZSB9fSlcbiAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHt7IHRibC5kaXNwbGF5TmFtZSB9fXt7IHRibC5jYXRlZ29yeSA/ICcg4oCiICcgKyB0YmwuY2F0ZWdvcnkgOiAnJyB9fVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIEBpZiAoc2VsZWN0ZWRFbnRpdHkoKSkge1xuICAgICAgICAgIDwhLS0gRGlzcGxheSBGaWVsZCAoVmlzaWJsZSB0ZXh0KSAtLT5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtcm93XCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtbGFiZWwtcm93XCI+XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZpZWxkLWxhYmVsXCI+XG4gICAgICAgICAgICAgICAge3sgaXNBZHZhbmNlZE1vZGUoKSA/ICdEaXNwbGF5IEZpZWxkIChWaXNpYmxlIFRleHQpJyA6ICdUZXh0IFNob3duIGluIERyb3Bkb3duJyB9fVxuICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICBAaWYgKCFpc0FkdmFuY2VkTW9kZSgpKSB7XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJhdXRvLWJhZGdlXCIgdGl0bGU9XCJBdXRvLWRldGVjdGVkIGNvbHVtbiBmb3IgdGV4dCBsYWJlbFwiPkF1dG8tZGV0ZWN0ZWQ8L3NwYW4+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPHNlbGVjdFxuICAgICAgICAgICAgICBjbGFzcz1cImZpZWxkLXNlbGVjdFwiXG4gICAgICAgICAgICAgIFtuZ01vZGVsXT1cInNlbGVjdGVkRGlzcGxheUZpZWxkKClcIlxuICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJvbkRpc3BsYXlGaWVsZENoYW5nZWQoJGV2ZW50KVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBTZWxlY3QgRGlzcGxheSBDb2x1bW4gLS08L29wdGlvbj5cbiAgICAgICAgICAgICAgQGZvciAoY29sIG9mIGVudGl0eUNvbHVtbnMoKTsgdHJhY2sgY29sLmZpZWxkKSB7XG4gICAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwiY29sLmZpZWxkXCI+XG4gICAgICAgICAgICAgICAgICB7eyBjb2wubGFiZWwgfX0ge3sgaXNBZHZhbmNlZE1vZGUoKSA/ICcoJyArIGNvbC5kYXRhVHlwZSArICcpJyA6ICcnIH19XG4gICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPCEtLSBWYWx1ZSBGaWVsZCAoU3RvcmVkIGtleSkgLS0+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLXJvd1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLWxhYmVsLXJvd1wiPlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmaWVsZC1sYWJlbFwiPlxuICAgICAgICAgICAgICAgIHt7IGlzQWR2YW5jZWRNb2RlKCkgPyAnVmFsdWUgRmllbGQgKFN0b3JlZCBLZXkpJyA6ICdJbnRlcm5hbCBWYWx1ZSAvIEtleScgfX1cbiAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgQGlmICghaXNBZHZhbmNlZE1vZGUoKSkge1xuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYXV0by1iYWRnZVwiIHRpdGxlPVwiQXV0by1kZXRlY3RlZCBjb2x1bW4gZm9yIHByaW1hcnkgSURcIj5BdXRvLWRldGVjdGVkPC9zcGFuPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxzZWxlY3RcbiAgICAgICAgICAgICAgY2xhc3M9XCJmaWVsZC1zZWxlY3RcIlxuICAgICAgICAgICAgICBbbmdNb2RlbF09XCJzZWxlY3RlZFZhbHVlRmllbGQoKVwiXG4gICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIm9uVmFsdWVGaWVsZENoYW5nZWQoJGV2ZW50KVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBTZWxlY3QgS2V5IENvbHVtbiAtLTwvb3B0aW9uPlxuICAgICAgICAgICAgICBAZm9yIChjb2wgb2YgZW50aXR5Q29sdW1ucygpOyB0cmFjayBjb2wuZmllbGQpIHtcbiAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCJjb2wuZmllbGRcIj5cbiAgICAgICAgICAgICAgICAgIHt7IGNvbC5sYWJlbCB9fSB7eyBpc0FkdmFuY2VkTW9kZSgpID8gJygnICsgY29sLmRhdGFUeXBlICsgJyknIDogJycgfX1cbiAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8IS0tIENhc2NhZGluZyBEcm9wZG93biBEZXBlbmRlbmN5IC0tPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC1yb3dcIj5cbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZpZWxkLWxhYmVsXCI+XG4gICAgICAgICAgICAgIHt7IGlzQWR2YW5jZWRNb2RlKCkgPyAnRGVwZW5kZW50IE9uIChDYXNjYWRpbmcgUGFyZW50IEZpZWxkKScgOiAnRmlsdGVyIGJ5IEFub3RoZXIgRmllbGQnIH19XG4gICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgPHNlbGVjdFxuICAgICAgICAgICAgICBjbGFzcz1cImZpZWxkLXNlbGVjdFwiXG4gICAgICAgICAgICAgIFtuZ01vZGVsXT1cInNlbGVjdGVkRGVwZW5kc09uKClcIlxuICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJvbkRlcGVuZHNPbkNoYW5nZWQoJGV2ZW50KVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBOb25lIChJbmRlcGVuZGVudCkgLS08L29wdGlvbj5cbiAgICAgICAgICAgICAgQGZvciAob3RoZXIgb2YgYXZhaWxhYmxlUGFyZW50RmllbGRzKCk7IHRyYWNrIG90aGVyLmtleSB8fCBvdGhlci5pZCkge1xuICAgICAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cIm90aGVyLmtleSB8fCBvdGhlci5pZFwiPnt7IG90aGVyLmxhYmVsIHx8IG90aGVyLmtleSB9fTwvb3B0aW9uPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZmllbGQtaGludFwiPlxuICAgICAgICAgICAgICB7eyBpc0FkdmFuY2VkTW9kZSgpID8gJ0F1dG9tYXRpY2FsbHkgcmUtcXVlcmllcyBvcHRpb25zIHdoZW4gcGFyZW50IGZpZWxkIGNoYW5nZXMuJyA6ICdPbmx5IGxvYWRzIG9wdGlvbnMgd2hlbiB0aGUgc2VsZWN0ZWQgZmllbGQgY2hhbmdlcy4nIH19XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgPCEtLSAzQi4gU1RPUkVEIFBST0NFRFVSRSBDT05GSUdVUkFUSU9OIC0tPlxuICAgICAgQGlmIChjdXJyZW50U291cmNlVHlwZSgpID09PSAncHJvY2VkdXJlJykge1xuICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtcm93XCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLWxhYmVsLXJvd1wiPlxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmllbGQtbGFiZWxcIj5cbiAgICAgICAgICAgICAge3sgaXNBZHZhbmNlZE1vZGUoKSA/ICdTdG9yZWQgUHJvY2VkdXJlJyA6ICdTZWxlY3QgRGF0YSBQcm9jZWR1cmUnIH19XG4gICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJidG4tcmVmcmVzaC1lbnRpdGllc1wiXG4gICAgICAgICAgICAgIChjbGljayk9XCJsb2FkRW50aXRpZXMoKVwiXG4gICAgICAgICAgICAgIHRpdGxlPVwiUmVmcmVzaCBhdmFpbGFibGUgcHJvY2VkdXJlcyBmcm9tIGJhY2tlbmRcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cInJlZnJlc2hcIiBbc2l6ZV09XCIxMVwiIC8+XG4gICAgICAgICAgICAgIDxzcGFuPlJlZnJlc2g8L3NwYW4+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8c2VsZWN0XG4gICAgICAgICAgICBjbGFzcz1cImZpZWxkLXNlbGVjdFwiXG4gICAgICAgICAgICBbbmdNb2RlbF09XCJzZWxlY3RlZEVudGl0eSgpXCJcbiAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIm9uRW50aXR5U2VsZWN0ZWQoJGV2ZW50KVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPi0tIENob29zZSBEYXRhIFF1ZXJ5IC8gU1AgLS08L29wdGlvbj5cbiAgICAgICAgICAgIEBmb3IgKHNwIG9mIGF2YWlsYWJsZVByb2NlZHVyZXMoKTsgdHJhY2sgc3AubmFtZSkge1xuICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCJzcC5uYW1lXCI+XG4gICAgICAgICAgICAgICAgQGlmIChpc0FkdmFuY2VkTW9kZSgpKSB7XG4gICAgICAgICAgICAgICAgICB7eyBzcC5zY2hlbWEgfX0ue3sgc3AubmFtZSB9fVxuICAgICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgICAge3sgc3AuZGlzcGxheU5hbWUgfX17eyBzcC5jYXRlZ29yeSA/ICcg4oCiICcgKyBzcC5jYXRlZ29yeSA6ICcnIH19XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgQGlmIChzZWxlY3RlZEVudGl0eSgpKSB7XG4gICAgICAgICAgPCEtLSBWaXN1YWwgUGFyYW1ldGVyIExpbmtlcnMgLS0+XG4gICAgICAgICAgQGlmIChwcm9jZWR1cmVQYXJhbWV0ZXJzKCkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInNwLXBhcmFtcy1ncm91cFwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwicGFyYW1zLWhlYWRlci1yb3dcIj5cbiAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmaWVsZC1sYWJlbFwiPlxuICAgICAgICAgICAgICAgICAge3sgaXNBZHZhbmNlZE1vZGUoKSA/ICdQcm9jZWR1cmUgSW5wdXQgUGFyYW1ldGVycycgOiAnRmlsdGVyIElucHV0cyAmIFBhcmFtZXRlcnMnIH19XG4gICAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgICBAaWYgKCFpc0FkdmFuY2VkTW9kZSgpKSB7XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInBhcmFtcy1oaW50XCI+TGluayB0byBjYW52YXMgY29udHJvbHMgb3Igc2V0IGZpeGVkIHZhbHVlczwvc3Bhbj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgIEBmb3IgKHBhcmFtIG9mIHByb2NlZHVyZVBhcmFtZXRlcnMoKTsgdHJhY2sgcGFyYW0ubmFtZSkge1xuICAgICAgICAgICAgICAgIDxycHQtcGFyYW1ldGVyLWJpbmRpbmctZWRpdG9yXG4gICAgICAgICAgICAgICAgICBbcGFyYW1dPVwicGFyYW1cIlxuICAgICAgICAgICAgICAgICAgW2N1cnJlbnRWYWx1ZV09XCJnZXRQYXJhbVZhbHVlKHBhcmFtLm5hbWUpXCJcbiAgICAgICAgICAgICAgICAgIFthbGxDb21wb25lbnRzXT1cImFsbENvbXBvbmVudHMoKVwiXG4gICAgICAgICAgICAgICAgICBbY3VycmVudENvbXBvbmVudElkXT1cImNvbXAoKS5pZFwiXG4gICAgICAgICAgICAgICAgICBbaXNBZHZhbmNlZE1vZGVdPVwiaXNBZHZhbmNlZE1vZGUoKVwiXG4gICAgICAgICAgICAgICAgICAodmFsdWVDaGFuZ2UpPVwic2V0UGFyYW1WYWx1ZShwYXJhbS5uYW1lLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgIChsaW5rZWRGaWVsZENoYW5nZSk9XCJvblBhcmFtTGlua2VkRmllbGRDaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgPCEtLSBEaXNwbGF5IEZpZWxkIChWaXNpYmxlIHRleHQpIC0tPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC1yb3dcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC1sYWJlbC1yb3dcIj5cbiAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmllbGQtbGFiZWxcIj5cbiAgICAgICAgICAgICAgICB7eyBpc0FkdmFuY2VkTW9kZSgpID8gJ0Rpc3BsYXkgRmllbGQgKGZyb20gU1AgcmVzdWx0KScgOiAnVGV4dCBTaG93biBpbiBEcm9wZG93bicgfX1cbiAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgQGlmICghaXNBZHZhbmNlZE1vZGUoKSkge1xuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYXV0by1iYWRnZVwiPkF1dG8tZGV0ZWN0ZWQ8L3NwYW4+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPHNlbGVjdFxuICAgICAgICAgICAgICBjbGFzcz1cImZpZWxkLXNlbGVjdFwiXG4gICAgICAgICAgICAgIFtuZ01vZGVsXT1cInNlbGVjdGVkRGlzcGxheUZpZWxkKClcIlxuICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJvbkRpc3BsYXlGaWVsZENoYW5nZWQoJGV2ZW50KVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBTZWxlY3QgRGlzcGxheSBDb2x1bW4gLS08L29wdGlvbj5cbiAgICAgICAgICAgICAgQGZvciAoY29sIG9mIGVudGl0eUNvbHVtbnMoKTsgdHJhY2sgY29sLmZpZWxkKSB7XG4gICAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwiY29sLmZpZWxkXCI+XG4gICAgICAgICAgICAgICAgICB7eyBjb2wubGFiZWwgfX0ge3sgaXNBZHZhbmNlZE1vZGUoKSA/ICcoJyArIGNvbC5kYXRhVHlwZSArICcpJyA6ICcnIH19XG4gICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPCEtLSBWYWx1ZSBGaWVsZCAoU3RvcmVkIGtleSkgLS0+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLXJvd1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLWxhYmVsLXJvd1wiPlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmaWVsZC1sYWJlbFwiPlxuICAgICAgICAgICAgICAgIHt7IGlzQWR2YW5jZWRNb2RlKCkgPyAnVmFsdWUgRmllbGQgKGZyb20gU1AgcmVzdWx0KScgOiAnSW50ZXJuYWwgVmFsdWUgLyBLZXknIH19XG4gICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgIEBpZiAoIWlzQWR2YW5jZWRNb2RlKCkpIHtcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImF1dG8tYmFkZ2VcIj5BdXRvLWRldGVjdGVkPC9zcGFuPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxzZWxlY3RcbiAgICAgICAgICAgICAgY2xhc3M9XCJmaWVsZC1zZWxlY3RcIlxuICAgICAgICAgICAgICBbbmdNb2RlbF09XCJzZWxlY3RlZFZhbHVlRmllbGQoKVwiXG4gICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIm9uVmFsdWVGaWVsZENoYW5nZWQoJGV2ZW50KVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBTZWxlY3QgS2V5IENvbHVtbiAtLTwvb3B0aW9uPlxuICAgICAgICAgICAgICBAZm9yIChjb2wgb2YgZW50aXR5Q29sdW1ucygpOyB0cmFjayBjb2wuZmllbGQpIHtcbiAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCJjb2wuZmllbGRcIj5cbiAgICAgICAgICAgICAgICAgIHt7IGNvbC5sYWJlbCB9fSB7eyBpc0FkdmFuY2VkTW9kZSgpID8gJygnICsgY29sLmRhdGFUeXBlICsgJyknIDogJycgfX1cbiAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgPCEtLSAzQy4gU1RBVElDIE9QVElPTlMgRURJVE9SIC0tPlxuICAgICAgQGlmIChjdXJyZW50U291cmNlVHlwZSgpID09PSAnc3RhdGljJykge1xuICAgICAgICA8ZGl2IGNsYXNzPVwic3RhdGljLW9wdGlvbnMtd3JhcHBlclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdGF0aWMtb3B0aW9ucy1oZWFkZXJcIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZmllbGQtbGFiZWxcIj5TdGF0aWMgT3B0aW9uczwvc3Bhbj5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuLWFkZC1vcHRpb25cIiAoY2xpY2spPVwiYWRkU3RhdGljT3B0aW9uKClcIj5cbiAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJwbHVzXCIgW3NpemVdPVwiMTFcIiAvPlxuICAgICAgICAgICAgICA8c3Bhbj5BZGQgT3B0aW9uPC9zcGFuPlxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RhdGljLW9wdGlvbnMtbGlzdFwiPlxuICAgICAgICAgICAgQGZvciAob3B0IG9mIHN0YXRpY09wdGlvbnMoKTsgdHJhY2sgJGluZGV4KSB7XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdGF0aWMtb3B0aW9uLXJvd1wiPlxuICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmaWVsZC1pbnB1dCBvcHQta2V5XCJcbiAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiS2V5XCJcbiAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cIm9wdC5rZXlcIlxuICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwidXBkYXRlU3RhdGljT3B0aW9uKCRpbmRleCwgJ2tleScsICRldmVudClcIlxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cImZpZWxkLWlucHV0IG9wdC1sYWJlbFwiXG4gICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIkxhYmVsXCJcbiAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cIm9wdC5sYWJlbFwiXG4gICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJ1cGRhdGVTdGF0aWNPcHRpb24oJGluZGV4LCAnbGFiZWwnLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJidG4tcmVtb3ZlLW9wdGlvblwiXG4gICAgICAgICAgICAgICAgICAoY2xpY2spPVwicmVtb3ZlU3RhdGljT3B0aW9uKCRpbmRleClcIlxuICAgICAgICAgICAgICAgICAgdGl0bGU9XCJSZW1vdmUgb3B0aW9uXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cInRyYXNoXCIgW3NpemVdPVwiMTJcIiAvPlxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICB9XG4gICAgPC9kaXY+XG4gIGAsXG4gIHN0eWxlczogW2BcbiAgICAuZGF0YXNvdXJjZS1oZWFkZXItYmFyIHtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICAgICAgbWFyZ2luLWJvdHRvbTogOHB4O1xuICAgIH1cbiAgICAubW9kZS10b2dnbGUtcGlsbCB7XG4gICAgICBkaXNwbGF5OiBpbmxpbmUtZmxleDtcbiAgICAgIGJhY2tncm91bmQ6ICNlMmU4ZjA7XG4gICAgICBib3JkZXItcmFkaXVzOiAxMnB4O1xuICAgICAgcGFkZGluZzogMnB4O1xuICAgICAgZ2FwOiAycHg7XG4gICAgfVxuICAgIC5waWxsLWJ0biB7XG4gICAgICBib3JkZXI6IG5vbmU7XG4gICAgICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbiAgICAgIHBhZGRpbmc6IDJweCA4cHg7XG4gICAgICBmb250LXNpemU6IDAuNjVyZW07XG4gICAgICBmb250LXdlaWdodDogNTAwO1xuICAgICAgY29sb3I6ICM2NDc0OGI7XG4gICAgICBib3JkZXItcmFkaXVzOiAxMHB4O1xuICAgICAgY3Vyc29yOiBwb2ludGVyO1xuICAgICAgdHJhbnNpdGlvbjogYWxsIDEyMG1zIGVhc2U7XG4gICAgfVxuICAgIC5waWxsLWJ0bjpob3ZlciB7XG4gICAgICBjb2xvcjogIzBmMTcyYTtcbiAgICB9XG4gICAgLnBpbGwtYnRuLmFjdGl2ZSB7XG4gICAgICBiYWNrZ3JvdW5kOiAjZmZmZmZmO1xuICAgICAgY29sb3I6IHZhcigtLXJwdC1jb2xvci1wcmltYXJ5LCAjMjU2M2ViKTtcbiAgICAgIGZvbnQtd2VpZ2h0OiA3MDA7XG4gICAgICBib3gtc2hhZG93OiAwIDFweCAycHggcmdiYSgwLCAwLCAwLCAwLjA4KTtcbiAgICB9XG4gICAgLnNvdXJjZS10eXBlLXN3aXRjaGVyIHtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBiYWNrZ3JvdW5kOiAjZjFmNWY5O1xuICAgICAgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tcnB0LWNvbG9yLWJvcmRlciwgI2NiZDVlMSk7XG4gICAgICBib3JkZXItcmFkaXVzOiA2cHg7XG4gICAgICBwYWRkaW5nOiAycHg7XG4gICAgICBnYXA6IDJweDtcbiAgICAgIG1hcmdpbi1ib3R0b206IDZweDtcbiAgICB9XG4gICAgLnNvdXJjZS10YWItYnRuIHtcbiAgICAgIGZsZXg6IDE7XG4gICAgICBkaXNwbGF5OiBpbmxpbmUtZmxleDtcbiAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgICAgIGdhcDogNXB4O1xuICAgICAgcGFkZGluZzogNnB4IDRweDtcbiAgICAgIGZvbnQtc2l6ZTogMC43cmVtO1xuICAgICAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgICAgIGNvbG9yOiB2YXIoLS1ycHQtY29sb3ItdGV4dC1tdXRlZCwgIzY0NzQ4Yik7XG4gICAgICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbiAgICAgIGJvcmRlcjogbm9uZTtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDRweDtcbiAgICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICAgIHRyYW5zaXRpb246IGFsbCAxMjBtcyBlYXNlO1xuICAgIH1cbiAgICAuc291cmNlLXRhYi1idG46aG92ZXIge1xuICAgICAgY29sb3I6IHZhcigtLXJwdC1jb2xvci10ZXh0LCAjMGYxNzJhKTtcbiAgICB9XG4gICAgLnNvdXJjZS10YWItYnRuLmFjdGl2ZSB7XG4gICAgICBiYWNrZ3JvdW5kOiAjZmZmZmZmO1xuICAgICAgY29sb3I6IHZhcigtLXJwdC1jb2xvci1wcmltYXJ5LCAjMjU2M2ViKTtcbiAgICAgIGJveC1zaGFkb3c6IDAgMXB4IDJweCByZ2JhKDAsIDAsIDAsIDAuMDUpO1xuICAgIH1cbiAgICAuYnRuLXJlZnJlc2gtZW50aXRpZXMge1xuICAgICAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAgZ2FwOiA0cHg7XG4gICAgICBib3JkZXI6IG5vbmU7XG4gICAgICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbiAgICAgIGNvbG9yOiB2YXIoLS1ycHQtY29sb3ItcHJpbWFyeSwgIzI1NjNlYik7XG4gICAgICBmb250LXNpemU6IDAuNjVyZW07XG4gICAgICBmb250LXdlaWdodDogNjAwO1xuICAgICAgY3Vyc29yOiBwb2ludGVyO1xuICAgICAgcGFkZGluZzogMDtcbiAgICB9XG4gICAgLmJ0bi1yZWZyZXNoLWVudGl0aWVzOmhvdmVyIHtcbiAgICAgIHRleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lO1xuICAgIH1cbiAgICAuYXV0by1iYWRnZSB7XG4gICAgICBmb250LXNpemU6IDAuNjJyZW07XG4gICAgICBmb250LXdlaWdodDogNjAwO1xuICAgICAgYmFja2dyb3VuZDogI2RjZmNlNztcbiAgICAgIGNvbG9yOiAjMTY2NTM0O1xuICAgICAgcGFkZGluZzogMXB4IDVweDtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDRweDtcbiAgICB9XG4gICAgLmZpZWxkLWhpbnQge1xuICAgICAgZm9udC1zaXplOiAwLjY1cmVtO1xuICAgICAgY29sb3I6IHZhcigtLXJwdC1jb2xvci10ZXh0LW11dGVkLCAjOTRhM2I4KTtcbiAgICAgIG1hcmdpbi10b3A6IDJweDtcbiAgICB9XG4gICAgLnNwLXBhcmFtcy1ncm91cCB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgIGdhcDogNnB4O1xuICAgICAgYmFja2dyb3VuZDogI2Y4ZmFmYztcbiAgICAgIHBhZGRpbmc6IDhweDtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDZweDtcbiAgICAgIGJvcmRlcjogMXB4IHNvbGlkICNlMmU4ZjA7XG4gICAgICBtYXJnaW4tYm90dG9tOiA2cHg7XG4gICAgfVxuICAgIC5wYXJhbXMtaGVhZGVyLXJvdyB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbiAgICB9XG4gICAgLnBhcmFtcy1oaW50IHtcbiAgICAgIGZvbnQtc2l6ZTogMC42NHJlbTtcbiAgICAgIGNvbG9yOiAjNjQ3NDhiO1xuICAgICAgZm9udC1zdHlsZTogaXRhbGljO1xuICAgIH1cbiAgICAuc3RhdGljLW9wdGlvbnMtd3JhcHBlciB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgIGdhcDogOHB4O1xuICAgIH1cbiAgICAuc3RhdGljLW9wdGlvbnMtaGVhZGVyIHtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICAgIH1cbiAgICAuYnRuLWFkZC1vcHRpb24ge1xuICAgICAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAgZ2FwOiA0cHg7XG4gICAgICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ycHQtY29sb3ItYm9yZGVyLCAjY2JkNWUxKTtcbiAgICAgIGJhY2tncm91bmQ6ICNmZmZmZmY7XG4gICAgICBib3JkZXItcmFkaXVzOiA0cHg7XG4gICAgICBwYWRkaW5nOiAzcHggOHB4O1xuICAgICAgZm9udC1zaXplOiAwLjY1cmVtO1xuICAgICAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgICAgIGNvbG9yOiB2YXIoLS1ycHQtY29sb3ItcHJpbWFyeSwgIzI1NjNlYik7XG4gICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgICB0cmFuc2l0aW9uOiBhbGwgMTIwbXMgZWFzZTtcbiAgICB9XG4gICAgLmJ0bi1hZGQtb3B0aW9uOmhvdmVyIHtcbiAgICAgIGJhY2tncm91bmQ6ICNlZmY2ZmY7XG4gICAgfVxuICAgIC5zdGF0aWMtb3B0aW9ucy1saXN0IHtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgICAgZ2FwOiA2cHg7XG4gICAgfVxuICAgIC5zdGF0aWMtb3B0aW9uLXJvdyB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIGdhcDogNnB4O1xuICAgIH1cbiAgICAub3B0LWtleSB7XG4gICAgICBmbGV4OiAxO1xuICAgIH1cbiAgICAub3B0LWxhYmVsIHtcbiAgICAgIGZsZXg6IDEuNTtcbiAgICB9XG4gICAgLmJ0bi1yZW1vdmUtb3B0aW9uIHtcbiAgICAgIHdpZHRoOiAyNHB4O1xuICAgICAgaGVpZ2h0OiAyNHB4O1xuICAgICAgYm9yZGVyOiBub25lO1xuICAgICAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG4gICAgICBjb2xvcjogIzk0YTNiODtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDRweDtcbiAgICAgIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgICAgY3Vyc29yOiBwb2ludGVyO1xuICAgICAgZmxleC1zaHJpbms6IDA7XG4gICAgICBwYWRkaW5nOiAwO1xuICAgICAgdHJhbnNpdGlvbjogYWxsIDEyMG1zIGVhc2U7XG4gICAgfVxuICAgIC5idG4tcmVtb3ZlLW9wdGlvbjpob3ZlciB7XG4gICAgICBiYWNrZ3JvdW5kOiAjZmVlMmUyO1xuICAgICAgY29sb3I6ICNlZjQ0NDQ7XG4gICAgfVxuICBgXSxcbn0pXG5leHBvcnQgY2xhc3MgUHJvcGVydHlFZGl0b3JEYXRhc291cmNlQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgcHJpdmF0ZSByZWFkb25seSBkaXNjb3ZlcnlBZGFwdGVyID0gaW5qZWN0KFJlcG9ydFNjaGVtYURpc2NvdmVyeUFkYXB0ZXIsIHsgb3B0aW9uYWw6IHRydWUgfSk7XG5cbiAgcmVhZG9ubHkgY29tcCA9IGlucHV0LnJlcXVpcmVkPFJlcG9ydENvbXBvbmVudERlZmluaXRpb24+KCk7XG4gIHJlYWRvbmx5IGFsbENvbXBvbmVudHMgPSBpbnB1dDxSZXBvcnRDb21wb25lbnREZWZpbml0aW9uW10+KFtdKTtcblxuICByZWFkb25seSB1cGRhdGVEYXRhU291cmNlID0gb3V0cHV0PENvbXBvbmVudERhdGFTb3VyY2VEZWZpbml0aW9uPigpO1xuICByZWFkb25seSB1cGRhdGVQcm9wZXJ0eSA9IG91dHB1dDx7IGtleTogc3RyaW5nOyB2YWx1ZTogdW5rbm93biB9PigpO1xuXG4gIHJlYWRvbmx5IGlzQWR2YW5jZWRNb2RlID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgcmVhZG9ubHkgYWxsRW50aXRpZXMgPSBzaWduYWw8RGF0YWJhc2VFbnRpdHlNZXRhZGF0YVtdPihbXSk7XG4gIHJlYWRvbmx5IGVudGl0eUNvbHVtbnMgPSBzaWduYWw8RW50aXR5Q29sdW1uTWV0YWRhdGFbXT4oW10pO1xuICByZWFkb25seSBwcm9jZWR1cmVQYXJhbWV0ZXJzID0gc2lnbmFsPFByb2NlZHVyZVBhcmFtZXRlck1ldGFkYXRhW10+KFtdKTtcblxuICByZWFkb25seSBjdXJyZW50U291cmNlVHlwZSA9IGNvbXB1dGVkPERyb3Bkb3duU291cmNlVHlwZT4oKCkgPT4ge1xuICAgIGNvbnN0IGRzID0gdGhpcy5jb21wKCkuZGF0YVNvdXJjZTtcbiAgICBpZiAoZHM/LnNvdXJjZVR5cGUpIHJldHVybiBkcy5zb3VyY2VUeXBlO1xuICAgIGlmIChkcz8uZW50aXR5TmFtZSkgcmV0dXJuICd0YWJsZSc7XG4gICAgcmV0dXJuICdzdGF0aWMnO1xuICB9KTtcblxuICByZWFkb25seSBzZWxlY3RlZEVudGl0eSA9IGNvbXB1dGVkKCgpID0+IHRoaXMuY29tcCgpLmRhdGFTb3VyY2U/LmVudGl0eU5hbWUgfHwgJycpO1xuICByZWFkb25seSBzZWxlY3RlZFZhbHVlRmllbGQgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmNvbXAoKS5kYXRhU291cmNlPy52YWx1ZUZpZWxkIHx8ICcnKTtcbiAgcmVhZG9ubHkgc2VsZWN0ZWREaXNwbGF5RmllbGQgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmNvbXAoKS5kYXRhU291cmNlPy5kaXNwbGF5RmllbGQgfHwgJycpO1xuICByZWFkb25seSBzZWxlY3RlZERlcGVuZHNPbiA9IGNvbXB1dGVkKCgpID0+IHRoaXMuY29tcCgpLmRhdGFTb3VyY2U/LmRlcGVuZHNPbj8uWzBdIHx8ICcnKTtcblxuICByZWFkb25seSBhdmFpbGFibGVUYWJsZXMgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgcmV0dXJuIHRoaXMuYWxsRW50aXRpZXMoKVxuICAgICAgLmZpbHRlcigoZSkgPT4gZS50eXBlID09PSAndGFibGUnIHx8IGUudHlwZSA9PT0gJ3ZpZXcnKVxuICAgICAgLm1hcCgoZSkgPT4gKHtcbiAgICAgICAgLi4uZSxcbiAgICAgICAgZGlzcGxheU5hbWU6IGUuZnJpZW5kbHlOYW1lIHx8IGh1bWFuaXplSWRlbnRpZmllcihlLm5hbWUpLFxuICAgICAgfSkpO1xuICB9KTtcblxuICByZWFkb25seSBhdmFpbGFibGVQcm9jZWR1cmVzID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIHJldHVybiB0aGlzLmFsbEVudGl0aWVzKClcbiAgICAgIC5maWx0ZXIoKGUpID0+IGUudHlwZSA9PT0gJ3N0b3JlZF9wcm9jZWR1cmUnKVxuICAgICAgLm1hcCgoZSkgPT4gKHtcbiAgICAgICAgLi4uZSxcbiAgICAgICAgZGlzcGxheU5hbWU6IGUuZnJpZW5kbHlOYW1lIHx8IGh1bWFuaXplSWRlbnRpZmllcihlLm5hbWUpLFxuICAgICAgfSkpO1xuICB9KTtcblxuICByZWFkb25seSBhdmFpbGFibGVQYXJlbnRGaWVsZHMgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgcmV0dXJuIHRoaXMuYWxsQ29tcG9uZW50cygpLmZpbHRlcigoYykgPT4gYy5pZCAhPT0gdGhpcy5jb21wKCkuaWQpO1xuICB9KTtcblxuICByZWFkb25seSBzdGF0aWNPcHRpb25zID0gY29tcHV0ZWQ8U3RhdGljT3B0aW9uSXRlbVtdPigoKSA9PiB7XG4gICAgY29uc3Qgb3B0cyA9IHRoaXMuY29tcCgpLnByb3BlcnRpZXM/Llsnb3B0aW9ucyddO1xuICAgIGlmIChBcnJheS5pc0FycmF5KG9wdHMpKSB7XG4gICAgICByZXR1cm4gb3B0cy5tYXAoKG8pID0+ICh7IGtleTogU3RyaW5nKG8ua2V5ID8/IG8udmFsdWUgPz8gJycpLCBsYWJlbDogU3RyaW5nKG8ubGFiZWwgPz8gJycpIH0pKTtcbiAgICB9XG4gICAgcmV0dXJuIFtcbiAgICAgIHsga2V5OiAnMScsIGxhYmVsOiAnT3B0aW9uIDEnIH0sXG4gICAgICB7IGtleTogJzInLCBsYWJlbDogJ09wdGlvbiAyJyB9LFxuICAgIF07XG4gIH0pO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIGVmZmVjdChcbiAgICAgICgpID0+IHtcbiAgICAgICAgY29uc3QgZW50aXR5ID0gdGhpcy5zZWxlY3RlZEVudGl0eSgpO1xuICAgICAgICBjb25zdCB0eXBlID0gdGhpcy5jdXJyZW50U291cmNlVHlwZSgpO1xuICAgICAgICBpZiAoZW50aXR5ICYmICh0eXBlID09PSAndGFibGUnIHx8IHR5cGUgPT09ICdwcm9jZWR1cmUnKSkge1xuICAgICAgICAgIHRoaXMubG9hZEVudGl0eURldGFpbHMoZW50aXR5LCB0eXBlKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHsgYWxsb3dTaWduYWxXcml0ZXM6IHRydWUgfVxuICAgICk7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmxvYWRFbnRpdGllcygpO1xuICB9XG5cbiAgbG9hZEVudGl0aWVzKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5kaXNjb3ZlcnlBZGFwdGVyKSByZXR1cm47XG4gICAgdGhpcy5kaXNjb3ZlcnlBZGFwdGVyLmdldEVudGl0aWVzKCkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChlbnRpdGllcykgPT4ge1xuICAgICAgICB0aGlzLmFsbEVudGl0aWVzLnNldChlbnRpdGllcyk7XG4gICAgICB9LFxuICAgICAgZXJyb3I6IChlcnIpID0+IGNvbnNvbGUuZXJyb3IoJ1tQcm9wZXJ0eUVkaXRvckRhdGFzb3VyY2VdIEZhaWxlZCB0byBsb2FkIGVudGl0aWVzOicsIGVyciksXG4gICAgfSk7XG4gIH1cblxuICBsb2FkRW50aXR5RGV0YWlscyhlbnRpdHlOYW1lOiBzdHJpbmcsIHR5cGU6IERyb3Bkb3duU291cmNlVHlwZSk6IHZvaWQge1xuICAgIGlmICghdGhpcy5kaXNjb3ZlcnlBZGFwdGVyKSByZXR1cm47XG5cbiAgICBjb25zdCBkYlR5cGUgPSB0eXBlID09PSAncHJvY2VkdXJlJyA/ICdzdG9yZWRfcHJvY2VkdXJlJyA6ICd0YWJsZSc7XG4gICAgdGhpcy5kaXNjb3ZlcnlBZGFwdGVyLmdldENvbHVtbnMoZW50aXR5TmFtZSwgJ2RibycsIGRiVHlwZSkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChjb2xzKSA9PiB7XG4gICAgICAgIHRoaXMuZW50aXR5Q29sdW1ucy5zZXQoY29scyk7XG5cbiAgICAgICAgLy8gQXV0by1kZXRlY3QgZGVmYXVsdCB2YWx1ZUZpZWxkIGFuZCBkaXNwbGF5RmllbGQgaWYgbm90IHlldCBzZXRcbiAgICAgICAgY29uc3QgY3VycmVudFZhbCA9IHRoaXMuc2VsZWN0ZWRWYWx1ZUZpZWxkKCk7XG4gICAgICAgIGNvbnN0IGN1cnJlbnREaXNwID0gdGhpcy5zZWxlY3RlZERpc3BsYXlGaWVsZCgpO1xuICAgICAgICBjb25zdCBzdWdnZXN0ZWRWYWwgPSBkZXRlY3REZWZhdWx0VmFsdWVGaWVsZChjb2xzKTtcbiAgICAgICAgY29uc3Qgc3VnZ2VzdGVkRGlzcCA9IGRldGVjdERlZmF1bHREaXNwbGF5RmllbGQoY29scyk7XG5cbiAgICAgICAgaWYgKCFjdXJyZW50VmFsIHx8ICFjdXJyZW50RGlzcCkge1xuICAgICAgICAgIHRoaXMudXBkYXRlRGF0YVNvdXJjZS5lbWl0KHtcbiAgICAgICAgICAgIC4uLih0aGlzLmNvbXAoKS5kYXRhU291cmNlID8/IHsgZGlzcGxheUZpZWxkOiAnJywgdmFsdWVGaWVsZDogJycgfSksXG4gICAgICAgICAgICBzb3VyY2VUeXBlOiB0eXBlLFxuICAgICAgICAgICAgZW50aXR5TmFtZSxcbiAgICAgICAgICAgIHZhbHVlRmllbGQ6IGN1cnJlbnRWYWwgfHwgc3VnZ2VzdGVkVmFsIHx8IGNvbHNbMF0/LmZpZWxkIHx8ICcnLFxuICAgICAgICAgICAgZGlzcGxheUZpZWxkOiBjdXJyZW50RGlzcCB8fCBzdWdnZXN0ZWREaXNwIHx8IGNvbHNbMV0/LmZpZWxkIHx8IGNvbHNbMF0/LmZpZWxkIHx8ICcnLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgZXJyb3I6IChlcnIpID0+IGNvbnNvbGUuZXJyb3IoYFtQcm9wZXJ0eUVkaXRvckRhdGFzb3VyY2VdIEZhaWxlZCB0byBsb2FkIGNvbHVtbnMgZm9yICR7ZW50aXR5TmFtZX06YCwgZXJyKSxcbiAgICB9KTtcblxuICAgIGlmICh0eXBlID09PSAncHJvY2VkdXJlJykge1xuICAgICAgdGhpcy5kaXNjb3ZlcnlBZGFwdGVyLmdldFBhcmFtZXRlcnMoZW50aXR5TmFtZSwgJ2RibycpLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChwYXJhbXMpID0+IHRoaXMucHJvY2VkdXJlUGFyYW1ldGVycy5zZXQocGFyYW1zKSxcbiAgICAgICAgZXJyb3I6IChlcnIpID0+IGNvbnNvbGUuZXJyb3IoYFtQcm9wZXJ0eUVkaXRvckRhdGFzb3VyY2VdIEZhaWxlZCB0byBsb2FkIHBhcmFtcyBmb3IgJHtlbnRpdHlOYW1lfTpgLCBlcnIpLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgc2V0U291cmNlVHlwZSh0eXBlOiBEcm9wZG93blNvdXJjZVR5cGUpOiB2b2lkIHtcbiAgICBpZiAodHlwZSA9PT0gJ3N0YXRpYycpIHtcbiAgICAgIHRoaXMudXBkYXRlRGF0YVNvdXJjZS5lbWl0KHtcbiAgICAgICAgc291cmNlVHlwZTogJ3N0YXRpYycsXG4gICAgICAgIGRpc3BsYXlGaWVsZDogJycsXG4gICAgICAgIHZhbHVlRmllbGQ6ICcnLFxuICAgICAgfSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZmlyc3RFbnRpdHkgPSB0eXBlID09PSAndGFibGUnID8gdGhpcy5hdmFpbGFibGVUYWJsZXMoKVswXT8ubmFtZSA6IHRoaXMuYXZhaWxhYmxlUHJvY2VkdXJlcygpWzBdPy5uYW1lO1xuICAgIHRoaXMudXBkYXRlRGF0YVNvdXJjZS5lbWl0KHtcbiAgICAgIHNvdXJjZVR5cGU6IHR5cGUsXG4gICAgICBlbnRpdHlOYW1lOiBmaXJzdEVudGl0eSB8fCAnJyxcbiAgICAgIHNjaGVtYTogJ2RibycsXG4gICAgICBkaXNwbGF5RmllbGQ6ICcnLFxuICAgICAgdmFsdWVGaWVsZDogJycsXG4gICAgfSk7XG4gIH1cblxuICBvbkVudGl0eVNlbGVjdGVkKGVudGl0eU5hbWU6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMudXBkYXRlRGF0YVNvdXJjZS5lbWl0KHtcbiAgICAgIC4uLih0aGlzLmNvbXAoKS5kYXRhU291cmNlID8/IHsgZGlzcGxheUZpZWxkOiAnJywgdmFsdWVGaWVsZDogJycgfSksXG4gICAgICBzb3VyY2VUeXBlOiB0aGlzLmN1cnJlbnRTb3VyY2VUeXBlKCksXG4gICAgICBlbnRpdHlOYW1lLFxuICAgICAgc2NoZW1hOiAnZGJvJyxcbiAgICAgIHZhbHVlRmllbGQ6ICcnLFxuICAgICAgZGlzcGxheUZpZWxkOiAnJyxcbiAgICB9KTtcbiAgfVxuXG4gIG9uVmFsdWVGaWVsZENoYW5nZWQodmFsdWVGaWVsZDogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy51cGRhdGVEYXRhU291cmNlLmVtaXQoe1xuICAgICAgLi4uKHRoaXMuY29tcCgpLmRhdGFTb3VyY2UgPz8geyBkaXNwbGF5RmllbGQ6ICcnLCB2YWx1ZUZpZWxkOiAnJyB9KSxcbiAgICAgIHZhbHVlRmllbGQsXG4gICAgfSk7XG4gIH1cblxuICBvbkRpc3BsYXlGaWVsZENoYW5nZWQoZGlzcGxheUZpZWxkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnVwZGF0ZURhdGFTb3VyY2UuZW1pdCh7XG4gICAgICAuLi4odGhpcy5jb21wKCkuZGF0YVNvdXJjZSA/PyB7IGRpc3BsYXlGaWVsZDogJycsIHZhbHVlRmllbGQ6ICcnIH0pLFxuICAgICAgZGlzcGxheUZpZWxkLFxuICAgIH0pO1xuICB9XG5cbiAgb25EZXBlbmRzT25DaGFuZ2VkKHBhcmVudEtleTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy51cGRhdGVEYXRhU291cmNlLmVtaXQoe1xuICAgICAgLi4uKHRoaXMuY29tcCgpLmRhdGFTb3VyY2UgPz8geyBkaXNwbGF5RmllbGQ6ICcnLCB2YWx1ZUZpZWxkOiAnJyB9KSxcbiAgICAgIGRlcGVuZHNPbjogcGFyZW50S2V5ID8gW3BhcmVudEtleV0gOiBbXSxcbiAgICB9KTtcbiAgfVxuXG4gIGdldFBhcmFtVmFsdWUocGFyYW1OYW1lOiBzdHJpbmcpOiBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5jb21wKCkuZGF0YVNvdXJjZT8ucGFyYW1ldGVyTWFwcGluZ3M/LltwYXJhbU5hbWVdID8/ICcnO1xuICB9XG5cbiAgc2V0UGFyYW1WYWx1ZShwYXJhbU5hbWU6IHN0cmluZywgdmFsdWU6IHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBjb25zdCBleGlzdGluZyA9IHRoaXMuY29tcCgpLmRhdGFTb3VyY2U/LnBhcmFtZXRlck1hcHBpbmdzID8/IHt9O1xuICAgIHRoaXMudXBkYXRlRGF0YVNvdXJjZS5lbWl0KHtcbiAgICAgIC4uLih0aGlzLmNvbXAoKS5kYXRhU291cmNlID8/IHsgZGlzcGxheUZpZWxkOiAnJywgdmFsdWVGaWVsZDogJycgfSksXG4gICAgICBwYXJhbWV0ZXJNYXBwaW5nczoge1xuICAgICAgICAuLi5leGlzdGluZyxcbiAgICAgICAgW3BhcmFtTmFtZV06IHZhbHVlLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIG9uUGFyYW1MaW5rZWRGaWVsZENoYW5nZShldnQ6IHsgcGFyYW1OYW1lOiBzdHJpbmc7IGZpZWxkS2V5OiBzdHJpbmc7IGlzTGlua2VkOiBib29sZWFuIH0pOiB2b2lkIHtcbiAgICBjb25zdCBjdXJyZW50RGVwZW5kc09uID0gWy4uLih0aGlzLmNvbXAoKS5kYXRhU291cmNlPy5kZXBlbmRzT24gPz8gW10pXTtcbiAgICBpZiAoZXZ0LmlzTGlua2VkICYmIGV2dC5maWVsZEtleSkge1xuICAgICAgaWYgKCFjdXJyZW50RGVwZW5kc09uLmluY2x1ZGVzKGV2dC5maWVsZEtleSkpIHtcbiAgICAgICAgY3VycmVudERlcGVuZHNPbi5wdXNoKGV2dC5maWVsZEtleSk7XG4gICAgICAgIHRoaXMudXBkYXRlRGF0YVNvdXJjZS5lbWl0KHtcbiAgICAgICAgICAuLi4odGhpcy5jb21wKCkuZGF0YVNvdXJjZSA/PyB7IGRpc3BsYXlGaWVsZDogJycsIHZhbHVlRmllbGQ6ICcnIH0pLFxuICAgICAgICAgIGRlcGVuZHNPbjogY3VycmVudERlcGVuZHNPbixcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgYWRkU3RhdGljT3B0aW9uKCk6IHZvaWQge1xuICAgIGNvbnN0IGN1cnJlbnQgPSBbLi4udGhpcy5zdGF0aWNPcHRpb25zKCldO1xuICAgIGNvbnN0IG5leHRJZHggPSBjdXJyZW50Lmxlbmd0aCArIDE7XG4gICAgY3VycmVudC5wdXNoKHsga2V5OiBTdHJpbmcobmV4dElkeCksIGxhYmVsOiBgT3B0aW9uICR7bmV4dElkeH1gIH0pO1xuICAgIHRoaXMudXBkYXRlUHJvcGVydHkuZW1pdCh7IGtleTogJ29wdGlvbnMnLCB2YWx1ZTogY3VycmVudCB9KTtcbiAgfVxuXG4gIHVwZGF0ZVN0YXRpY09wdGlvbihpbmRleDogbnVtYmVyLCBmaWVsZDogJ2tleScgfCAnbGFiZWwnLCB2YWw6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IGN1cnJlbnQgPSBbLi4udGhpcy5zdGF0aWNPcHRpb25zKCldO1xuICAgIGlmIChjdXJyZW50W2luZGV4XSkge1xuICAgICAgY3VycmVudFtpbmRleF0gPSB7IC4uLmN1cnJlbnRbaW5kZXhdLCBbZmllbGRdOiB2YWwgfTtcbiAgICAgIHRoaXMudXBkYXRlUHJvcGVydHkuZW1pdCh7IGtleTogJ29wdGlvbnMnLCB2YWx1ZTogY3VycmVudCB9KTtcbiAgICB9XG4gIH1cblxuICByZW1vdmVTdGF0aWNPcHRpb24oaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLnN0YXRpY09wdGlvbnMoKS5maWx0ZXIoKF8sIGkpID0+IGkgIT09IGluZGV4KTtcbiAgICB0aGlzLnVwZGF0ZVByb3BlcnR5LmVtaXQoeyBrZXk6ICdvcHRpb25zJywgdmFsdWU6IGN1cnJlbnQgfSk7XG4gIH1cbn1cblxuIl19
|