bways-report 0.1.5 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/README.md +291 -422
  2. package/esm2022/lib/core/config/bways-report-config.mjs +83 -0
  3. package/esm2022/lib/core/index.mjs +2 -1
  4. package/esm2022/lib/core/models/report-definition.model.mjs +1 -1
  5. package/esm2022/lib/core/services/index.mjs +2 -1
  6. package/esm2022/lib/core/services/report-data-discovery.service.mjs +138 -0
  7. package/esm2022/lib/core/services/report-session-context.service.mjs +11 -7
  8. package/esm2022/lib/core/tokens/reporting-config.token.mjs +1 -1
  9. package/esm2022/lib/core/utils/data-normalization.util.mjs +87 -1
  10. package/esm2022/lib/core/utils/identifier-humanizer.mjs +15 -4
  11. package/esm2022/lib/core/utils/report-parameter.util.mjs +119 -3
  12. package/esm2022/lib/data-access/adapters/endpoint-datasource.adapter.mjs +69 -0
  13. package/esm2022/lib/data-access/adapters/endpoint-lookup.adapter.mjs +98 -0
  14. package/esm2022/lib/data-access/adapters/endpoint-masterdata.adapter.mjs +57 -0
  15. package/esm2022/lib/data-access/adapters/endpoint-persistence.adapter.mjs +85 -0
  16. package/esm2022/lib/data-access/adapters/endpoint-schema-discovery.adapter.mjs +163 -0
  17. package/esm2022/lib/data-access/adapters/endpoint-tokens.mjs +12 -0
  18. package/esm2022/lib/data-access/adapters/http-lookup.adapter.mjs +20 -30
  19. package/esm2022/lib/data-access/adapters/index.mjs +8 -1
  20. package/esm2022/lib/data-access/contracts/lookup.contract.mjs +1 -1
  21. package/esm2022/lib/features/designer/components/component-palette/component-palette.component.mjs +12 -2
  22. package/esm2022/lib/features/designer/components/design-canvas/design-canvas.component.mjs +71 -13
  23. package/esm2022/lib/features/designer/components/dialogs/report-saved-dialog.component.mjs +407 -0
  24. package/esm2022/lib/features/designer/components/property-editor/parameter-binding-editor.component.mjs +403 -222
  25. package/esm2022/lib/features/designer/components/property-editor/property-editor-action.component.mjs +41 -34
  26. package/esm2022/lib/features/designer/components/property-editor/property-editor-datasource.component.mjs +142 -20
  27. package/esm2022/lib/features/designer/components/property-editor/property-editor-general.component.mjs +3 -3
  28. package/esm2022/lib/features/designer/components/property-editor/property-editor-grid.component.mjs +154 -5
  29. package/esm2022/lib/features/designer/components/property-editor/property-editor-layout.component.mjs +11 -5
  30. package/esm2022/lib/features/designer/components/property-editor/property-editor-report.component.mjs +3 -3
  31. package/esm2022/lib/features/designer/components/property-editor/property-editor-validation.component.mjs +15 -3
  32. package/esm2022/lib/features/designer/components/property-editor/property-editor.component.mjs +112 -39
  33. package/esm2022/lib/features/designer/components/toolbar/designer-toolbar.component.mjs +204 -10
  34. package/esm2022/lib/features/designer/designer.component.mjs +44 -3
  35. package/esm2022/lib/features/designer/services/designer-state.service.mjs +70 -3
  36. package/esm2022/lib/features/embed/bways-report-builder.component.mjs +207 -0
  37. package/esm2022/lib/features/embed/bways-report-menu.component.mjs +433 -0
  38. package/esm2022/lib/features/embed/bways-report-page.component.mjs +204 -0
  39. package/esm2022/lib/features/embed/index.mjs +5 -0
  40. package/esm2022/lib/features/embed/inject-report-menu.mjs +99 -0
  41. package/esm2022/lib/features/index.mjs +2 -1
  42. package/esm2022/lib/features/persistence/services/report-store.service.mjs +43 -5
  43. package/esm2022/lib/features/routing/components/routed-report-runtime.component.mjs +4 -4
  44. package/esm2022/lib/features/routing/index.mjs +2 -2
  45. package/esm2022/lib/features/routing/models/report-route.models.mjs +1 -1
  46. package/esm2022/lib/features/routing/report-routes.mjs +42 -1
  47. package/esm2022/lib/features/routing/resolvers/report.resolver.mjs +6 -8
  48. package/esm2022/lib/features/routing/services/report-menu.service.mjs +14 -4
  49. package/esm2022/lib/features/runtime/dynamic-renderer.component.mjs +22 -3
  50. package/esm2022/lib/features/runtime/report-grid-bridge.component.mjs +121 -15
  51. package/esm2022/lib/primitives/components/button/rpt-button.component.mjs +28 -5
  52. package/esm2022/lib/primitives/components/dropdown/rpt-dropdown.component.mjs +113 -20
  53. package/esm2022/lib/primitives/components/icon/rpt-icon.component.mjs +8 -1
  54. package/esm2022/lib/primitives/components/index.mjs +2 -1
  55. package/esm2022/lib/primitives/components/number/rpt-number.component.mjs +9 -3
  56. package/esm2022/lib/primitives/components/searchable-select/rpt-searchable-select.component.mjs +386 -0
  57. package/esm2022/lib/provide-reporting.mjs +156 -11
  58. package/fesm2022/bways-report.mjs +5703 -1766
  59. package/fesm2022/bways-report.mjs.map +1 -1
  60. package/lib/core/config/bways-report-config.d.ts +161 -0
  61. package/lib/core/index.d.ts +1 -0
  62. package/lib/core/models/report-definition.model.d.ts +16 -0
  63. package/lib/core/services/index.d.ts +1 -0
  64. package/lib/core/services/report-data-discovery.service.d.ts +38 -0
  65. package/lib/core/services/report-session-context.service.d.ts +1 -0
  66. package/lib/core/tokens/reporting-config.token.d.ts +18 -0
  67. package/lib/core/utils/data-normalization.util.d.ts +10 -0
  68. package/lib/core/utils/report-parameter.util.d.ts +18 -1
  69. package/lib/data-access/adapters/endpoint-datasource.adapter.d.ts +13 -0
  70. package/lib/data-access/adapters/endpoint-lookup.adapter.d.ts +14 -0
  71. package/lib/data-access/adapters/endpoint-masterdata.adapter.d.ts +11 -0
  72. package/lib/data-access/adapters/endpoint-persistence.adapter.d.ts +15 -0
  73. package/lib/data-access/adapters/endpoint-schema-discovery.adapter.d.ts +21 -0
  74. package/lib/data-access/adapters/endpoint-tokens.d.ts +21 -0
  75. package/lib/data-access/adapters/http-lookup.adapter.d.ts +2 -1
  76. package/lib/data-access/adapters/index.d.ts +7 -0
  77. package/lib/data-access/contracts/lookup.contract.d.ts +2 -2
  78. package/lib/features/designer/components/component-palette/component-palette.component.d.ts +1 -0
  79. package/lib/features/designer/components/design-canvas/design-canvas.component.d.ts +6 -2
  80. package/lib/features/designer/components/dialogs/report-saved-dialog.component.d.ts +34 -0
  81. package/lib/features/designer/components/property-editor/parameter-binding-editor.component.d.ts +6 -0
  82. package/lib/features/designer/components/property-editor/property-editor-action.component.d.ts +3 -0
  83. package/lib/features/designer/components/property-editor/property-editor-datasource.component.d.ts +12 -2
  84. package/lib/features/designer/components/property-editor/property-editor-grid.component.d.ts +41 -1
  85. package/lib/features/designer/components/property-editor/property-editor.component.d.ts +19 -0
  86. package/lib/features/designer/components/toolbar/designer-toolbar.component.d.ts +13 -1
  87. package/lib/features/designer/designer.component.d.ts +4 -0
  88. package/lib/features/designer/services/designer-state.service.d.ts +12 -1
  89. package/lib/features/embed/bways-report-builder.component.d.ts +48 -0
  90. package/lib/features/embed/bways-report-menu.component.d.ts +40 -0
  91. package/lib/features/embed/bways-report-page.component.d.ts +61 -0
  92. package/lib/features/embed/index.d.ts +4 -0
  93. package/lib/features/embed/inject-report-menu.d.ts +44 -0
  94. package/lib/features/index.d.ts +1 -0
  95. package/lib/features/persistence/services/report-store.service.d.ts +5 -0
  96. package/lib/features/routing/index.d.ts +1 -1
  97. package/lib/features/routing/models/report-route.models.d.ts +3 -0
  98. package/lib/features/routing/report-routes.d.ts +40 -0
  99. package/lib/features/routing/resolvers/report.resolver.d.ts +1 -1
  100. package/lib/features/runtime/dynamic-renderer.component.d.ts +1 -0
  101. package/lib/features/runtime/report-grid-bridge.component.d.ts +8 -59
  102. package/lib/primitives/components/button/rpt-button.component.d.ts +3 -0
  103. package/lib/primitives/components/dropdown/rpt-dropdown.component.d.ts +18 -2
  104. package/lib/primitives/components/index.d.ts +2 -0
  105. package/lib/primitives/components/searchable-select/rpt-searchable-select.component.d.ts +89 -0
  106. package/lib/provide-reporting.d.ts +28 -6
  107. package/package.json +1 -1
@@ -1,22 +1,62 @@
1
- import { ChangeDetectionStrategy, Component, computed, effect, ElementRef, HostListener, inject, input, signal, untracked, viewChild, } from '@angular/core';
1
+ import { ChangeDetectionStrategy, Component, computed, effect, ElementRef, HostListener, inject, input, output, signal, untracked, viewChild, } from '@angular/core';
2
2
  import { FormControl, ReactiveFormsModule } from '@angular/forms';
3
+ import { Overlay, OverlayModule, } from '@angular/cdk/overlay';
4
+ import { throwError } from 'rxjs';
5
+ import { timeout } from 'rxjs/operators';
3
6
  import { getValidationMessage } from '../../../core/validation/validation-factory';
4
7
  import { MasterDataProvider } from '../../../data-access/contracts/master-data.provider';
5
8
  import { ReportLookupAdapter } from '../../../data-access/contracts/lookup.contract';
6
9
  import { ReportSessionContextService } from '../../../core/services/report-session-context.service';
10
+ import { REPORTING_CONFIG } from '../../../core/tokens/reporting-config.token';
7
11
  import { findMissingCanvasFields, resolveParameterMappings, } from '../../../core/utils/report-parameter.util';
8
12
  import * as i0 from "@angular/core";
9
13
  import * as i1 from "@angular/forms";
14
+ import * as i2 from "@angular/cdk/overlay";
10
15
  export class RptDropdownComponent {
11
16
  masterDataProvider = inject(MasterDataProvider, { optional: true });
12
17
  lookupAdapter = inject(ReportLookupAdapter, { optional: true });
13
18
  sessionService = inject(ReportSessionContextService, { optional: true });
14
19
  elementRef = inject(ElementRef);
20
+ reportingConfig = inject(REPORTING_CONFIG, { optional: true });
21
+ overlay = inject(Overlay);
22
+ scrollStrategy = this.overlay.scrollStrategies.reposition();
23
+ triggerWidth = signal('auto');
24
+ overlayPositions = [
25
+ {
26
+ originX: 'start',
27
+ originY: 'bottom',
28
+ overlayX: 'start',
29
+ overlayY: 'top',
30
+ offsetY: 4,
31
+ },
32
+ {
33
+ originX: 'start',
34
+ originY: 'top',
35
+ overlayX: 'start',
36
+ overlayY: 'bottom',
37
+ offsetY: -4,
38
+ },
39
+ {
40
+ originX: 'end',
41
+ originY: 'bottom',
42
+ overlayX: 'end',
43
+ overlayY: 'top',
44
+ offsetY: 4,
45
+ },
46
+ {
47
+ originX: 'end',
48
+ originY: 'top',
49
+ overlayX: 'end',
50
+ overlayY: 'bottom',
51
+ offsetY: -4,
52
+ },
53
+ ];
15
54
  config = input.required();
16
55
  control = input();
17
56
  parentForm = input(null);
18
57
  /** Designer mode: shows a small status line (Loading / N records / Waiting for…). */
19
58
  showStatus = input(false);
59
+ dropdownClick = output();
20
60
  fallbackControl = new FormControl('');
21
61
  dynamicOptions = signal([]);
22
62
  lookupSub;
@@ -82,16 +122,37 @@ export class RptDropdownComponent {
82
122
  return all.filter((opt) => opt.label.toLowerCase().includes(term) || String(opt.key).toLowerCase().includes(term));
83
123
  });
84
124
  MAX_FILTER_RENDER = 200;
125
+ INITIAL_FILTER_RENDER = 200;
126
+ filterRenderLimit = signal(200);
85
127
  visibleFilteredOptions = computed(() => {
86
128
  const filtered = this.filteredOptions();
87
- if (filtered.length <= this.MAX_FILTER_RENDER)
129
+ const limit = this.filterRenderLimit();
130
+ if (filtered.length <= limit)
88
131
  return filtered;
89
- return filtered.slice(0, this.MAX_FILTER_RENDER);
132
+ return filtered.slice(0, limit);
90
133
  });
91
134
  excessFilteredCount = computed(() => {
92
- return Math.max(0, this.filteredOptions().length - this.MAX_FILTER_RENDER);
135
+ return Math.max(0, this.filteredOptions().length - this.filterRenderLimit());
93
136
  });
94
- MAX_RENDERED_OPTIONS = 500;
137
+ onOptionsScroll(event) {
138
+ const el = event.target;
139
+ if (!el)
140
+ return;
141
+ if (el.scrollTop + el.clientHeight >= el.scrollHeight - 120) {
142
+ this.loadMoreFiltered();
143
+ }
144
+ }
145
+ loadMoreFiltered() {
146
+ const total = this.filteredOptions().length;
147
+ const current = this.filterRenderLimit();
148
+ if (current < total) {
149
+ this.filterRenderLimit.update((c) => Math.min(total, c + 200));
150
+ }
151
+ }
152
+ loadAllFiltered() {
153
+ this.filterRenderLimit.set(this.filteredOptions().length);
154
+ }
155
+ MAX_RENDERED_OPTIONS = 5000;
95
156
  renderedOptions = computed(() => {
96
157
  const opts = this.allOptions();
97
158
  if (opts.length <= this.MAX_RENDERED_OPTIONS)
@@ -177,6 +238,7 @@ export class RptDropdownComponent {
177
238
  if (event) {
178
239
  event.stopPropagation();
179
240
  }
241
+ this.dropdownClick.emit();
180
242
  if (this.formControl().disabled)
181
243
  return;
182
244
  if (this.isOpen()) {
@@ -189,21 +251,27 @@ export class RptDropdownComponent {
189
251
  openDropdown() {
190
252
  if (this.formControl().disabled)
191
253
  return;
192
- // Check available viewport space to determine if menu should open above
193
254
  const wrapper = this.comboboxWrapperEl()?.nativeElement ?? this.elementRef.nativeElement;
194
255
  const rect = wrapper.getBoundingClientRect();
195
- const spaceBelow = window.innerHeight - rect.bottom;
196
- const spaceAbove = rect.top;
256
+ if (rect.width > 0) {
257
+ this.triggerWidth.set(rect.width);
258
+ }
197
259
  const preferAbove = this.config()?.properties?.['openAbove'] === true;
198
- const autoAbove = spaceBelow < 260 && spaceAbove > 160;
199
- this.opensAbove.set(preferAbove || autoAbove);
260
+ if (preferAbove) {
261
+ this.opensAbove.set(true);
262
+ }
200
263
  this.isOpen.set(true);
201
264
  this.searchTerm.set('');
265
+ this.filterRenderLimit.set(this.INITIAL_FILTER_RENDER);
202
266
  this.focusedIndex.set(-1);
203
- // Auto-focus search input after render
267
+ }
268
+ onPositionChange(change) {
269
+ this.opensAbove.set(change.connectionPair.originY === 'top');
270
+ }
271
+ onOverlayAttached() {
204
272
  setTimeout(() => {
205
273
  this.searchInputEl()?.nativeElement.focus();
206
- }, 10);
274
+ }, 25);
207
275
  }
208
276
  closeDropdown() {
209
277
  this.isOpen.set(false);
@@ -225,17 +293,30 @@ export class RptDropdownComponent {
225
293
  this.formControl().markAsDirty();
226
294
  this.formControl().markAsTouched();
227
295
  this.searchTerm.set('');
296
+ this.filterRenderLimit.set(this.INITIAL_FILTER_RENDER);
228
297
  this.focusedIndex.set(-1);
229
298
  }
299
+ /** Manually retry loading dynamic lookup options (e.g. after database timeout). */
300
+ retryLookup(event) {
301
+ if (event) {
302
+ event.stopPropagation();
303
+ event.preventDefault();
304
+ }
305
+ this.lastRequestKey = '';
306
+ this.loadError.set(null);
307
+ this.reloadDataSourceOptions(this.sessionService?.sessionContext() ?? {});
308
+ }
230
309
  clearSearch(event) {
231
310
  event.stopPropagation();
232
311
  this.searchTerm.set('');
312
+ this.filterRenderLimit.set(this.INITIAL_FILTER_RENDER);
233
313
  this.focusedIndex.set(-1);
234
314
  this.searchInputEl()?.nativeElement.focus();
235
315
  }
236
316
  onSearchInput(event) {
237
317
  const val = event.target.value;
238
318
  this.searchTerm.set(val);
319
+ this.filterRenderLimit.set(this.INITIAL_FILTER_RENDER);
239
320
  this.focusedIndex.set(0);
240
321
  }
241
322
  onTriggerKeydown(event) {
@@ -315,7 +396,7 @@ export class RptDropdownComponent {
315
396
  if (form && this.isDynamicSource()) {
316
397
  this.formChangesSub = form.valueChanges.subscribe(() => this.scheduleReload());
317
398
  }
318
- untracked(() => this.reloadDataSourceOptions(session));
399
+ untracked(() => this.scheduleReload());
319
400
  }, { allowSignalWrites: true });
320
401
  }
321
402
  ngOnDestroy() {
@@ -360,8 +441,8 @@ export class RptDropdownComponent {
360
441
  sourceType: ds.sourceType ?? 'table',
361
442
  entityName: ds.entityName,
362
443
  schema: ds.schema ?? 'dbo',
363
- valueField: ds.valueField || 'id',
364
- displayField: ds.displayField || 'name',
444
+ valueField: ds.valueField?.trim() || '',
445
+ displayField: ds.displayField?.trim() || '',
365
446
  filter: ds.filter,
366
447
  parameters: resolvedParams,
367
448
  };
@@ -369,10 +450,22 @@ export class RptDropdownComponent {
369
450
  if (requestKey === this.lastRequestKey)
370
451
  return; // nothing changed
371
452
  this.lastRequestKey = requestKey;
453
+ // Stored procedures on local databases can take a couple minutes to execute.
454
+ // Default timeout is 300,000ms (5 minutes), configurable via component properties or reportingConfig.
455
+ const timeoutMs = ds?.timeoutMs ||
456
+ this.config().properties?.['timeoutMs'] ||
457
+ this.reportingConfig?.lookupTimeoutMs ||
458
+ 300000;
372
459
  this.isLoading.set(true);
373
460
  this.loadError.set(null);
374
461
  this.lookupSub?.unsubscribe();
375
- this.lookupSub = this.lookupAdapter.fetchOptions(request).subscribe({
462
+ this.lookupSub = this.lookupAdapter
463
+ .fetchOptions(request)
464
+ .pipe(timeout({
465
+ each: timeoutMs,
466
+ with: () => throwError(() => new Error(`Lookup query timed out after ${Math.round(timeoutMs / 1000)}s (stored procedure took too long to respond on local database)`)),
467
+ }))
468
+ .subscribe({
376
469
  next: (items) => {
377
470
  this.isLoading.set(false);
378
471
  this.hasLoaded.set(true);
@@ -422,14 +515,14 @@ export class RptDropdownComponent {
422
515
  }
423
516
  }
424
517
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RptDropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
425
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: RptDropdownComponent, isStandalone: true, selector: "rpt-dropdown", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, control: { classPropertyName: "control", publicName: "control", isSignal: true, isRequired: false, transformFunction: null }, parentForm: { classPropertyName: "parentForm", publicName: "parentForm", isSignal: true, isRequired: false, transformFunction: null }, showStatus: { classPropertyName: "showStatus", publicName: "showStatus", isSignal: true, isRequired: false, transformFunction: null } }, host: { listeners: { "document:click": "onDocumentClick($event)", "document:keydown.escape": "onEscape()" }, properties: { "class.is-open": "isOpen()", "class.opens-above": "opensAbove()" } }, viewQueries: [{ propertyName: "comboboxWrapperEl", first: true, predicate: ["comboboxWrapper"], descendants: true, isSignal: true }, { propertyName: "searchInputEl", first: true, predicate: ["searchInput"], descendants: true, isSignal: true }, { propertyName: "optionsListEl", first: true, predicate: ["optionsListEl"], descendants: true, isSignal: true }], ngImport: i0, template: " <div class=\"rpt-field-group\">\n @if (config().label) {\n <label [for]=\"elementId()\" class=\"rpt-label\">\n {{ config().label }}\n @if (config().validation?.required) {\n <span class=\"rpt-required-marker\">*</span>\n }\n </label>\n }\n\n @if (isSearchable()) {\n <!-- Searchable Typeahead Combobox -->\n <div class=\"rpt-combobox-wrapper\" #comboboxWrapper>\n <button\n type=\"button\"\n class=\"rpt-combobox-trigger\"\n [id]=\"elementId()\"\n [class.rpt-invalid]=\"isInvalid()\"\n [class.is-open]=\"isOpen()\"\n [disabled]=\"formControl().disabled\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'listbox'\"\n (click)=\"toggleOpen($event)\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n <span class=\"trigger-label\" [class.is-placeholder]=\"!selectedOption()\">\n {{ selectedOption() ? selectedOption()!.label : placeholder() }}\n </span>\n\n <div class=\"trigger-actions\">\n @if (selectedOption() && !formControl().disabled) {\n <span\n role=\"button\"\n tabindex=\"0\"\n class=\"trigger-clear-btn\"\n title=\"Clear selection\"\n aria-label=\"Clear selection\"\n (click)=\"clearSelection($event)\"\n (keydown.enter)=\"clearSelection($event)\"\n (keydown.space)=\"clearSelection($event)\"\n >\n \u2715\n </span>\n }\n <span class=\"trigger-arrow\" [class.rotated]=\"isOpen()\" aria-hidden=\"true\">\n <svg width=\"12\" height=\"8\" viewBox=\"0 0 12 8\" fill=\"none\">\n <path d=\"M1 1.5L6 6.5L11 1.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n </div>\n </button>\n\n @if (isOpen()) {\n <div\n class=\"rpt-combobox-menu\"\n [class.opens-above]=\"opensAbove()\"\n role=\"listbox\"\n (click)=\"$event.stopPropagation()\"\n >\n <!-- Real-time Filter Search Box -->\n <div class=\"combobox-search-box\">\n <span class=\"combobox-search-icon\" aria-hidden=\"true\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"11\" cy=\"11\" r=\"8\"></circle>\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line>\n </svg>\n </span>\n <input\n #searchInput\n type=\"text\"\n class=\"combobox-search-input\"\n placeholder=\"Type to filter...\"\n [value]=\"searchTerm()\"\n [attr.aria-activedescendant]=\"focusedIndex() >= 0 ? (elementId() + '_opt_' + focusedIndex()) : null\"\n (input)=\"onSearchInput($event)\"\n (keydown)=\"onSearchKeydown($event)\"\n />\n @if (searchTerm()) {\n <button\n type=\"button\"\n class=\"combobox-search-clear\"\n title=\"Clear filter\"\n (click)=\"clearSearch($event)\"\n >\n \u2715\n </button>\n }\n </div>\n\n <!-- Filtered Options List -->\n <div class=\"combobox-options-list\" #optionsListEl>\n @if (isLoading()) {\n <div class=\"combobox-status-row loading\">\n <span class=\"status-dot dot-pulse\"></span>\n <span>Loading options from database...</span>\n </div>\n } @else if (loadError()) {\n <div class=\"combobox-status-row error\">\n <span>Error: {{ loadError() }}</span>\n </div>\n } @else if (isDynamicSource() && hasLoaded() && allOptions().length === 0) {\n <div class=\"combobox-status-row empty\">\n <span>No records found (check parameters)</span>\n </div>\n } @else if (filteredOptions().length === 0) {\n <div class=\"combobox-status-row empty\">\n <span>No options matching \"{{ searchTerm() }}\"</span>\n </div>\n } @else {\n @for (opt of visibleFilteredOptions(); track opt.key; let i = $index) {\n <div\n role=\"option\"\n [id]=\"elementId() + '_opt_' + i\"\n class=\"combobox-option-item\"\n [class.is-selected]=\"isSelected(opt)\"\n [class.is-focused]=\"focusedIndex() === i\"\n [attr.aria-selected]=\"isSelected(opt)\"\n (click)=\"selectOption(opt)\"\n (mouseenter)=\"focusedIndex.set(i)\"\n >\n <span class=\"opt-label\">{{ opt.label }}</span>\n @if (isSelected(opt)) {\n <span class=\"opt-check\" aria-hidden=\"true\">\u2713</span>\n }\n </div>\n }\n @if (excessFilteredCount() > 0) {\n <div class=\"combobox-status-row hint\">\n <span>Showing {{ MAX_FILTER_RENDER }} of {{ filteredOptions().length }} matches. Type to refine.</span>\n </div>\n }\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <!-- Native Browser Select Fallback -->\n <div class=\"rpt-select-wrapper\">\n <select\n [id]=\"elementId()\"\n [formControl]=\"formControl()\"\n [class.rpt-invalid]=\"isInvalid()\"\n class=\"rpt-select\"\n >\n @if (isLoading()) {\n <option value=\"\" disabled selected>Loading options from database...</option>\n } @else if (loadError()) {\n <option value=\"\" disabled selected>Error: {{ loadError() }}</option>\n } @else if (isDynamicSource() && hasLoaded() && allOptions().length === 0) {\n <option value=\"\" disabled selected>-- No records found (check parameters) --</option>\n } @else if (placeholder()) {\n <option value=\"\" [disabled]=\"config().validation?.required\">{{ placeholder() }}</option>\n }\n @for (opt of renderedOptions(); track opt.key) {\n <option [value]=\"opt.key\">{{ opt.label }}</option>\n }\n @if (hasExcessOptions()) {\n <option value=\"\" disabled>... and {{ excessOptionsCount() }} more records (refine filter) ...</option>\n }\n </select>\n <div class=\"rpt-select-arrow\" aria-hidden=\"true\">\n <svg width=\"12\" height=\"8\" viewBox=\"0 0 12 8\" fill=\"none\">\n <path d=\"M1 1.5L6 6.5L11 1.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n </div>\n }\n\n @if (showStatus() && isDynamicSource() && statusText()) {\n <div class=\"rpt-status-badge\" [attr.data-status]=\"statusKind()\">\n @switch (statusKind()) {\n @case ('loading') {\n <span class=\"status-dot dot-pulse\"></span>\n <span>Loading from database\u2026</span>\n }\n @case ('ok') {\n <span class=\"status-dot dot-ok\"></span>\n <span>{{ dynamicOptions().length }} records loaded</span>\n }\n @case ('waiting') {\n <span class=\"status-dot dot-warn\"></span>\n <span>Waiting for:</span>\n <div class=\"waiting-tokens\">\n @for (k of waitingFor(); track k) {\n <span class=\"waiting-token\">{{ k }}</span>\n }\n </div>\n }\n @case ('error') {\n <span class=\"status-dot dot-err\"></span>\n <span>{{ loadError() }}</span>\n }\n @case ('empty') {\n <span class=\"status-dot\"></span>\n <span>No records found for parameters</span>\n }\n @default {\n <span class=\"status-dot\"></span>\n }\n }\n </div>\n }\n\n @if (errorMessage()) {\n <span class=\"rpt-error-text\">{{ errorMessage() }}</span>\n }\n </div>", styles: [":host{display:block;width:100%;max-width:100%;min-width:0;box-sizing:border-box;font-family:var(--rpt-font-family, inherit);position:relative}.rpt-status-badge{display:flex;flex-wrap:wrap;align-items:center;gap:4px;font-size:.6875rem;padding:3px 6px;border-radius:4px;margin-top:4px;font-weight:500;line-height:1.3;max-width:100%;box-sizing:border-box;overflow:hidden;word-break:break-word}.rpt-status-badge>span{overflow-wrap:anywhere;word-break:break-word}.rpt-status-badge[data-status=loading]{background:#eff6ff;color:#2563eb;border:1px solid #dbeafe}.rpt-status-badge[data-status=ok]{background:#f0fdf4;color:#16a34a;border:1px solid #dcfce7}.rpt-status-badge[data-status=waiting]{background:#fffbeb;color:#d97706;border:1px solid #fef3c7}.rpt-status-badge[data-status=error]{background:#fef2f2;color:#dc2626;border:1px solid #fee2e2}.rpt-status-badge[data-status=empty]{background:#f8fafc;color:#64748b;border:1px solid #e2e8f0}.waiting-tokens{display:inline-flex;flex-wrap:wrap;align-items:center;gap:3px;margin-left:2px;max-width:100%}.waiting-token{background:#b453091f;border:1px solid rgba(180,83,9,.3);padding:1px 5px;border-radius:3px;font-weight:700;font-size:.625rem;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block;box-sizing:border-box}.status-dot{width:6px;height:6px;border-radius:50%;background:currentColor}.dot-pulse{animation:rpt-pulse 1s infinite alternate}@keyframes rpt-pulse{0%{opacity:.3}to{opacity:1}}.rpt-field-group{display:flex;flex-direction:column;max-width:100%;min-width:0;gap:4px;box-sizing:border-box;position:relative}.rpt-label{font-size:var(--rpt-font-size-sm, .75rem);font-weight:500;color:var(--rpt-color-text, #0f172a);flex-shrink:0}.rpt-required-marker{color:var(--rpt-color-danger, #ef4444);margin-left:2px}.rpt-select-wrapper{position:relative;width:100%;flex:1;min-height:0;display:flex;align-items:center}.rpt-select{width:100%;height:100%;min-height:38px;box-sizing:border-box;padding:6px 36px 6px 12px;font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text, #0f172a);background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);appearance:none;-webkit-appearance:none;outline:none;cursor:pointer;transition:border-color var(--rpt-transition-speed, .15s) ease,box-shadow var(--rpt-transition-speed, .15s) ease}.rpt-select:hover:not(:disabled){border-color:var(--rpt-color-border-hover, #94a3b8)}.rpt-select:focus{border-color:var(--rpt-color-border-focus, #2563eb);box-shadow:var(--rpt-box-shadow-focus, 0 0 0 3px rgba(37, 99, 235, .25))}.rpt-select:disabled{background-color:var(--rpt-color-surface, #f8fafc);color:var(--rpt-color-text-muted, #64748b);cursor:not-allowed}.rpt-select.rpt-invalid{border-color:var(--rpt-color-danger, #ef4444)}.rpt-select.rpt-invalid:focus{box-shadow:0 0 0 3px #ef444440}.rpt-select-arrow{position:absolute;right:12px;top:50%;transform:translateY(-50%);pointer-events:none;color:var(--rpt-color-text-muted, #64748b);display:flex;align-items:center}.rpt-combobox-wrapper{position:relative;width:100%;flex:1;min-height:0}.rpt-combobox-trigger{width:100%;height:100%;min-height:38px;box-sizing:border-box;padding:6px 10px 6px 12px;display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:var(--rpt-font-size-base, .875rem);font-family:inherit;color:var(--rpt-color-text, #0f172a);background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);outline:none;cursor:pointer;text-align:left;transition:border-color var(--rpt-transition-speed, .15s) ease,box-shadow var(--rpt-transition-speed, .15s) ease}.rpt-combobox-trigger:hover:not(:disabled){border-color:var(--rpt-color-border-hover, #94a3b8)}.rpt-combobox-trigger:focus-visible,.rpt-combobox-trigger.is-open{border-color:var(--rpt-color-border-focus, #2563eb);box-shadow:var(--rpt-box-shadow-focus, 0 0 0 3px rgba(37, 99, 235, .25))}.rpt-combobox-trigger:disabled{background-color:var(--rpt-color-surface, #f8fafc);color:var(--rpt-color-text-muted, #64748b);cursor:not-allowed}.rpt-combobox-trigger.rpt-invalid{border-color:var(--rpt-color-danger, #ef4444)}.rpt-combobox-trigger.rpt-invalid:focus-visible{box-shadow:0 0 0 3px #ef444440}.trigger-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.3}.trigger-label.is-placeholder{color:var(--rpt-color-text-muted, #94a3b8)}.trigger-actions{display:flex;align-items:center;gap:6px;flex-shrink:0}.trigger-clear-btn{display:flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:50%;font-size:.6875rem;color:var(--rpt-color-text-muted, #64748b);background-color:#f1f5f9;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .15s ease,color .15s ease}.trigger-clear-btn:hover{background-color:#e2e8f0;color:var(--rpt-color-text, #0f172a)}.trigger-arrow{display:flex;align-items:center;color:var(--rpt-color-text-muted, #64748b);transition:transform .18s ease}.trigger-arrow.rotated{transform:rotate(180deg)}.rpt-combobox-menu{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:1050;background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);box-shadow:0 10px 25px -5px #0000001f,0 8px 10px -6px #00000014;overflow:hidden;display:flex;flex-direction:column;animation:rpt-dropdown-pop .12s cubic-bezier(0,0,.2,1)}.rpt-combobox-menu.opens-above{top:auto;bottom:calc(100% + 4px);box-shadow:0 -10px 25px -5px #0000001f,0 -8px 10px -6px #00000014;animation:rpt-dropdown-pop-above .12s cubic-bezier(0,0,.2,1)}@keyframes rpt-dropdown-pop{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}@keyframes rpt-dropdown-pop-above{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.combobox-search-box{display:flex;align-items:center;gap:8px;padding:8px 10px;border-bottom:1px solid var(--rpt-color-border, #e2e8f0);background-color:#f8fafc}.combobox-search-icon{color:var(--rpt-color-text-muted, #94a3b8);display:flex;align-items:center;flex-shrink:0}.combobox-search-input{flex:1;border:none;outline:none;background:transparent;font-size:var(--rpt-font-size-sm, .8125rem);font-family:inherit;color:var(--rpt-color-text, #0f172a);min-width:0}.combobox-search-input::placeholder{color:#94a3b8}.combobox-search-clear{border:none;background:#e2e8f0;color:#64748b;width:16px;height:16px;border-radius:50%;font-size:.625rem;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0}.combobox-search-clear:hover{background:#cbd5e1;color:#0f172a}.combobox-options-list{max-height:220px;overflow-y:auto;overscroll-behavior:contain;padding:4px}.combobox-option-item{display:flex;align-items:center;justify-content:space-between;padding:7px 10px;border-radius:4px;font-size:var(--rpt-font-size-base, .84rem);color:var(--rpt-color-text, #0f172a);cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .1s ease}.combobox-option-item.is-focused{background-color:var(--rpt-color-surface-hover, #f1f5f9)}.combobox-option-item.is-selected{background-color:#eff6ff;color:var(--rpt-color-primary, #2563eb);font-weight:600}.opt-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.opt-check{font-size:.875rem;font-weight:700;color:var(--rpt-color-primary, #2563eb);margin-left:8px}.combobox-status-row{padding:10px 12px;font-size:.78rem;text-align:center;color:var(--rpt-color-text-muted, #64748b)}.combobox-status-row.loading{display:flex;align-items:center;justify-content:center;gap:6px;color:#2563eb}.combobox-status-row.error{color:var(--rpt-color-danger, #dc2626)}.combobox-status-row.hint{font-size:.72rem;color:#94a3b8;border-top:1px dashed #e2e8f0;margin-top:4px;padding:6px}.rpt-error-text{font-size:.7rem;color:var(--rpt-color-danger, #ef4444);margin-top:3px;line-height:1.25;max-width:100%;overflow-wrap:anywhere;word-break:break-word;display:block}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { 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.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
518
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: RptDropdownComponent, isStandalone: true, selector: "rpt-dropdown", inputs: { config: { classPropertyName: "config", publicName: "config", isSignal: true, isRequired: true, transformFunction: null }, control: { classPropertyName: "control", publicName: "control", isSignal: true, isRequired: false, transformFunction: null }, parentForm: { classPropertyName: "parentForm", publicName: "parentForm", isSignal: true, isRequired: false, transformFunction: null }, showStatus: { classPropertyName: "showStatus", publicName: "showStatus", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dropdownClick: "dropdownClick" }, host: { listeners: { "document:click": "onDocumentClick($event)", "document:keydown.escape": "onEscape()" }, properties: { "class.is-open": "isOpen()", "class.opens-above": "opensAbove()" } }, viewQueries: [{ propertyName: "comboboxWrapperEl", first: true, predicate: ["comboboxWrapper"], descendants: true, isSignal: true }, { propertyName: "searchInputEl", first: true, predicate: ["searchInput"], descendants: true, isSignal: true }, { propertyName: "optionsListEl", first: true, predicate: ["optionsListEl"], descendants: true, isSignal: true }], ngImport: i0, template: " <div class=\"rpt-field-group\">\n @if (config().label) {\n <label [for]=\"elementId()\" class=\"rpt-label\">\n {{ config().label }}\n @if (config().validation?.required) {\n <span class=\"rpt-required-marker\">*</span>\n }\n </label>\n }\n\n @if (isSearchable()) {\n <!-- Searchable Typeahead Combobox -->\n <div class=\"rpt-combobox-wrapper\" #comboboxWrapper #comboboxOrigin=\"cdkOverlayOrigin\" cdkOverlayOrigin>\n <button\n type=\"button\"\n class=\"rpt-combobox-trigger\"\n [id]=\"elementId()\"\n [class.rpt-invalid]=\"isInvalid()\"\n [class.is-open]=\"isOpen()\"\n [disabled]=\"formControl().disabled\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'listbox'\"\n (click)=\"toggleOpen($event)\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n <span class=\"trigger-label\" [class.is-placeholder]=\"!selectedOption()\">\n {{ selectedOption() ? selectedOption()!.label : placeholder() }}\n </span>\n\n <div class=\"trigger-actions\">\n @if (isLoading()) {\n <span class=\"status-dot dot-pulse\" style=\"color: #2563eb; margin-right: 4px;\" title=\"Executing query on database...\"></span>\n }\n @if (loadError() && !isLoading()) {\n <button\n type=\"button\"\n class=\"trigger-retry-btn\"\n title=\"Retry database query\"\n aria-label=\"Retry database query\"\n (click)=\"retryLookup($event)\"\n >\n \u21BB Retry\n </button>\n }\n @if (selectedOption() && !formControl().disabled) {\n <span\n role=\"button\"\n tabindex=\"0\"\n class=\"trigger-clear-btn\"\n title=\"Clear selection\"\n aria-label=\"Clear selection\"\n (click)=\"clearSelection($event)\"\n (keydown.enter)=\"clearSelection($event)\"\n (keydown.space)=\"clearSelection($event)\"\n >\n \u2715\n </span>\n }\n <span class=\"trigger-arrow\" [class.rotated]=\"isOpen()\" aria-hidden=\"true\">\n <svg width=\"12\" height=\"8\" viewBox=\"0 0 12 8\" fill=\"none\">\n <path d=\"M1 1.5L6 6.5L11 1.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n </div>\n </button>\n </div>\n\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"comboboxOrigin\"\n [cdkConnectedOverlayOpen]=\"isOpen()\"\n [cdkConnectedOverlayPositions]=\"overlayPositions\"\n [cdkConnectedOverlayWidth]=\"triggerWidth()\"\n [cdkConnectedOverlayFlexibleDimensions]=\"true\"\n [cdkConnectedOverlayViewportMargin]=\"8\"\n [cdkConnectedOverlayPush]=\"true\"\n [cdkConnectedOverlayScrollStrategy]=\"scrollStrategy\"\n (overlayOutsideClick)=\"closeDropdown()\"\n (positionChange)=\"onPositionChange($event)\"\n (attach)=\"onOverlayAttached()\"\n (detach)=\"closeDropdown()\"\n >\n <div\n class=\"rpt-combobox-menu\"\n [class.opens-above]=\"opensAbove()\"\n role=\"listbox\"\n (click)=\"$event.stopPropagation()\"\n >\n <!-- Real-time Filter Search Box -->\n <div class=\"combobox-search-box\">\n <span class=\"combobox-search-icon\" aria-hidden=\"true\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"11\" cy=\"11\" r=\"8\"></circle>\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line>\n </svg>\n </span>\n <input\n #searchInput\n type=\"text\"\n class=\"combobox-search-input\"\n placeholder=\"Type to filter...\"\n [value]=\"searchTerm()\"\n [attr.aria-activedescendant]=\"focusedIndex() >= 0 ? (elementId() + '_opt_' + focusedIndex()) : null\"\n (input)=\"onSearchInput($event)\"\n (keydown)=\"onSearchKeydown($event)\"\n />\n @if (searchTerm()) {\n <button\n type=\"button\"\n class=\"combobox-search-clear\"\n title=\"Clear filter\"\n (click)=\"clearSearch($event)\"\n >\n \u2715\n </button>\n }\n </div>\n\n <!-- Filtered Options List -->\n <div class=\"combobox-options-list\" #optionsListEl (scroll)=\"onOptionsScroll($event)\">\n @if (waitingFor().length > 0) {\n <div class=\"combobox-status-row waiting\">\n <span>Waiting for {{ waitingLabel() }}...</span>\n </div>\n } @else if (isLoading()) {\n <div class=\"combobox-status-row loading\">\n <span class=\"status-dot dot-pulse\"></span>\n <span>Executing query on database (may take 1\u20132 minutes on local database)...</span>\n </div>\n } @else if (loadError()) {\n <div class=\"combobox-status-row error\">\n <span>Error: {{ loadError() }}</span>\n <button type=\"button\" class=\"combobox-retry-btn\" (click)=\"retryLookup($event)\">\u21BB Retry Query</button>\n </div>\n } @else if (isDynamicSource() && hasLoaded() && allOptions().length === 0) {\n <div class=\"combobox-status-row empty\">\n <span>No records found (check parameters)</span>\n </div>\n } @else if (filteredOptions().length === 0) {\n <div class=\"combobox-status-row empty\">\n <span>No options matching \"{{ searchTerm() }}\"</span>\n </div>\n } @else {\n @for (opt of visibleFilteredOptions(); track opt.key; let i = $index) {\n <div\n role=\"option\"\n [id]=\"elementId() + '_opt_' + i\"\n class=\"combobox-option-item\"\n [class.is-selected]=\"isSelected(opt)\"\n [class.is-focused]=\"focusedIndex() === i\"\n [attr.aria-selected]=\"isSelected(opt)\"\n (click)=\"selectOption(opt)\"\n (mouseenter)=\"focusedIndex.set(i)\"\n >\n <span class=\"opt-label\">{{ opt.label }}</span>\n @if (isSelected(opt)) {\n <span class=\"opt-check\" aria-hidden=\"true\">\u2713</span>\n }\n </div>\n }\n @if (excessFilteredCount() > 0) {\n <div class=\"combobox-status-row hint\">\n <span>Showing {{ visibleFilteredOptions().length }} of {{ filteredOptions().length }} matches. Scroll down or</span>\n <button\n type=\"button\"\n class=\"combobox-load-all-btn\"\n (click)=\"loadAllFiltered(); $event.stopPropagation();\"\n >\n Load all {{ filteredOptions().length }}\n </button>\n </div>\n }\n }\n </div>\n </div>\n </ng-template>\n } @else {\n <!-- Native Browser Select Fallback -->\n <div class=\"rpt-select-wrapper\">\n <select\n [id]=\"elementId()\"\n [formControl]=\"formControl()\"\n [class.rpt-invalid]=\"isInvalid()\"\n class=\"rpt-select\"\n >\n @if (waitingFor().length > 0) {\n <option value=\"\" disabled selected>Waiting for {{ waitingLabel() }}...</option>\n } @else if (isLoading()) {\n <option value=\"\" disabled selected>Loading options from database...</option>\n } @else if (loadError()) {\n <option value=\"\" disabled selected>Error: {{ loadError() }}</option>\n } @else if (isDynamicSource() && hasLoaded() && allOptions().length === 0) {\n <option value=\"\" disabled selected>-- No records found (check parameters) --</option>\n } @else if (placeholder()) {\n <option value=\"\" [disabled]=\"config().validation?.required\">{{ placeholder() }}</option>\n }\n @for (opt of renderedOptions(); track opt.key) {\n <option [value]=\"opt.key\">{{ opt.label }}</option>\n }\n @if (hasExcessOptions()) {\n <option value=\"\" disabled>... and {{ excessOptionsCount() }} more records (refine filter) ...</option>\n }\n </select>\n <div class=\"rpt-select-arrow\" aria-hidden=\"true\">\n <svg width=\"12\" height=\"8\" viewBox=\"0 0 12 8\" fill=\"none\">\n <path d=\"M1 1.5L6 6.5L11 1.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n </div>\n }\n\n @if (showStatus() && isDynamicSource() && statusText()) {\n <div class=\"rpt-status-badge\" [attr.data-status]=\"statusKind()\">\n @switch (statusKind()) {\n @case ('loading') {\n <span class=\"status-dot dot-pulse\"></span>\n <span>Loading from database\u2026</span>\n }\n @case ('ok') {\n <span class=\"status-dot dot-ok\"></span>\n <span>{{ dynamicOptions().length }} records loaded</span>\n }\n @case ('waiting') {\n <span class=\"status-dot dot-warn\"></span>\n <span>Waiting for:</span>\n <div class=\"waiting-tokens\">\n @for (k of waitingFor(); track k) {\n <span class=\"waiting-token\">{{ k }}</span>\n }\n </div>\n }\n @case ('error') {\n <span class=\"status-dot dot-err\"></span>\n <span>{{ loadError() }}</span>\n <button type=\"button\" class=\"rpt-badge-retry-btn\" (click)=\"retryLookup($event)\">\u21BB Retry</button>\n }\n @case ('empty') {\n <span class=\"status-dot\"></span>\n <span>No records found for parameters</span>\n }\n @default {\n <span class=\"status-dot\"></span>\n }\n }\n </div>\n }\n\n @if (errorMessage()) {\n <span class=\"rpt-error-text\">{{ errorMessage() }}</span>\n }\n </div>", styles: [":host{display:block;width:100%;max-width:100%;min-width:0;box-sizing:border-box;font-family:var(--rpt-font-family, inherit);position:relative}.rpt-status-badge{display:flex;flex-wrap:wrap;align-items:center;gap:4px;font-size:.6875rem;padding:3px 6px;border-radius:4px;margin-top:4px;font-weight:500;line-height:1.3;max-width:100%;box-sizing:border-box;overflow:hidden;word-break:break-word}.rpt-status-badge>span{overflow-wrap:anywhere;word-break:break-word}.rpt-status-badge[data-status=loading]{background:#eff6ff;color:#2563eb;border:1px solid #dbeafe}.rpt-status-badge[data-status=ok]{background:#f0fdf4;color:#16a34a;border:1px solid #dcfce7}.rpt-status-badge[data-status=waiting]{background:#fffbeb;color:#d97706;border:1px solid #fef3c7}.rpt-status-badge[data-status=error]{background:#fef2f2;color:#dc2626;border:1px solid #fee2e2}.rpt-status-badge[data-status=empty]{background:#f8fafc;color:#64748b;border:1px solid #e2e8f0}.waiting-tokens{display:inline-flex;flex-wrap:wrap;align-items:center;gap:3px;margin-left:2px;max-width:100%}.waiting-token{background:#b453091f;border:1px solid rgba(180,83,9,.3);padding:1px 5px;border-radius:3px;font-weight:700;font-size:.625rem;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block;box-sizing:border-box}.status-dot{width:6px;height:6px;border-radius:50%;background:currentColor}.dot-pulse{animation:rpt-pulse 1s infinite alternate}@keyframes rpt-pulse{0%{opacity:.3}to{opacity:1}}.rpt-field-group{display:flex;flex-direction:column;max-width:100%;min-width:0;gap:4px;box-sizing:border-box;position:relative}.rpt-label{font-size:var(--rpt-font-size-sm, .75rem);font-weight:500;color:var(--rpt-color-text, #0f172a);flex-shrink:0}.rpt-required-marker{color:var(--rpt-color-danger, #ef4444);margin-left:2px}.rpt-select-wrapper{position:relative;width:100%;flex:1;min-height:0;display:flex;align-items:center}.rpt-select{width:100%;height:100%;min-height:38px;box-sizing:border-box;padding:6px 36px 6px 12px;font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text, #0f172a);background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);appearance:none;-webkit-appearance:none;outline:none;cursor:pointer;transition:border-color var(--rpt-transition-speed, .15s) ease,box-shadow var(--rpt-transition-speed, .15s) ease}.rpt-select:hover:not(:disabled){border-color:var(--rpt-color-border-hover, #94a3b8)}.rpt-select:focus{border-color:var(--rpt-color-border-focus, #2563eb);box-shadow:var(--rpt-box-shadow-focus, 0 0 0 3px rgba(37, 99, 235, .25))}.rpt-select:disabled{background-color:var(--rpt-color-surface, #f8fafc);color:var(--rpt-color-text-muted, #64748b);cursor:not-allowed}.rpt-select.rpt-invalid{border-color:var(--rpt-color-danger, #ef4444)}.rpt-select.rpt-invalid:focus{box-shadow:0 0 0 3px #ef444440}.rpt-select-arrow{position:absolute;right:12px;top:50%;transform:translateY(-50%);pointer-events:none;color:var(--rpt-color-text-muted, #64748b);display:flex;align-items:center}.rpt-combobox-wrapper{position:relative;width:100%;flex:1;min-height:0}.rpt-combobox-trigger{width:100%;height:100%;min-height:38px;box-sizing:border-box;padding:6px 10px 6px 12px;display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:var(--rpt-font-size-base, .875rem);font-family:inherit;color:var(--rpt-color-text, #0f172a);background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);outline:none;cursor:pointer;text-align:left;transition:border-color var(--rpt-transition-speed, .15s) ease,box-shadow var(--rpt-transition-speed, .15s) ease}.rpt-combobox-trigger:hover:not(:disabled){border-color:var(--rpt-color-border-hover, #94a3b8)}.rpt-combobox-trigger:focus-visible,.rpt-combobox-trigger.is-open{border-color:var(--rpt-color-border-focus, #2563eb);box-shadow:var(--rpt-box-shadow-focus, 0 0 0 3px rgba(37, 99, 235, .25))}.rpt-combobox-trigger:disabled{background-color:var(--rpt-color-surface, #f8fafc);color:var(--rpt-color-text-muted, #64748b);cursor:not-allowed}.rpt-combobox-trigger.rpt-invalid{border-color:var(--rpt-color-danger, #ef4444)}.rpt-combobox-trigger.rpt-invalid:focus-visible{box-shadow:0 0 0 3px #ef444440}.trigger-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.3}.trigger-label.is-placeholder{color:var(--rpt-color-text-muted, #94a3b8)}.trigger-actions{display:flex;align-items:center;gap:6px;flex-shrink:0}.trigger-clear-btn{display:flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:50%;font-size:.6875rem;color:var(--rpt-color-text-muted, #64748b);background-color:#f1f5f9;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .15s ease,color .15s ease}.trigger-clear-btn:hover{background-color:#e2e8f0;color:var(--rpt-color-text, #0f172a)}.trigger-arrow{display:flex;align-items:center;color:var(--rpt-color-text-muted, #64748b);transition:transform .18s ease}.trigger-arrow.rotated{transform:rotate(180deg)}.rpt-combobox-menu{width:100%;min-width:180px;max-width:100vw;box-sizing:border-box;background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);box-shadow:0 10px 25px -5px #00000024,0 8px 10px -6px #00000014;overflow:hidden;display:flex;flex-direction:column;animation:rpt-dropdown-pop .12s cubic-bezier(0,0,.2,1)}.rpt-combobox-menu.opens-above{box-shadow:0 -10px 25px -5px #00000024,0 -8px 10px -6px #00000014;animation:rpt-dropdown-pop-above .12s cubic-bezier(0,0,.2,1)}@keyframes rpt-dropdown-pop{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}@keyframes rpt-dropdown-pop-above{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.combobox-search-box{display:flex;align-items:center;gap:8px;padding:8px 10px;border-bottom:1px solid var(--rpt-color-border, #e2e8f0);background-color:#f8fafc}.combobox-search-icon{color:var(--rpt-color-text-muted, #94a3b8);display:flex;align-items:center;flex-shrink:0}.combobox-search-input{flex:1;border:none;outline:none;background:transparent;font-size:var(--rpt-font-size-sm, .8125rem);font-family:inherit;color:var(--rpt-color-text, #0f172a);min-width:0}.combobox-search-input::placeholder{color:#94a3b8}.combobox-search-clear{border:none;background:#e2e8f0;color:#64748b;width:16px;height:16px;border-radius:50%;font-size:.625rem;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0}.combobox-search-clear:hover{background:#cbd5e1;color:#0f172a}.combobox-options-list{max-height:220px;overflow-y:auto;overscroll-behavior:contain;padding:4px}.combobox-option-item{display:flex;align-items:center;justify-content:space-between;padding:7px 10px;border-radius:4px;font-size:var(--rpt-font-size-base, .84rem);color:var(--rpt-color-text, #0f172a);cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .1s ease}.combobox-option-item.is-focused{background-color:var(--rpt-color-surface-hover, #f1f5f9)}.combobox-option-item.is-selected{background-color:#eff6ff;color:var(--rpt-color-primary, #2563eb);font-weight:600}.opt-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.opt-check{font-size:.875rem;font-weight:700;color:var(--rpt-color-primary, #2563eb);margin-left:8px}.combobox-status-row{padding:10px 12px;font-size:.78rem;text-align:center;color:var(--rpt-color-text-muted, #64748b)}.combobox-status-row.loading{display:flex;align-items:center;justify-content:center;gap:6px;color:#2563eb}.combobox-status-row.error{display:flex;flex-direction:column;align-items:center;gap:6px;color:var(--rpt-color-danger, #dc2626)}.trigger-retry-btn,.combobox-retry-btn,.rpt-badge-retry-btn{display:inline-flex;align-items:center;gap:3px;font-size:.6875rem;font-weight:600;color:#dc2626;background:#fee2e2;border:1px solid #fca5a5;border-radius:4px;padding:2px 7px;cursor:pointer;line-height:1.2;transition:background-color .12s ease,color .12s ease}.trigger-retry-btn:hover,.combobox-retry-btn:hover,.rpt-badge-retry-btn:hover{background:#fecaca;color:#b91c1c;border-color:#f87171}.combobox-status-row.hint{font-size:.72rem;color:#64748b;border-top:1px dashed #cbd5e1;margin-top:4px;padding:6px 10px;background-color:#f8fafc;display:flex;align-items:center;justify-content:space-between;gap:8px;position:sticky;bottom:0;z-index:2;box-shadow:0 -2px 6px #0000000a}.combobox-load-all-btn{background:#eff6ff;border:1px solid #bfdbfe;color:#2563eb;font-size:.6875rem;font-weight:600;padding:3px 8px;border-radius:4px;cursor:pointer;white-space:nowrap;flex-shrink:0;transition:all .12s ease}.combobox-load-all-btn:hover{background:#2563eb;color:#fff;border-color:#2563eb}.rpt-error-text{font-size:.7rem;color:var(--rpt-color-danger, #ef4444);margin-top:3px;line-height:1.25;max-width:100%;overflow-wrap:anywhere;word-break:break-word;display:block}\n"], dependencies: [{ kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { 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.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: OverlayModule }, { kind: "directive", type: i2.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i2.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
426
519
  }
427
520
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: RptDropdownComponent, decorators: [{
428
521
  type: Component,
429
- args: [{ selector: 'rpt-dropdown', standalone: true, imports: [ReactiveFormsModule], host: {
522
+ args: [{ selector: 'rpt-dropdown', standalone: true, imports: [ReactiveFormsModule, OverlayModule], host: {
430
523
  '[class.is-open]': 'isOpen()',
431
524
  '[class.opens-above]': 'opensAbove()',
432
- }, changeDetection: ChangeDetectionStrategy.OnPush, template: " <div class=\"rpt-field-group\">\n @if (config().label) {\n <label [for]=\"elementId()\" class=\"rpt-label\">\n {{ config().label }}\n @if (config().validation?.required) {\n <span class=\"rpt-required-marker\">*</span>\n }\n </label>\n }\n\n @if (isSearchable()) {\n <!-- Searchable Typeahead Combobox -->\n <div class=\"rpt-combobox-wrapper\" #comboboxWrapper>\n <button\n type=\"button\"\n class=\"rpt-combobox-trigger\"\n [id]=\"elementId()\"\n [class.rpt-invalid]=\"isInvalid()\"\n [class.is-open]=\"isOpen()\"\n [disabled]=\"formControl().disabled\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'listbox'\"\n (click)=\"toggleOpen($event)\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n <span class=\"trigger-label\" [class.is-placeholder]=\"!selectedOption()\">\n {{ selectedOption() ? selectedOption()!.label : placeholder() }}\n </span>\n\n <div class=\"trigger-actions\">\n @if (selectedOption() && !formControl().disabled) {\n <span\n role=\"button\"\n tabindex=\"0\"\n class=\"trigger-clear-btn\"\n title=\"Clear selection\"\n aria-label=\"Clear selection\"\n (click)=\"clearSelection($event)\"\n (keydown.enter)=\"clearSelection($event)\"\n (keydown.space)=\"clearSelection($event)\"\n >\n \u2715\n </span>\n }\n <span class=\"trigger-arrow\" [class.rotated]=\"isOpen()\" aria-hidden=\"true\">\n <svg width=\"12\" height=\"8\" viewBox=\"0 0 12 8\" fill=\"none\">\n <path d=\"M1 1.5L6 6.5L11 1.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n </div>\n </button>\n\n @if (isOpen()) {\n <div\n class=\"rpt-combobox-menu\"\n [class.opens-above]=\"opensAbove()\"\n role=\"listbox\"\n (click)=\"$event.stopPropagation()\"\n >\n <!-- Real-time Filter Search Box -->\n <div class=\"combobox-search-box\">\n <span class=\"combobox-search-icon\" aria-hidden=\"true\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"11\" cy=\"11\" r=\"8\"></circle>\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line>\n </svg>\n </span>\n <input\n #searchInput\n type=\"text\"\n class=\"combobox-search-input\"\n placeholder=\"Type to filter...\"\n [value]=\"searchTerm()\"\n [attr.aria-activedescendant]=\"focusedIndex() >= 0 ? (elementId() + '_opt_' + focusedIndex()) : null\"\n (input)=\"onSearchInput($event)\"\n (keydown)=\"onSearchKeydown($event)\"\n />\n @if (searchTerm()) {\n <button\n type=\"button\"\n class=\"combobox-search-clear\"\n title=\"Clear filter\"\n (click)=\"clearSearch($event)\"\n >\n \u2715\n </button>\n }\n </div>\n\n <!-- Filtered Options List -->\n <div class=\"combobox-options-list\" #optionsListEl>\n @if (isLoading()) {\n <div class=\"combobox-status-row loading\">\n <span class=\"status-dot dot-pulse\"></span>\n <span>Loading options from database...</span>\n </div>\n } @else if (loadError()) {\n <div class=\"combobox-status-row error\">\n <span>Error: {{ loadError() }}</span>\n </div>\n } @else if (isDynamicSource() && hasLoaded() && allOptions().length === 0) {\n <div class=\"combobox-status-row empty\">\n <span>No records found (check parameters)</span>\n </div>\n } @else if (filteredOptions().length === 0) {\n <div class=\"combobox-status-row empty\">\n <span>No options matching \"{{ searchTerm() }}\"</span>\n </div>\n } @else {\n @for (opt of visibleFilteredOptions(); track opt.key; let i = $index) {\n <div\n role=\"option\"\n [id]=\"elementId() + '_opt_' + i\"\n class=\"combobox-option-item\"\n [class.is-selected]=\"isSelected(opt)\"\n [class.is-focused]=\"focusedIndex() === i\"\n [attr.aria-selected]=\"isSelected(opt)\"\n (click)=\"selectOption(opt)\"\n (mouseenter)=\"focusedIndex.set(i)\"\n >\n <span class=\"opt-label\">{{ opt.label }}</span>\n @if (isSelected(opt)) {\n <span class=\"opt-check\" aria-hidden=\"true\">\u2713</span>\n }\n </div>\n }\n @if (excessFilteredCount() > 0) {\n <div class=\"combobox-status-row hint\">\n <span>Showing {{ MAX_FILTER_RENDER }} of {{ filteredOptions().length }} matches. Type to refine.</span>\n </div>\n }\n }\n </div>\n </div>\n }\n </div>\n } @else {\n <!-- Native Browser Select Fallback -->\n <div class=\"rpt-select-wrapper\">\n <select\n [id]=\"elementId()\"\n [formControl]=\"formControl()\"\n [class.rpt-invalid]=\"isInvalid()\"\n class=\"rpt-select\"\n >\n @if (isLoading()) {\n <option value=\"\" disabled selected>Loading options from database...</option>\n } @else if (loadError()) {\n <option value=\"\" disabled selected>Error: {{ loadError() }}</option>\n } @else if (isDynamicSource() && hasLoaded() && allOptions().length === 0) {\n <option value=\"\" disabled selected>-- No records found (check parameters) --</option>\n } @else if (placeholder()) {\n <option value=\"\" [disabled]=\"config().validation?.required\">{{ placeholder() }}</option>\n }\n @for (opt of renderedOptions(); track opt.key) {\n <option [value]=\"opt.key\">{{ opt.label }}</option>\n }\n @if (hasExcessOptions()) {\n <option value=\"\" disabled>... and {{ excessOptionsCount() }} more records (refine filter) ...</option>\n }\n </select>\n <div class=\"rpt-select-arrow\" aria-hidden=\"true\">\n <svg width=\"12\" height=\"8\" viewBox=\"0 0 12 8\" fill=\"none\">\n <path d=\"M1 1.5L6 6.5L11 1.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n </div>\n }\n\n @if (showStatus() && isDynamicSource() && statusText()) {\n <div class=\"rpt-status-badge\" [attr.data-status]=\"statusKind()\">\n @switch (statusKind()) {\n @case ('loading') {\n <span class=\"status-dot dot-pulse\"></span>\n <span>Loading from database\u2026</span>\n }\n @case ('ok') {\n <span class=\"status-dot dot-ok\"></span>\n <span>{{ dynamicOptions().length }} records loaded</span>\n }\n @case ('waiting') {\n <span class=\"status-dot dot-warn\"></span>\n <span>Waiting for:</span>\n <div class=\"waiting-tokens\">\n @for (k of waitingFor(); track k) {\n <span class=\"waiting-token\">{{ k }}</span>\n }\n </div>\n }\n @case ('error') {\n <span class=\"status-dot dot-err\"></span>\n <span>{{ loadError() }}</span>\n }\n @case ('empty') {\n <span class=\"status-dot\"></span>\n <span>No records found for parameters</span>\n }\n @default {\n <span class=\"status-dot\"></span>\n }\n }\n </div>\n }\n\n @if (errorMessage()) {\n <span class=\"rpt-error-text\">{{ errorMessage() }}</span>\n }\n </div>", styles: [":host{display:block;width:100%;max-width:100%;min-width:0;box-sizing:border-box;font-family:var(--rpt-font-family, inherit);position:relative}.rpt-status-badge{display:flex;flex-wrap:wrap;align-items:center;gap:4px;font-size:.6875rem;padding:3px 6px;border-radius:4px;margin-top:4px;font-weight:500;line-height:1.3;max-width:100%;box-sizing:border-box;overflow:hidden;word-break:break-word}.rpt-status-badge>span{overflow-wrap:anywhere;word-break:break-word}.rpt-status-badge[data-status=loading]{background:#eff6ff;color:#2563eb;border:1px solid #dbeafe}.rpt-status-badge[data-status=ok]{background:#f0fdf4;color:#16a34a;border:1px solid #dcfce7}.rpt-status-badge[data-status=waiting]{background:#fffbeb;color:#d97706;border:1px solid #fef3c7}.rpt-status-badge[data-status=error]{background:#fef2f2;color:#dc2626;border:1px solid #fee2e2}.rpt-status-badge[data-status=empty]{background:#f8fafc;color:#64748b;border:1px solid #e2e8f0}.waiting-tokens{display:inline-flex;flex-wrap:wrap;align-items:center;gap:3px;margin-left:2px;max-width:100%}.waiting-token{background:#b453091f;border:1px solid rgba(180,83,9,.3);padding:1px 5px;border-radius:3px;font-weight:700;font-size:.625rem;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block;box-sizing:border-box}.status-dot{width:6px;height:6px;border-radius:50%;background:currentColor}.dot-pulse{animation:rpt-pulse 1s infinite alternate}@keyframes rpt-pulse{0%{opacity:.3}to{opacity:1}}.rpt-field-group{display:flex;flex-direction:column;max-width:100%;min-width:0;gap:4px;box-sizing:border-box;position:relative}.rpt-label{font-size:var(--rpt-font-size-sm, .75rem);font-weight:500;color:var(--rpt-color-text, #0f172a);flex-shrink:0}.rpt-required-marker{color:var(--rpt-color-danger, #ef4444);margin-left:2px}.rpt-select-wrapper{position:relative;width:100%;flex:1;min-height:0;display:flex;align-items:center}.rpt-select{width:100%;height:100%;min-height:38px;box-sizing:border-box;padding:6px 36px 6px 12px;font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text, #0f172a);background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);appearance:none;-webkit-appearance:none;outline:none;cursor:pointer;transition:border-color var(--rpt-transition-speed, .15s) ease,box-shadow var(--rpt-transition-speed, .15s) ease}.rpt-select:hover:not(:disabled){border-color:var(--rpt-color-border-hover, #94a3b8)}.rpt-select:focus{border-color:var(--rpt-color-border-focus, #2563eb);box-shadow:var(--rpt-box-shadow-focus, 0 0 0 3px rgba(37, 99, 235, .25))}.rpt-select:disabled{background-color:var(--rpt-color-surface, #f8fafc);color:var(--rpt-color-text-muted, #64748b);cursor:not-allowed}.rpt-select.rpt-invalid{border-color:var(--rpt-color-danger, #ef4444)}.rpt-select.rpt-invalid:focus{box-shadow:0 0 0 3px #ef444440}.rpt-select-arrow{position:absolute;right:12px;top:50%;transform:translateY(-50%);pointer-events:none;color:var(--rpt-color-text-muted, #64748b);display:flex;align-items:center}.rpt-combobox-wrapper{position:relative;width:100%;flex:1;min-height:0}.rpt-combobox-trigger{width:100%;height:100%;min-height:38px;box-sizing:border-box;padding:6px 10px 6px 12px;display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:var(--rpt-font-size-base, .875rem);font-family:inherit;color:var(--rpt-color-text, #0f172a);background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);outline:none;cursor:pointer;text-align:left;transition:border-color var(--rpt-transition-speed, .15s) ease,box-shadow var(--rpt-transition-speed, .15s) ease}.rpt-combobox-trigger:hover:not(:disabled){border-color:var(--rpt-color-border-hover, #94a3b8)}.rpt-combobox-trigger:focus-visible,.rpt-combobox-trigger.is-open{border-color:var(--rpt-color-border-focus, #2563eb);box-shadow:var(--rpt-box-shadow-focus, 0 0 0 3px rgba(37, 99, 235, .25))}.rpt-combobox-trigger:disabled{background-color:var(--rpt-color-surface, #f8fafc);color:var(--rpt-color-text-muted, #64748b);cursor:not-allowed}.rpt-combobox-trigger.rpt-invalid{border-color:var(--rpt-color-danger, #ef4444)}.rpt-combobox-trigger.rpt-invalid:focus-visible{box-shadow:0 0 0 3px #ef444440}.trigger-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.3}.trigger-label.is-placeholder{color:var(--rpt-color-text-muted, #94a3b8)}.trigger-actions{display:flex;align-items:center;gap:6px;flex-shrink:0}.trigger-clear-btn{display:flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:50%;font-size:.6875rem;color:var(--rpt-color-text-muted, #64748b);background-color:#f1f5f9;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .15s ease,color .15s ease}.trigger-clear-btn:hover{background-color:#e2e8f0;color:var(--rpt-color-text, #0f172a)}.trigger-arrow{display:flex;align-items:center;color:var(--rpt-color-text-muted, #64748b);transition:transform .18s ease}.trigger-arrow.rotated{transform:rotate(180deg)}.rpt-combobox-menu{position:absolute;top:calc(100% + 4px);left:0;right:0;z-index:1050;background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);box-shadow:0 10px 25px -5px #0000001f,0 8px 10px -6px #00000014;overflow:hidden;display:flex;flex-direction:column;animation:rpt-dropdown-pop .12s cubic-bezier(0,0,.2,1)}.rpt-combobox-menu.opens-above{top:auto;bottom:calc(100% + 4px);box-shadow:0 -10px 25px -5px #0000001f,0 -8px 10px -6px #00000014;animation:rpt-dropdown-pop-above .12s cubic-bezier(0,0,.2,1)}@keyframes rpt-dropdown-pop{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}@keyframes rpt-dropdown-pop-above{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.combobox-search-box{display:flex;align-items:center;gap:8px;padding:8px 10px;border-bottom:1px solid var(--rpt-color-border, #e2e8f0);background-color:#f8fafc}.combobox-search-icon{color:var(--rpt-color-text-muted, #94a3b8);display:flex;align-items:center;flex-shrink:0}.combobox-search-input{flex:1;border:none;outline:none;background:transparent;font-size:var(--rpt-font-size-sm, .8125rem);font-family:inherit;color:var(--rpt-color-text, #0f172a);min-width:0}.combobox-search-input::placeholder{color:#94a3b8}.combobox-search-clear{border:none;background:#e2e8f0;color:#64748b;width:16px;height:16px;border-radius:50%;font-size:.625rem;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0}.combobox-search-clear:hover{background:#cbd5e1;color:#0f172a}.combobox-options-list{max-height:220px;overflow-y:auto;overscroll-behavior:contain;padding:4px}.combobox-option-item{display:flex;align-items:center;justify-content:space-between;padding:7px 10px;border-radius:4px;font-size:var(--rpt-font-size-base, .84rem);color:var(--rpt-color-text, #0f172a);cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .1s ease}.combobox-option-item.is-focused{background-color:var(--rpt-color-surface-hover, #f1f5f9)}.combobox-option-item.is-selected{background-color:#eff6ff;color:var(--rpt-color-primary, #2563eb);font-weight:600}.opt-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.opt-check{font-size:.875rem;font-weight:700;color:var(--rpt-color-primary, #2563eb);margin-left:8px}.combobox-status-row{padding:10px 12px;font-size:.78rem;text-align:center;color:var(--rpt-color-text-muted, #64748b)}.combobox-status-row.loading{display:flex;align-items:center;justify-content:center;gap:6px;color:#2563eb}.combobox-status-row.error{color:var(--rpt-color-danger, #dc2626)}.combobox-status-row.hint{font-size:.72rem;color:#94a3b8;border-top:1px dashed #e2e8f0;margin-top:4px;padding:6px}.rpt-error-text{font-size:.7rem;color:var(--rpt-color-danger, #ef4444);margin-top:3px;line-height:1.25;max-width:100%;overflow-wrap:anywhere;word-break:break-word;display:block}\n"] }]
525
+ }, changeDetection: ChangeDetectionStrategy.OnPush, template: " <div class=\"rpt-field-group\">\n @if (config().label) {\n <label [for]=\"elementId()\" class=\"rpt-label\">\n {{ config().label }}\n @if (config().validation?.required) {\n <span class=\"rpt-required-marker\">*</span>\n }\n </label>\n }\n\n @if (isSearchable()) {\n <!-- Searchable Typeahead Combobox -->\n <div class=\"rpt-combobox-wrapper\" #comboboxWrapper #comboboxOrigin=\"cdkOverlayOrigin\" cdkOverlayOrigin>\n <button\n type=\"button\"\n class=\"rpt-combobox-trigger\"\n [id]=\"elementId()\"\n [class.rpt-invalid]=\"isInvalid()\"\n [class.is-open]=\"isOpen()\"\n [disabled]=\"formControl().disabled\"\n [attr.aria-expanded]=\"isOpen()\"\n [attr.aria-haspopup]=\"'listbox'\"\n (click)=\"toggleOpen($event)\"\n (keydown)=\"onTriggerKeydown($event)\"\n >\n <span class=\"trigger-label\" [class.is-placeholder]=\"!selectedOption()\">\n {{ selectedOption() ? selectedOption()!.label : placeholder() }}\n </span>\n\n <div class=\"trigger-actions\">\n @if (isLoading()) {\n <span class=\"status-dot dot-pulse\" style=\"color: #2563eb; margin-right: 4px;\" title=\"Executing query on database...\"></span>\n }\n @if (loadError() && !isLoading()) {\n <button\n type=\"button\"\n class=\"trigger-retry-btn\"\n title=\"Retry database query\"\n aria-label=\"Retry database query\"\n (click)=\"retryLookup($event)\"\n >\n \u21BB Retry\n </button>\n }\n @if (selectedOption() && !formControl().disabled) {\n <span\n role=\"button\"\n tabindex=\"0\"\n class=\"trigger-clear-btn\"\n title=\"Clear selection\"\n aria-label=\"Clear selection\"\n (click)=\"clearSelection($event)\"\n (keydown.enter)=\"clearSelection($event)\"\n (keydown.space)=\"clearSelection($event)\"\n >\n \u2715\n </span>\n }\n <span class=\"trigger-arrow\" [class.rotated]=\"isOpen()\" aria-hidden=\"true\">\n <svg width=\"12\" height=\"8\" viewBox=\"0 0 12 8\" fill=\"none\">\n <path d=\"M1 1.5L6 6.5L11 1.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </span>\n </div>\n </button>\n </div>\n\n <ng-template\n cdkConnectedOverlay\n [cdkConnectedOverlayOrigin]=\"comboboxOrigin\"\n [cdkConnectedOverlayOpen]=\"isOpen()\"\n [cdkConnectedOverlayPositions]=\"overlayPositions\"\n [cdkConnectedOverlayWidth]=\"triggerWidth()\"\n [cdkConnectedOverlayFlexibleDimensions]=\"true\"\n [cdkConnectedOverlayViewportMargin]=\"8\"\n [cdkConnectedOverlayPush]=\"true\"\n [cdkConnectedOverlayScrollStrategy]=\"scrollStrategy\"\n (overlayOutsideClick)=\"closeDropdown()\"\n (positionChange)=\"onPositionChange($event)\"\n (attach)=\"onOverlayAttached()\"\n (detach)=\"closeDropdown()\"\n >\n <div\n class=\"rpt-combobox-menu\"\n [class.opens-above]=\"opensAbove()\"\n role=\"listbox\"\n (click)=\"$event.stopPropagation()\"\n >\n <!-- Real-time Filter Search Box -->\n <div class=\"combobox-search-box\">\n <span class=\"combobox-search-icon\" aria-hidden=\"true\">\n <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <circle cx=\"11\" cy=\"11\" r=\"8\"></circle>\n <line x1=\"21\" y1=\"21\" x2=\"16.65\" y2=\"16.65\"></line>\n </svg>\n </span>\n <input\n #searchInput\n type=\"text\"\n class=\"combobox-search-input\"\n placeholder=\"Type to filter...\"\n [value]=\"searchTerm()\"\n [attr.aria-activedescendant]=\"focusedIndex() >= 0 ? (elementId() + '_opt_' + focusedIndex()) : null\"\n (input)=\"onSearchInput($event)\"\n (keydown)=\"onSearchKeydown($event)\"\n />\n @if (searchTerm()) {\n <button\n type=\"button\"\n class=\"combobox-search-clear\"\n title=\"Clear filter\"\n (click)=\"clearSearch($event)\"\n >\n \u2715\n </button>\n }\n </div>\n\n <!-- Filtered Options List -->\n <div class=\"combobox-options-list\" #optionsListEl (scroll)=\"onOptionsScroll($event)\">\n @if (waitingFor().length > 0) {\n <div class=\"combobox-status-row waiting\">\n <span>Waiting for {{ waitingLabel() }}...</span>\n </div>\n } @else if (isLoading()) {\n <div class=\"combobox-status-row loading\">\n <span class=\"status-dot dot-pulse\"></span>\n <span>Executing query on database (may take 1\u20132 minutes on local database)...</span>\n </div>\n } @else if (loadError()) {\n <div class=\"combobox-status-row error\">\n <span>Error: {{ loadError() }}</span>\n <button type=\"button\" class=\"combobox-retry-btn\" (click)=\"retryLookup($event)\">\u21BB Retry Query</button>\n </div>\n } @else if (isDynamicSource() && hasLoaded() && allOptions().length === 0) {\n <div class=\"combobox-status-row empty\">\n <span>No records found (check parameters)</span>\n </div>\n } @else if (filteredOptions().length === 0) {\n <div class=\"combobox-status-row empty\">\n <span>No options matching \"{{ searchTerm() }}\"</span>\n </div>\n } @else {\n @for (opt of visibleFilteredOptions(); track opt.key; let i = $index) {\n <div\n role=\"option\"\n [id]=\"elementId() + '_opt_' + i\"\n class=\"combobox-option-item\"\n [class.is-selected]=\"isSelected(opt)\"\n [class.is-focused]=\"focusedIndex() === i\"\n [attr.aria-selected]=\"isSelected(opt)\"\n (click)=\"selectOption(opt)\"\n (mouseenter)=\"focusedIndex.set(i)\"\n >\n <span class=\"opt-label\">{{ opt.label }}</span>\n @if (isSelected(opt)) {\n <span class=\"opt-check\" aria-hidden=\"true\">\u2713</span>\n }\n </div>\n }\n @if (excessFilteredCount() > 0) {\n <div class=\"combobox-status-row hint\">\n <span>Showing {{ visibleFilteredOptions().length }} of {{ filteredOptions().length }} matches. Scroll down or</span>\n <button\n type=\"button\"\n class=\"combobox-load-all-btn\"\n (click)=\"loadAllFiltered(); $event.stopPropagation();\"\n >\n Load all {{ filteredOptions().length }}\n </button>\n </div>\n }\n }\n </div>\n </div>\n </ng-template>\n } @else {\n <!-- Native Browser Select Fallback -->\n <div class=\"rpt-select-wrapper\">\n <select\n [id]=\"elementId()\"\n [formControl]=\"formControl()\"\n [class.rpt-invalid]=\"isInvalid()\"\n class=\"rpt-select\"\n >\n @if (waitingFor().length > 0) {\n <option value=\"\" disabled selected>Waiting for {{ waitingLabel() }}...</option>\n } @else if (isLoading()) {\n <option value=\"\" disabled selected>Loading options from database...</option>\n } @else if (loadError()) {\n <option value=\"\" disabled selected>Error: {{ loadError() }}</option>\n } @else if (isDynamicSource() && hasLoaded() && allOptions().length === 0) {\n <option value=\"\" disabled selected>-- No records found (check parameters) --</option>\n } @else if (placeholder()) {\n <option value=\"\" [disabled]=\"config().validation?.required\">{{ placeholder() }}</option>\n }\n @for (opt of renderedOptions(); track opt.key) {\n <option [value]=\"opt.key\">{{ opt.label }}</option>\n }\n @if (hasExcessOptions()) {\n <option value=\"\" disabled>... and {{ excessOptionsCount() }} more records (refine filter) ...</option>\n }\n </select>\n <div class=\"rpt-select-arrow\" aria-hidden=\"true\">\n <svg width=\"12\" height=\"8\" viewBox=\"0 0 12 8\" fill=\"none\">\n <path d=\"M1 1.5L6 6.5L11 1.5\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\n </svg>\n </div>\n </div>\n }\n\n @if (showStatus() && isDynamicSource() && statusText()) {\n <div class=\"rpt-status-badge\" [attr.data-status]=\"statusKind()\">\n @switch (statusKind()) {\n @case ('loading') {\n <span class=\"status-dot dot-pulse\"></span>\n <span>Loading from database\u2026</span>\n }\n @case ('ok') {\n <span class=\"status-dot dot-ok\"></span>\n <span>{{ dynamicOptions().length }} records loaded</span>\n }\n @case ('waiting') {\n <span class=\"status-dot dot-warn\"></span>\n <span>Waiting for:</span>\n <div class=\"waiting-tokens\">\n @for (k of waitingFor(); track k) {\n <span class=\"waiting-token\">{{ k }}</span>\n }\n </div>\n }\n @case ('error') {\n <span class=\"status-dot dot-err\"></span>\n <span>{{ loadError() }}</span>\n <button type=\"button\" class=\"rpt-badge-retry-btn\" (click)=\"retryLookup($event)\">\u21BB Retry</button>\n }\n @case ('empty') {\n <span class=\"status-dot\"></span>\n <span>No records found for parameters</span>\n }\n @default {\n <span class=\"status-dot\"></span>\n }\n }\n </div>\n }\n\n @if (errorMessage()) {\n <span class=\"rpt-error-text\">{{ errorMessage() }}</span>\n }\n </div>", styles: [":host{display:block;width:100%;max-width:100%;min-width:0;box-sizing:border-box;font-family:var(--rpt-font-family, inherit);position:relative}.rpt-status-badge{display:flex;flex-wrap:wrap;align-items:center;gap:4px;font-size:.6875rem;padding:3px 6px;border-radius:4px;margin-top:4px;font-weight:500;line-height:1.3;max-width:100%;box-sizing:border-box;overflow:hidden;word-break:break-word}.rpt-status-badge>span{overflow-wrap:anywhere;word-break:break-word}.rpt-status-badge[data-status=loading]{background:#eff6ff;color:#2563eb;border:1px solid #dbeafe}.rpt-status-badge[data-status=ok]{background:#f0fdf4;color:#16a34a;border:1px solid #dcfce7}.rpt-status-badge[data-status=waiting]{background:#fffbeb;color:#d97706;border:1px solid #fef3c7}.rpt-status-badge[data-status=error]{background:#fef2f2;color:#dc2626;border:1px solid #fee2e2}.rpt-status-badge[data-status=empty]{background:#f8fafc;color:#64748b;border:1px solid #e2e8f0}.waiting-tokens{display:inline-flex;flex-wrap:wrap;align-items:center;gap:3px;margin-left:2px;max-width:100%}.waiting-token{background:#b453091f;border:1px solid rgba(180,83,9,.3);padding:1px 5px;border-radius:3px;font-weight:700;font-size:.625rem;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;display:inline-block;box-sizing:border-box}.status-dot{width:6px;height:6px;border-radius:50%;background:currentColor}.dot-pulse{animation:rpt-pulse 1s infinite alternate}@keyframes rpt-pulse{0%{opacity:.3}to{opacity:1}}.rpt-field-group{display:flex;flex-direction:column;max-width:100%;min-width:0;gap:4px;box-sizing:border-box;position:relative}.rpt-label{font-size:var(--rpt-font-size-sm, .75rem);font-weight:500;color:var(--rpt-color-text, #0f172a);flex-shrink:0}.rpt-required-marker{color:var(--rpt-color-danger, #ef4444);margin-left:2px}.rpt-select-wrapper{position:relative;width:100%;flex:1;min-height:0;display:flex;align-items:center}.rpt-select{width:100%;height:100%;min-height:38px;box-sizing:border-box;padding:6px 36px 6px 12px;font-size:var(--rpt-font-size-base, .875rem);color:var(--rpt-color-text, #0f172a);background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);appearance:none;-webkit-appearance:none;outline:none;cursor:pointer;transition:border-color var(--rpt-transition-speed, .15s) ease,box-shadow var(--rpt-transition-speed, .15s) ease}.rpt-select:hover:not(:disabled){border-color:var(--rpt-color-border-hover, #94a3b8)}.rpt-select:focus{border-color:var(--rpt-color-border-focus, #2563eb);box-shadow:var(--rpt-box-shadow-focus, 0 0 0 3px rgba(37, 99, 235, .25))}.rpt-select:disabled{background-color:var(--rpt-color-surface, #f8fafc);color:var(--rpt-color-text-muted, #64748b);cursor:not-allowed}.rpt-select.rpt-invalid{border-color:var(--rpt-color-danger, #ef4444)}.rpt-select.rpt-invalid:focus{box-shadow:0 0 0 3px #ef444440}.rpt-select-arrow{position:absolute;right:12px;top:50%;transform:translateY(-50%);pointer-events:none;color:var(--rpt-color-text-muted, #64748b);display:flex;align-items:center}.rpt-combobox-wrapper{position:relative;width:100%;flex:1;min-height:0}.rpt-combobox-trigger{width:100%;height:100%;min-height:38px;box-sizing:border-box;padding:6px 10px 6px 12px;display:flex;align-items:center;justify-content:space-between;gap:8px;font-size:var(--rpt-font-size-base, .875rem);font-family:inherit;color:var(--rpt-color-text, #0f172a);background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);outline:none;cursor:pointer;text-align:left;transition:border-color var(--rpt-transition-speed, .15s) ease,box-shadow var(--rpt-transition-speed, .15s) ease}.rpt-combobox-trigger:hover:not(:disabled){border-color:var(--rpt-color-border-hover, #94a3b8)}.rpt-combobox-trigger:focus-visible,.rpt-combobox-trigger.is-open{border-color:var(--rpt-color-border-focus, #2563eb);box-shadow:var(--rpt-box-shadow-focus, 0 0 0 3px rgba(37, 99, 235, .25))}.rpt-combobox-trigger:disabled{background-color:var(--rpt-color-surface, #f8fafc);color:var(--rpt-color-text-muted, #64748b);cursor:not-allowed}.rpt-combobox-trigger.rpt-invalid{border-color:var(--rpt-color-danger, #ef4444)}.rpt-combobox-trigger.rpt-invalid:focus-visible{box-shadow:0 0 0 3px #ef444440}.trigger-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.3}.trigger-label.is-placeholder{color:var(--rpt-color-text-muted, #94a3b8)}.trigger-actions{display:flex;align-items:center;gap:6px;flex-shrink:0}.trigger-clear-btn{display:flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:50%;font-size:.6875rem;color:var(--rpt-color-text-muted, #64748b);background-color:#f1f5f9;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .15s ease,color .15s ease}.trigger-clear-btn:hover{background-color:#e2e8f0;color:var(--rpt-color-text, #0f172a)}.trigger-arrow{display:flex;align-items:center;color:var(--rpt-color-text-muted, #64748b);transition:transform .18s ease}.trigger-arrow.rotated{transform:rotate(180deg)}.rpt-combobox-menu{width:100%;min-width:180px;max-width:100vw;box-sizing:border-box;background-color:var(--rpt-color-bg, #ffffff);border:1px solid var(--rpt-color-border, #cbd5e1);border-radius:var(--rpt-border-radius, 6px);box-shadow:0 10px 25px -5px #00000024,0 8px 10px -6px #00000014;overflow:hidden;display:flex;flex-direction:column;animation:rpt-dropdown-pop .12s cubic-bezier(0,0,.2,1)}.rpt-combobox-menu.opens-above{box-shadow:0 -10px 25px -5px #00000024,0 -8px 10px -6px #00000014;animation:rpt-dropdown-pop-above .12s cubic-bezier(0,0,.2,1)}@keyframes rpt-dropdown-pop{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}@keyframes rpt-dropdown-pop-above{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.combobox-search-box{display:flex;align-items:center;gap:8px;padding:8px 10px;border-bottom:1px solid var(--rpt-color-border, #e2e8f0);background-color:#f8fafc}.combobox-search-icon{color:var(--rpt-color-text-muted, #94a3b8);display:flex;align-items:center;flex-shrink:0}.combobox-search-input{flex:1;border:none;outline:none;background:transparent;font-size:var(--rpt-font-size-sm, .8125rem);font-family:inherit;color:var(--rpt-color-text, #0f172a);min-width:0}.combobox-search-input::placeholder{color:#94a3b8}.combobox-search-clear{border:none;background:#e2e8f0;color:#64748b;width:16px;height:16px;border-radius:50%;font-size:.625rem;cursor:pointer;display:flex;align-items:center;justify-content:center;padding:0}.combobox-search-clear:hover{background:#cbd5e1;color:#0f172a}.combobox-options-list{max-height:220px;overflow-y:auto;overscroll-behavior:contain;padding:4px}.combobox-option-item{display:flex;align-items:center;justify-content:space-between;padding:7px 10px;border-radius:4px;font-size:var(--rpt-font-size-base, .84rem);color:var(--rpt-color-text, #0f172a);cursor:pointer;-webkit-user-select:none;user-select:none;transition:background-color .1s ease}.combobox-option-item.is-focused{background-color:var(--rpt-color-surface-hover, #f1f5f9)}.combobox-option-item.is-selected{background-color:#eff6ff;color:var(--rpt-color-primary, #2563eb);font-weight:600}.opt-label{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.opt-check{font-size:.875rem;font-weight:700;color:var(--rpt-color-primary, #2563eb);margin-left:8px}.combobox-status-row{padding:10px 12px;font-size:.78rem;text-align:center;color:var(--rpt-color-text-muted, #64748b)}.combobox-status-row.loading{display:flex;align-items:center;justify-content:center;gap:6px;color:#2563eb}.combobox-status-row.error{display:flex;flex-direction:column;align-items:center;gap:6px;color:var(--rpt-color-danger, #dc2626)}.trigger-retry-btn,.combobox-retry-btn,.rpt-badge-retry-btn{display:inline-flex;align-items:center;gap:3px;font-size:.6875rem;font-weight:600;color:#dc2626;background:#fee2e2;border:1px solid #fca5a5;border-radius:4px;padding:2px 7px;cursor:pointer;line-height:1.2;transition:background-color .12s ease,color .12s ease}.trigger-retry-btn:hover,.combobox-retry-btn:hover,.rpt-badge-retry-btn:hover{background:#fecaca;color:#b91c1c;border-color:#f87171}.combobox-status-row.hint{font-size:.72rem;color:#64748b;border-top:1px dashed #cbd5e1;margin-top:4px;padding:6px 10px;background-color:#f8fafc;display:flex;align-items:center;justify-content:space-between;gap:8px;position:sticky;bottom:0;z-index:2;box-shadow:0 -2px 6px #0000000a}.combobox-load-all-btn{background:#eff6ff;border:1px solid #bfdbfe;color:#2563eb;font-size:.6875rem;font-weight:600;padding:3px 8px;border-radius:4px;cursor:pointer;white-space:nowrap;flex-shrink:0;transition:all .12s ease}.combobox-load-all-btn:hover{background:#2563eb;color:#fff;border-color:#2563eb}.rpt-error-text{font-size:.7rem;color:var(--rpt-color-danger, #ef4444);margin-top:3px;line-height:1.25;max-width:100%;overflow-wrap:anywhere;word-break:break-word;display:block}\n"] }]
433
526
  }], ctorParameters: () => [], propDecorators: { onDocumentClick: [{
434
527
  type: HostListener,
435
528
  args: ['document:click', ['$event']]
@@ -437,4 +530,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
437
530
  type: HostListener,
438
531
  args: ['document:keydown.escape']
439
532
  }] } });
440
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnB0LWRyb3Bkb3duLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2J3YXlzLXJlcG9ydC9zcmMvbGliL3ByaW1pdGl2ZXMvY29tcG9uZW50cy9kcm9wZG93bi9ycHQtZHJvcGRvd24uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYndheXMtcmVwb3J0L3NyYy9saWIvcHJpbWl0aXZlcy9jb21wb25lbnRzL2Ryb3Bkb3duL3JwdC1kcm9wZG93bi5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxRQUFRLEVBQ1IsTUFBTSxFQUNOLFVBQVUsRUFDVixZQUFZLEVBQ1osTUFBTSxFQUNOLEtBQUssRUFFTCxNQUFNLEVBQ04sU0FBUyxFQUNULFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsV0FBVyxFQUFhLG1CQUFtQixFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFHN0UsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sNkNBQTZDLENBQUM7QUFDbkYsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0scURBQXFELENBQUM7QUFDekYsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sZ0RBQWdELENBQUM7QUFDckYsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sdURBQXVELENBQUM7QUFFcEcsT0FBTyxFQUNMLHVCQUF1QixFQUN2Qix3QkFBd0IsR0FDekIsTUFBTSwyQ0FBMkMsQ0FBQzs7O0FBbUJuRCxNQUFNLE9BQU8sb0JBQW9CO0lBQ2Qsa0JBQWtCLEdBQUcsTUFBTSxDQUFDLGtCQUFrQixFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDcEUsYUFBYSxHQUFHLE1BQU0sQ0FBQyxtQkFBbUIsRUFBRSxFQUFF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Q3ZDLEtBQUssRUFBRSxNQUFNLENBQUMsRUFBRSxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO3FCQUM1QyxDQUFDLENBQUMsQ0FDSixDQUFDO2dCQUNKLENBQUM7Z0JBQ0QsS0FBSyxFQUFFLENBQUMsR0FBRyxFQUFFLEVBQUU7b0JBQ2IsT0FBTyxDQUFDLEtBQUssQ0FBQyxnREFBZ0QsRUFBRSxDQUFDLFVBQVUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO29CQUNyRixJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDMUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7b0JBQ3pCLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxPQUFPLElBQUksNEJBQTRCLENBQUMsQ0FBQztnQkFDbkUsQ0FBQzthQUNGLENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDO3dHQTFjVSxvQkFBb0I7NEZBQXBCLG9CQUFvQixpb0NDNUNqQyw2OFJBK01VLGs3UEQ1S0UsbUJBQW1COzs0RkFTbEIsb0JBQW9CO2tCQVpoQyxTQUFTOytCQUNFLGNBQWMsY0FDWixJQUFJLFdBQ1AsQ0FBQyxtQkFBbUIsQ0FBQyxRQUN4Qjt3QkFDSixpQkFBaUIsRUFBRSxVQUFVO3dCQUM3QixxQkFBcUIsRUFBRSxjQUFjO3FCQUN0QyxtQkFHZ0IsdUJBQXVCLENBQUMsTUFBTTt3REF1Sy9DLGVBQWU7c0JBRGQsWUFBWTt1QkFBQyxnQkFBZ0IsRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkFVMUMsUUFBUTtzQkFEUCxZQUFZO3VCQUFDLHlCQUF5QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDb21wb25lbnQsXG4gIGNvbXB1dGVkLFxuICBlZmZlY3QsXG4gIEVsZW1lbnRSZWYsXG4gIEhvc3RMaXN0ZW5lcixcbiAgaW5qZWN0LFxuICBpbnB1dCxcbiAgT25EZXN0cm95LFxuICBzaWduYWwsXG4gIHVudHJhY2tlZCxcbiAgdmlld0NoaWxkLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1Db250cm9sLCBGb3JtR3JvdXAsIFJlYWN0aXZlRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IFJlcG9ydENvbXBvbmVudERlZmluaXRpb24gfSBmcm9tICcuLi8uLi8uLi9jb3JlL21vZGVscy9yZXBvcnQtY29tcG9uZW50Lm1vZGVsJztcbmltcG9ydCB7IGdldFZhbGlkYXRpb25NZXNzYWdlIH0gZnJvbSAnLi4vLi4vLi4vY29yZS92YWxpZGF0aW9uL3ZhbGlkYXRpb24tZmFjdG9yeSc7XG5pbXBvcnQgeyBNYXN0ZXJEYXRhUHJvdmlkZXIgfSBmcm9tICcuLi8uLi8uLi9kYXRhLWFjY2Vzcy9jb250cmFjdHMvbWFzdGVyLWRhdGEucHJvdmlkZXInO1xuaW1wb3J0IHsgUmVwb3J0TG9va3VwQWRhcHRlciB9IGZyb20gJy4uLy4uLy4uL2RhdGEtYWNjZXNzL2NvbnRyYWN0cy9sb29rdXAuY29udHJhY3QnO1xuaW1wb3J0IHsgUmVwb3J0U2Vzc2lvbkNvbnRleHRTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vLi4vY29yZS9zZXJ2aWNlcy9yZXBvcnQtc2Vzc2lvbi1jb250ZXh0LnNlcnZpY2UnO1xuaW1wb3J0IHsgU2Vzc2lvbkNvbnRleHRNYXAgfSBmcm9tICcuLi8uLi8uLi9jb3JlL3Rva2Vucy9zZXNzaW9uLWNvbnRleHQudG9rZW4nO1xuaW1wb3J0IHtcbiAgZmluZE1pc3NpbmdDYW52YXNGaWVsZHMsXG4gIHJlc29sdmVQYXJhbWV0ZXJNYXBwaW5ncyxcbn0gZnJvbSAnLi4vLi4vLi4vY29yZS91dGlscy9yZXBvcnQtcGFyYW1ldGVyLnV0aWwnO1xuXG5leHBvcnQgaW50ZXJmYWNlIERyb3Bkb3duT3B0aW9uIHtcbiAga2V5OiBzdHJpbmcgfCBudW1iZXI7XG4gIGxhYmVsOiBzdHJpbmc7XG59XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3JwdC1kcm9wZG93bicsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtSZWFjdGl2ZUZvcm1zTW9kdWxlXSxcbiAgaG9zdDoge1xuICAgICdbY2xhc3MuaXMtb3Blbl0nOiAnaXNPcGVuKCknLFxuICAgICdbY2xhc3Mub3BlbnMtYWJvdmVdJzogJ29wZW5zQWJvdmUoKScsXG4gIH0sXG4gIHRlbXBsYXRlVXJsOiAnLi9ycHQtZHJvcGRvd24uY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybDogJy4vcnB0LWRyb3Bkb3duLmNvbXBvbmVudC5jc3MnLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgUnB0RHJvcGRvd25Db21wb25lbnQgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICBwcml2YXRlIHJlYWRvbmx5IG1hc3RlckRhdGFQcm92aWRlciA9IGluamVjdChNYXN0ZXJEYXRhUHJvdmlkZXIsIHsgb3B0aW9uYWw6IHRydWUgfSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgbG9va3VwQWRhcHRlciA9IGluamVjdChSZXBvcnRMb29rdXBBZGFwdGVyLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuICBwcml2YXRlIHJlYWRvbmx5IHNlc3Npb25TZXJ2aWNlID0gaW5qZWN0KFJlcG9ydFNlc3Npb25Db250ZXh0U2VydmljZSwgeyBvcHRpb25hbDogdHJ1ZSB9KTtcbiAgcHJpdmF0ZSByZWFkb25seSBlbGVtZW50UmVmID0gaW5qZWN0KEVsZW1lbnRSZWYpO1xuXG4gIHJlYWRvbmx5IGNvbmZpZyA9IGlucHV0LnJlcXVpcmVkPFJlcG9ydENvbXBvbmVudERlZmluaXRpb24+KCk7XG4gIHJlYWRvbmx5IGNvbnRyb2wgPSBpbnB1dDxGb3JtQ29udHJvbCB8IG51bGwgfCB1bmRlZmluZWQ+KCk7XG4gIHJlYWRvbmx5IHBhcmVudEZvcm0gPSBpbnB1dDxGb3JtR3JvdXAgfCBudWxsPihudWxsKTtcbiAgLyoqIERlc2lnbmVyIG1vZGU6IHNob3dzIGEgc21hbGwgc3RhdHVzIGxpbmUgKExvYWRpbmcgLyBOIHJlY29yZHMgLyBXYWl0aW5nIGZvcuKApikuICovXG4gIHJlYWRvbmx5IHNob3dTdGF0dXMgPSBpbnB1dDxib29sZWFuPihmYWxzZSk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBmYWxsYmFja0NvbnRyb2wgPSBuZXcgRm9ybUNvbnRyb2woJycpO1xuICByZWFkb25seSBkeW5hbWljT3B0aW9ucyA9IHNpZ25hbDxEcm9wZG93bk9wdGlvbltdPihbXSk7XG4gIHByaXZhdGUgbG9va3VwU3ViPzogU3Vic2NyaXB0aW9uO1xuICBwcml2YXRlIG1hc3RlckRhdGFTdWI/OiBTdWJzY3JpcHRpb247XG4gIHByaXZhdGUgZm9ybUNoYW5nZXNTdWI/OiBTdWJzY3JpcHRpb247XG4gIHByaXZhdGUgcmVsb2FkVGltZXI/OiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PjtcbiAgcHJpdmF0ZSBsYXN0UmVxdWVzdEtleSA9ICcnO1xuXG4gIC8vIENvbWJvYm94IGludGVyYWN0aXZlIHN0YXRlXG4gIHJlYWRvbmx5IGlzT3BlbiA9IHNpZ25hbDxib29sZWFuPihmYWxzZSk7XG4gIHJlYWRvbmx5IG9wZW5zQWJvdmUgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICByZWFkb25seSBzZWFyY2hUZXJtID0gc2lnbmFsPHN0cmluZz4oJycpO1xuICByZWFkb25seSBmb2N1c2VkSW5kZXggPSBzaWduYWw8bnVtYmVyPigtMSk7XG4gIHJlYWRvbmx5IGN1cnJlbnRWYWx1ZSA9IHNpZ25hbDx1bmtub3duPihudWxsKTtcbiAgcmVhZG9ubHkgY29tYm9ib3hXcmFwcGVyRWwgPSB2aWV3Q2hpbGQ8RWxlbWVudFJlZjxIVE1MRWxlbWVudD4+KCdjb21ib2JveFdyYXBwZXInKTtcbiAgcmVhZG9ubHkgc2VhcmNoSW5wdXRFbCA9IHZpZXdDaGlsZDxFbGVtZW50UmVmPEhUTUxJbnB1dEVsZW1lbnQ+Pignc2VhcmNoSW5wdXQnKTtcbiAgcmVhZG9ubHkgb3B0aW9uc0xpc3RFbCA9IHZpZXdDaGlsZDxFbGVtZW50UmVmPEhUTUxFbGVtZW50Pj4oJ29wdGlvbnNMaXN0RWwnKTtcblxuICBwcml2YXRlIGNvbnRyb2xTdWI/OiBTdWJzY3JpcHRpb247XG5cbiAgcmVhZG9ubHkgZm9ybUNvbnRyb2wgPSBjb21wdXRlZCgoKSA9PiB0aGlzLmNvbnRyb2woKSA/PyB0aGlzLmZhbGxiYWNrQ29udHJvbCk7XG4gIHJlYWRvbmx5IGVsZW1lbnRJZCA9IGNvbXB1dGVkKCgpID0+IHRoaXMuY29uZmlnKCkua2V5IHx8IHRoaXMuY29uZmlnKCkuaWQpO1xuICByZWFkb25seSBwbGFjZWhvbGRlciA9IGNvbXB1dGVkKFxuICAgICgpID0+ICh0aGlzLmNvbmZpZygpLnByb3BlcnRpZXM/LlsncGxhY2Vob2xkZXInXSBhcyBzdHJpbmcpID8/ICctLSBTZWxlY3QgLS0nXG4gICk7XG5cbiAgcmVhZG9ubHkgaXNTZWFyY2hhYmxlID0gY29tcHV0ZWQoXG4gICAgKCkgPT4gdGhpcy5jb25maWcoKS5wcm9wZXJ0aWVzPy5bJ25hdGl2ZVNlbGVjdCddICE9PSB0cnVlXG4gICk7XG5cbiAgcmVhZG9ubHkgaXNMb2FkaW5nID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgcmVhZG9ubHkgaGFzTG9hZGVkID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgcmVhZG9ubHkgbG9hZEVycm9yID0gc2lnbmFsPHN0cmluZyB8IG51bGw+KG51bGwpO1xuICAvKiogQ2FudmFzIGZpZWxkIGtleXMgdGhhdCBtdXN0IGJlIGZpbGxlZCBiZWZvcmUgdGhlIGxvb2t1cCBjYW4gcnVuLiAqL1xuICByZWFkb25seSB3YWl0aW5nRm9yID0gc2lnbmFsPHN0cmluZ1tdPihbXSk7XG5cbiAgcmVhZG9ubHkgaXNEeW5hbWljU291cmNlID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGRzID0gdGhpcy5jb25maWcoKS5kYXRhU291cmNlO1xuICAgIHJldHVybiAhIShcbiAgICAgIGRzICYmXG4gICAgICAoZHMuc291cmNlVHlwZSA9PT0gJ3RhYmxlJyB8fFxuICAgICAgICBkcy5zb3VyY2VUeXBlID09PSAncHJvY2VkdXJlJyB8fFxuICAgICAgICBkcy5lbnRpdHlOYW1lIHx8XG4gICAgICAgIGRzLm1hc3Rlck5hbWUpXG4gICAgKTtcbiAgfSk7XG5cbiAgcmVhZG9ubHkgc3RhdGljT3B0aW9ucyA9IGNvbXB1dGVkPERyb3Bkb3duT3B0aW9uW10+KCgpID0+IHtcbiAgICBjb25zdCBvcHRzID0gdGhpcy5jb25maWcoKS5wcm9wZXJ0aWVzPy5bJ29wdGlvbnMnXTtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShvcHRzKSkge1xuICAgICAgcmV0dXJuIG9wdHM7XG4gICAgfVxuICAgIHJldHVybiBbXTtcbiAgfSk7XG5cbiAgcmVhZG9ubHkgYWxsT3B0aW9ucyA9IGNvbXB1dGVkPERyb3Bkb3duT3B0aW9uW10+KCgpID0+IHtcbiAgICBpZiAodGhpcy5pc0R5bmFtaWNTb3VyY2UoKSkge1xuICAgICAgcmV0dXJuIHRoaXMuZHluYW1pY09wdGlvbnMoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc3RhdGljT3B0aW9ucygpO1xuICB9KTtcblxuICByZWFkb25seSBzZWxlY3RlZE9wdGlvbiA9IGNvbXB1dGVkPERyb3Bkb3duT3B0aW9uIHwgbnVsbD4oKCkgPT4ge1xuICAgIGNvbnN0IHZhbCA9IHRoaXMuY3VycmVudFZhbHVlKCk7XG4gICAgaWYgKHZhbCA9PT0gbnVsbCB8fCB2YWwgPT09IHVuZGVmaW5lZCB8fCB2YWwgPT09ICcnKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCBzdHJWYWwgPSBTdHJpbmcodmFsKTtcbiAgICBjb25zdCBmb3VuZCA9IHRoaXMuYWxsT3B0aW9ucygpLmZpbmQoKG9wdCkgPT4gU3RyaW5nKG9wdC5rZXkpID09PSBzdHJWYWwpO1xuICAgIGlmIChmb3VuZCkgcmV0dXJuIGZvdW5kO1xuICAgIHJldHVybiB7IGtleTogdmFsIGFzIHN0cmluZyB8IG51bWJlciwgbGFiZWw6IHN0clZhbCB9O1xuICB9KTtcblxuICByZWFkb25seSBmaWx0ZXJlZE9wdGlvbnMgPSBjb21wdXRlZDxEcm9wZG93bk9wdGlvbltdPigoKSA9PiB7XG4gICAgY29uc3QgdGVybSA9IHRoaXMuc2VhcmNoVGVybSgpLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuICAgIGNvbnN0IGFsbCA9IHRoaXMuYWxsT3B0aW9ucygpO1xuICAgIGlmICghdGVybSkgcmV0dXJuIGFsbDtcbiAgICByZXR1cm4gYWxsLmZpbHRlcigob3B0KSA9PlxuICAgICAgb3B0LmxhYmVsLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXModGVybSkgfHwgU3RyaW5nKG9wdC5rZXkpLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXModGVybSlcbiAgICApO1xuICB9KTtcblxuICByZWFkb25seSBNQVhfRklMVEVSX1JFTkRFUiA9IDIwMDtcbiAgcmVhZG9ubHkgdmlzaWJsZUZpbHRlcmVkT3B0aW9ucyA9IGNvbXB1dGVkPERyb3Bkb3duT3B0aW9uW10+KCgpID0+IHtcbiAgICBjb25zdCBmaWx0ZXJlZCA9IHRoaXMuZmlsdGVyZWRPcHRpb25zKCk7XG4gICAgaWYgKGZpbHRlcmVkLmxlbmd0aCA8PSB0aGlzLk1BWF9GSUxURVJfUkVOREVSKSByZXR1cm4gZmlsdGVyZWQ7XG4gICAgcmV0dXJuIGZpbHRlcmVkLnNsaWNlKDAsIHRoaXMuTUFYX0ZJTFRFUl9SRU5ERVIpO1xuICB9KTtcblxuICByZWFkb25seSBleGNlc3NGaWx0ZXJlZENvdW50ID0gY29tcHV0ZWQ8bnVtYmVyPigoKSA9PiB7XG4gICAgcmV0dXJuIE1hdGgubWF4KDAsIHRoaXMuZmlsdGVyZWRPcHRpb25zKCkubGVuZ3RoIC0gdGhpcy5NQVhfRklMVEVSX1JFTkRFUik7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IE1BWF9SRU5ERVJFRF9PUFRJT05TID0gNTAwO1xuICByZWFkb25seSByZW5kZXJlZE9wdGlvbnMgPSBjb21wdXRlZDxEcm9wZG93bk9wdGlvbltdPigoKSA9PiB7XG4gICAgY29uc3Qgb3B0cyA9IHRoaXMuYWxsT3B0aW9ucygpO1xuICAgIGlmIChvcHRzLmxlbmd0aCA8PSB0aGlzLk1BWF9SRU5ERVJFRF9PUFRJT05TKSByZXR1cm4gb3B0cztcbiAgICByZXR1cm4gb3B0cy5zbGljZSgwLCB0aGlzLk1BWF9SRU5ERVJFRF9PUFRJT05TKTtcbiAgfSk7XG4gIHJlYWRvbmx5IGhhc0V4Y2Vzc09wdGlvbnMgPSBjb21wdXRlZDxib29sZWFuPigoKSA9PiB7XG4gICAgcmV0dXJuIHRoaXMuYWxsT3B0aW9ucygpLmxlbmd0aCA+IHRoaXMuTUFYX1JFTkRFUkVEX09QVElPTlM7XG4gIH0pO1xuICByZWFkb25seSBleGNlc3NPcHRpb25zQ291bnQgPSBjb21wdXRlZDxudW1iZXI+KCgpID0+IHtcbiAgICByZXR1cm4gTWF0aC5tYXgoMCwgdGhpcy5hbGxPcHRpb25zKCkubGVuZ3RoIC0gdGhpcy5NQVhfUkVOREVSRURfT1BUSU9OUyk7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IHdhaXRpbmdMYWJlbCA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCBrZXlzID0gdGhpcy53YWl0aW5nRm9yKCk7XG4gICAgaWYgKGtleXMubGVuZ3RoID09PSAwKSByZXR1cm4gJyc7XG4gICAgcmV0dXJuIGtleXMuam9pbignLCAnKTtcbiAgfSk7XG5cbiAgcmVhZG9ubHkgc3RhdHVzS2luZCA9IGNvbXB1dGVkPCdpZGxlJyB8ICdsb2FkaW5nJyB8ICdvaycgfCAnd2FpdGluZycgfCAnZXJyb3InIHwgJ2VtcHR5Jz4oKCkgPT4ge1xuICAgIGlmICghdGhpcy5pc0R5bmFtaWNTb3VyY2UoKSkgcmV0dXJuICdpZGxlJztcbiAgICBpZiAodGhpcy5pc0xvYWRpbmcoKSkgcmV0dXJuICdsb2FkaW5nJztcbiAgICBpZiAodGhpcy5sb2FkRXJyb3IoKSkgcmV0dXJuICdlcnJvcic7XG4gICAgaWYgKHRoaXMud2FpdGluZ0ZvcigpLmxlbmd0aCA+IDApIHJldHVybiAnd2FpdGluZyc7XG4gICAgaWYgKHRoaXMuaGFzTG9hZGVkKCkpIHJldHVybiB0aGlzLmR5bmFtaWNPcHRpb25zKCkubGVuZ3RoID4gMCA/ICdvaycgOiAnZW1wdHknO1xuICAgIHJldHVybiAnaWRsZSc7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IHN0YXR1c1RleHQgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgc3dpdGNoICh0aGlzLnN0YXR1c0tpbmQoKSkge1xuICAgICAgY2FzZSAnbG9hZGluZyc6XG4gICAgICAgIHJldHVybiAnTG9hZGluZyBmcm9tIGRhdGFiYXNl4oCmJztcbiAgICAgIGNhc2UgJ29rJzpcbiAgICAgICAgcmV0dXJuIGAke3RoaXMuZHluYW1pY09wdGlvbnMoKS5sZW5ndGh9IHJlY29yZHMgbG9hZGVkYDtcbiAgICAgIGNhc2UgJ3dhaXRpbmcnOlxuICAgICAgICByZXR1cm4gYFdhaXRpbmcgZm9yOiAke3RoaXMud2FpdGluZ0xhYmVsKCl9YDtcbiAgICAgIGNhc2UgJ2Vycm9yJzpcbiAgICAgICAgcmV0dXJuIHRoaXMubG9hZEVycm9yKCkgPz8gJ0ZhaWxlZCB0byBsb2FkJztcbiAgICAgIGNhc2UgJ2VtcHR5JzpcbiAgICAgICAgcmV0dXJuICdRdWVyeSByZXR1cm5lZCBubyByZWNvcmRzIGZvciB0aGVzZSBwYXJhbWV0ZXJzJztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiAnJztcbiAgICB9XG4gIH0pO1xuXG4gIHJlYWRvbmx5IGlzSW52YWxpZCA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCBjdHJsID0gdGhpcy5mb3JtQ29udHJvbCgpO1xuICAgIHJldHVybiBjdHJsLmludmFsaWQgJiYgKGN0cmwuZGlydHkgfHwgY3RybC50b3VjaGVkKTtcbiAgfSk7XG5cbiAgcmVhZG9ubHkgZXJyb3JNZXNzYWdlID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGN0cmwgPSB0aGlzLmZvcm1Db250cm9sKCk7XG4gICAgaWYgKCFjdHJsLmludmFsaWQgfHwgKCFjdHJsLmRpcnR5ICYmICFjdHJsLnRvdWNoZWQpKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuICAgIGNvbnN0IGVycm9ycyA9IGN0cmwuZXJyb3JzO1xuICAgIGlmICghZXJyb3JzKSByZXR1cm4gJyc7XG4gICAgY29uc3QgZmlyc3RLZXkgPSBPYmplY3Qua2V5cyhlcnJvcnMpWzBdO1xuICAgIHJldHVybiBnZXRWYWxpZGF0aW9uTWVzc2FnZSh0aGlzLmNvbmZpZygpLnZhbGlkYXRpb24sIGZpcnN0S2V5KTtcbiAgfSk7XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6Y2xpY2snLCBbJyRldmVudCddKVxuICBvbkRvY3VtZW50Q2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaXNPcGVuKCkpIHJldHVybjtcbiAgICBjb25zdCB0YXJnZXQgPSBldmVudC50YXJnZXQgYXMgTm9kZTtcbiAgICBpZiAoIXRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LmNvbnRhaW5zKHRhcmdldCkpIHtcbiAgICAgIHRoaXMuY2xvc2VEcm9wZG93bigpO1xuICAgIH1cbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ2RvY3VtZW50OmtleWRvd24uZXNjYXBlJylcbiAgb25Fc2NhcGUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNPcGVuKCkpIHtcbiAgICAgIHRoaXMuY2xvc2VEcm9wZG93bigpO1xuICAgIH1cbiAgfVxuXG4gIGlzU2VsZWN0ZWQob3B0OiBEcm9wZG93bk9wdGlvbik6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGN1ciA9IHRoaXMuY3VycmVudFZhbHVlKCk7XG4gICAgaWYgKGN1ciA9PT0gbnVsbCB8fCBjdXIgPT09IHVuZGVmaW5lZCB8fCBjdXIgPT09ICcnKSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIFN0cmluZyhjdXIpID09PSBTdHJpbmcob3B0LmtleSk7XG4gIH1cblxuICB0b2dnbGVPcGVuKGV2ZW50PzogRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoZXZlbnQpIHtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIH1cbiAgICBpZiAodGhpcy5mb3JtQ29udHJvbCgpLmRpc2FibGVkKSByZXR1cm47XG4gICAgaWYgKHRoaXMuaXNPcGVuKCkpIHtcbiAgICAgIHRoaXMuY2xvc2VEcm9wZG93bigpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLm9wZW5Ecm9wZG93bigpO1xuICAgIH1cbiAgfVxuXG4gIG9wZW5Ecm9wZG93bigpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5mb3JtQ29udHJvbCgpLmRpc2FibGVkKSByZXR1cm47XG5cbiAgICAvLyBDaGVjayBhdmFpbGFibGUgdmlld3BvcnQgc3BhY2UgdG8gZGV0ZXJtaW5lIGlmIG1lbnUgc2hvdWxkIG9wZW4gYWJvdmVcbiAgICBjb25zdCB3cmFwcGVyID0gdGhpcy5jb21ib2JveFdyYXBwZXJFbCgpPy5uYXRpdmVFbGVtZW50ID8/IHRoaXMuZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50O1xuICAgIGNvbnN0IHJlY3QgPSB3cmFwcGVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IHNwYWNlQmVsb3cgPSB3aW5kb3cuaW5uZXJIZWlnaHQgLSByZWN0LmJvdHRvbTtcbiAgICBjb25zdCBzcGFjZUFib3ZlID0gcmVjdC50b3A7XG5cbiAgICBjb25zdCBwcmVmZXJBYm92ZSA9IHRoaXMuY29uZmlnKCk/LnByb3BlcnRpZXM/Llsnb3BlbkFib3ZlJ10gPT09IHRydWU7XG4gICAgY29uc3QgYXV0b0Fib3ZlID0gc3BhY2VCZWxvdyA8IDI2MCAmJiBzcGFjZUFib3ZlID4gMTYwO1xuICAgIHRoaXMub3BlbnNBYm92ZS5zZXQocHJlZmVyQWJvdmUgfHwgYXV0b0Fib3ZlKTtcblxuICAgIHRoaXMuaXNPcGVuLnNldCh0cnVlKTtcbiAgICB0aGlzLnNlYXJjaFRlcm0uc2V0KCcnKTtcbiAgICB0aGlzLmZvY3VzZWRJbmRleC5zZXQoLTEpO1xuXG4gICAgLy8gQXV0by1mb2N1cyBzZWFyY2ggaW5wdXQgYWZ0ZXIgcmVuZGVyXG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnNlYXJjaElucHV0RWwoKT8ubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICAgIH0sIDEwKTtcbiAgfVxuXG4gIGNsb3NlRHJvcGRvd24oKTogdm9pZCB7XG4gICAgdGhpcy5pc09wZW4uc2V0KGZhbHNlKTtcbiAgICB0aGlzLmZvY3VzZWRJbmRleC5zZXQoLTEpO1xuICAgIHRoaXMuZm9ybUNvbnRyb2woKS5tYXJrQXNUb3VjaGVkKCk7XG4gIH1cblxuICBzZWxlY3RPcHRpb24ob3B0OiBEcm9wZG93bk9wdGlvbik6IHZvaWQge1xuICAgIHRoaXMuY3VycmVudFZhbHVlLnNldChvcHQua2V5KTtcbiAgICB0aGlzLmZvcm1Db250cm9sKCkuc2V0VmFsdWUob3B0LmtleSk7XG4gICAgdGhpcy5mb3JtQ29udHJvbCgpLm1hcmtBc0RpcnR5KCk7XG4gICAgdGhpcy5mb3JtQ29udHJvbCgpLm1hcmtBc1RvdWNoZWQoKTtcbiAgICB0aGlzLmNsb3NlRHJvcGRvd24oKTtcbiAgfVxuXG4gIGNsZWFyU2VsZWN0aW9uKGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgdGhpcy5jdXJyZW50VmFsdWUuc2V0KCcnKTtcbiAgICB0aGlzLmZvcm1Db250cm9sKCkuc2V0VmFsdWUoJycpO1xuICAgIHRoaXMuZm9ybUNvbnRyb2woKS5tYXJrQXNEaXJ0eSgpO1xuICAgIHRoaXMuZm9ybUNvbnRyb2woKS5tYXJrQXNUb3VjaGVkKCk7XG4gICAgdGhpcy5zZWFyY2hUZXJtLnNldCgnJyk7XG4gICAgdGhpcy5mb2N1c2VkSW5kZXguc2V0KC0xKTtcbiAgfVxuXG4gIGNsZWFyU2VhcmNoKGV2ZW50OiBFdmVudCk6IHZvaWQge1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMuc2VhcmNoVGVybS5zZXQoJycpO1xuICAgIHRoaXMuZm9jdXNlZEluZGV4LnNldCgtMSk7XG4gICAgdGhpcy5zZWFyY2hJbnB1dEVsKCk/Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcbiAgfVxuXG4gIG9uU2VhcmNoSW5wdXQoZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgdmFsID0gKGV2ZW50LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50KS52YWx1ZTtcbiAgICB0aGlzLnNlYXJjaFRlcm0uc2V0KHZhbCk7XG4gICAgdGhpcy5mb2N1c2VkSW5kZXguc2V0KDApO1xuICB9XG5cbiAgb25UcmlnZ2VyS2V5ZG93bihldmVudDogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgIGlmIChldmVudC5rZXkgPT09ICdBcnJvd0Rvd24nIHx8IGV2ZW50LmtleSA9PT0gJ0VudGVyJyB8fCBldmVudC5rZXkgPT09ICcgJykge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIHRoaXMub3BlbkRyb3Bkb3duKCk7XG4gICAgfVxuICB9XG5cbiAgb25TZWFyY2hLZXlkb3duKGV2ZW50OiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgdmlzaWJsZSA9IHRoaXMudmlzaWJsZUZpbHRlcmVkT3B0aW9ucygpO1xuICAgIGNvbnN0IGNvdW50ID0gdmlzaWJsZS5sZW5ndGg7XG5cbiAgICBzd2l0Y2ggKGV2ZW50LmtleSkge1xuICAgICAgY2FzZSAnQXJyb3dEb3duJzoge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBpZiAoY291bnQgPiAwKSB7XG4gICAgICAgICAgY29uc3QgbmV4dCA9ICh0aGlzLmZvY3VzZWRJbmRleCgpICsgMSkgJSBjb3VudDtcbiAgICAgICAgICB0aGlzLmZvY3VzZWRJbmRleC5zZXQobmV4dCk7XG4gICAgICAgICAgdGhpcy5zY3JvbGxGb2N1c2VkSW50b1ZpZXcoKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ0Fycm93VXAnOiB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGlmIChjb3VudCA+IDApIHtcbiAgICAgICAgICBjb25zdCBwcmV2ID0gdGhpcy5mb2N1c2VkSW5kZXgoKSA8PSAwID8gY291bnQgLSAxIDogdGhpcy5mb2N1c2VkSW5kZXgoKSAtIDE7XG4gICAgICAgICAgdGhpcy5mb2N1c2VkSW5kZXguc2V0KHByZXYpO1xuICAgICAgICAgIHRoaXMuc2Nyb2xsRm9jdXNlZEludG9WaWV3KCk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdFbnRlcic6IHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgY29uc3QgaWR4ID0gdGhpcy5mb2N1c2VkSW5kZXgoKTtcbiAgICAgICAgaWYgKGlkeCA+PSAwICYmIGlkeCA8IGNvdW50KSB7XG4gICAgICAgICAgdGhpcy5zZWxlY3RPcHRpb24odmlzaWJsZVtpZHhdKTtcbiAgICAgICAgfSBlbHNlIGlmIChjb3VudCA9PT0gMSkge1xuICAgICAgICAgIHRoaXMuc2VsZWN0T3B0aW9uKHZpc2libGVbMF0pO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnRXNjYXBlJzoge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICB0aGlzLmNsb3NlRHJvcGRvd24oKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdUYWInOiB7XG4gICAgICAgIHRoaXMuY2xvc2VEcm9wZG93bigpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHNjcm9sbEZvY3VzZWRJbnRvVmlldygpOiB2b2lkIHtcbiAgICBjb25zdCBsaXN0RWwgPSB0aGlzLm9wdGlvbnNMaXN0RWwoKT8ubmF0aXZlRWxlbWVudDtcbiAgICBpZiAoIWxpc3RFbCkgcmV0dXJuO1xuICAgIGNvbnN0IGl0ZW1zID0gbGlzdEVsLnF1ZXJ5U2VsZWN0b3JBbGw8SFRNTEVsZW1lbnQ+KCcuY29tYm9ib3gtb3B0aW9uLWl0ZW0nKTtcbiAgICBjb25zdCBpZHggPSB0aGlzLmZvY3VzZWRJbmRleCgpO1xuICAgIGlmIChpdGVtcyAmJiBpdGVtc1tpZHhdKSB7XG4gICAgICBpdGVtc1tpZHhdLnNjcm9sbEludG9WaWV3KHsgYmxvY2s6ICduZWFyZXN0JyB9KTtcbiAgICB9XG4gIH1cblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICAvLyBTeW5jIHJlYWN0aXZlIGZvcm0gY29udHJvbCB2YWx1ZSBjaGFuZ2VzIHRvIGN1cnJlbnRWYWx1ZSBzaWduYWxcbiAgICBlZmZlY3QoXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGN0cmwgPSB0aGlzLmZvcm1Db250cm9sKCk7XG4gICAgICAgIHVudHJhY2tlZCgoKSA9PiB0aGlzLmN1cnJlbnRWYWx1ZS5zZXQoY3RybC52YWx1ZSkpO1xuICAgICAgICB0aGlzLmNvbnRyb2xTdWI/LnVuc3Vic2NyaWJlKCk7XG4gICAgICAgIHRoaXMuY29udHJvbFN1YiA9IGN0cmwudmFsdWVDaGFuZ2VzLnN1YnNjcmliZSgodikgPT4gdGhpcy5jdXJyZW50VmFsdWUuc2V0KHYpKTtcbiAgICAgIH0sXG4gICAgICB7IGFsbG93U2lnbmFsV3JpdGVzOiB0cnVlIH1cbiAgICApO1xuXG4gICAgLy8gUmUtcnVuIHdoZW5ldmVyIHRoZSBib3VuZCBkYXRhIHNvdXJjZSwgdGhlIHNlc3Npb24sIG9yIHRoZSBwYXJlbnQgZm9ybSBjaGFuZ2VzLlxuICAgIGVmZmVjdChcbiAgICAgICgpID0+IHtcbiAgICAgICAgY29uc3Qgc2Vzc2lvbiA9IHRoaXMuc2Vzc2lvblNlcnZpY2U/LnNlc3Npb25Db250ZXh0KCkgPz8ge307XG4gICAgICAgIGNvbnN0IGZvcm0gPSB0aGlzLnBhcmVudEZvcm0oKTtcbiAgICAgICAgdGhpcy5jb25maWcoKTsgLy8gZGVwZW5kZW5jeTogZGF0YSBzb3VyY2UgY29uZmlndXJhdGlvblxuXG4gICAgICAgIHRoaXMuZm9ybUNoYW5nZXNTdWI/LnVuc3Vic2NyaWJlKCk7XG4gICAgICAgIGlmIChmb3JtICYmIHRoaXMuaXNEeW5hbWljU291cmNlKCkpIHtcbiAgICAgICAgICB0aGlzLmZvcm1DaGFuZ2VzU3ViID0gZm9ybS52YWx1ZUNoYW5nZXMuc3Vic2NyaWJlKCgpID0+IHRoaXMuc2NoZWR1bGVSZWxvYWQoKSk7XG4gICAgICAgIH1cbiAgICAgICAgdW50cmFja2VkKCgpID0+IHRoaXMucmVsb2FkRGF0YVNvdXJjZU9wdGlvbnMoc2Vzc2lvbikpO1xuICAgICAgfSxcbiAgICAgIHsgYWxsb3dTaWduYWxXcml0ZXM6IHRydWUgfVxuICAgICk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmNvbnRyb2xTdWI/LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5sb29rdXBTdWI/LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5tYXN0ZXJEYXRhU3ViPy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMuZm9ybUNoYW5nZXNTdWI/LnVuc3Vic2NyaWJlKCk7XG4gICAgaWYgKHRoaXMucmVsb2FkVGltZXIpIGNsZWFyVGltZW91dCh0aGlzLnJlbG9hZFRpbWVyKTtcbiAgfVxuXG4gIHByaXZhdGUgc2NoZWR1bGVSZWxvYWQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMucmVsb2FkVGltZXIpIGNsZWFyVGltZW91dCh0aGlzLnJlbG9hZFRpbWVyKTtcbiAgICB0aGlzLnJlbG9hZFRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnJlbG9hZERhdGFTb3VyY2VPcHRpb25zKHRoaXMuc2Vzc2lvblNlcnZpY2U/LnNlc3Npb25Db250ZXh0KCkgPz8ge30pO1xuICAgIH0sIDI1MCk7XG4gIH1cblxuICBwcml2YXRlIHJlbG9hZERhdGFTb3VyY2VPcHRpb25zKHNlc3Npb246IFNlc3Npb25Db250ZXh0TWFwKTogdm9pZCB7XG4gICAgY29uc3QgZHMgPSB0aGlzLmNvbmZpZygpLmRhdGFTb3VyY2U7XG4gICAgaWYgKCFkcyB8fCAhdGhpcy5pc0R5bmFtaWNTb3VyY2UoKSkgcmV0dXJuO1xuXG4gICAgLy8gMS4gRGF0YWJhc2UgVGFibGUgLyBTdG9yZWQgUHJvY2VkdXJlIExvb2t1cFxuICAgIGlmIChkcy5lbnRpdHlOYW1lICYmIChkcy5zb3VyY2VUeXBlID09PSAndGFibGUnIHx8IGRzLnNvdXJjZVR5cGUgPT09ICdwcm9jZWR1cmUnKSAmJiB0aGlzLmxvb2t1cEFkYXB0ZXIpIHtcbiAgICAgIGNvbnN0IGZvcm1WYWx1ZXMgPSB0aGlzLnBhcmVudEZvcm0oKT8uZ2V0UmF3VmFsdWUoKSA/PyB7fTtcblxuICAgICAgLy8gRG8gbm90IGNhbGwgdGhlIGRhdGFiYXNlIHVudGlsIGV2ZXJ5IGNhbnZhcyBmaWVsZCB0aGlzIGxvb2t1cCBkZXBlbmRzIG9uIGlzIGZpbGxlZC5cbiAgICAgIGNvbnN0IG1pc3NpbmcgPSBmaW5kTWlzc2luZ0NhbnZhc0ZpZWxkcyhkcy5wYXJhbWV0ZXJNYXBwaW5ncywgZm9ybVZhbHVlcyk7XG4gICAgICB0aGlzLndhaXRpbmdGb3Iuc2V0KG1pc3NpbmcpO1xuICAgICAgaWYgKG1pc3NpbmcubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLmxvb2t1cFN1Yj8udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgdGhpcy5pc0xvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgdGhpcy5sb2FkRXJyb3Iuc2V0KG51bGwpO1xuICAgICAgICB0aGlzLmR5bmFtaWNPcHRpb25zLnNldChbXSk7XG4gICAgICAgIHRoaXMubGFzdFJlcXVlc3RLZXkgPSAnJztcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBTdG9yZWQgcHJvY2VkdXJlcyBvbmx5IHJlY2VpdmUgZXhwbGljaXQgbWFwcGluZ3Mgc28gU1FMIFNlcnZlciBkb2Vzbid0IHJlamVjdCB1bmtub3duIGFyZ3VtZW50cy5cbiAgICAgIGNvbnN0IHJlc29sdmVkUGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHtcbiAgICAgICAgLi4uKGRzLnNvdXJjZVR5cGUgPT09ICd0YWJsZScgPyBzZXNzaW9uIDoge30pLFxuICAgICAgICAuLi5yZXNvbHZlUGFyYW1ldGVyTWFwcGluZ3MoZHMucGFyYW1ldGVyTWFwcGluZ3MsIHNlc3Npb24sIGZvcm1WYWx1ZXMpLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVxdWVzdCA9IHtcbiAgICAgICAgc291cmNlVHlwZTogZHMuc291cmNlVHlwZSA/PyAndGFibGUnLFxuICAgICAgICBlbnRpdHlOYW1lOiBkcy5lbnRpdHlOYW1lLFxuICAgICAgICBzY2hlbWE6IGRzLnNjaGVtYSA/PyAnZGJvJyxcbiAgICAgICAgdmFsdWVGaWVsZDogZHMudmFsdWVGaWVsZCB8fCAnaWQnLFxuICAgICAgICBkaXNwbGF5RmllbGQ6IGRzLmRpc3BsYXlGaWVsZCB8fCAnbmFtZScsXG4gICAgICAgIGZpbHRlcjogZHMuZmlsdGVyLFxuICAgICAgICBwYXJhbWV0ZXJzOiByZXNvbHZlZFBhcmFtcyxcbiAgICAgIH07XG4gICAgICBjb25zdCByZXF1ZXN0S2V5ID0gSlNPTi5zdHJpbmdpZnkocmVxdWVzdCk7XG4gICAgICBpZiAocmVxdWVzdEtleSA9PT0gdGhpcy5sYXN0UmVxdWVzdEtleSkgcmV0dXJuOyAvLyBub3RoaW5nIGNoYW5nZWRcbiAgICAgIHRoaXMubGFzdFJlcXVlc3RLZXkgPSByZXF1ZXN0S2V5O1xuXG4gICAgICB0aGlzLmlzTG9hZGluZy5zZXQodHJ1ZSk7XG4gICAgICB0aGlzLmxvYWRFcnJvci5zZXQobnVsbCk7XG4gICAgICB0aGlzLmxvb2t1cFN1Yj8udW5zdWJzY3JpYmUoKTtcbiAgICAgIHRoaXMubG9va3VwU3ViID0gdGhpcy5sb29rdXBBZGFwdGVyLmZldGNoT3B0aW9ucyhyZXF1ZXN0KS5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAoaXRlbXMpID0+IHtcbiAgICAgICAgICB0aGlzLmlzTG9hZGluZy5zZXQoZmFsc2UpO1xuICAgICAgICAgIHRoaXMuaGFzTG9hZGVkLnNldCh0cnVlKTtcbiAgICAgICAgICAvLyBEZWR1cGxpY2F0ZSBpdGVtcyBieSBrZXkvdmFsdWUgdG8gZW5zdXJlIGNsZWFuIHNlbGVjdCBvcHRpb25zXG4gICAgICAgICAgY29uc3Qgc2VlbiA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgICAgICAgIGNvbnN0IGRlZHVwZWQ6IERyb3Bkb3duT3B0aW9uW10gPSBbXTtcbiAgICAgICAgICBmb3IgKGNvbnN0IGl0IG9mIGl0ZW1zKSB7XG4gICAgICAgICAgICBjb25zdCBrID0gU3RyaW5nKGl0LnZhbHVlKTtcbiAgICAgICAgICAgIGlmICghc2Vlbi5oYXMoaykpIHtcbiAgICAgICAgICAgICAgc2Vlbi5hZGQoayk7XG4gICAgICAgICAgICAgIGRlZHVwZWQucHVzaCh7IGtleTogaywgbGFiZWw6IGl0LmxhYmVsIHx8IGsgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuZHluYW1pY09wdGlvbnMuc2V0KGRlZHVwZWQpO1xuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKGVycikgPT4ge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFtScHREcm9wZG93bl0gRmFpbGVkIHRvIGxvYWQgbG9va3VwIG9wdGlvbnMgZm9yICR7ZHMuZW50aXR5TmFtZX06YCwgZXJyKTtcbiAgICAgICAgICB0aGlzLmlzTG9hZGluZy5zZXQoZmFsc2UpO1xuICAgICAgICAgIHRoaXMuaGFzTG9hZGVkLnNldCh0cnVlKTtcbiAgICAgICAgICB0aGlzLmR5bmFtaWNPcHRpb25zLnNldChbXSk7XG4gICAgICAgICAgdGhpcy5sYXN0UmVxdWVzdEtleSA9ICcnOyAvLyBhbGxvdyByZXRyeVxuICAgICAgICAgIHRoaXMubG9hZEVycm9yLnNldChlcnI/Lm1lc3NhZ2UgfHwgJ0RhdGFiYXNlIHF1ZXJ5IGVycm9yJyk7XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyAyLiBMZWdhY3kgTWFzdGVyIERhdGEgUHJvdmlkZXJcbiAgICBpZiAoZHMubWFzdGVyTmFtZSAmJiB0aGlzLm1hc3RlckRhdGFQcm92aWRlciAmJiAhdGhpcy5tYXN0ZXJEYXRhU3ViKSB7XG4gICAgICB0aGlzLmlzTG9hZGluZy5zZXQodHJ1ZSk7XG4gICAgICB0aGlzLmxvYWRFcnJvci5zZXQobnVsbCk7XG4gICAgICB0aGlzLm1hc3RlckRhdGFTdWIgPSB0aGlzLm1hc3RlckRhdGFQcm92aWRlci5nZXRNYXN0ZXJEYXRhKGRzLm1hc3Rlck5hbWUpLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChpdGVtcykgPT4ge1xuICAgICAgICAgIHRoaXMuaXNMb2FkaW5nLnNldChmYWxzZSk7XG4gICAgICAgICAgdGhpcy5oYXNMb2FkZWQuc2V0KHRydWUpO1xuICAgICAgICAgIHRoaXMuZHluYW1pY09wdGlvbnMuc2V0KFxuICAgICAgICAgICAgaXRlbXMubWFwKChpdCkgPT4gKHtcbiAgICAgICAgICAgICAga2V5OiBTdHJpbmcoaXQudmFsdWUgPz8gaXRbJ2lkJ10gPz8gJycpLFxuICAgICAgICAgICAgICBsYWJlbDogU3RyaW5nKGl0LmxhYmVsID8/IGl0WyduYW1lJ10gPz8gJycpLFxuICAgICAgICAgICAgfSkpXG4gICAgICAgICAgKTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IChlcnIpID0+IHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGBbUnB0RHJvcGRvd25dIEZhaWxlZCB0byBsb2FkIG1hc3RlciBkYXRhIGZvciAke2RzLm1hc3Rlck5hbWV9OmAsIGVycik7XG4gICAgICAgICAgdGhpcy5pc0xvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgICB0aGlzLmhhc0xvYWRlZC5zZXQodHJ1ZSk7XG4gICAgICAgICAgdGhpcy5sb2FkRXJyb3Iuc2V0KGVycj8ubWVzc2FnZSB8fCAnRmFpbGVkIHRvIGxvYWQgbWFzdGVyIGRhdGEnKTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuIiwiICAgIDxkaXYgY2xhc3M9XCJycHQtZmllbGQtZ3JvdXBcIj5cbiAgICAgIEBpZiAoY29uZmlnKCkubGFiZWwpIHtcbiAgICAgICAgPGxhYmVsIFtmb3JdPVwiZWxlbWVudElkKClcIiBjbGFzcz1cInJwdC1sYWJlbFwiPlxuICAgICAgICAgIHt7IGNvbmZpZygpLmxhYmVsIH19XG4gICAgICAgICAgQGlmIChjb25maWcoKS52YWxpZGF0aW9uPy5yZXF1aXJlZCkge1xuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJycHQtcmVxdWlyZWQtbWFya2VyXCI+Kjwvc3Bhbj5cbiAgICAgICAgICB9XG4gICAgICAgIDwvbGFiZWw+XG4gICAgICB9XG5cbiAgICAgIEBpZiAoaXNTZWFyY2hhYmxlKCkpIHtcbiAgICAgICAgPCEtLSBTZWFyY2hhYmxlIFR5cGVhaGVhZCBDb21ib2JveCAtLT5cbiAgICAgICAgPGRpdiBjbGFzcz1cInJwdC1jb21ib2JveC13cmFwcGVyXCIgI2NvbWJvYm94V3JhcHBlcj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGNsYXNzPVwicnB0LWNvbWJvYm94LXRyaWdnZXJcIlxuICAgICAgICAgICAgW2lkXT1cImVsZW1lbnRJZCgpXCJcbiAgICAgICAgICAgIFtjbGFzcy5ycHQtaW52YWxpZF09XCJpc0ludmFsaWQoKVwiXG4gICAgICAgICAgICBbY2xhc3MuaXMtb3Blbl09XCJpc09wZW4oKVwiXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwiZm9ybUNvbnRyb2woKS5kaXNhYmxlZFwiXG4gICAgICAgICAgICBbYXR0ci5hcmlhLWV4cGFuZGVkXT1cImlzT3BlbigpXCJcbiAgICAgICAgICAgIFthdHRyLmFyaWEtaGFzcG9wdXBdPVwiJ2xpc3Rib3gnXCJcbiAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVPcGVuKCRldmVudClcIlxuICAgICAgICAgICAgKGtleWRvd24pPVwib25UcmlnZ2VyS2V5ZG93bigkZXZlbnQpXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRyaWdnZXItbGFiZWxcIiBbY2xhc3MuaXMtcGxhY2Vob2xkZXJdPVwiIXNlbGVjdGVkT3B0aW9uKClcIj5cbiAgICAgICAgICAgICAge3sgc2VsZWN0ZWRPcHRpb24oKSA/IHNlbGVjdGVkT3B0aW9uKCkhLmxhYmVsIDogcGxhY2Vob2xkZXIoKSB9fVxuICAgICAgICAgICAgPC9zcGFuPlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidHJpZ2dlci1hY3Rpb25zXCI+XG4gICAgICAgICAgICAgIEBpZiAoc2VsZWN0ZWRPcHRpb24oKSAmJiAhZm9ybUNvbnRyb2woKS5kaXNhYmxlZCkge1xuICAgICAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgICAgICByb2xlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgIHRhYmluZGV4PVwiMFwiXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cInRyaWdnZXItY2xlYXItYnRuXCJcbiAgICAgICAgICAgICAgICAgIHRpdGxlPVwiQ2xlYXIgc2VsZWN0aW9uXCJcbiAgICAgICAgICAgICAgICAgIGFyaWEtbGFiZWw9XCJDbGVhciBzZWxlY3Rpb25cIlxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNsZWFyU2VsZWN0aW9uKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgKGtleWRvd24uZW50ZXIpPVwiY2xlYXJTZWxlY3Rpb24oJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAoa2V5ZG93bi5zcGFjZSk9XCJjbGVhclNlbGVjdGlvbigkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICDinJVcbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0cmlnZ2VyLWFycm93XCIgW2NsYXNzLnJvdGF0ZWRdPVwiaXNPcGVuKClcIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICAgICAgICA8c3ZnIHdpZHRoPVwiMTJcIiBoZWlnaHQ9XCI4XCIgdmlld0JveD1cIjAgMCAxMiA4XCIgZmlsbD1cIm5vbmVcIj5cbiAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMSAxLjVMNiA2LjVMMTEgMS41XCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMS41XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIvPlxuICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2J1dHRvbj5cblxuICAgICAgICAgIEBpZiAoaXNPcGVuKCkpIHtcbiAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgY2xhc3M9XCJycHQtY29tYm9ib3gtbWVudVwiXG4gICAgICAgICAgICAgIFtjbGFzcy5vcGVucy1hYm92ZV09XCJvcGVuc0Fib3ZlKClcIlxuICAgICAgICAgICAgICByb2xlPVwibGlzdGJveFwiXG4gICAgICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgICAgICAgPlxuICAgICAgICAgICAgICA8IS0tIFJlYWwtdGltZSBGaWx0ZXIgU2VhcmNoIEJveCAtLT5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbWJvYm94LXNlYXJjaC1ib3hcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImNvbWJvYm94LXNlYXJjaC1pY29uXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+XG4gICAgICAgICAgICAgICAgICA8c3ZnIHdpZHRoPVwiMTNcIiBoZWlnaHQ9XCIxM1wiIHZpZXdCb3g9XCIwIDAgMjQgMjRcIiBmaWxsPVwibm9uZVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjIuNVwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiPlxuICAgICAgICAgICAgICAgICAgICA8Y2lyY2xlIGN4PVwiMTFcIiBjeT1cIjExXCIgcj1cIjhcIj48L2NpcmNsZT5cbiAgICAgICAgICAgICAgICAgICAgPGxpbmUgeDE9XCIyMVwiIHkxPVwiMjFcIiB4Mj1cIjE2LjY1XCIgeTI9XCIxNi42NVwiPjwvbGluZT5cbiAgICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICNzZWFyY2hJbnB1dFxuICAgICAgICAgICAgICAgICAgdHlwZT1cInRleHRcIlxuICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjb21ib2JveC1zZWFyY2gtaW5wdXRcIlxuICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI9XCJUeXBlIHRvIGZpbHRlci4uLlwiXG4gICAgICAgICAgICAgICAgICBbdmFsdWVdPVwic2VhcmNoVGVybSgpXCJcbiAgICAgICAgICAgICAgICAgIFthdHRyLmFyaWEtYWN0aXZlZGVzY2VuZGFudF09XCJmb2N1c2VkSW5kZXgoKSA+PSAwID8gKGVsZW1lbnRJZCgpICsgJ19vcHRfJyArIGZvY3VzZWRJbmRleCgpKSA6IG51bGxcIlxuICAgICAgICAgICAgICAgICAgKGlucHV0KT1cIm9uU2VhcmNoSW5wdXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAoa2V5ZG93bik9XCJvblNlYXJjaEtleWRvd24oJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgICBAaWYgKHNlYXJjaFRlcm0oKSkge1xuICAgICAgICAgICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjb21ib2JveC1zZWFyY2gtY2xlYXJcIlxuICAgICAgICAgICAgICAgICAgICB0aXRsZT1cIkNsZWFyIGZpbHRlclwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJjbGVhclNlYXJjaCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAg4pyVXG4gICAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgICAgIDwhLS0gRmlsdGVyZWQgT3B0aW9ucyBMaXN0IC0tPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29tYm9ib3gtb3B0aW9ucy1saXN0XCIgI29wdGlvbnNMaXN0RWw+XG4gICAgICAgICAgICAgICAgQGlmIChpc0xvYWRpbmcoKSkge1xuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbWJvYm94LXN0YXR1cy1yb3cgbG9hZGluZ1wiPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXR1cy1kb3QgZG90LXB1bHNlXCI+PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj5Mb2FkaW5nIG9wdGlvbnMgZnJvbSBkYXRhYmFzZS4uLjwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIH0gQGVsc2UgaWYgKGxvYWRFcnJvcigpKSB7XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29tYm9ib3gtc3RhdHVzLXJvdyBlcnJvclwiPlxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj5FcnJvcjoge3sgbG9hZEVycm9yKCkgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICB9IEBlbHNlIGlmIChpc0R5bmFtaWNTb3VyY2UoKSAmJiBoYXNMb2FkZWQoKSAmJiBhbGxPcHRpb25zKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29tYm9ib3gtc3RhdHVzLXJvdyBlbXB0eVwiPlxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj5ObyByZWNvcmRzIGZvdW5kIChjaGVjayBwYXJhbWV0ZXJzKTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIH0gQGVsc2UgaWYgKGZpbHRlcmVkT3B0aW9ucygpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbWJvYm94LXN0YXR1cy1yb3cgZW1wdHlcIj5cbiAgICAgICAgICAgICAgICAgICAgPHNwYW4+Tm8gb3B0aW9ucyBtYXRjaGluZyBcInt7IHNlYXJjaFRlcm0oKSB9fVwiPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICBAZm9yIChvcHQgb2YgdmlzaWJsZUZpbHRlcmVkT3B0aW9ucygpOyB0cmFjayBvcHQua2V5OyBsZXQgaSA9ICRpbmRleCkge1xuICAgICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgICAgcm9sZT1cIm9wdGlvblwiXG4gICAgICAgICAgICAgICAgICAgICAgW2lkXT1cImVsZW1lbnRJZCgpICsgJ19vcHRfJyArIGlcIlxuICAgICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY29tYm9ib3gtb3B0aW9uLWl0ZW1cIlxuICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1zZWxlY3RlZF09XCJpc1NlbGVjdGVkKG9wdClcIlxuICAgICAgICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1mb2N1c2VkXT1cImZvY3VzZWRJbmRleCgpID09PSBpXCJcbiAgICAgICAgICAgICAgICAgICAgICBbYXR0ci5hcmlhLXNlbGVjdGVkXT1cImlzU2VsZWN0ZWQob3B0KVwiXG4gICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInNlbGVjdE9wdGlvbihvcHQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAobW91c2VlbnRlcik9XCJmb2N1c2VkSW5kZXguc2V0KGkpXCJcbiAgICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwib3B0LWxhYmVsXCI+e3sgb3B0LmxhYmVsIH19PC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICAgIEBpZiAoaXNTZWxlY3RlZChvcHQpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm9wdC1jaGVja1wiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPuKckzwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgQGlmIChleGNlc3NGaWx0ZXJlZENvdW50KCkgPiAwKSB7XG4gICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb21ib2JveC1zdGF0dXMtcm93IGhpbnRcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8c3Bhbj5TaG93aW5nIHt7IE1BWF9GSUxURVJfUkVOREVSIH19IG9mIHt7IGZpbHRlcmVkT3B0aW9ucygpLmxlbmd0aCB9fSBtYXRjaGVzLiBUeXBlIHRvIHJlZmluZS48L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICB9XG4gICAgICAgIDwvZGl2PlxuICAgICAgfSBAZWxzZSB7XG4gICAgICAgIDwhLS0gTmF0aXZlIEJyb3dzZXIgU2VsZWN0IEZhbGxiYWNrIC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwicnB0LXNlbGVjdC13cmFwcGVyXCI+XG4gICAgICAgICAgPHNlbGVjdFxuICAgICAgICAgICAgW2lkXT1cImVsZW1lbnRJZCgpXCJcbiAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJmb3JtQ29udHJvbCgpXCJcbiAgICAgICAgICAgIFtjbGFzcy5ycHQtaW52YWxpZF09XCJpc0ludmFsaWQoKVwiXG4gICAgICAgICAgICBjbGFzcz1cInJwdC1zZWxlY3RcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIEBpZiAoaXNMb2FkaW5nKCkpIHtcbiAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiIGRpc2FibGVkIHNlbGVjdGVkPkxvYWRpbmcgb3B0aW9ucyBmcm9tIGRhdGFiYXNlLi4uPC9vcHRpb24+XG4gICAgICAgICAgICB9IEBlbHNlIGlmIChsb2FkRXJyb3IoKSkge1xuICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCIgZGlzYWJsZWQgc2VsZWN0ZWQ+RXJyb3I6IHt7IGxvYWRFcnJvcigpIH19PC9vcHRpb24+XG4gICAgICAgICAgICB9IEBlbHNlIGlmIChpc0R5bmFtaWNTb3VyY2UoKSAmJiBoYXNMb2FkZWQoKSAmJiBhbGxPcHRpb25zKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIiBkaXNhYmxlZCBzZWxlY3RlZD4tLSBObyByZWNvcmRzIGZvdW5kIChjaGVjayBwYXJhbWV0ZXJzKSAtLTwvb3B0aW9uPlxuICAgICAgICAgICAgfSBAZWxzZSBpZiAocGxhY2Vob2xkZXIoKSkge1xuICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCIgW2Rpc2FibGVkXT1cImNvbmZpZygpLnZhbGlkYXRpb24/LnJlcXVpcmVkXCI+e3sgcGxhY2Vob2xkZXIoKSB9fTwvb3B0aW9uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGZvciAob3B0IG9mIHJlbmRlcmVkT3B0aW9ucygpOyB0cmFjayBvcHQua2V5KSB7XG4gICAgICAgICAgICAgIDxvcHRpb24gW3ZhbHVlXT1cIm9wdC5rZXlcIj57eyBvcHQubGFiZWwgfX08L29wdGlvbj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEBpZiAoaGFzRXhjZXNzT3B0aW9ucygpKSB7XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIiBkaXNhYmxlZD4uLi4gYW5kIHt7IGV4Y2Vzc09wdGlvbnNDb3VudCgpIH19IG1vcmUgcmVjb3JkcyAocmVmaW5lIGZpbHRlcikgLi4uPC9vcHRpb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9zZWxlY3Q+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInJwdC1zZWxlY3QtYXJyb3dcIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICAgIDxzdmcgd2lkdGg9XCIxMlwiIGhlaWdodD1cIjhcIiB2aWV3Qm94PVwiMCAwIDEyIDhcIiBmaWxsPVwibm9uZVwiPlxuICAgICAgICAgICAgICA8cGF0aCBkPVwiTTEgMS41TDYgNi41TDExIDEuNVwiIHN0cm9rZT1cImN1cnJlbnRDb2xvclwiIHN0cm9rZS13aWR0aD1cIjEuNVwiIHN0cm9rZS1saW5lY2FwPVwicm91bmRcIiBzdHJva2UtbGluZWpvaW49XCJyb3VuZFwiLz5cbiAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L2Rpdj5cbiAgICAgIH1cblxuICAgICAgQGlmIChzaG93U3RhdHVzKCkgJiYgaXNEeW5hbWljU291cmNlKCkgJiYgc3RhdHVzVGV4dCgpKSB7XG4gICAgICAgIDxkaXYgY2xhc3M9XCJycHQtc3RhdHVzLWJhZGdlXCIgW2F0dHIuZGF0YS1zdGF0dXNdPVwic3RhdHVzS2luZCgpXCI+XG4gICAgICAgICAgQHN3aXRjaCAoc3RhdHVzS2luZCgpKSB7XG4gICAgICAgICAgICBAY2FzZSAoJ2xvYWRpbmcnKSB7XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3RhdHVzLWRvdCBkb3QtcHVsc2VcIj48L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuPkxvYWRpbmcgZnJvbSBkYXRhYmFzZeKApjwvc3Bhbj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEBjYXNlICgnb2snKSB7XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3RhdHVzLWRvdCBkb3Qtb2tcIj48L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuPnt7IGR5bmFtaWNPcHRpb25zKCkubGVuZ3RoIH19IHJlY29yZHMgbG9hZGVkPC9zcGFuPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGNhc2UgKCd3YWl0aW5nJykge1xuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXR1cy1kb3QgZG90LXdhcm5cIj48L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuPldhaXRpbmcgZm9yOjwvc3Bhbj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cIndhaXRpbmctdG9rZW5zXCI+XG4gICAgICAgICAgICAgICAgQGZvciAoayBvZiB3YWl0aW5nRm9yKCk7IHRyYWNrIGspIHtcbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwid2FpdGluZy10b2tlblwiPnt7IGsgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEBjYXNlICgnZXJyb3InKSB7XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3RhdHVzLWRvdCBkb3QtZXJyXCI+PC9zcGFuPlxuICAgICAgICAgICAgICA8c3Bhbj57eyBsb2FkRXJyb3IoKSB9fTwvc3Bhbj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEBjYXNlICgnZW1wdHknKSB7XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3RhdHVzLWRvdFwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4+Tm8gcmVjb3JkcyBmb3VuZCBmb3IgcGFyYW1ldGVyczwvc3Bhbj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIEBkZWZhdWx0IHtcbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0dXMtZG90XCI+PC9zcGFuPlxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgPC9kaXY+XG4gICAgICB9XG5cbiAgICAgIEBpZiAoZXJyb3JNZXNzYWdlKCkpIHtcbiAgICAgICAgPHNwYW4gY2xhc3M9XCJycHQtZXJyb3ItdGV4dFwiPnt7IGVycm9yTWVzc2FnZSgpIH19PC9zcGFuPlxuICAgICAgfVxuICAgIDwvZGl2PiJdfQ==
533
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnB0LWRyb3Bkb3duLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2J3YXlzLXJlcG9ydC9zcmMvbGliL3ByaW1pdGl2ZXMvY29tcG9uZW50cy9kcm9wZG93bi9ycHQtZHJvcGRvd24uY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYndheXMtcmVwb3J0L3NyYy9saWIvcHJpbWl0aXZlcy9jb21wb25lbnRzL2Ryb3Bkb3duL3JwdC1kcm9wZG93bi5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLFNBQVMsRUFDVCxRQUFRLEVBQ1IsTUFBTSxFQUNOLFVBQVUsRUFDVixZQUFZLEVBQ1osTUFBTSxFQUNOLEtBQUssRUFFTCxNQUFNLEVBQ04sTUFBTSxFQUNOLFNBQVMsRUFDVCxTQUFTLEdBQ1YsTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFFLFdBQVcsRUFBYSxtQkFBbUIsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdFLE9BQU8sRUFHTCxPQUFPLEVBQ1AsYUFBYSxHQUVkLE1BQU0sc0JBQXNCLENBQUM7QUFDOUIsT0FBTyxFQUFnQixVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDaEQsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXpDLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDZDQUE2QyxDQUFDO0FBQ25GLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHFEQUFxRCxDQUFDO0FBQ3pGLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGdEQUFnRCxDQUFDO0FBQ3JGLE9BQU8sRUFBRSwyQkFBMkIsRUFBRSxNQUFNLHVEQUF1RCxDQUFDO0FBQ3BHLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDZDQUE2QyxDQUFDO0FBRS9FLE9B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SUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO3dCQUN2QyxLQUFLLEVBQUUsTUFBTSxDQUFDLEVBQUUsQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQztxQkFDNUMsQ0FBQyxDQUFDLENBQ0osQ0FBQztnQkFDSixDQUFDO2dCQUNELEtBQUssRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFO29CQUNiLE9BQU8sQ0FBQyxLQUFLLENBQUMsZ0RBQWdELEVBQUUsQ0FBQyxVQUFVLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztvQkFDckYsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7b0JBQzFCLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO29CQUN6QixJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsT0FBTyxJQUFJLDRCQUE0QixDQUFDLENBQUM7Z0JBQ25FLENBQUM7YUFDRixDQUFDLENBQUM7UUFDTCxDQUFDO0lBQ0gsQ0FBQzt3R0FuakJVLG9CQUFvQjs0RkFBcEIsb0JBQW9CLDhxQ0N0RGpDLDJuV0EwUFUsczJSRDdNRSxtQkFBbUIsb3RCQUFFLGFBQWE7OzRGQVNqQyxvQkFBb0I7a0JBWmhDLFNBQVM7K0JBQ0UsY0FBYyxjQUNaLElBQUksV0FDUCxDQUFDLG1CQUFtQixFQUFFLGFBQWEsQ0FBQyxRQUN2Qzt3QkFDSixpQkFBaUIsRUFBRSxVQUFVO3dCQUM3QixxQkFBcUIsRUFBRSxjQUFjO3FCQUN0QyxtQkFHZ0IsdUJBQXVCLENBQUMsTUFBTTt3REFvTy9DLGVBQWU7c0JBRGQsWUFBWTt1QkFBQyxnQkFBZ0IsRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkFVMUMsUUFBUTtzQkFEUCxZQUFZO3VCQUFDLHlCQUF5QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDb21wb25lbnQsXG4gIGNvbXB1dGVkLFxuICBlZmZlY3QsXG4gIEVsZW1lbnRSZWYsXG4gIEhvc3RMaXN0ZW5lcixcbiAgaW5qZWN0LFxuICBpbnB1dCxcbiAgT25EZXN0cm95LFxuICBvdXRwdXQsXG4gIHNpZ25hbCxcbiAgdW50cmFja2VkLFxuICB2aWV3Q2hpbGQsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRm9ybUNvbnRyb2wsIEZvcm1Hcm91cCwgUmVhY3RpdmVGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7XG4gIENvbm5lY3RlZFBvc2l0aW9uLFxuICBDb25uZWN0ZWRPdmVybGF5UG9zaXRpb25DaGFuZ2UsXG4gIE92ZXJsYXksXG4gIE92ZXJsYXlNb2R1bGUsXG4gIFNjcm9sbFN0cmF0ZWd5LFxufSBmcm9tICdAYW5ndWxhci9jZGsvb3ZlcmxheSc7XG5pbXBvcnQgeyBTdWJzY3JpcHRpb24sIHRocm93RXJyb3IgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHRpbWVvdXQgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBSZXBvcnRDb21wb25lbnREZWZpbml0aW9uIH0gZnJvbSAnLi4vLi4vLi4vY29yZS9tb2RlbHMvcmVwb3J0LWNvbXBvbmVudC5tb2RlbCc7XG5pbXBvcnQgeyBnZXRWYWxpZGF0aW9uTWVzc2FnZSB9IGZyb20gJy4uLy4uLy4uL2NvcmUvdmFsaWRhdGlvbi92YWxpZGF0aW9uLWZhY3RvcnknO1xuaW1wb3J0IHsgTWFzdGVyRGF0YVByb3ZpZGVyIH0gZnJvbSAnLi4vLi4vLi4vZGF0YS1hY2Nlc3MvY29udHJhY3RzL21hc3Rlci1kYXRhLnByb3ZpZGVyJztcbmltcG9ydCB7IFJlcG9ydExvb2t1cEFkYXB0ZXIgfSBmcm9tICcuLi8uLi8uLi9kYXRhLWFjY2Vzcy9jb250cmFjdHMvbG9va3VwLmNvbnRyYWN0JztcbmltcG9ydCB7IFJlcG9ydFNlc3Npb25Db250ZXh0U2VydmljZSB9IGZyb20gJy4uLy4uLy4uL2NvcmUvc2VydmljZXMvcmVwb3J0LXNlc3Npb24tY29udGV4dC5zZXJ2aWNlJztcbmltcG9ydCB7IFJFUE9SVElOR19DT05GSUcgfSBmcm9tICcuLi8uLi8uLi9jb3JlL3Rva2Vucy9yZXBvcnRpbmctY29uZmlnLnRva2VuJztcbmltcG9ydCB7IFNlc3Npb25Db250ZXh0TWFwIH0gZnJvbSAnLi4vLi4vLi4vY29yZS90b2tlbnMvc2Vzc2lvbi1jb250ZXh0LnRva2VuJztcbmltcG9ydCB7XG4gIGZpbmRNaXNzaW5nQ2FudmFzRmllbGRzLFxuICByZXNvbHZlUGFyYW1ldGVyTWFwcGluZ3MsXG59IGZyb20gJy4uLy4uLy4uL2NvcmUvdXRpbHMvcmVwb3J0LXBhcmFtZXRlci51dGlsJztcblxuZXhwb3J0IGludGVyZmFjZSBEcm9wZG93bk9wdGlvbiB7XG4gIGtleTogc3RyaW5nIHwgbnVtYmVyO1xuICBsYWJlbDogc3RyaW5nO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdycHQtZHJvcGRvd24nLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbUmVhY3RpdmVGb3Jtc01vZHVsZSwgT3ZlcmxheU1vZHVsZV0sXG4gIGhvc3Q6IHtcbiAgICAnW2NsYXNzLmlzLW9wZW5dJzogJ2lzT3BlbigpJyxcbiAgICAnW2NsYXNzLm9wZW5zLWFib3ZlXSc6ICdvcGVuc0Fib3ZlKCknLFxuICB9LFxuICB0ZW1wbGF0ZVVybDogJy4vcnB0LWRyb3Bkb3duLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmw6ICcuL3JwdC1kcm9wZG93bi5jb21wb25lbnQuY3NzJyxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIFJwdERyb3Bkb3duQ29tcG9uZW50IGltcGxlbWVudHMgT25EZXN0cm95IHtcbiAgcHJpdmF0ZSByZWFkb25seSBtYXN0ZXJEYXRhUHJvdmlkZXIgPSBpbmplY3QoTWFzdGVyRGF0YVByb3ZpZGVyLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuICBwcml2YXRlIHJlYWRvbmx5IGxvb2t1cEFkYXB0ZXIgPSBpbmplY3QoUmVwb3J0TG9va3VwQWRhcHRlciwgeyBvcHRpb25hbDogdHJ1ZSB9KTtcbiAgcHJpdmF0ZSByZWFkb25seSBzZXNzaW9uU2VydmljZSA9IGluamVjdChSZXBvcnRTZXNzaW9uQ29udGV4dFNlcnZpY2UsIHsgb3B0aW9uYWw6IHRydWUgfSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgZWxlbWVudFJlZiA9IGluamVjdChFbGVtZW50UmVmKTtcbiAgcHJpdmF0ZSByZWFkb25seSByZXBvcnRpbmdDb25maWcgPSBpbmplY3QoUkVQT1JUSU5HX0NPTkZJRywgeyBvcHRpb25hbDogdHJ1ZSB9KTtcbiAgcHJpdmF0ZSByZWFkb25seSBvdmVybGF5ID0gaW5qZWN0KE92ZXJsYXkpO1xuXG4gIHJlYWRvbmx5IHNjcm9sbFN0cmF0ZWd5OiBTY3JvbGxTdHJhdGVneSA9IHRoaXMub3ZlcmxheS5zY3JvbGxTdHJhdGVnaWVzLnJlcG9zaXRpb24oKTtcbiAgcmVhZG9ubHkgdHJpZ2dlcldpZHRoID0gc2lnbmFsPG51bWJlciB8IHN0cmluZz4oJ2F1dG8nKTtcblxuICByZWFkb25seSBvdmVybGF5UG9zaXRpb25zOiBDb25uZWN0ZWRQb3NpdGlvbltdID0gW1xuICAgIHtcbiAgICAgIG9yaWdpblg6ICdzdGFydCcsXG4gICAgICBvcmlnaW5ZOiAnYm90dG9tJyxcbiAgICAgIG92ZXJsYXlYOiAnc3RhcnQnLFxuICAgICAgb3ZlcmxheVk6ICd0b3AnLFxuICAgICAgb2Zmc2V0WTogNCxcbiAgICB9LFxuICAgIHtcbiAgICAgIG9yaWdpblg6ICdzdGFydCcsXG4gICAgICBvcmlnaW5ZOiAndG9wJyxcbiAgICAgIG92ZXJsYXlYOiAnc3RhcnQnLFxuICAgICAgb3ZlcmxheVk6ICdib3R0b20nLFxuICAgICAgb2Zmc2V0WTogLTQsXG4gICAgfSxcbiAgICB7XG4gICAgICBvcmlnaW5YOiAnZW5kJyxcbiAgICAgIG9yaWdpblk6ICdib3R0b20nLFxuICAgICAgb3ZlcmxheVg6ICdlbmQnLFxuICAgICAgb3ZlcmxheVk6ICd0b3AnLFxuICAgICAgb2Zmc2V0WTogNCxcbiAgICB9LFxuICAgIHtcbiAgICAgIG9yaWdpblg6ICdlbmQnLFxuICAgICAgb3JpZ2luWTogJ3RvcCcsXG4gICAgICBvdmVybGF5WDogJ2VuZCcsXG4gICAgICBvdmVybGF5WTogJ2JvdHRvbScsXG4gICAgICBvZmZzZXRZOiAtNCxcbiAgICB9LFxuICBdO1xuXG4gIHJlYWRvbmx5IGNvbmZpZyA9IGlucHV0LnJlcXVpcmVkPFJlcG9ydENvbXBvbmVudERlZmluaXRpb24+KCk7XG4gIHJlYWRvbmx5IGNvbnRyb2wgPSBpbnB1dDxGb3JtQ29udHJvbCB8IG51bGwgfCB1bmRlZmluZWQ+KCk7XG4gIHJlYWRvbmx5IHBhcmVudEZvcm0gPSBpbnB1dDxGb3JtR3JvdXAgfCBudWxsPihudWxsKTtcbiAgLyoqIERlc2lnbmVyIG1vZGU6IHNob3dzIGEgc21hbGwgc3RhdHVzIGxpbmUgKExvYWRpbmcgLyBOIHJlY29yZHMgLyBXYWl0aW5nIGZvcuKApikuICovXG4gIHJlYWRvbmx5IHNob3dTdGF0dXMgPSBpbnB1dDxib29sZWFuPihmYWxzZSk7XG4gIHJlYWRvbmx5IGRyb3Bkb3duQ2xpY2sgPSBvdXRwdXQ8dm9pZD4oKTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGZhbGxiYWNrQ29udHJvbCA9IG5ldyBGb3JtQ29udHJvbCgnJyk7XG4gIHJlYWRvbmx5IGR5bmFtaWNPcHRpb25zID0gc2lnbmFsPERyb3Bkb3duT3B0aW9uW10+KFtdKTtcbiAgcHJpdmF0ZSBsb29rdXBTdWI/OiBTdWJzY3JpcHRpb247XG4gIHByaXZhdGUgbWFzdGVyRGF0YVN1Yj86IFN1YnNjcmlwdGlvbjtcbiAgcHJpdmF0ZSBmb3JtQ2hhbmdlc1N1Yj86IFN1YnNjcmlwdGlvbjtcbiAgcHJpdmF0ZSByZWxvYWRUaW1lcj86IFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+O1xuICBwcml2YXRlIGxhc3RSZXF1ZXN0S2V5ID0gJyc7XG5cbiAgLy8gQ29tYm9ib3ggaW50ZXJhY3RpdmUgc3RhdGVcbiAgcmVhZG9ubHkgaXNPcGVuID0gc2lnbmFsPGJvb2xlYW4+KGZhbHNlKTtcbiAgcmVhZG9ubHkgb3BlbnNBYm92ZSA9IHNpZ25hbDxib29sZWFuPihmYWxzZSk7XG4gIHJlYWRvbmx5IHNlYXJjaFRlcm0gPSBzaWduYWw8c3RyaW5nPignJyk7XG4gIHJlYWRvbmx5IGZvY3VzZWRJbmRleCA9IHNpZ25hbDxudW1iZXI+KC0xKTtcbiAgcmVhZG9ubHkgY3VycmVudFZhbHVlID0gc2lnbmFsPHVua25vd24+KG51bGwpO1xuICByZWFkb25seSBjb21ib2JveFdyYXBwZXJFbCA9IHZpZXdDaGlsZDxFbGVtZW50UmVmPEhUTUxFbGVtZW50Pj4oJ2NvbWJvYm94V3JhcHBlcicpO1xuICByZWFkb25seSBzZWFyY2hJbnB1dEVsID0gdmlld0NoaWxkPEVsZW1lbnRSZWY8SFRNTElucHV0RWxlbWVudD4+KCdzZWFyY2hJbnB1dCcpO1xuICByZWFkb25seSBvcHRpb25zTGlzdEVsID0gdmlld0NoaWxkPEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+Pignb3B0aW9uc0xpc3RFbCcpO1xuXG4gIHByaXZhdGUgY29udHJvbFN1Yj86IFN1YnNjcmlwdGlvbjtcblxuICByZWFkb25seSBmb3JtQ29udHJvbCA9IGNvbXB1dGVkKCgpID0+IHRoaXMuY29udHJvbCgpID8/IHRoaXMuZmFsbGJhY2tDb250cm9sKTtcbiAgcmVhZG9ubHkgZWxlbWVudElkID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5jb25maWcoKS5rZXkgfHwgdGhpcy5jb25maWcoKS5pZCk7XG4gIHJlYWRvbmx5IHBsYWNlaG9sZGVyID0gY29tcHV0ZWQoXG4gICAgKCkgPT4gKHRoaXMuY29uZmlnKCkucHJvcGVydGllcz8uWydwbGFjZWhvbGRlciddIGFzIHN0cmluZykgPz8gJy0tIFNlbGVjdCAtLSdcbiAgKTtcblxuICByZWFkb25seSBpc1NlYXJjaGFibGUgPSBjb21wdXRlZChcbiAgICAoKSA9PiB0aGlzLmNvbmZpZygpLnByb3BlcnRpZXM/LlsnbmF0aXZlU2VsZWN0J10gIT09IHRydWVcbiAgKTtcblxuICByZWFkb25seSBpc0xvYWRpbmcgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICByZWFkb25seSBoYXNMb2FkZWQgPSBzaWduYWw8Ym9vbGVhbj4oZmFsc2UpO1xuICByZWFkb25seSBsb2FkRXJyb3IgPSBzaWduYWw8c3RyaW5nIHwgbnVsbD4obnVsbCk7XG4gIC8qKiBDYW52YXMgZmllbGQga2V5cyB0aGF0IG11c3QgYmUgZmlsbGVkIGJlZm9yZSB0aGUgbG9va3VwIGNhbiBydW4uICovXG4gIHJlYWRvbmx5IHdhaXRpbmdGb3IgPSBzaWduYWw8c3RyaW5nW10+KFtdKTtcblxuICByZWFkb25seSBpc0R5bmFtaWNTb3VyY2UgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgY29uc3QgZHMgPSB0aGlzLmNvbmZpZygpLmRhdGFTb3VyY2U7XG4gICAgcmV0dXJuICEhKFxuICAgICAgZHMgJiZcbiAgICAgIChkcy5zb3VyY2VUeXBlID09PSAndGFibGUnIHx8XG4gICAgICAgIGRzLnNvdXJjZVR5cGUgPT09ICdwcm9jZWR1cmUnIHx8XG4gICAgICAgIGRzLmVudGl0eU5hbWUgfHxcbiAgICAgICAgZHMubWFzdGVyTmFtZSlcbiAgICApO1xuICB9KTtcblxuICByZWFkb25seSBzdGF0aWNPcHRpb25zID0gY29tcHV0ZWQ8RHJvcGRvd25PcHRpb25bXT4oKCkgPT4ge1xuICAgIGNvbnN0IG9wdHMgPSB0aGlzLmNvbmZpZygpLnByb3BlcnRpZXM/Llsnb3B0aW9ucyddO1xuICAgIGlmIChBcnJheS5pc0FycmF5KG9wdHMpKSB7XG4gICAgICByZXR1cm4gb3B0cztcbiAgICB9XG4gICAgcmV0dXJuIFtdO1xuICB9KTtcblxuICByZWFkb25seSBhbGxPcHRpb25zID0gY29tcHV0ZWQ8RHJvcGRvd25PcHRpb25bXT4oKCkgPT4ge1xuICAgIGlmICh0aGlzLmlzRHluYW1pY1NvdXJjZSgpKSB7XG4gICAgICByZXR1cm4gdGhpcy5keW5hbWljT3B0aW9ucygpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5zdGF0aWNPcHRpb25zKCk7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IHNlbGVjdGVkT3B0aW9uID0gY29tcHV0ZWQ8RHJvcGRvd25PcHRpb24gfCBudWxsPigoKSA9PiB7XG4gICAgY29uc3QgdmFsID0gdGhpcy5jdXJyZW50VmFsdWUoKTtcbiAgICBpZiAodmFsID09PSBudWxsIHx8IHZhbCA9PT0gdW5kZWZpbmVkIHx8IHZhbCA9PT0gJycpIHJldHVybiBudWxsO1xuICAgIGNvbnN0IHN0clZhbCA9IFN0cmluZyh2YWwpO1xuICAgIGNvbnN0IGZvdW5kID0gdGhpcy5hbGxPcHRpb25zKCkuZmluZCgob3B0KSA9PiBTdHJpbmcob3B0LmtleSkgPT09IHN0clZhbCk7XG4gICAgaWYgKGZvdW5kKSByZXR1cm4gZm91bmQ7XG4gICAgcmV0dXJuIHsga2V5OiB2YWwgYXMgc3RyaW5nIHwgbnVtYmVyLCBsYWJlbDogc3RyVmFsIH07XG4gIH0pO1xuXG4gIHJlYWRvbmx5IGZpbHRlcmVkT3B0aW9ucyA9IGNvbXB1dGVkPERyb3Bkb3duT3B0aW9uW10+KCgpID0+IHtcbiAgICBjb25zdCB0ZXJtID0gdGhpcy5zZWFyY2hUZXJtKCkudHJpbSgpLnRvTG93ZXJDYXNlKCk7XG4gICAgY29uc3QgYWxsID0gdGhpcy5hbGxPcHRpb25zKCk7XG4gICAgaWYgKCF0ZXJtKSByZXR1cm4gYWxsO1xuICAgIHJldHVybiBhbGwuZmlsdGVyKChvcHQpID0+XG4gICAgICBvcHQubGFiZWwudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyh0ZXJtKSB8fCBTdHJpbmcob3B0LmtleSkudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyh0ZXJtKVxuICAgICk7XG4gIH0pO1xuXG4gIHJlYWRvbmx5IE1BWF9GSUxURVJfUkVOREVSID0gMjAwO1xuICByZWFkb25seSBJTklUSUFMX0ZJTFRFUl9SRU5ERVIgPSAyMDA7XG4gIHJlYWRvbmx5IGZpbHRlclJlbmRlckxpbWl0ID0gc2lnbmFsPG51bWJlcj4oMjAwKTtcblxuICByZWFkb25seSB2aXNpYmxlRmlsdGVyZWRPcHRpb25zID0gY29tcHV0ZWQ8RHJvcGRvd25PcHRpb25bXT4oKCkgPT4ge1xuICAgIGNvbnN0IGZpbHRlcmVkID0gdGhpcy5maWx0ZXJlZE9wdGlvbnMoKTtcbiAgICBjb25zdCBsaW1pdCA9IHRoaXMuZmlsdGVyUmVuZGVyTGltaXQoKTtcbiAgICBpZiAoZmlsdGVyZWQubGVuZ3RoIDw9IGxpbWl0KSByZXR1cm4gZmlsdGVyZWQ7XG4gICAgcmV0dXJuIGZpbHRlcmVkLnNsaWNlKDAsIGxpbWl0KTtcbiAgfSk7XG5cbiAgcmVhZG9ubHkgZXhjZXNzRmlsdGVyZWRDb3VudCA9IGNvbXB1dGVkPG51bWJlcj4oKCkgPT4ge1xuICAgIHJldHVybiBNYXRoLm1heCgwLCB0aGlzLmZpbHRlcmVkT3B0aW9ucygpLmxlbmd0aCAtIHRoaXMuZmlsdGVyUmVuZGVyTGltaXQoKSk7XG4gIH0pO1xuXG4gIG9uT3B0aW9uc1Njcm9sbChldmVudDogRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBlbCA9IGV2ZW50LnRhcmdldCBhcyBIVE1MRWxlbWVudDtcbiAgICBpZiAoIWVsKSByZXR1cm47XG4gICAgaWYgKGVsLnNjcm9sbFRvcCArIGVsLmNsaWVudEhlaWdodCA+PSBlbC5zY3JvbGxIZWlnaHQgLSAxMjApIHtcbiAgICAgIHRoaXMubG9hZE1vcmVGaWx0ZXJlZCgpO1xuICAgIH1cbiAgfVxuXG4gIGxvYWRNb3JlRmlsdGVyZWQoKTogdm9pZCB7XG4gICAgY29uc3QgdG90YWwgPSB0aGlzLmZpbHRlcmVkT3B0aW9ucygpLmxlbmd0aDtcbiAgICBjb25zdCBjdXJyZW50ID0gdGhpcy5maWx0ZXJSZW5kZXJMaW1pdCgpO1xuICAgIGlmIChjdXJyZW50IDwgdG90YWwpIHtcbiAgICAgIHRoaXMuZmlsdGVyUmVuZGVyTGltaXQudXBkYXRlKChjKSA9PiBNYXRoLm1pbih0b3RhbCwgYyArIDIwMCkpO1xuICAgIH1cbiAgfVxuXG4gIGxvYWRBbGxGaWx0ZXJlZCgpOiB2b2lkIHtcbiAgICB0aGlzLmZpbHRlclJlbmRlckxpbWl0LnNldCh0aGlzLmZpbHRlcmVkT3B0aW9ucygpLmxlbmd0aCk7XG4gIH1cblxuICByZWFkb25seSBNQVhfUkVOREVSRURfT1BUSU9OUyA9IDUwMDA7XG4gIHJlYWRvbmx5IHJlbmRlcmVkT3B0aW9ucyA9IGNvbXB1dGVkPERyb3Bkb3duT3B0aW9uW10+KCgpID0+IHtcbiAgICBjb25zdCBvcHRzID0gdGhpcy5hbGxPcHRpb25zKCk7XG4gICAgaWYgKG9wdHMubGVuZ3RoIDw9IHRoaXMuTUFYX1JFTkRFUkVEX09QVElPTlMpIHJldHVybiBvcHRzO1xuICAgIHJldHVybiBvcHRzLnNsaWNlKDAsIHRoaXMuTUFYX1JFTkRFUkVEX09QVElPTlMpO1xuICB9KTtcbiAgcmVhZG9ubHkgaGFzRXhjZXNzT3B0aW9ucyA9IGNvbXB1dGVkPGJvb2xlYW4+KCgpID0+IHtcbiAgICByZXR1cm4gdGhpcy5hbGxPcHRpb25zKCkubGVuZ3RoID4gdGhpcy5NQVhfUkVOREVSRURfT1BUSU9OUztcbiAgfSk7XG4gIHJlYWRvbmx5IGV4Y2Vzc09wdGlvbnNDb3VudCA9IGNvbXB1dGVkPG51bWJlcj4oKCkgPT4ge1xuICAgIHJldHVybiBNYXRoLm1heCgwLCB0aGlzLmFsbE9wdGlvbnMoKS5sZW5ndGggLSB0aGlzLk1BWF9SRU5ERVJFRF9PUFRJT05TKTtcbiAgfSk7XG5cbiAgcmVhZG9ubHkgd2FpdGluZ0xhYmVsID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGtleXMgPSB0aGlzLndhaXRpbmdGb3IoKTtcbiAgICBpZiAoa2V5cy5sZW5ndGggPT09IDApIHJldHVybiAnJztcbiAgICByZXR1cm4ga2V5cy5qb2luKCcsICcpO1xuICB9KTtcblxuICByZWFkb25seSBzdGF0dXNLaW5kID0gY29tcHV0ZWQ8J2lkbGUnIHwgJ2xvYWRpbmcnIHwgJ29rJyB8ICd3YWl0aW5nJyB8ICdlcnJvcicgfCAnZW1wdHknPigoKSA9PiB7XG4gICAgaWYgKCF0aGlzLmlzRHluYW1pY1NvdXJjZSgpKSByZXR1cm4gJ2lkbGUnO1xuICAgIGlmICh0aGlzLmlzTG9hZGluZygpKSByZXR1cm4gJ2xvYWRpbmcnO1xuICAgIGlmICh0aGlzLmxvYWRFcnJvcigpKSByZXR1cm4gJ2Vycm9yJztcbiAgICBpZiAodGhpcy53YWl0aW5nRm9yKCkubGVuZ3RoID4gMCkgcmV0dXJuICd3YWl0aW5nJztcbiAgICBpZiAodGhpcy5oYXNMb2FkZWQoKSkgcmV0dXJuIHRoaXMuZHluYW1pY09wdGlvbnMoKS5sZW5ndGggPiAwID8gJ29rJyA6ICdlbXB0eSc7XG4gICAgcmV0dXJuICdpZGxlJztcbiAgfSk7XG5cbiAgcmVhZG9ubHkgc3RhdHVzVGV4dCA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBzd2l0Y2ggKHRoaXMuc3RhdHVzS2luZCgpKSB7XG4gICAgICBjYXNlICdsb2FkaW5nJzpcbiAgICAgICAgcmV0dXJuICdMb2FkaW5nIGZyb20gZGF0YWJhc2XigKYnO1xuICAgICAgY2FzZSAnb2snOlxuICAgICAgICByZXR1cm4gYCR7dGhpcy5keW5hbWljT3B0aW9ucygpLmxlbmd0aH0gcmVjb3JkcyBsb2FkZWRgO1xuICAgICAgY2FzZSAnd2FpdGluZyc6XG4gICAgICAgIHJldHVybiBgV2FpdGluZyBmb3I6ICR7dGhpcy53YWl0aW5nTGFiZWwoKX1gO1xuICAgICAgY2FzZSAnZXJyb3InOlxuICAgICAgICByZXR1cm4gdGhpcy5sb2FkRXJyb3IoKSA/PyAnRmFpbGVkIHRvIGxvYWQnO1xuICAgICAgY2FzZSAnZW1wdHknOlxuICAgICAgICByZXR1cm4gJ1F1ZXJ5IHJldHVybmVkIG5vIHJlY29yZHMgZm9yIHRoZXNlIHBhcmFtZXRlcnMnO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgcmV0dXJuICcnO1xuICAgIH1cbiAgfSk7XG5cbiAgcmVhZG9ubHkgaXNJbnZhbGlkID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGN0cmwgPSB0aGlzLmZvcm1Db250cm9sKCk7XG4gICAgcmV0dXJuIGN0cmwuaW52YWxpZCAmJiAoY3RybC5kaXJ0eSB8fCBjdHJsLnRvdWNoZWQpO1xuICB9KTtcblxuICByZWFkb25seSBlcnJvck1lc3NhZ2UgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgY29uc3QgY3RybCA9IHRoaXMuZm9ybUNvbnRyb2woKTtcbiAgICBpZiAoIWN0cmwuaW52YWxpZCB8fCAoIWN0cmwuZGlydHkgJiYgIWN0cmwudG91Y2hlZCkpIHtcbiAgICAgIHJldHVybiAnJztcbiAgICB9XG4gICAgY29uc3QgZXJyb3JzID0gY3RybC5lcnJvcnM7XG4gICAgaWYgKCFlcnJvcnMpIHJldHVybiAnJztcbiAgICBjb25zdCBmaXJzdEtleSA9IE9iamVjdC5rZXlzKGVycm9ycylbMF07XG4gICAgcmV0dXJuIGdldFZhbGlkYXRpb25NZXNzYWdlKHRoaXMuY29uZmlnKCkudmFsaWRhdGlvbiwgZmlyc3RLZXkpO1xuICB9KTtcblxuICBASG9zdExpc3RlbmVyKCdkb2N1bWVudDpjbGljaycsIFsnJGV2ZW50J10pXG4gIG9uRG9jdW1lbnRDbGljayhldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5pc09wZW4oKSkgcmV0dXJuO1xuICAgIGNvbnN0IHRhcmdldCA9IGV2ZW50LnRhcmdldCBhcyBOb2RlO1xuICAgIGlmICghdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuY29udGFpbnModGFyZ2V0KSkge1xuICAgICAgdGhpcy5jbG9zZURyb3Bkb3duKCk7XG4gICAgfVxuICB9XG5cbiAgQEhvc3RMaXN0ZW5lcignZG9jdW1lbnQ6a2V5ZG93bi5lc2NhcGUnKVxuICBvbkVzY2FwZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5pc09wZW4oKSkge1xuICAgICAgdGhpcy5jbG9zZURyb3Bkb3duKCk7XG4gICAgfVxuICB9XG5cbiAgaXNTZWxlY3RlZChvcHQ6IERyb3Bkb3duT3B0aW9uKTogYm9vbGVhbiB7XG4gICAgY29uc3QgY3VyID0gdGhpcy5jdXJyZW50VmFsdWUoKTtcbiAgICBpZiAoY3VyID09PSBudWxsIHx8IGN1ciA9PT0gdW5kZWZpbmVkIHx8IGN1ciA9PT0gJycpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gU3RyaW5nKGN1cikgPT09IFN0cmluZyhvcHQua2V5KTtcbiAgfVxuXG4gIHRvZ2dsZU9wZW4oZXZlbnQ/OiBFdmVudCk6IHZvaWQge1xuICAgIGlmIChldmVudCkge1xuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfVxuICAgIHRoaXMuZHJvcGRvd25DbGljay5lbWl0KCk7XG4gICAgaWYgKHRoaXMuZm9ybUNvbnRyb2woKS5kaXNhYmxlZCkgcmV0dXJuO1xuICAgIGlmICh0aGlzLmlzT3BlbigpKSB7XG4gICAgICB0aGlzLmNsb3NlRHJvcGRvd24oKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5vcGVuRHJvcGRvd24oKTtcbiAgICB9XG4gIH1cblxuICBvcGVuRHJvcGRvd24oKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZm9ybUNvbnRyb2woKS5kaXNhYmxlZCkgcmV0dXJuO1xuXG4gICAgY29uc3Qgd3JhcHBlciA9IHRoaXMuY29tYm9ib3hXcmFwcGVyRWwoKT8ubmF0aXZlRWxlbWVudCA/PyB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcbiAgICBjb25zdCByZWN0ID0gd3JhcHBlci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBpZiAocmVjdC53aWR0aCA+IDApIHtcbiAgICAgIHRoaXMudHJpZ2dlcldpZHRoLnNldChyZWN0LndpZHRoKTtcbiAgICB9XG5cbiAgICBjb25zdCBwcmVmZXJBYm92ZSA9IHRoaXMuY29uZmlnKCk/LnByb3BlcnRpZXM/Llsnb3BlbkFib3ZlJ10gPT09IHRydWU7XG4gICAgaWYgKHByZWZlckFib3ZlKSB7XG4gICAgICB0aGlzLm9wZW5zQWJvdmUuc2V0KHRydWUpO1xuICAgIH1cblxuICAgIHRoaXMuaXNPcGVuLnNldCh0cnVlKTtcbiAgICB0aGlzLnNlYXJjaFRlcm0uc2V0KCcnKTtcbiAgICB0aGlzLmZpbHRlclJlbmRlckxpbWl0LnNldCh0aGlzLklOSVRJQUxfRklMVEVSX1JFTkRFUik7XG4gICAgdGhpcy5mb2N1c2VkSW5kZXguc2V0KC0xKTtcbiAgfVxuXG4gIG9uUG9zaXRpb25DaGFuZ2UoY2hhbmdlOiBDb25uZWN0ZWRPdmVybGF5UG9zaXRpb25DaGFuZ2UpOiB2b2lkIHtcbiAgICB0aGlzLm9wZW5zQWJvdmUuc2V0KGNoYW5nZS5jb25uZWN0aW9uUGFpci5vcmlnaW5ZID09PSAndG9wJyk7XG4gIH1cblxuICBvbk92ZXJsYXlBdHRhY2hlZCgpOiB2b2lkIHtcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuc2VhcmNoSW5wdXRFbCgpPy5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG4gICAgfSwgMjUpO1xuICB9XG5cbiAgY2xvc2VEcm9wZG93bigpOiB2b2lkIHtcbiAgICB0aGlzLmlzT3Blbi5zZXQoZmFsc2UpO1xuICAgIHRoaXMuZm9jdXNlZEluZGV4LnNldCgtMSk7XG4gICAgdGhpcy5mb3JtQ29udHJvbCgpLm1hcmtBc1RvdWNoZWQoKTtcbiAgfVxuXG4gIHNlbGVjdE9wdGlvbihvcHQ6IERyb3Bkb3duT3B0aW9uKTogdm9pZCB7XG4gICAgdGhpcy5jdXJyZW50VmFsdWUuc2V0KG9wdC5rZXkpO1xuICAgIHRoaXMuZm9ybUNvbnRyb2woKS5zZXRWYWx1ZShvcHQua2V5KTtcbiAgICB0aGlzLmZvcm1Db250cm9sKCkubWFya0FzRGlydHkoKTtcbiAgICB0aGlzLmZvcm1Db250cm9sKCkubWFya0FzVG91Y2hlZCgpO1xuICAgIHRoaXMuY2xvc2VEcm9wZG93bigpO1xuICB9XG5cbiAgY2xlYXJTZWxlY3Rpb24oZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB0aGlzLmN1cnJlbnRWYWx1ZS5zZXQoJycpO1xuICAgIHRoaXMuZm9ybUNvbnRyb2woKS5zZXRWYWx1ZSgnJyk7XG4gICAgdGhpcy5mb3JtQ29udHJvbCgpLm1hcmtBc0RpcnR5KCk7XG4gICAgdGhpcy5mb3JtQ29udHJvbCgpLm1hcmtBc1RvdWNoZWQoKTtcbiAgICB0aGlzLnNlYXJjaFRlcm0uc2V0KCcnKTtcbiAgICB0aGlzLmZpbHRlclJlbmRlckxpbWl0LnNldCh0aGlzLklOSVRJQUxfRklMVEVSX1JFTkRFUik7XG4gICAgdGhpcy5mb2N1c2VkSW5kZXguc2V0KC0xKTtcbiAgfVxuXG4gIC8qKiBNYW51YWxseSByZXRyeSBsb2FkaW5nIGR5bmFtaWMgbG9va3VwIG9wdGlvbnMgKGUuZy4gYWZ0ZXIgZGF0YWJhc2UgdGltZW91dCkuICovXG4gIHJldHJ5TG9va3VwKGV2ZW50PzogRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoZXZlbnQpIHtcbiAgICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICB9XG4gICAgdGhpcy5sYXN0UmVxdWVzdEtleSA9ICcnO1xuICAgIHRoaXMubG9hZEVycm9yLnNldChudWxsKTtcbiAgICB0aGlzLnJlbG9hZERhdGFTb3VyY2VPcHRpb25zKHRoaXMuc2Vzc2lvblNlcnZpY2U/LnNlc3Npb25Db250ZXh0KCkgPz8ge30pO1xuICB9XG5cbiAgY2xlYXJTZWFyY2goZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgdGhpcy5zZWFyY2hUZXJtLnNldCgnJyk7XG4gICAgdGhpcy5maWx0ZXJSZW5kZXJMaW1pdC5zZXQodGhpcy5JTklUSUFMX0ZJTFRFUl9SRU5ERVIpO1xuICAgIHRoaXMuZm9jdXNlZEluZGV4LnNldCgtMSk7XG4gICAgdGhpcy5zZWFyY2hJbnB1dEVsKCk/Lm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcbiAgfVxuXG4gIG9uU2VhcmNoSW5wdXQoZXZlbnQ6IEV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgdmFsID0gKGV2ZW50LnRhcmdldCBhcyBIVE1MSW5wdXRFbGVtZW50KS52YWx1ZTtcbiAgICB0aGlzLnNlYXJjaFRlcm0uc2V0KHZhbCk7XG4gICAgdGhpcy5maWx0ZXJSZW5kZXJMaW1pdC5zZXQodGhpcy5JTklUSUFMX0ZJTFRFUl9SRU5ERVIpO1xuICAgIHRoaXMuZm9jdXNlZEluZGV4LnNldCgwKTtcbiAgfVxuXG4gIG9uVHJpZ2dlcktleWRvd24oZXZlbnQ6IEtleWJvYXJkRXZlbnQpOiB2b2lkIHtcbiAgICBpZiAoZXZlbnQua2V5ID09PSAnQXJyb3dEb3duJyB8fCBldmVudC5rZXkgPT09ICdFbnRlcicgfHwgZXZlbnQua2V5ID09PSAnICcpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICB0aGlzLm9wZW5Ecm9wZG93bigpO1xuICAgIH1cbiAgfVxuXG4gIG9uU2VhcmNoS2V5ZG93bihldmVudDogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IHZpc2libGUgPSB0aGlzLnZpc2libGVGaWx0ZXJlZE9wdGlvbnMoKTtcbiAgICBjb25zdCBjb3VudCA9IHZpc2libGUubGVuZ3RoO1xuXG4gICAgc3dpdGNoIChldmVudC5rZXkpIHtcbiAgICAgIGNhc2UgJ0Fycm93RG93bic6IHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgaWYgKGNvdW50ID4gMCkge1xuICAgICAgICAgIGNvbnN0IG5leHQgPSAodGhpcy5mb2N1c2VkSW5kZXgoKSArIDEpICUgY291bnQ7XG4gICAgICAgICAgdGhpcy5mb2N1c2VkSW5kZXguc2V0KG5leHQpO1xuICAgICAgICAgIHRoaXMuc2Nyb2xsRm9jdXNlZEludG9WaWV3KCk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlICdBcnJvd1VwJzoge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBpZiAoY291bnQgPiAwKSB7XG4gICAgICAgICAgY29uc3QgcHJldiA9IHRoaXMuZm9jdXNlZEluZGV4KCkgPD0gMCA/IGNvdW50IC0gMSA6IHRoaXMuZm9jdXNlZEluZGV4KCkgLSAxO1xuICAgICAgICAgIHRoaXMuZm9jdXNlZEluZGV4LnNldChwcmV2KTtcbiAgICAgICAgICB0aGlzLnNjcm9sbEZvY3VzZWRJbnRvVmlldygpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnRW50ZXInOiB7XG4gICAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICAgIGNvbnN0IGlkeCA9IHRoaXMuZm9jdXNlZEluZGV4KCk7XG4gICAgICAgIGlmIChpZHggPj0gMCAmJiBpZHggPCBjb3VudCkge1xuICAgICAgICAgIHRoaXMuc2VsZWN0T3B0aW9uKHZpc2libGVbaWR4XSk7XG4gICAgICAgIH0gZWxzZSBpZiAoY291bnQgPT09IDEpIHtcbiAgICAgICAgICB0aGlzLnNlbGVjdE9wdGlvbih2aXNpYmxlWzBdKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgJ0VzY2FwZSc6IHtcbiAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgdGhpcy5jbG9zZURyb3Bkb3duKCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAnVGFiJzoge1xuICAgICAgICB0aGlzLmNsb3NlRHJvcGRvd24oKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzY3JvbGxGb2N1c2VkSW50b1ZpZXcoKTogdm9pZCB7XG4gICAgY29uc3QgbGlzdEVsID0gdGhpcy5vcHRpb25zTGlzdEVsKCk/Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgaWYgKCFsaXN0RWwpIHJldHVybjtcbiAgICBjb25zdCBpdGVtcyA9IGxpc3RFbC5xdWVyeVNlbGVjdG9yQWxsPEhUTUxFbGVtZW50PignLmNvbWJvYm94LW9wdGlvbi1pdGVtJyk7XG4gICAgY29uc3QgaWR4ID0gdGhpcy5mb2N1c2VkSW5kZXgoKTtcbiAgICBpZiAoaXRlbXMgJiYgaXRlbXNbaWR4XSkge1xuICAgICAgaXRlbXNbaWR4XS5zY3JvbGxJbnRvVmlldyh7IGJsb2NrOiAnbmVhcmVzdCcgfSk7XG4gICAgfVxuICB9XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgLy8gU3luYyByZWFjdGl2ZSBmb3JtIGNvbnRyb2wgdmFsdWUgY2hhbmdlcyB0byBjdXJyZW50VmFsdWUgc2lnbmFsXG4gICAgZWZmZWN0KFxuICAgICAgKCkgPT4ge1xuICAgICAgICBjb25zdCBjdHJsID0gdGhpcy5mb3JtQ29udHJvbCgpO1xuICAgICAgICB1bnRyYWNrZWQoKCkgPT4gdGhpcy5jdXJyZW50VmFsdWUuc2V0KGN0cmwudmFsdWUpKTtcbiAgICAgICAgdGhpcy5jb250cm9sU3ViPy51bnN1YnNjcmliZSgpO1xuICAgICAgICB0aGlzLmNvbnRyb2xTdWIgPSBjdHJsLnZhbHVlQ2hhbmdlcy5zdWJzY3JpYmUoKHYpID0+IHRoaXMuY3VycmVudFZhbHVlLnNldCh2KSk7XG4gICAgICB9LFxuICAgICAgeyBhbGxvd1NpZ25hbFdyaXRlczogdHJ1ZSB9XG4gICAgKTtcblxuICAgIC8vIFJlLXJ1biB3aGVuZXZlciB0aGUgYm91bmQgZGF0YSBzb3VyY2UsIHRoZSBzZXNzaW9uLCBvciB0aGUgcGFyZW50IGZvcm0gY2hhbmdlcy5cbiAgICBlZmZlY3QoXG4gICAgICAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHNlc3Npb24gPSB0aGlzLnNlc3Npb25TZXJ2aWNlPy5zZXNzaW9uQ29udGV4dCgpID8/IHt9O1xuICAgICAgICBjb25zdCBmb3JtID0gdGhpcy5wYXJlbnRGb3JtKCk7XG4gICAgICAgIHRoaXMuY29uZmlnKCk7IC8vIGRlcGVuZGVuY3k6IGRhdGEgc291cmNlIGNvbmZpZ3VyYXRpb25cblxuICAgICAgICB0aGlzLmZvcm1DaGFuZ2VzU3ViPy51bnN1YnNjcmliZSgpO1xuICAgICAgICBpZiAoZm9ybSAmJiB0aGlzLmlzRHluYW1pY1NvdXJjZSgpKSB7XG4gICAgICAgICAgdGhpcy5mb3JtQ2hhbmdlc1N1YiA9IGZvcm0udmFsdWVDaGFuZ2VzLnN1YnNjcmliZSgoKSA9PiB0aGlzLnNjaGVkdWxlUmVsb2FkKCkpO1xuICAgICAgICB9XG4gICAgICAgIHVudHJhY2tlZCgoKSA9PiB0aGlzLnNjaGVkdWxlUmVsb2FkKCkpO1xuICAgICAgfSxcbiAgICAgIHsgYWxsb3dTaWduYWxXcml0ZXM6IHRydWUgfVxuICAgICk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmNvbnRyb2xTdWI/LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5sb29rdXBTdWI/LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5tYXN0ZXJEYXRhU3ViPy51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMuZm9ybUNoYW5nZXNTdWI/LnVuc3Vic2NyaWJlKCk7XG4gICAgaWYgKHRoaXMucmVsb2FkVGltZXIpIGNsZWFyVGltZW91dCh0aGlzLnJlbG9hZFRpbWVyKTtcbiAgfVxuXG4gIHByaXZhdGUgc2NoZWR1bGVSZWxvYWQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMucmVsb2FkVGltZXIpIGNsZWFyVGltZW91dCh0aGlzLnJlbG9hZFRpbWVyKTtcbiAgICB0aGlzLnJlbG9hZFRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLnJlbG9hZERhdGFTb3VyY2VPcHRpb25zKHRoaXMuc2Vzc2lvblNlcnZpY2U/LnNlc3Npb25Db250ZXh0KCkgPz8ge30pO1xuICAgIH0sIDI1MCk7XG4gIH1cblxuICBwcml2YXRlIHJlbG9hZERhdGFTb3VyY2VPcHRpb25zKHNlc3Npb246IFNlc3Npb25Db250ZXh0TWFwKTogdm9pZCB7XG4gICAgY29uc3QgZHMgPSB0aGlzLmNvbmZpZygpLmRhdGFTb3VyY2U7XG4gICAgaWYgKCFkcyB8fCAhdGhpcy5pc0R5bmFtaWNTb3VyY2UoKSkgcmV0dXJuO1xuXG4gICAgLy8gMS4gRGF0YWJhc2UgVGFibGUgLyBTdG9yZWQgUHJvY2VkdXJlIExvb2t1cFxuICAgIGlmIChkcy5lbnRpdHlOYW1lICYmIChkcy5zb3VyY2VUeXBlID09PSAndGFibGUnIHx8IGRzLnNvdXJjZVR5cGUgPT09ICdwcm9jZWR1cmUnKSAmJiB0aGlzLmxvb2t1cEFkYXB0ZXIpIHtcbiAgICAgIGNvbnN0IGZvcm1WYWx1ZXMgPSB0aGlzLnBhcmVudEZvcm0oKT8uZ2V0UmF3VmFsdWUoKSA/PyB7fTtcblxuICAgICAgLy8gRG8gbm90IGNhbGwgdGhlIGRhdGFiYXNlIHVudGlsIGV2ZXJ5IGNhbnZhcyBmaWVsZCB0aGlzIGxvb2t1cCBkZXBlbmRzIG9uIGlzIGZpbGxlZC5cbiAgICAgIGNvbnN0IG1pc3NpbmcgPSBmaW5kTWlzc2luZ0NhbnZhc0ZpZWxkcyhkcy5wYXJhbWV0ZXJNYXBwaW5ncywgZm9ybVZhbHVlcyk7XG4gICAgICB0aGlzLndhaXRpbmdGb3Iuc2V0KG1pc3NpbmcpO1xuICAgICAgaWYgKG1pc3NpbmcubGVuZ3RoID4gMCkge1xuICAgICAgICB0aGlzLmxvb2t1cFN1Yj8udW5zdWJzY3JpYmUoKTtcbiAgICAgICAgdGhpcy5pc0xvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgdGhpcy5sb2FkRXJyb3Iuc2V0KG51bGwpO1xuICAgICAgICB0aGlzLmR5bmFtaWNPcHRpb25zLnNldChbXSk7XG4gICAgICAgIHRoaXMubGFzdFJlcXVlc3RLZXkgPSAnJztcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBTdG9yZWQgcHJvY2VkdXJlcyBvbmx5IHJlY2VpdmUgZXhwbGljaXQgbWFwcGluZ3Mgc28gU1FMIFNlcnZlciBkb2Vzbid0IHJlamVjdCB1bmtub3duIGFyZ3VtZW50cy5cbiAgICAgIGNvbnN0IHJlc29sdmVkUGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiA9IHtcbiAgICAgICAgLi4uKGRzLnNvdXJjZVR5cGUgPT09ICd0YWJsZScgPyBzZXNzaW9uIDoge30pLFxuICAgICAgICAuLi5yZXNvbHZlUGFyYW1ldGVyTWFwcGluZ3MoZHMucGFyYW1ldGVyTWFwcGluZ3MsIHNlc3Npb24sIGZvcm1WYWx1ZXMpLFxuICAgICAgfTtcblxuICAgICAgY29uc3QgcmVxdWVzdCA9IHtcbiAgICAgICAgc291cmNlVHlwZTogZHMuc291cmNlVHlwZSA/PyAndGFibGUnLFxuICAgICAgICBlbnRpdHlOYW1lOiBkcy5lbnRpdHlOYW1lLFxuICAgICAgICBzY2hlbWE6IGRzLnNjaGVtYSA/PyAnZGJvJyxcbiAgICAgICAgdmFsdWVGaWVsZDogZHMudmFsdWVGaWVsZD8udHJpbSgpIHx8ICcnLFxuICAgICAgICBkaXNwbGF5RmllbGQ6IGRzLmRpc3BsYXlGaWVsZD8udHJpbSgpIHx8ICcnLFxuICAgICAgICBmaWx0ZXI6IGRzLmZpbHRlcixcbiAgICAgICAgcGFyYW1ldGVyczogcmVzb2x2ZWRQYXJhbXMsXG4gICAgICB9O1xuICAgICAgY29uc3QgcmVxdWVzdEtleSA9IEpTT04uc3RyaW5naWZ5KHJlcXVlc3QpO1xuICAgICAgaWYgKHJlcXVlc3RLZXkgPT09IHRoaXMubGFzdFJlcXVlc3RLZXkpIHJldHVybjsgLy8gbm90aGluZyBjaGFuZ2VkXG4gICAgICB0aGlzLmxhc3RSZXF1ZXN0S2V5ID0gcmVxdWVzdEtleTtcblxuICAgICAgLy8gU3RvcmVkIHByb2NlZHVyZXMgb24gbG9jYWwgZGF0YWJhc2VzIGNhbiB0YWtlIGEgY291cGxlIG1pbnV0ZXMgdG8gZXhlY3V0ZS5cbiAgICAgIC8vIERlZmF1bHQgdGltZW91dCBpcyAzMDAsMDAwbXMgKDUgbWludXRlcyksIGNvbmZpZ3VyYWJsZSB2aWEgY29tcG9uZW50IHByb3BlcnRpZXMgb3IgcmVwb3J0aW5nQ29uZmlnLlxuICAgICAgY29uc3QgdGltZW91dE1zID1cbiAgICAgICAgKChkcyBhcyBhbnkpPy50aW1lb3V0TXMgYXMgbnVtYmVyKSB8fFxuICAgICAgICAodGhpcy5jb25maWcoKS5wcm9wZXJ0aWVzPy5bJ3RpbWVvdXRNcyddIGFzIG51bWJlcikgfHxcbiAgICAgICAgdGhpcy5yZXBvcnRpbmdDb25maWc/Lmxvb2t1cFRpbWVvdXRNcyB8fFxuICAgICAgICAzMDAwMDA7XG5cbiAgICAgIHRoaXMuaXNMb2FkaW5nLnNldCh0cnVlKTtcbiAgICAgIHRoaXMubG9hZEVycm9yLnNldChudWxsKTtcbiAgICAgIHRoaXMubG9va3VwU3ViPy51bnN1YnNjcmliZSgpO1xuICAgICAgdGhpcy5sb29rdXBTdWIgPSB0aGlzLmxvb2t1cEFkYXB0ZXJcbiAgICAgICAgLmZldGNoT3B0aW9ucyhyZXF1ZXN0KVxuICAgICAgICAucGlwZShcbiAgICAgICAgICB0aW1lb3V0KHtcbiAgICAgICAgICAgIGVhY2g6IHRpbWVvdXRNcyxcbiAgICAgICAgICAgIHdpdGg6ICgpID0+XG4gICAgICAgICAgICAgIHRocm93RXJyb3IoXG4gICAgICAgICAgICAgICAgKCkgPT5cbiAgICAgICAgICAgICAgICAgIG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgYExvb2t1cCBxdWVyeSB0aW1lZCBvdXQgYWZ0ZXIgJHtNYXRoLnJvdW5kKHRpbWVvdXRNcyAvIDEwMDApfXMgKHN0b3JlZCBwcm9jZWR1cmUgdG9vayB0b28gbG9uZyB0byByZXNwb25kIG9uIGxvY2FsIGRhdGFiYXNlKWBcbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICB9KVxuICAgICAgICApXG4gICAgICAgIC5zdWJzY3JpYmUoe1xuICAgICAgICBuZXh0OiAoaXRlbXMpID0+IHtcbiAgICAgICAgICB0aGlzLmlzTG9hZGluZy5zZXQoZmFsc2UpO1xuICAgICAgICAgIHRoaXMuaGFzTG9hZGVkLnNldCh0cnVlKTtcbiAgICAgICAgICAvLyBEZWR1cGxpY2F0ZSBpdGVtcyBieSBrZXkvdmFsdWUgdG8gZW5zdXJlIGNsZWFuIHNlbGVjdCBvcHRpb25zXG4gICAgICAgICAgY29uc3Qgc2VlbiA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgICAgICAgIGNvbnN0IGRlZHVwZWQ6IERyb3Bkb3duT3B0aW9uW10gPSBbXTtcbiAgICAgICAgICBmb3IgKGNvbnN0IGl0IG9mIGl0ZW1zKSB7XG4gICAgICAgICAgICBjb25zdCBrID0gU3RyaW5nKGl0LnZhbHVlKTtcbiAgICAgICAgICAgIGlmICghc2Vlbi5oYXMoaykpIHtcbiAgICAgICAgICAgICAgc2Vlbi5hZGQoayk7XG4gICAgICAgICAgICAgIGRlZHVwZWQucHVzaCh7IGtleTogaywgbGFiZWw6IGl0LmxhYmVsIHx8IGsgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIHRoaXMuZHluYW1pY09wdGlvbnMuc2V0KGRlZHVwZWQpO1xuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKGVycikgPT4ge1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFtScHREcm9wZG93bl0gRmFpbGVkIHRvIGxvYWQgbG9va3VwIG9wdGlvbnMgZm9yICR7ZHMuZW50aXR5TmFtZX06YCwgZXJyKTtcbiAgICAgICAgICB0aGlzLmlzTG9hZGluZy5zZXQoZmFsc2UpO1xuICAgICAgICAgIHRoaXMuaGFzTG9hZGVkLnNldCh0cnVlKTtcbiAgICAgICAgICB0aGlzLmR5bmFtaWNPcHRpb25zLnNldChbXSk7XG4gICAgICAgICAgdGhpcy5sYXN0UmVxdWVzdEtleSA9ICcnOyAvLyBhbGxvdyByZXRyeVxuICAgICAgICAgIHRoaXMubG9hZEVycm9yLnNldChlcnI/Lm1lc3NhZ2UgfHwgJ0RhdGFiYXNlIHF1ZXJ5IGVycm9yJyk7XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyAyLiBMZWdhY3kgTWFzdGVyIERhdGEgUHJvdmlkZXJcbiAgICBpZiAoZHMubWFzdGVyTmFtZSAmJiB0aGlzLm1hc3RlckRhdGFQcm92aWRlciAmJiAhdGhpcy5tYXN0ZXJEYXRhU3ViKSB7XG4gICAgICB0aGlzLmlzTG9hZGluZy5zZXQodHJ1ZSk7XG4gICAgICB0aGlzLmxvYWRFcnJvci5zZXQobnVsbCk7XG4gICAgICB0aGlzLm1hc3RlckRhdGFTdWIgPSB0aGlzLm1hc3RlckRhdGFQcm92aWRlci5nZXRNYXN0ZXJEYXRhKGRzLm1hc3Rlck5hbWUpLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChpdGVtcykgPT4ge1xuICAgICAgICAgIHRoaXMuaXNMb2FkaW5nLnNldChmYWxzZSk7XG4gICAgICAgICAgdGhpcy5oYXNMb2FkZWQuc2V0KHRydWUpO1xuICAgICAgICAgIHRoaXMuZHluYW1pY09wdGlvbnMuc2V0KFxuICAgICAgICAgICAgaXRlbXMubWFwKChpdCkgPT4gKHtcbiAgICAgICAgICAgICAga2V5OiBTdHJpbmcoaXQudmFsdWUgPz8gaXRbJ2lkJ10gPz8gJycpLFxuICAgICAgICAgICAgICBsYWJlbDogU3RyaW5nKGl0LmxhYmVsID8/IGl0WyduYW1lJ10gPz8gJycpLFxuICAgICAgICAgICAgfSkpXG4gICAgICAgICAgKTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IChlcnIpID0+IHtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKGBbUnB0RHJvcGRvd25dIEZhaWxlZCB0byBsb2FkIG1hc3RlciBkYXRhIGZvciAke2RzLm1hc3Rlck5hbWV9OmAsIGVycik7XG4gICAgICAgICAgdGhpcy5pc0xvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICAgICAgICB0aGlzLmhhc0xvYWRlZC5zZXQodHJ1ZSk7XG4gICAgICAgICAgdGhpcy5sb2FkRXJyb3Iuc2V0KGVycj8ubWVzc2FnZSB8fCAnRmFpbGVkIHRvIGxvYWQgbWFzdGVyIGRhdGEnKTtcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxufVxuIiwiICAgIDxkaXYgY2xhc3M9XCJycHQtZmllbGQtZ3JvdXBcIj5cbiAgICAgIEBpZiAoY29uZmlnKCkubGFiZWwpIHtcbiAgICAgICAgPGxhYmVsIFtmb3JdPVwiZWxlbWVudElkKClcIiBjbGFzcz1cInJwdC1sYWJlbFwiPlxuICAgICAgICAgIHt7IGNvbmZpZygpLmxhYmVsIH19XG4gICAgICAgICAgQGlmIChjb25maWcoKS52YWxpZGF0aW9uPy5yZXF1aXJlZCkge1xuICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJycHQtcmVxdWlyZWQtbWFya2VyXCI+Kjwvc3Bhbj5cbiAgICAgICAgICB9XG4gICAgICAgIDwvbGFiZWw+XG4gICAgICB9XG5cbiAgICAgIEBpZiAoaXNTZWFyY2hhYmxlKCkpIHtcbiAgICAgICAgPCEtLSBTZWFyY2hhYmxlIFR5cGVhaGVhZCBDb21ib2JveCAtLT5cbiAgICAgICAgPGRpdiBjbGFzcz1cInJwdC1jb21ib2JveC13cmFwcGVyXCIgI2NvbWJvYm94V3JhcHBlciAjY29tYm9ib3hPcmlnaW49XCJjZGtPdmVybGF5T3JpZ2luXCIgY2RrT3ZlcmxheU9yaWdpbj5cbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGNsYXNzPVwicnB0LWNvbWJvYm94LXRyaWdnZXJcIlxuICAgICAgICAgICAgW2lkXT1cImVsZW1lbnRJZCgpXCJcbiAgICAgICAgICAgIFtjbGFzcy5ycHQtaW52YWxpZF09XCJpc0ludmFsaWQoKVwiXG4gICAgICAgICAgICBbY2xhc3MuaXMtb3Blbl09XCJpc09wZW4oKVwiXG4gICAgICAgICAgICBbZGlzYWJsZWRdPVwiZm9ybUNvbnRyb2woKS5kaXNhYmxlZFwiXG4gICAgICAgICAgICBbYXR0ci5hcmlhLWV4cGFuZGVkXT1cImlzT3BlbigpXCJcbiAgICAgICAgICAgIFthdHRyLmFyaWEtaGFzcG9wdXBdPVwiJ2xpc3Rib3gnXCJcbiAgICAgICAgICAgIChjbGljayk9XCJ0b2dnbGVPcGVuKCRldmVudClcIlxuICAgICAgICAgICAgKGtleWRvd24pPVwib25UcmlnZ2VyS2V5ZG93bigkZXZlbnQpXCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8c3BhbiBjbGFzcz1cInRyaWdnZXItbGFiZWxcIiBbY2xhc3MuaXMtcGxhY2Vob2xkZXJdPVwiIXNlbGVjdGVkT3B0aW9uKClcIj5cbiAgICAgICAgICAgICAge3sgc2VsZWN0ZWRPcHRpb24oKSA/IHNlbGVjdGVkT3B0aW9uKCkhLmxhYmVsIDogcGxhY2Vob2xkZXIoKSB9fVxuICAgICAgICAgICAgPC9zcGFuPlxuXG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidHJpZ2dlci1hY3Rpb25zXCI+XG4gICAgICAgICAgICAgIEBpZiAoaXNMb2FkaW5nKCkpIHtcbiAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXR1cy1kb3QgZG90LXB1bHNlXCIgc3R5bGU9XCJjb2xvcjogIzI1NjNlYjsgbWFyZ2luLXJpZ2h0OiA0cHg7XCIgdGl0bGU9XCJFeGVjdXRpbmcgcXVlcnkgb24gZGF0YWJhc2UuLi5cIj48L3NwYW4+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgQGlmIChsb2FkRXJyb3IoKSAmJiAhaXNMb2FkaW5nKCkpIHtcbiAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwidHJpZ2dlci1yZXRyeS1idG5cIlxuICAgICAgICAgICAgICAgICAgdGl0bGU9XCJSZXRyeSBkYXRhYmFzZSBxdWVyeVwiXG4gICAgICAgICAgICAgICAgICBhcmlhLWxhYmVsPVwiUmV0cnkgZGF0YWJhc2UgcXVlcnlcIlxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cInJldHJ5TG9va3VwKCRldmVudClcIlxuICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgIOKGuyBSZXRyeVxuICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIEBpZiAoc2VsZWN0ZWRPcHRpb24oKSAmJiAhZm9ybUNvbnRyb2woKS5kaXNhYmxlZCkge1xuICAgICAgICAgICAgICAgIDxzcGFuXG4gICAgICAgICAgICAgICAgICByb2xlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgIHRhYmluZGV4PVwiMFwiXG4gICAgICAgICAgICAgICAgICBjbGFzcz1cInRyaWdnZXItY2xlYXItYnRuXCJcbiAgICAgICAgICAgICAgICAgIHRpdGxlPVwiQ2xlYXIgc2VsZWN0aW9uXCJcbiAgICAgICAgICAgICAgICAgIGFyaWEtbGFiZWw9XCJDbGVhciBzZWxlY3Rpb25cIlxuICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNsZWFyU2VsZWN0aW9uKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgKGtleWRvd24uZW50ZXIpPVwiY2xlYXJTZWxlY3Rpb24oJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAoa2V5ZG93bi5zcGFjZSk9XCJjbGVhclNlbGVjdGlvbigkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICDinJVcbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ0cmlnZ2VyLWFycm93XCIgW2NsYXNzLnJvdGF0ZWRdPVwiaXNPcGVuKClcIiBhcmlhLWhpZGRlbj1cInRydWVcIj5cbiAgICAgICAgICAgICAgICA8c3ZnIHdpZHRoPVwiMTJcIiBoZWlnaHQ9XCI4XCIgdmlld0JveD1cIjAgMCAxMiA4XCIgZmlsbD1cIm5vbmVcIj5cbiAgICAgICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMSAxLjVMNiA2LjVMMTEgMS41XCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMS41XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIvPlxuICAgICAgICAgICAgICAgIDwvc3ZnPlxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgY2RrQ29ubmVjdGVkT3ZlcmxheVxuICAgICAgICAgIFtjZGtDb25uZWN0ZWRPdmVybGF5T3JpZ2luXT1cImNvbWJvYm94T3JpZ2luXCJcbiAgICAgICAgICBbY2RrQ29ubmVjdGVkT3ZlcmxheU9wZW5dPVwiaXNPcGVuKClcIlxuICAgICAgICAgIFtjZGtDb25uZWN0ZWRPdmVybGF5UG9zaXRpb25zXT1cIm92ZXJsYXlQb3NpdGlvbnNcIlxuICAgICAgICAgIFtjZGtDb25uZWN0ZWRPdmVybGF5V2lkdGhdPVwidHJpZ2dlcldpZHRoKClcIlxuICAgICAgICAgIFtjZGtDb25uZWN0ZWRPdmVybGF5RmxleGlibGVEaW1lbnNpb25zXT1cInRydWVcIlxuICAgICAgICAgIFtjZGtDb25uZWN0ZWRPdmVybGF5Vmlld3BvcnRNYXJnaW5dPVwiOFwiXG4gICAgICAgICAgW2Nka0Nvbm5lY3RlZE92ZXJsYXlQdXNoXT1cInRydWVcIlxuICAgICAgICAgIFtjZGtDb25uZWN0ZWRPdmVybGF5U2Nyb2xsU3RyYXRlZ3ldPVwic2Nyb2xsU3RyYXRlZ3lcIlxuICAgICAgICAgIChvdmVybGF5T3V0c2lkZUNsaWNrKT1cImNsb3NlRHJvcGRvd24oKVwiXG4gICAgICAgICAgKHBvc2l0aW9uQ2hhbmdlKT1cIm9uUG9zaXRpb25DaGFuZ2UoJGV2ZW50KVwiXG4gICAgICAgICAgKGF0dGFjaCk9XCJvbk92ZXJsYXlBdHRhY2hlZCgpXCJcbiAgICAgICAgICAoZGV0YWNoKT1cImNsb3NlRHJvcGRvd24oKVwiXG4gICAgICAgID5cbiAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICBjbGFzcz1cInJwdC1jb21ib2JveC1tZW51XCJcbiAgICAgICAgICAgIFtjbGFzcy5vcGVucy1hYm92ZV09XCJvcGVuc0Fib3ZlKClcIlxuICAgICAgICAgICAgcm9sZT1cImxpc3Rib3hcIlxuICAgICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPCEtLSBSZWFsLXRpbWUgRmlsdGVyIFNlYXJjaCBCb3ggLS0+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29tYm9ib3gtc2VhcmNoLWJveFwiPlxuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImNvbWJvYm94LXNlYXJjaC1pY29uXCIgYXJpYS1oaWRkZW49XCJ0cnVlXCI+XG4gICAgICAgICAgICAgICAgPHN2ZyB3aWR0aD1cIjEzXCIgaGVpZ2h0PVwiMTNcIiB2aWV3Qm94PVwiMCAwIDI0IDI0XCIgZmlsbD1cIm5vbmVcIiBzdHJva2U9XCJjdXJyZW50Q29sb3JcIiBzdHJva2Utd2lkdGg9XCIyLjVcIiBzdHJva2UtbGluZWNhcD1cInJvdW5kXCIgc3Ryb2tlLWxpbmVqb2luPVwicm91bmRcIj5cbiAgICAgICAgICAgICAgICAgIDxjaXJjbGUgY3g9XCIxMVwiIGN5PVwiMTFcIiByPVwiOFwiPjwvY2lyY2xlPlxuICAgICAgICAgICAgICAgICAgPGxpbmUgeDE9XCIyMVwiIHkxPVwiMjFcIiB4Mj1cIjE2LjY1XCIgeTI9XCIxNi42NVwiPjwvbGluZT5cbiAgICAgICAgICAgICAgICA8L3N2Zz5cbiAgICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAjc2VhcmNoSW5wdXRcbiAgICAgICAgICAgICAgICB0eXBlPVwidGV4dFwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJjb21ib2JveC1zZWFyY2gtaW5wdXRcIlxuICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwiVHlwZSB0byBmaWx0ZXIuLi5cIlxuICAgICAgICAgICAgICAgIFt2YWx1ZV09XCJzZWFyY2hUZXJtKClcIlxuICAgICAgICAgICAgICAgIFthdHRyLmFyaWEtYWN0aXZlZGVzY2VuZGFudF09XCJmb2N1c2VkSW5kZXgoKSA+PSAwID8gKGVsZW1lbnRJZCgpICsgJ19vcHRfJyArIGZvY3VzZWRJbmRleCgpKSA6IG51bGxcIlxuICAgICAgICAgICAgICAgIChpbnB1dCk9XCJvblNlYXJjaElucHV0KCRldmVudClcIlxuICAgICAgICAgICAgICAgIChrZXlkb3duKT1cIm9uU2VhcmNoS2V5ZG93bigkZXZlbnQpXCJcbiAgICAgICAgICAgICAgLz5cbiAgICAgICAgICAgICAgQGlmIChzZWFyY2hUZXJtKCkpIHtcbiAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY29tYm9ib3gtc2VhcmNoLWNsZWFyXCJcbiAgICAgICAgICAgICAgICAgIHRpdGxlPVwiQ2xlYXIgZmlsdGVyXCJcbiAgICAgICAgICAgICAgICAgIChjbGljayk9XCJjbGVhclNlYXJjaCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICDinJVcbiAgICAgICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICAgIDwhLS0gRmlsdGVyZWQgT3B0aW9ucyBMaXN0IC0tPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbWJvYm94LW9wdGlvbnMtbGlzdFwiICNvcHRpb25zTGlzdEVsIChzY3JvbGwpPVwib25PcHRpb25zU2Nyb2xsKCRldmVudClcIj5cbiAgICAgICAgICAgICAgQGlmICh3YWl0aW5nRm9yKCkubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb21ib2JveC1zdGF0dXMtcm93IHdhaXRpbmdcIj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuPldhaXRpbmcgZm9yIHt7IHdhaXRpbmdMYWJlbCgpIH19Li4uPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICB9IEBlbHNlIGlmIChpc0xvYWRpbmcoKSkge1xuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb21ib2JveC1zdGF0dXMtcm93IGxvYWRpbmdcIj5cbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3RhdHVzLWRvdCBkb3QtcHVsc2VcIj48L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8c3Bhbj5FeGVjdXRpbmcgcXVlcnkgb24gZGF0YWJhc2UgKG1heSB0YWtlIDHigJMyIG1pbnV0ZXMgb24gbG9jYWwgZGF0YWJhc2UpLi4uPC9zcGFuPlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICB9IEBlbHNlIGlmIChsb2FkRXJyb3IoKSkge1xuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb21ib2JveC1zdGF0dXMtcm93IGVycm9yXCI+XG4gICAgICAgICAgICAgICAgICA8c3Bhbj5FcnJvcjoge3sgbG9hZEVycm9yKCkgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cImNvbWJvYm94LXJldHJ5LWJ0blwiIChjbGljayk9XCJyZXRyeUxvb2t1cCgkZXZlbnQpXCI+4oa7IFJldHJ5IFF1ZXJ5PC9idXR0b24+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIH0gQGVsc2UgaWYgKGlzRHluYW1pY1NvdXJjZSgpICYmIGhhc0xvYWRlZCgpICYmIGFsbE9wdGlvbnMoKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiY29tYm9ib3gtc3RhdHVzLXJvdyBlbXB0eVwiPlxuICAgICAgICAgICAgICAgICAgPHNwYW4+Tm8gcmVjb3JkcyBmb3VuZCAoY2hlY2sgcGFyYW1ldGVycyk8L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIH0gQGVsc2UgaWYgKGZpbHRlcmVkT3B0aW9ucygpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJjb21ib2JveC1zdGF0dXMtcm93IGVtcHR5XCI+XG4gICAgICAgICAgICAgICAgICA8c3Bhbj5ObyBvcHRpb25zIG1hdGNoaW5nIFwie3sgc2VhcmNoVGVybSgpIH19XCI8L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgIEBmb3IgKG9wdCBvZiB2aXNpYmxlRmlsdGVyZWRPcHRpb25zKCk7IHRyYWNrIG9wdC5rZXk7IGxldCBpID0gJGluZGV4KSB7XG4gICAgICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgICAgIHJvbGU9XCJvcHRpb25cIlxuICAgICAgICAgICAgICAgICAgICBbaWRdPVwiZWxlbWVudElkKCkgKyAnX29wdF8nICsgaVwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY29tYm9ib3gtb3B0aW9uLWl0ZW1cIlxuICAgICAgICAgICAgICAgICAgICBbY2xhc3MuaXMtc2VsZWN0ZWRdPVwiaXNTZWxlY3RlZChvcHQpXCJcbiAgICAgICAgICAgICAgICAgICAgW2NsYXNzLmlzLWZvY3VzZWRdPVwiZm9jdXNlZEluZGV4KCkgPT09IGlcIlxuICAgICAgICAgICAgICAgICAgICBbYXR0ci5hcmlhLXNlbGVjdGVkXT1cImlzU2VsZWN0ZWQob3B0KVwiXG4gICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJzZWxlY3RPcHRpb24ob3B0KVwiXG4gICAgICAgICAgICAgICAgICAgIChtb3VzZWVudGVyKT1cImZvY3VzZWRJbmRleC5zZXQoaSlcIlxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm9wdC1sYWJlbFwiPnt7IG9wdC5sYWJlbCB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgQGlmIChpc1NlbGVjdGVkKG9wdCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cIm9wdC1jaGVja1wiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPuKckzwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIEBpZiAoZXhjZXNzRmlsdGVyZWRDb3VudCgpID4gMCkge1xuICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImNvbWJvYm94LXN0YXR1cy1yb3cgaGludFwiPlxuICAgICAgICAgICAgICAgICAgICA8c3Bhbj5TaG93aW5nIHt7IHZpc2libGVGaWx0ZXJlZE9wdGlvbnMoKS5sZW5ndGggfX0gb2Yge3sgZmlsdGVyZWRPcHRpb25zKCkubGVuZ3RoIH19IG1hdGNoZXMuIFNjcm9sbCBkb3duIG9yPC9zcGFuPlxuICAgICAgICAgICAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJjb21ib2JveC1sb2FkLWFsbC1idG5cIlxuICAgICAgICAgICAgICAgICAgICAgIChjbGljayk9XCJsb2FkQWxsRmlsdGVyZWQoKTsgJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpO1wiXG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICBMb2FkIGFsbCB7eyBmaWx0ZXJlZE9wdGlvbnMoKS5sZW5ndGggfX1cbiAgICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgfSBAZWxzZSB7XG4gICAgICAgIDwhLS0gTmF0aXZlIEJyb3dzZXIgU2VsZWN0IEZhbGxiYWNrIC0tPlxuICAgICAgICA8ZGl2IGNsYXNzPVwicnB0LXNlbGVjdC13cmFwcGVyXCI+XG4gICAgICAgICAgPHNlbGVjdFxuICAgICAgICAgICAgW2lkXT1cImVsZW1lbnRJZCgpXCJcbiAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJmb3JtQ29udHJvbCgpXCJcbiAgICAgICAgICAgIFtjbGFzcy5ycHQtaW52YWxpZF09XCJpc0ludmFsaWQoKVwiXG4gICAgICAgICAgICBjbGFzcz1cInJwdC1zZWxlY3RcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIEBpZiAod2FpdGluZ0ZvcigpLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiIGRpc2FibGVkIHNlbGVjdGVkPldhaXRpbmcgZm9yIHt7IHdhaXRpbmdMYWJlbCgpIH19Li4uPC9vcHRpb24+XG4gICAgICAgICAgICB9IEBlbHNlIGlmIChpc0xvYWRpbmcoKSkge1xuICAgICAgICAgICAgICA8b3B0aW9uIHZhbHVlPVwiXCIgZGlzYWJsZWQgc2VsZWN0ZWQ+TG9hZGluZyBvcHRpb25zIGZyb20gZGF0YWJhc2UuLi48L29wdGlvbj5cbiAgICAgICAgICAgIH0gQGVsc2UgaWYgKGxvYWRFcnJvcigpKSB7XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIiBkaXNhYmxlZCBzZWxlY3RlZD5FcnJvcjoge3sgbG9hZEVycm9yKCkgfX08L29wdGlvbj5cbiAgICAgICAgICAgIH0gQGVsc2UgaWYgKGlzRHluYW1pY1NvdXJjZSgpICYmIGhhc0xvYWRlZCgpICYmIGFsbE9wdGlvbnMoKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiIGRpc2FibGVkIHNlbGVjdGVkPi0tIE5vIHJlY29yZHMgZm91bmQgKGNoZWNrIHBhcmFtZXRlcnMpIC0tPC9vcHRpb24+XG4gICAgICAgICAgICB9IEBlbHNlIGlmIChwbGFjZWhvbGRlcigpKSB7XG4gICAgICAgICAgICAgIDxvcHRpb24gdmFsdWU9XCJcIiBbZGlzYWJsZWRdPVwiY29uZmlnKCkudmFsaWRhdGlvbj8ucmVxdWlyZWRcIj57eyBwbGFjZWhvbGRlcigpIH19PC9vcHRpb24+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBAZm9yIChvcHQgb2YgcmVuZGVyZWRPcHRpb25zKCk7IHRyYWNrIG9wdC5rZXkpIHtcbiAgICAgICAgICAgICAgPG9wdGlvbiBbdmFsdWVdPVwib3B0LmtleVwiPnt7IG9wdC5sYWJlbCB9fTwvb3B0aW9uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGlmIChoYXNFeGNlc3NPcHRpb25zKCkpIHtcbiAgICAgICAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiIGRpc2FibGVkPi4uLiBhbmQge3sgZXhjZXNzT3B0aW9uc0NvdW50KCkgfX0gbW9yZSByZWNvcmRzIChyZWZpbmUgZmlsdGVyKSAuLi48L29wdGlvbj5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICA8L3NlbGVjdD5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwicnB0LXNlbGVjdC1hcnJvd1wiIGFyaWEtaGlkZGVuPVwidHJ1ZVwiPlxuICAgICAgICAgICAgPHN2ZyB3aWR0aD1cIjEyXCIgaGVpZ2h0PVwiOFwiIHZpZXdCb3g9XCIwIDAgMTIgOFwiIGZpbGw9XCJub25lXCI+XG4gICAgICAgICAgICAgIDxwYXRoIGQ9XCJNMSAxLjVMNiA2LjVMMTEgMS41XCIgc3Ryb2tlPVwiY3VycmVudENvbG9yXCIgc3Ryb2tlLXdpZHRoPVwiMS41XCIgc3Ryb2tlLWxpbmVjYXA9XCJyb3VuZFwiIHN0cm9rZS1saW5lam9pbj1cInJvdW5kXCIvPlxuICAgICAgICAgICAgPC9zdmc+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgfVxuXG4gICAgICBAaWYgKHNob3dTdGF0dXMoKSAmJiBpc0R5bmFtaWNTb3VyY2UoKSAmJiBzdGF0dXNUZXh0KCkpIHtcbiAgICAgICAgPGRpdiBjbGFzcz1cInJwdC1zdGF0dXMtYmFkZ2VcIiBbYXR0ci5kYXRhLXN0YXR1c109XCJzdGF0dXNLaW5kKClcIj5cbiAgICAgICAgICBAc3dpdGNoIChzdGF0dXNLaW5kKCkpIHtcbiAgICAgICAgICAgIEBjYXNlICgnbG9hZGluZycpIHtcbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0dXMtZG90IGRvdC1wdWxzZVwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4+TG9hZGluZyBmcm9tIGRhdGFiYXNl4oCmPC9zcGFuPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGNhc2UgKCdvaycpIHtcbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0dXMtZG90IGRvdC1va1wiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4+e3sgZHluYW1pY09wdGlvbnMoKS5sZW5ndGggfX0gcmVjb3JkcyBsb2FkZWQ8L3NwYW4+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBAY2FzZSAoJ3dhaXRpbmcnKSB7XG4gICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwic3RhdHVzLWRvdCBkb3Qtd2FyblwiPjwvc3Bhbj5cbiAgICAgICAgICAgICAgPHNwYW4+V2FpdGluZyBmb3I6PC9zcGFuPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwid2FpdGluZy10b2tlbnNcIj5cbiAgICAgICAgICAgICAgICBAZm9yIChrIG9mIHdhaXRpbmdGb3IoKTsgdHJhY2sgaykge1xuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJ3YWl0aW5nLXRva2VuXCI+e3sgayB9fTwvc3Bhbj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGNhc2UgKCdlcnJvcicpIHtcbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0dXMtZG90IGRvdC1lcnJcIj48L3NwYW4+XG4gICAgICAgICAgICAgIDxzcGFuPnt7IGxvYWRFcnJvcigpIH19PC9zcGFuPlxuICAgICAgICAgICAgICA8YnV0dG9uIHR5cGU9XCJidXR0b25cIiBjbGFzcz1cInJwdC1iYWRnZS1yZXRyeS1idG5cIiAoY2xpY2spPVwicmV0cnlMb29rdXAoJGV2ZW50KVwiPuKGuyBSZXRyeTwvYnV0dG9uPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGNhc2UgKCdlbXB0eScpIHtcbiAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJzdGF0dXMtZG90XCI+PC9zcGFuPlxuICAgICAgICAgICAgICA8c3Bhbj5ObyByZWNvcmRzIGZvdW5kIGZvciBwYXJhbWV0ZXJzPC9zcGFuPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgQGRlZmF1bHQge1xuICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cInN0YXR1cy1kb3RcIj48L3NwYW4+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICA8L2Rpdj5cbiAgICAgIH1cblxuICAgICAgQGlmIChlcnJvck1lc3NhZ2UoKSkge1xuICAgICAgICA8c3BhbiBjbGFzcz1cInJwdC1lcnJvci10ZXh0XCI+e3sgZXJyb3JNZXNzYWdlKCkgfX08L3NwYW4+XG4gICAgICB9XG4gICAgPC9kaXY+Il19