@firestitch/report 18.8.1 → 18.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/app/reports/anchor-at-point.d.ts +14 -0
- package/app/reports/canvas-landing-page.d.ts +2 -0
- package/app/reports/components/component-chart/component-chart.component.d.ts +18 -2
- package/app/reports/components/component-kpi/component-kpi.component.d.ts +4 -1
- package/app/reports/components/component-text/component-text.component.d.ts +47 -2
- package/app/reports/components/component-text/value-embed.plugin.d.ts +67 -0
- package/app/reports/components/report-canvas/report-canvas.component.d.ts +37 -9
- package/app/reports/components/report-component/report-component.component.d.ts +45 -2
- package/app/reports/components/report-view-picker/report-view-picker.component.d.ts +21 -0
- package/app/reports/data/report.data.d.ts +18 -2
- package/app/reports/dialogs/component-settings/component-settings.component.d.ts +25 -2
- package/app/reports/dialogs/report-settings/report-settings.component.d.ts +15 -6
- package/app/reports/dialogs/report-view/report-view-dialog.component.d.ts +13 -0
- package/app/reports/drill-crumbs.d.ts +12 -0
- package/app/reports/enums/report-value-formula.enum.d.ts +6 -0
- package/app/reports/export/report-export-collector.service.d.ts +35 -4
- package/app/reports/export/report-export.service.d.ts +3 -1
- package/app/reports/export/report-filter-lines.d.ts +18 -0
- package/app/reports/export/report-pdf.service.d.ts +18 -2
- package/app/reports/export/report-pptx.service.d.ts +15 -2
- package/app/reports/export/report-text-layout.service.d.ts +35 -0
- package/app/reports/filter-settings-rules.d.ts +33 -0
- package/app/reports/format.d.ts +2 -1
- package/app/reports/interfaces/canvas-landing-input.interface.d.ts +8 -0
- package/app/reports/interfaces/component-data-applied.interface.d.ts +13 -0
- package/app/reports/interfaces/component-data-drill.interface.d.ts +22 -0
- package/app/reports/interfaces/filter-bar-placement.type.d.ts +1 -0
- package/app/reports/interfaces/filter-component-toggle-state.interface.d.ts +4 -0
- package/app/reports/interfaces/filter-settings-option.interface.d.ts +4 -0
- package/app/reports/interfaces/filter-type-select-state.interface.d.ts +5 -0
- package/app/reports/interfaces/report-chart-hit.interface.d.ts +5 -0
- package/app/reports/interfaces/report-chat-viewer-cross-filter-field.interface.d.ts +4 -0
- package/app/reports/interfaces/report-chat-viewer-cross-filter.interface.d.ts +7 -0
- package/app/reports/interfaces/report-chat-viewer-detail.interface.d.ts +4 -0
- package/app/reports/interfaces/report-chat-viewer-drill-step.interface.d.ts +5 -0
- package/app/reports/interfaces/report-chat-viewer-drill.interface.d.ts +5 -0
- package/app/reports/interfaces/report-chat-viewer-filter.interface.d.ts +3 -0
- package/app/reports/interfaces/report-chat-viewer-selection.interface.d.ts +5 -0
- package/app/reports/interfaces/report-chat-viewer-state.interface.d.ts +12 -0
- package/app/reports/interfaces/report-drill-crumb.interface.d.ts +6 -0
- package/app/reports/interfaces/report-drill-refusal.type.d.ts +1 -0
- package/app/reports/interfaces/report-drill-step.interface.d.ts +5 -0
- package/app/reports/interfaces/report-export-line-kind.type.d.ts +1 -0
- package/app/reports/interfaces/report-export-line.interface.d.ts +8 -0
- package/app/reports/interfaces/report-export-lines-input.interface.d.ts +9 -0
- package/app/reports/interfaces/report-export-snapshot.interface.d.ts +15 -0
- package/app/reports/interfaces/report-filter-line-context.interface.d.ts +8 -0
- package/app/reports/interfaces/report-filter-line-form.type.d.ts +1 -0
- package/app/reports/interfaces/report-filter-match.type.d.ts +1 -0
- package/app/reports/interfaces/report-filter-option-pair.interface.d.ts +4 -0
- package/app/reports/interfaces/report-filter-options-ask.interface.d.ts +6 -0
- package/app/reports/interfaces/report-filter-options-list.interface.d.ts +7 -0
- package/app/reports/interfaces/report-filter-options-request.interface.d.ts +6 -0
- package/app/reports/interfaces/report-filter-options-stream.interface.d.ts +11 -0
- package/app/reports/interfaces/report-filter-options.interface.d.ts +7 -0
- package/app/reports/interfaces/report-filter-skip.type.d.ts +1 -0
- package/app/reports/interfaces/report-mark-action.type.d.ts +1 -0
- package/app/reports/interfaces/report-mark-click.interface.d.ts +13 -0
- package/app/reports/interfaces/report-mark-context.interface.d.ts +6 -0
- package/app/reports/interfaces/report-mark-decision.interface.d.ts +6 -0
- package/app/reports/interfaces/report-mark-event.interface.d.ts +11 -0
- package/app/reports/interfaces/report-mark-point.interface.d.ts +8 -0
- package/app/reports/interfaces/report-temporary-state.interface.d.ts +4 -0
- package/app/reports/interfaces/report-tile-state.interface.d.ts +8 -0
- package/app/reports/interfaces/report-url-link.interface.d.ts +4 -0
- package/app/reports/interfaces/report-url-value-name.type.d.ts +1 -0
- package/app/reports/interfaces/report-url-write.interface.d.ts +4 -0
- package/app/reports/interfaces/report-view-config.interface.d.ts +11 -0
- package/app/reports/interfaces/report-view-create.interface.d.ts +7 -0
- package/app/reports/interfaces/report-view-deleted.interface.d.ts +4 -0
- package/app/reports/interfaces/report-view-dialog-data.interface.d.ts +7 -0
- package/app/reports/interfaces/report-view-dropped.interface.d.ts +5 -0
- package/app/reports/interfaces/report-view-menu-item.interface.d.ts +10 -0
- package/app/reports/interfaces/report-view-summary.interface.d.ts +11 -0
- package/app/reports/interfaces/report-view.interface.d.ts +7 -0
- package/app/reports/interfaces/report-viewer-feature.type.d.ts +1 -0
- package/app/reports/interfaces/report-views.interface.d.ts +7 -0
- package/app/reports/interfaces/report.interface.d.ts +48 -5
- package/app/reports/interfaces/tile-load-result.interface.d.ts +4 -0
- package/app/reports/layout.d.ts +2 -0
- package/app/reports/mark-click.d.ts +20 -0
- package/app/reports/option-builder.d.ts +12 -1
- package/app/reports/report-chat-viewer-state.d.ts +8 -0
- package/app/reports/report-date-presets.d.ts +2 -0
- package/app/reports/report-filter-items.d.ts +27 -22
- package/app/reports/report-tile.d.ts +2 -0
- package/app/reports/report-url-state.d.ts +27 -10
- package/app/reports/report-view-config.d.ts +36 -0
- package/app/reports/report-view-menu.d.ts +15 -0
- package/app/reports/report-viewer-features.d.ts +5 -0
- package/app/reports/services/report-filter-options.service.d.ts +26 -0
- package/app/reports/services/report-filter-state.service.d.ts +65 -2
- package/app/reports/services/report-view.service.d.ts +51 -0
- package/app/reports/text.d.ts +50 -0
- package/app/reports/tile-data-state.d.ts +7 -0
- package/app/reports/tile-loads.d.ts +4 -0
- package/app/reports/values.d.ts +17 -0
- package/app/reports/views/report/fs-ai-report.component.d.ts +9 -1
- package/app/reports/views/report/report.component.d.ts +6 -0
- package/esm2022/app/reports/anchor-at-point.mjs +49 -0
- package/esm2022/app/reports/canvas-landing-page.mjs +25 -0
- package/esm2022/app/reports/components/component-chart/component-chart.component.mjs +97 -5
- package/esm2022/app/reports/components/component-kpi/component-kpi.component.mjs +11 -4
- package/esm2022/app/reports/components/component-list/component-list.component.mjs +7 -1
- package/esm2022/app/reports/components/component-text/component-text.component.mjs +213 -16
- package/esm2022/app/reports/components/component-text/value-embed.plugin.mjs +484 -0
- package/esm2022/app/reports/components/report-canvas/report-canvas.component.mjs +296 -55
- package/esm2022/app/reports/components/report-component/report-component.component.mjs +318 -76
- package/esm2022/app/reports/components/report-view-picker/report-view-picker.component.mjs +115 -0
- package/esm2022/app/reports/data/report.data.mjs +103 -8
- package/esm2022/app/reports/dialogs/component-settings/component-settings.component.mjs +210 -44
- package/esm2022/app/reports/dialogs/report-settings/report-settings.component.mjs +86 -90
- package/esm2022/app/reports/dialogs/report-view/report-view-dialog.component.mjs +52 -0
- package/esm2022/app/reports/drill-crumbs.mjs +73 -0
- package/esm2022/app/reports/enums/report-value-formula.enum.mjs +14 -0
- package/esm2022/app/reports/export/report-export-collector.service.mjs +299 -125
- package/esm2022/app/reports/export/report-export.service.mjs +57 -19
- package/esm2022/app/reports/export/report-filter-lines.mjs +235 -0
- package/esm2022/app/reports/export/report-pdf.service.mjs +315 -71
- package/esm2022/app/reports/export/report-pptx.service.mjs +293 -71
- package/esm2022/app/reports/export/report-text-layout.service.mjs +241 -0
- package/esm2022/app/reports/filter-settings-rules.mjs +283 -0
- package/esm2022/app/reports/format.mjs +13 -30
- package/esm2022/app/reports/interfaces/canvas-landing-input.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/component-data-applied.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/component-data-drill.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/filter-bar-placement.type.mjs +2 -0
- package/esm2022/app/reports/interfaces/filter-component-toggle-state.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/filter-settings-option.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/filter-type-select-state.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-chart-hit.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-chat-viewer-cross-filter-field.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-chat-viewer-cross-filter.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-chat-viewer-detail.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-chat-viewer-drill-step.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-chat-viewer-drill.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-chat-viewer-filter.interface.mjs +1 -1
- package/esm2022/app/reports/interfaces/report-chat-viewer-selection.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-chat-viewer-state.interface.mjs +1 -1
- package/esm2022/app/reports/interfaces/report-drill-crumb.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-drill-refusal.type.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-drill-step.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-export-line-kind.type.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-export-line.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-export-lines-input.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-export-snapshot.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-filter-line-context.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-filter-line-form.type.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-filter-match.type.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-filter-option-pair.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-filter-options-ask.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-filter-options-list.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-filter-options-request.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-filter-options-stream.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-filter-options.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-filter-skip.type.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-mark-action.type.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-mark-click.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-mark-context.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-mark-decision.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-mark-event.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-mark-point.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-temporary-state.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-tile-state.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-url-link.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-url-value-name.type.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-url-write.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-view-config.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-view-create.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-view-deleted.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-view-dialog-data.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-view-dropped.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-view-menu-item.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-view-summary.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-view.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-viewer-feature.type.mjs +2 -0
- package/esm2022/app/reports/interfaces/report-views.interface.mjs +2 -0
- package/esm2022/app/reports/interfaces/report.interface.mjs +1 -1
- package/esm2022/app/reports/interfaces/tile-load-result.interface.mjs +2 -0
- package/esm2022/app/reports/layout.mjs +11 -1
- package/esm2022/app/reports/mark-click.mjs +193 -0
- package/esm2022/app/reports/option-builder.mjs +159 -15
- package/esm2022/app/reports/report-chat-viewer-state.mjs +34 -0
- package/esm2022/app/reports/report-date-presets.mjs +18 -0
- package/esm2022/app/reports/report-filter-items.mjs +343 -72
- package/esm2022/app/reports/report-tile.mjs +12 -0
- package/esm2022/app/reports/report-url-state.mjs +596 -108
- package/esm2022/app/reports/report-view-config.mjs +697 -0
- package/esm2022/app/reports/report-view-menu.mjs +119 -0
- package/esm2022/app/reports/report-viewer-features.mjs +42 -0
- package/esm2022/app/reports/services/report-filter-options.service.mjs +238 -0
- package/esm2022/app/reports/services/report-filter-state.service.mjs +715 -71
- package/esm2022/app/reports/services/report-view.service.mjs +358 -0
- package/esm2022/app/reports/text.mjs +293 -85
- package/esm2022/app/reports/tile-data-state.mjs +127 -0
- package/esm2022/app/reports/tile-loads.mjs +38 -0
- package/esm2022/app/reports/values.mjs +183 -0
- package/esm2022/app/reports/views/report/fs-ai-report.component.mjs +180 -46
- package/esm2022/app/reports/views/report/report.component.mjs +106 -23
- package/esm2022/public_api.mjs +24 -1
- package/fesm2022/{firestitch-report-echarts-CFnbJx44.mjs → firestitch-report-echarts-UBg8Wlhd.mjs} +2 -2
- package/fesm2022/{firestitch-report-echarts-CFnbJx44.mjs.map → firestitch-report-echarts-UBg8Wlhd.mjs.map} +1 -1
- package/fesm2022/{firestitch-report-firestitch-report-CSylkyko.mjs → firestitch-report-firestitch-report-B1keNrcK.mjs} +11315 -4201
- package/fesm2022/firestitch-report-firestitch-report-B1keNrcK.mjs.map +1 -0
- package/fesm2022/firestitch-report.mjs +1 -1
- package/package.json +1 -1
- package/public_api.d.ts +23 -0
- package/fesm2022/firestitch-report-firestitch-report-CSylkyko.mjs.map +0 -1
|
@@ -6,11 +6,13 @@ import { MAT_DIALOG_DATA, MatDialogActions, MatDialogContent, MatDialogRef, MatD
|
|
|
6
6
|
import { MatFormField, MatLabel, MatHint, MatSuffix } from '@angular/material/form-field';
|
|
7
7
|
import { MatInput } from '@angular/material/input';
|
|
8
8
|
import { MatOption, MatSelect } from '@angular/material/select';
|
|
9
|
+
import { MatSlideToggle } from '@angular/material/slide-toggle';
|
|
9
10
|
import { MatTabsModule } from '@angular/material/tabs';
|
|
10
11
|
import { FsAutocompleteChipsModule } from '@firestitch/autocomplete-chips';
|
|
11
12
|
import { FsDatePickerModule } from '@firestitch/datepicker';
|
|
12
13
|
import { FsDialogModule } from '@firestitch/dialog';
|
|
13
14
|
import { FsFormModule } from '@firestitch/form';
|
|
15
|
+
import { FsLabelModule } from '@firestitch/label';
|
|
14
16
|
import { FsMaskModule } from '@firestitch/mask';
|
|
15
17
|
import { FsMessage, FsMessageModule } from '@firestitch/message';
|
|
16
18
|
import { FsPrompt } from '@firestitch/prompt';
|
|
@@ -24,18 +26,20 @@ import { ReportValueFormat } from '../../enums/report-value-format.enum';
|
|
|
24
26
|
import { DAY_SHORT, REPORT_FALLBACK_CURRENCY, currencyName, formatLocalDate, formatNumber, localeName, resolveReportCurrency, resolveReportLocale, } from '../../format';
|
|
25
27
|
import { DEFAULT_HEADING_SIZE, HEADER_FOOTER_MAX, PAGE_DIMENSION_MAX, PAGE_DIMENSION_MIN } from '../../layout';
|
|
26
28
|
import { dateFromBound, dateToBound, loadGroupOptions, matchOptions, relativeLabel, resolveOptionValues, } from '../../report-filter-items';
|
|
29
|
+
import { DEFAULT_BOUND_SCALE, FIXED_DATES_PERIOD, boundsError, dateRangeDefault, defaultChanged, defaultPeriod, defaultPeriodOptions, defaultRowGroups, defaultRowLabel, numberRangeDefault, parseDefaultBound, selectDefault, showExcludeToggle, } from '../../filter-settings-rules';
|
|
27
30
|
import { reportLocalePatch } from './report-locale-patch';
|
|
28
31
|
import * as i0 from "@angular/core";
|
|
29
32
|
import * as i1 from "@angular/forms";
|
|
30
33
|
import * as i2 from "@firestitch/form";
|
|
31
|
-
import * as i3 from "@firestitch/
|
|
32
|
-
import * as i4 from "@firestitch/
|
|
33
|
-
import * as i5 from "@firestitch/
|
|
34
|
-
import * as i6 from "@firestitch/
|
|
35
|
-
import * as i7 from "@firestitch/
|
|
36
|
-
import * as i8 from "@firestitch/
|
|
37
|
-
import * as i9 from "@firestitch/
|
|
38
|
-
import * as i10 from "@
|
|
34
|
+
import * as i3 from "@firestitch/label";
|
|
35
|
+
import * as i4 from "@firestitch/mask";
|
|
36
|
+
import * as i5 from "@firestitch/dialog";
|
|
37
|
+
import * as i6 from "@firestitch/message";
|
|
38
|
+
import * as i7 from "@firestitch/tabs";
|
|
39
|
+
import * as i8 from "@firestitch/skeleton";
|
|
40
|
+
import * as i9 from "@firestitch/datepicker";
|
|
41
|
+
import * as i10 from "@firestitch/autocomplete-chips";
|
|
42
|
+
import * as i11 from "@angular/material/tabs";
|
|
39
43
|
// The day the Locale hint writes, a fixed calendar day so the example never
|
|
40
44
|
// changes under the operator.
|
|
41
45
|
const EXAMPLE_DAY = new Date(2026, 0, 5);
|
|
@@ -52,11 +56,12 @@ function currencyLabel(code) {
|
|
|
52
56
|
// Settings — name + page setup (size in inches, header/footer band depths).
|
|
53
57
|
// Styles — the report's typographic styles (sizes in POINTS, 1:1 with
|
|
54
58
|
// PDF/PowerPoint); the Heading size to start.
|
|
55
|
-
// Filters — the report
|
|
56
|
-
// seeds the report bar on every open (for every
|
|
57
|
-
// user-changeable — it pre-fills the control, it doesn't
|
|
58
|
-
// fix for heavy reports opening blank and timing out: a
|
|
59
|
-
// organization scopes the landing page from the first load.
|
|
59
|
+
// Filters — the report bar filters (every page or one page) and their
|
|
60
|
+
// DEFAULT values. A default seeds the report bar on every open (for every
|
|
61
|
+
// viewer) but stays user-changeable — it pre-fills the control, it doesn't
|
|
62
|
+
// lock it. This is the fix for heavy reports opening blank and timing out: a
|
|
63
|
+
// default month + organization scopes the landing page from the first load.
|
|
64
|
+
// The rules of the rows live in filter-settings-rules.ts.
|
|
60
65
|
export class ReportSettingsComponent {
|
|
61
66
|
selectedTab = 'settings';
|
|
62
67
|
name = '';
|
|
@@ -136,9 +141,19 @@ export class ReportSettingsComponent {
|
|
|
136
141
|
formatLocalDate(EXAMPLE_DAY, locale, DAY_SHORT),
|
|
137
142
|
].join(' · ');
|
|
138
143
|
});
|
|
139
|
-
// The report
|
|
144
|
+
// The report bar filters and their editable default values (Filters tab).
|
|
140
145
|
filterRows = signal([]);
|
|
141
|
-
|
|
146
|
+
fixedDatesPeriod = FIXED_DATES_PERIOD;
|
|
147
|
+
boundScale = DEFAULT_BOUND_SCALE;
|
|
148
|
+
// The Default minimum and Default maximum checks, through fsForm. Each field
|
|
149
|
+
// gets the other end as its validateData, so typing in one checks the pair
|
|
150
|
+
// again; boundsError words the refusal as the server does.
|
|
151
|
+
minBoundValidator = (control, max) => {
|
|
152
|
+
this._throwBoundsError(control.value, max);
|
|
153
|
+
};
|
|
154
|
+
maxBoundValidator = (control, min) => {
|
|
155
|
+
this._throwBoundsError(min, control.value);
|
|
156
|
+
};
|
|
142
157
|
_data = inject(MAT_DIALOG_DATA);
|
|
143
158
|
_dialogRef = inject(MatDialogRef);
|
|
144
159
|
_reportData = inject(ReportData);
|
|
@@ -193,6 +208,13 @@ export class ReportSettingsComponent {
|
|
|
193
208
|
.subscribe();
|
|
194
209
|
}
|
|
195
210
|
}
|
|
211
|
+
// A change to a row's Default period, exclude toggle or range ends. A new
|
|
212
|
+
// row object rather than a mutation, so the signal sees the change; the
|
|
213
|
+
// @for tracks group.id, so the row's controls survive the swap.
|
|
214
|
+
patchRow(row, patch) {
|
|
215
|
+
this.filterRows.update((rows) => rows
|
|
216
|
+
.map((item) => (item.group.id === row.group.id ? { ...item, ...patch } : item)));
|
|
217
|
+
}
|
|
196
218
|
// Confirm and delete here, while the dialog is still open, then close with
|
|
197
219
|
// a `deleted` result. The page reacts to the result; it no longer owns the
|
|
198
220
|
// prompt or the API call.
|
|
@@ -225,7 +247,7 @@ export class ReportSettingsComponent {
|
|
|
225
247
|
},
|
|
226
248
|
});
|
|
227
249
|
const defaults$ = this.filterRows()
|
|
228
|
-
.filter((row) => this.
|
|
250
|
+
.filter((row) => defaultChanged(row.group.config?.default, this._rowDefault(row)))
|
|
229
251
|
.map((row) => this._reportData.updateFilterGroup(reportId, row.group.id, {
|
|
230
252
|
default: this._rowDefault(row),
|
|
231
253
|
}));
|
|
@@ -235,12 +257,6 @@ export class ReportSettingsComponent {
|
|
|
235
257
|
this._dialogRef.close({ action: 'saved' });
|
|
236
258
|
}));
|
|
237
259
|
};
|
|
238
|
-
// Drop the row's stored rolling preset (Clear). A new row object rather than
|
|
239
|
-
// a mutation, so the signal sees the change; the @for tracks group.id, so
|
|
240
|
-
// the row's bindings survive the swap.
|
|
241
|
-
clearRelative(row) {
|
|
242
|
-
this.filterRows.update((rows) => rows.map((item) => (item === row ? { ...item, relative: null } : item)));
|
|
243
|
-
}
|
|
244
260
|
// The page dimension as a real number for the wire. fsMaskNumber hands back
|
|
245
261
|
// the unmasked string it built with a fixed '.' radix (which is the whole
|
|
246
262
|
// point of the mask - a native number input paints the viewer's locale
|
|
@@ -266,32 +282,23 @@ export class ReportSettingsComponent {
|
|
|
266
282
|
_storedOption(stored, offered, label) {
|
|
267
283
|
return stored && !offered.includes(stored) ? [{ value: stored, label: label(stored) }] : [];
|
|
268
284
|
}
|
|
269
|
-
|
|
270
|
-
|
|
285
|
+
_throwBoundsError(min, max) {
|
|
286
|
+
const error = boundsError(parseDefaultBound(min), parseDefaultBound(max));
|
|
287
|
+
if (error) {
|
|
288
|
+
throw new Error(error);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
// Build one editable row per report bar filter group (every page or one
|
|
292
|
+
// page), in bar order, seeding each draft from the group's stored default.
|
|
271
293
|
_buildFilterRows(report) {
|
|
272
|
-
const
|
|
273
|
-
const built = (report.filterGroups ?? [])
|
|
274
|
-
.filter((group) => group.level === 'report' || group.level === 'both')
|
|
275
|
-
.sort((a, b) => a.order - b.order)
|
|
294
|
+
const built = defaultRowGroups(report.filterGroups)
|
|
276
295
|
.map((group) => {
|
|
277
296
|
const groupDefault = group.config?.default;
|
|
278
297
|
// One shared, replayed option stream per group: the chips fetch and the
|
|
279
298
|
// stored default's labels read the same list, so it is fetched once.
|
|
280
|
-
const options$ = loadGroupOptions(group, this._reportData,
|
|
281
|
-
const row =
|
|
282
|
-
|
|
283
|
-
label: group.label || group.filters?.[0]?.filterColumn || 'Filter',
|
|
284
|
-
start: dateFromBound(groupDefault?.start),
|
|
285
|
-
end: dateFromBound(groupDefault?.end),
|
|
286
|
-
relative: groupDefault?.relative ?? null,
|
|
287
|
-
// Named below, once the option list carrying their labels is in.
|
|
288
|
-
values: [],
|
|
289
|
-
value: groupDefault?.value ?? '',
|
|
290
|
-
// fs-autocomplete-chips fetch: the group's distinct options, name-filtered.
|
|
291
|
-
// Same loader the report bar uses, so the two never drift.
|
|
292
|
-
fetch: (keyword) => matchOptions(options$, keyword),
|
|
293
|
-
};
|
|
294
|
-
return { row, options$, values: groupDefault?.values ?? [] };
|
|
299
|
+
const options$ = loadGroupOptions(group, this._reportData, report.id);
|
|
300
|
+
const row = this._filterRow(report, group, options$);
|
|
301
|
+
return { row, options$, values: groupDefault?.values ?? groupDefault?.excludeValues ?? [] };
|
|
295
302
|
});
|
|
296
303
|
const rows = built.map((entry) => entry.row);
|
|
297
304
|
const seeded = built.filter((entry) => entry.values.length);
|
|
@@ -313,26 +320,45 @@ export class ReportSettingsComponent {
|
|
|
313
320
|
}), takeUntilDestroyed(this._destroyRef))
|
|
314
321
|
.subscribe();
|
|
315
322
|
}
|
|
323
|
+
// One row's draft, seeded from its group's stored default. A stored select
|
|
324
|
+
// default's values are named later, once the option list carrying their
|
|
325
|
+
// labels is in (see _buildFilterRows).
|
|
326
|
+
_filterRow(report, group, options$) {
|
|
327
|
+
const groupDefault = group.config?.default;
|
|
328
|
+
return {
|
|
329
|
+
group,
|
|
330
|
+
label: defaultRowLabel(group, report.pages),
|
|
331
|
+
period: defaultPeriod(groupDefault),
|
|
332
|
+
periodOptions: defaultPeriodOptions(relativeLabel, groupDefault?.relative ?? null),
|
|
333
|
+
start: dateFromBound(groupDefault?.start),
|
|
334
|
+
end: dateFromBound(groupDefault?.end),
|
|
335
|
+
values: [],
|
|
336
|
+
exclude: !!groupDefault?.excludeValues?.length,
|
|
337
|
+
// An older server lists no features, and leaves no values out.
|
|
338
|
+
showExclude: showExcludeToggle(group, report.viewerFeatures),
|
|
339
|
+
value: groupDefault?.value ?? '',
|
|
340
|
+
min: groupDefault?.min ?? null,
|
|
341
|
+
max: groupDefault?.max ?? null,
|
|
342
|
+
// fs-autocomplete-chips fetch: the group's distinct options, name-filtered.
|
|
343
|
+
// Same loader the report bar uses, so the two never drift.
|
|
344
|
+
fetch: (keyword) => matchOptions(options$, keyword),
|
|
345
|
+
};
|
|
346
|
+
}
|
|
316
347
|
_publishFilterRows(rows) {
|
|
317
348
|
this.filterRows.set(rows);
|
|
318
349
|
this._filtersReady.set(true);
|
|
319
350
|
}
|
|
320
351
|
// The draft default normalized to the wire shape for this row's type, or null
|
|
321
|
-
// when empty (which clears the stored default).
|
|
322
|
-
// dates when there are any, else the carried rolling preset, never both: the
|
|
323
|
-
// server refuses a relative preset combined with dates.
|
|
352
|
+
// when empty (which clears the stored default).
|
|
324
353
|
_rowDefault(row) {
|
|
325
354
|
switch (row.group.type) {
|
|
326
|
-
case 'dateRange':
|
|
327
|
-
|
|
328
|
-
const end = dateToBound(row.end);
|
|
329
|
-
if (start || end) {
|
|
330
|
-
return { start: start ?? undefined, end: end ?? undefined };
|
|
331
|
-
}
|
|
332
|
-
return row.relative ? { relative: row.relative } : null;
|
|
333
|
-
}
|
|
355
|
+
case 'dateRange':
|
|
356
|
+
return dateRangeDefault(row.period, dateToBound(row.start), dateToBound(row.end));
|
|
334
357
|
case 'select':
|
|
335
|
-
|
|
358
|
+
// A hidden toggle leaves nothing out.
|
|
359
|
+
return selectDefault(row.values.map((option) => option.value), row.showExclude && row.exclude);
|
|
360
|
+
case 'numberRange':
|
|
361
|
+
return numberRangeDefault(row.min, row.max);
|
|
336
362
|
case 'keyword':
|
|
337
363
|
default: {
|
|
338
364
|
const value = row.value.trim();
|
|
@@ -340,46 +366,15 @@ export class ReportSettingsComponent {
|
|
|
340
366
|
}
|
|
341
367
|
}
|
|
342
368
|
}
|
|
343
|
-
// Whether the row's draft differs from the group's stored default — only
|
|
344
|
-
// changed rows are persisted on Save.
|
|
345
|
-
_defaultChanged(row) {
|
|
346
|
-
const before = JSON.stringify(this._normalize(row.group.config?.default ?? null));
|
|
347
|
-
const after = JSON.stringify(this._normalize(this._rowDefault(row)));
|
|
348
|
-
return before !== after;
|
|
349
|
-
}
|
|
350
|
-
// A stable comparison form: empty and undefined keys are dropped so a no-op
|
|
351
|
-
// edit doesn't read as a change. relative is compared like the rest: the row
|
|
352
|
-
// carries it, so an untouched rolling default reads as unchanged.
|
|
353
|
-
_normalize(value) {
|
|
354
|
-
if (!value) {
|
|
355
|
-
return null;
|
|
356
|
-
}
|
|
357
|
-
const normalized = {};
|
|
358
|
-
if (value.start) {
|
|
359
|
-
normalized.start = value.start;
|
|
360
|
-
}
|
|
361
|
-
if (value.end) {
|
|
362
|
-
normalized.end = value.end;
|
|
363
|
-
}
|
|
364
|
-
if (value.values?.length) {
|
|
365
|
-
normalized.values = value.values;
|
|
366
|
-
}
|
|
367
|
-
if (value.value) {
|
|
368
|
-
normalized.value = value.value;
|
|
369
|
-
}
|
|
370
|
-
if (value.relative) {
|
|
371
|
-
normalized.relative = value.relative;
|
|
372
|
-
}
|
|
373
|
-
return Object.keys(normalized).length ? normalized : null;
|
|
374
|
-
}
|
|
375
369
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportSettingsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
376
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ReportSettingsComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<form\n fsForm\n [submit]=\"save\">\n <fs-dialog>\n <h1 mat-dialog-title>\n Report Settings\n </h1>\n <mat-dialog-content>\n <!-- One skeleton over the whole body until the locale list is in. -->\n <ng-container *fsSkeletonForm=\"ready() || null\">\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 Name\n </mat-label>\n <input\n matInput\n [(ngModel)]=\"name\"\n name=\"name\"\n [fsFormRequired]=\"true\">\n </mat-form-field>\n <!--\n The page, typed in inches. Orientation is not asked for because it\n is not an independent choice - a page wider than it is tall IS\n landscape - so the two numbers say everything there is to say.\n -->\n <div class=\"fs-row.gap-sm.align-start\">\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Width\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"1\"\n [(ngModel)]=\"pageWidth\"\n name=\"pageWidth\"\n [fsFormRequired]=\"true\"\n [fsFormMin]=\"pageDimensionMin\"\n [fsFormMax]=\"pageDimensionMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"1\"\n [(ngModel)]=\"pageHeight\"\n name=\"pageHeight\"\n [fsFormRequired]=\"true\"\n [fsFormMin]=\"pageDimensionMin\"\n [fsFormMax]=\"pageDimensionMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n </div>\n <!--\n How deep the header and footer bands are. Their content is edited\n on the canvas (Edit layout \u2192 Header & footer); these reserve the\n space for it, and 0 means no band.\n -->\n <mat-form-field class=\"full-width\">\n <mat-label>\n Header height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"2\"\n [(ngModel)]=\"headerHeight\"\n name=\"headerHeight\"\n [fsFormMin]=\"0\"\n [fsFormMax]=\"headerFooterMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Footer height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"2\"\n [(ngModel)]=\"footerHeight\"\n name=\"footerHeight\"\n [fsFormMin]=\"0\"\n [fsFormMax]=\"headerFooterMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <fs-ai-report-timezone-select [(timezone)]=\"timezone\"></fs-ai-report-timezone-select>\n <!--\n How numbers and dates are written (formatting only: no text is\n translated) and which currency money is labeled in. Hidden on a\n server too old to resolve a report's locale.\n -->\n @if (locales()) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Locale\n </mat-label>\n <mat-select\n [ngModel]=\"locale()\"\n (ngModelChange)=\"locale.set($event)\"\n name=\"locale\">\n @for (option of localeOptions(); track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n {{ formatExample() }}\n </mat-hint>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Currency\n </mat-label>\n <mat-select\n [ngModel]=\"currency()\"\n (ngModelChange)=\"currency.set($event)\"\n name=\"currency\">\n @for (option of currencyOptions(); track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n Names the currency amounts are in; it does not convert them.\n </mat-hint>\n </mat-form-field>\n }\n </div>\n </mat-tab>\n <mat-tab\n label=\"Styles\"\n name=\"styles\">\n <div class=\"fs-column tab-body\">\n <mat-form-field>\n <mat-label>\n Heading Size\n </mat-label>\n <input\n matInput\n type=\"number\"\n step=\"1\"\n min=\"6\"\n max=\"96\"\n [(ngModel)]=\"headingSize\"\n name=\"headingSize\"\n [fsFormMin]=\"6\"\n [fsFormMax]=\"96\">\n <span matTextSuffix>\n pt\n </span>\n <mat-hint>\n Applies to component titles. Points map 1:1 to PDF and PowerPoint.\n </mat-hint>\n </mat-form-field>\n </div>\n </mat-tab>\n <mat-tab\n label=\"Filters\"\n name=\"filters\">\n <div class=\"fs-column tab-body\">\n @if (filterRows().length) {\n @for (row of filterRows(); track row.group.id) {\n @switch (row.group.type) {\n @case ('dateRange') {\n <div class=\"fs-row.gap-sm.align-center fs-flex\">\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Default From {{ row.label }}\n </mat-label>\n <input\n matInput\n fsDatePicker\n [(ngModel)]=\"row.start\"\n [name]=\"'start' + row.group.id\">\n </mat-form-field>\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Default To {{ row.label }}\n </mat-label>\n <input\n matInput\n fsDatePicker\n [(ngModel)]=\"row.end\"\n [name]=\"'end' + row.group.id\">\n </mat-form-field>\n </div>\n <!-- A stored rolling preset cannot be authored here, only\n kept, replaced by picking dates, or cleared. type=\"button\"\n keeps Clear from submitting the form. -->\n @if (row.relative && !row.start && !row.end) {\n <div class=\"fs-row.gap-sm.align-center\">\n <mat-hint class=\"fs-flex\">\n Rolling default: {{ relativeLabel(row.relative) }}. Pick dates to replace it.\n </mat-hint>\n <button\n mat-button\n type=\"button\"\n (click)=\"clearRelative(row)\">\n Clear\n </button>\n </div>\n }\n }\n @case ('select') {\n <fs-autocomplete-chips\n class=\"fs-flex\"\n [label]=\"'Default ' + row.label\"\n [fetch]=\"row.fetch\"\n [(ngModel)]=\"row.values\"\n [name]=\"'values' + row.group.id\"\n [multiple]=\"true\"\n [fetchOnFocus]=\"true\">\n <ng-template\n fsAutocompleteChipsTemplate\n let-object=\"object\">\n {{ object.name }}\n </ng-template>\n </fs-autocomplete-chips>\n }\n @default {\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Default {{ row.label }}\n </mat-label>\n <input\n matInput\n [(ngModel)]=\"row.value\"\n [name]=\"'value' + row.group.id\">\n </mat-form-field>\n }\n }\n }\n } @else {\n <fs-message-info>\n This report has no report-level filters yet. Add a filter to a\n component (its settings \u2192 Filters) and show it in the report bar,\n then set its default here.\n </fs-message-info>\n }\n </div>\n </mat-tab>\n </mat-tab-group>\n </ng-container>\n </mat-dialog-content>\n <mat-dialog-actions>\n <fs-form-dialog-actions>\n <button\n type=\"button\"\n mat-button\n color=\"warn\"\n (click)=\"delete()\">\n Delete\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}\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.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { 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.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { 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: "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: FsMessageModule }, { kind: "component", type: i5.FsMessageInfoComponent, selector: "fs-message-info" }, { 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: FsSkeletonModule }, { kind: "directive", type: i7.FsSkeletonFormDirective, selector: "[fsSkeletonForm]", inputs: ["fsSkeletonForm", "fsSkeletonFormLines"] }, { kind: "ngmodule", type: FsDatePickerModule }, { kind: "component", type: i8.FsDatePickerComponent, selector: "[fsDatePicker]", inputs: ["minYear", "maxYear", "minDate", "maxDate", "startOfDay", "view", "format", "minutes", "width"], outputs: ["change"] }, { kind: "ngmodule", type: FsAutocompleteChipsModule }, { kind: "component", type: i9.FsAutocompleteChipsComponent, selector: "fs-autocomplete-chips", inputs: ["fetch", "appearance", "floatLabel", "readonly", "size", "label", "placeholder", "chipImage", "chipBackground", "chipColor", "chipIcon", "chipIconColor", "chipClass", "chipPadding", "shape", "hint", "allowText", "allowObject", "delay", "minPanelWidth", "maxPanelHeight", "validateText", "removable", "allowClear", "color", "background", "orderable", "padless", "initOnClick", "fetchOnFocus", "multiple", "multipleAdd", "confirm", "disabled", "groupBy", "panelWidth", "panelClass", "compareWith"], outputs: ["selected", "removed", "reordered", "clear", "panelOpened", "panelClosed"] }, { kind: "directive", type: i9.FsAutocompleteObjectDirective, selector: "[fsAutocompleteObject],[fsAutocompleteChipsTemplate]" }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i10.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i10.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: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { 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: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { 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: 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: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { kind: "component", type: TimezoneSelectComponent, selector: "fs-ai-report-timezone-select", inputs: ["placeholder", "required", "disabled", "timezone"], outputs: ["timezoneChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
370
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ReportSettingsComponent, isStandalone: true, selector: "ng-component", ngImport: i0, template: "<form\n fsForm\n [submit]=\"save\">\n <fs-dialog>\n <h1 mat-dialog-title>\n Report Settings\n </h1>\n <mat-dialog-content>\n <!-- One skeleton over the whole body until the locale list is in. -->\n <ng-container *fsSkeletonForm=\"ready() || null\">\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 Name\n </mat-label>\n <input\n matInput\n [(ngModel)]=\"name\"\n name=\"name\"\n [fsFormRequired]=\"true\">\n </mat-form-field>\n <!--\n The page, typed in inches. Orientation is not asked for because it\n is not an independent choice - a page wider than it is tall IS\n landscape - so the two numbers say everything there is to say.\n -->\n <div class=\"fs-row.gap-sm.align-start\">\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Width\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"1\"\n [(ngModel)]=\"pageWidth\"\n name=\"pageWidth\"\n [fsFormRequired]=\"true\"\n [fsFormMin]=\"pageDimensionMin\"\n [fsFormMax]=\"pageDimensionMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"1\"\n [(ngModel)]=\"pageHeight\"\n name=\"pageHeight\"\n [fsFormRequired]=\"true\"\n [fsFormMin]=\"pageDimensionMin\"\n [fsFormMax]=\"pageDimensionMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n </div>\n <!--\n How deep the header and footer bands are. Their content is edited\n on the canvas (Edit layout \u2192 Header & footer); these reserve the\n space for it, and 0 means no band.\n -->\n <mat-form-field class=\"full-width\">\n <mat-label>\n Header height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"2\"\n [(ngModel)]=\"headerHeight\"\n name=\"headerHeight\"\n [fsFormMin]=\"0\"\n [fsFormMax]=\"headerFooterMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Footer height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"2\"\n [(ngModel)]=\"footerHeight\"\n name=\"footerHeight\"\n [fsFormMin]=\"0\"\n [fsFormMax]=\"headerFooterMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <fs-ai-report-timezone-select [(timezone)]=\"timezone\"></fs-ai-report-timezone-select>\n <!--\n How numbers and dates are written (formatting only: no text is\n translated) and which currency money is labeled in. Hidden on a\n server too old to resolve a report's locale.\n -->\n @if (locales()) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Locale\n </mat-label>\n <mat-select\n [ngModel]=\"locale()\"\n (ngModelChange)=\"locale.set($event)\"\n name=\"locale\">\n @for (option of localeOptions(); track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n {{ formatExample() }}\n </mat-hint>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Currency\n </mat-label>\n <mat-select\n [ngModel]=\"currency()\"\n (ngModelChange)=\"currency.set($event)\"\n name=\"currency\">\n @for (option of currencyOptions(); track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n Names the currency amounts are in; it does not convert them.\n </mat-hint>\n </mat-form-field>\n }\n </div>\n </mat-tab>\n <mat-tab\n label=\"Styles\"\n name=\"styles\">\n <div class=\"fs-column tab-body\">\n <mat-form-field>\n <mat-label>\n Heading Size\n </mat-label>\n <input\n matInput\n type=\"number\"\n step=\"1\"\n min=\"6\"\n max=\"96\"\n [(ngModel)]=\"headingSize\"\n name=\"headingSize\"\n [fsFormMin]=\"6\"\n [fsFormMax]=\"96\">\n <span matTextSuffix>\n pt\n </span>\n <mat-hint>\n Applies to component titles. Points map 1:1 to PDF and PowerPoint.\n </mat-hint>\n </mat-form-field>\n </div>\n </mat-tab>\n <mat-tab\n label=\"Filters\"\n name=\"filters\">\n <div class=\"fs-column tab-body\">\n @if (filterRows().length) {\n <!-- One section per report bar filter: its heading, then its\n default, one field per row. -->\n @for (row of filterRows(); track row.group.id) {\n <h3>\n {{ row.label }}\n </h3>\n @switch (row.group.type) {\n @case ('dateRange') {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Default period\n </mat-label>\n <mat-select\n [ngModel]=\"row.period\"\n (ngModelChange)=\"patchRow(row, { period: $event })\"\n [name]=\"'period' + row.group.id\">\n @for (option of row.periodOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n @if (row.period === fixedDatesPeriod) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Default from\n </mat-label>\n <input\n matInput\n fsDatePicker\n [(ngModel)]=\"row.start\"\n [name]=\"'start' + row.group.id\">\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Default to\n </mat-label>\n <input\n matInput\n fsDatePicker\n [(ngModel)]=\"row.end\"\n [name]=\"'end' + row.group.id\">\n </mat-form-field>\n }\n }\n @case ('select') {\n <fs-label-field class=\"full-width\">\n <fs-autocomplete-chips\n class=\"full-width\"\n label=\"Default values\"\n [fetch]=\"row.fetch\"\n [(ngModel)]=\"row.values\"\n [name]=\"'values' + row.group.id\"\n [multiple]=\"true\"\n [fetchOnFocus]=\"true\">\n <ng-template\n fsAutocompleteChipsTemplate\n let-object=\"object\">\n {{ object.name }}\n </ng-template>\n </fs-autocomplete-chips>\n </fs-label-field>\n @if (row.showExclude) {\n <fs-label-field>\n <mat-slide-toggle\n [ngModel]=\"row.exclude\"\n (ngModelChange)=\"patchRow(row, { exclude: $event })\"\n [name]=\"'exclude' + row.group.id\">\n Exclude these values\n </mat-slide-toggle>\n </fs-label-field>\n }\n }\n @case ('numberRange') {\n <!-- fsMaskNumber hands back text; the check and the save\n read it through parseDefaultBound, so 0 is kept. -->\n <mat-form-field class=\"full-width\">\n <mat-label>\n Default minimum\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [signed]=\"true\"\n [scale]=\"boundScale\"\n [ngModel]=\"row.min\"\n (ngModelChange)=\"patchRow(row, { min: $event })\"\n [name]=\"'min' + row.group.id\"\n [validate]=\"minBoundValidator\"\n [validateData]=\"row.max\">\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Default maximum\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [signed]=\"true\"\n [scale]=\"boundScale\"\n [ngModel]=\"row.max\"\n (ngModelChange)=\"patchRow(row, { max: $event })\"\n [name]=\"'max' + row.group.id\"\n [validate]=\"maxBoundValidator\"\n [validateData]=\"row.min\">\n </mat-form-field>\n }\n @default {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Default text\n </mat-label>\n <input\n matInput\n [(ngModel)]=\"row.value\"\n [name]=\"'value' + row.group.id\">\n </mat-form-field>\n }\n }\n }\n } @else {\n <fs-message-info>\n This report has no report bar filters yet. Add a filter to a\n component (its settings \u2192 Filters) and show it in the report bar,\n then set its default here.\n </fs-message-info>\n }\n </div>\n </mat-tab>\n </mat-tab-group>\n </ng-container>\n </mat-dialog-content>\n <mat-dialog-actions>\n <fs-form-dialog-actions>\n <button\n type=\"button\"\n mat-button\n color=\"warn\"\n (click)=\"delete()\">\n Delete\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}\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.NumberValueAccessor, selector: "input[type=number][formControlName],input[type=number][formControl],input[type=number][ngModel]" }, { 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.MinValidator, selector: "input[type=number][min][formControlName],input[type=number][min][formControl],input[type=number][min][ngModel]", inputs: ["min"] }, { kind: "directive", type: i1.MaxValidator, selector: "input[type=number][max][formControlName],input[type=number][max][formControl],input[type=number][max][ngModel]", inputs: ["max"] }, { 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.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: FsLabelModule }, { kind: "component", type: i3.FsLabelFieldComponent, selector: "fs-label-field", inputs: ["appearance", "showOutline", "disabled", "focused", "hoverable", "padless"] }, { kind: "ngmodule", type: FsMaskModule }, { kind: "directive", type: i4.FsMaskNumberDirective, selector: "[fsMaskNumber]" }, { kind: "ngmodule", type: FsDialogModule }, { kind: "component", type: i5.FsDialogComponent, selector: "fs-dialog", inputs: ["mobileMode", "mobileButtonPlacement", "mobileWidth", "mode", "buttonLayout"] }, { kind: "ngmodule", type: FsMessageModule }, { kind: "component", type: i6.FsMessageInfoComponent, selector: "fs-message-info" }, { kind: "ngmodule", type: FsTabsModule }, { kind: "directive", type: i7.FsTabsHeaderTabGroupDirective, selector: "mat-tab-group, matTabGroup, [matTabGroup]", inputs: ["orientation", "selected", "selectedData"], outputs: ["selectedChange", "selectedDataChange"], exportAs: ["fsTabsHeaderTabGroup"] }, { kind: "directive", type: i7.FsTabsTabDirective, selector: "mat-tab,matTab", inputs: ["name", "data"], exportAs: ["fsTabsTab"] }, { kind: "ngmodule", type: FsSkeletonModule }, { kind: "directive", type: i8.FsSkeletonFormDirective, selector: "[fsSkeletonForm]", inputs: ["fsSkeletonForm", "fsSkeletonFormLines"] }, { kind: "ngmodule", type: FsDatePickerModule }, { kind: "component", type: i9.FsDatePickerComponent, selector: "[fsDatePicker]", inputs: ["minYear", "maxYear", "minDate", "maxDate", "startOfDay", "view", "format", "minutes", "width"], outputs: ["change"] }, { kind: "ngmodule", type: FsAutocompleteChipsModule }, { kind: "component", type: i10.FsAutocompleteChipsComponent, selector: "fs-autocomplete-chips", inputs: ["fetch", "appearance", "floatLabel", "readonly", "size", "label", "placeholder", "chipImage", "chipBackground", "chipColor", "chipIcon", "chipIconColor", "chipClass", "chipPadding", "shape", "hint", "allowText", "allowObject", "delay", "minPanelWidth", "maxPanelHeight", "validateText", "removable", "allowClear", "color", "background", "orderable", "padless", "initOnClick", "fetchOnFocus", "multiple", "multipleAdd", "confirm", "disabled", "groupBy", "panelWidth", "panelClass", "compareWith"], outputs: ["selected", "removed", "reordered", "clear", "panelOpened", "panelClosed"] }, { kind: "directive", type: i10.FsAutocompleteObjectDirective, selector: "[fsAutocompleteObject],[fsAutocompleteChipsTemplate]" }, { kind: "ngmodule", type: MatTabsModule }, { kind: "component", type: i11.MatTab, selector: "mat-tab", inputs: ["disabled", "label", "aria-label", "aria-labelledby", "labelClass", "bodyClass"], exportAs: ["matTab"] }, { kind: "component", type: i11.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: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { 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: "component", type: MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: MatLabel, selector: "mat-label" }, { kind: "directive", type: MatHint, selector: "mat-hint", inputs: ["align", "id"] }, { kind: "directive", type: MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { 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: 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: MatOption, selector: "mat-option", inputs: ["value", "id", "disabled"], outputs: ["onSelectionChange"], exportAs: ["matOption"] }, { 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: "component", type: TimezoneSelectComponent, selector: "fs-ai-report-timezone-select", inputs: ["placeholder", "required", "disabled", "timezone"], outputs: ["timezoneChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
|
|
377
371
|
}
|
|
378
372
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportSettingsComponent, decorators: [{
|
|
379
373
|
type: Component,
|
|
380
374
|
args: [{ changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
|
|
381
375
|
FormsModule,
|
|
382
376
|
FsFormModule,
|
|
377
|
+
FsLabelModule,
|
|
383
378
|
FsMaskModule,
|
|
384
379
|
FsDialogModule,
|
|
385
380
|
FsMessageModule,
|
|
@@ -399,7 +394,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
399
394
|
MatInput,
|
|
400
395
|
MatSelect,
|
|
401
396
|
MatOption,
|
|
397
|
+
MatSlideToggle,
|
|
402
398
|
TimezoneSelectComponent,
|
|
403
|
-
], template: "<form\n fsForm\n [submit]=\"save\">\n <fs-dialog>\n <h1 mat-dialog-title>\n Report Settings\n </h1>\n <mat-dialog-content>\n <!-- One skeleton over the whole body until the locale list is in. -->\n <ng-container *fsSkeletonForm=\"ready() || null\">\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 Name\n </mat-label>\n <input\n matInput\n [(ngModel)]=\"name\"\n name=\"name\"\n [fsFormRequired]=\"true\">\n </mat-form-field>\n <!--\n The page, typed in inches. Orientation is not asked for because it\n is not an independent choice - a page wider than it is tall IS\n landscape - so the two numbers say everything there is to say.\n -->\n <div class=\"fs-row.gap-sm.align-start\">\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Width\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"1\"\n [(ngModel)]=\"pageWidth\"\n name=\"pageWidth\"\n [fsFormRequired]=\"true\"\n [fsFormMin]=\"pageDimensionMin\"\n [fsFormMax]=\"pageDimensionMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"1\"\n [(ngModel)]=\"pageHeight\"\n name=\"pageHeight\"\n [fsFormRequired]=\"true\"\n [fsFormMin]=\"pageDimensionMin\"\n [fsFormMax]=\"pageDimensionMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n </div>\n <!--\n How deep the header and footer bands are. Their content is edited\n on the canvas (Edit layout \u2192 Header & footer); these reserve the\n space for it, and 0 means no band.\n -->\n <mat-form-field class=\"full-width\">\n <mat-label>\n Header height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"2\"\n [(ngModel)]=\"headerHeight\"\n name=\"headerHeight\"\n [fsFormMin]=\"0\"\n [fsFormMax]=\"headerFooterMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Footer height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"2\"\n [(ngModel)]=\"footerHeight\"\n name=\"footerHeight\"\n [fsFormMin]=\"0\"\n [fsFormMax]=\"headerFooterMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <fs-ai-report-timezone-select [(timezone)]=\"timezone\"></fs-ai-report-timezone-select>\n <!--\n How numbers and dates are written (formatting only: no text is\n translated) and which currency money is labeled in. Hidden on a\n server too old to resolve a report's locale.\n -->\n @if (locales()) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Locale\n </mat-label>\n <mat-select\n [ngModel]=\"locale()\"\n (ngModelChange)=\"locale.set($event)\"\n name=\"locale\">\n @for (option of localeOptions(); track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n {{ formatExample() }}\n </mat-hint>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Currency\n </mat-label>\n <mat-select\n [ngModel]=\"currency()\"\n (ngModelChange)=\"currency.set($event)\"\n name=\"currency\">\n @for (option of currencyOptions(); track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n Names the currency amounts are in; it does not convert them.\n </mat-hint>\n </mat-form-field>\n }\n </div>\n </mat-tab>\n <mat-tab\n label=\"Styles\"\n name=\"styles\">\n <div class=\"fs-column tab-body\">\n <mat-form-field>\n <mat-label>\n Heading Size\n </mat-label>\n <input\n matInput\n type=\"number\"\n step=\"1\"\n min=\"6\"\n max=\"96\"\n [(ngModel)]=\"headingSize\"\n name=\"headingSize\"\n [fsFormMin]=\"6\"\n [fsFormMax]=\"96\">\n <span matTextSuffix>\n pt\n </span>\n <mat-hint>\n Applies to component titles. Points map 1:1 to PDF and PowerPoint.\n </mat-hint>\n </mat-form-field>\n </div>\n </mat-tab>\n <mat-tab\n label=\"Filters\"\n name=\"filters\">\n <div class=\"fs-column tab-body\">\n @if (filterRows().length) {\n @for (row of filterRows(); track row.group.id) {\n @switch (row.group.type) {\n @case ('dateRange') {\n <div class=\"fs-row.gap-sm.align-center fs-flex\">\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Default From {{ row.label }}\n </mat-label>\n <input\n matInput\n fsDatePicker\n [(ngModel)]=\"row.start\"\n [name]=\"'start' + row.group.id\">\n </mat-form-field>\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Default To {{ row.label }}\n </mat-label>\n <input\n matInput\n fsDatePicker\n [(ngModel)]=\"row.end\"\n [name]=\"'end' + row.group.id\">\n </mat-form-field>\n </div>\n <!-- A stored rolling preset cannot be authored here, only\n kept, replaced by picking dates, or cleared. type=\"button\"\n keeps Clear from submitting the form. -->\n @if (row.relative && !row.start && !row.end) {\n <div class=\"fs-row.gap-sm.align-center\">\n <mat-hint class=\"fs-flex\">\n Rolling default: {{ relativeLabel(row.relative) }}. Pick dates to replace it.\n </mat-hint>\n <button\n mat-button\n type=\"button\"\n (click)=\"clearRelative(row)\">\n Clear\n </button>\n </div>\n }\n }\n @case ('select') {\n <fs-autocomplete-chips\n class=\"fs-flex\"\n [label]=\"'Default ' + row.label\"\n [fetch]=\"row.fetch\"\n [(ngModel)]=\"row.values\"\n [name]=\"'values' + row.group.id\"\n [multiple]=\"true\"\n [fetchOnFocus]=\"true\">\n <ng-template\n fsAutocompleteChipsTemplate\n let-object=\"object\">\n {{ object.name }}\n </ng-template>\n </fs-autocomplete-chips>\n }\n @default {\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Default {{ row.label }}\n </mat-label>\n <input\n matInput\n [(ngModel)]=\"row.value\"\n [name]=\"'value' + row.group.id\">\n </mat-form-field>\n }\n }\n }\n } @else {\n <fs-message-info>\n This report has no report-level filters yet. Add a filter to a\n component (its settings \u2192 Filters) and show it in the report bar,\n then set its default here.\n </fs-message-info>\n }\n </div>\n </mat-tab>\n </mat-tab-group>\n </ng-container>\n </mat-dialog-content>\n <mat-dialog-actions>\n <fs-form-dialog-actions>\n <button\n type=\"button\"\n mat-button\n color=\"warn\"\n (click)=\"delete()\">\n Delete\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}\n"] }]
|
|
399
|
+
], template: "<form\n fsForm\n [submit]=\"save\">\n <fs-dialog>\n <h1 mat-dialog-title>\n Report Settings\n </h1>\n <mat-dialog-content>\n <!-- One skeleton over the whole body until the locale list is in. -->\n <ng-container *fsSkeletonForm=\"ready() || null\">\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 Name\n </mat-label>\n <input\n matInput\n [(ngModel)]=\"name\"\n name=\"name\"\n [fsFormRequired]=\"true\">\n </mat-form-field>\n <!--\n The page, typed in inches. Orientation is not asked for because it\n is not an independent choice - a page wider than it is tall IS\n landscape - so the two numbers say everything there is to say.\n -->\n <div class=\"fs-row.gap-sm.align-start\">\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Width\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"1\"\n [(ngModel)]=\"pageWidth\"\n name=\"pageWidth\"\n [fsFormRequired]=\"true\"\n [fsFormMin]=\"pageDimensionMin\"\n [fsFormMax]=\"pageDimensionMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <mat-form-field class=\"fs-flex\">\n <mat-label>\n Height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"1\"\n [(ngModel)]=\"pageHeight\"\n name=\"pageHeight\"\n [fsFormRequired]=\"true\"\n [fsFormMin]=\"pageDimensionMin\"\n [fsFormMax]=\"pageDimensionMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n </div>\n <!--\n How deep the header and footer bands are. Their content is edited\n on the canvas (Edit layout \u2192 Header & footer); these reserve the\n space for it, and 0 means no band.\n -->\n <mat-form-field class=\"full-width\">\n <mat-label>\n Header height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"2\"\n [(ngModel)]=\"headerHeight\"\n name=\"headerHeight\"\n [fsFormMin]=\"0\"\n [fsFormMax]=\"headerFooterMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Footer height\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [scale]=\"2\"\n [(ngModel)]=\"footerHeight\"\n name=\"footerHeight\"\n [fsFormMin]=\"0\"\n [fsFormMax]=\"headerFooterMax\">\n <div matTextSuffix>\n inches\n </div>\n </mat-form-field>\n <fs-ai-report-timezone-select [(timezone)]=\"timezone\"></fs-ai-report-timezone-select>\n <!--\n How numbers and dates are written (formatting only: no text is\n translated) and which currency money is labeled in. Hidden on a\n server too old to resolve a report's locale.\n -->\n @if (locales()) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Locale\n </mat-label>\n <mat-select\n [ngModel]=\"locale()\"\n (ngModelChange)=\"locale.set($event)\"\n name=\"locale\">\n @for (option of localeOptions(); track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n {{ formatExample() }}\n </mat-hint>\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Currency\n </mat-label>\n <mat-select\n [ngModel]=\"currency()\"\n (ngModelChange)=\"currency.set($event)\"\n name=\"currency\">\n @for (option of currencyOptions(); track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.label }}\n </mat-option>\n }\n </mat-select>\n <mat-hint>\n Names the currency amounts are in; it does not convert them.\n </mat-hint>\n </mat-form-field>\n }\n </div>\n </mat-tab>\n <mat-tab\n label=\"Styles\"\n name=\"styles\">\n <div class=\"fs-column tab-body\">\n <mat-form-field>\n <mat-label>\n Heading Size\n </mat-label>\n <input\n matInput\n type=\"number\"\n step=\"1\"\n min=\"6\"\n max=\"96\"\n [(ngModel)]=\"headingSize\"\n name=\"headingSize\"\n [fsFormMin]=\"6\"\n [fsFormMax]=\"96\">\n <span matTextSuffix>\n pt\n </span>\n <mat-hint>\n Applies to component titles. Points map 1:1 to PDF and PowerPoint.\n </mat-hint>\n </mat-form-field>\n </div>\n </mat-tab>\n <mat-tab\n label=\"Filters\"\n name=\"filters\">\n <div class=\"fs-column tab-body\">\n @if (filterRows().length) {\n <!-- One section per report bar filter: its heading, then its\n default, one field per row. -->\n @for (row of filterRows(); track row.group.id) {\n <h3>\n {{ row.label }}\n </h3>\n @switch (row.group.type) {\n @case ('dateRange') {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Default period\n </mat-label>\n <mat-select\n [ngModel]=\"row.period\"\n (ngModelChange)=\"patchRow(row, { period: $event })\"\n [name]=\"'period' + row.group.id\">\n @for (option of row.periodOptions; track option.value) {\n <mat-option [value]=\"option.value\">\n {{ option.name }}\n </mat-option>\n }\n </mat-select>\n </mat-form-field>\n @if (row.period === fixedDatesPeriod) {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Default from\n </mat-label>\n <input\n matInput\n fsDatePicker\n [(ngModel)]=\"row.start\"\n [name]=\"'start' + row.group.id\">\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Default to\n </mat-label>\n <input\n matInput\n fsDatePicker\n [(ngModel)]=\"row.end\"\n [name]=\"'end' + row.group.id\">\n </mat-form-field>\n }\n }\n @case ('select') {\n <fs-label-field class=\"full-width\">\n <fs-autocomplete-chips\n class=\"full-width\"\n label=\"Default values\"\n [fetch]=\"row.fetch\"\n [(ngModel)]=\"row.values\"\n [name]=\"'values' + row.group.id\"\n [multiple]=\"true\"\n [fetchOnFocus]=\"true\">\n <ng-template\n fsAutocompleteChipsTemplate\n let-object=\"object\">\n {{ object.name }}\n </ng-template>\n </fs-autocomplete-chips>\n </fs-label-field>\n @if (row.showExclude) {\n <fs-label-field>\n <mat-slide-toggle\n [ngModel]=\"row.exclude\"\n (ngModelChange)=\"patchRow(row, { exclude: $event })\"\n [name]=\"'exclude' + row.group.id\">\n Exclude these values\n </mat-slide-toggle>\n </fs-label-field>\n }\n }\n @case ('numberRange') {\n <!-- fsMaskNumber hands back text; the check and the save\n read it through parseDefaultBound, so 0 is kept. -->\n <mat-form-field class=\"full-width\">\n <mat-label>\n Default minimum\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [signed]=\"true\"\n [scale]=\"boundScale\"\n [ngModel]=\"row.min\"\n (ngModelChange)=\"patchRow(row, { min: $event })\"\n [name]=\"'min' + row.group.id\"\n [validate]=\"minBoundValidator\"\n [validateData]=\"row.max\">\n </mat-form-field>\n <mat-form-field class=\"full-width\">\n <mat-label>\n Default maximum\n </mat-label>\n <input\n matInput\n fsMaskNumber\n [signed]=\"true\"\n [scale]=\"boundScale\"\n [ngModel]=\"row.max\"\n (ngModelChange)=\"patchRow(row, { max: $event })\"\n [name]=\"'max' + row.group.id\"\n [validate]=\"maxBoundValidator\"\n [validateData]=\"row.min\">\n </mat-form-field>\n }\n @default {\n <mat-form-field class=\"full-width\">\n <mat-label>\n Default text\n </mat-label>\n <input\n matInput\n [(ngModel)]=\"row.value\"\n [name]=\"'value' + row.group.id\">\n </mat-form-field>\n }\n }\n }\n } @else {\n <fs-message-info>\n This report has no report bar filters yet. Add a filter to a\n component (its settings \u2192 Filters) and show it in the report bar,\n then set its default here.\n </fs-message-info>\n }\n </div>\n </mat-tab>\n </mat-tab-group>\n </ng-container>\n </mat-dialog-content>\n <mat-dialog-actions>\n <fs-form-dialog-actions>\n <button\n type=\"button\"\n mat-button\n color=\"warn\"\n (click)=\"delete()\">\n Delete\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}\n"] }]
|
|
404
400
|
}] });
|
|
405
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LXNldHRpbmdzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy9kaWFsb2dzL3JlcG9ydC1zZXR0aW5ncy9yZXBvcnQtc2V0dGluZ3MuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2RpYWxvZ3MvcmVwb3J0LXNldHRpbmdzL3JlcG9ydC1zZXR0aW5ncy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBVSxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNqSCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFN0MsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxlQUFlLEVBQUUsZ0JBQWdCLEVBQUUsZ0JBQWdCLEVBQUUsWUFBWSxFQUFFLGNBQWMsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQzdILE9BQU8sRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUMxRixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDbkQsT0FBTyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFdkQsT0FBTyxFQUFFLHlCQUF5QixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDM0UsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDNUQs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LCtvQkFDYixTQUFTLGlMQUNULGNBQWMsK0hBQ2QsZ0JBQWdCLHlHQUNoQixnQkFBZ0IsNEhBQ2hCLFlBQVksNExBQ1osUUFBUSxzREFDUixPQUFPLDhFQUNQLFNBQVMscUhBQ1QsUUFBUSxpVUFDUixTQUFTLHdlQUNULFNBQVMscUpBQ1QsdUJBQXVCOzs0RkFHZCx1QkFBdUI7a0JBOUJuQyxTQUFTO3NDQUdTLHVCQUF1QixDQUFDLE1BQU0sY0FDbkMsSUFBSSxXQUNQO3dCQUNQLFdBQVc7d0JBQ1gsWUFBWTt3QkFDWixZQUFZO3dCQUNaLGNBQWM7d0JBQ2QsZUFBZTt3QkFDZixZQUFZO3dCQUNaLGdCQUFnQjt3QkFDaEIsa0JBQWtCO3dCQUNsQix5QkFBeUI7d0JBQ3pCLGFBQWE7d0JBQ2IsU0FBUzt3QkFDVCxjQUFjO3dCQUNkLGdCQUFnQjt3QkFDaEIsZ0JBQWdCO3dCQUNoQixZQUFZO3dCQUNaLFFBQVE7d0JBQ1IsT0FBTzt3QkFDUCxTQUFTO3dCQUNULFFBQVE7d0JBQ1IsU0FBUzt3QkFDVCxTQUFTO3dCQUNULHVCQUF1QjtxQkFDeEIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBEZXN0cm95UmVmLCBPbkluaXQsIGNvbXB1dGVkLCBpbmplY3QsIHNpZ25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbmltcG9ydCB7IE1hdEJ1dHRvbiB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2J1dHRvbic7XG5pbXBvcnQgeyBNQVRfRElBTE9HX0RBVEEsIE1hdERpYWxvZ0FjdGlvbnMsIE1hdERpYWxvZ0NvbnRlbnQsIE1hdERpYWxvZ1JlZiwgTWF0RGlhbG9nVGl0bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9kaWFsb2cnO1xuaW1wb3J0IHsgTWF0Rm9ybUZpZWxkLCBNYXRMYWJlbCwgTWF0SGludCwgTWF0U3VmZml4IH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZm9ybS1maWVsZCc7XG5pbXBvcnQgeyBNYXRJbnB1dCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2lucHV0JztcbmltcG9ydCB7IE1hdE9wdGlvbiwgTWF0U2VsZWN0IH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvc2VsZWN0JztcbmltcG9ydCB7IE1hdFRhYnNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC90YWJzJztcblxuaW1wb3J0IHsgRnNBdXRvY29tcGxldGVDaGlwc01vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL2F1dG9jb21wbGV0ZS1jaGlwcyc7XG5pbXBvcnQgeyBGc0RhdGVQaWNrZXJNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9kYXRlcGlja2VyJztcbmltcG9ydCB7IEZzRGlhbG9nTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvZGlhbG9nJztcbmltcG9ydCB7IEZzRm9ybU1vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL2Zvcm0nO1xuaW1wb3J0IHsgRnNNYXNrTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvbWFzayc7XG5pbXBvcnQgeyBGc01lc3NhZ2UsIEZzTWVzc2FnZU1vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL21lc3NhZ2UnO1xuaW1wb3J0IHsgRnNQcm9tcHQgfSBmcm9tICdAZmlyZXN0aXRjaC9wcm9tcHQnO1xuaW1wb3J0IHsgRnNTa2VsZXRvbk1vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL3NrZWxldG9uJztcbmltcG9ydCB7IEZzVGFic01vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL3RhYnMnO1xuXG5pbXBvcnQgeyBUaW1lem9uZVNlbGVjdENvbXBvbmVudCB9IGZyb20gJy4uLy4uL2NvbXBvbmVudHMvdGltZXpvbmUtc2VsZWN0L3RpbWV6b25lLXNlbGVjdC5jb21wb25lbnQnO1xuXG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBmb3JrSm9pbiwgb2YgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGNhdGNoRXJyb3IsIGZpbmFsaXplLCBzd2l0Y2hNYXAsIHRhcCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgUmVwb3J0RGF0YSB9IGZyb20gJy4uLy4uL2RhdGEvcmVwb3J0LmRhdGEnO1xuaW1wb3J0IHsgUmVwb3J0VmFsdWVGb3JtYXQgfSBmcm9tICcuLi8uLi9lbnVtcy9yZXBvcnQtdmFsdWUtZm9ybWF0LmVudW0nO1xuaW1wb3J0IHtcbiAgREFZX1NIT1JULFxuICBSRVBPUlRfRkFMTEJBQ0tfQ1VSUkVOQ1ksXG4gIGN1cnJlbmN5TmFtZSxcbiAgZm9ybWF0TG9jYWxEYXRlLFxuICBmb3JtYXROdW1iZXIsXG4gIGxvY2FsZU5hbWUsXG4gIHJlc29sdmVSZXBvcnRDdXJyZW5jeSxcbiAgcmVzb2x2ZVJlcG9ydExvY2FsZSxcbn0gZnJvbSAnLi4vLi4vZm9ybWF0JztcbmltcG9ydCB7XG4gIEZpbHRlckdyb3VwRGVmYXVsdCxcbiAgUmVwb3J0LFxuICBSZXBvcnRGaWx0ZXJHcm91cCxcbiAgUmVwb3J0TG9jYWxlcyxcbn0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9yZXBvcnQuaW50ZXJmYWNlJztcbmltcG9ydCB7IERFRkFVTFRfSEVBRElOR19TSVpFLCBIRUFERVJfRk9PVEVSX01BWCwgUEFHRV9ESU1FTlNJT05fTUFYLCBQQUdFX0RJTUVOU0lPTl9NSU4gfSBmcm9tICcuLi8uLi9sYXlvdXQnO1xuaW1wb3J0IHtcbiAgZGF0ZUZyb21Cb3VuZCwgZGF0ZVRvQm91bmQsIGxvYWRHcm91cE9wdGlvbnMsIG1hdGNoT3B0aW9ucywgcmVsYXRpdmVMYWJlbCwgcmVzb2x2ZU9wdGlvblZhbHVlcyxcbn0gZnJvbSAnLi4vLi4vcmVwb3J0LWZpbHRlci1pdGVtcyc7XG5cbmltcG9ydCB7IHJlcG9ydExvY2FsZVBhdGNoIH0gZnJvbSAnLi9yZXBvcnQtbG9jYWxlLXBhdGNoJztcblxuXG4vLyBXaGF0IHRoZSBkaWFsb2cgaGFuZHMgYmFjayB3aGVuIGl0IGNsb3Nlcywgc28gdGhlIHBhZ2Uga25vd3Mgd2hhdCBoYXBwZW5lZFxuLy8gd2l0aG91dCBzbmlmZmluZyBtYWdpYyBzdHJpbmdzLiBBIGRpc21pc3NlZCBkaWFsb2cgY2xvc2VzIHdpdGggYHVuZGVmaW5lZGAuXG5leHBvcnQgaW50ZXJmYWNlIFJlcG9ydFNldHRpbmdzUmVzdWx0IHtcbiAgYWN0aW9uOiAnc2F2ZWQnIHwgJ2RlbGV0ZWQnO1xufVxuXG5cbi8vIE9uZSByZXBvcnQtbGV2ZWwgZmlsdGVyIGluIHRoZSBGaWx0ZXJzIHRhYjogaXRzIGdyb3VwLCB0aGUgaW5mZXJyZWQgaW50ZXJmYWNlLFxuLy8gYW5kIGFuIGVkaXRhYmxlIGRyYWZ0IGRlZmF1bHQuIFRoZSBkcmFmdCBmaWVsZHMgdXNlZCBkZXBlbmQgb24gdGhlIHR5cGVcbi8vIChkYXRlUmFuZ2Ug4oaSIHN0YXJ0L2VuZCBEYXRlcyBvciBhIHN0b3JlZCByb2xsaW5nIGByZWxhdGl2ZWAgcHJlc2V0OyBzZWxlY3Qg4oaSXG4vLyB2YWx1ZXM7IGtleXdvcmQg4oaSIHRleHQpLiBgZmV0Y2hgIGxvYWRzIHRoZSBzZWxlY3Qgb3B0aW9ucyB0aGUgc2FtZSB3YXkgdGhlXG4vLyByZXBvcnQgYmFyIGRvZXMuXG5pbnRlcmZhY2UgRmlsdGVyRGVmYXVsdFJvdyB7XG4gIGdyb3VwOiBSZXBvcnRGaWx0ZXJHcm91cDtcbiAgbGFiZWw6IHN0cmluZztcbiAgc3RhcnQ6IERhdGUgfCBudWxsO1xuICBlbmQ6IERhdGUgfCBudWxsO1xuICAvLyBUaGUgc3RvcmVkIHJvbGxpbmcgcHJlc2V0IChlLmcuICdsYXN0MTJNb250aHMnKS4gTm90IGF1dGhvcmVkIGhlcmU6IGl0IGlzXG4gIC8vIGNhcnJpZWQgc28gYW4gdW50b3VjaGVkIG9uZSBpcyBzZW50IGJhY2sgYXMgaXQgd2FzLCBhbmQgcGlja2VkIGRhdGVzIG9yXG4gIC8vIENsZWFyIHJlcGxhY2UgaXQuXG4gIHJlbGF0aXZlOiBzdHJpbmcgfCBudWxsO1xuICB2YWx1ZXM6IHsgbmFtZTogc3RyaW5nOyB2YWx1ZTogdW5rbm93biB9W107XG4gIHZhbHVlOiBzdHJpbmc7XG4gIGZldGNoOiAoa2V5d29yZD86IHN0cmluZykgPT4gT2JzZXJ2YWJsZTx7IG5hbWU6IHN0cmluZzsgdmFsdWU6IHVua25vd24gfVtdPjtcbn1cblxuLy8gT25lIGVudHJ5IG9mIHRoZSBMb2NhbGUgb3IgQ3VycmVuY3kgc2VsZWN0LiAnJyBpcyB0aGUgZXhwbGljaXQgRGVmYXVsdC5cbmludGVyZmFjZSBMb2NhbGVTZWxlY3RPcHRpb24ge1xuICB2YWx1ZTogc3RyaW5nO1xuICBsYWJlbDogc3RyaW5nO1xufVxuXG4vLyBUaGUgZGF5IHRoZSBMb2NhbGUgaGludCB3cml0ZXMsIGEgZml4ZWQgY2FsZW5kYXIgZGF5IHNvIHRoZSBleGFtcGxlIG5ldmVyXG4vLyBjaGFuZ2VzIHVuZGVyIHRoZSBvcGVyYXRvci5cbmNvbnN0IEVYQU1QTEVfREFZID0gbmV3IERhdGUoMjAyNiwgMCwgNSk7XG5jb25zdCBFWEFNUExFX0FNT1VOVCA9IDEyMzQuNTtcblxuLy8gJ0NhbmFkaWFuIEZyZW5jaCAoZnItQ0EpJywgJ0NhbmFkaWFuIERvbGxhciAoQ0FEKSc6IEVuZ2xpc2ggbmFtZXMgd2hhdGV2ZXJcbi8vIHRoZSByZXBvcnQncyBsb2NhbGUsIHdpdGggdGhlIGNvZGUgdGhhdCBpcyBzdG9yZWQuXG5mdW5jdGlvbiBsb2NhbGVMYWJlbCh0YWc6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgJHtsb2NhbGVOYW1lKHRhZyl9ICgke3RhZ30pYDtcbn1cblxuZnVuY3Rpb24gY3VycmVuY3lMYWJlbChjb2RlOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYCR7Y3VycmVuY3lOYW1lKGNvZGUpfSAoJHtjb2RlfSlgO1xufVxuXG5cbi8vIFJlcG9ydCBzZXR0aW5ncywgaW4gdGhyZWUgdGFiczpcbi8vICAgU2V0dGluZ3Mg4oCUIG5hbWUgKyBwYWdlIHNldHVwIChzaXplIGluIGluY2hlcywgaGVhZGVyL2Zvb3RlciBiYW5kIGRlcHRocykuXG4vLyAgIFN0eWxlcyAgIOKAlCB0aGUgcmVwb3J0J3MgdHlwb2dyYXBoaWMgc3R5bGVzIChzaXplcyBpbiBQT0lOVFMsIDE6MSB3aXRoXG4vLyAgIFBERi9Qb3dlclBvaW50KTsgdGhlIEhlYWRpbmcgc2l6ZSB0byBzdGFydC5cbi8vICAgRmlsdGVycyAg4oCUIHRoZSByZXBvcnQtbGV2ZWwgZmlsdGVycyBhbmQgdGhlaXIgREVGQVVMVCB2YWx1ZXMuIEEgZGVmYXVsdFxuLy8gICBzZWVkcyB0aGUgcmVwb3J0IGJhciBvbiBldmVyeSBvcGVuIChmb3IgZXZlcnkgdmlld2VyKSBidXQgc3RheXNcbi8vICAgdXNlci1jaGFuZ2VhYmxlIOKAlCBpdCBwcmUtZmlsbHMgdGhlIGNvbnRyb2wsIGl0IGRvZXNuJ3QgbG9jayBpdC4gVGhpcyBpcyB0aGVcbi8vICAgZml4IGZvciBoZWF2eSByZXBvcnRzIG9wZW5pbmcgYmxhbmsgYW5kIHRpbWluZyBvdXQ6IGEgZGVmYXVsdCBtb250aCArXG4vLyAgIG9yZ2FuaXphdGlvbiBzY29wZXMgdGhlIGxhbmRpbmcgcGFnZSBmcm9tIHRoZSBmaXJzdCBsb2FkLlxuQENvbXBvbmVudCh7XG4gIHRlbXBsYXRlVXJsOiAnLi9yZXBvcnQtc2V0dGluZ3MuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9yZXBvcnQtc2V0dGluZ3MuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBGb3Jtc01vZHVsZSxcbiAgICBGc0Zvcm1Nb2R1bGUsXG4gICAgRnNNYXNrTW9kdWxlLFxuICAgIEZzRGlhbG9nTW9kdWxlLFxuICAgIEZzTWVzc2FnZU1vZHVsZSxcbiAgICBGc1RhYnNNb2R1bGUsXG4gICAgRnNTa2VsZXRvbk1vZHVsZSxcbiAgICBGc0RhdGVQaWNrZXJNb2R1bGUsXG4gICAgRnNBdXRvY29tcGxldGVDaGlwc01vZHVsZSxcbiAgICBNYXRUYWJzTW9kdWxlLFxuICAgIE1hdEJ1dHRvbixcbiAgICBNYXREaWFsb2dUaXRsZSxcbiAgICBNYXREaWFsb2dDb250ZW50LFxuICAgIE1hdERpYWxvZ0FjdGlvbnMsXG4gICAgTWF0Rm9ybUZpZWxkLFxuICAgIE1hdExhYmVsLFxuICAgIE1hdEhpbnQsXG4gICAgTWF0U3VmZml4LFxuICAgIE1hdElucHV0LFxuICAgIE1hdFNlbGVjdCxcbiAgICBNYXRPcHRpb24sXG4gICAgVGltZXpvbmVTZWxlY3RDb21wb25lbnQsXG4gIF0sXG59KVxuZXhwb3J0IGNsYXNzIFJlcG9ydFNldHRpbmdzQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcblxuICBwdWJsaWMgc2VsZWN0ZWRUYWIgPSAnc2V0dGluZ3MnO1xuXG4gIHB1YmxpYyBuYW1lID0gJyc7XG4gIC8vIFRoZSBwYWdlIGluIGluY2hlcy4gTm8gaW5pdGlhbGl6ZXI6IGV2ZXJ5IHJlcG9ydCBjYXJyaWVzIGEgc2l6ZSwgYW5kXG4gIC8vIG5nT25Jbml0IHNlZWRzIGJvdGggYmVmb3JlIHRoZSB0YWIgcmVuZGVycywgc28gYSBwbGFjZWhvbGRlciBoZXJlIGNvdWxkIG9ubHlcbiAgLy8gZXZlciBiZSBhIHdyb25nIG51bWJlciBicmllZmx5IHNob3dpbmcgYXMgdGhlIG9wZXJhdG9yJ3Mgb3duLlxuICAvL1xuICAvLyBUeXBlZCBgbnVtYmVyIHwgc3RyaW5nYCBiZWNhdXNlIGZzTWFza051bWJlciBpcyB0aGUgY29udHJvbDogaXQgaXMgc2VlZGVkXG4gIC8vIHdpdGggdGhlIHJlcG9ydCdzIG51bWJlciBidXQgaGFuZHMgYmFjayB0aGUgdW5tYXNrZWQgU1RSSU5HIHRoZSBvcGVyYXRvclxuICAvLyB0eXBlZC4gU2F2ZSBjYXN0cyBpdCBvbmNlLCBvbiB0aGUgd2F5IG91dCDigJQgc2VlIGBfcGFnZURpbWVuc2lvbigpYC5cbiAgcHVibGljIHBhZ2VXaWR0aDogbnVtYmVyIHwgc3RyaW5nO1xuICBwdWJsaWMgcGFnZUhlaWdodDogbnVtYmVyIHwgc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgcGFnZURpbWVuc2lvbk1pbiA9IFBBR0VfRElNRU5TSU9OX01JTjtcbiAgcHVibGljIHJlYWRvbmx5IHBhZ2VEaW1lbnNpb25NYXggPSBQQUdFX0RJTUVOU0lPTl9NQVg7XG4gIC8vIFRoZSBoZWFkZXIgYW5kIGZvb3RlciBiYW5kIGRlcHRocywgaW5jaGVzIOKAlCB0eXBlZCBsaWtlIHRoZSBwYWdlIHNpemVcbiAgLy8gYmVjYXVzZSBmc01hc2tOdW1iZXIgaGFuZHMgYmFjayBhIHN0cmluZy5cbiAgcHVibGljIGhlYWRlckhlaWdodDogbnVtYmVyIHwgc3RyaW5nID0gMDtcbiAgcHVibGljIGZvb3RlckhlaWdodDogbnVtYmVyIHwgc3RyaW5nID0gMDtcbiAgcHVibGljIHJlYWRvbmx5IGhlYWRlckZvb3Rlck1heCA9IEhFQURFUl9GT09URVJfTUFYO1xuICAvLyBTZWVkZWQgd2l0aCB0aGUgem9uZSB0aGUgcmVwb3J0IGFjdHVhbGx5IHVzZXM6IGl0cyBvd24gc3RvcmVkIHpvbmUsIGVsc2VcbiAgLy8gdGhlIGFwcGxpY2F0aW9uIGRlZmF1bHQgdGhlIHNlcnZlciByZXNvbHZlZCAoZWZmZWN0aXZlVGltZXpvbmUpLiBTYXZlIHNlbmRzXG4gIC8vIGl0IG9ubHkgd2hlbiBpdCBkaWZmZXJzIGZyb20gdGhhdCBlZmZlY3RpdmUgem9uZSwgc28gb3BlbmluZyBhbmQgc2F2aW5nIGFcbiAgLy8gcmVwb3J0IHRoYXQgZm9sbG93cyB0aGUgZGVmYXVsdCBuZXZlciBwaW5zIGl0IHRvIGEgem9uZS5cbiAgcHVibGljIHRpbWV6b25lID0gJyc7XG4gIHB1YmxpYyBoZWFkaW5nU2l6ZSA9IERFRkFVTFRfSEVBRElOR19TSVpFO1xuXG4gIC8vIFRoZSBsb2NhbGVzIGFuZCBjdXJyZW5jaWVzIHRoZSBzZXJ2ZXIgb2ZmZXJzLiBudWxsIHVudGlsIGxvYWRlZCwgYW5kXG4gIC8vIG5ldmVyIGxvYWRlZCBmcm9tIGEgc2VydmVyIHRvbyBvbGQgdG8gc2VuZCBlZmZlY3RpdmVMb2NhbGU6IHRoZXJlIHRoZVxuICAvLyBzZWxlY3RzIHN0YXkgaGlkZGVuIGFuZCB0aGUgcmVwb3J0IHJlYWRzIGVuLVVTL1VTRC5cbiAgcHVibGljIHJlYWRvbmx5IGxvY2FsZXMgPSBzaWduYWw8UmVwb3J0TG9jYWxlcyB8IG51bGw+KG51bGwpO1xuICAvLyBUaGUgcmVwb3J0J3Mgb3duIGxvY2FsZSBhbmQgY3VycmVuY3ksICcnIHdoZW4gaXQgZm9sbG93cyB0aGUgZGVmYXVsdC4gU2F2ZVxuICAvLyBzZW5kcyBlYWNoIG9ubHkgd2hlbiBpdCBkaWZmZXJzIGZyb20gdGhlIHN0b3JlZCB2YWx1ZS5cbiAgcHVibGljIHJlYWRvbmx5IGxvY2FsZSA9IHNpZ25hbCgnJyk7XG4gIHB1YmxpYyByZWFkb25seSBjdXJyZW5jeSA9IHNpZ25hbCgnJyk7XG4gIC8vIFRoZSB3aG9sZSBmb3JtIHdhaXRzIGJlaGluZCBvbmUgc2tlbGV0b24gdW50aWwgdGhlIGZpbHRlciByb3dzIGFyZSBidWlsdFxuICAvLyBhbmQgdGhlIGxvY2FsZSByZXF1ZXN0IGhhcyBzZXR0bGVkLCBzbyB0aGUgU2V0dGluZ3MgdGFiIG5ldmVyIHNob3dzXG4gIC8vIHdpdGhvdXQgaXRzIExvY2FsZSBhbmQgQ3VycmVuY3kgc2VsZWN0cy4gQSBmYWlsZWQgbG9jYWxlIHJlcXVlc3Qgc2V0dGxlc1xuICAvLyB0b286IHRoZSB0d28gc2VsZWN0cyBzdGF5IGhpZGRlbiAobG9jYWxlcygpIGlzIHN0aWxsIG51bGwpIGFuZCBldmVyeSBvdGhlclxuICAvLyBzZXR0aW5nIHN0YXlzIGVkaXRhYmxlLlxuICBwdWJsaWMgcmVhZG9ubHkgcmVhZHkgPSBjb21wdXRlZCgoKSA9PiB0aGlzLl9maWx0ZXJzUmVhZHkoKSAmJiAoIXRoaXMuX3NlcnZlckhhc0xvY2FsZSB8fCB0aGlzLl9sb2NhbGVzU2V0dGxlZCgpKSk7XG5cbiAgLy8gQW4gZXhwbGljaXQgRGVmYXVsdCAoJycpIG5hbWluZyB0aGUgbG9jYWxlIGl0IHN0YW5kcyBmb3IsIHRoZW4gZWFjaCBvZmZlcmVkXG4gIC8vIGxvY2FsZS4gQSBzdG9yZWQgbG9jYWxlIHRoZSBzZXJ2ZXIgbm8gbG9uZ2VyIG9mZmVycyBpcyBsaXN0ZWQgZmlyc3QsIHNvXG4gIC8vIHRoZSBzZWxlY3Qgc3RpbGwgc2hvd3Mgd2hhdCB0aGUgcmVwb3J0IGhvbGRzLlxuICBwdWJsaWMgcmVhZG9ubHkgbG9jYWxlT3B0aW9ucyA9IGNvbXB1dGVkPExvY2FsZVNlbGVjdE9wdGlvbltdPigoKSA9PiB7XG4gICAgY29uc3QgbG9jYWxlcyA9IHRoaXMubG9jYWxlcygpO1xuICAgIGlmICghbG9jYWxlcykge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIGNvbnN0IG9mZmVyZWQgPSBsb2NhbGVzLm9wdGlvbnMubWFwKChvcHRpb24pID0+IG9wdGlvbi5sb2NhbGUpO1xuXG4gICAgcmV0dXJuIFtcbiAgICAgIC4uLnRoaXMuX3N0b3JlZE9wdGlvbih0aGlzLl9kYXRhLnJlcG9ydC5sb2NhbGUsIG9mZmVyZWQsIGxvY2FsZUxhYmVsKSxcbiAgICAgIHsgdmFsdWU6ICcnLCBsYWJlbDogYERlZmF1bHQg4oCUICR7bG9jYWxlTmFtZShsb2NhbGVzLmRlZmF1bHRMb2NhbGUpfWAgfSxcbiAgICAgIC4uLm9mZmVyZWQubWFwKCh0YWcpID0+ICh7IHZhbHVlOiB0YWcsIGxhYmVsOiBsb2NhbGVMYWJlbCh0YWcpIH0pKSxcbiAgICBdO1xuICB9KTtcblxuICAvLyBBbiBleHBsaWNpdCBEZWZhdWx0ICgnJykgbmFtaW5nIHRoZSBjdXJyZW5jeSB0aGUgc2VsZWN0ZWQgbG9jYWxlIHVzZXMgd2hlblxuICAvLyB0aGUgcmVwb3J0IG5hbWVzIG5vbmUsIHRoZW4gZXZlcnkgY3VycmVuY3kuIEEgc3RvcmVkIGNvZGUgdGhlIHNlcnZlciBub1xuICAvLyBsb25nZXIgb2ZmZXJzIGlzIGxpc3RlZCBmaXJzdC5cbiAgcHVibGljIHJlYWRvbmx5IGN1cnJlbmN5T3B0aW9ucyA9IGNvbXB1dGVkPExvY2FsZVNlbGVjdE9wdGlvbltdPigoKSA9PiB7XG4gICAgY29uc3QgbG9jYWxlcyA9IHRoaXMubG9jYWxlcygpO1xuICAgIGlmICghbG9jYWxlcykge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIHJldHVybiBbXG4gICAgICAuLi50aGlzLl9zdG9yZWRPcHRpb24odGhpcy5fZGF0YS5yZXBvcnQuY3VycmVuY3ksIGxvY2FsZXMuY3VycmVuY2llcywgY3VycmVuY3lMYWJlbCksXG4gICAgICB7IHZhbHVlOiAnJywgbGFiZWw6IGBEZWZhdWx0IOKAlCAke2N1cnJlbmN5TGFiZWwodGhpcy5fZGVmYXVsdEN1cnJlbmN5KCkpfWAgfSxcbiAgICAgIC4uLmxvY2FsZXMuY3VycmVuY2llcy5tYXAoKGNvZGUpID0+ICh7IHZhbHVlOiBjb2RlLCBsYWJlbDogY3VycmVuY3lMYWJlbChjb2RlKSB9KSksXG4gICAgXTtcbiAgfSk7XG5cbiAgLy8gSG93IHRoZSByZXBvcnQgd2lsbCB3cml0ZSBhbiBhbW91bnQgYW5kIGEgZGF5IG9uY2Ugc2F2ZWQ6IHRoZSBzZWxlY3RlZFxuICAvLyBsb2NhbGUgYW5kIGN1cnJlbmN5LCBvciB0aGUgZGVmYXVsdHMgdGhleSBmYWxsIGJhY2sgdG8sIGUuZy5cbiAgLy8gJzEgMjM0LDUwICQgwrcgNSBqYW52LiAyMDI2JyBpbiBmci1DQS5cbiAgcHVibGljIHJlYWRvbmx5IGZvcm1hdEV4YW1wbGUgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgY29uc3QgbG9jYWxlID0gcmVzb2x2ZVJlcG9ydExvY2FsZSh0aGlzLl9hcHBsaWVkTG9jYWxlKCkpO1xuICAgIGNvbnN0IGN1cnJlbmN5ID0gcmVzb2x2ZVJlcG9ydEN1cnJlbmN5KHRoaXMuX2FwcGxpZWRDdXJyZW5jeSgpKTtcblxuICAgIHJldHVybiBbXG4gICAgICBmb3JtYXROdW1iZXIoXG4gICAgICAgIEVYQU1QTEVfQU1PVU5ULFxuICAgICAgICB7IGZvcm1hdDogUmVwb3J0VmFsdWVGb3JtYXQuQ3VycmVuY3ksIHByZWNpc2lvbjogMiB9LFxuICAgICAgICB7IGxvY2FsZSwgY3VycmVuY3ksIHJhdGlvUGVyY2VudDogdHJ1ZSB9LFxuICAgICAgKSxcbiAgICAgIGZvcm1hdExvY2FsRGF0ZShFWEFNUExFX0RBWSwgbG9jYWxlLCBEQVlfU0hPUlQpLFxuICAgIF0uam9pbignIMK3ICcpO1xuICB9KTtcblxuICAvLyBUaGUgcmVwb3J0LWxldmVsIGZpbHRlcnMgYW5kIHRoZWlyIGVkaXRhYmxlIGRlZmF1bHQgdmFsdWVzIChGaWx0ZXJzIHRhYikuXG4gIHB1YmxpYyByZWFkb25seSBmaWx0ZXJSb3dzID0gc2lnbmFsPEZpbHRlckRlZmF1bHRSb3dbXT4oW10pO1xuICBwdWJsaWMgcmVhZG9ubHkgcmVsYXRpdmVMYWJlbCA9IHJlbGF0aXZlTGFiZWw7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBfZGF0YTogeyByZXBvcnQ6IFJlcG9ydCB9ID0gaW5qZWN0KE1BVF9ESUFMT0dfREFUQSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2RpYWxvZ1JlZiA9IGluamVjdDxNYXREaWFsb2dSZWY8UmVwb3J0U2V0dGluZ3NDb21wb25lbnQsIFJlcG9ydFNldHRpbmdzUmVzdWx0Pj4oTWF0RGlhbG9nUmVmKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfcmVwb3J0RGF0YSA9IGluamVjdChSZXBvcnREYXRhKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfbWVzc2FnZSA9IGluamVjdChGc01lc3NhZ2UpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9wcm9tcHQgPSBpbmplY3QoRnNQcm9tcHQpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9kZXN0cm95UmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuICAvLyBPbmx5IGEgc2VydmVyIHRoYXQgcmVzb2x2ZXMgYSByZXBvcnQncyBsb2NhbGUgb2ZmZXJzIHRoZSBsb2NhbGUgbGlzdC5cbiAgcHJpdmF0ZSByZWFkb25seSBfc2VydmVySGFzTG9jYWxlID0gdGhpcy5fZGF0YS5yZXBvcnQuZWZmZWN0aXZlTG9jYWxlICE9PSB1bmRlZmluZWQ7XG4gIC8vIFRydWUgb25jZSB0aGUgbG9jYWxlIHJlcXVlc3QgaGFzIGFuc3dlcmVkLCB3aXRoIHRoZSBsaXN0IG9yIGFuIGVycm9yLlxuICBwcml2YXRlIHJlYWRvbmx5IF9sb2NhbGVzU2V0dGxlZCA9IHNpZ25hbChmYWxzZSk7XG4gIC8vIFRydWUgb25jZSB0aGUgZmlsdGVyIHJvd3MgYXJlIHB1Ymxpc2hlZCAoc2VlIF9idWlsZEZpbHRlclJvd3MpLlxuICBwcml2YXRlIHJlYWRvbmx5IF9maWx0ZXJzUmVhZHkgPSBzaWduYWwoZmFsc2UpO1xuXG4gIC8vIFRoZSBsb2NhbGUgdGhlIHJlcG9ydCB3b3VsZCBiZSB3cml0dGVuIGluOiB0aGUgc2VsZWN0ZWQgb25lIHdoZW4gdGhlXG4gIC8vIHNlcnZlciBvZmZlcnMgaXQsIGVsc2UgdGhlIGRlZmF1bHQgKGEgc3RvcmVkIGxvY2FsZSBpdCBubyBsb25nZXIgb2ZmZXJzXG4gIC8vIGZhbGxzIGJhY2sgdG8gdGhlIGRlZmF1bHQsIGFzIGl0IGRvZXMgb24gdGhlIHNlcnZlcikuXG4gIHByaXZhdGUgcmVhZG9ubHkgX2FwcGxpZWRMb2NhbGUgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgY29uc3QgbG9jYWxlcyA9IHRoaXMubG9jYWxlcygpO1xuICAgIGNvbnN0IGxvY2FsZSA9IHRoaXMubG9jYWxlKCk7XG5cbiAgICByZXR1cm4gbG9jYWxlcz8ub3B0aW9ucy5zb21lKChvcHRpb24pID0+IG9wdGlvbi5sb2NhbGUgPT09IGxvY2FsZSlcbiAgICAgID8gbG9jYWxlXG4gICAgICA6IGxvY2FsZXM/LmRlZmF1bHRMb2NhbGUgPz8gJyc7XG4gIH0pO1xuXG4gIC8vIFRoZSBjdXJyZW5jeSBhIHJlcG9ydCBpbiB0aGUgYXBwbGllZCBsb2NhbGUgdXNlcyB3aGVuIGl0IG5hbWVzIG5vbmUuXG4gIHByaXZhdGUgcmVhZG9ubHkgX2RlZmF1bHRDdXJyZW5jeSA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCBsb2NhbGUgPSB0aGlzLl9hcHBsaWVkTG9jYWxlKCk7XG5cbiAgICByZXR1cm4gdGhpcy5sb2NhbGVzKCk/Lm9wdGlvbnMuZmluZCgob3B0aW9uKSA9PiBvcHRpb24ubG9jYWxlID09PSBsb2NhbGUpPy5kZWZhdWx0Q3VycmVuY3lcbiAgICAgID8/IFJFUE9SVF9GQUxMQkFDS19DVVJSRU5DWTtcbiAgfSk7XG5cbiAgLy8gVGhlIGN1cnJlbmN5IHRoZSByZXBvcnQgd291bGQgbGFiZWwgbW9uZXkgaW46IHRoZSBzZWxlY3RlZCBvbmUgd2hlbiB0aGVcbiAgLy8gc2VydmVyIG9mZmVycyBpdCwgZWxzZSB0aGUgZGVmYXVsdC5cbiAgcHJpdmF0ZSByZWFkb25seSBfYXBwbGllZEN1cnJlbmN5ID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGN1cnJlbmN5ID0gdGhpcy5jdXJyZW5jeSgpO1xuXG4gICAgcmV0dXJuIHRoaXMubG9jYWxlcygpPy5jdXJyZW5jaWVzLmluY2x1ZGVzKGN1cnJlbmN5KVxuICAgICAgPyBjdXJyZW5jeVxuICAgICAgOiB0aGlzLl9kZWZhdWx0Q3VycmVuY3koKTtcbiAgfSk7XG5cbiAgcHVibGljIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIGNvbnN0IHJlcG9ydCA9IHRoaXMuX2RhdGEucmVwb3J0O1xuICAgIHRoaXMubmFtZSA9IHJlcG9ydC5uYW1lO1xuICAgIHRoaXMucGFnZVdpZHRoID0gcmVwb3J0LnBhZ2VXaWR0aDtcbiAgICB0aGlzLnBhZ2VIZWlnaHQgPSByZXBvcnQucGFnZUhlaWdodDtcbiAgICB0aGlzLmhlYWRlckhlaWdodCA9IHJlcG9ydC5jb25maWc/LmhlYWRlckZvb3Rlcj8uaGVhZGVySGVpZ2h0ID8/IDA7XG4gICAgdGhpcy5mb290ZXJIZWlnaHQgPSByZXBvcnQuY29uZmlnPy5oZWFkZXJGb290ZXI/LmZvb3RlckhlaWdodCA/PyAwO1xuICAgIHRoaXMudGltZXpvbmUgPSByZXBvcnQudGltZXpvbmUgPz8gcmVwb3J0LmVmZmVjdGl2ZVRpbWV6b25lID8/ICcnO1xuICAgIHRoaXMuaGVhZGluZ1NpemUgPSByZXBvcnQuY29uZmlnPy5zdHlsZXM/LmhlYWRpbmc/LnNpemUgPz8gREVGQVVMVF9IRUFESU5HX1NJWkU7XG4gICAgdGhpcy5sb2NhbGUuc2V0KHJlcG9ydC5sb2NhbGUgPz8gJycpO1xuICAgIHRoaXMuY3VycmVuY3kuc2V0KHJlcG9ydC5jdXJyZW5jeSA/PyAnJyk7XG5cbiAgICB0aGlzLl9idWlsZEZpbHRlclJvd3MocmVwb3J0KTtcblxuICAgIGlmICh0aGlzLl9zZXJ2ZXJIYXNMb2NhbGUpIHtcbiAgICAgIHRoaXMuX3JlcG9ydERhdGEubG9jYWxlcygpXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIHRhcCgobG9jYWxlcykgPT4gdGhpcy5sb2NhbGVzLnNldChsb2NhbGVzKSksXG4gICAgICAgICAgY2F0Y2hFcnJvcigoKSA9PiBvZihudWxsKSksXG4gICAgICAgICAgZmluYWxpemUoKCkgPT4gdGhpcy5fbG9jYWxlc1NldHRsZWQuc2V0KHRydWUpKSxcbiAgICAgICAgICB0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fZGVzdHJveVJlZiksXG4gICAgICAgIClcbiAgICAgICAgLnN1YnNjcmliZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8vIENvbmZpcm0gYW5kIGRlbGV0ZSBoZXJlLCB3aGlsZSB0aGUgZGlhbG9nIGlzIHN0aWxsIG9wZW4sIHRoZW4gY2xvc2Ugd2l0aFxuICAvLyBhIGBkZWxldGVkYCByZXN1bHQuIFRoZSBwYWdlIHJlYWN0cyB0byB0aGUgcmVzdWx0OyBpdCBubyBsb25nZXIgb3ducyB0aGVcbiAgLy8gcHJvbXB0IG9yIHRoZSBBUEkgY2FsbC5cbiAgcHVibGljIGRlbGV0ZSgpOiB2b2lkIHtcbiAgICB0aGlzLl9wcm9tcHQuY29uZmlybSh7XG4gICAgICB0aXRsZTogJ0RlbGV0ZSBSZXBvcnQnLFxuICAgICAgdGVtcGxhdGU6IGBEZWxldGUgXCIke3RoaXMuX2RhdGEucmVwb3J0Lm5hbWV9XCI/IFRoaXMgY2Fubm90IGJlIHVuZG9uZS5gLFxuICAgIH0pXG4gICAgICAucGlwZShcbiAgICAgICAgc3dpdGNoTWFwKCgpID0+IHRoaXMuX3JlcG9ydERhdGEuZGVsZXRlKHRoaXMuX2RhdGEucmVwb3J0LmlkKSksXG4gICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICB0aGlzLl9tZXNzYWdlLnN1Y2Nlc3MoJ1JlcG9ydCBkZWxldGVkJyk7XG4gICAgICAgIHRoaXMuX2RpYWxvZ1JlZi5jbG9zZSh7IGFjdGlvbjogJ2RlbGV0ZWQnIH0pO1xuICAgICAgfSk7XG4gIH1cblxuICBwdWJsaWMgc2F2ZSA9ICgpID0+IHtcbiAgICBjb25zdCByZXBvcnRJZCA9IHRoaXMuX2RhdGEucmVwb3J0LmlkO1xuXG4gICAgLy8gUGVyc2lzdCB0aGUgcmVwb3J0IHNldHRpbmdzIGFuZCBlYWNoIGNoYW5nZWQgZmlsdGVyIGRlZmF1bHQgdG9nZXRoZXIsIHNvXG4gICAgLy8gdGhlIHNpbmdsZSBTYXZlIGNvdmVycyBhbGwgdGhyZWUgdGFicy4gVGhlIHJlcG9ydCByZWxvYWRzIG9uIHRoZSBgc2F2ZWRgXG4gICAgLy8gcmVzdWx0LCByZS1zZWVkaW5nIHRoZSBiYXIgZnJvbSB0aGUgbmV3IGRlZmF1bHRzLlxuICAgIGNvbnN0IHNldHRpbmdzJCA9IHRoaXMuX3JlcG9ydERhdGEudXBkYXRlKHJlcG9ydElkLCB7XG4gICAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgICBwYWdlV2lkdGg6IHRoaXMuX3BhZ2VEaW1lbnNpb24odGhpcy5wYWdlV2lkdGgpLFxuICAgICAgcGFnZUhlaWdodDogdGhpcy5fcGFnZURpbWVuc2lvbih0aGlzLnBhZ2VIZWlnaHQpLFxuICAgICAgLi4udGhpcy5fdGltZXpvbmVTZXR0aW5nKCksXG4gICAgICAuLi5yZXBvcnRMb2NhbGVQYXRjaCh0aGlzLl9kYXRhLnJlcG9ydCwgdGhpcy5sb2NhbGUoKSwgdGhpcy5jdXJyZW5jeSgpKSxcbiAgICAgIHN0eWxlczogeyBoZWFkaW5nOiB7IHNpemU6IHRoaXMuaGVhZGluZ1NpemUgfSB9LFxuICAgICAgaGVhZGVyRm9vdGVyOiB7XG4gICAgICAgIGhlYWRlckhlaWdodDogdGhpcy5fcGFnZURpbWVuc2lvbih0aGlzLmhlYWRlckhlaWdodCkgfHwgMCxcbiAgICAgICAgZm9vdGVySGVpZ2h0OiB0aGlzLl9wYWdlRGltZW5zaW9uKHRoaXMuZm9vdGVySGVpZ2h0KSB8fCAwLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGRlZmF1bHRzJCA9IHRoaXMuZmlsdGVyUm93cygpXG4gICAgICAuZmlsdGVyKChyb3cpID0+IHRoaXMuX2RlZmF1bHRDaGFuZ2VkKHJvdykpXG4gICAgICAubWFwKChyb3cpID0+IHRoaXMuX3JlcG9ydERhdGEudXBkYXRlRmlsdGVyR3JvdXAocmVwb3J0SWQsIHJvdy5ncm91cC5pZCwge1xuICAgICAgICBkZWZhdWx0OiB0aGlzLl9yb3dEZWZhdWx0KHJvdyksXG4gICAgICB9KSk7XG5cbiAgICByZXR1cm4gZm9ya0pvaW4oW3NldHRpbmdzJCwgLi4uZGVmYXVsdHMkXSlcbiAgICAgIC5waXBlKFxuICAgICAgICB0YXAoKCkgPT4ge1xuICAgICAgICAgIHRoaXMuX21lc3NhZ2Uuc3VjY2VzcygnUmVwb3J0IHNldHRpbmdzIHNhdmVkJyk7XG4gICAgICAgICAgdGhpcy5fZGlhbG9nUmVmLmNsb3NlKHsgYWN0aW9uOiAnc2F2ZWQnIH0pO1xuICAgICAgICB9KSxcbiAgICAgICk7XG4gIH07XG5cbiAgLy8gRHJvcCB0aGUgcm93J3Mgc3RvcmVkIHJvbGxpbmcgcHJlc2V0IChDbGVhcikuIEEgbmV3IHJvdyBvYmplY3QgcmF0aGVyIHRoYW5cbiAgLy8gYSBtdXRhdGlvbiwgc28gdGhlIHNpZ25hbCBzZWVzIHRoZSBjaGFuZ2U7IHRoZSBAZm9yIHRyYWNrcyBncm91cC5pZCwgc29cbiAgLy8gdGhlIHJvdydzIGJpbmRpbmdzIHN1cnZpdmUgdGhlIHN3YXAuXG4gIHB1YmxpYyBjbGVhclJlbGF0aXZlKHJvdzogRmlsdGVyRGVmYXVsdFJvdyk6IHZvaWQge1xuICAgIHRoaXMuZmlsdGVyUm93cy51cGRhdGUoKHJvd3MpID0+IHJvd3MubWFwKChpdGVtKSA9PiAoaXRlbSA9PT0gcm93ID8geyAuLi5pdGVtLCByZWxhdGl2ZTogbnVsbCB9IDogaXRlbSkpKTtcbiAgfVxuXG4gIC8vIFRoZSBwYWdlIGRpbWVuc2lvbiBhcyBhIHJlYWwgbnVtYmVyIGZvciB0aGUgd2lyZS4gZnNNYXNrTnVtYmVyIGhhbmRzIGJhY2tcbiAgLy8gdGhlIHVubWFza2VkIHN0cmluZyBpdCBidWlsdCB3aXRoIGEgZml4ZWQgJy4nIHJhZGl4ICh3aGljaCBpcyB0aGUgd2hvbGVcbiAgLy8gcG9pbnQgb2YgdGhlIG1hc2sgLSBhIG5hdGl2ZSBudW1iZXIgaW5wdXQgcGFpbnRzIHRoZSB2aWV3ZXIncyBsb2NhbGVcbiAgLy8gc2VwYXJhdG9yIGluc3RlYWQpLCBzbyB0aGUgY2FzdCBoZXJlIGlzIGEgc3RyYWlnaHQgcGFyc2UgYW5kIG5ldmVyIHNlZXMgYVxuICAvLyBjb21tYS4gVGhlIGJhY2tlbmQgcmVqZWN0cyBhbnl0aGluZyBub24tbnVtZXJpYyByYXRoZXIgdGhhbiBjb2VyY2luZywgc28gYVxuICAvLyBOYU4gZmFpbHMgbG91ZGx5IGluc3RlYWQgb2Ygc2lsZW50bHkgc3RvcmluZyBhIHdyb25nIHBhZ2Ugc2l6ZS5cbiAgcHJpdmF0ZSBfcGFnZURpbWVuc2lvbih2YWx1ZTogbnVtYmVyIHwgc3RyaW5nKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyA/IHZhbHVlIDogcGFyc2VGbG9hdCh2YWx1ZSk7XG4gIH1cblxuICAvLyBUaGUgem9uZSBmb3IgdGhlIHNldHRpbmdzIFBVVCwgc2VudCBvbmx5IHdoZW4gaXQgbW92ZXMgdGhlIHJlcG9ydCBvZmYgdGhlXG4gIC8vIHpvbmUgaXQgYWxyZWFkeSB1c2VzLCBzbyBhbiB1bnRvdWNoZWQgZGlhbG9nIG5ldmVyIHBpbnMgYSByZXBvcnQgdGhhdFxuICAvLyBmb2xsb3dzIHRoZSBhcHBsaWNhdGlvbiBkZWZhdWx0LiBBIHNlcnZlciB0b28gb2xkIHRvIHNlbmRcbiAgLy8gZWZmZWN0aXZlVGltZXpvbmUgZ2V0cyB0aGUgem9uZSBldmVyeSB0aW1lLCBhcyBpdCBhbHdheXMgZGlkLlxuICBwcml2YXRlIF90aW1lem9uZVNldHRpbmcoKTogeyB0aW1lem9uZT86IHN0cmluZyB9IHtcbiAgICBjb25zdCBlZmZlY3RpdmVUaW1lem9uZSA9IHRoaXMuX2RhdGEucmVwb3J0LmVmZmVjdGl2ZVRpbWV6b25lO1xuXG4gICAgcmV0dXJuIGVmZmVjdGl2ZVRpbWV6b25lID09PSB1bmRlZmluZWQgfHwgdGhpcy50aW1lem9uZSAhPT0gZWZmZWN0aXZlVGltZXpvbmVcbiAgICAgID8geyB0aW1lem9uZTogdGhpcy50aW1lem9uZSB9XG4gICAgICA6IHt9O1xuICB9XG5cbiAgLy8gVGhlIHN0b3JlZCB2YWx1ZSBhcyBpdHMgb3duIG9wdGlvbiB3aGVuIHRoZSBzZXJ2ZXIgbm8gbG9uZ2VyIG9mZmVycyBpdCwgc29cbiAgLy8gdGhlIHNlbGVjdCBuYW1lcyBpdCBpbnN0ZWFkIG9mIHNob3dpbmcgYmxhbmsuIExlZnQgYXMgaXQgaXMsIGl0IGlzIG5ldmVyXG4gIC8vIHNlbnQgKHNlZSByZXBvcnRMb2NhbGVQYXRjaCksIGFuZCB0aGUgcmVwb3J0IHJlYWRzIHRoZSBkZWZhdWx0IG1lYW53aGlsZS5cbiAgcHJpdmF0ZSBfc3RvcmVkT3B0aW9uKFxuICAgIHN0b3JlZDogc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZCxcbiAgICBvZmZlcmVkOiBzdHJpbmdbXSxcbiAgICBsYWJlbDogKHZhbHVlOiBzdHJpbmcpID0+IHN0cmluZyxcbiAgKTogTG9jYWxlU2VsZWN0T3B0aW9uW10ge1xuICAgIHJldHVybiBzdG9yZWQgJiYgIW9mZmVyZWQuaW5jbHVkZXMoc3RvcmVkKSA/IFt7IHZhbHVlOiBzdG9yZWQsIGxhYmVsOiBsYWJlbChzdG9yZWQpIH1dIDogW107XG4gIH1cblxuICAvLyBCdWlsZCBvbmUgZWRpdGFibGUgcm93IHBlciByZXBvcnQtbGV2ZWwgZmlsdGVyIGdyb3VwIChsZXZlbCByZXBvcnQgb3IgYm90aCksXG4gIC8vIGluIGJhciBvcmRlciwgc2VlZGluZyBlYWNoIGRyYWZ0IGZyb20gdGhlIGdyb3VwJ3Mgc3RvcmVkIGRlZmF1bHQuXG4gIHByaXZhdGUgX2J1aWxkRmlsdGVyUm93cyhyZXBvcnQ6IFJlcG9ydCk6IHZvaWQge1xuICAgIGNvbnN0IHJlcG9ydElkID0gcmVwb3J0LmlkO1xuXG4gICAgY29uc3QgYnVpbHQgPSAocmVwb3J0LmZpbHRlckdyb3VwcyA/PyBbXSlcbiAgICAgIC5maWx0ZXIoKGdyb3VwKSA9PiBncm91cC5sZXZlbCA9PT0gJ3JlcG9ydCcgfHwgZ3JvdXAubGV2ZWwgPT09ICdib3RoJylcbiAgICAgIC5zb3J0KChhLCBiKSA9PiBhLm9yZGVyIC0gYi5vcmRlcilcbiAgICAgIC5tYXAoKGdyb3VwKSA9PiB7XG4gICAgICAgIGNvbnN0IGdyb3VwRGVmYXVsdCA9IGdyb3VwLmNvbmZpZz8uZGVmYXVsdDtcbiAgICAgICAgLy8gT25lIHNoYXJlZCwgcmVwbGF5ZWQgb3B0aW9uIHN0cmVhbSBwZXIgZ3JvdXA6IHRoZSBjaGlwcyBmZXRjaCBhbmQgdGhlXG4gICAgICAgIC8vIHN0b3JlZCBkZWZhdWx0J3MgbGFiZWxzIHJlYWQgdGhlIHNhbWUgbGlzdCwgc28gaXQgaXMgZmV0Y2hlZCBvbmNlLlxuICAgICAgICBjb25zdCBvcHRpb25zJCA9IGxvYWRHcm91cE9wdGlvbnMoZ3JvdXAsIHRoaXMuX3JlcG9ydERhdGEsIHJlcG9ydElkKTtcblxuICAgICAgICBjb25zdCByb3c6IEZpbHRlckRlZmF1bHRSb3cgPSB7XG4gICAgICAgICAgZ3JvdXAsXG4gICAgICAgICAgbGFiZWw6IGdyb3VwLmxhYmVsIHx8IGdyb3VwLmZpbHRlcnM/LlswXT8uZmlsdGVyQ29sdW1uIHx8ICdGaWx0ZXInLFxuICAgICAgICAgIHN0YXJ0OiBkYXRlRnJvbUJvdW5kKGdyb3VwRGVmYXVsdD8uc3RhcnQpLFxuICAgICAgICAgIGVuZDogZGF0ZUZyb21Cb3VuZChncm91cERlZmF1bHQ/LmVuZCksXG4gICAgICAgICAgcmVsYXRpdmU6IGdyb3VwRGVmYXVsdD8ucmVsYXRpdmUgPz8gbnVsbCxcbiAgICAgICAgICAvLyBOYW1lZCBiZWxvdywgb25jZSB0aGUgb3B0aW9uIGxpc3QgY2FycnlpbmcgdGhlaXIgbGFiZWxzIGlzIGluLlxuICAgICAgICAgIHZhbHVlczogW10sXG4gICAgICAgICAgdmFsdWU6IGdyb3VwRGVmYXVsdD8udmFsdWUgPz8gJycsXG4gICAgICAgICAgLy8gZnMtYXV0b2NvbXBsZXRlLWNoaXBzIGZldGNoOiB0aGUgZ3JvdXAncyBkaXN0aW5jdCBvcHRpb25zLCBuYW1lLWZpbHRlcmVkLlxuICAgICAgICAgIC8vIFNhbWUgbG9hZGVyIHRoZSByZXBvcnQgYmFyIHVzZXMsIHNvIHRoZSB0d28gbmV2ZXIgZHJpZnQuXG4gICAgICAgICAgZmV0Y2g6IChrZXl3b3JkPzogc3RyaW5nKSA9PiBtYXRjaE9wdGlvbnMob3B0aW9ucyQsIGtleXdvcmQpLFxuICAgICAgICB9O1xuXG4gICAgICAgIHJldHVybiB7IHJvdywgb3B0aW9ucyQsIHZhbHVlczogZ3JvdXBEZWZhdWx0Py52YWx1ZXMgPz8gW10gfTtcbiAgICAgIH0pO1xuXG4gICAgY29uc3Qgcm93cyA9IGJ1aWx0Lm1hcCgoZW50cnkpID0+IGVudHJ5LnJvdyk7XG4gICAgY29uc3Qgc2VlZGVkID0gYnVpbHQuZmlsdGVyKChlbnRyeSkgPT4gZW50cnkudmFsdWVzLmxlbmd0aCk7XG5cbiAgICAvLyBOb3RoaW5nIHRvIG5hbWUg4oCUIHB1Ymxpc2ggaW1tZWRpYXRlbHkgcmF0aGVyIHRoYW4gd2FpdGluZyBvbiBhIHJlcXVlc3RcbiAgICAvLyBubyByb3cgbmVlZHMuXG4gICAgaWYgKCFzZWVkZWQubGVuZ3RoKSB7XG4gICAgICB0aGlzLl9wdWJsaXNoRmlsdGVyUm93cyhyb3dzKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIEEgc3RvcmVkIHNlbGVjdCBkZWZhdWx0IGhvbGRzIGlkcywgc28gaXRzIGNoaXBzIGNhbiBvbmx5IGJlIG5hbWVkIG9uY2UgdGhlXG4gICAgLy8gb3B0aW9uIGxpc3QgaXMgaW4uIFJlc29sdmUgZXZlcnkgc2VlZGVkIHJvdyBmaXJzdCBhbmQgcHVibGlzaCB0aGUgcm93cyBpblxuICAgIC8vIG9uZSBnbywgc28gdGhlIHRhYiBuZXZlciByZW5kZXJzIGEgY2hpcCBzaG93aW5nIGEgcmF3IGlkLiBXaGVuIGFuIG9wdGlvblxuICAgIC8vIGxpc3QgZmFpbHMgdG8gbG9hZCwgdGhlIHJvd3MgcHVibGlzaCB1bnJlc29sdmVkOiBlYWNoIGNoaXAgbmFtZXMgaXRzIGlkLFxuICAgIC8vIGFuZCBhbiB1bnRvdWNoZWQgcm93IHN0aWxsIHNhdmVzIHRoZSBzdG9yZWQgZGVmYXVsdCB1bmNoYW5nZWQuXG4gICAgZm9ya0pvaW4oc2VlZGVkLm1hcCgoZW50cnkpID0+IHJlc29sdmVPcHRpb25WYWx1ZXMoZW50cnkub3B0aW9ucyQsIGVudHJ5LnZhbHVlcykpKVxuICAgICAgLnBpcGUoXG4gICAgICAgIGNhdGNoRXJyb3IoKCkgPT4gb2Yoc2VlZGVkLm1hcCgoZW50cnkpID0+IGVudHJ5LnZhbHVlcy5tYXAoKHZhbHVlKSA9PiAoeyBuYW1lOiBTdHJpbmcodmFsdWUpLCB2YWx1ZSB9KSkpKSksXG4gICAgICAgIHRhcCgocmVzb2x2ZWQpID0+IHtcbiAgICAgICAgICByZXNvbHZlZC5mb3JFYWNoKCh2YWx1ZXMsIGluZGV4KSA9PiBzZWVkZWRbaW5kZXhdLnJvdy52YWx1ZXMgPSB2YWx1ZXMpO1xuICAgICAgICAgIHRoaXMuX3B1Ymxpc2hGaWx0ZXJSb3dzKHJvd3MpO1xuICAgICAgICB9KSxcbiAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSBfcHVibGlzaEZpbHRlclJvd3Mocm93czogRmlsdGVyRGVmYXVsdFJvd1tdKTogdm9pZCB7XG4gICAgdGhpcy5maWx0ZXJSb3dzLnNldChyb3dzKTtcbiAgICB0aGlzLl9maWx0ZXJzUmVhZHkuc2V0KHRydWUpO1xuICB9XG5cbiAgLy8gVGhlIGRyYWZ0IGRlZmF1bHQgbm9ybWFsaXplZCB0byB0aGUgd2lyZSBzaGFwZSBmb3IgdGhpcyByb3cncyB0eXBlLCBvciBudWxsXG4gIC8vIHdoZW4gZW1wdHkgKHdoaWNoIGNsZWFycyB0aGUgc3RvcmVkIGRlZmF1bHQpLiBBIGRhdGUgcmFuZ2UgaXMgdGhlIHBpY2tlZFxuICAvLyBkYXRlcyB3aGVuIHRoZXJlIGFyZSBhbnksIGVsc2UgdGhlIGNhcnJpZWQgcm9sbGluZyBwcmVzZXQsIG5ldmVyIGJvdGg6IHRoZVxuICAvLyBzZXJ2ZXIgcmVmdXNlcyBhIHJlbGF0aXZlIHByZXNldCBjb21iaW5lZCB3aXRoIGRhdGVzLlxuICBwcml2YXRlIF9yb3dEZWZhdWx0KHJvdzogRmlsdGVyRGVmYXVsdFJvdyk6IEZpbHRlckdyb3VwRGVmYXVsdCB8IG51bGwge1xuICAgIHN3aXRjaCAocm93Lmdyb3VwLnR5cGUpIHtcbiAgICAgIGNhc2UgJ2RhdGVSYW5nZSc6IHtcbiAgICAgICAgY29uc3Qgc3RhcnQgPSBkYXRlVG9Cb3VuZChyb3cuc3RhcnQpO1xuICAgICAgICBjb25zdCBlbmQgPSBkYXRlVG9Cb3VuZChyb3cuZW5kKTtcblxuICAgICAgICBpZiAoc3RhcnQgfHwgZW5kKSB7XG4gICAgICAgICAgcmV0dXJuIHsgc3RhcnQ6IHN0YXJ0ID8/IHVuZGVmaW5lZCwgZW5kOiBlbmQgPz8gdW5kZWZpbmVkIH07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcm93LnJlbGF0aXZlID8geyByZWxhdGl2ZTogcm93LnJlbGF0aXZlIH0gOiBudWxsO1xuICAgICAgfVxuXG4gICAgICBjYXNlICdzZWxlY3QnOlxuICAgICAgICByZXR1cm4gcm93LnZhbHVlcy5sZW5ndGggPyB7IHZhbHVlczogcm93LnZhbHVlcy5tYXAoKG9wdGlvbikgPT4gb3B0aW9uLnZhbHVlKSB9IDogbnVsbDtcblxuICAgICAgY2FzZSAna2V5d29yZCc6XG4gICAgICBkZWZhdWx0OiB7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gcm93LnZhbHVlLnRyaW0oKTtcblxuICAgICAgICByZXR1cm4gdmFsdWUgPyB7IHZhbHVlIH0gOiBudWxsO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIFdoZXRoZXIgdGhlIHJvdydzIGRyYWZ0IGRpZmZlcnMgZnJvbSB0aGUgZ3JvdXAncyBzdG9yZWQgZGVmYXVsdCDigJQgb25seVxuICAvLyBjaGFuZ2VkIHJvd3MgYXJlIHBlcnNpc3RlZCBvbiBTYXZlLlxuICBwcml2YXRlIF9kZWZhdWx0Q2hhbmdlZChyb3c6IEZpbHRlckRlZmF1bHRSb3cpOiBib29sZWFuIHtcbiAgICBjb25zdCBiZWZvcmUgPSBKU09OLnN0cmluZ2lmeSh0aGlzLl9ub3JtYWxpemUocm93Lmdyb3VwLmNvbmZpZz8uZGVmYXVsdCA/PyBudWxsKSk7XG4gICAgY29uc3QgYWZ0ZXIgPSBKU09OLnN0cmluZ2lmeSh0aGlzLl9ub3JtYWxpemUodGhpcy5fcm93RGVmYXVsdChyb3cpKSk7XG5cbiAgICByZXR1cm4gYmVmb3JlICE9PSBhZnRlcjtcbiAgfVxuXG4gIC8vIEEgc3RhYmxlIGNvbXBhcmlzb24gZm9ybTogZW1wdHkgYW5kIHVuZGVmaW5lZCBrZXlzIGFyZSBkcm9wcGVkIHNvIGEgbm8tb3BcbiAgLy8gZWRpdCBkb2Vzbid0IHJlYWQgYXMgYSBjaGFuZ2UuIHJlbGF0aXZlIGlzIGNvbXBhcmVkIGxpa2UgdGhlIHJlc3Q6IHRoZSByb3dcbiAgLy8gY2FycmllcyBpdCwgc28gYW4gdW50b3VjaGVkIHJvbGxpbmcgZGVmYXVsdCByZWFkcyBhcyB1bmNoYW5nZWQuXG4gIHByaXZhdGUgX25vcm1hbGl6ZSh2YWx1ZTogRmlsdGVyR3JvdXBEZWZhdWx0IHwgbnVsbCk6IEZpbHRlckdyb3VwRGVmYXVsdCB8IG51bGwge1xuICAgIGlmICghdmFsdWUpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IG5vcm1hbGl6ZWQ6IEZpbHRlckdyb3VwRGVmYXVsdCA9IHt9O1xuICAgIGlmICh2YWx1ZS5zdGFydCkge1xuICAgICAgbm9ybWFsaXplZC5zdGFydCA9IHZhbHVlLnN0YXJ0O1xuICAgIH1cbiAgICBpZiAodmFsdWUuZW5kKSB7XG4gICAgICBub3JtYWxpemVkLmVuZCA9IHZhbHVlLmVuZDtcbiAgICB9XG4gICAgaWYgKHZhbHVlLnZhbHVlcz8ubGVuZ3RoKSB7XG4gICAgICBub3JtYWxpemVkLnZhbHVlcyA9IHZhbHVlLnZhbHVlcztcbiAgICB9XG4gICAgaWYgKHZhbHVlLnZhbHVlKSB7XG4gICAgICBub3JtYWxpemVkLnZhbHVlID0gdmFsdWUudmFsdWU7XG4gICAgfVxuICAgIGlmICh2YWx1ZS5yZWxhdGl2ZSkge1xuICAgICAgbm9ybWFsaXplZC5yZWxhdGl2ZSA9IHZhbHVlLnJlbGF0aXZlO1xuICAgIH1cblxuICAgIHJldHVybiBPYmplY3Qua2V5cyhub3JtYWxpemVkKS5sZW5ndGggPyBub3JtYWxpemVkIDogbnVsbDtcbiAgfVxufVxuIiwiPGZvcm1cbiAgICBmc0Zvcm1cbiAgICBbc3VibWl0XT1cInNhdmVcIj5cbiAgPGZzLWRpYWxvZz5cbiAgICA8aDEgbWF0LWRpYWxvZy10aXRsZT5cbiAgICAgIFJlcG9ydCBTZXR0aW5nc1xuICAgIDwvaDE+XG4gICAgPG1hdC1kaWFsb2ctY29udGVudD5cbiAgICAgIDwhLS0gT25lIHNrZWxldG9uIG92ZXIgdGhlIHdob2xlIGJvZHkgdW50aWwgdGhlIGxvY2FsZSBsaXN0IGlzIGluLiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgKmZzU2tlbGV0b25Gb3JtPVwicmVhZHkoKSB8fCBudWxsXCI+XG4gICAgICAgIDxtYXQtdGFiLWdyb3VwIFsoc2VsZWN0ZWQpXT1cInNlbGVjdGVkVGFiXCI+XG4gICAgICAgICAgPG1hdC10YWJcbiAgICAgICAgICAgICAgbGFiZWw9XCJTZXR0aW5nc1wiXG4gICAgICAgICAgICAgIG5hbWU9XCJzZXR0aW5nc1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZzLWNvbHVtbiB0YWItYm9keVwiPlxuICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgIE5hbWVcbiAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cIm5hbWVcIlxuICAgICAgICAgICAgICAgICAgbmFtZT1cIm5hbWVcIlxuICAgICAgICAgICAgICAgICAgW2ZzRm9ybVJlcXVpcmVkXT1cInRydWVcIj5cbiAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgPCEtLVxuICAgICAgICAgICAgICAgIFRoZSBwYWdlLCB0eXBlZCBpbiBpbmNoZXMuIE9yaWVudGF0aW9uIGlzIG5vdCBhc2tlZCBmb3IgYmVjYXVzZSBpdFxuICAgICAgICAgICAgICAgIGlzIG5vdCBhbiBpbmRlcGVuZGVudCBjaG9pY2UgLSBhIHBhZ2Ugd2lkZXIgdGhhbiBpdCBpcyB0YWxsIElTXG4gICAgICAgICAgICAgICAgbGFuZHNjYXBlIC0gc28gdGhlIHR3byBudW1iZXJzIHNheSBldmVyeXRoaW5nIHRoZXJlIGlzIHRvIHNheS5cbiAgICAgICAgICAgICAgLS0+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmcy1yb3cuZ2FwLXNtLmFsaWduLXN0YXJ0XCI+XG4gICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZnMtZmxleFwiPlxuICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgV2lkdGhcbiAgICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICBmc01hc2tOdW1iZXJcbiAgICAgICAgICAgICAgICAgICAgICBbc2NhbGVdPVwiMVwiXG4gICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJwYWdlV2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICAgIG5hbWU9XCJwYWdlV2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1SZXF1aXJlZF09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICBbZnNGb3JtTWluXT1cInBhZ2VEaW1lbnNpb25NaW5cIlxuICAgICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1NYXhdPVwicGFnZURpbWVuc2lvbk1heFwiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBtYXRUZXh0U3VmZml4PlxuICAgICAgICAgICAgICAgICAgICBpbmNoZXNcbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZnMtZmxleFwiPlxuICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgSGVpZ2h0XG4gICAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICAgICAgZnNNYXNrTnVtYmVyXG4gICAgICAgICAgICAgICAgICAgICAgW3NjYWxlXT1cIjFcIlxuICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwicGFnZUhlaWdodFwiXG4gICAgICAgICAgICAgICAgICAgICAgbmFtZT1cInBhZ2VIZWlnaHRcIlxuICAgICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1SZXF1aXJlZF09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICBbZnNGb3JtTWluXT1cInBhZ2VEaW1lbnNpb25NaW5cIlxuICAgICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1NYXhdPVwicGFnZURpbWVuc2lvbk1heFwiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBtYXRUZXh0U3VmZml4PlxuICAgICAgICAgICAgICAgICAgICBpbmNoZXNcbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8IS0tXG4gICAgICAgICAgICAgICAgSG93IGRlZXAgdGhlIGhlYWRlciBhbmQgZm9vdGVyIGJhbmRzIGFyZS4gVGhlaXIgY29udGVudCBpcyBlZGl0ZWRcbiAgICAgICAgICAgICAgICBvbiB0aGUgY2FudmFzIChFZGl0IGxheW91dCDihpIgSGVhZGVyICYgZm9vdGVyKTsgdGhlc2UgcmVzZXJ2ZSB0aGVcbiAgICAgICAgICAgICAgICBzcGFjZSBmb3IgaXQsIGFuZCAwIG1lYW5zIG5vIGJhbmQuXG4gICAgICAgICAgICAgIC0tPlxuICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJmdWxsLXdpZHRoXCI+XG4gICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgIEhlYWRlciBoZWlnaHRcbiAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgICAgZnNNYXNrTnVtYmVyXG4gICAgICAgICAgICAgICAgICAgIFtzY2FsZV09XCIyXCJcbiAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJoZWFkZXJIZWlnaHRcIlxuICAgICAgICAgICAgICAgICAgICBuYW1lPVwiaGVhZGVySGVpZ2h0XCJcbiAgICAgICAgICAgICAgICAgICAgW2ZzRm9ybU1pbl09XCIwXCJcbiAgICAgICAgICAgICAgICAgICAgW2ZzRm9ybU1heF09XCJoZWFkZXJGb290ZXJNYXhcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IG1hdFRleHRTdWZmaXg+XG4gICAgICAgICAgICAgICAgICBpbmNoZXNcbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZnVsbC13aWR0aFwiPlxuICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICBGb290ZXIgaGVpZ2h0XG4gICAgICAgICAgICAgICAgPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICAgIGZzTWFza051bWJlclxuICAgICAgICAgICAgICAgICAgICBbc2NhbGVdPVwiMlwiXG4gICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiZm9vdGVySGVpZ2h0XCJcbiAgICAgICAgICAgICAgICAgICAgbmFtZT1cImZvb3RlckhlaWdodFwiXG4gICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1NaW5dPVwiMFwiXG4gICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1NYXhdPVwiaGVhZGVyRm9vdGVyTWF4XCI+XG4gICAgICAgICAgICAgICAgPGRpdiBtYXRUZXh0U3VmZml4PlxuICAgICAgICAgICAgICAgICAgaW5jaGVzXG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgIDxmcy1haS1yZXBvcnQtdGltZXpvbmUtc2VsZWN0IFsodGltZXpvbmUpXT1cInRpbWV6b25lXCI+PC9mcy1haS1yZXBvcnQtdGltZXpvbmUtc2VsZWN0PlxuICAgICAgICAgICAgICA8IS0tXG4gICAgICAgICAgICAgICAgSG93IG51bWJlcnMgYW5kIGRhdGVzIGFyZSB3cml0dGVuIChmb3JtYXR0aW5nIG9ubHk6IG5vIHRleHQgaXNcbiAgICAgICAgICAgICAgICB0cmFuc2xhdGVkKSBhbmQgd2hpY2ggY3VycmVuY3kgbW9uZXkgaXMgbGFiZWxlZCBpbi4gSGlkZGVuIG9uIGFcbiAgICAgICAgICAgICAgICBzZXJ2ZXIgdG9vIG9sZCB0byByZXNvbHZlIGEgcmVwb3J0J3MgbG9jYWxlLlxuICAgICAgICAgICAgICAtLT5cbiAgICAgICAgICAgICAgQGlmIChsb2NhbGVzKCkpIHtcbiAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJmdWxsLXdpZHRoXCI+XG4gICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICBMb2NhbGVcbiAgICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgPG1hdC1zZWxlY3RcbiAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJsb2NhbGUoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwibG9jYWxlLnNldCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICBuYW1lPVwibG9jYWxlXCI+XG4gICAgICAgICAgICAgICAgICAgIEBmb3IgKG9wdGlvbiBvZiBsb2NhbGVPcHRpb25zKCk7IHRyYWNrIG9wdGlvbi52YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIFt2YWx1ZV09XCJvcHRpb24udmFsdWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7IG9wdGlvbi5sYWJlbCB9fVxuICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgPG1hdC1oaW50PlxuICAgICAgICAgICAgICAgICAgICB7eyBmb3JtYXRFeGFtcGxlKCkgfX1cbiAgICAgICAgICAgICAgICAgIDwvbWF0LWhpbnQ+XG4gICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJmdWxsLXdpZHRoXCI+XG4gICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICBDdXJyZW5jeVxuICAgICAgICAgICAgICAgICAgPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8bWF0LXNlbGVjdFxuICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cImN1cnJlbmN5KClcIlxuICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cImN1cnJlbmN5LnNldCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICBuYW1lPVwiY3VycmVuY3lcIj5cbiAgICAgICAgICAgICAgICAgICAgQGZvciAob3B0aW9uIG9mIGN1cnJlbmN5T3B0aW9ucygpOyB0cmFjayBvcHRpb24udmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwib3B0aW9uLnZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICB7eyBvcHRpb24ubGFiZWwgfX1cbiAgICAgICAgICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cbiAgICAgICAgICAgICAgICAgIDxtYXQtaGludD5cbiAgICAgICAgICAgICAgICAgICAgTmFtZXMgdGhlIGN1cnJlbmN5IGFtb3VudHMgYXJlIGluOyBpdCBkb2VzIG5vdCBjb252ZXJ0IHRoZW0uXG4gICAgICAgICAgICAgICAgICA8L21hdC1oaW50PlxuICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvbWF0LXRhYj5cbiAgICAgICAgICA8bWF0LXRhYlxuICAgICAgICAgICAgICBsYWJlbD1cIlN0eWxlc1wiXG4gICAgICAgICAgICAgIG5hbWU9XCJzdHlsZXNcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmcy1jb2x1bW4gdGFiLWJvZHlcIj5cbiAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICBIZWFkaW5nIFNpemVcbiAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICAgICAgICAgIHN0ZXA9XCIxXCJcbiAgICAgICAgICAgICAgICAgIG1pbj1cIjZcIlxuICAgICAgICAgICAgICAgICAgbWF4PVwiOTZcIlxuICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJoZWFkaW5nU2l6ZVwiXG4gICAgICAgICAgICAgICAgICBuYW1lPVwiaGVhZGluZ1NpemVcIlxuICAgICAgICAgICAgICAgICAgW2ZzRm9ybU1pbl09XCI2XCJcbiAgICAgICAgICAgICAgICAgIFtmc0Zvcm1NYXhdPVwiOTZcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBtYXRUZXh0U3VmZml4PlxuICAgICAgICAgICAgICAgICAgcHRcbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgPG1hdC1oaW50PlxuICAgICAgICAgICAgICAgICAgQXBwbGllcyB0byBjb21wb25lbnQgdGl0bGVzLiBQb2ludHMgbWFwIDE6MSB0byBQREYgYW5kIFBvd2VyUG9pbnQuXG4gICAgICAgICAgICAgICAgPC9tYXQtaGludD5cbiAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvbWF0LXRhYj5cbiAgICAgICAgICA8bWF0LXRhYlxuICAgICAgICAgICAgICBsYWJlbD1cIkZpbHRlcnNcIlxuICAgICAgICAgICAgICBuYW1lPVwiZmlsdGVyc1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZzLWNvbHVtbiB0YWItYm9keVwiPlxuICAgICAgICAgICAgICBAaWYgKGZpbHRlclJvd3MoKS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICBAZm9yIChyb3cgb2YgZmlsdGVyUm93cygpOyB0cmFjayByb3cuZ3JvdXAuaWQpIHtcbiAgICAgICAgICAgICAgICAgIEBzd2l0Y2ggKHJvdy5ncm91cC50eXBlKSB7XG4gICAgICAgICAgICAgICAgICAgIEBjYXNlICgnZGF0ZVJhbmdlJykge1xuICAgICAgICAgICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmcy1yb3cuZ2FwLXNtLmFsaWduLWNlbnRlciBmcy1mbGV4XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJmcy1mbGV4XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVmYXVsdCBGcm9tIHt7IHJvdy5sYWJlbCB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmc0RhdGVQaWNrZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInJvdy5zdGFydFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW25hbWVdPVwiJ3N0YXJ0JyArIHJvdy5ncm91cC5pZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImZzLWZsZXhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZWZhdWx0IFRvIHt7IHJvdy5sYWJlbCB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmc0RhdGVQaWNrZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInJvdy5lbmRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuYW1lXT1cIidlbmQnICsgcm93Lmdyb3VwLmlkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgICAgIDwhLS0gQSBzdG9yZWQgcm9sbGluZyBwcmVzZXQgY2Fubm90IGJlIGF1dGhvcmVkIGhlcmUsIG9ubHlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGtlcHQsIHJlcGxhY2VkIGJ5IHBpY2tpbmcgZGF0ZXMsIG9yIGNsZWFyZWQuIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAga2VlcHMgQ2xlYXIgZnJvbSBzdWJtaXR0aW5nIHRoZSBmb3JtLiAtLT5cbiAgICAgICAgICAgICAgICAgICAgICBAaWYgKHJvdy5yZWxhdGl2ZSAmJiAhcm93LnN0YXJ0ICYmICFyb3cuZW5kKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZnMtcm93LmdhcC1zbS5hbGlnbi1jZW50ZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1oaW50IGNsYXNzPVwiZnMtZmxleFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJvbGxpbmcgZGVmYXVsdDoge3sgcmVsYXRpdmVMYWJlbChyb3cucmVsYXRpdmUpIH19LiBQaWNrIGRhdGVzIHRvIHJlcGxhY2UgaXQuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWhpbnQ+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdC1idXR0b25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cImNsZWFyUmVsYXRpdmUocm93KVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIENsZWFyXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEBjYXNlICgnc2VsZWN0Jykge1xuICAgICAgICAgICAgICAgICAgICAgIDxmcy1hdXRvY29tcGxldGUtY2hpcHNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmcy1mbGV4XCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW2xhYmVsXT1cIidEZWZhdWx0ICcgKyByb3cubGFiZWxcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbZmV0Y2hdPVwicm93LmZldGNoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJyb3cudmFsdWVzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW25hbWVdPVwiJ3ZhbHVlcycgKyByb3cuZ3JvdXAuaWRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICBbbXVsdGlwbGVdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgIFtmZXRjaE9uRm9jdXNdPVwidHJ1ZVwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZnNBdXRvY29tcGxldGVDaGlwc1RlbXBsYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0LW9iamVjdD1cIm9iamVjdFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICB7eyBvYmplY3QubmFtZSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICA8L2ZzLWF1dG9jb21wbGV0ZS1jaGlwcz5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBAZGVmYXVsdCB7XG4gICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZnMtZmxleFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgRGVmYXVsdCB7eyByb3cubGFiZWwgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwicm93LnZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW25hbWVdPVwiJ3ZhbHVlJyArIHJvdy5ncm91cC5pZFwiPlxuICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgIDxmcy1tZXNzYWdlLWluZm8+XG4gICAgICAgICAgICAgICAgICBUaGlzIHJlcG9ydCBoYXMgbm8gcmVwb3J0LWxldmVsIGZpbHRlcnMgeWV0LiBBZGQgYSBmaWx0ZXIgdG8gYVxuICAgICAgICAgICAgICAgICAgY29tcG9uZW50IChpdHMgc2V0dGluZ3Mg4oaSIEZpbHRlcnMpIGFuZCBzaG93IGl0IGluIHRoZSByZXBvcnQgYmFyLFxuICAgICAgICAgICAgICAgICAgdGhlbiBzZXQgaXRzIGRlZmF1bHQgaGVyZS5cbiAgICAgICAgICAgICAgICA8L2ZzLW1lc3NhZ2UtaW5mbz5cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9tYXQtdGFiPlxuICAgICAgICA8L21hdC10YWItZ3JvdXA+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICA8L21hdC1kaWFsb2ctY29udGVudD5cbiAgICA8bWF0LWRpYWxvZy1hY3Rpb25zPlxuICAgICAgPGZzLWZvcm0tZGlhbG9nLWFjdGlvbnM+XG4gICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICAgICAgbWF0LWJ1dHRvblxuICAgICAgICAgICAgY29sb3I9XCJ3YXJuXCJcbiAgICAgICAgICAgIChjbGljayk9XCJkZWxldGUoKVwiPlxuICAgICAgICAgIERlbGV0ZVxuICAgICAgICA8L2J1dHRvbj5cbiAgICAgIDwvZnMtZm9ybS1kaWFsb2ctYWN0aW9ucz5cbiAgICA8L21hdC1kaWFsb2ctYWN0aW9ucz5cbiAgPC9mcy1kaWFsb2c+XG48L2Zvcm0+Il19
|
|
401
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LXNldHRpbmdzLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy9kaWFsb2dzL3JlcG9ydC1zZXR0aW5ncy9yZXBvcnQtc2V0dGluZ3MuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2RpYWxvZ3MvcmVwb3J0LXNldHRpbmdzL3JlcG9ydC1zZXR0aW5ncy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBVSxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNqSCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQW1CLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTlELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsZUFBZSxFQUFFLGdCQUFnQixFQUFFLGdCQUFnQixFQUFFLFlBQVksRUFBRSxjQUFjLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUM3SCxPQUFPLEVBQUUsWUFBWSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDMUYsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ25ELE9BQU8sRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFDaEUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBQ2hFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUV2RCxPQUFPLEVBQUUseUJBQXlCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUMzRSxP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QUFRLGlVQUNSLFNBQVMsd2VBQ1QsU0FBUyxxSkFDVCxjQUFjLDBVQUNkLHVCQUF1Qjs7NEZBR2QsdUJBQXVCO2tCQWhDbkMsU0FBUztzQ0FHUyx1QkFBdUIsQ0FBQyxNQUFNLGNBQ25DLElBQUksV0FDUDt3QkFDUCxXQUFXO3dCQUNYLFlBQVk7d0JBQ1osYUFBYTt3QkFDYixZQUFZO3dCQUNaLGNBQWM7d0JBQ2QsZUFBZTt3QkFDZixZQUFZO3dCQUNaLGdCQUFnQjt3QkFDaEIsa0JBQWtCO3dCQUNsQix5QkFBeUI7d0JBQ3pCLGFBQWE7d0JBQ2IsU0FBUzt3QkFDVCxjQUFjO3dCQUNkLGdCQUFnQjt3QkFDaEIsZ0JBQWdCO3dCQUNoQixZQUFZO3dCQUNaLFFBQVE7d0JBQ1IsT0FBTzt3QkFDUCxTQUFTO3dCQUNULFFBQVE7d0JBQ1IsU0FBUzt3QkFDVCxTQUFTO3dCQUNULGNBQWM7d0JBQ2QsdUJBQXVCO3FCQUN4QiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIERlc3Ryb3lSZWYsIE9uSW5pdCwgY29tcHV0ZWQsIGluamVjdCwgc2lnbmFsIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyB0YWtlVW50aWxEZXN0cm95ZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5pbXBvcnQgeyBBYnN0cmFjdENvbnRyb2wsIEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5pbXBvcnQgeyBNYXRCdXR0b24gfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9idXR0b24nO1xuaW1wb3J0IHsgTUFUX0RJQUxPR19EQVRBLCBNYXREaWFsb2dBY3Rpb25zLCBNYXREaWFsb2dDb250ZW50LCBNYXREaWFsb2dSZWYsIE1hdERpYWxvZ1RpdGxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvZGlhbG9nJztcbmltcG9ydCB7IE1hdEZvcm1GaWVsZCwgTWF0TGFiZWwsIE1hdEhpbnQsIE1hdFN1ZmZpeCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2Zvcm0tZmllbGQnO1xuaW1wb3J0IHsgTWF0SW5wdXQgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pbnB1dCc7XG5pbXBvcnQgeyBNYXRPcHRpb24sIE1hdFNlbGVjdCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3NlbGVjdCc7XG5pbXBvcnQgeyBNYXRTbGlkZVRvZ2dsZSB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3NsaWRlLXRvZ2dsZSc7XG5pbXBvcnQgeyBNYXRUYWJzTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvdGFicyc7XG5cbmltcG9ydCB7IEZzQXV0b2NvbXBsZXRlQ2hpcHNNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9hdXRvY29tcGxldGUtY2hpcHMnO1xuaW1wb3J0IHsgRnNEYXRlUGlja2VyTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvZGF0ZXBpY2tlcic7XG5pbXBvcnQgeyBGc0RpYWxvZ01vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL2RpYWxvZyc7XG5pbXBvcnQgeyBGc0Zvcm1Nb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9mb3JtJztcbmltcG9ydCB7IEZzTGFiZWxNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9sYWJlbCc7XG5pbXBvcnQgeyBGc01hc2tNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9tYXNrJztcbmltcG9ydCB7IEZzTWVzc2FnZSwgRnNNZXNzYWdlTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvbWVzc2FnZSc7XG5pbXBvcnQgeyBGc1Byb21wdCB9IGZyb20gJ0BmaXJlc3RpdGNoL3Byb21wdCc7XG5pbXBvcnQgeyBGc1NrZWxldG9uTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvc2tlbGV0b24nO1xuaW1wb3J0IHsgRnNUYWJzTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvdGFicyc7XG5cbmltcG9ydCB7IFRpbWV6b25lU2VsZWN0Q29tcG9uZW50IH0gZnJvbSAnLi4vLi4vY29tcG9uZW50cy90aW1lem9uZS1zZWxlY3QvdGltZXpvbmUtc2VsZWN0LmNvbXBvbmVudCc7XG5cbmltcG9ydCB7IE9ic2VydmFibGUsIGZvcmtKb2luLCBvZiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgY2F0Y2hFcnJvciwgZmluYWxpemUsIHN3aXRjaE1hcCwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBSZXBvcnREYXRhIH0gZnJvbSAnLi4vLi4vZGF0YS9yZXBvcnQuZGF0YSc7XG5pbXBvcnQgeyBSZXBvcnRWYWx1ZUZvcm1hdCB9IGZyb20gJy4uLy4uL2VudW1zL3JlcG9ydC12YWx1ZS1mb3JtYXQuZW51bSc7XG5pbXBvcnQge1xuICBEQVlfU0hPUlQsXG4gIFJFUE9SVF9GQUxMQkFDS19DVVJSRU5DWSxcbiAgY3VycmVuY3lOYW1lLFxuICBmb3JtYXRMb2NhbERhdGUsXG4gIGZvcm1hdE51bWJlcixcbiAgbG9jYWxlTmFtZSxcbiAgcmVzb2x2ZVJlcG9ydEN1cnJlbmN5LFxuICByZXNvbHZlUmVwb3J0TG9jYWxlLFxufSBmcm9tICcuLi8uLi9mb3JtYXQnO1xuaW1wb3J0IHtcbiAgRmlsdGVyR3JvdXBEZWZhdWx0LFxuICBSZXBvcnQsXG4gIFJlcG9ydEZpbHRlckdyb3VwLFxuICBSZXBvcnRMb2NhbGVzLFxufSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL3JlcG9ydC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgREVGQVVMVF9IRUFESU5HX1NJWkUsIEhFQURFUl9GT09URVJfTUFYLCBQQUdFX0RJTUVOU0lPTl9NQVgsIFBBR0VfRElNRU5TSU9OX01JTiB9IGZyb20gJy4uLy4uL2xheW91dCc7XG5pbXBvcnQge1xuICBkYXRlRnJvbUJvdW5kLCBkYXRlVG9Cb3VuZCwgbG9hZEdyb3VwT3B0aW9ucywgbWF0Y2hPcHRpb25zLCByZWxhdGl2ZUxhYmVsLCByZXNvbHZlT3B0aW9uVmFsdWVzLFxufSBmcm9tICcuLi8uLi9yZXBvcnQtZmlsdGVyLWl0ZW1zJztcbmltcG9ydCB7XG4gIERFRkFVTFRfQk9VTkRfU0NBTEUsXG4gIEZJWEVEX0RBVEVTX1BFUklPRCxcbiAgYm91bmRzRXJyb3IsXG4gIGRhdGVSYW5nZURlZmF1bHQsXG4gIGRlZmF1bHRDaGFuZ2VkLFxuICBkZWZhdWx0UGVyaW9kLFxuICBkZWZhdWx0UGVyaW9kT3B0aW9ucyxcbiAgZGVmYXVsdFJvd0dyb3VwcyxcbiAgZGVmYXVsdFJvd0xhYmVsLFxuICBudW1iZXJSYW5nZURlZmF1bHQsXG4gIHBhcnNlRGVmYXVsdEJvdW5kLFxuICBzZWxlY3REZWZhdWx0LFxuICBzaG93RXhjbHVkZVRvZ2dsZSxcbn0gZnJvbSAnLi4vLi4vZmlsdGVyLXNldHRpbmdzLXJ1bGVzJztcbmltcG9ydCB7IEZpbHRlclNldHRpbmdzT3B0aW9uIH0gZnJvbSAnLi4vLi4vaW50ZXJmYWNlcy9maWx0ZXItc2V0dGluZ3Mtb3B0aW9uLmludGVyZmFjZSc7XG5cbmltcG9ydCB7IHJlcG9ydExvY2FsZVBhdGNoIH0gZnJvbSAnLi9yZXBvcnQtbG9jYWxlLXBhdGNoJztcblxuXG4vLyBXaGF0IHRoZSBkaWFsb2cgaGFuZHMgYmFjayB3aGVuIGl0IGNsb3Nlcywgc28gdGhlIHBhZ2Uga25vd3Mgd2hhdCBoYXBwZW5lZFxuLy8gd2l0aG91dCBzbmlmZmluZyBtYWdpYyBzdHJpbmdzLiBBIGRpc21pc3NlZCBkaWFsb2cgY2xvc2VzIHdpdGggYHVuZGVmaW5lZGAuXG5leHBvcnQgaW50ZXJmYWNlIFJlcG9ydFNldHRpbmdzUmVzdWx0IHtcbiAgYWN0aW9uOiAnc2F2ZWQnIHwgJ2RlbGV0ZWQnO1xufVxuXG5cbi8vIE9uZSByZXBvcnQgYmFyIGZpbHRlciBpbiB0aGUgRmlsdGVycyB0YWI6IGl0cyBncm91cCwgYW5kIGFuIGVkaXRhYmxlIGRyYWZ0XG4vLyBkZWZhdWx0LiBUaGUgZHJhZnQgZmllbGRzIHVzZWQgZGVwZW5kIG9uIHRoZSB0eXBlIChkYXRlUmFuZ2Ug4oaSIGEgRGVmYXVsdFxuLy8gcGVyaW9kLCB3aGljaCBpcyBhIHJlbGF0aXZlIHJhbmdlIG9yIEZpeGVkIGRhdGVzIHdpdGggc3RhcnQvZW5kIERhdGVzO1xuLy8gc2VsZWN0IOKGkiB2YWx1ZXMsIGtlcHQgb3IgbGVmdCBvdXQ7IGtleXdvcmQg4oaSIHRleHQ7IG51bWJlclJhbmdlIOKGkiBtaW4gYW5kXG4vLyBtYXgpLiBgZmV0Y2hgIGxvYWRzIHRoZSBzZWxlY3Qgb3B0aW9ucyB0aGUgc2FtZSB3YXkgdGhlIHJlcG9ydCBiYXIgZG9lcy5cbmludGVyZmFjZSBGaWx0ZXJEZWZhdWx0Um93IHtcbiAgZ3JvdXA6IFJlcG9ydEZpbHRlckdyb3VwO1xuICBsYWJlbDogc3RyaW5nO1xuICAvLyBBIHJlbGF0aXZlIHJhbmdlIG5hbWUsIG9yIEZJWEVEX0RBVEVTX1BFUklPRCBmb3Igc3RhcnQgYW5kIGVuZC5cbiAgcGVyaW9kOiBzdHJpbmc7XG4gIHBlcmlvZE9wdGlvbnM6IEZpbHRlclNldHRpbmdzT3B0aW9uW107XG4gIHN0YXJ0OiBEYXRlIHwgbnVsbDtcbiAgZW5kOiBEYXRlIHwgbnVsbDtcbiAgdmFsdWVzOiB7IG5hbWU6IHN0cmluZzsgdmFsdWU6IHVua25vd24gfVtdO1xuICAvLyBUaGUgdmFsdWVzIGFyZSBsZWZ0IG91dCByYXRoZXIgdGhhbiBrZXB0LlxuICBleGNsdWRlOiBib29sZWFuO1xuICBzaG93RXhjbHVkZTogYm9vbGVhbjtcbiAgdmFsdWU6IHN0cmluZztcbiAgLy8gVGhlIHJhbmdlIGVuZHMgYXMgdHlwZWQ6IGZzTWFza051bWJlciBoYW5kcyBiYWNrIHRleHQuIFJlYWQgdGhyb3VnaFxuICAvLyBwYXJzZURlZmF1bHRCb3VuZC5cbiAgbWluOiBudW1iZXIgfCBzdHJpbmcgfCBudWxsO1xuICBtYXg6IG51bWJlciB8IHN0cmluZyB8IG51bGw7XG4gIGZldGNoOiAoa2V5d29yZD86IHN0cmluZykgPT4gT2JzZXJ2YWJsZTx7IG5hbWU6IHN0cmluZzsgdmFsdWU6IHVua25vd24gfVtdPjtcbn1cblxuLy8gT25lIGVudHJ5IG9mIHRoZSBMb2NhbGUgb3IgQ3VycmVuY3kgc2VsZWN0LiAnJyBpcyB0aGUgZXhwbGljaXQgRGVmYXVsdC5cbmludGVyZmFjZSBMb2NhbGVTZWxlY3RPcHRpb24ge1xuICB2YWx1ZTogc3RyaW5nO1xuICBsYWJlbDogc3RyaW5nO1xufVxuXG4vLyBUaGUgZGF5IHRoZSBMb2NhbGUgaGludCB3cml0ZXMsIGEgZml4ZWQgY2FsZW5kYXIgZGF5IHNvIHRoZSBleGFtcGxlIG5ldmVyXG4vLyBjaGFuZ2VzIHVuZGVyIHRoZSBvcGVyYXRvci5cbmNvbnN0IEVYQU1QTEVfREFZID0gbmV3IERhdGUoMjAyNiwgMCwgNSk7XG5jb25zdCBFWEFNUExFX0FNT1VOVCA9IDEyMzQuNTtcblxuLy8gJ0NhbmFkaWFuIEZyZW5jaCAoZnItQ0EpJywgJ0NhbmFkaWFuIERvbGxhciAoQ0FEKSc6IEVuZ2xpc2ggbmFtZXMgd2hhdGV2ZXJcbi8vIHRoZSByZXBvcnQncyBsb2NhbGUsIHdpdGggdGhlIGNvZGUgdGhhdCBpcyBzdG9yZWQuXG5mdW5jdGlvbiBsb2NhbGVMYWJlbCh0YWc6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBgJHtsb2NhbGVOYW1lKHRhZyl9ICgke3RhZ30pYDtcbn1cblxuZnVuY3Rpb24gY3VycmVuY3lMYWJlbChjb2RlOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYCR7Y3VycmVuY3lOYW1lKGNvZGUpfSAoJHtjb2RlfSlgO1xufVxuXG5cbi8vIFJlcG9ydCBzZXR0aW5ncywgaW4gdGhyZWUgdGFiczpcbi8vICAgU2V0dGluZ3Mg4oCUIG5hbWUgKyBwYWdlIHNldHVwIChzaXplIGluIGluY2hlcywgaGVhZGVyL2Zvb3RlciBiYW5kIGRlcHRocykuXG4vLyAgIFN0eWxlcyAgIOKAlCB0aGUgcmVwb3J0J3MgdHlwb2dyYXBoaWMgc3R5bGVzIChzaXplcyBpbiBQT0lOVFMsIDE6MSB3aXRoXG4vLyAgIFBERi9Qb3dlclBvaW50KTsgdGhlIEhlYWRpbmcgc2l6ZSB0byBzdGFydC5cbi8vICAgRmlsdGVycyAg4oCUIHRoZSByZXBvcnQgYmFyIGZpbHRlcnMgKGV2ZXJ5IHBhZ2Ugb3Igb25lIHBhZ2UpIGFuZCB0aGVpclxuLy8gICBERUZBVUxUIHZhbHVlcy4gQSBkZWZhdWx0IHNlZWRzIHRoZSByZXBvcnQgYmFyIG9uIGV2ZXJ5IG9wZW4gKGZvciBldmVyeVxuLy8gICB2aWV3ZXIpIGJ1dCBzdGF5cyB1c2VyLWNoYW5nZWFibGUg4oCUIGl0IHByZS1maWxscyB0aGUgY29udHJvbCwgaXQgZG9lc24ndFxuLy8gICBsb2NrIGl0LiBUaGlzIGlzIHRoZSBmaXggZm9yIGhlYXZ5IHJlcG9ydHMgb3BlbmluZyBibGFuayBhbmQgdGltaW5nIG91dDogYVxuLy8gICBkZWZhdWx0IG1vbnRoICsgb3JnYW5pemF0aW9uIHNjb3BlcyB0aGUgbGFuZGluZyBwYWdlIGZyb20gdGhlIGZpcnN0IGxvYWQuXG4vLyAgIFRoZSBydWxlcyBvZiB0aGUgcm93cyBsaXZlIGluIGZpbHRlci1zZXR0aW5ncy1ydWxlcy50cy5cbkBDb21wb25lbnQoe1xuICB0ZW1wbGF0ZVVybDogJy4vcmVwb3J0LXNldHRpbmdzLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vcmVwb3J0LXNldHRpbmdzLmNvbXBvbmVudC5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgRm9ybXNNb2R1bGUsXG4gICAgRnNGb3JtTW9kdWxlLFxuICAgIEZzTGFiZWxNb2R1bGUsXG4gICAgRnNNYXNrTW9kdWxlLFxuICAgIEZzRGlhbG9nTW9kdWxlLFxuICAgIEZzTWVzc2FnZU1vZHVsZSxcbiAgICBGc1RhYnNNb2R1bGUsXG4gICAgRnNTa2VsZXRvbk1vZHVsZSxcbiAgICBGc0RhdGVQaWNrZXJNb2R1bGUsXG4gICAgRnNBdXRvY29tcGxldGVDaGlwc01vZHVsZSxcbiAgICBNYXRUYWJzTW9kdWxlLFxuICAgIE1hdEJ1dHRvbixcbiAgICBNYXREaWFsb2dUaXRsZSxcbiAgICBNYXREaWFsb2dDb250ZW50LFxuICAgIE1hdERpYWxvZ0FjdGlvbnMsXG4gICAgTWF0Rm9ybUZpZWxkLFxuICAgIE1hdExhYmVsLFxuICAgIE1hdEhpbnQsXG4gICAgTWF0U3VmZml4LFxuICAgIE1hdElucHV0LFxuICAgIE1hdFNlbGVjdCxcbiAgICBNYXRPcHRpb24sXG4gICAgTWF0U2xpZGVUb2dnbGUsXG4gICAgVGltZXpvbmVTZWxlY3RDb21wb25lbnQsXG4gIF0sXG59KVxuZXhwb3J0IGNsYXNzIFJlcG9ydFNldHRpbmdzQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcblxuICBwdWJsaWMgc2VsZWN0ZWRUYWIgPSAnc2V0dGluZ3MnO1xuXG4gIHB1YmxpYyBuYW1lID0gJyc7XG4gIC8vIFRoZSBwYWdlIGluIGluY2hlcy4gTm8gaW5pdGlhbGl6ZXI6IGV2ZXJ5IHJlcG9ydCBjYXJyaWVzIGEgc2l6ZSwgYW5kXG4gIC8vIG5nT25Jbml0IHNlZWRzIGJvdGggYmVmb3JlIHRoZSB0YWIgcmVuZGVycywgc28gYSBwbGFjZWhvbGRlciBoZXJlIGNvdWxkIG9ubHlcbiAgLy8gZXZlciBiZSBhIHdyb25nIG51bWJlciBicmllZmx5IHNob3dpbmcgYXMgdGhlIG9wZXJhdG9yJ3Mgb3duLlxuICAvL1xuICAvLyBUeXBlZCBgbnVtYmVyIHwgc3RyaW5nYCBiZWNhdXNlIGZzTWFza051bWJlciBpcyB0aGUgY29udHJvbDogaXQgaXMgc2VlZGVkXG4gIC8vIHdpdGggdGhlIHJlcG9ydCdzIG51bWJlciBidXQgaGFuZHMgYmFjayB0aGUgdW5tYXNrZWQgU1RSSU5HIHRoZSBvcGVyYXRvclxuICAvLyB0eXBlZC4gU2F2ZSBjYXN0cyBpdCBvbmNlLCBvbiB0aGUgd2F5IG91dCDigJQgc2VlIGBfcGFnZURpbWVuc2lvbigpYC5cbiAgcHVibGljIHBhZ2VXaWR0aDogbnVtYmVyIHwgc3RyaW5nO1xuICBwdWJsaWMgcGFnZUhlaWdodDogbnVtYmVyIHwgc3RyaW5nO1xuICBwdWJsaWMgcmVhZG9ubHkgcGFnZURpbWVuc2lvbk1pbiA9IFBBR0VfRElNRU5TSU9OX01JTjtcbiAgcHVibGljIHJlYWRvbmx5IHBhZ2VEaW1lbnNpb25NYXggPSBQQUdFX0RJTUVOU0lPTl9NQVg7XG4gIC8vIFRoZSBoZWFkZXIgYW5kIGZvb3RlciBiYW5kIGRlcHRocywgaW5jaGVzIOKAlCB0eXBlZCBsaWtlIHRoZSBwYWdlIHNpemVcbiAgLy8gYmVjYXVzZSBmc01hc2tOdW1iZXIgaGFuZHMgYmFjayBhIHN0cmluZy5cbiAgcHVibGljIGhlYWRlckhlaWdodDogbnVtYmVyIHwgc3RyaW5nID0gMDtcbiAgcHVibGljIGZvb3RlckhlaWdodDogbnVtYmVyIHwgc3RyaW5nID0gMDtcbiAgcHVibGljIHJlYWRvbmx5IGhlYWRlckZvb3Rlck1heCA9IEhFQURFUl9GT09URVJfTUFYO1xuICAvLyBTZWVkZWQgd2l0aCB0aGUgem9uZSB0aGUgcmVwb3J0IGFjdHVhbGx5IHVzZXM6IGl0cyBvd24gc3RvcmVkIHpvbmUsIGVsc2VcbiAgLy8gdGhlIGFwcGxpY2F0aW9uIGRlZmF1bHQgdGhlIHNlcnZlciByZXNvbHZlZCAoZWZmZWN0aXZlVGltZXpvbmUpLiBTYXZlIHNlbmRzXG4gIC8vIGl0IG9ubHkgd2hlbiBpdCBkaWZmZXJzIGZyb20gdGhhdCBlZmZlY3RpdmUgem9uZSwgc28gb3BlbmluZyBhbmQgc2F2aW5nIGFcbiAgLy8gcmVwb3J0IHRoYXQgZm9sbG93cyB0aGUgZGVmYXVsdCBuZXZlciBwaW5zIGl0IHRvIGEgem9uZS5cbiAgcHVibGljIHRpbWV6b25lID0gJyc7XG4gIHB1YmxpYyBoZWFkaW5nU2l6ZSA9IERFRkFVTFRfSEVBRElOR19TSVpFO1xuXG4gIC8vIFRoZSBsb2NhbGVzIGFuZCBjdXJyZW5jaWVzIHRoZSBzZXJ2ZXIgb2ZmZXJzLiBudWxsIHVudGlsIGxvYWRlZCwgYW5kXG4gIC8vIG5ldmVyIGxvYWRlZCBmcm9tIGEgc2VydmVyIHRvbyBvbGQgdG8gc2VuZCBlZmZlY3RpdmVMb2NhbGU6IHRoZXJlIHRoZVxuICAvLyBzZWxlY3RzIHN0YXkgaGlkZGVuIGFuZCB0aGUgcmVwb3J0IHJlYWRzIGVuLVVTL1VTRC5cbiAgcHVibGljIHJlYWRvbmx5IGxvY2FsZXMgPSBzaWduYWw8UmVwb3J0TG9jYWxlcyB8IG51bGw+KG51bGwpO1xuICAvLyBUaGUgcmVwb3J0J3Mgb3duIGxvY2FsZSBhbmQgY3VycmVuY3ksICcnIHdoZW4gaXQgZm9sbG93cyB0aGUgZGVmYXVsdC4gU2F2ZVxuICAvLyBzZW5kcyBlYWNoIG9ubHkgd2hlbiBpdCBkaWZmZXJzIGZyb20gdGhlIHN0b3JlZCB2YWx1ZS5cbiAgcHVibGljIHJlYWRvbmx5IGxvY2FsZSA9IHNpZ25hbCgnJyk7XG4gIHB1YmxpYyByZWFkb25seSBjdXJyZW5jeSA9IHNpZ25hbCgnJyk7XG4gIC8vIFRoZSB3aG9sZSBmb3JtIHdhaXRzIGJlaGluZCBvbmUgc2tlbGV0b24gdW50aWwgdGhlIGZpbHRlciByb3dzIGFyZSBidWlsdFxuICAvLyBhbmQgdGhlIGxvY2FsZSByZXF1ZXN0IGhhcyBzZXR0bGVkLCBzbyB0aGUgU2V0dGluZ3MgdGFiIG5ldmVyIHNob3dzXG4gIC8vIHdpdGhvdXQgaXRzIExvY2FsZSBhbmQgQ3VycmVuY3kgc2VsZWN0cy4gQSBmYWlsZWQgbG9jYWxlIHJlcXVlc3Qgc2V0dGxlc1xuICAvLyB0b286IHRoZSB0d28gc2VsZWN0cyBzdGF5IGhpZGRlbiAobG9jYWxlcygpIGlzIHN0aWxsIG51bGwpIGFuZCBldmVyeSBvdGhlclxuICAvLyBzZXR0aW5nIHN0YXlzIGVkaXRhYmxlLlxuICBwdWJsaWMgcmVhZG9ubHkgcmVhZHkgPSBjb21wdXRlZCgoKSA9PiB0aGlzLl9maWx0ZXJzUmVhZHkoKSAmJiAoIXRoaXMuX3NlcnZlckhhc0xvY2FsZSB8fCB0aGlzLl9sb2NhbGVzU2V0dGxlZCgpKSk7XG5cbiAgLy8gQW4gZXhwbGljaXQgRGVmYXVsdCAoJycpIG5hbWluZyB0aGUgbG9jYWxlIGl0IHN0YW5kcyBmb3IsIHRoZW4gZWFjaCBvZmZlcmVkXG4gIC8vIGxvY2FsZS4gQSBzdG9yZWQgbG9jYWxlIHRoZSBzZXJ2ZXIgbm8gbG9uZ2VyIG9mZmVycyBpcyBsaXN0ZWQgZmlyc3QsIHNvXG4gIC8vIHRoZSBzZWxlY3Qgc3RpbGwgc2hvd3Mgd2hhdCB0aGUgcmVwb3J0IGhvbGRzLlxuICBwdWJsaWMgcmVhZG9ubHkgbG9jYWxlT3B0aW9ucyA9IGNvbXB1dGVkPExvY2FsZVNlbGVjdE9wdGlvbltdPigoKSA9PiB7XG4gICAgY29uc3QgbG9jYWxlcyA9IHRoaXMubG9jYWxlcygpO1xuICAgIGlmICghbG9jYWxlcykge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIGNvbnN0IG9mZmVyZWQgPSBsb2NhbGVzLm9wdGlvbnMubWFwKChvcHRpb24pID0+IG9wdGlvbi5sb2NhbGUpO1xuXG4gICAgcmV0dXJuIFtcbiAgICAgIC4uLnRoaXMuX3N0b3JlZE9wdGlvbih0aGlzLl9kYXRhLnJlcG9ydC5sb2NhbGUsIG9mZmVyZWQsIGxvY2FsZUxhYmVsKSxcbiAgICAgIHsgdmFsdWU6ICcnLCBsYWJlbDogYERlZmF1bHQg4oCUICR7bG9jYWxlTmFtZShsb2NhbGVzLmRlZmF1bHRMb2NhbGUpfWAgfSxcbiAgICAgIC4uLm9mZmVyZWQubWFwKCh0YWcpID0+ICh7IHZhbHVlOiB0YWcsIGxhYmVsOiBsb2NhbGVMYWJlbCh0YWcpIH0pKSxcbiAgICBdO1xuICB9KTtcblxuICAvLyBBbiBleHBsaWNpdCBEZWZhdWx0ICgnJykgbmFtaW5nIHRoZSBjdXJyZW5jeSB0aGUgc2VsZWN0ZWQgbG9jYWxlIHVzZXMgd2hlblxuICAvLyB0aGUgcmVwb3J0IG5hbWVzIG5vbmUsIHRoZW4gZXZlcnkgY3VycmVuY3kuIEEgc3RvcmVkIGNvZGUgdGhlIHNlcnZlciBub1xuICAvLyBsb25nZXIgb2ZmZXJzIGlzIGxpc3RlZCBmaXJzdC5cbiAgcHVibGljIHJlYWRvbmx5IGN1cnJlbmN5T3B0aW9ucyA9IGNvbXB1dGVkPExvY2FsZVNlbGVjdE9wdGlvbltdPigoKSA9PiB7XG4gICAgY29uc3QgbG9jYWxlcyA9IHRoaXMubG9jYWxlcygpO1xuICAgIGlmICghbG9jYWxlcykge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIHJldHVybiBbXG4gICAgICAuLi50aGlzLl9zdG9yZWRPcHRpb24odGhpcy5fZGF0YS5yZXBvcnQuY3VycmVuY3ksIGxvY2FsZXMuY3VycmVuY2llcywgY3VycmVuY3lMYWJlbCksXG4gICAgICB7IHZhbHVlOiAnJywgbGFiZWw6IGBEZWZhdWx0IOKAlCAke2N1cnJlbmN5TGFiZWwodGhpcy5fZGVmYXVsdEN1cnJlbmN5KCkpfWAgfSxcbiAgICAgIC4uLmxvY2FsZXMuY3VycmVuY2llcy5tYXAoKGNvZGUpID0+ICh7IHZhbHVlOiBjb2RlLCBsYWJlbDogY3VycmVuY3lMYWJlbChjb2RlKSB9KSksXG4gICAgXTtcbiAgfSk7XG5cbiAgLy8gSG93IHRoZSByZXBvcnQgd2lsbCB3cml0ZSBhbiBhbW91bnQgYW5kIGEgZGF5IG9uY2Ugc2F2ZWQ6IHRoZSBzZWxlY3RlZFxuICAvLyBsb2NhbGUgYW5kIGN1cnJlbmN5LCBvciB0aGUgZGVmYXVsdHMgdGhleSBmYWxsIGJhY2sgdG8sIGUuZy5cbiAgLy8gJzEgMjM0LDUwICQgwrcgNSBqYW52LiAyMDI2JyBpbiBmci1DQS5cbiAgcHVibGljIHJlYWRvbmx5IGZvcm1hdEV4YW1wbGUgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgY29uc3QgbG9jYWxlID0gcmVzb2x2ZVJlcG9ydExvY2FsZSh0aGlzLl9hcHBsaWVkTG9jYWxlKCkpO1xuICAgIGNvbnN0IGN1cnJlbmN5ID0gcmVzb2x2ZVJlcG9ydEN1cnJlbmN5KHRoaXMuX2FwcGxpZWRDdXJyZW5jeSgpKTtcblxuICAgIHJldHVybiBbXG4gICAgICBmb3JtYXROdW1iZXIoXG4gICAgICAgIEVYQU1QTEVfQU1PVU5ULFxuICAgICAgICB7IGZvcm1hdDogUmVwb3J0VmFsdWVGb3JtYXQuQ3VycmVuY3ksIHByZWNpc2lvbjogMiB9LFxuICAgICAgICB7IGxvY2FsZSwgY3VycmVuY3ksIHJhdGlvUGVyY2VudDogdHJ1ZSB9LFxuICAgICAgKSxcbiAgICAgIGZvcm1hdExvY2FsRGF0ZShFWEFNUExFX0RBWSwgbG9jYWxlLCBEQVlfU0hPUlQpLFxuICAgIF0uam9pbignIMK3ICcpO1xuICB9KTtcblxuICAvLyBUaGUgcmVwb3J0IGJhciBmaWx0ZXJzIGFuZCB0aGVpciBlZGl0YWJsZSBkZWZhdWx0IHZhbHVlcyAoRmlsdGVycyB0YWIpLlxuICBwdWJsaWMgcmVhZG9ubHkgZmlsdGVyUm93cyA9IHNpZ25hbDxGaWx0ZXJEZWZhdWx0Um93W10+KFtdKTtcbiAgcHVibGljIHJlYWRvbmx5IGZpeGVkRGF0ZXNQZXJpb2QgPSBGSVhFRF9EQVRFU19QRVJJT0Q7XG4gIHB1YmxpYyByZWFkb25seSBib3VuZFNjYWxlID0gREVGQVVMVF9CT1VORF9TQ0FMRTtcblxuICAvLyBUaGUgRGVmYXVsdCBtaW5pbXVtIGFuZCBEZWZhdWx0IG1heGltdW0gY2hlY2tzLCB0aHJvdWdoIGZzRm9ybS4gRWFjaCBmaWVsZFxuICAvLyBnZXRzIHRoZSBvdGhlciBlbmQgYXMgaXRzIHZhbGlkYXRlRGF0YSwgc28gdHlwaW5nIGluIG9uZSBjaGVja3MgdGhlIHBhaXJcbiAgLy8gYWdhaW47IGJvdW5kc0Vycm9yIHdvcmRzIHRoZSByZWZ1c2FsIGFzIHRoZSBzZXJ2ZXIgZG9lcy5cbiAgcHVibGljIHJlYWRvbmx5IG1pbkJvdW5kVmFsaWRhdG9yID0gKGNvbnRyb2w6IEFic3RyYWN0Q29udHJvbCwgbWF4OiB1bmtub3duKTogdm9pZCA9PiB7XG4gICAgdGhpcy5fdGhyb3dCb3VuZHNFcnJvcihjb250cm9sLnZhbHVlLCBtYXgpO1xuICB9O1xuXG4gIHB1YmxpYyByZWFkb25seSBtYXhCb3VuZFZhbGlkYXRvciA9IChjb250cm9sOiBBYnN0cmFjdENvbnRyb2wsIG1pbjogdW5rbm93bik6IHZvaWQgPT4ge1xuICAgIHRoaXMuX3Rocm93Qm91bmRzRXJyb3IobWluLCBjb250cm9sLnZhbHVlKTtcbiAgfTtcblxuICBwcml2YXRlIHJlYWRvbmx5IF9kYXRhOiB7IHJlcG9ydDogUmVwb3J0IH0gPSBpbmplY3QoTUFUX0RJQUxPR19EQVRBKTtcbiAgcHJpdmF0ZSByZWFkb25seSBfZGlhbG9nUmVmID0gaW5qZWN0PE1hdERpYWxvZ1JlZjxSZXBvcnRTZXR0aW5nc0NvbXBvbmVudCwgUmVwb3J0U2V0dGluZ3NSZXN1bHQ+PihNYXREaWFsb2dSZWYpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9yZXBvcnREYXRhID0gaW5qZWN0KFJlcG9ydERhdGEpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9tZXNzYWdlID0gaW5qZWN0KEZzTWVzc2FnZSk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX3Byb21wdCA9IGluamVjdChGc1Byb21wdCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2Rlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZik7XG4gIC8vIE9ubHkgYSBzZXJ2ZXIgdGhhdCByZXNvbHZlcyBhIHJlcG9ydCdzIGxvY2FsZSBvZmZlcnMgdGhlIGxvY2FsZSBsaXN0LlxuICBwcml2YXRlIHJlYWRvbmx5IF9zZXJ2ZXJIYXNMb2NhbGUgPSB0aGlzLl9kYXRhLnJlcG9ydC5lZmZlY3RpdmVMb2NhbGUgIT09IHVuZGVmaW5lZDtcbiAgLy8gVHJ1ZSBvbmNlIHRoZSBsb2NhbGUgcmVxdWVzdCBoYXMgYW5zd2VyZWQsIHdpdGggdGhlIGxpc3Qgb3IgYW4gZXJyb3IuXG4gIHByaXZhdGUgcmVhZG9ubHkgX2xvY2FsZXNTZXR0bGVkID0gc2lnbmFsKGZhbHNlKTtcbiAgLy8gVHJ1ZSBvbmNlIHRoZSBmaWx0ZXIgcm93cyBhcmUgcHVibGlzaGVkIChzZWUgX2J1aWxkRmlsdGVyUm93cykuXG4gIHByaXZhdGUgcmVhZG9ubHkgX2ZpbHRlcnNSZWFkeSA9IHNpZ25hbChmYWxzZSk7XG5cbiAgLy8gVGhlIGxvY2FsZSB0aGUgcmVwb3J0IHdvdWxkIGJlIHdyaXR0ZW4gaW46IHRoZSBzZWxlY3RlZCBvbmUgd2hlbiB0aGVcbiAgLy8gc2VydmVyIG9mZmVycyBpdCwgZWxzZSB0aGUgZGVmYXVsdCAoYSBzdG9yZWQgbG9jYWxlIGl0IG5vIGxvbmdlciBvZmZlcnNcbiAgLy8gZmFsbHMgYmFjayB0byB0aGUgZGVmYXVsdCwgYXMgaXQgZG9lcyBvbiB0aGUgc2VydmVyKS5cbiAgcHJpdmF0ZSByZWFkb25seSBfYXBwbGllZExvY2FsZSA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCBsb2NhbGVzID0gdGhpcy5sb2NhbGVzKCk7XG4gICAgY29uc3QgbG9jYWxlID0gdGhpcy5sb2NhbGUoKTtcblxuICAgIHJldHVybiBsb2NhbGVzPy5vcHRpb25zLnNvbWUoKG9wdGlvbikgPT4gb3B0aW9uLmxvY2FsZSA9PT0gbG9jYWxlKVxuICAgICAgPyBsb2NhbGVcbiAgICAgIDogbG9jYWxlcz8uZGVmYXVsdExvY2FsZSA/PyAnJztcbiAgfSk7XG5cbiAgLy8gVGhlIGN1cnJlbmN5IGEgcmVwb3J0IGluIHRoZSBhcHBsaWVkIGxvY2FsZSB1c2VzIHdoZW4gaXQgbmFtZXMgbm9uZS5cbiAgcHJpdmF0ZSByZWFkb25seSBfZGVmYXVsdEN1cnJlbmN5ID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IGxvY2FsZSA9IHRoaXMuX2FwcGxpZWRMb2NhbGUoKTtcblxuICAgIHJldHVybiB0aGlzLmxvY2FsZXMoKT8ub3B0aW9ucy5maW5kKChvcHRpb24pID0+IG9wdGlvbi5sb2NhbGUgPT09IGxvY2FsZSk/LmRlZmF1bHRDdXJyZW5jeVxuICAgICAgPz8gUkVQT1JUX0ZBTExCQUNLX0NVUlJFTkNZO1xuICB9KTtcblxuICAvLyBUaGUgY3VycmVuY3kgdGhlIHJlcG9ydCB3b3VsZCBsYWJlbCBtb25leSBpbjogdGhlIHNlbGVjdGVkIG9uZSB3aGVuIHRoZVxuICAvLyBzZXJ2ZXIgb2ZmZXJzIGl0LCBlbHNlIHRoZSBkZWZhdWx0LlxuICBwcml2YXRlIHJlYWRvbmx5IF9hcHBsaWVkQ3VycmVuY3kgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgY29uc3QgY3VycmVuY3kgPSB0aGlzLmN1cnJlbmN5KCk7XG5cbiAgICByZXR1cm4gdGhpcy5sb2NhbGVzKCk/LmN1cnJlbmNpZXMuaW5jbHVkZXMoY3VycmVuY3kpXG4gICAgICA/IGN1cnJlbmN5XG4gICAgICA6IHRoaXMuX2RlZmF1bHRDdXJyZW5jeSgpO1xuICB9KTtcblxuICBwdWJsaWMgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgY29uc3QgcmVwb3J0ID0gdGhpcy5fZGF0YS5yZXBvcnQ7XG4gICAgdGhpcy5uYW1lID0gcmVwb3J0Lm5hbWU7XG4gICAgdGhpcy5wYWdlV2lkdGggPSByZXBvcnQucGFnZVdpZHRoO1xuICAgIHRoaXMucGFnZUhlaWdodCA9IHJlcG9ydC5wYWdlSGVpZ2h0O1xuICAgIHRoaXMuaGVhZGVySGVpZ2h0ID0gcmVwb3J0LmNvbmZpZz8uaGVhZGVyRm9vdGVyPy5oZWFkZXJIZWlnaHQgPz8gMDtcbiAgICB0aGlzLmZvb3RlckhlaWdodCA9IHJlcG9ydC5jb25maWc/LmhlYWRlckZvb3Rlcj8uZm9vdGVySGVpZ2h0ID8/IDA7XG4gICAgdGhpcy50aW1lem9uZSA9IHJlcG9ydC50aW1lem9uZSA/PyByZXBvcnQuZWZmZWN0aXZlVGltZXpvbmUgPz8gJyc7XG4gICAgdGhpcy5oZWFkaW5nU2l6ZSA9IHJlcG9ydC5jb25maWc/LnN0eWxlcz8uaGVhZGluZz8uc2l6ZSA/PyBERUZBVUxUX0hFQURJTkdfU0laRTtcbiAgICB0aGlzLmxvY2FsZS5zZXQocmVwb3J0LmxvY2FsZSA/PyAnJyk7XG4gICAgdGhpcy5jdXJyZW5jeS5zZXQocmVwb3J0LmN1cnJlbmN5ID8/ICcnKTtcblxuICAgIHRoaXMuX2J1aWxkRmlsdGVyUm93cyhyZXBvcnQpO1xuXG4gICAgaWYgKHRoaXMuX3NlcnZlckhhc0xvY2FsZSkge1xuICAgICAgdGhpcy5fcmVwb3J0RGF0YS5sb2NhbGVzKClcbiAgICAgICAgLnBpcGUoXG4gICAgICAgICAgdGFwKChsb2NhbGVzKSA9PiB0aGlzLmxvY2FsZXMuc2V0KGxvY2FsZXMpKSxcbiAgICAgICAgICBjYXRjaEVycm9yKCgpID0+IG9mKG51bGwpKSxcbiAgICAgICAgICBmaW5hbGl6ZSgoKSA9PiB0aGlzLl9sb2NhbGVzU2V0dGxlZC5zZXQodHJ1ZSkpLFxuICAgICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSxcbiAgICAgICAgKVxuICAgICAgICAuc3Vic2NyaWJlKCk7XG4gICAgfVxuICB9XG5cbiAgLy8gQSBjaGFuZ2UgdG8gYSByb3cncyBEZWZhdWx0IHBlcmlvZCwgZXhjbHVkZSB0b2dnbGUgb3IgcmFuZ2UgZW5kcy4gQSBuZXdcbiAgLy8gcm93IG9iamVjdCByYXRoZXIgdGhhbiBhIG11dGF0aW9uLCBzbyB0aGUgc2lnbmFsIHNlZXMgdGhlIGNoYW5nZTsgdGhlXG4gIC8vIEBmb3IgdHJhY2tzIGdyb3VwLmlkLCBzbyB0aGUgcm93J3MgY29udHJvbHMgc3Vydml2ZSB0aGUgc3dhcC5cbiAgcHVibGljIHBhdGNoUm93KHJvdzogRmlsdGVyRGVmYXVsdFJvdywgcGF0Y2g6IFBhcnRpYWw8RmlsdGVyRGVmYXVsdFJvdz4pOiB2b2lkIHtcbiAgICB0aGlzLmZpbHRlclJvd3MudXBkYXRlKChyb3dzKSA9PiByb3dzXG4gICAgICAubWFwKChpdGVtKSA9PiAoaXRlbS5ncm91cC5pZCA9PT0gcm93Lmdyb3VwLmlkID8geyAuLi5pdGVtLCAuLi5wYXRjaCB9IDogaXRlbSkpKTtcbiAgfVxuXG4gIC8vIENvbmZpcm0gYW5kIGRlbGV0ZSBoZXJlLCB3aGlsZSB0aGUgZGlhbG9nIGlzIHN0aWxsIG9wZW4sIHRoZW4gY2xvc2Ugd2l0aFxuICAvLyBhIGBkZWxldGVkYCByZXN1bHQuIFRoZSBwYWdlIHJlYWN0cyB0byB0aGUgcmVzdWx0OyBpdCBubyBsb25nZXIgb3ducyB0aGVcbiAgLy8gcHJvbXB0IG9yIHRoZSBBUEkgY2FsbC5cbiAgcHVibGljIGRlbGV0ZSgpOiB2b2lkIHtcbiAgICB0aGlzLl9wcm9tcHQuY29uZmlybSh7XG4gICAgICB0aXRsZTogJ0RlbGV0ZSBSZXBvcnQnLFxuICAgICAgdGVtcGxhdGU6IGBEZWxldGUgXCIke3RoaXMuX2RhdGEucmVwb3J0Lm5hbWV9XCI/IFRoaXMgY2Fubm90IGJlIHVuZG9uZS5gLFxuICAgIH0pXG4gICAgICAucGlwZShcbiAgICAgICAgc3dpdGNoTWFwKCgpID0+IHRoaXMuX3JlcG9ydERhdGEuZGVsZXRlKHRoaXMuX2RhdGEucmVwb3J0LmlkKSksXG4gICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgICB0aGlzLl9tZXNzYWdlLnN1Y2Nlc3MoJ1JlcG9ydCBkZWxldGVkJyk7XG4gICAgICAgIHRoaXMuX2RpYWxvZ1JlZi5jbG9zZSh7IGFjdGlvbjogJ2RlbGV0ZWQnIH0pO1xuICAgICAgfSk7XG4gIH1cblxuICBwdWJsaWMgc2F2ZSA9ICgpID0+IHtcbiAgICBjb25zdCByZXBvcnRJZCA9IHRoaXMuX2RhdGEucmVwb3J0LmlkO1xuXG4gICAgLy8gUGVyc2lzdCB0aGUgcmVwb3J0IHNldHRpbmdzIGFuZCBlYWNoIGNoYW5nZWQgZmlsdGVyIGRlZmF1bHQgdG9nZXRoZXIsIHNvXG4gICAgLy8gdGhlIHNpbmdsZSBTYXZlIGNvdmVycyBhbGwgdGhyZWUgdGFicy4gVGhlIHJlcG9ydCByZWxvYWRzIG9uIHRoZSBgc2F2ZWRgXG4gICAgLy8gcmVzdWx0LCByZS1zZWVkaW5nIHRoZSBiYXIgZnJvbSB0aGUgbmV3IGRlZmF1bHRzLlxuICAgIGNvbnN0IHNldHRpbmdzJCA9IHRoaXMuX3JlcG9ydERhdGEudXBkYXRlKHJlcG9ydElkLCB7XG4gICAgICBuYW1lOiB0aGlzLm5hbWUsXG4gICAgICBwYWdlV2lkdGg6IHRoaXMuX3BhZ2VEaW1lbnNpb24odGhpcy5wYWdlV2lkdGgpLFxuICAgICAgcGFnZUhlaWdodDogdGhpcy5fcGFnZURpbWVuc2lvbih0aGlzLnBhZ2VIZWlnaHQpLFxuICAgICAgLi4udGhpcy5fdGltZXpvbmVTZXR0aW5nKCksXG4gICAgICAuLi5yZXBvcnRMb2NhbGVQYXRjaCh0aGlzLl9kYXRhLnJlcG9ydCwgdGhpcy5sb2NhbGUoKSwgdGhpcy5jdXJyZW5jeSgpKSxcbiAgICAgIHN0eWxlczogeyBoZWFkaW5nOiB7IHNpemU6IHRoaXMuaGVhZGluZ1NpemUgfSB9LFxuICAgICAgaGVhZGVyRm9vdGVyOiB7XG4gICAgICAgIGhlYWRlckhlaWdodDogdGhpcy5fcGFnZURpbWVuc2lvbih0aGlzLmhlYWRlckhlaWdodCkgfHwgMCxcbiAgICAgICAgZm9vdGVySGVpZ2h0OiB0aGlzLl9wYWdlRGltZW5zaW9uKHRoaXMuZm9vdGVySGVpZ2h0KSB8fCAwLFxuICAgICAgfSxcbiAgICB9KTtcblxuICAgIGNvbnN0IGRlZmF1bHRzJCA9IHRoaXMuZmlsdGVyUm93cygpXG4gICAgICAuZmlsdGVyKChyb3cpID0+IGRlZmF1bHRDaGFuZ2VkKHJvdy5ncm91cC5jb25maWc/LmRlZmF1bHQsIHRoaXMuX3Jvd0RlZmF1bHQocm93KSkpXG4gICAgICAubWFwKChyb3cpID0+IHRoaXMuX3JlcG9ydERhdGEudXBkYXRlRmlsdGVyR3JvdXAocmVwb3J0SWQsIHJvdy5ncm91cC5pZCwge1xuICAgICAgICBkZWZhdWx0OiB0aGlzLl9yb3dEZWZhdWx0KHJvdyksXG4gICAgICB9KSk7XG5cbiAgICByZXR1cm4gZm9ya0pvaW4oW3NldHRpbmdzJCwgLi4uZGVmYXVsdHMkXSlcbiAgICAgIC5waXBlKFxuICAgICAgICB0YXAoKCkgPT4ge1xuICAgICAgICAgIHRoaXMuX21lc3NhZ2Uuc3VjY2VzcygnUmVwb3J0IHNldHRpbmdzIHNhdmVkJyk7XG4gICAgICAgICAgdGhpcy5fZGlhbG9nUmVmLmNsb3NlKHsgYWN0aW9uOiAnc2F2ZWQnIH0pO1xuICAgICAgICB9KSxcbiAgICAgICk7XG4gIH07XG5cbiAgLy8gVGhlIHBhZ2UgZGltZW5zaW9uIGFzIGEgcmVhbCBudW1iZXIgZm9yIHRoZSB3aXJlLiBmc01hc2tOdW1iZXIgaGFuZHMgYmFja1xuICAvLyB0aGUgdW5tYXNrZWQgc3RyaW5nIGl0IGJ1aWx0IHdpdGggYSBmaXhlZCAnLicgcmFkaXggKHdoaWNoIGlzIHRoZSB3aG9sZVxuICAvLyBwb2ludCBvZiB0aGUgbWFzayAtIGEgbmF0aXZlIG51bWJlciBpbnB1dCBwYWludHMgdGhlIHZpZXdlcidzIGxvY2FsZVxuICAvLyBzZXBhcmF0b3IgaW5zdGVhZCksIHNvIHRoZSBjYXN0IGhlcmUgaXMgYSBzdHJhaWdodCBwYXJzZSBhbmQgbmV2ZXIgc2VlcyBhXG4gIC8vIGNvbW1hLiBUaGUgYmFja2VuZCByZWplY3RzIGFueXRoaW5nIG5vbi1udW1lcmljIHJhdGhlciB0aGFuIGNvZXJjaW5nLCBzbyBhXG4gIC8vIE5hTiBmYWlscyBsb3VkbHkgaW5zdGVhZCBvZiBzaWxlbnRseSBzdG9yaW5nIGEgd3JvbmcgcGFnZSBzaXplLlxuICBwcml2YXRlIF9wYWdlRGltZW5zaW9uKHZhbHVlOiBudW1iZXIgfCBzdHJpbmcpOiBudW1iZXIge1xuICAgIHJldHVybiB0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInID8gdmFsdWUgOiBwYXJzZUZsb2F0KHZhbHVlKTtcbiAgfVxuXG4gIC8vIFRoZSB6b25lIGZvciB0aGUgc2V0dGluZ3MgUFVULCBzZW50IG9ubHkgd2hlbiBpdCBtb3ZlcyB0aGUgcmVwb3J0IG9mZiB0aGVcbiAgLy8gem9uZSBpdCBhbHJlYWR5IHVzZXMsIHNvIGFuIHVudG91Y2hlZCBkaWFsb2cgbmV2ZXIgcGlucyBhIHJlcG9ydCB0aGF0XG4gIC8vIGZvbGxvd3MgdGhlIGFwcGxpY2F0aW9uIGRlZmF1bHQuIEEgc2VydmVyIHRvbyBvbGQgdG8gc2VuZFxuICAvLyBlZmZlY3RpdmVUaW1lem9uZSBnZXRzIHRoZSB6b25lIGV2ZXJ5IHRpbWUsIGFzIGl0IGFsd2F5cyBkaWQuXG4gIHByaXZhdGUgX3RpbWV6b25lU2V0dGluZygpOiB7IHRpbWV6b25lPzogc3RyaW5nIH0ge1xuICAgIGNvbnN0IGVmZmVjdGl2ZVRpbWV6b25lID0gdGhpcy5fZGF0YS5yZXBvcnQuZWZmZWN0aXZlVGltZXpvbmU7XG5cbiAgICByZXR1cm4gZWZmZWN0aXZlVGltZXpvbmUgPT09IHVuZGVmaW5lZCB8fCB0aGlzLnRpbWV6b25lICE9PSBlZmZlY3RpdmVUaW1lem9uZVxuICAgICAgPyB7IHRpbWV6b25lOiB0aGlzLnRpbWV6b25lIH1cbiAgICAgIDoge307XG4gIH1cblxuICAvLyBUaGUgc3RvcmVkIHZhbHVlIGFzIGl0cyBvd24gb3B0aW9uIHdoZW4gdGhlIHNlcnZlciBubyBsb25nZXIgb2ZmZXJzIGl0LCBzb1xuICAvLyB0aGUgc2VsZWN0IG5hbWVzIGl0IGluc3RlYWQgb2Ygc2hvd2luZyBibGFuay4gTGVmdCBhcyBpdCBpcywgaXQgaXMgbmV2ZXJcbiAgLy8gc2VudCAoc2VlIHJlcG9ydExvY2FsZVBhdGNoKSwgYW5kIHRoZSByZXBvcnQgcmVhZHMgdGhlIGRlZmF1bHQgbWVhbndoaWxlLlxuICBwcml2YXRlIF9zdG9yZWRPcHRpb24oXG4gICAgc3RvcmVkOiBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkLFxuICAgIG9mZmVyZWQ6IHN0cmluZ1tdLFxuICAgIGxhYmVsOiAodmFsdWU6IHN0cmluZykgPT4gc3RyaW5nLFxuICApOiBMb2NhbGVTZWxlY3RPcHRpb25bXSB7XG4gICAgcmV0dXJuIHN0b3JlZCAmJiAhb2ZmZXJlZC5pbmNsdWRlcyhzdG9yZWQpID8gW3sgdmFsdWU6IHN0b3JlZCwgbGFiZWw6IGxhYmVsKHN0b3JlZCkgfV0gOiBbXTtcbiAgfVxuXG4gIHByaXZhdGUgX3Rocm93Qm91bmRzRXJyb3IobWluOiB1bmtub3duLCBtYXg6IHVua25vd24pOiB2b2lkIHtcbiAgICBjb25zdCBlcnJvciA9IGJvdW5kc0Vycm9yKHBhcnNlRGVmYXVsdEJvdW5kKG1pbiksIHBhcnNlRGVmYXVsdEJvdW5kKG1heCkpO1xuXG4gICAgaWYgKGVycm9yKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3IpO1xuICAgIH1cbiAgfVxuXG4gIC8vIEJ1aWxkIG9uZSBlZGl0YWJsZSByb3cgcGVyIHJlcG9ydCBiYXIgZmlsdGVyIGdyb3VwIChldmVyeSBwYWdlIG9yIG9uZVxuICAvLyBwYWdlKSwgaW4gYmFyIG9yZGVyLCBzZWVkaW5nIGVhY2ggZHJhZnQgZnJvbSB0aGUgZ3JvdXAncyBzdG9yZWQgZGVmYXVsdC5cbiAgcHJpdmF0ZSBfYnVpbGRGaWx0ZXJSb3dzKHJlcG9ydDogUmVwb3J0KTogdm9pZCB7XG4gICAgY29uc3QgYnVpbHQgPSBkZWZhdWx0Um93R3JvdXBzKHJlcG9ydC5maWx0ZXJHcm91cHMpXG4gICAgICAubWFwKChncm91cCkgPT4ge1xuICAgICAgICBjb25zdCBncm91cERlZmF1bHQgPSBncm91cC5jb25maWc/LmRlZmF1bHQ7XG4gICAgICAgIC8vIE9uZSBzaGFyZWQsIHJlcGxheWVkIG9wdGlvbiBzdHJlYW0gcGVyIGdyb3VwOiB0aGUgY2hpcHMgZmV0Y2ggYW5kIHRoZVxuICAgICAgICAvLyBzdG9yZWQgZGVmYXVsdCdzIGxhYmVscyByZWFkIHRoZSBzYW1lIGxpc3QsIHNvIGl0IGlzIGZldGNoZWQgb25jZS5cbiAgICAgICAgY29uc3Qgb3B0aW9ucyQgPSBsb2FkR3JvdXBPcHRpb25zKGdyb3VwLCB0aGlzLl9yZXBvcnREYXRhLCByZXBvcnQuaWQpO1xuICAgICAgICBjb25zdCByb3cgPSB0aGlzLl9maWx0ZXJSb3cocmVwb3J0LCBncm91cCwgb3B0aW9ucyQpO1xuXG4gICAgICAgIHJldHVybiB7IHJvdywgb3B0aW9ucyQsIHZhbHVlczogZ3JvdXBEZWZhdWx0Py52YWx1ZXMgPz8gZ3JvdXBEZWZhdWx0Py5leGNsdWRlVmFsdWVzID8/IFtdIH07XG4gICAgICB9KTtcblxuICAgIGNvbnN0IHJvd3MgPSBidWlsdC5tYXAoKGVudHJ5KSA9PiBlbnRyeS5yb3cpO1xuICAgIGNvbnN0IHNlZWRlZCA9IGJ1aWx0LmZpbHRlcigoZW50cnkpID0+IGVudHJ5LnZhbHVlcy5sZW5ndGgpO1xuXG4gICAgLy8gTm90aGluZyB0byBuYW1lIOKAlCBwdWJsaXNoIGltbWVkaWF0ZWx5IHJhdGhlciB0aGFuIHdhaXRpbmcgb24gYSByZXF1ZXN0XG4gICAgLy8gbm8gcm93IG5lZWRzLlxuICAgIGlmICghc2VlZGVkLmxlbmd0aCkge1xuICAgICAgdGhpcy5fcHVibGlzaEZpbHRlclJvd3Mocm93cyk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBBIHN0b3JlZCBzZWxlY3QgZGVmYXVsdCBob2xkcyBpZHMsIHNvIGl0cyBjaGlwcyBjYW4gb25seSBiZSBuYW1lZCBvbmNlIHRoZVxuICAgIC8vIG9wdGlvbiBsaXN0IGlzIGluLiBSZXNvbHZlIGV2ZXJ5IHNlZWRlZCByb3cgZmlyc3QgYW5kIHB1Ymxpc2ggdGhlIHJvd3MgaW5cbiAgICAvLyBvbmUgZ28sIHNvIHRoZSB0YWIgbmV2ZXIgcmVuZGVycyBhIGNoaXAgc2hvd2luZyBhIHJhdyBpZC4gV2hlbiBhbiBvcHRpb25cbiAgICAvLyBsaXN0IGZhaWxzIHRvIGxvYWQsIHRoZSByb3dzIHB1Ymxpc2ggdW5yZXNvbHZlZDogZWFjaCBjaGlwIG5hbWVzIGl0cyBpZCxcbiAgICAvLyBhbmQgYW4gdW50b3VjaGVkIHJvdyBzdGlsbCBzYXZlcyB0aGUgc3RvcmVkIGRlZmF1bHQgdW5jaGFuZ2VkLlxuICAgIGZvcmtKb2luKHNlZWRlZC5tYXAoKGVudHJ5KSA9PiByZXNvbHZlT3B0aW9uVmFsdWVzKGVudHJ5Lm9wdGlvbnMkLCBlbnRyeS52YWx1ZXMpKSlcbiAgICAgIC5waXBlKFxuICAgICAgICBjYXRjaEVycm9yKCgpID0+IG9mKHNlZWRlZC5tYXAoKGVudHJ5KSA9PiBlbnRyeS52YWx1ZXMubWFwKCh2YWx1ZSkgPT4gKHsgbmFtZTogU3RyaW5nKHZhbHVlKSwgdmFsdWUgfSkpKSkpLFxuICAgICAgICB0YXAoKHJlc29sdmVkKSA9PiB7XG4gICAgICAgICAgcmVzb2x2ZWQuZm9yRWFjaCgodmFsdWVzLCBpbmRleCkgPT4gc2VlZGVkW2luZGV4XS5yb3cudmFsdWVzID0gdmFsdWVzKTtcbiAgICAgICAgICB0aGlzLl9wdWJsaXNoRmlsdGVyUm93cyhyb3dzKTtcbiAgICAgICAgfSksXG4gICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIC8vIE9uZSByb3cncyBkcmFmdCwgc2VlZGVkIGZyb20gaXRzIGdyb3VwJ3Mgc3RvcmVkIGRlZmF1bHQuIEEgc3RvcmVkIHNlbGVjdFxuICAvLyBkZWZhdWx0J3MgdmFsdWVzIGFyZSBuYW1lZCBsYXRlciwgb25jZSB0aGUgb3B0aW9uIGxpc3QgY2FycnlpbmcgdGhlaXJcbiAgLy8gbGFiZWxzIGlzIGluIChzZWUgX2J1aWxkRmlsdGVyUm93cykuXG4gIHByaXZhdGUgX2ZpbHRlclJvdyhcbiAgICByZXBvcnQ6IFJlcG9ydCxcbiAgICBncm91cDogUmVwb3J0RmlsdGVyR3JvdXAsXG4gICAgb3B0aW9ucyQ6IE9ic2VydmFibGU8eyBuYW1lOiBzdHJpbmc7IHZhbHVlOiB1bmtub3duIH1bXT4sXG4gICk6IEZpbHRlckRlZmF1bHRSb3cge1xuICAgIGNvbnN0IGdyb3VwRGVmYXVsdCA9IGdyb3VwLmNvbmZpZz8uZGVmYXVsdDtcblxuICAgIHJldHVybiB7XG4gICAgICBncm91cCxcbiAgICAgIGxhYmVsOiBkZWZhdWx0Um93TGFiZWwoZ3JvdXAsIHJlcG9ydC5wYWdlcyksXG4gICAgICBwZXJpb2Q6IGRlZmF1bHRQZXJpb2QoZ3JvdXBEZWZhdWx0KSxcbiAgICAgIHBlcmlvZE9wdGlvbnM6IGRlZmF1bHRQZXJpb2RPcHRpb25zKHJlbGF0aXZlTGFiZWwsIGdyb3VwRGVmYXVsdD8ucmVsYXRpdmUgPz8gbnVsbCksXG4gICAgICBzdGFydDogZGF0ZUZyb21Cb3VuZChncm91cERlZmF1bHQ/LnN0YXJ0KSxcbiAgICAgIGVuZDogZGF0ZUZyb21Cb3VuZChncm91cERlZmF1bHQ/LmVuZCksXG4gICAgICB2YWx1ZXM6IFtdLFxuICAgICAgZXhjbHVkZTogISFncm91cERlZmF1bHQ/LmV4Y2x1ZGVWYWx1ZXM/Lmxlbmd0aCxcbiAgICAgIC8vIEFuIG9sZGVyIHNlcnZlciBsaXN0cyBubyBmZWF0dXJlcywgYW5kIGxlYXZlcyBubyB2YWx1ZXMgb3V0LlxuICAgICAgc2hvd0V4Y2x1ZGU6IHNob3dFeGNsdWRlVG9nZ2xlKGdyb3VwLCByZXBvcnQudmlld2VyRmVhdHVyZXMpLFxuICAgICAgdmFsdWU6IGdyb3VwRGVmYXVsdD8udmFsdWUgPz8gJycsXG4gICAgICBtaW46IGdyb3VwRGVmYXVsdD8ubWluID8/IG51bGwsXG4gICAgICBtYXg6IGdyb3VwRGVmYXVsdD8ubWF4ID8/IG51bGwsXG4gICAgICAvLyBmcy1hdXRvY29tcGxldGUtY2hpcHMgZmV0Y2g6IHRoZSBncm91cCdzIGRpc3RpbmN0IG9wdGlvbnMsIG5hbWUtZmlsdGVyZWQuXG4gICAgICAvLyBTYW1lIGxvYWRlciB0aGUgcmVwb3J0IGJhciB1c2VzLCBzbyB0aGUgdHdvIG5ldmVyIGRyaWZ0LlxuICAgICAgZmV0Y2g6IChrZXl3b3JkPzogc3RyaW5nKSA9PiBtYXRjaE9wdGlvbnMob3B0aW9ucyQsIGtleXdvcmQpLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIF9wdWJsaXNoRmlsdGVyUm93cyhyb3dzOiBGaWx0ZXJEZWZhdWx0Um93W10pOiB2b2lkIHtcbiAgICB0aGlzLmZpbHRlclJvd3Muc2V0KHJvd3MpO1xuICAgIHRoaXMuX2ZpbHRlcnNSZWFkeS5zZXQodHJ1ZSk7XG4gIH1cblxuICAvLyBUaGUgZHJhZnQgZGVmYXVsdCBub3JtYWxpemVkIHRvIHRoZSB3aXJlIHNoYXBlIGZvciB0aGlzIHJvdydzIHR5cGUsIG9yIG51bGxcbiAgLy8gd2hlbiBlbXB0eSAod2hpY2ggY2xlYXJzIHRoZSBzdG9yZWQgZGVmYXVsdCkuXG4gIHByaXZhdGUgX3Jvd0RlZmF1bHQocm93OiBGaWx0ZXJEZWZhdWx0Um93KTogRmlsdGVyR3JvdXBEZWZhdWx0IHwgbnVsbCB7XG4gICAgc3dpdGNoIChyb3cuZ3JvdXAudHlwZSkge1xuICAgICAgY2FzZSAnZGF0ZVJhbmdlJzpcbiAgICAgICAgcmV0dXJuIGRhdGVSYW5nZURlZmF1bHQocm93LnBlcmlvZCwgZGF0ZVRvQm91bmQocm93LnN0YXJ0KSwgZGF0ZVRvQm91bmQocm93LmVuZCkpO1xuXG4gICAgICBjYXNlICdzZWxlY3QnOlxuICAgICAgICAvLyBBIGhpZGRlbiB0b2dnbGUgbGVhdmVzIG5vdGhpbmcgb3V0LlxuICAgICAgICByZXR1cm4gc2VsZWN0RGVmYXVsdChyb3cudmFsdWVzLm1hcCgob3B0aW9uKSA9PiBvcHRpb24udmFsdWUpLCByb3cuc2hvd0V4Y2x1ZGUgJiYgcm93LmV4Y2x1ZGUpO1xuXG4gICAgICBjYXNlICdudW1iZXJSYW5nZSc6XG4gICAgICAgIHJldHVybiBudW1iZXJSYW5nZURlZmF1bHQocm93Lm1pbiwgcm93Lm1heCk7XG5cbiAgICAgIGNhc2UgJ2tleXdvcmQnOlxuICAgICAgZGVmYXVsdDoge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IHJvdy52YWx1ZS50cmltKCk7XG5cbiAgICAgICAgcmV0dXJuIHZhbHVlID8geyB2YWx1ZSB9IDogbnVsbDtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxufVxuIiwiPGZvcm1cbiAgICBmc0Zvcm1cbiAgICBbc3VibWl0XT1cInNhdmVcIj5cbiAgPGZzLWRpYWxvZz5cbiAgICA8aDEgbWF0LWRpYWxvZy10aXRsZT5cbiAgICAgIFJlcG9ydCBTZXR0aW5nc1xuICAgIDwvaDE+XG4gICAgPG1hdC1kaWFsb2ctY29udGVudD5cbiAgICAgIDwhLS0gT25lIHNrZWxldG9uIG92ZXIgdGhlIHdob2xlIGJvZHkgdW50aWwgdGhlIGxvY2FsZSBsaXN0IGlzIGluLiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgKmZzU2tlbGV0b25Gb3JtPVwicmVhZHkoKSB8fCBudWxsXCI+XG4gICAgICAgIDxtYXQtdGFiLWdyb3VwIFsoc2VsZWN0ZWQpXT1cInNlbGVjdGVkVGFiXCI+XG4gICAgICAgICAgPG1hdC10YWJcbiAgICAgICAgICAgICAgbGFiZWw9XCJTZXR0aW5nc1wiXG4gICAgICAgICAgICAgIG5hbWU9XCJzZXR0aW5nc1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZzLWNvbHVtbiB0YWItYm9keVwiPlxuICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgIE5hbWVcbiAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cIm5hbWVcIlxuICAgICAgICAgICAgICAgICAgbmFtZT1cIm5hbWVcIlxuICAgICAgICAgICAgICAgICAgW2ZzRm9ybVJlcXVpcmVkXT1cInRydWVcIj5cbiAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgPCEtLVxuICAgICAgICAgICAgICAgIFRoZSBwYWdlLCB0eXBlZCBpbiBpbmNoZXMuIE9yaWVudGF0aW9uIGlzIG5vdCBhc2tlZCBmb3IgYmVjYXVzZSBpdFxuICAgICAgICAgICAgICAgIGlzIG5vdCBhbiBpbmRlcGVuZGVudCBjaG9pY2UgLSBhIHBhZ2Ugd2lkZXIgdGhhbiBpdCBpcyB0YWxsIElTXG4gICAgICAgICAgICAgICAgbGFuZHNjYXBlIC0gc28gdGhlIHR3byBudW1iZXJzIHNheSBldmVyeXRoaW5nIHRoZXJlIGlzIHRvIHNheS5cbiAgICAgICAgICAgICAgLS0+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmcy1yb3cuZ2FwLXNtLmFsaWduLXN0YXJ0XCI+XG4gICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZnMtZmxleFwiPlxuICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgV2lkdGhcbiAgICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICBmc01hc2tOdW1iZXJcbiAgICAgICAgICAgICAgICAgICAgICBbc2NhbGVdPVwiMVwiXG4gICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJwYWdlV2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICAgIG5hbWU9XCJwYWdlV2lkdGhcIlxuICAgICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1SZXF1aXJlZF09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICBbZnNGb3JtTWluXT1cInBhZ2VEaW1lbnNpb25NaW5cIlxuICAgICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1NYXhdPVwicGFnZURpbWVuc2lvbk1heFwiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBtYXRUZXh0U3VmZml4PlxuICAgICAgICAgICAgICAgICAgICBpbmNoZXNcbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZnMtZmxleFwiPlxuICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgSGVpZ2h0XG4gICAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICAgICAgZnNNYXNrTnVtYmVyXG4gICAgICAgICAgICAgICAgICAgICAgW3NjYWxlXT1cIjFcIlxuICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwicGFnZUhlaWdodFwiXG4gICAgICAgICAgICAgICAgICAgICAgbmFtZT1cInBhZ2VIZWlnaHRcIlxuICAgICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1SZXF1aXJlZF09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICBbZnNGb3JtTWluXT1cInBhZ2VEaW1lbnNpb25NaW5cIlxuICAgICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1NYXhdPVwicGFnZURpbWVuc2lvbk1heFwiPlxuICAgICAgICAgICAgICAgICAgPGRpdiBtYXRUZXh0U3VmZml4PlxuICAgICAgICAgICAgICAgICAgICBpbmNoZXNcbiAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICA8IS0tXG4gICAgICAgICAgICAgICAgSG93IGRlZXAgdGhlIGhlYWRlciBhbmQgZm9vdGVyIGJhbmRzIGFyZS4gVGhlaXIgY29udGVudCBpcyBlZGl0ZWRcbiAgICAgICAgICAgICAgICBvbiB0aGUgY2FudmFzIChFZGl0IGxheW91dCDihpIgSGVhZGVyICYgZm9vdGVyKTsgdGhlc2UgcmVzZXJ2ZSB0aGVcbiAgICAgICAgICAgICAgICBzcGFjZSBmb3IgaXQsIGFuZCAwIG1lYW5zIG5vIGJhbmQuXG4gICAgICAgICAgICAgIC0tPlxuICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJmdWxsLXdpZHRoXCI+XG4gICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgIEhlYWRlciBoZWlnaHRcbiAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgICAgZnNNYXNrTnVtYmVyXG4gICAgICAgICAgICAgICAgICAgIFtzY2FsZV09XCIyXCJcbiAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJoZWFkZXJIZWlnaHRcIlxuICAgICAgICAgICAgICAgICAgICBuYW1lPVwiaGVhZGVySGVpZ2h0XCJcbiAgICAgICAgICAgICAgICAgICAgW2ZzRm9ybU1pbl09XCIwXCJcbiAgICAgICAgICAgICAgICAgICAgW2ZzRm9ybU1heF09XCJoZWFkZXJGb290ZXJNYXhcIj5cbiAgICAgICAgICAgICAgICA8ZGl2IG1hdFRleHRTdWZmaXg+XG4gICAgICAgICAgICAgICAgICBpbmNoZXNcbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZnVsbC13aWR0aFwiPlxuICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICBGb290ZXIgaGVpZ2h0XG4gICAgICAgICAgICAgICAgPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICAgIGZzTWFza051bWJlclxuICAgICAgICAgICAgICAgICAgICBbc2NhbGVdPVwiMlwiXG4gICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwiZm9vdGVySGVpZ2h0XCJcbiAgICAgICAgICAgICAgICAgICAgbmFtZT1cImZvb3RlckhlaWdodFwiXG4gICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1NaW5dPVwiMFwiXG4gICAgICAgICAgICAgICAgICAgIFtmc0Zvcm1NYXhdPVwiaGVhZGVyRm9vdGVyTWF4XCI+XG4gICAgICAgICAgICAgICAgPGRpdiBtYXRUZXh0U3VmZml4PlxuICAgICAgICAgICAgICAgICAgaW5jaGVzXG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgIDxmcy1haS1yZXBvcnQtdGltZXpvbmUtc2VsZWN0IFsodGltZXpvbmUpXT1cInRpbWV6b25lXCI+PC9mcy1haS1yZXBvcnQtdGltZXpvbmUtc2VsZWN0PlxuICAgICAgICAgICAgICA8IS0tXG4gICAgICAgICAgICAgICAgSG93IG51bWJlcnMgYW5kIGRhdGVzIGFyZSB3cml0dGVuIChmb3JtYXR0aW5nIG9ubHk6IG5vIHRleHQgaXNcbiAgICAgICAgICAgICAgICB0cmFuc2xhdGVkKSBhbmQgd2hpY2ggY3VycmVuY3kgbW9uZXkgaXMgbGFiZWxlZCBpbi4gSGlkZGVuIG9uIGFcbiAgICAgICAgICAgICAgICBzZXJ2ZXIgdG9vIG9sZCB0byByZXNvbHZlIGEgcmVwb3J0J3MgbG9jYWxlLlxuICAgICAgICAgICAgICAtLT5cbiAgICAgICAgICAgICAgQGlmIChsb2NhbGVzKCkpIHtcbiAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJmdWxsLXdpZHRoXCI+XG4gICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICBMb2NhbGVcbiAgICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgPG1hdC1zZWxlY3RcbiAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJsb2NhbGUoKVwiXG4gICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwibG9jYWxlLnNldCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICBuYW1lPVwibG9jYWxlXCI+XG4gICAgICAgICAgICAgICAgICAgIEBmb3IgKG9wdGlvbiBvZiBsb2NhbGVPcHRpb25zKCk7IHRyYWNrIG9wdGlvbi52YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIFt2YWx1ZV09XCJvcHRpb24udmFsdWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7IG9wdGlvbi5sYWJlbCB9fVxuICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LW9wdGlvbj5cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgPC9tYXQtc2VsZWN0PlxuICAgICAgICAgICAgICAgICAgPG1hdC1oaW50PlxuICAgICAgICAgICAgICAgICAgICB7eyBmb3JtYXRFeGFtcGxlKCkgfX1cbiAgICAgICAgICAgICAgICAgIDwvbWF0LWhpbnQ+XG4gICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJmdWxsLXdpZHRoXCI+XG4gICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICBDdXJyZW5jeVxuICAgICAgICAgICAgICAgICAgPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICA8bWF0LXNlbGVjdFxuICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cImN1cnJlbmN5KClcIlxuICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cImN1cnJlbmN5LnNldCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAgICAgICBuYW1lPVwiY3VycmVuY3lcIj5cbiAgICAgICAgICAgICAgICAgICAgQGZvciAob3B0aW9uIG9mIGN1cnJlbmN5T3B0aW9ucygpOyB0cmFjayBvcHRpb24udmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8bWF0LW9wdGlvbiBbdmFsdWVdPVwib3B0aW9uLnZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICB7eyBvcHRpb24ubGFiZWwgfX1cbiAgICAgICAgICAgICAgICAgICAgICA8L21hdC1vcHRpb24+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIDwvbWF0LXNlbGVjdD5cbiAgICAgICAgICAgICAgICAgIDxtYXQtaGludD5cbiAgICAgICAgICAgICAgICAgICAgTmFtZXMgdGhlIGN1cnJlbmN5IGFtb3VudHMgYXJlIGluOyBpdCBkb2VzIG5vdCBjb252ZXJ0IHRoZW0uXG4gICAgICAgICAgICAgICAgICA8L21hdC1oaW50PlxuICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvbWF0LXRhYj5cbiAgICAgICAgICA8bWF0LXRhYlxuICAgICAgICAgICAgICBsYWJlbD1cIlN0eWxlc1wiXG4gICAgICAgICAgICAgIG5hbWU9XCJzdHlsZXNcIj5cbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJmcy1jb2x1bW4gdGFiLWJvZHlcIj5cbiAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICBIZWFkaW5nIFNpemVcbiAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICA8aW5wdXRcbiAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICB0eXBlPVwibnVtYmVyXCJcbiAgICAgICAgICAgICAgICAgIHN0ZXA9XCIxXCJcbiAgICAgICAgICAgICAgICAgIG1pbj1cIjZcIlxuICAgICAgICAgICAgICAgICAgbWF4PVwiOTZcIlxuICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJoZWFkaW5nU2l6ZVwiXG4gICAgICAgICAgICAgICAgICBuYW1lPVwiaGVhZGluZ1NpemVcIlxuICAgICAgICAgICAgICAgICAgW2ZzRm9ybU1pbl09XCI2XCJcbiAgICAgICAgICAgICAgICAgIFtmc0Zvcm1NYXhdPVwiOTZcIj5cbiAgICAgICAgICAgICAgICA8c3BhbiBtYXRUZXh0U3VmZml4PlxuICAgICAgICAgICAgICAgICAgcHRcbiAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgPG1hdC1oaW50PlxuICAgICAgICAgICAgICAgICAgQXBwbGllcyB0byBjb21wb25lbnQgdGl0bGVzLiBQb2ludHMgbWFwIDE6MSB0byBQREYgYW5kIFBvd2VyUG9pbnQuXG4gICAgICAgICAgICAgICAgPC9tYXQtaGludD5cbiAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvbWF0LXRhYj5cbiAgICAgICAgICA8bWF0LXRhYlxuICAgICAgICAgICAgICBsYWJlbD1cIkZpbHRlcnNcIlxuICAgICAgICAgICAgICBuYW1lPVwiZmlsdGVyc1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImZzLWNvbHVtbiB0YWItYm9keVwiPlxuICAgICAgICAgICAgICBAaWYgKGZpbHRlclJvd3MoKS5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgICA8IS0tIE9uZSBzZWN0aW9uIHBlciByZXBvcnQgYmFyIGZpbHRlcjogaXRzIGhlYWRpbmcsIHRoZW4gaXRzXG4gICAgICAgICAgICAgICAgICAgICBkZWZhdWx0LCBvbmUgZmllbGQgcGVyIHJvdy4gLS0+XG4gICAgICAgICAgICAgICAgQGZvciAocm93IG9mIGZpbHRlclJvd3MoKTsgdHJhY2sgcm93Lmdyb3VwLmlkKSB7XG4gICAgICAgICAgICAgICAgICA8aDM+XG4gICAgICAgICAgICAgICAgICAgIHt7IHJvdy5sYWJlbCB9fVxuICAgICAgICAgICAgICAgICAgPC9oMz5cbiAgICAgICAgICAgICAgICAgIEBzd2l0Y2ggKHJvdy5ncm91cC50eXBlKSB7XG4gICAgICAgICAgICAgICAgICAgIEBjYXNlICgnZGF0ZVJhbmdlJykge1xuICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImZ1bGwtd2lkdGhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIERlZmF1bHQgcGVyaW9kXG4gICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtc2VsZWN0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwicm93LnBlcmlvZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwicGF0Y2hSb3cocm93LCB7IHBlcmlvZDogJGV2ZW50IH0pXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmFtZV09XCIncGVyaW9kJyArIHJvdy5ncm91cC5pZFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICBAZm9yIChvcHRpb24gb2Ygcm93LnBlcmlvZE9wdGlvbnM7IHRyYWNrIG9wdGlvbi52YWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtb3B0aW9uIFt2YWx1ZV09XCJvcHRpb24udmFsdWVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IG9wdGlvbi5uYW1lIH19XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtb3B0aW9uPlxuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1zZWxlY3Q+XG4gICAgICAgICAgICAgICAgICAgICAgPC9tYXQtZm9ybS1maWVsZD5cbiAgICAgICAgICAgICAgICAgICAgICBAaWYgKHJvdy5wZXJpb2QgPT09IGZpeGVkRGF0ZXNQZXJpb2QpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtZm9ybS1maWVsZCBjbGFzcz1cImZ1bGwtd2lkdGhcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEZWZhdWx0IGZyb21cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZnNEYXRlUGlja2VyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgWyhuZ01vZGVsKV09XCJyb3cuc3RhcnRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuYW1lXT1cIidzdGFydCcgKyByb3cuZ3JvdXAuaWRcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJmdWxsLXdpZHRoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxtYXQtbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgRGVmYXVsdCB0b1xuICAgICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmc0RhdGVQaWNrZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInJvdy5lbmRcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuYW1lXT1cIidlbmQnICsgcm93Lmdyb3VwLmlkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBAY2FzZSAoJ3NlbGVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8ZnMtbGFiZWwtZmllbGQgY2xhc3M9XCJmdWxsLXdpZHRoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8ZnMtYXV0b2NvbXBsZXRlLWNoaXBzXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJmdWxsLXdpZHRoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYWJlbD1cIkRlZmF1bHQgdmFsdWVzXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbZmV0Y2hdPVwicm93LmZldGNoXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbKG5nTW9kZWwpXT1cInJvdy52YWx1ZXNcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuYW1lXT1cIid2YWx1ZXMnICsgcm93Lmdyb3VwLmlkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbXVsdGlwbGVdPVwidHJ1ZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2ZldGNoT25Gb2N1c109XCJ0cnVlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnNBdXRvY29tcGxldGVDaGlwc1RlbXBsYXRlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQtb2JqZWN0PVwib2JqZWN0XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgb2JqZWN0Lm5hbWUgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvZnMtYXV0b2NvbXBsZXRlLWNoaXBzPlxuICAgICAgICAgICAgICAgICAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgICAgICAgICAgICAgICAgQGlmIChyb3cuc2hvd0V4Y2x1ZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIDxmcy1sYWJlbC1maWVsZD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1zbGlkZS10b2dnbGVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuZ01vZGVsXT1cInJvdy5leGNsdWRlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cInBhdGNoUm93KHJvdywgeyBleGNsdWRlOiAkZXZlbnQgfSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW25hbWVdPVwiJ2V4Y2x1ZGUnICsgcm93Lmdyb3VwLmlkXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgRXhjbHVkZSB0aGVzZSB2YWx1ZXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgPC9tYXQtc2xpZGUtdG9nZ2xlPlxuICAgICAgICAgICAgICAgICAgICAgICAgPC9mcy1sYWJlbC1maWVsZD5cbiAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgQGNhc2UgKCdudW1iZXJSYW5nZScpIHtcbiAgICAgICAgICAgICAgICAgICAgICA8IS0tIGZzTWFza051bWJlciBoYW5kcyBiYWNrIHRleHQ7IHRoZSBjaGVjayBhbmQgdGhlIHNhdmVcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlYWQgaXQgdGhyb3VnaCBwYXJzZURlZmF1bHRCb3VuZCwgc28gMCBpcyBrZXB0LiAtLT5cbiAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJmdWxsLXdpZHRoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICBEZWZhdWx0IG1pbmltdW1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF0SW5wdXRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmc01hc2tOdW1iZXJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2lnbmVkXT1cInRydWVcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtzY2FsZV09XCJib3VuZFNjYWxlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmdNb2RlbF09XCJyb3cubWluXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJwYXRjaFJvdyhyb3csIHsgbWluOiAkZXZlbnQgfSlcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFtuYW1lXT1cIidtaW4nICsgcm93Lmdyb3VwLmlkXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdmFsaWRhdGVdPVwibWluQm91bmRWYWxpZGF0b3JcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFt2YWxpZGF0ZURhdGFdPVwicm93Lm1heFwiPlxuICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgICAgICAgPG1hdC1mb3JtLWZpZWxkIGNsYXNzPVwiZnVsbC13aWR0aFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPG1hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgRGVmYXVsdCBtYXhpbXVtXG4gICAgICAgICAgICAgICAgICAgICAgICA8L21hdC1sYWJlbD5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxpbnB1dFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZnNNYXNrTnVtYmVyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3NpZ25lZF09XCJ0cnVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbc2NhbGVdPVwiYm91bmRTY2FsZVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW25nTW9kZWxdPVwicm93Lm1heFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwicGF0Y2hSb3cocm93LCB7IG1heDogJGV2ZW50IH0pXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbbmFtZV09XCInbWF4JyArIHJvdy5ncm91cC5pZFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbGlkYXRlXT1cIm1heEJvdW5kVmFsaWRhdG9yXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBbdmFsaWRhdGVEYXRhXT1cInJvdy5taW5cIj5cbiAgICAgICAgICAgICAgICAgICAgICA8L21hdC1mb3JtLWZpZWxkPlxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIEBkZWZhdWx0IHtcbiAgICAgICAgICAgICAgICAgICAgICA8bWF0LWZvcm0tZmllbGQgY2xhc3M9XCJmdWxsLXdpZHRoXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgICBEZWZhdWx0IHRleHRcbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWxhYmVsPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgIG1hdElucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgIFsobmdNb2RlbCldPVwicm93LnZhbHVlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgW25hbWVdPVwiJ3ZhbHVlJyArIHJvdy5ncm91cC5pZFwiPlxuICAgICAgICAgICAgICAgICAgICAgIDwvbWF0LWZvcm0tZmllbGQ+XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIH0gQGVsc2Uge1xuICAgICAgICAgICAgICAgIDxmcy1tZXNzYWdlLWluZm8+XG4gICAgICAgICAgICAgICAgICBUaGlzIHJlcG9ydCBoYXMgbm8gcmVwb3J0IGJhciBmaWx0ZXJzIHlldC4gQWRkIGEgZmlsdGVyIHRvIGFcbiAgICAgICAgICAgICAgICAgIGNvbXBvbmVudCAoaXRzIHNldHRpbmdzIOKGkiBGaWx0ZXJzKSBhbmQgc2hvdyBpdCBpbiB0aGUgcmVwb3J0IGJhcixcbiAgICAgICAgICAgICAgICAgIHRoZW4gc2V0IGl0cyBkZWZhdWx0IGhlcmUuXG4gICAgICAgICAgICAgICAgPC9mcy1tZXNzYWdlLWluZm8+XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvbWF0LXRhYj5cbiAgICAgICAgPC9tYXQtdGFiLWdyb3VwPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9tYXQtZGlhbG9nLWNvbnRlbnQ+XG4gICAgPG1hdC1kaWFsb2ctYWN0aW9ucz5cbiAgICAgIDxmcy1mb3JtLWRpYWxvZy1hY3Rpb25zPlxuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgICAgIG1hdC1idXR0b25cbiAgICAgICAgICAgIGNvbG9yPVwid2FyblwiXG4gICAgICAgICAgICAoY2xpY2spPVwiZGVsZXRlKClcIj5cbiAgICAgICAgICBEZWxldGVcbiAgICAgICAgPC9idXR0b24+XG4gICAgICA8L2ZzLWZvcm0tZGlhbG9nLWFjdGlvbnM+XG4gICAgPC9tYXQtZGlhbG9nLWFjdGlvbnM+XG4gIDwvZnMtZGlhbG9nPlxuPC9mb3JtPiJdfQ==
|