@firestitch/report 18.10.0 → 18.10.2

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 (66) hide show
  1. package/app/reports/components/component-text/component-text.component.d.ts +1 -0
  2. package/app/reports/components/component-text/value-embed.plugin.d.ts +25 -1
  3. package/app/reports/components/report-canvas/report-canvas.component.d.ts +12 -0
  4. package/app/reports/components/report-component/report-component.component.d.ts +1 -0
  5. package/app/reports/data/report.data.d.ts +5 -7
  6. package/app/reports/dialogs/component-settings/component-settings.component.d.ts +13 -1
  7. package/app/reports/dialogs/report-settings/report-settings.component.d.ts +30 -2
  8. package/app/reports/export/report-export-collector.service.d.ts +13 -5
  9. package/app/reports/export/report-filter-lines.d.ts +3 -0
  10. package/app/reports/filter-settings-rules.d.ts +4 -0
  11. package/app/reports/filter-text.d.ts +8 -0
  12. package/app/reports/format.d.ts +1 -0
  13. package/app/reports/interfaces/report-export-lines-input.interface.d.ts +1 -0
  14. package/app/reports/interfaces/report-filter-group-changes.interface.d.ts +7 -0
  15. package/app/reports/interfaces/report.interface.d.ts +1 -14
  16. package/app/reports/report-filter-items.d.ts +11 -8
  17. package/app/reports/report-view-config.d.ts +1 -3
  18. package/app/reports/services/report-filter-state.service.d.ts +5 -14
  19. package/app/reports/services/report-view.service.d.ts +1 -13
  20. package/app/reports/text.d.ts +16 -0
  21. package/app/reports/views/report/fs-ai-report.component.d.ts +2 -8
  22. package/esm2022/app/reports/canvas-landing-page.mjs +7 -6
  23. package/esm2022/app/reports/components/component-list/component-list.component.mjs +5 -5
  24. package/esm2022/app/reports/components/component-text/component-text.component.mjs +34 -22
  25. package/esm2022/app/reports/components/component-text/value-embed.plugin.mjs +254 -42
  26. package/esm2022/app/reports/components/report-canvas/report-canvas.component.mjs +130 -24
  27. package/esm2022/app/reports/components/report-component/report-component.component.mjs +38 -19
  28. package/esm2022/app/reports/data/report.data.mjs +19 -11
  29. package/esm2022/app/reports/dialogs/component-settings/component-settings.component.mjs +57 -14
  30. package/esm2022/app/reports/dialogs/report-settings/report-settings.component.mjs +169 -21
  31. package/esm2022/app/reports/export/report-export-collector.service.mjs +84 -33
  32. package/esm2022/app/reports/export/report-filter-lines.mjs +25 -8
  33. package/esm2022/app/reports/export/report-pdf.service.mjs +31 -21
  34. package/esm2022/app/reports/export/report-pptx.service.mjs +21 -11
  35. package/esm2022/app/reports/filter-settings-rules.mjs +8 -1
  36. package/esm2022/app/reports/filter-text.mjs +154 -0
  37. package/esm2022/app/reports/format.mjs +3 -2
  38. package/esm2022/app/reports/interfaces/canvas-landing-input.interface.mjs +1 -1
  39. package/esm2022/app/reports/interfaces/report-export-lines-input.interface.mjs +1 -1
  40. package/esm2022/app/reports/interfaces/report-filter-group-changes.interface.mjs +2 -0
  41. package/esm2022/app/reports/interfaces/report-temporary-state.interface.mjs +1 -1
  42. package/esm2022/app/reports/interfaces/report-view-config.interface.mjs +1 -1
  43. package/esm2022/app/reports/interfaces/report.interface.mjs +1 -1
  44. package/esm2022/app/reports/report-date-presets.mjs +2 -2
  45. package/esm2022/app/reports/report-filter-items.mjs +48 -106
  46. package/esm2022/app/reports/report-view-config.mjs +6 -116
  47. package/esm2022/app/reports/services/report-filter-state.service.mjs +92 -269
  48. package/esm2022/app/reports/services/report-view.service.mjs +25 -165
  49. package/esm2022/app/reports/text.mjs +59 -13
  50. package/esm2022/app/reports/views/report/fs-ai-report.component.mjs +69 -130
  51. package/esm2022/app/reports/views/report/report.component.mjs +25 -19
  52. package/fesm2022/{firestitch-report-echarts-UBg8Wlhd.mjs → firestitch-report-echarts-CyHkFToO.mjs} +2 -2
  53. package/fesm2022/{firestitch-report-echarts-UBg8Wlhd.mjs.map → firestitch-report-echarts-CyHkFToO.mjs.map} +1 -1
  54. package/fesm2022/{firestitch-report-firestitch-report-B1keNrcK.mjs → firestitch-report-firestitch-report-DftB7M1o.mjs} +2936 -3254
  55. package/fesm2022/firestitch-report-firestitch-report-DftB7M1o.mjs.map +1 -0
  56. package/fesm2022/firestitch-report.mjs +1 -1
  57. package/package.json +1 -1
  58. package/app/reports/interfaces/report-url-link.interface.d.ts +0 -4
  59. package/app/reports/interfaces/report-url-value-name.type.d.ts +0 -1
  60. package/app/reports/interfaces/report-url-write.interface.d.ts +0 -4
  61. package/app/reports/report-url-state.d.ts +0 -36
  62. package/esm2022/app/reports/interfaces/report-url-link.interface.mjs +0 -2
  63. package/esm2022/app/reports/interfaces/report-url-value-name.type.mjs +0 -2
  64. package/esm2022/app/reports/interfaces/report-url-write.interface.mjs +0 -2
  65. package/esm2022/app/reports/report-url-state.mjs +0 -677
  66. package/fesm2022/firestitch-report-firestitch-report-B1keNrcK.mjs.map +0 -1
@@ -1,9 +1,10 @@
1
- import { ChangeDetectionStrategy, Component, DestroyRef, EventEmitter, computed, inject, signal, } from '@angular/core';
1
+ import { ChangeDetectionStrategy, Component, DestroyRef, EventEmitter, computed, inject, signal, viewChild, } from '@angular/core';
2
2
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
3
3
  import { FormsModule } from '@angular/forms';
4
4
  import { MAT_DIALOG_DATA, MatDialogActions, MatDialogClose, MatDialogContent, MatDialogRef, MatDialogTitle } from '@angular/material/dialog';
5
5
  import { MatFormField, MatHint, MatLabel, MatSuffix } from '@angular/material/form-field';
6
- import { MatButton } from '@angular/material/button';
6
+ import { MatButton, MatIconButton } from '@angular/material/button';
7
+ import { MatIcon } from '@angular/material/icon';
7
8
  import { MatInput } from '@angular/material/input';
8
9
  import { MatOption, MatSelect } from '@angular/material/select';
9
10
  import { MatSlideToggle } from '@angular/material/slide-toggle';
@@ -13,6 +14,7 @@ import { FsDialogModule } from '@firestitch/dialog';
13
14
  import { FsFormModule } from '@firestitch/form';
14
15
  import { FsLabelModule } from '@firestitch/label';
15
16
  import { FsMaskModule } from '@firestitch/mask';
17
+ import { FsMenuModule } from '@firestitch/menu';
16
18
  import { FsMessage } from '@firestitch/message';
17
19
  import { FsPrompt } from '@firestitch/prompt';
18
20
  import { FsTabsModule } from '@firestitch/tabs';
@@ -26,7 +28,7 @@ import { KPI_SPARKLINE_DEFAULT_GRANULARITY, KPI_SPARKLINE_DEFAULT_PERIODS, kpiCa
26
28
  import { GRANULARITY_OPTIONS, } from '../../interfaces/report.interface';
27
29
  import { DEFAULT_COMPONENT_PADDING } from '../../layout';
28
30
  import { FILTER_TYPE_OPTIONS, barPlacement, barPlacementOptions, componentToggleState, filterLevel, filterLevelChoices, shownOnComponent, typeSelectState, valueFilterLevel, valuePlacementOptions, } from '../../filter-settings-rules';
29
- import { escapeHtml } from '../../text';
31
+ import { escapeHtml, fieldToken, fillTitleTokens, textFields } from '../../text';
30
32
  import { operandKeys, reportComponents, valueKey } from '../../values';
31
33
  import * as i0 from "@angular/core";
32
34
  import * as i1 from "@angular/forms";
@@ -36,6 +38,7 @@ import * as i4 from "@firestitch/dialog";
36
38
  import * as i5 from "@firestitch/label";
37
39
  import * as i6 from "@firestitch/tabs";
38
40
  import * as i7 from "@angular/material/tabs";
41
+ import * as i8 from "@firestitch/menu";
39
42
  // What a rise in a KPI's value means, for the Increase is select.
40
43
  const KPI_CHANGE_POLARITY_OPTIONS = [
41
44
  { value: ReportChangePolarity.Good, name: 'Good news — a rise shows green' },
@@ -59,10 +62,12 @@ const FORMULA_LINES = {
59
62
  };
60
63
  // Component settings, in tabs:
61
64
  // Settings — title and content padding (a value: just its name, since it
62
- // sits inside a text block's words and has no box), and on a derived KPI its card:
63
- // what a rise means, a target and a sparkline (number formats stay with
64
- // the AI). Position/size are tuned by dragging on the canvas; height
65
- // behaviour follows from the component type.
65
+ // sits inside a text block's words and has no box). A title may carry the
66
+ // page, report and filter fields a text block's words do: its Insert field
67
+ // menu puts one in at the caret, and the line under it says how the title
68
+ // reads. On a derived KPI its card: what a rise means, a target and a
69
+ // sparkline (number formats stay with the AI). Position/size are tuned by
70
+ // dragging on the canvas; height behaviour follows from the component type.
66
71
  // Filters — ONE listing of every filterable column on this component. Each
67
72
  // row carries two toggles: show in the report bar and/or show on this
68
73
  // component (both, either, or neither). The interface (date range vs value
@@ -82,7 +87,22 @@ export class ComponentSettingsComponent {
82
87
  component;
83
88
  report;
84
89
  selectedTab = 'settings';
85
- title = '';
90
+ title = signal('');
91
+ // What the title's Insert field menu lists, in order: the page and report
92
+ // fields, then each filter of the report in the filter bar's order. A value
93
+ // token is never offered: values belong to a page's text.
94
+ titleFields = computed(() => textFields(this._data.tokens));
95
+ // How the title reads where the component is drawn, while it holds a token
96
+ // ('Sign-ups — September 2026'); empty for a title with none, and for a
97
+ // value, whose Name is just its name.
98
+ titleShownAs = computed(() => {
99
+ const title = this.title();
100
+ const shown = fillTitleTokens(title, this._data.tokens);
101
+ return !this.isValue() && shown !== title ? shown : '';
102
+ });
103
+ // The dialog's heading: the title as it reads (a value's Name as it is),
104
+ // else what the component is.
105
+ heading = computed(() => this._shownTitle() || (this.isValue() ? 'Value' : 'Component'));
86
106
  // Component padding in inches. `number | string` for the same reason as the
87
107
  // page dimensions in report-settings: fsMaskNumber seeds from the number but
88
108
  // hands back the unmasked string, and save casts it once on the way out.
@@ -149,6 +169,7 @@ export class ComponentSettingsComponent {
149
169
  numberRange: 'Number range',
150
170
  };
151
171
  _data = inject(MAT_DIALOG_DATA);
172
+ _titleInput = viewChild('titleInput');
152
173
  _dialogRef = inject(MatDialogRef);
153
174
  _reportData = inject(ReportData);
154
175
  _message = inject(FsMessage);
@@ -157,7 +178,7 @@ export class ComponentSettingsComponent {
157
178
  ngOnInit() {
158
179
  this.report = this._data.report;
159
180
  this.component = this._data.component;
160
- this.title = this.component.title ?? '';
181
+ this.title.set(this.component.title ?? '');
161
182
  this.isValue.set(this.component.type === 'value');
162
183
  this.isFormula.set(!!this.component.config?.formula);
163
184
  const padding = this.component.config?.padding;
@@ -198,7 +219,7 @@ export class ComponentSettingsComponent {
198
219
  }
199
220
  : {
200
221
  title: 'Delete Component',
201
- template: `Are you sure you would like to delete "${escapeHtml(this.component.title || 'this component')}"? This cannot be undone.`,
222
+ template: `Are you sure you would like to delete "${escapeHtml(this._shownTitle() || 'this component')}"? This cannot be undone.`,
202
223
  })
203
224
  .pipe(switchMap(() => this._reportData.deleteComponent(this.report.id, this.component.id)), tap(() => {
204
225
  this._message.success(this.isValue() ? 'Value deleted' : 'Component deleted');
@@ -206,6 +227,20 @@ export class ComponentSettingsComponent {
206
227
  }), takeUntilDestroyed(this._destroyRef))
207
228
  .subscribe();
208
229
  }
230
+ // Puts a field's token into the title at the caret, over any text selected
231
+ // there, as if it were typed: the model follows and the field is dirty. The
232
+ // input keeps its caret while the menu is open; focus comes back to it once
233
+ // the menu has handed focus back to its button.
234
+ insertField(field) {
235
+ const input = this._titleInput()?.nativeElement;
236
+ if (!input) {
237
+ return;
238
+ }
239
+ const end = input.value.length;
240
+ input.setRangeText(fieldToken(field), input.selectionStart ?? end, input.selectionEnd ?? end, 'end');
241
+ input.dispatchEvent(new Event('input'));
242
+ setTimeout(() => input.focus());
243
+ }
209
244
  // A percent target's bound, in the percent it is typed in. It reads the
210
245
  // control, which fsForm validates before ngModelChange updates the signal.
211
246
  validateTarget = (control) => {
@@ -218,7 +253,7 @@ export class ComponentSettingsComponent {
218
253
  const settings = {
219
254
  // The server trims a title; a value's Name is what its chips show, so it
220
255
  // goes as the server keeps it.
221
- title: this.isValue() ? this.title.trim() : this.title,
256
+ title: this.isValue() ? this.title().trim() : this.title(),
222
257
  padding: {
223
258
  top: this._padding(this.paddingTop),
224
259
  right: this._padding(this.paddingRight),
@@ -341,6 +376,11 @@ export class ComponentSettingsComponent {
341
376
  this.rows.update((rows) => rows.map((item) => (item.column === row.column ? patched : item)));
342
377
  return patched;
343
378
  }
379
+ // The stored title as it reads where the component is drawn, its tokens
380
+ // filled; a value's Name as it is.
381
+ _shownTitle() {
382
+ return this.isValue() ? this.component.title ?? '' : fillTitleTokens(this.component.title, this._data.tokens);
383
+ }
344
384
  // What a formula works out, naming each operand as its chips do. An op this
345
385
  // viewer does not know reads nothing.
346
386
  _formulaLine() {
@@ -547,7 +587,7 @@ export class ComponentSettingsComponent {
547
587
  .replace(/\b\w/g, (character) => character.toUpperCase());
548
588
  }
549
589
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ComponentSettingsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
550
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ComponentSettingsComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<form\n fsForm\n [submit]=\"save\">\n <fs-dialog>\n <h1 mat-dialog-title>\n {{ component.title || (isValue() ? 'Value' : 'Component') }}\n </h1>\n <mat-dialog-content>\n <mat-tab-group [(selected)]=\"selectedTab\">\n <mat-tab\n label=\"Settings\"\n name=\"settings\">\n <div class=\"fs-column tab-body\">\n <mat-form-field>\n <mat-label>\n {{ isValue() ? 'Name' : 'Title' }}\n </mat-label>\n <input\n matInput\n [(ngModel)]=\"title\"\n name=\"title\"\n [fsFormRequired]=\"isValue()\">\n </mat-form-field>\n <!-- A formula value is read-only beyond its name: what it works\n out is the AI's to change. A formula this viewer cannot\n read has no line, and no row. -->\n @if (formulaLine()) {\n <fs-label-field>\n <fs-label>\n Formula\n </fs-label>\n {{ formulaLine() }}\n <fs-label-message>\n Worked out on the server; it follows the filters of the values it reads.\n </fs-label-message>\n </fs-label-field>\n }\n <!-- A value sits inside a text block's words: no box, no padding. -->\n @if (!isValue()) {\n <div class=\"subheading-2\">\n Padding\n </div>\n <div class=\"geometry-row\">\n <mat-form-field>\n <mat-label>\n Top\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingTop\"\n name=\"paddingTop\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Right\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingRight\"\n name=\"paddingRight\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Bottom\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingBottom\"\n name=\"paddingBottom\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Left\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingLeft\"\n name=\"paddingLeft\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n </div>\n }\n <!-- A derived KPI's card: what a rise means, a target and a\n sparkline. The server computes the progress and the points. -->\n @if (kpiCard()) {\n <div class=\"subheading-2\">\n Card\n </div>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Increase is\n </mat-label>\n <mat-select\n [ngModel]=\"increaseIs()\"\n (ngModelChange)=\"increaseIs.set($event)\"\n name=\"increaseIs\">\n @for (option of kpiPolarityOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n Colors the change and decides when the target is met.\n </mat-hint>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Target\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"6\"\n [signed]=\"true\"\n [ngModel]=\"targetValue()\"\n (ngModelChange)=\"targetValue.set($event)\"\n name=\"targetValue\"\n [validate]=\"validateTarget\">\n @if (targetPercent()) {\n <div matTextSuffix>\n %\n </div>\n }\n <mat-hint>\n The value to reach. Leave empty for no target.\n </mat-hint>\n </mat-form-field>\n @if (hasTarget()) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Target label\n </mat-label>\n <input\n matInput\n [ngModel]=\"targetLabel()\"\n (ngModelChange)=\"targetLabel.set($event)\"\n name=\"targetLabel\">\n <mat-hint>\n Shown before the target, such as Goal. Empty reads Target.\n </mat-hint>\n </mat-form-field>\n }\n <fs-label-field>\n <mat-slide-toggle\n [ngModel]=\"sparkline()\"\n (ngModelChange)=\"sparkline.set($event)\"\n name=\"sparkline\">\n Sparkline\n </mat-slide-toggle>\n <mat-hint>\n A small trend line of the value over its last periods.\n </mat-hint>\n </fs-label-field>\n @if (sparkline()) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Sparkline period\n </mat-label>\n <mat-select\n [ngModel]=\"sparklineGranularity()\"\n (ngModelChange)=\"sparklineGranularity.set($event)\"\n name=\"sparklineGranularity\">\n @for (option of granularityOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Sparkline periods\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"0\"\n [ngModel]=\"sparklinePeriods()\"\n (ngModelChange)=\"sparklinePeriods.set($event)\"\n name=\"sparklinePeriods\"\n [fsFormRequired]=\"true\"\n [fsFormInteger]=\"true\"\n [fsFormMin]=\"sparklineMinPeriods\"\n [fsFormMax]=\"sparklineMaxPeriods\">\n <mat-hint>\n How many periods the line covers, {{ sparklineMinPeriods }} to {{ sparklineMaxPeriods }}.\n </mat-hint>\n </mat-form-field>\n }\n }\n </div>\n </mat-tab>\n <!-- A formula runs no statement and follows the filters of the values\n it reads, so it has neither a Filters nor an SQL tab. -->\n @if (!isFormula()) {\n <mat-tab\n label=\"Filters\"\n name=\"filters\">\n <div class=\"tab-body\">\n @if (columnsError()) {\n <div class=\"filters-empty error\">\n {{ columnsError() }}\n </div>\n } @else if (rows().length) {\n <!-- Every filterable column. Pick where its control shows: in\n the report bar (every page, or this page only), on this\n component, both, or neither. The interface follows the\n data; a numeric column can be values or a number range.\n A value sits inside text and has no component to show a\n control on, so it gets the report bar column only. -->\n <table class=\"filter-table\">\n <thead>\n <tr>\n <th class=\"filter-col-name\">\n Filter\n </th>\n <th class=\"filter-col-type\">\n Type\n </th>\n <th class=\"filter-col-select\">\n Report bar\n </th>\n @if (!isValue()) {\n <th class=\"filter-col-toggle\">\n This component\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of rows(); track row.column) {\n <tr>\n <td class=\"filter-col-name\">\n {{ row.label }}\n </td>\n <td class=\"filter-col-type\">\n @if (row.typeSelect.show) {\n <mat-form-field\n [subscriptSizing]=\"'dynamic'\"\n [matTooltip]=\"row.typeSelect.tooltip\">\n <mat-select\n [panelWidth]=\"null\"\n [ngModel]=\"row.type\"\n (ngModelChange)=\"setType(row, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"row.typeSelect.disabled\"\n aria-label=\"Type\">\n @for (option of typeOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n } @else {\n {{ typeLabel(row.type) }}\n }\n </td>\n <td class=\"filter-col-select\">\n <mat-form-field [subscriptSizing]=\"'dynamic'\">\n <mat-select\n [panelWidth]=\"null\"\n [ngModel]=\"row.placement\"\n (ngModelChange)=\"setPlacement(row, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n aria-label=\"Report bar\">\n @for (option of row.placementOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </td>\n @if (!isValue()) {\n <td class=\"filter-col-toggle\">\n <mat-slide-toggle\n [ngModel]=\"row.component\"\n (ngModelChange)=\"setComponent(row, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"row.componentToggle.disabled\"\n [matTooltip]=\"row.componentToggle.tooltip\">\n </mat-slide-toggle>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <div class=\"filters-empty\">\n This component has no filterable columns yet \u2014 give it some SQL first.\n </div>\n }\n </div>\n </mat-tab>\n <mat-tab\n label=\"SQL\"\n name=\"sql\">\n <div class=\"tab-body\">\n @if (sqlError()) {\n <div class=\"filters-empty error\">\n {{ sqlError() }}\n </div>\n } @else if (sql()) {\n @if (sqlBaseline()) {\n <!-- A derived component's statement is compiled from its\n document with no viewer state, so it is not byte-for-byte\n what produced the numbers on screen. Said here rather than\n left for the reader to discover. -->\n <div class=\"filters-empty\">\n Compiled from this component's query \u2014 no filters applied, times in {{ sqlTimezone() }}.\n </div>\n }\n <pre class=\"code-block\">{{ sql() }}</pre>\n } @else {\n <div class=\"filters-empty\">\n This component has no SQL yet.\n </div>\n }\n </div>\n </mat-tab>\n }\n <mat-tab\n label=\"Config\"\n name=\"config\">\n <div class=\"tab-body\">\n <pre class=\"code-block\">\n {{ configJson }}\n </pre>\n </div>\n </mat-tab>\n </mat-tab-group>\n </mat-dialog-content>\n <mat-dialog-actions>\n <!-- Save | Delete | Cancel, the standard order. fs-form-dialog-actions\n renders its own Save/Done BEFORE the projected content, which would\n put Delete after Cancel, so `[save]=\"false\"` foots the row here and\n all three buttons are projected in order. Save submits the Settings\n tab; the other tabs persist as you touch them, so they get Done. -->\n <fs-form-dialog-actions [save]=\"false\">\n @if (selectedTab === 'settings') {\n <button\n mat-button\n type=\"submit\"\n color=\"primary\">\n Save\n </button>\n } @else {\n <button\n mat-button\n type=\"button\"\n color=\"primary\"\n [mat-dialog-close]=\"null\">\n Done\n </button>\n }\n <button\n mat-button\n type=\"button\"\n color=\"warn\"\n (click)=\"delete()\">\n Delete\n </button>\n <button\n mat-button\n type=\"button\"\n class=\"cancel-button\"\n [mat-dialog-close]=\"null\">\n Cancel\n </button>\n </fs-form-dialog-actions>\n </mat-dialog-actions>\n </fs-dialog>\n</form>", styles: ["mat-form-field{width:100%}.tab-body{padding-top:16px}.geometry-row{display:flex;gap:8px}.geometry-row mat-form-field{flex:1}.filter-table{border-spacing:0;width:100%;border-collapse:collapse}.filter-table thead th{color:#8f8f8f;font-weight:400;font-size:85%;text-align:left;padding:8px 16px}.filter-table tbody tr{clip-path:xywh(0 3px 100% calc(100% - 6px) round 10px)}.filter-table tbody td{border:none;background-color:#fafafa;padding:8px 16px;vertical-align:middle;text-align:left}.filter-table .filter-col-name{font-weight:600;color:#1f2933}.filter-table .filter-col-type{color:#7b8794;width:150px}.filter-table .filter-col-select{width:160px}.filter-table td.filter-col-type,.filter-table td.filter-col-select{padding-left:8px;padding-right:8px}.filter-table td.filter-col-type mat-form-field,.filter-table td.filter-col-select mat-form-field{width:100%;--mat-form-field-container-height: 36px;--mat-form-field-container-vertical-padding: 6px}.filter-table td.filter-col-type ::ng-deep .mat-mdc-form-field-infix,.filter-table td.filter-col-select ::ng-deep .mat-mdc-form-field-infix{width:auto}.filter-table td.filter-col-type ::ng-deep .mat-mdc-form-field-subscript-wrapper,.filter-table td.filter-col-select ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.filter-table .filter-col-toggle,.filter-table th.filter-col-toggle{width:110px;text-align:center}.filters-empty{font-size:13px;color:#7b8794;padding:8px 0 4px}.filters-empty.error{color:#e15759}.code-block{margin:0;padding:10px 12px;background:#1f2933;color:#e4e7eb;border-radius:6px;font-family:JetBrains Mono,Consolas,monospace;font-size:12px;line-height:1.5;white-space:pre-wrap;word-break:break-word;max-height:240px;overflow:auto}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormDirective, selector: "[fsForm]", inputs: ["wrapperSelector", "messageSelector", "hintSelector", "labelSelector", "autocomplete", "shortcuts", "confirm", "confirmDialog", "confirmDrawer", "confirmBrowser", "dirtySubmitButton", "submit", "successDelay", "errorDelay", "deactivationGuard"], outputs: ["fsForm", "invalid", "valid", "submitted", "reseted", "cleared"], exportAs: ["fsForm"] }, { kind: "directive", type: i2.FsFormRequiredDirective, selector: "[fsFormRequired],[ngModel][required]", inputs: ["fsFormRequired", "required", "fsFormRequiredMessage"] }, { kind: "directive", type: i2.FsFormMinDirective, selector: "[fsFormMin]", inputs: ["fsFormMin", "fsFormMinMessage"] }, { kind: "directive", type: i2.FsFormMaxDirective, selector: "[fsFormMax]", inputs: ["fsFormMax", "fsFormMaxMessage"] }, { kind: "directive", type: i2.FsFormIntegerDirective, selector: "[fsFormInteger]", inputs: ["fsFormInteger", "fsFormIntegerMessage"] }, { kind: "directive", type: i2.FsFormValidateDirective, selector: "[validate]", inputs: ["validate", "validateData", "validateOnSubmit"] }, { kind: "component", type: i2.FsFormDialogActionsComponent, selector: "fs-form-dialog-actions", inputs: ["save", "create", "close", "done", "closeData", "name"] }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }, { kind: "directive", type: i2.FsButtonDirective, selector: "[mat-raised-button],[mat-button],[mat-flat-button],[mat-stroked-button]", inputs: ["name", "dirtySubmit"] }, { kind: "ngmodule", type: FsMaskModule }, { kind: "directive", type: i3.FsMaskNumberDirective, selector: "[fsMaskNumber]" }, { kind: "ngmodule", type: FsDialogModule }, { kind: "component", type: i4.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }, { kind: "ngmodule", type: FsLabelModule }, { kind: "component", type: i5.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i5.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "component", type: i5.FsLabelMessageComponent, selector: "fs-label-message" }, { kind: "ngmodule", type: FsTabsModule }, { kind: "directive", type: i6.FsTabsHeaderTabGroupDirective, selector: "mat-tab-group, matTabGroup, [matTabGroup]", inputs: ["orientation", "selected", "selectedData"], outputs: ["selectedChange", "selectedDataChange"], exportAs: ["fsTabsHeaderTabGroup"] }, { kind: "directive", type: i6.FsTabsTabDirective, selector: "mat-tab,matTab", inputs: ["name", "data"], exportAs: ["fsTabsTab"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i7.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i7.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "directive", type: MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
590
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ComponentSettingsComponent, isStandalone: true, selector: "ng-component", viewQueries: [{ propertyName: "_titleInput", first: true, predicate: ["titleInput"], descendants: true, isSignal: true }], ngImport: i0, template: "<form\n fsForm\n [submit]=\"save\">\n <fs-dialog>\n <h1 mat-dialog-title>\n {{ heading() }}\n </h1>\n <mat-dialog-content>\n <mat-tab-group [(selected)]=\"selectedTab\">\n <mat-tab\n label=\"Settings\"\n name=\"settings\">\n <div class=\"fs-column tab-body\">\n <!-- A value's Name is just its name. A title may carry the page,\n report and filter fields a text block's words do: Insert\n field puts one in at the caret, and the hint says how the\n title reads where the component is drawn. -->\n @if (isValue()) {\n <mat-form-field>\n <mat-label>\n Name\n </mat-label>\n <input\n matInput\n [ngModel]=\"title()\"\n (ngModelChange)=\"title.set($event)\"\n name=\"title\"\n [fsFormRequired]=\"true\">\n </mat-form-field>\n } @else {\n <mat-form-field>\n <mat-label>\n Title\n </mat-label>\n <input\n #titleInput\n matInput\n [ngModel]=\"title()\"\n (ngModelChange)=\"title.set($event)\"\n name=\"title\">\n <!-- The button swallows its own click: the form field would\n otherwise put focus back in the input while the menu is\n open, and a key pressed then would move the caret the\n field goes in at. -->\n <button\n mat-icon-button\n matIconSuffix\n type=\"button\"\n aria-label=\"Insert field\"\n [fsMenuTriggerFor]=\"insertFieldMenu\"\n (click)=\"$event.stopPropagation()\">\n <mat-icon>sell</mat-icon>\n </button>\n @if (titleShownAs()) {\n <mat-hint>\n Shows as: {{ titleShownAs() }}\n </mat-hint>\n }\n </mat-form-field>\n <fs-menu #insertFieldMenu>\n @for (entry of titleFields(); track entry.field) {\n <ng-template\n fs-menu-item\n (click)=\"insertField(entry.field)\">\n {{ entry.name }}\n </ng-template>\n }\n </fs-menu>\n }\n <!-- A formula value is read-only beyond its name: what it works\n out is the AI's to change. A formula this viewer cannot\n read has no line, and no row. -->\n @if (formulaLine()) {\n <fs-label-field>\n <fs-label>\n Formula\n </fs-label>\n {{ formulaLine() }}\n <fs-label-message>\n Worked out on the server; it follows the filters of the values it reads.\n </fs-label-message>\n </fs-label-field>\n }\n <!-- A value sits inside a text block's words: no box, no padding. -->\n @if (!isValue()) {\n <div class=\"subheading-2\">\n Padding\n </div>\n <div class=\"geometry-row\">\n <mat-form-field>\n <mat-label>\n Top\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingTop\"\n name=\"paddingTop\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Right\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingRight\"\n name=\"paddingRight\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Bottom\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingBottom\"\n name=\"paddingBottom\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Left\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingLeft\"\n name=\"paddingLeft\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n </div>\n }\n <!-- A derived KPI's card: what a rise means, a target and a\n sparkline. The server computes the progress and the points. -->\n @if (kpiCard()) {\n <div class=\"subheading-2\">\n Card\n </div>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Increase is\n </mat-label>\n <mat-select\n [ngModel]=\"increaseIs()\"\n (ngModelChange)=\"increaseIs.set($event)\"\n name=\"increaseIs\">\n @for (option of kpiPolarityOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n Colors the change and decides when the target is met.\n </mat-hint>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Target\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"6\"\n [signed]=\"true\"\n [ngModel]=\"targetValue()\"\n (ngModelChange)=\"targetValue.set($event)\"\n name=\"targetValue\"\n [validate]=\"validateTarget\">\n @if (targetPercent()) {\n <div matTextSuffix>\n %\n </div>\n }\n <mat-hint>\n The value to reach. Leave empty for no target.\n </mat-hint>\n </mat-form-field>\n @if (hasTarget()) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Target label\n </mat-label>\n <input\n matInput\n [ngModel]=\"targetLabel()\"\n (ngModelChange)=\"targetLabel.set($event)\"\n name=\"targetLabel\">\n <mat-hint>\n Shown before the target, such as Goal. Empty reads Target.\n </mat-hint>\n </mat-form-field>\n }\n <fs-label-field>\n <mat-slide-toggle\n [ngModel]=\"sparkline()\"\n (ngModelChange)=\"sparkline.set($event)\"\n name=\"sparkline\">\n Sparkline\n </mat-slide-toggle>\n <mat-hint>\n A small trend line of the value over its last periods.\n </mat-hint>\n </fs-label-field>\n @if (sparkline()) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Sparkline period\n </mat-label>\n <mat-select\n [ngModel]=\"sparklineGranularity()\"\n (ngModelChange)=\"sparklineGranularity.set($event)\"\n name=\"sparklineGranularity\">\n @for (option of granularityOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Sparkline periods\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"0\"\n [ngModel]=\"sparklinePeriods()\"\n (ngModelChange)=\"sparklinePeriods.set($event)\"\n name=\"sparklinePeriods\"\n [fsFormRequired]=\"true\"\n [fsFormInteger]=\"true\"\n [fsFormMin]=\"sparklineMinPeriods\"\n [fsFormMax]=\"sparklineMaxPeriods\">\n <mat-hint>\n How many periods the line covers, {{ sparklineMinPeriods }} to {{ sparklineMaxPeriods }}.\n </mat-hint>\n </mat-form-field>\n }\n }\n </div>\n </mat-tab>\n <!-- A formula runs no statement and follows the filters of the values\n it reads, so it has neither a Filters nor an SQL tab. -->\n @if (!isFormula()) {\n <mat-tab\n label=\"Filters\"\n name=\"filters\">\n <div class=\"tab-body\">\n @if (columnsError()) {\n <div class=\"filters-empty error\">\n {{ columnsError() }}\n </div>\n } @else if (rows().length) {\n <!-- Every filterable column. Pick where its control shows: in\n the report bar (every page, or this page only), on this\n component, both, or neither. The interface follows the\n data; a numeric column can be values or a number range.\n A value sits inside text and has no component to show a\n control on, so it gets the report bar column only. -->\n <table class=\"filter-table\">\n <thead>\n <tr>\n <th class=\"filter-col-name\">\n Filter\n </th>\n <th class=\"filter-col-type\">\n Type\n </th>\n <th class=\"filter-col-select\">\n Report bar\n </th>\n @if (!isValue()) {\n <th class=\"filter-col-toggle\">\n This component\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of rows(); track row.column) {\n <tr>\n <td class=\"filter-col-name\">\n {{ row.label }}\n </td>\n <td class=\"filter-col-type\">\n @if (row.typeSelect.show) {\n <mat-form-field\n [subscriptSizing]=\"'dynamic'\"\n [matTooltip]=\"row.typeSelect.tooltip\">\n <mat-select\n [panelWidth]=\"null\"\n [ngModel]=\"row.type\"\n (ngModelChange)=\"setType(row, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"row.typeSelect.disabled\"\n aria-label=\"Type\">\n @for (option of typeOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n } @else {\n {{ typeLabel(row.type) }}\n }\n </td>\n <td class=\"filter-col-select\">\n <mat-form-field [subscriptSizing]=\"'dynamic'\">\n <mat-select\n [panelWidth]=\"null\"\n [ngModel]=\"row.placement\"\n (ngModelChange)=\"setPlacement(row, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n aria-label=\"Report bar\">\n @for (option of row.placementOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </td>\n @if (!isValue()) {\n <td class=\"filter-col-toggle\">\n <mat-slide-toggle\n [ngModel]=\"row.component\"\n (ngModelChange)=\"setComponent(row, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"row.componentToggle.disabled\"\n [matTooltip]=\"row.componentToggle.tooltip\">\n </mat-slide-toggle>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <div class=\"filters-empty\">\n This component has no filterable columns yet \u2014 give it some SQL first.\n </div>\n }\n </div>\n </mat-tab>\n <mat-tab\n label=\"SQL\"\n name=\"sql\">\n <div class=\"tab-body\">\n @if (sqlError()) {\n <div class=\"filters-empty error\">\n {{ sqlError() }}\n </div>\n } @else if (sql()) {\n @if (sqlBaseline()) {\n <!-- A derived component's statement is compiled from its\n document with no viewer state, so it is not byte-for-byte\n what produced the numbers on screen. Said here rather than\n left for the reader to discover. -->\n <div class=\"filters-empty\">\n Compiled from this component's query \u2014 no filters applied, times in {{ sqlTimezone() }}.\n </div>\n }\n <pre class=\"code-block\">{{ sql() }}</pre>\n } @else {\n <div class=\"filters-empty\">\n This component has no SQL yet.\n </div>\n }\n </div>\n </mat-tab>\n }\n <mat-tab\n label=\"Config\"\n name=\"config\">\n <div class=\"tab-body\">\n <pre class=\"code-block\">\n {{ configJson }}\n </pre>\n </div>\n </mat-tab>\n </mat-tab-group>\n </mat-dialog-content>\n <mat-dialog-actions>\n <!-- Save | Delete | Cancel, the standard order. fs-form-dialog-actions\n renders its own Save/Done BEFORE the projected content, which would\n put Delete after Cancel, so `[save]=\"false\"` foots the row here and\n all three buttons are projected in order. Save submits the Settings\n tab; the other tabs persist as you touch them, so they get Done. -->\n <fs-form-dialog-actions [save]=\"false\">\n @if (selectedTab === 'settings') {\n <button\n mat-button\n type=\"submit\"\n color=\"primary\">\n Save\n </button>\n } @else {\n <button\n mat-button\n type=\"button\"\n color=\"primary\"\n [mat-dialog-close]=\"null\">\n Done\n </button>\n }\n <button\n mat-button\n type=\"button\"\n color=\"warn\"\n (click)=\"delete()\">\n Delete\n </button>\n <button\n mat-button\n type=\"button\"\n class=\"cancel-button\"\n [mat-dialog-close]=\"null\">\n Cancel\n </button>\n </fs-form-dialog-actions>\n </mat-dialog-actions>\n </fs-dialog>\n</form>", styles: ["mat-form-field{width:100%}.tab-body{padding-top:16px}.geometry-row{display:flex;gap:8px}.geometry-row mat-form-field{flex:1}.filter-table{border-spacing:0;width:100%;border-collapse:collapse}.filter-table thead th{color:#8f8f8f;font-weight:400;font-size:85%;text-align:left;padding:8px 16px}.filter-table tbody tr{clip-path:xywh(0 3px 100% calc(100% - 6px) round 10px)}.filter-table tbody td{border:none;background-color:#fafafa;padding:8px 16px;vertical-align:middle;text-align:left}.filter-table .filter-col-name{font-weight:600;color:#1f2933}.filter-table .filter-col-type{color:#7b8794;width:150px}.filter-table .filter-col-select{width:160px}.filter-table td.filter-col-type,.filter-table td.filter-col-select{padding-left:8px;padding-right:8px}.filter-table td.filter-col-type mat-form-field,.filter-table td.filter-col-select mat-form-field{width:100%;--mat-form-field-container-height: 36px;--mat-form-field-container-vertical-padding: 6px}.filter-table td.filter-col-type ::ng-deep .mat-mdc-form-field-infix,.filter-table td.filter-col-select ::ng-deep .mat-mdc-form-field-infix{width:auto}.filter-table td.filter-col-type ::ng-deep .mat-mdc-form-field-subscript-wrapper,.filter-table td.filter-col-select ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.filter-table .filter-col-toggle,.filter-table th.filter-col-toggle{width:110px;text-align:center}.filters-empty{font-size:13px;color:#7b8794;padding:8px 0 4px}.filters-empty.error{color:#e15759}.code-block{margin:0;padding:10px 12px;background:#1f2933;color:#e4e7eb;border-radius:6px;font-family:JetBrains Mono,Consolas,monospace;font-size:12px;line-height:1.5;white-space:pre-wrap;word-break:break-word;max-height:240px;overflow:auto}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i1.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "ngmodule", type: FsFormModule }, { kind: "directive", type: i2.FsFormDirective, selector: "[fsForm]", inputs: ["wrapperSelector", "messageSelector", "hintSelector", "labelSelector", "autocomplete", "shortcuts", "confirm", "confirmDialog", "confirmDrawer", "confirmBrowser", "dirtySubmitButton", "submit", "successDelay", "errorDelay", "deactivationGuard"], outputs: ["fsForm", "invalid", "valid", "submitted", "reseted", "cleared"], exportAs: ["fsForm"] }, { kind: "directive", type: i2.FsFormRequiredDirective, selector: "[fsFormRequired],[ngModel][required]", inputs: ["fsFormRequired", "required", "fsFormRequiredMessage"] }, { kind: "directive", type: i2.FsFormMinDirective, selector: "[fsFormMin]", inputs: ["fsFormMin", "fsFormMinMessage"] }, { kind: "directive", type: i2.FsFormMaxDirective, selector: "[fsFormMax]", inputs: ["fsFormMax", "fsFormMaxMessage"] }, { kind: "directive", type: i2.FsFormIntegerDirective, selector: "[fsFormInteger]", inputs: ["fsFormInteger", "fsFormIntegerMessage"] }, { kind: "directive", type: i2.FsFormValidateDirective, selector: "[validate]", inputs: ["validate", "validateData", "validateOnSubmit"] }, { kind: "component", type: i2.FsFormDialogActionsComponent, selector: "fs-form-dialog-actions", inputs: ["save", "create", "close", "done", "closeData", "name"] }, { kind: "directive", type: i2.FsFormNoFsValidatorsDirective, selector: "[ngModel]:not([required]):not([fsFormRequired]):not([fsFormCompare]):not([fsFormDateRange]):not([fsFormEmail]):not([fsFormEmails]):not([fsFormFunction]):not([fsFormGreater]):not([fsFormGreaterEqual]):not([fsFormInteger]):not([fsFormLesser]):not([fsFormMax]):not([fsFormMaxLength]):not([fsFormMin]):not([fsFormMinLength]):not([fsFormNumeric]):not([fsFormPattern]):not([fsFormPhone]):not([fsFormUrl]):not([validate])" }, { kind: "directive", type: i2.FsButtonDirective, selector: "[mat-raised-button],[mat-button],[mat-flat-button],[mat-stroked-button]", inputs: ["name", "dirtySubmit"] }, { kind: "ngmodule", type: FsMaskModule }, { kind: "directive", type: i3.FsMaskNumberDirective, selector: "[fsMaskNumber]" }, { kind: "ngmodule", type: FsDialogModule }, { kind: "component", type: i4.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }, { kind: "ngmodule", type: FsLabelModule }, { kind: "component", type: i5.FsLabelComponent, selector: "fs-label" }, { kind: "component", type: i5.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "component", type: i5.FsLabelMessageComponent, selector: "fs-label-message" }, { kind: "ngmodule", type: FsTabsModule }, { kind: "directive", type: i6.FsTabsHeaderTabGroupDirective, selector: "mat-tab-group, matTabGroup, [matTabGroup]", inputs: ["orientation", "selected", "selectedData"], outputs: ["selectedChange", "selectedDataChange"], exportAs: ["fsTabsHeaderTabGroup"] }, { kind: "directive", type: i6.FsTabsTabDirective, selector: "mat-tab,matTab", inputs: ["name", "data"], exportAs: ["fsTabsTab"] }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i7.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i7.MatTabGroup, selector: "mat-tab-group", inputs: ["color", "fitInkBarToContent", "mat-stretch-tabs", "dynamicHeight", "selectedIndex", "headerPosition", "animationDuration", "contentTabIndex", "disablePagination", "disableRipple", "preserveContent", "backgroundColor", "aria-label", "aria-labelledby"], outputs: ["selectedIndexChange", "focusChange", "animationDone", "selectedTabChange"], exportAs: ["matTabGroup"] }, { kind: "directive", type: MatDialogTitle, selector: "[mat-dialog-title], [matDialogTitle]", inputs: ["id"], exportAs: ["matDialogTitle"] }, { kind: "directive", type: MatDialogContent, selector: "[mat-dialog-content], mat-dialog-content, [matDialogContent]" }, { kind: "directive", type: MatDialogActions, selector: "[mat-dialog-actions], mat-dialog-actions, [matDialogActions]", inputs: ["align"] }, { kind: "directive", type: MatDialogClose, selector: "[mat-dialog-close], [matDialogClose]", inputs: ["aria-label", "type", "mat-dialog-close", "matDialogClose"], exportAs: ["matDialogClose"] }, { kind: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "directive", type: MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: MatSelect, selector: "mat-select", inputs: ["aria-describedby", "panelClass", "disabled", "disableRipple", "tabIndex", "hideSingleSelectionIndicator", "placeholder", "required", "multiple", "disableOptionCentering", "compareWith", "value", "aria-label", "aria-labelledby", "errorStateMatcher", "typeaheadDebounceInterval", "sortComparator", "id", "panelWidth"], outputs: ["openedChange", "opened", "closed", "selectionChange", "valueChange"], exportAs: ["matSelect"] }, { kind: "component", type: MatSlideToggle, selector: "mat-slide-toggle", inputs: ["name", "id", "labelPosition", "aria-label", "aria-labelledby", "aria-describedby", "required", "color", "disabled", "disableRipple", "tabIndex", "checked", "hideIcon", "disabledInteractive"], outputs: ["change", "toggleChange"], exportAs: ["matSlideToggle"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: FsMenuModule }, { kind: "component", type: i8.FsMenuComponent, selector: "fs-menu", inputs: ["class", "buttonClass", "buttonType", "buttonColor"], outputs: ["opened", "closed"] }, { kind: "directive", type: i8.FsMenuItemDirective, selector: "fs-menu-group,[fs-menu-item]" }, { kind: "directive", type: i8.FsMenuTriggerDirective, selector: "[fsMenuTriggerFor]", inputs: ["fsMenuTriggerFor"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
551
591
  }
552
592
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ComponentSettingsComponent, decorators: [{
553
593
  type: Component,
@@ -568,11 +608,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
568
608
  MatLabel,
569
609
  MatSuffix,
570
610
  MatButton,
611
+ MatIcon,
612
+ MatIconButton,
571
613
  MatInput,
572
614
  MatOption,
573
615
  MatSelect,
574
616
  MatSlideToggle,
575
617
  MatTooltip,
576
- ], template: "<form\n fsForm\n [submit]=\"save\">\n <fs-dialog>\n <h1 mat-dialog-title>\n {{ component.title || (isValue() ? 'Value' : 'Component') }}\n </h1>\n <mat-dialog-content>\n <mat-tab-group [(selected)]=\"selectedTab\">\n <mat-tab\n label=\"Settings\"\n name=\"settings\">\n <div class=\"fs-column tab-body\">\n <mat-form-field>\n <mat-label>\n {{ isValue() ? 'Name' : 'Title' }}\n </mat-label>\n <input\n matInput\n [(ngModel)]=\"title\"\n name=\"title\"\n [fsFormRequired]=\"isValue()\">\n </mat-form-field>\n <!-- A formula value is read-only beyond its name: what it works\n out is the AI's to change. A formula this viewer cannot\n read has no line, and no row. -->\n @if (formulaLine()) {\n <fs-label-field>\n <fs-label>\n Formula\n </fs-label>\n {{ formulaLine() }}\n <fs-label-message>\n Worked out on the server; it follows the filters of the values it reads.\n </fs-label-message>\n </fs-label-field>\n }\n <!-- A value sits inside a text block's words: no box, no padding. -->\n @if (!isValue()) {\n <div class=\"subheading-2\">\n Padding\n </div>\n <div class=\"geometry-row\">\n <mat-form-field>\n <mat-label>\n Top\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingTop\"\n name=\"paddingTop\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Right\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingRight\"\n name=\"paddingRight\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Bottom\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingBottom\"\n name=\"paddingBottom\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Left\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingLeft\"\n name=\"paddingLeft\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n </div>\n }\n <!-- A derived KPI's card: what a rise means, a target and a\n sparkline. The server computes the progress and the points. -->\n @if (kpiCard()) {\n <div class=\"subheading-2\">\n Card\n </div>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Increase is\n </mat-label>\n <mat-select\n [ngModel]=\"increaseIs()\"\n (ngModelChange)=\"increaseIs.set($event)\"\n name=\"increaseIs\">\n @for (option of kpiPolarityOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n Colors the change and decides when the target is met.\n </mat-hint>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Target\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"6\"\n [signed]=\"true\"\n [ngModel]=\"targetValue()\"\n (ngModelChange)=\"targetValue.set($event)\"\n name=\"targetValue\"\n [validate]=\"validateTarget\">\n @if (targetPercent()) {\n <div matTextSuffix>\n %\n </div>\n }\n <mat-hint>\n The value to reach. Leave empty for no target.\n </mat-hint>\n </mat-form-field>\n @if (hasTarget()) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Target label\n </mat-label>\n <input\n matInput\n [ngModel]=\"targetLabel()\"\n (ngModelChange)=\"targetLabel.set($event)\"\n name=\"targetLabel\">\n <mat-hint>\n Shown before the target, such as Goal. Empty reads Target.\n </mat-hint>\n </mat-form-field>\n }\n <fs-label-field>\n <mat-slide-toggle\n [ngModel]=\"sparkline()\"\n (ngModelChange)=\"sparkline.set($event)\"\n name=\"sparkline\">\n Sparkline\n </mat-slide-toggle>\n <mat-hint>\n A small trend line of the value over its last periods.\n </mat-hint>\n </fs-label-field>\n @if (sparkline()) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Sparkline period\n </mat-label>\n <mat-select\n [ngModel]=\"sparklineGranularity()\"\n (ngModelChange)=\"sparklineGranularity.set($event)\"\n name=\"sparklineGranularity\">\n @for (option of granularityOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Sparkline periods\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"0\"\n [ngModel]=\"sparklinePeriods()\"\n (ngModelChange)=\"sparklinePeriods.set($event)\"\n name=\"sparklinePeriods\"\n [fsFormRequired]=\"true\"\n [fsFormInteger]=\"true\"\n [fsFormMin]=\"sparklineMinPeriods\"\n [fsFormMax]=\"sparklineMaxPeriods\">\n <mat-hint>\n How many periods the line covers, {{ sparklineMinPeriods }} to {{ sparklineMaxPeriods }}.\n </mat-hint>\n </mat-form-field>\n }\n }\n </div>\n </mat-tab>\n <!-- A formula runs no statement and follows the filters of the values\n it reads, so it has neither a Filters nor an SQL tab. -->\n @if (!isFormula()) {\n <mat-tab\n label=\"Filters\"\n name=\"filters\">\n <div class=\"tab-body\">\n @if (columnsError()) {\n <div class=\"filters-empty error\">\n {{ columnsError() }}\n </div>\n } @else if (rows().length) {\n <!-- Every filterable column. Pick where its control shows: in\n the report bar (every page, or this page only), on this\n component, both, or neither. The interface follows the\n data; a numeric column can be values or a number range.\n A value sits inside text and has no component to show a\n control on, so it gets the report bar column only. -->\n <table class=\"filter-table\">\n <thead>\n <tr>\n <th class=\"filter-col-name\">\n Filter\n </th>\n <th class=\"filter-col-type\">\n Type\n </th>\n <th class=\"filter-col-select\">\n Report bar\n </th>\n @if (!isValue()) {\n <th class=\"filter-col-toggle\">\n This component\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of rows(); track row.column) {\n <tr>\n <td class=\"filter-col-name\">\n {{ row.label }}\n </td>\n <td class=\"filter-col-type\">\n @if (row.typeSelect.show) {\n <mat-form-field\n [subscriptSizing]=\"'dynamic'\"\n [matTooltip]=\"row.typeSelect.tooltip\">\n <mat-select\n [panelWidth]=\"null\"\n [ngModel]=\"row.type\"\n (ngModelChange)=\"setType(row, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"row.typeSelect.disabled\"\n aria-label=\"Type\">\n @for (option of typeOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n } @else {\n {{ typeLabel(row.type) }}\n }\n </td>\n <td class=\"filter-col-select\">\n <mat-form-field [subscriptSizing]=\"'dynamic'\">\n <mat-select\n [panelWidth]=\"null\"\n [ngModel]=\"row.placement\"\n (ngModelChange)=\"setPlacement(row, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n aria-label=\"Report bar\">\n @for (option of row.placementOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </td>\n @if (!isValue()) {\n <td class=\"filter-col-toggle\">\n <mat-slide-toggle\n [ngModel]=\"row.component\"\n (ngModelChange)=\"setComponent(row, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"row.componentToggle.disabled\"\n [matTooltip]=\"row.componentToggle.tooltip\">\n </mat-slide-toggle>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <div class=\"filters-empty\">\n This component has no filterable columns yet \u2014 give it some SQL first.\n </div>\n }\n </div>\n </mat-tab>\n <mat-tab\n label=\"SQL\"\n name=\"sql\">\n <div class=\"tab-body\">\n @if (sqlError()) {\n <div class=\"filters-empty error\">\n {{ sqlError() }}\n </div>\n } @else if (sql()) {\n @if (sqlBaseline()) {\n <!-- A derived component's statement is compiled from its\n document with no viewer state, so it is not byte-for-byte\n what produced the numbers on screen. Said here rather than\n left for the reader to discover. -->\n <div class=\"filters-empty\">\n Compiled from this component's query \u2014 no filters applied, times in {{ sqlTimezone() }}.\n </div>\n }\n <pre class=\"code-block\">{{ sql() }}</pre>\n } @else {\n <div class=\"filters-empty\">\n This component has no SQL yet.\n </div>\n }\n </div>\n </mat-tab>\n }\n <mat-tab\n label=\"Config\"\n name=\"config\">\n <div class=\"tab-body\">\n <pre class=\"code-block\">\n {{ configJson }}\n </pre>\n </div>\n </mat-tab>\n </mat-tab-group>\n </mat-dialog-content>\n <mat-dialog-actions>\n <!-- Save | Delete | Cancel, the standard order. fs-form-dialog-actions\n renders its own Save/Done BEFORE the projected content, which would\n put Delete after Cancel, so `[save]=\"false\"` foots the row here and\n all three buttons are projected in order. Save submits the Settings\n tab; the other tabs persist as you touch them, so they get Done. -->\n <fs-form-dialog-actions [save]=\"false\">\n @if (selectedTab === 'settings') {\n <button\n mat-button\n type=\"submit\"\n color=\"primary\">\n Save\n </button>\n } @else {\n <button\n mat-button\n type=\"button\"\n color=\"primary\"\n [mat-dialog-close]=\"null\">\n Done\n </button>\n }\n <button\n mat-button\n type=\"button\"\n color=\"warn\"\n (click)=\"delete()\">\n Delete\n </button>\n <button\n mat-button\n type=\"button\"\n class=\"cancel-button\"\n [mat-dialog-close]=\"null\">\n Cancel\n </button>\n </fs-form-dialog-actions>\n </mat-dialog-actions>\n </fs-dialog>\n</form>", styles: ["mat-form-field{width:100%}.tab-body{padding-top:16px}.geometry-row{display:flex;gap:8px}.geometry-row mat-form-field{flex:1}.filter-table{border-spacing:0;width:100%;border-collapse:collapse}.filter-table thead th{color:#8f8f8f;font-weight:400;font-size:85%;text-align:left;padding:8px 16px}.filter-table tbody tr{clip-path:xywh(0 3px 100% calc(100% - 6px) round 10px)}.filter-table tbody td{border:none;background-color:#fafafa;padding:8px 16px;vertical-align:middle;text-align:left}.filter-table .filter-col-name{font-weight:600;color:#1f2933}.filter-table .filter-col-type{color:#7b8794;width:150px}.filter-table .filter-col-select{width:160px}.filter-table td.filter-col-type,.filter-table td.filter-col-select{padding-left:8px;padding-right:8px}.filter-table td.filter-col-type mat-form-field,.filter-table td.filter-col-select mat-form-field{width:100%;--mat-form-field-container-height: 36px;--mat-form-field-container-vertical-padding: 6px}.filter-table td.filter-col-type ::ng-deep .mat-mdc-form-field-infix,.filter-table td.filter-col-select ::ng-deep .mat-mdc-form-field-infix{width:auto}.filter-table td.filter-col-type ::ng-deep .mat-mdc-form-field-subscript-wrapper,.filter-table td.filter-col-select ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.filter-table .filter-col-toggle,.filter-table th.filter-col-toggle{width:110px;text-align:center}.filters-empty{font-size:13px;color:#7b8794;padding:8px 0 4px}.filters-empty.error{color:#e15759}.code-block{margin:0;padding:10px 12px;background:#1f2933;color:#e4e7eb;border-radius:6px;font-family:JetBrains Mono,Consolas,monospace;font-size:12px;line-height:1.5;white-space:pre-wrap;word-break:break-word;max-height:240px;overflow:auto}\n"] }]
618
+ FsMenuModule,
619
+ ], template: "<form\n fsForm\n [submit]=\"save\">\n <fs-dialog>\n <h1 mat-dialog-title>\n {{ heading() }}\n </h1>\n <mat-dialog-content>\n <mat-tab-group [(selected)]=\"selectedTab\">\n <mat-tab\n label=\"Settings\"\n name=\"settings\">\n <div class=\"fs-column tab-body\">\n <!-- A value's Name is just its name. A title may carry the page,\n report and filter fields a text block's words do: Insert\n field puts one in at the caret, and the hint says how the\n title reads where the component is drawn. -->\n @if (isValue()) {\n <mat-form-field>\n <mat-label>\n Name\n </mat-label>\n <input\n matInput\n [ngModel]=\"title()\"\n (ngModelChange)=\"title.set($event)\"\n name=\"title\"\n [fsFormRequired]=\"true\">\n </mat-form-field>\n } @else {\n <mat-form-field>\n <mat-label>\n Title\n </mat-label>\n <input\n #titleInput\n matInput\n [ngModel]=\"title()\"\n (ngModelChange)=\"title.set($event)\"\n name=\"title\">\n <!-- The button swallows its own click: the form field would\n otherwise put focus back in the input while the menu is\n open, and a key pressed then would move the caret the\n field goes in at. -->\n <button\n mat-icon-button\n matIconSuffix\n type=\"button\"\n aria-label=\"Insert field\"\n [fsMenuTriggerFor]=\"insertFieldMenu\"\n (click)=\"$event.stopPropagation()\">\n <mat-icon>sell</mat-icon>\n </button>\n @if (titleShownAs()) {\n <mat-hint>\n Shows as: {{ titleShownAs() }}\n </mat-hint>\n }\n </mat-form-field>\n <fs-menu #insertFieldMenu>\n @for (entry of titleFields(); track entry.field) {\n <ng-template\n fs-menu-item\n (click)=\"insertField(entry.field)\">\n {{ entry.name }}\n </ng-template>\n }\n </fs-menu>\n }\n <!-- A formula value is read-only beyond its name: what it works\n out is the AI's to change. A formula this viewer cannot\n read has no line, and no row. -->\n @if (formulaLine()) {\n <fs-label-field>\n <fs-label>\n Formula\n </fs-label>\n {{ formulaLine() }}\n <fs-label-message>\n Worked out on the server; it follows the filters of the values it reads.\n </fs-label-message>\n </fs-label-field>\n }\n <!-- A value sits inside a text block's words: no box, no padding. -->\n @if (!isValue()) {\n <div class=\"subheading-2\">\n Padding\n </div>\n <div class=\"geometry-row\">\n <mat-form-field>\n <mat-label>\n Top\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingTop\"\n name=\"paddingTop\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Right\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingRight\"\n name=\"paddingRight\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Bottom\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingBottom\"\n name=\"paddingBottom\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n <mat-form-field>\n <mat-label>\n Left\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"3\"\n [(ngModel)]=\"paddingLeft\"\n name=\"paddingLeft\"\n [fsFormMin]=\"0\">\n <div matTextSuffix>\n in\n </div>\n </mat-form-field>\n </div>\n }\n <!-- A derived KPI's card: what a rise means, a target and a\n sparkline. The server computes the progress and the points. -->\n @if (kpiCard()) {\n <div class=\"subheading-2\">\n Card\n </div>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Increase is\n </mat-label>\n <mat-select\n [ngModel]=\"increaseIs()\"\n (ngModelChange)=\"increaseIs.set($event)\"\n name=\"increaseIs\">\n @for (option of kpiPolarityOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n Colors the change and decides when the target is met.\n </mat-hint>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Target\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"6\"\n [signed]=\"true\"\n [ngModel]=\"targetValue()\"\n (ngModelChange)=\"targetValue.set($event)\"\n name=\"targetValue\"\n [validate]=\"validateTarget\">\n @if (targetPercent()) {\n <div matTextSuffix>\n %\n </div>\n }\n <mat-hint>\n The value to reach. Leave empty for no target.\n </mat-hint>\n </mat-form-field>\n @if (hasTarget()) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Target label\n </mat-label>\n <input\n matInput\n [ngModel]=\"targetLabel()\"\n (ngModelChange)=\"targetLabel.set($event)\"\n name=\"targetLabel\">\n <mat-hint>\n Shown before the target, such as Goal. Empty reads Target.\n </mat-hint>\n </mat-form-field>\n }\n <fs-label-field>\n <mat-slide-toggle\n [ngModel]=\"sparkline()\"\n (ngModelChange)=\"sparkline.set($event)\"\n name=\"sparkline\">\n Sparkline\n </mat-slide-toggle>\n <mat-hint>\n A small trend line of the value over its last periods.\n </mat-hint>\n </fs-label-field>\n @if (sparkline()) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Sparkline period\n </mat-label>\n <mat-select\n [ngModel]=\"sparklineGranularity()\"\n (ngModelChange)=\"sparklineGranularity.set($event)\"\n name=\"sparklineGranularity\">\n @for (option of granularityOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Sparkline periods\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"0\"\n [ngModel]=\"sparklinePeriods()\"\n (ngModelChange)=\"sparklinePeriods.set($event)\"\n name=\"sparklinePeriods\"\n [fsFormRequired]=\"true\"\n [fsFormInteger]=\"true\"\n [fsFormMin]=\"sparklineMinPeriods\"\n [fsFormMax]=\"sparklineMaxPeriods\">\n <mat-hint>\n How many periods the line covers, {{ sparklineMinPeriods }} to {{ sparklineMaxPeriods }}.\n </mat-hint>\n </mat-form-field>\n }\n }\n </div>\n </mat-tab>\n <!-- A formula runs no statement and follows the filters of the values\n it reads, so it has neither a Filters nor an SQL tab. -->\n @if (!isFormula()) {\n <mat-tab\n label=\"Filters\"\n name=\"filters\">\n <div class=\"tab-body\">\n @if (columnsError()) {\n <div class=\"filters-empty error\">\n {{ columnsError() }}\n </div>\n } @else if (rows().length) {\n <!-- Every filterable column. Pick where its control shows: in\n the report bar (every page, or this page only), on this\n component, both, or neither. The interface follows the\n data; a numeric column can be values or a number range.\n A value sits inside text and has no component to show a\n control on, so it gets the report bar column only. -->\n <table class=\"filter-table\">\n <thead>\n <tr>\n <th class=\"filter-col-name\">\n Filter\n </th>\n <th class=\"filter-col-type\">\n Type\n </th>\n <th class=\"filter-col-select\">\n Report bar\n </th>\n @if (!isValue()) {\n <th class=\"filter-col-toggle\">\n This component\n </th>\n }\n </tr>\n </thead>\n <tbody>\n @for (row of rows(); track row.column) {\n <tr>\n <td class=\"filter-col-name\">\n {{ row.label }}\n </td>\n <td class=\"filter-col-type\">\n @if (row.typeSelect.show) {\n <mat-form-field\n [subscriptSizing]=\"'dynamic'\"\n [matTooltip]=\"row.typeSelect.tooltip\">\n <mat-select\n [panelWidth]=\"null\"\n [ngModel]=\"row.type\"\n (ngModelChange)=\"setType(row, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"row.typeSelect.disabled\"\n aria-label=\"Type\">\n @for (option of typeOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n } @else {\n {{ typeLabel(row.type) }}\n }\n </td>\n <td class=\"filter-col-select\">\n <mat-form-field [subscriptSizing]=\"'dynamic'\">\n <mat-select\n [panelWidth]=\"null\"\n [ngModel]=\"row.placement\"\n (ngModelChange)=\"setPlacement(row, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n aria-label=\"Report bar\">\n @for (option of row.placementOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n </td>\n @if (!isValue()) {\n <td class=\"filter-col-toggle\">\n <mat-slide-toggle\n [ngModel]=\"row.component\"\n (ngModelChange)=\"setComponent(row, $event)\"\n [ngModelOptions]=\"{ standalone: true }\"\n [disabled]=\"row.componentToggle.disabled\"\n [matTooltip]=\"row.componentToggle.tooltip\">\n </mat-slide-toggle>\n </td>\n }\n </tr>\n }\n </tbody>\n </table>\n } @else {\n <div class=\"filters-empty\">\n This component has no filterable columns yet \u2014 give it some SQL first.\n </div>\n }\n </div>\n </mat-tab>\n <mat-tab\n label=\"SQL\"\n name=\"sql\">\n <div class=\"tab-body\">\n @if (sqlError()) {\n <div class=\"filters-empty error\">\n {{ sqlError() }}\n </div>\n } @else if (sql()) {\n @if (sqlBaseline()) {\n <!-- A derived component's statement is compiled from its\n document with no viewer state, so it is not byte-for-byte\n what produced the numbers on screen. Said here rather than\n left for the reader to discover. -->\n <div class=\"filters-empty\">\n Compiled from this component's query \u2014 no filters applied, times in {{ sqlTimezone() }}.\n </div>\n }\n <pre class=\"code-block\">{{ sql() }}</pre>\n } @else {\n <div class=\"filters-empty\">\n This component has no SQL yet.\n </div>\n }\n </div>\n </mat-tab>\n }\n <mat-tab\n label=\"Config\"\n name=\"config\">\n <div class=\"tab-body\">\n <pre class=\"code-block\">\n {{ configJson }}\n </pre>\n </div>\n </mat-tab>\n </mat-tab-group>\n </mat-dialog-content>\n <mat-dialog-actions>\n <!-- Save | Delete | Cancel, the standard order. fs-form-dialog-actions\n renders its own Save/Done BEFORE the projected content, which would\n put Delete after Cancel, so `[save]=\"false\"` foots the row here and\n all three buttons are projected in order. Save submits the Settings\n tab; the other tabs persist as you touch them, so they get Done. -->\n <fs-form-dialog-actions [save]=\"false\">\n @if (selectedTab === 'settings') {\n <button\n mat-button\n type=\"submit\"\n color=\"primary\">\n Save\n </button>\n } @else {\n <button\n mat-button\n type=\"button\"\n color=\"primary\"\n [mat-dialog-close]=\"null\">\n Done\n </button>\n }\n <button\n mat-button\n type=\"button\"\n color=\"warn\"\n (click)=\"delete()\">\n Delete\n </button>\n <button\n mat-button\n type=\"button\"\n class=\"cancel-button\"\n [mat-dialog-close]=\"null\">\n Cancel\n </button>\n </fs-form-dialog-actions>\n </mat-dialog-actions>\n </fs-dialog>\n</form>", styles: ["mat-form-field{width:100%}.tab-body{padding-top:16px}.geometry-row{display:flex;gap:8px}.geometry-row mat-form-field{flex:1}.filter-table{border-spacing:0;width:100%;border-collapse:collapse}.filter-table thead th{color:#8f8f8f;font-weight:400;font-size:85%;text-align:left;padding:8px 16px}.filter-table tbody tr{clip-path:xywh(0 3px 100% calc(100% - 6px) round 10px)}.filter-table tbody td{border:none;background-color:#fafafa;padding:8px 16px;vertical-align:middle;text-align:left}.filter-table .filter-col-name{font-weight:600;color:#1f2933}.filter-table .filter-col-type{color:#7b8794;width:150px}.filter-table .filter-col-select{width:160px}.filter-table td.filter-col-type,.filter-table td.filter-col-select{padding-left:8px;padding-right:8px}.filter-table td.filter-col-type mat-form-field,.filter-table td.filter-col-select mat-form-field{width:100%;--mat-form-field-container-height: 36px;--mat-form-field-container-vertical-padding: 6px}.filter-table td.filter-col-type ::ng-deep .mat-mdc-form-field-infix,.filter-table td.filter-col-select ::ng-deep .mat-mdc-form-field-infix{width:auto}.filter-table td.filter-col-type ::ng-deep .mat-mdc-form-field-subscript-wrapper,.filter-table td.filter-col-select ::ng-deep .mat-mdc-form-field-subscript-wrapper{display:none}.filter-table .filter-col-toggle,.filter-table th.filter-col-toggle{width:110px;text-align:center}.filters-empty{font-size:13px;color:#7b8794;padding:8px 0 4px}.filters-empty.error{color:#e15759}.code-block{margin:0;padding:10px 12px;background:#1f2933;color:#e4e7eb;border-radius:6px;font-family:JetBrains Mono,Consolas,monospace;font-size:12px;line-height:1.5;white-space:pre-wrap;word-break:break-word;max-height:240px;overflow:auto}\n"] }]
577
620
  }] });
578
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9uZW50LXNldHRpbmdzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy9kaWFsb2dzL2NvbXBvbmVudC1zZXR0aW5ncy9jb21wb25lbnQtc2V0dGluZ3MuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2RpYWxvZ3MvY29tcG9uZW50LXNldHRpbmdzL2NvbXBvbmVudC1zZXR0aW5ncy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQVUsUUFBUSxFQUFFLE1BQU0sRUFBRSxNQUFNLEdBQy9GLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ2hFLE9BQU8sRUFBbUIsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFOUQsT0FBTyxFQUFFLGVBQWUsRUFBRSxnQkFBZ0IsRUFBRSxjQUFjLEVBQUUsZ0JBQWdCLEVBQUUsWUFBWSxFQUFFLGNBQWMsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzdJLE9BQU8sRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUMxRixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDckQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ25ELE9BQU8sRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDaEUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ2hFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN2RCxPQUFPLEVBQUUs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QUFFO2FBQ04sT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDLFNBQVMsRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7SUFDOUQsQ0FBQzt3R0F0aUJVLDBCQUEwQjs0RkFBMUIsMEJBQTBCLHdFQ2pMdkMseW5mQThZTywydUREcFBILFdBQVcsdWlDQUNYLFlBQVksNjZEQUNaLFlBQVksaUhBQ1osY0FBYyxnTUFDZCxhQUFhLHNXQUNiLFlBQVksbWFBQ1osYUFBYSw2b0JBQ2IsY0FBYywrSEFDZCxnQkFBZ0IseUdBQ2hCLGdCQUFnQiw0SEFDaEIsY0FBYyxxTEFDZCxZQUFZLDRMQUNaLE9BQU8sOEVBQ1AsUUFBUSxzREFDUixTQUFTLHFIQUNULFNBQVMsaUxBQ1QsUUFBUSxpVUFDUixTQUFTLHFKQUNULFNBQVMsd2VBQ1QsY0FBYywwVUFDZCxVQUFVOzs0RkFHRCwwQkFBMEI7a0JBN0J0QyxTQUFTO3NDQUdTLHVCQUF1QixDQUFDLE1BQU0sY0FDbkMsSUFBSSxXQUNQO3dCQUNQLFdBQVc7d0JBQ1gsWUFBWTt3QkFDWixZQUFZO3dCQUNaLGNBQWM7d0JBQ2QsYUFBYTt3QkFDYixZQUFZO3dCQUNaLGFBQWE7d0JBQ2IsY0FBYzt3QkFDZCxnQkFBZ0I7d0JBQ2hCLGdCQUFnQjt3QkFDaEIsY0FBYzt3QkFDZCxZQUFZO3dCQUNaLE9BQU87d0JBQ1AsUUFBUTt3QkFDUixTQUFTO3dCQUNULFNBQVM7d0JBQ1QsUUFBUTt3QkFDUixTQUFTO3dCQUNULFNBQVM7d0JBQ1QsY0FBYzt3QkFDZCxVQUFVO3FCQUNYIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgRGVzdHJveVJlZiwgRXZlbnRFbWl0dGVyLCBPbkluaXQsIGNvbXB1dGVkLCBpbmplY3QsIHNpZ25hbCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyB0YWtlVW50aWxEZXN0cm95ZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5pbXBvcnQgeyBBYnN0cmFjdENvbnRyb2wsIEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5pbXBvcnQgeyBNQVRfRElBTE9HX0RBVEEsIE1hdERpYWxvZ0FjdGlvbnMsIE1hdERpYWxvZ0Nsb3NlLCBNYXREaWFsb2dDb250ZW50LCBNYXREaWFsb2dSZWYsIE1hdERpYWxvZ1RpdGxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcbmltcG9ydCB7IE1hdEZvcm1GaWVsZCwgTWF0SGludCwgTWF0TGFiZWwsIE1hdFN1ZmZpeCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2Zvcm0tZmllbGQnO1xuaW1wb3J0IHsgTWF0QnV0dG9uIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvYnV0dG9uJztcbmltcG9ydCB7IE1hdElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaW5wdXQnO1xuaW1wb3J0IHsgTWF0T3B0aW9uLCBNYXRTZWxlY3QgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zZWxlY3QnO1xuaW1wb3J0IHsgTWF0U2xpZGVUb2dnbGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zbGlkZS10b2dnbGUnO1xuaW1wb3J0IHsgTWF0VGFic01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3RhYnMnO1xuaW1wb3J0IHsgTWF0VG9vbHRpcCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3Rvb2x0aXAnO1xuXG5pbXBvcnQgeyBGc0RpYWxvZ01vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL2RpYWxvZyc7XG5pbXBvcnQgeyBGc0Zvcm1Nb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9mb3JtJztcbmltcG9ydCB7IEZzTGFiZWxNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9sYWJlbCc7XG5pbXBvcnQgeyBGc01hc2tNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9tYXNrJztcbmltcG9ydCB7IEZzTWVzc2FnZSB9IGZyb20gJ0BmaXJlc3RpdGNoL21lc3NhZ2UnO1xuaW1wb3J0IHsgRnNQcm9tcHQgfSBmcm9tICdAZmlyZXN0aXRjaC9wcm9tcHQnO1xuaW1wb3J0IHsgRnNUYWJzTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvdGFicyc7XG5cbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHN3aXRjaE1hcCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBSZXBvcnREYXRhIH0gZnJvbSAnLi4vLi4vZGF0YS9yZXBvcnQuZGF0YSc7XG5pbXBvcnQgeyBSZXBvcnRDaGFuZ2VQb2xhcml0eSB9IGZyb20gJy4uLy4uL2VudW1zL3JlcG9ydC1jaGFuZ2UtcG9sYXJpdHkuZW51bSc7XG5pbXBvcnQgeyBSZXBvcnRWYWx1ZUZvcm1hdCB9IGZyb20gJy4uLy4uL2VudW1zL3JlcG9ydC12YWx1ZS1mb3JtYXQuZW51bSc7XG5pbXBvcnQgeyBSZXBvcnRWYWx1ZUZvcm11bGEgfSBmcm9tICcuLi8uLi9lbnVtcy9yZXBvcnQtdmFsdWUtZm9ybXVsYS5lbnVtJztcbmltcG9ydCB7IHJlc29sdmVGb3JtYXRDb250ZXh0IH0gZnJvbSAnLi4vLi4vZm9ybWF0JztcbmltcG9ydCB7XG4gIEtQSV9TUEFSS0xJTkVfREVGQVVMVF9HUkFOVUxBUklUWSxcbiAgS1BJX1NQQVJLTElORV9ERUZBVUxUX1BFUklPRFMsXG4gIGtwaUNhcmRTZXR0aW5ncyxcbiAgc2FtZUtwaUNhcmRTZXR0aW5ncyxcbn0gZnJvbSAnLi4vLi4va3BpLWNhcmQnO1xuaW1wb3J0IHtcbiAgQ2hhcnRHcmFudWxhcml0eSxcbiAgQ29tcG9uZW50U2V0dGluZ3MsXG4gIEdSQU5VTEFSSVRZX09QVElPTlMsXG4gIEtwaUNhcmRTZXR0aW5ncyxcbiAgS3BpQ29uZmlnLFxuICBSZXBvcnQsXG4gIFJlcG9ydENvbXBvbmVudCxcbiAgUmVwb3J0Q29tcG9uZW50U3FsLFxuICBSZXBvcnRGaWx0ZXIsXG4gIFJlcG9ydEZpbHRlckdyb3VwLFxuICBSZXBvcnRGaWx0ZXJMZXZlbCxcbiAgUmVwb3J0RmlsdGVyVHlwZSxcbiAgUmVwb3J0RmlsdGVyYWJsZUNvbHVtbixcbn0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9yZXBvcnQuaW50ZXJmYWNlJztcbmltcG9ydCB7IERFRkFVTFRfQ09NUE9ORU5UX1BBRERJTkcgfSBmcm9tICcuLi8uLi9sYXlvdXQnO1xuaW1wb3J0IHtcbiAgRklMVEVSX1RZUEVfT1BUSU9OUyxcbiAgYmFyUGxhY2VtZW50LFxuICBiYXJQbGFjZW1lbnRPcHRpb25zLFxuICBjb21wb25lbnRUb2dnbGVTdGF0ZSxcbiAgZmlsdGVyTGV2ZWwsXG4gIGZpbHRlckxldmVsQ2hvaWNlcyxcbiAgc2hvd25PbkNvbXBvbmVudCxcbiAgdHlwZVNlbGVjdFN0YXRlLFxuICB2YWx1ZUZpbHRlckxldmVsLFxuICB2YWx1ZVBsYWNlbWVudE9wdGlvbnMsXG59IGZyb20gJy4uLy4uL2ZpbHRlci1zZXR0aW5ncy1ydWxlcyc7XG5pbXBvcnQgeyBGaWx0ZXJCYXJQbGFjZW1lbnQgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL2ZpbHRlci1iYXItcGxhY2VtZW50LnR5cGUnO1xuaW1wb3J0IHsgRmlsdGVyQ29tcG9uZW50VG9nZ2xlU3RhdGUgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL2ZpbHRlci1jb21wb25lbnQtdG9nZ2xlLXN0YXRlLmludGVyZmFjZSc7XG5pbXBvcnQgeyBGaWx0ZXJTZXR0aW5nc09wdGlvbiB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvZmlsdGVyLXNldHRpbmdzLW9wdGlvbi5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgRmlsdGVyVHlwZVNlbGVjdFN0YXRlIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9maWx0ZXItdHlwZS1zZWxlY3Qtc3RhdGUuaW50ZXJmYWNlJztcbmltcG9ydCB7IGVzY2FwZUh0bWwgfSBmcm9tICcuLi8uLi90ZXh0JztcbmltcG9ydCB7IG9wZXJhbmRLZXlzLCByZXBvcnRDb21wb25lbnRzLCB2YWx1ZUtleSB9IGZyb20gJy4uLy4uL3ZhbHVlcyc7XG5cblxuLy8gV2hhdCB0aGUgZGlhbG9nIGhhbmRzIGJhY2suIFRoZSBTZXR0aW5ncyB0YWIncyBTYXZlIGNhcnJpZXMgdGhlIG5ld1xuLy8gYHNldHRpbmdzYDsgRGVsZXRlIGNhcnJpZXMgYGRlbGV0ZWRgIGFuZCBubyBzZXR0aW5ncywgYmVjYXVzZSB0aGUgY29tcG9uZW50XG4vLyBpdCB3YXMgb3BlbmVkIGZvciBubyBsb25nZXIgZXhpc3RzLiBFdmVyeSBvdGhlciBleGl0IChDYW5jZWwsIERvbmUsIEVzY2FwZSxcbi8vIGJhY2tkcm9wKSBjbG9zZXMgd2l0aCBubyByZXN1bHQg4oCUIGZpbHRlciB3b3JrIGlzIGFubm91bmNlZCBhcyBpdCBoYXBwZW5zXG4vLyBpbnN0ZWFkLCB0aHJvdWdoIGBmaWx0ZXJzQ2hhbmdlZGAuXG5leHBvcnQgaW50ZXJmYWNlIENvbXBvbmVudFNldHRpbmdzUmVzdWx0IHtcbiAgc2V0dGluZ3M/OiBDb21wb25lbnRTZXR0aW5ncztcbiAgZGVsZXRlZD86IGJvb2xlYW47XG59XG5cbi8vIFdoYXQgdGhlIHNldHRpbmdzIGVuZHBvaW50IHJldHVybnMgZm9yIHRoZSBjb21wb25lbnQ6IGl0cyBpZCBhbmQsIGZyb20gYVxuLy8gc2VydmVyIHRoYXQgc2F2ZXMgYSBLUEkncyBjYXJkIGtleXMsIHRoZSB3aG9sZSBjb25maWcgYXMgc2F2ZWQuXG5pbnRlcmZhY2UgQ29tcG9uZW50U2V0dGluZ3NSZXNwb25zZSB7XG4gIGlkOiBudW1iZXI7XG4gIGNvbmZpZz86IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHwgbnVsbDtcbn1cblxuXG4vLyBXaGF0IGEgcmlzZSBpbiBhIEtQSSdzIHZhbHVlIG1lYW5zLCBmb3IgdGhlIEluY3JlYXNlIGlzIHNlbGVjdC5cbmNvbnN0IEtQSV9DSEFOR0VfUE9MQVJJVFlfT1BUSU9OUzogeyB2YWx1ZTogUmVwb3J0Q2hhbmdlUG9sYXJpdHk7IG5hbWU6IHN0cmluZyB9W10gPSBbXG4gIHsgdmFsdWU6IFJlcG9ydENoYW5nZVBvbGFyaXR5Lkdvb2QsIG5hbWU6ICdHb29kIG5ld3Mg4oCUIGEgcmlzZSBzaG93cyBncmVlbicgfSxcbiAgeyB2YWx1ZTogUmVwb3J0Q2hhbmdlUG9sYXJpdHkuQmFkLCBuYW1lOiAnQmFkIG5ld3Mg4oCUIGEgcmlzZSBzaG93cyByZWQnIH0sXG4gIHsgdmFsdWU6IFJlcG9ydENoYW5nZVBvbGFyaXR5Lk5ldXRyYWwsIG5hbWU6ICdOZWl0aGVyIOKAlCBubyBjb2xvcicgfSxcbl07XG5cbi8vIEEgS1BJIHNwYXJrbGluZSdzIHBlcmlvZHMgc3RheSB3aXRoaW4gMiB0byA2MC5cbmNvbnN0IEtQSV9TUEFSS0xJTkVfTUlOX1BFUklPRFMgPSAyO1xuY29uc3QgS1BJX1NQQVJLTElORV9NQVhfUEVSSU9EUyA9IDYwO1xuXG4vLyBBIHBlcmNlbnQgS1BJJ3MgdGFyZ2V0IGlzIGVudGVyZWQgYXMgdGhlIHBlcmNlbnQgc2hvd24gKDE1IGZvciAxNSUpIGFuZFxuLy8gc3RvcmVkIGFzIHRoZSAwLTEgcmF0aW8gaXRzIHZhbHVlIGFycml2ZXMgaW47IHRoZSBzZXJ2ZXIgcmVmdXNlcyBhIHN0b3JlZFxuLy8gdGFyZ2V0IGFib3ZlIDEwMCwgd2hpY2ggaXMgMTAsMDAwJSBoZXJlLlxuY29uc3QgS1BJX1BFUkNFTlRfVEFSR0VUX01BWCA9IDEwMDAwO1xuXG4vLyBIb3cgYSBmb3JtdWxhIHZhbHVlJ3MgU2V0dGluZ3MgdGFiIHdyaXRlcyBvdXQgd2hhdCBpdCB3b3JrcyBvdXQsIGluIGl0c1xuLy8gb3BlcmFuZHMnIG5hbWVzLlxuY29uc3QgRk9STVVMQV9MSU5FUzogUmVjb3JkPFJlcG9ydFZhbHVlRm9ybXVsYSwgKG5hbWVzOiBzdHJpbmdbXSkgPT4gc3RyaW5nPiA9IHtcbiAgW1JlcG9ydFZhbHVlRm9ybXVsYS5DaGFuZ2VdOiAobmFtZXMpID0+IG5hbWVzLmpvaW4oJyDiiJIgJyksXG4gIFtSZXBvcnRWYWx1ZUZvcm11bGEuUGVyY2VudENoYW5nZV06IChbYSwgYl0pID0+IGAlIGNoYW5nZSBvZiAke2F9IG92ZXIgJHtifWAsXG4gIFtSZXBvcnRWYWx1ZUZvcm11bGEuUmF0aW9dOiAobmFtZXMpID0+IG5hbWVzLmpvaW4oJyDDtyAnKSxcbiAgW1JlcG9ydFZhbHVlRm9ybXVsYS5TdW1dOiAobmFtZXMpID0+IG5hbWVzLmpvaW4oJyArICcpLFxufTtcblxuXG4vLyBPbmUgcm93IG9mIHRoZSBGaWx0ZXJzIHRhYiBsaXN0aW5nOiBhIGZpbHRlcmFibGUgY29sdW1uLCBpdHMgZmlsdGVyJ3MgdHlwZVxuLy8gKHRoZSBpbmZlcnJlZCBvbmUsIHRoZSBvbmUgcGlja2VkLCBvciB0aGUgZmlsdGVyJ3Mgb3duKSwgYW5kIHdoZXJlIGl0c1xuLy8gZmlsdGVyIHNob3dzICh0aGUgUmVwb3J0IGJhciBzZWxlY3QgYW5kIHRoZSBUaGlzIGNvbXBvbmVudCB0b2dnbGUpLlxuaW50ZXJmYWNlIEZpbHRlclJvdyB7XG4gIGNvbHVtbjogc3RyaW5nO1xuICB0eXBlOiBSZXBvcnRGaWx0ZXJUeXBlO1xuICBsYWJlbDogc3RyaW5nO1xuICBwbGFjZW1lbnQ6IEZpbHRlckJhclBsYWNlbWVudDtcbiAgY29tcG9uZW50OiBib29sZWFuO1xuICB0eXBlU2VsZWN0OiBGaWx0ZXJUeXBlU2VsZWN0U3RhdGU7XG4gIHBsYWNlbWVudE9wdGlvbnM6IEZpbHRlclNldHRpbmdzT3B0aW9uPEZpbHRlckJhclBsYWNlbWVudD5bXTtcbiAgY29tcG9uZW50VG9nZ2xlOiBGaWx0ZXJDb21wb25lbnRUb2dnbGVTdGF0ZTtcbn1cblxuXG4vLyBDb21wb25lbnQgc2V0dGluZ3MsIGluIHRhYnM6XG4vLyAgIFNldHRpbmdzIOKAlCB0aXRsZSBhbmQgY29udGVudCBwYWRkaW5nIChhIHZhbHVlOiBqdXN0IGl0cyBuYW1lLCBzaW5jZSBpdFxuLy8gICBzaXRzIGluc2lkZSBhIHRleHQgYmxvY2sncyB3b3JkcyBhbmQgaGFzIG5vIGJveCksIGFuZCBvbiBhIGRlcml2ZWQgS1BJIGl0cyBjYXJkOlxuLy8gICB3aGF0IGEgcmlzZSBtZWFucywgYSB0YXJnZXQgYW5kIGEgc3BhcmtsaW5lIChudW1iZXIgZm9ybWF0cyBzdGF5IHdpdGhcbi8vICAgdGhlIEFJKS4gUG9zaXRpb24vc2l6ZSBhcmUgdHVuZWQgYnkgZHJhZ2dpbmcgb24gdGhlIGNhbnZhczsgaGVpZ2h0XG4vLyAgIGJlaGF2aW91ciBmb2xsb3dzIGZyb20gdGhlIGNvbXBvbmVudCB0eXBlLlxuLy8gICBGaWx0ZXJzICDigJQgT05FIGxpc3Rpbmcgb2YgZXZlcnkgZmlsdGVyYWJsZSBjb2x1bW4gb24gdGhpcyBjb21wb25lbnQuIEVhY2hcbi8vICAgcm93IGNhcnJpZXMgdHdvIHRvZ2dsZXM6IHNob3cgaW4gdGhlIHJlcG9ydCBiYXIgYW5kL29yIHNob3cgb24gdGhpc1xuLy8gICBjb21wb25lbnQgKGJvdGgsIGVpdGhlciwgb3IgbmVpdGhlcikuIFRoZSBpbnRlcmZhY2UgKGRhdGUgcmFuZ2UgdnMgdmFsdWVcbi8vICAgcGlja2VyKSBpcyBpbmZlcnJlZCBmcm9tIHRoZSBkYXRhLCBuZXZlciBjaG9zZW4uIEVhY2ggdG9nZ2xlIHBlcnNpc3RzXG4vLyAgIGltbWVkaWF0ZWx5IGFuZCByZWZyZXNoZXMgdGhlIGluLWRpYWxvZyBsaXN0LiBBIHZhbHVlIGhhcyBubyBjb21wb25lbnRcbi8vICAgdG8gc2hvdyBhIGZpbHRlciBvbiwgc28gaXQgZ2V0cyB0aGUgcmVwb3J0IGJhciB0b2dnbGUgb25seS5cbi8vICAgU1FMIC8gQ29uZmlnIOKAlCByZWFkLW9ubHkgZGlhZ25vc3RpY3MuXG4vLyBBIGZvcm11bGEgdmFsdWUgaGFzIG5vIEZpbHRlcnMgb3IgU1FMIHRhYjogdGhlIHNlcnZlciB3b3JrcyBpdCBvdXQgb2Ygb3RoZXJcbi8vIHZhbHVlcyBvbiBpdHMgcGFnZSwgc28gaXQgcnVucyBubyBzdGF0ZW1lbnQgYW5kIGZvbGxvd3MgdGhlIGZpbHRlcnMgb2YgdGhlXG4vLyB2YWx1ZXMgaXQgcmVhZHMuIEl0cyBTZXR0aW5ncyB0YWIgc2F5cyB3aGF0IGl0IHdvcmtzIG91dCwgdW5kZXIgaXRzIG5hbWUuXG5AQ29tcG9uZW50KHtcbiAgdGVtcGxhdGVVcmw6ICcuL2NvbXBvbmVudC1zZXR0aW5ncy5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL2NvbXBvbmVudC1zZXR0aW5ncy5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIEZvcm1zTW9kdWxlLFxuICAgIEZzRm9ybU1vZHVsZSxcbiAgICBGc01hc2tNb2R1bGUsXG4gICAgRnNEaWFsb2dNb2R1bGUsXG4gICAgRnNMYWJlbE1vZHVsZSxcbiAgICBGc1RhYnNNb2R1bGUsXG4gICAgTWF0VGFic01vZHVsZSxcbiAgICBNYXREaWFsb2dUaXRsZSxcbiAgICBNYXREaWFsb2dDb250ZW50LFxuICAgIE1hdERpYWxvZ0FjdGlvbnMsXG4gICAgTWF0RGlhbG9nQ2xvc2UsXG4gICAgTWF0Rm9ybUZpZWxkLFxuICAgIE1hdEhpbnQsXG4gICAgTWF0TGFiZWwsXG4gICAgTWF0U3VmZml4LFxuICAgIE1hdEJ1dHRvbixcbiAgICBNYXRJbnB1dCxcbiAgICBNYXRPcHRpb24sXG4gICAgTWF0U2VsZWN0LFxuICAgIE1hdFNsaWRlVG9nZ2xlLFxuICAgIE1hdFRvb2x0aXAsXG4gIF0sXG59KVxuZXhwb3J0IGNsYXNzIENvbXBvbmVudFNldHRpbmdzQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcblxuICAvLyBBIGZpbHRlciB3YXMgYWRkZWQsIHJlbW92ZWQgb3IgcmUtbGV2ZWxsZWQsIHNvIHRoZSByZXBvcnQncyBmaWx0ZXIgZ3JvdXBzXG4gIC8vIGNoYW5nZWQuIFRob3NlIG11dGF0aW9ucyBwZXJzaXN0IHRoZSBtb21lbnQgdGhleSBhcmUgY2xpY2tlZCBhbmQgdGhlIGRpYWxvZ1xuICAvLyBjYW4gdGhlbiBiZSBkaXNtaXNzZWQgYnkgYSByb3V0ZSB0aGF0IGNhcnJpZXMgbm8gcmVzdWx0IChFc2NhcGUsIGJhY2tkcm9wKSxcbiAgLy8gc28gdGhlIHBhZ2UgaXMgdG9sZCBoZXJlIHJhdGhlciB0aGFuIHRocm91Z2ggdGhlIGNsb3NlIHJlc3VsdC5cbiAgcHVibGljIHJlYWRvbmx5IGZpbHRlcnNDaGFuZ2VkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIHB1YmxpYyBjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudDtcbiAgcHVibGljIHJlcG9ydDogUmVwb3J0O1xuXG4gIHB1YmxpYyBzZWxlY3RlZFRhYiA9ICdzZXR0aW5ncyc7XG5cbiAgcHVibGljIHRpdGxlID0gJyc7XG5cbiAgLy8gQ29tcG9uZW50IHBhZGRpbmcgaW4gaW5jaGVzLiBgbnVtYmVyIHwgc3RyaW5nYCBmb3IgdGhlIHNhbWUgcmVhc29uIGFzIHRoZVxuICAvLyBwYWdlIGRpbWVuc2lvbnMgaW4gcmVwb3J0LXNldHRpbmdzOiBmc01hc2tOdW1iZXIgc2VlZHMgZnJvbSB0aGUgbnVtYmVyIGJ1dFxuICAvLyBoYW5kcyBiYWNrIHRoZSB1bm1hc2tlZCBzdHJpbmcsIGFuZCBzYXZlIGNhc3RzIGl0IG9uY2Ugb24gdGhlIHdheSBvdXQuXG4gIHB1YmxpYyBwYWRkaW5nVG9wOiBudW1iZXIgfCBzdHJpbmcgPSBERUZBVUxUX0NPTVBPTkVOVF9QQURESU5HO1xuICBwdWJsaWMgcGFkZGluZ1JpZ2h0OiBudW1iZXIgfCBzdHJpbmcgPSBERUZBVUxUX0NPTVBPTkVOVF9QQURESU5HO1xuICBwdWJsaWMgcGFkZGluZ0JvdHRvbTogbnVtYmVyIHwgc3RyaW5nID0gREVGQVVMVF9DT01QT05FTlRfUEFERElORztcbiAgcHVibGljIHBhZGRpbmdMZWZ0OiBudW1iZXIgfCBzdHJpbmcgPSBERUZBVUxUX0NPTVBPTkVOVF9QQURESU5HO1xuXG4gIHB1YmxpYyBjb25maWdKc29uID0gJyc7XG5cbiAgLy8gLS0tLSBLUEkgY2FyZCBzdGF0ZSAoYSBkZXJpdmVkIEtQSSBvbmx5KSAtLS0tXG4gIHB1YmxpYyByZWFkb25seSBrcGlQb2xhcml0eU9wdGlvbnMgPSBLUElfQ0hBTkdFX1BPTEFSSVRZX09QVElPTlM7XG4gIHB1YmxpYyByZWFkb25seSBncmFudWxhcml0eU9wdGlvbnMgPSBHUkFOVUxBUklUWV9PUFRJT05TO1xuICBwdWJsaWMgcmVhZG9ubHkgc3BhcmtsaW5lTWluUGVyaW9kcyA9IEtQSV9TUEFSS0xJTkVfTUlOX1BFUklPRFM7XG4gIHB1YmxpYyByZWFkb25seSBzcGFya2xpbmVNYXhQZXJpb2RzID0gS1BJX1NQQVJLTElORV9NQVhfUEVSSU9EUztcbiAgcHVibGljIHJlYWRvbmx5IGtwaUNhcmQgPSBzaWduYWwoZmFsc2UpO1xuICAvLyBBIHZhbHVlIGluc2lkZSBhIHRleHQgYmxvY2s6IG5vIGJveCwgc28gbm8gcGFkZGluZy5cbiAgcHVibGljIHJlYWRvbmx5IGlzVmFsdWUgPSBzaWduYWwoZmFsc2UpO1xuICAvLyBBIGZvcm11bGEgdmFsdWU6IG5vIHN0YXRlbWVudCwgY29sdW1ucyBvciBmaWx0ZXJzIG9mIGl0cyBvd24uXG4gIHB1YmxpYyByZWFkb25seSBpc0Zvcm11bGEgPSBzaWduYWwoZmFsc2UpO1xuICAvLyBXaGF0IGEgZm9ybXVsYSB3b3JrcyBvdXQsIGluIGl0cyBvcGVyYW5kcycgbmFtZXM7IGVtcHR5IGZvciBhbnkgb3RoZXJcbiAgLy8gY29tcG9uZW50LlxuICBwdWJsaWMgcmVhZG9ubHkgZm9ybXVsYUxpbmUgPSBjb21wdXRlZCgoKSA9PiAodGhpcy5pc0Zvcm11bGEoKSA/IHRoaXMuX2Zvcm11bGFMaW5lKCkgOiAnJykpO1xuICBwdWJsaWMgcmVhZG9ubHkgaW5jcmVhc2VJcyA9IHNpZ25hbDxSZXBvcnRDaGFuZ2VQb2xhcml0eT4oUmVwb3J0Q2hhbmdlUG9sYXJpdHkuR29vZCk7XG4gIC8vIFRoZSB0YXJnZXQgYXMgdHlwZWQ6IGZzTWFza051bWJlciBoYW5kcyBiYWNrIHRoZSB1bm1hc2tlZCBzdHJpbmcuIEVtcHR5XG4gIC8vIG1lYW5zIG5vIHRhcmdldC4gQSBwZXJjZW50IEtQSSdzIGlzIGluIHBlcmNlbnQgKHRhcmdldFBlcmNlbnQpLlxuICBwdWJsaWMgcmVhZG9ubHkgdGFyZ2V0VmFsdWUgPSBzaWduYWw8bnVtYmVyIHwgc3RyaW5nIHwgbnVsbD4obnVsbCk7XG4gIHB1YmxpYyByZWFkb25seSB0YXJnZXRMYWJlbCA9IHNpZ25hbCgnJyk7XG4gIHB1YmxpYyByZWFkb25seSB0YXJnZXRQZXJjZW50ID0gc2lnbmFsKGZhbHNlKTtcbiAgcHVibGljIHJlYWRvbmx5IGhhc1RhcmdldCA9IGNvbXB1dGVkKCgpID0+IHRoaXMuX251bWJlcih0aGlzLnRhcmdldFZhbHVlKCkpICE9PSBudWxsKTtcbiAgcHVibGljIHJlYWRvbmx5IHNwYXJrbGluZSA9IHNpZ25hbChmYWxzZSk7XG4gIHB1YmxpYyByZWFkb25seSBzcGFya2xpbmVHcmFudWxhcml0eSA9IHNpZ25hbDxDaGFydEdyYW51bGFyaXR5PihLUElfU1BBUktMSU5FX0RFRkFVTFRfR1JBTlVMQVJJVFkpO1xuICBwdWJsaWMgcmVhZG9ubHkgc3BhcmtsaW5lUGVyaW9kcyA9IHNpZ25hbDxudW1iZXIgfCBzdHJpbmc+KEtQSV9TUEFSS0xJTkVfREVGQVVMVF9QRVJJT0RTKTtcblxuICAvLyAtLS0tIFNRTCB0YWIgc3RhdGUgLS0tLVxuICAvLyBUaGUgc3RhdGVtZW50LCBvbmNlIGZldGNoZWQuIE51bGwgd2hpbGUgaXQgaXMgaW4gZmxpZ2h0LCBhbmQgbnVsbCB3aGVuIHRoZVxuICAvLyBjb21wb25lbnQncyBkb2N1bWVudCBjb3VsZCBub3QgYmUgY29tcGlsZWQgKHNxbEVycm9yIHRoZW4gc2F5cyB3aHkpLlxuICBwdWJsaWMgcmVhZG9ubHkgc3FsID0gc2lnbmFsPHN0cmluZyB8IG51bGw+KG51bGwpO1xuICAvLyBUcnVlIHdoZW4gdGhlIHN0YXRlbWVudCBpcyBhIERFUklWRUQgYmFzZWxpbmU6IG5vIGZpbHRlcnMsIHRoZSBhdXRob3JlZFxuICAvLyBncmFpbiwgdGltZXMgaW4gdGhlIHJlcG9ydCdzIGVmZmVjdGl2ZSB6b25lLiBUaGUgdGFiIHNheXMgc28sIGJlY2F1c2UgdGhlXG4gIC8vIG51bWJlcnMgb24gc2NyZWVuIGNvbWUgZnJvbSB0aGlzIHN0YXRlbWVudCBwbHVzIHRoZSB2aWV3ZXIncyBvd24gY2hvaWNlc1xuICAvLyBhbmQgdGhlIHR3byBjYW4gZGlmZmVyLlxuICBwdWJsaWMgcmVhZG9ubHkgc3FsQmFzZWxpbmUgPSBzaWduYWwoZmFsc2UpO1xuICAvLyBUaGUgem9uZSB0aGUgc3RhdGVtZW50IHdhcyBjb21waWxlZCBpbjogdGhlIHJlcG9ydCdzIGVmZmVjdGl2ZSB6b25lLCBzZW50XG4gIC8vIHdpdGggdGhlIFNRTC4gQSBzZXJ2ZXIgdG9vIG9sZCB0byBzZW5kIGl0IGNvbXBpbGVkIGluIFVUQy5cbiAgcHVibGljIHJlYWRvbmx5IHNxbFRpbWV6b25lID0gc2lnbmFsKCdVVEMnKTtcbiAgcHVibGljIHJlYWRvbmx5IHNxbEVycm9yID0gc2lnbmFsPHN0cmluZyB8IG51bGw+KG51bGwpO1xuXG4gIC8vIC0tLS0gZmlsdGVyIG1hbmFnZW1lbnQgc3RhdGUgLS0tLVxuICAvLyBPbmUgcm93IHBlciBmaWx0ZXJhYmxlIGNvbHVtbi4gVGhlIHBsYWNlbWVudCBhbmQgdGhlIHRvZ2dsZSBjaGFuZ2VcbiAgLy8gb3B0aW1pc3RpY2FsbHkgb24gY2xpY2sgKHNvIHRoZSBVSSBuZXZlciBibGlua3Mgd2hpbGUgdGhlIHJlcXVlc3QgaXMgaW5cbiAgLy8gZmxpZ2h0KSBhbmQgcmVjb25jaWxlIGZyb20gdGhlIHNlcnZlciBvbiByZWxvYWQuXG4gIHB1YmxpYyByZWFkb25seSByb3dzID0gc2lnbmFsPEZpbHRlclJvd1tdPihbXSk7XG4gIHB1YmxpYyByZWFkb25seSBjb2x1bW5zRXJyb3IgPSBzaWduYWw8c3RyaW5nIHwgbnVsbD4obnVsbCk7XG4gIC8vIFRoZSBUeXBlIHNlbGVjdCdzIGNob2ljZXMuIEEgcm93J3MgVHlwZSBzZWxlY3QsIFJlcG9ydCBiYXIgc2VsZWN0IGFuZFxuICAvLyBUaGlzIGNvbXBvbmVudCB0b2dnbGUgZm9sbG93IHRoZSBydWxlcyBpbiBmaWx0ZXItc2V0dGluZ3MtcnVsZXMudHMuXG4gIHB1YmxpYyByZWFkb25seSB0eXBlT3B0aW9ucyA9IEZJTFRFUl9UWVBFX09QVElPTlM7XG5cbiAgLy8gVGhlIHJhdyBpbnB1dHMgdGhlIHJvd3MgYXJlIGJ1aWx0IGZyb20uXG4gIHByaXZhdGUgX2ZpbHRlcmFibGVDb2x1bW5zOiBSZXBvcnRGaWx0ZXJhYmxlQ29sdW1uW10gPSBbXTtcbiAgcHJpdmF0ZSBfZmlsdGVyczogUmVwb3J0RmlsdGVyW10gPSBbXTtcbiAgcHJpdmF0ZSBfZ3JvdXBzQnlJZCA9IG5ldyBNYXA8bnVtYmVyLCBSZXBvcnRGaWx0ZXJHcm91cD4oKTtcbiAgLy8gVGhlIHR5cGUgcGlja2VkIGZvciBhIGNvbHVtbiB3aXRoIG5vIGZpbHRlciB5ZXQsIHNvIGEgcmVsb2FkIGtlZXBzIGl0LlxuICBwcml2YXRlIF9waWNrZWRUeXBlcyA9IG5ldyBNYXA8c3RyaW5nLCBSZXBvcnRGaWx0ZXJUeXBlPigpO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgX3R5cGVMYWJlbHM6IFJlY29yZDxSZXBvcnRGaWx0ZXJUeXBlLCBzdHJpbmc+ID0ge1xuICAgIHNlbGVjdDogJ1BpY2sgdmFsdWVzJyxcbiAgICBkYXRlUmFuZ2U6ICdEYXRlIHJhbmdlJyxcbiAgICBrZXl3b3JkOiAnU2VhcmNoIHRleHQnLFxuICAgIG51bWJlclJhbmdlOiAnTnVtYmVyIHJhbmdlJyxcbiAgfTtcblxuICBwcml2YXRlIHJlYWRvbmx5IF9kYXRhOiB7IHJlcG9ydDogUmVwb3J0OyBjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudCB9ID0gaW5qZWN0KE1BVF9ESUFMT0dfREFUQSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2RpYWxvZ1JlZiA9IGluamVjdDxNYXREaWFsb2dSZWY8Q29tcG9uZW50U2V0dGluZ3NDb21wb25lbnQsIENvbXBvbmVudFNldHRpbmdzUmVzdWx0Pj4oTWF0RGlhbG9nUmVmKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfcmVwb3J0RGF0YSA9IGluamVjdChSZXBvcnREYXRhKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfbWVzc2FnZSA9IGluamVjdChGc01lc3NhZ2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9wcm9tcHQgPSBpbmplY3QoRnNQcm9tcHQpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9kZXN0cm95UmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuXG4gIHB1YmxpYyBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLnJlcG9ydCA9IHRoaXMuX2RhdGEucmVwb3J0O1xuICAgIHRoaXMuY29tcG9uZW50ID0gdGhpcy5fZGF0YS5jb21wb25lbnQ7XG5cbiAgICB0aGlzLnRpdGxlID0gdGhpcy5jb21wb25lbnQudGl0bGUgPz8gJyc7XG4gICAgdGhpcy5pc1ZhbHVlLnNldCh0aGlzLmNvbXBvbmVudC50eXBlID09PSAndmFsdWUnKTtcbiAgICB0aGlzLmlzRm9ybXVsYS5zZXQoISF0aGlzLmNvbXBvbmVudC5jb25maWc/LmZvcm11bGEpO1xuXG4gICAgY29uc3QgcGFkZGluZyA9IHRoaXMuY29tcG9uZW50LmNvbmZpZz8ucGFkZGluZztcbiAgICB0aGlzLnBhZGRpbmdUb3AgPSBwYWRkaW5nPy50b3AgPz8gREVGQVVMVF9DT01QT05FTlRfUEFERElORztcbiAgICB0aGlzLnBhZGRpbmdSaWdodCA9IHBhZGRpbmc/LnJpZ2h0ID8/IERFRkFVTFRfQ09NUE9ORU5UX1BBRERJTkc7XG4gICAgdGhpcy5wYWRkaW5nQm90dG9tID0gcGFkZGluZz8uYm90dG9tID8/IERFRkFVTFRfQ09NUE9ORU5UX1BBRERJTkc7XG4gICAgdGhpcy5wYWRkaW5nTGVmdCA9IHBhZGRpbmc/LmxlZnQgPz8gREVGQVVMVF9DT01QT05FTlRfUEFERElORztcblxuICAgIHRoaXMuY29uZmlnSnNvbiA9IEpTT04uc3RyaW5naWZ5KHRoaXMuY29tcG9uZW50LmNvbmZpZyA/PyB7fSwgbnVsbCwgMik7XG5cbiAgICB0aGlzLl9zZWVkS3BpQ2FyZCgpO1xuXG4gICAgdGhpcy5fc2VlZEZpbHRlcnModGhpcy5yZXBvcnQsIHRoaXMuY29tcG9uZW50LmlkKTtcblxuICAgIC8vIEEgZm9ybXVsYSBoYXMgbm8gc3RhdGVtZW50IHRvIGNvbXBpbGUgYW5kIG5vIGNvbHVtbnMgdG8gZmlsdGVyIG9uLCBhbmRcbiAgICAvLyB0aGUgc2VydmVyIHdvdWxkIHJlZnVzZSBib3RoIHJlcXVlc3RzLlxuICAgIGlmICghdGhpcy5pc0Zvcm11bGEoKSkge1xuICAgICAgdGhpcy5fbG9hZENvbHVtbnMoKTtcbiAgICAgIHRoaXMuX2xvYWRTcWwoKTtcbiAgICB9XG4gIH1cblxuICAvLyBIdW1hbi1mcmllbmRseSBuYW1lIGZvciB0aGUgaW5mZXJyZWQgaW50ZXJmYWNlIHNob3duIGJlc2lkZSBlYWNoIGNvbHVtbi5cbiAgcHVibGljIHR5cGVMYWJlbCh0eXBlOiBSZXBvcnRGaWx0ZXJUeXBlKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5fdHlwZUxhYmVsc1t0eXBlXSA/PyB0eXBlO1xuICB9XG5cbiAgLy8gQ29uZmlybSBhbmQgZGVsZXRlIGhlcmUsIHdoaWxlIHRoZSBkaWFsb2cgaXMgc3RpbGwgb3BlbiwgdGhlbiBjbG9zZSB3aXRoIGFcbiAgLy8gYGRlbGV0ZWRgIHJlc3VsdCBmb3IgdGhlIHBhZ2UgdG8gYWN0IG9uIOKAlCB0aGUgc2FtZSBzaGFwZSB0aGUgcmVwb3J0XG4gIC8vIHNldHRpbmdzIGRpYWxvZyB1c2VzIGZvciBkZWxldGluZyBhIHJlcG9ydC5cbiAgLy9cbiAgLy8gVGhlIGNvbmZpcm0gc2F5cyBpdCBjYW5ub3QgYmUgdW5kb25lIGJlY2F1c2UsIGZyb20gdGhlIFVJLCBpdCBjYW5ub3Q6IHRoZVxuICAvLyByb3cgaXMgc29mdC1kZWxldGVkIHNlcnZlci1zaWRlIGJ1dCBub3RoaW5nIGhlcmUgcmVzdG9yZXMgYSBjb21wb25lbnQuXG4gIC8vIEEgdmFsdWUncyBjb25maXJtIGFsc28gc2F5cyB3aGF0IGdvZXMgd2l0aCBpdDogdGhlIHNlcnZlciB0YWtlcyBpdHNcbiAgLy8gdG9rZW5zIG91dCBvZiBldmVyeSB0ZXh0IG9uIGl0cyBwYWdlLCBub3QganVzdCB0aGUgb25lIGl0IHdhcyBvcGVuZWQgZnJvbSxcbiAgLy8gYW5kIGRlbGV0ZXMgdGhlIGZvcm11bGFzIHRoYXQgcmVhZCBpdCAoX2RlcGVuZGVudHNOb3RlKS5cbiAgLy9cbiAgLy8gVGhlIHByb21wdCByZW5kZXJzIGl0cyB0ZW1wbGF0ZSBhcyBodG1sLCBzbyBldmVyeSBuYW1lIGluIGl0IGlzIGVzY2FwZWQuXG4gIHB1YmxpYyBkZWxldGUoKTogdm9pZCB7XG4gICAgdGhpcy5fcHJvbXB0LmNvbmZpcm0odGhpcy5pc1ZhbHVlKClcbiAgICAgID8ge1xuICAgICAgICB0aXRsZTogJ0RlbGV0ZSBWYWx1ZScsXG4gICAgICAgIHRlbXBsYXRlOiBgRGVsZXRlIHRoZSB2YWx1ZSBcIiR7ZXNjYXBlSHRtbCh0aGlzLmNvbXBvbmVudC50aXRsZSB8fCB2YWx1ZUtleSh0aGlzLmNvbXBvbmVudCkpfVwiPyBJdCBpcyBhbHNvIHRha2VuIG91dCBvZiBldmVyeSB0ZXh0IG9uIHRoaXMgcGFnZS4gVGhpcyBjYW5ub3QgYmUgdW5kb25lLiR7dGhpcy5fZGVwZW5kZW50c05vdGUoKX1gLFxuICAgICAgfVxuICAgICAgOiB7XG4gICAgICAgIHRpdGxlOiAnRGVsZXRlIENvbXBvbmVudCcsXG4gICAgICAgIHRlbXBsYXRlOiBgQXJlIHlvdSBzdXJlIHlvdSB3b3VsZCBsaWtlIHRvIGRlbGV0ZSBcIiR7ZXNjYXBlSHRtbCh0aGlzLmNvbXBvbmVudC50aXRsZSB8fCAndGhpcyBjb21wb25lbnQnKX1cIj8gVGhpcyBjYW5ub3QgYmUgdW5kb25lLmAsXG4gICAgICB9KVxuICAgICAgLnBpcGUoXG4gICAgICAgIHN3aXRjaE1hcCgoKSA9PiB0aGlzLl9yZXBvcnREYXRhLmRlbGV0ZUNvbXBvbmVudCh0aGlzLnJlcG9ydC5pZCwgdGhpcy5jb21wb25lbnQuaWQpKSxcbiAgICAgICAgdGFwKCgpID0+IHtcbiAgICAgICAgICB0aGlzLl9tZXNzYWdlLnN1Y2Nlc3ModGhpcy5pc1ZhbHVlKCkgPyAnVmFsdWUgZGVsZXRlZCcgOiAnQ29tcG9uZW50IGRlbGV0ZWQnKTtcbiAgICAgICAgICB0aGlzLl9kaWFsb2dSZWYuY2xvc2UoeyBkZWxldGVkOiB0cnVlIH0pO1xuICAgICAgICB9KSxcbiAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgpO1xuICB9XG5cbiAgLy8gQSBwZXJjZW50IHRhcmdldCdzIGJvdW5kLCBpbiB0aGUgcGVyY2VudCBpdCBpcyB0eXBlZCBpbi4gSXQgcmVhZHMgdGhlXG4gIC8vIGNvbnRyb2wsIHdoaWNoIGZzRm9ybSB2YWxpZGF0ZXMgYmVmb3JlIG5nTW9kZWxDaGFuZ2UgdXBkYXRlcyB0aGUgc2lnbmFsLlxuICBwdWJsaWMgdmFsaWRhdGVUYXJnZXQgPSAoY29udHJvbDogQWJzdHJhY3RDb250cm9sKTogdm9pZCA9PiB7XG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLl9udW1iZXIoY29udHJvbC52YWx1ZSk7XG5cbiAgICBpZiAodGhpcy50YXJnZXRQZXJjZW50KCkgJiYgdmFsdWUgIT09IG51bGwgJiYgdmFsdWUgPiBLUElfUEVSQ0VOVF9UQVJHRVRfTUFYKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0EgcGVyY2VudCB0YXJnZXQgY2FuIGJlIGF0IG1vc3QgMTAsMDAwJScpO1xuICAgIH1cbiAgfTtcblxuICBwdWJsaWMgc2F2ZSA9ICgpID0+IHtcbiAgICBjb25zdCBzZXR0aW5nczogQ29tcG9uZW50U2V0dGluZ3MgPSB7XG4gICAgICAvLyBUaGUgc2VydmVyIHRyaW1zIGEgdGl0bGU7IGEgdmFsdWUncyBOYW1lIGlzIHdoYXQgaXRzIGNoaXBzIHNob3csIHNvIGl0XG4gICAgICAvLyBnb2VzIGFzIHRoZSBzZXJ2ZXIga2VlcHMgaXQuXG4gICAgICB0aXRsZTogdGhpcy5pc1ZhbHVlKCkgPyB0aGlzLnRpdGxlLnRyaW0oKSA6IHRoaXMudGl0bGUsXG4gICAgICBwYWRkaW5nOiB7XG4gICAgICAgIHRvcDogdGhpcy5fcGFkZGluZyh0aGlzLnBhZGRpbmdUb3ApLFxuICAgICAgICByaWdodDogdGhpcy5fcGFkZGluZyh0aGlzLnBhZGRpbmdSaWdodCksXG4gICAgICAgIGJvdHRvbTogdGhpcy5fcGFkZGluZyh0aGlzLnBhZGRpbmdCb3R0b20pLFxuICAgICAgICBsZWZ0OiB0aGlzLl9wYWRkaW5nKHRoaXMucGFkZGluZ0xlZnQpLFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgLy8gVGhlIGNhcmQga2V5cyBnbyBhcyBjb25maWcga2V5cyBiZXNpZGUgdGhlIHBhZGRpbmcgKGluY3JlYXNlSXMsIHRhcmdldFxuICAgIC8vIGFuZCBzcGFya2xpbmUsIG51bGwgdG8gcmVtb3ZlIG9uZSksIGFuZCBvbmx5IHdoZW4gdGhleSBjaGFuZ2VkLCBzbyBhXG4gICAgLy8gdGl0bGUgZWRpdCBuZXZlciB0b3VjaGVzIHRoZW0uXG4gICAgY29uc3Qga3BpID0gdGhpcy5rcGlDYXJkKCkgPyB0aGlzLl9rcGlDYXJkU2V0dGluZ3MoKSA6IG51bGw7XG4gICAgY29uc3Qga3BpQ2hhbmdlZCA9ICEha3BpXG4gICAgICAmJiAhc2FtZUtwaUNhcmRTZXR0aW5ncyhrcGksIGtwaUNhcmRTZXR0aW5ncyh0aGlzLmNvbXBvbmVudC5jb25maWcgYXMgS3BpQ29uZmlnKSk7XG5cbiAgICByZXR1cm4gdGhpcy5fcmVwb3J0RGF0YS51cGRhdGVDb21wb25lbnQodGhpcy5yZXBvcnQuaWQsIHRoaXMuY29tcG9uZW50LmlkLCB7XG4gICAgICB0aXRsZTogc2V0dGluZ3MudGl0bGUsXG4gICAgICAuLi4odGhpcy5pc1ZhbHVlKCkgPyB7fSA6IHsgcGFkZGluZzogc2V0dGluZ3MucGFkZGluZyB9KSxcbiAgICAgIC4uLihrcGlDaGFuZ2VkID8ga3BpIDoge30pLFxuICAgIH0pXG4gICAgICAucGlwZShcbiAgICAgICAgdGFwKChyZXNwb25zZTogQ29tcG9uZW50U2V0dGluZ3NSZXNwb25zZSkgPT4ge1xuICAgICAgICAgIC8vIFRoZSBjYXJkIGlzIGRyYXduIGZyb20gdGhlIGtleXMgdGhlIHNlcnZlciBzYXZlZCwgcmVhZCBiYWNrIGZyb21cbiAgICAgICAgICAvLyB0aGUgY29uZmlnIGl0IHJldHVybnMuIEEgc2VydmVyIHRoYXQgcmV0dXJucyBubyBjb25maWcgZGlkIG5vdFxuICAgICAgICAgIC8vIHNhdmUgdGhlbSwgc28gdGhlIGNhcmQga2VlcHMgd2hhdCBpdCBoYWQgYW5kIHRoZSBkaWFsb2cgc2F5cyBzby5cbiAgICAgICAgICBjb25zdCBzYXZlZCA9IGtwaUNoYW5nZWQgPyB0aGlzLl9zYXZlZEtwaUNhcmQocmVzcG9uc2UpIDogbnVsbDtcblxuICAgICAgICAgIGlmIChrcGlDaGFuZ2VkICYmICFzYXZlZCkge1xuICAgICAgICAgICAgdGhpcy5fbWVzc2FnZS53YXJuaW5nKCdDb21wb25lbnQgc2F2ZWQsIGJ1dCB0aGUgc2VydmVyIGRpZCBub3Qgc2F2ZSB0aGUgY2FyZCBzZXR0aW5ncycpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9tZXNzYWdlLnN1Y2Nlc3ModGhpcy5pc1ZhbHVlKCkgPyAnVmFsdWUgc2F2ZWQnIDogJ0NvbXBvbmVudCBzYXZlZCcpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMuX2RpYWxvZ1JlZi5jbG9zZSh7IHNldHRpbmdzOiBzYXZlZCA/IHsgLi4uc2V0dGluZ3MsIGtwaTogc2F2ZWQgfSA6IHNldHRpbmdzIH0pO1xuICAgICAgICB9KSxcbiAgICAgICk7XG4gIH07XG5cbiAgLy8gVGhlIHR5cGUgYSBjb2x1bW4ncyBmaWx0ZXIgd2lsbCBiZSBtYWRlIHdpdGguIE9ubHkgYSBjb2x1bW4gd2l0aCBub1xuICAvLyBmaWx0ZXIgb2ZmZXJzIHRoZSBwaWNrICh0aGUgVHlwZSBzZWxlY3QgaXMgbG9ja2VkIG90aGVyd2lzZSksIGFuZCBub3RoaW5nXG4gIC8vIGlzIHNhdmVkIHVudGlsIHRoZSBmaWx0ZXIgaXMgbWFkZS5cbiAgcHVibGljIHNldFR5cGUocm93OiBGaWx0ZXJSb3csIHR5cGU6IFJlcG9ydEZpbHRlclR5cGUpOiB2b2lkIHtcbiAgICB0aGlzLl9waWNrZWRUeXBlcy5zZXQocm93LmNvbHVtbiwgdHlwZSk7XG4gICAgdGhpcy5fcGF0Y2hSb3cocm93LCB7IHR5cGUgfSk7XG4gIH1cblxuICAvLyBXaGVyZSB0aGUgcm93J3MgZmlsdGVyIHNob3dzIGluIHRoZSByZXBvcnQgYmFyLiBUaGlzIHBhZ2Ugb25seSBzaG93cyBpdFxuICAvLyBpbiBpdHMgcGFnZSdzIGJhciBhbG9uZSwgc28gdGhlIFRoaXMgY29tcG9uZW50IHRvZ2dsZSBnb2VzIG9mZiBhbmQgbG9ja3MuXG4gIC8vIEEgdmFsdWUgaGFzIHRoaXMgc2VsZWN0IG9ubHksIHdpdGggaXRzIG93biBydWxlcyAoX2FwcGx5VmFsdWVMZXZlbCkuXG4gIHB1YmxpYyBzZXRQbGFjZW1lbnQocm93OiBGaWx0ZXJSb3csIHBsYWNlbWVudDogRmlsdGVyQmFyUGxhY2VtZW50KTogdm9pZCB7XG4gICAgY29uc3QgcGF0Y2hlZCA9IHRoaXMuX3BhdGNoUm93KHJvdywge1xuICAgICAgcGxhY2VtZW50LFxuICAgICAgY29tcG9uZW50OiBwbGFjZW1lbnQgPT09ICdwYWdlJyA/IGZhbHNlIDogcm93LmNvbXBvbmVudCxcbiAgICAgIGNvbXBvbmVudFRvZ2dsZTogY29tcG9uZW50VG9nZ2xlU3RhdGUocGxhY2VtZW50KSxcbiAgICB9KTtcblxuICAgIGlmICh0aGlzLmlzVmFsdWUoKSkge1xuICAgICAgdGhpcy5fYXBwbHlWYWx1ZUxldmVsKHBhdGNoZWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9hcHBseUxldmVsKHBhdGNoZWQpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEEgdmFsdWUgaGFzIG5vIFRoaXMgY29tcG9uZW50IHRvZ2dsZS5cbiAgcHVibGljIHNldENvbXBvbmVudChyb3c6IEZpbHRlclJvdywgY29tcG9uZW50OiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNWYWx1ZSgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fYXBwbHlMZXZlbCh0aGlzLl9wYXRjaFJvdyhyb3csIHsgY29tcG9uZW50IH0pKTtcbiAgfVxuXG4gIC8vIFBlcnNpc3QgdGhlIGxldmVsIHRoZSByb3cncyBjb250cm9scyBhc2sgZm9yLCB0aGVuIHJlY29uY2lsZSBvbiByZWxvYWQuXG4gIC8vIE5vIGxldmVsIOKGkiBubyBmaWx0ZXIgKHJlbW92ZWQpOyBvdGhlcndpc2UgdGhlIGZpbHRlciBleGlzdHMgYXQgdGhhdFxuICAvLyBsZXZlbC4gQSBzZXJ2ZXIgcmVmdXNhbCAoYSBwYWdlIGZpbHRlciB3aG9zZSBtZW1iZXJzIHNpdCBvbiB0d28gcGFnZXMpXG4gIC8vIHNob3dzIGl0cyBvd24gdGV4dCBhbmQgdGhlIHJvdyBzbmFwcyBiYWNrLlxuICBwcml2YXRlIF9hcHBseUxldmVsKHJvdzogRmlsdGVyUm93KTogdm9pZCB7XG4gICAgY29uc3QgbGV2ZWwgPSBmaWx0ZXJMZXZlbChyb3cucGxhY2VtZW50LCByb3cuY29tcG9uZW50KTtcbiAgICBjb25zdCBleGlzdGluZyA9IHRoaXMuX2ZpbHRlcnMuZmluZCgoZmlsdGVyKSA9PiBmaWx0ZXIuZmlsdGVyQ29sdW1uID09PSByb3cuY29sdW1uKTtcblxuICAgIGlmICghbGV2ZWwpIHtcbiAgICAgIGlmIChleGlzdGluZykge1xuICAgICAgICB0aGlzLl9ydW4odGhpcy5fcmVwb3J0RGF0YS5kZWxldGVGaWx0ZXIodGhpcy5yZXBvcnQuaWQsIGV4aXN0aW5nLmlkKSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgIHRoaXMuX3J1bih0aGlzLl9yZXBvcnREYXRhLnVwZGF0ZUZpbHRlckdyb3VwKHRoaXMucmVwb3J0LmlkLCBleGlzdGluZy5maWx0ZXJHcm91cElkLCB7IGxldmVsIH0pKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fYWRkRmlsdGVyKHJvdywgbGV2ZWwpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEEgdmFsdWUncyBSZXBvcnQgYmFyIHNlbGVjdCwgdGhlIG9ubHkgY29udHJvbCBpdCBoYXMuIEl0cyBmaWx0ZXIncyBncm91cFxuICAvLyBtYXkgYmUgc2hhcmVkICh0aGUgcmVwb3J0J3MgUGVyaW9kLCBzYXkpLCBhbmQgYSB2YWx1ZSBoYXMgbm8gc3RyaXAgb2YgaXRzXG4gIC8vIG93biwgc28gYSBwaWNrIG5ldmVyIGxvd2VycyB0aGUgZ3JvdXAgKHZhbHVlRmlsdGVyTGV2ZWwpLiBBIHBpY2sgdGhhdFxuICAvLyBtb3ZlcyBub3RoaW5nIHB1dHMgdGhlIHJvdyBiYWNrIGFzIHRoZSBncm91cCBzdGFuZHMuXG4gIHByaXZhdGUgX2FwcGx5VmFsdWVMZXZlbChyb3c6IEZpbHRlclJvdyk6IHZvaWQge1xuICAgIGNvbnN0IGV4aXN0aW5nID0gdGhpcy5fZmlsdGVycy5maW5kKChmaWx0ZXIpID0+IGZpbHRlci5maWx0ZXJDb2x1bW4gPT09IHJvdy5jb2x1bW4pO1xuICAgIGNvbnN0IGN1cnJlbnQgPSBleGlzdGluZyA/IHRoaXMuX2dyb3Vwc0J5SWQuZ2V0KGV4aXN0aW5nLmZpbHRlckdyb3VwSWQpPy5sZXZlbCA6IHVuZGVmaW5lZDtcbiAgICBjb25zdCBsZXZlbCA9IHZhbHVlRmlsdGVyTGV2ZWwocm93LnBsYWNlbWVudCwgY3VycmVudCk7XG5cbiAgICBpZiAoIWxldmVsKSB7XG4gICAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgICAgdGhpcy5fcnVuKHRoaXMuX3JlcG9ydERhdGEuZGVsZXRlRmlsdGVyKHRoaXMucmVwb3J0LmlkLCBleGlzdGluZy5pZCkpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIWV4aXN0aW5nKSB7XG4gICAgICB0aGlzLl9hZGRGaWx0ZXIocm93LCBsZXZlbCk7XG4gICAgfSBlbHNlIGlmIChsZXZlbCAhPT0gY3VycmVudCkge1xuICAgICAgdGhpcy5fcnVuKHRoaXMuX3JlcG9ydERhdGEudXBkYXRlRmlsdGVyR3JvdXAodGhpcy5yZXBvcnQuaWQsIGV4aXN0aW5nLmZpbHRlckdyb3VwSWQsIHsgbGV2ZWwgfSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9yZWJ1aWxkUm93cygpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFRoZSB0eXBlIGdvZXMgb25seSB3aGVuIHRoZSBhdXRob3IgY291bGQgcGljayBpdDsgb3RoZXJ3aXNlIHRoZSBzZXJ2ZXJcbiAgLy8gaW5mZXJzIGl0LCBhcyBpdCBhbHdheXMgaGFzLlxuICBwcml2YXRlIF9hZGRGaWx0ZXIocm93OiBGaWx0ZXJSb3csIGxldmVsOiBSZXBvcnRGaWx0ZXJMZXZlbCk6IHZvaWQge1xuICAgIHRoaXMuX3J1bih0aGlzLl9yZXBvcnREYXRhLmFkZEZpbHRlcih0aGlzLnJlcG9ydC5pZCwgdGhpcy5jb21wb25lbnQuaWQsIHtcbiAgICAgIGZpbHRlckNvbHVtbjogcm93LmNvbHVtbixcbiAgICAgIGxhYmVsOiByb3cubGFiZWwsXG4gICAgICBsZXZlbCxcbiAgICAgIC4uLihyb3cudHlwZVNlbGVjdC5zaG93ID8geyB0eXBlOiByb3cudHlwZSB9IDoge30pLFxuICAgIH0pKTtcbiAgfVxuXG4gIC8vIEEgbmV3IHJvdyBvYmplY3QgcmF0aGVyIHRoYW4gYSBtdXRhdGlvbiwgc28gdGhlIHNpZ25hbCBzZWVzIHRoZSBjaGFuZ2U7XG4gIC8vIHRoZSBAZm9yIHRyYWNrcyB0aGUgY29sdW1uLCBzbyB0aGUgcm93J3MgY29udHJvbHMgc3Vydml2ZSB0aGUgc3dhcC5cbiAgcHJpdmF0ZSBfcGF0Y2hSb3cocm93OiBGaWx0ZXJSb3csIHBhdGNoOiBQYXJ0aWFsPEZpbHRlclJvdz4pOiBGaWx0ZXJSb3cge1xuICAgIGNvbnN0IHBhdGNoZWQgPSB7IC4uLnJvdywgLi4ucGF0Y2ggfTtcbiAgICB0aGlzLnJvd3MudXBkYXRlKChyb3dzKSA9PiByb3dzLm1hcCgoaXRlbSkgPT4gKGl0ZW0uY29sdW1uID09PSByb3cuY29sdW1uID8gcGF0Y2hlZCA6IGl0ZW0pKSk7XG5cbiAgICByZXR1cm4gcGF0Y2hlZDtcbiAgfVxuXG4gIC8vIFdoYXQgYSBmb3JtdWxhIHdvcmtzIG91dCwgbmFtaW5nIGVhY2ggb3BlcmFuZCBhcyBpdHMgY2hpcHMgZG8uIEFuIG9wIHRoaXNcbiAgLy8gdmlld2VyIGRvZXMgbm90IGtub3cgcmVhZHMgbm90aGluZy5cbiAgcHJpdmF0ZSBfZm9ybXVsYUxpbmUoKTogc3RyaW5nIHtcbiAgICBjb25zdCBmb3JtdWxhID0gdGhpcy5jb21wb25lbnQuY29uZmlnPy5mb3JtdWxhO1xuICAgIGNvbnN0IGxpbmUgPSBmb3JtdWxhID8gRk9STVVMQV9MSU5FU1tmb3JtdWxhLm9wXSA6IHVuZGVmaW5lZDtcbiAgICBjb25zdCB2YWx1ZXMgPSB0aGlzLl9sYXllclZhbHVlcygpO1xuXG4gICAgcmV0dXJuIGxpbmUgPyBsaW5lKG9wZXJhbmRLZXlzKHRoaXMuY29tcG9uZW50KS5tYXAoKGtleSkgPT4gdGhpcy5fdmFsdWVOYW1lKHZhbHVlcywga2V5KSkpIDogJyc7XG4gIH1cblxuICAvLyBUaGUgc2VudGVuY2UgYSBxdWVyeSB2YWx1ZSdzIGRlbGV0ZSBjb25maXJtIGVuZHMgd2l0aCB3aGVuIGZvcm11bGFzIG9uIGl0c1xuICAvLyBsYXllciByZWFkIGl0OiB0aGUgc2VydmVyIGRlbGV0ZXMgdGhvc2Ugd2l0aCBpdC4gRW1wdHkgd2hlbiBub25lIGRvZXMsIGFuZFxuICAvLyBmb3IgYSBmb3JtdWxhLCB3aG9zZSBvcGVyYW5kcyBzdGF5LlxuICBwcml2YXRlIF9kZXBlbmRlbnRzTm90ZSgpOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLmlzRm9ybXVsYSgpKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgY29uc3Qga2V5ID0gdmFsdWVLZXkodGhpcy5jb21wb25lbnQpO1xuICAgIGNvbnN0IG5hbWVzID0gdGhpcy5fbGF5ZXJWYWx1ZXMoKVxuICAgICAgLmZpbHRlcigodmFsdWUpID0+IG9wZXJhbmRLZXlzKHZhbHVlKS5pbmNsdWRlcyhrZXkpKVxuICAgICAgLm1hcCgodmFsdWUpID0+IGVzY2FwZUh0bWwodmFsdWUudGl0bGUgfHwgdmFsdWVLZXkodmFsdWUpKSk7XG5cbiAgICByZXR1cm4gbmFtZXMubGVuZ3RoID8gYCBUaGUgdmFsdWVzIHdvcmtlZCBvdXQgZnJvbSBpdCBhcmUgZGVsZXRlZCB0b286ICR7bmFtZXMuam9pbignLCAnKX0uYCA6ICcnO1xuICB9XG5cbiAgLy8gVGhlIHZhbHVlcyBvZiB0aGUgbGF5ZXIgdGhpcyB2YWx1ZSBiZWxvbmdzIHRvOiB0aGUgcGFnZSB3aG9zZSB2YWx1ZXMgaG9sZFxuICAvLyBpdCwgZWxzZSB0aGUgbWFzdGVyJ3MgKGEgaGVhZGVyIG9yIGZvb3RlciB2YWx1ZSkuXG4gIHByaXZhdGUgX2xheWVyVmFsdWVzKCk6IFJlcG9ydENvbXBvbmVudFtdIHtcbiAgICBjb25zdCBwYWdlID0gKHRoaXMucmVwb3J0LnBhZ2VzID8/IFtdKVxuICAgICAgLmZpbmQoKGNhbmRpZGF0ZSkgPT4gKGNhbmRpZGF0ZS52YWx1ZXMgPz8gW10pLnNvbWUoKHZhbHVlKSA9PiB2YWx1ZS5pZCA9PT0gdGhpcy5jb21wb25lbnQuaWQpKTtcblxuICAgIHJldHVybiAocGFnZSA/PyB0aGlzLnJlcG9ydC5tYXN0ZXIpPy52YWx1ZXMgPz8gW107XG4gIH1cblxuICAvLyBXaGF0IGEgdmFsdWUgaXMgY2FsbGVkIHdoZXJlIGl0cyBjaGlwcyBzaG93IGl0OiBpdHMgbmFtZSwgZWxzZSBpdHMga2V5LlxuICAvLyBUaGUgbmV3ZXN0IHZhbHVlIGhvbGRzIGEga2V5LCBhcyBpdCBkb2VzIGluIHRoZSB0ZXh0J3MgdG9rZW5zLlxuICBwcml2YXRlIF92YWx1ZU5hbWUodmFsdWVzOiBSZXBvcnRDb21wb25lbnRbXSwga2V5OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHZhbHVlID0gdmFsdWVzLmZpbHRlcigoY2FuZGlkYXRlKSA9PiB2YWx1ZUtleShjYW5kaWRhdGUpID09PSBrZXkpLnBvcCgpO1xuXG4gICAgcmV0dXJuIHZhbHVlPy50aXRsZSB8fCBrZXk7XG4gIH1cblxuICAvLyBBIGRlcml2ZWQgS1BJJ3MgY2FyZCBrZXlzLCBmcm9tIGl0cyBjb25maWcuIEEgc3FsLW1vZGUgS1BJIGNhbm5vdCBjYXJyeVxuICAvLyB0aGVtLCBzbyBpdCBnZXRzIG5vIGNhcmQgZmllbGRzLlxuICBwcml2YXRlIF9zZWVkS3BpQ2FyZCgpOiB2b2lkIHtcbiAgICBjb25zdCBjb25maWcgPSAodGhpcy5jb21wb25lbnQuY29uZmlnID8/IHt9KSBhcyBLcGlDb25maWc7XG5cbiAgICB0aGlzLmtwaUNhcmQuc2V0KHRoaXMuY29tcG9uZW50LnR5cGUgPT09ICdrcGknICYmICF0aGlzLmNvbXBvbmVudC5zcWwpO1xuICAgIHRoaXMuaW5jcmVhc2VJcy5zZXQoY29uZmlnLmluY3JlYXNlSXMgPz8gUmVwb3J0Q2hhbmdlUG9sYXJpdHkuR29vZCk7XG4gICAgdGhpcy50YXJnZXRQZXJjZW50LnNldChjb25maWcubWVhc3VyZT8uZm9ybWF0ID09PSBSZXBvcnRWYWx1ZUZvcm1hdC5QZXJjZW50XG4gICAgICAmJiByZXNvbHZlRm9ybWF0Q29udGV4dCh0aGlzLnJlcG9ydCkucmF0aW9QZXJjZW50KTtcbiAgICB0aGlzLnRhcmdldFZhbHVlLnNldCh0aGlzLl90YXJnZXRTaG93bihjb25maWcudGFyZ2V0Py52YWx1ZSA/PyBudWxsKSk7XG4gICAgdGhpcy50YXJnZXRMYWJlbC5zZXQoY29uZmlnLnRhcmdldD8ubGFiZWwgPz8gJycpO1xuICAgIHRoaXMuc3BhcmtsaW5lLnNldCghIWNvbmZpZy5zcGFya2xpbmUpO1xuICAgIHRoaXMuc3BhcmtsaW5lR3JhbnVsYXJpdHkuc2V0KGNvbmZpZy5zcGFya2xpbmU/LmdyYW51bGFyaXR5ID8/IEtQSV9TUEFSS0xJTkVfREVGQVVMVF9HUkFOVUxBUklUWSk7XG4gICAgdGhpcy5zcGFya2xpbmVQZXJpb2RzLnNldChjb25maWcuc3BhcmtsaW5lPy5wZXJpb2RzID8/IEtQSV9TUEFSS0xJTkVfREVGQVVMVF9QRVJJT0RTKTtcbiAgfVxuXG4gIC8vIFRoZSBjYXJkIGtleXMgdGhlIHNlcnZlciBzYXZlZCwgZnJvbSB0aGUgY29uZmlnIGl0cyByZXNwb25zZSBjYXJyaWVzO1xuICAvLyBudWxsIHdoZW4gaXQgY2FycmllcyBub25lIChhIHNlcnZlciB0aGF0IGRvZXMgbm90IHNhdmUgdGhlbSkuXG4gIHByaXZhdGUgX3NhdmVkS3BpQ2FyZChyZXNwb25zZTogQ29tcG9uZW50U2V0dGluZ3NSZXNwb25zZSB8IG51bGwgfCB1bmRlZmluZWQpOiBLcGlDYXJkU2V0dGluZ3MgfCBudWxsIHtcbiAgICBjb25zdCBjb25maWcgPSByZXNwb25zZT8uY29uZmlnO1xuXG4gICAgcmV0dXJuIGNvbmZpZyAmJiB0eXBlb2YgY29uZmlnID09PSAnb2JqZWN0JyA/IGtwaUNhcmRTZXR0aW5ncyhjb25maWcgYXMgS3BpQ29uZmlnKSA6IG51bGw7XG4gIH1cblxuICAvLyBHb29kIGlzIHdoYXQgYW4gYWJzZW50IGluY3JlYXNlSXMgcmVhZHMsIHNvIGl0IGlzIHNhdmVkIGFzIGFic2VudC5cbiAgcHJpdmF0ZSBfa3BpQ2FyZFNldHRpbmdzKCk6IEtwaUNhcmRTZXR0aW5ncyB7XG4gICAgY29uc3QgdGFyZ2V0ID0gdGhpcy5fbnVtYmVyKHRoaXMudGFyZ2V0VmFsdWUoKSk7XG4gICAgY29uc3QgbGFiZWwgPSB0aGlzLnRhcmdldExhYmVsKCkudHJpbSgpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGluY3JlYXNlSXM6IHRoaXMuaW5jcmVhc2VJcygpID09PSBSZXBvcnRDaGFuZ2VQb2xhcml0eS5Hb29kID8gbnVsbCA6IHRoaXMuaW5jcmVhc2VJcygpLFxuICAgICAgdGFyZ2V0OiB0YXJnZXQgPT09IG51bGwgPyBudWxsIDogeyB2YWx1ZTogdGhpcy5fdGFyZ2V0U3RvcmVkKHRhcmdldCksIGxhYmVsOiBsYWJlbCB8fCBudWxsIH0sXG4gICAgICBzcGFya2xpbmU6IHRoaXMuc3BhcmtsaW5lKClcbiAgICAgICAgPyB7IGdyYW51bGFyaXR5OiB0aGlzLnNwYXJrbGluZUdyYW51bGFyaXR5KCksIHBlcmlvZHM6IHRoaXMuX251bWJlcih0aGlzLnNwYXJrbGluZVBlcmlvZHMoKSkgfVxuICAgICAgICA6IG51bGwsXG4gICAgfTtcbiAgfVxuXG4gIC8vIEEgc3RvcmVkIHJhdGlvIGFzIHRoZSBwZXJjZW50IHR5cGVkLCByb3VuZGVkIHNvIDAuMTUgcmVhZHMgMTUgYW5kIG5vdFxuICAvLyAxNS4wMDAwMDAwMDAwMDAwMDIuXG4gIHByaXZhdGUgX3RhcmdldFNob3duKHZhbHVlOiBudW1iZXIgfCBudWxsKTogbnVtYmVyIHwgbnVsbCB7XG4gICAgaWYgKHZhbHVlID09PSBudWxsIHx8ICF0aGlzLnRhcmdldFBlcmNlbnQoKSkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIHJldHVybiBNYXRoLnJvdW5kKHZhbHVlICogMTAwICogMWU2KSAvIDFlNjtcbiAgfVxuXG4gIHByaXZhdGUgX3RhcmdldFN0b3JlZCh2YWx1ZTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy50YXJnZXRQZXJjZW50KCkgPyB2YWx1ZSAvIDEwMCA6IHZhbHVlO1xuICB9XG5cbiAgLy8gQSB0eXBlZCBudW1iZXIsIG9yIG51bGwgd2hlbiB0aGUgZmllbGQgaXMgZW1wdHkuXG4gIHByaXZhdGUgX251bWJlcih2YWx1ZTogbnVtYmVyIHwgc3RyaW5nIHwgbnVsbCk6IG51bWJlciB8IG51bGwge1xuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gJycpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IG51bWJlciA9IHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgPyB2YWx1ZSA6IHBhcnNlRmxvYXQodmFsdWUpO1xuXG4gICAgcmV0dXJuIE51bWJlci5pc0Zpbml0ZShudW1iZXIpID8gbnVtYmVyIDogbnVsbDtcbiAgfVxuXG4gIC8vIFRoZSBwYWRkaW5nIGFzIGEgcmVhbCBudW1iZXIgZm9yIHRoZSB3aXJlLiBmc01hc2tOdW1iZXIgaGFuZHMgYmFjayB0aGVcbiAgLy8gdW5tYXNrZWQgc3RyaW5nIGl0IGJ1aWx0IHdpdGggYSBmaXhlZCAnLicgcmFkaXgsIHNvIHRoaXMgaXMgYSBzdHJhaWdodFxuICAvLyBwYXJzZSAtIHRoZSB3aG9sZSByZWFzb24gZm9yIHRoZSBtYXNrIGlzIHRoYXQgYSBuYXRpdmUgbnVtYmVyIGlucHV0IHdvdWxkXG4gIC8vIHBhaW50IChhbmQgcmVhZCBiYWNrKSB0aGUgdmlld2VyJ3Mgb3duIGxvY2FsZSBzZXBhcmF0b3IgaW5zdGVhZC5cbiAgcHJpdmF0ZSBfcGFkZGluZyh2YWx1ZTogbnVtYmVyIHwgc3RyaW5nKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyA/IHZhbHVlIDogcGFyc2VGbG9hdCh2YWx1ZSk7XG4gIH1cblxuICAvLyBSdW4gYSBmaWx0ZXIgbXV0YXRpb24sIHRoZW4gcmVsb2FkIHRvIHJlY29uY2lsZSB0aGUgb3B0aW1pc3RpYyBzdGF0ZS5cbiAgcHJpdmF0ZSBfcnVuKHJlcXVlc3Q6IE9ic2VydmFibGU8dW5rbm93bj4pOiB2b2lkIHtcbiAgICByZXF1ZXN0LnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAoKSA9PiB0aGlzLl9hZnRlck11dGF0aW9uKCksXG4gICAgICBlcnJvcjogKGVycm9yKSA9PiB0aGlzLl9tdXRhdGlvbkVycm9yKGVycm9yKSxcbiAgICB9KTtcbiAgfVxuXG4gIC8vIEJ1aWxkIHRoZSByb3cgdmlldy1tb2RlbCBmcm9tIHRoZSBsb2FkZWQgY29sdW1ucyArIGZpbHRlcnMvZ3JvdXBzLiBFYWNoXG4gIC8vIHJvdydzIGNvbnRyb2xzIHJlZmxlY3Qgd2hlcmUgaXRzIGZpbHRlciBncm91cCBjdXJyZW50bHkgc2hvd3M7IGEgY29sdW1uXG4gIC8vIHdpdGggYSBmaWx0ZXIgc2hvd3MgdGhlIGZpbHRlcidzIG93biB0eXBlLiBBIHZhbHVlJ3Mgcm93cyBuZXZlciByZWFkIGFzXG4gIC8vIG9uIGEgY29tcG9uZW50OiBpdCBoYXMgbm8gc3RyaXAsIHdoYXRldmVyIGxldmVsIGEgZ3JvdXAgaXQgc2hhcmVzIGlzIGF0LFxuICAvLyBhbmQgaXRzIFJlcG9ydCBiYXIgc2VsZWN0IG9mZmVycyBubyBwaWNrIHRoYXQgbG93ZXJzIHRoYXQgZ3JvdXAuXG4gIHByaXZhdGUgX3JlYnVpbGRSb3dzKCk6IHZvaWQge1xuICAgIGNvbnN0IGxldmVsQ2hvaWNlcyA9IGZpbHRlckxldmVsQ2hvaWNlcyh0aGlzLnJlcG9ydC52aWV3ZXJGZWF0dXJlcywgdGhpcy5fb25QYWdlKCkpO1xuXG4gICAgdGhpcy5yb3dzLnNldCh0aGlzLl9maWx0ZXJhYmxlQ29sdW1ucy5tYXAoKGNvbHVtbikgPT4ge1xuICAgICAgY29uc3QgZmlsdGVyID0gdGhpcy5fZmlsdGVycy5maW5kKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZS5maWx0ZXJDb2x1bW4gPT09IGNvbHVtbi5jb2x1bW4pO1xuICAgICAgY29uc3QgZ3JvdXAgPSBmaWx0ZXIgPyB0aGlzLl9ncm91cHNCeUlkLmdldChmaWx0ZXIuZmlsdGVyR3JvdXBJZCkgOiB1bmRlZmluZWQ7XG4gICAgICBjb25zdCBwbGFjZW1lbnQgPSBiYXJQbGFjZW1lbnQoZ3JvdXA/LmxldmVsKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29sdW1uOiBjb2x1bW4uY29sdW1uLFxuICAgICAgICB0eXBlOiBncm91cD8udHlwZVxuICAgICAgICAgID8/IHRoaXMuX3BpY2tlZFR5cGVzLmdldChjb2x1bW4uY29sdW1uKVxuICAgICAgICAgID8/IGNvbHVtbi50eXBlcz8uWzBdXG4gICAgICAgICAgPz8gY29sdW1uLnR5cGUsXG4gICAgICAgIGxhYmVsOiBmaWx0ZXI/LmxhYmVsXG4gICAgICAgICAgfHwgdGhpcy5fZ3JvdXBzQnlJZC5nZXQoZmlsdGVyPy5maWx0ZXJHcm91cElkID8/IC0xKT8ubGFiZWxcbiAgICAgICAgICB8fCB0aGlzLl9odW1hbml6ZShjb2x1bW4uY29sdW1uKSxcbiAgICAgICAgcGxhY2VtZW50LFxuICAgICAgICBjb21wb25lbnQ6ICF0aGlzLmlzVmFsdWUoKSAmJiBzaG93bk9uQ29tcG9uZW50KGdyb3VwPy5sZXZlbCksXG4gICAgICAgIHR5cGVTZWxlY3Q6IHR5cGVTZWxlY3RTdGF0ZShjb2x1bW4udHlwZXMsICEhZmlsdGVyLCB0aGlzLnJlcG9ydC52aWV3ZXJGZWF0dXJlcyksXG4gICAgICAgIHBsYWNlbWVudE9wdGlvbnM6IHRoaXMuaXNWYWx1ZSgpXG4gICAgICAgICAgPyB2YWx1ZVBsYWNlbWVudE9wdGlvbnMobGV2ZWxDaG9pY2VzLCBncm91cD8ubGV2ZWwpXG4gICAgICAgICAgOiBiYXJQbGFjZW1lbnRPcHRpb25zKGxldmVsQ2hvaWNlcywgcGxhY2VtZW50KSxcbiAgICAgICAgY29tcG9uZW50VG9nZ2xlOiBjb21wb25lbnRUb2dnbGVTdGF0ZShwbGFjZW1lbnQpLFxuICAgICAgfTtcbiAgICB9KSk7XG4gIH1cblxuICAvLyBXaGV0aGVyIHRoZSBjb21wb25lbnQgc2l0cyBvbiBhIHBhZ2U6IGFtb25nIGl0cyBjb21wb25lbnRzLCBvciwgZm9yIGFcbiAgLy8gdmFsdWUsIGl0cyB2YWx1ZXMuIEEgaGVhZGVyIG9yIGZvb3RlciBjb21wb25lbnQgb3IgdmFsdWUgc2l0cyBvbiBub25lLFxuICAvLyBzbyBpdHMgZmlsdGVycyBjYW5ub3QgYmUgcGFnZSBmaWx0ZXJzLlxuICBwcml2YXRlIF9vblBhZ2UoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICh0aGlzLnJlcG9ydC5wYWdlcyA/PyBbXSlcbiAgICAgIC5zb21lKChwYWdlKSA9PiBbLi4uKHBhZ2UuY29tcG9uZW50cyA/PyBbXSksIC4uLihwYWdlLnZhbHVlcyA/PyBbXSldXG4gICAgICAgIC5zb21lKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZS5pZCA9PT0gdGhpcy5jb21wb25lbnQuaWQpKTtcbiAgfVxuXG4gIC8vIEFmdGVyIGFueSBmaWx0ZXIgbXV0YXRpb246IHJlLWZldGNoIHRoZSByZXBvcnQgc28gdGhlIGRpYWxvZydzIGZpbHRlciBsaXN0XG4gIC8vIChhbmQgdGhlIHBhcmVudCBjYW52YXMsIG9uIGNsb3NlKSByZWZsZWN0IHRoZSBuZXcgZ3JvdXBzL2xldmVscy5cbiAgcHJpdmF0ZSBfYWZ0ZXJNdXRhdGlvbigpOiB2b2lkIHtcbiAgICB0aGlzLmZpbHRlcnNDaGFuZ2VkLmVtaXQoKTtcblxuICAgIHRoaXMuX3JlcG9ydERhdGEuZ2V0KHRoaXMucmVwb3J0LmlkKVxuICAgICAgLnN1YnNjcmliZSgocmVwb3J0OiBSZXBvcnQpID0+IHtcbiAgICAgICAgdGhpcy5yZXBvcnQgPSByZXBvcnQ7XG4gICAgICAgIHRoaXMuX3NlZWRGaWx0ZXJzKHJlcG9ydCwgdGhpcy5jb21wb25lbnQuaWQpO1xuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9tdXRhdGlvbkVycm9yKGVycm9yOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLl9tZXNzYWdlLmVycm9yKGVycm9yPy5lcnJvcj8ubWVzc2FnZSA/PyBlcnJvcj8ubWVzc2FnZSA/PyAnRmlsdGVyIG9wZXJhdGlvbiBmYWlsZWQnKTtcbiAgICAvLyBSZS1zZWVkIGZyb20gdGhlIHNlcnZlciBzbyB0aGUgb3B0aW1pc3RpYyB0b2dnbGUgc25hcHMgYmFjayB0byB0cnV0aC5cbiAgICB0aGlzLl9hZnRlck11dGF0aW9uKCk7XG4gIH1cblxuICAvLyBUaGUgY29tcG9uZW50J3MgZmlsdGVycyBhbmQgdGhlIGdyb3VwcyB0aGV5IHNpdCBpbiwgZnJvbSB0aGUgcmVwb3J0IGFzXG4gIC8vIGxhc3QgbG9hZGVkLiBBIHZhbHVlIGlzIGxpc3RlZCBpbiBpdHMgcGFnZSdzIHZhbHVlcywgbm90IGl0cyBjb21wb25lbnRzLlxuICBwcml2YXRlIF9zZWVkRmlsdGVycyhyZXBvcnQ6IFJlcG9ydCwgY29tcG9uZW50SWQ6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuX2dyb3Vwc0J5SWQgPSBuZXcgTWFwKChyZXBvcnQuZmlsdGVyR3JvdXBzID8/IFtdKS5tYXAoKGdyb3VwKSA9PiBbZ3JvdXAuaWQsIGdyb3VwXSkpO1xuXG4gICAgY29uc3QgY29tcG9uZW50ID0gcmVwb3J0Q29tcG9uZW50cyhyZXBvcnQpXG4gICAgICAuZmluZCgoY2FuZGlkYXRlKSA9PiBjYW5kaWRhdGUuaWQgPT09IGNvbXBvbmVudElkKTtcblxuICAgIHRoaXMuX2ZpbHRlcnMgPSBjb21wb25lbnQ/LmZpbHRlcnMgPz8gW107XG4gICAgdGhpcy5fcmVidWlsZFJvd3MoKTtcbiAgfVxuXG4gIC8vIFRoZSBzdGF0ZW1lbnQgdGhlIFNRTCB0YWIgc2hvd3MuIEZldGNoZWQgcmF0aGVyIHRoYW4gcmVhZCBvZmYgdGhlXG4gIC8vIGNvbXBvbmVudDogYSBkZXJpdmVkIGNvbXBvbmVudCBzdG9yZXMgYSBkb2N1bWVudCwgbm90IFNRTCwgc28gaXRzXG4gIC8vIHN0YXRlbWVudCBvbmx5IGV4aXN0cyBvbmNlIHRoZSBiYWNrZW5kIGNvbXBpbGVzIGl0LlxuICAvL1xuICAvLyBMb2FkZWQgaW4gbmdPbkluaXQgYmVzaWRlIHRoZSBjb2x1bW5zLCBOT1Qgb24gdGFiIGFjdGl2YXRpb24uIFRoZSB0YWJzIGFyZVxuICAvLyBub3QgbGF6eSAobm8gbWF0VGFiQ29udGVudCksIGFuZCBzd2l0Y2hpbmcgdGhlIHRhYi1ncm91cCdzIGBbKHNlbGVjdGVkKV1gXG4gIC8vIGJhbmFuYS1ib3ggdG8gYSBvbmUtd2F5IGJpbmRpbmcgcGx1cyAoc2VsZWN0ZWRDaGFuZ2UpIHRvIGdldCBhIGhvb2sgd291bGRcbiAgLy8gYnJlYWsgaXQ6IEZzVGFic0hlYWRlclRhYkdyb3VwRGlyZWN0aXZlIHNlbGYtYXNzaWducyBgdGhpcy5zZWxlY3RlZGAgYmVmb3JlXG4gIC8vIGl0IGVtaXRzLCBzbyB0aGUgZXZlbnQgaXMgZmlsdGVyZWQgb3V0IGFuZCB0aGUgbG9hZCB3b3VsZCBuZXZlciBmaXJlLiBPbmVcbiAgLy8gc21hbGwgcmVxdWVzdCB3aGVuIGEgZGlhbG9nIG9wZW5zIGlzIG5vdCB3b3J0aCB0aGF0IHJpc2suXG4gIHByaXZhdGUgX2xvYWRTcWwoKTogdm9pZCB7XG4gICAgdGhpcy5fcmVwb3J0RGF0YS5jb21wb25lbnRTcWwodGhpcy5yZXBvcnQuaWQsIHRoaXMuY29tcG9uZW50LmlkKVxuICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChwcmV2aWV3OiBSZXBvcnRDb21wb25lbnRTcWwpID0+IHtcbiAgICAgICAgICB0aGlzLnNxbC5zZXQocHJldmlldz8uc3FsID8/IG51bGwpO1xuICAgICAgICAgIHRoaXMuc3FsQmFzZWxpbmUuc2V0KCEhcHJldmlldz8uYmFzZWxpbmUpO1xuICAgICAgICAgIHRoaXMuc3FsVGltZXpvbmUuc2V0KHByZXZpZXc/LnRpbWV6b25lIHx8ICdVVEMnKTtcbiAgICAgICAgICB0aGlzLnNxbEVycm9yLnNldChwcmV2aWV3Py5lcnJvciA/PyBudWxsKTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IChlcnJvcikgPT4ge1xuICAgICAgICAgIHRoaXMuc3FsLnNldChudWxsKTtcbiAgICAgICAgICB0aGlzLnNxbEVycm9yLnNldChlcnJvcj8uZXJyb3I/Lm1lc3NhZ2UgPz8gJ0NvdWxkIG5vdCByZWFkIHRoZSBjb21wb25lbnQgU1FMJyk7XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX2xvYWRDb2x1bW5zKCk6IHZvaWQge1xuICAgIHRoaXMuX3JlcG9ydERhdGEuY29tcG9uZW50Q29sdW1ucyh0aGlzLnJlcG9ydC5pZCwgdGhpcy5jb21wb25lbnQuaWQpXG4gICAgICAuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dDogKGNvbHVtbnM6IFJlcG9ydEZpbHRlcmFibGVDb2x1bW5bXSkgPT4ge1xuICAgICAgICAgIHRoaXMuX2ZpbHRlcmFibGVDb2x1bW5zID0gY29sdW1ucyA/PyBbXTtcbiAgICAgICAgICB0aGlzLl9yZWJ1aWxkUm93cygpO1xuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKGVycm9yKSA9PiB7XG4gICAgICAgICAgdGhpcy5jb2x1bW5zRXJyb3Iuc2V0KGVycm9yPy5lcnJvcj8ubWVzc2FnZSA/PyAnQ291bGQgbm90IHJlYWQgdGhlIGNvbXBvbmVudCBjb2x1bW5zJyk7XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX2h1bWFuaXplKGNvbHVtbjogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gY29sdW1uXG4gICAgICAucmVwbGFjZSgvW19cXC1dKy9nLCAnICcpXG4gICAgICAucmVwbGFjZSgvXFxzKy9nLCAnICcpXG4gICAgICAudHJpbSgpXG4gICAgICAucmVwbGFjZSgvXFxiXFx3L2csIChjaGFyYWN0ZXIpID0+IGNoYXJhY3Rlci50b1VwcGVyQ2FzZSgpKTtcbiAgfVxufVxuIiwiPGZvcm1cbiAgICBmc0Zvcm1cbiAgICBbc3VibWl0XT1cInNhdmVcIj5cbiAgPGZzLWRpYWxvZz5cbiAgICA8aDEgbWF0LWRpYWxvZy10aXRsZT5cbiAgICAgIHt7IGNvbXBvbmVudC50aXRsZSB8fCAoaXNWYWx1ZSgpID8gJ1ZhbHVlJyA6ICdDb21wb25lbnQnKSB9fVxuICAgIDwvaDE+XG4gICAgPG1hdC1kaWFsb2ctY29udGVudD5cbiAgICAgIDxtYXQtdGFiLWdyb3VwIFsoc2VsZWN0ZWQpXT1cInNlbGVjdGVkVGFiXCI+XG4gICAgICAgIDxtYXQtdGFiXG4gICAgICAgICAgICBsYWJlbD1cIlNldHRpbmdzXCJcbiAgICAgICAgICAgIG5hbWU9XCJzZXR0aW5nc1wiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmcy1jb2x1bW4gdGFiLWJvZHlcIj5cbiAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICB7eyBpc1ZhbHVlKCkgPyAnTmFtZScgOiAnVGl0bGUnIH19XG4gICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICBtYXRJbnB1dFxuICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwidGl0bGVcIlxuICAgICAgICAgICAgICAgIG5hbWU9XCJ0aXRsZVwiXG4gICAgICAgICAgICAgICAgW2ZzRm9ybVJlcXVpcmVkXT1cImlzVmFsdWUoKVwiPlxuICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDwhLS0gQSBmb3JtdWxhIHZhbHVlIGlzIHJlYWQtb25seSBiZXlvbmQgaXRzIG5hbWU6IHdoYXQgaXQgd29ya3NcbiAgICAgICAgICAgICAgICAgb3V0IGlzIHRoZSBBSSdzIHRvIGNoYW5nZS4gQSBmb3JtdWxhIHRoaXMgdmlld2VyIGNhbm5vdFxuICAgICAgICAgICAgICAgICByZWFkIGhhcyBubyBsaW5lLCBhbmQgbm8gcm93LiAtLT5cbiAgICAgICAgICAgIEBpZiAoZm9ybXVsYUxpbmUoKSkge1xuICAgICAgICAgICAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgICAgICAgICAgPGZzLWxhYmVsPlxuICAgICAgICAgICAgICAgICAgRm9ybXVsYVxuICAgICAgICAgICAgICAgIDwvZnMtbGFiZWw+XG4gICAgICAgICAgICAgICAge3sgZm9ybXVsYUxpbmUoKSB9fVxuICAgICAgICAgICAgICAgIDxmcy1sYWJlbC1tZXNzYWdlPlxuICAgICAgICAgICAgICAgICAgV29ya2VkIG91dCBvbiB0aGUgc2VydmVyOyBpdCBmb2xsb3dzIHRoZSBmaWx0ZXJzIG9mIHRoZSB2YWx1ZXMgaXQgcmVhZHMuXG4gICAgICAgICAgICAgICAgPC9mcy1sYWJlbC1tZXNzYWdlPlxuICAgICAgICAgICAgICA8L2ZzLWxhYmVsLWZpZWxkPlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgPCEtLSBBIHZhbHVlIHNpdHMgaW5zaWRlIGEgdGV4dCBibG9jaydzIHdvcmRzOiBubyBib3gsIG5vIHBhZGRpbmcuIC0tPlxuICAgICAgICAgICAgQGlmICghaXNWYWx1ZSgpKSB7XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJzdWJoZWFkaW5nLTJcIj5cbiAgICAgICAgICAgICAgICBQYWRkaW5nXG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZ2VvbWV0cnktcm93XCI+XG4gICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgVG9wXG4gICAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICBtYXRJbnB1dFxuICAgICAgICAgICAgICAgICAgICBmc01hc2tOdW1iZXJcbiAgICAgICAgICAgICAgICAgICAgW3NjYWxlXT1cIjNcIlxuICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInBhZGRpbmdUb3BcIlxuICAgICAgICAgICAgICAgICAgICBuYW1lPVwicGFkZGluZ1RvcFwiXG4gICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1NaW5dPVwiMFwiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBtYXRUZXh0U3VmZml4PlxuICAgICAgICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICBSaWdodFxuICAgICAgICAgICAgICAgICAgPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgICAgZnNNYXNrTnVtYmVyXG4gICAgICAgICAgICAgICAgICAgIFtzY2FsZV09XCIzXCJcbiAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJwYWRkaW5nUmlnaHRcIlxuICAgICAgICAgICAgICAgICAgICBuYW1lPVwicGFkZGluZ1JpZ2h0XCJcbiAgICAgICAgICAgICAgICAgICAgW2ZzRm9ybU1pbl09XCIwXCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IG1hdFRleHRTdWZmaXg+XG4gICAgICAgICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIEJvdHRvbVxuICAgICAgICAgICAgICAgICAgPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgICAgZnNNYXNrTnVtYmVyXG4gICAgICAgICAgICAgICAgICAgIFtzY2FsZV09XCIzXCJcbiAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJwYWRkaW5nQm90dG9tXCJcbiAgICAgICAgICAgICAgICAgICAgbmFtZT1cInBhZGRpbmdCb3R0b21cIlxuICAgICAgICAgICAgICAgICAgICBbZnNGb3JtTWluXT1cIjBcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgbWF0VGV4dFN1ZmZpeD5cbiAgICAgICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgTGVmdFxuICAgICAgICAgICAgICAgICAgPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgICAgZnNNYXNrTnVtYmVyXG4gICAgICAgICAgICAgICAgICAgIFtzY2FsZV09XCIzXCJcbiAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJwYWRkaW5nTGVmdFwiXG4gICAgICAgICAgICAgICAgICAgIG5hbWU9XCJwYWRkaW5nTGVmdFwiXG4gICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1NaW5dPVwiMFwiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBtYXRUZXh0U3VmZml4PlxuICAgICAgICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICA8IS0tIEEgZGVyaXZlZCBLUEkncyBjYXJkOiB3aGF0IGEgcmlzZSBtZWFucywgYSB0YXJnZXQgYW5kIGFcbiAgICAgICAgICAgICAgICAgc3BhcmtsaW5lLiBUaGUgc2VydmVyIGNvbXB1dGVzIHRoZSBwcm9ncmVzcyBhbmQgdGhlIHBvaW50cy4gLS0+XG4gICAgICAgICAgICBAaWYgKGtwaUNhcmQoKSkge1xuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3ViaGVhZGluZy0yXCI+XG4gICAgICAgICAgICAgICAgQ2FyZFxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZnVsbC13aWR0aFwiPlxuICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICBJbmNyZWFzZSBpc1xuICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgIDxtYXQtc2VsZWN0XG4gICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cImluY3JlYXNlSXMoKVwiXG4gICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cImluY3JlYXNlSXMuc2V0KCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICBuYW1lPVwiaW5jcmVhc2VJc1wiPlxuICAgICAgICAgICAgICAgICAgQGZvciAob3B0aW9uIG9mIGtwaVBvbGFyaXR5T3B0aW9uczsgdHJhY2sgb3B0aW9uLnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIFt2YWx1ZV09XCJvcHRpb24udmFsdWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICB7eyBvcHRpb24ubmFtZSB9fVxuICAgICAgICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxuICAgICAgICAgICAgICAgIDxtYXQtaGludD5cbiAgICAgICAgICAgICAgICAgIENvbG9ycyB0aGUgY2hhbmdlIGFuZCBkZWNpZGVzIHdoZW4gdGhlIHRhcmdldCBpcyBtZXQuXG4gICAgICAgICAgICAgICAgPC9tYXQtaGludD5cbiAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZnVsbC13aWR0aFwiPlxuICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICBUYXJnZXRcbiAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICBmc01hc2tOdW1iZXJcbiAgICAgICAgICAgICAgICAgIFtzY2FsZV09XCI2XCJcbiAgICAgICAgICAgICAgICAgIFtzaWduZWRdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJ0YXJnZXRWYWx1ZSgpXCJcbiAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInRhcmdldFZhbHVlLnNldCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgIG5hbWU9XCJ0YXJnZXRWYWx1ZVwiXG4gICAgICAgICAgICAgICAgICBbdmFsaWRhdGVdPVwidmFsaWRhdGVUYXJnZXRcIj5cbiAgICAgICAgICAgICAgICBAaWYgKHRhcmdldFBlcmNlbnQoKSkge1xuICAgICAgICAgICAgICAgICAgPGRpdiBtYXRUZXh0U3VmZml4PlxuICAgICAgICAgICAgICAgICAgICAlXG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgPG1hdC1oaW50PlxuICAgICAgICAgICAgICAgICAgVGhlIHZhbHVlIHRvIHJlYWNoLiBMZWF2ZSBlbXB0eSBmb3Igbm8gdGFyZ2V0LlxuICAgICAgICAgICAgICAgIDwvbWF0LWhpbnQ+XG4gICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgIEBpZiAoaGFzVGFyZ2V0KCkpIHtcbiAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJmdWxsLXdpZHRoXCI+XG4gICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICBUYXJnZXQgbGFiZWxcbiAgICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInRhcmdldExhYmVsKClcIlxuICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJ0YXJnZXRMYWJlbC5zZXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgIG5hbWU9XCJ0YXJnZXRMYWJlbFwiPlxuICAgICAgICAgICAgICAgICAgPG1hdC1oaW50PlxuICAgICAgICAgICAgICAgICAgICBTaG93biBiZWZvcmUgdGhlIHRhcmdldCwgc3VjaCBhcyBHb2FsLiBFbXB0eSByZWFkcyBUYXJnZXQuXG4gICAgICAgICAgICAgICAgICA8L21hdC1oaW50PlxuICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPGZzLWxhYmVsLWZpZWxkPlxuICAgICAgICAgICAgICAgIDxtYXQtc2xpZGUtdG9nZ2xlXG4gICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInNwYXJrbGluZSgpXCJcbiAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwic3BhcmtsaW5lLnNldCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgbmFtZT1cInNwYXJrbGluZVwiPlxuICAgICAgICAgICAgICAgICAgU3BhcmtsaW5lXG4gICAgICAgICAgICAgICAgPC9tYXQtc2xpZGUtdG9nZ2xlPlxuICAgICAgICAgICAgICAgIDxtYXQtaGludD5cbiAgICAgICAgICAgICAgICAgIEEgc21hbGwgdHJlbmQgbGluZSBvZiB0aGUgdmFsdWUgb3ZlciBpdHMgbGFzdCBwZXJpb2RzLlxuICAgICAgICAgICAgICAgIDwvbWF0LWhpbnQ+XG4gICAgICAgICAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgICAgICAgIEBpZiAoc3BhcmtsaW5lKCkpIHtcbiAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJmdWxsLXdpZHRoXCI+XG4gICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICBTcGFya2xpbmUgcGVyaW9kXG4gICAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgIDxtYXQtc2VsZWN0XG4gICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwic3BhcmtsaW5lR3JhbnVsYXJpdHkoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwic3BhcmtsaW5lR3JhbnVsYXJpdHkuc2V0KCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgIG5hbWU9XCJzcGFya2xpbmVHcmFudWxhcml0eVwiPlxuICAgICAgICAgICAgICAgICAgICBAZm9yIChvcHRpb24gb2YgZ3JhbnVsYXJpdHlPcHRpb25zOyB0cmFjayBvcHRpb24udmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwib3B0aW9uLnZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICB7eyBvcHRpb24ubmFtZSB9fVxuICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxuICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZnVsbC13aWR0aFwiPlxuICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgU3BhcmtsaW5lIHBlcmlvZHNcbiAgICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICAgIGZzTWFza051bWJlclxuICAgICAgICAgICAgICAgICAgICBbc2NhbGVdPVwiMFwiXG4gICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInNwYXJrbGluZVBlcmlvZHMoKVwiXG4gICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInNwYXJrbGluZVBlcmlvZHMuc2V0KCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICBuYW1lPVwic3BhcmtsaW5lUGVyaW9kc1wiXG4gICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1SZXF1aXJlZF09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgW2ZzRm9ybUludGVnZXJdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1NaW5dPVwic3BhcmtsaW5lTWluUGVyaW9kc1wiXG4gICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1NYXhdPVwic3BhcmtsaW5lTWF4UGVyaW9kc1wiPlxuICAgICAgICAgICAgICAgICAgPG1hdC1oaW50PlxuICAgICAgICAgICAgICAgICAgICBIb3cgbWFueSBwZXJpb2RzIHRoZSBsaW5lIGNvdmVycywge3sgc3BhcmtsaW5lTWluUGVyaW9kcyB9fSB0byB7eyBzcGFya2xpbmVNYXhQZXJpb2RzIH19LlxuICAgICAgICAgICAgICAgICAgPC9tYXQtaGludD5cbiAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbWF0LXRhYj5cbiAgICAgICAgPCEtLSBBIGZvcm11bGEgcnVucyBubyBzdGF0ZW1lbnQgYW5kIGZvbGxvd3MgdGhlIGZpbHRlcnMgb2YgdGhlIHZhbHVlc1xuICAgICAgICAgICAgIGl0IHJlYWRzLCBzbyBpdCBoYXMgbmVpdGhlciBhIEZpbHRlcnMgbm9yIGFuIFNRTCB0YWIuIC0tPlxuICAgICAgICBAaWYgKCFpc0Zvcm11bGEoKSkge1xuICAgICAgICAgIDxtYXQtdGFiXG4gICAgICAgICAgICAgIGxhYmVsPVwiRmlsdGVyc1wiXG4gICAgICAgICAgICAgIG5hbWU9XCJmaWx0ZXJzXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGFiLWJvZHlcIj5cbiAgICAgICAgICAgICAgQGlmIChjb2x1bW5zRXJyb3IoKSkge1xuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWx0ZXJzLWVtcHR5IGVycm9yXCI+XG4gICAgICAgICAgICAgICAgICB7eyBjb2x1bW5zRXJyb3IoKSB9fVxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICB9IEBlbHNlIGlmIChyb3dzKCkubGVuZ3RoKSB7XG4gICAgICAgICAgICAgICAgPCEtLSBFdmVyeSBmaWx0ZXJhYmxlIGNvbHVtbi4gUGljayB3aGVyZSBpdHMgY29udHJvbCBzaG93czogaW5cbiAgICAgICAgICAgICAgICAgICAgIHRoZSByZXBvcnQgYmFyIChldmVyeSBwYWdlLCBvciB0aGlzIHBhZ2Ugb25seSksIG9uIHRoaXNcbiAgICAgICAgICAgICAgICAgICAgIGNvbXBvbmVudCwgYm90aCwgb3IgbmVpdGhlci4gVGhlIGludGVyZmFjZSBmb2xsb3dzIHRoZVxuICAgICAgICAgICAgICAgICAgICAgZGF0YTsgYSBudW1lcmljIGNvbHVtbiBjYW4gYmUgdmFsdWVzIG9yIGEgbnVtYmVyIHJhbmdlLlxuICAgICAgICAgICAgICAgICAgICAgQSB2YWx1ZSBzaXRzIGluc2lkZSB0ZXh0IGFuZCBoYXMgbm8gY29tcG9uZW50IHRvIHNob3cgYVxuICAgICAgICAgICAgICAgICAgICAgY29udHJvbCBvbiwgc28gaXQgZ2V0cyB0aGUgcmVwb3J0IGJhciBjb2x1bW4gb25seS4gLS0+XG4gICAgICAgICAgICAgICAgPHRhYmxlIGNsYXNzPVwiZmlsdGVyLXRhYmxlXCI+XG4gICAgICAgICAgICAgICAgICA8dGhlYWQ+XG4gICAgICAgICAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgICAgICAgICA8dGggY2xhc3M9XCJmaWx0ZXItY29sLW5hbWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIEZpbHRlclxuICAgICAgICAgICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgPHRoIGNsYXNzPVwiZmlsdGVyLWNvbC10eXBlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBUeXBlXG4gICAgICAgICAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICA8dGggY2xhc3M9XCJmaWx0ZXItY29sLXNlbGVjdFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgUmVwb3J0IGJhclxuICAgICAgICAgICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgQGlmICghaXNWYWx1ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGggY2xhc3M9XCJmaWx0ZXItY29sLXRvZ2dsZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICBUaGlzIGNvbXBvbmVudFxuICAgICAgICAgICAgICAgICAgICAgICAgPC90aD5cbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgICA8L3RoZWFkPlxuICAgICAgICAgICAgICAgICAgPHRib2R5PlxuICAgICAgICAgICAgICAgICAgICBAZm9yIChyb3cgb2Ygcm93cygpOyB0cmFjayByb3cuY29sdW1uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgPHRyPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiZmlsdGVyLWNvbC1uYW1lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHt7IHJvdy5sYWJlbCB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cImZpbHRlci1jb2wtdHlwZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICBAaWYgKHJvdy50eXBlU2VsZWN0LnNob3cpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3N1YnNjcmlwdFNpemluZ109XCInZHluYW1pYydcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbWF0VG9vbHRpcF09XCJyb3cudHlwZVNlbGVjdC50b29sdGlwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXNlbGVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtwYW5lbFdpZHRoXT1cIm51bGxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInJvdy50eXBlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJzZXRUeXBlKHJvdywgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxPcHRpb25zXT1cInsgc3RhbmRhbG9uZTogdHJ1ZSB9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwicm93LnR5cGVTZWxlY3QuZGlzYWJsZWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFyaWEtbGFiZWw9XCJUeXBlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBmb3IgKG9wdGlvbiBvZiB0eXBlT3B0aW9uczsgdHJhY2sgb3B0aW9uLnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gW3ZhbHVlXT1cIm9wdGlvbi52YWx1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgb3B0aW9uLm5hbWUgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyB0eXBlTGFiZWwocm93LnR5cGUpIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJmaWx0ZXItY29sLXNlbGVjdFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgW3N1YnNjcmlwdFNpemluZ109XCInZHluYW1pYydcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8bWF0LXNlbGVjdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGFuZWxXaWR0aF09XCJudWxsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwicm93LnBsYWNlbWVudFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInNldFBsYWNlbWVudChyb3csICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbE9wdGlvbnNdPVwieyBzdGFuZGFsb25lOiB0cnVlIH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmlhLWxhYmVsPVwiUmVwb3J0IGJhclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQGZvciAob3B0aW9uIG9mIHJvdy5wbGFjZW1lbnRPcHRpb25zOyB0cmFjayBvcHRpb24udmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gW3ZhbHVlXT1cIm9wdGlvbi52YWx1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IG9wdGlvbi5uYW1lIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgQGlmICghaXNWYWx1ZSgpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cImZpbHRlci1jb2wtdG9nZ2xlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zbGlkZS10b2dnbGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInJvdy5jb21wb25lbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwic2V0Q29tcG9uZW50KHJvdywgJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbE9wdGlvbnNdPVwieyBzdGFuZGFsb25lOiB0cnVlIH1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cInJvdy5jb21wb25lbnRUb2dnbGUuZGlzYWJsZWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21hdFRvb2x0aXBdPVwicm93LmNvbXBvbmVudFRvZ2dsZS50b29sdGlwXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtc2xpZGUtdG9nZ2xlPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIDwvdGJvZHk+XG4gICAgICAgICAgICAgICAgPC90YWJsZT5cbiAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZpbHRlcnMtZW1wdHlcIj5cbiAgICAgICAgICAgICAgICAgIFRoaXMgY29tcG9uZW50IGhhcyBubyBmaWx0ZXJhYmxlIGNvbHVtbnMgeWV0IOKAlCBnaXZlIGl0IHNvbWUgU1FMIGZpcnN0LlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L21hdC10YWI+XG4gICAgICAgICAgPG1hdC10YWJcbiAgICAgICAgICAgICAgbGFiZWw9XCJTUUxcIlxuICAgICAgICAgICAgICBuYW1lPVwic3FsXCI+XG4gICAgICAgICAgICA8ZGl2IGNsYXNzPVwidGFiLWJvZHlcIj5cbiAgICAgICAgICAgICAgQGlmIChzcWxFcnJvcigpKSB7XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZpbHRlcnMtZW1wdHkgZXJyb3JcIj5cbiAgICAgICAgICAgICAgICAgIHt7IHNxbEVycm9yKCkgfX1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgfSBAZWxzZSBpZiAoc3FsKCkpIHtcbiAgICAgICAgICAgICAgICBAaWYgKHNxbEJhc2VsaW5lKCkpIHtcbiAgICAgICAgICAgICAgICAgIDwhLS0gQSBkZXJpdmVkIGNvbXBvbmVudCdzIHN0YXRlbWVudCBpcyBjb21waWxlZCBmcm9tIGl0c1xuICAgICAgICAgICAgICAgICAgICAgICBkb2N1bWVudCB3aXRoIG5vIHZpZXdlciBzdGF0ZSwgc28gaXQgaXMgbm90IGJ5dGUtZm9yLWJ5dGVcbiAgICAgICAgICAgICAgICAgICAgICAgd2hhdCBwcm9kdWNlZCB0aGUgbnVtYmVycyBvbiBzY3JlZW4uIFNhaWQgaGVyZSByYXRoZXIgdGhhblxuICAgICAgICAgICAgICAgICAgICAgICBsZWZ0IGZvciB0aGUgcmVhZGVyIHRvIGRpc2NvdmVyLiAtLT5cbiAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWx0ZXJzLWVtcHR5XCI+XG4gICAgICAgICAgICAgICAgICAgIENvbXBpbGVkIGZyb20gdGhpcyBjb21wb25lbnQncyBxdWVyeSDigJQgbm8gZmlsdGVycyBhcHBsaWVkLCB0aW1lcyBpbiB7eyBzcWxUaW1lem9uZSgpIH19LlxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDxwcmUgY2xhc3M9XCJjb2RlLWJsb2NrXCI+e3sgc3FsKCkgfX08L3ByZT5cbiAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZpbHRlcnMtZW1wdHlcIj5cbiAgICAgICAgICAgICAgICAgIFRoaXMgY29tcG9uZW50IGhhcyBubyBTUUwgeWV0LlxuICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L21hdC10YWI+XG4gICAgICAgIH1cbiAgICAgICAgPG1hdC10YWJcbiAgICAgICAgICAgIGxhYmVsPVwiQ29uZmlnXCJcbiAgICAgICAgICAgIG5hbWU9XCJjb25maWdcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwidGFiLWJvZHlcIj5cbiAgICAgICAgICAgIDxwcmUgY2xhc3M9XCJjb2RlLWJsb2NrXCI+XG4gICAgICAgICAgICAgIHt7IGNvbmZpZ0pzb24gfX1cbiAgICAgICAgICAgIDwvcHJlPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L21hdC10YWI+XG4gICAgICA8L21hdC10YWItZ3JvdXA+XG4gICAgPC9tYXQtZGlhbG9nLWNvbnRlbnQ+XG4gICAgPG1hdC1kaWFsb2ctYWN0aW9ucz5cbiAgICAgIDwhLS0gU2F2ZSB8IERlbGV0ZSB8IENhbmNlbCwgdGhlIHN0YW5kYXJkIG9yZGVyLiBmcy1mb3JtLWRpYWxvZy1hY3Rpb25zXG4gICAgICAgICAgIHJlbmRlcnMgaXRzIG93biBTYXZlL0RvbmUgQkVGT1JFIHRoZSBwcm9qZWN0ZWQgY29udGVudCwgd2hpY2ggd291bGRcbiAgICAgICAgICAgcHV0IERlbGV0ZSBhZnRlciBDYW5jZWwsIHNvIGBbc2F2ZV09XCJmYWxzZVwiYCBmb290cyB0aGUgcm93IGhlcmUgYW5kXG4gICAgICAgICAgIGFsbCB0aHJlZSBidXR0b25zIGFyZSBwcm9qZWN0ZWQgaW4gb3JkZXIuIFNhdmUgc3VibWl0cyB0aGUgU2V0dGluZ3NcbiAgICAgICAgICAgdGFiOyB0aGUgb3RoZXIgdGFicyBwZXJzaXN0IGFzIHlvdSB0b3VjaCB0aGVtLCBzbyB0aGV5IGdldCBEb25lLiAtLT5cbiAgICAgIDxmcy1mb3JtLWRpYWxvZy1hY3Rpb25zIFtzYXZlXT1cImZhbHNlXCI+XG4gICAgICAgIEBpZiAoc2VsZWN0ZWRUYWIgPT09ICdzZXR0aW5ncycpIHtcbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgIG1hdC1idXR0b25cbiAgICAgICAgICAgICAgdHlwZT1cInN1Ym1pdFwiXG4gICAgICAgICAgICAgIGNvbG9yPVwicHJpbWFyeVwiPlxuICAgICAgICAgICAgU2F2ZVxuICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICAgIG1hdC1idXR0b25cbiAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgIGNvbG9yPVwicHJpbWFyeVwiXG4gICAgICAgICAgICAgIFttYXQtZGlhbG9nLWNsb3NlXT1cIm51bGxcIj5cbiAgICAgICAgICAgIERvbmVcbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgfVxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICBtYXQtYnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGNvbG9yPVwid2FyblwiXG4gICAgICAgICAgICAoY2xpY2spPVwiZGVsZXRlKClcIj5cbiAgICAgICAgICBEZWxldGVcbiAgICAgICAgPC9idXR0b24+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIG1hdC1idXR0b25cbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgY2xhc3M9XCJjYW5jZWwtYnV0dG9uXCJcbiAgICAgICAgICAgIFttYXQtZGlhbG9nLWNsb3NlXT1cIm51bGxcIj5cbiAgICAgICAgICBDYW5jZWxcbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2ZzLWZvcm0tZGlhbG9nLWFjdGlvbnM+XG4gICAgPC9tYXQtZGlhbG9nLWFjdGlvbnM+XG4gIDwvZnMtZGlhbG9nPlxuPC9mb3JtPiJdfQ==
621
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcG9uZW50LXNldHRpbmdzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy9kaWFsb2dzL2NvbXBvbmVudC1zZXR0aW5ncy9jb21wb25lbnQtc2V0dGluZ3MuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2RpYWxvZ3MvY29tcG9uZW50LXNldHRpbmdzL2NvbXBvbmVudC1zZXR0aW5ncy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBYyxZQUFZLEVBQVUsUUFBUSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsU0FBUyxHQUN0SCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQW1CLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTlELE9BQU8sRUFBRSxlQUFlLEVBQUUsZ0JBQWdCLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUFFLFlBQVksRUFBRSxjQUFjLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUM3SSxPQUFPLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsU0FBUyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDMUYsT0FBTyxFQUFFLFNBQVMsRUFBRSxhQUFhLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNwRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDakQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ25ELE9BQU8sRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDaEUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGdDQUFnQyxD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K0hBQ2QsZ0JBQWdCLHlHQUNoQixnQkFBZ0IsNEhBQ2hCLGNBQWMscUxBQ2QsWUFBWSw0TEFDWixPQUFPLDhFQUNQLFFBQVEsc0RBQ1IsU0FBUyxxSEFDVCxTQUFTLGlMQUNULE9BQU8sMklBQ1AsYUFBYSw2RkFDYixRQUFRLGlVQUNSLFNBQVMscUpBQ1QsU0FBUyx3ZUFDVCxjQUFjLDBVQUNkLFVBQVUsZ1JBQ1YsWUFBWTs7NEZBR0gsMEJBQTBCO2tCQWhDdEMsU0FBUztzQ0FHUyx1QkFBdUIsQ0FBQyxNQUFNLGNBQ25DLElBQUksV0FDUDt3QkFDUCxXQUFXO3dCQUNYLFlBQVk7d0JBQ1osWUFBWTt3QkFDWixjQUFjO3dCQUNkLGFBQWE7d0JBQ2IsWUFBWTt3QkFDWixhQUFhO3dCQUNiLGNBQWM7d0JBQ2QsZ0JBQWdCO3dCQUNoQixnQkFBZ0I7d0JBQ2hCLGNBQWM7d0JBQ2QsWUFBWTt3QkFDWixPQUFPO3dCQUNQLFFBQVE7d0JBQ1IsU0FBUzt3QkFDVCxTQUFTO3dCQUNULE9BQU87d0JBQ1AsYUFBYTt3QkFDYixRQUFRO3dCQUNSLFNBQVM7d0JBQ1QsU0FBUzt3QkFDVCxjQUFjO3dCQUNkLFVBQVU7d0JBQ1YsWUFBWTtxQkFDYiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIERlc3Ryb3lSZWYsIEVsZW1lbnRSZWYsIEV2ZW50RW1pdHRlciwgT25Jbml0LCBjb21wdXRlZCwgaW5qZWN0LCBzaWduYWwsIHZpZXdDaGlsZCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyB0YWtlVW50aWxEZXN0cm95ZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5pbXBvcnQgeyBBYnN0cmFjdENvbnRyb2wsIEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5pbXBvcnQgeyBNQVRfRElBTE9HX0RBVEEsIE1hdERpYWxvZ0FjdGlvbnMsIE1hdERpYWxvZ0Nsb3NlLCBNYXREaWFsb2dDb250ZW50LCBNYXREaWFsb2dSZWYsIE1hdERpYWxvZ1RpdGxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcbmltcG9ydCB7IE1hdEZvcm1GaWVsZCwgTWF0SGludCwgTWF0TGFiZWwsIE1hdFN1ZmZpeCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2Zvcm0tZmllbGQnO1xuaW1wb3J0IHsgTWF0QnV0dG9uLCBNYXRJY29uQnV0dG9uIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvYnV0dG9uJztcbmltcG9ydCB7IE1hdEljb24gfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pY29uJztcbmltcG9ydCB7IE1hdElucHV0IH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaW5wdXQnO1xuaW1wb3J0IHsgTWF0T3B0aW9uLCBNYXRTZWxlY3QgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zZWxlY3QnO1xuaW1wb3J0IHsgTWF0U2xpZGVUb2dnbGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9zbGlkZS10b2dnbGUnO1xuaW1wb3J0IHsgTWF0VGFic01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3RhYnMnO1xuaW1wb3J0IHsgTWF0VG9vbHRpcCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3Rvb2x0aXAnO1xuXG5pbXBvcnQgeyBGc0RpYWxvZ01vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL2RpYWxvZyc7XG5pbXBvcnQgeyBGc0Zvcm1Nb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9mb3JtJztcbmltcG9ydCB7IEZzTGFiZWxNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9sYWJlbCc7XG5pbXBvcnQgeyBGc01hc2tNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9tYXNrJztcbmltcG9ydCB7IEZzTWVudU1vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL21lbnUnO1xuaW1wb3J0IHsgRnNNZXNzYWdlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvbWVzc2FnZSc7XG5pbXBvcnQgeyBGc1Byb21wdCB9IGZyb20gJ0BmaXJlc3RpdGNoL3Byb21wdCc7XG5pbXBvcnQgeyBGc1RhYnNNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC90YWJzJztcblxuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgc3dpdGNoTWFwLCB0YXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IFJlcG9ydERhdGEgfSBmcm9tICcuLi8uLi9kYXRhL3JlcG9ydC5kYXRhJztcbmltcG9ydCB7IFJlcG9ydENoYW5nZVBvbGFyaXR5IH0gZnJvbSAnLi4vLi4vZW51bXMvcmVwb3J0LWNoYW5nZS1wb2xhcml0eS5lbnVtJztcbmltcG9ydCB7IFJlcG9ydFZhbHVlRm9ybWF0IH0gZnJvbSAnLi4vLi4vZW51bXMvcmVwb3J0LXZhbHVlLWZvcm1hdC5lbnVtJztcbmltcG9ydCB7IFJlcG9ydFZhbHVlRm9ybXVsYSB9IGZyb20gJy4uLy4uL2VudW1zL3JlcG9ydC12YWx1ZS1mb3JtdWxhLmVudW0nO1xuaW1wb3J0IHsgcmVzb2x2ZUZvcm1hdENvbnRleHQgfSBmcm9tICcuLi8uLi9mb3JtYXQnO1xuaW1wb3J0IHtcbiAgS1BJX1NQQVJLTElORV9ERUZBVUxUX0dSQU5VTEFSSVRZLFxuICBLUElfU1BBUktMSU5FX0RFRkFVTFRfUEVSSU9EUyxcbiAga3BpQ2FyZFNldHRpbmdzLFxuICBzYW1lS3BpQ2FyZFNldHRpbmdzLFxufSBmcm9tICcuLi8uLi9rcGktY2FyZCc7XG5pbXBvcnQge1xuICBDaGFydEdyYW51bGFyaXR5LFxuICBDb21wb25lbnRTZXR0aW5ncyxcbiAgR1JBTlVMQVJJVFlfT1BUSU9OUyxcbiAgS3BpQ2FyZFNldHRpbmdzLFxuICBLcGlDb25maWcsXG4gIFJlcG9ydCxcbiAgUmVwb3J0Q29tcG9uZW50LFxuICBSZXBvcnRDb21wb25lbnRTcWwsXG4gIFJlcG9ydEZpbHRlcixcbiAgUmVwb3J0RmlsdGVyR3JvdXAsXG4gIFJlcG9ydEZpbHRlckxldmVsLFxuICBSZXBvcnRGaWx0ZXJUeXBlLFxuICBSZXBvcnRGaWx0ZXJhYmxlQ29sdW1uLFxufSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL3JlcG9ydC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgREVGQVVMVF9DT01QT05FTlRfUEFERElORyB9IGZyb20gJy4uLy4uL2xheW91dCc7XG5pbXBvcnQge1xuICBGSUxURVJfVFlQRV9PUFRJT05TLFxuICBiYXJQbGFjZW1lbnQsXG4gIGJhclBsYWNlbWVudE9wdGlvbnMsXG4gIGNvbXBvbmVudFRvZ2dsZVN0YXRlLFxuICBmaWx0ZXJMZXZlbCxcbiAgZmlsdGVyTGV2ZWxDaG9pY2VzLFxuICBzaG93bk9uQ29tcG9uZW50LFxuICB0eXBlU2VsZWN0U3RhdGUsXG4gIHZhbHVlRmlsdGVyTGV2ZWwsXG4gIHZhbHVlUGxhY2VtZW50T3B0aW9ucyxcbn0gZnJvbSAnLi4vLi4vZmlsdGVyLXNldHRpbmdzLXJ1bGVzJztcbmltcG9ydCB7IEZpbHRlckJhclBsYWNlbWVudCB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvZmlsdGVyLWJhci1wbGFjZW1lbnQudHlwZSc7XG5pbXBvcnQgeyBGaWx0ZXJDb21wb25lbnRUb2dnbGVTdGF0ZSB9IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvZmlsdGVyLWNvbXBvbmVudC10b2dnbGUtc3RhdGUuaW50ZXJmYWNlJztcbmltcG9ydCB7IEZpbHRlclNldHRpbmdzT3B0aW9uIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9maWx0ZXItc2V0dGluZ3Mtb3B0aW9uLmludGVyZmFjZSc7XG5pbXBvcnQgeyBGaWx0ZXJUeXBlU2VsZWN0U3RhdGUgfSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL2ZpbHRlci10eXBlLXNlbGVjdC1zdGF0ZS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgVGV4dFRva2VuQ29udGV4dCwgZXNjYXBlSHRtbCwgZmllbGRUb2tlbiwgZmlsbFRpdGxlVG9rZW5zLCB0ZXh0RmllbGRzIH0gZnJvbSAnLi4vLi4vdGV4dCc7XG5pbXBvcnQgeyBvcGVyYW5kS2V5cywgcmVwb3J0Q29tcG9uZW50cywgdmFsdWVLZXkgfSBmcm9tICcuLi8uLi92YWx1ZXMnO1xuXG5cbi8vIFdoYXQgdGhlIGRpYWxvZyBoYW5kcyBiYWNrLiBUaGUgU2V0dGluZ3MgdGFiJ3MgU2F2ZSBjYXJyaWVzIHRoZSBuZXdcbi8vIGBzZXR0aW5nc2A7IERlbGV0ZSBjYXJyaWVzIGBkZWxldGVkYCBhbmQgbm8gc2V0dGluZ3MsIGJlY2F1c2UgdGhlIGNvbXBvbmVudFxuLy8gaXQgd2FzIG9wZW5lZCBmb3Igbm8gbG9uZ2VyIGV4aXN0cy4gRXZlcnkgb3RoZXIgZXhpdCAoQ2FuY2VsLCBEb25lLCBFc2NhcGUsXG4vLyBiYWNrZHJvcCkgY2xvc2VzIHdpdGggbm8gcmVzdWx0IOKAlCBmaWx0ZXIgd29yayBpcyBhbm5vdW5jZWQgYXMgaXQgaGFwcGVuc1xuLy8gaW5zdGVhZCwgdGhyb3VnaCBgZmlsdGVyc0NoYW5nZWRgLlxuZXhwb3J0IGludGVyZmFjZSBDb21wb25lbnRTZXR0aW5nc1Jlc3VsdCB7XG4gIHNldHRpbmdzPzogQ29tcG9uZW50U2V0dGluZ3M7XG4gIGRlbGV0ZWQ/OiBib29sZWFuO1xufVxuXG4vLyBXaGF0IHRoZSBkaWFsb2cgb3BlbnMgd2l0aDogdGhlIHJlcG9ydCwgdGhlIGNvbXBvbmVudCwgYW5kIHdoYXQgdGhlIHRva2Vuc1xuLy8gb2YgdGhlIGNvbXBvbmVudCdzIHRpdGxlIGZpbGwgd2l0aCB3aGVyZSBpdCBpcyBkcmF3biAoaXRzIHBhZ2Uncywgb3IgdGhlXG4vLyBtYXN0ZXIncyBmb3IgYSBoZWFkZXIgb3IgZm9vdGVyIGNvbXBvbmVudCksIGZvciB0aGUgdGl0bGUncyBJbnNlcnQgZmllbGRcbi8vIG1lbnUgYW5kIHRoZSBsaW5lIHNheWluZyBob3cgdGhlIHRpdGxlIHJlYWRzLlxuZXhwb3J0IGludGVyZmFjZSBDb21wb25lbnRTZXR0aW5nc0RpYWxvZ0RhdGEge1xuICByZXBvcnQ6IFJlcG9ydDtcbiAgY29tcG9uZW50OiBSZXBvcnRDb21wb25lbnQ7XG4gIHRva2VuczogVGV4dFRva2VuQ29udGV4dDtcbn1cblxuLy8gV2hhdCB0aGUgc2V0dGluZ3MgZW5kcG9pbnQgcmV0dXJucyBmb3IgdGhlIGNvbXBvbmVudDogaXRzIGlkIGFuZCwgZnJvbSBhXG4vLyBzZXJ2ZXIgdGhhdCBzYXZlcyBhIEtQSSdzIGNhcmQga2V5cywgdGhlIHdob2xlIGNvbmZpZyBhcyBzYXZlZC5cbmludGVyZmFjZSBDb21wb25lbnRTZXR0aW5nc1Jlc3BvbnNlIHtcbiAgaWQ6IG51bWJlcjtcbiAgY29uZmlnPzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gfCBudWxsO1xufVxuXG5cbi8vIFdoYXQgYSByaXNlIGluIGEgS1BJJ3MgdmFsdWUgbWVhbnMsIGZvciB0aGUgSW5jcmVhc2UgaXMgc2VsZWN0LlxuY29uc3QgS1BJX0NIQU5HRV9QT0xBUklUWV9PUFRJT05TOiB7IHZhbHVlOiBSZXBvcnRDaGFuZ2VQb2xhcml0eTsgbmFtZTogc3RyaW5nIH1bXSA9IFtcbiAgeyB2YWx1ZTogUmVwb3J0Q2hhbmdlUG9sYXJpdHkuR29vZCwgbmFtZTogJ0dvb2QgbmV3cyDigJQgYSByaXNlIHNob3dzIGdyZWVuJyB9LFxuICB7IHZhbHVlOiBSZXBvcnRDaGFuZ2VQb2xhcml0eS5CYWQsIG5hbWU6ICdCYWQgbmV3cyDigJQgYSByaXNlIHNob3dzIHJlZCcgfSxcbiAgeyB2YWx1ZTogUmVwb3J0Q2hhbmdlUG9sYXJpdHkuTmV1dHJhbCwgbmFtZTogJ05laXRoZXIg4oCUIG5vIGNvbG9yJyB9LFxuXTtcblxuLy8gQSBLUEkgc3BhcmtsaW5lJ3MgcGVyaW9kcyBzdGF5IHdpdGhpbiAyIHRvIDYwLlxuY29uc3QgS1BJX1NQQVJLTElORV9NSU5fUEVSSU9EUyA9IDI7XG5jb25zdCBLUElfU1BBUktMSU5FX01BWF9QRVJJT0RTID0gNjA7XG5cbi8vIEEgcGVyY2VudCBLUEkncyB0YXJnZXQgaXMgZW50ZXJlZCBhcyB0aGUgcGVyY2VudCBzaG93biAoMTUgZm9yIDE1JSkgYW5kXG4vLyBzdG9yZWQgYXMgdGhlIDAtMSByYXRpbyBpdHMgdmFsdWUgYXJyaXZlcyBpbjsgdGhlIHNlcnZlciByZWZ1c2VzIGEgc3RvcmVkXG4vLyB0YXJnZXQgYWJvdmUgMTAwLCB3aGljaCBpcyAxMCwwMDAlIGhlcmUuXG5jb25zdCBLUElfUEVSQ0VOVF9UQVJHRVRfTUFYID0gMTAwMDA7XG5cbi8vIEhvdyBhIGZvcm11bGEgdmFsdWUncyBTZXR0aW5ncyB0YWIgd3JpdGVzIG91dCB3aGF0IGl0IHdvcmtzIG91dCwgaW4gaXRzXG4vLyBvcGVyYW5kcycgbmFtZXMuXG5jb25zdCBGT1JNVUxBX0xJTkVTOiBSZWNvcmQ8UmVwb3J0VmFsdWVGb3JtdWxhLCAobmFtZXM6IHN0cmluZ1tdKSA9PiBzdHJpbmc+ID0ge1xuICBbUmVwb3J0VmFsdWVGb3JtdWxhLkNoYW5nZV06IChuYW1lcykgPT4gbmFtZXMuam9pbignIOKIkiAnKSxcbiAgW1JlcG9ydFZhbHVlRm9ybXVsYS5QZXJjZW50Q2hhbmdlXTogKFthLCBiXSkgPT4gYCUgY2hhbmdlIG9mICR7YX0gb3ZlciAke2J9YCxcbiAgW1JlcG9ydFZhbHVlRm9ybXVsYS5SYXRpb106IChuYW1lcykgPT4gbmFtZXMuam9pbignIMO3ICcpLFxuICBbUmVwb3J0VmFsdWVGb3JtdWxhLlN1bV06IChuYW1lcykgPT4gbmFtZXMuam9pbignICsgJyksXG59O1xuXG5cbi8vIE9uZSByb3cgb2YgdGhlIEZpbHRlcnMgdGFiIGxpc3Rpbmc6IGEgZmlsdGVyYWJsZSBjb2x1bW4sIGl0cyBmaWx0ZXIncyB0eXBlXG4vLyAodGhlIGluZmVycmVkIG9uZSwgdGhlIG9uZSBwaWNrZWQsIG9yIHRoZSBmaWx0ZXIncyBvd24pLCBhbmQgd2hlcmUgaXRzXG4vLyBmaWx0ZXIgc2hvd3MgKHRoZSBSZXBvcnQgYmFyIHNlbGVjdCBhbmQgdGhlIFRoaXMgY29tcG9uZW50IHRvZ2dsZSkuXG5pbnRlcmZhY2UgRmlsdGVyUm93IHtcbiAgY29sdW1uOiBzdHJpbmc7XG4gIHR5cGU6IFJlcG9ydEZpbHRlclR5cGU7XG4gIGxhYmVsOiBzdHJpbmc7XG4gIHBsYWNlbWVudDogRmlsdGVyQmFyUGxhY2VtZW50O1xuICBjb21wb25lbnQ6IGJvb2xlYW47XG4gIHR5cGVTZWxlY3Q6IEZpbHRlclR5cGVTZWxlY3RTdGF0ZTtcbiAgcGxhY2VtZW50T3B0aW9uczogRmlsdGVyU2V0dGluZ3NPcHRpb248RmlsdGVyQmFyUGxhY2VtZW50PltdO1xuICBjb21wb25lbnRUb2dnbGU6IEZpbHRlckNvbXBvbmVudFRvZ2dsZVN0YXRlO1xufVxuXG5cbi8vIENvbXBvbmVudCBzZXR0aW5ncywgaW4gdGFiczpcbi8vICAgU2V0dGluZ3Mg4oCUIHRpdGxlIGFuZCBjb250ZW50IHBhZGRpbmcgKGEgdmFsdWU6IGp1c3QgaXRzIG5hbWUsIHNpbmNlIGl0XG4vLyAgIHNpdHMgaW5zaWRlIGEgdGV4dCBibG9jaydzIHdvcmRzIGFuZCBoYXMgbm8gYm94KS4gQSB0aXRsZSBtYXkgY2FycnkgdGhlXG4vLyAgIHBhZ2UsIHJlcG9ydCBhbmQgZmlsdGVyIGZpZWxkcyBhIHRleHQgYmxvY2sncyB3b3JkcyBkbzogaXRzIEluc2VydCBmaWVsZFxuLy8gICBtZW51IHB1dHMgb25lIGluIGF0IHRoZSBjYXJldCwgYW5kIHRoZSBsaW5lIHVuZGVyIGl0IHNheXMgaG93IHRoZSB0aXRsZVxuLy8gICByZWFkcy4gT24gYSBkZXJpdmVkIEtQSSBpdHMgY2FyZDogd2hhdCBhIHJpc2UgbWVhbnMsIGEgdGFyZ2V0IGFuZCBhXG4vLyAgIHNwYXJrbGluZSAobnVtYmVyIGZvcm1hdHMgc3RheSB3aXRoIHRoZSBBSSkuIFBvc2l0aW9uL3NpemUgYXJlIHR1bmVkIGJ5XG4vLyAgIGRyYWdnaW5nIG9uIHRoZSBjYW52YXM7IGhlaWdodCBiZWhhdmlvdXIgZm9sbG93cyBmcm9tIHRoZSBjb21wb25lbnQgdHlwZS5cbi8vICAgRmlsdGVycyAg4oCUIE9ORSBsaXN0aW5nIG9mIGV2ZXJ5IGZpbHRlcmFibGUgY29sdW1uIG9uIHRoaXMgY29tcG9uZW50LiBFYWNoXG4vLyAgIHJvdyBjYXJyaWVzIHR3byB0b2dnbGVzOiBzaG93IGluIHRoZSByZXBvcnQgYmFyIGFuZC9vciBzaG93IG9uIHRoaXNcbi8vICAgY29tcG9uZW50IChib3RoLCBlaXRoZXIsIG9yIG5laXRoZXIpLiBUaGUgaW50ZXJmYWNlIChkYXRlIHJhbmdlIHZzIHZhbHVlXG4vLyAgIHBpY2tlcikgaXMgaW5mZXJyZWQgZnJvbSB0aGUgZGF0YSwgbmV2ZXIgY2hvc2VuLiBFYWNoIHRvZ2dsZSBwZXJzaXN0c1xuLy8gICBpbW1lZGlhdGVseSBhbmQgcmVmcmVzaGVzIHRoZSBpbi1kaWFsb2cgbGlzdC4gQSB2YWx1ZSBoYXMgbm8gY29tcG9uZW50XG4vLyAgIHRvIHNob3cgYSBmaWx0ZXIgb24sIHNvIGl0IGdldHMgdGhlIHJlcG9ydCBiYXIgdG9nZ2xlIG9ubHkuXG4vLyAgIFNRTCAvIENvbmZpZyDigJQgcmVhZC1vbmx5IGRpYWdub3N0aWNzLlxuLy8gQSBmb3JtdWxhIHZhbHVlIGhhcyBubyBGaWx0ZXJzIG9yIFNRTCB0YWI6IHRoZSBzZXJ2ZXIgd29ya3MgaXQgb3V0IG9mIG90aGVyXG4vLyB2YWx1ZXMgb24gaXRzIHBhZ2UsIHNvIGl0IHJ1bnMgbm8gc3RhdGVtZW50IGFuZCBmb2xsb3dzIHRoZSBmaWx0ZXJzIG9mIHRoZVxuLy8gdmFsdWVzIGl0IHJlYWRzLiBJdHMgU2V0dGluZ3MgdGFiIHNheXMgd2hhdCBpdCB3b3JrcyBvdXQsIHVuZGVyIGl0cyBuYW1lLlxuQENvbXBvbmVudCh7XG4gIHRlbXBsYXRlVXJsOiAnLi9jb21wb25lbnQtc2V0dGluZ3MuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9jb21wb25lbnQtc2V0dGluZ3MuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBGb3Jtc01vZHVsZSxcbiAgICBGc0Zvcm1Nb2R1bGUsXG4gICAgRnNNYXNrTW9kdWxlLFxuICAgIEZzRGlhbG9nTW9kdWxlLFxuICAgIEZzTGFiZWxNb2R1bGUsXG4gICAgRnNUYWJzTW9kdWxlLFxuICAgIE1hdFRhYnNNb2R1bGUsXG4gICAgTWF0RGlhbG9nVGl0bGUsXG4gICAgTWF0RGlhbG9nQ29udGVudCxcbiAgICBNYXREaWFsb2dBY3Rpb25zLFxuICAgIE1hdERpYWxvZ0Nsb3NlLFxuICAgIE1hdEZvcm1GaWVsZCxcbiAgICBNYXRIaW50LFxuICAgIE1hdExhYmVsLFxuICAgIE1hdFN1ZmZpeCxcbiAgICBNYXRCdXR0b24sXG4gICAgTWF0SWNvbixcbiAgICBNYXRJY29uQnV0dG9uLFxuICAgIE1hdElucHV0LFxuICAgIE1hdE9wdGlvbixcbiAgICBNYXRTZWxlY3QsXG4gICAgTWF0U2xpZGVUb2dnbGUsXG4gICAgTWF0VG9vbHRpcCxcbiAgICBGc01lbnVNb2R1bGUsXG4gIF0sXG59KVxuZXhwb3J0IGNsYXNzIENvbXBvbmVudFNldHRpbmdzQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcblxuICAvLyBBIGZpbHRlciB3YXMgYWRkZWQsIHJlbW92ZWQgb3IgcmUtbGV2ZWxsZWQsIHNvIHRoZSByZXBvcnQncyBmaWx0ZXIgZ3JvdXBzXG4gIC8vIGNoYW5nZWQuIFRob3NlIG11dGF0aW9ucyBwZXJzaXN0IHRoZSBtb21lbnQgdGhleSBhcmUgY2xpY2tlZCBhbmQgdGhlIGRpYWxvZ1xuICAvLyBjYW4gdGhlbiBiZSBkaXNtaXNzZWQgYnkgYSByb3V0ZSB0aGF0IGNhcnJpZXMgbm8gcmVzdWx0IChFc2NhcGUsIGJhY2tkcm9wKSxcbiAgLy8gc28gdGhlIHBhZ2UgaXMgdG9sZCBoZXJlIHJhdGhlciB0aGFuIHRocm91Z2ggdGhlIGNsb3NlIHJlc3VsdC5cbiAgcHVibGljIHJlYWRvbmx5IGZpbHRlcnNDaGFuZ2VkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIHB1YmxpYyBjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudDtcbiAgcHVibGljIHJlcG9ydDogUmVwb3J0O1xuXG4gIHB1YmxpYyBzZWxlY3RlZFRhYiA9ICdzZXR0aW5ncyc7XG5cbiAgcHVibGljIHJlYWRvbmx5IHRpdGxlID0gc2lnbmFsKCcnKTtcblxuICAvLyBXaGF0IHRoZSB0aXRsZSdzIEluc2VydCBmaWVsZCBtZW51IGxpc3RzLCBpbiBvcmRlcjogdGhlIHBhZ2UgYW5kIHJlcG9ydFxuICAvLyBmaWVsZHMsIHRoZW4gZWFjaCBmaWx0ZXIgb2YgdGhlIHJlcG9ydCBpbiB0aGUgZmlsdGVyIGJhcidzIG9yZGVyLiBBIHZhbHVlXG4gIC8vIHRva2VuIGlzIG5ldmVyIG9mZmVyZWQ6IHZhbHVlcyBiZWxvbmcgdG8gYSBwYWdlJ3MgdGV4dC5cbiAgcHVibGljIHJlYWRvbmx5IHRpdGxlRmllbGRzID0gY29tcHV0ZWQoKCkgPT4gdGV4dEZpZWxkcyh0aGlzLl9kYXRhLnRva2VucykpO1xuXG4gIC8vIEhvdyB0aGUgdGl0bGUgcmVhZHMgd2hlcmUgdGhlIGNvbXBvbmVudCBpcyBkcmF3biwgd2hpbGUgaXQgaG9sZHMgYSB0b2tlblxuICAvLyAoJ1NpZ24tdXBzIOKAlCBTZXB0ZW1iZXIgMjAyNicpOyBlbXB0eSBmb3IgYSB0aXRsZSB3aXRoIG5vbmUsIGFuZCBmb3IgYVxuICAvLyB2YWx1ZSwgd2hvc2UgTmFtZSBpcyBqdXN0IGl0cyBuYW1lLlxuICBwdWJsaWMgcmVhZG9ubHkgdGl0bGVTaG93bkFzID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IHRpdGxlID0gdGhpcy50aXRsZSgpO1xuICAgIGNvbnN0IHNob3duID0gZmlsbFRpdGxlVG9rZW5zKHRpdGxlLCB0aGlzLl9kYXRhLnRva2Vucyk7XG5cbiAgICByZXR1cm4gIXRoaXMuaXNWYWx1ZSgpICYmIHNob3duICE9PSB0aXRsZSA/IHNob3duIDogJyc7XG4gIH0pO1xuXG4gIC8vIFRoZSBkaWFsb2cncyBoZWFkaW5nOiB0aGUgdGl0bGUgYXMgaXQgcmVhZHMgKGEgdmFsdWUncyBOYW1lIGFzIGl0IGlzKSxcbiAgLy8gZWxzZSB3aGF0IHRoZSBjb21wb25lbnQgaXMuXG4gIHB1YmxpYyByZWFkb25seSBoZWFkaW5nID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5fc2hvd25UaXRsZSgpIHx8ICh0aGlzLmlzVmFsdWUoKSA/ICdWYWx1ZScgOiAnQ29tcG9uZW50JykpO1xuXG4gIC8vIENvbXBvbmVudCBwYWRkaW5nIGluIGluY2hlcy4gYG51bWJlciB8IHN0cmluZ2AgZm9yIHRoZSBzYW1lIHJlYXNvbiBhcyB0aGVcbiAgLy8gcGFnZSBkaW1lbnNpb25zIGluIHJlcG9ydC1zZXR0aW5nczogZnNNYXNrTnVtYmVyIHNlZWRzIGZyb20gdGhlIG51bWJlciBidXRcbiAgLy8gaGFuZHMgYmFjayB0aGUgdW5tYXNrZWQgc3RyaW5nLCBhbmQgc2F2ZSBjYXN0cyBpdCBvbmNlIG9uIHRoZSB3YXkgb3V0LlxuICBwdWJsaWMgcGFkZGluZ1RvcDogbnVtYmVyIHwgc3RyaW5nID0gREVGQVVMVF9DT01QT05FTlRfUEFERElORztcbiAgcHVibGljIHBhZGRpbmdSaWdodDogbnVtYmVyIHwgc3RyaW5nID0gREVGQVVMVF9DT01QT05FTlRfUEFERElORztcbiAgcHVibGljIHBhZGRpbmdCb3R0b206IG51bWJlciB8IHN0cmluZyA9IERFRkFVTFRfQ09NUE9ORU5UX1BBRERJTkc7XG4gIHB1YmxpYyBwYWRkaW5nTGVmdDogbnVtYmVyIHwgc3RyaW5nID0gREVGQVVMVF9DT01QT05FTlRfUEFERElORztcblxuICBwdWJsaWMgY29uZmlnSnNvbiA9ICcnO1xuXG4gIC8vIC0tLS0gS1BJIGNhcmQgc3RhdGUgKGEgZGVyaXZlZCBLUEkgb25seSkgLS0tLVxuICBwdWJsaWMgcmVhZG9ubHkga3BpUG9sYXJpdHlPcHRpb25zID0gS1BJX0NIQU5HRV9QT0xBUklUWV9PUFRJT05TO1xuICBwdWJsaWMgcmVhZG9ubHkgZ3JhbnVsYXJpdHlPcHRpb25zID0gR1JBTlVMQVJJVFlfT1BUSU9OUztcbiAgcHVibGljIHJlYWRvbmx5IHNwYXJrbGluZU1pblBlcmlvZHMgPSBLUElfU1BBUktMSU5FX01JTl9QRVJJT0RTO1xuICBwdWJsaWMgcmVhZG9ubHkgc3BhcmtsaW5lTWF4UGVyaW9kcyA9IEtQSV9TUEFSS0xJTkVfTUFYX1BFUklPRFM7XG4gIHB1YmxpYyByZWFkb25seSBrcGlDYXJkID0gc2lnbmFsKGZhbHNlKTtcbiAgLy8gQSB2YWx1ZSBpbnNpZGUgYSB0ZXh0IGJsb2NrOiBubyBib3gsIHNvIG5vIHBhZGRpbmcuXG4gIHB1YmxpYyByZWFkb25seSBpc1ZhbHVlID0gc2lnbmFsKGZhbHNlKTtcbiAgLy8gQSBmb3JtdWxhIHZhbHVlOiBubyBzdGF0ZW1lbnQsIGNvbHVtbnMgb3IgZmlsdGVycyBvZiBpdHMgb3duLlxuICBwdWJsaWMgcmVhZG9ubHkgaXNGb3JtdWxhID0gc2lnbmFsKGZhbHNlKTtcbiAgLy8gV2hhdCBhIGZvcm11bGEgd29ya3Mgb3V0LCBpbiBpdHMgb3BlcmFuZHMnIG5hbWVzOyBlbXB0eSBmb3IgYW55IG90aGVyXG4gIC8vIGNvbXBvbmVudC5cbiAgcHVibGljIHJlYWRvbmx5IGZvcm11bGFMaW5lID0gY29tcHV0ZWQoKCkgPT4gKHRoaXMuaXNGb3JtdWxhKCkgPyB0aGlzLl9mb3JtdWxhTGluZSgpIDogJycpKTtcbiAgcHVibGljIHJlYWRvbmx5IGluY3JlYXNlSXMgPSBzaWduYWw8UmVwb3J0Q2hhbmdlUG9sYXJpdHk+KFJlcG9ydENoYW5nZVBvbGFyaXR5Lkdvb2QpO1xuICAvLyBUaGUgdGFyZ2V0IGFzIHR5cGVkOiBmc01hc2tOdW1iZXIgaGFuZHMgYmFjayB0aGUgdW5tYXNrZWQgc3RyaW5nLiBFbXB0eVxuICAvLyBtZWFucyBubyB0YXJnZXQuIEEgcGVyY2VudCBLUEkncyBpcyBpbiBwZXJjZW50ICh0YXJnZXRQZXJjZW50KS5cbiAgcHVibGljIHJlYWRvbmx5IHRhcmdldFZhbHVlID0gc2lnbmFsPG51bWJlciB8IHN0cmluZyB8IG51bGw+KG51bGwpO1xuICBwdWJsaWMgcmVhZG9ubHkgdGFyZ2V0TGFiZWwgPSBzaWduYWwoJycpO1xuICBwdWJsaWMgcmVhZG9ubHkgdGFyZ2V0UGVyY2VudCA9IHNpZ25hbChmYWxzZSk7XG4gIHB1YmxpYyByZWFkb25seSBoYXNUYXJnZXQgPSBjb21wdXRlZCgoKSA9PiB0aGlzLl9udW1iZXIodGhpcy50YXJnZXRWYWx1ZSgpKSAhPT0gbnVsbCk7XG4gIHB1YmxpYyByZWFkb25seSBzcGFya2xpbmUgPSBzaWduYWwoZmFsc2UpO1xuICBwdWJsaWMgcmVhZG9ubHkgc3BhcmtsaW5lR3JhbnVsYXJpdHkgPSBzaWduYWw8Q2hhcnRHcmFudWxhcml0eT4oS1BJX1NQQVJLTElORV9ERUZBVUxUX0dSQU5VTEFSSVRZKTtcbiAgcHVibGljIHJlYWRvbmx5IHNwYXJrbGluZVBlcmlvZHMgPSBzaWduYWw8bnVtYmVyIHwgc3RyaW5nPihLUElfU1BBUktMSU5FX0RFRkFVTFRfUEVSSU9EUyk7XG5cbiAgLy8gLS0tLSBTUUwgdGFiIHN0YXRlIC0tLS1cbiAgLy8gVGhlIHN0YXRlbWVudCwgb25jZSBmZXRjaGVkLiBOdWxsIHdoaWxlIGl0IGlzIGluIGZsaWdodCwgYW5kIG51bGwgd2hlbiB0aGVcbiAgLy8gY29tcG9uZW50J3MgZG9jdW1lbnQgY291bGQgbm90IGJlIGNvbXBpbGVkIChzcWxFcnJvciB0aGVuIHNheXMgd2h5KS5cbiAgcHVibGljIHJlYWRvbmx5IHNxbCA9IHNpZ25hbDxzdHJpbmcgfCBudWxsPihudWxsKTtcbiAgLy8gVHJ1ZSB3aGVuIHRoZSBzdGF0ZW1lbnQgaXMgYSBERVJJVkVEIGJhc2VsaW5lOiBubyBmaWx0ZXJzLCB0aGUgYXV0aG9yZWRcbiAgLy8gZ3JhaW4sIHRpbWVzIGluIHRoZSByZXBvcnQncyBlZmZlY3RpdmUgem9uZS4gVGhlIHRhYiBzYXlzIHNvLCBiZWNhdXNlIHRoZVxuICAvLyBudW1iZXJzIG9uIHNjcmVlbiBjb21lIGZyb20gdGhpcyBzdGF0ZW1lbnQgcGx1cyB0aGUgdmlld2VyJ3Mgb3duIGNob2ljZXNcbiAgLy8gYW5kIHRoZSB0d28gY2FuIGRpZmZlci5cbiAgcHVibGljIHJlYWRvbmx5IHNxbEJhc2VsaW5lID0gc2lnbmFsKGZhbHNlKTtcbiAgLy8gVGhlIHpvbmUgdGhlIHN0YXRlbWVudCB3YXMgY29tcGlsZWQgaW46IHRoZSByZXBvcnQncyBlZmZlY3RpdmUgem9uZSwgc2VudFxuICAvLyB3aXRoIHRoZSBTUUwuIEEgc2VydmVyIHRvbyBvbGQgdG8gc2VuZCBpdCBjb21waWxlZCBpbiBVVEMuXG4gIHB1YmxpYyByZWFkb25seSBzcWxUaW1lem9uZSA9IHNpZ25hbCgnVVRDJyk7XG4gIHB1YmxpYyByZWFkb25seSBzcWxFcnJvciA9IHNpZ25hbDxzdHJpbmcgfCBudWxsPihudWxsKTtcblxuICAvLyAtLS0tIGZpbHRlciBtYW5hZ2VtZW50IHN0YXRlIC0tLS1cbiAgLy8gT25lIHJvdyBwZXIgZmlsdGVyYWJsZSBjb2x1bW4uIFRoZSBwbGFjZW1lbnQgYW5kIHRoZSB0b2dnbGUgY2hhbmdlXG4gIC8vIG9wdGltaXN0aWNhbGx5IG9uIGNsaWNrIChzbyB0aGUgVUkgbmV2ZXIgYmxpbmtzIHdoaWxlIHRoZSByZXF1ZXN0IGlzIGluXG4gIC8vIGZsaWdodCkgYW5kIHJlY29uY2lsZSBmcm9tIHRoZSBzZXJ2ZXIgb24gcmVsb2FkLlxuICBwdWJsaWMgcmVhZG9ubHkgcm93cyA9IHNpZ25hbDxGaWx0ZXJSb3dbXT4oW10pO1xuICBwdWJsaWMgcmVhZG9ubHkgY29sdW1uc0Vycm9yID0gc2lnbmFsPHN0cmluZyB8IG51bGw+KG51bGwpO1xuICAvLyBUaGUgVHlwZSBzZWxlY3QncyBjaG9pY2VzLiBBIHJvdydzIFR5cGUgc2VsZWN0LCBSZXBvcnQgYmFyIHNlbGVjdCBhbmRcbiAgLy8gVGhpcyBjb21wb25lbnQgdG9nZ2xlIGZvbGxvdyB0aGUgcnVsZXMgaW4gZmlsdGVyLXNldHRpbmdzLXJ1bGVzLnRzLlxuICBwdWJsaWMgcmVhZG9ubHkgdHlwZU9wdGlvbnMgPSBGSUxURVJfVFlQRV9PUFRJT05TO1xuXG4gIC8vIFRoZSByYXcgaW5wdXRzIHRoZSByb3dzIGFyZSBidWlsdCBmcm9tLlxuICBwcml2YXRlIF9maWx0ZXJhYmxlQ29sdW1uczogUmVwb3J0RmlsdGVyYWJsZUNvbHVtbltdID0gW107XG4gIHByaXZhdGUgX2ZpbHRlcnM6IFJlcG9ydEZpbHRlcltdID0gW107XG4gIHByaXZhdGUgX2dyb3Vwc0J5SWQgPSBuZXcgTWFwPG51bWJlciwgUmVwb3J0RmlsdGVyR3JvdXA+KCk7XG4gIC8vIFRoZSB0eXBlIHBpY2tlZCBmb3IgYSBjb2x1bW4gd2l0aCBubyBmaWx0ZXIgeWV0LCBzbyBhIHJlbG9hZCBrZWVwcyBpdC5cbiAgcHJpdmF0ZSBfcGlja2VkVHlwZXMgPSBuZXcgTWFwPHN0cmluZywgUmVwb3J0RmlsdGVyVHlwZT4oKTtcblxuICBwcml2YXRlIHJlYWRvbmx5IF90eXBlTGFiZWxzOiBSZWNvcmQ8UmVwb3J0RmlsdGVyVHlwZSwgc3RyaW5nPiA9IHtcbiAgICBzZWxlY3Q6ICdQaWNrIHZhbHVlcycsXG4gICAgZGF0ZVJhbmdlOiAnRGF0ZSByYW5nZScsXG4gICAga2V5d29yZDogJ1NlYXJjaCB0ZXh0JyxcbiAgICBudW1iZXJSYW5nZTogJ051bWJlciByYW5nZScsXG4gIH07XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfZGF0YTogQ29tcG9uZW50U2V0dGluZ3NEaWFsb2dEYXRhID0gaW5qZWN0KE1BVF9ESUFMT0dfREFUQSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX3RpdGxlSW5wdXQgPSB2aWV3Q2hpbGQ8RWxlbWVudFJlZjxIVE1MSW5wdXRFbGVtZW50Pj4oJ3RpdGxlSW5wdXQnKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfZGlhbG9nUmVmID0gaW5qZWN0PE1hdERpYWxvZ1JlZjxDb21wb25lbnRTZXR0aW5nc0NvbXBvbmVudCwgQ29tcG9uZW50U2V0dGluZ3NSZXN1bHQ+PihNYXREaWFsb2dSZWYpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9yZXBvcnREYXRhID0gaW5qZWN0KFJlcG9ydERhdGEpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9tZXNzYWdlID0gaW5qZWN0KEZzTWVzc2FnZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX3Byb21wdCA9IGluamVjdChGc1Byb21wdCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2Rlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZik7XG5cbiAgcHVibGljIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMucmVwb3J0ID0gdGhpcy5fZGF0YS5yZXBvcnQ7XG4gICAgdGhpcy5jb21wb25lbnQgPSB0aGlzLl9kYXRhLmNvbXBvbmVudDtcblxuICAgIHRoaXMudGl0bGUuc2V0KHRoaXMuY29tcG9uZW50LnRpdGxlID8/ICcnKTtcbiAgICB0aGlzLmlzVmFsdWUuc2V0KHRoaXMuY29tcG9uZW50LnR5cGUgPT09ICd2YWx1ZScpO1xuICAgIHRoaXMuaXNGb3JtdWxhLnNldCghIXRoaXMuY29tcG9uZW50LmNvbmZpZz8uZm9ybXVsYSk7XG5cbiAgICBjb25zdCBwYWRkaW5nID0gdGhpcy5jb21wb25lbnQuY29uZmlnPy5wYWRkaW5nO1xuICAgIHRoaXMucGFkZGluZ1RvcCA9IHBhZGRpbmc/LnRvcCA/PyBERUZBVUxUX0NPTVBPTkVOVF9QQURESU5HO1xuICAgIHRoaXMucGFkZGluZ1JpZ2h0ID0gcGFkZGluZz8ucmlnaHQgPz8gREVGQVVMVF9DT01QT05FTlRfUEFERElORztcbiAgICB0aGlzLnBhZGRpbmdCb3R0b20gPSBwYWRkaW5nPy5ib3R0b20gPz8gREVGQVVMVF9DT01QT05FTlRfUEFERElORztcbiAgICB0aGlzLnBhZGRpbmdMZWZ0ID0gcGFkZGluZz8ubGVmdCA/PyBERUZBVUxUX0NPTVBPTkVOVF9QQURESU5HO1xuXG4gICAgdGhpcy5jb25maWdKc29uID0gSlNPTi5zdHJpbmdpZnkodGhpcy5jb21wb25lbnQuY29uZmlnID8/IHt9LCBudWxsLCAyKTtcblxuICAgIHRoaXMuX3NlZWRLcGlDYXJkKCk7XG5cbiAgICB0aGlzLl9zZWVkRmlsdGVycyh0aGlzLnJlcG9ydCwgdGhpcy5jb21wb25lbnQuaWQpO1xuXG4gICAgLy8gQSBmb3JtdWxhIGhhcyBubyBzdGF0ZW1lbnQgdG8gY29tcGlsZSBhbmQgbm8gY29sdW1ucyB0byBmaWx0ZXIgb24sIGFuZFxuICAgIC8vIHRoZSBzZXJ2ZXIgd291bGQgcmVmdXNlIGJvdGggcmVxdWVzdHMuXG4gICAgaWYgKCF0aGlzLmlzRm9ybXVsYSgpKSB7XG4gICAgICB0aGlzLl9sb2FkQ29sdW1ucygpO1xuICAgICAgdGhpcy5fbG9hZFNxbCgpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEh1bWFuLWZyaWVuZGx5IG5hbWUgZm9yIHRoZSBpbmZlcnJlZCBpbnRlcmZhY2Ugc2hvd24gYmVzaWRlIGVhY2ggY29sdW1uLlxuICBwdWJsaWMgdHlwZUxhYmVsKHR5cGU6IFJlcG9ydEZpbHRlclR5cGUpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLl90eXBlTGFiZWxzW3R5cGVdID8/IHR5cGU7XG4gIH1cblxuICAvLyBDb25maXJtIGFuZCBkZWxldGUgaGVyZSwgd2hpbGUgdGhlIGRpYWxvZyBpcyBzdGlsbCBvcGVuLCB0aGVuIGNsb3NlIHdpdGggYVxuICAvLyBgZGVsZXRlZGAgcmVzdWx0IGZvciB0aGUgcGFnZSB0byBhY3Qgb24g4oCUIHRoZSBzYW1lIHNoYXBlIHRoZSByZXBvcnRcbiAgLy8gc2V0dGluZ3MgZGlhbG9nIHVzZXMgZm9yIGRlbGV0aW5nIGEgcmVwb3J0LlxuICAvL1xuICAvLyBUaGUgY29uZmlybSBzYXlzIGl0IGNhbm5vdCBiZSB1bmRvbmUgYmVjYXVzZSwgZnJvbSB0aGUgVUksIGl0IGNhbm5vdDogdGhlXG4gIC8vIHJvdyBpcyBzb2Z0LWRlbGV0ZWQgc2VydmVyLXNpZGUgYnV0IG5vdGhpbmcgaGVyZSByZXN0b3JlcyBhIGNvbXBvbmVudC5cbiAgLy8gQSB2YWx1ZSdzIGNvbmZpcm0gYWxzbyBzYXlzIHdoYXQgZ29lcyB3aXRoIGl0OiB0aGUgc2VydmVyIHRha2VzIGl0c1xuICAvLyB0b2tlbnMgb3V0IG9mIGV2ZXJ5IHRleHQgb24gaXRzIHBhZ2UsIG5vdCBqdXN0IHRoZSBvbmUgaXQgd2FzIG9wZW5lZCBmcm9tLFxuICAvLyBhbmQgZGVsZXRlcyB0aGUgZm9ybXVsYXMgdGhhdCByZWFkIGl0IChfZGVwZW5kZW50c05vdGUpLlxuICAvL1xuICAvLyBUaGUgcHJvbXB0IHJlbmRlcnMgaXRzIHRlbXBsYXRlIGFzIGh0bWwsIHNvIGV2ZXJ5IG5hbWUgaW4gaXQgaXMgZXNjYXBlZC5cbiAgcHVibGljIGRlbGV0ZSgpOiB2b2lkIHtcbiAgICB0aGlzLl9wcm9tcHQuY29uZmlybSh0aGlzLmlzVmFsdWUoKVxuICAgICAgPyB7XG4gICAgICAgIHRpdGxlOiAnRGVsZXRlIFZhbHVlJyxcbiAgICAgICAgdGVtcGxhdGU6IGBEZWxldGUgdGhlIHZhbHVlIFwiJHtlc2NhcGVIdG1sKHRoaXMuY29tcG9uZW50LnRpdGxlIHx8IHZhbHVlS2V5KHRoaXMuY29tcG9uZW50KSl9XCI/IEl0IGlzIGFsc28gdGFrZW4gb3V0IG9mIGV2ZXJ5IHRleHQgb24gdGhpcyBwYWdlLiBUaGlzIGNhbm5vdCBiZSB1bmRvbmUuJHt0aGlzLl9kZXBlbmRlbnRzTm90ZSgpfWAsXG4gICAgICB9XG4gICAgICA6IHtcbiAgICAgICAgdGl0bGU6ICdEZWxldGUgQ29tcG9uZW50JyxcbiAgICAgICAgdGVtcGxhdGU6IGBBcmUgeW91IHN1cmUgeW91IHdvdWxkIGxpa2UgdG8gZGVsZXRlIFwiJHtlc2NhcGVIdG1sKHRoaXMuX3Nob3duVGl0bGUoKSB8fCAndGhpcyBjb21wb25lbnQnKX1cIj8gVGhpcyBjYW5ub3QgYmUgdW5kb25lLmAsXG4gICAgICB9KVxuICAgICAgLnBpcGUoXG4gICAgICAgIHN3aXRjaE1hcCgoKSA9PiB0aGlzLl9yZXBvcnREYXRhLmRlbGV0ZUNvbXBvbmVudCh0aGlzLnJlcG9ydC5pZCwgdGhpcy5jb21wb25lbnQuaWQpKSxcbiAgICAgICAgdGFwKCgpID0+IHtcbiAgICAgICAgICB0aGlzLl9tZXNzYWdlLnN1Y2Nlc3ModGhpcy5pc1ZhbHVlKCkgPyAnVmFsdWUgZGVsZXRlZCcgOiAnQ29tcG9uZW50IGRlbGV0ZWQnKTtcbiAgICAgICAgICB0aGlzLl9kaWFsb2dSZWYuY2xvc2UoeyBkZWxldGVkOiB0cnVlIH0pO1xuICAgICAgICB9KSxcbiAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgpO1xuICB9XG5cbiAgLy8gUHV0cyBhIGZpZWxkJ3MgdG9rZW4gaW50byB0aGUgdGl0bGUgYXQgdGhlIGNhcmV0LCBvdmVyIGFueSB0ZXh0IHNlbGVjdGVkXG4gIC8vIHRoZXJlLCBhcyBpZiBpdCB3ZXJlIHR5cGVkOiB0aGUgbW9kZWwgZm9sbG93cyBhbmQgdGhlIGZpZWxkIGlzIGRpcnR5LiBUaGVcbiAgLy8gaW5wdXQga2VlcHMgaXRzIGNhcmV0IHdoaWxlIHRoZSBtZW51IGlzIG9wZW47IGZvY3VzIGNvbWVzIGJhY2sgdG8gaXQgb25jZVxuICAvLyB0aGUgbWVudSBoYXMgaGFuZGVkIGZvY3VzIGJhY2sgdG8gaXRzIGJ1dHRvbi5cbiAgcHVibGljIGluc2VydEZpZWxkKGZpZWxkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBpbnB1dCA9IHRoaXMuX3RpdGxlSW5wdXQoKT8ubmF0aXZlRWxlbWVudDtcbiAgICBpZiAoIWlucHV0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZW5kID0gaW5wdXQudmFsdWUubGVuZ3RoO1xuICAgIGlucHV0LnNldFJhbmdlVGV4dChmaWVsZFRva2VuKGZpZWxkKSwgaW5wdXQuc2VsZWN0aW9uU3RhcnQgPz8gZW5kLCBpbnB1dC5zZWxlY3Rpb25FbmQgPz8gZW5kLCAnZW5kJyk7XG4gICAgaW5wdXQuZGlzcGF0Y2hFdmVudChuZXcgRXZlbnQoJ2lucHV0JykpO1xuICAgIHNldFRpbWVvdXQoKCkgPT4gaW5wdXQuZm9jdXMoKSk7XG4gIH1cblxuICAvLyBBIHBlcmNlbnQgdGFyZ2V0J3MgYm91bmQsIGluIHRoZSBwZXJjZW50IGl0IGlzIHR5cGVkIGluLiBJdCByZWFkcyB0aGVcbiAgLy8gY29udHJvbCwgd2hpY2ggZnNGb3JtIHZhbGlkYXRlcyBiZWZvcmUgbmdNb2RlbENoYW5nZSB1cGRhdGVzIHRoZSBzaWduYWwuXG4gIHB1YmxpYyB2YWxpZGF0ZVRhcmdldCA9IChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wpOiB2b2lkID0+IHtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuX251bWJlcihjb250cm9sLnZhbHVlKTtcblxuICAgIGlmICh0aGlzLnRhcmdldFBlcmNlbnQoKSAmJiB2YWx1ZSAhPT0gbnVsbCAmJiB2YWx1ZSA+IEtQSV9QRVJDRU5UX1RBUkdFVF9NQVgpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQSBwZXJjZW50IHRhcmdldCBjYW4gYmUgYXQgbW9zdCAxMCwwMDAlJyk7XG4gICAgfVxuICB9O1xuXG4gIHB1YmxpYyBzYXZlID0gKCkgPT4ge1xuICAgIGNvbnN0IHNldHRpbmdzOiBDb21wb25lbnRTZXR0aW5ncyA9IHtcbiAgICAgIC8vIFRoZSBzZXJ2ZXIgdHJpbXMgYSB0aXRsZTsgYSB2YWx1ZSdzIE5hbWUgaXMgd2hhdCBpdHMgY2hpcHMgc2hvdywgc28gaXRcbiAgICAgIC8vIGdvZXMgYXMgdGhlIHNlcnZlciBrZWVwcyBpdC5cbiAgICAgIHRpdGxlOiB0aGlzLmlzVmFsdWUoKSA/IHRoaXMudGl0bGUoKS50cmltKCkgOiB0aGlzLnRpdGxlKCksXG4gICAgICBwYWRkaW5nOiB7XG4gICAgICAgIHRvcDogdGhpcy5fcGFkZGluZyh0aGlzLnBhZGRpbmdUb3ApLFxuICAgICAgICByaWdodDogdGhpcy5fcGFkZGluZyh0aGlzLnBhZGRpbmdSaWdodCksXG4gICAgICAgIGJvdHRvbTogdGhpcy5fcGFkZGluZyh0aGlzLnBhZGRpbmdCb3R0b20pLFxuICAgICAgICBsZWZ0OiB0aGlzLl9wYWRkaW5nKHRoaXMucGFkZGluZ0xlZnQpLFxuICAgICAgfSxcbiAgICB9O1xuXG4gICAgLy8gVGhlIGNhcmQga2V5cyBnbyBhcyBjb25maWcga2V5cyBiZXNpZGUgdGhlIHBhZGRpbmcgKGluY3JlYXNlSXMsIHRhcmdldFxuICAgIC8vIGFuZCBzcGFya2xpbmUsIG51bGwgdG8gcmVtb3ZlIG9uZSksIGFuZCBvbmx5IHdoZW4gdGhleSBjaGFuZ2VkLCBzbyBhXG4gICAgLy8gdGl0bGUgZWRpdCBuZXZlciB0b3VjaGVzIHRoZW0uXG4gICAgY29uc3Qga3BpID0gdGhpcy5rcGlDYXJkKCkgPyB0aGlzLl9rcGlDYXJkU2V0dGluZ3MoKSA6IG51bGw7XG4gICAgY29uc3Qga3BpQ2hhbmdlZCA9ICEha3BpXG4gICAgICAmJiAhc2FtZUtwaUNhcmRTZXR0aW5ncyhrcGksIGtwaUNhcmRTZXR0aW5ncyh0aGlzLmNvbXBvbmVudC5jb25maWcgYXMgS3BpQ29uZmlnKSk7XG5cbiAgICByZXR1cm4gdGhpcy5fcmVwb3J0RGF0YS51cGRhdGVDb21wb25lbnQodGhpcy5yZXBvcnQuaWQsIHRoaXMuY29tcG9uZW50LmlkLCB7XG4gICAgICB0aXRsZTogc2V0dGluZ3MudGl0bGUsXG4gICAgICAuLi4odGhpcy5pc1ZhbHVlKCkgPyB7fSA6IHsgcGFkZGluZzogc2V0dGluZ3MucGFkZGluZyB9KSxcbiAgICAgIC4uLihrcGlDaGFuZ2VkID8ga3BpIDoge30pLFxuICAgIH0pXG4gICAgICAucGlwZShcbiAgICAgICAgdGFwKChyZXNwb25zZTogQ29tcG9uZW50U2V0dGluZ3NSZXNwb25zZSkgPT4ge1xuICAgICAgICAgIC8vIFRoZSBjYXJkIGlzIGRyYXduIGZyb20gdGhlIGtleXMgdGhlIHNlcnZlciBzYXZlZCwgcmVhZCBiYWNrIGZyb21cbiAgICAgICAgICAvLyB0aGUgY29uZmlnIGl0IHJldHVybnMuIEEgc2VydmVyIHRoYXQgcmV0dXJucyBubyBjb25maWcgZGlkIG5vdFxuICAgICAgICAgIC8vIHNhdmUgdGhlbSwgc28gdGhlIGNhcmQga2VlcHMgd2hhdCBpdCBoYWQgYW5kIHRoZSBkaWFsb2cgc2F5cyBzby5cbiAgICAgICAgICBjb25zdCBzYXZlZCA9IGtwaUNoYW5nZWQgPyB0aGlzLl9zYXZlZEtwaUNhcmQocmVzcG9uc2UpIDogbnVsbDtcblxuICAgICAgICAgIGlmIChrcGlDaGFuZ2VkICYmICFzYXZlZCkge1xuICAgICAgICAgICAgdGhpcy5fbWVzc2FnZS53YXJuaW5nKCdDb21wb25lbnQgc2F2ZWQsIGJ1dCB0aGUgc2VydmVyIGRpZCBub3Qgc2F2ZSB0aGUgY2FyZCBzZXR0aW5ncycpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0aGlzLl9tZXNzYWdlLnN1Y2Nlc3ModGhpcy5pc1ZhbHVlKCkgPyAnVmFsdWUgc2F2ZWQnIDogJ0NvbXBvbmVudCBzYXZlZCcpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMuX2RpYWxvZ1JlZi5jbG9zZSh7IHNldHRpbmdzOiBzYXZlZCA/IHsgLi4uc2V0dGluZ3MsIGtwaTogc2F2ZWQgfSA6IHNldHRpbmdzIH0pO1xuICAgICAgICB9KSxcbiAgICAgICk7XG4gIH07XG5cbiAgLy8gVGhlIHR5cGUgYSBjb2x1bW4ncyBmaWx0ZXIgd2lsbCBiZSBtYWRlIHdpdGguIE9ubHkgYSBjb2x1bW4gd2l0aCBub1xuICAvLyBmaWx0ZXIgb2ZmZXJzIHRoZSBwaWNrICh0aGUgVHlwZSBzZWxlY3QgaXMgbG9ja2VkIG90aGVyd2lzZSksIGFuZCBub3RoaW5nXG4gIC8vIGlzIHNhdmVkIHVudGlsIHRoZSBmaWx0ZXIgaXMgbWFkZS5cbiAgcHVibGljIHNldFR5cGUocm93OiBGaWx0ZXJSb3csIHR5cGU6IFJlcG9ydEZpbHRlclR5cGUpOiB2b2lkIHtcbiAgICB0aGlzLl9waWNrZWRUeXBlcy5zZXQocm93LmNvbHVtbiwgdHlwZSk7XG4gICAgdGhpcy5fcGF0Y2hSb3cocm93LCB7IHR5cGUgfSk7XG4gIH1cblxuICAvLyBXaGVyZSB0aGUgcm93J3MgZmlsdGVyIHNob3dzIGluIHRoZSByZXBvcnQgYmFyLiBUaGlzIHBhZ2Ugb25seSBzaG93cyBpdFxuICAvLyBpbiBpdHMgcGFnZSdzIGJhciBhbG9uZSwgc28gdGhlIFRoaXMgY29tcG9uZW50IHRvZ2dsZSBnb2VzIG9mZiBhbmQgbG9ja3MuXG4gIC8vIEEgdmFsdWUgaGFzIHRoaXMgc2VsZWN0IG9ubHksIHdpdGggaXRzIG93biBydWxlcyAoX2FwcGx5VmFsdWVMZXZlbCkuXG4gIHB1YmxpYyBzZXRQbGFjZW1lbnQocm93OiBGaWx0ZXJSb3csIHBsYWNlbWVudDogRmlsdGVyQmFyUGxhY2VtZW50KTogdm9pZCB7XG4gICAgY29uc3QgcGF0Y2hlZCA9IHRoaXMuX3BhdGNoUm93KHJvdywge1xuICAgICAgcGxhY2VtZW50LFxuICAgICAgY29tcG9uZW50OiBwbGFjZW1lbnQgPT09ICdwYWdlJyA/IGZhbHNlIDogcm93LmNvbXBvbmVudCxcbiAgICAgIGNvbXBvbmVudFRvZ2dsZTogY29tcG9uZW50VG9nZ2xlU3RhdGUocGxhY2VtZW50KSxcbiAgICB9KTtcblxuICAgIGlmICh0aGlzLmlzVmFsdWUoKSkge1xuICAgICAgdGhpcy5fYXBwbHlWYWx1ZUxldmVsKHBhdGNoZWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9hcHBseUxldmVsKHBhdGNoZWQpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEEgdmFsdWUgaGFzIG5vIFRoaXMgY29tcG9uZW50IHRvZ2dsZS5cbiAgcHVibGljIHNldENvbXBvbmVudChyb3c6IEZpbHRlclJvdywgY29tcG9uZW50OiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaXNWYWx1ZSgpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fYXBwbHlMZXZlbCh0aGlzLl9wYXRjaFJvdyhyb3csIHsgY29tcG9uZW50IH0pKTtcbiAgfVxuXG4gIC8vIFBlcnNpc3QgdGhlIGxldmVsIHRoZSByb3cncyBjb250cm9scyBhc2sgZm9yLCB0aGVuIHJlY29uY2lsZSBvbiByZWxvYWQuXG4gIC8vIE5vIGxldmVsIOKGkiBubyBmaWx0ZXIgKHJlbW92ZWQpOyBvdGhlcndpc2UgdGhlIGZpbHRlciBleGlzdHMgYXQgdGhhdFxuICAvLyBsZXZlbC4gQSBzZXJ2ZXIgcmVmdXNhbCAoYSBwYWdlIGZpbHRlciB3aG9zZSBtZW1iZXJzIHNpdCBvbiB0d28gcGFnZXMpXG4gIC8vIHNob3dzIGl0cyBvd24gdGV4dCBhbmQgdGhlIHJvdyBzbmFwcyBiYWNrLlxuICBwcml2YXRlIF9hcHBseUxldmVsKHJvdzogRmlsdGVyUm93KTogdm9pZCB7XG4gICAgY29uc3QgbGV2ZWwgPSBmaWx0ZXJMZXZlbChyb3cucGxhY2VtZW50LCByb3cuY29tcG9uZW50KTtcbiAgICBjb25zdCBleGlzdGluZyA9IHRoaXMuX2ZpbHRlcnMuZmluZCgoZmlsdGVyKSA9PiBmaWx0ZXIuZmlsdGVyQ29sdW1uID09PSByb3cuY29sdW1uKTtcblxuICAgIGlmICghbGV2ZWwpIHtcbiAgICAgIGlmIChleGlzdGluZykge1xuICAgICAgICB0aGlzLl9ydW4odGhpcy5fcmVwb3J0RGF0YS5kZWxldGVGaWx0ZXIodGhpcy5yZXBvcnQuaWQsIGV4aXN0aW5nLmlkKSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgIHRoaXMuX3J1bih0aGlzLl9yZXBvcnREYXRhLnVwZGF0ZUZpbHRlckdyb3VwKHRoaXMucmVwb3J0LmlkLCBleGlzdGluZy5maWx0ZXJHcm91cElkLCB7IGxldmVsIH0pKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fYWRkRmlsdGVyKHJvdywgbGV2ZWwpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEEgdmFsdWUncyBSZXBvcnQgYmFyIHNlbGVjdCwgdGhlIG9ubHkgY29udHJvbCBpdCBoYXMuIEl0cyBmaWx0ZXIncyBncm91cFxuICAvLyBtYXkgYmUgc2hhcmVkICh0aGUgcmVwb3J0J3MgUGVyaW9kLCBzYXkpLCBhbmQgYSB2YWx1ZSBoYXMgbm8gc3RyaXAgb2YgaXRzXG4gIC8vIG93biwgc28gYSBwaWNrIG5ldmVyIGxvd2VycyB0aGUgZ3JvdXAgKHZhbHVlRmlsdGVyTGV2ZWwpLiBBIHBpY2sgdGhhdFxuICAvLyBtb3ZlcyBub3RoaW5nIHB1dHMgdGhlIHJvdyBiYWNrIGFzIHRoZSBncm91cCBzdGFuZHMuXG4gIHByaXZhdGUgX2FwcGx5VmFsdWVMZXZlbChyb3c6IEZpbHRlclJvdyk6IHZvaWQge1xuICAgIGNvbnN0IGV4aXN0aW5nID0gdGhpcy5fZmlsdGVycy5maW5kKChmaWx0ZXIpID0+IGZpbHRlci5maWx0ZXJDb2x1bW4gPT09IHJvdy5jb2x1bW4pO1xuICAgIGNvbnN0IGN1cnJlbnQgPSBleGlzdGluZyA/IHRoaXMuX2dyb3Vwc0J5SWQuZ2V0KGV4aXN0aW5nLmZpbHRlckdyb3VwSWQpPy5sZXZlbCA6IHVuZGVmaW5lZDtcbiAgICBjb25zdCBsZXZlbCA9IHZhbHVlRmlsdGVyTGV2ZWwocm93LnBsYWNlbWVudCwgY3VycmVudCk7XG5cbiAgICBpZiAoIWxldmVsKSB7XG4gICAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgICAgdGhpcy5fcnVuKHRoaXMuX3JlcG9ydERhdGEuZGVsZXRlRmlsdGVyKHRoaXMucmVwb3J0LmlkLCBleGlzdGluZy5pZCkpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoIWV4aXN0aW5nKSB7XG4gICAgICB0aGlzLl9hZGRGaWx0ZXIocm93LCBsZXZlbCk7XG4gICAgfSBlbHNlIGlmIChsZXZlbCAhPT0gY3VycmVudCkge1xuICAgICAgdGhpcy5fcnVuKHRoaXMuX3JlcG9ydERhdGEudXBkYXRlRmlsdGVyR3JvdXAodGhpcy5yZXBvcnQuaWQsIGV4aXN0aW5nLmZpbHRlckdyb3VwSWQsIHsgbGV2ZWwgfSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9yZWJ1aWxkUm93cygpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFRoZSB0eXBlIGdvZXMgb25seSB3aGVuIHRoZSBhdXRob3IgY291bGQgcGljayBpdDsgb3RoZXJ3aXNlIHRoZSBzZXJ2ZXJcbiAgLy8gaW5mZXJzIGl0LCBhcyBpdCBhbHdheXMgaGFzLlxuICBwcml2YXRlIF9hZGRGaWx0ZXIocm93OiBGaWx0ZXJSb3csIGxldmVsOiBSZXBvcnRGaWx0ZXJMZXZlbCk6IHZvaWQge1xuICAgIHRoaXMuX3J1bih0aGlzLl9yZXBvcnREYXRhLmFkZEZpbHRlcih0aGlzLnJlcG9ydC5pZCwgdGhpcy5jb21wb25lbnQuaWQsIHtcbiAgICAgIGZpbHRlckNvbHVtbjogcm93LmNvbHVtbixcbiAgICAgIGxhYmVsOiByb3cubGFiZWwsXG4gICAgICBsZXZlbCxcbiAgICAgIC4uLihyb3cudHlwZVNlbGVjdC5zaG93ID8geyB0eXBlOiByb3cudHlwZSB9IDoge30pLFxuICAgIH0pKTtcbiAgfVxuXG4gIC8vIEEgbmV3IHJvdyBvYmplY3QgcmF0aGVyIHRoYW4gYSBtdXRhdGlvbiwgc28gdGhlIHNpZ25hbCBzZWVzIHRoZSBjaGFuZ2U7XG4gIC8vIHRoZSBAZm9yIHRyYWNrcyB0aGUgY29sdW1uLCBzbyB0aGUgcm93J3MgY29udHJvbHMgc3Vydml2ZSB0aGUgc3dhcC5cbiAgcHJpdmF0ZSBfcGF0Y2hSb3cocm93OiBGaWx0ZXJSb3csIHBhdGNoOiBQYXJ0aWFsPEZpbHRlclJvdz4pOiBGaWx0ZXJSb3cge1xuICAgIGNvbnN0IHBhdGNoZWQgPSB7IC4uLnJvdywgLi4ucGF0Y2ggfTtcbiAgICB0aGlzLnJvd3MudXBkYXRlKChyb3dzKSA9PiByb3dzLm1hcCgoaXRlbSkgPT4gKGl0ZW0uY29sdW1uID09PSByb3cuY29sdW1uID8gcGF0Y2hlZCA6IGl0ZW0pKSk7XG5cbiAgICByZXR1cm4gcGF0Y2hlZDtcbiAgfVxuXG4gIC8vIFRoZSBzdG9yZWQgdGl0bGUgYXMgaXQgcmVhZHMgd2hlcmUgdGhlIGNvbXBvbmVudCBpcyBkcmF3biwgaXRzIHRva2Vuc1xuICAvLyBmaWxsZWQ7IGEgdmFsdWUncyBOYW1lIGFzIGl0IGlzLlxuICBwcml2YXRlIF9zaG93blRpdGxlKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuaXNWYWx1ZSgpID8gdGhpcy5jb21wb25lbnQudGl0bGUgPz8gJycgOiBmaWxsVGl0bGVUb2tlbnModGhpcy5jb21wb25lbnQudGl0bGUsIHRoaXMuX2RhdGEudG9rZW5zKTtcbiAgfVxuXG4gIC8vIFdoYXQgYSBmb3JtdWxhIHdvcmtzIG91dCwgbmFtaW5nIGVhY2ggb3BlcmFuZCBhcyBpdHMgY2hpcHMgZG8uIEFuIG9wIHRoaXNcbiAgLy8gdmlld2VyIGRvZXMgbm90IGtub3cgcmVhZHMgbm90aGluZy5cbiAgcHJpdmF0ZSBfZm9ybXVsYUxpbmUoKTogc3RyaW5nIHtcbiAgICBjb25zdCBmb3JtdWxhID0gdGhpcy5jb21wb25lbnQuY29uZmlnPy5mb3JtdWxhO1xuICAgIGNvbnN0IGxpbmUgPSBmb3JtdWxhID8gRk9STVVMQV9MSU5FU1tmb3JtdWxhLm9wXSA6IHVuZGVmaW5lZDtcbiAgICBjb25zdCB2YWx1ZXMgPSB0aGlzLl9sYXllclZhbHVlcygpO1xuXG4gICAgcmV0dXJuIGxpbmUgPyBsaW5lKG9wZXJhbmRLZXlzKHRoaXMuY29tcG9uZW50KS5tYXAoKGtleSkgPT4gdGhpcy5fdmFsdWVOYW1lKHZhbHVlcywga2V5KSkpIDogJyc7XG4gIH1cblxuICAvLyBUaGUgc2VudGVuY2UgYSBxdWVyeSB2YWx1ZSdzIGRlbGV0ZSBjb25maXJtIGVuZHMgd2l0aCB3aGVuIGZvcm11bGFzIG9uIGl0c1xuICAvLyBsYXllciByZWFkIGl0OiB0aGUgc2VydmVyIGRlbGV0ZXMgdGhvc2Ugd2l0aCBpdC4gRW1wdHkgd2hlbiBub25lIGRvZXMsIGFuZFxuICAvLyBmb3IgYSBmb3JtdWxhLCB3aG9zZSBvcGVyYW5kcyBzdGF5LlxuICBwcml2YXRlIF9kZXBlbmRlbnRzTm90ZSgpOiBzdHJpbmcge1xuICAgIGlmICh0aGlzLmlzRm9ybXVsYSgpKSB7XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuXG4gICAgY29uc3Qga2V5ID0gdmFsdWVLZXkodGhpcy5jb21wb25lbnQpO1xuICAgIGNvbnN0IG5hbWVzID0gdGhpcy5fbGF5ZXJWYWx1ZXMoKVxuICAgICAgLmZpbHRlcigodmFsdWUpID0+IG9wZXJhbmRLZXlzKHZhbHVlKS5pbmNsdWRlcyhrZXkpKVxuICAgICAgLm1hcCgodmFsdWUpID0+IGVzY2FwZUh0bWwodmFsdWUudGl0bGUgfHwgdmFsdWVLZXkodmFsdWUpKSk7XG5cbiAgICByZXR1cm4gbmFtZXMubGVuZ3RoID8gYCBUaGUgdmFsdWVzIHdvcmtlZCBvdXQgZnJvbSBpdCBhcmUgZGVsZXRlZCB0b286ICR7bmFtZXMuam9pbignLCAnKX0uYCA6ICcnO1xuICB9XG5cbiAgLy8gVGhlIHZhbHVlcyBvZiB0aGUgbGF5ZXIgdGhpcyB2YWx1ZSBiZWxvbmdzIHRvOiB0aGUgcGFnZSB3aG9zZSB2YWx1ZXMgaG9sZFxuICAvLyBpdCwgZWxzZSB0aGUgbWFzdGVyJ3MgKGEgaGVhZGVyIG9yIGZvb3RlciB2YWx1ZSkuXG4gIHByaXZhdGUgX2xheWVyVmFsdWVzKCk6IFJlcG9ydENvbXBvbmVudFtdIHtcbiAgICBjb25zdCBwYWdlID0gKHRoaXMucmVwb3J0LnBhZ2VzID8/IFtdKVxuICAgICAgLmZpbmQoKGNhbmRpZGF0ZSkgPT4gKGNhbmRpZGF0ZS52YWx1ZXMgPz8gW10pLnNvbWUoKHZhbHVlKSA9PiB2YWx1ZS5pZCA9PT0gdGhpcy5jb21wb25lbnQuaWQpKTtcblxuICAgIHJldHVybiAocGFnZSA/PyB0aGlzLnJlcG9ydC5tYXN0ZXIpPy52YWx1ZXMgPz8gW107XG4gIH1cblxuICAvLyBXaGF0IGEgdmFsdWUgaXMgY2FsbGVkIHdoZXJlIGl0cyBjaGlwcyBzaG93IGl0OiBpdHMgbmFtZSwgZWxzZSBpdHMga2V5LlxuICAvLyBUaGUgbmV3ZXN0IHZhbHVlIGhvbGRzIGEga2V5LCBhcyBpdCBkb2VzIGluIHRoZSB0ZXh0J3MgdG9rZW5zLlxuICBwcml2YXRlIF92YWx1ZU5hbWUodmFsdWVzOiBSZXBvcnRDb21wb25lbnRbXSwga2V5OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHZhbHVlID0gdmFsdWVzLmZpbHRlcigoY2FuZGlkYXRlKSA9PiB2YWx1ZUtleShjYW5kaWRhdGUpID09PSBrZXkpLnBvcCgpO1xuXG4gICAgcmV0dXJuIHZhbHVlPy50aXRsZSB8fCBrZXk7XG4gIH1cblxuICAvLyBBIGRlcml2ZWQgS1BJJ3MgY2FyZCBrZXlzLCBmcm9tIGl0cyBjb25maWcuIEEgc3FsLW1vZGUgS1BJIGNhbm5vdCBjYXJyeVxuICAvLyB0aGVtLCBzbyBpdCBnZXRzIG5vIGNhcmQgZmllbGRzLlxuICBwcml2YXRlIF9zZWVkS3BpQ2FyZCgpOiB2b2lkIHtcbiAgICBjb25zdCBjb25maWcgPSAodGhpcy5jb21wb25lbnQuY29uZmlnID8/IHt9KSBhcyBLcGlDb25maWc7XG5cbiAgICB0aGlzLmtwaUNhcmQuc2V0KHRoaXMuY29tcG9uZW50LnR5cGUgPT09ICdrcGknICYmICF0aGlzLmNvbXBvbmVudC5zcWwpO1xuICAgIHRoaXMuaW5jcmVhc2VJcy5zZXQoY29uZmlnLmluY3JlYXNlSXMgPz8gUmVwb3J0Q2hhbmdlUG9sYXJpdHkuR29vZCk7XG4gICAgdGhpcy50YXJnZXRQZXJjZW50LnNldChjb25maWcubWVhc3VyZT8uZm9ybWF0ID09PSBSZXBvcnRWYWx1ZUZvcm1hdC5QZXJjZW50XG4gICAgICAmJiByZXNvbHZlRm9ybWF0Q29udGV4dCh0aGlzLnJlcG9ydCkucmF0aW9QZXJjZW50KTtcbiAgICB0aGlzLnRhcmdldFZhbHVlLnNldCh0aGlzLl90YXJnZXRTaG93bihjb25maWcudGFyZ2V0Py52YWx1ZSA/PyBudWxsKSk7XG4gICAgdGhpcy50YXJnZXRMYWJlbC5zZXQoY29uZmlnLnRhcmdldD8ubGFiZWwgPz8gJycpO1xuICAgIHRoaXMuc3BhcmtsaW5lLnNldCghIWNvbmZpZy5zcGFya2xpbmUpO1xuICAgIHRoaXMuc3BhcmtsaW5lR3JhbnVsYXJpdHkuc2V0KGNvbmZpZy5zcGFya2xpbmU/LmdyYW51bGFyaXR5ID8/IEtQSV9TUEFSS0xJTkVfREVGQVVMVF9HUkFOVUxBUklUWSk7XG4gICAgdGhpcy5zcGFya2xpbmVQZXJpb2RzLnNldChjb25maWcuc3BhcmtsaW5lPy5wZXJpb2RzID8/IEtQSV9TUEFSS0xJTkVfREVGQVVMVF9QRVJJT0RTKTtcbiAgfVxuXG4gIC8vIFRoZSBjYXJkIGtleXMgdGhlIHNlcnZlciBzYXZlZCwgZnJvbSB0aGUgY29uZmlnIGl0cyByZXNwb25zZSBjYXJyaWVzO1xuICAvLyBudWxsIHdoZW4gaXQgY2FycmllcyBub25lIChhIHNlcnZlciB0aGF0IGRvZXMgbm90IHNhdmUgdGhlbSkuXG4gIHByaXZhdGUgX3NhdmVkS3BpQ2FyZChyZXNwb25zZTogQ29tcG9uZW50U2V0dGluZ3NSZXNwb25zZSB8IG51bGwgfCB1bmRlZmluZWQpOiBLcGlDYXJkU2V0dGluZ3MgfCBudWxsIHtcbiAgICBjb25zdCBjb25maWcgPSByZXNwb25zZT8uY29uZmlnO1xuXG4gICAgcmV0dXJuIGNvbmZpZyAmJiB0eXBlb2YgY29uZmlnID09PSAnb2JqZWN0JyA/IGtwaUNhcmRTZXR0aW5ncyhjb25maWcgYXMgS3BpQ29uZmlnKSA6IG51bGw7XG4gIH1cblxuICAvLyBHb29kIGlzIHdoYXQgYW4gYWJzZW50IGluY3JlYXNlSXMgcmVhZHMsIHNvIGl0IGlzIHNhdmVkIGFzIGFic2VudC5cbiAgcHJpdmF0ZSBfa3BpQ2FyZFNldHRpbmdzKCk6IEtwaUNhcmRTZXR0aW5ncyB7XG4gICAgY29uc3QgdGFyZ2V0ID0gdGhpcy5fbnVtYmVyKHRoaXMudGFyZ2V0VmFsdWUoKSk7XG4gICAgY29uc3QgbGFiZWwgPSB0aGlzLnRhcmdldExhYmVsKCkudHJpbSgpO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGluY3JlYXNlSXM6IHRoaXMuaW5jcmVhc2VJcygpID09PSBSZXBvcnRDaGFuZ2VQb2xhcml0eS5Hb29kID8gbnVsbCA6IHRoaXMuaW5jcmVhc2VJcygpLFxuICAgICAgdGFyZ2V0OiB0YXJnZXQgPT09IG51bGwgPyBudWxsIDogeyB2YWx1ZTogdGhpcy5fdGFyZ2V0U3RvcmVkKHRhcmdldCksIGxhYmVsOiBsYWJlbCB8fCBudWxsIH0sXG4gICAgICBzcGFya2xpbmU6IHRoaXMuc3BhcmtsaW5lKClcbiAgICAgICAgPyB7IGdyYW51bGFyaXR5OiB0aGlzLnNwYXJrbGluZUdyYW51bGFyaXR5KCksIHBlcmlvZHM6IHRoaXMuX251bWJlcih0aGlzLnNwYXJrbGluZVBlcmlvZHMoKSkgfVxuICAgICAgICA6IG51bGwsXG4gICAgfTtcbiAgfVxuXG4gIC8vIEEgc3RvcmVkIHJhdGlvIGFzIHRoZSBwZXJjZW50IHR5cGVkLCByb3VuZGVkIHNvIDAuMTUgcmVhZHMgMTUgYW5kIG5vdFxuICAvLyAxNS4wMDAwMDAwMDAwMDAwMDIuXG4gIHByaXZhdGUgX3RhcmdldFNob3duKHZhbHVlOiBudW1iZXIgfCBudWxsKTogbnVtYmVyIHwgbnVsbCB7XG4gICAgaWYgKHZhbHVlID09PSBudWxsIHx8ICF0aGlzLnRhcmdldFBlcmNlbnQoKSkge1xuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH1cblxuICAgIHJldHVybiBNYXRoLnJvdW5kKHZhbHVlICogMTAwICogMWU2KSAvIDFlNjtcbiAgfVxuXG4gIHByaXZhdGUgX3RhcmdldFN0b3JlZCh2YWx1ZTogbnVtYmVyKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy50YXJnZXRQZXJjZW50KCkgPyB2YWx1ZSAvIDEwMCA6IHZhbHVlO1xuICB9XG5cbiAgLy8gQSB0eXBlZCBudW1iZXIsIG9yIG51bGwgd2hlbiB0aGUgZmllbGQgaXMgZW1wdHkuXG4gIHByaXZhdGUgX251bWJlcih2YWx1ZTogbnVtYmVyIHwgc3RyaW5nIHwgbnVsbCk6IG51bWJlciB8IG51bGwge1xuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gJycpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IG51bWJlciA9IHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicgPyB2YWx1ZSA6IHBhcnNlRmxvYXQodmFsdWUpO1xuXG4gICAgcmV0dXJuIE51bWJlci5pc0Zpbml0ZShudW1iZXIpID8gbnVtYmVyIDogbnVsbDtcbiAgfVxuXG4gIC8vIFRoZSBwYWRkaW5nIGFzIGEgcmVhbCBudW1iZXIgZm9yIHRoZSB3aXJlLiBmc01hc2tOdW1iZXIgaGFuZHMgYmFjayB0aGVcbiAgLy8gdW5tYXNrZWQgc3RyaW5nIGl0IGJ1aWx0IHdpdGggYSBmaXhlZCAnLicgcmFkaXgsIHNvIHRoaXMgaXMgYSBzdHJhaWdodFxuICAvLyBwYXJzZSAtIHRoZSB3aG9sZSByZWFzb24gZm9yIHRoZSBtYXNrIGlzIHRoYXQgYSBuYXRpdmUgbnVtYmVyIGlucHV0IHdvdWxkXG4gIC8vIHBhaW50IChhbmQgcmVhZCBiYWNrKSB0aGUgdmlld2VyJ3Mgb3duIGxvY2FsZSBzZXBhcmF0b3IgaW5zdGVhZC5cbiAgcHJpdmF0ZSBfcGFkZGluZyh2YWx1ZTogbnVtYmVyIHwgc3RyaW5nKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyA/IHZhbHVlIDogcGFyc2VGbG9hdCh2YWx1ZSk7XG4gIH1cblxuICAvLyBSdW4gYSBmaWx0ZXIgbXV0YXRpb24sIHRoZW4gcmVsb2FkIHRvIHJlY29uY2lsZSB0aGUgb3B0aW1pc3RpYyBzdGF0ZS5cbiAgcHJpdmF0ZSBfcnVuKHJlcXVlc3Q6IE9ic2VydmFibGU8dW5rbm93bj4pOiB2b2lkIHtcbiAgICByZXF1ZXN0LnN1YnNjcmliZSh7XG4gICAgICBuZXh0OiAoKSA9PiB0aGlzLl9hZnRlck11dGF0aW9uKCksXG4gICAgICBlcnJvcjogKGVycm9yKSA9PiB0aGlzLl9tdXRhdGlvbkVycm9yKGVycm9yKSxcbiAgICB9KTtcbiAgfVxuXG4gIC8vIEJ1aWxkIHRoZSByb3cgdmlldy1tb2RlbCBmcm9tIHRoZSBsb2FkZWQgY29sdW1ucyArIGZpbHRlcnMvZ3JvdXBzLiBFYWNoXG4gIC8vIHJvdydzIGNvbnRyb2xzIHJlZmxlY3Qgd2hlcmUgaXRzIGZpbHRlciBncm91cCBjdXJyZW50bHkgc2hvd3M7IGEgY29sdW1uXG4gIC8vIHdpdGggYSBmaWx0ZXIgc2hvd3MgdGhlIGZpbHRlcidzIG93biB0eXBlLiBBIHZhbHVlJ3Mgcm93cyBuZXZlciByZWFkIGFzXG4gIC8vIG9uIGEgY29tcG9uZW50OiBpdCBoYXMgbm8gc3RyaXAsIHdoYXRldmVyIGxldmVsIGEgZ3JvdXAgaXQgc2hhcmVzIGlzIGF0LFxuICAvLyBhbmQgaXRzIFJlcG9ydCBiYXIgc2VsZWN0IG9mZmVycyBubyBwaWNrIHRoYXQgbG93ZXJzIHRoYXQgZ3JvdXAuXG4gIHByaXZhdGUgX3JlYnVpbGRSb3dzKCk6IHZvaWQge1xuICAgIGNvbnN0IGxldmVsQ2hvaWNlcyA9IGZpbHRlckxldmVsQ2hvaWNlcyh0aGlzLnJlcG9ydC52aWV3ZXJGZWF0dXJlcywgdGhpcy5fb25QYWdlKCkpO1xuXG4gICAgdGhpcy5yb3dzLnNldCh0aGlzLl9maWx0ZXJhYmxlQ29sdW1ucy5tYXAoKGNvbHVtbikgPT4ge1xuICAgICAgY29uc3QgZmlsdGVyID0gdGhpcy5fZmlsdGVycy5maW5kKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZS5maWx0ZXJDb2x1bW4gPT09IGNvbHVtbi5jb2x1bW4pO1xuICAgICAgY29uc3QgZ3JvdXAgPSBmaWx0ZXIgPyB0aGlzLl9ncm91cHNCeUlkLmdldChmaWx0ZXIuZmlsdGVyR3JvdXBJZCkgOiB1bmRlZmluZWQ7XG4gICAgICBjb25zdCBwbGFjZW1lbnQgPSBiYXJQbGFjZW1lbnQoZ3JvdXA/LmxldmVsKTtcblxuICAgICAgcmV0dXJuIHtcbiAgICAgICAgY29sdW1uOiBjb2x1bW4uY29sdW1uLFxuICAgICAgICB0eXBlOiBncm91cD8udHlwZVxuICAgICAgICAgID8/IHRoaXMuX3BpY2tlZFR5cGVzLmdldChjb2x1bW4uY29sdW1uKVxuICAgICAgICAgID8/IGNvbHVtbi50eXBlcz8uWzBdXG4gICAgICAgICAgPz8gY29sdW1uLnR5cGUsXG4gICAgICAgIGxhYmVsOiBmaWx0ZXI/LmxhYmVsXG4gICAgICAgICAgfHwgdGhpcy5fZ3JvdXBzQnlJZC5nZXQoZmlsdGVyPy5maWx0ZXJHcm91cElkID8/IC0xKT8ubGFiZWxcbiAgICAgICAgICB8fCB0aGlzLl9odW1hbml6ZShjb2x1bW4uY29sdW1uKSxcbiAgICAgICAgcGxhY2VtZW50LFxuICAgICAgICBjb21wb25lbnQ6ICF0aGlzLmlzVmFsdWUoKSAmJiBzaG93bk9uQ29tcG9uZW50KGdyb3VwPy5sZXZlbCksXG4gICAgICAgIHR5cGVTZWxlY3Q6IHR5cGVTZWxlY3RTdGF0ZShjb2x1bW4udHlwZXMsICEhZmlsdGVyLCB0aGlzLnJlcG9ydC52aWV3ZXJGZWF0dXJlcyksXG4gICAgICAgIHBsYWNlbWVudE9wdGlvbnM6IHRoaXMuaXNWYWx1ZSgpXG4gICAgICAgICAgPyB2YWx1ZVBsYWNlbWVudE9wdGlvbnMobGV2ZWxDaG9pY2VzLCBncm91cD8ubGV2ZWwpXG4gICAgICAgICAgOiBiYXJQbGFjZW1lbnRPcHRpb25zKGxldmVsQ2hvaWNlcywgcGxhY2VtZW50KSxcbiAgICAgICAgY29tcG9uZW50VG9nZ2xlOiBjb21wb25lbnRUb2dnbGVTdGF0ZShwbGFjZW1lbnQpLFxuICAgICAgfTtcbiAgICB9KSk7XG4gIH1cblxuICAvLyBXaGV0aGVyIHRoZSBjb21wb25lbnQgc2l0cyBvbiBhIHBhZ2U6IGFtb25nIGl0cyBjb21wb25lbnRzLCBvciwgZm9yIGFcbiAgLy8gdmFsdWUsIGl0cyB2YWx1ZXMuIEEgaGVhZGVyIG9yIGZvb3RlciBjb21wb25lbnQgb3IgdmFsdWUgc2l0cyBvbiBub25lLFxuICAvLyBzbyBpdHMgZmlsdGVycyBjYW5ub3QgYmUgcGFnZSBmaWx0ZXJzLlxuICBwcml2YXRlIF9vblBhZ2UoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICh0aGlzLnJlcG9ydC5wYWdlcyA/PyBbXSlcbiAgICAgIC5zb21lKChwYWdlKSA9PiBbLi4uKHBhZ2UuY29tcG9uZW50cyA/PyBbXSksIC4uLihwYWdlLnZhbHVlcyA/PyBbXSldXG4gICAgICAgIC5zb21lKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZS5pZCA9PT0gdGhpcy5jb21wb25lbnQuaWQpKTtcbiAgfVxuXG4gIC8vIEFmdGVyIGFueSBmaWx0ZXIgbXV0YXRpb246IHJlLWZldGNoIHRoZSByZXBvcnQgc28gdGhlIGRpYWxvZydzIGZpbHRlciBsaXN0XG4gIC8vIChhbmQgdGhlIHBhcmVudCBjYW52YXMsIG9uIGNsb3NlKSByZWZsZWN0IHRoZSBuZXcgZ3JvdXBzL2xldmVscy5cbiAgcHJpdmF0ZSBfYWZ0ZXJNdXRhdGlvbigpOiB2b2lkIHtcbiAgICB0aGlzLmZpbHRlcnNDaGFuZ2VkLmVtaXQoKTtcblxuICAgIHRoaXMuX3JlcG9ydERhdGEuZ2V0KHRoaXMucmVwb3J0LmlkKVxuICAgICAgLnN1YnNjcmliZSgocmVwb3J0OiBSZXBvcnQpID0+IHtcbiAgICAgICAgdGhpcy5yZXBvcnQgPSByZXBvcnQ7XG4gICAgICAgIHRoaXMuX3NlZWRGaWx0ZXJzKHJlcG9ydCwgdGhpcy5jb21wb25lbnQuaWQpO1xuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9tdXRhdGlvbkVycm9yKGVycm9yOiBhbnkpOiB2b2lkIHtcbiAgICB0aGlzLl9tZXNzYWdlLmVycm9yKGVycm9yPy5lcnJvcj8ubWVzc2FnZSA/PyBlcnJvcj8ubWVzc2FnZSA/PyAnRmlsdGVyIG9wZXJhdGlvbiBmYWlsZWQnKTtcbiAgICAvLyBSZS1zZWVkIGZyb20gdGhlIHNlcnZlciBzbyB0aGUgb3B0aW1pc3RpYyB0b2dnbGUgc25hcHMgYmFjayB0byB0cnV0aC5cbiAgICB0aGlzLl9hZnRlck11dGF0aW9uKCk7XG4gIH1cblxuICAvLyBUaGUgY29tcG9uZW50J3MgZmlsdGVycyBhbmQgdGhlIGdyb3VwcyB0aGV5IHNpdCBpbiwgZnJvbSB0aGUgcmVwb3J0IGFzXG4gIC8vIGxhc3QgbG9hZGVkLiBBIHZhbHVlIGlzIGxpc3RlZCBpbiBpdHMgcGFnZSdzIHZhbHVlcywgbm90IGl0cyBjb21wb25lbnRzLlxuICBwcml2YXRlIF9zZWVkRmlsdGVycyhyZXBvcnQ6IFJlcG9ydCwgY29tcG9uZW50SWQ6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuX2dyb3Vwc0J5SWQgPSBuZXcgTWFwKChyZXBvcnQuZmlsdGVyR3JvdXBzID8/IFtdKS5tYXAoKGdyb3VwKSA9PiBbZ3JvdXAuaWQsIGdyb3VwXSkpO1xuXG4gICAgY29uc3QgY29tcG9uZW50ID0gcmVwb3J0Q29tcG9uZW50cyhyZXBvcnQpXG4gICAgICAuZmluZCgoY2FuZGlkYXRlKSA9PiBjYW5kaWRhdGUuaWQgPT09IGNvbXBvbmVudElkKTtcblxuICAgIHRoaXMuX2ZpbHRlcnMgPSBjb21wb25lbnQ/LmZpbHRlcnMgPz8gW107XG4gICAgdGhpcy5fcmVidWlsZFJvd3MoKTtcbiAgfVxuXG4gIC8vIFRoZSBzdGF0ZW1lbnQgdGhlIFNRTCB0YWIgc2hvd3MuIEZldGNoZWQgcmF0aGVyIHRoYW4gcmVhZCBvZmYgdGhlXG4gIC8vIGNvbXBvbmVudDogYSBkZXJpdmVkIGNvbXBvbmVudCBzdG9yZXMgYSBkb2N1bWVudCwgbm90IFNRTCwgc28gaXRzXG4gIC8vIHN0YXRlbWVudCBvbmx5IGV4aXN0cyBvbmNlIHRoZSBiYWNrZW5kIGNvbXBpbGVzIGl0LlxuICAvL1xuICAvLyBMb2FkZWQgaW4gbmdPbkluaXQgYmVzaWRlIHRoZSBjb2x1bW5zLCBOT1Qgb24gdGFiIGFjdGl2YXRpb24uIFRoZSB0YWJzIGFyZVxuICAvLyBub3QgbGF6eSAobm8gbWF0VGFiQ29udGVudCksIGFuZCBzd2l0Y2hpbmcgdGhlIHRhYi1ncm91cCdzIGBbKHNlbGVjdGVkKV1gXG4gIC8vIGJhbmFuYS1ib3ggdG8gYSBvbmUtd2F5IGJpbmRpbmcgcGx1cyAoc2VsZWN0ZWRDaGFuZ2UpIHRvIGdldCBhIGhvb2sgd291bGRcbiAgLy8gYnJlYWsgaXQ6IEZzVGFic0hlYWRlclRhYkdyb3VwRGlyZWN0aXZlIHNlbGYtYXNzaWducyBgdGhpcy5zZWxlY3RlZGAgYmVmb3JlXG4gIC8vIGl0IGVtaXRzLCBzbyB0aGUgZXZlbnQgaXMgZmlsdGVyZWQgb3V0IGFuZCB0aGUgbG9hZCB3b3VsZCBuZXZlciBmaXJlLiBPbmVcbiAgLy8gc21hbGwgcmVxdWVzdCB3aGVuIGEgZGlhbG9nIG9wZW5zIGlzIG5vdCB3b3J0aCB0aGF0IHJpc2suXG4gIHByaXZhdGUgX2xvYWRTcWwoKTogdm9pZCB7XG4gICAgdGhpcy5fcmVwb3J0RGF0YS5jb21wb25lbnRTcWwodGhpcy5yZXBvcnQuaWQsIHRoaXMuY29tcG9uZW50LmlkKVxuICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChwcmV2aWV3OiBSZXBvcnRDb21wb25lbnRTcWwpID0+IHtcbiAgICAgICAgICB0aGlzLnNxbC5zZXQocHJldmlldz8uc3FsID8/IG51bGwpO1xuICAgICAgICAgIHRoaXMuc3FsQmFzZWxpbmUuc2V0KCEhcHJldmlldz8uYmFzZWxpbmUpO1xuICAgICAgICAgIHRoaXMuc3FsVGltZXpvbmUuc2V0KHByZXZpZXc/LnRpbWV6b25lIHx8ICdVVEMnKTtcbiAgICAgICAgICB0aGlzLnNxbEVycm9yLnNldChwcmV2aWV3Py5lcnJvciA/PyBudWxsKTtcbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IChlcnJvcikgPT4ge1xuICAgICAgICAgIHRoaXMuc3FsLnNldChudWxsKTtcbiAgICAgICAgICB0aGlzLnNxbEVycm9yLnNldChlcnJvcj8uZXJyb3I/Lm1lc3NhZ2UgPz8gJ0NvdWxkIG5vdCByZWFkIHRoZSBjb21wb25lbnQgU1FMJyk7XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX2xvYWRDb2x1bW5zKCk6IHZvaWQge1xuICAgIHRoaXMuX3JlcG9ydERhdGEuY29tcG9uZW50Q29sdW1ucyh0aGlzLnJlcG9ydC5pZCwgdGhpcy5jb21wb25lbnQuaWQpXG4gICAgICAuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dDogKGNvbHVtbnM6IFJlcG9ydEZpbHRlcmFibGVDb2x1bW5bXSkgPT4ge1xuICAgICAgICAgIHRoaXMuX2ZpbHRlcmFibGVDb2x1bW5zID0gY29sdW1ucyA/PyBbXTtcbiAgICAgICAgICB0aGlzLl9yZWJ1aWxkUm93cygpO1xuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKGVycm9yKSA9PiB7XG4gICAgICAgICAgdGhpcy5jb2x1bW5zRXJyb3Iuc2V0KGVycm9yPy5lcnJvcj8ubWVzc2FnZSA/PyAnQ291bGQgbm90IHJlYWQgdGhlIGNvbXBvbmVudCBjb2x1bW5zJyk7XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX2h1bWFuaXplKGNvbHVtbjogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gY29sdW1uXG4gICAgICAucmVwbGFjZSgvW19cXC1dKy9nLCAnICcpXG4gICAgICAucmVwbGFjZSgvXFxzKy9nLCAnICcpXG4gICAgICAudHJpbSgpXG4gICAgICAucmVwbGFjZSgvXFxiXFx3L2csIChjaGFyYWN0ZXIpID0+IGNoYXJhY3Rlci50b1VwcGVyQ2FzZSgpKTtcbiAgfVxufVxuIiwiPGZvcm1cbiAgICBmc0Zvcm1cbiAgICBbc3VibWl0XT1cInNhdmVcIj5cbiAgPGZzLWRpYWxvZz5cbiAgICA8aDEgbWF0LWRpYWxvZy10aXRsZT5cbiAgICAgIHt7IGhlYWRpbmcoKSB9fVxuICAgIDwvaDE+XG4gICAgPG1hdC1kaWFsb2ctY29udGVudD5cbiAgICAgIDxtYXQtdGFiLWdyb3VwIFsoc2VsZWN0ZWQpXT1cInNlbGVjdGVkVGFiXCI+XG4gICAgICAgIDxtYXQtdGFiXG4gICAgICAgICAgICBsYWJlbD1cIlNldHRpbmdzXCJcbiAgICAgICAgICAgIG5hbWU9XCJzZXR0aW5nc1wiPlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJmcy1jb2x1bW4gdGFiLWJvZHlcIj5cbiAgICAgICAgICAgIDwhLS0gQSB2YWx1ZSdzIE5hbWUgaXMganVzdCBpdHMgbmFtZS4gQSB0aXRsZSBtYXkgY2FycnkgdGhlIHBhZ2UsXG4gICAgICAgICAgICAgICAgIHJlcG9ydCBhbmQgZmlsdGVyIGZpZWxkcyBhIHRleHQgYmxvY2sncyB3b3JkcyBkbzogSW5zZXJ0XG4gICAgICAgICAgICAgICAgIGZpZWxkIHB1dHMgb25lIGluIGF0IHRoZSBjYXJldCwgYW5kIHRoZSBoaW50IHNheXMgaG93IHRoZVxuICAgICAgICAgICAgICAgICB0aXRsZSByZWFkcyB3aGVyZSB0aGUgY29tcG9uZW50IGlzIGRyYXduLiAtLT5cbiAgICAgICAgICAgIEBpZiAoaXNWYWx1ZSgpKSB7XG4gICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgTmFtZVxuICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInRpdGxlKClcIlxuICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwidGl0bGUuc2V0KCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgbmFtZT1cInRpdGxlXCJcbiAgICAgICAgICAgICAgICAgIFtmc0Zvcm1SZXF1aXJlZF09XCJ0cnVlXCI+XG4gICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICBUaXRsZVxuICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgI3RpdGxlSW5wdXRcbiAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJ0aXRsZSgpXCJcbiAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInRpdGxlLnNldCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgIG5hbWU9XCJ0aXRsZVwiPlxuICAgICAgICAgICAgICAgIDwhLS0gVGhlIGJ1dHRvbiBzd2FsbG93cyBpdHMgb3duIGNsaWNrOiB0aGUgZm9ybSBmaWVsZCB3b3VsZFxuICAgICAgICAgICAgICAgICAgICAgb3RoZXJ3aXNlIHB1dCBmb2N1cyBiYWNrIGluIHRoZSBpbnB1dCB3aGlsZSB0aGUgbWVudSBpc1xuICAgICAgICAgICAgICAgICAgICAgb3BlbiwgYW5kIGEga2V5IHByZXNzZWQgdGhlbiB3b3VsZCBtb3ZlIHRoZSBjYXJldCB0aGVcbiAgICAgICAgICAgICAgICAgICAgIGZpZWxkIGdvZXMgaW4gYXQuIC0tPlxuICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgbWF0LWljb24tYnV0dG9uXG4gICAgICAgICAgICAgICAgICAgIG1hdEljb25TdWZmaXhcbiAgICAgICAgICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICAgICAgICAgIGFyaWEtbGFiZWw9XCJJbnNlcnQgZmllbGRcIlxuICAgICAgICAgICAgICAgICAgICBbZnNNZW51VHJpZ2dlckZvcl09XCJpbnNlcnRGaWVsZE1lbnVcIlxuICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgICAgICAgICAgICAgICA8bWF0LWljb24+c2VsbDwvbWF0LWljb24+XG4gICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgQGlmICh0aXRsZVNob3duQXMoKSkge1xuICAgICAgICAgICAgICAgICAgPG1hdC1oaW50PlxuICAgICAgICAgICAgICAgICAgICBTaG93cyBhczoge3sgdGl0bGVTaG93bkFzKCkgfX1cbiAgICAgICAgICAgICAgICAgIDwvbWF0LWhpbnQ+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICA8ZnMtbWVudSAjaW5zZXJ0RmllbGRNZW51PlxuICAgICAgICAgICAgICAgIEBmb3IgKGVudHJ5IG9mIHRpdGxlRmllbGRzKCk7IHRyYWNrIGVudHJ5LmZpZWxkKSB7XG4gICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgICAgICAgICAgICBmcy1tZW51LWl0ZW1cbiAgICAgICAgICAgICAgICAgICAgICAoY2xpY2spPVwiaW5zZXJ0RmllbGQoZW50cnkuZmllbGQpXCI+XG4gICAgICAgICAgICAgICAgICAgIHt7IGVudHJ5Lm5hbWUgfX1cbiAgICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICA8L2ZzLW1lbnU+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICA8IS0tIEEgZm9ybXVsYSB2YWx1ZSBpcyByZWFkLW9ubHkgYmV5b25kIGl0cyBuYW1lOiB3aGF0IGl0IHdvcmtzXG4gICAgICAgICAgICAgICAgIG91dCBpcyB0aGUgQUkncyB0byBjaGFuZ2UuIEEgZm9ybXVsYSB0aGlzIHZpZXdlciBjYW5ub3RcbiAgICAgICAgICAgICAgICAgcmVhZCBoYXMgbm8gbGluZSwgYW5kIG5vIHJvdy4gLS0+XG4gICAgICAgICAgICBAaWYgKGZvcm11bGFMaW5lKCkpIHtcbiAgICAgICAgICAgICAgPGZzLWxhYmVsLWZpZWxkPlxuICAgICAgICAgICAgICAgIDxmcy1sYWJlbD5cbiAgICAgICAgICAgICAgICAgIEZvcm11bGFcbiAgICAgICAgICAgICAgICA8L2ZzLWxhYmVsPlxuICAgICAgICAgICAgICAgIHt7IGZvcm11bGFMaW5lKCkgfX1cbiAgICAgICAgICAgICAgICA8ZnMtbGFiZWwtbWVzc2FnZT5cbiAgICAgICAgICAgICAgICAgIFdvcmtlZCBvdXQgb24gdGhlIHNlcnZlcjsgaXQgZm9sbG93cyB0aGUgZmlsdGVycyBvZiB0aGUgdmFsdWVzIGl0IHJlYWRzLlxuICAgICAgICAgICAgICAgIDwvZnMtbGFiZWwtbWVzc2FnZT5cbiAgICAgICAgICAgICAgPC9mcy1sYWJlbC1maWVsZD5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwhLS0gQSB2YWx1ZSBzaXRzIGluc2lkZSBhIHRleHQgYmxvY2sncyB3b3Jkczogbm8gYm94LCBubyBwYWRkaW5nLiAtLT5cbiAgICAgICAgICAgIEBpZiAoIWlzVmFsdWUoKSkge1xuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwic3ViaGVhZGluZy0yXCI+XG4gICAgICAgICAgICAgICAgUGFkZGluZ1xuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImdlb21ldHJ5LXJvd1wiPlxuICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIFRvcFxuICAgICAgICAgICAgICAgICAgPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgICAgZnNNYXNrTnVtYmVyXG4gICAgICAgICAgICAgICAgICAgIFtzY2FsZV09XCIzXCJcbiAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJwYWRkaW5nVG9wXCJcbiAgICAgICAgICAgICAgICAgICAgbmFtZT1cInBhZGRpbmdUb3BcIlxuICAgICAgICAgICAgICAgICAgICBbZnNGb3JtTWluXT1cIjBcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgbWF0VGV4dFN1ZmZpeD5cbiAgICAgICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgUmlnaHRcbiAgICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICAgIGZzTWFza051bWJlclxuICAgICAgICAgICAgICAgICAgICBbc2NhbGVdPVwiM1wiXG4gICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwicGFkZGluZ1JpZ2h0XCJcbiAgICAgICAgICAgICAgICAgICAgbmFtZT1cInBhZGRpbmdSaWdodFwiXG4gICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1NaW5dPVwiMFwiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBtYXRUZXh0U3VmZml4PlxuICAgICAgICAgICAgICAgICAgICBpblxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICBCb3R0b21cbiAgICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICAgIGZzTWFza051bWJlclxuICAgICAgICAgICAgICAgICAgICBbc2NhbGVdPVwiM1wiXG4gICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwicGFkZGluZ0JvdHRvbVwiXG4gICAgICAgICAgICAgICAgICAgIG5hbWU9XCJwYWRkaW5nQm90dG9tXCJcbiAgICAgICAgICAgICAgICAgICAgW2ZzRm9ybU1pbl09XCIwXCI+XG4gICAgICAgICAgICAgICAgICA8ZGl2IG1hdFRleHRTdWZmaXg+XG4gICAgICAgICAgICAgICAgICAgIGluXG4gICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIExlZnRcbiAgICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICAgIGZzTWFza051bWJlclxuICAgICAgICAgICAgICAgICAgICBbc2NhbGVdPVwiM1wiXG4gICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwicGFkZGluZ0xlZnRcIlxuICAgICAgICAgICAgICAgICAgICBuYW1lPVwicGFkZGluZ0xlZnRcIlxuICAgICAgICAgICAgICAgICAgICBbZnNGb3JtTWluXT1cIjBcIj5cbiAgICAgICAgICAgICAgICAgIDxkaXYgbWF0VGV4dFN1ZmZpeD5cbiAgICAgICAgICAgICAgICAgICAgaW5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgPCEtLSBBIGRlcml2ZWQgS1BJJ3MgY2FyZDogd2hhdCBhIHJpc2UgbWVhbnMsIGEgdGFyZ2V0IGFuZCBhXG4gICAgICAgICAgICAgICAgIHNwYXJrbGluZS4gVGhlIHNlcnZlciBjb21wdXRlcyB0aGUgcHJvZ3Jlc3MgYW5kIHRoZSBwb2ludHMuIC0tPlxuICAgICAgICAgICAgQGlmIChrcGlDYXJkKCkpIHtcbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cInN1YmhlYWRpbmctMlwiPlxuICAgICAgICAgICAgICAgIENhcmRcbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImZ1bGwtd2lkdGhcIj5cbiAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgSW5jcmVhc2UgaXNcbiAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICA8bWF0LXNlbGVjdFxuICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJpbmNyZWFzZUlzKClcIlxuICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJpbmNyZWFzZUlzLnNldCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgbmFtZT1cImluY3JlYXNlSXNcIj5cbiAgICAgICAgICAgICAgICAgIEBmb3IgKG9wdGlvbiBvZiBrcGlQb2xhcml0eU9wdGlvbnM7IHRyYWNrIG9wdGlvbi52YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwib3B0aW9uLnZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAge3sgb3B0aW9uLm5hbWUgfX1cbiAgICAgICAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cbiAgICAgICAgICAgICAgICA8bWF0LWhpbnQ+XG4gICAgICAgICAgICAgICAgICBDb2xvcnMgdGhlIGNoYW5nZSBhbmQgZGVjaWRlcyB3aGVuIHRoZSB0YXJnZXQgaXMgbWV0LlxuICAgICAgICAgICAgICAgIDwvbWF0LWhpbnQ+XG4gICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImZ1bGwtd2lkdGhcIj5cbiAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgVGFyZ2V0XG4gICAgICAgICAgICAgICAgPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICBtYXRJbnB1dFxuICAgICAgICAgICAgICAgICAgZnNNYXNrTnVtYmVyXG4gICAgICAgICAgICAgICAgICBbc2NhbGVdPVwiNlwiXG4gICAgICAgICAgICAgICAgICBbc2lnbmVkXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwidGFyZ2V0VmFsdWUoKVwiXG4gICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJ0YXJnZXRWYWx1ZS5zZXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICBuYW1lPVwidGFyZ2V0VmFsdWVcIlxuICAgICAgICAgICAgICAgICAgW3ZhbGlkYXRlXT1cInZhbGlkYXRlVGFyZ2V0XCI+XG4gICAgICAgICAgICAgICAgQGlmICh0YXJnZXRQZXJjZW50KCkpIHtcbiAgICAgICAgICAgICAgICAgIDxkaXYgbWF0VGV4dFN1ZmZpeD5cbiAgICAgICAgICAgICAgICAgICAgJVxuICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIDxtYXQtaGludD5cbiAgICAgICAgICAgICAgICAgIFRoZSB2YWx1ZSB0byByZWFjaC4gTGVhdmUgZW1wdHkgZm9yIG5vIHRhcmdldC5cbiAgICAgICAgICAgICAgICA8L21hdC1oaW50PlxuICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICBAaWYgKGhhc1RhcmdldCgpKSB7XG4gICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZnVsbC13aWR0aFwiPlxuICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgVGFyZ2V0IGxhYmVsXG4gICAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICBtYXRJbnB1dFxuICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJ0YXJnZXRMYWJlbCgpXCJcbiAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwidGFyZ2V0TGFiZWwuc2V0KCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICBuYW1lPVwidGFyZ2V0TGFiZWxcIj5cbiAgICAgICAgICAgICAgICAgIDxtYXQtaGludD5cbiAgICAgICAgICAgICAgICAgICAgU2hvd24gYmVmb3JlIHRoZSB0YXJnZXQsIHN1Y2ggYXMgR29hbC4gRW1wdHkgcmVhZHMgVGFyZ2V0LlxuICAgICAgICAgICAgICAgICAgPC9tYXQtaGludD5cbiAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDxmcy1sYWJlbC1maWVsZD5cbiAgICAgICAgICAgICAgICA8bWF0LXNsaWRlLXRvZ2dsZVxuICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJzcGFya2xpbmUoKVwiXG4gICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInNwYXJrbGluZS5zZXQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAgIG5hbWU9XCJzcGFya2xpbmVcIj5cbiAgICAgICAgICAgICAgICAgIFNwYXJrbGluZVxuICAgICAgICAgICAgICAgIDwvbWF0LXNsaWRlLXRvZ2dsZT5cbiAgICAgICAgICAgICAgICA8bWF0LWhpbnQ+XG4gICAgICAgICAgICAgICAgICBBIHNtYWxsIHRyZW5kIGxpbmUgb2YgdGhlIHZhbHVlIG92ZXIgaXRzIGxhc3QgcGVyaW9kcy5cbiAgICAgICAgICAgICAgICA8L21hdC1oaW50PlxuICAgICAgICAgICAgICA8L2ZzLWxhYmVsLWZpZWxkPlxuICAgICAgICAgICAgICBAaWYgKHNwYXJrbGluZSgpKSB7XG4gICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZnVsbC13aWR0aFwiPlxuICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgU3BhcmtsaW5lIHBlcmlvZFxuICAgICAgICAgICAgICAgICAgPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8bWF0LXNlbGVjdFxuICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInNwYXJrbGluZUdyYW51bGFyaXR5KClcIlxuICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInNwYXJrbGluZUdyYW51bGFyaXR5LnNldCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICBuYW1lPVwic3BhcmtsaW5lR3JhbnVsYXJpdHlcIj5cbiAgICAgICAgICAgICAgICAgICAgQGZvciAob3B0aW9uIG9mIGdyYW51bGFyaXR5T3B0aW9uczsgdHJhY2sgb3B0aW9uLnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgPG1hdC1vcHRpb24gW3ZhbHVlXT1cIm9wdGlvbi52YWx1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAge3sgb3B0aW9uLm5hbWUgfX1cbiAgICAgICAgICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cbiAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImZ1bGwtd2lkdGhcIj5cbiAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgIFNwYXJrbGluZSBwZXJpb2RzXG4gICAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICBtYXRJbnB1dFxuICAgICAgICAgICAgICAgICAgICBmc01hc2tOdW1iZXJcbiAgICAgICAgICAgICAgICAgICAgW3NjYWxlXT1cIjBcIlxuICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJzcGFya2xpbmVQZXJpb2RzKClcIlxuICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJzcGFya2xpbmVQZXJpb2RzLnNldCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgbmFtZT1cInNwYXJrbGluZVBlcmlvZHNcIlxuICAgICAgICAgICAgICAgICAgICBbZnNGb3JtUmVxdWlyZWRdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1JbnRlZ2VyXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICBbZnNGb3JtTWluXT1cInNwYXJrbGluZU1pblBlcmlvZHNcIlxuICAgICAgICAgICAgICAgICAgICBbZnNGb3JtTWF4XT1cInNwYXJrbGluZU1heFBlcmlvZHNcIj5cbiAgICAgICAgICAgICAgICAgIDxtYXQtaGludD5cbiAgICAgICAgICAgICAgICAgICAgSG93IG1hbnkgcGVyaW9kcyB0aGUgbGluZSBjb3ZlcnMsIHt7IHNwYXJrbGluZU1pblBlcmlvZHMgfX0gdG8ge3sgc3BhcmtsaW5lTWF4UGVyaW9kcyB9fS5cbiAgICAgICAgICAgICAgICAgIDwvbWF0LWhpbnQ+XG4gICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L21hdC10YWI+XG4gICAgICAgIDwhLS0gQSBmb3JtdWxhIHJ1bnMgbm8gc3RhdGVtZW50IGFuZCBmb2xsb3dzIHRoZSBmaWx0ZXJzIG9mIHRoZSB2YWx1ZXNcbiAgICAgICAgICAgICBpdCByZWFkcywgc28gaXQgaGFzIG5laXRoZXIgYSBGaWx0ZXJzIG5vciBhbiBTUUwgdGFiLiAtLT5cbiAgICAgICAgQGlmICghaXNGb3JtdWxhKCkpIHtcbiAgICAgICAgICA8bWF0LXRhYlxuICAgICAgICAgICAgICBsYWJlbD1cIkZpbHRlcnNcIlxuICAgICAgICAgICAgICBuYW1lPVwiZmlsdGVyc1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRhYi1ib2R5XCI+XG4gICAgICAgICAgICAgIEBpZiAoY29sdW1uc0Vycm9yKCkpIHtcbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmlsdGVycy1lbXB0eSBlcnJvclwiPlxuICAgICAgICAgICAgICAgICAge3sgY29sdW1uc0Vycm9yKCkgfX1cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgfSBAZWxzZSBpZiAocm93cygpLmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIDwhLS0gRXZlcnkgZmlsdGVyYWJsZSBjb2x1bW4uIFBpY2sgd2hlcmUgaXRzIGNvbnRyb2wgc2hvd3M6IGluXG4gICAgICAgICAgICAgICAgICAgICB0aGUgcmVwb3J0IGJhciAoZXZlcnkgcGFnZSwgb3IgdGhpcyBwYWdlIG9ubHkpLCBvbiB0aGlzXG4gICAgICAgICAgICAgICAgICAgICBjb21wb25lbnQsIGJvdGgsIG9yIG5laXRoZXIuIFRoZSBpbnRlcmZhY2UgZm9sbG93cyB0aGVcbiAgICAgICAgICAgICAgICAgICAgIGRhdGE7IGEgbnVtZXJpYyBjb2x1bW4gY2FuIGJlIHZhbHVlcyBvciBhIG51bWJlciByYW5nZS5cbiAgICAgICAgICAgICAgICAgICAgIEEgdmFsdWUgc2l0cyBpbnNpZGUgdGV4dCBhbmQgaGFzIG5vIGNvbXBvbmVudCB0byBzaG93IGFcbiAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wgb24sIHNvIGl0IGdldHMgdGhlIHJlcG9ydCBiYXIgY29sdW1uIG9ubHkuIC0tPlxuICAgICAgICAgICAgICAgIDx0YWJsZSBjbGFzcz1cImZpbHRlci10YWJsZVwiPlxuICAgICAgICAgICAgICAgICAgPHRoZWFkPlxuICAgICAgICAgICAgICAgICAgICA8dHI+XG4gICAgICAgICAgICAgICAgICAgICAgPHRoIGNsYXNzPVwiZmlsdGVyLWNvbC1uYW1lXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICBGaWx0ZXJcbiAgICAgICAgICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgIDx0aCBjbGFzcz1cImZpbHRlci1jb2wtdHlwZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgVHlwZVxuICAgICAgICAgICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgPHRoIGNsYXNzPVwiZmlsdGVyLWNvbC1zZWxlY3RcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIFJlcG9ydCBiYXJcbiAgICAgICAgICAgICAgICAgICAgICA8L3RoPlxuICAgICAgICAgICAgICAgICAgICAgIEBpZiAoIWlzVmFsdWUoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgPHRoIGNsYXNzPVwiZmlsdGVyLWNvbC10b2dnbGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgVGhpcyBjb21wb25lbnRcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGg+XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgICAgPC90aGVhZD5cbiAgICAgICAgICAgICAgICAgIDx0Ym9keT5cbiAgICAgICAgICAgICAgICAgICAgQGZvciAocm93IG9mIHJvd3MoKTsgdHJhY2sgcm93LmNvbHVtbikge1xuICAgICAgICAgICAgICAgICAgICAgIDx0cj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDx0ZCBjbGFzcz1cImZpbHRlci1jb2wtbmFtZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICB7eyByb3cubGFiZWwgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJmaWx0ZXItY29sLXR5cGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgQGlmIChyb3cudHlwZVNlbGVjdC5zaG93KSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzdWJzY3JpcHRTaXppbmddPVwiJ2R5bmFtaWMnXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW21hdFRvb2x0aXBdPVwicm93LnR5cGVTZWxlY3QudG9vbHRpcFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zZWxlY3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbcGFuZWxXaWR0aF09XCJudWxsXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJyb3cudHlwZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwic2V0VHlwZShyb3csICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsT3B0aW9uc109XCJ7IHN0YW5kYWxvbmU6IHRydWUgfVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cInJvdy50eXBlU2VsZWN0LmRpc2FibGVkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhcmlhLWxhYmVsPVwiVHlwZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAZm9yIChvcHRpb24gb2YgdHlwZU9wdGlvbnM7IHRyYWNrIG9wdGlvbi52YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIFt2YWx1ZV09XCJvcHRpb24udmFsdWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IG9wdGlvbi5uYW1lIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgdHlwZUxhYmVsKHJvdy50eXBlKSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiZmlsdGVyLWNvbC1zZWxlY3RcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIFtzdWJzY3JpcHRTaXppbmddPVwiJ2R5bmFtaWMnXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zZWxlY3RcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW3BhbmVsV2lkdGhdPVwibnVsbFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInJvdy5wbGFjZW1lbnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJzZXRQbGFjZW1lbnQocm93LCAkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxPcHRpb25zXT1cInsgc3RhbmRhbG9uZTogdHJ1ZSB9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJpYS1sYWJlbD1cIlJlcG9ydCBiYXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEBmb3IgKG9wdGlvbiBvZiByb3cucGxhY2VtZW50T3B0aW9uczsgdHJhY2sgb3B0aW9uLnZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIFt2YWx1ZV09XCJvcHRpb24udmFsdWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBvcHRpb24ubmFtZSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIEBpZiAoIWlzVmFsdWUoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJmaWx0ZXItY29sLXRvZ2dsZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtc2xpZGUtdG9nZ2xlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJyb3cuY29tcG9uZW50XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInNldENvbXBvbmVudChyb3csICRldmVudClcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxPcHRpb25zXT1cInsgc3RhbmRhbG9uZTogdHJ1ZSB9XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtkaXNhYmxlZF09XCJyb3cuY29tcG9uZW50VG9nZ2xlLmRpc2FibGVkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFttYXRUb29sdGlwXT1cInJvdy5jb21wb25lbnRUb2dnbGUudG9vbHRpcFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LXNsaWRlLXRvZ2dsZT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICA8L3RyPlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICA8L3Rib2R5PlxuICAgICAgICAgICAgICAgIDwvdGFibGU+XG4gICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWx0ZXJzLWVtcHR5XCI+XG4gICAgICAgICAgICAgICAgICBUaGlzIGNvbXBvbmVudCBoYXMgbm8gZmlsdGVyYWJsZSBjb2x1bW5zIHlldCDigJQgZ2l2ZSBpdCBzb21lIFNRTCBmaXJzdC5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9tYXQtdGFiPlxuICAgICAgICAgIDxtYXQtdGFiXG4gICAgICAgICAgICAgIGxhYmVsPVwiU1FMXCJcbiAgICAgICAgICAgICAgbmFtZT1cInNxbFwiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRhYi1ib2R5XCI+XG4gICAgICAgICAgICAgIEBpZiAoc3FsRXJyb3IoKSkge1xuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWx0ZXJzLWVtcHR5IGVycm9yXCI+XG4gICAgICAgICAgICAgICAgICB7eyBzcWxFcnJvcigpIH19XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIH0gQGVsc2UgaWYgKHNxbCgpKSB7XG4gICAgICAgICAgICAgICAgQGlmIChzcWxCYXNlbGluZSgpKSB7XG4gICAgICAgICAgICAgICAgICA8IS0tIEEgZGVyaXZlZCBjb21wb25lbnQncyBzdGF0ZW1lbnQgaXMgY29tcGlsZWQgZnJvbSBpdHNcbiAgICAgICAgICAgICAgICAgICAgICAgZG9jdW1lbnQgd2l0aCBubyB2aWV3ZXIgc3RhdGUsIHNvIGl0IGlzIG5vdCBieXRlLWZvci1ieXRlXG4gICAgICAgICAgICAgICAgICAgICAgIHdoYXQgcHJvZHVjZWQgdGhlIG51bWJlcnMgb24gc2NyZWVuLiBTYWlkIGhlcmUgcmF0aGVyIHRoYW5cbiAgICAgICAgICAgICAgICAgICAgICAgbGVmdCBmb3IgdGhlIHJlYWRlciB0byBkaXNjb3Zlci4gLS0+XG4gICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmlsdGVycy1lbXB0eVwiPlxuICAgICAgICAgICAgICAgICAgICBDb21waWxlZCBmcm9tIHRoaXMgY29tcG9uZW50J3MgcXVlcnkg4oCUIG5vIGZpbHRlcnMgYXBwbGllZCwgdGltZXMgaW4ge3sgc3FsVGltZXpvbmUoKSB9fS5cbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICA8cHJlIGNsYXNzPVwiY29kZS1ibG9ja1wiPnt7IHNxbCgpIH19PC9wcmU+XG4gICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmaWx0ZXJzLWVtcHR5XCI+XG4gICAgICAgICAgICAgICAgICBUaGlzIGNvbXBvbmVudCBoYXMgbm8gU1FMIHlldC5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9tYXQtdGFiPlxuICAgICAgICB9XG4gICAgICAgIDxtYXQtdGFiXG4gICAgICAgICAgICBsYWJlbD1cIkNvbmZpZ1wiXG4gICAgICAgICAgICBuYW1lPVwiY29uZmlnXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInRhYi1ib2R5XCI+XG4gICAgICAgICAgICA8cHJlIGNsYXNzPVwiY29kZS1ibG9ja1wiPlxuICAgICAgICAgICAgICB7eyBjb25maWdKc29uIH19XG4gICAgICAgICAgICA8L3ByZT5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9tYXQtdGFiPlxuICAgICAgPC9tYXQtdGFiLWdyb3VwPlxuICAgIDwvbWF0LWRpYWxvZy1jb250ZW50PlxuICAgIDxtYXQtZGlhbG9nLWFjdGlvbnM+XG4gICAgICA8IS0tIFNhdmUgfCBEZWxldGUgfCBDYW5jZWwsIHRoZSBzdGFuZGFyZCBvcmRlci4gZnMtZm9ybS1kaWFsb2ctYWN0aW9uc1xuICAgICAgICAgICByZW5kZXJzIGl0cyBvd24gU2F2ZS9Eb25lIEJFRk9SRSB0aGUgcHJvamVjdGVkIGNvbnRlbnQsIHdoaWNoIHdvdWxkXG4gICAgICAgICAgIHB1dCBEZWxldGUgYWZ0ZXIgQ2FuY2VsLCBzbyBgW3NhdmVdPVwiZmFsc2VcImAgZm9vdHMgdGhlIHJvdyBoZXJlIGFuZFxuICAgICAgICAgICBhbGwgdGhyZWUgYnV0dG9ucyBhcmUgcHJvamVjdGVkIGluIG9yZGVyLiBTYXZlIHN1Ym1pdHMgdGhlIFNldHRpbmdzXG4gICAgICAgICAgIHRhYjsgdGhlIG90aGVyIHRhYnMgcGVyc2lzdCBhcyB5b3UgdG91Y2ggdGhlbSwgc28gdGhleSBnZXQgRG9uZS4gLS0+XG4gICAgICA8ZnMtZm9ybS1kaWFsb2ctYWN0aW9ucyBbc2F2ZV09XCJmYWxzZVwiPlxuICAgICAgICBAaWYgKHNlbGVjdGVkVGFiID09PSAnc2V0dGluZ3MnKSB7XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICBtYXQtYnV0dG9uXG4gICAgICAgICAgICAgIHR5cGU9XCJzdWJtaXRcIlxuICAgICAgICAgICAgICBjb2xvcj1cInByaW1hcnlcIj5cbiAgICAgICAgICAgIFNhdmVcbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgICBtYXQtYnV0dG9uXG4gICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICBjb2xvcj1cInByaW1hcnlcIlxuICAgICAgICAgICAgICBbbWF0LWRpYWxvZy1jbG9zZV09XCJudWxsXCI+XG4gICAgICAgICAgICBEb25lXG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgIH1cbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgbWF0LWJ1dHRvblxuICAgICAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICAgICBjb2xvcj1cIndhcm5cIlxuICAgICAgICAgICAgKGNsaWNrKT1cImRlbGV0ZSgpXCI+XG4gICAgICAgICAgRGVsZXRlXG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICBtYXQtYnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIGNsYXNzPVwiY2FuY2VsLWJ1dHRvblwiXG4gICAgICAgICAgICBbbWF0LWRpYWxvZy1jbG9zZV09XCJudWxsXCI+XG4gICAgICAgICAgQ2FuY2VsXG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgPC9mcy1mb3JtLWRpYWxvZy1hY3Rpb25zPlxuICAgIDwvbWF0LWRpYWxvZy1hY3Rpb25zPlxuICA8L2ZzLWRpYWxvZz5cbjwvZm9ybT4iXX0=