bways-report 0.1.3 → 0.1.5
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/esm2022/lib/core/models/report-grid.model.mjs +1 -1
- package/esm2022/lib/core/services/index.mjs +2 -1
- package/esm2022/lib/core/services/report-storage.service.mjs +63 -0
- package/esm2022/lib/core/tokens/index.mjs +2 -1
- package/esm2022/lib/core/tokens/storage.token.mjs +128 -0
- package/esm2022/lib/data-access/adapters/local-storage-persistence.adapter.mjs +16 -44
- package/esm2022/lib/features/designer/components/component-palette/component-palette.component.mjs +5 -352
- package/esm2022/lib/features/designer/components/design-canvas/design-canvas.component.mjs +6 -1011
- package/esm2022/lib/features/designer/components/property-editor/property-editor-datasource.component.mjs +66 -683
- package/esm2022/lib/features/designer/components/property-editor/property-editor-grid.component.mjs +3 -789
- package/esm2022/lib/features/designer/components/property-editor/property-editor.component.mjs +14 -480
- package/esm2022/lib/features/designer/components/toolbar/designer-toolbar.component.mjs +88 -25
- package/esm2022/lib/features/designer/designer.component.mjs +194 -65
- package/esm2022/lib/features/designer/services/designer-state.service.mjs +9 -2
- package/esm2022/lib/features/routing/components/routed-report-runtime.component.mjs +2 -2
- package/esm2022/lib/features/runtime/dynamic-renderer.component.mjs +11 -3
- package/esm2022/lib/features/runtime/report-execution.service.mjs +1 -9
- package/esm2022/lib/features/runtime/report-grid-bridge.component.mjs +223 -24
- package/esm2022/lib/features/runtime/report-runtime.component.mjs +11 -3
- package/esm2022/lib/features/runtime/rpt-report.component.mjs +11 -3
- package/esm2022/lib/primitives/components/checkbox/rpt-checkbox.component.mjs +3 -3
- package/esm2022/lib/primitives/components/date/rpt-date.component.mjs +3 -3
- package/esm2022/lib/primitives/components/date-range/rpt-date-range.component.mjs +3 -3
- package/esm2022/lib/primitives/components/dropdown/rpt-dropdown.component.mjs +4 -422
- package/esm2022/lib/primitives/components/icon/rpt-icon.component.mjs +23 -1
- package/esm2022/lib/primitives/components/input/rpt-input.component.mjs +3 -3
- package/esm2022/lib/primitives/components/kpi-card/rpt-kpi-card.component.mjs +3 -3
- package/esm2022/lib/primitives/components/number/rpt-number.component.mjs +3 -3
- package/fesm2022/bways-report.mjs +2094 -5139
- package/fesm2022/bways-report.mjs.map +1 -1
- package/lib/core/models/report-grid.model.d.ts +23 -1
- package/lib/core/services/index.d.ts +1 -0
- package/lib/core/services/report-storage.service.d.ts +26 -0
- package/lib/core/tokens/index.d.ts +2 -0
- package/lib/core/tokens/storage.token.d.ts +48 -0
- package/lib/data-access/adapters/local-storage-persistence.adapter.d.ts +1 -0
- package/lib/features/designer/components/component-palette/component-palette.component.d.ts +2 -1
- package/lib/features/designer/components/property-editor/property-editor-datasource.component.d.ts +9 -0
- package/lib/features/designer/components/property-editor/property-editor.component.d.ts +4 -1
- package/lib/features/designer/components/toolbar/designer-toolbar.component.d.ts +5 -1
- package/lib/features/designer/designer.component.d.ts +6 -0
- package/lib/features/runtime/dynamic-renderer.component.d.ts +4 -1
- package/lib/features/runtime/report-grid-bridge.component.d.ts +47 -4
- package/lib/features/runtime/report-runtime.component.d.ts +4 -1
- package/lib/features/runtime/rpt-report.component.d.ts +4 -1
- package/package.json +9 -1
|
@@ -125,12 +125,64 @@ export class PropertyEditorDatasourceComponent {
|
|
|
125
125
|
this.discoveryAdapter.getParameters(entityName, 'dbo').subscribe({
|
|
126
126
|
next: (params) => {
|
|
127
127
|
this.procedureParameters.set(params);
|
|
128
|
-
|
|
128
|
+
// Only auto-link to existing session or existing canvas fields.
|
|
129
|
+
// NEVER mutate canvas or create new components automatically!
|
|
130
|
+
this.autoLinkExistingParameters(params);
|
|
129
131
|
},
|
|
130
132
|
error: (err) => console.error(`[PropertyEditorDatasource] Failed to load params for ${entityName}:`, err),
|
|
131
133
|
});
|
|
132
134
|
}
|
|
133
135
|
}
|
|
136
|
+
/**
|
|
137
|
+
* Non-destructive linking: binds parameters to session or already-existing canvas fields.
|
|
138
|
+
* Never mutates or adds new components to the canvas.
|
|
139
|
+
*/
|
|
140
|
+
autoLinkExistingParameters(paramsList) {
|
|
141
|
+
const params = paramsList || this.procedureParameters();
|
|
142
|
+
if (!params || params.length === 0)
|
|
143
|
+
return;
|
|
144
|
+
const currentMappings = { ...(this.comp().dataSource?.parameterMappings ?? {}) };
|
|
145
|
+
let changed = false;
|
|
146
|
+
for (const param of params) {
|
|
147
|
+
const clean = param.name.replace(/^@/, '');
|
|
148
|
+
const existing = currentMappings[param.name] ?? currentMappings[clean];
|
|
149
|
+
if (existing !== undefined && existing !== '') {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
// 1. Session match (e.g. companyId, branchId, userId)
|
|
153
|
+
const sessionMatch = this.sessionService?.matchParameter(clean) ?? this.sessionService?.matchParameter(param.name);
|
|
154
|
+
if (sessionMatch) {
|
|
155
|
+
currentMappings[param.name] = `{{session.${sessionMatch.sessionKey}}}`;
|
|
156
|
+
currentMappings[clean] = `{{session.${sessionMatch.sessionKey}}}`;
|
|
157
|
+
changed = true;
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
// 2. Existing canvas field match
|
|
161
|
+
const matchedComp = this.allComponents().find((c) => {
|
|
162
|
+
if (c.id === this.comp().id)
|
|
163
|
+
return false;
|
|
164
|
+
const ck = (c.key || '').toLowerCase();
|
|
165
|
+
const cl = clean.toLowerCase();
|
|
166
|
+
return ck === cl || ck === toFieldKey(cl);
|
|
167
|
+
});
|
|
168
|
+
if (matchedComp) {
|
|
169
|
+
currentMappings[param.name] = `{{${matchedComp.key}}}`;
|
|
170
|
+
currentMappings[clean] = `{{${matchedComp.key}}}`;
|
|
171
|
+
changed = true;
|
|
172
|
+
continue;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
if (changed) {
|
|
176
|
+
this.updateDataSource.emit({
|
|
177
|
+
...(this.comp().dataSource ?? { displayField: '', valueField: '' }),
|
|
178
|
+
parameterMappings: currentMappings,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Explicit user-initiated action: links existing fields, and creates missing filter inputs on canvas.
|
|
184
|
+
* Restores selection to the current dropdown component so the user stays in this property editor.
|
|
185
|
+
*/
|
|
134
186
|
autoWireAllParameters(paramsList) {
|
|
135
187
|
const params = paramsList || this.procedureParameters();
|
|
136
188
|
if (!params || params.length === 0)
|
|
@@ -165,7 +217,7 @@ export class PropertyEditorDatasourceComponent {
|
|
|
165
217
|
changed = true;
|
|
166
218
|
continue;
|
|
167
219
|
}
|
|
168
|
-
// 3. Auto-create missing canvas field
|
|
220
|
+
// 3. Auto-create missing canvas field when explicitly requested by user
|
|
169
221
|
if (this.designerState) {
|
|
170
222
|
const lower = clean.toLowerCase();
|
|
171
223
|
let compType = 'input';
|
|
@@ -197,6 +249,10 @@ export class PropertyEditorDatasourceComponent {
|
|
|
197
249
|
}
|
|
198
250
|
}
|
|
199
251
|
}
|
|
252
|
+
// Restore selection to current dropdown so user is not navigated away
|
|
253
|
+
if (this.designerState) {
|
|
254
|
+
this.designerState.selectComponent(this.comp().id);
|
|
255
|
+
}
|
|
200
256
|
if (changed) {
|
|
201
257
|
this.updateDataSource.emit({
|
|
202
258
|
...(this.comp().dataSource ?? { displayField: '', valueField: '' }),
|
|
@@ -216,10 +272,13 @@ export class PropertyEditorDatasourceComponent {
|
|
|
216
272
|
if (this.allEntities().length === 0) {
|
|
217
273
|
this.loadEntities();
|
|
218
274
|
}
|
|
219
|
-
const
|
|
275
|
+
const currentEntity = this.comp().dataSource?.entityName;
|
|
276
|
+
const isValidForType = type === 'table'
|
|
277
|
+
? this.availableTables().some((t) => t.name === currentEntity)
|
|
278
|
+
: this.availableProcedures().some((p) => p.name === currentEntity);
|
|
220
279
|
this.updateDataSource.emit({
|
|
221
280
|
sourceType: type,
|
|
222
|
-
entityName:
|
|
281
|
+
entityName: isValidForType ? (currentEntity || '') : '',
|
|
223
282
|
schema: 'dbo',
|
|
224
283
|
displayField: '',
|
|
225
284
|
valueField: '',
|
|
@@ -301,686 +360,10 @@ export class PropertyEditorDatasourceComponent {
|
|
|
301
360
|
this.updateProperty.emit({ key: 'options', value: current });
|
|
302
361
|
}
|
|
303
362
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PropertyEditorDatasourceComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
304
|
-
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: `
|
|
305
|
-
<div class="property-group">
|
|
306
|
-
<!-- 1. Header with Simple / Advanced Mode Toggle -->
|
|
307
|
-
<div class="datasource-header-bar">
|
|
308
|
-
<div class="group-title">Options Data Source</div>
|
|
309
|
-
<div class="mode-toggle-pill">
|
|
310
|
-
<button
|
|
311
|
-
type="button"
|
|
312
|
-
class="pill-btn"
|
|
313
|
-
[class.active]="!isAdvancedMode()"
|
|
314
|
-
(click)="isAdvancedMode.set(false)"
|
|
315
|
-
title="Simplified view for business users with friendly names"
|
|
316
|
-
>
|
|
317
|
-
Simple
|
|
318
|
-
</button>
|
|
319
|
-
<button
|
|
320
|
-
type="button"
|
|
321
|
-
class="pill-btn"
|
|
322
|
-
[class.active]="isAdvancedMode()"
|
|
323
|
-
(click)="isAdvancedMode.set(true)"
|
|
324
|
-
title="Technical view with SQL types and expressions"
|
|
325
|
-
>
|
|
326
|
-
Advanced
|
|
327
|
-
</button>
|
|
328
|
-
</div>
|
|
329
|
-
</div>
|
|
330
|
-
|
|
331
|
-
<!-- 2. Source Type Segmented Switcher -->
|
|
332
|
-
<div class="source-type-switcher">
|
|
333
|
-
<button
|
|
334
|
-
type="button"
|
|
335
|
-
class="source-tab-btn"
|
|
336
|
-
[class.active]="currentSourceType() === 'table'"
|
|
337
|
-
(click)="setSourceType('table')"
|
|
338
|
-
>
|
|
339
|
-
<rpt-icon name="table" [size]="12" />
|
|
340
|
-
<span>{{ isAdvancedMode() ? 'Table / View' : 'Database Table' }}</span>
|
|
341
|
-
</button>
|
|
342
|
-
<button
|
|
343
|
-
type="button"
|
|
344
|
-
class="source-tab-btn"
|
|
345
|
-
[class.active]="currentSourceType() === 'procedure'"
|
|
346
|
-
(click)="setSourceType('procedure')"
|
|
347
|
-
>
|
|
348
|
-
<rpt-icon name="code" [size]="12" />
|
|
349
|
-
<span>{{ isAdvancedMode() ? 'Stored Proc' : 'Data Query' }}</span>
|
|
350
|
-
</button>
|
|
351
|
-
<button
|
|
352
|
-
type="button"
|
|
353
|
-
class="source-tab-btn"
|
|
354
|
-
[class.active]="currentSourceType() === 'static'"
|
|
355
|
-
(click)="setSourceType('static')"
|
|
356
|
-
>
|
|
357
|
-
<rpt-icon name="edit" [size]="12" />
|
|
358
|
-
<span>Static List</span>
|
|
359
|
-
</button>
|
|
360
|
-
</div>
|
|
361
|
-
|
|
362
|
-
<!-- 3A. DATABASE TABLE / VIEW CONFIGURATION -->
|
|
363
|
-
@if (currentSourceType() === 'table') {
|
|
364
|
-
<div class="field-row">
|
|
365
|
-
<div class="field-label-row">
|
|
366
|
-
<label class="field-label">
|
|
367
|
-
{{ isAdvancedMode() ? 'Database Table / View' : 'Select Data Source' }}
|
|
368
|
-
</label>
|
|
369
|
-
<button
|
|
370
|
-
type="button"
|
|
371
|
-
class="btn-refresh-entities"
|
|
372
|
-
(click)="loadEntities()"
|
|
373
|
-
title="Refresh available tables from backend"
|
|
374
|
-
>
|
|
375
|
-
<rpt-icon name="refresh" [size]="11" />
|
|
376
|
-
<span>Refresh</span>
|
|
377
|
-
</button>
|
|
378
|
-
</div>
|
|
379
|
-
<select
|
|
380
|
-
class="field-select"
|
|
381
|
-
[ngModel]="selectedEntity()"
|
|
382
|
-
(ngModelChange)="onEntitySelected($event)"
|
|
383
|
-
[disabled]="isLoadingEntities()"
|
|
384
|
-
>
|
|
385
|
-
@if (isLoadingEntities()) {
|
|
386
|
-
<option value="">Loading tables from database...</option>
|
|
387
|
-
} @else if (availableTables().length === 0) {
|
|
388
|
-
<option value="">-- No tables found (Click Refresh) --</option>
|
|
389
|
-
} @else {
|
|
390
|
-
<option value="">-- Choose Data Table --</option>
|
|
391
|
-
}
|
|
392
|
-
@for (tbl of availableTables(); track tbl.name) {
|
|
393
|
-
<option [value]="tbl.name">
|
|
394
|
-
@if (isAdvancedMode()) {
|
|
395
|
-
{{ tbl.schema }}.{{ tbl.name }} ({{ tbl.type }})
|
|
396
|
-
} @else {
|
|
397
|
-
{{ tbl.displayName }}{{ tbl.category ? ' • ' + tbl.category : '' }}
|
|
398
|
-
}
|
|
399
|
-
</option>
|
|
400
|
-
}
|
|
401
|
-
</select>
|
|
402
|
-
</div>
|
|
403
|
-
|
|
404
|
-
@if (selectedEntity()) {
|
|
405
|
-
<!-- Display Field (Visible text) -->
|
|
406
|
-
<div class="field-row">
|
|
407
|
-
<div class="field-label-row">
|
|
408
|
-
<label class="field-label">
|
|
409
|
-
{{ isAdvancedMode() ? 'Display Field (Visible Text)' : 'Text Shown in Dropdown' }}
|
|
410
|
-
</label>
|
|
411
|
-
@if (!isAdvancedMode()) {
|
|
412
|
-
<span class="auto-badge" title="Auto-detected column for text label">Auto-detected</span>
|
|
413
|
-
}
|
|
414
|
-
</div>
|
|
415
|
-
<select
|
|
416
|
-
class="field-select"
|
|
417
|
-
[ngModel]="selectedDisplayField()"
|
|
418
|
-
(ngModelChange)="onDisplayFieldChanged($event)"
|
|
419
|
-
>
|
|
420
|
-
<option value="">-- Select Display Column --</option>
|
|
421
|
-
@for (col of entityColumns(); track col.field) {
|
|
422
|
-
<option [value]="col.field">
|
|
423
|
-
{{ col.label }} {{ isAdvancedMode() ? '(' + col.dataType + ')' : '' }}
|
|
424
|
-
</option>
|
|
425
|
-
}
|
|
426
|
-
</select>
|
|
427
|
-
</div>
|
|
428
|
-
|
|
429
|
-
<!-- Value Field (Stored key) -->
|
|
430
|
-
<div class="field-row">
|
|
431
|
-
<div class="field-label-row">
|
|
432
|
-
<label class="field-label">
|
|
433
|
-
{{ isAdvancedMode() ? 'Value Field (Stored Key)' : 'Internal Value / Key' }}
|
|
434
|
-
</label>
|
|
435
|
-
@if (!isAdvancedMode()) {
|
|
436
|
-
<span class="auto-badge" title="Auto-detected column for primary ID">Auto-detected</span>
|
|
437
|
-
}
|
|
438
|
-
</div>
|
|
439
|
-
<select
|
|
440
|
-
class="field-select"
|
|
441
|
-
[ngModel]="selectedValueField()"
|
|
442
|
-
(ngModelChange)="onValueFieldChanged($event)"
|
|
443
|
-
>
|
|
444
|
-
<option value="">-- Select Key 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
|
-
<!-- Cascading Dropdown Dependency -->
|
|
454
|
-
<div class="field-row">
|
|
455
|
-
<label class="field-label">
|
|
456
|
-
{{ isAdvancedMode() ? 'Dependent On (Cascading Parent Field)' : 'Filter by Another Field' }}
|
|
457
|
-
</label>
|
|
458
|
-
<select
|
|
459
|
-
class="field-select"
|
|
460
|
-
[ngModel]="selectedDependsOn()"
|
|
461
|
-
(ngModelChange)="onDependsOnChanged($event)"
|
|
462
|
-
>
|
|
463
|
-
<option value="">-- None (Independent) --</option>
|
|
464
|
-
@for (other of availableParentFields(); track other.key || other.id) {
|
|
465
|
-
<option [value]="other.key || other.id">{{ other.label || other.key }}</option>
|
|
466
|
-
}
|
|
467
|
-
</select>
|
|
468
|
-
<span class="field-hint">
|
|
469
|
-
{{ isAdvancedMode() ? 'Automatically re-queries options when parent field changes.' : 'Only loads options when the selected field changes.' }}
|
|
470
|
-
</span>
|
|
471
|
-
</div>
|
|
472
|
-
}
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
<!-- 3B. STORED PROCEDURE CONFIGURATION -->
|
|
476
|
-
@if (currentSourceType() === 'procedure') {
|
|
477
|
-
<div class="field-row">
|
|
478
|
-
<div class="field-label-row">
|
|
479
|
-
<label class="field-label">
|
|
480
|
-
{{ isAdvancedMode() ? 'Stored Procedure' : 'Select Data Procedure' }}
|
|
481
|
-
</label>
|
|
482
|
-
<button
|
|
483
|
-
type="button"
|
|
484
|
-
class="btn-refresh-entities"
|
|
485
|
-
(click)="loadEntities()"
|
|
486
|
-
title="Refresh available procedures from backend"
|
|
487
|
-
>
|
|
488
|
-
<rpt-icon name="refresh" [size]="11" />
|
|
489
|
-
<span>Refresh</span>
|
|
490
|
-
</button>
|
|
491
|
-
</div>
|
|
492
|
-
<select
|
|
493
|
-
class="field-select"
|
|
494
|
-
[ngModel]="selectedEntity()"
|
|
495
|
-
(ngModelChange)="onEntitySelected($event)"
|
|
496
|
-
[disabled]="isLoadingEntities()"
|
|
497
|
-
>
|
|
498
|
-
@if (isLoadingEntities()) {
|
|
499
|
-
<option value="">Loading stored procedures from database...</option>
|
|
500
|
-
} @else if (availableProcedures().length === 0) {
|
|
501
|
-
<option value="">-- No stored procedures found (Click Refresh) --</option>
|
|
502
|
-
} @else {
|
|
503
|
-
<option value="">-- Choose Data Query / SP --</option>
|
|
504
|
-
}
|
|
505
|
-
@for (sp of availableProcedures(); track sp.name) {
|
|
506
|
-
<option [value]="sp.name">
|
|
507
|
-
@if (isAdvancedMode()) {
|
|
508
|
-
{{ sp.schema }}.{{ sp.name }}
|
|
509
|
-
} @else {
|
|
510
|
-
{{ sp.displayName }}{{ sp.category ? ' • ' + sp.category : '' }}
|
|
511
|
-
}
|
|
512
|
-
</option>
|
|
513
|
-
}
|
|
514
|
-
</select>
|
|
515
|
-
</div>
|
|
516
|
-
|
|
517
|
-
@if (selectedEntity()) {
|
|
518
|
-
<!-- Visual Parameter Linkers -->
|
|
519
|
-
@if (procedureParameters().length > 0) {
|
|
520
|
-
<div class="sp-params-group">
|
|
521
|
-
<div class="params-header-row">
|
|
522
|
-
<label class="field-label">
|
|
523
|
-
{{ isAdvancedMode() ? 'Procedure Input Parameters' : 'Filter Inputs & Parameters' }}
|
|
524
|
-
</label>
|
|
525
|
-
<button
|
|
526
|
-
type="button"
|
|
527
|
-
class="btn-auto-params"
|
|
528
|
-
(click)="autoWireAllParameters()"
|
|
529
|
-
title="Auto-detect session parameters and add missing filter controls to the canvas"
|
|
530
|
-
>
|
|
531
|
-
<rpt-icon name="check" [size]="11" />
|
|
532
|
-
<span>Auto-Wire Canvas Inputs</span>
|
|
533
|
-
</button>
|
|
534
|
-
</div>
|
|
535
|
-
|
|
536
|
-
@for (param of procedureParameters(); track param.name) {
|
|
537
|
-
<rpt-parameter-binding-editor
|
|
538
|
-
[param]="param"
|
|
539
|
-
[currentValue]="getParamValue(param.name)"
|
|
540
|
-
[allComponents]="allComponents()"
|
|
541
|
-
[currentComponentId]="comp().id"
|
|
542
|
-
[isAdvancedMode]="isAdvancedMode()"
|
|
543
|
-
(valueChange)="setParamValue(param.name, $event)"
|
|
544
|
-
(linkedFieldChange)="onParamLinkedFieldChange($event)"
|
|
545
|
-
/>
|
|
546
|
-
}
|
|
547
|
-
</div>
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
<!-- Display Field (Visible text) -->
|
|
551
|
-
<div class="field-row">
|
|
552
|
-
<div class="field-label-row">
|
|
553
|
-
<label class="field-label">
|
|
554
|
-
{{ isAdvancedMode() ? 'Display Field (from SP result)' : 'Text Shown in Dropdown' }}
|
|
555
|
-
</label>
|
|
556
|
-
@if (!isAdvancedMode()) {
|
|
557
|
-
<span class="auto-badge">Auto-detected</span>
|
|
558
|
-
}
|
|
559
|
-
</div>
|
|
560
|
-
<select
|
|
561
|
-
class="field-select"
|
|
562
|
-
[ngModel]="selectedDisplayField()"
|
|
563
|
-
(ngModelChange)="onDisplayFieldChanged($event)"
|
|
564
|
-
>
|
|
565
|
-
<option value="">-- Select Display Column --</option>
|
|
566
|
-
@for (col of entityColumns(); track col.field) {
|
|
567
|
-
<option [value]="col.field">
|
|
568
|
-
{{ col.label }} {{ isAdvancedMode() ? '(' + col.dataType + ')' : '' }}
|
|
569
|
-
</option>
|
|
570
|
-
}
|
|
571
|
-
</select>
|
|
572
|
-
</div>
|
|
573
|
-
|
|
574
|
-
<!-- Value Field (Stored key) -->
|
|
575
|
-
<div class="field-row">
|
|
576
|
-
<div class="field-label-row">
|
|
577
|
-
<label class="field-label">
|
|
578
|
-
{{ isAdvancedMode() ? 'Value Field (from SP result)' : 'Internal Value / Key' }}
|
|
579
|
-
</label>
|
|
580
|
-
@if (!isAdvancedMode()) {
|
|
581
|
-
<span class="auto-badge">Auto-detected</span>
|
|
582
|
-
}
|
|
583
|
-
</div>
|
|
584
|
-
<select
|
|
585
|
-
class="field-select"
|
|
586
|
-
[ngModel]="selectedValueField()"
|
|
587
|
-
(ngModelChange)="onValueFieldChanged($event)"
|
|
588
|
-
>
|
|
589
|
-
<option value="">-- Select Key Column --</option>
|
|
590
|
-
@for (col of entityColumns(); track col.field) {
|
|
591
|
-
<option [value]="col.field">
|
|
592
|
-
{{ col.label }} {{ isAdvancedMode() ? '(' + col.dataType + ')' : '' }}
|
|
593
|
-
</option>
|
|
594
|
-
}
|
|
595
|
-
</select>
|
|
596
|
-
</div>
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
|
|
600
|
-
<!-- 3C. STATIC OPTIONS EDITOR -->
|
|
601
|
-
@if (currentSourceType() === 'static') {
|
|
602
|
-
<div class="static-options-wrapper">
|
|
603
|
-
<div class="static-options-header">
|
|
604
|
-
<span class="field-label">Static Options</span>
|
|
605
|
-
<button type="button" class="btn-add-option" (click)="addStaticOption()">
|
|
606
|
-
<rpt-icon name="plus" [size]="11" />
|
|
607
|
-
<span>Add Option</span>
|
|
608
|
-
</button>
|
|
609
|
-
</div>
|
|
610
|
-
|
|
611
|
-
<div class="static-options-list">
|
|
612
|
-
@for (opt of staticOptions(); track $index) {
|
|
613
|
-
<div class="static-option-row">
|
|
614
|
-
<input
|
|
615
|
-
type="text"
|
|
616
|
-
class="field-input opt-key"
|
|
617
|
-
placeholder="Key"
|
|
618
|
-
[ngModel]="opt.key"
|
|
619
|
-
(ngModelChange)="updateStaticOption($index, 'key', $event)"
|
|
620
|
-
/>
|
|
621
|
-
<input
|
|
622
|
-
type="text"
|
|
623
|
-
class="field-input opt-label"
|
|
624
|
-
placeholder="Label"
|
|
625
|
-
[ngModel]="opt.label"
|
|
626
|
-
(ngModelChange)="updateStaticOption($index, 'label', $event)"
|
|
627
|
-
/>
|
|
628
|
-
<button
|
|
629
|
-
type="button"
|
|
630
|
-
class="btn-remove-option"
|
|
631
|
-
(click)="removeStaticOption($index)"
|
|
632
|
-
title="Remove option"
|
|
633
|
-
>
|
|
634
|
-
<rpt-icon name="trash" [size]="12" />
|
|
635
|
-
</button>
|
|
636
|
-
</div>
|
|
637
|
-
}
|
|
638
|
-
</div>
|
|
639
|
-
</div>
|
|
640
|
-
}
|
|
641
|
-
</div>
|
|
642
|
-
`, 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}.btn-auto-params{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;font-size:.65rem;font-weight:600;color:#2563eb;background:#eff6ff;border:1px solid #bfdbfe;border-radius:4px;cursor:pointer;transition:all .12s ease}.btn-auto-params:hover{background:#2563eb;color:#fff}.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 });
|
|
363
|
+
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: " <div class=\"property-group\">\n <!-- 1. Header with Simple / Advanced Mode Toggle -->\n <div class=\"datasource-header-bar\">\n <div class=\"group-title\">Options Data Source</div>\n <div class=\"mode-toggle-pill\">\n <button\n type=\"button\"\n class=\"pill-btn\"\n [class.active]=\"!isAdvancedMode()\"\n (click)=\"isAdvancedMode.set(false)\"\n title=\"Simplified view for business users with friendly names\"\n >\n Simple\n </button>\n <button\n type=\"button\"\n class=\"pill-btn\"\n [class.active]=\"isAdvancedMode()\"\n (click)=\"isAdvancedMode.set(true)\"\n title=\"Technical view with SQL types and expressions\"\n >\n Advanced\n </button>\n </div>\n </div>\n\n <!-- 2. Source Type Segmented Switcher -->\n <div class=\"source-type-switcher\">\n <button\n type=\"button\"\n class=\"source-tab-btn\"\n [class.active]=\"currentSourceType() === 'table'\"\n (click)=\"setSourceType('table')\"\n >\n <rpt-icon name=\"table\" [size]=\"12\" />\n <span>{{ isAdvancedMode() ? 'Table / View' : 'Database Table' }}</span>\n </button>\n <button\n type=\"button\"\n class=\"source-tab-btn\"\n [class.active]=\"currentSourceType() === 'procedure'\"\n (click)=\"setSourceType('procedure')\"\n >\n <rpt-icon name=\"code\" [size]=\"12\" />\n <span>{{ isAdvancedMode() ? 'Stored Proc' : 'Data Query' }}</span>\n </button>\n <button\n type=\"button\"\n class=\"source-tab-btn\"\n [class.active]=\"currentSourceType() === 'static'\"\n (click)=\"setSourceType('static')\"\n >\n <rpt-icon name=\"edit\" [size]=\"12\" />\n <span>Static List</span>\n </button>\n </div>\n\n <!-- 3A. DATABASE TABLE / VIEW CONFIGURATION -->\n @if (currentSourceType() === 'table') {\n <div class=\"field-row\">\n <div class=\"field-label-row\">\n <label class=\"field-label\">\n {{ isAdvancedMode() ? 'Database Table / View' : 'Select Data Source' }}\n </label>\n <button\n type=\"button\"\n class=\"btn-refresh-entities\"\n (click)=\"loadEntities()\"\n title=\"Refresh available tables from backend\"\n >\n <rpt-icon name=\"refresh\" [size]=\"11\" />\n <span>Refresh</span>\n </button>\n </div>\n <select\n class=\"field-select\"\n [ngModel]=\"selectedEntity()\"\n (ngModelChange)=\"onEntitySelected($event)\"\n [disabled]=\"isLoadingEntities()\"\n >\n @if (isLoadingEntities()) {\n <option value=\"\">Loading tables from database...</option>\n } @else if (availableTables().length === 0) {\n <option value=\"\">-- No tables found (Click Refresh) --</option>\n } @else {\n <option value=\"\">-- Choose Data Table --</option>\n }\n @for (tbl of availableTables(); track tbl.name) {\n <option [value]=\"tbl.name\">\n @if (isAdvancedMode()) {\n {{ tbl.schema }}.{{ tbl.name }} ({{ tbl.type }})\n } @else {\n {{ tbl.displayName }}{{ tbl.category ? ' \u2022 ' + tbl.category : '' }}\n }\n </option>\n }\n </select>\n </div>\n\n @if (selectedEntity()) {\n <!-- Display Field (Visible text) -->\n <div class=\"field-row\">\n <div class=\"field-label-row\">\n <label class=\"field-label\">\n {{ isAdvancedMode() ? 'Display Field (Visible Text)' : 'Text Shown in Dropdown' }}\n </label>\n @if (!isAdvancedMode()) {\n <span class=\"auto-badge\" title=\"Auto-detected column for text label\">Auto-detected</span>\n }\n </div>\n <select\n class=\"field-select\"\n [ngModel]=\"selectedDisplayField()\"\n (ngModelChange)=\"onDisplayFieldChanged($event)\"\n >\n <option value=\"\">-- Select Display Column --</option>\n @for (col of entityColumns(); track col.field) {\n <option [value]=\"col.field\">\n {{ col.label }} {{ isAdvancedMode() ? '(' + col.dataType + ')' : '' }}\n </option>\n }\n </select>\n </div>\n\n <!-- Value Field (Stored key) -->\n <div class=\"field-row\">\n <div class=\"field-label-row\">\n <label class=\"field-label\">\n {{ isAdvancedMode() ? 'Value Field (Stored Key)' : 'Internal Value / Key' }}\n </label>\n @if (!isAdvancedMode()) {\n <span class=\"auto-badge\" title=\"Auto-detected column for primary ID\">Auto-detected</span>\n }\n </div>\n <select\n class=\"field-select\"\n [ngModel]=\"selectedValueField()\"\n (ngModelChange)=\"onValueFieldChanged($event)\"\n >\n <option value=\"\">-- Select Key Column --</option>\n @for (col of entityColumns(); track col.field) {\n <option [value]=\"col.field\">\n {{ col.label }} {{ isAdvancedMode() ? '(' + col.dataType + ')' : '' }}\n </option>\n }\n </select>\n </div>\n\n <!-- Cascading Dropdown Dependency -->\n <div class=\"field-row\">\n <label class=\"field-label\">\n {{ isAdvancedMode() ? 'Dependent On (Cascading Parent Field)' : 'Filter by Another Field' }}\n </label>\n <select\n class=\"field-select\"\n [ngModel]=\"selectedDependsOn()\"\n (ngModelChange)=\"onDependsOnChanged($event)\"\n >\n <option value=\"\">-- None (Independent) --</option>\n @for (other of availableParentFields(); track other.key || other.id) {\n <option [value]=\"other.key || other.id\">{{ other.label || other.key }}</option>\n }\n </select>\n <span class=\"field-hint\">\n {{ isAdvancedMode() ? 'Automatically re-queries options when parent field changes.' : 'Only loads options when the selected field changes.' }}\n </span>\n </div>\n }\n }\n\n <!-- 3B. STORED PROCEDURE CONFIGURATION -->\n @if (currentSourceType() === 'procedure') {\n <div class=\"field-row\">\n <div class=\"field-label-row\">\n <label class=\"field-label\">\n {{ isAdvancedMode() ? 'Stored Procedure' : 'Select Data Procedure' }}\n </label>\n <button\n type=\"button\"\n class=\"btn-refresh-entities\"\n (click)=\"loadEntities()\"\n title=\"Refresh available procedures from backend\"\n >\n <rpt-icon name=\"refresh\" [size]=\"11\" />\n <span>Refresh</span>\n </button>\n </div>\n <select\n class=\"field-select\"\n [ngModel]=\"selectedEntity()\"\n (ngModelChange)=\"onEntitySelected($event)\"\n [disabled]=\"isLoadingEntities()\"\n >\n @if (isLoadingEntities()) {\n <option value=\"\">Loading stored procedures from database...</option>\n } @else if (availableProcedures().length === 0) {\n <option value=\"\">-- No stored procedures found (Click Refresh) --</option>\n } @else {\n <option value=\"\">-- Choose Data Query / SP --</option>\n }\n @for (sp of availableProcedures(); track sp.name) {\n <option [value]=\"sp.name\">\n @if (isAdvancedMode()) {\n {{ sp.schema }}.{{ sp.name }}\n } @else {\n {{ sp.displayName }}{{ sp.category ? ' \u2022 ' + sp.category : '' }}\n }\n </option>\n }\n </select>\n </div>\n\n @if (selectedEntity()) {\n <!-- Visual Parameter Linkers -->\n @if (procedureParameters().length > 0) {\n <div class=\"sp-params-group\">\n <div class=\"params-header-row\">\n <label class=\"field-label\">\n {{ isAdvancedMode() ? 'Procedure Input Parameters' : 'Filter Inputs & Parameters' }}\n </label>\n <button\n type=\"button\"\n class=\"btn-auto-params\"\n (click)=\"autoWireAllParameters()\"\n title=\"Auto-detect session parameters and add missing filter controls to the canvas\"\n >\n <rpt-icon name=\"check\" [size]=\"11\" />\n <span>Auto-Wire Canvas Inputs</span>\n </button>\n </div>\n\n @for (param of procedureParameters(); track param.name) {\n <rpt-parameter-binding-editor\n [param]=\"param\"\n [currentValue]=\"getParamValue(param.name)\"\n [allComponents]=\"allComponents()\"\n [currentComponentId]=\"comp().id\"\n [isAdvancedMode]=\"isAdvancedMode()\"\n (valueChange)=\"setParamValue(param.name, $event)\"\n (linkedFieldChange)=\"onParamLinkedFieldChange($event)\"\n />\n }\n </div>\n }\n\n <!-- Display Field (Visible text) -->\n <div class=\"field-row\">\n <div class=\"field-label-row\">\n <label class=\"field-label\">\n {{ isAdvancedMode() ? 'Display Field (from SP result)' : 'Text Shown in Dropdown' }}\n </label>\n @if (!isAdvancedMode()) {\n <span class=\"auto-badge\">Auto-detected</span>\n }\n </div>\n <select\n class=\"field-select\"\n [ngModel]=\"selectedDisplayField()\"\n (ngModelChange)=\"onDisplayFieldChanged($event)\"\n >\n <option value=\"\">-- Select Display Column --</option>\n @for (col of entityColumns(); track col.field) {\n <option [value]=\"col.field\">\n {{ col.label }} {{ isAdvancedMode() ? '(' + col.dataType + ')' : '' }}\n </option>\n }\n </select>\n </div>\n\n <!-- Value Field (Stored key) -->\n <div class=\"field-row\">\n <div class=\"field-label-row\">\n <label class=\"field-label\">\n {{ isAdvancedMode() ? 'Value Field (from SP result)' : 'Internal Value / Key' }}\n </label>\n @if (!isAdvancedMode()) {\n <span class=\"auto-badge\">Auto-detected</span>\n }\n </div>\n <select\n class=\"field-select\"\n [ngModel]=\"selectedValueField()\"\n (ngModelChange)=\"onValueFieldChanged($event)\"\n >\n <option value=\"\">-- Select Key Column --</option>\n @for (col of entityColumns(); track col.field) {\n <option [value]=\"col.field\">\n {{ col.label }} {{ isAdvancedMode() ? '(' + col.dataType + ')' : '' }}\n </option>\n }\n </select>\n </div>\n }\n }\n\n <!-- 3C. STATIC OPTIONS EDITOR -->\n @if (currentSourceType() === 'static') {\n <div class=\"static-options-wrapper\">\n <div class=\"static-options-header\">\n <span class=\"field-label\">Static Options</span>\n <button type=\"button\" class=\"btn-add-option\" (click)=\"addStaticOption()\">\n <rpt-icon name=\"plus\" [size]=\"11\" />\n <span>Add Option</span>\n </button>\n </div>\n\n <div class=\"static-options-list\">\n @for (opt of staticOptions(); track $index) {\n <div class=\"static-option-row\">\n <input\n type=\"text\"\n class=\"field-input opt-key\"\n placeholder=\"Key\"\n [ngModel]=\"opt.key\"\n (ngModelChange)=\"updateStaticOption($index, 'key', $event)\"\n />\n <input\n type=\"text\"\n class=\"field-input opt-label\"\n placeholder=\"Label\"\n [ngModel]=\"opt.label\"\n (ngModelChange)=\"updateStaticOption($index, 'label', $event)\"\n />\n <button\n type=\"button\"\n class=\"btn-remove-option\"\n (click)=\"removeStaticOption($index)\"\n title=\"Remove option\"\n >\n <rpt-icon name=\"trash\" [size]=\"12\" />\n </button>\n </div>\n }\n </div>\n </div>\n }\n </div>", 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}.btn-auto-params{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;font-size:.65rem;font-weight:600;color:#2563eb;background:#eff6ff;border:1px solid #bfdbfe;border-radius:4px;cursor:pointer;transition:all .12s ease}.btn-auto-params:hover{background:#2563eb;color:#fff}.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 });
|
|
643
364
|
}
|
|
644
365
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: PropertyEditorDatasourceComponent, decorators: [{
|
|
645
366
|
type: Component,
|
|
646
|
-
args: [{ selector: 'rpt-property-editor-datasource', standalone: true, imports: [CommonModule, FormsModule, RptIconComponent, ParameterBindingEditorComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: `
|
|
647
|
-
<div class="property-group">
|
|
648
|
-
<!-- 1. Header with Simple / Advanced Mode Toggle -->
|
|
649
|
-
<div class="datasource-header-bar">
|
|
650
|
-
<div class="group-title">Options Data Source</div>
|
|
651
|
-
<div class="mode-toggle-pill">
|
|
652
|
-
<button
|
|
653
|
-
type="button"
|
|
654
|
-
class="pill-btn"
|
|
655
|
-
[class.active]="!isAdvancedMode()"
|
|
656
|
-
(click)="isAdvancedMode.set(false)"
|
|
657
|
-
title="Simplified view for business users with friendly names"
|
|
658
|
-
>
|
|
659
|
-
Simple
|
|
660
|
-
</button>
|
|
661
|
-
<button
|
|
662
|
-
type="button"
|
|
663
|
-
class="pill-btn"
|
|
664
|
-
[class.active]="isAdvancedMode()"
|
|
665
|
-
(click)="isAdvancedMode.set(true)"
|
|
666
|
-
title="Technical view with SQL types and expressions"
|
|
667
|
-
>
|
|
668
|
-
Advanced
|
|
669
|
-
</button>
|
|
670
|
-
</div>
|
|
671
|
-
</div>
|
|
672
|
-
|
|
673
|
-
<!-- 2. Source Type Segmented Switcher -->
|
|
674
|
-
<div class="source-type-switcher">
|
|
675
|
-
<button
|
|
676
|
-
type="button"
|
|
677
|
-
class="source-tab-btn"
|
|
678
|
-
[class.active]="currentSourceType() === 'table'"
|
|
679
|
-
(click)="setSourceType('table')"
|
|
680
|
-
>
|
|
681
|
-
<rpt-icon name="table" [size]="12" />
|
|
682
|
-
<span>{{ isAdvancedMode() ? 'Table / View' : 'Database Table' }}</span>
|
|
683
|
-
</button>
|
|
684
|
-
<button
|
|
685
|
-
type="button"
|
|
686
|
-
class="source-tab-btn"
|
|
687
|
-
[class.active]="currentSourceType() === 'procedure'"
|
|
688
|
-
(click)="setSourceType('procedure')"
|
|
689
|
-
>
|
|
690
|
-
<rpt-icon name="code" [size]="12" />
|
|
691
|
-
<span>{{ isAdvancedMode() ? 'Stored Proc' : 'Data Query' }}</span>
|
|
692
|
-
</button>
|
|
693
|
-
<button
|
|
694
|
-
type="button"
|
|
695
|
-
class="source-tab-btn"
|
|
696
|
-
[class.active]="currentSourceType() === 'static'"
|
|
697
|
-
(click)="setSourceType('static')"
|
|
698
|
-
>
|
|
699
|
-
<rpt-icon name="edit" [size]="12" />
|
|
700
|
-
<span>Static List</span>
|
|
701
|
-
</button>
|
|
702
|
-
</div>
|
|
703
|
-
|
|
704
|
-
<!-- 3A. DATABASE TABLE / VIEW CONFIGURATION -->
|
|
705
|
-
@if (currentSourceType() === 'table') {
|
|
706
|
-
<div class="field-row">
|
|
707
|
-
<div class="field-label-row">
|
|
708
|
-
<label class="field-label">
|
|
709
|
-
{{ isAdvancedMode() ? 'Database Table / View' : 'Select Data Source' }}
|
|
710
|
-
</label>
|
|
711
|
-
<button
|
|
712
|
-
type="button"
|
|
713
|
-
class="btn-refresh-entities"
|
|
714
|
-
(click)="loadEntities()"
|
|
715
|
-
title="Refresh available tables from backend"
|
|
716
|
-
>
|
|
717
|
-
<rpt-icon name="refresh" [size]="11" />
|
|
718
|
-
<span>Refresh</span>
|
|
719
|
-
</button>
|
|
720
|
-
</div>
|
|
721
|
-
<select
|
|
722
|
-
class="field-select"
|
|
723
|
-
[ngModel]="selectedEntity()"
|
|
724
|
-
(ngModelChange)="onEntitySelected($event)"
|
|
725
|
-
[disabled]="isLoadingEntities()"
|
|
726
|
-
>
|
|
727
|
-
@if (isLoadingEntities()) {
|
|
728
|
-
<option value="">Loading tables from database...</option>
|
|
729
|
-
} @else if (availableTables().length === 0) {
|
|
730
|
-
<option value="">-- No tables found (Click Refresh) --</option>
|
|
731
|
-
} @else {
|
|
732
|
-
<option value="">-- Choose Data Table --</option>
|
|
733
|
-
}
|
|
734
|
-
@for (tbl of availableTables(); track tbl.name) {
|
|
735
|
-
<option [value]="tbl.name">
|
|
736
|
-
@if (isAdvancedMode()) {
|
|
737
|
-
{{ tbl.schema }}.{{ tbl.name }} ({{ tbl.type }})
|
|
738
|
-
} @else {
|
|
739
|
-
{{ tbl.displayName }}{{ tbl.category ? ' • ' + tbl.category : '' }}
|
|
740
|
-
}
|
|
741
|
-
</option>
|
|
742
|
-
}
|
|
743
|
-
</select>
|
|
744
|
-
</div>
|
|
745
|
-
|
|
746
|
-
@if (selectedEntity()) {
|
|
747
|
-
<!-- Display Field (Visible text) -->
|
|
748
|
-
<div class="field-row">
|
|
749
|
-
<div class="field-label-row">
|
|
750
|
-
<label class="field-label">
|
|
751
|
-
{{ isAdvancedMode() ? 'Display Field (Visible Text)' : 'Text Shown in Dropdown' }}
|
|
752
|
-
</label>
|
|
753
|
-
@if (!isAdvancedMode()) {
|
|
754
|
-
<span class="auto-badge" title="Auto-detected column for text label">Auto-detected</span>
|
|
755
|
-
}
|
|
756
|
-
</div>
|
|
757
|
-
<select
|
|
758
|
-
class="field-select"
|
|
759
|
-
[ngModel]="selectedDisplayField()"
|
|
760
|
-
(ngModelChange)="onDisplayFieldChanged($event)"
|
|
761
|
-
>
|
|
762
|
-
<option value="">-- Select Display Column --</option>
|
|
763
|
-
@for (col of entityColumns(); track col.field) {
|
|
764
|
-
<option [value]="col.field">
|
|
765
|
-
{{ col.label }} {{ isAdvancedMode() ? '(' + col.dataType + ')' : '' }}
|
|
766
|
-
</option>
|
|
767
|
-
}
|
|
768
|
-
</select>
|
|
769
|
-
</div>
|
|
770
|
-
|
|
771
|
-
<!-- Value Field (Stored key) -->
|
|
772
|
-
<div class="field-row">
|
|
773
|
-
<div class="field-label-row">
|
|
774
|
-
<label class="field-label">
|
|
775
|
-
{{ isAdvancedMode() ? 'Value Field (Stored Key)' : 'Internal Value / Key' }}
|
|
776
|
-
</label>
|
|
777
|
-
@if (!isAdvancedMode()) {
|
|
778
|
-
<span class="auto-badge" title="Auto-detected column for primary ID">Auto-detected</span>
|
|
779
|
-
}
|
|
780
|
-
</div>
|
|
781
|
-
<select
|
|
782
|
-
class="field-select"
|
|
783
|
-
[ngModel]="selectedValueField()"
|
|
784
|
-
(ngModelChange)="onValueFieldChanged($event)"
|
|
785
|
-
>
|
|
786
|
-
<option value="">-- Select Key Column --</option>
|
|
787
|
-
@for (col of entityColumns(); track col.field) {
|
|
788
|
-
<option [value]="col.field">
|
|
789
|
-
{{ col.label }} {{ isAdvancedMode() ? '(' + col.dataType + ')' : '' }}
|
|
790
|
-
</option>
|
|
791
|
-
}
|
|
792
|
-
</select>
|
|
793
|
-
</div>
|
|
794
|
-
|
|
795
|
-
<!-- Cascading Dropdown Dependency -->
|
|
796
|
-
<div class="field-row">
|
|
797
|
-
<label class="field-label">
|
|
798
|
-
{{ isAdvancedMode() ? 'Dependent On (Cascading Parent Field)' : 'Filter by Another Field' }}
|
|
799
|
-
</label>
|
|
800
|
-
<select
|
|
801
|
-
class="field-select"
|
|
802
|
-
[ngModel]="selectedDependsOn()"
|
|
803
|
-
(ngModelChange)="onDependsOnChanged($event)"
|
|
804
|
-
>
|
|
805
|
-
<option value="">-- None (Independent) --</option>
|
|
806
|
-
@for (other of availableParentFields(); track other.key || other.id) {
|
|
807
|
-
<option [value]="other.key || other.id">{{ other.label || other.key }}</option>
|
|
808
|
-
}
|
|
809
|
-
</select>
|
|
810
|
-
<span class="field-hint">
|
|
811
|
-
{{ isAdvancedMode() ? 'Automatically re-queries options when parent field changes.' : 'Only loads options when the selected field changes.' }}
|
|
812
|
-
</span>
|
|
813
|
-
</div>
|
|
814
|
-
}
|
|
815
|
-
}
|
|
816
|
-
|
|
817
|
-
<!-- 3B. STORED PROCEDURE CONFIGURATION -->
|
|
818
|
-
@if (currentSourceType() === 'procedure') {
|
|
819
|
-
<div class="field-row">
|
|
820
|
-
<div class="field-label-row">
|
|
821
|
-
<label class="field-label">
|
|
822
|
-
{{ isAdvancedMode() ? 'Stored Procedure' : 'Select Data Procedure' }}
|
|
823
|
-
</label>
|
|
824
|
-
<button
|
|
825
|
-
type="button"
|
|
826
|
-
class="btn-refresh-entities"
|
|
827
|
-
(click)="loadEntities()"
|
|
828
|
-
title="Refresh available procedures from backend"
|
|
829
|
-
>
|
|
830
|
-
<rpt-icon name="refresh" [size]="11" />
|
|
831
|
-
<span>Refresh</span>
|
|
832
|
-
</button>
|
|
833
|
-
</div>
|
|
834
|
-
<select
|
|
835
|
-
class="field-select"
|
|
836
|
-
[ngModel]="selectedEntity()"
|
|
837
|
-
(ngModelChange)="onEntitySelected($event)"
|
|
838
|
-
[disabled]="isLoadingEntities()"
|
|
839
|
-
>
|
|
840
|
-
@if (isLoadingEntities()) {
|
|
841
|
-
<option value="">Loading stored procedures from database...</option>
|
|
842
|
-
} @else if (availableProcedures().length === 0) {
|
|
843
|
-
<option value="">-- No stored procedures found (Click Refresh) --</option>
|
|
844
|
-
} @else {
|
|
845
|
-
<option value="">-- Choose Data Query / SP --</option>
|
|
846
|
-
}
|
|
847
|
-
@for (sp of availableProcedures(); track sp.name) {
|
|
848
|
-
<option [value]="sp.name">
|
|
849
|
-
@if (isAdvancedMode()) {
|
|
850
|
-
{{ sp.schema }}.{{ sp.name }}
|
|
851
|
-
} @else {
|
|
852
|
-
{{ sp.displayName }}{{ sp.category ? ' • ' + sp.category : '' }}
|
|
853
|
-
}
|
|
854
|
-
</option>
|
|
855
|
-
}
|
|
856
|
-
</select>
|
|
857
|
-
</div>
|
|
858
|
-
|
|
859
|
-
@if (selectedEntity()) {
|
|
860
|
-
<!-- Visual Parameter Linkers -->
|
|
861
|
-
@if (procedureParameters().length > 0) {
|
|
862
|
-
<div class="sp-params-group">
|
|
863
|
-
<div class="params-header-row">
|
|
864
|
-
<label class="field-label">
|
|
865
|
-
{{ isAdvancedMode() ? 'Procedure Input Parameters' : 'Filter Inputs & Parameters' }}
|
|
866
|
-
</label>
|
|
867
|
-
<button
|
|
868
|
-
type="button"
|
|
869
|
-
class="btn-auto-params"
|
|
870
|
-
(click)="autoWireAllParameters()"
|
|
871
|
-
title="Auto-detect session parameters and add missing filter controls to the canvas"
|
|
872
|
-
>
|
|
873
|
-
<rpt-icon name="check" [size]="11" />
|
|
874
|
-
<span>Auto-Wire Canvas Inputs</span>
|
|
875
|
-
</button>
|
|
876
|
-
</div>
|
|
877
|
-
|
|
878
|
-
@for (param of procedureParameters(); track param.name) {
|
|
879
|
-
<rpt-parameter-binding-editor
|
|
880
|
-
[param]="param"
|
|
881
|
-
[currentValue]="getParamValue(param.name)"
|
|
882
|
-
[allComponents]="allComponents()"
|
|
883
|
-
[currentComponentId]="comp().id"
|
|
884
|
-
[isAdvancedMode]="isAdvancedMode()"
|
|
885
|
-
(valueChange)="setParamValue(param.name, $event)"
|
|
886
|
-
(linkedFieldChange)="onParamLinkedFieldChange($event)"
|
|
887
|
-
/>
|
|
888
|
-
}
|
|
889
|
-
</div>
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
<!-- Display Field (Visible text) -->
|
|
893
|
-
<div class="field-row">
|
|
894
|
-
<div class="field-label-row">
|
|
895
|
-
<label class="field-label">
|
|
896
|
-
{{ isAdvancedMode() ? 'Display Field (from SP result)' : 'Text Shown in Dropdown' }}
|
|
897
|
-
</label>
|
|
898
|
-
@if (!isAdvancedMode()) {
|
|
899
|
-
<span class="auto-badge">Auto-detected</span>
|
|
900
|
-
}
|
|
901
|
-
</div>
|
|
902
|
-
<select
|
|
903
|
-
class="field-select"
|
|
904
|
-
[ngModel]="selectedDisplayField()"
|
|
905
|
-
(ngModelChange)="onDisplayFieldChanged($event)"
|
|
906
|
-
>
|
|
907
|
-
<option value="">-- Select Display Column --</option>
|
|
908
|
-
@for (col of entityColumns(); track col.field) {
|
|
909
|
-
<option [value]="col.field">
|
|
910
|
-
{{ col.label }} {{ isAdvancedMode() ? '(' + col.dataType + ')' : '' }}
|
|
911
|
-
</option>
|
|
912
|
-
}
|
|
913
|
-
</select>
|
|
914
|
-
</div>
|
|
915
|
-
|
|
916
|
-
<!-- Value Field (Stored key) -->
|
|
917
|
-
<div class="field-row">
|
|
918
|
-
<div class="field-label-row">
|
|
919
|
-
<label class="field-label">
|
|
920
|
-
{{ isAdvancedMode() ? 'Value Field (from SP result)' : 'Internal Value / Key' }}
|
|
921
|
-
</label>
|
|
922
|
-
@if (!isAdvancedMode()) {
|
|
923
|
-
<span class="auto-badge">Auto-detected</span>
|
|
924
|
-
}
|
|
925
|
-
</div>
|
|
926
|
-
<select
|
|
927
|
-
class="field-select"
|
|
928
|
-
[ngModel]="selectedValueField()"
|
|
929
|
-
(ngModelChange)="onValueFieldChanged($event)"
|
|
930
|
-
>
|
|
931
|
-
<option value="">-- Select Key Column --</option>
|
|
932
|
-
@for (col of entityColumns(); track col.field) {
|
|
933
|
-
<option [value]="col.field">
|
|
934
|
-
{{ col.label }} {{ isAdvancedMode() ? '(' + col.dataType + ')' : '' }}
|
|
935
|
-
</option>
|
|
936
|
-
}
|
|
937
|
-
</select>
|
|
938
|
-
</div>
|
|
939
|
-
}
|
|
940
|
-
}
|
|
941
|
-
|
|
942
|
-
<!-- 3C. STATIC OPTIONS EDITOR -->
|
|
943
|
-
@if (currentSourceType() === 'static') {
|
|
944
|
-
<div class="static-options-wrapper">
|
|
945
|
-
<div class="static-options-header">
|
|
946
|
-
<span class="field-label">Static Options</span>
|
|
947
|
-
<button type="button" class="btn-add-option" (click)="addStaticOption()">
|
|
948
|
-
<rpt-icon name="plus" [size]="11" />
|
|
949
|
-
<span>Add Option</span>
|
|
950
|
-
</button>
|
|
951
|
-
</div>
|
|
952
|
-
|
|
953
|
-
<div class="static-options-list">
|
|
954
|
-
@for (opt of staticOptions(); track $index) {
|
|
955
|
-
<div class="static-option-row">
|
|
956
|
-
<input
|
|
957
|
-
type="text"
|
|
958
|
-
class="field-input opt-key"
|
|
959
|
-
placeholder="Key"
|
|
960
|
-
[ngModel]="opt.key"
|
|
961
|
-
(ngModelChange)="updateStaticOption($index, 'key', $event)"
|
|
962
|
-
/>
|
|
963
|
-
<input
|
|
964
|
-
type="text"
|
|
965
|
-
class="field-input opt-label"
|
|
966
|
-
placeholder="Label"
|
|
967
|
-
[ngModel]="opt.label"
|
|
968
|
-
(ngModelChange)="updateStaticOption($index, 'label', $event)"
|
|
969
|
-
/>
|
|
970
|
-
<button
|
|
971
|
-
type="button"
|
|
972
|
-
class="btn-remove-option"
|
|
973
|
-
(click)="removeStaticOption($index)"
|
|
974
|
-
title="Remove option"
|
|
975
|
-
>
|
|
976
|
-
<rpt-icon name="trash" [size]="12" />
|
|
977
|
-
</button>
|
|
978
|
-
</div>
|
|
979
|
-
}
|
|
980
|
-
</div>
|
|
981
|
-
</div>
|
|
982
|
-
}
|
|
983
|
-
</div>
|
|
984
|
-
`, 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}.btn-auto-params{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;font-size:.65rem;font-weight:600;color:#2563eb;background:#eff6ff;border:1px solid #bfdbfe;border-radius:4px;cursor:pointer;transition:all .12s ease}.btn-auto-params:hover{background:#2563eb;color:#fff}.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"] }]
|
|
367
|
+
args: [{ selector: 'rpt-property-editor-datasource', standalone: true, imports: [CommonModule, FormsModule, RptIconComponent, ParameterBindingEditorComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: " <div class=\"property-group\">\n <!-- 1. Header with Simple / Advanced Mode Toggle -->\n <div class=\"datasource-header-bar\">\n <div class=\"group-title\">Options Data Source</div>\n <div class=\"mode-toggle-pill\">\n <button\n type=\"button\"\n class=\"pill-btn\"\n [class.active]=\"!isAdvancedMode()\"\n (click)=\"isAdvancedMode.set(false)\"\n title=\"Simplified view for business users with friendly names\"\n >\n Simple\n </button>\n <button\n type=\"button\"\n class=\"pill-btn\"\n [class.active]=\"isAdvancedMode()\"\n (click)=\"isAdvancedMode.set(true)\"\n title=\"Technical view with SQL types and expressions\"\n >\n Advanced\n </button>\n </div>\n </div>\n\n <!-- 2. Source Type Segmented Switcher -->\n <div class=\"source-type-switcher\">\n <button\n type=\"button\"\n class=\"source-tab-btn\"\n [class.active]=\"currentSourceType() === 'table'\"\n (click)=\"setSourceType('table')\"\n >\n <rpt-icon name=\"table\" [size]=\"12\" />\n <span>{{ isAdvancedMode() ? 'Table / View' : 'Database Table' }}</span>\n </button>\n <button\n type=\"button\"\n class=\"source-tab-btn\"\n [class.active]=\"currentSourceType() === 'procedure'\"\n (click)=\"setSourceType('procedure')\"\n >\n <rpt-icon name=\"code\" [size]=\"12\" />\n <span>{{ isAdvancedMode() ? 'Stored Proc' : 'Data Query' }}</span>\n </button>\n <button\n type=\"button\"\n class=\"source-tab-btn\"\n [class.active]=\"currentSourceType() === 'static'\"\n (click)=\"setSourceType('static')\"\n >\n <rpt-icon name=\"edit\" [size]=\"12\" />\n <span>Static List</span>\n </button>\n </div>\n\n <!-- 3A. DATABASE TABLE / VIEW CONFIGURATION -->\n @if (currentSourceType() === 'table') {\n <div class=\"field-row\">\n <div class=\"field-label-row\">\n <label class=\"field-label\">\n {{ isAdvancedMode() ? 'Database Table / View' : 'Select Data Source' }}\n </label>\n <button\n type=\"button\"\n class=\"btn-refresh-entities\"\n (click)=\"loadEntities()\"\n title=\"Refresh available tables from backend\"\n >\n <rpt-icon name=\"refresh\" [size]=\"11\" />\n <span>Refresh</span>\n </button>\n </div>\n <select\n class=\"field-select\"\n [ngModel]=\"selectedEntity()\"\n (ngModelChange)=\"onEntitySelected($event)\"\n [disabled]=\"isLoadingEntities()\"\n >\n @if (isLoadingEntities()) {\n <option value=\"\">Loading tables from database...</option>\n } @else if (availableTables().length === 0) {\n <option value=\"\">-- No tables found (Click Refresh) --</option>\n } @else {\n <option value=\"\">-- Choose Data Table --</option>\n }\n @for (tbl of availableTables(); track tbl.name) {\n <option [value]=\"tbl.name\">\n @if (isAdvancedMode()) {\n {{ tbl.schema }}.{{ tbl.name }} ({{ tbl.type }})\n } @else {\n {{ tbl.displayName }}{{ tbl.category ? ' \u2022 ' + tbl.category : '' }}\n }\n </option>\n }\n </select>\n </div>\n\n @if (selectedEntity()) {\n <!-- Display Field (Visible text) -->\n <div class=\"field-row\">\n <div class=\"field-label-row\">\n <label class=\"field-label\">\n {{ isAdvancedMode() ? 'Display Field (Visible Text)' : 'Text Shown in Dropdown' }}\n </label>\n @if (!isAdvancedMode()) {\n <span class=\"auto-badge\" title=\"Auto-detected column for text label\">Auto-detected</span>\n }\n </div>\n <select\n class=\"field-select\"\n [ngModel]=\"selectedDisplayField()\"\n (ngModelChange)=\"onDisplayFieldChanged($event)\"\n >\n <option value=\"\">-- Select Display Column --</option>\n @for (col of entityColumns(); track col.field) {\n <option [value]=\"col.field\">\n {{ col.label }} {{ isAdvancedMode() ? '(' + col.dataType + ')' : '' }}\n </option>\n }\n </select>\n </div>\n\n <!-- Value Field (Stored key) -->\n <div class=\"field-row\">\n <div class=\"field-label-row\">\n <label class=\"field-label\">\n {{ isAdvancedMode() ? 'Value Field (Stored Key)' : 'Internal Value / Key' }}\n </label>\n @if (!isAdvancedMode()) {\n <span class=\"auto-badge\" title=\"Auto-detected column for primary ID\">Auto-detected</span>\n }\n </div>\n <select\n class=\"field-select\"\n [ngModel]=\"selectedValueField()\"\n (ngModelChange)=\"onValueFieldChanged($event)\"\n >\n <option value=\"\">-- Select Key Column --</option>\n @for (col of entityColumns(); track col.field) {\n <option [value]=\"col.field\">\n {{ col.label }} {{ isAdvancedMode() ? '(' + col.dataType + ')' : '' }}\n </option>\n }\n </select>\n </div>\n\n <!-- Cascading Dropdown Dependency -->\n <div class=\"field-row\">\n <label class=\"field-label\">\n {{ isAdvancedMode() ? 'Dependent On (Cascading Parent Field)' : 'Filter by Another Field' }}\n </label>\n <select\n class=\"field-select\"\n [ngModel]=\"selectedDependsOn()\"\n (ngModelChange)=\"onDependsOnChanged($event)\"\n >\n <option value=\"\">-- None (Independent) --</option>\n @for (other of availableParentFields(); track other.key || other.id) {\n <option [value]=\"other.key || other.id\">{{ other.label || other.key }}</option>\n }\n </select>\n <span class=\"field-hint\">\n {{ isAdvancedMode() ? 'Automatically re-queries options when parent field changes.' : 'Only loads options when the selected field changes.' }}\n </span>\n </div>\n }\n }\n\n <!-- 3B. STORED PROCEDURE CONFIGURATION -->\n @if (currentSourceType() === 'procedure') {\n <div class=\"field-row\">\n <div class=\"field-label-row\">\n <label class=\"field-label\">\n {{ isAdvancedMode() ? 'Stored Procedure' : 'Select Data Procedure' }}\n </label>\n <button\n type=\"button\"\n class=\"btn-refresh-entities\"\n (click)=\"loadEntities()\"\n title=\"Refresh available procedures from backend\"\n >\n <rpt-icon name=\"refresh\" [size]=\"11\" />\n <span>Refresh</span>\n </button>\n </div>\n <select\n class=\"field-select\"\n [ngModel]=\"selectedEntity()\"\n (ngModelChange)=\"onEntitySelected($event)\"\n [disabled]=\"isLoadingEntities()\"\n >\n @if (isLoadingEntities()) {\n <option value=\"\">Loading stored procedures from database...</option>\n } @else if (availableProcedures().length === 0) {\n <option value=\"\">-- No stored procedures found (Click Refresh) --</option>\n } @else {\n <option value=\"\">-- Choose Data Query / SP --</option>\n }\n @for (sp of availableProcedures(); track sp.name) {\n <option [value]=\"sp.name\">\n @if (isAdvancedMode()) {\n {{ sp.schema }}.{{ sp.name }}\n } @else {\n {{ sp.displayName }}{{ sp.category ? ' \u2022 ' + sp.category : '' }}\n }\n </option>\n }\n </select>\n </div>\n\n @if (selectedEntity()) {\n <!-- Visual Parameter Linkers -->\n @if (procedureParameters().length > 0) {\n <div class=\"sp-params-group\">\n <div class=\"params-header-row\">\n <label class=\"field-label\">\n {{ isAdvancedMode() ? 'Procedure Input Parameters' : 'Filter Inputs & Parameters' }}\n </label>\n <button\n type=\"button\"\n class=\"btn-auto-params\"\n (click)=\"autoWireAllParameters()\"\n title=\"Auto-detect session parameters and add missing filter controls to the canvas\"\n >\n <rpt-icon name=\"check\" [size]=\"11\" />\n <span>Auto-Wire Canvas Inputs</span>\n </button>\n </div>\n\n @for (param of procedureParameters(); track param.name) {\n <rpt-parameter-binding-editor\n [param]=\"param\"\n [currentValue]=\"getParamValue(param.name)\"\n [allComponents]=\"allComponents()\"\n [currentComponentId]=\"comp().id\"\n [isAdvancedMode]=\"isAdvancedMode()\"\n (valueChange)=\"setParamValue(param.name, $event)\"\n (linkedFieldChange)=\"onParamLinkedFieldChange($event)\"\n />\n }\n </div>\n }\n\n <!-- Display Field (Visible text) -->\n <div class=\"field-row\">\n <div class=\"field-label-row\">\n <label class=\"field-label\">\n {{ isAdvancedMode() ? 'Display Field (from SP result)' : 'Text Shown in Dropdown' }}\n </label>\n @if (!isAdvancedMode()) {\n <span class=\"auto-badge\">Auto-detected</span>\n }\n </div>\n <select\n class=\"field-select\"\n [ngModel]=\"selectedDisplayField()\"\n (ngModelChange)=\"onDisplayFieldChanged($event)\"\n >\n <option value=\"\">-- Select Display Column --</option>\n @for (col of entityColumns(); track col.field) {\n <option [value]=\"col.field\">\n {{ col.label }} {{ isAdvancedMode() ? '(' + col.dataType + ')' : '' }}\n </option>\n }\n </select>\n </div>\n\n <!-- Value Field (Stored key) -->\n <div class=\"field-row\">\n <div class=\"field-label-row\">\n <label class=\"field-label\">\n {{ isAdvancedMode() ? 'Value Field (from SP result)' : 'Internal Value / Key' }}\n </label>\n @if (!isAdvancedMode()) {\n <span class=\"auto-badge\">Auto-detected</span>\n }\n </div>\n <select\n class=\"field-select\"\n [ngModel]=\"selectedValueField()\"\n (ngModelChange)=\"onValueFieldChanged($event)\"\n >\n <option value=\"\">-- Select Key Column --</option>\n @for (col of entityColumns(); track col.field) {\n <option [value]=\"col.field\">\n {{ col.label }} {{ isAdvancedMode() ? '(' + col.dataType + ')' : '' }}\n </option>\n }\n </select>\n </div>\n }\n }\n\n <!-- 3C. STATIC OPTIONS EDITOR -->\n @if (currentSourceType() === 'static') {\n <div class=\"static-options-wrapper\">\n <div class=\"static-options-header\">\n <span class=\"field-label\">Static Options</span>\n <button type=\"button\" class=\"btn-add-option\" (click)=\"addStaticOption()\">\n <rpt-icon name=\"plus\" [size]=\"11\" />\n <span>Add Option</span>\n </button>\n </div>\n\n <div class=\"static-options-list\">\n @for (opt of staticOptions(); track $index) {\n <div class=\"static-option-row\">\n <input\n type=\"text\"\n class=\"field-input opt-key\"\n placeholder=\"Key\"\n [ngModel]=\"opt.key\"\n (ngModelChange)=\"updateStaticOption($index, 'key', $event)\"\n />\n <input\n type=\"text\"\n class=\"field-input opt-label\"\n placeholder=\"Label\"\n [ngModel]=\"opt.label\"\n (ngModelChange)=\"updateStaticOption($index, 'label', $event)\"\n />\n <button\n type=\"button\"\n class=\"btn-remove-option\"\n (click)=\"removeStaticOption($index)\"\n title=\"Remove option\"\n >\n <rpt-icon name=\"trash\" [size]=\"12\" />\n </button>\n </div>\n }\n </div>\n </div>\n }\n </div>", 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}.btn-auto-params{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;font-size:.65rem;font-weight:600;color:#2563eb;background:#eff6ff;border:1px solid #bfdbfe;border-radius:4px;cursor:pointer;transition:all .12s ease}.btn-auto-params:hover{background:#2563eb;color:#fff}.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"] }]
|
|
985
368
|
}], ctorParameters: () => [] });
|
|
986
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvcGVydHktZWRpdG9yLWRhdGFzb3VyY2UuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYndheXMtcmVwb3J0L3NyYy9saWIvZmVhdHVyZXMvZGVzaWduZXIvY29tcG9uZW50cy9wcm9wZXJ0eS1lZGl0b3IvcHJvcGVydHktZWRpdG9yLWRhdGFzb3VyY2UuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDTCx1QkFBdUIsRUFDdkIsU0FBUyxFQUNULFFBQVEsRUFDUixNQUFNLEVBQ04sTUFBTSxFQUNOLEtBQUssRUFFTCxNQUFNLEVBQ04sTUFBTSxHQUNQLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMvQyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFNN0MsT0FBTyxFQUlMLDRCQUE0QixHQUM3QixNQUFNLDZEQUE2RCxDQUFDO0FBQ3JFLE9BQU8sRUFDTCx5QkFBeUIsRUFDekIsdUJBQXVCLEVBQ3ZCLGtCQUFrQixHQUNuQixNQUFNLDZDQUE2QyxDQUFDO0FBQ3JELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSw4Q0FBOEMsQ0FBQztBQUMxRSxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSwwREFBMEQsQ0FBQztBQUN2RyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUM3RSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSwyREFBMkQsQ0FBQztBQUM3RixPQUFPLEVBQUUsK0JBQStCLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQzs7O0FBcWlCdkYsTUFBTSxPQUFPLGlDQUFpQztJQUMzQixnQkFBZ0IsR0FBRyxNQUFNLENBQUMsNEJBQTRCLEVBQUUsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUM1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Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWtWVCIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDb21wb25lbnQsXG4gIGNvbXB1dGVkLFxuICBlZmZlY3QsXG4gIGluamVjdCxcbiAgaW5wdXQsXG4gIE9uSW5pdCxcbiAgb3V0cHV0LFxuICBzaWduYWwsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHtcbiAgQ29tcG9uZW50RGF0YVNvdXJjZURlZmluaXRpb24sXG4gIERyb3Bkb3duU291cmNlVHlwZSxcbiAgUmVwb3J0Q29tcG9uZW50RGVmaW5pdGlvbixcbn0gZnJvbSAnLi4vLi4vLi4vLi4vY29yZS9tb2RlbHMvcmVwb3J0LWNvbXBvbmVudC5tb2RlbCc7XG5pbXBvcnQge1xuICBEYXRhYmFzZUVudGl0eU1ldGFkYXRhLFxuICBFbnRpdHlDb2x1bW5NZXRhZGF0YSxcbiAgUHJvY2VkdXJlUGFyYW1ldGVyTWV0YWRhdGEsXG4gIFJlcG9ydFNjaGVtYURpc2NvdmVyeUFkYXB0ZXIsXG59IGZyb20gJy4uLy4uLy4uLy4uL2RhdGEtYWNjZXNzL2NvbnRyYWN0cy9zY2hlbWEtZGlzY292ZXJ5LmNvbnRyYWN0JztcbmltcG9ydCB7XG4gIGRldGVjdERlZmF1bHREaXNwbGF5RmllbGQsXG4gIGRldGVjdERlZmF1bHRWYWx1ZUZpZWxkLFxuICBodW1hbml6ZUlkZW50aWZpZXIsXG59IGZyb20gJy4uLy4uLy4uLy4uL2NvcmUvdXRpbHMvaWRlbnRpZmllci1odW1hbml6ZXInO1xuaW1wb3J0IHsgdG9GaWVsZEtleSB9IGZyb20gJy4uLy4uLy4uLy4uL2NvcmUvdXRpbHMvcmVwb3J0LXBhcmFtZXRlci51dGlsJztcbmltcG9ydCB7IFJlcG9ydFNlc3Npb25Db250ZXh0U2VydmljZSB9IGZyb20gJy4uLy4uLy4uLy4uL2NvcmUvc2VydmljZXMvcmVwb3J0LXNlc3Npb24tY29udGV4dC5zZXJ2aWNlJztcbmltcG9ydCB7IERlc2lnbmVyU3RhdGVTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvZGVzaWduZXItc3RhdGUuc2VydmljZSc7XG5pbXBvcnQgeyBScHRJY29uQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vLi4vLi4vcHJpbWl0aXZlcy9jb21wb25lbnRzL2ljb24vcnB0LWljb24uY29tcG9uZW50JztcbmltcG9ydCB7IFBhcmFtZXRlckJpbmRpbmdFZGl0b3JDb21wb25lbnQgfSBmcm9tICcuL3BhcmFtZXRlci1iaW5kaW5nLWVkaXRvci5jb21wb25lbnQnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFN0YXRpY09wdGlvbkl0ZW0ge1xuICBrZXk6IHN0cmluZztcbiAgbGFiZWw6IHN0cmluZztcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAncnB0LXByb3BlcnR5LWVkaXRvci1kYXRhc291cmNlJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW0NvbW1vbk1vZHVsZSwgRm9ybXNNb2R1bGUsIFJwdEljb25Db21wb25lbnQsIFBhcmFtZXRlckJpbmRpbmdFZGl0b3JDb21wb25lbnRdLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgc3R5bGVVcmxzOiBbJy4vcHJvcGVydHktZWRpdG9yLmNvbW1vbi5jc3MnXSxcbiAgdGVtcGxhdGU6IGBcbiAgICA8ZGl2IGNsYXNzPVwicHJvcGVydHktZ3JvdXBcIj5cbiAgICAgIDwhLS0gMS4gSGVhZGVyIHdpdGggU2ltcGxlIC8gQWR2YW5jZWQgTW9kZSBUb2dnbGUgLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwiZGF0YXNvdXJjZS1oZWFkZXItYmFyXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJncm91cC10aXRsZVwiPk9wdGlvbnMgRGF0YSBTb3VyY2U8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGUtdG9nZ2xlLXBpbGxcIj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGNsYXNzPVwicGlsbC1idG5cIlxuICAgICAgICAgICAgW2NsYXNzLmFjdGl2ZV09XCIhaXNBZHZhbmNlZE1vZGUoKVwiXG4gICAgICAgICAgICAoY2xpY2spPVwiaXNBZHZhbmNlZE1vZGUuc2V0KGZhbHNlKVwiXG4gICAgICAgICAgICB0aXRsZT1cIlNpbXBsaWZpZWQgdmlldyBmb3IgYnVzaW5lc3MgdXNlcnMgd2l0aCBmcmllbmRseSBuYW1lc1wiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgU2ltcGxlXG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICBjbGFzcz1cInBpbGwtYnRuXCJcbiAgICAgICAgICAgIFtjbGFzcy5hY3RpdmVdPVwiaXNBZHZhbmNlZE1vZGUoKVwiXG4gICAgICAgICAgICAoY2xpY2spPVwiaXNBZHZhbmNlZE1vZGUuc2V0KHRydWUpXCJcbiAgICAgICAgICAgIHRpdGxlPVwiVGVjaG5pY2FsIHZpZXcgd2l0aCBTUUwgdHlwZXMgYW5kIGV4cHJlc3Npb25zXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICBBZHZhbmNlZFxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIDIuIFNvdXJjZSBUeXBlIFNlZ21lbnRlZCBTd2l0Y2hlciAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJzb3VyY2UtdHlwZS1zd2l0Y2hlclwiPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgY2xhc3M9XCJzb3VyY2UtdGFiLWJ0blwiXG4gICAgICAgICAgW2NsYXNzLmFjdGl2ZV09XCJjdXJyZW50U291cmNlVHlwZSgpID09PSAndGFibGUnXCJcbiAgICAgICAgICAoY2xpY2spPVwic2V0U291cmNlVHlwZSgndGFibGUnKVwiXG4gICAgICAgID5cbiAgICAgICAgICA8cnB0LWljb24gbmFtZT1cInRhYmxlXCIgW3NpemVdPVwiMTJcIiAvPlxuICAgICAgICAgIDxzcGFuPnt7IGlzQWR2YW5jZWRNb2RlKCkgPyAnVGFibGUgLyBWaWV3JyA6ICdEYXRhYmFzZSBUYWJsZScgfX08L3NwYW4+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgY2xhc3M9XCJzb3VyY2UtdGFiLWJ0blwiXG4gICAgICAgICAgW2NsYXNzLmFjdGl2ZV09XCJjdXJyZW50U291cmNlVHlwZSgpID09PSAncHJvY2VkdXJlJ1wiXG4gICAgICAgICAgKGNsaWNrKT1cInNldFNvdXJjZVR5cGUoJ3Byb2NlZHVyZScpXCJcbiAgICAgICAgPlxuICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwiY29kZVwiIFtzaXplXT1cIjEyXCIgLz5cbiAgICAgICAgICA8c3Bhbj57eyBpc0FkdmFuY2VkTW9kZSgpID8gJ1N0b3JlZCBQcm9jJyA6ICdEYXRhIFF1ZXJ5JyB9fTwvc3Bhbj5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICBjbGFzcz1cInNvdXJjZS10YWItYnRuXCJcbiAgICAgICAgICBbY2xhc3MuYWN0aXZlXT1cImN1cnJlbnRTb3VyY2VUeXBlKCkgPT09ICdzdGF0aWMnXCJcbiAgICAgICAgICAoY2xpY2spPVwic2V0U291cmNlVHlwZSgnc3RhdGljJylcIlxuICAgICAgICA+XG4gICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJlZGl0XCIgW3NpemVdPVwiMTJcIiAvPlxuICAgICAgICAgIDxzcGFuPlN0YXRpYyBMaXN0PC9zcGFuPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIDNBLiBEQVRBQkFTRSBUQUJMRSAvIFZJRVcgQ09ORklHVVJBVElPTiAtLT5cbiAgICAgIEBpZiAoY3VycmVudFNvdXJjZVR5cGUoKSA9PT0gJ3RhYmxlJykge1xuICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtcm93XCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLWxhYmVsLXJvd1wiPlxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmllbGQtbGFiZWxcIj5cbiAgICAgICAgICAgICAge3sgaXNBZHZhbmNlZE1vZGUoKSA/ICdEYXRhYmFzZSBUYWJsZSAvIFZpZXcnIDogJ1NlbGVjdCBEYXRhIFNvdXJjZScgfX1cbiAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICBjbGFzcz1cImJ0bi1yZWZyZXNoLWVudGl0aWVzXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cImxvYWRFbnRpdGllcygpXCJcbiAgICAgICAgICAgICAgdGl0bGU9XCJSZWZyZXNoIGF2YWlsYWJsZSB0YWJsZXMgZnJvbSBiYWNrZW5kXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJyZWZyZXNoXCIgW3NpemVdPVwiMTFcIiAvPlxuICAgICAgICAgICAgICA8c3Bhbj5SZWZyZXNoPC9zcGFuPlxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPHNlbGVjdFxuICAgICAgICAgICAgY2xhc3M9XCJmaWVsZC1zZWxlY3RcIlxuICAgICAgICAgICAgW25nTW9kZWxdPVwic2VsZWN0ZWRFbnRpdHkoKVwiXG4gICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJvbkVudGl0eVNlbGVjdGVkKCRldmVudClcIlxuICAgICAgICAgICAgW2Rpc2FibGVkXT1cImlzTG9hZGluZ0VudGl0aWVzKClcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIEBpZiAoaXNMb2FkaW5nRW50aXRpZXMoKSkge1xuICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+TG9hZGluZyB0YWJsZXMgZnJvbSBkYXRhYmFzZS4uLjwvb3B0aW9uPlxuICAgICAgICAgICAgfSBAZWxzZSBpZiAoYXZhaWxhYmxlVGFibGVzKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBObyB0YWJsZXMgZm91bmQgKENsaWNrIFJlZnJlc2gpIC0tPC9vcHRpb24+XG4gICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPi0tIENob29zZSBEYXRhIFRhYmxlIC0tPC9vcHRpb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBAZm9yICh0Ymwgb2YgYXZhaWxhYmxlVGFibGVzKCk7IHRyYWNrIHRibC5uYW1lKSB7XG4gICAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cInRibC5uYW1lXCI+XG4gICAgICAgICAgICAgICAgQGlmIChpc0FkdmFuY2VkTW9kZSgpKSB7XG4gICAgICAgICAgICAgICAgICB7eyB0Ymwuc2NoZW1hIH19Lnt7IHRibC5uYW1lIH19ICh7eyB0YmwudHlwZSB9fSlcbiAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHt7IHRibC5kaXNwbGF5TmFtZSB9fXt7IHRibC5jYXRlZ29yeSA/ICcg4oCiICcgKyB0YmwuY2F0ZWdvcnkgOiAnJyB9fVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIEBpZiAoc2VsZWN0ZWRFbnRpdHkoKSkge1xuICAgICAgICAgIDwhLS0gRGlzcGxheSBGaWVsZCAoVmlzaWJsZSB0ZXh0KSAtLT5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtcm93XCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtbGFiZWwtcm93XCI+XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZpZWxkLWxhYmVsXCI+XG4gICAgICAgICAgICAgICAge3sgaXNBZHZhbmNlZE1vZGUoKSA/ICdEaXNwbGF5IEZpZWxkIChWaXNpYmxlIFRleHQpJyA6ICdUZXh0IFNob3duIGluIERyb3Bkb3duJyB9fVxuICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICBAaWYgKCFpc0FkdmFuY2VkTW9kZSgpKSB7XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJhdXRvLWJhZGdlXCIgdGl0bGU9XCJBdXRvLWRldGVjdGVkIGNvbHVtbiBmb3IgdGV4dCBsYWJlbFwiPkF1dG8tZGV0ZWN0ZWQ8L3NwYW4+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPHNlbGVjdFxuICAgICAgICAgICAgICBjbGFzcz1cImZpZWxkLXNlbGVjdFwiXG4gICAgICAgICAgICAgIFtuZ01vZGVsXT1cInNlbGVjdGVkRGlzcGxheUZpZWxkKClcIlxuICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJvbkRpc3BsYXlGaWVsZENoYW5nZWQoJGV2ZW50KVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBTZWxlY3QgRGlzcGxheSBDb2x1bW4gLS08L29wdGlvbj5cbiAgICAgICAgICAgICAgQGZvciAoY29sIG9mIGVudGl0eUNvbHVtbnMoKTsgdHJhY2sgY29sLmZpZWxkKSB7XG4gICAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwiY29sLmZpZWxkXCI+XG4gICAgICAgICAgICAgICAgICB7eyBjb2wubGFiZWwgfX0ge3sgaXNBZHZhbmNlZE1vZGUoKSA/ICcoJyArIGNvbC5kYXRhVHlwZSArICcpJyA6ICcnIH19XG4gICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPCEtLSBWYWx1ZSBGaWVsZCAoU3RvcmVkIGtleSkgLS0+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLXJvd1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLWxhYmVsLXJvd1wiPlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmaWVsZC1sYWJlbFwiPlxuICAgICAgICAgICAgICAgIHt7IGlzQWR2YW5jZWRNb2RlKCkgPyAnVmFsdWUgRmllbGQgKFN0b3JlZCBLZXkpJyA6ICdJbnRlcm5hbCBWYWx1ZSAvIEtleScgfX1cbiAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgQGlmICghaXNBZHZhbmNlZE1vZGUoKSkge1xuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYXV0by1iYWRnZVwiIHRpdGxlPVwiQXV0by1kZXRlY3RlZCBjb2x1bW4gZm9yIHByaW1hcnkgSURcIj5BdXRvLWRldGVjdGVkPC9zcGFuPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxzZWxlY3RcbiAgICAgICAgICAgICAgY2xhc3M9XCJmaWVsZC1zZWxlY3RcIlxuICAgICAgICAgICAgICBbbmdNb2RlbF09XCJzZWxlY3RlZFZhbHVlRmllbGQoKVwiXG4gICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIm9uVmFsdWVGaWVsZENoYW5nZWQoJGV2ZW50KVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBTZWxlY3QgS2V5IENvbHVtbiAtLTwvb3B0aW9uPlxuICAgICAgICAgICAgICBAZm9yIChjb2wgb2YgZW50aXR5Q29sdW1ucygpOyB0cmFjayBjb2wuZmllbGQpIHtcbiAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCJjb2wuZmllbGRcIj5cbiAgICAgICAgICAgICAgICAgIHt7IGNvbC5sYWJlbCB9fSB7eyBpc0FkdmFuY2VkTW9kZSgpID8gJygnICsgY29sLmRhdGFUeXBlICsgJyknIDogJycgfX1cbiAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8IS0tIENhc2NhZGluZyBEcm9wZG93biBEZXBlbmRlbmN5IC0tPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC1yb3dcIj5cbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZpZWxkLWxhYmVsXCI+XG4gICAgICAgICAgICAgIHt7IGlzQWR2YW5jZWRNb2RlKCkgPyAnRGVwZW5kZW50IE9uIChDYXNjYWRpbmcgUGFyZW50IEZpZWxkKScgOiAnRmlsdGVyIGJ5IEFub3RoZXIgRmllbGQnIH19XG4gICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgPHNlbGVjdFxuICAgICAgICAgICAgICBjbGFzcz1cImZpZWxkLXNlbGVjdFwiXG4gICAgICAgICAgICAgIFtuZ01vZGVsXT1cInNlbGVjdGVkRGVwZW5kc09uKClcIlxuICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJvbkRlcGVuZHNPbkNoYW5nZWQoJGV2ZW50KVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBOb25lIChJbmRlcGVuZGVudCkgLS08L29wdGlvbj5cbiAgICAgICAgICAgICAgQGZvciAob3RoZXIgb2YgYXZhaWxhYmxlUGFyZW50RmllbGRzKCk7IHRyYWNrIG90aGVyLmtleSB8fCBvdGhlci5pZCkge1xuICAgICAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cIm90aGVyLmtleSB8fCBvdGhlci5pZFwiPnt7IG90aGVyLmxhYmVsIHx8IG90aGVyLmtleSB9fTwvb3B0aW9uPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZmllbGQtaGludFwiPlxuICAgICAgICAgICAgICB7eyBpc0FkdmFuY2VkTW9kZSgpID8gJ0F1dG9tYXRpY2FsbHkgcmUtcXVlcmllcyBvcHRpb25zIHdoZW4gcGFyZW50IGZpZWxkIGNoYW5nZXMuJyA6ICdPbmx5IGxvYWRzIG9wdGlvbnMgd2hlbiB0aGUgc2VsZWN0ZWQgZmllbGQgY2hhbmdlcy4nIH19XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgPCEtLSAzQi4gU1RPUkVEIFBST0NFRFVSRSBDT05GSUdVUkFUSU9OIC0tPlxuICAgICAgQGlmIChjdXJyZW50U291cmNlVHlwZSgpID09PSAncHJvY2VkdXJlJykge1xuICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtcm93XCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLWxhYmVsLXJvd1wiPlxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmllbGQtbGFiZWxcIj5cbiAgICAgICAgICAgICAge3sgaXNBZHZhbmNlZE1vZGUoKSA/ICdTdG9yZWQgUHJvY2VkdXJlJyA6ICdTZWxlY3QgRGF0YSBQcm9jZWR1cmUnIH19XG4gICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJidG4tcmVmcmVzaC1lbnRpdGllc1wiXG4gICAgICAgICAgICAgIChjbGljayk9XCJsb2FkRW50aXRpZXMoKVwiXG4gICAgICAgICAgICAgIHRpdGxlPVwiUmVmcmVzaCBhdmFpbGFibGUgcHJvY2VkdXJlcyBmcm9tIGJhY2tlbmRcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cInJlZnJlc2hcIiBbc2l6ZV09XCIxMVwiIC8+XG4gICAgICAgICAgICAgIDxzcGFuPlJlZnJlc2g8L3NwYW4+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8c2VsZWN0XG4gICAgICAgICAgICBjbGFzcz1cImZpZWxkLXNlbGVjdFwiXG4gICAgICAgICAgICBbbmdNb2RlbF09XCJzZWxlY3RlZEVudGl0eSgpXCJcbiAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIm9uRW50aXR5U2VsZWN0ZWQoJGV2ZW50KVwiXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwiaXNMb2FkaW5nRW50aXRpZXMoKVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgQGlmIChpc0xvYWRpbmdFbnRpdGllcygpKSB7XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj5Mb2FkaW5nIHN0b3JlZCBwcm9jZWR1cmVzIGZyb20gZGF0YWJhc2UuLi48L29wdGlvbj5cbiAgICAgICAgICAgIH0gQGVsc2UgaWYgKGF2YWlsYWJsZVByb2NlZHVyZXMoKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPi0tIE5vIHN0b3JlZCBwcm9jZWR1cmVzIGZvdW5kIChDbGljayBSZWZyZXNoKSAtLTwvb3B0aW9uPlxuICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBDaG9vc2UgRGF0YSBRdWVyeSAvIFNQIC0tPC9vcHRpb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBAZm9yIChzcCBvZiBhdmFpbGFibGVQcm9jZWR1cmVzKCk7IHRyYWNrIHNwLm5hbWUpIHtcbiAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwic3AubmFtZVwiPlxuICAgICAgICAgICAgICAgIEBpZiAoaXNBZHZhbmNlZE1vZGUoKSkge1xuICAgICAgICAgICAgICAgICAge3sgc3Auc2NoZW1hIH19Lnt7IHNwLm5hbWUgfX1cbiAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHt7IHNwLmRpc3BsYXlOYW1lIH19e3sgc3AuY2F0ZWdvcnkgPyAnIOKAoiAnICsgc3AuY2F0ZWdvcnkgOiAnJyB9fVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIEBpZiAoc2VsZWN0ZWRFbnRpdHkoKSkge1xuICAgICAgICAgIDwhLS0gVmlzdWFsIFBhcmFtZXRlciBMaW5rZXJzIC0tPlxuICAgICAgICAgIEBpZiAocHJvY2VkdXJlUGFyYW1ldGVycygpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzcC1wYXJhbXMtZ3JvdXBcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBhcmFtcy1oZWFkZXItcm93XCI+XG4gICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmllbGQtbGFiZWxcIj5cbiAgICAgICAgICAgICAgICAgIHt7IGlzQWR2YW5jZWRNb2RlKCkgPyAnUHJvY2VkdXJlIElucHV0IFBhcmFtZXRlcnMnIDogJ0ZpbHRlciBJbnB1dHMgJiBQYXJhbWV0ZXJzJyB9fVxuICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cImJ0bi1hdXRvLXBhcmFtc1wiXG4gICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYXV0b1dpcmVBbGxQYXJhbWV0ZXJzKClcIlxuICAgICAgICAgICAgICAgICAgdGl0bGU9XCJBdXRvLWRldGVjdCBzZXNzaW9uIHBhcmFtZXRlcnMgYW5kIGFkZCBtaXNzaW5nIGZpbHRlciBjb250cm9scyB0byB0aGUgY2FudmFzXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cImNoZWNrXCIgW3NpemVdPVwiMTFcIiAvPlxuICAgICAgICAgICAgICAgICAgPHNwYW4+QXV0by1XaXJlIENhbnZhcyBJbnB1dHM8L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgIEBmb3IgKHBhcmFtIG9mIHByb2NlZHVyZVBhcmFtZXRlcnMoKTsgdHJhY2sgcGFyYW0ubmFtZSkge1xuICAgICAgICAgICAgICAgIDxycHQtcGFyYW1ldGVyLWJpbmRpbmctZWRpdG9yXG4gICAgICAgICAgICAgICAgICBbcGFyYW1dPVwicGFyYW1cIlxuICAgICAgICAgICAgICAgICAgW2N1cnJlbnRWYWx1ZV09XCJnZXRQYXJhbVZhbHVlKHBhcmFtLm5hbWUpXCJcbiAgICAgICAgICAgICAgICAgIFthbGxDb21wb25lbnRzXT1cImFsbENvbXBvbmVudHMoKVwiXG4gICAgICAgICAgICAgICAgICBbY3VycmVudENvbXBvbmVudElkXT1cImNvbXAoKS5pZFwiXG4gICAgICAgICAgICAgICAgICBbaXNBZHZhbmNlZE1vZGVdPVwiaXNBZHZhbmNlZE1vZGUoKVwiXG4gICAgICAgICAgICAgICAgICAodmFsdWVDaGFuZ2UpPVwic2V0UGFyYW1WYWx1ZShwYXJhbS5uYW1lLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgIChsaW5rZWRGaWVsZENoYW5nZSk9XCJvblBhcmFtTGlua2VkRmllbGRDaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgPCEtLSBEaXNwbGF5IEZpZWxkIChWaXNpYmxlIHRleHQpIC0tPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC1yb3dcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC1sYWJlbC1yb3dcIj5cbiAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmllbGQtbGFiZWxcIj5cbiAgICAgICAgICAgICAgICB7eyBpc0FkdmFuY2VkTW9kZSgpID8gJ0Rpc3BsYXkgRmllbGQgKGZyb20gU1AgcmVzdWx0KScgOiAnVGV4dCBTaG93biBpbiBEcm9wZG93bicgfX1cbiAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgQGlmICghaXNBZHZhbmNlZE1vZGUoKSkge1xuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYXV0by1iYWRnZVwiPkF1dG8tZGV0ZWN0ZWQ8L3NwYW4+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPHNlbGVjdFxuICAgICAgICAgICAgICBjbGFzcz1cImZpZWxkLXNlbGVjdFwiXG4gICAgICAgICAgICAgIFtuZ01vZGVsXT1cInNlbGVjdGVkRGlzcGxheUZpZWxkKClcIlxuICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJvbkRpc3BsYXlGaWVsZENoYW5nZWQoJGV2ZW50KVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBTZWxlY3QgRGlzcGxheSBDb2x1bW4gLS08L29wdGlvbj5cbiAgICAgICAgICAgICAgQGZvciAoY29sIG9mIGVudGl0eUNvbHVtbnMoKTsgdHJhY2sgY29sLmZpZWxkKSB7XG4gICAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwiY29sLmZpZWxkXCI+XG4gICAgICAgICAgICAgICAgICB7eyBjb2wubGFiZWwgfX0ge3sgaXNBZHZhbmNlZE1vZGUoKSA/ICcoJyArIGNvbC5kYXRhVHlwZSArICcpJyA6ICcnIH19XG4gICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPCEtLSBWYWx1ZSBGaWVsZCAoU3RvcmVkIGtleSkgLS0+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLXJvd1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLWxhYmVsLXJvd1wiPlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmaWVsZC1sYWJlbFwiPlxuICAgICAgICAgICAgICAgIHt7IGlzQWR2YW5jZWRNb2RlKCkgPyAnVmFsdWUgRmllbGQgKGZyb20gU1AgcmVzdWx0KScgOiAnSW50ZXJuYWwgVmFsdWUgLyBLZXknIH19XG4gICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgIEBpZiAoIWlzQWR2YW5jZWRNb2RlKCkpIHtcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImF1dG8tYmFkZ2VcIj5BdXRvLWRldGVjdGVkPC9zcGFuPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxzZWxlY3RcbiAgICAgICAgICAgICAgY2xhc3M9XCJmaWVsZC1zZWxlY3RcIlxuICAgICAgICAgICAgICBbbmdNb2RlbF09XCJzZWxlY3RlZFZhbHVlRmllbGQoKVwiXG4gICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIm9uVmFsdWVGaWVsZENoYW5nZWQoJGV2ZW50KVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBTZWxlY3QgS2V5IENvbHVtbiAtLTwvb3B0aW9uPlxuICAgICAgICAgICAgICBAZm9yIChjb2wgb2YgZW50aXR5Q29sdW1ucygpOyB0cmFjayBjb2wuZmllbGQpIHtcbiAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCJjb2wuZmllbGRcIj5cbiAgICAgICAgICAgICAgICAgIHt7IGNvbC5sYWJlbCB9fSB7eyBpc0FkdmFuY2VkTW9kZSgpID8gJygnICsgY29sLmRhdGFUeXBlICsgJyknIDogJycgfX1cbiAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgPCEtLSAzQy4gU1RBVElDIE9QVElPTlMgRURJVE9SIC0tPlxuICAgICAgQGlmIChjdXJyZW50U291cmNlVHlwZSgpID09PSAnc3RhdGljJykge1xuICAgICAgICA8ZGl2IGNsYXNzPVwic3RhdGljLW9wdGlvbnMtd3JhcHBlclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdGF0aWMtb3B0aW9ucy1oZWFkZXJcIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZmllbGQtbGFiZWxcIj5TdGF0aWMgT3B0aW9uczwvc3Bhbj5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuLWFkZC1vcHRpb25cIiAoY2xpY2spPVwiYWRkU3RhdGljT3B0aW9uKClcIj5cbiAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJwbHVzXCIgW3NpemVdPVwiMTFcIiAvPlxuICAgICAgICAgICAgICA8c3Bhbj5BZGQgT3B0aW9uPC9zcGFuPlxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RhdGljLW9wdGlvbnMtbGlzdFwiPlxuICAgICAgICAgICAgQGZvciAob3B0IG9mIHN0YXRpY09wdGlvbnMoKTsgdHJhY2sgJGluZGV4KSB7XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdGF0aWMtb3B0aW9uLXJvd1wiPlxuICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmaWVsZC1pbnB1dCBvcHQta2V5XCJcbiAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiS2V5XCJcbiAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cIm9wdC5rZXlcIlxuICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwidXBkYXRlU3RhdGljT3B0aW9uKCRpbmRleCwgJ2tleScsICRldmVudClcIlxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cImZpZWxkLWlucHV0IG9wdC1sYWJlbFwiXG4gICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIkxhYmVsXCJcbiAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cIm9wdC5sYWJlbFwiXG4gICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJ1cGRhdGVTdGF0aWNPcHRpb24oJGluZGV4LCAnbGFiZWwnLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJidG4tcmVtb3ZlLW9wdGlvblwiXG4gICAgICAgICAgICAgICAgICAoY2xpY2spPVwicmVtb3ZlU3RhdGljT3B0aW9uKCRpbmRleClcIlxuICAgICAgICAgICAgICAgICAgdGl0bGU9XCJSZW1vdmUgb3B0aW9uXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cInRyYXNoXCIgW3NpemVdPVwiMTJcIiAvPlxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICB9XG4gICAgPC9kaXY+XG4gIGAsXG4gIHN0eWxlczogW2BcbiAgICAuZGF0YXNvdXJjZS1oZWFkZXItYmFyIHtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICAgICAgbWFyZ2luLWJvdHRvbTogOHB4O1xuICAgIH1cbiAgICAubW9kZS10b2dnbGUtcGlsbCB7XG4gICAgICBkaXNwbGF5OiBpbmxpbmUtZmxleDtcbiAgICAgIGJhY2tncm91bmQ6ICNlMmU4ZjA7XG4gICAgICBib3JkZXItcmFkaXVzOiAxMnB4O1xuICAgICAgcGFkZGluZzogMnB4O1xuICAgICAgZ2FwOiAycHg7XG4gICAgfVxuICAgIC5waWxsLWJ0biB7XG4gICAgICBib3JkZXI6IG5vbmU7XG4gICAgICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbiAgICAgIHBhZGRpbmc6IDJweCA4cHg7XG4gICAgICBmb250LXNpemU6IDAuNjVyZW07XG4gICAgICBmb250LXdlaWdodDogNTAwO1xuICAgICAgY29sb3I6ICM2NDc0OGI7XG4gICAgICBib3JkZXItcmFkaXVzOiAxMHB4O1xuICAgICAgY3Vyc29yOiBwb2ludGVyO1xuICAgICAgdHJhbnNpdGlvbjogYWxsIDEyMG1zIGVhc2U7XG4gICAgfVxuICAgIC5waWxsLWJ0bjpob3ZlciB7XG4gICAgICBjb2xvcjogIzBmMTcyYTtcbiAgICB9XG4gICAgLnBpbGwtYnRuLmFjdGl2ZSB7XG4gICAgICBiYWNrZ3JvdW5kOiAjZmZmZmZmO1xuICAgICAgY29sb3I6IHZhcigtLXJwdC1jb2xvci1wcmltYXJ5LCAjMjU2M2ViKTtcbiAgICAgIGZvbnQtd2VpZ2h0OiA3MDA7XG4gICAgICBib3gtc2hhZG93OiAwIDFweCAycHggcmdiYSgwLCAwLCAwLCAwLjA4KTtcbiAgICB9XG4gICAgLnNvdXJjZS10eXBlLXN3aXRjaGVyIHtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBiYWNrZ3JvdW5kOiAjZjFmNWY5O1xuICAgICAgYm9yZGVyOiAxcHggc29saWQgdmFyKC0tcnB0LWNvbG9yLWJvcmRlciwgI2NiZDVlMSk7XG4gICAgICBib3JkZXItcmFkaXVzOiA2cHg7XG4gICAgICBwYWRkaW5nOiAycHg7XG4gICAgICBnYXA6IDJweDtcbiAgICAgIG1hcmdpbi1ib3R0b206IDZweDtcbiAgICB9XG4gICAgLnNvdXJjZS10YWItYnRuIHtcbiAgICAgIGZsZXg6IDE7XG4gICAgICBkaXNwbGF5OiBpbmxpbmUtZmxleDtcbiAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICBqdXN0aWZ5LWNvbnRlbnQ6IGNlbnRlcjtcbiAgICAgIGdhcDogNXB4O1xuICAgICAgcGFkZGluZzogNnB4IDRweDtcbiAgICAgIGZvbnQtc2l6ZTogMC43cmVtO1xuICAgICAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgICAgIGNvbG9yOiB2YXIoLS1ycHQtY29sb3ItdGV4dC1tdXRlZCwgIzY0NzQ4Yik7XG4gICAgICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbiAgICAgIGJvcmRlcjogbm9uZTtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDRweDtcbiAgICAgIGN1cnNvcjogcG9pbnRlcjtcbiAgICAgIHRyYW5zaXRpb246IGFsbCAxMjBtcyBlYXNlO1xuICAgIH1cbiAgICAuc291cmNlLXRhYi1idG46aG92ZXIge1xuICAgICAgY29sb3I6IHZhcigtLXJwdC1jb2xvci10ZXh0LCAjMGYxNzJhKTtcbiAgICB9XG4gICAgLnNvdXJjZS10YWItYnRuLmFjdGl2ZSB7XG4gICAgICBiYWNrZ3JvdW5kOiAjZmZmZmZmO1xuICAgICAgY29sb3I6IHZhcigtLXJwdC1jb2xvci1wcmltYXJ5LCAjMjU2M2ViKTtcbiAgICAgIGJveC1zaGFkb3c6IDAgMXB4IDJweCByZ2JhKDAsIDAsIDAsIDAuMDUpO1xuICAgIH1cbiAgICAuYnRuLXJlZnJlc2gtZW50aXRpZXMge1xuICAgICAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAgZ2FwOiA0cHg7XG4gICAgICBib3JkZXI6IG5vbmU7XG4gICAgICBiYWNrZ3JvdW5kOiB0cmFuc3BhcmVudDtcbiAgICAgIGNvbG9yOiB2YXIoLS1ycHQtY29sb3ItcHJpbWFyeSwgIzI1NjNlYik7XG4gICAgICBmb250LXNpemU6IDAuNjVyZW07XG4gICAgICBmb250LXdlaWdodDogNjAwO1xuICAgICAgY3Vyc29yOiBwb2ludGVyO1xuICAgICAgcGFkZGluZzogMDtcbiAgICB9XG4gICAgLmJ0bi1yZWZyZXNoLWVudGl0aWVzOmhvdmVyIHtcbiAgICAgIHRleHQtZGVjb3JhdGlvbjogdW5kZXJsaW5lO1xuICAgIH1cbiAgICAuYnRuLWF1dG8tcGFyYW1zIHtcbiAgICAgIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIGdhcDogNHB4O1xuICAgICAgcGFkZGluZzogMnB4IDhweDtcbiAgICAgIGZvbnQtc2l6ZTogMC42NXJlbTtcbiAgICAgIGZvbnQtd2VpZ2h0OiA2MDA7XG4gICAgICBjb2xvcjogIzI1NjNlYjtcbiAgICAgIGJhY2tncm91bmQ6ICNlZmY2ZmY7XG4gICAgICBib3JkZXI6IDFweCBzb2xpZCAjYmZkYmZlO1xuICAgICAgYm9yZGVyLXJhZGl1czogNHB4O1xuICAgICAgY3Vyc29yOiBwb2ludGVyO1xuICAgICAgdHJhbnNpdGlvbjogYWxsIDEyMG1zIGVhc2U7XG4gICAgfVxuICAgIC5idG4tYXV0by1wYXJhbXM6aG92ZXIge1xuICAgICAgYmFja2dyb3VuZDogIzI1NjNlYjtcbiAgICAgIGNvbG9yOiAjZmZmZmZmO1xuICAgIH1cbiAgICAuYXV0by1iYWRnZSB7XG4gICAgICBmb250LXNpemU6IDAuNjJyZW07XG4gICAgICBmb250LXdlaWdodDogNjAwO1xuICAgICAgYmFja2dyb3VuZDogI2RjZmNlNztcbiAgICAgIGNvbG9yOiAjMTY2NTM0O1xuICAgICAgcGFkZGluZzogMXB4IDVweDtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDRweDtcbiAgICB9XG4gICAgLmZpZWxkLWhpbnQge1xuICAgICAgZm9udC1zaXplOiAwLjY1cmVtO1xuICAgICAgY29sb3I6IHZhcigtLXJwdC1jb2xvci10ZXh0LW11dGVkLCAjOTRhM2I4KTtcbiAgICAgIG1hcmdpbi10b3A6IDJweDtcbiAgICB9XG4gICAgLnNwLXBhcmFtcy1ncm91cCB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgIGdhcDogNnB4O1xuICAgICAgYmFja2dyb3VuZDogI2Y4ZmFmYztcbiAgICAgIHBhZGRpbmc6IDhweDtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDZweDtcbiAgICAgIGJvcmRlcjogMXB4IHNvbGlkICNlMmU4ZjA7XG4gICAgICBtYXJnaW4tYm90dG9tOiA2cHg7XG4gICAgfVxuICAgIC5wYXJhbXMtaGVhZGVyLXJvdyB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIGp1c3RpZnktY29udGVudDogc3BhY2UtYmV0d2VlbjtcbiAgICB9XG4gICAgLnBhcmFtcy1oaW50IHtcbiAgICAgIGZvbnQtc2l6ZTogMC42NHJlbTtcbiAgICAgIGNvbG9yOiAjNjQ3NDhiO1xuICAgICAgZm9udC1zdHlsZTogaXRhbGljO1xuICAgIH1cbiAgICAuc3RhdGljLW9wdGlvbnMtd3JhcHBlciB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgZmxleC1kaXJlY3Rpb246IGNvbHVtbjtcbiAgICAgIGdhcDogOHB4O1xuICAgIH1cbiAgICAuc3RhdGljLW9wdGlvbnMtaGVhZGVyIHtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAganVzdGlmeS1jb250ZW50OiBzcGFjZS1iZXR3ZWVuO1xuICAgIH1cbiAgICAuYnRuLWFkZC1vcHRpb24ge1xuICAgICAgZGlzcGxheTogaW5saW5lLWZsZXg7XG4gICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAgZ2FwOiA0cHg7XG4gICAgICBib3JkZXI6IDFweCBzb2xpZCB2YXIoLS1ycHQtY29sb3ItYm9yZGVyLCAjY2JkNWUxKTtcbiAgICAgIGJhY2tncm91bmQ6ICNmZmZmZmY7XG4gICAgICBib3JkZXItcmFkaXVzOiA0cHg7XG4gICAgICBwYWRkaW5nOiAzcHggOHB4O1xuICAgICAgZm9udC1zaXplOiAwLjY1cmVtO1xuICAgICAgZm9udC13ZWlnaHQ6IDYwMDtcbiAgICAgIGNvbG9yOiB2YXIoLS1ycHQtY29sb3ItcHJpbWFyeSwgIzI1NjNlYik7XG4gICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgICB0cmFuc2l0aW9uOiBhbGwgMTIwbXMgZWFzZTtcbiAgICB9XG4gICAgLmJ0bi1hZGQtb3B0aW9uOmhvdmVyIHtcbiAgICAgIGJhY2tncm91bmQ6ICNlZmY2ZmY7XG4gICAgfVxuICAgIC5zdGF0aWMtb3B0aW9ucy1saXN0IHtcbiAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgICAgZ2FwOiA2cHg7XG4gICAgfVxuICAgIC5zdGF0aWMtb3B0aW9uLXJvdyB7XG4gICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIGdhcDogNnB4O1xuICAgIH1cbiAgICAub3B0LWtleSB7XG4gICAgICBmbGV4OiAxO1xuICAgIH1cbiAgICAub3B0LWxhYmVsIHtcbiAgICAgIGZsZXg6IDEuNTtcbiAgICB9XG4gICAgLmJ0bi1yZW1vdmUtb3B0aW9uIHtcbiAgICAgIHdpZHRoOiAyNHB4O1xuICAgICAgaGVpZ2h0OiAyNHB4O1xuICAgICAgYm9yZGVyOiBub25lO1xuICAgICAgYmFja2dyb3VuZDogdHJhbnNwYXJlbnQ7XG4gICAgICBjb2xvcjogIzk0YTNiODtcbiAgICAgIGJvcmRlci1yYWRpdXM6IDRweDtcbiAgICAgIGRpc3BsYXk6IGlubGluZS1mbGV4O1xuICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgICAgY3Vyc29yOiBwb2ludGVyO1xuICAgICAgZmxleC1zaHJpbms6IDA7XG4gICAgICBwYWRkaW5nOiAwO1xuICAgICAgdHJhbnNpdGlvbjogYWxsIDEyMG1zIGVhc2U7XG4gICAgfVxuICAgIC5idG4tcmVtb3ZlLW9wdGlvbjpob3ZlciB7XG4gICAgICBiYWNrZ3JvdW5kOiAjZmVlMmUyO1xuICAgICAgY29sb3I6ICNlZjQ0NDQ7XG4gICAgfVxuICBgXSxcbn0pXG5leHBvcnQgY2xhc3MgUHJvcGVydHlFZGl0b3JEYXRhc291cmNlQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgcHJpdmF0ZSByZWFkb25seSBkaXNjb3ZlcnlBZGFwdGVyID0gaW5qZWN0KFJlcG9ydFNjaGVtYURpc2NvdmVyeUFkYXB0ZXIsIHsgb3B0aW9uYWw6IHRydWUgfSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgc2Vzc2lvblNlcnZpY2UgPSBpbmplY3QoUmVwb3J0U2Vzc2lvbkNvbnRleHRTZXJ2aWNlLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuICBwcml2YXRlIHJlYWRvbmx5IGRlc2lnbmVyU3RhdGUgPSBpbmplY3QoRGVzaWduZXJTdGF0ZVNlcnZpY2UsIHsgb3B0aW9uYWw6IHRydWUgfSk7XG5cbiAgcmVhZG9ubHkgY29tcCA9IGlucHV0LnJlcXVpcmVkPFJlcG9ydENvbXBvbmVudERlZmluaXRpb24+KCk7XG4gIHJlYWRvbmx5IGFsbENvbXBvbmVudHMgPSBpbnB1dDxSZXBvcnRDb21wb25lbnREZWZpbml0aW9uW10+KFtdKTtcblxuICByZWFkb25seSB1cGRhdGVEYXRhU291cmNlID0gb3V0cHV0PENvbXBvbmVudERhdGFTb3VyY2VEZWZpbml0aW9uPigpO1xuICByZWFkb25seSB1cGRhdGVQcm9wZXJ0eSA9IG91dHB1dDx7IGtleTogc3RyaW5nOyB2YWx1ZTogdW5rbm93biB9PigpO1xuXG4gIHJlYWRvbmx5IGlzQWR2YW5jZWRNb2RlID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgcmVhZG9ubHkgaXNMb2FkaW5nRW50aXRpZXMgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICByZWFkb25seSBhbGxFbnRpdGllcyA9IHNpZ25hbDxEYXRhYmFzZUVudGl0eU1ldGFkYXRhW10+KFtdKTtcbiAgcmVhZG9ubHkgZW50aXR5Q29sdW1ucyA9IHNpZ25hbDxFbnRpdHlDb2x1bW5NZXRhZGF0YVtdPihbXSk7XG4gIHJlYWRvbmx5IHByb2NlZHVyZVBhcmFtZXRlcnMgPSBzaWduYWw8UHJvY2VkdXJlUGFyYW1ldGVyTWV0YWRhdGFbXT4oW10pO1xuXG4gIHJlYWRvbmx5IGN1cnJlbnRTb3VyY2VUeXBlID0gY29tcHV0ZWQ8RHJvcGRvd25Tb3VyY2VUeXBlPigoKSA9PiB7XG4gICAgY29uc3QgZHMgPSB0aGlzLmNvbXAoKS5kYXRhU291cmNlO1xuICAgIGlmIChkcz8uc291cmNlVHlwZSkgcmV0dXJuIGRzLnNvdXJjZVR5cGU7XG4gICAgaWYgKGRzPy5lbnRpdHlOYW1lKSByZXR1cm4gJ3RhYmxlJztcbiAgICByZXR1cm4gJ3N0YXRpYyc7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IHNlbGVjdGVkRW50aXR5ID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5jb21wKCkuZGF0YVNvdXJjZT8uZW50aXR5TmFtZSB8fCAnJyk7XG4gIHJlYWRvbmx5IHNlbGVjdGVkVmFsdWVGaWVsZCA9IGNvbXB1dGVkKCgpID0+IHRoaXMuY29tcCgpLmRhdGFTb3VyY2U/LnZhbHVlRmllbGQgfHwgJycpO1xuICByZWFkb25seSBzZWxlY3RlZERpc3BsYXlGaWVsZCA9IGNvbXB1dGVkKCgpID0+IHRoaXMuY29tcCgpLmRhdGFTb3VyY2U/LmRpc3BsYXlGaWVsZCB8fCAnJyk7XG4gIHJlYWRvbmx5IHNlbGVjdGVkRGVwZW5kc09uID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5jb21wKCkuZGF0YVNvdXJjZT8uZGVwZW5kc09uPy5bMF0gfHwgJycpO1xuXG4gIHJlYWRvbmx5IGF2YWlsYWJsZVRhYmxlcyA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICByZXR1cm4gdGhpcy5hbGxFbnRpdGllcygpXG4gICAgICAuZmlsdGVyKChlKSA9PiB7XG4gICAgICAgIGNvbnN0IHQgPSAoZS50eXBlIHx8ICcnKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICByZXR1cm4gdCA9PT0gJ3RhYmxlJyB8fCB0ID09PSAndmlldyc7XG4gICAgICB9KVxuICAgICAgLm1hcCgoZSkgPT4gKHtcbiAgICAgICAgLi4uZSxcbiAgICAgICAgZGlzcGxheU5hbWU6IGUuZnJpZW5kbHlOYW1lIHx8IGh1bWFuaXplSWRlbnRpZmllcihlLm5hbWUpLFxuICAgICAgfSkpO1xuICB9KTtcblxuICByZWFkb25seSBhdmFpbGFibGVQcm9jZWR1cmVzID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIHJldHVybiB0aGlzLmFsbEVudGl0aWVzKClcbiAgICAgIC5maWx0ZXIoKGUpID0+IHtcbiAgICAgICAgY29uc3QgdCA9IChlLnR5cGUgfHwgJycpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIHJldHVybiB0ID09PSAnc3RvcmVkX3Byb2NlZHVyZScgfHwgdCA9PT0gJ3Byb2NlZHVyZScgfHwgdC5pbmNsdWRlcygncHJvY2VkdXJlJyk7XG4gICAgICB9KVxuICAgICAgLm1hcCgoZSkgPT4gKHtcbiAgICAgICAgLi4uZSxcbiAgICAgICAgZGlzcGxheU5hbWU6IGUuZnJpZW5kbHlOYW1lIHx8IGh1bWFuaXplSWRlbnRpZmllcihlLm5hbWUpLFxuICAgICAgfSkpO1xuICB9KTtcblxuICByZWFkb25seSBhdmFpbGFibGVQYXJlbnRGaWVsZHMgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgcmV0dXJuIHRoaXMuYWxsQ29tcG9uZW50cygpLmZpbHRlcigoYykgPT4gYy5pZCAhPT0gdGhpcy5jb21wKCkuaWQpO1xuICB9KTtcblxuICByZWFkb25seSBzdGF0aWNPcHRpb25zID0gY29tcHV0ZWQ8U3RhdGljT3B0aW9uSXRlbVtdPigoKSA9PiB7XG4gICAgY29uc3Qgb3B0cyA9IHRoaXMuY29tcCgpLnByb3BlcnRpZXM/Llsnb3B0aW9ucyddO1xuICAgIGlmIChBcnJheS5pc0FycmF5KG9wdHMpKSB7XG4gICAgICByZXR1cm4gb3B0cy5tYXAoKG8pID0+ICh7IGtleTogU3RyaW5nKG8ua2V5ID8/IG8udmFsdWUgPz8gJycpLCBsYWJlbDogU3RyaW5nKG8ubGFiZWwgPz8gJycpIH0pKTtcbiAgICB9XG4gICAgcmV0dXJuIFtcbiAgICAgIHsga2V5OiAnMScsIGxhYmVsOiAnT3B0aW9uIDEnIH0sXG4gICAgICB7IGtleTogJzInLCBsYWJlbDogJ09wdGlvbiAyJyB9LFxuICAgIF07XG4gIH0pO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIGVmZmVjdChcbiAgICAgICgpID0+IHtcbiAgICAgICAgY29uc3QgZW50aXR5ID0gdGhpcy5zZWxlY3RlZEVudGl0eSgpO1xuICAgICAgICBjb25zdCB0eXBlID0gdGhpcy5jdXJyZW50U291cmNlVHlwZSgpO1xuICAgICAgICBpZiAoZW50aXR5ICYmICh0eXBlID09PSAndGFibGUnIHx8IHR5cGUgPT09ICdwcm9jZWR1cmUnKSkge1xuICAgICAgICAgIHRoaXMubG9hZEVudGl0eURldGFpbHMoZW50aXR5LCB0eXBlKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHsgYWxsb3dTaWduYWxXcml0ZXM6IHRydWUgfVxuICAgICk7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmxvYWRFbnRpdGllcygpO1xuICB9XG5cbiAgbG9hZEVudGl0aWVzKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5kaXNjb3ZlcnlBZGFwdGVyKSByZXR1cm47XG4gICAgdGhpcy5pc0xvYWRpbmdFbnRpdGllcy5zZXQodHJ1ZSk7XG4gICAgdGhpcy5kaXNjb3ZlcnlBZGFwdGVyLmdldEVudGl0aWVzKCkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChlbnRpdGllcykgPT4ge1xuICAgICAgICB0aGlzLmFsbEVudGl0aWVzLnNldChlbnRpdGllcyk7XG4gICAgICAgIHRoaXMuaXNMb2FkaW5nRW50aXRpZXMuc2V0KGZhbHNlKTtcbiAgICAgIH0sXG4gICAgICBlcnJvcjogKGVycikgPT4ge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdbUHJvcGVydHlFZGl0b3JEYXRhc291cmNlXSBGYWlsZWQgdG8gbG9hZCBlbnRpdGllczonLCBlcnIpO1xuICAgICAgICB0aGlzLmlzTG9hZGluZ0VudGl0aWVzLnNldChmYWxzZSk7XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgbG9hZEVudGl0eURldGFpbHMoZW50aXR5TmFtZTogc3RyaW5nLCB0eXBlOiBEcm9wZG93blNvdXJjZVR5cGUpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZGlzY292ZXJ5QWRhcHRlcikgcmV0dXJuO1xuXG4gICAgY29uc3QgZGJUeXBlID0gdHlwZSA9PT0gJ3Byb2NlZHVyZScgPyAnc3RvcmVkX3Byb2NlZHVyZScgOiAndGFibGUnO1xuICAgIHRoaXMuZGlzY292ZXJ5QWRhcHRlci5nZXRDb2x1bW5zKGVudGl0eU5hbWUsICdkYm8nLCBkYlR5cGUpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAoY29scykgPT4ge1xuICAgICAgICB0aGlzLmVudGl0eUNvbHVtbnMuc2V0KGNvbHMpO1xuXG4gICAgICAgIC8vIEF1dG8tZGV0ZWN0IGRlZmF1bHQgdmFsdWVGaWVsZCBhbmQgZGlzcGxheUZpZWxkIGlmIG5vdCB5ZXQgc2V0XG4gICAgICAgIGNvbnN0IGN1cnJlbnRWYWwgPSB0aGlzLnNlbGVjdGVkVmFsdWVGaWVsZCgpO1xuICAgICAgICBjb25zdCBjdXJyZW50RGlzcCA9IHRoaXMuc2VsZWN0ZWREaXNwbGF5RmllbGQoKTtcbiAgICAgICAgY29uc3Qgc3VnZ2VzdGVkVmFsID0gZGV0ZWN0RGVmYXVsdFZhbHVlRmllbGQoY29scyk7XG4gICAgICAgIGNvbnN0IHN1Z2dlc3RlZERpc3AgPSBkZXRlY3REZWZhdWx0RGlzcGxheUZpZWxkKGNvbHMpO1xuXG4gICAgICAgIGlmICghY3VycmVudFZhbCB8fCAhY3VycmVudERpc3ApIHtcbiAgICAgICAgICB0aGlzLnVwZGF0ZURhdGFTb3VyY2UuZW1pdCh7XG4gICAgICAgICAgICAuLi4odGhpcy5jb21wKCkuZGF0YVNvdXJjZSA/PyB7IGRpc3BsYXlGaWVsZDogJycsIHZhbHVlRmllbGQ6ICcnIH0pLFxuICAgICAgICAgICAgc291cmNlVHlwZTogdHlwZSxcbiAgICAgICAgICAgIGVudGl0eU5hbWUsXG4gICAgICAgICAgICB2YWx1ZUZpZWxkOiBjdXJyZW50VmFsIHx8IHN1Z2dlc3RlZFZhbCB8fCBjb2xzWzBdPy5maWVsZCB8fCAnJyxcbiAgICAgICAgICAgIGRpc3BsYXlGaWVsZDogY3VycmVudERpc3AgfHwgc3VnZ2VzdGVkRGlzcCB8fCBjb2xzWzFdPy5maWVsZCB8fCBjb2xzWzBdPy5maWVsZCB8fCAnJyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGVycm9yOiAoZXJyKSA9PiBjb25zb2xlLmVycm9yKGBbUHJvcGVydHlFZGl0b3JEYXRhc291cmNlXSBGYWlsZWQgdG8gbG9hZCBjb2x1bW5zIGZvciAke2VudGl0eU5hbWV9OmAsIGVyciksXG4gICAgfSk7XG5cbiAgICBpZiAodHlwZSA9PT0gJ3Byb2NlZHVyZScpIHtcbiAgICAgIHRoaXMuZGlzY292ZXJ5QWRhcHRlci5nZXRQYXJhbWV0ZXJzKGVudGl0eU5hbWUsICdkYm8nKS5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAocGFyYW1zKSA9PiB7XG4gICAgICAgICAgdGhpcy5wcm9jZWR1cmVQYXJhbWV0ZXJzLnNldChwYXJhbXMpO1xuICAgICAgICAgIHRoaXMuYXV0b1dpcmVBbGxQYXJhbWV0ZXJzKHBhcmFtcyk7XG4gICAgICAgIH0sXG4gICAgICAgIGVycm9yOiAoZXJyKSA9PiBjb25zb2xlLmVycm9yKGBbUHJvcGVydHlFZGl0b3JEYXRhc291cmNlXSBGYWlsZWQgdG8gbG9hZCBwYXJhbXMgZm9yICR7ZW50aXR5TmFtZX06YCwgZXJyKSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIGF1dG9XaXJlQWxsUGFyYW1ldGVycyhwYXJhbXNMaXN0PzogUHJvY2VkdXJlUGFyYW1ldGVyTWV0YWRhdGFbXSk6IHZvaWQge1xuICAgIGNvbnN0IHBhcmFtcyA9IHBhcmFtc0xpc3QgfHwgdGhpcy5wcm9jZWR1cmVQYXJhbWV0ZXJzKCk7XG4gICAgaWYgKCFwYXJhbXMgfHwgcGFyYW1zLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuXG4gICAgY29uc3QgY3VycmVudE1hcHBpbmdzID0geyAuLi4odGhpcy5jb21wKCkuZGF0YVNvdXJjZT8ucGFyYW1ldGVyTWFwcGluZ3MgPz8ge30pIH07XG4gICAgbGV0IGNoYW5nZWQgPSBmYWxzZTtcblxuICAgIGZvciAoY29uc3QgcGFyYW0gb2YgcGFyYW1zKSB7XG4gICAgICBjb25zdCBjbGVhbiA9IHBhcmFtLm5hbWUucmVwbGFjZSgvXkAvLCAnJyk7XG4gICAgICBjb25zdCBleGlzdGluZyA9IGN1cnJlbnRNYXBwaW5nc1twYXJhbS5uYW1lXSA/PyBjdXJyZW50TWFwcGluZ3NbY2xlYW5dO1xuICAgICAgaWYgKGV4aXN0aW5nICE9PSB1bmRlZmluZWQgJiYgZXhpc3RpbmcgIT09ICcnKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyAxLiBTZXNzaW9uIG1hdGNoIChlLmcuIGNvbXBhbnlJZCwgYnJhbmNoSWQsIHVzZXJJZClcbiAgICAgIGNvbnN0IHNlc3Npb25NYXRjaCA9XG4gICAgICAgIHRoaXMuc2Vzc2lvblNlcnZpY2U/Lm1hdGNoUGFyYW1ldGVyKGNsZWFuKSA/PyB0aGlzLnNlc3Npb25TZXJ2aWNlPy5tYXRjaFBhcmFtZXRlcihwYXJhbS5uYW1lKTtcbiAgICAgIGlmIChzZXNzaW9uTWF0Y2gpIHtcbiAgICAgICAgY3VycmVudE1hcHBpbmdzW3BhcmFtLm5hbWVdID0gYHt7c2Vzc2lvbi4ke3Nlc3Npb25NYXRjaC5zZXNzaW9uS2V5fX19YDtcbiAgICAgICAgY3VycmVudE1hcHBpbmdzW2NsZWFuXSA9IGB7e3Nlc3Npb24uJHtzZXNzaW9uTWF0Y2guc2Vzc2lvbktleX19fWA7XG4gICAgICAgIGNoYW5nZWQgPSB0cnVlO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gMi4gRXhpc3RpbmcgY2FudmFzIGZpZWxkIG1hdGNoXG4gICAgICBjb25zdCBtYXRjaGVkQ29tcCA9IHRoaXMuYWxsQ29tcG9uZW50cygpLmZpbmQoKGMpID0+IHtcbiAgICAgICAgaWYgKGMuaWQgPT09IHRoaXMuY29tcCgpLmlkKSByZXR1cm4gZmFsc2U7XG4gICAgICAgIGNvbnN0IGNrID0gKGMua2V5IHx8ICcnKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICBjb25zdCBjbCA9IGNsZWFuLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIHJldHVybiBjayA9PT0gY2wgfHwgY2sgPT09IHRvRmllbGRLZXkoY2wpO1xuICAgICAgfSk7XG4gICAgICBpZiAobWF0Y2hlZENvbXApIHtcbiAgICAgICAgY3VycmVudE1hcHBpbmdzW3BhcmFtLm5hbWVdID0gYHt7JHttYXRjaGVkQ29tcC5rZXl9fX1gO1xuICAgICAgICBjdXJyZW50TWFwcGluZ3NbY2xlYW5dID0gYHt7JHttYXRjaGVkQ29tcC5rZXl9fX1gO1xuICAgICAgICBjaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIDMuIEF1dG8tY3JlYXRlIG1pc3NpbmcgY2FudmFzIGZpZWxkIHNvIHVzZXIgY2FuIGZpbGwgaXQgZGlyZWN0bHkgb24gY2FudmFzXG4gICAgICBpZiAodGhpcy5kZXNpZ25lclN0YXRlKSB7XG4gICAgICAgIGNvbnN0IGxvd2VyID0gY2xlYW4udG9Mb3dlckNhc2UoKTtcbiAgICAgICAgbGV0IGNvbXBUeXBlID0gJ2lucHV0JztcbiAgICAgICAgaWYgKGxvd2VyLmluY2x1ZGVzKCdkYXRlJykgfHwgbG93ZXIuaW5jbHVkZXMoJ3RpbWUnKSB8fCBwYXJhbS5kYXRhVHlwZT8udG9Mb3dlckNhc2UoKS5pbmNsdWRlcygnZGF0ZScpKSB7XG4gICAgICAgICAgY29tcFR5cGUgPSAnZGF0ZSc7XG4gICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgcGFyYW0uZGF0YVR5cGU/LnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoJ2ludCcpIHx8XG4gICAgICAgICAgcGFyYW0uZGF0YVR5cGU/LnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoJ2RlY2ltYWwnKSB8fFxuICAgICAgICAgIHBhcmFtLmRhdGFUeXBlPy50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKCdudW1lcmljJykgfHxcbiAgICAgICAgICBwYXJhbS5kYXRhVHlwZT8udG9Mb3dlckNhc2UoKS5pbmNsdWRlcygnZmxvYXQnKSB8fFxuICAgICAgICAgIGxvd2VyLmluY2x1ZGVzKCdubycpIHx8XG4gICAgICAgICAgbG93ZXIuaW5jbHVkZXMoJ2lkJykgfHxcbiAgICAgICAgICBsb3dlci5pbmNsdWRlcygnYW1vdW50JykgfHxcbiAgICAgICAgICBsb3dlci5pbmNsdWRlcygncmF0ZScpIHx8XG4gICAgICAgICAgbG93ZXIuaW5jbHVkZXMoJ3F0eScpXG4gICAgICAgICkge1xuICAgICAgICAgIGNvbXBUeXBlID0gJ251bWJlcic7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBuZXdLZXkgPSB0b0ZpZWxkS2V5KGNsZWFuKTtcbiAgICAgICAgY29uc3QgbmV3TGFiZWwgPSBodW1hbml6ZUlkZW50aWZpZXIoY2xlYW4pO1xuICAgICAgICBjb25zdCBjcmVhdGVkID0gdGhpcy5kZXNpZ25lclN0YXRlLmFkZENvbXBvbmVudChjb21wVHlwZSwgdW5kZWZpbmVkLCB7XG4gICAgICAgICAga2V5OiBuZXdLZXksXG4gICAgICAgICAgbGFiZWw6IG5ld0xhYmVsLFxuICAgICAgICAgIHByb3BlcnRpZXM6IGNvbXBUeXBlID09PSAnZGF0ZScgPyB7IHBsYWNlaG9sZGVyOiAnU2VsZWN0ICcgKyBuZXdMYWJlbCB9IDoge30sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChjcmVhdGVkKSB7XG4gICAgICAgICAgY3VycmVudE1hcHBpbmdzW3BhcmFtLm5hbWVdID0gYHt7JHtjcmVhdGVkLmtleX19fWA7XG4gICAgICAgICAgY3VycmVudE1hcHBpbmdzW2NsZWFuXSA9IGB7eyR7Y3JlYXRlZC5rZXl9fX1gO1xuICAgICAgICAgIGNoYW5nZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZWQpIHtcbiAgICAgIHRoaXMudXBkYXRlRGF0YVNvdXJjZS5lbWl0KHtcbiAgICAgICAgLi4uKHRoaXMuY29tcCgpLmRhdGFTb3VyY2UgPz8geyBkaXNwbGF5RmllbGQ6ICcnLCB2YWx1ZUZpZWxkOiAnJyB9KSxcbiAgICAgICAgcGFyYW1ldGVyTWFwcGluZ3M6IGN1cnJlbnRNYXBwaW5ncyxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHNldFNvdXJjZVR5cGUodHlwZTogRHJvcGRvd25Tb3VyY2VUeXBlKTogdm9pZCB7XG4gICAgaWYgKHR5cGUgPT09ICdzdGF0aWMnKSB7XG4gICAgICB0aGlzLnVwZGF0ZURhdGFTb3VyY2UuZW1pdCh7XG4gICAgICAgIHNvdXJjZVR5cGU6ICdzdGF0aWMnLFxuICAgICAgICBkaXNwbGF5RmllbGQ6ICcnLFxuICAgICAgICB2YWx1ZUZpZWxkOiAnJyxcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmFsbEVudGl0aWVzKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLmxvYWRFbnRpdGllcygpO1xuICAgIH1cblxuICAgIGNvbnN0IGZpcnN0RW50aXR5ID0gdHlwZSA9PT0gJ3RhYmxlJyA/IHRoaXMuYXZhaWxhYmxlVGFibGVzKClbMF0/Lm5hbWUgOiB0aGlzLmF2YWlsYWJsZVByb2NlZHVyZXMoKVswXT8ubmFtZTtcbiAgICB0aGlzLnVwZGF0ZURhdGFTb3VyY2UuZW1pdCh7XG4gICAgICBzb3VyY2VUeXBlOiB0eXBlLFxuICAgICAgZW50aXR5TmFtZTogZmlyc3RFbnRpdHkgfHwgJycsXG4gICAgICBzY2hlbWE6ICdkYm8nLFxuICAgICAgZGlzcGxheUZpZWxkOiAnJyxcbiAgICAgIHZhbHVlRmllbGQ6ICcnLFxuICAgIH0pO1xuICB9XG5cbiAgb25FbnRpdHlTZWxlY3RlZChlbnRpdHlOYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnVwZGF0ZURhdGFTb3VyY2UuZW1pdCh7XG4gICAgICAuLi4odGhpcy5jb21wKCkuZGF0YVNvdXJjZSA/PyB7IGRpc3BsYXlGaWVsZDogJycsIHZhbHVlRmllbGQ6ICcnIH0pLFxuICAgICAgc291cmNlVHlwZTogdGhpcy5jdXJyZW50U291cmNlVHlwZSgpLFxuICAgICAgZW50aXR5TmFtZSxcbiAgICAgIHNjaGVtYTogJ2RibycsXG4gICAgICB2YWx1ZUZpZWxkOiAnJyxcbiAgICAgIGRpc3BsYXlGaWVsZDogJycsXG4gICAgfSk7XG4gIH1cblxuICBvblZhbHVlRmllbGRDaGFuZ2VkKHZhbHVlRmllbGQ6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMudXBkYXRlRGF0YVNvdXJjZS5lbWl0KHtcbiAgICAgIC4uLih0aGlzLmNvbXAoKS5kYXRhU291cmNlID8/IHsgZGlzcGxheUZpZWxkOiAnJywgdmFsdWVGaWVsZDogJycgfSksXG4gICAgICB2YWx1ZUZpZWxkLFxuICAgIH0pO1xuICB9XG5cbiAgb25EaXNwbGF5RmllbGRDaGFuZ2VkKGRpc3BsYXlGaWVsZDogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy51cGRhdGVEYXRhU291cmNlLmVtaXQoe1xuICAgICAgLi4uKHRoaXMuY29tcCgpLmRhdGFTb3VyY2UgPz8geyBkaXNwbGF5RmllbGQ6ICcnLCB2YWx1ZUZpZWxkOiAnJyB9KSxcbiAgICAgIGRpc3BsYXlGaWVsZCxcbiAgICB9KTtcbiAgfVxuXG4gIG9uRGVwZW5kc09uQ2hhbmdlZChwYXJlbnRLZXk6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMudXBkYXRlRGF0YVNvdXJjZS5lbWl0KHtcbiAgICAgIC4uLih0aGlzLmNvbXAoKS5kYXRhU291cmNlID8/IHsgZGlzcGxheUZpZWxkOiAnJywgdmFsdWVGaWVsZDogJycgfSksXG4gICAgICBkZXBlbmRzT246IHBhcmVudEtleSA/IFtwYXJlbnRLZXldIDogW10sXG4gICAgfSk7XG4gIH1cblxuICBnZXRQYXJhbVZhbHVlKHBhcmFtTmFtZTogc3RyaW5nKTogc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbiB7XG4gICAgY29uc3QgY2xlYW4gPSBwYXJhbU5hbWUucmVwbGFjZSgvXkAvLCAnJyk7XG4gICAgY29uc3QgbWFwcGluZ3MgPSB0aGlzLmNvbXAoKS5kYXRhU291cmNlPy5wYXJhbWV0ZXJNYXBwaW5ncyA/PyB7fTtcbiAgICByZXR1cm4gKFxuICAgICAgbWFwcGluZ3NbcGFyYW1OYW1lXSA/P1xuICAgICAgbWFwcGluZ3NbY2xlYW5dID8/XG4gICAgICBtYXBwaW5nc1tgQCR7Y2xlYW59YF0gPz9cbiAgICAgICcnXG4gICAgKTtcbiAgfVxuXG4gIHNldFBhcmFtVmFsdWUocGFyYW1OYW1lOiBzdHJpbmcsIHZhbHVlOiBzdHJpbmcgfCBudW1iZXIgfCBib29sZWFuKTogdm9pZCB7XG4gICAgY29uc3QgY2xlYW4gPSBwYXJhbU5hbWUucmVwbGFjZSgvXkAvLCAnJyk7XG4gICAgY29uc3QgZXhpc3RpbmcgPSB7IC4uLih0aGlzLmNvbXAoKS5kYXRhU291cmNlPy5wYXJhbWV0ZXJNYXBwaW5ncyA/PyB7fSkgfTtcbiAgICBleGlzdGluZ1twYXJhbU5hbWVdID0gdmFsdWU7XG4gICAgZXhpc3RpbmdbY2xlYW5dID0gdmFsdWU7XG4gICAgdGhpcy51cGRhdGVEYXRhU291cmNlLmVtaXQoe1xuICAgICAgLi4uKHRoaXMuY29tcCgpLmRhdGFTb3VyY2UgPz8geyBkaXNwbGF5RmllbGQ6ICcnLCB2YWx1ZUZpZWxkOiAnJyB9KSxcbiAgICAgIHBhcmFtZXRlck1hcHBpbmdzOiBleGlzdGluZyxcbiAgICB9KTtcbiAgfVxuXG4gIG9uUGFyYW1MaW5rZWRGaWVsZENoYW5nZShldnQ6IHsgcGFyYW1OYW1lOiBzdHJpbmc7IGZpZWxkS2V5OiBzdHJpbmc7IGlzTGlua2VkOiBib29sZWFuIH0pOiB2b2lkIHtcbiAgICBjb25zdCBjdXJyZW50RGVwZW5kc09uID0gWy4uLih0aGlzLmNvbXAoKS5kYXRhU291cmNlPy5kZXBlbmRzT24gPz8gW10pXTtcbiAgICBpZiAoZXZ0LmlzTGlua2VkICYmIGV2dC5maWVsZEtleSkge1xuICAgICAgaWYgKCFjdXJyZW50RGVwZW5kc09uLmluY2x1ZGVzKGV2dC5maWVsZEtleSkpIHtcbiAgICAgICAgY3VycmVudERlcGVuZHNPbi5wdXNoKGV2dC5maWVsZEtleSk7XG4gICAgICAgIHRoaXMudXBkYXRlRGF0YVNvdXJjZS5lbWl0KHtcbiAgICAgICAgICAuLi4odGhpcy5jb21wKCkuZGF0YVNvdXJjZSA/PyB7IGRpc3BsYXlGaWVsZDogJycsIHZhbHVlRmllbGQ6ICcnIH0pLFxuICAgICAgICAgIGRlcGVuZHNPbjogY3VycmVudERlcGVuZHNPbixcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgYWRkU3RhdGljT3B0aW9uKCk6IHZvaWQge1xuICAgIGNvbnN0IGN1cnJlbnQgPSBbLi4udGhpcy5zdGF0aWNPcHRpb25zKCldO1xuICAgIGNvbnN0IG5leHRJZHggPSBjdXJyZW50Lmxlbmd0aCArIDE7XG4gICAgY3VycmVudC5wdXNoKHsga2V5OiBTdHJpbmcobmV4dElkeCksIGxhYmVsOiBgT3B0aW9uICR7bmV4dElkeH1gIH0pO1xuICAgIHRoaXMudXBkYXRlUHJvcGVydHkuZW1pdCh7IGtleTogJ29wdGlvbnMnLCB2YWx1ZTogY3VycmVudCB9KTtcbiAgfVxuXG4gIHVwZGF0ZVN0YXRpY09wdGlvbihpbmRleDogbnVtYmVyLCBmaWVsZDogJ2tleScgfCAnbGFiZWwnLCB2YWw6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IGN1cnJlbnQgPSBbLi4udGhpcy5zdGF0aWNPcHRpb25zKCldO1xuICAgIGlmIChjdXJyZW50W2luZGV4XSkge1xuICAgICAgY3VycmVudFtpbmRleF0gPSB7IC4uLmN1cnJlbnRbaW5kZXhdLCBbZmllbGRdOiB2YWwgfTtcbiAgICAgIHRoaXMudXBkYXRlUHJvcGVydHkuZW1pdCh7IGtleTogJ29wdGlvbnMnLCB2YWx1ZTogY3VycmVudCB9KTtcbiAgICB9XG4gIH1cblxuICByZW1vdmVTdGF0aWNPcHRpb24oaW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IGN1cnJlbnQgPSB0aGlzLnN0YXRpY09wdGlvbnMoKS5maWx0ZXIoKF8sIGkpID0+IGkgIT09IGluZGV4KTtcbiAgICB0aGlzLnVwZGF0ZVByb3BlcnR5LmVtaXQoeyBrZXk6ICdvcHRpb25zJywgdmFsdWU6IGN1cnJlbnQgfSk7XG4gIH1cbn1cblxuIl19
|
|
369
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvcGVydHktZWRpdG9yLWRhdGFzb3VyY2UuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYndheXMtcmVwb3J0L3NyYy9saWIvZmVhdHVyZXMvZGVzaWduZXIvY29tcG9uZW50cy9wcm9wZXJ0eS1lZGl0b3IvcHJvcGVydHktZWRpdG9yLWRhdGFzb3VyY2UuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYndheXMtcmVwb3J0L3NyYy9saWIvZmVhdHVyZXMvZGVzaWduZXIvY29tcG9uZW50cy9wcm9wZXJ0eS1lZGl0b3IvcHJvcGVydHktZWRpdG9yLWRhdGFzb3VyY2UuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixTQUFTLEVBQ1QsUUFBUSxFQUNSLE1BQU0sRUFDTixNQUFNLEVBQ04sS0FBSyxFQUVMLE1BQU0sRUFDTixNQUFNLEdBQ1AsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQU03QyxPQUFPLEVBSUwsNEJBQTRCLEdBQzdCLE1BQU0sNkRBQTZELENBQUM7QUFDckUsT0FBTyxFQUNMLHlCQUF5QixFQUN6Qix1QkFBdUIsRUFDdkIsa0JBQWtCLEdBQ25CLE1BQU0sNkNBQTZDLENBQUM7QUFDckQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDhDQUE4QyxDQUFDO0FBQzFFLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLDBEQUEwRCxDQUFDO0FBQ3ZHLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQzdFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDJEQUEyRCxDQUFDO0FBQzdGLE9B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LG1CQUN0RSx1QkFBdUIsQ0FBQyxNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENvbXBvbmVudCxcbiAgY29tcHV0ZWQsXG4gIGVmZmVjdCxcbiAgaW5qZWN0LFxuICBpbnB1dCxcbiAgT25Jbml0LFxuICBvdXRwdXQsXG4gIHNpZ25hbCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQge1xuICBDb21wb25lbnREYXRhU291cmNlRGVmaW5pdGlvbixcbiAgRHJvcGRvd25Tb3VyY2VUeXBlLFxuICBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uLFxufSBmcm9tICcuLi8uLi8uLi8uLi9jb3JlL21vZGVscy9yZXBvcnQtY29tcG9uZW50Lm1vZGVsJztcbmltcG9ydCB7XG4gIERhdGFiYXNlRW50aXR5TWV0YWRhdGEsXG4gIEVudGl0eUNvbHVtbk1ldGFkYXRhLFxuICBQcm9jZWR1cmVQYXJhbWV0ZXJNZXRhZGF0YSxcbiAgUmVwb3J0U2NoZW1hRGlzY292ZXJ5QWRhcHRlcixcbn0gZnJvbSAnLi4vLi4vLi4vLi4vZGF0YS1hY2Nlc3MvY29udHJhY3RzL3NjaGVtYS1kaXNjb3ZlcnkuY29udHJhY3QnO1xuaW1wb3J0IHtcbiAgZGV0ZWN0RGVmYXVsdERpc3BsYXlGaWVsZCxcbiAgZGV0ZWN0RGVmYXVsdFZhbHVlRmllbGQsXG4gIGh1bWFuaXplSWRlbnRpZmllcixcbn0gZnJvbSAnLi4vLi4vLi4vLi4vY29yZS91dGlscy9pZGVudGlmaWVyLWh1bWFuaXplcic7XG5pbXBvcnQgeyB0b0ZpZWxkS2V5IH0gZnJvbSAnLi4vLi4vLi4vLi4vY29yZS91dGlscy9yZXBvcnQtcGFyYW1ldGVyLnV0aWwnO1xuaW1wb3J0IHsgUmVwb3J0U2Vzc2lvbkNvbnRleHRTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vLi4vY29yZS9zZXJ2aWNlcy9yZXBvcnQtc2Vzc2lvbi1jb250ZXh0LnNlcnZpY2UnO1xuaW1wb3J0IHsgRGVzaWduZXJTdGF0ZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9kZXNpZ25lci1zdGF0ZS5zZXJ2aWNlJztcbmltcG9ydCB7IFJwdEljb25Db21wb25lbnQgfSBmcm9tICcuLi8uLi8uLi8uLi9wcmltaXRpdmVzL2NvbXBvbmVudHMvaWNvbi9ycHQtaWNvbi5jb21wb25lbnQnO1xuaW1wb3J0IHsgUGFyYW1ldGVyQmluZGluZ0VkaXRvckNvbXBvbmVudCB9IGZyb20gJy4vcGFyYW1ldGVyLWJpbmRpbmctZWRpdG9yLmNvbXBvbmVudCc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU3RhdGljT3B0aW9uSXRlbSB7XG4gIGtleTogc3RyaW5nO1xuICBsYWJlbDogc3RyaW5nO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdycHQtcHJvcGVydHktZWRpdG9yLWRhdGFzb3VyY2UnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBGb3Jtc01vZHVsZSwgUnB0SWNvbkNvbXBvbmVudCwgUGFyYW1ldGVyQmluZGluZ0VkaXRvckNvbXBvbmVudF0sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICB0ZW1wbGF0ZVVybDogJy4vcHJvcGVydHktZWRpdG9yLWRhdGFzb3VyY2UuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9wcm9wZXJ0eS1lZGl0b3IuY29tbW9uLmNzcycsICcuL3Byb3BlcnR5LWVkaXRvci1kYXRhc291cmNlLmNvbXBvbmVudC5jc3MnXSxcbn0pXG5leHBvcnQgY2xhc3MgUHJvcGVydHlFZGl0b3JEYXRhc291cmNlQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgcHJpdmF0ZSByZWFkb25seSBkaXNjb3ZlcnlBZGFwdGVyID0gaW5qZWN0KFJlcG9ydFNjaGVtYURpc2NvdmVyeUFkYXB0ZXIsIHsgb3B0aW9uYWw6IHRydWUgfSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgc2Vzc2lvblNlcnZpY2UgPSBpbmplY3QoUmVwb3J0U2Vzc2lvbkNvbnRleHRTZXJ2aWNlLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuICBwcml2YXRlIHJlYWRvbmx5IGRlc2lnbmVyU3RhdGUgPSBpbmplY3QoRGVzaWduZXJTdGF0ZVNlcnZpY2UsIHsgb3B0aW9uYWw6IHRydWUgfSk7XG5cbiAgcmVhZG9ubHkgY29tcCA9IGlucHV0LnJlcXVpcmVkPFJlcG9ydENvbXBvbmVudERlZmluaXRpb24+KCk7XG4gIHJlYWRvbmx5IGFsbENvbXBvbmVudHMgPSBpbnB1dDxSZXBvcnRDb21wb25lbnREZWZpbml0aW9uW10+KFtdKTtcblxuICByZWFkb25seSB1cGRhdGVEYXRhU291cmNlID0gb3V0cHV0PENvbXBvbmVudERhdGFTb3VyY2VEZWZpbml0aW9uPigpO1xuICByZWFkb25seSB1cGRhdGVQcm9wZXJ0eSA9IG91dHB1dDx7IGtleTogc3RyaW5nOyB2YWx1ZTogdW5rbm93biB9PigpO1xuXG4gIHJlYWRvbmx5IGlzQWR2YW5jZWRNb2RlID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgcmVhZG9ubHkgaXNMb2FkaW5nRW50aXRpZXMgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICByZWFkb25seSBhbGxFbnRpdGllcyA9IHNpZ25hbDxEYXRhYmFzZUVudGl0eU1ldGFkYXRhW10+KFtdKTtcbiAgcmVhZG9ubHkgZW50aXR5Q29sdW1ucyA9IHNpZ25hbDxFbnRpdHlDb2x1bW5NZXRhZGF0YVtdPihbXSk7XG4gIHJlYWRvbmx5IHByb2NlZHVyZVBhcmFtZXRlcnMgPSBzaWduYWw8UHJvY2VkdXJlUGFyYW1ldGVyTWV0YWRhdGFbXT4oW10pO1xuXG4gIHJlYWRvbmx5IGN1cnJlbnRTb3VyY2VUeXBlID0gY29tcHV0ZWQ8RHJvcGRvd25Tb3VyY2VUeXBlPigoKSA9PiB7XG4gICAgY29uc3QgZHMgPSB0aGlzLmNvbXAoKS5kYXRhU291cmNlO1xuICAgIGlmIChkcz8uc291cmNlVHlwZSkgcmV0dXJuIGRzLnNvdXJjZVR5cGU7XG4gICAgaWYgKGRzPy5lbnRpdHlOYW1lKSByZXR1cm4gJ3RhYmxlJztcbiAgICByZXR1cm4gJ3N0YXRpYyc7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IHNlbGVjdGVkRW50aXR5ID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5jb21wKCkuZGF0YVNvdXJjZT8uZW50aXR5TmFtZSB8fCAnJyk7XG4gIHJlYWRvbmx5IHNlbGVjdGVkVmFsdWVGaWVsZCA9IGNvbXB1dGVkKCgpID0+IHRoaXMuY29tcCgpLmRhdGFTb3VyY2U/LnZhbHVlRmllbGQgfHwgJycpO1xuICByZWFkb25seSBzZWxlY3RlZERpc3BsYXlGaWVsZCA9IGNvbXB1dGVkKCgpID0+IHRoaXMuY29tcCgpLmRhdGFTb3VyY2U/LmRpc3BsYXlGaWVsZCB8fCAnJyk7XG4gIHJlYWRvbmx5IHNlbGVjdGVkRGVwZW5kc09uID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5jb21wKCkuZGF0YVNvdXJjZT8uZGVwZW5kc09uPy5bMF0gfHwgJycpO1xuXG4gIHJlYWRvbmx5IGF2YWlsYWJsZVRhYmxlcyA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICByZXR1cm4gdGhpcy5hbGxFbnRpdGllcygpXG4gICAgICAuZmlsdGVyKChlKSA9PiB7XG4gICAgICAgIGNvbnN0IHQgPSAoZS50eXBlIHx8ICcnKS50b0xvd2VyQ2FzZSgpO1xuICAgICAgICByZXR1cm4gdCA9PT0gJ3RhYmxlJyB8fCB0ID09PSAndmlldyc7XG4gICAgICB9KVxuICAgICAgLm1hcCgoZSkgPT4gKHtcbiAgICAgICAgLi4uZSxcbiAgICAgICAgZGlzcGxheU5hbWU6IGUuZnJpZW5kbHlOYW1lIHx8IGh1bWFuaXplSWRlbnRpZmllcihlLm5hbWUpLFxuICAgICAgfSkpO1xuICB9KTtcblxuICByZWFkb25seSBhdmFpbGFibGVQcm9jZWR1cmVzID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIHJldHVybiB0aGlzLmFsbEVudGl0aWVzKClcbiAgICAgIC5maWx0ZXIoKGUpID0+IHtcbiAgICAgICAgY29uc3QgdCA9IChlLnR5cGUgfHwgJycpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIHJldHVybiB0ID09PSAnc3RvcmVkX3Byb2NlZHVyZScgfHwgdCA9PT0gJ3Byb2NlZHVyZScgfHwgdC5pbmNsdWRlcygncHJvY2VkdXJlJyk7XG4gICAgICB9KVxuICAgICAgLm1hcCgoZSkgPT4gKHtcbiAgICAgICAgLi4uZSxcbiAgICAgICAgZGlzcGxheU5hbWU6IGUuZnJpZW5kbHlOYW1lIHx8IGh1bWFuaXplSWRlbnRpZmllcihlLm5hbWUpLFxuICAgICAgfSkpO1xuICB9KTtcblxuICByZWFkb25seSBhdmFpbGFibGVQYXJlbnRGaWVsZHMgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgcmV0dXJuIHRoaXMuYWxsQ29tcG9uZW50cygpLmZpbHRlcigoYykgPT4gYy5pZCAhPT0gdGhpcy5jb21wKCkuaWQpO1xuICB9KTtcblxuICByZWFkb25seSBzdGF0aWNPcHRpb25zID0gY29tcHV0ZWQ8U3RhdGljT3B0aW9uSXRlbVtdPigoKSA9PiB7XG4gICAgY29uc3Qgb3B0cyA9IHRoaXMuY29tcCgpLnByb3BlcnRpZXM/Llsnb3B0aW9ucyddO1xuICAgIGlmIChBcnJheS5pc0FycmF5KG9wdHMpKSB7XG4gICAgICByZXR1cm4gb3B0cy5tYXAoKG8pID0+ICh7IGtleTogU3RyaW5nKG8ua2V5ID8/IG8udmFsdWUgPz8gJycpLCBsYWJlbDogU3RyaW5nKG8ubGFiZWwgPz8gJycpIH0pKTtcbiAgICB9XG4gICAgcmV0dXJuIFtcbiAgICAgIHsga2V5OiAnMScsIGxhYmVsOiAnT3B0aW9uIDEnIH0sXG4gICAgICB7IGtleTogJzInLCBsYWJlbDogJ09wdGlvbiAyJyB9LFxuICAgIF07XG4gIH0pO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIGVmZmVjdChcbiAgICAgICgpID0+IHtcbiAgICAgICAgY29uc3QgZW50aXR5ID0gdGhpcy5zZWxlY3RlZEVudGl0eSgpO1xuICAgICAgICBjb25zdCB0eXBlID0gdGhpcy5jdXJyZW50U291cmNlVHlwZSgpO1xuICAgICAgICBpZiAoZW50aXR5ICYmICh0eXBlID09PSAndGFibGUnIHx8IHR5cGUgPT09ICdwcm9jZWR1cmUnKSkge1xuICAgICAgICAgIHRoaXMubG9hZEVudGl0eURldGFpbHMoZW50aXR5LCB0eXBlKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHsgYWxsb3dTaWduYWxXcml0ZXM6IHRydWUgfVxuICAgICk7XG4gIH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmxvYWRFbnRpdGllcygpO1xuICB9XG5cbiAgbG9hZEVudGl0aWVzKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5kaXNjb3ZlcnlBZGFwdGVyKSByZXR1cm47XG4gICAgdGhpcy5pc0xvYWRpbmdFbnRpdGllcy5zZXQodHJ1ZSk7XG4gICAgdGhpcy5kaXNjb3ZlcnlBZGFwdGVyLmdldEVudGl0aWVzKCkuc3Vic2NyaWJlKHtcbiAgICAgIG5leHQ6IChlbnRpdGllcykgPT4ge1xuICAgICAgICB0aGlzLmFsbEVudGl0aWVzLnNldChlbnRpdGllcyk7XG4gICAgICAgIHRoaXMuaXNMb2FkaW5nRW50aXRpZXMuc2V0KGZhbHNlKTtcbiAgICAgIH0sXG4gICAgICBlcnJvcjogKGVycikgPT4ge1xuICAgICAgICBjb25zb2xlLmVycm9yKCdbUHJvcGVydHlFZGl0b3JEYXRhc291cmNlXSBGYWlsZWQgdG8gbG9hZCBlbnRpdGllczonLCBlcnIpO1xuICAgICAgICB0aGlzLmlzTG9hZGluZ0VudGl0aWVzLnNldChmYWxzZSk7XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgbG9hZEVudGl0eURldGFpbHMoZW50aXR5TmFtZTogc3RyaW5nLCB0eXBlOiBEcm9wZG93blNvdXJjZVR5cGUpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZGlzY292ZXJ5QWRhcHRlcikgcmV0dXJuO1xuXG4gICAgY29uc3QgZGJUeXBlID0gdHlwZSA9PT0gJ3Byb2NlZHVyZScgPyAnc3RvcmVkX3Byb2NlZHVyZScgOiAndGFibGUnO1xuICAgIHRoaXMuZGlzY292ZXJ5QWRhcHRlci5nZXRDb2x1bW5zKGVudGl0eU5hbWUsICdkYm8nLCBkYlR5cGUpLnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAoY29scykgPT4ge1xuICAgICAgICB0aGlzLmVudGl0eUNvbHVtbnMuc2V0KGNvbHMpO1xuXG4gICAgICAgIC8vIEF1dG8tZGV0ZWN0IGRlZmF1bHQgdmFsdWVGaWVsZCBhbmQgZGlzcGxheUZpZWxkIGlmIG5vdCB5ZXQgc2V0XG4gICAgICAgIGNvbnN0IGN1cnJlbnRWYWwgPSB0aGlzLnNlbGVjdGVkVmFsdWVGaWVsZCgpO1xuICAgICAgICBjb25zdCBjdXJyZW50RGlzcCA9IHRoaXMuc2VsZWN0ZWREaXNwbGF5RmllbGQoKTtcbiAgICAgICAgY29uc3Qgc3VnZ2VzdGVkVmFsID0gZGV0ZWN0RGVmYXVsdFZhbHVlRmllbGQoY29scyk7XG4gICAgICAgIGNvbnN0IHN1Z2dlc3RlZERpc3AgPSBkZXRlY3REZWZhdWx0RGlzcGxheUZpZWxkKGNvbHMpO1xuXG4gICAgICAgIGlmICghY3VycmVudFZhbCB8fCAhY3VycmVudERpc3ApIHtcbiAgICAgICAgICB0aGlzLnVwZGF0ZURhdGFTb3VyY2UuZW1pdCh7XG4gICAgICAgICAgICAuLi4odGhpcy5jb21wKCkuZGF0YVNvdXJjZSA/PyB7IGRpc3BsYXlGaWVsZDogJycsIHZhbHVlRmllbGQ6ICcnIH0pLFxuICAgICAgICAgICAgc291cmNlVHlwZTogdHlwZSxcbiAgICAgICAgICAgIGVudGl0eU5hbWUsXG4gICAgICAgICAgICB2YWx1ZUZpZWxkOiBjdXJyZW50VmFsIHx8IHN1Z2dlc3RlZFZhbCB8fCBjb2xzWzBdPy5maWVsZCB8fCAnJyxcbiAgICAgICAgICAgIGRpc3BsYXlGaWVsZDogY3VycmVudERpc3AgfHwgc3VnZ2VzdGVkRGlzcCB8fCBjb2xzWzFdPy5maWVsZCB8fCBjb2xzWzBdPy5maWVsZCB8fCAnJyxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIGVycm9yOiAoZXJyKSA9PiBjb25zb2xlLmVycm9yKGBbUHJvcGVydHlFZGl0b3JEYXRhc291cmNlXSBGYWlsZWQgdG8gbG9hZCBjb2x1bW5zIGZvciAke2VudGl0eU5hbWV9OmAsIGVyciksXG4gICAgfSk7XG5cbiAgICBpZiAodHlwZSA9PT0gJ3Byb2NlZHVyZScpIHtcbiAgICAgIHRoaXMuZGlzY292ZXJ5QWRhcHRlci5nZXRQYXJhbWV0ZXJzKGVudGl0eU5hbWUsICdkYm8nKS5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAocGFyYW1zKSA9PiB7XG4gICAgICAgICAgdGhpcy5wcm9jZWR1cmVQYXJhbWV0ZXJzLnNldChwYXJhbXMpO1xuICAgICAgICAgIC8vIE9ubHkgYXV0by1saW5rIHRvIGV4aXN0aW5nIHNlc3Npb24gb3IgZXhpc3RpbmcgY2FudmFzIGZpZWxkcy5cbiAgICAgICAgICAvLyBORVZFUiBtdXRhdGUgY2FudmFzIG9yIGNyZWF0ZSBuZXcgY29tcG9uZW50cyBhdXRvbWF0aWNhbGx5IVxuICAgICAgICAgIHRoaXMuYXV0b0xpbmtFeGlzdGluZ1BhcmFtZXRlcnMocGFyYW1zKTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IChlcnIpID0+IGNvbnNvbGUuZXJyb3IoYFtQcm9wZXJ0eUVkaXRvckRhdGFzb3VyY2VdIEZhaWxlZCB0byBsb2FkIHBhcmFtcyBmb3IgJHtlbnRpdHlOYW1lfTpgLCBlcnIpLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE5vbi1kZXN0cnVjdGl2ZSBsaW5raW5nOiBiaW5kcyBwYXJhbWV0ZXJzIHRvIHNlc3Npb24gb3IgYWxyZWFkeS1leGlzdGluZyBjYW52YXMgZmllbGRzLlxuICAgKiBOZXZlciBtdXRhdGVzIG9yIGFkZHMgbmV3IGNvbXBvbmVudHMgdG8gdGhlIGNhbnZhcy5cbiAgICovXG4gIGF1dG9MaW5rRXhpc3RpbmdQYXJhbWV0ZXJzKHBhcmFtc0xpc3Q/OiBQcm9jZWR1cmVQYXJhbWV0ZXJNZXRhZGF0YVtdKTogdm9pZCB7XG4gICAgY29uc3QgcGFyYW1zID0gcGFyYW1zTGlzdCB8fCB0aGlzLnByb2NlZHVyZVBhcmFtZXRlcnMoKTtcbiAgICBpZiAoIXBhcmFtcyB8fCBwYXJhbXMubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgICBjb25zdCBjdXJyZW50TWFwcGluZ3MgPSB7IC4uLih0aGlzLmNvbXAoKS5kYXRhU291cmNlPy5wYXJhbWV0ZXJNYXBwaW5ncyA/PyB7fSkgfTtcbiAgICBsZXQgY2hhbmdlZCA9IGZhbHNlO1xuXG4gICAgZm9yIChjb25zdCBwYXJhbSBvZiBwYXJhbXMpIHtcbiAgICAgIGNvbnN0IGNsZWFuID0gcGFyYW0ubmFtZS5yZXBsYWNlKC9eQC8sICcnKTtcbiAgICAgIGNvbnN0IGV4aXN0aW5nID0gY3VycmVudE1hcHBpbmdzW3BhcmFtLm5hbWVdID8/IGN1cnJlbnRNYXBwaW5nc1tjbGVhbl07XG4gICAgICBpZiAoZXhpc3RpbmcgIT09IHVuZGVmaW5lZCAmJiBleGlzdGluZyAhPT0gJycpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIDEuIFNlc3Npb24gbWF0Y2ggKGUuZy4gY29tcGFueUlkLCBicmFuY2hJZCwgdXNlcklkKVxuICAgICAgY29uc3Qgc2Vzc2lvbk1hdGNoID1cbiAgICAgICAgdGhpcy5zZXNzaW9uU2VydmljZT8ubWF0Y2hQYXJhbWV0ZXIoY2xlYW4pID8/IHRoaXMuc2Vzc2lvblNlcnZpY2U/Lm1hdGNoUGFyYW1ldGVyKHBhcmFtLm5hbWUpO1xuICAgICAgaWYgKHNlc3Npb25NYXRjaCkge1xuICAgICAgICBjdXJyZW50TWFwcGluZ3NbcGFyYW0ubmFtZV0gPSBge3tzZXNzaW9uLiR7c2Vzc2lvbk1hdGNoLnNlc3Npb25LZXl9fX1gO1xuICAgICAgICBjdXJyZW50TWFwcGluZ3NbY2xlYW5dID0gYHt7c2Vzc2lvbi4ke3Nlc3Npb25NYXRjaC5zZXNzaW9uS2V5fX19YDtcbiAgICAgICAgY2hhbmdlZCA9IHRydWU7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyAyLiBFeGlzdGluZyBjYW52YXMgZmllbGQgbWF0Y2hcbiAgICAgIGNvbnN0IG1hdGNoZWRDb21wID0gdGhpcy5hbGxDb21wb25lbnRzKCkuZmluZCgoYykgPT4ge1xuICAgICAgICBpZiAoYy5pZCA9PT0gdGhpcy5jb21wKCkuaWQpIHJldHVybiBmYWxzZTtcbiAgICAgICAgY29uc3QgY2sgPSAoYy5rZXkgfHwgJycpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIGNvbnN0IGNsID0gY2xlYW4udG9Mb3dlckNhc2UoKTtcbiAgICAgICAgcmV0dXJuIGNrID09PSBjbCB8fCBjayA9PT0gdG9GaWVsZEtleShjbCk7XG4gICAgICB9KTtcbiAgICAgIGlmIChtYXRjaGVkQ29tcCkge1xuICAgICAgICBjdXJyZW50TWFwcGluZ3NbcGFyYW0ubmFtZV0gPSBge3ske21hdGNoZWRDb21wLmtleX19fWA7XG4gICAgICAgIGN1cnJlbnRNYXBwaW5nc1tjbGVhbl0gPSBge3ske21hdGNoZWRDb21wLmtleX19fWA7XG4gICAgICAgIGNoYW5nZWQgPSB0cnVlO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY2hhbmdlZCkge1xuICAgICAgdGhpcy51cGRhdGVEYXRhU291cmNlLmVtaXQoe1xuICAgICAgICAuLi4odGhpcy5jb21wKCkuZGF0YVNvdXJjZSA/PyB7IGRpc3BsYXlGaWVsZDogJycsIHZhbHVlRmllbGQ6ICcnIH0pLFxuICAgICAgICBwYXJhbWV0ZXJNYXBwaW5nczogY3VycmVudE1hcHBpbmdzLFxuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEV4cGxpY2l0IHVzZXItaW5pdGlhdGVkIGFjdGlvbjogbGlua3MgZXhpc3RpbmcgZmllbGRzLCBhbmQgY3JlYXRlcyBtaXNzaW5nIGZpbHRlciBpbnB1dHMgb24gY2FudmFzLlxuICAgKiBSZXN0b3JlcyBzZWxlY3Rpb24gdG8gdGhlIGN1cnJlbnQgZHJvcGRvd24gY29tcG9uZW50IHNvIHRoZSB1c2VyIHN0YXlzIGluIHRoaXMgcHJvcGVydHkgZWRpdG9yLlxuICAgKi9cbiAgYXV0b1dpcmVBbGxQYXJhbWV0ZXJzKHBhcmFtc0xpc3Q/OiBQcm9jZWR1cmVQYXJhbWV0ZXJNZXRhZGF0YVtdKTogdm9pZCB7XG4gICAgY29uc3QgcGFyYW1zID0gcGFyYW1zTGlzdCB8fCB0aGlzLnByb2NlZHVyZVBhcmFtZXRlcnMoKTtcbiAgICBpZiAoIXBhcmFtcyB8fCBwYXJhbXMubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgICBjb25zdCBjdXJyZW50TWFwcGluZ3MgPSB7IC4uLih0aGlzLmNvbXAoKS5kYXRhU291cmNlPy5wYXJhbWV0ZXJNYXBwaW5ncyA/PyB7fSkgfTtcbiAgICBsZXQgY2hhbmdlZCA9IGZhbHNlO1xuXG4gICAgZm9yIChjb25zdCBwYXJhbSBvZiBwYXJhbXMpIHtcbiAgICAgIGNvbnN0IGNsZWFuID0gcGFyYW0ubmFtZS5yZXBsYWNlKC9eQC8sICcnKTtcbiAgICAgIGNvbnN0IGV4aXN0aW5nID0gY3VycmVudE1hcHBpbmdzW3BhcmFtLm5hbWVdID8/IGN1cnJlbnRNYXBwaW5nc1tjbGVhbl07XG4gICAgICBpZiAoZXhpc3RpbmcgIT09IHVuZGVmaW5lZCAmJiBleGlzdGluZyAhPT0gJycpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIDEuIFNlc3Npb24gbWF0Y2ggKGUuZy4gY29tcGFueUlkLCBicmFuY2hJZCwgdXNlcklkKVxuICAgICAgY29uc3Qgc2Vzc2lvbk1hdGNoID1cbiAgICAgICAgdGhpcy5zZXNzaW9uU2VydmljZT8ubWF0Y2hQYXJhbWV0ZXIoY2xlYW4pID8/IHRoaXMuc2Vzc2lvblNlcnZpY2U/Lm1hdGNoUGFyYW1ldGVyKHBhcmFtLm5hbWUpO1xuICAgICAgaWYgKHNlc3Npb25NYXRjaCkge1xuICAgICAgICBjdXJyZW50TWFwcGluZ3NbcGFyYW0ubmFtZV0gPSBge3tzZXNzaW9uLiR7c2Vzc2lvbk1hdGNoLnNlc3Npb25LZXl9fX1gO1xuICAgICAgICBjdXJyZW50TWFwcGluZ3NbY2xlYW5dID0gYHt7c2Vzc2lvbi4ke3Nlc3Npb25NYXRjaC5zZXNzaW9uS2V5fX19YDtcbiAgICAgICAgY2hhbmdlZCA9IHRydWU7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICAvLyAyLiBFeGlzdGluZyBjYW52YXMgZmllbGQgbWF0Y2hcbiAgICAgIGNvbnN0IG1hdGNoZWRDb21wID0gdGhpcy5hbGxDb21wb25lbnRzKCkuZmluZCgoYykgPT4ge1xuICAgICAgICBpZiAoYy5pZCA9PT0gdGhpcy5jb21wKCkuaWQpIHJldHVybiBmYWxzZTtcbiAgICAgICAgY29uc3QgY2sgPSAoYy5rZXkgfHwgJycpLnRvTG93ZXJDYXNlKCk7XG4gICAgICAgIGNvbnN0IGNsID0gY2xlYW4udG9Mb3dlckNhc2UoKTtcbiAgICAgICAgcmV0dXJuIGNrID09PSBjbCB8fCBjayA9PT0gdG9GaWVsZEtleShjbCk7XG4gICAgICB9KTtcbiAgICAgIGlmIChtYXRjaGVkQ29tcCkge1xuICAgICAgICBjdXJyZW50TWFwcGluZ3NbcGFyYW0ubmFtZV0gPSBge3ske21hdGNoZWRDb21wLmtleX19fWA7XG4gICAgICAgIGN1cnJlbnRNYXBwaW5nc1tjbGVhbl0gPSBge3ske21hdGNoZWRDb21wLmtleX19fWA7XG4gICAgICAgIGNoYW5nZWQgPSB0cnVlO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gMy4gQXV0by1jcmVhdGUgbWlzc2luZyBjYW52YXMgZmllbGQgd2hlbiBleHBsaWNpdGx5IHJlcXVlc3RlZCBieSB1c2VyXG4gICAgICBpZiAodGhpcy5kZXNpZ25lclN0YXRlKSB7XG4gICAgICAgIGNvbnN0IGxvd2VyID0gY2xlYW4udG9Mb3dlckNhc2UoKTtcbiAgICAgICAgbGV0IGNvbXBUeXBlID0gJ2lucHV0JztcbiAgICAgICAgaWYgKGxvd2VyLmluY2x1ZGVzKCdkYXRlJykgfHwgbG93ZXIuaW5jbHVkZXMoJ3RpbWUnKSB8fCBwYXJhbS5kYXRhVHlwZT8udG9Mb3dlckNhc2UoKS5pbmNsdWRlcygnZGF0ZScpKSB7XG4gICAgICAgICAgY29tcFR5cGUgPSAnZGF0ZSc7XG4gICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgcGFyYW0uZGF0YVR5cGU/LnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoJ2ludCcpIHx8XG4gICAgICAgICAgcGFyYW0uZGF0YVR5cGU/LnRvTG93ZXJDYXNlKCkuaW5jbHVkZXMoJ2RlY2ltYWwnKSB8fFxuICAgICAgICAgIHBhcmFtLmRhdGFUeXBlPy50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKCdudW1lcmljJykgfHxcbiAgICAgICAgICBwYXJhbS5kYXRhVHlwZT8udG9Mb3dlckNhc2UoKS5pbmNsdWRlcygnZmxvYXQnKSB8fFxuICAgICAgICAgIGxvd2VyLmluY2x1ZGVzKCdubycpIHx8XG4gICAgICAgICAgbG93ZXIuaW5jbHVkZXMoJ2lkJykgfHxcbiAgICAgICAgICBsb3dlci5pbmNsdWRlcygnYW1vdW50JykgfHxcbiAgICAgICAgICBsb3dlci5pbmNsdWRlcygncmF0ZScpIHx8XG4gICAgICAgICAgbG93ZXIuaW5jbHVkZXMoJ3F0eScpXG4gICAgICAgICkge1xuICAgICAgICAgIGNvbXBUeXBlID0gJ251bWJlcic7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBuZXdLZXkgPSB0b0ZpZWxkS2V5KGNsZWFuKTtcbiAgICAgICAgY29uc3QgbmV3TGFiZWwgPSBodW1hbml6ZUlkZW50aWZpZXIoY2xlYW4pO1xuICAgICAgICBjb25zdCBjcmVhdGVkID0gdGhpcy5kZXNpZ25lclN0YXRlLmFkZENvbXBvbmVudChjb21wVHlwZSwgdW5kZWZpbmVkLCB7XG4gICAgICAgICAga2V5OiBuZXdLZXksXG4gICAgICAgICAgbGFiZWw6IG5ld0xhYmVsLFxuICAgICAgICAgIHByb3BlcnRpZXM6IGNvbXBUeXBlID09PSAnZGF0ZScgPyB7IHBsYWNlaG9sZGVyOiAnU2VsZWN0ICcgKyBuZXdMYWJlbCB9IDoge30sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChjcmVhdGVkKSB7XG4gICAgICAgICAgY3VycmVudE1hcHBpbmdzW3BhcmFtLm5hbWVdID0gYHt7JHtjcmVhdGVkLmtleX19fWA7XG4gICAgICAgICAgY3VycmVudE1hcHBpbmdzW2NsZWFuXSA9IGB7eyR7Y3JlYXRlZC5rZXl9fX1gO1xuICAgICAgICAgIGNoYW5nZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gUmVzdG9yZSBzZWxlY3Rpb24gdG8gY3VycmVudCBkcm9wZG93biBzbyB1c2VyIGlzIG5vdCBuYXZpZ2F0ZWQgYXdheVxuICAgIGlmICh0aGlzLmRlc2lnbmVyU3RhdGUpIHtcbiAgICAgIHRoaXMuZGVzaWduZXJTdGF0ZS5zZWxlY3RDb21wb25lbnQodGhpcy5jb21wKCkuaWQpO1xuICAgIH1cblxuICAgIGlmIChjaGFuZ2VkKSB7XG4gICAgICB0aGlzLnVwZGF0ZURhdGFTb3VyY2UuZW1pdCh7XG4gICAgICAgIC4uLih0aGlzLmNvbXAoKS5kYXRhU291cmNlID8/IHsgZGlzcGxheUZpZWxkOiAnJywgdmFsdWVGaWVsZDogJycgfSksXG4gICAgICAgIHBhcmFtZXRlck1hcHBpbmdzOiBjdXJyZW50TWFwcGluZ3MsXG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICBzZXRTb3VyY2VUeXBlKHR5cGU6IERyb3Bkb3duU291cmNlVHlwZSk6IHZvaWQge1xuICAgIGlmICh0eXBlID09PSAnc3RhdGljJykge1xuICAgICAgdGhpcy51cGRhdGVEYXRhU291cmNlLmVtaXQoe1xuICAgICAgICBzb3VyY2VUeXBlOiAnc3RhdGljJyxcbiAgICAgICAgZGlzcGxheUZpZWxkOiAnJyxcbiAgICAgICAgdmFsdWVGaWVsZDogJycsXG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5hbGxFbnRpdGllcygpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5sb2FkRW50aXRpZXMoKTtcbiAgICB9XG5cbiAgICBjb25zdCBjdXJyZW50RW50aXR5ID0gdGhpcy5jb21wKCkuZGF0YVNvdXJjZT8uZW50aXR5TmFtZTtcbiAgICBjb25zdCBpc1ZhbGlkRm9yVHlwZSA9XG4gICAgICB0eXBlID09PSAndGFibGUnXG4gICAgICAgID8gdGhpcy5hdmFpbGFibGVUYWJsZXMoKS5zb21lKCh0KSA9PiB0Lm5hbWUgPT09IGN1cnJlbnRFbnRpdHkpXG4gICAgICAgIDogdGhpcy5hdmFpbGFibGVQcm9jZWR1cmVzKCkuc29tZSgocCkgPT4gcC5uYW1lID09PSBjdXJyZW50RW50aXR5KTtcblxuICAgIHRoaXMudXBkYXRlRGF0YVNvdXJjZS5lbWl0KHtcbiAgICAgIHNvdXJjZVR5cGU6IHR5cGUsXG4gICAgICBlbnRpdHlOYW1lOiBpc1ZhbGlkRm9yVHlwZSA/IChjdXJyZW50RW50aXR5IHx8ICcnKSA6ICcnLFxuICAgICAgc2NoZW1hOiAnZGJvJyxcbiAgICAgIGRpc3BsYXlGaWVsZDogJycsXG4gICAgICB2YWx1ZUZpZWxkOiAnJyxcbiAgICB9KTtcbiAgfVxuXG4gIG9uRW50aXR5U2VsZWN0ZWQoZW50aXR5TmFtZTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy51cGRhdGVEYXRhU291cmNlLmVtaXQoe1xuICAgICAgLi4uKHRoaXMuY29tcCgpLmRhdGFTb3VyY2UgPz8geyBkaXNwbGF5RmllbGQ6ICcnLCB2YWx1ZUZpZWxkOiAnJyB9KSxcbiAgICAgIHNvdXJjZVR5cGU6IHRoaXMuY3VycmVudFNvdXJjZVR5cGUoKSxcbiAgICAgIGVudGl0eU5hbWUsXG4gICAgICBzY2hlbWE6ICdkYm8nLFxuICAgICAgdmFsdWVGaWVsZDogJycsXG4gICAgICBkaXNwbGF5RmllbGQ6ICcnLFxuICAgIH0pO1xuICB9XG5cbiAgb25WYWx1ZUZpZWxkQ2hhbmdlZCh2YWx1ZUZpZWxkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnVwZGF0ZURhdGFTb3VyY2UuZW1pdCh7XG4gICAgICAuLi4odGhpcy5jb21wKCkuZGF0YVNvdXJjZSA/PyB7IGRpc3BsYXlGaWVsZDogJycsIHZhbHVlRmllbGQ6ICcnIH0pLFxuICAgICAgdmFsdWVGaWVsZCxcbiAgICB9KTtcbiAgfVxuXG4gIG9uRGlzcGxheUZpZWxkQ2hhbmdlZChkaXNwbGF5RmllbGQ6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMudXBkYXRlRGF0YVNvdXJjZS5lbWl0KHtcbiAgICAgIC4uLih0aGlzLmNvbXAoKS5kYXRhU291cmNlID8/IHsgZGlzcGxheUZpZWxkOiAnJywgdmFsdWVGaWVsZDogJycgfSksXG4gICAgICBkaXNwbGF5RmllbGQsXG4gICAgfSk7XG4gIH1cblxuICBvbkRlcGVuZHNPbkNoYW5nZWQocGFyZW50S2V5OiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnVwZGF0ZURhdGFTb3VyY2UuZW1pdCh7XG4gICAgICAuLi4odGhpcy5jb21wKCkuZGF0YVNvdXJjZSA/PyB7IGRpc3BsYXlGaWVsZDogJycsIHZhbHVlRmllbGQ6ICcnIH0pLFxuICAgICAgZGVwZW5kc09uOiBwYXJlbnRLZXkgPyBbcGFyZW50S2V5XSA6IFtdLFxuICAgIH0pO1xuICB9XG5cbiAgZ2V0UGFyYW1WYWx1ZShwYXJhbU5hbWU6IHN0cmluZyk6IHN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4ge1xuICAgIGNvbnN0IGNsZWFuID0gcGFyYW1OYW1lLnJlcGxhY2UoL15ALywgJycpO1xuICAgIGNvbnN0IG1hcHBpbmdzID0gdGhpcy5jb21wKCkuZGF0YVNvdXJjZT8ucGFyYW1ldGVyTWFwcGluZ3MgPz8ge307XG4gICAgcmV0dXJuIChcbiAgICAgIG1hcHBpbmdzW3BhcmFtTmFtZV0gPz9cbiAgICAgIG1hcHBpbmdzW2NsZWFuXSA/P1xuICAgICAgbWFwcGluZ3NbYEAke2NsZWFufWBdID8/XG4gICAgICAnJ1xuICAgICk7XG4gIH1cblxuICBzZXRQYXJhbVZhbHVlKHBhcmFtTmFtZTogc3RyaW5nLCB2YWx1ZTogc3RyaW5nIHwgbnVtYmVyIHwgYm9vbGVhbik6IHZvaWQge1xuICAgIGNvbnN0IGNsZWFuID0gcGFyYW1OYW1lLnJlcGxhY2UoL15ALywgJycpO1xuICAgIGNvbnN0IGV4aXN0aW5nID0geyAuLi4odGhpcy5jb21wKCkuZGF0YVNvdXJjZT8ucGFyYW1ldGVyTWFwcGluZ3MgPz8ge30pIH07XG4gICAgZXhpc3RpbmdbcGFyYW1OYW1lXSA9IHZhbHVlO1xuICAgIGV4aXN0aW5nW2NsZWFuXSA9IHZhbHVlO1xuICAgIHRoaXMudXBkYXRlRGF0YVNvdXJjZS5lbWl0KHtcbiAgICAgIC4uLih0aGlzLmNvbXAoKS5kYXRhU291cmNlID8/IHsgZGlzcGxheUZpZWxkOiAnJywgdmFsdWVGaWVsZDogJycgfSksXG4gICAgICBwYXJhbWV0ZXJNYXBwaW5nczogZXhpc3RpbmcsXG4gICAgfSk7XG4gIH1cblxuICBvblBhcmFtTGlua2VkRmllbGRDaGFuZ2UoZXZ0OiB7IHBhcmFtTmFtZTogc3RyaW5nOyBmaWVsZEtleTogc3RyaW5nOyBpc0xpbmtlZDogYm9vbGVhbiB9KTogdm9pZCB7XG4gICAgY29uc3QgY3VycmVudERlcGVuZHNPbiA9IFsuLi4odGhpcy5jb21wKCkuZGF0YVNvdXJjZT8uZGVwZW5kc09uID8/IFtdKV07XG4gICAgaWYgKGV2dC5pc0xpbmtlZCAmJiBldnQuZmllbGRLZXkpIHtcbiAgICAgIGlmICghY3VycmVudERlcGVuZHNPbi5pbmNsdWRlcyhldnQuZmllbGRLZXkpKSB7XG4gICAgICAgIGN1cnJlbnREZXBlbmRzT24ucHVzaChldnQuZmllbGRLZXkpO1xuICAgICAgICB0aGlzLnVwZGF0ZURhdGFTb3VyY2UuZW1pdCh7XG4gICAgICAgICAgLi4uKHRoaXMuY29tcCgpLmRhdGFTb3VyY2UgPz8geyBkaXNwbGF5RmllbGQ6ICcnLCB2YWx1ZUZpZWxkOiAnJyB9KSxcbiAgICAgICAgICBkZXBlbmRzT246IGN1cnJlbnREZXBlbmRzT24sXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGFkZFN0YXRpY09wdGlvbigpOiB2b2lkIHtcbiAgICBjb25zdCBjdXJyZW50ID0gWy4uLnRoaXMuc3RhdGljT3B0aW9ucygpXTtcbiAgICBjb25zdCBuZXh0SWR4ID0gY3VycmVudC5sZW5ndGggKyAxO1xuICAgIGN1cnJlbnQucHVzaCh7IGtleTogU3RyaW5nKG5leHRJZHgpLCBsYWJlbDogYE9wdGlvbiAke25leHRJZHh9YCB9KTtcbiAgICB0aGlzLnVwZGF0ZVByb3BlcnR5LmVtaXQoeyBrZXk6ICdvcHRpb25zJywgdmFsdWU6IGN1cnJlbnQgfSk7XG4gIH1cblxuICB1cGRhdGVTdGF0aWNPcHRpb24oaW5kZXg6IG51bWJlciwgZmllbGQ6ICdrZXknIHwgJ2xhYmVsJywgdmFsOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBjdXJyZW50ID0gWy4uLnRoaXMuc3RhdGljT3B0aW9ucygpXTtcbiAgICBpZiAoY3VycmVudFtpbmRleF0pIHtcbiAgICAgIGN1cnJlbnRbaW5kZXhdID0geyAuLi5jdXJyZW50W2luZGV4XSwgW2ZpZWxkXTogdmFsIH07XG4gICAgICB0aGlzLnVwZGF0ZVByb3BlcnR5LmVtaXQoeyBrZXk6ICdvcHRpb25zJywgdmFsdWU6IGN1cnJlbnQgfSk7XG4gICAgfVxuICB9XG5cbiAgcmVtb3ZlU3RhdGljT3B0aW9uKGluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5zdGF0aWNPcHRpb25zKCkuZmlsdGVyKChfLCBpKSA9PiBpICE9PSBpbmRleCk7XG4gICAgdGhpcy51cGRhdGVQcm9wZXJ0eS5lbWl0KHsga2V5OiAnb3B0aW9ucycsIHZhbHVlOiBjdXJyZW50IH0pO1xuICB9XG59XG5cbiIsIiAgICA8ZGl2IGNsYXNzPVwicHJvcGVydHktZ3JvdXBcIj5cbiAgICAgIDwhLS0gMS4gSGVhZGVyIHdpdGggU2ltcGxlIC8gQWR2YW5jZWQgTW9kZSBUb2dnbGUgLS0+XG4gICAgICA8ZGl2IGNsYXNzPVwiZGF0YXNvdXJjZS1oZWFkZXItYmFyXCI+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJncm91cC10aXRsZVwiPk9wdGlvbnMgRGF0YSBTb3VyY2U8L2Rpdj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm1vZGUtdG9nZ2xlLXBpbGxcIj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGNsYXNzPVwicGlsbC1idG5cIlxuICAgICAgICAgICAgW2NsYXNzLmFjdGl2ZV09XCIhaXNBZHZhbmNlZE1vZGUoKVwiXG4gICAgICAgICAgICAoY2xpY2spPVwiaXNBZHZhbmNlZE1vZGUuc2V0KGZhbHNlKVwiXG4gICAgICAgICAgICB0aXRsZT1cIlNpbXBsaWZpZWQgdmlldyBmb3IgYnVzaW5lc3MgdXNlcnMgd2l0aCBmcmllbmRseSBuYW1lc1wiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgU2ltcGxlXG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICBjbGFzcz1cInBpbGwtYnRuXCJcbiAgICAgICAgICAgIFtjbGFzcy5hY3RpdmVdPVwiaXNBZHZhbmNlZE1vZGUoKVwiXG4gICAgICAgICAgICAoY2xpY2spPVwiaXNBZHZhbmNlZE1vZGUuc2V0KHRydWUpXCJcbiAgICAgICAgICAgIHRpdGxlPVwiVGVjaG5pY2FsIHZpZXcgd2l0aCBTUUwgdHlwZXMgYW5kIGV4cHJlc3Npb25zXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICBBZHZhbmNlZFxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIDIuIFNvdXJjZSBUeXBlIFNlZ21lbnRlZCBTd2l0Y2hlciAtLT5cbiAgICAgIDxkaXYgY2xhc3M9XCJzb3VyY2UtdHlwZS1zd2l0Y2hlclwiPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgY2xhc3M9XCJzb3VyY2UtdGFiLWJ0blwiXG4gICAgICAgICAgW2NsYXNzLmFjdGl2ZV09XCJjdXJyZW50U291cmNlVHlwZSgpID09PSAndGFibGUnXCJcbiAgICAgICAgICAoY2xpY2spPVwic2V0U291cmNlVHlwZSgndGFibGUnKVwiXG4gICAgICAgID5cbiAgICAgICAgICA8cnB0LWljb24gbmFtZT1cInRhYmxlXCIgW3NpemVdPVwiMTJcIiAvPlxuICAgICAgICAgIDxzcGFuPnt7IGlzQWR2YW5jZWRNb2RlKCkgPyAnVGFibGUgLyBWaWV3JyA6ICdEYXRhYmFzZSBUYWJsZScgfX08L3NwYW4+XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgY2xhc3M9XCJzb3VyY2UtdGFiLWJ0blwiXG4gICAgICAgICAgW2NsYXNzLmFjdGl2ZV09XCJjdXJyZW50U291cmNlVHlwZSgpID09PSAncHJvY2VkdXJlJ1wiXG4gICAgICAgICAgKGNsaWNrKT1cInNldFNvdXJjZVR5cGUoJ3Byb2NlZHVyZScpXCJcbiAgICAgICAgPlxuICAgICAgICAgIDxycHQtaWNvbiBuYW1lPVwiY29kZVwiIFtzaXplXT1cIjEyXCIgLz5cbiAgICAgICAgICA8c3Bhbj57eyBpc0FkdmFuY2VkTW9kZSgpID8gJ1N0b3JlZCBQcm9jJyA6ICdEYXRhIFF1ZXJ5JyB9fTwvc3Bhbj5cbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICBjbGFzcz1cInNvdXJjZS10YWItYnRuXCJcbiAgICAgICAgICBbY2xhc3MuYWN0aXZlXT1cImN1cnJlbnRTb3VyY2VUeXBlKCkgPT09ICdzdGF0aWMnXCJcbiAgICAgICAgICAoY2xpY2spPVwic2V0U291cmNlVHlwZSgnc3RhdGljJylcIlxuICAgICAgICA+XG4gICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJlZGl0XCIgW3NpemVdPVwiMTJcIiAvPlxuICAgICAgICAgIDxzcGFuPlN0YXRpYyBMaXN0PC9zcGFuPlxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIDNBLiBEQVRBQkFTRSBUQUJMRSAvIFZJRVcgQ09ORklHVVJBVElPTiAtLT5cbiAgICAgIEBpZiAoY3VycmVudFNvdXJjZVR5cGUoKSA9PT0gJ3RhYmxlJykge1xuICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtcm93XCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLWxhYmVsLXJvd1wiPlxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmllbGQtbGFiZWxcIj5cbiAgICAgICAgICAgICAge3sgaXNBZHZhbmNlZE1vZGUoKSA/ICdEYXRhYmFzZSBUYWJsZSAvIFZpZXcnIDogJ1NlbGVjdCBEYXRhIFNvdXJjZScgfX1cbiAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICBjbGFzcz1cImJ0bi1yZWZyZXNoLWVudGl0aWVzXCJcbiAgICAgICAgICAgICAgKGNsaWNrKT1cImxvYWRFbnRpdGllcygpXCJcbiAgICAgICAgICAgICAgdGl0bGU9XCJSZWZyZXNoIGF2YWlsYWJsZSB0YWJsZXMgZnJvbSBiYWNrZW5kXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJyZWZyZXNoXCIgW3NpemVdPVwiMTFcIiAvPlxuICAgICAgICAgICAgICA8c3Bhbj5SZWZyZXNoPC9zcGFuPlxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPHNlbGVjdFxuICAgICAgICAgICAgY2xhc3M9XCJmaWVsZC1zZWxlY3RcIlxuICAgICAgICAgICAgW25nTW9kZWxdPVwic2VsZWN0ZWRFbnRpdHkoKVwiXG4gICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJvbkVudGl0eVNlbGVjdGVkKCRldmVudClcIlxuICAgICAgICAgICAgW2Rpc2FibGVkXT1cImlzTG9hZGluZ0VudGl0aWVzKClcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIEBpZiAoaXNMb2FkaW5nRW50aXRpZXMoKSkge1xuICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCI+TG9hZGluZyB0YWJsZXMgZnJvbSBkYXRhYmFzZS4uLjwvb3B0aW9uPlxuICAgICAgICAgICAgfSBAZWxzZSBpZiAoYXZhaWxhYmxlVGFibGVzKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBObyB0YWJsZXMgZm91bmQgKENsaWNrIFJlZnJlc2gpIC0tPC9vcHRpb24+XG4gICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPi0tIENob29zZSBEYXRhIFRhYmxlIC0tPC9vcHRpb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBAZm9yICh0Ymwgb2YgYXZhaWxhYmxlVGFibGVzKCk7IHRyYWNrIHRibC5uYW1lKSB7XG4gICAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cInRibC5uYW1lXCI+XG4gICAgICAgICAgICAgICAgQGlmIChpc0FkdmFuY2VkTW9kZSgpKSB7XG4gICAgICAgICAgICAgICAgICB7eyB0Ymwuc2NoZW1hIH19Lnt7IHRibC5uYW1lIH19ICh7eyB0YmwudHlwZSB9fSlcbiAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHt7IHRibC5kaXNwbGF5TmFtZSB9fXt7IHRibC5jYXRlZ29yeSA/ICcg4oCiICcgKyB0YmwuY2F0ZWdvcnkgOiAnJyB9fVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIEBpZiAoc2VsZWN0ZWRFbnRpdHkoKSkge1xuICAgICAgICAgIDwhLS0gRGlzcGxheSBGaWVsZCAoVmlzaWJsZSB0ZXh0KSAtLT5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtcm93XCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtbGFiZWwtcm93XCI+XG4gICAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZpZWxkLWxhYmVsXCI+XG4gICAgICAgICAgICAgICAge3sgaXNBZHZhbmNlZE1vZGUoKSA/ICdEaXNwbGF5IEZpZWxkIChWaXNpYmxlIFRleHQpJyA6ICdUZXh0IFNob3duIGluIERyb3Bkb3duJyB9fVxuICAgICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgICBAaWYgKCFpc0FkdmFuY2VkTW9kZSgpKSB7XG4gICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJhdXRvLWJhZGdlXCIgdGl0bGU9XCJBdXRvLWRldGVjdGVkIGNvbHVtbiBmb3IgdGV4dCBsYWJlbFwiPkF1dG8tZGV0ZWN0ZWQ8L3NwYW4+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPHNlbGVjdFxuICAgICAgICAgICAgICBjbGFzcz1cImZpZWxkLXNlbGVjdFwiXG4gICAgICAgICAgICAgIFtuZ01vZGVsXT1cInNlbGVjdGVkRGlzcGxheUZpZWxkKClcIlxuICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJvbkRpc3BsYXlGaWVsZENoYW5nZWQoJGV2ZW50KVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBTZWxlY3QgRGlzcGxheSBDb2x1bW4gLS08L29wdGlvbj5cbiAgICAgICAgICAgICAgQGZvciAoY29sIG9mIGVudGl0eUNvbHVtbnMoKTsgdHJhY2sgY29sLmZpZWxkKSB7XG4gICAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwiY29sLmZpZWxkXCI+XG4gICAgICAgICAgICAgICAgICB7eyBjb2wubGFiZWwgfX0ge3sgaXNBZHZhbmNlZE1vZGUoKSA/ICcoJyArIGNvbC5kYXRhVHlwZSArICcpJyA6ICcnIH19XG4gICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPCEtLSBWYWx1ZSBGaWVsZCAoU3RvcmVkIGtleSkgLS0+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLXJvd1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLWxhYmVsLXJvd1wiPlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmaWVsZC1sYWJlbFwiPlxuICAgICAgICAgICAgICAgIHt7IGlzQWR2YW5jZWRNb2RlKCkgPyAnVmFsdWUgRmllbGQgKFN0b3JlZCBLZXkpJyA6ICdJbnRlcm5hbCBWYWx1ZSAvIEtleScgfX1cbiAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgQGlmICghaXNBZHZhbmNlZE1vZGUoKSkge1xuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYXV0by1iYWRnZVwiIHRpdGxlPVwiQXV0by1kZXRlY3RlZCBjb2x1bW4gZm9yIHByaW1hcnkgSURcIj5BdXRvLWRldGVjdGVkPC9zcGFuPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxzZWxlY3RcbiAgICAgICAgICAgICAgY2xhc3M9XCJmaWVsZC1zZWxlY3RcIlxuICAgICAgICAgICAgICBbbmdNb2RlbF09XCJzZWxlY3RlZFZhbHVlRmllbGQoKVwiXG4gICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIm9uVmFsdWVGaWVsZENoYW5nZWQoJGV2ZW50KVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBTZWxlY3QgS2V5IENvbHVtbiAtLTwvb3B0aW9uPlxuICAgICAgICAgICAgICBAZm9yIChjb2wgb2YgZW50aXR5Q29sdW1ucygpOyB0cmFjayBjb2wuZmllbGQpIHtcbiAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCJjb2wuZmllbGRcIj5cbiAgICAgICAgICAgICAgICAgIHt7IGNvbC5sYWJlbCB9fSB7eyBpc0FkdmFuY2VkTW9kZSgpID8gJygnICsgY29sLmRhdGFUeXBlICsgJyknIDogJycgfX1cbiAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8IS0tIENhc2NhZGluZyBEcm9wZG93biBEZXBlbmRlbmN5IC0tPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC1yb3dcIj5cbiAgICAgICAgICAgIDxsYWJlbCBjbGFzcz1cImZpZWxkLWxhYmVsXCI+XG4gICAgICAgICAgICAgIHt7IGlzQWR2YW5jZWRNb2RlKCkgPyAnRGVwZW5kZW50IE9uIChDYXNjYWRpbmcgUGFyZW50IEZpZWxkKScgOiAnRmlsdGVyIGJ5IEFub3RoZXIgRmllbGQnIH19XG4gICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgPHNlbGVjdFxuICAgICAgICAgICAgICBjbGFzcz1cImZpZWxkLXNlbGVjdFwiXG4gICAgICAgICAgICAgIFtuZ01vZGVsXT1cInNlbGVjdGVkRGVwZW5kc09uKClcIlxuICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJvbkRlcGVuZHNPbkNoYW5nZWQoJGV2ZW50KVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBOb25lIChJbmRlcGVuZGVudCkgLS08L29wdGlvbj5cbiAgICAgICAgICAgICAgQGZvciAob3RoZXIgb2YgYXZhaWxhYmxlUGFyZW50RmllbGRzKCk7IHRyYWNrIG90aGVyLmtleSB8fCBvdGhlci5pZCkge1xuICAgICAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cIm90aGVyLmtleSB8fCBvdGhlci5pZFwiPnt7IG90aGVyLmxhYmVsIHx8IG90aGVyLmtleSB9fTwvb3B0aW9uPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZmllbGQtaGludFwiPlxuICAgICAgICAgICAgICB7eyBpc0FkdmFuY2VkTW9kZSgpID8gJ0F1dG9tYXRpY2FsbHkgcmUtcXVlcmllcyBvcHRpb25zIHdoZW4gcGFyZW50IGZpZWxkIGNoYW5nZXMuJyA6ICdPbmx5IGxvYWRzIG9wdGlvbnMgd2hlbiB0aGUgc2VsZWN0ZWQgZmllbGQgY2hhbmdlcy4nIH19XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgPCEtLSAzQi4gU1RPUkVEIFBST0NFRFVSRSBDT05GSUdVUkFUSU9OIC0tPlxuICAgICAgQGlmIChjdXJyZW50U291cmNlVHlwZSgpID09PSAncHJvY2VkdXJlJykge1xuICAgICAgICA8ZGl2IGNsYXNzPVwiZmllbGQtcm93XCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLWxhYmVsLXJvd1wiPlxuICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmllbGQtbGFiZWxcIj5cbiAgICAgICAgICAgICAge3sgaXNBZHZhbmNlZE1vZGUoKSA/ICdTdG9yZWQgUHJvY2VkdXJlJyA6ICdTZWxlY3QgRGF0YSBQcm9jZWR1cmUnIH19XG4gICAgICAgICAgICA8L2xhYmVsPlxuICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgY2xhc3M9XCJidG4tcmVmcmVzaC1lbnRpdGllc1wiXG4gICAgICAgICAgICAgIChjbGljayk9XCJsb2FkRW50aXRpZXMoKVwiXG4gICAgICAgICAgICAgIHRpdGxlPVwiUmVmcmVzaCBhdmFpbGFibGUgcHJvY2VkdXJlcyBmcm9tIGJhY2tlbmRcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cInJlZnJlc2hcIiBbc2l6ZV09XCIxMVwiIC8+XG4gICAgICAgICAgICAgIDxzcGFuPlJlZnJlc2g8L3NwYW4+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8c2VsZWN0XG4gICAgICAgICAgICBjbGFzcz1cImZpZWxkLXNlbGVjdFwiXG4gICAgICAgICAgICBbbmdNb2RlbF09XCJzZWxlY3RlZEVudGl0eSgpXCJcbiAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIm9uRW50aXR5U2VsZWN0ZWQoJGV2ZW50KVwiXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwiaXNMb2FkaW5nRW50aXRpZXMoKVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgQGlmIChpc0xvYWRpbmdFbnRpdGllcygpKSB7XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj5Mb2FkaW5nIHN0b3JlZCBwcm9jZWR1cmVzIGZyb20gZGF0YWJhc2UuLi48L29wdGlvbj5cbiAgICAgICAgICAgIH0gQGVsc2UgaWYgKGF2YWlsYWJsZVByb2NlZHVyZXMoKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPi0tIE5vIHN0b3JlZCBwcm9jZWR1cmVzIGZvdW5kIChDbGljayBSZWZyZXNoKSAtLTwvb3B0aW9uPlxuICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBDaG9vc2UgRGF0YSBRdWVyeSAvIFNQIC0tPC9vcHRpb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBAZm9yIChzcCBvZiBhdmFpbGFibGVQcm9jZWR1cmVzKCk7IHRyYWNrIHNwLm5hbWUpIHtcbiAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwic3AubmFtZVwiPlxuICAgICAgICAgICAgICAgIEBpZiAoaXNBZHZhbmNlZE1vZGUoKSkge1xuICAgICAgICAgICAgICAgICAge3sgc3Auc2NoZW1hIH19Lnt7IHNwLm5hbWUgfX1cbiAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgIHt7IHNwLmRpc3BsYXlOYW1lIH19e3sgc3AuY2F0ZWdvcnkgPyAnIOKAoiAnICsgc3AuY2F0ZWdvcnkgOiAnJyB9fVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgIDwvZGl2PlxuXG4gICAgICAgIEBpZiAoc2VsZWN0ZWRFbnRpdHkoKSkge1xuICAgICAgICAgIDwhLS0gVmlzdWFsIFBhcmFtZXRlciBMaW5rZXJzIC0tPlxuICAgICAgICAgIEBpZiAocHJvY2VkdXJlUGFyYW1ldGVycygpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzcC1wYXJhbXMtZ3JvdXBcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBhcmFtcy1oZWFkZXItcm93XCI+XG4gICAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmllbGQtbGFiZWxcIj5cbiAgICAgICAgICAgICAgICAgIHt7IGlzQWR2YW5jZWRNb2RlKCkgPyAnUHJvY2VkdXJlIElucHV0IFBhcmFtZXRlcnMnIDogJ0ZpbHRlciBJbnB1dHMgJiBQYXJhbWV0ZXJzJyB9fVxuICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cImJ0bi1hdXRvLXBhcmFtc1wiXG4gICAgICAgICAgICAgICAgICAoY2xpY2spPVwiYXV0b1dpcmVBbGxQYXJhbWV0ZXJzKClcIlxuICAgICAgICAgICAgICAgICAgdGl0bGU9XCJBdXRvLWRldGVjdCBzZXNzaW9uIHBhcmFtZXRlcnMgYW5kIGFkZCBtaXNzaW5nIGZpbHRlciBjb250cm9scyB0byB0aGUgY2FudmFzXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cImNoZWNrXCIgW3NpemVdPVwiMTFcIiAvPlxuICAgICAgICAgICAgICAgICAgPHNwYW4+QXV0by1XaXJlIENhbnZhcyBJbnB1dHM8L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgIEBmb3IgKHBhcmFtIG9mIHByb2NlZHVyZVBhcmFtZXRlcnMoKTsgdHJhY2sgcGFyYW0ubmFtZSkge1xuICAgICAgICAgICAgICAgIDxycHQtcGFyYW1ldGVyLWJpbmRpbmctZWRpdG9yXG4gICAgICAgICAgICAgICAgICBbcGFyYW1dPVwicGFyYW1cIlxuICAgICAgICAgICAgICAgICAgW2N1cnJlbnRWYWx1ZV09XCJnZXRQYXJhbVZhbHVlKHBhcmFtLm5hbWUpXCJcbiAgICAgICAgICAgICAgICAgIFthbGxDb21wb25lbnRzXT1cImFsbENvbXBvbmVudHMoKVwiXG4gICAgICAgICAgICAgICAgICBbY3VycmVudENvbXBvbmVudElkXT1cImNvbXAoKS5pZFwiXG4gICAgICAgICAgICAgICAgICBbaXNBZHZhbmNlZE1vZGVdPVwiaXNBZHZhbmNlZE1vZGUoKVwiXG4gICAgICAgICAgICAgICAgICAodmFsdWVDaGFuZ2UpPVwic2V0UGFyYW1WYWx1ZShwYXJhbS5uYW1lLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgIChsaW5rZWRGaWVsZENoYW5nZSk9XCJvblBhcmFtTGlua2VkRmllbGRDaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgPCEtLSBEaXNwbGF5IEZpZWxkIChWaXNpYmxlIHRleHQpIC0tPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC1yb3dcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZC1sYWJlbC1yb3dcIj5cbiAgICAgICAgICAgICAgPGxhYmVsIGNsYXNzPVwiZmllbGQtbGFiZWxcIj5cbiAgICAgICAgICAgICAgICB7eyBpc0FkdmFuY2VkTW9kZSgpID8gJ0Rpc3BsYXkgRmllbGQgKGZyb20gU1AgcmVzdWx0KScgOiAnVGV4dCBTaG93biBpbiBEcm9wZG93bicgfX1cbiAgICAgICAgICAgICAgPC9sYWJlbD5cbiAgICAgICAgICAgICAgQGlmICghaXNBZHZhbmNlZE1vZGUoKSkge1xuICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYXV0by1iYWRnZVwiPkF1dG8tZGV0ZWN0ZWQ8L3NwYW4+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPHNlbGVjdFxuICAgICAgICAgICAgICBjbGFzcz1cImZpZWxkLXNlbGVjdFwiXG4gICAgICAgICAgICAgIFtuZ01vZGVsXT1cInNlbGVjdGVkRGlzcGxheUZpZWxkKClcIlxuICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJvbkRpc3BsYXlGaWVsZENoYW5nZWQoJGV2ZW50KVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBTZWxlY3QgRGlzcGxheSBDb2x1bW4gLS08L29wdGlvbj5cbiAgICAgICAgICAgICAgQGZvciAoY29sIG9mIGVudGl0eUNvbHVtbnMoKTsgdHJhY2sgY29sLmZpZWxkKSB7XG4gICAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwiY29sLmZpZWxkXCI+XG4gICAgICAgICAgICAgICAgICB7eyBjb2wubGFiZWwgfX0ge3sgaXNBZHZhbmNlZE1vZGUoKSA/ICcoJyArIGNvbC5kYXRhVHlwZSArICcpJyA6ICcnIH19XG4gICAgICAgICAgICAgICAgPC9vcHRpb24+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvc2VsZWN0PlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgPCEtLSBWYWx1ZSBGaWVsZCAoU3RvcmVkIGtleSkgLS0+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLXJvd1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZpZWxkLWxhYmVsLXJvd1wiPlxuICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJmaWVsZC1sYWJlbFwiPlxuICAgICAgICAgICAgICAgIHt7IGlzQWR2YW5jZWRNb2RlKCkgPyAnVmFsdWUgRmllbGQgKGZyb20gU1AgcmVzdWx0KScgOiAnSW50ZXJuYWwgVmFsdWUgLyBLZXknIH19XG4gICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgIEBpZiAoIWlzQWR2YW5jZWRNb2RlKCkpIHtcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImF1dG8tYmFkZ2VcIj5BdXRvLWRldGVjdGVkPC9zcGFuPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDxzZWxlY3RcbiAgICAgICAgICAgICAgY2xhc3M9XCJmaWVsZC1zZWxlY3RcIlxuICAgICAgICAgICAgICBbbmdNb2RlbF09XCJzZWxlY3RlZFZhbHVlRmllbGQoKVwiXG4gICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIm9uVmFsdWVGaWVsZENoYW5nZWQoJGV2ZW50KVwiXG4gICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIj4tLSBTZWxlY3QgS2V5IENvbHVtbiAtLTwvb3B0aW9uPlxuICAgICAgICAgICAgICBAZm9yIChjb2wgb2YgZW50aXR5Q29sdW1ucygpOyB0cmFjayBjb2wuZmllbGQpIHtcbiAgICAgICAgICAgICAgICA8b3B0aW9uIFt2YWx1ZV09XCJjb2wuZmllbGRcIj5cbiAgICAgICAgICAgICAgICAgIHt7IGNvbC5sYWJlbCB9fSB7eyBpc0FkdmFuY2VkTW9kZSgpID8gJygnICsgY29sLmRhdGFUeXBlICsgJyknIDogJycgfX1cbiAgICAgICAgICAgICAgICA8L29wdGlvbj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgPCEtLSAzQy4gU1RBVElDIE9QVElPTlMgRURJVE9SIC0tPlxuICAgICAgQGlmIChjdXJyZW50U291cmNlVHlwZSgpID09PSAnc3RhdGljJykge1xuICAgICAgICA8ZGl2IGNsYXNzPVwic3RhdGljLW9wdGlvbnMtd3JhcHBlclwiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdGF0aWMtb3B0aW9ucy1oZWFkZXJcIj5cbiAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiZmllbGQtbGFiZWxcIj5TdGF0aWMgT3B0aW9uczwvc3Bhbj5cbiAgICAgICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuLWFkZC1vcHRpb25cIiAoY2xpY2spPVwiYWRkU3RhdGljT3B0aW9uKClcIj5cbiAgICAgICAgICAgICAgPHJwdC1pY29uIG5hbWU9XCJwbHVzXCIgW3NpemVdPVwiMTFcIiAvPlxuICAgICAgICAgICAgICA8c3Bhbj5BZGQgT3B0aW9uPC9zcGFuPlxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwic3RhdGljLW9wdGlvbnMtbGlzdFwiPlxuICAgICAgICAgICAgQGZvciAob3B0IG9mIHN0YXRpY09wdGlvbnMoKTsgdHJhY2sgJGluZGV4KSB7XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdGF0aWMtb3B0aW9uLXJvd1wiPlxuICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmaWVsZC1pbnB1dCBvcHQta2V5XCJcbiAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiS2V5XCJcbiAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cIm9wdC5rZXlcIlxuICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwidXBkYXRlU3RhdGljT3B0aW9uKCRpbmRleCwgJ2tleScsICRldmVudClcIlxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cImZpZWxkLWlucHV0IG9wdC1sYWJlbFwiXG4gICAgICAgICAgICAgICAgICBwbGFjZWhvbGRlcj1cIkxhYmVsXCJcbiAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cIm9wdC5sYWJlbFwiXG4gICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJ1cGRhdGVTdGF0aWNPcHRpb24oJGluZGV4LCAnbGFiZWwnLCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJidG4tcmVtb3ZlLW9wdGlvblwiXG4gICAgICAgICAgICAgICAgICAoY2xpY2spPVwicmVtb3ZlU3RhdGljT3B0aW9uKCRpbmRleClcIlxuICAgICAgICAgICAgICAgICAgdGl0bGU9XCJSZW1vdmUgb3B0aW9uXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICA8cnB0LWljb24gbmFtZT1cInRyYXNoXCIgW3NpemVdPVwiMTJcIiAvPlxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9kaXY+XG4gICAgICB9XG4gICAgPC9kaXY+Il19
|