@firestitch/report 18.9.0 → 18.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/app/reports/anchor-at-point.d.ts +14 -0
  2. package/app/reports/canvas-landing-page.d.ts +2 -0
  3. package/app/reports/components/component-chart/component-chart.component.d.ts +18 -2
  4. package/app/reports/components/component-kpi/component-kpi.component.d.ts +4 -1
  5. package/app/reports/components/report-canvas/report-canvas.component.d.ts +3 -0
  6. package/app/reports/components/report-component/report-component.component.d.ts +35 -1
  7. package/app/reports/components/report-view-picker/report-view-picker.component.d.ts +21 -0
  8. package/app/reports/data/report.data.d.ts +17 -2
  9. package/app/reports/dialogs/component-settings/component-settings.component.d.ts +18 -3
  10. package/app/reports/dialogs/report-settings/report-settings.component.d.ts +15 -6
  11. package/app/reports/dialogs/report-view/report-view-dialog.component.d.ts +13 -0
  12. package/app/reports/drill-crumbs.d.ts +12 -0
  13. package/app/reports/export/report-export-collector.service.d.ts +13 -4
  14. package/app/reports/export/report-filter-lines.d.ts +18 -0
  15. package/app/reports/filter-settings-rules.d.ts +33 -0
  16. package/app/reports/format.d.ts +0 -1
  17. package/app/reports/interfaces/canvas-landing-input.interface.d.ts +8 -0
  18. package/app/reports/interfaces/component-data-applied.interface.d.ts +13 -0
  19. package/app/reports/interfaces/component-data-drill.interface.d.ts +22 -0
  20. package/app/reports/interfaces/filter-bar-placement.type.d.ts +1 -0
  21. package/app/reports/interfaces/filter-component-toggle-state.interface.d.ts +4 -0
  22. package/app/reports/interfaces/filter-settings-option.interface.d.ts +4 -0
  23. package/app/reports/interfaces/filter-type-select-state.interface.d.ts +5 -0
  24. package/app/reports/interfaces/report-chart-hit.interface.d.ts +5 -0
  25. package/app/reports/interfaces/report-chat-viewer-cross-filter-field.interface.d.ts +4 -0
  26. package/app/reports/interfaces/report-chat-viewer-cross-filter.interface.d.ts +7 -0
  27. package/app/reports/interfaces/report-chat-viewer-detail.interface.d.ts +4 -0
  28. package/app/reports/interfaces/report-chat-viewer-drill-step.interface.d.ts +5 -0
  29. package/app/reports/interfaces/report-chat-viewer-drill.interface.d.ts +5 -0
  30. package/app/reports/interfaces/report-chat-viewer-filter.interface.d.ts +3 -0
  31. package/app/reports/interfaces/report-chat-viewer-selection.interface.d.ts +5 -0
  32. package/app/reports/interfaces/report-chat-viewer-state.interface.d.ts +12 -0
  33. package/app/reports/interfaces/report-drill-crumb.interface.d.ts +6 -0
  34. package/app/reports/interfaces/report-drill-refusal.type.d.ts +1 -0
  35. package/app/reports/interfaces/report-drill-step.interface.d.ts +5 -0
  36. package/app/reports/interfaces/report-export-line-kind.type.d.ts +1 -0
  37. package/app/reports/interfaces/report-export-line.interface.d.ts +8 -0
  38. package/app/reports/interfaces/report-export-lines-input.interface.d.ts +9 -0
  39. package/app/reports/interfaces/report-export-snapshot.interface.d.ts +15 -0
  40. package/app/reports/interfaces/report-filter-line-context.interface.d.ts +8 -0
  41. package/app/reports/interfaces/report-filter-line-form.type.d.ts +1 -0
  42. package/app/reports/interfaces/report-filter-match.type.d.ts +1 -0
  43. package/app/reports/interfaces/report-filter-option-pair.interface.d.ts +4 -0
  44. package/app/reports/interfaces/report-filter-options-ask.interface.d.ts +6 -0
  45. package/app/reports/interfaces/report-filter-options-list.interface.d.ts +7 -0
  46. package/app/reports/interfaces/report-filter-options-request.interface.d.ts +6 -0
  47. package/app/reports/interfaces/report-filter-options-stream.interface.d.ts +11 -0
  48. package/app/reports/interfaces/report-filter-options.interface.d.ts +7 -0
  49. package/app/reports/interfaces/report-filter-skip.type.d.ts +1 -0
  50. package/app/reports/interfaces/report-mark-action.type.d.ts +1 -0
  51. package/app/reports/interfaces/report-mark-click.interface.d.ts +13 -0
  52. package/app/reports/interfaces/report-mark-context.interface.d.ts +6 -0
  53. package/app/reports/interfaces/report-mark-decision.interface.d.ts +6 -0
  54. package/app/reports/interfaces/report-mark-event.interface.d.ts +11 -0
  55. package/app/reports/interfaces/report-mark-point.interface.d.ts +8 -0
  56. package/app/reports/interfaces/report-temporary-state.interface.d.ts +4 -0
  57. package/app/reports/interfaces/report-tile-state.interface.d.ts +8 -0
  58. package/app/reports/interfaces/report-url-link.interface.d.ts +4 -0
  59. package/app/reports/interfaces/report-url-value-name.type.d.ts +1 -0
  60. package/app/reports/interfaces/report-url-write.interface.d.ts +4 -0
  61. package/app/reports/interfaces/report-view-config.interface.d.ts +11 -0
  62. package/app/reports/interfaces/report-view-create.interface.d.ts +7 -0
  63. package/app/reports/interfaces/report-view-deleted.interface.d.ts +4 -0
  64. package/app/reports/interfaces/report-view-dialog-data.interface.d.ts +7 -0
  65. package/app/reports/interfaces/report-view-dropped.interface.d.ts +5 -0
  66. package/app/reports/interfaces/report-view-menu-item.interface.d.ts +10 -0
  67. package/app/reports/interfaces/report-view-summary.interface.d.ts +11 -0
  68. package/app/reports/interfaces/report-view.interface.d.ts +7 -0
  69. package/app/reports/interfaces/report-viewer-feature.type.d.ts +1 -0
  70. package/app/reports/interfaces/report-views.interface.d.ts +7 -0
  71. package/app/reports/interfaces/report.interface.d.ts +27 -3
  72. package/app/reports/interfaces/tile-load-result.interface.d.ts +4 -0
  73. package/app/reports/mark-click.d.ts +20 -0
  74. package/app/reports/option-builder.d.ts +12 -1
  75. package/app/reports/report-chat-viewer-state.d.ts +8 -0
  76. package/app/reports/report-date-presets.d.ts +2 -0
  77. package/app/reports/report-filter-items.d.ts +27 -22
  78. package/app/reports/report-tile.d.ts +2 -0
  79. package/app/reports/report-url-state.d.ts +27 -10
  80. package/app/reports/report-view-config.d.ts +36 -0
  81. package/app/reports/report-view-menu.d.ts +15 -0
  82. package/app/reports/report-viewer-features.d.ts +5 -0
  83. package/app/reports/services/report-filter-options.service.d.ts +26 -0
  84. package/app/reports/services/report-filter-state.service.d.ts +64 -1
  85. package/app/reports/services/report-view.service.d.ts +51 -0
  86. package/app/reports/tile-data-state.d.ts +7 -0
  87. package/app/reports/tile-loads.d.ts +4 -0
  88. package/app/reports/views/report/fs-ai-report.component.d.ts +9 -1
  89. package/app/reports/views/report/report.component.d.ts +6 -0
  90. package/esm2022/app/reports/anchor-at-point.mjs +49 -0
  91. package/esm2022/app/reports/canvas-landing-page.mjs +25 -0
  92. package/esm2022/app/reports/components/component-chart/component-chart.component.mjs +97 -5
  93. package/esm2022/app/reports/components/component-kpi/component-kpi.component.mjs +11 -4
  94. package/esm2022/app/reports/components/component-list/component-list.component.mjs +7 -1
  95. package/esm2022/app/reports/components/report-canvas/report-canvas.component.mjs +47 -32
  96. package/esm2022/app/reports/components/report-component/report-component.component.mjs +257 -61
  97. package/esm2022/app/reports/components/report-view-picker/report-view-picker.component.mjs +115 -0
  98. package/esm2022/app/reports/data/report.data.mjs +87 -10
  99. package/esm2022/app/reports/dialogs/component-settings/component-settings.component.mjs +106 -51
  100. package/esm2022/app/reports/dialogs/report-settings/report-settings.component.mjs +86 -90
  101. package/esm2022/app/reports/dialogs/report-view/report-view-dialog.component.mjs +52 -0
  102. package/esm2022/app/reports/drill-crumbs.mjs +73 -0
  103. package/esm2022/app/reports/export/report-export-collector.service.mjs +187 -117
  104. package/esm2022/app/reports/export/report-filter-lines.mjs +235 -0
  105. package/esm2022/app/reports/export/report-pdf.service.mjs +12 -7
  106. package/esm2022/app/reports/export/report-pptx.service.mjs +18 -14
  107. package/esm2022/app/reports/filter-settings-rules.mjs +283 -0
  108. package/esm2022/app/reports/format.mjs +2 -22
  109. package/esm2022/app/reports/interfaces/canvas-landing-input.interface.mjs +2 -0
  110. package/esm2022/app/reports/interfaces/component-data-applied.interface.mjs +2 -0
  111. package/esm2022/app/reports/interfaces/component-data-drill.interface.mjs +2 -0
  112. package/esm2022/app/reports/interfaces/filter-bar-placement.type.mjs +2 -0
  113. package/esm2022/app/reports/interfaces/filter-component-toggle-state.interface.mjs +2 -0
  114. package/esm2022/app/reports/interfaces/filter-settings-option.interface.mjs +2 -0
  115. package/esm2022/app/reports/interfaces/filter-type-select-state.interface.mjs +2 -0
  116. package/esm2022/app/reports/interfaces/report-chart-hit.interface.mjs +2 -0
  117. package/esm2022/app/reports/interfaces/report-chat-viewer-cross-filter-field.interface.mjs +2 -0
  118. package/esm2022/app/reports/interfaces/report-chat-viewer-cross-filter.interface.mjs +2 -0
  119. package/esm2022/app/reports/interfaces/report-chat-viewer-detail.interface.mjs +2 -0
  120. package/esm2022/app/reports/interfaces/report-chat-viewer-drill-step.interface.mjs +2 -0
  121. package/esm2022/app/reports/interfaces/report-chat-viewer-drill.interface.mjs +2 -0
  122. package/esm2022/app/reports/interfaces/report-chat-viewer-filter.interface.mjs +1 -1
  123. package/esm2022/app/reports/interfaces/report-chat-viewer-selection.interface.mjs +2 -0
  124. package/esm2022/app/reports/interfaces/report-chat-viewer-state.interface.mjs +1 -1
  125. package/esm2022/app/reports/interfaces/report-drill-crumb.interface.mjs +2 -0
  126. package/esm2022/app/reports/interfaces/report-drill-refusal.type.mjs +2 -0
  127. package/esm2022/app/reports/interfaces/report-drill-step.interface.mjs +2 -0
  128. package/esm2022/app/reports/interfaces/report-export-line-kind.type.mjs +2 -0
  129. package/esm2022/app/reports/interfaces/report-export-line.interface.mjs +2 -0
  130. package/esm2022/app/reports/interfaces/report-export-lines-input.interface.mjs +2 -0
  131. package/esm2022/app/reports/interfaces/report-export-snapshot.interface.mjs +2 -0
  132. package/esm2022/app/reports/interfaces/report-filter-line-context.interface.mjs +2 -0
  133. package/esm2022/app/reports/interfaces/report-filter-line-form.type.mjs +2 -0
  134. package/esm2022/app/reports/interfaces/report-filter-match.type.mjs +2 -0
  135. package/esm2022/app/reports/interfaces/report-filter-option-pair.interface.mjs +2 -0
  136. package/esm2022/app/reports/interfaces/report-filter-options-ask.interface.mjs +2 -0
  137. package/esm2022/app/reports/interfaces/report-filter-options-list.interface.mjs +2 -0
  138. package/esm2022/app/reports/interfaces/report-filter-options-request.interface.mjs +2 -0
  139. package/esm2022/app/reports/interfaces/report-filter-options-stream.interface.mjs +2 -0
  140. package/esm2022/app/reports/interfaces/report-filter-options.interface.mjs +2 -0
  141. package/esm2022/app/reports/interfaces/report-filter-skip.type.mjs +2 -0
  142. package/esm2022/app/reports/interfaces/report-mark-action.type.mjs +2 -0
  143. package/esm2022/app/reports/interfaces/report-mark-click.interface.mjs +2 -0
  144. package/esm2022/app/reports/interfaces/report-mark-context.interface.mjs +2 -0
  145. package/esm2022/app/reports/interfaces/report-mark-decision.interface.mjs +2 -0
  146. package/esm2022/app/reports/interfaces/report-mark-event.interface.mjs +2 -0
  147. package/esm2022/app/reports/interfaces/report-mark-point.interface.mjs +2 -0
  148. package/esm2022/app/reports/interfaces/report-temporary-state.interface.mjs +2 -0
  149. package/esm2022/app/reports/interfaces/report-tile-state.interface.mjs +2 -0
  150. package/esm2022/app/reports/interfaces/report-url-link.interface.mjs +2 -0
  151. package/esm2022/app/reports/interfaces/report-url-value-name.type.mjs +2 -0
  152. package/esm2022/app/reports/interfaces/report-url-write.interface.mjs +2 -0
  153. package/esm2022/app/reports/interfaces/report-view-config.interface.mjs +2 -0
  154. package/esm2022/app/reports/interfaces/report-view-create.interface.mjs +2 -0
  155. package/esm2022/app/reports/interfaces/report-view-deleted.interface.mjs +2 -0
  156. package/esm2022/app/reports/interfaces/report-view-dialog-data.interface.mjs +2 -0
  157. package/esm2022/app/reports/interfaces/report-view-dropped.interface.mjs +2 -0
  158. package/esm2022/app/reports/interfaces/report-view-menu-item.interface.mjs +2 -0
  159. package/esm2022/app/reports/interfaces/report-view-summary.interface.mjs +2 -0
  160. package/esm2022/app/reports/interfaces/report-view.interface.mjs +2 -0
  161. package/esm2022/app/reports/interfaces/report-viewer-feature.type.mjs +2 -0
  162. package/esm2022/app/reports/interfaces/report-views.interface.mjs +2 -0
  163. package/esm2022/app/reports/interfaces/report.interface.mjs +1 -1
  164. package/esm2022/app/reports/interfaces/tile-load-result.interface.mjs +2 -0
  165. package/esm2022/app/reports/mark-click.mjs +193 -0
  166. package/esm2022/app/reports/option-builder.mjs +159 -15
  167. package/esm2022/app/reports/report-chat-viewer-state.mjs +34 -0
  168. package/esm2022/app/reports/report-date-presets.mjs +18 -0
  169. package/esm2022/app/reports/report-filter-items.mjs +343 -72
  170. package/esm2022/app/reports/report-tile.mjs +12 -0
  171. package/esm2022/app/reports/report-url-state.mjs +596 -108
  172. package/esm2022/app/reports/report-view-config.mjs +697 -0
  173. package/esm2022/app/reports/report-view-menu.mjs +119 -0
  174. package/esm2022/app/reports/report-viewer-features.mjs +42 -0
  175. package/esm2022/app/reports/services/report-filter-options.service.mjs +238 -0
  176. package/esm2022/app/reports/services/report-filter-state.service.mjs +697 -62
  177. package/esm2022/app/reports/services/report-view.service.mjs +358 -0
  178. package/esm2022/app/reports/tile-data-state.mjs +127 -0
  179. package/esm2022/app/reports/tile-loads.mjs +38 -0
  180. package/esm2022/app/reports/views/report/fs-ai-report.component.mjs +177 -46
  181. package/esm2022/app/reports/views/report/report.component.mjs +103 -23
  182. package/esm2022/public_api.mjs +23 -1
  183. package/fesm2022/{firestitch-report-echarts-DBMOHmBF.mjs → firestitch-report-echarts-UBg8Wlhd.mjs} +2 -2
  184. package/fesm2022/{firestitch-report-echarts-DBMOHmBF.mjs.map → firestitch-report-echarts-UBg8Wlhd.mjs.map} +1 -1
  185. package/fesm2022/{firestitch-report-firestitch-report-CqbXT1gh.mjs → firestitch-report-firestitch-report-B1keNrcK.mjs} +9063 -4272
  186. package/fesm2022/firestitch-report-firestitch-report-B1keNrcK.mjs.map +1 -0
  187. package/fesm2022/firestitch-report.mjs +1 -1
  188. package/package.json +1 -1
  189. package/public_api.d.ts +22 -0
  190. package/fesm2022/firestitch-report-firestitch-report-CqbXT1gh.mjs.map +0 -1
@@ -0,0 +1,283 @@
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
+ // Every Report bar choice, in the order the select lists them.
17
+ const BAR_PLACEMENT_OPTIONS = [
18
+ { value: 'off', name: 'Off' },
19
+ { value: 'every', name: 'Every page' },
20
+ { value: 'page', name: 'This page only' },
21
+ ];
22
+ // A number with its group commas in place ('1,250.5', '-12,000').
23
+ const GROUPED_DECIMAL = /^-?\d{1,3}(,\d{3})+(\.\d*)?$/;
24
+ // A plain decimal number ('1250.5', '-3', '0', '.5'). Hex, binary, octal,
25
+ // exponents and inner spaces do not match, though Number() reads some.
26
+ const PLAIN_DECIMAL = /^-?(\d+(\.\d*)?|\.\d+)$/;
27
+ // A default range end as typed. An empty field is no end. A number input
28
+ // with a mask hands back text with its group commas ('1,250.5'), so those go
29
+ // before Number() reads it; 0 is an end like any other. Anything that is not
30
+ // a decimal number is no end.
31
+ export function parseDefaultBound(raw) {
32
+ if (typeof raw === 'number') {
33
+ return Number.isFinite(raw) ? raw : null;
34
+ }
35
+ if (typeof raw !== 'string') {
36
+ return null;
37
+ }
38
+ const trimmed = raw.trim();
39
+ const text = GROUPED_DECIMAL.test(trimmed) ? trimmed.replace(/,/g, '') : trimmed;
40
+ if (!PLAIN_DECIMAL.test(text)) {
41
+ return null;
42
+ }
43
+ const value = Number(text);
44
+ return Number.isFinite(value) ? value : null;
45
+ }
46
+ // Why two range ends cannot be saved, in the server's words, or null. An open
47
+ // end is always fine.
48
+ export function boundsError(min, max) {
49
+ if (min === null || max === null || min <= max) {
50
+ return null;
51
+ }
52
+ return `min (${min}) is above max (${max}).`;
53
+ }
54
+ // The Type select of a column on the component settings' Filters tab. It
55
+ // shows when the column can take either type and the server serves number
56
+ // ranges (an older server lists no features). A filter's type cannot change,
57
+ // so it is locked while the column has a filter on this component.
58
+ export function typeSelectState(types, hasFilterOnThisComponent, features) {
59
+ const show = (features ?? []).includes('numberRange')
60
+ && FILTER_TYPE_OPTIONS.every((option) => (types ?? []).includes(option.value));
61
+ if (!show) {
62
+ return { show: false, disabled: false, tooltip: null };
63
+ }
64
+ return {
65
+ show: true,
66
+ disabled: hasFilterOnThisComponent,
67
+ tooltip: hasFilterOnThisComponent ? TYPE_LOCKED_TOOLTIP : null,
68
+ };
69
+ }
70
+ // The levels a new or moved filter can take on a component. This page only
71
+ // needs a server that serves page filters and a component on a page (a
72
+ // header or footer component is on no page).
73
+ export function filterLevelChoices(features, onPage) {
74
+ const levels = ['component', 'report', 'both'];
75
+ return onPage && (features ?? []).includes('pageScope')
76
+ ? [...levels, 'page']
77
+ : levels;
78
+ }
79
+ // The Report bar select's choices for the levels on offer. The choice a row
80
+ // already holds is always listed, so the select never shows blank.
81
+ export function barPlacementOptions(levelChoices, current = 'off') {
82
+ return BAR_PLACEMENT_OPTIONS.filter((option) => {
83
+ switch (option.value) {
84
+ case 'every':
85
+ return levelChoices.includes('report') || levelChoices.includes('both') || current === 'every';
86
+ case 'page':
87
+ return levelChoices.includes('page') || current === 'page';
88
+ default:
89
+ return true;
90
+ }
91
+ });
92
+ }
93
+ // A value's Report bar choices. A value has no strip of its own and its
94
+ // group may be shared, so a pick never lowers the group (the inline values
95
+ // rule): This page only is offered for a new filter, or for a group that is
96
+ // already a page group, never to move a shared group to one page.
97
+ export function valuePlacementOptions(levelChoices, current) {
98
+ const choices = !current || current === 'page'
99
+ ? levelChoices
100
+ : levelChoices.filter((level) => level !== 'page');
101
+ return barPlacementOptions(choices, barPlacement(current));
102
+ }
103
+ // The level a value's filter group ends at after a Report bar pick, or null
104
+ // when the value leaves it. Off unlinks this value alone and the group keeps
105
+ // its other members. A new filter takes the pick's level. Every page raises a
106
+ // strip-only group to both, keeping its strips, and a page group to the
107
+ // report bar. Nothing else moves the group, so a value never lowers it.
108
+ export function valueFilterLevel(placement, current) {
109
+ if (placement === 'off') {
110
+ return null;
111
+ }
112
+ if (!current) {
113
+ return placement === 'page' ? 'page' : 'report';
114
+ }
115
+ if (placement !== 'every') {
116
+ return current;
117
+ }
118
+ switch (current) {
119
+ case 'component':
120
+ return 'both';
121
+ case 'page':
122
+ return 'report';
123
+ default:
124
+ return current;
125
+ }
126
+ }
127
+ // Where a group of a level shows in the report bar. No group (no filter) is
128
+ // off.
129
+ export function barPlacement(level) {
130
+ switch (level) {
131
+ case 'report':
132
+ case 'both':
133
+ return 'every';
134
+ case 'page':
135
+ return 'page';
136
+ default:
137
+ return 'off';
138
+ }
139
+ }
140
+ // Whether a group of a level shows on its components.
141
+ export function shownOnComponent(level) {
142
+ return level === 'component' || level === 'both';
143
+ }
144
+ // The level the two controls of a row ask for, or null when they ask for no
145
+ // filter at all. A page filter shows in its page's bar only, so This page
146
+ // only ignores the This component toggle.
147
+ export function filterLevel(placement, component) {
148
+ switch (placement) {
149
+ case 'page':
150
+ return 'page';
151
+ case 'every':
152
+ return component ? 'both' : 'report';
153
+ default:
154
+ return component ? 'component' : null;
155
+ }
156
+ }
157
+ // The This component toggle of a row: locked while This page only is picked.
158
+ export function componentToggleState(placement) {
159
+ return placement === 'page'
160
+ ? { disabled: true, tooltip: PAGE_FILTER_TOOLTIP }
161
+ : { disabled: false, tooltip: COMPONENT_TOGGLE_TOOLTIP };
162
+ }
163
+ // The groups the report settings' Filters tab lists defaults for: those of
164
+ // the report bar, every page or one, in bar order.
165
+ export function defaultRowGroups(groups) {
166
+ return (groups ?? [])
167
+ .filter((group) => group.level === 'report' || group.level === 'both' || group.level === 'page')
168
+ .sort((a, b) => a.order - b.order);
169
+ }
170
+ // A default row's label: a page group names its page, 'Region (page
171
+ // "Overview")'. A page with no name reads as the canvas names it ('Page 2').
172
+ // A page this report no longer holds adds nothing.
173
+ export function defaultRowLabel(group, pages) {
174
+ const label = group.label || group.filters?.[0]?.filterColumn || 'Filter';
175
+ if (group.level !== 'page') {
176
+ return label;
177
+ }
178
+ const index = (pages ?? []).findIndex((page) => page.id === group.pageId);
179
+ if (index < 0) {
180
+ return label;
181
+ }
182
+ return `${label} (page "${pages[index].name || `Page ${index + 1}`}")`;
183
+ }
184
+ // The Default period select's choices: Fixed dates, then every relative
185
+ // range in the server enum's order, named by `labels`. A stored range this
186
+ // viewer does not know is listed last, so the select still shows it.
187
+ export function defaultPeriodOptions(labels, stored = null) {
188
+ const options = [
189
+ { value: FIXED_DATES_PERIOD, name: 'Fixed dates' },
190
+ ...RELATIVE_RANGE_NAMES.map((relative) => ({ value: relative, name: labels(relative) })),
191
+ ];
192
+ return stored && stored !== FIXED_DATES_PERIOD && !isRelativeRange(stored)
193
+ ? [...options, { value: stored, name: labels(stored) }]
194
+ : options;
195
+ }
196
+ // The Default period a stored date range default opens on: its relative
197
+ // range, else Fixed dates (the days, or none).
198
+ export function defaultPeriod(stored) {
199
+ return stored?.relative && !stored.start && !stored.end
200
+ ? stored.relative
201
+ : FIXED_DATES_PERIOD;
202
+ }
203
+ // A date range default in its stored shape: the relative range picked, else
204
+ // the fixed days, or null when there are none. Never both: the server
205
+ // refuses a relative range with days.
206
+ export function dateRangeDefault(period, start, end) {
207
+ if (period !== FIXED_DATES_PERIOD) {
208
+ return { relative: period };
209
+ }
210
+ if (!start && !end) {
211
+ return null;
212
+ }
213
+ return { ...(start ? { start } : {}), ...(end ? { end } : {}) };
214
+ }
215
+ // A select default in its stored shape: the picks kept, or left out while
216
+ // Exclude these values is on, or null when nothing is picked.
217
+ export function selectDefault(values, exclude) {
218
+ if (!values.length) {
219
+ return null;
220
+ }
221
+ return exclude ? { excludeValues: values } : { values };
222
+ }
223
+ // A number range default in its stored shape from the ends as typed: an
224
+ // open end is left out, 0 is kept, and two open ends are no default.
225
+ export function numberRangeDefault(rawMin, rawMax) {
226
+ const min = parseDefaultBound(rawMin);
227
+ const max = parseDefaultBound(rawMax);
228
+ if (min === null && max === null) {
229
+ return null;
230
+ }
231
+ return { ...(min !== null ? { min } : {}), ...(max !== null ? { max } : {}) };
232
+ }
233
+ // Whether a select group's default row offers Exclude these values: the
234
+ // report bar's rule (offersExclude), so not on a server that does not serve
235
+ // exclude (an older server lists no features) nor on a group with a member
236
+ // that binds several columns (multiColumn). A default that already leaves
237
+ // values out keeps the toggle, so it can be turned off.
238
+ export function showExcludeToggle(group, features) {
239
+ if (group.type === 'select' && group.config?.default?.excludeValues?.length) {
240
+ return true;
241
+ }
242
+ return offersExclude(group, features);
243
+ }
244
+ // A stored or draft default in a stable form for comparing: empty and
245
+ // absent keys are dropped, so a no-op edit does not read as a change. 0 is an
246
+ // end like any other. Nothing left is null.
247
+ export function normalizeDefault(value) {
248
+ if (!value) {
249
+ return null;
250
+ }
251
+ const normalized = {};
252
+ if (value.start) {
253
+ normalized.start = value.start;
254
+ }
255
+ if (value.end) {
256
+ normalized.end = value.end;
257
+ }
258
+ if (value.values?.length) {
259
+ normalized.values = value.values;
260
+ }
261
+ if (value.excludeValues?.length) {
262
+ normalized.excludeValues = value.excludeValues;
263
+ }
264
+ if (typeof value.min === 'number') {
265
+ normalized.min = value.min;
266
+ }
267
+ if (typeof value.max === 'number') {
268
+ normalized.max = value.max;
269
+ }
270
+ if (value.value) {
271
+ normalized.value = value.value;
272
+ }
273
+ if (value.relative) {
274
+ normalized.relative = value.relative;
275
+ }
276
+ return Object.keys(normalized).length ? normalized : null;
277
+ }
278
+ // Whether a row's draft default differs from the group's stored one. Only a
279
+ // changed row is saved.
280
+ export function defaultChanged(stored, draft) {
281
+ return JSON.stringify(normalizeDefault(stored)) !== JSON.stringify(normalizeDefault(draft));
282
+ }
283
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmlsdGVyLXNldHRpbmdzLXJ1bGVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2ZpbHRlci1zZXR0aW5ncy1ydWxlcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFtQkEsT0FBTyxFQUFFLG9CQUFvQixFQUFFLGVBQWUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQzdFLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUd6RCxxRUFBcUU7QUFDckUsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQTZDO0lBQzNFLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFO0lBQ25DLEVBQUUsS0FBSyxFQUFFLGFBQWEsRUFBRSxJQUFJLEVBQUUsY0FBYyxFQUFFO0NBQy9DLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBRyx1Q0FBdUMsQ0FBQztBQUMzRSxNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBRywyQ0FBMkMsQ0FBQztBQUMvRSxNQUFNLENBQUMsTUFBTSx3QkFBd0IsR0FBRyx3QkFBd0IsQ0FBQztBQUVqRSwyRUFBMkU7QUFDM0UsdUJBQXVCO0FBQ3ZCLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLE9BQU8sQ0FBQztBQUUxQyxnRUFBZ0U7QUFDaEUsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUcsQ0FBQyxDQUFDO0FBRXJDLCtEQUErRDtBQUMvRCxNQUFNLHFCQUFxQixHQUErQztJQUN4RSxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRTtJQUM3QixFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLFlBQVksRUFBRTtJQUN0QyxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLGdCQUFnQixFQUFFO0NBQzFDLENBQUM7QUFHRixrRUFBa0U7QUFDbEUsTUFBTSxlQUFl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TUFBTSxVQUFVLGNBQWMsQ0FDNUIsTUFBNkMsRUFDN0MsS0FBNEM7SUFFNUMsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLGdCQUFnQixDQUFDLE1BQU0sQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO0FBQzlGLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBUaGUgcnVsZXMgYmVoaW5kIHRoZSB0d28gZmlsdGVyIHNldHRpbmdzIGRpYWxvZ3MsIGtlcHQgcHVyZSBzbyB0aGUgbm9kZVxuLy8gaGFybmVzcyBjaGVja3MgdGhlbSB3aXRob3V0IGEgZGlhbG9nLiBUaGUgY29tcG9uZW50IHNldHRpbmdzJyBGaWx0ZXJzIHRhYlxuLy8gcmVhZHMgdGhlIFR5cGUgc2VsZWN0LCB0aGUgUmVwb3J0IGJhciBzZWxlY3QgYW5kIHRoZSBUaGlzIGNvbXBvbmVudCB0b2dnbGVcbi8vIGZyb20gaGVyZTsgdGhlIHJlcG9ydCBzZXR0aW5ncycgRmlsdGVycyB0YWIgcmVhZHMgaXRzIGRlZmF1bHQgcm93cyAodGhlXG4vLyBwZXJpb2QsIHRoZSBleGNsdWRlIHRvZ2dsZSwgdGhlIG51bWJlciByYW5nZSBlbmRzIGFuZCB0aGVpciBjaGVjaykgZnJvbVxuLy8gaGVyZS4gVGhlIGRpYWxvZ3Mgb25seSBjYWxsIHRoZXNlLlxuaW1wb3J0IHsgRmlsdGVyQmFyUGxhY2VtZW50IH0gZnJvbSAnLi9pbnRlcmZhY2VzL2ZpbHRlci1iYXItcGxhY2VtZW50LnR5cGUnO1xuaW1wb3J0IHsgRmlsdGVyQ29tcG9uZW50VG9nZ2xlU3RhdGUgfSBmcm9tICcuL2ludGVyZmFjZXMvZmlsdGVyLWNvbXBvbmVudC10b2dnbGUtc3RhdGUuaW50ZXJmYWNlJztcbmltcG9ydCB7IEZpbHRlclNldHRpbmdzT3B0aW9uIH0gZnJvbSAnLi9pbnRlcmZhY2VzL2ZpbHRlci1zZXR0aW5ncy1vcHRpb24uaW50ZXJmYWNlJztcbmltcG9ydCB7IEZpbHRlclR5cGVTZWxlY3RTdGF0ZSB9IGZyb20gJy4vaW50ZXJmYWNlcy9maWx0ZXItdHlwZS1zZWxlY3Qtc3RhdGUuaW50ZXJmYWNlJztcbmltcG9ydCB7IFJlcG9ydFZpZXdlckZlYXR1cmUgfSBmcm9tICcuL2ludGVyZmFjZXMvcmVwb3J0LXZpZXdlci1mZWF0dXJlLnR5cGUnO1xuaW1wb3J0IHtcbiAgRmlsdGVyR3JvdXBEZWZhdWx0LFxuICBSZXBvcnRGaWx0ZXJHcm91cCxcbiAgUmVwb3J0RmlsdGVyTGV2ZWwsXG4gIFJlcG9ydEZpbHRlclR5cGUsXG4gIFJlcG9ydFBhZ2UsXG4gIFJlcG9ydFJlbGF0aXZlUmFuZ2UsXG59IGZyb20gJy4vaW50ZXJmYWNlcy9yZXBvcnQuaW50ZXJmYWNlJztcbmltcG9ydCB7IFJFTEFUSVZFX1JBTkdFX05BTUVTLCBpc1JlbGF0aXZlUmFuZ2UgfSBmcm9tICcuL3JlcG9ydC12aWV3LWNvbmZpZyc7XG5pbXBvcnQgeyBvZmZlcnNFeGNsdWRlIH0gZnJvbSAnLi9yZXBvcnQtdmlld2VyLWZlYXR1cmVzJztcblxuXG4vLyBUaGUgVHlwZSBzZWxlY3QncyBjaG9pY2VzLiBBIGNvbHVtbiB0aGF0IGNhbiBiZSBlaXRoZXIgaG9sZHMgYm90aC5cbmV4cG9ydCBjb25zdCBGSUxURVJfVFlQRV9PUFRJT05TOiBGaWx0ZXJTZXR0aW5nc09wdGlvbjxSZXBvcnRGaWx0ZXJUeXBlPltdID0gW1xuICB7IHZhbHVlOiAnc2VsZWN0JywgbmFtZTogJ1ZhbHVlcycgfSxcbiAgeyB2YWx1ZTogJ251bWJlclJhbmdlJywgbmFtZTogJ051bWJlciByYW5nZScgfSxcbl07XG5cbmV4cG9ydCBjb25zdCBUWVBFX0xPQ0tFRF9UT09MVElQID0gJ1JlbW92ZSB0aGUgZmlsdGVyIHRvIGNoYW5nZSBpdHMgdHlwZS4nO1xuZXhwb3J0IGNvbnN0IFBBR0VfRklMVEVSX1RPT0xUSVAgPSAnQSBwYWdlIGZpbHRlciBzaG93cyBpbiB0aGUgcGFnZSBiYXIgb25seS4nO1xuZXhwb3J0IGNvbnN0IENPTVBPTkVOVF9UT0dHTEVfVE9PTFRJUCA9ICdTaG93IG9uIHRoaXMgY29tcG9uZW50JztcblxuLy8gVGhlIERlZmF1bHQgcGVyaW9kIHNlbGVjdCdzIHZhbHVlIGZvciBhIHJhbmdlIG9mIGZpeGVkIGRheXMuIE5vIHJlbGF0aXZlXG4vLyByYW5nZSBpcyBuYW1lZCB0aGlzLlxuZXhwb3J0IGNvbnN0IEZJWEVEX0RBVEVTX1BFUklPRCA9ICdmaXhlZCc7XG5cbi8vIEhvdyBtYW55IGRlY2ltYWxzIGEgRGVmYXVsdCBtaW5pbXVtIG9yIERlZmF1bHQgbWF4aW11bSB0YWtlcy5cbmV4cG9ydCBjb25zdCBERUZBVUxUX0JPVU5EX1NDQUxFID0gNjtcblxuLy8gRXZlcnkgUmVwb3J0IGJhciBjaG9pY2UsIGluIHRoZSBvcmRlciB0aGUgc2VsZWN0IGxpc3RzIHRoZW0uXG5jb25zdCBCQVJfUExBQ0VNRU5UX09QVElPTlM6IEZpbHRlclNldHRpbmdzT3B0aW9uPEZpbHRlckJhclBsYWNlbWVudD5bXSA9IFtcbiAgeyB2YWx1ZTogJ29mZicsIG5hbWU6ICdPZmYnIH0sXG4gIHsgdmFsdWU6ICdldmVyeScsIG5hbWU6ICdFdmVyeSBwYWdlJyB9LFxuICB7IHZhbHVlOiAncGFnZScsIG5hbWU6ICdUaGlzIHBhZ2Ugb25seScgfSxcbl07XG5cblxuLy8gQSBudW1iZXIgd2l0aCBpdHMgZ3JvdXAgY29tbWFzIGluIHBsYWNlICgnMSwyNTAuNScsICctMTIsMDAwJykuXG5jb25zdCBHUk9VUEVEX0RFQ0lNQUwgPSAvXi0/XFxkezEsM30oLFxcZHszfSkrKFxcLlxcZCopPyQvO1xuLy8gQSBwbGFpbiBkZWNpbWFsIG51bWJlciAoJzEyNTAuNScsICctMycsICcwJywgJy41JykuIEhleCwgYmluYXJ5LCBvY3RhbCxcbi8vIGV4cG9uZW50cyBhbmQgaW5uZXIgc3BhY2VzIGRvIG5vdCBtYXRjaCwgdGhvdWdoIE51bWJlcigpIHJlYWRzIHNvbWUuXG5jb25zdCBQTEFJTl9ERUNJTUFMID0gL14tPyhcXGQrKFxcLlxcZCopP3xcXC5cXGQrKSQvO1xuXG4vLyBBIGRlZmF1bHQgcmFuZ2UgZW5kIGFzIHR5cGVkLiBBbiBlbXB0eSBmaWVsZCBpcyBubyBlbmQuIEEgbnVtYmVyIGlucHV0XG4vLyB3aXRoIGEgbWFzayBoYW5kcyBiYWNrIHRleHQgd2l0aCBpdHMgZ3JvdXAgY29tbWFzICgnMSwyNTAuNScpLCBzbyB0aG9zZSBnb1xuLy8gYmVmb3JlIE51bWJlcigpIHJlYWRzIGl0OyAwIGlzIGFuIGVuZCBsaWtlIGFueSBvdGhlci4gQW55dGhpbmcgdGhhdCBpcyBub3Rcbi8vIGEgZGVjaW1hbCBudW1iZXIgaXMgbm8gZW5kLlxuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlRGVmYXVsdEJvdW5kKHJhdzogdW5rbm93bik6IG51bWJlciB8IG51bGwge1xuICBpZiAodHlwZW9mIHJhdyA9PT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4gTnVtYmVyLmlzRmluaXRlKHJhdykgPyByYXcgOiBudWxsO1xuICB9XG5cbiAgaWYgKHR5cGVvZiByYXcgIT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCB0cmltbWVkID0gcmF3LnRyaW0oKTtcbiAgY29uc3QgdGV4dCA9IEdST1VQRURfREVDSU1BTC50ZXN0KHRyaW1tZWQpID8gdHJpbW1lZC5yZXBsYWNlKC8sL2csICcnKSA6IHRyaW1tZWQ7XG4gIGlmICghUExBSU5fREVDSU1BTC50ZXN0KHRleHQpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCB2YWx1ZSA9IE51bWJlcih0ZXh0KTtcblxuICByZXR1cm4gTnVtYmVyLmlzRmluaXRlKHZhbHVlKSA/IHZhbHVlIDogbnVsbDtcbn1cblxuLy8gV2h5IHR3byByYW5nZSBlbmRzIGNhbm5vdCBiZSBzYXZlZCwgaW4gdGhlIHNlcnZlcidzIHdvcmRzLCBvciBudWxsLiBBbiBvcGVuXG4vLyBlbmQgaXMgYWx3YXlzIGZpbmUuXG5leHBvcnQgZnVuY3Rpb24gYm91bmRzRXJyb3IobWluOiBudW1iZXIgfCBudWxsLCBtYXg6IG51bWJlciB8IG51bGwpOiBzdHJpbmcgfCBudWxsIHtcbiAgaWYgKG1pbiA9PT0gbnVsbCB8fCBtYXggPT09IG51bGwgfHwgbWluIDw9IG1heCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIGBtaW4gKCR7bWlufSkgaXMgYWJvdmUgbWF4ICgke21heH0pLmA7XG59XG5cbi8vIFRoZSBUeXBlIHNlbGVjdCBvZiBhIGNvbHVtbiBvbiB0aGUgY29tcG9uZW50IHNldHRpbmdzJyBGaWx0ZXJzIHRhYi4gSXRcbi8vIHNob3dzIHdoZW4gdGhlIGNvbHVtbiBjYW4gdGFrZSBlaXRoZXIgdHlwZSBhbmQgdGhlIHNlcnZlciBzZXJ2ZXMgbnVtYmVyXG4vLyByYW5nZXMgKGFuIG9sZGVyIHNlcnZlciBsaXN0cyBubyBmZWF0dXJlcykuIEEgZmlsdGVyJ3MgdHlwZSBjYW5ub3QgY2hhbmdlLFxuLy8gc28gaXQgaXMgbG9ja2VkIHdoaWxlIHRoZSBjb2x1bW4gaGFzIGEgZmlsdGVyIG9uIHRoaXMgY29tcG9uZW50LlxuZXhwb3J0IGZ1bmN0aW9uIHR5cGVTZWxlY3RTdGF0ZShcbiAgdHlwZXM6IFJlcG9ydEZpbHRlclR5cGVbXSB8IG51bGwgfCB1bmRlZmluZWQsXG4gIGhhc0ZpbHRlck9uVGhpc0NvbXBvbmVudDogYm9vbGVhbixcbiAgZmVhdHVyZXM6IFJlcG9ydFZpZXdlckZlYXR1cmVbXSB8IG51bGwgfCB1bmRlZmluZWQsXG4pOiBGaWx0ZXJUeXBlU2VsZWN0U3RhdGUge1xuICBjb25zdCBzaG93ID0gKGZlYXR1cmVzID8/IFtdKS5pbmNsdWRlcygnbnVtYmVyUmFuZ2UnKVxuICAgICYmIEZJTFRFUl9UWVBFX09QVElPTlMuZXZlcnkoKG9wdGlvbikgPT4gKHR5cGVzID8/IFtdKS5pbmNsdWRlcyhvcHRpb24udmFsdWUpKTtcblxuICBpZiAoIXNob3cpIHtcbiAgICByZXR1cm4geyBzaG93OiBmYWxzZSwgZGlzYWJsZWQ6IGZhbHNlLCB0b29sdGlwOiBudWxsIH07XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHNob3c6IHRydWUsXG4gICAgZGlzYWJsZWQ6IGhhc0ZpbHRlck9uVGhpc0NvbXBvbmVudCxcbiAgICB0b29sdGlwOiBoYXNGaWx0ZXJPblRoaXNDb21wb25lbnQgPyBUWVBFX0xPQ0tFRF9UT09MVElQIDogbnVsbCxcbiAgfTtcbn1cblxuLy8gVGhlIGxldmVscyBhIG5ldyBvciBtb3ZlZCBmaWx0ZXIgY2FuIHRha2Ugb24gYSBjb21wb25lbnQuIFRoaXMgcGFnZSBvbmx5XG4vLyBuZWVkcyBhIHNlcnZlciB0aGF0IHNlcnZlcyBwYWdlIGZpbHRlcnMgYW5kIGEgY29tcG9uZW50IG9uIGEgcGFnZSAoYVxuLy8gaGVhZGVyIG9yIGZvb3RlciBjb21wb25lbnQgaXMgb24gbm8gcGFnZSkuXG5leHBvcnQgZnVuY3Rpb24gZmlsdGVyTGV2ZWxDaG9pY2VzKFxuICBmZWF0dXJlczogUmVwb3J0Vmlld2VyRmVhdHVyZVtdIHwgbnVsbCB8IHVuZGVmaW5lZCxcbiAgb25QYWdlOiBib29sZWFuLFxuKTogUmVwb3J0RmlsdGVyTGV2ZWxbXSB7XG4gIGNvbnN0IGxldmVsczogUmVwb3J0RmlsdGVyTGV2ZWxbXSA9IFsnY29tcG9uZW50JywgJ3JlcG9ydCcsICdib3RoJ107XG5cbiAgcmV0dXJuIG9uUGFnZSAmJiAoZmVhdHVyZXMgPz8gW10pLmluY2x1ZGVzKCdwYWdlU2NvcGUnKVxuICAgID8gWy4uLmxldmVscywgJ3BhZ2UnXVxuICAgIDogbGV2ZWxzO1xufVxuXG4vLyBUaGUgUmVwb3J0IGJhciBzZWxlY3QncyBjaG9pY2VzIGZvciB0aGUgbGV2ZWxzIG9uIG9mZmVyLiBUaGUgY2hvaWNlIGEgcm93XG4vLyBhbHJlYWR5IGhvbGRzIGlzIGFsd2F5cyBsaXN0ZWQsIHNvIHRoZSBzZWxlY3QgbmV2ZXIgc2hvd3MgYmxhbmsuXG5leHBvcnQgZnVuY3Rpb24gYmFyUGxhY2VtZW50T3B0aW9ucyhcbiAgbGV2ZWxDaG9pY2VzOiBSZXBvcnRGaWx0ZXJMZXZlbFtdLFxuICBjdXJyZW50OiBGaWx0ZXJCYXJQbGFjZW1lbnQgPSAnb2ZmJyxcbik6IEZpbHRlclNldHRpbmdzT3B0aW9uPEZpbHRlckJhclBsYWNlbWVudD5bXSB7XG4gIHJldHVybiBCQVJfUExBQ0VNRU5UX09QVElPTlMuZmlsdGVyKChvcHRpb24pID0+IHtcbiAgICBzd2l0Y2ggKG9wdGlvbi52YWx1ZSkge1xuICAgICAgY2FzZSAnZXZlcnknOlxuICAgICAgICByZXR1cm4gbGV2ZWxDaG9pY2VzLmluY2x1ZGVzKCdyZXBvcnQnKSB8fCBsZXZlbENob2ljZXMuaW5jbHVkZXMoJ2JvdGgnKSB8fCBjdXJyZW50ID09PSAnZXZlcnknO1xuICAgICAgY2FzZSAncGFnZSc6XG4gICAgICAgIHJldHVybiBsZXZlbENob2ljZXMuaW5jbHVkZXMoJ3BhZ2UnKSB8fCBjdXJyZW50ID09PSAncGFnZSc7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH0pO1xufVxuXG4vLyBBIHZhbHVlJ3MgUmVwb3J0IGJhciBjaG9pY2VzLiBBIHZhbHVlIGhhcyBubyBzdHJpcCBvZiBpdHMgb3duIGFuZCBpdHNcbi8vIGdyb3VwIG1heSBiZSBzaGFyZWQsIHNvIGEgcGljayBuZXZlciBsb3dlcnMgdGhlIGdyb3VwICh0aGUgaW5saW5lIHZhbHVlc1xuLy8gcnVsZSk6IFRoaXMgcGFnZSBvbmx5IGlzIG9mZmVyZWQgZm9yIGEgbmV3IGZpbHRlciwgb3IgZm9yIGEgZ3JvdXAgdGhhdCBpc1xuLy8gYWxyZWFkeSBhIHBhZ2UgZ3JvdXAsIG5ldmVyIHRvIG1vdmUgYSBzaGFyZWQgZ3JvdXAgdG8gb25lIHBhZ2UuXG5leHBvcnQgZnVuY3Rpb24gdmFsdWVQbGFjZW1lbnRPcHRpb25zKFxuICBsZXZlbENob2ljZXM6IFJlcG9ydEZpbHRlckxldmVsW10sXG4gIGN1cnJlbnQ6IFJlcG9ydEZpbHRlckxldmVsIHwgbnVsbCB8IHVuZGVmaW5lZCxcbik6IEZpbHRlclNldHRpbmdzT3B0aW9uPEZpbHRlckJhclBsYWNlbWVudD5bXSB7XG4gIGNvbnN0IGNob2ljZXMgPSAhY3VycmVudCB8fCBjdXJyZW50ID09PSAncGFnZSdcbiAgICA/IGxldmVsQ2hvaWNlc1xuICAgIDogbGV2ZWxDaG9pY2VzLmZpbHRlcigobGV2ZWwpID0+IGxldmVsICE9PSAncGFnZScpO1xuXG4gIHJldHVybiBiYXJQbGFjZW1lbnRPcHRpb25zKGNob2ljZXMsIGJhclBsYWNlbWVudChjdXJyZW50KSk7XG59XG5cbi8vIFRoZSBsZXZlbCBhIHZhbHVlJ3MgZmlsdGVyIGdyb3VwIGVuZHMgYXQgYWZ0ZXIgYSBSZXBvcnQgYmFyIHBpY2ssIG9yIG51bGxcbi8vIHdoZW4gdGhlIHZhbHVlIGxlYXZlcyBpdC4gT2ZmIHVubGlua3MgdGhpcyB2YWx1ZSBhbG9uZSBhbmQgdGhlIGdyb3VwIGtlZXBzXG4vLyBpdHMgb3RoZXIgbWVtYmVycy4gQSBuZXcgZmlsdGVyIHRha2VzIHRoZSBwaWNrJ3MgbGV2ZWwuIEV2ZXJ5IHBhZ2UgcmFpc2VzIGFcbi8vIHN0cmlwLW9ubHkgZ3JvdXAgdG8gYm90aCwga2VlcGluZyBpdHMgc3RyaXBzLCBhbmQgYSBwYWdlIGdyb3VwIHRvIHRoZVxuLy8gcmVwb3J0IGJhci4gTm90aGluZyBlbHNlIG1vdmVzIHRoZSBncm91cCwgc28gYSB2YWx1ZSBuZXZlciBsb3dlcnMgaXQuXG5leHBvcnQgZnVuY3Rpb24gdmFsdWVGaWx0ZXJMZXZlbChcbiAgcGxhY2VtZW50OiBGaWx0ZXJCYXJQbGFjZW1lbnQsXG4gIGN1cnJlbnQ6IFJlcG9ydEZpbHRlckxldmVsIHwgbnVsbCB8IHVuZGVmaW5lZCxcbik6IFJlcG9ydEZpbHRlckxldmVsIHwgbnVsbCB7XG4gIGlmIChwbGFjZW1lbnQgPT09ICdvZmYnKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBpZiAoIWN1cnJlbnQpIHtcbiAgICByZXR1cm4gcGxhY2VtZW50ID09PSAncGFnZScgPyAncGFnZScgOiAncmVwb3J0JztcbiAgfVxuXG4gIGlmIChwbGFjZW1lbnQgIT09ICdldmVyeScpIHtcbiAgICByZXR1cm4gY3VycmVudDtcbiAgfVxuXG4gIHN3aXRjaCAoY3VycmVudCkge1xuICAgIGNhc2UgJ2NvbXBvbmVudCc6XG4gICAgICByZXR1cm4gJ2JvdGgnO1xuICAgIGNhc2UgJ3BhZ2UnOlxuICAgICAgcmV0dXJuICdyZXBvcnQnO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gY3VycmVudDtcbiAgfVxufVxuXG4vLyBXaGVyZSBhIGdyb3VwIG9mIGEgbGV2ZWwgc2hvd3MgaW4gdGhlIHJlcG9ydCBiYXIuIE5vIGdyb3VwIChubyBmaWx0ZXIpIGlzXG4vLyBvZmYuXG5leHBvcnQgZnVuY3Rpb24gYmFyUGxhY2VtZW50KGxldmVsOiBSZXBvcnRGaWx0ZXJMZXZlbCB8IG51bGwgfCB1bmRlZmluZWQpOiBGaWx0ZXJCYXJQbGFjZW1lbnQge1xuICBzd2l0Y2ggKGxldmVsKSB7XG4gICAgY2FzZSAncmVwb3J0JzpcbiAgICBjYXNlICdib3RoJzpcbiAgICAgIHJldHVybiAnZXZlcnknO1xuICAgIGNhc2UgJ3BhZ2UnOlxuICAgICAgcmV0dXJuICdwYWdlJztcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuICdvZmYnO1xuICB9XG59XG5cbi8vIFdoZXRoZXIgYSBncm91cCBvZiBhIGxldmVsIHNob3dzIG9uIGl0cyBjb21wb25lbnRzLlxuZXhwb3J0IGZ1bmN0aW9uIHNob3duT25Db21wb25lbnQobGV2ZWw6IFJlcG9ydEZpbHRlckxldmVsIHwgbnVsbCB8IHVuZGVmaW5lZCk6IGJvb2xlYW4ge1xuICByZXR1cm4gbGV2ZWwgPT09ICdjb21wb25lbnQnIHx8IGxldmVsID09PSAnYm90aCc7XG59XG5cbi8vIFRoZSBsZXZlbCB0aGUgdHdvIGNvbnRyb2xzIG9mIGEgcm93IGFzayBmb3IsIG9yIG51bGwgd2hlbiB0aGV5IGFzayBmb3Igbm9cbi8vIGZpbHRlciBhdCBhbGwuIEEgcGFnZSBmaWx0ZXIgc2hvd3MgaW4gaXRzIHBhZ2UncyBiYXIgb25seSwgc28gVGhpcyBwYWdlXG4vLyBvbmx5IGlnbm9yZXMgdGhlIFRoaXMgY29tcG9uZW50IHRvZ2dsZS5cbmV4cG9ydCBmdW5jdGlvbiBmaWx0ZXJMZXZlbChwbGFjZW1lbnQ6IEZpbHRlckJhclBsYWNlbWVudCwgY29tcG9uZW50OiBib29sZWFuKTogUmVwb3J0RmlsdGVyTGV2ZWwgfCBudWxsIHtcbiAgc3dpdGNoIChwbGFjZW1lbnQpIHtcbiAgICBjYXNlICdwYWdlJzpcbiAgICAgIHJldHVybiAncGFnZSc7XG4gICAgY2FzZSAnZXZlcnknOlxuICAgICAgcmV0dXJuIGNvbXBvbmVudCA/ICdib3RoJyA6ICdyZXBvcnQnO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gY29tcG9uZW50ID8gJ2NvbXBvbmVudCcgOiBudWxsO1xuICB9XG59XG5cbi8vIFRoZSBUaGlzIGNvbXBvbmVudCB0b2dnbGUgb2YgYSByb3c6IGxvY2tlZCB3aGlsZSBUaGlzIHBhZ2Ugb25seSBpcyBwaWNrZWQuXG5leHBvcnQgZnVuY3Rpb24gY29tcG9uZW50VG9nZ2xlU3RhdGUocGxhY2VtZW50OiBGaWx0ZXJCYXJQbGFjZW1lbnQpOiBGaWx0ZXJDb21wb25lbnRUb2dnbGVTdGF0ZSB7XG4gIHJldHVybiBwbGFjZW1lbnQgPT09ICdwYWdlJ1xuICAgID8geyBkaXNhYmxlZDogdHJ1ZSwgdG9vbHRpcDogUEFHRV9GSUxURVJfVE9PTFRJUCB9XG4gICAgOiB7IGRpc2FibGVkOiBmYWxzZSwgdG9vbHRpcDogQ09NUE9ORU5UX1RPR0dMRV9UT09MVElQIH07XG59XG5cbi8vIFRoZSBncm91cHMgdGhlIHJlcG9ydCBzZXR0aW5ncycgRmlsdGVycyB0YWIgbGlzdHMgZGVmYXVsdHMgZm9yOiB0aG9zZSBvZlxuLy8gdGhlIHJlcG9ydCBiYXIsIGV2ZXJ5IHBhZ2Ugb3Igb25lLCBpbiBiYXIgb3JkZXIuXG5leHBvcnQgZnVuY3Rpb24gZGVmYXVsdFJvd0dyb3Vwcyhncm91cHM6IFJlcG9ydEZpbHRlckdyb3VwW10gfCBudWxsIHwgdW5kZWZpbmVkKTogUmVwb3J0RmlsdGVyR3JvdXBbXSB7XG4gIHJldHVybiAoZ3JvdXBzID8/IFtdKVxuICAgIC5maWx0ZXIoKGdyb3VwKSA9PiBncm91cC5sZXZlbCA9PT0gJ3JlcG9ydCcgfHwgZ3JvdXAubGV2ZWwgPT09ICdib3RoJyB8fCBncm91cC5sZXZlbCA9PT0gJ3BhZ2UnKVxuICAgIC5zb3J0KChhLCBiKSA9PiBhLm9yZGVyIC0gYi5vcmRlcik7XG59XG5cbi8vIEEgZGVmYXVsdCByb3cncyBsYWJlbDogYSBwYWdlIGdyb3VwIG5hbWVzIGl0cyBwYWdlLCAnUmVnaW9uIChwYWdlXG4vLyBcIk92ZXJ2aWV3XCIpJy4gQSBwYWdlIHdpdGggbm8gbmFtZSByZWFkcyBhcyB0aGUgY2FudmFzIG5hbWVzIGl0ICgnUGFnZSAyJykuXG4vLyBBIHBhZ2UgdGhpcyByZXBvcnQgbm8gbG9uZ2VyIGhvbGRzIGFkZHMgbm90aGluZy5cbmV4cG9ydCBmdW5jdGlvbiBkZWZhdWx0Um93TGFiZWwoZ3JvdXA6IFJlcG9ydEZpbHRlckdyb3VwLCBwYWdlczogUmVwb3J0UGFnZVtdIHwgbnVsbCB8IHVuZGVmaW5lZCk6IHN0cmluZyB7XG4gIGNvbnN0IGxhYmVsID0gZ3JvdXAubGFiZWwgfHwgZ3JvdXAuZmlsdGVycz8uWzBdPy5maWx0ZXJDb2x1bW4gfHwgJ0ZpbHRlcic7XG5cbiAgaWYgKGdyb3VwLmxldmVsICE9PSAncGFnZScpIHtcbiAgICByZXR1cm4gbGFiZWw7XG4gIH1cblxuICBjb25zdCBpbmRleCA9IChwYWdlcyA/PyBbXSkuZmluZEluZGV4KChwYWdlKSA9PiBwYWdlLmlkID09PSBncm91cC5wYWdlSWQpO1xuICBpZiAoaW5kZXggPCAwKSB7XG4gICAgcmV0dXJuIGxhYmVsO1xuICB9XG5cbiAgcmV0dXJuIGAke2xhYmVsfSAocGFnZSBcIiR7cGFnZXNbaW5kZXhdLm5hbWUgfHwgYFBhZ2UgJHtpbmRleCArIDF9YH1cIilgO1xufVxuXG4vLyBUaGUgRGVmYXVsdCBwZXJpb2Qgc2VsZWN0J3MgY2hvaWNlczogRml4ZWQgZGF0ZXMsIHRoZW4gZXZlcnkgcmVsYXRpdmVcbi8vIHJhbmdlIGluIHRoZSBzZXJ2ZXIgZW51bSdzIG9yZGVyLCBuYW1lZCBieSBgbGFiZWxzYC4gQSBzdG9yZWQgcmFuZ2UgdGhpc1xuLy8gdmlld2VyIGRvZXMgbm90IGtub3cgaXMgbGlzdGVkIGxhc3QsIHNvIHRoZSBzZWxlY3Qgc3RpbGwgc2hvd3MgaXQuXG5leHBvcnQgZnVuY3Rpb24gZGVmYXVsdFBlcmlvZE9wdGlvbnMoXG4gIGxhYmVsczogKHJlbGF0aXZlOiBSZXBvcnRSZWxhdGl2ZVJhbmdlKSA9PiBzdHJpbmcsXG4gIHN0b3JlZDogc3RyaW5nIHwgbnVsbCA9IG51bGwsXG4pOiBGaWx0ZXJTZXR0aW5nc09wdGlvbltdIHtcbiAgY29uc3Qgb3B0aW9uczogRmlsdGVyU2V0dGluZ3NPcHRpb25bXSA9IFtcbiAgICB7IHZhbHVlOiBGSVhFRF9EQVRFU19QRVJJT0QsIG5hbWU6ICdGaXhlZCBkYXRlcycgfSxcbiAgICAuLi5SRUxBVElWRV9SQU5HRV9OQU1FUy5tYXAoKHJlbGF0aXZlKSA9PiAoeyB2YWx1ZTogcmVsYXRpdmUsIG5hbWU6IGxhYmVscyhyZWxhdGl2ZSkgfSkpLFxuICBdO1xuXG4gIHJldHVybiBzdG9yZWQgJiYgc3RvcmVkICE9PSBGSVhFRF9EQVRFU19QRVJJT0QgJiYgIWlzUmVsYXRpdmVSYW5nZShzdG9yZWQpXG4gICAgPyBbLi4ub3B0aW9ucywgeyB2YWx1ZTogc3RvcmVkLCBuYW1lOiBsYWJlbHMoc3RvcmVkIGFzIFJlcG9ydFJlbGF0aXZlUmFuZ2UpIH1dXG4gICAgOiBvcHRpb25zO1xufVxuXG4vLyBUaGUgRGVmYXVsdCBwZXJpb2QgYSBzdG9yZWQgZGF0ZSByYW5nZSBkZWZhdWx0IG9wZW5zIG9uOiBpdHMgcmVsYXRpdmVcbi8vIHJhbmdlLCBlbHNlIEZpeGVkIGRhdGVzICh0aGUgZGF5cywgb3Igbm9uZSkuXG5leHBvcnQgZnVuY3Rpb24gZGVmYXVsdFBlcmlvZChzdG9yZWQ6IEZpbHRlckdyb3VwRGVmYXVsdCB8IG51bGwgfCB1bmRlZmluZWQpOiBzdHJpbmcge1xuICByZXR1cm4gc3RvcmVkPy5yZWxhdGl2ZSAmJiAhc3RvcmVkLnN0YXJ0ICYmICFzdG9yZWQuZW5kXG4gICAgPyBzdG9yZWQucmVsYXRpdmVcbiAgICA6IEZJWEVEX0RBVEVTX1BFUklPRDtcbn1cblxuLy8gQSBkYXRlIHJhbmdlIGRlZmF1bHQgaW4gaXRzIHN0b3JlZCBzaGFwZTogdGhlIHJlbGF0aXZlIHJhbmdlIHBpY2tlZCwgZWxzZVxuLy8gdGhlIGZpeGVkIGRheXMsIG9yIG51bGwgd2hlbiB0aGVyZSBhcmUgbm9uZS4gTmV2ZXIgYm90aDogdGhlIHNlcnZlclxuLy8gcmVmdXNlcyBhIHJlbGF0aXZlIHJhbmdlIHdpdGggZGF5cy5cbmV4cG9ydCBmdW5jdGlvbiBkYXRlUmFuZ2VEZWZhdWx0KFxuICBwZXJpb2Q6IHN0cmluZyxcbiAgc3RhcnQ6IHN0cmluZyB8IG51bGwsXG4gIGVuZDogc3RyaW5nIHwgbnVsbCxcbik6IEZpbHRlckdyb3VwRGVmYXVsdCB8IG51bGwge1xuICBpZiAocGVyaW9kICE9PSBGSVhFRF9EQVRFU19QRVJJT0QpIHtcbiAgICByZXR1cm4geyByZWxhdGl2ZTogcGVyaW9kIH07XG4gIH1cblxuICBpZiAoIXN0YXJ0ICYmICFlbmQpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiB7IC4uLihzdGFydCA/IHsgc3RhcnQgfSA6IHt9KSwgLi4uKGVuZCA/IHsgZW5kIH0gOiB7fSkgfTtcbn1cblxuLy8gQSBzZWxlY3QgZGVmYXVsdCBpbiBpdHMgc3RvcmVkIHNoYXBlOiB0aGUgcGlja3Mga2VwdCwgb3IgbGVmdCBvdXQgd2hpbGVcbi8vIEV4Y2x1ZGUgdGhlc2UgdmFsdWVzIGlzIG9uLCBvciBudWxsIHdoZW4gbm90aGluZyBpcyBwaWNrZWQuXG5leHBvcnQgZnVuY3Rpb24gc2VsZWN0RGVmYXVsdCh2YWx1ZXM6IHVua25vd25bXSwgZXhjbHVkZTogYm9vbGVhbik6IEZpbHRlckdyb3VwRGVmYXVsdCB8IG51bGwge1xuICBpZiAoIXZhbHVlcy5sZW5ndGgpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiBleGNsdWRlID8geyBleGNsdWRlVmFsdWVzOiB2YWx1ZXMgfSA6IHsgdmFsdWVzIH07XG59XG5cbi8vIEEgbnVtYmVyIHJhbmdlIGRlZmF1bHQgaW4gaXRzIHN0b3JlZCBzaGFwZSBmcm9tIHRoZSBlbmRzIGFzIHR5cGVkOiBhblxuLy8gb3BlbiBlbmQgaXMgbGVmdCBvdXQsIDAgaXMga2VwdCwgYW5kIHR3byBvcGVuIGVuZHMgYXJlIG5vIGRlZmF1bHQuXG5leHBvcnQgZnVuY3Rpb24gbnVtYmVyUmFuZ2VEZWZhdWx0KHJhd01pbjogdW5rbm93biwgcmF3TWF4OiB1bmtub3duKTogRmlsdGVyR3JvdXBEZWZhdWx0IHwgbnVsbCB7XG4gIGNvbnN0IG1pbiA9IHBhcnNlRGVmYXVsdEJvdW5kKHJhd01pbik7XG4gIGNvbnN0IG1heCA9IHBhcnNlRGVmYXVsdEJvdW5kKHJhd01heCk7XG5cbiAgaWYgKG1pbiA9PT0gbnVsbCAmJiBtYXggPT09IG51bGwpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHJldHVybiB7IC4uLihtaW4gIT09IG51bGwgPyB7IG1pbiB9IDoge30pLCAuLi4obWF4ICE9PSBudWxsID8geyBtYXggfSA6IHt9KSB9O1xufVxuXG4vLyBXaGV0aGVyIGEgc2VsZWN0IGdyb3VwJ3MgZGVmYXVsdCByb3cgb2ZmZXJzIEV4Y2x1ZGUgdGhlc2UgdmFsdWVzOiB0aGVcbi8vIHJlcG9ydCBiYXIncyBydWxlIChvZmZlcnNFeGNsdWRlKSwgc28gbm90IG9uIGEgc2VydmVyIHRoYXQgZG9lcyBub3Qgc2VydmVcbi8vIGV4Y2x1ZGUgKGFuIG9sZGVyIHNlcnZlciBsaXN0cyBubyBmZWF0dXJlcykgbm9yIG9uIGEgZ3JvdXAgd2l0aCBhIG1lbWJlclxuLy8gdGhhdCBiaW5kcyBzZXZlcmFsIGNvbHVtbnMgKG11bHRpQ29sdW1uKS4gQSBkZWZhdWx0IHRoYXQgYWxyZWFkeSBsZWF2ZXNcbi8vIHZhbHVlcyBvdXQga2VlcHMgdGhlIHRvZ2dsZSwgc28gaXQgY2FuIGJlIHR1cm5lZCBvZmYuXG5leHBvcnQgZnVuY3Rpb24gc2hvd0V4Y2x1ZGVUb2dnbGUoXG4gIGdyb3VwOiBSZXBvcnRGaWx0ZXJHcm91cCxcbiAgZmVhdHVyZXM6IFJlcG9ydFZpZXdlckZlYXR1cmVbXSB8IG51bGwgfCB1bmRlZmluZWQsXG4pOiBib29sZWFuIHtcbiAgaWYgKGdyb3VwLnR5cGUgPT09ICdzZWxlY3QnICYmIGdyb3VwLmNvbmZpZz8uZGVmYXVsdD8uZXhjbHVkZVZhbHVlcz8ubGVuZ3RoKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICByZXR1cm4gb2ZmZXJzRXhjbHVkZShncm91cCwgZmVhdHVyZXMpO1xufVxuXG4vLyBBIHN0b3JlZCBvciBkcmFmdCBkZWZhdWx0IGluIGEgc3RhYmxlIGZvcm0gZm9yIGNvbXBhcmluZzogZW1wdHkgYW5kXG4vLyBhYnNlbnQga2V5cyBhcmUgZHJvcHBlZCwgc28gYSBuby1vcCBlZGl0IGRvZXMgbm90IHJlYWQgYXMgYSBjaGFuZ2UuIDAgaXMgYW5cbi8vIGVuZCBsaWtlIGFueSBvdGhlci4gTm90aGluZyBsZWZ0IGlzIG51bGwuXG5leHBvcnQgZnVuY3Rpb24gbm9ybWFsaXplRGVmYXVsdCh2YWx1ZTogRmlsdGVyR3JvdXBEZWZhdWx0IHwgbnVsbCB8IHVuZGVmaW5lZCk6IEZpbHRlckdyb3VwRGVmYXVsdCB8IG51bGwge1xuICBpZiAoIXZhbHVlKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBjb25zdCBub3JtYWxpemVkOiBGaWx0ZXJHcm91cERlZmF1bHQgPSB7fTtcbiAgaWYgKHZhbHVlLnN0YXJ0KSB7XG4gICAgbm9ybWFsaXplZC5zdGFydCA9IHZhbHVlLnN0YXJ0O1xuICB9XG4gIGlmICh2YWx1ZS5lbmQpIHtcbiAgICBub3JtYWxpemVkLmVuZCA9IHZhbHVlLmVuZDtcbiAgfVxuICBpZiAodmFsdWUudmFsdWVzPy5sZW5ndGgpIHtcbiAgICBub3JtYWxpemVkLnZhbHVlcyA9IHZhbHVlLnZhbHVlcztcbiAgfVxuICBpZiAodmFsdWUuZXhjbHVkZVZhbHVlcz8ubGVuZ3RoKSB7XG4gICAgbm9ybWFsaXplZC5leGNsdWRlVmFsdWVzID0gdmFsdWUuZXhjbHVkZVZhbHVlcztcbiAgfVxuICBpZiAodHlwZW9mIHZhbHVlLm1pbiA9PT0gJ251bWJlcicpIHtcbiAgICBub3JtYWxpemVkLm1pbiA9IHZhbHVlLm1pbjtcbiAgfVxuICBpZiAodHlwZW9mIHZhbHVlLm1heCA9PT0gJ251bWJlcicpIHtcbiAgICBub3JtYWxpemVkLm1heCA9IHZhbHVlLm1heDtcbiAgfVxuICBpZiAodmFsdWUudmFsdWUpIHtcbiAgICBub3JtYWxpemVkLnZhbHVlID0gdmFsdWUudmFsdWU7XG4gIH1cbiAgaWYgKHZhbHVlLnJlbGF0aXZlKSB7XG4gICAgbm9ybWFsaXplZC5yZWxhdGl2ZSA9IHZhbHVlLnJlbGF0aXZlO1xuICB9XG5cbiAgcmV0dXJuIE9iamVjdC5rZXlzKG5vcm1hbGl6ZWQpLmxlbmd0aCA/IG5vcm1hbGl6ZWQgOiBudWxsO1xufVxuXG4vLyBXaGV0aGVyIGEgcm93J3MgZHJhZnQgZGVmYXVsdCBkaWZmZXJzIGZyb20gdGhlIGdyb3VwJ3Mgc3RvcmVkIG9uZS4gT25seSBhXG4vLyBjaGFuZ2VkIHJvdyBpcyBzYXZlZC5cbmV4cG9ydCBmdW5jdGlvbiBkZWZhdWx0Q2hhbmdlZChcbiAgc3RvcmVkOiBGaWx0ZXJHcm91cERlZmF1bHQgfCBudWxsIHwgdW5kZWZpbmVkLFxuICBkcmFmdDogRmlsdGVyR3JvdXBEZWZhdWx0IHwgbnVsbCB8IHVuZGVmaW5lZCxcbik6IGJvb2xlYW4ge1xuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkobm9ybWFsaXplRGVmYXVsdChzdG9yZWQpKSAhPT0gSlNPTi5zdHJpbmdpZnkobm9ybWFsaXplRGVmYXVsdChkcmFmdCkpO1xufVxuIl19