@firestitch/report 18.9.0 → 18.10.1
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/report-canvas/report-canvas.component.d.ts +3 -0
- package/app/reports/components/report-component/report-component.component.d.ts +35 -1
- package/app/reports/components/report-view-picker/report-view-picker.component.d.ts +21 -0
- package/app/reports/data/report.data.d.ts +20 -7
- package/app/reports/dialogs/component-settings/component-settings.component.d.ts +18 -3
- package/app/reports/dialogs/report-settings/report-settings.component.d.ts +45 -8
- 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/export/report-export-collector.service.d.ts +13 -4
- package/app/reports/export/report-filter-lines.d.ts +18 -0
- package/app/reports/filter-settings-rules.d.ts +37 -0
- package/app/reports/format.d.ts +0 -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-group-changes.interface.d.ts +7 -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-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 +27 -16
- package/app/reports/interfaces/tile-load-result.interface.d.ts +4 -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 +20 -21
- package/app/reports/report-tile.d.ts +2 -0
- package/app/reports/report-view-config.d.ts +34 -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 -11
- package/app/reports/services/report-view.service.d.ts +39 -0
- package/app/reports/tile-data-state.d.ts +7 -0
- package/app/reports/tile-loads.d.ts +4 -0
- package/app/reports/views/report/fs-ai-report.component.d.ts +10 -8
- 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 +26 -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 +11 -5
- package/esm2022/app/reports/components/report-canvas/report-canvas.component.mjs +56 -40
- package/esm2022/app/reports/components/report-component/report-component.component.mjs +261 -65
- package/esm2022/app/reports/components/report-view-picker/report-view-picker.component.mjs +115 -0
- package/esm2022/app/reports/data/report.data.mjs +94 -14
- package/esm2022/app/reports/dialogs/component-settings/component-settings.component.mjs +106 -51
- package/esm2022/app/reports/dialogs/report-settings/report-settings.component.mjs +248 -104
- 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/export/report-export-collector.service.mjs +187 -117
- package/esm2022/app/reports/export/report-filter-lines.mjs +235 -0
- package/esm2022/app/reports/export/report-pdf.service.mjs +12 -7
- package/esm2022/app/reports/export/report-pptx.service.mjs +18 -14
- package/esm2022/app/reports/filter-settings-rules.mjs +290 -0
- package/esm2022/app/reports/format.mjs +2 -22
- 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-group-changes.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-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/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 +263 -72
- package/esm2022/app/reports/report-tile.mjs +12 -0
- package/esm2022/app/reports/report-view-config.mjs +587 -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 +668 -210
- package/esm2022/app/reports/services/report-view.service.mjs +218 -0
- package/esm2022/app/reports/tile-data-state.mjs +127 -0
- package/esm2022/app/reports/tile-loads.mjs +38 -0
- package/esm2022/app/reports/views/report/fs-ai-report.component.mjs +194 -127
- package/esm2022/app/reports/views/report/report.component.mjs +112 -29
- package/esm2022/public_api.mjs +23 -1
- package/fesm2022/{firestitch-report-echarts-DBMOHmBF.mjs → firestitch-report-echarts-DHEH_K_q.mjs} +2 -2
- package/fesm2022/{firestitch-report-echarts-DBMOHmBF.mjs.map → firestitch-report-echarts-DHEH_K_q.mjs.map} +1 -1
- package/fesm2022/{firestitch-report-firestitch-report-CqbXT1gh.mjs → firestitch-report-firestitch-report-ZcHTnNKq.mjs} +8222 -4447
- package/fesm2022/firestitch-report-firestitch-report-ZcHTnNKq.mjs.map +1 -0
- package/fesm2022/firestitch-report.mjs +1 -1
- package/package.json +1 -1
- package/public_api.d.ts +22 -0
- package/app/reports/report-url-state.d.ts +0 -19
- package/esm2022/app/reports/report-url-state.mjs +0 -189
- package/fesm2022/firestitch-report-firestitch-report-CqbXT1gh.mjs.map +0 -1
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { ItemType } from '@firestitch/filter';
|
|
1
|
+
import { ItemType, getExcludeName } from '@firestitch/filter';
|
|
2
2
|
import { format, parseISO } from 'date-fns';
|
|
3
3
|
import { of } from 'rxjs';
|
|
4
4
|
import { map, shareReplay } from 'rxjs/operators';
|
|
5
|
-
import {
|
|
5
|
+
import { filterLineText, matchLineText } from './export/report-filter-lines';
|
|
6
|
+
import { DAY_SHORT, formatLocalDate, resolveFormatContext } from './format';
|
|
6
7
|
import { GRANULARITY_OPTIONS, } from './interfaces/report.interface';
|
|
8
|
+
import { offersExclude } from './report-viewer-features';
|
|
7
9
|
// A date-range boundary as the picked LOCAL calendar day (no time, no tz).
|
|
8
10
|
// Date-range filters are calendar-day semantics, so the boundary must carry
|
|
9
11
|
// only Y-M-D — never a timezone-bearing instant the backend would shift.
|
|
@@ -67,30 +69,45 @@ export function relativeLabel(relative) {
|
|
|
67
69
|
// query values back into per-group FilterGroupValues. Shared by the report-bar
|
|
68
70
|
// fs-filter and the per-component fs-filter so both render through the same
|
|
69
71
|
// library and write into ReportFilterStateService identically. Items are named
|
|
70
|
-
//
|
|
71
|
-
//
|
|
72
|
-
|
|
73
|
-
// The query key fs-filter uses for a group's item(s), and the report URL's key
|
|
74
|
-
// for the group's value (report-url-state.ts). One naming for both.
|
|
75
|
-
export function groupItemName(group) {
|
|
76
|
-
return `${GROUP_PARAM_PREFIX}${group.id}`;
|
|
77
|
-
}
|
|
72
|
+
// by the group's id (groupItemName), so the query keys map straight back to
|
|
73
|
+
// the group. A report never puts these keys in the browser URL: fs-filter's
|
|
74
|
+
// own query-param syncing is off in every report bar.
|
|
78
75
|
// The query key for the report's group-by control. Fixed rather than derived
|
|
79
76
|
// from an id because a report has exactly one — and it is NOT a filter group,
|
|
80
77
|
// so it is read straight off the change query instead of through
|
|
81
|
-
// groupValuesFromQuery.
|
|
82
|
-
//
|
|
83
|
-
// request's `state.frequency`.
|
|
78
|
+
// groupValuesFromQuery. The grain travels to the server as the data request's
|
|
79
|
+
// `state.frequency`.
|
|
84
80
|
export const GROUP_BY_ITEM = 'groupBy';
|
|
81
|
+
// The word before a group's id in the name of its fs-filter item (filter12).
|
|
82
|
+
const ITEM_NAME_WORD = 'filter';
|
|
83
|
+
// The query key of one end of an fs-filter range item: the item's name and
|
|
84
|
+
// the end with its first letter upper-cased (fs-filter's getRangeName), so
|
|
85
|
+
// filter12 gives filter12Min and filter12From.
|
|
86
|
+
export function itemRangeName(name, end) {
|
|
87
|
+
return `${name}${end.charAt(0).toUpperCase()}${end.slice(1)}`;
|
|
88
|
+
}
|
|
89
|
+
// The name of a group's fs-filter item: 'filter' and the group's id. The id
|
|
90
|
+
// never changes, so neither a new label nor a new name moves a bar's keys,
|
|
91
|
+
// and no item name can take another item's (groupBy, match, listSearch).
|
|
92
|
+
export function groupItemName(group) {
|
|
93
|
+
return `${ITEM_NAME_WORD}${group.id}`;
|
|
94
|
+
}
|
|
95
|
+
// The label a group's chip shows: its own, else its first member's column.
|
|
96
|
+
function groupLabel(group) {
|
|
97
|
+
return group.label || group.filters?.[0]?.filterColumn || '';
|
|
98
|
+
}
|
|
85
99
|
// A select group's distinct options, as { name, value } pairs. The server sends
|
|
86
100
|
// { value, label }: the value is what the filter matches on (an entity's stable
|
|
87
101
|
// id) and the label is what the viewer reads — so a renamed entity keeps its id
|
|
88
102
|
// and simply shows its new name here. Options come from the first member filter
|
|
89
103
|
// that declares them — members are the same data point, so any member's list
|
|
90
104
|
// serves the group. The list is fetched once (the server caps it) and replayed
|
|
91
|
-
// (shareReplay), so repeated reads never refetch.
|
|
92
|
-
//
|
|
93
|
-
//
|
|
105
|
+
// (shareReplay), so repeated reads never refetch. This is the full list, never
|
|
106
|
+
// narrowed by other filters: the report-settings default picker reads it (an
|
|
107
|
+
// author sets a default against the whole list), and so does the export's
|
|
108
|
+
// filter wording for a pick the bar has not named. The bars read
|
|
109
|
+
// ReportFilterOptionsService instead. Returns an empty list when no member
|
|
110
|
+
// provides options.
|
|
94
111
|
export function loadGroupOptions(group, reportData, reportId) {
|
|
95
112
|
const optionFilter = (group.filters ?? []).find((member) => member.hasOptions);
|
|
96
113
|
if (!optionFilter) {
|
|
@@ -102,15 +119,21 @@ export function loadGroupOptions(group, reportData, reportId) {
|
|
|
102
119
|
}
|
|
103
120
|
// Stored filter values (ids) paired back with the labels to show for them.
|
|
104
121
|
// A saved default holds only values, so the names have to be read back off the
|
|
105
|
-
// option list — that indirection is exactly what survives a rename.
|
|
106
|
-
//
|
|
107
|
-
//
|
|
108
|
-
//
|
|
109
|
-
|
|
110
|
-
|
|
122
|
+
// option list — that indirection is exactly what survives a rename. `label`
|
|
123
|
+
// names a value first: a name already learned (ReportFilterOptionsService.label)
|
|
124
|
+
// holds for a pick a narrowed list leaves out, and when it names every value
|
|
125
|
+
// the list is not read at all. A value with no name and no matching option
|
|
126
|
+
// (its entity was deleted, so it is no longer listed) falls back to showing
|
|
127
|
+
// the raw value rather than dropping the chip, which would silently widen the
|
|
128
|
+
// filter.
|
|
129
|
+
export function resolveOptionValues(options$, values, label = () => null) {
|
|
130
|
+
const named = (options) => values.map((value) => {
|
|
111
131
|
const option = options.find((candidate) => String(candidate.value) === String(value));
|
|
112
|
-
return { name: option?.name ?? String(value), value };
|
|
113
|
-
})
|
|
132
|
+
return { name: label(value) ?? option?.name ?? String(value), value };
|
|
133
|
+
});
|
|
134
|
+
return values.every((value) => label(value) !== null)
|
|
135
|
+
? of(named([]))
|
|
136
|
+
: options$.pipe(map(named));
|
|
114
137
|
}
|
|
115
138
|
// Case-insensitive name filter applied to a loaded option list — the typed
|
|
116
139
|
// keyword has to be matched here because fs-autocomplete renders what we return
|
|
@@ -121,47 +144,160 @@ export function matchOptions(options$, keyword) {
|
|
|
121
144
|
? options.filter((option) => option.name.toLowerCase().includes(term))
|
|
122
145
|
: options));
|
|
123
146
|
}
|
|
147
|
+
// The panel row of a select whose list the server cut at 500.
|
|
148
|
+
export const OPTIONS_TRUNCATED_NOTE = 'Showing the first 500. Type to narrow.';
|
|
149
|
+
// The panel row of a select whose list could not be read. The next focus or
|
|
150
|
+
// keystroke asks again.
|
|
151
|
+
export const OPTIONS_FAILED_NOTE = 'Could not load the list.';
|
|
124
152
|
// Build the fs-filter config item for a group, seeding its default from the
|
|
125
153
|
// current session value so authored/relative defaults show selected on open.
|
|
126
|
-
|
|
154
|
+
// A select lists what `options` offers for it in `report`. `features` is the
|
|
155
|
+
// report's viewerFeatures: a select offers 'Exclude these' by the rule of
|
|
156
|
+
// offersExclude (the server lists excludeValues and no member binds several
|
|
157
|
+
// columns), and a number range is a min/max control only when it lists
|
|
158
|
+
// numberRange.
|
|
159
|
+
export function filterItemForGroup(group, options, report, initial, features = []) {
|
|
127
160
|
const name = groupItemName(group);
|
|
128
|
-
const label = group
|
|
161
|
+
const label = groupLabel(group);
|
|
129
162
|
switch (group.type) {
|
|
130
163
|
case 'dateRange':
|
|
131
|
-
return
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
};
|
|
139
|
-
case 'select': {
|
|
140
|
-
// One shared, replayed option stream so typing never refetches.
|
|
141
|
-
const options$ = loadGroupOptions(group, reportData, reportId);
|
|
142
|
-
const values = initial?.values;
|
|
143
|
-
return {
|
|
144
|
-
name,
|
|
145
|
-
type: ItemType.AutoCompleteChips,
|
|
146
|
-
label,
|
|
147
|
-
fetchOnFocus: true,
|
|
148
|
-
values: (keyword) => matchOptions(options$, keyword),
|
|
149
|
-
// Stored values are ids, so the chips can only be named once the option
|
|
150
|
-
// list has loaded — hence the observable form of `default`.
|
|
151
|
-
default: values?.length
|
|
152
|
-
? () => resolveOptionValues(options$, values)
|
|
153
|
-
: undefined,
|
|
154
|
-
};
|
|
155
|
-
}
|
|
164
|
+
return dateRangeFilterItem(name, label, initial);
|
|
165
|
+
case 'select':
|
|
166
|
+
return selectFilterItem(group, label, options, report, initial, offersExclude(group, features));
|
|
167
|
+
case 'numberRange':
|
|
168
|
+
return features.includes('numberRange')
|
|
169
|
+
? numberRangeFilterItem(group, label, report, initial)
|
|
170
|
+
: keywordFilterItem(name, label, initial);
|
|
156
171
|
case 'keyword':
|
|
157
172
|
default:
|
|
158
|
-
return
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
173
|
+
return keywordFilterItem(name, label, initial);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// A date range opens on its days, and its chip shows them. A preset picked in
|
|
177
|
+
// the date picker only sets the days.
|
|
178
|
+
function dateRangeFilterItem(name, label, initial) {
|
|
179
|
+
const hasDays = !!(initial?.start || initial?.end);
|
|
180
|
+
return {
|
|
181
|
+
name,
|
|
182
|
+
type: ItemType.DateRange,
|
|
183
|
+
label: { from: `${label} From`, to: `${label} To` },
|
|
184
|
+
default: hasDays
|
|
185
|
+
? { from: initial.start ?? undefined, to: initial.end ?? undefined }
|
|
186
|
+
: undefined,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
// A select's picks, kept or left out. With `exclude` the list has the
|
|
190
|
+
// 'Exclude these' row, and a value that leaves out opens with it on. Its list
|
|
191
|
+
// is read on focus and on each keystroke: the options service fetches it when
|
|
192
|
+
// the other filters changed since and replays it otherwise, and typing
|
|
193
|
+
// filters it here. A list the server cut, or one that could not be read,
|
|
194
|
+
// says so in a panel row.
|
|
195
|
+
function selectFilterItem(group, label, options, report, initial, exclude) {
|
|
196
|
+
const excluding = exclude && !initial?.values?.length && !!initial?.excludeValues?.length;
|
|
197
|
+
const picks = excluding ? initial.excludeValues : initial?.values;
|
|
198
|
+
const options$ = options.options(group, report);
|
|
199
|
+
return {
|
|
200
|
+
name: groupItemName(group),
|
|
201
|
+
type: ItemType.AutoCompleteChips,
|
|
202
|
+
label,
|
|
203
|
+
fetchOnFocus: true,
|
|
204
|
+
exclude: exclude ? {} : undefined,
|
|
205
|
+
values: (keyword) => matchOptions(options$, keyword),
|
|
206
|
+
panelNote: () => optionsNote(options, group.id),
|
|
207
|
+
// Stored values are ids, so a chip is named by a name already learned or
|
|
208
|
+
// once the option list has loaded — hence the observable form of `default`.
|
|
209
|
+
default: picks?.length
|
|
210
|
+
? () => resolveOptionValues(options$, picks, (value) => options.label(group.id, value))
|
|
211
|
+
.pipe(map((selected) => (excluding ? { exclude: true, selected } : selected)))
|
|
212
|
+
: undefined,
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
// The panel row of a select's latest list: a failure first, then a cut list.
|
|
216
|
+
function optionsNote(options, groupId) {
|
|
217
|
+
if (options.failed(groupId)) {
|
|
218
|
+
return OPTIONS_FAILED_NOTE;
|
|
164
219
|
}
|
|
220
|
+
return options.truncated(groupId) ? OPTIONS_TRUNCATED_NOTE : null;
|
|
221
|
+
}
|
|
222
|
+
// A number range's low and high ends, either one open. 0 is an end like any
|
|
223
|
+
// other. Its chip reads as the export lines do ('Amount: 0 or more',
|
|
224
|
+
// 'Amount: 0 to 10'): the ends are read off the item's query the way the
|
|
225
|
+
// bar's change reads them, and worded in the report's locale.
|
|
226
|
+
function numberRangeFilterItem(group, label, report, initial) {
|
|
227
|
+
const name = groupItemName(group);
|
|
228
|
+
const min = initial?.min ?? undefined;
|
|
229
|
+
const max = initial?.max ?? undefined;
|
|
230
|
+
const locale = resolveFormatContext(report ?? {}).locale;
|
|
231
|
+
return {
|
|
232
|
+
name,
|
|
233
|
+
type: ItemType.Range,
|
|
234
|
+
label,
|
|
235
|
+
default: min !== undefined || max !== undefined ? { min, max } : undefined,
|
|
236
|
+
chipText: (item) => filterLineText({ label, level: group.level }, numberRangeFromQuery(item.query, name), { locale }, 'chip'),
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
function keywordFilterItem(name, label, initial) {
|
|
240
|
+
return {
|
|
241
|
+
name,
|
|
242
|
+
type: ItemType.Keyword,
|
|
243
|
+
label,
|
|
244
|
+
default: initial?.value,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
// The groups a match of 'any' combines: report bar groups (a page group on
|
|
248
|
+
// its own page only) that a viewer picks values, text or a number range in.
|
|
249
|
+
// Dates, tile-only groups and the cross-filter always narrow on their own.
|
|
250
|
+
// The server holds the same rule and checks every id it is sent.
|
|
251
|
+
const MATCH_ANY_LEVELS = ['report', 'both', 'page'];
|
|
252
|
+
const MATCH_ANY_TYPES = ['select', 'keyword', 'numberRange'];
|
|
253
|
+
// Whether a group joins a match of 'any' on page `pageId`.
|
|
254
|
+
export function isMatchAnyGroup(group, pageId) {
|
|
255
|
+
return MATCH_ANY_LEVELS.includes(group.level)
|
|
256
|
+
&& MATCH_ANY_TYPES.includes(group.type)
|
|
257
|
+
&& (group.level !== 'page' || (!!pageId && group.pageId === pageId));
|
|
258
|
+
}
|
|
259
|
+
// The report bar's groups in their saved order: the report and both groups,
|
|
260
|
+
// and the page groups of the page on screen (`pageId`).
|
|
261
|
+
export function reportBarGroups(report, pageId) {
|
|
262
|
+
return (report?.filterGroups ?? [])
|
|
263
|
+
.filter((group) => group.level === 'report' || group.level === 'both'
|
|
264
|
+
|| (group.level === 'page' && !!pageId && group.pageId === pageId))
|
|
265
|
+
.sort((a, b) => a.order - b.order);
|
|
266
|
+
}
|
|
267
|
+
// Whether the report has a group shown on one page only, so its report bar
|
|
268
|
+
// changes with the page on screen.
|
|
269
|
+
export function hasPageGroup(report) {
|
|
270
|
+
return (report?.filterGroups ?? []).some((group) => group.level === 'page');
|
|
271
|
+
}
|
|
272
|
+
// The query key of the report bar's Match control. Not a filter group: it
|
|
273
|
+
// says how the groups combine, so it is read straight off the change query.
|
|
274
|
+
export const MATCH_ITEM = 'match';
|
|
275
|
+
const MATCH_OPTIONS = [
|
|
276
|
+
{ name: 'All filters', value: 'all' },
|
|
277
|
+
{ name: 'Any filter', value: 'any' },
|
|
278
|
+
];
|
|
279
|
+
// The report bar's Match control, last in the bar, or null when it would do
|
|
280
|
+
// nothing: the server must serve matchAny, and the bar must hold two or more
|
|
281
|
+
// groups that combine (an 'any' over one group is that group).
|
|
282
|
+
export function matchFilterItem(report, groups, pageId, match) {
|
|
283
|
+
const eligible = groups.filter((group) => isMatchAnyGroup(group, pageId));
|
|
284
|
+
if (!report?.viewerFeatures?.includes('matchAny') || eligible.length < 2) {
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
return {
|
|
288
|
+
name: MATCH_ITEM,
|
|
289
|
+
type: ItemType.Select,
|
|
290
|
+
label: 'Match',
|
|
291
|
+
multiple: false,
|
|
292
|
+
values: () => MATCH_OPTIONS,
|
|
293
|
+
default: match,
|
|
294
|
+
// 'Match: any filter' or 'Match: all filters', in the export lines' words.
|
|
295
|
+
chipText: (item) => matchLineText(matchFromQuery(item.query), 'chip'),
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
// The match a change query of a bar with the Match control asks for.
|
|
299
|
+
export function matchFromQuery(query) {
|
|
300
|
+
return query?.[MATCH_ITEM] === 'any' ? 'any' : 'all';
|
|
165
301
|
}
|
|
166
302
|
// The query key of a list's search box in its component header. Fixed rather
|
|
167
303
|
// than derived from an id because a header holds at most one, and it is NOT a
|
|
@@ -169,7 +305,7 @@ export function filterItemForGroup(group, reportData, reportId, initial) {
|
|
|
169
305
|
// the change query and travels as the list's own `state.search`.
|
|
170
306
|
export const LIST_SEARCH_ITEM = 'listSearch';
|
|
171
307
|
// The longest search the server applies (ReportQueryRunner::MAX_SEARCH_LENGTH).
|
|
172
|
-
// The viewer cuts the text to it too, so the
|
|
308
|
+
// The viewer cuts the text to it too, so the state, the request and the export
|
|
173
309
|
// title all carry the text that was actually searched.
|
|
174
310
|
export const LIST_SEARCH_MAX_LENGTH = 100;
|
|
175
311
|
// The fs-filter config item for a list's search box, seeded with the text the
|
|
@@ -249,22 +385,77 @@ export function groupBySignature(report) {
|
|
|
249
385
|
export function groupValuesFromQuery(query, groups) {
|
|
250
386
|
return groups.map((group) => {
|
|
251
387
|
const name = groupItemName(group);
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
groupId: group.id,
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
388
|
+
switch (group.type) {
|
|
389
|
+
case 'dateRange':
|
|
390
|
+
return { groupId: group.id, value: dateRangeFromQuery(query, name) };
|
|
391
|
+
case 'select':
|
|
392
|
+
return { groupId: group.id, value: selectFromQuery(query, name) };
|
|
393
|
+
case 'numberRange':
|
|
394
|
+
return { groupId: group.id, value: numberRangeFromQuery(query, name) };
|
|
395
|
+
default: {
|
|
396
|
+
const keyword = String(query[name] ?? '').trim();
|
|
397
|
+
return { groupId: group.id, value: keyword ? { value: keyword } : null };
|
|
398
|
+
}
|
|
263
399
|
}
|
|
264
|
-
const keyword = String(query[name] ?? '').trim();
|
|
265
|
-
return { groupId: group.id, value: keyword ? { value: keyword } : null };
|
|
266
400
|
});
|
|
267
401
|
}
|
|
402
|
+
// A date range's days (<name>From, <name>To).
|
|
403
|
+
function dateRangeFromQuery(query, name) {
|
|
404
|
+
const start = query[itemRangeName(name, 'from')];
|
|
405
|
+
const end = query[itemRangeName(name, 'to')];
|
|
406
|
+
if (!start && !end) {
|
|
407
|
+
return null;
|
|
408
|
+
}
|
|
409
|
+
return { start: start || null, end: end || null };
|
|
410
|
+
}
|
|
411
|
+
// A select's picks: kept (<name>), or left out while its exclude row is on
|
|
412
|
+
// (exclude<Name>).
|
|
413
|
+
function selectFromQuery(query, name) {
|
|
414
|
+
const excludeValues = selectQueryValues(query[getExcludeName(name)]);
|
|
415
|
+
if (excludeValues.length) {
|
|
416
|
+
return { excludeValues };
|
|
417
|
+
}
|
|
418
|
+
const values = selectQueryValues(query[name]);
|
|
419
|
+
return values.length ? { values } : null;
|
|
420
|
+
}
|
|
421
|
+
// A number range's ends (<name>Min, <name>Max). An end left empty is open.
|
|
422
|
+
function numberRangeFromQuery(query, name) {
|
|
423
|
+
const min = rangeBound(query[itemRangeName(name, 'min')]);
|
|
424
|
+
const max = rangeBound(query[itemRangeName(name, 'max')]);
|
|
425
|
+
if (min === null && max === null) {
|
|
426
|
+
return null;
|
|
427
|
+
}
|
|
428
|
+
return {
|
|
429
|
+
...(min !== null ? { min } : {}),
|
|
430
|
+
...(max !== null ? { max } : {}),
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
// One end of a number range as fs-filter's Range sends it: the text typed in
|
|
434
|
+
// its input. Number() reads any non-empty text, so '0' is the end 0; empty or
|
|
435
|
+
// unreadable text is an open end.
|
|
436
|
+
function rangeBound(raw) {
|
|
437
|
+
const text = typeof raw === 'number' ? String(raw) : String(raw ?? '').trim();
|
|
438
|
+
const number = text === '' ? NaN : Number(text);
|
|
439
|
+
return Number.isFinite(number) ? number : null;
|
|
440
|
+
}
|
|
441
|
+
// A group value as text, the same for the same value whatever its source:
|
|
442
|
+
// days as calendar days, picks and ends as text, keyword text trimmed. The
|
|
443
|
+
// value a tile header was built with is keyed on it, so a header is created
|
|
444
|
+
// again when another bar changes a group it shows.
|
|
445
|
+
export function groupValueSignature(value) {
|
|
446
|
+
if (!value) {
|
|
447
|
+
return '';
|
|
448
|
+
}
|
|
449
|
+
return JSON.stringify([
|
|
450
|
+
dateBoundString(value.start) ?? '',
|
|
451
|
+
dateBoundString(value.end) ?? '',
|
|
452
|
+
(value.values ?? []).map(String),
|
|
453
|
+
(value.excludeValues ?? []).map(String),
|
|
454
|
+
(value.value ?? '').trim(),
|
|
455
|
+
value.min ?? '',
|
|
456
|
+
value.max ?? '',
|
|
457
|
+
]);
|
|
458
|
+
}
|
|
268
459
|
// fs-filter's AutoCompleteChips serialises a multi-select into ONE query value:
|
|
269
460
|
// the selected values joined by "," (its `query` getter does `.map(value).join(',')`).
|
|
270
461
|
// So a 2+ selection arrives as the string "a,b", not an array — splitting on ","
|
|
@@ -279,4 +470,4 @@ function selectQueryValues(raw) {
|
|
|
279
470
|
}
|
|
280
471
|
return String(raw).split(',');
|
|
281
472
|
}
|
|
282
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LWZpbHRlci1pdGVtcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy9yZXBvcnQtZmlsdGVyLWl0ZW1zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBcUIsUUFBUSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFakUsT0FBTyxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFNUMsT0FBTyxFQUFjLEVBQUUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN0QyxPQUFPLEVBQUUsR0FBRyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBR2xELE9BQU8sRUFBRSxTQUFTLEVBQUUsZUFBZSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBQ3RELE9BQU8sRUFDK0IsbUJBQW1CLEdBRXhELE1BQU0sK0JBQStCLENBQUM7QUFHdkMsMkVBQTJFO0FBQzNFLDRFQUE0RTtBQUM1RSx5RUFBeUU7QUFDekUsTUFBTSxVQUFVLGVBQWUsQ0FBQyxLQUF1QztJQUNyRSxJQUFJLEtBQUssWUFBWSxJQUFJLEVBQUUsQ0FBQztRQUMxQixPQUFPLE1BQU0sQ0FBQyxLQUFLLEVBQUUsWUFBWSxDQUFDLENBQUM7SUFDckMsQ0FBQztJQUVELHNFQUFzRTtJQUN0RSw4QkFBOEI7SUFDOUIsT0FBTyxLQUFLLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7QUFDeEQsQ0FBQztBQUdELDhFQUE4RTtBQUM5RSwrRUFBK0U7QUFDL0UsOEVBQThFO0FBQzlFLGlFQUFpRTtBQUNqRSxFQUFFO0FBQ0YsZ0ZBQWdGO0FBQ2hGLGdGQUFnRjtBQUNoRiw2REFBNkQ7QUFDN0QsRUFBRTtBQUNGLDRFQUE0RTtBQUM1RSwyQ0FBMkM7QUFDM0MsTUFBTSxVQUFVLGNBQWMsQ0FBQyxLQUF1QyxFQUFFLE1BQXVCO0lBQzdGLE1BQU0sS0FBSyxHQUFHLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUVyQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDWCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxNQUFNLElBQUksR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7SUFFN0IsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQ2pHLENBQUM7QUFHRCwyRUFBMkU7QUFDM0UsNkVBQTZFO0FBQzdFLGdEQUFnRDtBQUNoRCxNQUFNLFVBQVUsYUFBYSxDQUFDLEtBQWdDO0lBQzVELElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNYLE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVELE1BQU0sSUFBSSxHQUFHLFFBQVEsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBRTFDLE9BQU8sTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7QUFDcEQsQ0FBQztBQUdELDhFQUE4RTtBQUM5RSw2RUFBNkU7QUFDN0UsNENBQTRDO0FBQzVDLE1BQU0sVUFBVSxXQUFXLENBQUMsS0FBOEI7SUFDeEQsT0FBTyxLQUFLLFlBQVksSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDNUQsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsWUFBWSxDQUFDO1FBQzdCLENBQUMsQ0FBQyxJQUFJLENBQUM7QUFDWCxDQUFDO0FBR0QsOEVBQThFO0FBQzlFLDBFQUEwRTtBQUMxRSwyRUFBMkU7QUFDM0UsMENBQTBDO0FBQzFDLE1BQU0sVUFBVSxhQUFhLENBQUMsUUFBZ0I7SUFDNUMsTUFBTSxLQUFLLEdBQUcsUUFBUTtTQUNuQixPQUFPLENBQUMsb0JBQW9CLEVBQUUsT0FBTyxDQUFDO1NBQ3RDLE9BQU8sQ0FBQyxjQUFjLEVBQUUsT0FBTyxDQUFDO1NBQ2hDLFdBQVcsRUFBRSxDQUFDO0lBRWpCLE9BQU8sS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3hELENBQUM7QUFHRCw4RUFBOEU7QUFDOUUsK0VBQStFO0FBQy9FLDRFQUE0RTtBQUM1RSwrRUFBK0U7QUFDL0UsaUVBQWlFO0FBRWpFLHVFQUF1RTtBQUN2RSxNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxHQUFHLENBQUM7QUFFdEMsK0VBQStFO0FBQy9FLG9FQUFvRTtBQUNwRSxNQUFNLFVBQVUsYUFBYSxDQUFDLEtBQW9DO0lBQ2hFLE9BQU8sR0FBRyxrQkFBa0IsR0FBRyxLQUFLLENBQUMsRUFBRSxFQUFFLENBQUM7QUFDNUMsQ0FBQztBQUVELDZFQUE2RTtBQUM3RSw4RUFBOEU7QUFDOUUsaUVBQWlFO0FBQ2pFLHNFQUFzRTtBQUN0RSxxRUFBcUU7QUFDckUsK0JBQStCO0FBQy9CLE1BQU0sQ0FBQyxNQUFNLGFBQWEsR0FBRyxTQUFTLENBQUM7QUFFdkMsZ0ZBQWdGO0FBQ2hGLGdGQUFnRjtBQUNoRixnRkFBZ0Y7QUFDaEYsZ0ZBQWdGO0FBQ2hGLDZFQUE2RTtBQUM3RSwrRUFBK0U7QUFDL0UsMkVBQTJFO0FBQzNFLGdGQUFnRjtBQUNoRix5REFBeUQ7QUFDekQsTUFBTSxVQUFVLGdCQUFnQixDQUM5QixLQUF3QixFQUN4QixVQUFzQixFQUN0QixRQUFnQjtJQUVoQixNQUFNLFlBQVksR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDL0UsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ2xCLE9BQU8sRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ2hCLENBQUM7SUFFRCxPQUFPLFVBQVUsQ0FBQyxhQUFhLENBQUMsUUFBUSxFQUFFLFlBQVksQ0FBQyxFQUFFLENBQUM7U0FDdkQsSUFBSSxDQUNILEdBQUcsQ0FBQyxDQUFDLE9BQTZCLEVBQUUsRUFBRSxDQUFDLENBQUMsT0FBTyxJQUFJLEVBQUUsQ0FBQztTQUNuRCxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUNsRSxXQUFXLENBQUMsRUFBRSxVQUFVLEVBQUUsQ0FBQyxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUNoRCxDQUFDO0FBQ04sQ0FBQztBQUVELDJFQUEyRTtBQUMzRSwrRUFBK0U7QUFDL0UsaUZBQWlGO0FBQ2pGLCtFQUErRTtBQUMvRSwyRUFBMkU7QUFDM0UsNkJBQTZCO0FBQzdCLE1BQU0sVUFBVSxtQkFBbUIsQ0FDakMsUUFBd0QsRUFDeEQsTUFBaUI7SUFFakIsT0FBTyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1FBQ3pELE1BQU0sTUFBTSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLEtBQUssTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFFdEYsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsSUFBSSxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQztJQUN4RCxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDUCxDQUFDO0FBRUQsMkVBQTJFO0FBQzNFLGdGQUFnRjtBQUNoRixZQUFZO0FBQ1osTUFBTSxVQUFVLFlBQVksQ0FDMUIsUUFBd0QsRUFDeEQsT0FBZ0I7SUFFaEIsTUFBTSxJQUFJLEdBQUcsQ0FBQyxPQUFPLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsV0FBVyxFQUFFLENBQUM7SUFFbEQsT0FBTyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsSUFBSTtRQUN4QyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7QUFDaEIsQ0FBQztBQUVELDRFQUE0RTtBQUM1RSw2RUFBNkU7QUFDN0UsTUFBTSxVQUFVLGtCQUFrQixDQUNoQyxLQUF3QixFQUN4QixVQUFzQixFQUN0QixRQUFnQixFQUNoQixPQUEwQjtJQUUxQixNQUFNLElBQUksR0FBRyxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDbEMsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLEtBQUssSUFBSSxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsWUFBWSxJQUFJLEVBQUUsQ0FBQztJQUVwRSxRQUFRLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNuQixLQUFLLFdBQVc7WUFDZCxPQUFPO2dCQUNMLElBQUk7Z0JBQ0osSUFBSSxFQUFFLFFBQVEsQ0FBQyxTQUFTO2dCQUN4QixLQUFLLEVBQUUsRUFBRSxJQUFJLEVBQUUsR0FBRyxLQUFLLE9BQU8sRUFBRSxFQUFFLEVBQUUsR0FBRyxLQUFLLEtBQUssRUFBRTtnQkFDbkQsT0FBTyxFQUFFLENBQUMsT0FBTyxFQUFFLEtBQUssSUFBSSxPQUFPLEVBQUUsR0FBRyxDQUFDO29CQUN2QyxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsT0FBTyxDQUFDLEtBQUssSUFBSSxTQUFTLEVBQUUsRUFBRSxFQUFFLE9BQU8sQ0FBQyxHQUFHLElBQUksU0FBUyxFQUFFO29CQUNwRSxDQUFDLENBQUMsU0FBUzthQUNkLENBQUM7UUFFSixLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUM7WUFDZCxnRUFBZ0U7WUFDaEUsTUFBTSxRQUFRLEdBQUcsZ0JBQWdCLENBQUMsS0FBSyxFQUFFLFVBQVUsRUFBRSxRQUFRLENBQUMsQ0FBQztZQUMvRCxNQUFNLE1BQU0sR0FBRyxPQUFPLEVBQUUsTUFBTSxDQUFDO1lBRS9CLE9BQU87Z0JBQ0wsSUFBSTtnQkFDSixJQUFJLEVBQUUsUUFBUSxDQUFDLGlCQUFpQjtnQkFDaEMsS0FBSztnQkFDTCxZQUFZLEVBQUUsSUFBSTtnQkFDbEIsTUFBTSxFQUFFLENBQUMsT0FBZ0IsRUFBRSxFQUFFLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUM7Z0JBQzdELHdFQUF3RTtnQkFDeEUsNERBQTREO2dCQUM1RCxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU07b0JBQ3JCLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDO29CQUM3QyxDQUFDLENBQUMsU0FBUzthQUNkLENBQUM7UUFDSixDQUFDO1FBRUQsS0FBSyxTQUFTLENBQUM7UUFDZjtZQUNFLE9BQU87Z0JBQ0wsSUFBSTtnQkFDSixJQUFJLEVBQUUsUUFBUSxDQUFDLE9BQU87Z0JBQ3RCLEtBQUs7Z0JBQ0wsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLO2FBQ3hCLENBQUM7SUFDTixDQUFDO0FBQ0gsQ0FBQztBQUVELDZFQUE2RTtBQUM3RSw4RUFBOEU7QUFDOUUsNkVBQTZFO0FBQzdFLGlFQUFpRTtBQUNqRSxNQUFNLENBQUMsTUFBTSxnQkFBZ0IsR0FBRyxZQUFZLENBQUM7QUFFN0MsZ0ZBQWdGO0FBQ2hGLDZFQUE2RTtBQUM3RSx1REFBdUQ7QUFDdkQsTUFBTSxDQUFDLE1BQU0sc0JBQXNCLEdBQUcsR0FBRyxDQUFDO0FBRTFDLDhFQUE4RTtBQUM5RSx5RUFBeUU7QUFDekUsMEVBQTBFO0FBQzFFLG9CQUFvQjtBQUNwQixNQUFNLFVBQVUsY0FBYyxDQUFDLEtBQW9CO0lBQ2pELE9BQU87UUFDTCxJQUFJLEVBQUUsUUFBUSxDQUFDLE9BQU87UUFDdEIsSUFBSSxFQUFFLGdCQUFnQjtRQUN0QixLQUFLLEVBQUUsUUFBUTtRQUNmLE9BQU8sRUFBRSxLQUFLLElBQUksU0FBUztLQUM1QixDQUFDO0FBQ0osQ0FBQztBQUVELDRFQUE0RTtBQUM1RSwyRUFBMkU7QUFDM0Usb0RBQW9EO0FBQ3BELE1BQU0sVUFBVSxrQkFBa0IsQ0FBQyxNQUFxQjtJQUN0RCxPQUFPLENBQUMsTUFBTSxFQUFFLEtBQUssSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUNyRixTQUFTLENBQUMsSUFBSSxLQUFLLE9BQU8sSUFBSSxTQUFTLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxJQUFJLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQztBQUM3RSxDQUFDO0FBRUQsK0VBQStFO0FBQy9FLCtFQUErRTtBQUMvRSw4RUFBOEU7QUFDOUUsU0FBUyxjQUFjLENBQUMsTUFBYztJQUNwQyxNQUFNLGFBQWEsR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLE9BQU8sRUFBRSxhQUFhLElBQUksRUFBRSxDQUFDO0lBRWxFLE9BQU8sYUFBYSxDQUFDLE1BQU07UUFDekIsQ0FBQyxDQUFDLG1CQUFtQixDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDOUUsQ0FBQyxDQUFDLG1CQUFtQixDQUFDO0FBQzFCLENBQUM7QUFFRCwrRUFBK0U7QUFDL0UsZ0ZBQWdGO0FBQ2hGLGtGQUFrRjtBQUNsRixNQUFNLFVBQVUsb0JBQW9CLENBQUMsTUFBYyxFQUFFLFdBQW9DO0lBQ3ZGLE9BQU8sQ0FBQyxXQUFXLElBQUksY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssS0FBSyxXQUFXLENBQUMsQ0FBQztBQUMvRixDQUFDO0FBRUQsZ0ZBQWdGO0FBQ2hGLDJCQUEyQjtBQUMzQixFQUFFO0FBQ0YsMkVBQTJFO0FBQzNFLDBFQUEwRTtBQUMxRSwyRUFBMkU7QUFDM0Usd0NBQXdDO0FBQ3hDLGdGQUFnRjtBQUNoRiw4REFBOEQ7QUFDOUQsTUFBTSxVQUFVLGlCQUFpQixDQUMvQixNQUFjLEVBQ2QsT0FBaUM7SUFFakMsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUM7SUFFdkMsMkVBQTJFO0lBQzNFLDZFQUE2RTtJQUM3RSx3RUFBd0U7SUFDeEUsSUFBSSxPQUFPLEVBQUUsT0FBTyxLQUFLLEtBQUssSUFBSSxDQUFDLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7UUFDOUQsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsTUFBTSxNQUFNLEdBQUcsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBRXRDLE9BQU87UUFDTCxJQUFJLEVBQUUsYUFBYTtRQUNuQixJQUFJLEVBQUUsUUFBUSxDQUFDLE1BQU07UUFDckIsS0FBSyxFQUFFLE9BQU8sRUFBRSxLQUFLLElBQUksVUFBVTtRQUNuQyxRQUFRLEVBQUUsS0FBSztRQUNmLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxNQUFNO1FBQ3BCLE9BQU8sRUFBRSxvQkFBb0IsQ0FBQyxNQUFNLEVBQUUsT0FBTyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sSUFBSSxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUztLQUM1RixDQUFDO0FBQ0osQ0FBQztBQUVELGdGQUFnRjtBQUNoRiw4RUFBOEU7QUFDOUUsNkVBQTZFO0FBQzdFLDREQUE0RDtBQUM1RCxNQUFNLFVBQVUsZ0JBQWdCLENBQUMsTUFBcUI7SUFDcEQsSUFBSSxDQUFDLE1BQU0sSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7UUFDMUMsT0FBTyxFQUFFLENBQUM7SUFDWixDQUFDO0lBRUQsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUM7SUFFdkMsT0FBTyxDQUFDLFNBQVMsRUFBRSxPQUFPLEVBQUUsS0FBSyxJQUFJLEVBQUUsRUFBRSxDQUFDLE9BQU8sRUFBRSxhQUFhLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQy9GLENBQUM7QUFFRCw4RUFBOEU7QUFDOUUsMkVBQTJFO0FBQzNFLHFDQUFxQztBQUNyQyxNQUFNLFVBQVUsb0JBQW9CLENBQ2xDLEtBQTBCLEVBQzFCLE1BQTJCO0lBRTNCLE9BQU8sTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1FBQzFCLE1BQU0sSUFBSSxHQUFHLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUVsQyxJQUFJLEtBQUssQ0FBQyxJQUFJLEtBQUssV0FBVyxFQUFFLENBQUM7WUFDL0IsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLEdBQUcsSUFBSSxNQUFNLENBQUMsQ0FBQztZQUNuQyxNQUFNLEdBQUcsR0FBRyxLQUFLLENBQUMsR0FBRyxJQUFJLElBQUksQ0FBQyxDQUFDO1lBRS9CLE9BQU87Z0JBQ0wsT0FBTyxFQUFFLEtBQUssQ0FBQyxFQUFFO2dCQUNqQixLQUFLLEVBQUUsQ0FBQyxLQUFLLElBQUksR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssSUFBSSxJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSTthQUMxRSxDQUFDO1FBQ0osQ0FBQztRQUVELElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUM1QixNQUFNLE1BQU0sR0FBRyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUU5QyxPQUFPLEVBQUUsT0FBTyxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3pFLENBQUM7UUFFRCxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO1FBRWpELE9BQU8sRUFBRSxPQUFPLEVBQUUsS0FBSyxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDM0UsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQsZ0ZBQWdGO0FBQ2hGLHVGQUF1RjtBQUN2RixpRkFBaUY7QUFDakYsZ0ZBQWdGO0FBQ2hGLGdGQUFnRjtBQUNoRixTQUFTLGlCQUFpQixDQUFDLEdBQVk7SUFDckMsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDdkIsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDO0lBRUQsSUFBSSxHQUFHLEtBQUssSUFBSSxJQUFJLEdBQUcsS0FBSyxTQUFTLElBQUksR0FBRyxLQUFLLEVBQUUsRUFBRSxDQUFDO1FBQ3BELE9BQU8sRUFBRSxDQUFDO0lBQ1osQ0FBQztJQUVELE9BQU8sTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUNoQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSUZpbHRlckNvbmZpZ0l0ZW0sIEl0ZW1UeXBlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvZmlsdGVyJztcblxuaW1wb3J0IHsgZm9ybWF0LCBwYXJzZUlTTyB9IGZyb20gJ2RhdGUtZm5zJztcblxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgb2YgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcCwgc2hhcmVSZXBsYXkgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IFJlcG9ydERhdGEgfSBmcm9tICcuL2RhdGEvcmVwb3J0LmRhdGEnO1xuaW1wb3J0IHsgREFZX1NIT1JULCBmb3JtYXRMb2NhbERhdGUgfSBmcm9tICcuL2Zvcm1hdCc7XG5pbXBvcnQge1xuICBDaGFydEdyYW51bGFyaXR5LCBGaWx0ZXJHcm91cFZhbHVlLCBHUkFOVUxBUklUWV9PUFRJT05TLCBSZXBvcnQsIFJlcG9ydEZpbHRlckdyb3VwLCBSZXBvcnRGaWx0ZXJPcHRpb24sXG4gIFJlcG9ydExvY2FsZVRhZyxcbn0gZnJvbSAnLi9pbnRlcmZhY2VzL3JlcG9ydC5pbnRlcmZhY2UnO1xuXG5cbi8vIEEgZGF0ZS1yYW5nZSBib3VuZGFyeSBhcyB0aGUgcGlja2VkIExPQ0FMIGNhbGVuZGFyIGRheSAobm8gdGltZSwgbm8gdHopLlxuLy8gRGF0ZS1yYW5nZSBmaWx0ZXJzIGFyZSBjYWxlbmRhci1kYXkgc2VtYW50aWNzLCBzbyB0aGUgYm91bmRhcnkgbXVzdCBjYXJyeVxuLy8gb25seSBZLU0tRCDigJQgbmV2ZXIgYSB0aW1lem9uZS1iZWFyaW5nIGluc3RhbnQgdGhlIGJhY2tlbmQgd291bGQgc2hpZnQuXG5leHBvcnQgZnVuY3Rpb24gZGF0ZUJvdW5kU3RyaW5nKHZhbHVlOiBEYXRlIHwgc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZCk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUpIHtcbiAgICByZXR1cm4gZm9ybWF0KHZhbHVlLCAneXl5eS1NTS1kZCcpO1xuICB9XG5cbiAgLy8gQXV0aG9yZWQvcmVsYXRpdmUgZGVmYXVsdHMgYXJyaXZlIGFzIHN0cmluZ3MgYWxyZWFkeSBpbiBZLU0tRCBmb3JtO1xuICAvLyBrZWVwIGp1c3QgdGhlIGRhdGUgcG9ydGlvbi5cbiAgcmV0dXJuIHZhbHVlID8gU3RyaW5nKHZhbHVlKS5zbGljZSgwLCAxMCkgOiB1bmRlZmluZWQ7XG59XG5cblxuLy8gQSBkYXRlLXJhbmdlIGJvdW5kYXJ5IGFzIGl0IHNob3VsZCBSRUFEIG9uIGEgY292ZXIgcGFnZSDigJQgdGhlIHNhbWUgY2FsZW5kYXJcbi8vIGRheSBkYXRlQm91bmRTdHJpbmcoKSBoYW5kcyB0aGUgc2VydmVyLCBzbyBhIHByaW50ZWQgcGVyaW9kIGNhbiBuZXZlciBuYW1lIGFcbi8vIGRpZmZlcmVudCBkYXkgdGhhbiB0aGUgbnVtYmVycyB1bmRlciBpdCB3ZXJlIGZpbHRlcmVkIGJ5LiBSZXR1cm5zIG51bGwgd2hlblxuLy8gdGhlcmUgaXMgbm8gYm91bmRhcnk7IHRoZSBjYWxsZXIgc3VwcGxpZXMgaXRzIG93biBwbGFjZWhvbGRlci5cbi8vXG4vLyBUaGUgcGFyc2UgaGFzIHRvIGJlIHBhcnNlSVNPLCBub3QgYG5ldyBEYXRlYDogYG5ldyBEYXRlKCcyMDI2LTA1LTAxJylgIGlzIFVUQ1xuLy8gbWlkbmlnaHQsIHNvIGZvcm1hdHRpbmcgaXQgYW55d2hlcmUgd2VzdCBvZiBVVEMgcHJpbnRzIEFwciAzMC4gcGFyc2VJU08gcmVhZHNcbi8vIGEgYmFyZSBZLU0tRCBhcyBMT0NBTCBtaWRuaWdodCwgd2hpY2ggbm8gb2Zmc2V0IGNhbiBzaGlmdC5cbi8vXG4vLyBUaGUgZGF5IGlzIHdyaXR0ZW4gaW4gdGhlIHJlcG9ydCdzIGxvY2FsZSwgYXMgaXRzIGRhdGUgY2VsbHMgYXJlOiAnSmFuIDUsXG4vLyAyMDI2JyBpbiBlbi1VUywgJzUgamFudi4gMjAyNicgaW4gZnItQ0EuXG5leHBvcnQgZnVuY3Rpb24gZGF0ZUJvdW5kTGFiZWwodmFsdWU6IERhdGUgfCBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkLCBsb2NhbGU6IFJlcG9ydExvY2FsZVRhZyk6IHN0cmluZyB8IG51bGwge1xuICBjb25zdCBib3VuZCA9IGRhdGVCb3VuZFN0cmluZyh2YWx1ZSk7XG5cbiAgaWYgKCFib3VuZCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgZGF0ZSA9IHBhcnNlSVNPKGJvdW5kKTtcblxuICByZXR1cm4gTnVtYmVyLmlzTmFOKGRhdGUuZ2V0VGltZSgpKSA/IFN0cmluZyh2YWx1ZSkgOiBmb3JtYXRMb2NhbERhdGUoZGF0ZSwgbG9jYWxlLCBEQVlfU0hPUlQpO1xufVxuXG5cbi8vIEEgc3RvcmVkIHl5eXktTU0tZGQgYm91bmRhcnkgYXMgYSBsb2NhbCBEYXRlIGZvciBhIGRhdGUgcGlja2VyLCBvciBudWxsLlxuLy8gcGFyc2VJU08gcmVhZHMgYSBiYXJlIFktTS1EIGFzIExPQ0FMIG1pZG5pZ2h0LCBzbyB0aGUgcGlja2VyIHNob3dzIHRoZSBkYXlcbi8vIHRoYXQgd2FzIHN0b3JlZCwgd2hhdGV2ZXIgdGhlIGJyb3dzZXIncyB6b25lLlxuZXhwb3J0IGZ1bmN0aW9uIGRhdGVGcm9tQm91bmQodmFsdWU6IHN0cmluZyB8IG51bGwgfCB1bmRlZmluZWQpOiBEYXRlIHwgbnVsbCB7XG4gIGlmICghdmFsdWUpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IGRhdGUgPSBwYXJzZUlTTyh2YWx1ZS5zbGljZSgwLCAxMCkpO1xuXG4gIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0ZS5nZXRUaW1lKCkpID8gbnVsbCA6IGRhdGU7XG59XG5cblxuLy8gQSBwaWNrZWQgRGF0ZSBhcyBhIHl5eXktTU0tZGQgYm91bmRhcnkgZm9yIHN0b3JhZ2UsIG9yIG51bGwuIFVzZXMgdGhlIGxvY2FsXG4vLyBjYWxlbmRhciBkYXkgKGZvcm1hdCwgbm90IHRvSVNPU3RyaW5nKSBzbyB0aGUgYm91bmRhcnkgaXMgdGhlIGRheSB0aGF0IHdhc1xuLy8gcGlja2VkLCByZWdhcmRsZXNzIG9mIHRoZSBicm93c2VyJ3Mgem9uZS5cbmV4cG9ydCBmdW5jdGlvbiBkYXRlVG9Cb3VuZCh2YWx1ZTogRGF0ZSB8IG51bGwgfCB1bmRlZmluZWQpOiBzdHJpbmcgfCBudWxsIHtcbiAgcmV0dXJuIHZhbHVlIGluc3RhbmNlb2YgRGF0ZSAmJiAhTnVtYmVyLmlzTmFOKHZhbHVlLmdldFRpbWUoKSlcbiAgICA/IGZvcm1hdCh2YWx1ZSwgJ3l5eXktTU0tZGQnKVxuICAgIDogbnVsbDtcbn1cblxuXG4vLyBBIHJlbGF0aXZlIGRhdGUtcmFuZ2UgcHJlc2V0IGtleSBhcyBhIHNlbnRlbmNlLWNhc2UgbGFiZWwsIGRlcml2ZWQgZnJvbSB0aGVcbi8vIGNhbWVsQ2FzZSBrZXkgaXRzZWxmICgnbGFzdDEyTW9udGhzJyByZWFkcyAnTGFzdCAxMiBtb250aHMnLCAndGhpc1dlZWsnXG4vLyByZWFkcyAnVGhpcyB3ZWVrJyksIHNvIG5vIGxpc3Qgb2YgcHJlc2V0cyBpcyBtaXJyb3JlZCBoZXJlIGFuZCBhIGtleSB0aGVcbi8vIHNlcnZlciBhZGRzIGxhdGVyIHN0aWxsIHJlYWRzIHNlbnNpYmx5LlxuZXhwb3J0IGZ1bmN0aW9uIHJlbGF0aXZlTGFiZWwocmVsYXRpdmU6IHN0cmluZyk6IHN0cmluZyB7XG4gIGNvbnN0IHdvcmRzID0gcmVsYXRpdmVcbiAgICAucmVwbGFjZSgvKFthLXpdKShbQS1aMC05XSkvZywgJyQxICQyJylcbiAgICAucmVwbGFjZSgvKFxcZCkoW0EtWl0pL2csICckMSAkMicpXG4gICAgLnRvTG93ZXJDYXNlKCk7XG5cbiAgcmV0dXJuIHdvcmRzLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgd29yZHMuc2xpY2UoMSk7XG59XG5cblxuLy8gTWFwcyBhIHJlcG9ydCBmaWx0ZXIgR1JPVVAgdG8gYW4gZnMtZmlsdGVyIGNvbmZpZyBpdGVtLCBhbmQgcmVhZHMgZnMtZmlsdGVyXG4vLyBxdWVyeSB2YWx1ZXMgYmFjayBpbnRvIHBlci1ncm91cCBGaWx0ZXJHcm91cFZhbHVlcy4gU2hhcmVkIGJ5IHRoZSByZXBvcnQtYmFyXG4vLyBmcy1maWx0ZXIgYW5kIHRoZSBwZXItY29tcG9uZW50IGZzLWZpbHRlciBzbyBib3RoIHJlbmRlciB0aHJvdWdoIHRoZSBzYW1lXG4vLyBsaWJyYXJ5IGFuZCB3cml0ZSBpbnRvIFJlcG9ydEZpbHRlclN0YXRlU2VydmljZSBpZGVudGljYWxseS4gSXRlbXMgYXJlIG5hbWVkXG4vLyBgZzxncm91cElkPmAgc28gdGhlIHF1ZXJ5IGtleXMgbWFwIHN0cmFpZ2h0IGJhY2sgdG8gdGhlIGdyb3VwLlxuXG4vLyBUaGUgcHJlZml4IG9mIGEgZ3JvdXAncyBpdGVtIG5hbWUsIGFuZCBvZiBpdHMga2V5IGluIHRoZSByZXBvcnQgVVJMLlxuZXhwb3J0IGNvbnN0IEdST1VQX1BBUkFNX1BSRUZJWCA9ICdnJztcblxuLy8gVGhlIHF1ZXJ5IGtleSBmcy1maWx0ZXIgdXNlcyBmb3IgYSBncm91cCdzIGl0ZW0ocyksIGFuZCB0aGUgcmVwb3J0IFVSTCdzIGtleVxuLy8gZm9yIHRoZSBncm91cCdzIHZhbHVlIChyZXBvcnQtdXJsLXN0YXRlLnRzKS4gT25lIG5hbWluZyBmb3IgYm90aC5cbmV4cG9ydCBmdW5jdGlvbiBncm91cEl0ZW1OYW1lKGdyb3VwOiBQaWNrPFJlcG9ydEZpbHRlckdyb3VwLCAnaWQnPik6IHN0cmluZyB7XG4gIHJldHVybiBgJHtHUk9VUF9QQVJBTV9QUkVGSVh9JHtncm91cC5pZH1gO1xufVxuXG4vLyBUaGUgcXVlcnkga2V5IGZvciB0aGUgcmVwb3J0J3MgZ3JvdXAtYnkgY29udHJvbC4gRml4ZWQgcmF0aGVyIHRoYW4gZGVyaXZlZFxuLy8gZnJvbSBhbiBpZCBiZWNhdXNlIGEgcmVwb3J0IGhhcyBleGFjdGx5IG9uZSDigJQgYW5kIGl0IGlzIE5PVCBhIGZpbHRlciBncm91cCxcbi8vIHNvIGl0IGlzIHJlYWQgc3RyYWlnaHQgb2ZmIHRoZSBjaGFuZ2UgcXVlcnkgaW5zdGVhZCBvZiB0aHJvdWdoXG4vLyBncm91cFZhbHVlc0Zyb21RdWVyeS4gSXQgaXMgYWxzbyB0aGUgcmVwb3J0IFVSTCdzIGtleSBmb3IgdGhlIGdyYWluXG4vLyAocmVwb3J0LXVybC1zdGF0ZS50cykuIFRoZSBncmFpbiB0cmF2ZWxzIHRvIHRoZSBzZXJ2ZXIgYXMgdGhlIGRhdGFcbi8vIHJlcXVlc3QncyBgc3RhdGUuZnJlcXVlbmN5YC5cbmV4cG9ydCBjb25zdCBHUk9VUF9CWV9JVEVNID0gJ2dyb3VwQnknO1xuXG4vLyBBIHNlbGVjdCBncm91cCdzIGRpc3RpbmN0IG9wdGlvbnMsIGFzIHsgbmFtZSwgdmFsdWUgfSBwYWlycy4gVGhlIHNlcnZlciBzZW5kc1xuLy8geyB2YWx1ZSwgbGFiZWwgfTogdGhlIHZhbHVlIGlzIHdoYXQgdGhlIGZpbHRlciBtYXRjaGVzIG9uIChhbiBlbnRpdHkncyBzdGFibGVcbi8vIGlkKSBhbmQgdGhlIGxhYmVsIGlzIHdoYXQgdGhlIHZpZXdlciByZWFkcyDigJQgc28gYSByZW5hbWVkIGVudGl0eSBrZWVwcyBpdHMgaWRcbi8vIGFuZCBzaW1wbHkgc2hvd3MgaXRzIG5ldyBuYW1lIGhlcmUuIE9wdGlvbnMgY29tZSBmcm9tIHRoZSBmaXJzdCBtZW1iZXIgZmlsdGVyXG4vLyB0aGF0IGRlY2xhcmVzIHRoZW0g4oCUIG1lbWJlcnMgYXJlIHRoZSBzYW1lIGRhdGEgcG9pbnQsIHNvIGFueSBtZW1iZXIncyBsaXN0XG4vLyBzZXJ2ZXMgdGhlIGdyb3VwLiBUaGUgbGlzdCBpcyBmZXRjaGVkIG9uY2UgKHRoZSBzZXJ2ZXIgY2FwcyBpdCkgYW5kIHJlcGxheWVkXG4vLyAoc2hhcmVSZXBsYXkpLCBzbyByZXBlYXRlZCByZWFkcyBuZXZlciByZWZldGNoLiBTaGFyZWQgYnkgdGhlIHJlcG9ydC1iYXJcbi8vIHNlbGVjdCBjb250cm9sIGFuZCB0aGUgcmVwb3J0LXNldHRpbmdzIGRlZmF1bHQgcGlja2VyIHNvIHRoZSB0d28gbmV2ZXIgZHJpZnQuXG4vLyBSZXR1cm5zIGFuIGVtcHR5IGxpc3Qgd2hlbiBubyBtZW1iZXIgcHJvdmlkZXMgb3B0aW9ucy5cbmV4cG9ydCBmdW5jdGlvbiBsb2FkR3JvdXBPcHRpb25zKFxuICBncm91cDogUmVwb3J0RmlsdGVyR3JvdXAsXG4gIHJlcG9ydERhdGE6IFJlcG9ydERhdGEsXG4gIHJlcG9ydElkOiBudW1iZXIsXG4pOiBPYnNlcnZhYmxlPHsgbmFtZTogc3RyaW5nOyB2YWx1ZTogdW5rbm93biB9W10+IHtcbiAgY29uc3Qgb3B0aW9uRmlsdGVyID0gKGdyb3VwLmZpbHRlcnMgPz8gW10pLmZpbmQoKG1lbWJlcikgPT4gbWVtYmVyLmhhc09wdGlvbnMpO1xuICBpZiAoIW9wdGlvbkZpbHRlcikge1xuICAgIHJldHVybiBvZihbXSk7XG4gIH1cblxuICByZXR1cm4gcmVwb3J0RGF0YS5maWx0ZXJPcHRpb25zKHJlcG9ydElkLCBvcHRpb25GaWx0ZXIuaWQpXG4gICAgLnBpcGUoXG4gICAgICBtYXAoKG9wdGlvbnM6IFJlcG9ydEZpbHRlck9wdGlvbltdKSA9PiAob3B0aW9ucyA/PyBbXSlcbiAgICAgICAgLm1hcCgob3B0aW9uKSA9PiAoeyBuYW1lOiBvcHRpb24ubGFiZWwsIHZhbHVlOiBvcHRpb24udmFsdWUgfSkpKSxcbiAgICAgIHNoYXJlUmVwbGF5KHsgYnVmZmVyU2l6ZTogMSwgcmVmQ291bnQ6IGZhbHNlIH0pLFxuICAgICk7XG59XG5cbi8vIFN0b3JlZCBmaWx0ZXIgdmFsdWVzIChpZHMpIHBhaXJlZCBiYWNrIHdpdGggdGhlIGxhYmVscyB0byBzaG93IGZvciB0aGVtLlxuLy8gQSBzYXZlZCBkZWZhdWx0IGhvbGRzIG9ubHkgdmFsdWVzLCBzbyB0aGUgbmFtZXMgaGF2ZSB0byBiZSByZWFkIGJhY2sgb2ZmIHRoZVxuLy8gb3B0aW9uIGxpc3Qg4oCUIHRoYXQgaW5kaXJlY3Rpb24gaXMgZXhhY3RseSB3aGF0IHN1cnZpdmVzIGEgcmVuYW1lLiBBIHZhbHVlIHdpdGhcbi8vIG5vIG1hdGNoaW5nIG9wdGlvbiAoaXRzIGVudGl0eSB3YXMgZGVsZXRlZCwgc28gaXQgaXMgbm8gbG9uZ2VyIGxpc3RlZCkgZmFsbHNcbi8vIGJhY2sgdG8gc2hvd2luZyB0aGUgcmF3IHZhbHVlIHJhdGhlciB0aGFuIGRyb3BwaW5nIHRoZSBjaGlwLCB3aGljaCB3b3VsZFxuLy8gc2lsZW50bHkgd2lkZW4gdGhlIGZpbHRlci5cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlT3B0aW9uVmFsdWVzKFxuICBvcHRpb25zJDogT2JzZXJ2YWJsZTx7IG5hbWU6IHN0cmluZzsgdmFsdWU6IHVua25vd24gfVtdPixcbiAgdmFsdWVzOiB1bmtub3duW10sXG4pOiBPYnNlcnZhYmxlPHsgbmFtZTogc3RyaW5nOyB2YWx1ZTogdW5rbm93biB9W10+IHtcbiAgcmV0dXJuIG9wdGlvbnMkLnBpcGUobWFwKChvcHRpb25zKSA9PiB2YWx1ZXMubWFwKCh2YWx1ZSkgPT4ge1xuICAgIGNvbnN0IG9wdGlvbiA9IG9wdGlvbnMuZmluZCgoY2FuZGlkYXRlKSA9PiBTdHJpbmcoY2FuZGlkYXRlLnZhbHVlKSA9PT0gU3RyaW5nKHZhbHVlKSk7XG5cbiAgICByZXR1cm4geyBuYW1lOiBvcHRpb24/Lm5hbWUgPz8gU3RyaW5nKHZhbHVlKSwgdmFsdWUgfTtcbiAgfSkpKTtcbn1cblxuLy8gQ2FzZS1pbnNlbnNpdGl2ZSBuYW1lIGZpbHRlciBhcHBsaWVkIHRvIGEgbG9hZGVkIG9wdGlvbiBsaXN0IOKAlCB0aGUgdHlwZWRcbi8vIGtleXdvcmQgaGFzIHRvIGJlIG1hdGNoZWQgaGVyZSBiZWNhdXNlIGZzLWF1dG9jb21wbGV0ZSByZW5kZXJzIHdoYXQgd2UgcmV0dXJuXG4vLyB2ZXJiYXRpbS5cbmV4cG9ydCBmdW5jdGlvbiBtYXRjaE9wdGlvbnMoXG4gIG9wdGlvbnMkOiBPYnNlcnZhYmxlPHsgbmFtZTogc3RyaW5nOyB2YWx1ZTogdW5rbm93biB9W10+LFxuICBrZXl3b3JkPzogc3RyaW5nLFxuKTogT2JzZXJ2YWJsZTx7IG5hbWU6IHN0cmluZzsgdmFsdWU6IHVua25vd24gfVtdPiB7XG4gIGNvbnN0IHRlcm0gPSAoa2V5d29yZCA/PyAnJykudHJpbSgpLnRvTG93ZXJDYXNlKCk7XG5cbiAgcmV0dXJuIG9wdGlvbnMkLnBpcGUobWFwKChvcHRpb25zKSA9PiB0ZXJtXG4gICAgPyBvcHRpb25zLmZpbHRlcigob3B0aW9uKSA9PiBvcHRpb24ubmFtZS50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKHRlcm0pKVxuICAgIDogb3B0aW9ucykpO1xufVxuXG4vLyBCdWlsZCB0aGUgZnMtZmlsdGVyIGNvbmZpZyBpdGVtIGZvciBhIGdyb3VwLCBzZWVkaW5nIGl0cyBkZWZhdWx0IGZyb20gdGhlXG4vLyBjdXJyZW50IHNlc3Npb24gdmFsdWUgc28gYXV0aG9yZWQvcmVsYXRpdmUgZGVmYXVsdHMgc2hvdyBzZWxlY3RlZCBvbiBvcGVuLlxuZXhwb3J0IGZ1bmN0aW9uIGZpbHRlckl0ZW1Gb3JHcm91cChcbiAgZ3JvdXA6IFJlcG9ydEZpbHRlckdyb3VwLFxuICByZXBvcnREYXRhOiBSZXBvcnREYXRhLFxuICByZXBvcnRJZDogbnVtYmVyLFxuICBpbml0aWFsPzogRmlsdGVyR3JvdXBWYWx1ZSxcbik6IElGaWx0ZXJDb25maWdJdGVtIHtcbiAgY29uc3QgbmFtZSA9IGdyb3VwSXRlbU5hbWUoZ3JvdXApO1xuICBjb25zdCBsYWJlbCA9IGdyb3VwLmxhYmVsIHx8IGdyb3VwLmZpbHRlcnM/LlswXT8uZmlsdGVyQ29sdW1uIHx8ICcnO1xuXG4gIHN3aXRjaCAoZ3JvdXAudHlwZSkge1xuICAgIGNhc2UgJ2RhdGVSYW5nZSc6XG4gICAgICByZXR1cm4ge1xuICAgICAgICBuYW1lLFxuICAgICAgICB0eXBlOiBJdGVtVHlwZS5EYXRlUmFuZ2UsXG4gICAgICAgIGxhYmVsOiB7IGZyb206IGAke2xhYmVsfSBGcm9tYCwgdG86IGAke2xhYmVsfSBUb2AgfSxcbiAgICAgICAgZGVmYXVsdDogKGluaXRpYWw/LnN0YXJ0IHx8IGluaXRpYWw/LmVuZClcbiAgICAgICAgICA/IHsgZnJvbTogaW5pdGlhbC5zdGFydCA/PyB1bmRlZmluZWQsIHRvOiBpbml0aWFsLmVuZCA/PyB1bmRlZmluZWQgfVxuICAgICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgfTtcblxuICAgIGNhc2UgJ3NlbGVjdCc6IHtcbiAgICAgIC8vIE9uZSBzaGFyZWQsIHJlcGxheWVkIG9wdGlvbiBzdHJlYW0gc28gdHlwaW5nIG5ldmVyIHJlZmV0Y2hlcy5cbiAgICAgIGNvbnN0IG9wdGlvbnMkID0gbG9hZEdyb3VwT3B0aW9ucyhncm91cCwgcmVwb3J0RGF0YSwgcmVwb3J0SWQpO1xuICAgICAgY29uc3QgdmFsdWVzID0gaW5pdGlhbD8udmFsdWVzO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBuYW1lLFxuICAgICAgICB0eXBlOiBJdGVtVHlwZS5BdXRvQ29tcGxldGVDaGlwcyxcbiAgICAgICAgbGFiZWwsXG4gICAgICAgIGZldGNoT25Gb2N1czogdHJ1ZSxcbiAgICAgICAgdmFsdWVzOiAoa2V5d29yZD86IHN0cmluZykgPT4gbWF0Y2hPcHRpb25zKG9wdGlvbnMkLCBrZXl3b3JkKSxcbiAgICAgICAgLy8gU3RvcmVkIHZhbHVlcyBhcmUgaWRzLCBzbyB0aGUgY2hpcHMgY2FuIG9ubHkgYmUgbmFtZWQgb25jZSB0aGUgb3B0aW9uXG4gICAgICAgIC8vIGxpc3QgaGFzIGxvYWRlZCDigJQgaGVuY2UgdGhlIG9ic2VydmFibGUgZm9ybSBvZiBgZGVmYXVsdGAuXG4gICAgICAgIGRlZmF1bHQ6IHZhbHVlcz8ubGVuZ3RoXG4gICAgICAgICAgPyAoKSA9PiByZXNvbHZlT3B0aW9uVmFsdWVzKG9wdGlvbnMkLCB2YWx1ZXMpXG4gICAgICAgICAgOiB1bmRlZmluZWQsXG4gICAgICB9O1xuICAgIH1cblxuICAgIGNhc2UgJ2tleXdvcmQnOlxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4ge1xuICAgICAgICBuYW1lLFxuICAgICAgICB0eXBlOiBJdGVtVHlwZS5LZXl3b3JkLFxuICAgICAgICBsYWJlbCxcbiAgICAgICAgZGVmYXVsdDogaW5pdGlhbD8udmFsdWUsXG4gICAgICB9O1xuICB9XG59XG5cbi8vIFRoZSBxdWVyeSBrZXkgb2YgYSBsaXN0J3Mgc2VhcmNoIGJveCBpbiBpdHMgY29tcG9uZW50IGhlYWRlci4gRml4ZWQgcmF0aGVyXG4vLyB0aGFuIGRlcml2ZWQgZnJvbSBhbiBpZCBiZWNhdXNlIGEgaGVhZGVyIGhvbGRzIGF0IG1vc3Qgb25lLCBhbmQgaXQgaXMgTk9UIGFcbi8vIGZpbHRlciBncm91cDogaXRzIHRleHQgbmFycm93cyB0aGF0IGxpc3QgYWxvbmUsIHNvIGl0IGlzIHJlYWQgc3RyYWlnaHQgb2ZmXG4vLyB0aGUgY2hhbmdlIHF1ZXJ5IGFuZCB0cmF2ZWxzIGFzIHRoZSBsaXN0J3Mgb3duIGBzdGF0ZS5zZWFyY2hgLlxuZXhwb3J0IGNvbnN0IExJU1RfU0VBUkNIX0lURU0gPSAnbGlzdFNlYXJjaCc7XG5cbi8vIFRoZSBsb25nZXN0IHNlYXJjaCB0aGUgc2VydmVyIGFwcGxpZXMgKFJlcG9ydFF1ZXJ5UnVubmVyOjpNQVhfU0VBUkNIX0xFTkdUSCkuXG4vLyBUaGUgdmlld2VyIGN1dHMgdGhlIHRleHQgdG8gaXQgdG9vLCBzbyB0aGUgVVJMLCB0aGUgcmVxdWVzdCBhbmQgdGhlIGV4cG9ydFxuLy8gdGl0bGUgYWxsIGNhcnJ5IHRoZSB0ZXh0IHRoYXQgd2FzIGFjdHVhbGx5IHNlYXJjaGVkLlxuZXhwb3J0IGNvbnN0IExJU1RfU0VBUkNIX01BWF9MRU5HVEggPSAxMDA7XG5cbi8vIFRoZSBmcy1maWx0ZXIgY29uZmlnIGl0ZW0gZm9yIGEgbGlzdCdzIHNlYXJjaCBib3gsIHNlZWRlZCB3aXRoIHRoZSB0ZXh0IHRoZVxuLy8gdmlld2VyIGxhc3Qgc2VhcmNoZWQuIGZzLWZpbHRlciBzaG93cyBvbmUgc2VhcmNoIGJveCBwZXIgYmFyIChpdHMgbGFzdFxuLy8ga2V5d29yZCBpdGVtKSwgc28gdGhlIGNhbGxlciBhZGRzIHRoaXMgb25seSB0byBhIGhlYWRlciB3aXRoIG5vIGtleXdvcmRcbi8vIGdyb3VwIG9mIGl0cyBvd24uXG5leHBvcnQgZnVuY3Rpb24gbGlzdFNlYXJjaEl0ZW0odmFsdWU6IHN0cmluZyB8IG51bGwpOiBJRmlsdGVyQ29uZmlnSXRlbSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogSXRlbVR5cGUuS2V5d29yZCxcbiAgICBuYW1lOiBMSVNUX1NFQVJDSF9JVEVNLFxuICAgIGxhYmVsOiAnU2VhcmNoJyxcbiAgICBkZWZhdWx0OiB2YWx1ZSA/PyB1bmRlZmluZWQsXG4gIH07XG59XG5cbi8vIFdoZXRoZXIgdGhlIHJlcG9ydCBoYXMgYSBjaGFydCB0aGUgZ3JvdXAtYnkgY29udHJvbCBjYW4gcmUtYnVja2V0LiBBIHRpbWVcbi8vIHgtYXhpcyBpcyB0aGUgd2hvbGUgcXVhbGlmaWNhdGlvbjogdGhlIGNvbnRyb2wgY2hhbmdlcyB0aGUgZ3JhaW4gb2YgdGhhdFxuLy8gYXhpcywgYW5kIGEgY2F0ZWdvcnkgYXhpcyBoYXMgbm8gZ3JhaW4gdG8gY2hhbmdlLlxuZXhwb3J0IGZ1bmN0aW9uIGhhc1RpbWVTZXJpZXNDaGFydChyZXBvcnQ6IFJlcG9ydCB8IG51bGwpOiBib29sZWFuIHtcbiAgcmV0dXJuIChyZXBvcnQ/LnBhZ2VzID8/IFtdKS5zb21lKChwYWdlKSA9PiAocGFnZS5jb21wb25lbnRzID8/IFtdKS5zb21lKChjb21wb25lbnQpID0+XG4gICAgY29tcG9uZW50LnR5cGUgPT09ICdjaGFydCcgJiYgY29tcG9uZW50LmNvbmZpZz8ueEF4aXM/LmtpbmQgPT09ICd0aW1lJykpO1xufVxuXG4vLyBUaGUgZ3JhaW5zIHRoZSByZXBvcnQncyBncm91cC1ieSBjb250cm9sIG9mZmVycywgbmFtZWQgZm9yIHRoZSB2aWV3ZXIuIFdISUNIXG4vLyBvZiB0aGVtIGNvbWVzIGZyb20gdGhlIHJlcG9ydDsgaG93IHRoZXkgcmVhZCBjb21lcyBmcm9tIEdSQU5VTEFSSVRZX09QVElPTlMuXG4vLyBBbiBlbXB0eSBzdG9yZWQgbGlzdCBtZWFucyBldmVyeSBncmFpbiDigJQgdGhlIHNhbWUgcnVsZSB0aGUgYmFja2VuZCBhcHBsaWVzLlxuZnVuY3Rpb24gZ3JvdXBCeU9wdGlvbnMocmVwb3J0OiBSZXBvcnQpOiB7IHZhbHVlOiBDaGFydEdyYW51bGFyaXR5OyBuYW1lOiBzdHJpbmcgfVtdIHtcbiAgY29uc3QgZ3JhbnVsYXJpdGllcyA9IHJlcG9ydC5jb25maWc/Lmdyb3VwQnk/LmdyYW51bGFyaXRpZXMgPz8gW107XG5cbiAgcmV0dXJuIGdyYW51bGFyaXRpZXMubGVuZ3RoXG4gICAgPyBHUkFOVUxBUklUWV9PUFRJT05TLmZpbHRlcigob3B0aW9uKSA9PiBncmFudWxhcml0aWVzLmluY2x1ZGVzKG9wdGlvbi52YWx1ZSkpXG4gICAgOiBHUkFOVUxBUklUWV9PUFRJT05TO1xufVxuXG4vLyBXaGV0aGVyIGEgZ3JhaW4gaXMgb25lIHRoZSByZXBvcnQncyBjb250cm9sIHN0aWxsIG9mZmVycy4gQSBncmFpbiBpdCBkb2Vzbid0XG4vLyBjYW5ub3Qgc3RheSBpbiBlZmZlY3Q6IHRoZSBhZ2VudCBjYW4gbmFycm93IHRoZSBsaXN0IGF0IGFueSB0aW1lLCBhbmQgYSBjaGFydFxuLy8gbGVmdCBidWNrZXRpbmcgYXQgYSBkcm9wcGVkIGdyYWluIGlzIG9uZSB0aGUgdmlld2VyIGNhbiBuZWl0aGVyIHNlZSBub3IgY2hhbmdlLlxuZXhwb3J0IGZ1bmN0aW9uIGlzR3JhbnVsYXJpdHlPZmZlcmVkKHJlcG9ydDogUmVwb3J0LCBncmFudWxhcml0eTogQ2hhcnRHcmFudWxhcml0eSB8IG51bGwpOiBib29sZWFuIHtcbiAgcmV0dXJuICFncmFudWxhcml0eSB8fCBncm91cEJ5T3B0aW9ucyhyZXBvcnQpLnNvbWUoKG9wdGlvbikgPT4gb3B0aW9uLnZhbHVlID09PSBncmFudWxhcml0eSk7XG59XG5cbi8vIFRoZSBmcy1maWx0ZXIgY29uZmlnIGl0ZW0gZm9yIHRoZSByZXBvcnQncyBncm91cC1ieSBjb250cm9sLCBvciBudWxsIHdoZW4gdGhlXG4vLyByZXBvcnQgaGFzIG5vbmUgdG8gc2hvdy5cbi8vXG4vLyBJdCBsZWFkcyB0aGUgc2FtZSBiYXIgdGhlIGZpbHRlcnMgcmVuZGVyIGluLCBidXQgaXQgaXMgTk9UIG9uZTogYSBmaWx0ZXJcbi8vIG5hcnJvd3MgV0hJQ0ggcm93cyBhcmUgY291bnRlZCwgdGhpcyBjaGFuZ2VzIGhvdyB0aGUgc3Vydml2aW5nIHJvd3MgYXJlXG4vLyBCVUNLRVRFRCDigJQgYW5kIGl0IGNvbWVzIGZpcnN0IGJlY2F1c2UgdGhlIGdyYWluIGlzIHdoYXQgYSB2aWV3ZXIgc2V0dGxlc1xuLy8gYmVmb3JlIGRlY2lkaW5nIHdoaWNoIHJvd3MgdGhleSB3YW50LlxuLy8gUGlja2luZyBhIGdyYWluIHNldHMgYSBzZXNzaW9uLXdpZGUgb3ZlcnJpZGUgdGhhdCByaWRlcyBhbG9uZyBpbiBlYWNoIGNoYXJ0J3Ncbi8vIGRhdGEgcmVxdWVzdCwgc28gdGhlIGNoYXJ0cyB0aGVtc2VsdmVzIGFyZSBuZXZlciByZXdyaXR0ZW4uXG5leHBvcnQgZnVuY3Rpb24gZ3JvdXBCeUZpbHRlckl0ZW0oXG4gIHJlcG9ydDogUmVwb3J0LFxuICBpbml0aWFsPzogQ2hhcnRHcmFudWxhcml0eSB8IG51bGwsXG4pOiBJRmlsdGVyQ29uZmlnSXRlbSB8IG51bGwge1xuICBjb25zdCBncm91cEJ5ID0gcmVwb3J0LmNvbmZpZz8uZ3JvdXBCeTtcblxuICAvLyBPbmx5IGFuIEVYUExJQ0lUIGZhbHNlIGhpZGVzIHRoZSBjb250cm9sLiBBbiBhYnNlbnQgYmxvY2sgbWVhbnMgYSByZXBvcnRcbiAgLy8gc2VydmVkIGJ5IGEgYnVpbGQgdGhhdCBwcmVkYXRlcyB0aGUgY29udHJvbCBiZWluZyBzdG9yZWQsIGFuZCBldmVyeSBvbmUgb2ZcbiAgLy8gdGhvc2UgaGFkIG9uZSDigJQgdGhlIGJhY2tlbmQgcmVzb2x2ZXMgaXQgdGhlIHNhbWUgd2F5IChSZXBvcnRHcm91cEJ5KS5cbiAgaWYgKGdyb3VwQnk/LmVuYWJsZWQgPT09IGZhbHNlIHx8ICFoYXNUaW1lU2VyaWVzQ2hhcnQocmVwb3J0KSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgdmFsdWVzID0gZ3JvdXBCeU9wdGlvbnMocmVwb3J0KTtcblxuICByZXR1cm4ge1xuICAgIG5hbWU6IEdST1VQX0JZX0lURU0sXG4gICAgdHlwZTogSXRlbVR5cGUuU2VsZWN0LFxuICAgIGxhYmVsOiBncm91cEJ5Py5sYWJlbCB8fCAnR3JvdXAgQnknLFxuICAgIG11bHRpcGxlOiBmYWxzZSxcbiAgICB2YWx1ZXM6ICgpID0+IHZhbHVlcyxcbiAgICBkZWZhdWx0OiBpc0dyYW51bGFyaXR5T2ZmZXJlZChyZXBvcnQsIGluaXRpYWwgPz8gbnVsbCkgPyAoaW5pdGlhbCA/PyB1bmRlZmluZWQpIDogdW5kZWZpbmVkLFxuICB9O1xufVxuXG4vLyBUaGUgZ3JvdXAtYnkgY29udHJvbCdzIGNvbnRyaWJ1dGlvbiB0byB0aGUgdG9vbGJhcidzIGZzLWZpbHRlciBrZXkuIGZzLWZpbHRlclxuLy8gcmVhZHMgaXRzIGNvbmZpZyBvbmNlIGF0IGluaXQsIGFuZCB0aGUgYWdlbnQgY2FuIGNoYW5nZSB0aGUgY29udHJvbCdzIGxhYmVsXG4vLyBvciB0aGUgZ3JhaW5zIGl0IG9mZmVycyDigJQgd2l0aG91dCB0aG9zZSBpbiB0aGUga2V5IHRoZSBiYXIga2VlcHMgcmVuZGVyaW5nXG4vLyB0aGUgY29udHJvbCBpdCB3YXMgY3JlYXRlZCB3aXRoIHVudGlsIGEgZnVsbCBwYWdlIHJlbG9hZC5cbmV4cG9ydCBmdW5jdGlvbiBncm91cEJ5U2lnbmF0dXJlKHJlcG9ydDogUmVwb3J0IHwgbnVsbCk6IHN0cmluZyB7XG4gIGlmICghcmVwb3J0IHx8ICFncm91cEJ5RmlsdGVySXRlbShyZXBvcnQpKSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgY29uc3QgZ3JvdXBCeSA9IHJlcG9ydC5jb25maWc/Lmdyb3VwQnk7XG5cbiAgcmV0dXJuIFsnZ3JvdXBCeScsIGdyb3VwQnk/LmxhYmVsID8/ICcnLCAoZ3JvdXBCeT8uZ3JhbnVsYXJpdGllcyA/PyBbXSkuam9pbignLCcpXS5qb2luKCc6Jyk7XG59XG5cbi8vIFJlYWQgYW4gZnMtZmlsdGVyIGNoYW5nZSBxdWVyeSBpbnRvIHBlci1ncm91cCB2YWx1ZXMuIFJldHVybnMgb25lIGVudHJ5IHBlclxuLy8gZ3JvdXAgd2l0aCB0aGUgdmFsdWUgdG8gc3RvcmUgKG9yIG51bGwgdG8gY2xlYXIpIOKAlCBjYWxsZXJzIGZlZWQgdGhlc2UgdG9cbi8vIFJlcG9ydEZpbHRlclN0YXRlU2VydmljZS5zZXRWYWx1ZS5cbmV4cG9ydCBmdW5jdGlvbiBncm91cFZhbHVlc0Zyb21RdWVyeShcbiAgcXVlcnk6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gIGdyb3VwczogUmVwb3J0RmlsdGVyR3JvdXBbXSxcbik6IHsgZ3JvdXBJZDogbnVtYmVyOyB2YWx1ZTogRmlsdGVyR3JvdXBWYWx1ZSB8IG51bGwgfVtdIHtcbiAgcmV0dXJuIGdyb3Vwcy5tYXAoKGdyb3VwKSA9PiB7XG4gICAgY29uc3QgbmFtZSA9IGdyb3VwSXRlbU5hbWUoZ3JvdXApO1xuXG4gICAgaWYgKGdyb3VwLnR5cGUgPT09ICdkYXRlUmFuZ2UnKSB7XG4gICAgICBjb25zdCBzdGFydCA9IHF1ZXJ5W2Ake25hbWV9RnJvbWBdO1xuICAgICAgY29uc3QgZW5kID0gcXVlcnlbYCR7bmFtZX1Ub2BdO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBncm91cElkOiBncm91cC5pZCxcbiAgICAgICAgdmFsdWU6IChzdGFydCB8fCBlbmQpID8geyBzdGFydDogc3RhcnQgfHwgbnVsbCwgZW5kOiBlbmQgfHwgbnVsbCB9IDogbnVsbCxcbiAgICAgIH07XG4gICAgfVxuXG4gICAgaWYgKGdyb3VwLnR5cGUgPT09ICdzZWxlY3QnKSB7XG4gICAgICBjb25zdCB2YWx1ZXMgPSBzZWxlY3RRdWVyeVZhbHVlcyhxdWVyeVtuYW1lXSk7XG5cbiAgICAgIHJldHVybiB7IGdyb3VwSWQ6IGdyb3VwLmlkLCB2YWx1ZTogdmFsdWVzLmxlbmd0aCA/IHsgdmFsdWVzIH0gOiBudWxsIH07XG4gICAgfVxuXG4gICAgY29uc3Qga2V5d29yZCA9IFN0cmluZyhxdWVyeVtuYW1lXSA/PyAnJykudHJpbSgpO1xuXG4gICAgcmV0dXJuIHsgZ3JvdXBJZDogZ3JvdXAuaWQsIHZhbHVlOiBrZXl3b3JkID8geyB2YWx1ZToga2V5d29yZCB9IDogbnVsbCB9O1xuICB9KTtcbn1cblxuLy8gZnMtZmlsdGVyJ3MgQXV0b0NvbXBsZXRlQ2hpcHMgc2VyaWFsaXNlcyBhIG11bHRpLXNlbGVjdCBpbnRvIE9ORSBxdWVyeSB2YWx1ZTpcbi8vIHRoZSBzZWxlY3RlZCB2YWx1ZXMgam9pbmVkIGJ5IFwiLFwiIChpdHMgYHF1ZXJ5YCBnZXR0ZXIgZG9lcyBgLm1hcCh2YWx1ZSkuam9pbignLCcpYCkuXG4vLyBTbyBhIDIrIHNlbGVjdGlvbiBhcnJpdmVzIGFzIHRoZSBzdHJpbmcgXCJhLGJcIiwgbm90IGFuIGFycmF5IOKAlCBzcGxpdHRpbmcgb24gXCIsXCJcbi8vIHJldmVyc2VzIHRoYXQgZmFpdGhmdWxseS4gV2l0aG91dCB0aGlzLCBhIG11bHRpLXNlbGVjdCB3YXMgc2VudCBhcyB0aGUgc2luZ2xlXG4vLyB2YWx1ZSBbXCJhLGJcIl0sIHByb2R1Y2luZyBgY29sIElOICgnYSxiJylgIHNlcnZlci1zaWRlLCB3aGljaCBtYXRjaGVzIG5vdGhpbmcuXG5mdW5jdGlvbiBzZWxlY3RRdWVyeVZhbHVlcyhyYXc6IHVua25vd24pOiB1bmtub3duW10ge1xuICBpZiAoQXJyYXkuaXNBcnJheShyYXcpKSB7XG4gICAgcmV0dXJuIHJhdztcbiAgfVxuXG4gIGlmIChyYXcgPT09IG51bGwgfHwgcmF3ID09PSB1bmRlZmluZWQgfHwgcmF3ID09PSAnJykge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIHJldHVybiBTdHJpbmcocmF3KS5zcGxpdCgnLCcpO1xufVxuIl19
|
|
473
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LWZpbHRlci1pdGVtcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy9yZXBvcnQtZmlsdGVyLWl0ZW1zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBcUIsUUFBUSxFQUFFLGNBQWMsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRWpGLE9BQU8sRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sVUFBVSxDQUFDO0FBRTVDLE9BQU8sRUFBYyxFQUFFLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDdEMsT0FBTyxFQUFFLEdBQUcsRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUdsRCxPQUFPLEVBQUUsY0FBYyxFQUFFLGFBQWEsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQzdFLE9BQU8sRUFBRSxTQUFTLEVBQUUsZUFBZSxFQUFFLG9CQUFvQixFQUFFLE1BQU0sVUFBVSxDQUFDO0FBSTVFLE9BQU8sRUFDK0IsbUJBQW1CLEdBRXhELE1BQU0sK0JBQStCLENBQUM7QUFDdkMsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBSXpELDJFQUEyRTtBQUMzRSw0RUFBNEU7QUFDNUUseUVBQXlFO0FBQ3pFLE1BQU0sVUFBVSxlQUFlLENBQUMsS0FBdUM7SUFDckUsSUFBSSxLQUFLLFlBQVksSUFBSSxFQUFFLENBQUM7UUFDMUIsT0FBTyxNQUFNLENBQUMsS0FBSyxFQUFFLFlBQVksQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRCxzRUFBc0U7SUFDdEUsOEJBQThCO0lBQzlCLE9BQU8sS0FBSyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0FBQ3hELENBQUM7QUFHRCw4RUFBOEU7QUFDOUUsK0VBQStFO0FBQy9FLDhFQUE4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QUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ2hDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJRmlsdGVyQ29uZmlnSXRlbSwgSXRlbVR5cGUsIGdldEV4Y2x1ZGVOYW1lIH0gZnJvbSAnQGZpcmVzdGl0Y2gvZmlsdGVyJztcblxuaW1wb3J0IHsgZm9ybWF0LCBwYXJzZUlTTyB9IGZyb20gJ2RhdGUtZm5zJztcblxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgb2YgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IG1hcCwgc2hhcmVSZXBsYXkgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IFJlcG9ydERhdGEgfSBmcm9tICcuL2RhdGEvcmVwb3J0LmRhdGEnO1xuaW1wb3J0IHsgZmlsdGVyTGluZVRleHQsIG1hdGNoTGluZVRleHQgfSBmcm9tICcuL2V4cG9ydC9yZXBvcnQtZmlsdGVyLWxpbmVzJztcbmltcG9ydCB7IERBWV9TSE9SVCwgZm9ybWF0TG9jYWxEYXRlLCByZXNvbHZlRm9ybWF0Q29udGV4dCB9IGZyb20gJy4vZm9ybWF0JztcbmltcG9ydCB7IFJlcG9ydEZpbHRlck1hdGNoIH0gZnJvbSAnLi9pbnRlcmZhY2VzL3JlcG9ydC1maWx0ZXItbWF0Y2gudHlwZSc7XG5pbXBvcnQgeyBSZXBvcnRGaWx0ZXJPcHRpb25QYWlyIH0gZnJvbSAnLi9pbnRlcmZhY2VzL3JlcG9ydC1maWx0ZXItb3B0aW9uLXBhaXIuaW50ZXJmYWNlJztcbmltcG9ydCB7IFJlcG9ydFZpZXdlckZlYXR1cmUgfSBmcm9tICcuL2ludGVyZmFjZXMvcmVwb3J0LXZpZXdlci1mZWF0dXJlLnR5cGUnO1xuaW1wb3J0IHtcbiAgQ2hhcnRHcmFudWxhcml0eSwgRmlsdGVyR3JvdXBWYWx1ZSwgR1JBTlVMQVJJVFlfT1BUSU9OUywgUmVwb3J0LCBSZXBvcnRGaWx0ZXJHcm91cCwgUmVwb3J0RmlsdGVyTGV2ZWwsXG4gIFJlcG9ydEZpbHRlck9wdGlvbiwgUmVwb3J0RmlsdGVyVHlwZSwgUmVwb3J0TG9jYWxlVGFnLFxufSBmcm9tICcuL2ludGVyZmFjZXMvcmVwb3J0LmludGVyZmFjZSc7XG5pbXBvcnQgeyBvZmZlcnNFeGNsdWRlIH0gZnJvbSAnLi9yZXBvcnQtdmlld2VyLWZlYXR1cmVzJztcbmltcG9ydCB7IFJlcG9ydEZpbHRlck9wdGlvbnNTZXJ2aWNlIH0gZnJvbSAnLi9zZXJ2aWNlcy9yZXBvcnQtZmlsdGVyLW9wdGlvbnMuc2VydmljZSc7XG5cblxuLy8gQSBkYXRlLXJhbmdlIGJvdW5kYXJ5IGFzIHRoZSBwaWNrZWQgTE9DQUwgY2FsZW5kYXIgZGF5IChubyB0aW1lLCBubyB0eikuXG4vLyBEYXRlLXJhbmdlIGZpbHRlcnMgYXJlIGNhbGVuZGFyLWRheSBzZW1hbnRpY3MsIHNvIHRoZSBib3VuZGFyeSBtdXN0IGNhcnJ5XG4vLyBvbmx5IFktTS1EIOKAlCBuZXZlciBhIHRpbWV6b25lLWJlYXJpbmcgaW5zdGFudCB0aGUgYmFja2VuZCB3b3VsZCBzaGlmdC5cbmV4cG9ydCBmdW5jdGlvbiBkYXRlQm91bmRTdHJpbmcodmFsdWU6IERhdGUgfCBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgIHJldHVybiBmb3JtYXQodmFsdWUsICd5eXl5LU1NLWRkJyk7XG4gIH1cblxuICAvLyBBdXRob3JlZC9yZWxhdGl2ZSBkZWZhdWx0cyBhcnJpdmUgYXMgc3RyaW5ncyBhbHJlYWR5IGluIFktTS1EIGZvcm07XG4gIC8vIGtlZXAganVzdCB0aGUgZGF0ZSBwb3J0aW9uLlxuICByZXR1cm4gdmFsdWUgPyBTdHJpbmcodmFsdWUpLnNsaWNlKDAsIDEwKSA6IHVuZGVmaW5lZDtcbn1cblxuXG4vLyBBIGRhdGUtcmFuZ2UgYm91bmRhcnkgYXMgaXQgc2hvdWxkIFJFQUQgb24gYSBjb3ZlciBwYWdlIOKAlCB0aGUgc2FtZSBjYWxlbmRhclxuLy8gZGF5IGRhdGVCb3VuZFN0cmluZygpIGhhbmRzIHRoZSBzZXJ2ZXIsIHNvIGEgcHJpbnRlZCBwZXJpb2QgY2FuIG5ldmVyIG5hbWUgYVxuLy8gZGlmZmVyZW50IGRheSB0aGFuIHRoZSBudW1iZXJzIHVuZGVyIGl0IHdlcmUgZmlsdGVyZWQgYnkuIFJldHVybnMgbnVsbCB3aGVuXG4vLyB0aGVyZSBpcyBubyBib3VuZGFyeTsgdGhlIGNhbGxlciBzdXBwbGllcyBpdHMgb3duIHBsYWNlaG9sZGVyLlxuLy9cbi8vIFRoZSBwYXJzZSBoYXMgdG8gYmUgcGFyc2VJU08sIG5vdCBgbmV3IERhdGVgOiBgbmV3IERhdGUoJzIwMjYtMDUtMDEnKWAgaXMgVVRDXG4vLyBtaWRuaWdodCwgc28gZm9ybWF0dGluZyBpdCBhbnl3aGVyZSB3ZXN0IG9mIFVUQyBwcmludHMgQXByIDMwLiBwYXJzZUlTTyByZWFkc1xuLy8gYSBiYXJlIFktTS1EIGFzIExPQ0FMIG1pZG5pZ2h0LCB3aGljaCBubyBvZmZzZXQgY2FuIHNoaWZ0LlxuLy9cbi8vIFRoZSBkYXkgaXMgd3JpdHRlbiBpbiB0aGUgcmVwb3J0J3MgbG9jYWxlLCBhcyBpdHMgZGF0ZSBjZWxscyBhcmU6ICdKYW4gNSxcbi8vIDIwMjYnIGluIGVuLVVTLCAnNSBqYW52LiAyMDI2JyBpbiBmci1DQS5cbmV4cG9ydCBmdW5jdGlvbiBkYXRlQm91bmRMYWJlbCh2YWx1ZTogRGF0ZSB8IHN0cmluZyB8IG51bGwgfCB1bmRlZmluZWQsIGxvY2FsZTogUmVwb3J0TG9jYWxlVGFnKTogc3RyaW5nIHwgbnVsbCB7XG4gIGNvbnN0IGJvdW5kID0gZGF0ZUJvdW5kU3RyaW5nKHZhbHVlKTtcblxuICBpZiAoIWJvdW5kKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBkYXRlID0gcGFyc2VJU08oYm91bmQpO1xuXG4gIHJldHVybiBOdW1iZXIuaXNOYU4oZGF0ZS5nZXRUaW1lKCkpID8gU3RyaW5nKHZhbHVlKSA6IGZvcm1hdExvY2FsRGF0ZShkYXRlLCBsb2NhbGUsIERBWV9TSE9SVCk7XG59XG5cblxuLy8gQSBzdG9yZWQgeXl5eS1NTS1kZCBib3VuZGFyeSBhcyBhIGxvY2FsIERhdGUgZm9yIGEgZGF0ZSBwaWNrZXIsIG9yIG51bGwuXG4vLyBwYXJzZUlTTyByZWFkcyBhIGJhcmUgWS1NLUQgYXMgTE9DQUwgbWlkbmlnaHQsIHNvIHRoZSBwaWNrZXIgc2hvd3MgdGhlIGRheVxuLy8gdGhhdCB3YXMgc3RvcmVkLCB3aGF0ZXZlciB0aGUgYnJvd3NlcidzIHpvbmUuXG5leHBvcnQgZnVuY3Rpb24gZGF0ZUZyb21Cb3VuZCh2YWx1ZTogc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZCk6IERhdGUgfCBudWxsIHtcbiAgaWYgKCF2YWx1ZSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgZGF0ZSA9IHBhcnNlSVNPKHZhbHVlLnNsaWNlKDAsIDEwKSk7XG5cbiAgcmV0dXJuIE51bWJlci5pc05hTihkYXRlLmdldFRpbWUoKSkgPyBudWxsIDogZGF0ZTtcbn1cblxuXG4vLyBBIHBpY2tlZCBEYXRlIGFzIGEgeXl5eS1NTS1kZCBib3VuZGFyeSBmb3Igc3RvcmFnZSwgb3IgbnVsbC4gVXNlcyB0aGUgbG9jYWxcbi8vIGNhbGVuZGFyIGRheSAoZm9ybWF0LCBub3QgdG9JU09TdHJpbmcpIHNvIHRoZSBib3VuZGFyeSBpcyB0aGUgZGF5IHRoYXQgd2FzXG4vLyBwaWNrZWQsIHJlZ2FyZGxlc3Mgb2YgdGhlIGJyb3dzZXIncyB6b25lLlxuZXhwb3J0IGZ1bmN0aW9uIGRhdGVUb0JvdW5kKHZhbHVlOiBEYXRlIHwgbnVsbCB8IHVuZGVmaW5lZCk6IHN0cmluZyB8IG51bGwge1xuICByZXR1cm4gdmFsdWUgaW5zdGFuY2VvZiBEYXRlICYmICFOdW1iZXIuaXNOYU4odmFsdWUuZ2V0VGltZSgpKVxuICAgID8gZm9ybWF0KHZhbHVlLCAneXl5eS1NTS1kZCcpXG4gICAgOiBudWxsO1xufVxuXG5cbi8vIEEgcmVsYXRpdmUgZGF0ZS1yYW5nZSBwcmVzZXQga2V5IGFzIGEgc2VudGVuY2UtY2FzZSBsYWJlbCwgZGVyaXZlZCBmcm9tIHRoZVxuLy8gY2FtZWxDYXNlIGtleSBpdHNlbGYgKCdsYXN0MTJNb250aHMnIHJlYWRzICdMYXN0IDEyIG1vbnRocycsICd0aGlzV2Vlaydcbi8vIHJlYWRzICdUaGlzIHdlZWsnKSwgc28gbm8gbGlzdCBvZiBwcmVzZXRzIGlzIG1pcnJvcmVkIGhlcmUgYW5kIGEga2V5IHRoZVxuLy8gc2VydmVyIGFkZHMgbGF0ZXIgc3RpbGwgcmVhZHMgc2Vuc2libHkuXG5leHBvcnQgZnVuY3Rpb24gcmVsYXRpdmVMYWJlbChyZWxhdGl2ZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3Qgd29yZHMgPSByZWxhdGl2ZVxuICAgIC5yZXBsYWNlKC8oW2Etel0pKFtBLVowLTldKS9nLCAnJDEgJDInKVxuICAgIC5yZXBsYWNlKC8oXFxkKShbQS1aXSkvZywgJyQxICQyJylcbiAgICAudG9Mb3dlckNhc2UoKTtcblxuICByZXR1cm4gd29yZHMuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyB3b3Jkcy5zbGljZSgxKTtcbn1cblxuXG4vLyBNYXBzIGEgcmVwb3J0IGZpbHRlciBHUk9VUCB0byBhbiBmcy1maWx0ZXIgY29uZmlnIGl0ZW0sIGFuZCByZWFkcyBmcy1maWx0ZXJcbi8vIHF1ZXJ5IHZhbHVlcyBiYWNrIGludG8gcGVyLWdyb3VwIEZpbHRlckdyb3VwVmFsdWVzLiBTaGFyZWQgYnkgdGhlIHJlcG9ydC1iYXJcbi8vIGZzLWZpbHRlciBhbmQgdGhlIHBlci1jb21wb25lbnQgZnMtZmlsdGVyIHNvIGJvdGggcmVuZGVyIHRocm91Z2ggdGhlIHNhbWVcbi8vIGxpYnJhcnkgYW5kIHdyaXRlIGludG8gUmVwb3J0RmlsdGVyU3RhdGVTZXJ2aWNlIGlkZW50aWNhbGx5LiBJdGVtcyBhcmUgbmFtZWRcbi8vIGJ5IHRoZSBncm91cCdzIGlkIChncm91cEl0ZW1OYW1lKSwgc28gdGhlIHF1ZXJ5IGtleXMgbWFwIHN0cmFpZ2h0IGJhY2sgdG9cbi8vIHRoZSBncm91cC4gQSByZXBvcnQgbmV2ZXIgcHV0cyB0aGVzZSBrZXlzIGluIHRoZSBicm93c2VyIFVSTDogZnMtZmlsdGVyJ3Ncbi8vIG93biBxdWVyeS1wYXJhbSBzeW5jaW5nIGlzIG9mZiBpbiBldmVyeSByZXBvcnQgYmFyLlxuXG4vLyBUaGUgcXVlcnkga2V5IGZvciB0aGUgcmVwb3J0J3MgZ3JvdXAtYnkgY29udHJvbC4gRml4ZWQgcmF0aGVyIHRoYW4gZGVyaXZlZFxuLy8gZnJvbSBhbiBpZCBiZWNhdXNlIGEgcmVwb3J0IGhhcyBleGFjdGx5IG9uZSDigJQgYW5kIGl0IGlzIE5PVCBhIGZpbHRlciBncm91cCxcbi8vIHNvIGl0IGlzIHJlYWQgc3RyYWlnaHQgb2ZmIHRoZSBjaGFuZ2UgcXVlcnkgaW5zdGVhZCBvZiB0aHJvdWdoXG4vLyBncm91cFZhbHVlc0Zyb21RdWVyeS4gVGhlIGdyYWluIHRyYXZlbHMgdG8gdGhlIHNlcnZlciBhcyB0aGUgZGF0YSByZXF1ZXN0J3Ncbi8vIGBzdGF0ZS5mcmVxdWVuY3lgLlxuZXhwb3J0IGNvbnN0IEdST1VQX0JZX0lURU0gPSAnZ3JvdXBCeSc7XG5cbi8vIFRoZSB3b3JkIGJlZm9yZSBhIGdyb3VwJ3MgaWQgaW4gdGhlIG5hbWUgb2YgaXRzIGZzLWZpbHRlciBpdGVtIChmaWx0ZXIxMikuXG5jb25zdCBJVEVNX05BTUVfV09SRCA9ICdmaWx0ZXInO1xuXG4vLyBUaGUgZW5kcyBvZiBhbiBmcy1maWx0ZXIgcmFuZ2UgaXRlbTogUmFuZ2Ugd3JpdGVzIDxuYW1lPk1pbiBhbmQgPG5hbWU+TWF4LFxuLy8gRGF0ZVJhbmdlIDxuYW1lPkZyb20gYW5kIDxuYW1lPlRvLlxuZXhwb3J0IHR5cGUgSXRlbVJhbmdlRW5kID0gJ21pbicgfCAnbWF4JyB8ICdmcm9tJyB8ICd0byc7XG5cbi8vIFRoZSBxdWVyeSBrZXkgb2Ygb25lIGVuZCBvZiBhbiBmcy1maWx0ZXIgcmFuZ2UgaXRlbTogdGhlIGl0ZW0ncyBuYW1lIGFuZFxuLy8gdGhlIGVuZCB3aXRoIGl0cyBmaXJzdCBsZXR0ZXIgdXBwZXItY2FzZWQgKGZzLWZpbHRlcidzIGdldFJhbmdlTmFtZSksIHNvXG4vLyBmaWx0ZXIxMiBnaXZlcyBmaWx0ZXIxMk1pbiBhbmQgZmlsdGVyMTJGcm9tLlxuZXhwb3J0IGZ1bmN0aW9uIGl0ZW1SYW5nZU5hbWUobmFtZTogc3RyaW5nLCBlbmQ6IEl0ZW1SYW5nZUVuZCk6IHN0cmluZyB7XG4gIHJldHVybiBgJHtuYW1lfSR7ZW5kLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpfSR7ZW5kLnNsaWNlKDEpfWA7XG59XG5cbi8vIFRoZSBuYW1lIG9mIGEgZ3JvdXAncyBmcy1maWx0ZXIgaXRlbTogJ2ZpbHRlcicgYW5kIHRoZSBncm91cCdzIGlkLiBUaGUgaWRcbi8vIG5ldmVyIGNoYW5nZXMsIHNvIG5laXRoZXIgYSBuZXcgbGFiZWwgbm9yIGEgbmV3IG5hbWUgbW92ZXMgYSBiYXIncyBrZXlzLFxuLy8gYW5kIG5vIGl0ZW0gbmFtZSBjYW4gdGFrZSBhbm90aGVyIGl0ZW0ncyAoZ3JvdXBCeSwgbWF0Y2gsIGxpc3RTZWFyY2gpLlxuZXhwb3J0IGZ1bmN0aW9uIGdyb3VwSXRlbU5hbWUoZ3JvdXA6IFBpY2s8UmVwb3J0RmlsdGVyR3JvdXAsICdpZCc+KTogc3RyaW5nIHtcbiAgcmV0dXJuIGAke0lURU1fTkFNRV9XT1JEfSR7Z3JvdXAuaWR9YDtcbn1cblxuLy8gVGhlIGxhYmVsIGEgZ3JvdXAncyBjaGlwIHNob3dzOiBpdHMgb3duLCBlbHNlIGl0cyBmaXJzdCBtZW1iZXIncyBjb2x1bW4uXG5mdW5jdGlvbiBncm91cExhYmVsKGdyb3VwOiBQaWNrPFJlcG9ydEZpbHRlckdyb3VwLCAnbGFiZWwnIHwgJ2ZpbHRlcnMnPik6IHN0cmluZyB7XG4gIHJldHVybiBncm91cC5sYWJlbCB8fCBncm91cC5maWx0ZXJzPy5bMF0/LmZpbHRlckNvbHVtbiB8fCAnJztcbn1cblxuLy8gQSBzZWxlY3QgZ3JvdXAncyBkaXN0aW5jdCBvcHRpb25zLCBhcyB7IG5hbWUsIHZhbHVlIH0gcGFpcnMuIFRoZSBzZXJ2ZXIgc2VuZHNcbi8vIHsgdmFsdWUsIGxhYmVsIH06IHRoZSB2YWx1ZSBpcyB3aGF0IHRoZSBmaWx0ZXIgbWF0Y2hlcyBvbiAoYW4gZW50aXR5J3Mgc3RhYmxlXG4vLyBpZCkgYW5kIHRoZSBsYWJlbCBpcyB3aGF0IHRoZSB2aWV3ZXIgcmVhZHMg4oCUIHNvIGEgcmVuYW1lZCBlbnRpdHkga2VlcHMgaXRzIGlkXG4vLyBhbmQgc2ltcGx5IHNob3dzIGl0cyBuZXcgbmFtZSBoZXJlLiBPcHRpb25zIGNvbWUgZnJvbSB0aGUgZmlyc3QgbWVtYmVyIGZpbHRlclxuLy8gdGhhdCBkZWNsYXJlcyB0aGVtIOKAlCBtZW1iZXJzIGFyZSB0aGUgc2FtZSBkYXRhIHBvaW50LCBzbyBhbnkgbWVtYmVyJ3MgbGlzdFxuLy8gc2VydmVzIHRoZSBncm91cC4gVGhlIGxpc3QgaXMgZmV0Y2hlZCBvbmNlICh0aGUgc2VydmVyIGNhcHMgaXQpIGFuZCByZXBsYXllZFxuLy8gKHNoYXJlUmVwbGF5KSwgc28gcmVwZWF0ZWQgcmVhZHMgbmV2ZXIgcmVmZXRjaC4gVGhpcyBpcyB0aGUgZnVsbCBsaXN0LCBuZXZlclxuLy8gbmFycm93ZWQgYnkgb3RoZXIgZmlsdGVyczogdGhlIHJlcG9ydC1zZXR0aW5ncyBkZWZhdWx0IHBpY2tlciByZWFkcyBpdCAoYW5cbi8vIGF1dGhvciBzZXRzIGEgZGVmYXVsdCBhZ2FpbnN0IHRoZSB3aG9sZSBsaXN0KSwgYW5kIHNvIGRvZXMgdGhlIGV4cG9ydCdzXG4vLyBmaWx0ZXIgd29yZGluZyBmb3IgYSBwaWNrIHRoZSBiYXIgaGFzIG5vdCBuYW1lZC4gVGhlIGJhcnMgcmVhZFxuLy8gUmVwb3J0RmlsdGVyT3B0aW9uc1NlcnZpY2UgaW5zdGVhZC4gUmV0dXJucyBhbiBlbXB0eSBsaXN0IHdoZW4gbm8gbWVtYmVyXG4vLyBwcm92aWRlcyBvcHRpb25zLlxuZXhwb3J0IGZ1bmN0aW9uIGxvYWRHcm91cE9wdGlvbnMoXG4gIGdyb3VwOiBSZXBvcnRGaWx0ZXJHcm91cCxcbiAgcmVwb3J0RGF0YTogUmVwb3J0RGF0YSxcbiAgcmVwb3J0SWQ6IG51bWJlcixcbik6IE9ic2VydmFibGU8UmVwb3J0RmlsdGVyT3B0aW9uUGFpcltdPiB7XG4gIGNvbnN0IG9wdGlvbkZpbHRlciA9IChncm91cC5maWx0ZXJzID8/IFtdKS5maW5kKChtZW1iZXIpID0+IG1lbWJlci5oYXNPcHRpb25zKTtcbiAgaWYgKCFvcHRpb25GaWx0ZXIpIHtcbiAgICByZXR1cm4gb2YoW10pO1xuICB9XG5cbiAgcmV0dXJuIHJlcG9ydERhdGEuZmlsdGVyT3B0aW9ucyhyZXBvcnRJZCwgb3B0aW9uRmlsdGVyLmlkKVxuICAgIC5waXBlKFxuICAgICAgbWFwKChvcHRpb25zOiBSZXBvcnRGaWx0ZXJPcHRpb25bXSkgPT4gKG9wdGlvbnMgPz8gW10pXG4gICAgICAgIC5tYXAoKG9wdGlvbikgPT4gKHsgbmFtZTogb3B0aW9uLmxhYmVsLCB2YWx1ZTogb3B0aW9uLnZhbHVlIH0pKSksXG4gICAgICBzaGFyZVJlcGxheSh7IGJ1ZmZlclNpemU6IDEsIHJlZkNvdW50OiBmYWxzZSB9KSxcbiAgICApO1xufVxuXG4vLyBTdG9yZWQgZmlsdGVyIHZhbHVlcyAoaWRzKSBwYWlyZWQgYmFjayB3aXRoIHRoZSBsYWJlbHMgdG8gc2hvdyBmb3IgdGhlbS5cbi8vIEEgc2F2ZWQgZGVmYXVsdCBob2xkcyBvbmx5IHZhbHVlcywgc28gdGhlIG5hbWVzIGhhdmUgdG8gYmUgcmVhZCBiYWNrIG9mZiB0aGVcbi8vIG9wdGlvbiBsaXN0IOKAlCB0aGF0IGluZGlyZWN0aW9uIGlzIGV4YWN0bHkgd2hhdCBzdXJ2aXZlcyBhIHJlbmFtZS4gYGxhYmVsYFxuLy8gbmFtZXMgYSB2YWx1ZSBmaXJzdDogYSBuYW1lIGFscmVhZHkgbGVhcm5lZCAoUmVwb3J0RmlsdGVyT3B0aW9uc1NlcnZpY2UubGFiZWwpXG4vLyBob2xkcyBmb3IgYSBwaWNrIGEgbmFycm93ZWQgbGlzdCBsZWF2ZXMgb3V0LCBhbmQgd2hlbiBpdCBuYW1lcyBldmVyeSB2YWx1ZVxuLy8gdGhlIGxpc3QgaXMgbm90IHJlYWQgYXQgYWxsLiBBIHZhbHVlIHdpdGggbm8gbmFtZSBhbmQgbm8gbWF0Y2hpbmcgb3B0aW9uXG4vLyAoaXRzIGVudGl0eSB3YXMgZGVsZXRlZCwgc28gaXQgaXMgbm8gbG9uZ2VyIGxpc3RlZCkgZmFsbHMgYmFjayB0byBzaG93aW5nXG4vLyB0aGUgcmF3IHZhbHVlIHJhdGhlciB0aGFuIGRyb3BwaW5nIHRoZSBjaGlwLCB3aGljaCB3b3VsZCBzaWxlbnRseSB3aWRlbiB0aGVcbi8vIGZpbHRlci5cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlT3B0aW9uVmFsdWVzKFxuICBvcHRpb25zJDogT2JzZXJ2YWJsZTxSZXBvcnRGaWx0ZXJPcHRpb25QYWlyW10+LFxuICB2YWx1ZXM6IHVua25vd25bXSxcbiAgbGFiZWw6ICh2YWx1ZTogdW5rbm93bikgPT4gc3RyaW5nIHwgbnVsbCA9ICgpID0+IG51bGwsXG4pOiBPYnNlcnZhYmxlPFJlcG9ydEZpbHRlck9wdGlvblBhaXJbXT4ge1xuICBjb25zdCBuYW1lZCA9IChvcHRpb25zOiBSZXBvcnRGaWx0ZXJPcHRpb25QYWlyW10pID0+IHZhbHVlcy5tYXAoKHZhbHVlKSA9PiB7XG4gICAgY29uc3Qgb3B0aW9uID0gb3B0aW9ucy5maW5kKChjYW5kaWRhdGUpID0+IFN0cmluZyhjYW5kaWRhdGUudmFsdWUpID09PSBTdHJpbmcodmFsdWUpKTtcblxuICAgIHJldHVybiB7IG5hbWU6IGxhYmVsKHZhbHVlKSA/PyBvcHRpb24/Lm5hbWUgPz8gU3RyaW5nKHZhbHVlKSwgdmFsdWUgfTtcbiAgfSk7XG5cbiAgcmV0dXJuIHZhbHVlcy5ldmVyeSgodmFsdWUpID0+IGxhYmVsKHZhbHVlKSAhPT0gbnVsbClcbiAgICA/IG9mKG5hbWVkKFtdKSlcbiAgICA6IG9wdGlvbnMkLnBpcGUobWFwKG5hbWVkKSk7XG59XG5cbi8vIENhc2UtaW5zZW5zaXRpdmUgbmFtZSBmaWx0ZXIgYXBwbGllZCB0byBhIGxvYWRlZCBvcHRpb24gbGlzdCDigJQgdGhlIHR5cGVkXG4vLyBrZXl3b3JkIGhhcyB0byBiZSBtYXRjaGVkIGhlcmUgYmVjYXVzZSBmcy1hdXRvY29tcGxldGUgcmVuZGVycyB3aGF0IHdlIHJldHVyblxuLy8gdmVyYmF0aW0uXG5leHBvcnQgZnVuY3Rpb24gbWF0Y2hPcHRpb25zKFxuICBvcHRpb25zJDogT2JzZXJ2YWJsZTxSZXBvcnRGaWx0ZXJPcHRpb25QYWlyW10+LFxuICBrZXl3b3JkPzogc3RyaW5nLFxuKTogT2JzZXJ2YWJsZTxSZXBvcnRGaWx0ZXJPcHRpb25QYWlyW10+IHtcbiAgY29uc3QgdGVybSA9IChrZXl3b3JkID8/ICcnKS50cmltKCkudG9Mb3dlckNhc2UoKTtcblxuICByZXR1cm4gb3B0aW9ucyQucGlwZShtYXAoKG9wdGlvbnMpID0+IHRlcm1cbiAgICA/IG9wdGlvbnMuZmlsdGVyKChvcHRpb24pID0+IG9wdGlvbi5uYW1lLnRvTG93ZXJDYXNlKCkuaW5jbHVkZXModGVybSkpXG4gICAgOiBvcHRpb25zKSk7XG59XG5cbi8vIFRoZSBwYW5lbCByb3cgb2YgYSBzZWxlY3Qgd2hvc2UgbGlzdCB0aGUgc2VydmVyIGN1dCBhdCA1MDAuXG5leHBvcnQgY29uc3QgT1BUSU9OU19UUlVOQ0FURURfTk9URSA9ICdTaG93aW5nIHRoZSBmaXJzdCA1MDAuIFR5cGUgdG8gbmFycm93Lic7XG5cbi8vIFRoZSBwYW5lbCByb3cgb2YgYSBzZWxlY3Qgd2hvc2UgbGlzdCBjb3VsZCBub3QgYmUgcmVhZC4gVGhlIG5leHQgZm9jdXMgb3Jcbi8vIGtleXN0cm9rZSBhc2tzIGFnYWluLlxuZXhwb3J0IGNvbnN0IE9QVElPTlNfRkFJTEVEX05PVEUgPSAnQ291bGQgbm90IGxvYWQgdGhlIGxpc3QuJztcblxuLy8gQnVpbGQgdGhlIGZzLWZpbHRlciBjb25maWcgaXRlbSBmb3IgYSBncm91cCwgc2VlZGluZyBpdHMgZGVmYXVsdCBmcm9tIHRoZVxuLy8gY3VycmVudCBzZXNzaW9uIHZhbHVlIHNvIGF1dGhvcmVkL3JlbGF0aXZlIGRlZmF1bHRzIHNob3cgc2VsZWN0ZWQgb24gb3Blbi5cbi8vIEEgc2VsZWN0IGxpc3RzIHdoYXQgYG9wdGlvbnNgIG9mZmVycyBmb3IgaXQgaW4gYHJlcG9ydGAuIGBmZWF0dXJlc2AgaXMgdGhlXG4vLyByZXBvcnQncyB2aWV3ZXJGZWF0dXJlczogYSBzZWxlY3Qgb2ZmZXJzICdFeGNsdWRlIHRoZXNlJyBieSB0aGUgcnVsZSBvZlxuLy8gb2ZmZXJzRXhjbHVkZSAodGhlIHNlcnZlciBsaXN0cyBleGNsdWRlVmFsdWVzIGFuZCBubyBtZW1iZXIgYmluZHMgc2V2ZXJhbFxuLy8gY29sdW1ucyksIGFuZCBhIG51bWJlciByYW5nZSBpcyBhIG1pbi9tYXggY29udHJvbCBvbmx5IHdoZW4gaXQgbGlzdHNcbi8vIG51bWJlclJhbmdlLlxuZXhwb3J0IGZ1bmN0aW9uIGZpbHRlckl0ZW1Gb3JHcm91cChcbiAgZ3JvdXA6IFJlcG9ydEZpbHRlckdyb3VwLFxuICBvcHRpb25zOiBSZXBvcnRGaWx0ZXJPcHRpb25zU2VydmljZSxcbiAgcmVwb3J0OiBSZXBvcnQgfCBudWxsLFxuICBpbml0aWFsPzogRmlsdGVyR3JvdXBWYWx1ZSxcbiAgZmVhdHVyZXM6IHJlYWRvbmx5IFJlcG9ydFZpZXdlckZlYXR1cmVbXSA9IFtdLFxuKTogSUZpbHRlckNvbmZpZ0l0ZW0ge1xuICBjb25zdCBuYW1lID0gZ3JvdXBJdGVtTmFtZShncm91cCk7XG4gIGNvbnN0IGxhYmVsID0gZ3JvdXBMYWJlbChncm91cCk7XG5cbiAgc3dpdGNoIChncm91cC50eXBlKSB7XG4gICAgY2FzZSAnZGF0ZVJhbmdlJzpcbiAgICAgIHJldHVybiBkYXRlUmFuZ2VGaWx0ZXJJdGVtKG5hbWUsIGxhYmVsLCBpbml0aWFsKTtcblxuICAgIGNhc2UgJ3NlbGVjdCc6XG4gICAgICByZXR1cm4gc2VsZWN0RmlsdGVySXRlbShncm91cCwgbGFiZWwsIG9wdGlvbnMsIHJlcG9ydCwgaW5pdGlhbCwgb2ZmZXJzRXhjbHVkZShncm91cCwgZmVhdHVyZXMpKTtcblxuICAgIGNhc2UgJ251bWJlclJhbmdlJzpcbiAgICAgIHJldHVybiBmZWF0dXJlcy5pbmNsdWRlcygnbnVtYmVyUmFuZ2UnKVxuICAgICAgICA/IG51bWJlclJhbmdlRmlsdGVySXRlbShncm91cCwgbGFiZWwsIHJlcG9ydCwgaW5pdGlhbClcbiAgICAgICAgOiBrZXl3b3JkRmlsdGVySXRlbShuYW1lLCBsYWJlbCwgaW5pdGlhbCk7XG5cbiAgICBjYXNlICdrZXl3b3JkJzpcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIGtleXdvcmRGaWx0ZXJJdGVtKG5hbWUsIGxhYmVsLCBpbml0aWFsKTtcbiAgfVxufVxuXG4vLyBBIGRhdGUgcmFuZ2Ugb3BlbnMgb24gaXRzIGRheXMsIGFuZCBpdHMgY2hpcCBzaG93cyB0aGVtLiBBIHByZXNldCBwaWNrZWQgaW5cbi8vIHRoZSBkYXRlIHBpY2tlciBvbmx5IHNldHMgdGhlIGRheXMuXG5mdW5jdGlvbiBkYXRlUmFuZ2VGaWx0ZXJJdGVtKG5hbWU6IHN0cmluZywgbGFiZWw6IHN0cmluZywgaW5pdGlhbD86IEZpbHRlckdyb3VwVmFsdWUpOiBJRmlsdGVyQ29uZmlnSXRlbSB7XG4gIGNvbnN0IGhhc0RheXMgPSAhIShpbml0aWFsPy5zdGFydCB8fCBpbml0aWFsPy5lbmQpO1xuXG4gIHJldHVybiB7XG4gICAgbmFtZSxcbiAgICB0eXBlOiBJdGVtVHlwZS5EYXRlUmFuZ2UsXG4gICAgbGFiZWw6IHsgZnJvbTogYCR7bGFiZWx9IEZyb21gLCB0bzogYCR7bGFiZWx9IFRvYCB9LFxuICAgIGRlZmF1bHQ6IGhhc0RheXNcbiAgICAgID8geyBmcm9tOiBpbml0aWFsLnN0YXJ0ID8/IHVuZGVmaW5lZCwgdG86IGluaXRpYWwuZW5kID8/IHVuZGVmaW5lZCB9XG4gICAgICA6IHVuZGVmaW5lZCxcbiAgfTtcbn1cblxuLy8gQSBzZWxlY3QncyBwaWNrcywga2VwdCBvciBsZWZ0IG91dC4gV2l0aCBgZXhjbHVkZWAgdGhlIGxpc3QgaGFzIHRoZVxuLy8gJ0V4Y2x1ZGUgdGhlc2UnIHJvdywgYW5kIGEgdmFsdWUgdGhhdCBsZWF2ZXMgb3V0IG9wZW5zIHdpdGggaXQgb24uIEl0cyBsaXN0XG4vLyBpcyByZWFkIG9uIGZvY3VzIGFuZCBvbiBlYWNoIGtleXN0cm9rZTogdGhlIG9wdGlvbnMgc2VydmljZSBmZXRjaGVzIGl0IHdoZW5cbi8vIHRoZSBvdGhlciBmaWx0ZXJzIGNoYW5nZWQgc2luY2UgYW5kIHJlcGxheXMgaXQgb3RoZXJ3aXNlLCBhbmQgdHlwaW5nXG4vLyBmaWx0ZXJzIGl0IGhlcmUuIEEgbGlzdCB0aGUgc2VydmVyIGN1dCwgb3Igb25lIHRoYXQgY291bGQgbm90IGJlIHJlYWQsXG4vLyBzYXlzIHNvIGluIGEgcGFuZWwgcm93LlxuZnVuY3Rpb24gc2VsZWN0RmlsdGVySXRlbShcbiAgZ3JvdXA6IFJlcG9ydEZpbHRlckdyb3VwLFxuICBsYWJlbDogc3RyaW5nLFxuICBvcHRpb25zOiBSZXBvcnRGaWx0ZXJPcHRpb25zU2VydmljZSxcbiAgcmVwb3J0OiBSZXBvcnQgfCBudWxsLFxuICBpbml0aWFsOiBGaWx0ZXJHcm91cFZhbHVlIHwgdW5kZWZpbmVkLFxuICBleGNsdWRlOiBib29sZWFuLFxuKTogSUZpbHRlckNvbmZpZ0l0ZW0ge1xuICBjb25zdCBleGNsdWRpbmcgPSBleGNsdWRlICYmICFpbml0aWFsPy52YWx1ZXM/Lmxlbmd0aCAmJiAhIWluaXRpYWw/LmV4Y2x1ZGVWYWx1ZXM/Lmxlbmd0aDtcbiAgY29uc3QgcGlja3MgPSBleGNsdWRpbmcgPyBpbml0aWFsLmV4Y2x1ZGVWYWx1ZXMgOiBpbml0aWFsPy52YWx1ZXM7XG4gIGNvbnN0IG9wdGlvbnMkID0gb3B0aW9ucy5vcHRpb25zKGdyb3VwLCByZXBvcnQpO1xuXG4gIHJldHVybiB7XG4gICAgbmFtZTogZ3JvdXBJdGVtTmFtZShncm91cCksXG4gICAgdHlwZTogSXRlbVR5cGUuQXV0b0NvbXBsZXRlQ2hpcHMsXG4gICAgbGFiZWwsXG4gICAgZmV0Y2hPbkZvY3VzOiB0cnVlLFxuICAgIGV4Y2x1ZGU6IGV4Y2x1ZGUgPyB7fSA6IHVuZGVmaW5lZCxcbiAgICB2YWx1ZXM6IChrZXl3b3JkPzogc3RyaW5nKSA9PiBtYXRjaE9wdGlvbnMob3B0aW9ucyQsIGtleXdvcmQpLFxuICAgIHBhbmVsTm90ZTogKCkgPT4gb3B0aW9uc05vdGUob3B0aW9ucywgZ3JvdXAuaWQpLFxuICAgIC8vIFN0b3JlZCB2YWx1ZXMgYXJlIGlkcywgc28gYSBjaGlwIGlzIG5hbWVkIGJ5IGEgbmFtZSBhbHJlYWR5IGxlYXJuZWQgb3JcbiAgICAvLyBvbmNlIHRoZSBvcHRpb24gbGlzdCBoYXMgbG9hZGVkIOKAlCBoZW5jZSB0aGUgb2JzZXJ2YWJsZSBmb3JtIG9mIGBkZWZhdWx0YC5cbiAgICBkZWZhdWx0OiBwaWNrcz8ubGVuZ3RoXG4gICAgICA/ICgpID0+IHJlc29sdmVPcHRpb25WYWx1ZXMob3B0aW9ucyQsIHBpY2tzLCAodmFsdWUpID0+IG9wdGlvbnMubGFiZWwoZ3JvdXAuaWQsIHZhbHVlKSlcbiAgICAgICAgLnBpcGUobWFwKChzZWxlY3RlZCkgPT4gKGV4Y2x1ZGluZyA/IHsgZXhjbHVkZTogdHJ1ZSwgc2VsZWN0ZWQgfSA6IHNlbGVjdGVkKSkpXG4gICAgICA6IHVuZGVmaW5lZCxcbiAgfTtcbn1cblxuLy8gVGhlIHBhbmVsIHJvdyBvZiBhIHNlbGVjdCdzIGxhdGVzdCBsaXN0OiBhIGZhaWx1cmUgZmlyc3QsIHRoZW4gYSBjdXQgbGlzdC5cbmZ1bmN0aW9uIG9wdGlvbnNOb3RlKG9wdGlvbnM6IFJlcG9ydEZpbHRlck9wdGlvbnNTZXJ2aWNlLCBncm91cElkOiBudW1iZXIpOiBzdHJpbmcgfCBudWxsIHtcbiAgaWYgKG9wdGlvbnMuZmFpbGVkKGdyb3VwSWQpKSB7XG4gICAgcmV0dXJuIE9QVElPTlNfRkFJTEVEX05PVEU7XG4gIH1cblxuICByZXR1cm4gb3B0aW9ucy50cnVuY2F0ZWQoZ3JvdXBJZCkgPyBPUFRJT05TX1RSVU5DQVRFRF9OT1RFIDogbnVsbDtcbn1cblxuLy8gQSBudW1iZXIgcmFuZ2UncyBsb3cgYW5kIGhpZ2ggZW5kcywgZWl0aGVyIG9uZSBvcGVuLiAwIGlzIGFuIGVuZCBsaWtlIGFueVxuLy8gb3RoZXIuIEl0cyBjaGlwIHJlYWRzIGFzIHRoZSBleHBvcnQgbGluZXMgZG8gKCdBbW91bnQ6IDAgb3IgbW9yZScsXG4vLyAnQW1vdW50OiAwIHRvIDEwJyk6IHRoZSBlbmRzIGFyZSByZWFkIG9mZiB0aGUgaXRlbSdzIHF1ZXJ5IHRoZSB3YXkgdGhlXG4vLyBiYXIncyBjaGFuZ2UgcmVhZHMgdGhlbSwgYW5kIHdvcmRlZCBpbiB0aGUgcmVwb3J0J3MgbG9jYWxlLlxuZnVuY3Rpb24gbnVtYmVyUmFuZ2VGaWx0ZXJJdGVtKFxuICBncm91cDogUmVwb3J0RmlsdGVyR3JvdXAsXG4gIGxhYmVsOiBzdHJpbmcsXG4gIHJlcG9ydDogUmVwb3J0IHwgbnVsbCxcbiAgaW5pdGlhbD86IEZpbHRlckdyb3VwVmFsdWUsXG4pOiBJRmlsdGVyQ29uZmlnSXRlbSB7XG4gIGNvbnN0IG5hbWUgPSBncm91cEl0ZW1OYW1lKGdyb3VwKTtcbiAgY29uc3QgbWluID0gaW5pdGlhbD8ubWluID8/IHVuZGVmaW5lZDtcbiAgY29uc3QgbWF4ID0gaW5pdGlhbD8ubWF4ID8/IHVuZGVmaW5lZDtcbiAgY29uc3QgbG9jYWxlID0gcmVzb2x2ZUZvcm1hdENvbnRleHQocmVwb3J0ID8/IHt9KS5sb2NhbGU7XG5cbiAgcmV0dXJuIHtcbiAgICBuYW1lLFxuICAgIHR5cGU6IEl0ZW1UeXBlLlJhbmdlLFxuICAgIGxhYmVsLFxuICAgIGRlZmF1bHQ6IG1pbiAhPT0gdW5kZWZpbmVkIHx8IG1heCAhPT0gdW5kZWZpbmVkID8geyBtaW4sIG1heCB9IDogdW5kZWZpbmVkLFxuICAgIGNoaXBUZXh0OiAoaXRlbSkgPT4gZmlsdGVyTGluZVRleHQoXG4gICAgICB7IGxhYmVsLCBsZXZlbDogZ3JvdXAubGV2ZWwgfSxcbiAgICAgIG51bWJlclJhbmdlRnJvbVF1ZXJ5KGl0ZW0ucXVlcnksIG5hbWUpLFxuICAgICAgeyBsb2NhbGUgfSxcbiAgICAgICdjaGlwJyxcbiAgICApLFxuICB9O1xufVxuXG5mdW5jdGlvbiBrZXl3b3JkRmlsdGVySXRlbShuYW1lOiBzdHJpbmcsIGxhYmVsOiBzdHJpbmcsIGluaXRpYWw/OiBGaWx0ZXJHcm91cFZhbHVlKTogSUZpbHRlckNvbmZpZ0l0ZW0ge1xuICByZXR1cm4ge1xuICAgIG5hbWUsXG4gICAgdHlwZTogSXRlbVR5cGUuS2V5d29yZCxcbiAgICBsYWJlbCxcbiAgICBkZWZhdWx0OiBpbml0aWFsPy52YWx1ZSxcbiAgfTtcbn1cblxuLy8gVGhlIGdyb3VwcyBhIG1hdGNoIG9mICdhbnknIGNvbWJpbmVzOiByZXBvcnQgYmFyIGdyb3VwcyAoYSBwYWdlIGdyb3VwIG9uXG4vLyBpdHMgb3duIHBhZ2Ugb25seSkgdGhhdCBhIHZpZXdlciBwaWNrcyB2YWx1ZXMsIHRleHQgb3IgYSBudW1iZXIgcmFuZ2UgaW4uXG4vLyBEYXRlcywgdGlsZS1vbmx5IGdyb3VwcyBhbmQgdGhlIGNyb3NzLWZpbHRlciBhbHdheXMgbmFycm93IG9uIHRoZWlyIG93bi5cbi8vIFRoZSBzZXJ2ZXIgaG9sZHMgdGhlIHNhbWUgcnVsZSBhbmQgY2hlY2tzIGV2ZXJ5IGlkIGl0IGlzIHNlbnQuXG5jb25zdCBNQVRDSF9BTllfTEVWRUxTOiByZWFkb25seSBSZXBvcnRGaWx0ZXJMZXZlbFtdID0gWydyZXBvcnQnLCAnYm90aCcsICdwYWdlJ107XG5jb25zdCBNQVRDSF9BTllfVFlQRVM6IHJlYWRvbmx5IFJlcG9ydEZpbHRlclR5cGVbXSA9IFsnc2VsZWN0JywgJ2tleXdvcmQnLCAnbnVtYmVyUmFuZ2UnXTtcblxuLy8gV2hldGhlciBhIGdyb3VwIGpvaW5zIGEgbWF0Y2ggb2YgJ2FueScgb24gcGFnZSBgcGFnZUlkYC5cbmV4cG9ydCBmdW5jdGlvbiBpc01hdGNoQW55R3JvdXAoZ3JvdXA6IFJlcG9ydEZpbHRlckdyb3VwLCBwYWdlSWQ6IG51bWJlciB8IG51bGwpOiBib29sZWFuIHtcbiAgcmV0dXJuIE1BVENIX0FOWV9MRVZFTFMuaW5jbHVkZXMoZ3JvdXAubGV2ZWwpXG4gICAgJiYgTUFUQ0hfQU5ZX1RZUEVTLmluY2x1ZGVzKGdyb3VwLnR5cGUpXG4gICAgJiYgKGdyb3VwLmxldmVsICE9PSAncGFnZScgfHwgKCEhcGFnZUlkICYmIGdyb3VwLnBhZ2VJZCA9PT0gcGFnZUlkKSk7XG59XG5cbi8vIFRoZSByZXBvcnQgYmFyJ3MgZ3JvdXBzIGluIHRoZWlyIHNhdmVkIG9yZGVyOiB0aGUgcmVwb3J0IGFuZCBib3RoIGdyb3Vwcyxcbi8vIGFuZCB0aGUgcGFnZSBncm91cHMgb2YgdGhlIHBhZ2Ugb24gc2NyZWVuIChgcGFnZUlkYCkuXG5leHBvcnQgZnVuY3Rpb24gcmVwb3J0QmFyR3JvdXBzKHJlcG9ydDogUmVwb3J0IHwgbnVsbCwgcGFnZUlkOiBudW1iZXIgfCBudWxsKTogUmVwb3J0RmlsdGVyR3JvdXBbXSB7XG4gIHJldHVybiAocmVwb3J0Py5maWx0ZXJHcm91cHMgPz8gW10pXG4gICAgLmZpbHRlcigoZ3JvdXApID0+IGdyb3VwLmxldmVsID09PSAncmVwb3J0JyB8fCBncm91cC5sZXZlbCA9PT0gJ2JvdGgnXG4gICAgICB8fCAoZ3JvdXAubGV2ZWwgPT09ICdwYWdlJyAmJiAhIXBhZ2VJZCAmJiBncm91cC5wYWdlSWQgPT09IHBhZ2VJZCkpXG4gICAgLnNvcnQoKGEsIGIpID0+IGEub3JkZXIgLSBiLm9yZGVyKTtcbn1cblxuLy8gV2hldGhlciB0aGUgcmVwb3J0IGhhcyBhIGdyb3VwIHNob3duIG9uIG9uZSBwYWdlIG9ubHksIHNvIGl0cyByZXBvcnQgYmFyXG4vLyBjaGFuZ2VzIHdpdGggdGhlIHBhZ2Ugb24gc2NyZWVuLlxuZXhwb3J0IGZ1bmN0aW9uIGhhc1BhZ2VHcm91cChyZXBvcnQ6IFJlcG9ydCB8IG51bGwpOiBib29sZWFuIHtcbiAgcmV0dXJuIChyZXBvcnQ/LmZpbHRlckdyb3VwcyA/PyBbXSkuc29tZSgoZ3JvdXApID0+IGdyb3VwLmxldmVsID09PSAncGFnZScpO1xufVxuXG4vLyBUaGUgcXVlcnkga2V5IG9mIHRoZSByZXBvcnQgYmFyJ3MgTWF0Y2ggY29udHJvbC4gTm90IGEgZmlsdGVyIGdyb3VwOiBpdFxuLy8gc2F5cyBob3cgdGhlIGdyb3VwcyBjb21iaW5lLCBzbyBpdCBpcyByZWFkIHN0cmFpZ2h0IG9mZiB0aGUgY2hhbmdlIHF1ZXJ5LlxuZXhwb3J0IGNvbnN0IE1BVENIX0lURU0gPSAnbWF0Y2gnO1xuXG5jb25zdCBNQVRDSF9PUFRJT05TOiB7IG5hbWU6IHN0cmluZzsgdmFsdWU6IFJlcG9ydEZpbHRlck1hdGNoIH1bXSA9IFtcbiAgeyBuYW1lOiAnQWxsIGZpbHRlcnMnLCB2YWx1ZTogJ2FsbCcgfSxcbiAgeyBuYW1lOiAnQW55IGZpbHRlcicsIHZhbHVlOiAnYW55JyB9LFxuXTtcblxuLy8gVGhlIHJlcG9ydCBiYXIncyBNYXRjaCBjb250cm9sLCBsYXN0IGluIHRoZSBiYXIsIG9yIG51bGwgd2hlbiBpdCB3b3VsZCBkb1xuLy8gbm90aGluZzogdGhlIHNlcnZlciBtdXN0IHNlcnZlIG1hdGNoQW55LCBhbmQgdGhlIGJhciBtdXN0IGhvbGQgdHdvIG9yIG1vcmVcbi8vIGdyb3VwcyB0aGF0IGNvbWJpbmUgKGFuICdhbnknIG92ZXIgb25lIGdyb3VwIGlzIHRoYXQgZ3JvdXApLlxuZXhwb3J0IGZ1bmN0aW9uIG1hdGNoRmlsdGVySXRlbShcbiAgcmVwb3J0OiBSZXBvcnQgfCBudWxsLFxuICBncm91cHM6IFJlcG9ydEZpbHRlckdyb3VwW10sXG4gIHBhZ2VJZDogbnVtYmVyIHwgbnVsbCxcbiAgbWF0Y2g6IFJlcG9ydEZpbHRlck1hdGNoLFxuKTogSUZpbHRlckNvbmZpZ0l0ZW0gfCBudWxsIHtcbiAgY29uc3QgZWxpZ2libGUgPSBncm91cHMuZmlsdGVyKChncm91cCkgPT4gaXNNYXRjaEFueUdyb3VwKGdyb3VwLCBwYWdlSWQpKTtcblxuICBpZiAoIXJlcG9ydD8udmlld2VyRmVhdHVyZXM/LmluY2x1ZGVzKCdtYXRjaEFueScpIHx8IGVsaWdpYmxlLmxlbmd0aCA8IDIpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgbmFtZTogTUFUQ0hfSVRFTSxcbiAgICB0eXBlOiBJdGVtVHlwZS5TZWxlY3QsXG4gICAgbGFiZWw6ICdNYXRjaCcsXG4gICAgbXVsdGlwbGU6IGZhbHNlLFxuICAgIHZhbHVlczogKCkgPT4gTUFUQ0hfT1BUSU9OUyxcbiAgICBkZWZhdWx0OiBtYXRjaCxcbiAgICAvLyAnTWF0Y2g6IGFueSBmaWx0ZXInIG9yICdNYXRjaDogYWxsIGZpbHRlcnMnLCBpbiB0aGUgZXhwb3J0IGxpbmVzJyB3b3Jkcy5cbiAgICBjaGlwVGV4dDogKGl0ZW0pID0+IG1hdGNoTGluZVRleHQobWF0Y2hGcm9tUXVlcnkoaXRlbS5xdWVyeSksICdjaGlwJyksXG4gIH07XG59XG5cbi8vIFRoZSBtYXRjaCBhIGNoYW5nZSBxdWVyeSBvZiBhIGJhciB3aXRoIHRoZSBNYXRjaCBjb250cm9sIGFza3MgZm9yLlxuZXhwb3J0IGZ1bmN0aW9uIG1hdGNoRnJvbVF1ZXJ5KHF1ZXJ5OiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IFJlcG9ydEZpbHRlck1hdGNoIHtcbiAgcmV0dXJuIHF1ZXJ5Py5bTUFUQ0hfSVRFTV0gPT09ICdhbnknID8gJ2FueScgOiAnYWxsJztcbn1cblxuLy8gVGhlIHF1ZXJ5IGtleSBvZiBhIGxpc3QncyBzZWFyY2ggYm94IGluIGl0cyBjb21wb25lbnQgaGVhZGVyLiBGaXhlZCByYXRoZXJcbi8vIHRoYW4gZGVyaXZlZCBmcm9tIGFuIGlkIGJlY2F1c2UgYSBoZWFkZXIgaG9sZHMgYXQgbW9zdCBvbmUsIGFuZCBpdCBpcyBOT1QgYVxuLy8gZmlsdGVyIGdyb3VwOiBpdHMgdGV4dCBuYXJyb3dzIHRoYXQgbGlzdCBhbG9uZSwgc28gaXQgaXMgcmVhZCBzdHJhaWdodCBvZmZcbi8vIHRoZSBjaGFuZ2UgcXVlcnkgYW5kIHRyYXZlbHMgYXMgdGhlIGxpc3QncyBvd24gYHN0YXRlLnNlYXJjaGAuXG5leHBvcnQgY29uc3QgTElTVF9TRUFSQ0hfSVRFTSA9ICdsaXN0U2VhcmNoJztcblxuLy8gVGhlIGxvbmdlc3Qgc2VhcmNoIHRoZSBzZXJ2ZXIgYXBwbGllcyAoUmVwb3J0UXVlcnlSdW5uZXI6Ok1BWF9TRUFSQ0hfTEVOR1RIKS5cbi8vIFRoZSB2aWV3ZXIgY3V0cyB0aGUgdGV4dCB0byBpdCB0b28sIHNvIHRoZSBzdGF0ZSwgdGhlIHJlcXVlc3QgYW5kIHRoZSBleHBvcnRcbi8vIHRpdGxlIGFsbCBjYXJyeSB0aGUgdGV4dCB0aGF0IHdhcyBhY3R1YWxseSBzZWFyY2hlZC5cbmV4cG9ydCBjb25zdCBMSVNUX1NFQVJDSF9NQVhfTEVOR1RIID0gMTAwO1xuXG4vLyBUaGUgZnMtZmlsdGVyIGNvbmZpZyBpdGVtIGZvciBhIGxpc3QncyBzZWFyY2ggYm94LCBzZWVkZWQgd2l0aCB0aGUgdGV4dCB0aGVcbi8vIHZpZXdlciBsYXN0IHNlYXJjaGVkLiBmcy1maWx0ZXIgc2hvd3Mgb25lIHNlYXJjaCBib3ggcGVyIGJhciAoaXRzIGxhc3Rcbi8vIGtleXdvcmQgaXRlbSksIHNvIHRoZSBjYWxsZXIgYWRkcyB0aGlzIG9ubHkgdG8gYSBoZWFkZXIgd2l0aCBubyBrZXl3b3JkXG4vLyBncm91cCBvZiBpdHMgb3duLlxuZXhwb3J0IGZ1bmN0aW9uIGxpc3RTZWFyY2hJdGVtKHZhbHVlOiBzdHJpbmcgfCBudWxsKTogSUZpbHRlckNvbmZpZ0l0ZW0ge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IEl0ZW1UeXBlLktleXdvcmQsXG4gICAgbmFtZTogTElTVF9TRUFSQ0hfSVRFTSxcbiAgICBsYWJlbDogJ1NlYXJjaCcsXG4gICAgZGVmYXVsdDogdmFsdWUgPz8gdW5kZWZpbmVkLFxuICB9O1xufVxuXG4vLyBXaGV0aGVyIHRoZSByZXBvcnQgaGFzIGEgY2hhcnQgdGhlIGdyb3VwLWJ5IGNvbnRyb2wgY2FuIHJlLWJ1Y2tldC4gQSB0aW1lXG4vLyB4LWF4aXMgaXMgdGhlIHdob2xlIHF1YWxpZmljYXRpb246IHRoZSBjb250cm9sIGNoYW5nZXMgdGhlIGdyYWluIG9mIHRoYXRcbi8vIGF4aXMsIGFuZCBhIGNhdGVnb3J5IGF4aXMgaGFzIG5vIGdyYWluIHRvIGNoYW5nZS5cbmV4cG9ydCBmdW5jdGlvbiBoYXNUaW1lU2VyaWVzQ2hhcnQocmVwb3J0OiBSZXBvcnQgfCBudWxsKTogYm9vbGVhbiB7XG4gIHJldHVybiAocmVwb3J0Py5wYWdlcyA/PyBbXSkuc29tZSgocGFnZSkgPT4gKHBhZ2UuY29tcG9uZW50cyA/PyBbXSkuc29tZSgoY29tcG9uZW50KSA9PlxuICAgIGNvbXBvbmVudC50eXBlID09PSAnY2hhcnQnICYmIGNvbXBvbmVudC5jb25maWc/LnhBeGlzPy5raW5kID09PSAndGltZScpKTtcbn1cblxuLy8gVGhlIGdyYWlucyB0aGUgcmVwb3J0J3MgZ3JvdXAtYnkgY29udHJvbCBvZmZlcnMsIG5hbWVkIGZvciB0aGUgdmlld2VyLiBXSElDSFxuLy8gb2YgdGhlbSBjb21lcyBmcm9tIHRoZSByZXBvcnQ7IGhvdyB0aGV5IHJlYWQgY29tZXMgZnJvbSBHUkFOVUxBUklUWV9PUFRJT05TLlxuLy8gQW4gZW1wdHkgc3RvcmVkIGxpc3QgbWVhbnMgZXZlcnkgZ3JhaW4g4oCUIHRoZSBzYW1lIHJ1bGUgdGhlIGJhY2tlbmQgYXBwbGllcy5cbmZ1bmN0aW9uIGdyb3VwQnlPcHRpb25zKHJlcG9ydDogUmVwb3J0KTogeyB2YWx1ZTogQ2hhcnRHcmFudWxhcml0eTsgbmFtZTogc3RyaW5nIH1bXSB7XG4gIGNvbnN0IGdyYW51bGFyaXRpZXMgPSByZXBvcnQuY29uZmlnPy5ncm91cEJ5Py5ncmFudWxhcml0aWVzID8/IFtdO1xuXG4gIHJldHVybiBncmFudWxhcml0aWVzLmxlbmd0aFxuICAgID8gR1JBTlVMQVJJVFlfT1BUSU9OUy5maWx0ZXIoKG9wdGlvbikgPT4gZ3JhbnVsYXJpdGllcy5pbmNsdWRlcyhvcHRpb24udmFsdWUpKVxuICAgIDogR1JBTlVMQVJJVFlfT1BUSU9OUztcbn1cblxuLy8gV2hldGhlciBhIGdyYWluIGlzIG9uZSB0aGUgcmVwb3J0J3MgY29udHJvbCBzdGlsbCBvZmZlcnMuIEEgZ3JhaW4gaXQgZG9lc24ndFxuLy8gY2Fubm90IHN0YXkgaW4gZWZmZWN0OiB0aGUgYWdlbnQgY2FuIG5hcnJvdyB0aGUgbGlzdCBhdCBhbnkgdGltZSwgYW5kIGEgY2hhcnRcbi8vIGxlZnQgYnVja2V0aW5nIGF0IGEgZHJvcHBlZCBncmFpbiBpcyBvbmUgdGhlIHZpZXdlciBjYW4gbmVpdGhlciBzZWUgbm9yIGNoYW5nZS5cbmV4cG9ydCBmdW5jdGlvbiBpc0dyYW51bGFyaXR5T2ZmZXJlZChyZXBvcnQ6IFJlcG9ydCwgZ3JhbnVsYXJpdHk6IENoYXJ0R3JhbnVsYXJpdHkgfCBudWxsKTogYm9vbGVhbiB7XG4gIHJldHVybiAhZ3JhbnVsYXJpdHkgfHwgZ3JvdXBCeU9wdGlvbnMocmVwb3J0KS5zb21lKChvcHRpb24pID0+IG9wdGlvbi52YWx1ZSA9PT0gZ3JhbnVsYXJpdHkpO1xufVxuXG4vLyBUaGUgZnMtZmlsdGVyIGNvbmZpZyBpdGVtIGZvciB0aGUgcmVwb3J0J3MgZ3JvdXAtYnkgY29udHJvbCwgb3IgbnVsbCB3aGVuIHRoZVxuLy8gcmVwb3J0IGhhcyBub25lIHRvIHNob3cuXG4vL1xuLy8gSXQgbGVhZHMgdGhlIHNhbWUgYmFyIHRoZSBmaWx0ZXJzIHJlbmRlciBpbiwgYnV0IGl0IGlzIE5PVCBvbmU6IGEgZmlsdGVyXG4vLyBuYXJyb3dzIFdISUNIIHJvd3MgYXJlIGNvdW50ZWQsIHRoaXMgY2hhbmdlcyBob3cgdGhlIHN1cnZpdmluZyByb3dzIGFyZVxuLy8gQlVDS0VURUQg4oCUIGFuZCBpdCBjb21lcyBmaXJzdCBiZWNhdXNlIHRoZSBncmFpbiBpcyB3aGF0IGEgdmlld2VyIHNldHRsZXNcbi8vIGJlZm9yZSBkZWNpZGluZyB3aGljaCByb3dzIHRoZXkgd2FudC5cbi8vIFBpY2tpbmcgYSBncmFpbiBzZXRzIGEgc2Vzc2lvbi13aWRlIG92ZXJyaWRlIHRoYXQgcmlkZXMgYWxvbmcgaW4gZWFjaCBjaGFydCdzXG4vLyBkYXRhIHJlcXVlc3QsIHNvIHRoZSBjaGFydHMgdGhlbXNlbHZlcyBhcmUgbmV2ZXIgcmV3cml0dGVuLlxuZXhwb3J0IGZ1bmN0aW9uIGdyb3VwQnlGaWx0ZXJJdGVtKFxuICByZXBvcnQ6IFJlcG9ydCxcbiAgaW5pdGlhbD86IENoYXJ0R3JhbnVsYXJpdHkgfCBudWxsLFxuKTogSUZpbHRlckNvbmZpZ0l0ZW0gfCBudWxsIHtcbiAgY29uc3QgZ3JvdXBCeSA9IHJlcG9ydC5jb25maWc/Lmdyb3VwQnk7XG5cbiAgLy8gT25seSBhbiBFWFBMSUNJVCBmYWxzZSBoaWRlcyB0aGUgY29udHJvbC4gQW4gYWJzZW50IGJsb2NrIG1lYW5zIGEgcmVwb3J0XG4gIC8vIHNlcnZlZCBieSBhIGJ1aWxkIHRoYXQgcHJlZGF0ZXMgdGhlIGNvbnRyb2wgYmVpbmcgc3RvcmVkLCBhbmQgZXZlcnkgb25lIG9mXG4gIC8vIHRob3NlIGhhZCBvbmUg4oCUIHRoZSBiYWNrZW5kIHJlc29sdmVzIGl0IHRoZSBzYW1lIHdheSAoUmVwb3J0R3JvdXBCeSkuXG4gIGlmIChncm91cEJ5Py5lbmFibGVkID09PSBmYWxzZSB8fCAhaGFzVGltZVNlcmllc0NoYXJ0KHJlcG9ydCkpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IHZhbHVlcyA9IGdyb3VwQnlPcHRpb25zKHJlcG9ydCk7XG5cbiAgcmV0dXJuIHtcbiAgICBuYW1lOiBHUk9VUF9CWV9JVEVNLFxuICAgIHR5cGU6IEl0ZW1UeXBlLlNlbGVjdCxcbiAgICBsYWJlbDogZ3JvdXBCeT8ubGFiZWwgfHwgJ0dyb3VwIEJ5JyxcbiAgICBtdWx0aXBsZTogZmFsc2UsXG4gICAgdmFsdWVzOiAoKSA9PiB2YWx1ZXMsXG4gICAgZGVmYXVsdDogaXNHcmFudWxhcml0eU9mZmVyZWQocmVwb3J0LCBpbml0aWFsID8/IG51bGwpID8gKGluaXRpYWwgPz8gdW5kZWZpbmVkKSA6IHVuZGVmaW5lZCxcbiAgfTtcbn1cblxuLy8gVGhlIGdyb3VwLWJ5IGNvbnRyb2wncyBjb250cmlidXRpb24gdG8gdGhlIHRvb2xiYXIncyBmcy1maWx0ZXIga2V5LiBmcy1maWx0ZXJcbi8vIHJlYWRzIGl0cyBjb25maWcgb25jZSBhdCBpbml0LCBhbmQgdGhlIGFnZW50IGNhbiBjaGFuZ2UgdGhlIGNvbnRyb2wncyBsYWJlbFxuLy8gb3IgdGhlIGdyYWlucyBpdCBvZmZlcnMg4oCUIHdpdGhvdXQgdGhvc2UgaW4gdGhlIGtleSB0aGUgYmFyIGtlZXBzIHJlbmRlcmluZ1xuLy8gdGhlIGNvbnRyb2wgaXQgd2FzIGNyZWF0ZWQgd2l0aCB1bnRpbCBhIGZ1bGwgcGFnZSByZWxvYWQuXG5leHBvcnQgZnVuY3Rpb24gZ3JvdXBCeVNpZ25hdHVyZShyZXBvcnQ6IFJlcG9ydCB8IG51bGwpOiBzdHJpbmcge1xuICBpZiAoIXJlcG9ydCB8fCAhZ3JvdXBCeUZpbHRlckl0ZW0ocmVwb3J0KSkge1xuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIGNvbnN0IGdyb3VwQnkgPSByZXBvcnQuY29uZmlnPy5ncm91cEJ5O1xuXG4gIHJldHVybiBbJ2dyb3VwQnknLCBncm91cEJ5Py5sYWJlbCA/PyAnJywgKGdyb3VwQnk/LmdyYW51bGFyaXRpZXMgPz8gW10pLmpvaW4oJywnKV0uam9pbignOicpO1xufVxuXG4vLyBSZWFkIGFuIGZzLWZpbHRlciBjaGFuZ2UgcXVlcnkgaW50byBwZXItZ3JvdXAgdmFsdWVzLiBSZXR1cm5zIG9uZSBlbnRyeSBwZXJcbi8vIGdyb3VwIHdpdGggdGhlIHZhbHVlIHRvIHN0b3JlIChvciBudWxsIHRvIGNsZWFyKSDigJQgY2FsbGVycyBmZWVkIHRoZXNlIHRvXG4vLyBSZXBvcnRGaWx0ZXJTdGF0ZVNlcnZpY2Uuc2V0VmFsdWUuXG5leHBvcnQgZnVuY3Rpb24gZ3JvdXBWYWx1ZXNGcm9tUXVlcnkoXG4gIHF1ZXJ5OiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICBncm91cHM6IFJlcG9ydEZpbHRlckdyb3VwW10sXG4pOiB7IGdyb3VwSWQ6IG51bWJlcjsgdmFsdWU6IEZpbHRlckdyb3VwVmFsdWUgfCBudWxsIH1bXSB7XG4gIHJldHVybiBncm91cHMubWFwKChncm91cCkgPT4ge1xuICAgIGNvbnN0IG5hbWUgPSBncm91cEl0ZW1OYW1lKGdyb3VwKTtcblxuICAgIHN3aXRjaCAoZ3JvdXAudHlwZSkge1xuICAgICAgY2FzZSAnZGF0ZVJhbmdlJzpcbiAgICAgICAgcmV0dXJuIHsgZ3JvdXBJZDogZ3JvdXAuaWQsIHZhbHVlOiBkYXRlUmFuZ2VGcm9tUXVlcnkocXVlcnksIG5hbWUpIH07XG5cbiAgICAgIGNhc2UgJ3NlbGVjdCc6XG4gICAgICAgIHJldHVybiB7IGdyb3VwSWQ6IGdyb3VwLmlkLCB2YWx1ZTogc2VsZWN0RnJvbVF1ZXJ5KHF1ZXJ5LCBuYW1lKSB9O1xuXG4gICAgICBjYXNlICdudW1iZXJSYW5nZSc6XG4gICAgICAgIHJldHVybiB7IGdyb3VwSWQ6IGdyb3VwLmlkLCB2YWx1ZTogbnVtYmVyUmFuZ2VGcm9tUXVlcnkocXVlcnksIG5hbWUpIH07XG5cbiAgICAgIGRlZmF1bHQ6IHtcbiAgICAgICAgY29uc3Qga2V5d29yZCA9IFN0cmluZyhxdWVyeVtuYW1lXSA/PyAnJykudHJpbSgpO1xuXG4gICAgICAgIHJldHVybiB7IGdyb3VwSWQ6IGdyb3VwLmlkLCB2YWx1ZToga2V5d29yZCA/IHsgdmFsdWU6IGtleXdvcmQgfSA6IG51bGwgfTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xufVxuXG4vLyBBIGRhdGUgcmFuZ2UncyBkYXlzICg8bmFtZT5Gcm9tLCA8bmFtZT5UbykuXG5mdW5jdGlvbiBkYXRlUmFuZ2VGcm9tUXVlcnkocXVlcnk6IFJlY29yZDxzdHJpbmcsIGFueT4sIG5hbWU6IHN0cmluZyk6IEZpbHRlckdyb3VwVmFsdWUgfCBudWxsIHtcbiAgY29uc3Qgc3RhcnQgPSBxdWVyeVtpdGVtUmFuZ2VOYW1lKG5hbWUsICdmcm9tJyldO1xuICBjb25zdCBlbmQgPSBxdWVyeVtpdGVtUmFuZ2VOYW1lKG5hbWUsICd0bycpXTtcblxuICBpZiAoIXN0YXJ0ICYmICFlbmQpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiB7IHN0YXJ0OiBzdGFydCB8fCBudWxsLCBlbmQ6IGVuZCB8fCBudWxsIH07XG59XG5cbi8vIEEgc2VsZWN0J3MgcGlja3M6IGtlcHQgKDxuYW1lPiksIG9yIGxlZnQgb3V0IHdoaWxlIGl0cyBleGNsdWRlIHJvdyBpcyBvblxuLy8gKGV4Y2x1ZGU8TmFtZT4pLlxuZnVuY3Rpb24gc2VsZWN0RnJvbVF1ZXJ5KHF1ZXJ5OiBSZWNvcmQ8c3RyaW5nLCBhbnk+LCBuYW1lOiBzdHJpbmcpOiBGaWx0ZXJHcm91cFZhbHVlIHwgbnVsbCB7XG4gIGNvbnN0IGV4Y2x1ZGVWYWx1ZXMgPSBzZWxlY3RRdWVyeVZhbHVlcyhxdWVyeVtnZXRFeGNsdWRlTmFtZShuYW1lKV0pO1xuICBpZiAoZXhjbHVkZVZhbHVlcy5sZW5ndGgpIHtcbiAgICByZXR1cm4geyBleGNsdWRlVmFsdWVzIH07XG4gIH1cblxuICBjb25zdCB2YWx1ZXMgPSBzZWxlY3RRdWVyeVZhbHVlcyhxdWVyeVtuYW1lXSk7XG5cbiAgcmV0dXJuIHZhbHVlcy5sZW5ndGggPyB7IHZhbHVlcyB9IDogbnVsbDtcbn1cblxuLy8gQSBudW1iZXIgcmFuZ2UncyBlbmRzICg8bmFtZT5NaW4sIDxuYW1lPk1heCkuIEFuIGVuZCBsZWZ0IGVtcHR5IGlzIG9wZW4uXG5mdW5jdGlvbiBudW1iZXJSYW5nZUZyb21RdWVyeShxdWVyeTogUmVjb3JkPHN0cmluZywgYW55PiwgbmFtZTogc3RyaW5nKTogRmlsdGVyR3JvdXBWYWx1ZSB8IG51bGwge1xuICBjb25zdCBtaW4gPSByYW5nZUJvdW5kKHF1ZXJ5W2l0ZW1SYW5nZU5hbWUobmFtZSwgJ21pbicpXSk7XG4gIGNvbnN0IG1heCA9IHJhbmdlQm91bmQocXVlcnlbaXRlbVJhbmdlTmFtZShuYW1lLCAnbWF4JyldKTtcblxuICBpZiAobWluID09PSBudWxsICYmIG1heCA9PT0gbnVsbCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICAuLi4obWluICE9PSBudWxsID8geyBtaW4gfSA6IHt9KSxcbiAgICAuLi4obWF4ICE9PSBudWxsID8geyBtYXggfSA6IHt9KSxcbiAgfTtcbn1cblxuLy8gT25lIGVuZCBvZiBhIG51bWJlciByYW5nZSBhcyBmcy1maWx0ZXIncyBSYW5nZSBzZW5kcyBpdDogdGhlIHRleHQgdHlwZWQgaW5cbi8vIGl0cyBpbnB1dC4gTnVtYmVyKCkgcmVhZHMgYW55IG5vbi1lbXB0eSB0ZXh0LCBzbyAnMCcgaXMgdGhlIGVuZCAwOyBlbXB0eSBvclxuLy8gdW5yZWFkYWJsZSB0ZXh0IGlzIGFuIG9wZW4gZW5kLlxuZnVuY3Rpb24gcmFuZ2VCb3VuZChyYXc6IHVua25vd24pOiBudW1iZXIgfCBudWxsIHtcbiAgY29uc3QgdGV4dCA9IHR5cGVvZiByYXcgPT09ICdudW1iZXInID8gU3RyaW5nKHJhdykgOiBTdHJpbmcocmF3ID8/ICcnKS50cmltKCk7XG4gIGNvbnN0IG51bWJlciA9IHRleHQgPT09ICcnID8gTmFOIDogTnVtYmVyKHRleHQpO1xuXG4gIHJldHVybiBOdW1iZXIuaXNGaW5pdGUobnVtYmVyKSA/IG51bWJlciA6IG51bGw7XG59XG5cbi8vIEEgZ3JvdXAgdmFsdWUgYXMgdGV4dCwgdGhlIHNhbWUgZm9yIHRoZSBzYW1lIHZhbHVlIHdoYXRldmVyIGl0cyBzb3VyY2U6XG4vLyBkYXlzIGFzIGNhbGVuZGFyIGRheXMsIHBpY2tzIGFuZCBlbmRzIGFzIHRleHQsIGtleXdvcmQgdGV4dCB0cmltbWVkLiBUaGVcbi8vIHZhbHVlIGEgdGlsZSBoZWFkZXIgd2FzIGJ1aWx0IHdpdGggaXMga2V5ZWQgb24gaXQsIHNvIGEgaGVhZGVyIGlzIGNyZWF0ZWRcbi8vIGFnYWluIHdoZW4gYW5vdGhlciBiYXIgY2hhbmdlcyBhIGdyb3VwIGl0IHNob3dzLlxuZXhwb3J0IGZ1bmN0aW9uIGdyb3VwVmFsdWVTaWduYXR1cmUodmFsdWU6IEZpbHRlckdyb3VwVmFsdWUgfCBudWxsIHwgdW5kZWZpbmVkKTogc3RyaW5nIHtcbiAgaWYgKCF2YWx1ZSkge1xuICAgIHJldHVybiAnJztcbiAgfVxuXG4gIHJldHVybiBKU09OLnN0cmluZ2lmeShbXG4gICAgZGF0ZUJvdW5kU3RyaW5nKHZhbHVlLnN0YXJ0KSA/PyAnJyxcbiAgICBkYXRlQm91bmRTdHJpbmcodmFsdWUuZW5kKSA/PyAnJyxcbiAgICAodmFsdWUudmFsdWVzID8/IFtdKS5tYXAoU3RyaW5nKSxcbiAgICAodmFsdWUuZXhjbHVkZVZhbHVlcyA/PyBbXSkubWFwKFN0cmluZyksXG4gICAgKHZhbHVlLnZhbHVlID8/ICcnKS50cmltKCksXG4gICAgdmFsdWUubWluID8/ICcnLFxuICAgIHZhbHVlLm1heCA/PyAnJyxcbiAgXSk7XG59XG5cbi8vIGZzLWZpbHRlcidzIEF1dG9Db21wbGV0ZUNoaXBzIHNlcmlhbGlzZXMgYSBtdWx0aS1zZWxlY3QgaW50byBPTkUgcXVlcnkgdmFsdWU6XG4vLyB0aGUgc2VsZWN0ZWQgdmFsdWVzIGpvaW5lZCBieSBcIixcIiAoaXRzIGBxdWVyeWAgZ2V0dGVyIGRvZXMgYC5tYXAodmFsdWUpLmpvaW4oJywnKWApLlxuLy8gU28gYSAyKyBzZWxlY3Rpb24gYXJyaXZlcyBhcyB0aGUgc3RyaW5nIFwiYSxiXCIsIG5vdCBhbiBhcnJheSDigJQgc3BsaXR0aW5nIG9uIFwiLFwiXG4vLyByZXZlcnNlcyB0aGF0IGZhaXRoZnVsbHkuIFdpdGhvdXQgdGhpcywgYSBtdWx0aS1zZWxlY3Qgd2FzIHNlbnQgYXMgdGhlIHNpbmdsZVxuLy8gdmFsdWUgW1wiYSxiXCJdLCBwcm9kdWNpbmcgYGNvbCBJTiAoJ2EsYicpYCBzZXJ2ZXItc2lkZSwgd2hpY2ggbWF0Y2hlcyBub3RoaW5nLlxuZnVuY3Rpb24gc2VsZWN0UXVlcnlWYWx1ZXMocmF3OiB1bmtub3duKTogdW5rbm93bltdIHtcbiAgaWYgKEFycmF5LmlzQXJyYXkocmF3KSkge1xuICAgIHJldHVybiByYXc7XG4gIH1cblxuICBpZiAocmF3ID09PSBudWxsIHx8IHJhdyA9PT0gdW5kZWZpbmVkIHx8IHJhdyA9PT0gJycpIHtcbiAgICByZXR1cm4gW107XG4gIH1cblxuICByZXR1cm4gU3RyaW5nKHJhdykuc3BsaXQoJywnKTtcbn1cbiJdfQ==
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// The component types that are tiles: each is drawn on the page from its own
|
|
2
|
+
// read of the data. The list is positive, so a type added later (or one this
|
|
3
|
+
// viewer does not know) is never taken for a tile. The server's twin is
|
|
4
|
+
// ReportComponentModel::isTile().
|
|
5
|
+
const TILE_TYPES = ['chart', 'list', 'kpi'];
|
|
6
|
+
// Whether a component is a tile: a chart, a list or a KPI. Only a tile is
|
|
7
|
+
// drawn as one, fetched, exported as a file or counted among a filter group's
|
|
8
|
+
// tiles; every loop over a report's tiles reads this.
|
|
9
|
+
export function isTile(component) {
|
|
10
|
+
return !!component && TILE_TYPES.includes(component.type);
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LXRpbGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvYXBwL3JlcG9ydHMvcmVwb3J0LXRpbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBR0EsNkVBQTZFO0FBQzdFLDZFQUE2RTtBQUM3RSx3RUFBd0U7QUFDeEUsa0NBQWtDO0FBQ2xDLE1BQU0sVUFBVSxHQUFtQyxDQUFDLE9BQU8sRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFFNUUsMEVBQTBFO0FBQzFFLDhFQUE4RTtBQUM5RSxzREFBc0Q7QUFDdEQsTUFBTSxVQUFVLE1BQU0sQ0FBQyxTQUEyRDtJQUNoRixPQUFPLENBQUMsQ0FBQyxTQUFTLElBQUksVUFBVSxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDNUQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJlcG9ydENvbXBvbmVudCwgUmVwb3J0Q29tcG9uZW50VHlwZSB9IGZyb20gJy4vaW50ZXJmYWNlcy9yZXBvcnQuaW50ZXJmYWNlJztcblxuXG4vLyBUaGUgY29tcG9uZW50IHR5cGVzIHRoYXQgYXJlIHRpbGVzOiBlYWNoIGlzIGRyYXduIG9uIHRoZSBwYWdlIGZyb20gaXRzIG93blxuLy8gcmVhZCBvZiB0aGUgZGF0YS4gVGhlIGxpc3QgaXMgcG9zaXRpdmUsIHNvIGEgdHlwZSBhZGRlZCBsYXRlciAob3Igb25lIHRoaXNcbi8vIHZpZXdlciBkb2VzIG5vdCBrbm93KSBpcyBuZXZlciB0YWtlbiBmb3IgYSB0aWxlLiBUaGUgc2VydmVyJ3MgdHdpbiBpc1xuLy8gUmVwb3J0Q29tcG9uZW50TW9kZWw6OmlzVGlsZSgpLlxuY29uc3QgVElMRV9UWVBFUzogcmVhZG9ubHkgUmVwb3J0Q29tcG9uZW50VHlwZVtdID0gWydjaGFydCcsICdsaXN0JywgJ2twaSddO1xuXG4vLyBXaGV0aGVyIGEgY29tcG9uZW50IGlzIGEgdGlsZTogYSBjaGFydCwgYSBsaXN0IG9yIGEgS1BJLiBPbmx5IGEgdGlsZSBpc1xuLy8gZHJhd24gYXMgb25lLCBmZXRjaGVkLCBleHBvcnRlZCBhcyBhIGZpbGUgb3IgY291bnRlZCBhbW9uZyBhIGZpbHRlciBncm91cCdzXG4vLyB0aWxlczsgZXZlcnkgbG9vcCBvdmVyIGEgcmVwb3J0J3MgdGlsZXMgcmVhZHMgdGhpcy5cbmV4cG9ydCBmdW5jdGlvbiBpc1RpbGUoY29tcG9uZW50OiBQaWNrPFJlcG9ydENvbXBvbmVudCwgJ3R5cGUnPiB8IG51bGwgfCB1bmRlZmluZWQpOiBib29sZWFuIHtcbiAgcmV0dXJuICEhY29tcG9uZW50ICYmIFRJTEVfVFlQRVMuaW5jbHVkZXMoY29tcG9uZW50LnR5cGUpO1xufVxuIl19
|