@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
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
import { RELATIVE_RANGE_NAMES, isRelativeRange } from './report-view-config';
|
|
2
|
+
import { offersExclude } from './report-viewer-features';
|
|
3
|
+
// The Type select's choices. A column that can be either holds both.
|
|
4
|
+
export const FILTER_TYPE_OPTIONS = [
|
|
5
|
+
{ value: 'select', name: 'Values' },
|
|
6
|
+
{ value: 'numberRange', name: 'Number range' },
|
|
7
|
+
];
|
|
8
|
+
export const TYPE_LOCKED_TOOLTIP = 'Remove the filter to change its type.';
|
|
9
|
+
export const PAGE_FILTER_TOOLTIP = 'A page filter shows in the page bar only.';
|
|
10
|
+
export const COMPONENT_TOGGLE_TOOLTIP = 'Show on this component';
|
|
11
|
+
// The Default period select's value for a range of fixed days. No relative
|
|
12
|
+
// range is named this.
|
|
13
|
+
export const FIXED_DATES_PERIOD = 'fixed';
|
|
14
|
+
// How many decimals a Default minimum or Default maximum takes.
|
|
15
|
+
export const DEFAULT_BOUND_SCALE = 6;
|
|
16
|
+
// A filter's Name and Label, checked as the server checks them, so a bad one
|
|
17
|
+
// is caught before Save. The name is an identifier: a letter, then letters
|
|
18
|
+
// and digits. That it is unique in the report is the server's to check.
|
|
19
|
+
export const FILTER_NAME_PATTERN = /^[A-Za-z][A-Za-z0-9]*$/;
|
|
20
|
+
export const FILTER_NAME_PATTERN_MESSAGE = 'A name starts with a letter and holds only letters and digits.';
|
|
21
|
+
export const FILTER_NAME_MAX_LENGTH = 50;
|
|
22
|
+
export const FILTER_LABEL_MAX_LENGTH = 200;
|
|
23
|
+
// Every Report bar choice, in the order the select lists them.
|
|
24
|
+
const BAR_PLACEMENT_OPTIONS = [
|
|
25
|
+
{ value: 'off', name: 'Off' },
|
|
26
|
+
{ value: 'every', name: 'Every page' },
|
|
27
|
+
{ value: 'page', name: 'This page only' },
|
|
28
|
+
];
|
|
29
|
+
// A number with its group commas in place ('1,250.5', '-12,000').
|
|
30
|
+
const GROUPED_DECIMAL = /^-?\d{1,3}(,\d{3})+(\.\d*)?$/;
|
|
31
|
+
// A plain decimal number ('1250.5', '-3', '0', '.5'). Hex, binary, octal,
|
|
32
|
+
// exponents and inner spaces do not match, though Number() reads some.
|
|
33
|
+
const PLAIN_DECIMAL = /^-?(\d+(\.\d*)?|\.\d+)$/;
|
|
34
|
+
// A default range end as typed. An empty field is no end. A number input
|
|
35
|
+
// with a mask hands back text with its group commas ('1,250.5'), so those go
|
|
36
|
+
// before Number() reads it; 0 is an end like any other. Anything that is not
|
|
37
|
+
// a decimal number is no end.
|
|
38
|
+
export function parseDefaultBound(raw) {
|
|
39
|
+
if (typeof raw === 'number') {
|
|
40
|
+
return Number.isFinite(raw) ? raw : null;
|
|
41
|
+
}
|
|
42
|
+
if (typeof raw !== 'string') {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
const trimmed = raw.trim();
|
|
46
|
+
const text = GROUPED_DECIMAL.test(trimmed) ? trimmed.replace(/,/g, '') : trimmed;
|
|
47
|
+
if (!PLAIN_DECIMAL.test(text)) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
const value = Number(text);
|
|
51
|
+
return Number.isFinite(value) ? value : null;
|
|
52
|
+
}
|
|
53
|
+
// Why two range ends cannot be saved, in the server's words, or null. An open
|
|
54
|
+
// end is always fine.
|
|
55
|
+
export function boundsError(min, max) {
|
|
56
|
+
if (min === null || max === null || min <= max) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
return `min (${min}) is above max (${max}).`;
|
|
60
|
+
}
|
|
61
|
+
// The Type select of a column on the component settings' Filters tab. It
|
|
62
|
+
// shows when the column can take either type and the server serves number
|
|
63
|
+
// ranges (an older server lists no features). A filter's type cannot change,
|
|
64
|
+
// so it is locked while the column has a filter on this component.
|
|
65
|
+
export function typeSelectState(types, hasFilterOnThisComponent, features) {
|
|
66
|
+
const show = (features ?? []).includes('numberRange')
|
|
67
|
+
&& FILTER_TYPE_OPTIONS.every((option) => (types ?? []).includes(option.value));
|
|
68
|
+
if (!show) {
|
|
69
|
+
return { show: false, disabled: false, tooltip: null };
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
show: true,
|
|
73
|
+
disabled: hasFilterOnThisComponent,
|
|
74
|
+
tooltip: hasFilterOnThisComponent ? TYPE_LOCKED_TOOLTIP : null,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
// The levels a new or moved filter can take on a component. This page only
|
|
78
|
+
// needs a server that serves page filters and a component on a page (a
|
|
79
|
+
// header or footer component is on no page).
|
|
80
|
+
export function filterLevelChoices(features, onPage) {
|
|
81
|
+
const levels = ['component', 'report', 'both'];
|
|
82
|
+
return onPage && (features ?? []).includes('pageScope')
|
|
83
|
+
? [...levels, 'page']
|
|
84
|
+
: levels;
|
|
85
|
+
}
|
|
86
|
+
// The Report bar select's choices for the levels on offer. The choice a row
|
|
87
|
+
// already holds is always listed, so the select never shows blank.
|
|
88
|
+
export function barPlacementOptions(levelChoices, current = 'off') {
|
|
89
|
+
return BAR_PLACEMENT_OPTIONS.filter((option) => {
|
|
90
|
+
switch (option.value) {
|
|
91
|
+
case 'every':
|
|
92
|
+
return levelChoices.includes('report') || levelChoices.includes('both') || current === 'every';
|
|
93
|
+
case 'page':
|
|
94
|
+
return levelChoices.includes('page') || current === 'page';
|
|
95
|
+
default:
|
|
96
|
+
return true;
|
|
97
|
+
}
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
// A value's Report bar choices. A value has no strip of its own and its
|
|
101
|
+
// group may be shared, so a pick never lowers the group (the inline values
|
|
102
|
+
// rule): This page only is offered for a new filter, or for a group that is
|
|
103
|
+
// already a page group, never to move a shared group to one page.
|
|
104
|
+
export function valuePlacementOptions(levelChoices, current) {
|
|
105
|
+
const choices = !current || current === 'page'
|
|
106
|
+
? levelChoices
|
|
107
|
+
: levelChoices.filter((level) => level !== 'page');
|
|
108
|
+
return barPlacementOptions(choices, barPlacement(current));
|
|
109
|
+
}
|
|
110
|
+
// The level a value's filter group ends at after a Report bar pick, or null
|
|
111
|
+
// when the value leaves it. Off unlinks this value alone and the group keeps
|
|
112
|
+
// its other members. A new filter takes the pick's level. Every page raises a
|
|
113
|
+
// strip-only group to both, keeping its strips, and a page group to the
|
|
114
|
+
// report bar. Nothing else moves the group, so a value never lowers it.
|
|
115
|
+
export function valueFilterLevel(placement, current) {
|
|
116
|
+
if (placement === 'off') {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
if (!current) {
|
|
120
|
+
return placement === 'page' ? 'page' : 'report';
|
|
121
|
+
}
|
|
122
|
+
if (placement !== 'every') {
|
|
123
|
+
return current;
|
|
124
|
+
}
|
|
125
|
+
switch (current) {
|
|
126
|
+
case 'component':
|
|
127
|
+
return 'both';
|
|
128
|
+
case 'page':
|
|
129
|
+
return 'report';
|
|
130
|
+
default:
|
|
131
|
+
return current;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// Where a group of a level shows in the report bar. No group (no filter) is
|
|
135
|
+
// off.
|
|
136
|
+
export function barPlacement(level) {
|
|
137
|
+
switch (level) {
|
|
138
|
+
case 'report':
|
|
139
|
+
case 'both':
|
|
140
|
+
return 'every';
|
|
141
|
+
case 'page':
|
|
142
|
+
return 'page';
|
|
143
|
+
default:
|
|
144
|
+
return 'off';
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
// Whether a group of a level shows on its components.
|
|
148
|
+
export function shownOnComponent(level) {
|
|
149
|
+
return level === 'component' || level === 'both';
|
|
150
|
+
}
|
|
151
|
+
// The level the two controls of a row ask for, or null when they ask for no
|
|
152
|
+
// filter at all. A page filter shows in its page's bar only, so This page
|
|
153
|
+
// only ignores the This component toggle.
|
|
154
|
+
export function filterLevel(placement, component) {
|
|
155
|
+
switch (placement) {
|
|
156
|
+
case 'page':
|
|
157
|
+
return 'page';
|
|
158
|
+
case 'every':
|
|
159
|
+
return component ? 'both' : 'report';
|
|
160
|
+
default:
|
|
161
|
+
return component ? 'component' : null;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
// The This component toggle of a row: locked while This page only is picked.
|
|
165
|
+
export function componentToggleState(placement) {
|
|
166
|
+
return placement === 'page'
|
|
167
|
+
? { disabled: true, tooltip: PAGE_FILTER_TOOLTIP }
|
|
168
|
+
: { disabled: false, tooltip: COMPONENT_TOGGLE_TOOLTIP };
|
|
169
|
+
}
|
|
170
|
+
// The groups the report settings' Filters tab lists defaults for: those of
|
|
171
|
+
// the report bar, every page or one, in bar order.
|
|
172
|
+
export function defaultRowGroups(groups) {
|
|
173
|
+
return (groups ?? [])
|
|
174
|
+
.filter((group) => group.level === 'report' || group.level === 'both' || group.level === 'page')
|
|
175
|
+
.sort((a, b) => a.order - b.order);
|
|
176
|
+
}
|
|
177
|
+
// A default row's label: a page group names its page, 'Region (page
|
|
178
|
+
// "Overview")'. A page with no name reads as the canvas names it ('Page 2').
|
|
179
|
+
// A page this report no longer holds adds nothing.
|
|
180
|
+
export function defaultRowLabel(group, pages) {
|
|
181
|
+
const label = group.label || group.filters?.[0]?.filterColumn || 'Filter';
|
|
182
|
+
if (group.level !== 'page') {
|
|
183
|
+
return label;
|
|
184
|
+
}
|
|
185
|
+
const index = (pages ?? []).findIndex((page) => page.id === group.pageId);
|
|
186
|
+
if (index < 0) {
|
|
187
|
+
return label;
|
|
188
|
+
}
|
|
189
|
+
return `${label} (page "${pages[index].name || `Page ${index + 1}`}")`;
|
|
190
|
+
}
|
|
191
|
+
// The Default period select's choices: Fixed dates, then every relative
|
|
192
|
+
// range in the server enum's order, named by `labels`. A stored range this
|
|
193
|
+
// viewer does not know is listed last, so the select still shows it.
|
|
194
|
+
export function defaultPeriodOptions(labels, stored = null) {
|
|
195
|
+
const options = [
|
|
196
|
+
{ value: FIXED_DATES_PERIOD, name: 'Fixed dates' },
|
|
197
|
+
...RELATIVE_RANGE_NAMES.map((relative) => ({ value: relative, name: labels(relative) })),
|
|
198
|
+
];
|
|
199
|
+
return stored && stored !== FIXED_DATES_PERIOD && !isRelativeRange(stored)
|
|
200
|
+
? [...options, { value: stored, name: labels(stored) }]
|
|
201
|
+
: options;
|
|
202
|
+
}
|
|
203
|
+
// The Default period a stored date range default opens on: its relative
|
|
204
|
+
// range, else Fixed dates (the days, or none).
|
|
205
|
+
export function defaultPeriod(stored) {
|
|
206
|
+
return stored?.relative && !stored.start && !stored.end
|
|
207
|
+
? stored.relative
|
|
208
|
+
: FIXED_DATES_PERIOD;
|
|
209
|
+
}
|
|
210
|
+
// A date range default in its stored shape: the relative range picked, else
|
|
211
|
+
// the fixed days, or null when there are none. Never both: the server
|
|
212
|
+
// refuses a relative range with days.
|
|
213
|
+
export function dateRangeDefault(period, start, end) {
|
|
214
|
+
if (period !== FIXED_DATES_PERIOD) {
|
|
215
|
+
return { relative: period };
|
|
216
|
+
}
|
|
217
|
+
if (!start && !end) {
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
return { ...(start ? { start } : {}), ...(end ? { end } : {}) };
|
|
221
|
+
}
|
|
222
|
+
// A select default in its stored shape: the picks kept, or left out while
|
|
223
|
+
// Exclude these values is on, or null when nothing is picked.
|
|
224
|
+
export function selectDefault(values, exclude) {
|
|
225
|
+
if (!values.length) {
|
|
226
|
+
return null;
|
|
227
|
+
}
|
|
228
|
+
return exclude ? { excludeValues: values } : { values };
|
|
229
|
+
}
|
|
230
|
+
// A number range default in its stored shape from the ends as typed: an
|
|
231
|
+
// open end is left out, 0 is kept, and two open ends are no default.
|
|
232
|
+
export function numberRangeDefault(rawMin, rawMax) {
|
|
233
|
+
const min = parseDefaultBound(rawMin);
|
|
234
|
+
const max = parseDefaultBound(rawMax);
|
|
235
|
+
if (min === null && max === null) {
|
|
236
|
+
return null;
|
|
237
|
+
}
|
|
238
|
+
return { ...(min !== null ? { min } : {}), ...(max !== null ? { max } : {}) };
|
|
239
|
+
}
|
|
240
|
+
// Whether a select group's default row offers Exclude these values: the
|
|
241
|
+
// report bar's rule (offersExclude), so not on a server that does not serve
|
|
242
|
+
// exclude (an older server lists no features) nor on a group with a member
|
|
243
|
+
// that binds several columns (multiColumn). A default that already leaves
|
|
244
|
+
// values out keeps the toggle, so it can be turned off.
|
|
245
|
+
export function showExcludeToggle(group, features) {
|
|
246
|
+
if (group.type === 'select' && group.config?.default?.excludeValues?.length) {
|
|
247
|
+
return true;
|
|
248
|
+
}
|
|
249
|
+
return offersExclude(group, features);
|
|
250
|
+
}
|
|
251
|
+
// A stored or draft default in a stable form for comparing: empty and
|
|
252
|
+
// absent keys are dropped, so a no-op edit does not read as a change. 0 is an
|
|
253
|
+
// end like any other. Nothing left is null.
|
|
254
|
+
export function normalizeDefault(value) {
|
|
255
|
+
if (!value) {
|
|
256
|
+
return null;
|
|
257
|
+
}
|
|
258
|
+
const normalized = {};
|
|
259
|
+
if (value.start) {
|
|
260
|
+
normalized.start = value.start;
|
|
261
|
+
}
|
|
262
|
+
if (value.end) {
|
|
263
|
+
normalized.end = value.end;
|
|
264
|
+
}
|
|
265
|
+
if (value.values?.length) {
|
|
266
|
+
normalized.values = value.values;
|
|
267
|
+
}
|
|
268
|
+
if (value.excludeValues?.length) {
|
|
269
|
+
normalized.excludeValues = value.excludeValues;
|
|
270
|
+
}
|
|
271
|
+
if (typeof value.min === 'number') {
|
|
272
|
+
normalized.min = value.min;
|
|
273
|
+
}
|
|
274
|
+
if (typeof value.max === 'number') {
|
|
275
|
+
normalized.max = value.max;
|
|
276
|
+
}
|
|
277
|
+
if (value.value) {
|
|
278
|
+
normalized.value = value.value;
|
|
279
|
+
}
|
|
280
|
+
if (value.relative) {
|
|
281
|
+
normalized.relative = value.relative;
|
|
282
|
+
}
|
|
283
|
+
return Object.keys(normalized).length ? normalized : null;
|
|
284
|
+
}
|
|
285
|
+
// Whether a row's draft default differs from the group's stored one. Only a
|
|
286
|
+
// changed row is saved.
|
|
287
|
+
export function defaultChanged(stored, draft) {
|
|
288
|
+
return JSON.stringify(normalizeDefault(stored)) !== JSON.stringify(normalizeDefault(draft));
|
|
289
|
+
}
|
|
290
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsdGVyLXNldHRpbmdzLXJ1bGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2ZpbHRlci1zZXR0aW5ncy1ydWxlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFtQkEsT0FBTyxFQUFFLG9CQUFvQixFQUFFLGVBQWUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQzdFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUd6RCxxRUFBcUU7QUFDckUsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQTZDO0lBQzNFLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFO0lBQ25DLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFFO0NBQy9DLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBRyx1Q0FBdUMsQ0FBQztBQUMzRSxNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBRywyQ0FBMkMsQ0FBQztBQUMvRSxNQUFNLENBQUMsTUFBTSx3QkFBd0IsR0FBRyx3QkFBd0IsQ0FBQztBQUVqRSwyRUFBMkU7QUFDM0UsdUJBQXVCO0FBQ3ZCLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLE9BQU8sQ0FBQztBQUUxQyxnRUFBZ0U7QUFDaEUsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUcsQ0FBQyxDQUFDO0FBRXJDLDZFQUE2RTtBQUM3RSwyRUFBMkU7QUFDM0Usd0VBQXdFO0FBQ3hFLE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLHdCQUF3QixDQUFDO0FBQzVELE1BQU0sQ0FBQyxNQUFNLDJCQUEyQixHQUFHLGdFQUFnRSxDQUFDO0FBQzVHLE1BQU0sQ0FBQyxNQUFNLHNCQUFzQixHQUFHLEVBQUUsQ0FBQztBQUN6QyxNQUFNLENBQUMsTUFBTSx1QkFBdUIsR0FBRyxHQUFHLENBQUM7QUFFM0MsK0RBQStEO0FB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LENBQUMsUUFBUSxFQUFFLENBQUM7UUFDbkIsVUFBVSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDO0lBQ3ZDLENBQUM7SUFFRCxPQUFPLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztBQUM1RCxDQUFDO0FBRUQsNEVBQTRFO0FBQzVFLHdCQUF3QjtBQUN4QixNQUFNLFVBQVUsY0FBYyxDQUM1QixNQUE2QyxFQUM3QyxLQUE0QztJQUU1QyxPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsZ0JBQWdCLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyxJQUFJLENBQUMsU0FBUyxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7QUFDOUYsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIFRoZSBydWxlcyBiZWhpbmQgdGhlIHR3byBmaWx0ZXIgc2V0dGluZ3MgZGlhbG9ncywga2VwdCBwdXJlIHNvIHRoZSBub2RlXG4vLyBoYXJuZXNzIGNoZWNrcyB0aGVtIHdpdGhvdXQgYSBkaWFsb2cuIFRoZSBjb21wb25lbnQgc2V0dGluZ3MnIEZpbHRlcnMgdGFiXG4vLyByZWFkcyB0aGUgVHlwZSBzZWxlY3QsIHRoZSBSZXBvcnQgYmFyIHNlbGVjdCBhbmQgdGhlIFRoaXMgY29tcG9uZW50IHRvZ2dsZVxuLy8gZnJvbSBoZXJlOyB0aGUgcmVwb3J0IHNldHRpbmdzJyBGaWx0ZXJzIHRhYiByZWFkcyBpdHMgZGVmYXVsdCByb3dzICh0aGVcbi8vIHBlcmlvZCwgdGhlIGV4Y2x1ZGUgdG9nZ2xlLCB0aGUgbnVtYmVyIHJhbmdlIGVuZHMgYW5kIHRoZWlyIGNoZWNrKSBmcm9tXG4vLyBoZXJlLiBUaGUgZGlhbG9ncyBvbmx5IGNhbGwgdGhlc2UuXG5pbXBvcnQgeyBGaWx0ZXJCYXJQbGFjZW1lbnQgfSBmcm9tICcuL2ludGVyZmFjZXMvZmlsdGVyLWJhci1wbGFjZW1lbnQudHlwZSc7XG5pbXBvcnQgeyBGaWx0ZXJDb21wb25lbnRUb2dnbGVTdGF0ZSB9IGZyb20gJy4vaW50ZXJmYWNlcy9maWx0ZXItY29tcG9uZW50LXRvZ2dsZS1zdGF0ZS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgRmlsdGVyU2V0dGluZ3NPcHRpb24gfSBmcm9tICcuL2ludGVyZmFjZXMvZmlsdGVyLXNldHRpbmdzLW9wdGlvbi5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgRmlsdGVyVHlwZVNlbGVjdFN0YXRlIH0gZnJvbSAnLi9pbnRlcmZhY2VzL2ZpbHRlci10eXBlLXNlbGVjdC1zdGF0ZS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgUmVwb3J0Vmlld2VyRmVhdHVyZSB9IGZyb20gJy4vaW50ZXJmYWNlcy9yZXBvcnQtdmlld2VyLWZlYXR1cmUudHlwZSc7XG5pbXBvcnQge1xuICBGaWx0ZXJHcm91cERlZmF1bHQsXG4gIFJlcG9ydEZpbHRlckdyb3VwLFxuICBSZXBvcnRGaWx0ZXJMZXZlbCxcbiAgUmVwb3J0RmlsdGVyVHlwZSxcbiAgUmVwb3J0UGFnZSxcbiAgUmVwb3J0UmVsYXRpdmVSYW5nZSxcbn0gZnJvbSAnLi9pbnRlcmZhY2VzL3JlcG9ydC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgUkVMQVRJVkVfUkFOR0VfTkFNRVMsIGlzUmVsYXRpdmVSYW5nZSB9IGZyb20gJy4vcmVwb3J0LXZpZXctY29uZmlnJztcbmltcG9ydCB7IG9mZmVyc0V4Y2x1ZGUgfSBmcm9tICcuL3JlcG9ydC12aWV3ZXItZmVhdHVyZXMnO1xuXG5cbi8vIFRoZSBUeXBlIHNlbGVjdCdzIGNob2ljZXMuIEEgY29sdW1uIHRoYXQgY2FuIGJlIGVpdGhlciBob2xkcyBib3RoLlxuZXhwb3J0IGNvbnN0IEZJTFRFUl9UWVBFX09QVElPTlM6IEZpbHRlclNldHRpbmdzT3B0aW9uPFJlcG9ydEZpbHRlclR5cGU+W10gPSBbXG4gIHsgdmFsdWU6ICdzZWxlY3QnLCBuYW1lOiAnVmFsdWVzJyB9LFxuICB7IHZhbHVlOiAnbnVtYmVyUmFuZ2UnLCBuYW1lOiAnTnVtYmVyIHJhbmdlJyB9LFxuXTtcblxuZXhwb3J0IGNvbnN0IFRZUEVfTE9DS0VEX1RPT0xUSVAgPSAnUmVtb3ZlIHRoZSBmaWx0ZXIgdG8gY2hhbmdlIGl0cyB0eXBlLic7XG5leHBvcnQgY29uc3QgUEFHRV9GSUxURVJfVE9PTFRJUCA9ICdBIHBhZ2UgZmlsdGVyIHNob3dzIGluIHRoZSBwYWdlIGJhciBvbmx5Lic7XG5leHBvcnQgY29uc3QgQ09NUE9ORU5UX1RPR0dMRV9UT09MVElQID0gJ1Nob3cgb24gdGhpcyBjb21wb25lbnQnO1xuXG4vLyBUaGUgRGVmYXVsdCBwZXJpb2Qgc2VsZWN0J3MgdmFsdWUgZm9yIGEgcmFuZ2Ugb2YgZml4ZWQgZGF5cy4gTm8gcmVsYXRpdmVcbi8vIHJhbmdlIGlzIG5hbWVkIHRoaXMuXG5leHBvcnQgY29uc3QgRklYRURfREFURVNfUEVSSU9EID0gJ2ZpeGVkJztcblxuLy8gSG93IG1hbnkgZGVjaW1hbHMgYSBEZWZhdWx0IG1pbmltdW0gb3IgRGVmYXVsdCBtYXhpbXVtIHRha2VzLlxuZXhwb3J0IGNvbnN0IERFRkFVTFRfQk9VTkRfU0NBTEUgPSA2O1xuXG4vLyBBIGZpbHRlcidzIE5hbWUgYW5kIExhYmVsLCBjaGVja2VkIGFzIHRoZSBzZXJ2ZXIgY2hlY2tzIHRoZW0sIHNvIGEgYmFkIG9uZVxuLy8gaXMgY2F1Z2h0IGJlZm9yZSBTYXZlLiBUaGUgbmFtZSBpcyBhbiBpZGVudGlmaWVyOiBhIGxldHRlciwgdGhlbiBsZXR0ZXJzXG4vLyBhbmQgZGlnaXRzLiBUaGF0IGl0IGlzIHVuaXF1ZSBpbiB0aGUgcmVwb3J0IGlzIHRoZSBzZXJ2ZXIncyB0byBjaGVjay5cbmV4cG9ydCBjb25zdCBGSUxURVJfTkFNRV9QQVRURVJOID0gL15bQS1aYS16XVtBLVphLXowLTldKiQvO1xuZXhwb3J0IGNvbnN0IEZJTFRFUl9OQU1FX1BBVFRFUk5fTUVTU0FHRSA9ICdBIG5hbWUgc3RhcnRzIHdpdGggYSBsZXR0ZXIgYW5kIGhvbGRzIG9ubHkgbGV0dGVycyBhbmQgZGlnaXRzLic7XG5leHBvcnQgY29uc3QgRklMVEVSX05BTUVfTUFYX0xFTkdUSCA9IDUwO1xuZXhwb3J0IGNvbnN0IEZJTFRFUl9MQUJFTF9NQVhfTEVOR1RIID0gMjAwO1xuXG4vLyBFdmVyeSBSZXBvcnQgYmFyIGNob2ljZSwgaW4gdGhlIG9yZGVyIHRoZSBzZWxlY3QgbGlzdHMgdGhlbS5cbmNvbnN0IEJBUl9QTEFDRU1FTlRfT1BUSU9OUzogRmlsdGVyU2V0dGluZ3NPcHRpb248RmlsdGVyQmFyUGxhY2VtZW50PltdID0gW1xuICB7IHZhbHVlOiAnb2ZmJywgbmFtZTogJ09mZicgfSxcbiAgeyB2YWx1ZTogJ2V2ZXJ5JywgbmFtZTogJ0V2ZXJ5IHBhZ2UnIH0sXG4gIHsgdmFsdWU6ICdwYWdlJywgbmFtZTogJ1RoaXMgcGFnZSBvbmx5JyB9LFxuXTtcblxuXG4vLyBBIG51bWJlciB3aXRoIGl0cyBncm91cCBjb21tYXMgaW4gcGxhY2UgKCcxLDI1MC41JywgJy0xMiwwMDAnKS5cbmNvbnN0IEdST1VQRURfREVDSU1BTCA9IC9eLT9cXGR7MSwzfSgsXFxkezN9KSsoXFwuXFxkKik/JC87XG4vLyBBIHBsYWluIGRlY2ltYWwgbnVtYmVyICgnMTI1MC41JywgJy0zJywgJzAnLCAnLjUnKS4gSGV4LCBiaW5hcnksIG9jdGFsLFxuLy8gZXhwb25lbnRzIGFuZCBpbm5lciBzcGFjZXMgZG8gbm90IG1hdGNoLCB0aG91Z2ggTnVtYmVyKCkgcmVhZHMgc29tZS5cbmNvbnN0IFBMQUlOX0RFQ0lNQUwgPSAvXi0/KFxcZCsoXFwuXFxkKik/fFxcLlxcZCspJC87XG5cbi8vIEEgZGVmYXVsdCByYW5nZSBlbmQgYXMgdHlwZWQuIEFuIGVtcHR5IGZpZWxkIGlzIG5vIGVuZC4gQSBudW1iZXIgaW5wdXRcbi8vIHdpdGggYSBtYXNrIGhhbmRzIGJhY2sgdGV4dCB3aXRoIGl0cyBncm91cCBjb21tYXMgKCcxLDI1MC41JyksIHNvIHRob3NlIGdvXG4vLyBiZWZvcmUgTnVtYmVyKCkgcmVhZHMgaXQ7IDAgaXMgYW4gZW5kIGxpa2UgYW55IG90aGVyLiBBbnl0aGluZyB0aGF0IGlzIG5vdFxuLy8gYSBkZWNpbWFsIG51bWJlciBpcyBubyBlbmQuXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VEZWZhdWx0Qm91bmQocmF3OiB1bmtub3duKTogbnVtYmVyIHwgbnVsbCB7XG4gIGlmICh0eXBlb2YgcmF3ID09PSAnbnVtYmVyJykge1xuICAgIHJldHVybiBOdW1iZXIuaXNGaW5pdGUocmF3KSA/IHJhdyA6IG51bGw7XG4gIH1cblxuICBpZiAodHlwZW9mIHJhdyAhPT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IHRyaW1tZWQgPSByYXcudHJpbSgpO1xuICBjb25zdCB0ZXh0ID0gR1JPVVBFRF9ERUNJTUFMLnRlc3QodHJpbW1lZCkgPyB0cmltbWVkLnJlcGxhY2UoLywvZywgJycpIDogdHJpbW1lZDtcbiAgaWYgKCFQTEFJTl9ERUNJTUFMLnRlc3QodGV4dCkpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IHZhbHVlID0gTnVtYmVyKHRleHQpO1xuXG4gIHJldHVybiBOdW1iZXIuaXNGaW5pdGUodmFsdWUpID8gdmFsdWUgOiBudWxsO1xufVxuXG4vLyBXaHkgdHdvIHJhbmdlIGVuZHMgY2Fubm90IGJlIHNhdmVkLCBpbiB0aGUgc2VydmVyJ3Mgd29yZHMsIG9yIG51bGwuIEFuIG9wZW5cbi8vIGVuZCBpcyBhbHdheXMgZmluZS5cbmV4cG9ydCBmdW5jdGlvbiBib3VuZHNFcnJvcihtaW46IG51bWJlciB8IG51bGwsIG1heDogbnVtYmVyIHwgbnVsbCk6IHN0cmluZyB8IG51bGwge1xuICBpZiAobWluID09PSBudWxsIHx8IG1heCA9PT0gbnVsbCB8fCBtaW4gPD0gbWF4KSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICByZXR1cm4gYG1pbiAoJHttaW59KSBpcyBhYm92ZSBtYXggKCR7bWF4fSkuYDtcbn1cblxuLy8gVGhlIFR5cGUgc2VsZWN0IG9mIGEgY29sdW1uIG9uIHRoZSBjb21wb25lbnQgc2V0dGluZ3MnIEZpbHRlcnMgdGFiLiBJdFxuLy8gc2hvd3Mgd2hlbiB0aGUgY29sdW1uIGNhbiB0YWtlIGVpdGhlciB0eXBlIGFuZCB0aGUgc2VydmVyIHNlcnZlcyBudW1iZXJcbi8vIHJhbmdlcyAoYW4gb2xkZXIgc2VydmVyIGxpc3RzIG5vIGZlYXR1cmVzKS4gQSBmaWx0ZXIncyB0eXBlIGNhbm5vdCBjaGFuZ2UsXG4vLyBzbyBpdCBpcyBsb2NrZWQgd2hpbGUgdGhlIGNvbHVtbiBoYXMgYSBmaWx0ZXIgb24gdGhpcyBjb21wb25lbnQuXG5leHBvcnQgZnVuY3Rpb24gdHlwZVNlbGVjdFN0YXRlKFxuICB0eXBlczogUmVwb3J0RmlsdGVyVHlwZVtdIHwgbnVsbCB8IHVuZGVmaW5lZCxcbiAgaGFzRmlsdGVyT25UaGlzQ29tcG9uZW50OiBib29sZWFuLFxuICBmZWF0dXJlczogUmVwb3J0Vmlld2VyRmVhdHVyZVtdIHwgbnVsbCB8IHVuZGVmaW5lZCxcbik6IEZpbHRlclR5cGVTZWxlY3RTdGF0ZSB7XG4gIGNvbnN0IHNob3cgPSAoZmVhdHVyZXMgPz8gW10pLmluY2x1ZGVzKCdudW1iZXJSYW5nZScpXG4gICAgJiYgRklMVEVSX1RZUEVfT1BUSU9OUy5ldmVyeSgob3B0aW9uKSA9PiAodHlwZXMgPz8gW10pLmluY2x1ZGVzKG9wdGlvbi52YWx1ZSkpO1xuXG4gIGlmICghc2hvdykge1xuICAgIHJldHVybiB7IHNob3c6IGZhbHNlLCBkaXNhYmxlZDogZmFsc2UsIHRvb2x0aXA6IG51bGwgfTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgc2hvdzogdHJ1ZSxcbiAgICBkaXNhYmxlZDogaGFzRmlsdGVyT25UaGlzQ29tcG9uZW50LFxuICAgIHRvb2x0aXA6IGhhc0ZpbHRlck9uVGhpc0NvbXBvbmVudCA/IFRZUEVfTE9DS0VEX1RPT0xUSVAgOiBudWxsLFxuICB9O1xufVxuXG4vLyBUaGUgbGV2ZWxzIGEgbmV3IG9yIG1vdmVkIGZpbHRlciBjYW4gdGFrZSBvbiBhIGNvbXBvbmVudC4gVGhpcyBwYWdlIG9ubHlcbi8vIG5lZWRzIGEgc2VydmVyIHRoYXQgc2VydmVzIHBhZ2UgZmlsdGVycyBhbmQgYSBjb21wb25lbnQgb24gYSBwYWdlIChhXG4vLyBoZWFkZXIgb3IgZm9vdGVyIGNvbXBvbmVudCBpcyBvbiBubyBwYWdlKS5cbmV4cG9ydCBmdW5jdGlvbiBmaWx0ZXJMZXZlbENob2ljZXMoXG4gIGZlYXR1cmVzOiBSZXBvcnRWaWV3ZXJGZWF0dXJlW10gfCBudWxsIHwgdW5kZWZpbmVkLFxuICBvblBhZ2U6IGJvb2xlYW4sXG4pOiBSZXBvcnRGaWx0ZXJMZXZlbFtdIHtcbiAgY29uc3QgbGV2ZWxzOiBSZXBvcnRGaWx0ZXJMZXZlbFtdID0gWydjb21wb25lbnQnLCAncmVwb3J0JywgJ2JvdGgnXTtcblxuICByZXR1cm4gb25QYWdlICYmIChmZWF0dXJlcyA/PyBbXSkuaW5jbHVkZXMoJ3BhZ2VTY29wZScpXG4gICAgPyBbLi4ubGV2ZWxzLCAncGFnZSddXG4gICAgOiBsZXZlbHM7XG59XG5cbi8vIFRoZSBSZXBvcnQgYmFyIHNlbGVjdCdzIGNob2ljZXMgZm9yIHRoZSBsZXZlbHMgb24gb2ZmZXIuIFRoZSBjaG9pY2UgYSByb3dcbi8vIGFscmVhZHkgaG9sZHMgaXMgYWx3YXlzIGxpc3RlZCwgc28gdGhlIHNlbGVjdCBuZXZlciBzaG93cyBibGFuay5cbmV4cG9ydCBmdW5jdGlvbiBiYXJQbGFjZW1lbnRPcHRpb25zKFxuICBsZXZlbENob2ljZXM6IFJlcG9ydEZpbHRlckxldmVsW10sXG4gIGN1cnJlbnQ6IEZpbHRlckJhclBsYWNlbWVudCA9ICdvZmYnLFxuKTogRmlsdGVyU2V0dGluZ3NPcHRpb248RmlsdGVyQmFyUGxhY2VtZW50PltdIHtcbiAgcmV0dXJuIEJBUl9QTEFDRU1FTlRfT1BUSU9OUy5maWx0ZXIoKG9wdGlvbikgPT4ge1xuICAgIHN3aXRjaCAob3B0aW9uLnZhbHVlKSB7XG4gICAgICBjYXNlICdldmVyeSc6XG4gICAgICAgIHJldHVybiBsZXZlbENob2ljZXMuaW5jbHVkZXMoJ3JlcG9ydCcpIHx8IGxldmVsQ2hvaWNlcy5pbmNsdWRlcygnYm90aCcpIHx8IGN1cnJlbnQgPT09ICdldmVyeSc7XG4gICAgICBjYXNlICdwYWdlJzpcbiAgICAgICAgcmV0dXJuIGxldmVsQ2hvaWNlcy5pbmNsdWRlcygncGFnZScpIHx8IGN1cnJlbnQgPT09ICdwYWdlJztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfSk7XG59XG5cbi8vIEEgdmFsdWUncyBSZXBvcnQgYmFyIGNob2ljZXMuIEEgdmFsdWUgaGFzIG5vIHN0cmlwIG9mIGl0cyBvd24gYW5kIGl0c1xuLy8gZ3JvdXAgbWF5IGJlIHNoYXJlZCwgc28gYSBwaWNrIG5ldmVyIGxvd2VycyB0aGUgZ3JvdXAgKHRoZSBpbmxpbmUgdmFsdWVzXG4vLyBydWxlKTogVGhpcyBwYWdlIG9ubHkgaXMgb2ZmZXJlZCBmb3IgYSBuZXcgZmlsdGVyLCBvciBmb3IgYSBncm91cCB0aGF0IGlzXG4vLyBhbHJlYWR5IGEgcGFnZSBncm91cCwgbmV2ZXIgdG8gbW92ZSBhIHNoYXJlZCBncm91cCB0byBvbmUgcGFnZS5cbmV4cG9ydCBmdW5jdGlvbiB2YWx1ZVBsYWNlbWVudE9wdGlvbnMoXG4gIGxldmVsQ2hvaWNlczogUmVwb3J0RmlsdGVyTGV2ZWxbXSxcbiAgY3VycmVudDogUmVwb3J0RmlsdGVyTGV2ZWwgfCBudWxsIHwgdW5kZWZpbmVkLFxuKTogRmlsdGVyU2V0dGluZ3NPcHRpb248RmlsdGVyQmFyUGxhY2VtZW50PltdIHtcbiAgY29uc3QgY2hvaWNlcyA9ICFjdXJyZW50IHx8IGN1cnJlbnQgPT09ICdwYWdlJ1xuICAgID8gbGV2ZWxDaG9pY2VzXG4gICAgOiBsZXZlbENob2ljZXMuZmlsdGVyKChsZXZlbCkgPT4gbGV2ZWwgIT09ICdwYWdlJyk7XG5cbiAgcmV0dXJuIGJhclBsYWNlbWVudE9wdGlvbnMoY2hvaWNlcywgYmFyUGxhY2VtZW50KGN1cnJlbnQpKTtcbn1cblxuLy8gVGhlIGxldmVsIGEgdmFsdWUncyBmaWx0ZXIgZ3JvdXAgZW5kcyBhdCBhZnRlciBhIFJlcG9ydCBiYXIgcGljaywgb3IgbnVsbFxuLy8gd2hlbiB0aGUgdmFsdWUgbGVhdmVzIGl0LiBPZmYgdW5saW5rcyB0aGlzIHZhbHVlIGFsb25lIGFuZCB0aGUgZ3JvdXAga2VlcHNcbi8vIGl0cyBvdGhlciBtZW1iZXJzLiBBIG5ldyBmaWx0ZXIgdGFrZXMgdGhlIHBpY2sncyBsZXZlbC4gRXZlcnkgcGFnZSByYWlzZXMgYVxuLy8gc3RyaXAtb25seSBncm91cCB0byBib3RoLCBrZWVwaW5nIGl0cyBzdHJpcHMsIGFuZCBhIHBhZ2UgZ3JvdXAgdG8gdGhlXG4vLyByZXBvcnQgYmFyLiBOb3RoaW5nIGVsc2UgbW92ZXMgdGhlIGdyb3VwLCBzbyBhIHZhbHVlIG5ldmVyIGxvd2VycyBpdC5cbmV4cG9ydCBmdW5jdGlvbiB2YWx1ZUZpbHRlckxldmVsKFxuICBwbGFjZW1lbnQ6IEZpbHRlckJhclBsYWNlbWVudCxcbiAgY3VycmVudDogUmVwb3J0RmlsdGVyTGV2ZWwgfCBudWxsIHwgdW5kZWZpbmVkLFxuKTogUmVwb3J0RmlsdGVyTGV2ZWwgfCBudWxsIHtcbiAgaWYgKHBsYWNlbWVudCA9PT0gJ29mZicpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGlmICghY3VycmVudCkge1xuICAgIHJldHVybiBwbGFjZW1lbnQgPT09ICdwYWdlJyA/ICdwYWdlJyA6ICdyZXBvcnQnO1xuICB9XG5cbiAgaWYgKHBsYWNlbWVudCAhPT0gJ2V2ZXJ5Jykge1xuICAgIHJldHVybiBjdXJyZW50O1xuICB9XG5cbiAgc3dpdGNoIChjdXJyZW50KSB7XG4gICAgY2FzZSAnY29tcG9uZW50JzpcbiAgICAgIHJldHVybiAnYm90aCc7XG4gICAgY2FzZSAncGFnZSc6XG4gICAgICByZXR1cm4gJ3JlcG9ydCc7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBjdXJyZW50O1xuICB9XG59XG5cbi8vIFdoZXJlIGEgZ3JvdXAgb2YgYSBsZXZlbCBzaG93cyBpbiB0aGUgcmVwb3J0IGJhci4gTm8gZ3JvdXAgKG5vIGZpbHRlcikgaXNcbi8vIG9mZi5cbmV4cG9ydCBmdW5jdGlvbiBiYXJQbGFjZW1lbnQobGV2ZWw6IFJlcG9ydEZpbHRlckxldmVsIHwgbnVsbCB8IHVuZGVmaW5lZCk6IEZpbHRlckJhclBsYWNlbWVudCB7XG4gIHN3aXRjaCAobGV2ZWwpIHtcbiAgICBjYXNlICdyZXBvcnQnOlxuICAgIGNhc2UgJ2JvdGgnOlxuICAgICAgcmV0dXJuICdldmVyeSc7XG4gICAgY2FzZSAncGFnZSc6XG4gICAgICByZXR1cm4gJ3BhZ2UnO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gJ29mZic7XG4gIH1cbn1cblxuLy8gV2hldGhlciBhIGdyb3VwIG9mIGEgbGV2ZWwgc2hvd3Mgb24gaXRzIGNvbXBvbmVudHMuXG5leHBvcnQgZnVuY3Rpb24gc2hvd25PbkNvbXBvbmVudChsZXZlbDogUmVwb3J0RmlsdGVyTGV2ZWwgfCBudWxsIHwgdW5kZWZpbmVkKTogYm9vbGVhbiB7XG4gIHJldHVybiBsZXZlbCA9PT0gJ2NvbXBvbmVudCcgfHwgbGV2ZWwgPT09ICdib3RoJztcbn1cblxuLy8gVGhlIGxldmVsIHRoZSB0d28gY29udHJvbHMgb2YgYSByb3cgYXNrIGZvciwgb3IgbnVsbCB3aGVuIHRoZXkgYXNrIGZvciBub1xuLy8gZmlsdGVyIGF0IGFsbC4gQSBwYWdlIGZpbHRlciBzaG93cyBpbiBpdHMgcGFnZSdzIGJhciBvbmx5LCBzbyBUaGlzIHBhZ2Vcbi8vIG9ubHkgaWdub3JlcyB0aGUgVGhpcyBjb21wb25lbnQgdG9nZ2xlLlxuZXhwb3J0IGZ1bmN0aW9uIGZpbHRlckxldmVsKHBsYWNlbWVudDogRmlsdGVyQmFyUGxhY2VtZW50LCBjb21wb25lbnQ6IGJvb2xlYW4pOiBSZXBvcnRGaWx0ZXJMZXZlbCB8IG51bGwge1xuICBzd2l0Y2ggKHBsYWNlbWVudCkge1xuICAgIGNhc2UgJ3BhZ2UnOlxuICAgICAgcmV0dXJuICdwYWdlJztcbiAgICBjYXNlICdldmVyeSc6XG4gICAgICByZXR1cm4gY29tcG9uZW50ID8gJ2JvdGgnIDogJ3JlcG9ydCc7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiBjb21wb25lbnQgPyAnY29tcG9uZW50JyA6IG51bGw7XG4gIH1cbn1cblxuLy8gVGhlIFRoaXMgY29tcG9uZW50IHRvZ2dsZSBvZiBhIHJvdzogbG9ja2VkIHdoaWxlIFRoaXMgcGFnZSBvbmx5IGlzIHBpY2tlZC5cbmV4cG9ydCBmdW5jdGlvbiBjb21wb25lbnRUb2dnbGVTdGF0ZShwbGFjZW1lbnQ6IEZpbHRlckJhclBsYWNlbWVudCk6IEZpbHRlckNvbXBvbmVudFRvZ2dsZVN0YXRlIHtcbiAgcmV0dXJuIHBsYWNlbWVudCA9PT0gJ3BhZ2UnXG4gICAgPyB7IGRpc2FibGVkOiB0cnVlLCB0b29sdGlwOiBQQUdFX0ZJTFRFUl9UT09MVElQIH1cbiAgICA6IHsgZGlzYWJsZWQ6IGZhbHNlLCB0b29sdGlwOiBDT01QT05FTlRfVE9HR0xFX1RPT0xUSVAgfTtcbn1cblxuLy8gVGhlIGdyb3VwcyB0aGUgcmVwb3J0IHNldHRpbmdzJyBGaWx0ZXJzIHRhYiBsaXN0cyBkZWZhdWx0cyBmb3I6IHRob3NlIG9mXG4vLyB0aGUgcmVwb3J0IGJhciwgZXZlcnkgcGFnZSBvciBvbmUsIGluIGJhciBvcmRlci5cbmV4cG9ydCBmdW5jdGlvbiBkZWZhdWx0Um93R3JvdXBzKGdyb3VwczogUmVwb3J0RmlsdGVyR3JvdXBbXSB8IG51bGwgfCB1bmRlZmluZWQpOiBSZXBvcnRGaWx0ZXJHcm91cFtdIHtcbiAgcmV0dXJuIChncm91cHMgPz8gW10pXG4gICAgLmZpbHRlcigoZ3JvdXApID0+IGdyb3VwLmxldmVsID09PSAncmVwb3J0JyB8fCBncm91cC5sZXZlbCA9PT0gJ2JvdGgnIHx8IGdyb3VwLmxldmVsID09PSAncGFnZScpXG4gICAgLnNvcnQoKGEsIGIpID0+IGEub3JkZXIgLSBiLm9yZGVyKTtcbn1cblxuLy8gQSBkZWZhdWx0IHJvdydzIGxhYmVsOiBhIHBhZ2UgZ3JvdXAgbmFtZXMgaXRzIHBhZ2UsICdSZWdpb24gKHBhZ2Vcbi8vIFwiT3ZlcnZpZXdcIiknLiBBIHBhZ2Ugd2l0aCBubyBuYW1lIHJlYWRzIGFzIHRoZSBjYW52YXMgbmFtZXMgaXQgKCdQYWdlIDInKS5cbi8vIEEgcGFnZSB0aGlzIHJlcG9ydCBubyBsb25nZXIgaG9sZHMgYWRkcyBub3RoaW5nLlxuZXhwb3J0IGZ1bmN0aW9uIGRlZmF1bHRSb3dMYWJlbChncm91cDogUmVwb3J0RmlsdGVyR3JvdXAsIHBhZ2VzOiBSZXBvcnRQYWdlW10gfCBudWxsIHwgdW5kZWZpbmVkKTogc3RyaW5nIHtcbiAgY29uc3QgbGFiZWwgPSBncm91cC5sYWJlbCB8fCBncm91cC5maWx0ZXJzPy5bMF0/LmZpbHRlckNvbHVtbiB8fCAnRmlsdGVyJztcblxuICBpZiAoZ3JvdXAubGV2ZWwgIT09ICdwYWdlJykge1xuICAgIHJldHVybiBsYWJlbDtcbiAgfVxuXG4gIGNvbnN0IGluZGV4ID0gKHBhZ2VzID8/IFtdKS5maW5kSW5kZXgoKHBhZ2UpID0+IHBhZ2UuaWQgPT09IGdyb3VwLnBhZ2VJZCk7XG4gIGlmIChpbmRleCA8IDApIHtcbiAgICByZXR1cm4gbGFiZWw7XG4gIH1cblxuICByZXR1cm4gYCR7bGFiZWx9IChwYWdlIFwiJHtwYWdlc1tpbmRleF0ubmFtZSB8fCBgUGFnZSAke2luZGV4ICsgMX1gfVwiKWA7XG59XG5cbi8vIFRoZSBEZWZhdWx0IHBlcmlvZCBzZWxlY3QncyBjaG9pY2VzOiBGaXhlZCBkYXRlcywgdGhlbiBldmVyeSByZWxhdGl2ZVxuLy8gcmFuZ2UgaW4gdGhlIHNlcnZlciBlbnVtJ3Mgb3JkZXIsIG5hbWVkIGJ5IGBsYWJlbHNgLiBBIHN0b3JlZCByYW5nZSB0aGlzXG4vLyB2aWV3ZXIgZG9lcyBub3Qga25vdyBpcyBsaXN0ZWQgbGFzdCwgc28gdGhlIHNlbGVjdCBzdGlsbCBzaG93cyBpdC5cbmV4cG9ydCBmdW5jdGlvbiBkZWZhdWx0UGVyaW9kT3B0aW9ucyhcbiAgbGFiZWxzOiAocmVsYXRpdmU6IFJlcG9ydFJlbGF0aXZlUmFuZ2UpID0+IHN0cmluZyxcbiAgc3RvcmVkOiBzdHJpbmcgfCBudWxsID0gbnVsbCxcbik6IEZpbHRlclNldHRpbmdzT3B0aW9uW10ge1xuICBjb25zdCBvcHRpb25zOiBGaWx0ZXJTZXR0aW5nc09wdGlvbltdID0gW1xuICAgIHsgdmFsdWU6IEZJWEVEX0RBVEVTX1BFUklPRCwgbmFtZTogJ0ZpeGVkIGRhdGVzJyB9LFxuICAgIC4uLlJFTEFUSVZFX1JBTkdFX05BTUVTLm1hcCgocmVsYXRpdmUpID0+ICh7IHZhbHVlOiByZWxhdGl2ZSwgbmFtZTogbGFiZWxzKHJlbGF0aXZlKSB9KSksXG4gIF07XG5cbiAgcmV0dXJuIHN0b3JlZCAmJiBzdG9yZWQgIT09IEZJWEVEX0RBVEVTX1BFUklPRCAmJiAhaXNSZWxhdGl2ZVJhbmdlKHN0b3JlZClcbiAgICA/IFsuLi5vcHRpb25zLCB7IHZhbHVlOiBzdG9yZWQsIG5hbWU6IGxhYmVscyhzdG9yZWQgYXMgUmVwb3J0UmVsYXRpdmVSYW5nZSkgfV1cbiAgICA6IG9wdGlvbnM7XG59XG5cbi8vIFRoZSBEZWZhdWx0IHBlcmlvZCBhIHN0b3JlZCBkYXRlIHJhbmdlIGRlZmF1bHQgb3BlbnMgb246IGl0cyByZWxhdGl2ZVxuLy8gcmFuZ2UsIGVsc2UgRml4ZWQgZGF0ZXMgKHRoZSBkYXlzLCBvciBub25lKS5cbmV4cG9ydCBmdW5jdGlvbiBkZWZhdWx0UGVyaW9kKHN0b3JlZDogRmlsdGVyR3JvdXBEZWZhdWx0IHwgbnVsbCB8IHVuZGVmaW5lZCk6IHN0cmluZyB7XG4gIHJldHVybiBzdG9yZWQ/LnJlbGF0aXZlICYmICFzdG9yZWQuc3RhcnQgJiYgIXN0b3JlZC5lbmRcbiAgICA/IHN0b3JlZC5yZWxhdGl2ZVxuICAgIDogRklYRURfREFURVNfUEVSSU9EO1xufVxuXG4vLyBBIGRhdGUgcmFuZ2UgZGVmYXVsdCBpbiBpdHMgc3RvcmVkIHNoYXBlOiB0aGUgcmVsYXRpdmUgcmFuZ2UgcGlja2VkLCBlbHNlXG4vLyB0aGUgZml4ZWQgZGF5cywgb3IgbnVsbCB3aGVuIHRoZXJlIGFyZSBub25lLiBOZXZlciBib3RoOiB0aGUgc2VydmVyXG4vLyByZWZ1c2VzIGEgcmVsYXRpdmUgcmFuZ2Ugd2l0aCBkYXlzLlxuZXhwb3J0IGZ1bmN0aW9uIGRhdGVSYW5nZURlZmF1bHQoXG4gIHBlcmlvZDogc3RyaW5nLFxuICBzdGFydDogc3RyaW5nIHwgbnVsbCxcbiAgZW5kOiBzdHJpbmcgfCBudWxsLFxuKTogRmlsdGVyR3JvdXBEZWZhdWx0IHwgbnVsbCB7XG4gIGlmIChwZXJpb2QgIT09IEZJWEVEX0RBVEVTX1BFUklPRCkge1xuICAgIHJldHVybiB7IHJlbGF0aXZlOiBwZXJpb2QgfTtcbiAgfVxuXG4gIGlmICghc3RhcnQgJiYgIWVuZCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIHsgLi4uKHN0YXJ0ID8geyBzdGFydCB9IDoge30pLCAuLi4oZW5kID8geyBlbmQgfSA6IHt9KSB9O1xufVxuXG4vLyBBIHNlbGVjdCBkZWZhdWx0IGluIGl0cyBzdG9yZWQgc2hhcGU6IHRoZSBwaWNrcyBrZXB0LCBvciBsZWZ0IG91dCB3aGlsZVxuLy8gRXhjbHVkZSB0aGVzZSB2YWx1ZXMgaXMgb24sIG9yIG51bGwgd2hlbiBub3RoaW5nIGlzIHBpY2tlZC5cbmV4cG9ydCBmdW5jdGlvbiBzZWxlY3REZWZhdWx0KHZhbHVlczogdW5rbm93bltdLCBleGNsdWRlOiBib29sZWFuKTogRmlsdGVyR3JvdXBEZWZhdWx0IHwgbnVsbCB7XG4gIGlmICghdmFsdWVzLmxlbmd0aCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIGV4Y2x1ZGUgPyB7IGV4Y2x1ZGVWYWx1ZXM6IHZhbHVlcyB9IDogeyB2YWx1ZXMgfTtcbn1cblxuLy8gQSBudW1iZXIgcmFuZ2UgZGVmYXVsdCBpbiBpdHMgc3RvcmVkIHNoYXBlIGZyb20gdGhlIGVuZHMgYXMgdHlwZWQ6IGFuXG4vLyBvcGVuIGVuZCBpcyBsZWZ0IG91dCwgMCBpcyBrZXB0LCBhbmQgdHdvIG9wZW4gZW5kcyBhcmUgbm8gZGVmYXVsdC5cbmV4cG9ydCBmdW5jdGlvbiBudW1iZXJSYW5nZURlZmF1bHQocmF3TWluOiB1bmtub3duLCByYXdNYXg6IHVua25vd24pOiBGaWx0ZXJHcm91cERlZmF1bHQgfCBudWxsIHtcbiAgY29uc3QgbWluID0gcGFyc2VEZWZhdWx0Qm91bmQocmF3TWluKTtcbiAgY29uc3QgbWF4ID0gcGFyc2VEZWZhdWx0Qm91bmQocmF3TWF4KTtcblxuICBpZiAobWluID09PSBudWxsICYmIG1heCA9PT0gbnVsbCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIHsgLi4uKG1pbiAhPT0gbnVsbCA/IHsgbWluIH0gOiB7fSksIC4uLihtYXggIT09IG51bGwgPyB7IG1heCB9IDoge30pIH07XG59XG5cbi8vIFdoZXRoZXIgYSBzZWxlY3QgZ3JvdXAncyBkZWZhdWx0IHJvdyBvZmZlcnMgRXhjbHVkZSB0aGVzZSB2YWx1ZXM6IHRoZVxuLy8gcmVwb3J0IGJhcidzIHJ1bGUgKG9mZmVyc0V4Y2x1ZGUpLCBzbyBub3Qgb24gYSBzZXJ2ZXIgdGhhdCBkb2VzIG5vdCBzZXJ2ZVxuLy8gZXhjbHVkZSAoYW4gb2xkZXIgc2VydmVyIGxpc3RzIG5vIGZlYXR1cmVzKSBub3Igb24gYSBncm91cCB3aXRoIGEgbWVtYmVyXG4vLyB0aGF0IGJpbmRzIHNldmVyYWwgY29sdW1ucyAobXVsdGlDb2x1bW4pLiBBIGRlZmF1bHQgdGhhdCBhbHJlYWR5IGxlYXZlc1xuLy8gdmFsdWVzIG91dCBrZWVwcyB0aGUgdG9nZ2xlLCBzbyBpdCBjYW4gYmUgdHVybmVkIG9mZi5cbmV4cG9ydCBmdW5jdGlvbiBzaG93RXhjbHVkZVRvZ2dsZShcbiAgZ3JvdXA6IFJlcG9ydEZpbHRlckdyb3VwLFxuICBmZWF0dXJlczogUmVwb3J0Vmlld2VyRmVhdHVyZVtdIHwgbnVsbCB8IHVuZGVmaW5lZCxcbik6IGJvb2xlYW4ge1xuICBpZiAoZ3JvdXAudHlwZSA9PT0gJ3NlbGVjdCcgJiYgZ3JvdXAuY29uZmlnPy5kZWZhdWx0Py5leGNsdWRlVmFsdWVzPy5sZW5ndGgpIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiBvZmZlcnNFeGNsdWRlKGdyb3VwLCBmZWF0dXJlcyk7XG59XG5cbi8vIEEgc3RvcmVkIG9yIGRyYWZ0IGRlZmF1bHQgaW4gYSBzdGFibGUgZm9ybSBmb3IgY29tcGFyaW5nOiBlbXB0eSBhbmRcbi8vIGFic2VudCBrZXlzIGFyZSBkcm9wcGVkLCBzbyBhIG5vLW9wIGVkaXQgZG9lcyBub3QgcmVhZCBhcyBhIGNoYW5nZS4gMCBpcyBhblxuLy8gZW5kIGxpa2UgYW55IG90aGVyLiBOb3RoaW5nIGxlZnQgaXMgbnVsbC5cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVEZWZhdWx0KHZhbHVlOiBGaWx0ZXJHcm91cERlZmF1bHQgfCBudWxsIHwgdW5kZWZpbmVkKTogRmlsdGVyR3JvdXBEZWZhdWx0IHwgbnVsbCB7XG4gIGlmICghdmFsdWUpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIGNvbnN0IG5vcm1hbGl6ZWQ6IEZpbHRlckdyb3VwRGVmYXVsdCA9IHt9O1xuICBpZiAodmFsdWUuc3RhcnQpIHtcbiAgICBub3JtYWxpemVkLnN0YXJ0ID0gdmFsdWUuc3RhcnQ7XG4gIH1cbiAgaWYgKHZhbHVlLmVuZCkge1xuICAgIG5vcm1hbGl6ZWQuZW5kID0gdmFsdWUuZW5kO1xuICB9XG4gIGlmICh2YWx1ZS52YWx1ZXM/Lmxlbmd0aCkge1xuICAgIG5vcm1hbGl6ZWQudmFsdWVzID0gdmFsdWUudmFsdWVzO1xuICB9XG4gIGlmICh2YWx1ZS5leGNsdWRlVmFsdWVzPy5sZW5ndGgpIHtcbiAgICBub3JtYWxpemVkLmV4Y2x1ZGVWYWx1ZXMgPSB2YWx1ZS5leGNsdWRlVmFsdWVzO1xuICB9XG4gIGlmICh0eXBlb2YgdmFsdWUubWluID09PSAnbnVtYmVyJykge1xuICAgIG5vcm1hbGl6ZWQubWluID0gdmFsdWUubWluO1xuICB9XG4gIGlmICh0eXBlb2YgdmFsdWUubWF4ID09PSAnbnVtYmVyJykge1xuICAgIG5vcm1hbGl6ZWQubWF4ID0gdmFsdWUubWF4O1xuICB9XG4gIGlmICh2YWx1ZS52YWx1ZSkge1xuICAgIG5vcm1hbGl6ZWQudmFsdWUgPSB2YWx1ZS52YWx1ZTtcbiAgfVxuICBpZiAodmFsdWUucmVsYXRpdmUpIHtcbiAgICBub3JtYWxpemVkLnJlbGF0aXZlID0gdmFsdWUucmVsYXRpdmU7XG4gIH1cblxuICByZXR1cm4gT2JqZWN0LmtleXMobm9ybWFsaXplZCkubGVuZ3RoID8gbm9ybWFsaXplZCA6IG51bGw7XG59XG5cbi8vIFdoZXRoZXIgYSByb3cncyBkcmFmdCBkZWZhdWx0IGRpZmZlcnMgZnJvbSB0aGUgZ3JvdXAncyBzdG9yZWQgb25lLiBPbmx5IGFcbi8vIGNoYW5nZWQgcm93IGlzIHNhdmVkLlxuZXhwb3J0IGZ1bmN0aW9uIGRlZmF1bHRDaGFuZ2VkKFxuICBzdG9yZWQ6IEZpbHRlckdyb3VwRGVmYXVsdCB8IG51bGwgfCB1bmRlZmluZWQsXG4gIGRyYWZ0OiBGaWx0ZXJHcm91cERlZmF1bHQgfCBudWxsIHwgdW5kZWZpbmVkLFxuKTogYm9vbGVhbiB7XG4gIHJldHVybiBKU09OLnN0cmluZ2lmeShub3JtYWxpemVEZWZhdWx0KHN0b3JlZCkpICE9PSBKU09OLnN0cmluZ2lmeShub3JtYWxpemVEZWZhdWx0KGRyYWZ0KSk7XG59XG4iXX0=
|