@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.
Files changed (186) 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 +20 -7
  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 +45 -8
  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 +37 -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-group-changes.interface.d.ts +7 -0
  41. package/app/reports/interfaces/report-filter-line-context.interface.d.ts +8 -0
  42. package/app/reports/interfaces/report-filter-line-form.type.d.ts +1 -0
  43. package/app/reports/interfaces/report-filter-match.type.d.ts +1 -0
  44. package/app/reports/interfaces/report-filter-option-pair.interface.d.ts +4 -0
  45. package/app/reports/interfaces/report-filter-options-ask.interface.d.ts +6 -0
  46. package/app/reports/interfaces/report-filter-options-list.interface.d.ts +7 -0
  47. package/app/reports/interfaces/report-filter-options-request.interface.d.ts +6 -0
  48. package/app/reports/interfaces/report-filter-options-stream.interface.d.ts +11 -0
  49. package/app/reports/interfaces/report-filter-options.interface.d.ts +7 -0
  50. package/app/reports/interfaces/report-filter-skip.type.d.ts +1 -0
  51. package/app/reports/interfaces/report-mark-action.type.d.ts +1 -0
  52. package/app/reports/interfaces/report-mark-click.interface.d.ts +13 -0
  53. package/app/reports/interfaces/report-mark-context.interface.d.ts +6 -0
  54. package/app/reports/interfaces/report-mark-decision.interface.d.ts +6 -0
  55. package/app/reports/interfaces/report-mark-event.interface.d.ts +11 -0
  56. package/app/reports/interfaces/report-mark-point.interface.d.ts +8 -0
  57. package/app/reports/interfaces/report-temporary-state.interface.d.ts +4 -0
  58. package/app/reports/interfaces/report-tile-state.interface.d.ts +8 -0
  59. package/app/reports/interfaces/report-view-config.interface.d.ts +11 -0
  60. package/app/reports/interfaces/report-view-create.interface.d.ts +7 -0
  61. package/app/reports/interfaces/report-view-deleted.interface.d.ts +4 -0
  62. package/app/reports/interfaces/report-view-dialog-data.interface.d.ts +7 -0
  63. package/app/reports/interfaces/report-view-dropped.interface.d.ts +5 -0
  64. package/app/reports/interfaces/report-view-menu-item.interface.d.ts +10 -0
  65. package/app/reports/interfaces/report-view-summary.interface.d.ts +11 -0
  66. package/app/reports/interfaces/report-view.interface.d.ts +7 -0
  67. package/app/reports/interfaces/report-viewer-feature.type.d.ts +1 -0
  68. package/app/reports/interfaces/report-views.interface.d.ts +7 -0
  69. package/app/reports/interfaces/report.interface.d.ts +27 -16
  70. package/app/reports/interfaces/tile-load-result.interface.d.ts +4 -0
  71. package/app/reports/mark-click.d.ts +20 -0
  72. package/app/reports/option-builder.d.ts +12 -1
  73. package/app/reports/report-chat-viewer-state.d.ts +8 -0
  74. package/app/reports/report-date-presets.d.ts +2 -0
  75. package/app/reports/report-filter-items.d.ts +20 -21
  76. package/app/reports/report-tile.d.ts +2 -0
  77. package/app/reports/report-view-config.d.ts +34 -0
  78. package/app/reports/report-view-menu.d.ts +15 -0
  79. package/app/reports/report-viewer-features.d.ts +5 -0
  80. package/app/reports/services/report-filter-options.service.d.ts +26 -0
  81. package/app/reports/services/report-filter-state.service.d.ts +65 -11
  82. package/app/reports/services/report-view.service.d.ts +39 -0
  83. package/app/reports/tile-data-state.d.ts +7 -0
  84. package/app/reports/tile-loads.d.ts +4 -0
  85. package/app/reports/views/report/fs-ai-report.component.d.ts +10 -8
  86. package/app/reports/views/report/report.component.d.ts +6 -0
  87. package/esm2022/app/reports/anchor-at-point.mjs +49 -0
  88. package/esm2022/app/reports/canvas-landing-page.mjs +26 -0
  89. package/esm2022/app/reports/components/component-chart/component-chart.component.mjs +97 -5
  90. package/esm2022/app/reports/components/component-kpi/component-kpi.component.mjs +11 -4
  91. package/esm2022/app/reports/components/component-list/component-list.component.mjs +11 -5
  92. package/esm2022/app/reports/components/report-canvas/report-canvas.component.mjs +56 -40
  93. package/esm2022/app/reports/components/report-component/report-component.component.mjs +261 -65
  94. package/esm2022/app/reports/components/report-view-picker/report-view-picker.component.mjs +115 -0
  95. package/esm2022/app/reports/data/report.data.mjs +94 -14
  96. package/esm2022/app/reports/dialogs/component-settings/component-settings.component.mjs +106 -51
  97. package/esm2022/app/reports/dialogs/report-settings/report-settings.component.mjs +248 -104
  98. package/esm2022/app/reports/dialogs/report-view/report-view-dialog.component.mjs +52 -0
  99. package/esm2022/app/reports/drill-crumbs.mjs +73 -0
  100. package/esm2022/app/reports/export/report-export-collector.service.mjs +187 -117
  101. package/esm2022/app/reports/export/report-filter-lines.mjs +235 -0
  102. package/esm2022/app/reports/export/report-pdf.service.mjs +12 -7
  103. package/esm2022/app/reports/export/report-pptx.service.mjs +18 -14
  104. package/esm2022/app/reports/filter-settings-rules.mjs +290 -0
  105. package/esm2022/app/reports/format.mjs +2 -22
  106. package/esm2022/app/reports/interfaces/canvas-landing-input.interface.mjs +2 -0
  107. package/esm2022/app/reports/interfaces/component-data-applied.interface.mjs +2 -0
  108. package/esm2022/app/reports/interfaces/component-data-drill.interface.mjs +2 -0
  109. package/esm2022/app/reports/interfaces/filter-bar-placement.type.mjs +2 -0
  110. package/esm2022/app/reports/interfaces/filter-component-toggle-state.interface.mjs +2 -0
  111. package/esm2022/app/reports/interfaces/filter-settings-option.interface.mjs +2 -0
  112. package/esm2022/app/reports/interfaces/filter-type-select-state.interface.mjs +2 -0
  113. package/esm2022/app/reports/interfaces/report-chart-hit.interface.mjs +2 -0
  114. package/esm2022/app/reports/interfaces/report-chat-viewer-cross-filter-field.interface.mjs +2 -0
  115. package/esm2022/app/reports/interfaces/report-chat-viewer-cross-filter.interface.mjs +2 -0
  116. package/esm2022/app/reports/interfaces/report-chat-viewer-detail.interface.mjs +2 -0
  117. package/esm2022/app/reports/interfaces/report-chat-viewer-drill-step.interface.mjs +2 -0
  118. package/esm2022/app/reports/interfaces/report-chat-viewer-drill.interface.mjs +2 -0
  119. package/esm2022/app/reports/interfaces/report-chat-viewer-filter.interface.mjs +1 -1
  120. package/esm2022/app/reports/interfaces/report-chat-viewer-selection.interface.mjs +2 -0
  121. package/esm2022/app/reports/interfaces/report-chat-viewer-state.interface.mjs +1 -1
  122. package/esm2022/app/reports/interfaces/report-drill-crumb.interface.mjs +2 -0
  123. package/esm2022/app/reports/interfaces/report-drill-refusal.type.mjs +2 -0
  124. package/esm2022/app/reports/interfaces/report-drill-step.interface.mjs +2 -0
  125. package/esm2022/app/reports/interfaces/report-export-line-kind.type.mjs +2 -0
  126. package/esm2022/app/reports/interfaces/report-export-line.interface.mjs +2 -0
  127. package/esm2022/app/reports/interfaces/report-export-lines-input.interface.mjs +2 -0
  128. package/esm2022/app/reports/interfaces/report-export-snapshot.interface.mjs +2 -0
  129. package/esm2022/app/reports/interfaces/report-filter-group-changes.interface.mjs +2 -0
  130. package/esm2022/app/reports/interfaces/report-filter-line-context.interface.mjs +2 -0
  131. package/esm2022/app/reports/interfaces/report-filter-line-form.type.mjs +2 -0
  132. package/esm2022/app/reports/interfaces/report-filter-match.type.mjs +2 -0
  133. package/esm2022/app/reports/interfaces/report-filter-option-pair.interface.mjs +2 -0
  134. package/esm2022/app/reports/interfaces/report-filter-options-ask.interface.mjs +2 -0
  135. package/esm2022/app/reports/interfaces/report-filter-options-list.interface.mjs +2 -0
  136. package/esm2022/app/reports/interfaces/report-filter-options-request.interface.mjs +2 -0
  137. package/esm2022/app/reports/interfaces/report-filter-options-stream.interface.mjs +2 -0
  138. package/esm2022/app/reports/interfaces/report-filter-options.interface.mjs +2 -0
  139. package/esm2022/app/reports/interfaces/report-filter-skip.type.mjs +2 -0
  140. package/esm2022/app/reports/interfaces/report-mark-action.type.mjs +2 -0
  141. package/esm2022/app/reports/interfaces/report-mark-click.interface.mjs +2 -0
  142. package/esm2022/app/reports/interfaces/report-mark-context.interface.mjs +2 -0
  143. package/esm2022/app/reports/interfaces/report-mark-decision.interface.mjs +2 -0
  144. package/esm2022/app/reports/interfaces/report-mark-event.interface.mjs +2 -0
  145. package/esm2022/app/reports/interfaces/report-mark-point.interface.mjs +2 -0
  146. package/esm2022/app/reports/interfaces/report-temporary-state.interface.mjs +2 -0
  147. package/esm2022/app/reports/interfaces/report-tile-state.interface.mjs +2 -0
  148. package/esm2022/app/reports/interfaces/report-view-config.interface.mjs +2 -0
  149. package/esm2022/app/reports/interfaces/report-view-create.interface.mjs +2 -0
  150. package/esm2022/app/reports/interfaces/report-view-deleted.interface.mjs +2 -0
  151. package/esm2022/app/reports/interfaces/report-view-dialog-data.interface.mjs +2 -0
  152. package/esm2022/app/reports/interfaces/report-view-dropped.interface.mjs +2 -0
  153. package/esm2022/app/reports/interfaces/report-view-menu-item.interface.mjs +2 -0
  154. package/esm2022/app/reports/interfaces/report-view-summary.interface.mjs +2 -0
  155. package/esm2022/app/reports/interfaces/report-view.interface.mjs +2 -0
  156. package/esm2022/app/reports/interfaces/report-viewer-feature.type.mjs +2 -0
  157. package/esm2022/app/reports/interfaces/report-views.interface.mjs +2 -0
  158. package/esm2022/app/reports/interfaces/report.interface.mjs +1 -1
  159. package/esm2022/app/reports/interfaces/tile-load-result.interface.mjs +2 -0
  160. package/esm2022/app/reports/mark-click.mjs +193 -0
  161. package/esm2022/app/reports/option-builder.mjs +159 -15
  162. package/esm2022/app/reports/report-chat-viewer-state.mjs +34 -0
  163. package/esm2022/app/reports/report-date-presets.mjs +18 -0
  164. package/esm2022/app/reports/report-filter-items.mjs +263 -72
  165. package/esm2022/app/reports/report-tile.mjs +12 -0
  166. package/esm2022/app/reports/report-view-config.mjs +587 -0
  167. package/esm2022/app/reports/report-view-menu.mjs +119 -0
  168. package/esm2022/app/reports/report-viewer-features.mjs +42 -0
  169. package/esm2022/app/reports/services/report-filter-options.service.mjs +238 -0
  170. package/esm2022/app/reports/services/report-filter-state.service.mjs +668 -210
  171. package/esm2022/app/reports/services/report-view.service.mjs +218 -0
  172. package/esm2022/app/reports/tile-data-state.mjs +127 -0
  173. package/esm2022/app/reports/tile-loads.mjs +38 -0
  174. package/esm2022/app/reports/views/report/fs-ai-report.component.mjs +194 -127
  175. package/esm2022/app/reports/views/report/report.component.mjs +112 -29
  176. package/esm2022/public_api.mjs +23 -1
  177. package/fesm2022/{firestitch-report-echarts-DBMOHmBF.mjs → firestitch-report-echarts-DHEH_K_q.mjs} +2 -2
  178. package/fesm2022/{firestitch-report-echarts-DBMOHmBF.mjs.map → firestitch-report-echarts-DHEH_K_q.mjs.map} +1 -1
  179. package/fesm2022/{firestitch-report-firestitch-report-CqbXT1gh.mjs → firestitch-report-firestitch-report-ZcHTnNKq.mjs} +8222 -4447
  180. package/fesm2022/firestitch-report-firestitch-report-ZcHTnNKq.mjs.map +1 -0
  181. package/fesm2022/firestitch-report.mjs +1 -1
  182. package/package.json +1 -1
  183. package/public_api.d.ts +22 -0
  184. package/app/reports/report-url-state.d.ts +0 -19
  185. package/esm2022/app/reports/report-url-state.mjs +0 -189
  186. package/fesm2022/firestitch-report-firestitch-report-CqbXT1gh.mjs.map +0 -1
@@ -0,0 +1,119 @@
1
+ export const VIEWS_LABEL = 'Views';
2
+ export const EDITED_TOOLTIP = 'The screen differs from this view';
3
+ export const SAVE_AS_TITLE = 'Save as new view';
4
+ export const RENAME_TITLE = 'Rename view';
5
+ export const CROSS_FILTER_NOTE = 'Cross-filters are temporary and are not saved.';
6
+ export const VIEW_NAME_BLANK = 'Enter a name';
7
+ // The server's limit on a view's name.
8
+ export const VIEW_NAME_MAX_LENGTH = 100;
9
+ // The menu for the open view (null when none is open), the views the viewer
10
+ // may see, whether the screen differs from the open view, and whether the
11
+ // viewer may share its views.
12
+ export function viewMenuItems(open, views, edited, canShare) {
13
+ const rows = [
14
+ ...views.filter((view) => view.mine),
15
+ ...views.filter((view) => !view.mine),
16
+ ].map((view) => viewRow(view, open, edited));
17
+ const actions = openViewActions(open, edited, canShare);
18
+ const resets = [
19
+ ...(open && edited ? [action('resetToView', `Reset to "${open.name}"`)] : []),
20
+ action('resetToDefaults', 'Reset to report defaults'),
21
+ ];
22
+ return [
23
+ ...rows,
24
+ ...withDivider(actions, rows.length > 0),
25
+ ...withDivider(resets, true),
26
+ ];
27
+ }
28
+ // The picker's label: 'Views', or the open view's name, marked while the
29
+ // screen differs from it.
30
+ export function pickerLabel(open, edited) {
31
+ if (!open) {
32
+ return VIEWS_LABEL;
33
+ }
34
+ return edited ? `${open.name} (edited)` : open.name;
35
+ }
36
+ // The picker's tooltip: only while the screen differs from the open view.
37
+ export function pickerTooltip(open, edited) {
38
+ return open && edited ? EDITED_TOOLTIP : null;
39
+ }
40
+ // The question before a view is deleted. A shared view says that everyone
41
+ // loses it.
42
+ export function deletePromptText(view) {
43
+ const question = `Delete the view "${view.name}"?`;
44
+ return view.shared ? `${question} Everyone it is shared with loses it.` : question;
45
+ }
46
+ // The line the save dialog shows under the name, or null: a cross-filter is
47
+ // on, and it does not go into the view.
48
+ export function saveDialogNote(hasCrossFilter) {
49
+ return hasCrossFilter ? CROSS_FILTER_NOTE : null;
50
+ }
51
+ // A name made of spaces only is no name; the server trims it.
52
+ export function viewNameError(name) {
53
+ return (name ?? '').trim() ? null : VIEW_NAME_BLANK;
54
+ }
55
+ function viewRow(view, open, edited) {
56
+ const isOpen = view.id === open?.id;
57
+ return {
58
+ kind: 'view',
59
+ label: view.name,
60
+ disabled: isOpen && !edited,
61
+ tooltip: viewTooltip(view),
62
+ divider: false,
63
+ viewId: view.id,
64
+ open: isOpen,
65
+ icon: viewIcon(view),
66
+ };
67
+ }
68
+ // Who shared a view of someone else's; whether one of the viewer's own opens
69
+ // by default or is shared.
70
+ function viewTooltip(view) {
71
+ if (!view.mine) {
72
+ return view.ownerName ? `Shared by ${view.ownerName}` : 'Shared with everyone';
73
+ }
74
+ if (view.personalDefault && view.shared) {
75
+ return 'Opens by default, shared with everyone';
76
+ }
77
+ if (view.personalDefault) {
78
+ return 'Opens by default';
79
+ }
80
+ return view.shared ? 'Shared with everyone' : null;
81
+ }
82
+ // The open row keeps this icon too; its check is drawn beside it.
83
+ function viewIcon(view) {
84
+ if (!view.mine) {
85
+ return 'people';
86
+ }
87
+ return view.personalDefault ? 'star' : null;
88
+ }
89
+ // The rows that act on the open view; with none open, only Save as new view.
90
+ function openViewActions(open, edited, canShare) {
91
+ const items = [];
92
+ if (open?.canChange && edited) {
93
+ items.push(action('saveChanges', 'Save changes'));
94
+ }
95
+ items.push(action('saveAsNew', 'Save as new view...'));
96
+ if (open?.canChange) {
97
+ items.push(action('rename', 'Rename...'));
98
+ }
99
+ if (open?.mine) {
100
+ items.push(open.personalDefault
101
+ ? action('clearDefault', 'Stop opening it by default')
102
+ : action('setDefault', 'Make it my default'));
103
+ }
104
+ if (open?.mine && canShare) {
105
+ items.push(open.shared ? action('unshare', 'Stop sharing') : action('share', 'Share with everyone'));
106
+ }
107
+ if (open?.canDelete) {
108
+ items.push(action('delete', 'Delete...'));
109
+ }
110
+ return items;
111
+ }
112
+ function action(kind, label) {
113
+ return { kind, label, disabled: false, tooltip: null, divider: false, viewId: null, open: false, icon: null };
114
+ }
115
+ // The same rows, the first with a line above it when `divider` is set.
116
+ function withDivider(items, divider) {
117
+ return items.map((item, index) => (index === 0 && divider ? { ...item, divider: true } : item));
118
+ }
119
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LXZpZXctbWVudS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy9yZXBvcnQtdmlldy1tZW51LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQW9CQSxNQUFNLENBQUMsTUFBTSxXQUFXLEdBQUcsT0FBTyxDQUFDO0FBQ25DLE1BQU0sQ0FBQyxNQUFNLGNBQWMsR0FBRyxtQ0FBbUMsQ0FBQztBQUNsRSxNQUFNLENBQUMsTUFBTSxhQUFhLEdBQUcsa0JBQWtCLENBQUM7QUFDaEQsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUFHLGFBQWEsQ0FBQztBQUMxQyxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxnREFBZ0QsQ0FBQztBQUNsRixNQUFNLENBQUMsTUFBTSxlQUFlLEdBQUcsY0FBYyxDQUFDO0FBRTlDLHVDQUF1QztBQUN2QyxNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBRyxHQUFHLENBQUM7QUFHeEMsNEVBQTRFO0FBQzVFLDBFQUEwRTtBQUMxRSw4QkFBOEI7QUFDOUIsTUFBTSxVQUFVLGFBQWEsQ0FDM0IsSUFBOEIsRUFDOUIsS0FBbUMsRUFDbkMsTUFBZSxFQUNmLFFBQWlCO0lBRWpCLE1BQU0sSUFBSSxHQUFHO1FBQ1gsR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO1FBQ3BDLEdBQUcsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO0tBQ3RDLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBQzdDLE1BQU0sT0FBTyxHQUFHLGVBQWUsQ0FBQyxJQUFJLEVBQUUsTUFBTSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lB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Ly8gV2hhdCB0aGUgVmlld3MgcGlja2VyIHNob3dzOiBpdHMgbGFiZWwsIGl0cyBtZW51IGFuZCB0aGUgd29yZHMgb2YgaXRzXG4vLyBwcm9tcHRzLiBQdXJlLCBzbyB0aGUgbm9kZSBoYXJuZXNzIHJ1bnMgZXZlcnkgY2FzZTsgdGhlIHBpY2tlclxuLy8gKFJlcG9ydFZpZXdQaWNrZXJDb21wb25lbnQpIG9ubHkgZHJhd3MgdGhlIHJvd3MgYW5kIHJ1bnMgdGhlIG9uZSBjbGlja2VkLlxuLy9cbi8vIFRoZSBtZW51LCB0b3AgdG8gYm90dG9tOlxuLy8gLSBUaGUgdmlld2VyJ3Mgb3duIHZpZXdzLCB0aGVuIHRoZSB2aWV3cyBvdGhlcnMgc2hhcmUgKGEgcGVvcGxlIGljb24gYW5kXG4vLyAgICdTaGFyZWQgYnkgPG5hbWU+JykuIFRoZSBvcGVuIHZpZXcgaGFzIGEgY2hlY2sgYmVzaWRlIGl0cyBvd24gaWNvbiBhbmRcbi8vICAgY2Fubm90IGJlIHBpY2tlZCBhZ2FpbiB3aGlsZSB0aGUgc2NyZWVuIHN0aWxsIHNob3dzIGl0OyB0aGUgdmlld2VyJ3Ncbi8vICAgZGVmYXVsdCBoYXMgYSBzdGFyLlxuLy8gLSBUaGUgYWN0aW9ucyBvbiB0aGUgb3BlbiB2aWV3LiBTYXZlIGNoYW5nZXMgb25seSB3aGlsZSB0aGUgc2NyZWVuXG4vLyAgIGRpZmZlcnMgZnJvbSBhIHZpZXcgdGhlIHZpZXdlciBtYXkgY2hhbmdlOyBSZW5hbWUgb25seSBvbiBhIHZpZXcgdGhlXG4vLyAgIHZpZXdlciBtYXkgY2hhbmdlOyB0aGUgZGVmYXVsdCBhbmQgc2hhcmluZyByb3dzIG9ubHkgb24gdGhlIHZpZXdlcidzXG4vLyAgIG93biB2aWV3LCBhbmQgc2hhcmluZyBvbmx5IHdoZW4gdGhlIHZpZXdlciBtYXkgc2hhcmU7IERlbGV0ZSBvbmx5IG9uIGFcbi8vICAgdmlldyB0aGUgdmlld2VyIG1heSBkZWxldGUuIFNhdmUgYXMgbmV3IHZpZXcgaXMgYWx3YXlzIHRoZXJlLlxuLy8gLSBSZXNldCB0byB0aGUgb3BlbiB2aWV3IHdoaWxlIHRoZSBzY3JlZW4gZGlmZmVycyBmcm9tIGl0LCBhbmQgUmVzZXQgdG9cbi8vICAgcmVwb3J0IGRlZmF1bHRzLlxuaW1wb3J0IHsgUmVwb3J0Vmlld01lbnVJdGVtIH0gZnJvbSAnLi9pbnRlcmZhY2VzL3JlcG9ydC12aWV3LW1lbnUtaXRlbS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgUmVwb3J0Vmlld1N1bW1hcnkgfSBmcm9tICcuL2ludGVyZmFjZXMvcmVwb3J0LXZpZXctc3VtbWFyeS5pbnRlcmZhY2UnO1xuXG5cbmV4cG9ydCBjb25zdCBWSUVXU19MQUJFTCA9ICdWaWV3cyc7XG5leHBvcnQgY29uc3QgRURJVEVEX1RPT0xUSVAgPSAnVGhlIHNjcmVlbiBkaWZmZXJzIGZyb20gdGhpcyB2aWV3JztcbmV4cG9ydCBjb25zdCBTQVZFX0FTX1RJVExFID0gJ1NhdmUgYXMgbmV3IHZpZXcnO1xuZXhwb3J0IGNvbnN0IFJFTkFNRV9USVRMRSA9ICdSZW5hbWUgdmlldyc7XG5leHBvcnQgY29uc3QgQ1JPU1NfRklMVEVSX05PVEUgPSAnQ3Jvc3MtZmlsdGVycyBhcmUgdGVtcG9yYXJ5IGFuZCBhcmUgbm90IHNhdmVkLic7XG5leHBvcnQgY29uc3QgVklFV19OQU1FX0JMQU5LID0gJ0VudGVyIGEgbmFtZSc7XG5cbi8vIFRoZSBzZXJ2ZXIncyBsaW1pdCBvbiBhIHZpZXcncyBuYW1lLlxuZXhwb3J0IGNvbnN0IFZJRVdfTkFNRV9NQVhfTEVOR1RIID0gMTAwO1xuXG5cbi8vIFRoZSBtZW51IGZvciB0aGUgb3BlbiB2aWV3IChudWxsIHdoZW4gbm9uZSBpcyBvcGVuKSwgdGhlIHZpZXdzIHRoZSB2aWV3ZXJcbi8vIG1heSBzZWUsIHdoZXRoZXIgdGhlIHNjcmVlbiBkaWZmZXJzIGZyb20gdGhlIG9wZW4gdmlldywgYW5kIHdoZXRoZXIgdGhlXG4vLyB2aWV3ZXIgbWF5IHNoYXJlIGl0cyB2aWV3cy5cbmV4cG9ydCBmdW5jdGlvbiB2aWV3TWVudUl0ZW1zKFxuICBvcGVuOiBSZXBvcnRWaWV3U3VtbWFyeSB8IG51bGwsXG4gIHZpZXdzOiByZWFkb25seSBSZXBvcnRWaWV3U3VtbWFyeVtdLFxuICBlZGl0ZWQ6IGJvb2xlYW4sXG4gIGNhblNoYXJlOiBib29sZWFuLFxuKTogUmVwb3J0Vmlld01lbnVJdGVtW10ge1xuICBjb25zdCByb3dzID0gW1xuICAgIC4uLnZpZXdzLmZpbHRlcigodmlldykgPT4gdmlldy5taW5lKSxcbiAgICAuLi52aWV3cy5maWx0ZXIoKHZpZXcpID0+ICF2aWV3Lm1pbmUpLFxuICBdLm1hcCgodmlldykgPT4gdmlld1Jvdyh2aWV3LCBvcGVuLCBlZGl0ZWQpKTtcbiAgY29uc3QgYWN0aW9ucyA9IG9wZW5WaWV3QWN0aW9ucyhvcGVuLCBlZGl0ZWQsIGNhblNoYXJlKTtcbiAgY29uc3QgcmVzZXRzOiBSZXBvcnRWaWV3TWVudUl0ZW1bXSA9IFtcbiAgICAuLi4ob3BlbiAmJiBlZGl0ZWQgPyBbYWN0aW9uKCdyZXNldFRvVmlldycsIGBSZXNldCB0byBcIiR7b3Blbi5uYW1lfVwiYCldIDogW10pLFxuICAgIGFjdGlvbigncmVzZXRUb0RlZmF1bHRzJywgJ1Jlc2V0IHRvIHJlcG9ydCBkZWZhdWx0cycpLFxuICBdO1xuXG4gIHJldHVybiBbXG4gICAgLi4ucm93cyxcbiAgICAuLi53aXRoRGl2aWRlcihhY3Rpb25zLCByb3dzLmxlbmd0aCA+IDApLFxuICAgIC4uLndpdGhEaXZpZGVyKHJlc2V0cywgdHJ1ZSksXG4gIF07XG59XG5cbi8vIFRoZSBwaWNrZXIncyBsYWJlbDogJ1ZpZXdzJywgb3IgdGhlIG9wZW4gdmlldydzIG5hbWUsIG1hcmtlZCB3aGlsZSB0aGVcbi8vIHNjcmVlbiBkaWZmZXJzIGZyb20gaXQuXG5leHBvcnQgZnVuY3Rpb24gcGlja2VyTGFiZWwob3BlbjogUGljazxSZXBvcnRWaWV3U3VtbWFyeSwgJ25hbWUnPiB8IG51bGwsIGVkaXRlZDogYm9vbGVhbik6IHN0cmluZyB7XG4gIGlmICghb3Blbikge1xuICAgIHJldHVybiBWSUVXU19MQUJFTDtcbiAgfVxuXG4gIHJldHVybiBlZGl0ZWQgPyBgJHtvcGVuLm5hbWV9IChlZGl0ZWQpYCA6IG9wZW4ubmFtZTtcbn1cblxuLy8gVGhlIHBpY2tlcidzIHRvb2x0aXA6IG9ubHkgd2hpbGUgdGhlIHNjcmVlbiBkaWZmZXJzIGZyb20gdGhlIG9wZW4gdmlldy5cbmV4cG9ydCBmdW5jdGlvbiBwaWNrZXJUb29sdGlwKG9wZW46IFBpY2s8UmVwb3J0Vmlld1N1bW1hcnksICduYW1lJz4gfCBudWxsLCBlZGl0ZWQ6IGJvb2xlYW4pOiBzdHJpbmcgfCBudWxsIHtcbiAgcmV0dXJuIG9wZW4gJiYgZWRpdGVkID8gRURJVEVEX1RPT0xUSVAgOiBudWxsO1xufVxuXG4vLyBUaGUgcXVlc3Rpb24gYmVmb3JlIGEgdmlldyBpcyBkZWxldGVkLiBBIHNoYXJlZCB2aWV3IHNheXMgdGhhdCBldmVyeW9uZVxuLy8gbG9zZXMgaXQuXG5leHBvcnQgZnVuY3Rpb24gZGVsZXRlUHJvbXB0VGV4dCh2aWV3OiBQaWNrPFJlcG9ydFZpZXdTdW1tYXJ5LCAnbmFtZScgfCAnc2hhcmVkJz4pOiBzdHJpbmcge1xuICBjb25zdCBxdWVzdGlvbiA9IGBEZWxldGUgdGhlIHZpZXcgXCIke3ZpZXcubmFtZX1cIj9gO1xuXG4gIHJldHVybiB2aWV3LnNoYXJlZCA/IGAke3F1ZXN0aW9ufSBFdmVyeW9uZSBpdCBpcyBzaGFyZWQgd2l0aCBsb3NlcyBpdC5gIDogcXVlc3Rpb247XG59XG5cbi8vIFRoZSBsaW5lIHRoZSBzYXZlIGRpYWxvZyBzaG93cyB1bmRlciB0aGUgbmFtZSwgb3IgbnVsbDogYSBjcm9zcy1maWx0ZXIgaXNcbi8vIG9uLCBhbmQgaXQgZG9lcyBub3QgZ28gaW50byB0aGUgdmlldy5cbmV4cG9ydCBmdW5jdGlvbiBzYXZlRGlhbG9nTm90ZShoYXNDcm9zc0ZpbHRlcjogYm9vbGVhbik6IHN0cmluZyB8IG51bGwge1xuICByZXR1cm4gaGFzQ3Jvc3NGaWx0ZXIgPyBDUk9TU19GSUxURVJfTk9URSA6IG51bGw7XG59XG5cbi8vIEEgbmFtZSBtYWRlIG9mIHNwYWNlcyBvbmx5IGlzIG5vIG5hbWU7IHRoZSBzZXJ2ZXIgdHJpbXMgaXQuXG5leHBvcnQgZnVuY3Rpb24gdmlld05hbWVFcnJvcihuYW1lOiBzdHJpbmcgfCBudWxsIHwgdW5kZWZpbmVkKTogc3RyaW5nIHwgbnVsbCB7XG4gIHJldHVybiAobmFtZSA/PyAnJykudHJpbSgpID8gbnVsbCA6IFZJRVdfTkFNRV9CTEFOSztcbn1cblxuXG5mdW5jdGlvbiB2aWV3Um93KHZpZXc6IFJlcG9ydFZpZXdTdW1tYXJ5LCBvcGVuOiBSZXBvcnRWaWV3U3VtbWFyeSB8IG51bGwsIGVkaXRlZDogYm9vbGVhbik6IFJlcG9ydFZpZXdNZW51SXRlbSB7XG4gIGNvbnN0IGlzT3BlbiA9IHZpZXcuaWQgPT09IG9wZW4/LmlkO1xuXG4gIHJldHVybiB7XG4gICAga2luZDogJ3ZpZXcnLFxuICAgIGxhYmVsOiB2aWV3Lm5hbWUsXG4gICAgZGlzYWJsZWQ6IGlzT3BlbiAmJiAhZWRpdGVkLFxuICAgIHRvb2x0aXA6IHZpZXdUb29sdGlwKHZpZXcpLFxuICAgIGRpdmlkZXI6IGZhbHNlLFxuICAgIHZpZXdJZDogdmlldy5pZCxcbiAgICBvcGVuOiBpc09wZW4sXG4gICAgaWNvbjogdmlld0ljb24odmlldyksXG4gIH07XG59XG5cbi8vIFdobyBzaGFyZWQgYSB2aWV3IG9mIHNvbWVvbmUgZWxzZSdzOyB3aGV0aGVyIG9uZSBvZiB0aGUgdmlld2VyJ3Mgb3duIG9wZW5zXG4vLyBieSBkZWZhdWx0IG9yIGlzIHNoYXJlZC5cbmZ1bmN0aW9uIHZpZXdUb29sdGlwKHZpZXc6IFJlcG9ydFZpZXdTdW1tYXJ5KTogc3RyaW5nIHwgbnVsbCB7XG4gIGlmICghdmlldy5taW5lKSB7XG4gICAgcmV0dXJuIHZpZXcub3duZXJOYW1lID8gYFNoYXJlZCBieSAke3ZpZXcub3duZXJOYW1lfWAgOiAnU2hhcmVkIHdpdGggZXZlcnlvbmUnO1xuICB9XG5cbiAgaWYgKHZpZXcucGVyc29uYWxEZWZhdWx0ICYmIHZpZXcuc2hhcmVkKSB7XG4gICAgcmV0dXJuICdPcGVucyBieSBkZWZhdWx0LCBzaGFyZWQgd2l0aCBldmVyeW9uZSc7XG4gIH1cblxuICBpZiAodmlldy5wZXJzb25hbERlZmF1bHQpIHtcbiAgICByZXR1cm4gJ09wZW5zIGJ5IGRlZmF1bHQnO1xuICB9XG5cbiAgcmV0dXJuIHZpZXcuc2hhcmVkID8gJ1NoYXJlZCB3aXRoIGV2ZXJ5b25lJyA6IG51bGw7XG59XG5cbi8vIFRoZSBvcGVuIHJvdyBrZWVwcyB0aGlzIGljb24gdG9vOyBpdHMgY2hlY2sgaXMgZHJhd24gYmVzaWRlIGl0LlxuZnVuY3Rpb24gdmlld0ljb24odmlldzogUmVwb3J0Vmlld1N1bW1hcnkpOiBSZXBvcnRWaWV3TWVudUl0ZW1bJ2ljb24nXSB7XG4gIGlmICghdmlldy5taW5lKSB7XG4gICAgcmV0dXJuICdwZW9wbGUnO1xuICB9XG5cbiAgcmV0dXJuIHZpZXcucGVyc29uYWxEZWZhdWx0ID8gJ3N0YXInIDogbnVsbDtcbn1cblxuLy8gVGhlIHJvd3MgdGhhdCBhY3Qgb24gdGhlIG9wZW4gdmlldzsgd2l0aCBub25lIG9wZW4sIG9ubHkgU2F2ZSBhcyBuZXcgdmlldy5cbmZ1bmN0aW9uIG9wZW5WaWV3QWN0aW9ucyhvcGVuOiBSZXBvcnRWaWV3U3VtbWFyeSB8IG51bGwsIGVkaXRlZDogYm9vbGVhbiwgY2FuU2hhcmU6IGJvb2xlYW4pOiBSZXBvcnRWaWV3TWVudUl0ZW1bXSB7XG4gIGNvbnN0IGl0ZW1zOiBSZXBvcnRWaWV3TWVudUl0ZW1bXSA9IFtdO1xuXG4gIGlmIChvcGVuPy5jYW5DaGFuZ2UgJiYgZWRpdGVkKSB7XG4gICAgaXRlbXMucHVzaChhY3Rpb24oJ3NhdmVDaGFuZ2VzJywgJ1NhdmUgY2hhbmdlcycpKTtcbiAgfVxuXG4gIGl0ZW1zLnB1c2goYWN0aW9uKCdzYXZlQXNOZXcnLCAnU2F2ZSBhcyBuZXcgdmlldy4uLicpKTtcblxuICBpZiAob3Blbj8uY2FuQ2hhbmdlKSB7XG4gICAgaXRlbXMucHVzaChhY3Rpb24oJ3JlbmFtZScsICdSZW5hbWUuLi4nKSk7XG4gIH1cblxuICBpZiAob3Blbj8ubWluZSkge1xuICAgIGl0ZW1zLnB1c2gob3Blbi5wZXJzb25hbERlZmF1bHRcbiAgICAgID8gYWN0aW9uKCdjbGVhckRlZmF1bHQnLCAnU3RvcCBvcGVuaW5nIGl0IGJ5IGRlZmF1bHQnKVxuICAgICAgOiBhY3Rpb24oJ3NldERlZmF1bHQnLCAnTWFrZSBpdCBteSBkZWZhdWx0JykpO1xuICB9XG5cbiAgaWYgKG9wZW4/Lm1pbmUgJiYgY2FuU2hhcmUpIHtcbiAgICBpdGVtcy5wdXNoKG9wZW4uc2hhcmVkID8gYWN0aW9uKCd1bnNoYXJlJywgJ1N0b3Agc2hhcmluZycpIDogYWN0aW9uKCdzaGFyZScsICdTaGFyZSB3aXRoIGV2ZXJ5b25lJykpO1xuICB9XG5cbiAgaWYgKG9wZW4/LmNhbkRlbGV0ZSkge1xuICAgIGl0ZW1zLnB1c2goYWN0aW9uKCdkZWxldGUnLCAnRGVsZXRlLi4uJykpO1xuICB9XG5cbiAgcmV0dXJuIGl0ZW1zO1xufVxuXG5mdW5jdGlvbiBhY3Rpb24oa2luZDogUmVwb3J0Vmlld01lbnVJdGVtWydraW5kJ10sIGxhYmVsOiBzdHJpbmcpOiBSZXBvcnRWaWV3TWVudUl0ZW0ge1xuICByZXR1cm4geyBraW5kLCBsYWJlbCwgZGlzYWJsZWQ6IGZhbHNlLCB0b29sdGlwOiBudWxsLCBkaXZpZGVyOiBmYWxzZSwgdmlld0lkOiBudWxsLCBvcGVuOiBmYWxzZSwgaWNvbjogbnVsbCB9O1xufVxuXG4vLyBUaGUgc2FtZSByb3dzLCB0aGUgZmlyc3Qgd2l0aCBhIGxpbmUgYWJvdmUgaXQgd2hlbiBgZGl2aWRlcmAgaXMgc2V0LlxuZnVuY3Rpb24gd2l0aERpdmlkZXIoaXRlbXM6IFJlcG9ydFZpZXdNZW51SXRlbVtdLCBkaXZpZGVyOiBib29sZWFuKTogUmVwb3J0Vmlld01lbnVJdGVtW10ge1xuICByZXR1cm4gaXRlbXMubWFwKChpdGVtLCBpbmRleCkgPT4gKGluZGV4ID09PSAwICYmIGRpdmlkZXIgPyB7IC4uLml0ZW0sIGRpdmlkZXI6IHRydWUgfSA6IGl0ZW0pKTtcbn1cbiJdfQ==
@@ -0,0 +1,42 @@
1
+ // The viewer features this viewer implements: the report GET names them
2
+ // (features=<comma list>), and the server assembles the report for exactly
3
+ // these. A feature joins the list in the change that builds its control, never
4
+ // before: the server sends a group only in a shape the viewer says it can show
5
+ // and clear, and a listed feature without its control would get a filter the
6
+ // viewer can neither show nor clear.
7
+ //
8
+ // scopeFilters needs no control of its own: a scope member is an ordinary
9
+ // filter row on its tile. excludeValues is a select's 'Exclude these' row,
10
+ // numberRange its min/max control, matchAny the report bar's Match select,
11
+ // and pageScope shows a page's groups in the report bar of that page.
12
+ // cascadingOptions narrows a select's list by the other filters of its tile
13
+ // (ReportFilterOptionsService). views is the Views picker in the report's
14
+ // header (ReportViewPickerComponent). drill is a time chart's click down, with
15
+ // the tile header's breadcrumb and its menu's Drill up and Back to top as the
16
+ // way back.
17
+ export const VIEWER_FEATURES = [
18
+ 'scopeFilters',
19
+ 'excludeValues',
20
+ 'numberRange',
21
+ 'matchAny',
22
+ 'pageScope',
23
+ 'cascadingOptions',
24
+ 'views',
25
+ 'drill',
26
+ ];
27
+ // The features a report offers on this screen: the ones its server serves
28
+ // (Report.viewerFeatures) that this viewer also implements.
29
+ export function offeredViewerFeatures(served) {
30
+ return (served ?? []).filter((feature) => VIEWER_FEATURES.includes(feature));
31
+ }
32
+ // Whether a select group offers 'Exclude these': the one rule the report bar,
33
+ // the tile headers and the report settings' default row share. The server
34
+ // must serve excludeValues, and no enabled member may bind several columns
35
+ // (multiColumn), since the server cannot leave values out there (an older
36
+ // server sends no multiColumn, and the toggle shows as before).
37
+ export function offersExclude(group, features) {
38
+ return group.type === 'select'
39
+ && !group.multiColumn
40
+ && (features ?? []).includes('excludeValues');
41
+ }
42
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LXZpZXdlci1mZWF0dXJlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy9yZXBvcnQtdmlld2VyLWZlYXR1cmVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUlBLHdFQUF3RTtBQUN4RSwyRUFBMkU7QUFDM0UsK0VBQStFO0FBQy9FLCtFQUErRTtBQUMvRSw2RUFBNkU7QUFDN0UscUNBQXFDO0FBQ3JDLEVBQUU7QUFDRiwwRUFBMEU7QUFDMUUsMkVBQTJFO0FBQzNFLDJFQUEyRTtBQUMzRSxzRUFBc0U7QUFDdEUsNEVBQTRFO0FBQzVFLDBFQUEwRTtBQUMxRSwrRUFBK0U7QUFDL0UsOEVBQThFO0FBQzlFLFlBQVk7QUFDWixNQUFNLENBQUMsTUFBTSxlQUFlLEdBQW1DO0lBQzdELGNBQWM7SUFDZCxlQUFlO0lBQ2YsYUFBYTtJQUNiLFVBQVU7SUFDVixXQUFXO0lBQ1gsa0JBQWtCO0lBQ2xCLE9BQU87SUFDUCxPQUFPO0NBQ1IsQ0FBQztBQUVGLDBFQUEwRTtBQUMxRSw0REFBNEQ7QUFDNUQsTUFBTSxVQUFVLHFCQUFxQixDQUFDLE1BQXlEO0lBQzdGLE9BQU8sQ0FBQyxNQUFNLElBQUksRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQyxlQUFlLENBQUMsUUFBUSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7QUFDL0UsQ0FBQztBQUVELDhFQUE4RTtBQUM5RSwwRUFBMEU7QUFDMUUsMkVBQTJFO0FBQzNFLDBFQUEwRTtBQUMxRSxnRUFBZ0U7QUFDaEUsTUFBTSxVQUFVLGFBQWEsQ0FDM0IsS0FBc0QsRUFDdEQsUUFBMkQ7SUFFM0QsT0FBTyxLQUFLLENBQUMsSUFBSSxLQUFLLFFBQVE7V0FDekIsQ0FBQyxLQUFLLENBQUMsV0FBVztXQUNsQixDQUFDLFFBQVEsSUFBSSxFQUFFLENBQUMsQ0FBQyxRQUFRLENBQUMsZUFBZSxDQUFDLENBQUM7QUFDbEQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFJlcG9ydFZpZXdlckZlYXR1cmUgfSBmcm9tICcuL2ludGVyZmFjZXMvcmVwb3J0LXZpZXdlci1mZWF0dXJlLnR5cGUnO1xuaW1wb3J0IHsgUmVwb3J0RmlsdGVyR3JvdXAgfSBmcm9tICcuL2ludGVyZmFjZXMvcmVwb3J0LmludGVyZmFjZSc7XG5cblxuLy8gVGhlIHZpZXdlciBmZWF0dXJlcyB0aGlzIHZpZXdlciBpbXBsZW1lbnRzOiB0aGUgcmVwb3J0IEdFVCBuYW1lcyB0aGVtXG4vLyAoZmVhdHVyZXM9PGNvbW1hIGxpc3Q+KSwgYW5kIHRoZSBzZXJ2ZXIgYXNzZW1ibGVzIHRoZSByZXBvcnQgZm9yIGV4YWN0bHlcbi8vIHRoZXNlLiBBIGZlYXR1cmUgam9pbnMgdGhlIGxpc3QgaW4gdGhlIGNoYW5nZSB0aGF0IGJ1aWxkcyBpdHMgY29udHJvbCwgbmV2ZXJcbi8vIGJlZm9yZTogdGhlIHNlcnZlciBzZW5kcyBhIGdyb3VwIG9ubHkgaW4gYSBzaGFwZSB0aGUgdmlld2VyIHNheXMgaXQgY2FuIHNob3dcbi8vIGFuZCBjbGVhciwgYW5kIGEgbGlzdGVkIGZlYXR1cmUgd2l0aG91dCBpdHMgY29udHJvbCB3b3VsZCBnZXQgYSBmaWx0ZXIgdGhlXG4vLyB2aWV3ZXIgY2FuIG5laXRoZXIgc2hvdyBub3IgY2xlYXIuXG4vL1xuLy8gc2NvcGVGaWx0ZXJzIG5lZWRzIG5vIGNvbnRyb2wgb2YgaXRzIG93bjogYSBzY29wZSBtZW1iZXIgaXMgYW4gb3JkaW5hcnlcbi8vIGZpbHRlciByb3cgb24gaXRzIHRpbGUuIGV4Y2x1ZGVWYWx1ZXMgaXMgYSBzZWxlY3QncyAnRXhjbHVkZSB0aGVzZScgcm93LFxuLy8gbnVtYmVyUmFuZ2UgaXRzIG1pbi9tYXggY29udHJvbCwgbWF0Y2hBbnkgdGhlIHJlcG9ydCBiYXIncyBNYXRjaCBzZWxlY3QsXG4vLyBhbmQgcGFnZVNjb3BlIHNob3dzIGEgcGFnZSdzIGdyb3VwcyBpbiB0aGUgcmVwb3J0IGJhciBvZiB0aGF0IHBhZ2UuXG4vLyBjYXNjYWRpbmdPcHRpb25zIG5hcnJvd3MgYSBzZWxlY3QncyBsaXN0IGJ5IHRoZSBvdGhlciBmaWx0ZXJzIG9mIGl0cyB0aWxlXG4vLyAoUmVwb3J0RmlsdGVyT3B0aW9uc1NlcnZpY2UpLiB2aWV3cyBpcyB0aGUgVmlld3MgcGlja2VyIGluIHRoZSByZXBvcnQnc1xuLy8gaGVhZGVyIChSZXBvcnRWaWV3UGlja2VyQ29tcG9uZW50KS4gZHJpbGwgaXMgYSB0aW1lIGNoYXJ0J3MgY2xpY2sgZG93biwgd2l0aFxuLy8gdGhlIHRpbGUgaGVhZGVyJ3MgYnJlYWRjcnVtYiBhbmQgaXRzIG1lbnUncyBEcmlsbCB1cCBhbmQgQmFjayB0byB0b3AgYXMgdGhlXG4vLyB3YXkgYmFjay5cbmV4cG9ydCBjb25zdCBWSUVXRVJfRkVBVFVSRVM6IHJlYWRvbmx5IFJlcG9ydFZpZXdlckZlYXR1cmVbXSA9IFtcbiAgJ3Njb3BlRmlsdGVycycsXG4gICdleGNsdWRlVmFsdWVzJyxcbiAgJ251bWJlclJhbmdlJyxcbiAgJ21hdGNoQW55JyxcbiAgJ3BhZ2VTY29wZScsXG4gICdjYXNjYWRpbmdPcHRpb25zJyxcbiAgJ3ZpZXdzJyxcbiAgJ2RyaWxsJyxcbl07XG5cbi8vIFRoZSBmZWF0dXJlcyBhIHJlcG9ydCBvZmZlcnMgb24gdGhpcyBzY3JlZW46IHRoZSBvbmVzIGl0cyBzZXJ2ZXIgc2VydmVzXG4vLyAoUmVwb3J0LnZpZXdlckZlYXR1cmVzKSB0aGF0IHRoaXMgdmlld2VyIGFsc28gaW1wbGVtZW50cy5cbmV4cG9ydCBmdW5jdGlvbiBvZmZlcmVkVmlld2VyRmVhdHVyZXMoc2VydmVkOiByZWFkb25seSBSZXBvcnRWaWV3ZXJGZWF0dXJlW10gfCBudWxsIHwgdW5kZWZpbmVkKTogUmVwb3J0Vmlld2VyRmVhdHVyZVtdIHtcbiAgcmV0dXJuIChzZXJ2ZWQgPz8gW10pLmZpbHRlcigoZmVhdHVyZSkgPT4gVklFV0VSX0ZFQVRVUkVTLmluY2x1ZGVzKGZlYXR1cmUpKTtcbn1cblxuLy8gV2hldGhlciBhIHNlbGVjdCBncm91cCBvZmZlcnMgJ0V4Y2x1ZGUgdGhlc2UnOiB0aGUgb25lIHJ1bGUgdGhlIHJlcG9ydCBiYXIsXG4vLyB0aGUgdGlsZSBoZWFkZXJzIGFuZCB0aGUgcmVwb3J0IHNldHRpbmdzJyBkZWZhdWx0IHJvdyBzaGFyZS4gVGhlIHNlcnZlclxuLy8gbXVzdCBzZXJ2ZSBleGNsdWRlVmFsdWVzLCBhbmQgbm8gZW5hYmxlZCBtZW1iZXIgbWF5IGJpbmQgc2V2ZXJhbCBjb2x1bW5zXG4vLyAobXVsdGlDb2x1bW4pLCBzaW5jZSB0aGUgc2VydmVyIGNhbm5vdCBsZWF2ZSB2YWx1ZXMgb3V0IHRoZXJlIChhbiBvbGRlclxuLy8gc2VydmVyIHNlbmRzIG5vIG11bHRpQ29sdW1uLCBhbmQgdGhlIHRvZ2dsZSBzaG93cyBhcyBiZWZvcmUpLlxuZXhwb3J0IGZ1bmN0aW9uIG9mZmVyc0V4Y2x1ZGUoXG4gIGdyb3VwOiBQaWNrPFJlcG9ydEZpbHRlckdyb3VwLCAndHlwZScgfCAnbXVsdGlDb2x1bW4nPixcbiAgZmVhdHVyZXM6IHJlYWRvbmx5IFJlcG9ydFZpZXdlckZlYXR1cmVbXSB8IG51bGwgfCB1bmRlZmluZWQsXG4pOiBib29sZWFuIHtcbiAgcmV0dXJuIGdyb3VwLnR5cGUgPT09ICdzZWxlY3QnXG4gICAgJiYgIWdyb3VwLm11bHRpQ29sdW1uXG4gICAgJiYgKGZlYXR1cmVzID8/IFtdKS5pbmNsdWRlcygnZXhjbHVkZVZhbHVlcycpO1xufVxuIl19
@@ -0,0 +1,238 @@
1
+ import { DestroyRef, Injectable, inject } from '@angular/core';
2
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
3
+ import { Subject, defer, of } from 'rxjs';
4
+ import { catchError, filter, map, shareReplay, switchMap, take, tap } from 'rxjs/operators';
5
+ import { ReportData } from '../data/report.data';
6
+ import { isMatchAnyGroup } from '../report-filter-items';
7
+ import { tileDataState, tilePageId, valuesMatchAnyGroupIds } from '../tile-data-state';
8
+ import { reportComponents } from '../values';
9
+ import { ReportFilterStateService } from './report-filter-state.service';
10
+ import * as i0 from "@angular/core";
11
+ // The most picks one request asks names for: the server's option cap.
12
+ const SELECTED_CAP = 500;
13
+ // The options a select group's control offers. When the server serves
14
+ // cascadingOptions, a group's list is narrowed by the other entries of its
15
+ // host tile (the narrowed options POST); otherwise it is the full list (the
16
+ // options GET), fetched once per group while its host stays the same. The
17
+ // host is the member whose list the group shows (optionsHost).
18
+ //
19
+ // A list is replayed while its request's signature holds: the host's entries
20
+ // without the group's own, without a cross-filter entry and, while the
21
+ // groups match 'any', without the other groups this one combines with. A new
22
+ // signature fetches again, and a request still in flight for an older one is
23
+ // dropped (switchMap). fs-filter asks on focus and on each keystroke, so a
24
+ // list is fetched on the first of them after a change and replayed for the
25
+ // rest; typing filters the replayed list in the viewer (matchOptions).
26
+ //
27
+ // Every list and every 'selected' answer teaches label() the names of the
28
+ // values it holds, so a pick the narrowed list leaves out keeps its name.
29
+ //
30
+ // Each load of the report (the first, and every reload after a chat or
31
+ // dialog edit) starts again: no list is replayed and no name is kept from an
32
+ // earlier load, so an edit to a tile's source or to an option's name shows on
33
+ // the next ask, as when every bar build fetched its list.
34
+ export class ReportFilterOptionsService {
35
+ _reportData = inject(ReportData);
36
+ _filterState = inject(ReportFilterStateService);
37
+ _destroyRef = inject(DestroyRef);
38
+ _streams = new Map();
39
+ _labels = new Map();
40
+ // The picks each group has asked names for, so a value the server cannot
41
+ // name (its entity was deleted) is asked for once, not on every keystroke.
42
+ _asked = new Map();
43
+ // The report load the lists and names above belong to (the object init()
44
+ // last read).
45
+ _loaded = null;
46
+ // The options the group's control offers now. Nothing is read or sent
47
+ // until the list is subscribed to, so the signature is the one of the
48
+ // moment the control asks.
49
+ options(group, report) {
50
+ return defer(() => {
51
+ const narrowed = !!report?.viewerFeatures?.includes('cascadingOptions');
52
+ const host = optionsHost(group, narrowed);
53
+ if (!host || !report) {
54
+ return of([]);
55
+ }
56
+ this._syncLoad();
57
+ const stream = this._stream(group.id);
58
+ const seq = this._ask(stream, group, report, host, narrowed);
59
+ return stream.lists$
60
+ .pipe(filter((list) => list.seq >= seq), take(1), map((list) => list.options));
61
+ });
62
+ }
63
+ // The name a value of the group was last listed or labeled with in this
64
+ // load of the report, or null when no list or answer has named it yet.
65
+ label(groupId, value) {
66
+ this._syncLoad();
67
+ return this._labels.get(groupId)?.get(String(value)) ?? null;
68
+ }
69
+ // Whether the group's latest list was cut at 500.
70
+ truncated(groupId) {
71
+ this._syncLoad();
72
+ return this._streams.get(groupId)?.truncated ?? false;
73
+ }
74
+ // Whether the group's latest request failed. Its list is then empty, and
75
+ // the next ask fetches again.
76
+ failed(groupId) {
77
+ this._syncLoad();
78
+ return this._streams.get(groupId)?.failed ?? false;
79
+ }
80
+ // Sends a request when the signature moved, or when a pick has no name
81
+ // yet and was never asked for. Returns the number of the request whose
82
+ // answer the caller takes: the one sent, else the latest.
83
+ _ask(stream, group, report, host, narrowed) {
84
+ const body = narrowed ? this._request(group, report, host) : null;
85
+ // The host member is part of it: a report edit that moves the group's
86
+ // list to another member or column lists again.
87
+ const signature = JSON.stringify([host.id, host.filterColumn, body?.filters ?? null, body?.matchAnyGroupIds ?? []]);
88
+ const unnamed = (body?.selected ?? [])
89
+ .filter((value) => this.label(group.id, value) === null && !this._askedFor(group.id).has(String(value)));
90
+ if (signature === stream.signature && !unnamed.length) {
91
+ return stream.seq;
92
+ }
93
+ unnamed.forEach((value) => this._askedFor(group.id).add(String(value)));
94
+ stream.signature = signature;
95
+ stream.seq += 1;
96
+ stream.requests$.next({ seq: stream.seq, fetch: this._fetch(stream, group.id, report.id, host.id, body) });
97
+ return stream.seq;
98
+ }
99
+ // The narrowed request for the group: what its host tile's data request
100
+ // carries now, minus the entries that must not narrow the group's list.
101
+ _request(group, report, host) {
102
+ const tile = reportComponents(report).find((component) => component.id === host.componentId) ?? null;
103
+ const selected = groupPicks(this._filterState.value(group.id));
104
+ if (!tile) {
105
+ return { filters: [], ...(selected.length ? { selected } : {}) };
106
+ }
107
+ const snapshot = this._filterState.snapshot();
108
+ // A group whose only members are inline values lists through a value,
109
+ // which combines its groups by the tile rule over its own page.
110
+ const matchAnyGroupIds = tile.type === 'value'
111
+ ? valuesMatchAnyGroupIds(report, tilePageId(report, tile, snapshot), snapshot)
112
+ : tileDataState(report, tile, snapshot).matchAnyGroupIds ?? [];
113
+ // Under 'any' another group this one combines with does not limit which
114
+ // of its values can show rows, so the list leaves it out.
115
+ const combined = matchAnyGroupIds.length && isMatchAnyGroup(group, tilePageId(report, tile, snapshot))
116
+ ? matchAnyGroupIds
117
+ : [];
118
+ const groupOf = new Map((tile.filters ?? []).map((member) => [member.id, member.filterGroupId]));
119
+ const filters = this._filterState.resolveForComponent(tile)
120
+ .filter((entry) => {
121
+ const groupId = groupOf.get(entry.filterId) ?? null;
122
+ return !isCrossEntry(entry) && groupId !== group.id && !combined.includes(groupId);
123
+ });
124
+ return {
125
+ filters,
126
+ ...(matchAnyGroupIds.length ? { matchAnyGroupIds } : {}),
127
+ ...(selected.length ? { selected } : {}),
128
+ };
129
+ }
130
+ // One request's answer as a list. A failed request answers an empty list
131
+ // marked failed, and clears the signature, so the next ask fetches again.
132
+ _fetch(stream, groupId, reportId, filterId, body) {
133
+ const seq = stream.seq;
134
+ // An answer that lands after the report loaded again teaches no name.
135
+ const loaded = this._filterState.report();
136
+ const answer$ = body
137
+ ? this._reportData.filterOptionsNarrowed(reportId, filterId, body)
138
+ : this._reportData.filterOptions(reportId, filterId)
139
+ .pipe(map((options) => ({ options, truncated: false, narrowedBy: [], selected: [] })));
140
+ return answer$
141
+ .pipe(tap((answer) => {
142
+ if (this._filterState.report() === loaded) {
143
+ this._remember(groupId, [...(answer?.options ?? []), ...(answer?.selected ?? [])]);
144
+ }
145
+ }), map((answer) => ({
146
+ seq,
147
+ truncated: !!answer?.truncated,
148
+ failed: false,
149
+ options: (answer?.options ?? []).map((option) => ({ name: option.label, value: option.value })),
150
+ })), catchError(() => {
151
+ stream.signature = null;
152
+ return of({ seq, truncated: false, failed: true, options: [] });
153
+ }));
154
+ }
155
+ // The group's stream, opened on its first ask. It is subscribed to here,
156
+ // for the life of the report view, so an answer is kept for the next ask
157
+ // even when the control that asked has moved on. When the view goes, the
158
+ // stream ends: a request still in flight is dropped, whoever still listens.
159
+ _stream(groupId) {
160
+ const existing = this._streams.get(groupId);
161
+ if (existing) {
162
+ return existing;
163
+ }
164
+ const requests$ = new Subject();
165
+ const stream = {
166
+ signature: null,
167
+ seq: 0,
168
+ truncated: false,
169
+ failed: false,
170
+ requests$,
171
+ lists$: requests$
172
+ .pipe(switchMap((request) => request.fetch), tap((list) => {
173
+ stream.truncated = list.truncated;
174
+ stream.failed = list.failed;
175
+ }), takeUntilDestroyed(this._destroyRef), shareReplay({ bufferSize: 1, refCount: false })),
176
+ };
177
+ // Ends with the stream, when the view goes.
178
+ stream.lists$.subscribe();
179
+ this._streams.set(groupId, stream);
180
+ return stream;
181
+ }
182
+ // A new load of the report (init() read another report object) drops what
183
+ // the last load learned: every signature, so each list is fetched again on
184
+ // its next ask, and every name and asked pick.
185
+ _syncLoad() {
186
+ const loaded = this._filterState.report();
187
+ if (loaded === this._loaded) {
188
+ return;
189
+ }
190
+ this._loaded = loaded;
191
+ this._streams.forEach((stream) => {
192
+ stream.signature = null;
193
+ });
194
+ this._labels.clear();
195
+ this._asked.clear();
196
+ }
197
+ _remember(groupId, options) {
198
+ const labels = this._labels.get(groupId) ?? new Map();
199
+ for (const option of options) {
200
+ if (option && typeof option.label === 'string') {
201
+ labels.set(String(option.value), option.label);
202
+ }
203
+ }
204
+ this._labels.set(groupId, labels);
205
+ }
206
+ _askedFor(groupId) {
207
+ const asked = this._asked.get(groupId) ?? new Set();
208
+ this._asked.set(groupId, asked);
209
+ return asked;
210
+ }
211
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportFilterOptionsService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
212
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportFilterOptionsService });
213
+ }
214
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportFilterOptionsService, decorators: [{
215
+ type: Injectable
216
+ }] });
217
+ // The member whose list a group shows. The narrowed POST names the server's
218
+ // host: the first enabled member with options, else the first with options.
219
+ // The options GET keeps its older rule, the first member with options, as
220
+ // loadGroupOptions does, so an older server is asked what it always was.
221
+ function optionsHost(group, narrowed) {
222
+ const members = (group.filters ?? []).filter((member) => member.hasOptions);
223
+ return (narrowed ? members.find((member) => member.enabled) : null) ?? members[0] ?? null;
224
+ }
225
+ // A cross-filter entry rides in the same filters array as the group entries
226
+ // and carries its crossFilterId. It never narrows a list: a click is a
227
+ // temporary look, and the chip of the cross-filter already shows it.
228
+ function isCrossEntry(entry) {
229
+ return 'crossFilterId' in entry;
230
+ }
231
+ // A select group's picks, kept or left out, that a request can name: text
232
+ // and numbers, at most SELECTED_CAP.
233
+ function groupPicks(value) {
234
+ return [...(value?.values ?? []), ...(value?.excludeValues ?? [])]
235
+ .filter((pick) => typeof pick === 'string' || typeof pick === 'number')
236
+ .slice(0, SELECTED_CAP);
237
+ }
238
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LWZpbHRlci1vcHRpb25zLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvYXBwL3JlcG9ydHMvc2VydmljZXMvcmVwb3J0LWZpbHRlci1vcHRpb25zLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQy9ELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRWhFLE9BQU8sRUFBYyxPQUFPLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN0RCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsV0FBVyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFNUYsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBVWpELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN6RCxPQUFPLEVBQUUsYUFBYSxFQUFFLFVBQVUsRUFBRSxzQkFBc0IsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ3ZGLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUU3QyxPQUFPLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQzs7QUFHekUsc0VBQXNFO0FBQ3RFLE1BQU0sWUFBWSxHQUFHLEdBQUcsQ0FBQztBQUV6QixzRUFBc0U7QUFDdEUsMkVBQTJFO0FBQzNFLDRFQUE0RTtBQUM1RSwwRUFBMEU7QUFDMUUsK0RBQStEO0FBQy9ELEVBQUU7QUFDRiw2RUFBNkU7QUFDN0UsdUVBQXVFO0FBQ3ZFLDZFQUE2RTtBQUM3RSw2RUFBNkU7QUFDN0UsMkVBQTJFO0FBQzNFLDJFQUEyRTtBQUMzRSx1RUFBdUU7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QUUsQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUM7QUFDNUYsQ0FBQztBQUVELDRFQUE0RTtBQUM1RSx1RUFBdUU7QUFDdkUscUVBQXFFO0FBQ3JFLFNBQVMsWUFBWSxDQUFDLEtBQTBCO0lBQzlDLE9BQU8sZUFBZSxJQUFJLEtBQUssQ0FBQztBQUNsQyxDQUFDO0FBRUQsMEVBQTBFO0FBQzFFLHFDQUFxQztBQUNyQyxTQUFTLFVBQVUsQ0FBQyxLQUFtQztJQUNyRCxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxNQUFNLElBQUksRUFBRSxDQUFDLEVBQUUsR0FBRyxDQUFDLEtBQUssRUFBRSxhQUFhLElBQUksRUFBRSxDQUFDLENBQUM7U0FDL0QsTUFBTSxDQUFDLENBQUMsSUFBSSxFQUEyQixFQUFFLENBQUMsT0FBTyxJQUFJLEtBQUssUUFBUSxJQUFJLE9BQU8sSUFBSSxLQUFLLFFBQVEsQ0FBQztTQUMvRixLQUFLLENBQUMsQ0FBQyxFQUFFLFlBQVksQ0FBQyxDQUFDO0FBQzVCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEZXN0cm95UmVmLCBJbmplY3RhYmxlLCBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcblxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgU3ViamVjdCwgZGVmZXIsIG9mIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBjYXRjaEVycm9yLCBmaWx0ZXIsIG1hcCwgc2hhcmVSZXBsYXksIHN3aXRjaE1hcCwgdGFrZSwgdGFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQgeyBSZXBvcnREYXRhIH0gZnJvbSAnLi4vZGF0YS9yZXBvcnQuZGF0YSc7XG5pbXBvcnQgeyBSZXBvcnRGaWx0ZXJPcHRpb25QYWlyIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZXBvcnQtZmlsdGVyLW9wdGlvbi1wYWlyLmludGVyZmFjZSc7XG5pbXBvcnQgeyBSZXBvcnRGaWx0ZXJPcHRpb25zQXNrIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZXBvcnQtZmlsdGVyLW9wdGlvbnMtYXNrLmludGVyZmFjZSc7XG5pbXBvcnQgeyBSZXBvcnRGaWx0ZXJPcHRpb25zTGlzdCB9IGZyb20gJy4uL2ludGVyZmFjZXMvcmVwb3J0LWZpbHRlci1vcHRpb25zLWxpc3QuaW50ZXJmYWNlJztcbmltcG9ydCB7IFJlcG9ydEZpbHRlck9wdGlvbnNSZXF1ZXN0IH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZXBvcnQtZmlsdGVyLW9wdGlvbnMtcmVxdWVzdC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgUmVwb3J0RmlsdGVyT3B0aW9uc1N0cmVhbSB9IGZyb20gJy4uL2ludGVyZmFjZXMvcmVwb3J0LWZpbHRlci1vcHRpb25zLXN0cmVhbS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgUmVwb3J0RmlsdGVyT3B0aW9ucyB9IGZyb20gJy4uL2ludGVyZmFjZXMvcmVwb3J0LWZpbHRlci1vcHRpb25zLmludGVyZmFjZSc7XG5pbXBvcnQge1xuICBGaWx0ZXJHcm91cFZhbHVlLCBSZXBvcnQsIFJlcG9ydEZpbHRlciwgUmVwb3J0RmlsdGVyR3JvdXAsIFJlcG9ydEZpbHRlck9wdGlvbiwgUmVzb2x2ZWRGaWx0ZXJWYWx1ZSxcbn0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZXBvcnQuaW50ZXJmYWNlJztcbmltcG9ydCB7IGlzTWF0Y2hBbnlHcm91cCB9IGZyb20gJy4uL3JlcG9ydC1maWx0ZXItaXRlbXMnO1xuaW1wb3J0IHsgdGlsZURhdGFTdGF0ZSwgdGlsZVBhZ2VJZCwgdmFsdWVzTWF0Y2hBbnlHcm91cElkcyB9IGZyb20gJy4uL3RpbGUtZGF0YS1zdGF0ZSc7XG5pbXBvcnQgeyByZXBvcnRDb21wb25lbnRzIH0gZnJvbSAnLi4vdmFsdWVzJztcblxuaW1wb3J0IHsgUmVwb3J0RmlsdGVyU3RhdGVTZXJ2aWNlIH0gZnJvbSAnLi9yZXBvcnQtZmlsdGVyLXN0YXRlLnNlcnZpY2UnO1xuXG5cbi8vIFRoZSBtb3N0IHBpY2tzIG9uZSByZXF1ZXN0IGFza3MgbmFtZXMgZm9yOiB0aGUgc2VydmVyJ3Mgb3B0aW9uIGNhcC5cbmNvbnN0IFNFTEVDVEVEX0NBUCA9IDUwMDtcblxuLy8gVGhlIG9wdGlvbnMgYSBzZWxlY3QgZ3JvdXAncyBjb250cm9sIG9mZmVycy4gV2hlbiB0aGUgc2VydmVyIHNlcnZlc1xuLy8gY2FzY2FkaW5nT3B0aW9ucywgYSBncm91cCdzIGxpc3QgaXMgbmFycm93ZWQgYnkgdGhlIG90aGVyIGVudHJpZXMgb2YgaXRzXG4vLyBob3N0IHRpbGUgKHRoZSBuYXJyb3dlZCBvcHRpb25zIFBPU1QpOyBvdGhlcndpc2UgaXQgaXMgdGhlIGZ1bGwgbGlzdCAodGhlXG4vLyBvcHRpb25zIEdFVCksIGZldGNoZWQgb25jZSBwZXIgZ3JvdXAgd2hpbGUgaXRzIGhvc3Qgc3RheXMgdGhlIHNhbWUuIFRoZVxuLy8gaG9zdCBpcyB0aGUgbWVtYmVyIHdob3NlIGxpc3QgdGhlIGdyb3VwIHNob3dzIChvcHRpb25zSG9zdCkuXG4vL1xuLy8gQSBsaXN0IGlzIHJlcGxheWVkIHdoaWxlIGl0cyByZXF1ZXN0J3Mgc2lnbmF0dXJlIGhvbGRzOiB0aGUgaG9zdCdzIGVudHJpZXNcbi8vIHdpdGhvdXQgdGhlIGdyb3VwJ3Mgb3duLCB3aXRob3V0IGEgY3Jvc3MtZmlsdGVyIGVudHJ5IGFuZCwgd2hpbGUgdGhlXG4vLyBncm91cHMgbWF0Y2ggJ2FueScsIHdpdGhvdXQgdGhlIG90aGVyIGdyb3VwcyB0aGlzIG9uZSBjb21iaW5lcyB3aXRoLiBBIG5ld1xuLy8gc2lnbmF0dXJlIGZldGNoZXMgYWdhaW4sIGFuZCBhIHJlcXVlc3Qgc3RpbGwgaW4gZmxpZ2h0IGZvciBhbiBvbGRlciBvbmUgaXNcbi8vIGRyb3BwZWQgKHN3aXRjaE1hcCkuIGZzLWZpbHRlciBhc2tzIG9uIGZvY3VzIGFuZCBvbiBlYWNoIGtleXN0cm9rZSwgc28gYVxuLy8gbGlzdCBpcyBmZXRjaGVkIG9uIHRoZSBmaXJzdCBvZiB0aGVtIGFmdGVyIGEgY2hhbmdlIGFuZCByZXBsYXllZCBmb3IgdGhlXG4vLyByZXN0OyB0eXBpbmcgZmlsdGVycyB0aGUgcmVwbGF5ZWQgbGlzdCBpbiB0aGUgdmlld2VyIChtYXRjaE9wdGlvbnMpLlxuLy9cbi8vIEV2ZXJ5IGxpc3QgYW5kIGV2ZXJ5ICdzZWxlY3RlZCcgYW5zd2VyIHRlYWNoZXMgbGFiZWwoKSB0aGUgbmFtZXMgb2YgdGhlXG4vLyB2YWx1ZXMgaXQgaG9sZHMsIHNvIGEgcGljayB0aGUgbmFycm93ZWQgbGlzdCBsZWF2ZXMgb3V0IGtlZXBzIGl0cyBuYW1lLlxuLy9cbi8vIEVhY2ggbG9hZCBvZiB0aGUgcmVwb3J0ICh0aGUgZmlyc3QsIGFuZCBldmVyeSByZWxvYWQgYWZ0ZXIgYSBjaGF0IG9yXG4vLyBkaWFsb2cgZWRpdCkgc3RhcnRzIGFnYWluOiBubyBsaXN0IGlzIHJlcGxheWVkIGFuZCBubyBuYW1lIGlzIGtlcHQgZnJvbSBhblxuLy8gZWFybGllciBsb2FkLCBzbyBhbiBlZGl0IHRvIGEgdGlsZSdzIHNvdXJjZSBvciB0byBhbiBvcHRpb24ncyBuYW1lIHNob3dzIG9uXG4vLyB0aGUgbmV4dCBhc2ssIGFzIHdoZW4gZXZlcnkgYmFyIGJ1aWxkIGZldGNoZWQgaXRzIGxpc3QuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgUmVwb3J0RmlsdGVyT3B0aW9uc1NlcnZpY2Uge1xuXG4gIHByaXZhdGUgX3JlcG9ydERhdGEgPSBpbmplY3QoUmVwb3J0RGF0YSk7XG4gIHByaXZhdGUgX2ZpbHRlclN0YXRlID0gaW5qZWN0KFJlcG9ydEZpbHRlclN0YXRlU2VydmljZSk7XG4gIHByaXZhdGUgX2Rlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZik7XG4gIHByaXZhdGUgX3N0cmVhbXMgPSBuZXcgTWFwPG51bWJlciwgUmVwb3J0RmlsdGVyT3B0aW9uc1N0cmVhbT4oKTtcbiAgcHJpdmF0ZSBfbGFiZWxzID0gbmV3IE1hcDxudW1iZXIsIE1hcDxzdHJpbmcsIHN0cmluZz4+KCk7XG4gIC8vIFRoZSBwaWNrcyBlYWNoIGdyb3VwIGhhcyBhc2tlZCBuYW1lcyBmb3IsIHNvIGEgdmFsdWUgdGhlIHNlcnZlciBjYW5ub3RcbiAgLy8gbmFtZSAoaXRzIGVudGl0eSB3YXMgZGVsZXRlZCkgaXMgYXNrZWQgZm9yIG9uY2UsIG5vdCBvbiBldmVyeSBrZXlzdHJva2UuXG4gIHByaXZhdGUgX2Fza2VkID0gbmV3IE1hcDxudW1iZXIsIFNldDxzdHJpbmc+PigpO1xuICAvLyBUaGUgcmVwb3J0IGxvYWQgdGhlIGxpc3RzIGFuZCBuYW1lcyBhYm92ZSBiZWxvbmcgdG8gKHRoZSBvYmplY3QgaW5pdCgpXG4gIC8vIGxhc3QgcmVhZCkuXG4gIHByaXZhdGUgX2xvYWRlZDogUmVwb3J0IHwgbnVsbCA9IG51bGw7XG5cbiAgLy8gVGhlIG9wdGlvbnMgdGhlIGdyb3VwJ3MgY29udHJvbCBvZmZlcnMgbm93LiBOb3RoaW5nIGlzIHJlYWQgb3Igc2VudFxuICAvLyB1bnRpbCB0aGUgbGlzdCBpcyBzdWJzY3JpYmVkIHRvLCBzbyB0aGUgc2lnbmF0dXJlIGlzIHRoZSBvbmUgb2YgdGhlXG4gIC8vIG1vbWVudCB0aGUgY29udHJvbCBhc2tzLlxuICBwdWJsaWMgb3B0aW9ucyhncm91cDogUmVwb3J0RmlsdGVyR3JvdXAsIHJlcG9ydDogUmVwb3J0IHwgbnVsbCk6IE9ic2VydmFibGU8UmVwb3J0RmlsdGVyT3B0aW9uUGFpcltdPiB7XG4gICAgcmV0dXJuIGRlZmVyKCgpID0+IHtcbiAgICAgIGNvbnN0IG5hcnJvd2VkID0gISFyZXBvcnQ/LnZpZXdlckZlYXR1cmVzPy5pbmNsdWRlcygnY2FzY2FkaW5nT3B0aW9ucycpO1xuICAgICAgY29uc3QgaG9zdCA9IG9wdGlvbnNIb3N0KGdyb3VwLCBuYXJyb3dlZCk7XG5cbiAgICAgIGlmICghaG9zdCB8fCAhcmVwb3J0KSB7XG4gICAgICAgIHJldHVybiBvZihbXSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX3N5bmNMb2FkKCk7XG4gICAgICBjb25zdCBzdHJlYW0gPSB0aGlzLl9zdHJlYW0oZ3JvdXAuaWQpO1xuICAgICAgY29uc3Qgc2VxID0gdGhpcy5fYXNrKHN0cmVhbSwgZ3JvdXAsIHJlcG9ydCwgaG9zdCwgbmFycm93ZWQpO1xuXG4gICAgICByZXR1cm4gc3RyZWFtLmxpc3RzJFxuICAgICAgICAucGlwZShcbiAgICAgICAgICBmaWx0ZXIoKGxpc3QpID0+IGxpc3Quc2VxID49IHNlcSksXG4gICAgICAgICAgdGFrZSgxKSxcbiAgICAgICAgICBtYXAoKGxpc3QpID0+IGxpc3Qub3B0aW9ucyksXG4gICAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBUaGUgbmFtZSBhIHZhbHVlIG9mIHRoZSBncm91cCB3YXMgbGFzdCBsaXN0ZWQgb3IgbGFiZWxlZCB3aXRoIGluIHRoaXNcbiAgLy8gbG9hZCBvZiB0aGUgcmVwb3J0LCBvciBudWxsIHdoZW4gbm8gbGlzdCBvciBhbnN3ZXIgaGFzIG5hbWVkIGl0IHlldC5cbiAgcHVibGljIGxhYmVsKGdyb3VwSWQ6IG51bWJlciwgdmFsdWU6IHVua25vd24pOiBzdHJpbmcgfCBudWxsIHtcbiAgICB0aGlzLl9zeW5jTG9hZCgpO1xuXG4gICAgcmV0dXJuIHRoaXMuX2xhYmVscy5nZXQoZ3JvdXBJZCk/LmdldChTdHJpbmcodmFsdWUpKSA/PyBudWxsO1xuICB9XG5cbiAgLy8gV2hldGhlciB0aGUgZ3JvdXAncyBsYXRlc3QgbGlzdCB3YXMgY3V0IGF0IDUwMC5cbiAgcHVibGljIHRydW5jYXRlZChncm91cElkOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICB0aGlzLl9zeW5jTG9hZCgpO1xuXG4gICAgcmV0dXJuIHRoaXMuX3N0cmVhbXMuZ2V0KGdyb3VwSWQpPy50cnVuY2F0ZWQgPz8gZmFsc2U7XG4gIH1cblxuICAvLyBXaGV0aGVyIHRoZSBncm91cCdzIGxhdGVzdCByZXF1ZXN0IGZhaWxlZC4gSXRzIGxpc3QgaXMgdGhlbiBlbXB0eSwgYW5kXG4gIC8vIHRoZSBuZXh0IGFzayBmZXRjaGVzIGFnYWluLlxuICBwdWJsaWMgZmFpbGVkKGdyb3VwSWQ6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIHRoaXMuX3N5bmNMb2FkKCk7XG5cbiAgICByZXR1cm4gdGhpcy5fc3RyZWFtcy5nZXQoZ3JvdXBJZCk/LmZhaWxlZCA/PyBmYWxzZTtcbiAgfVxuXG4gIC8vIFNlbmRzIGEgcmVxdWVzdCB3aGVuIHRoZSBzaWduYXR1cmUgbW92ZWQsIG9yIHdoZW4gYSBwaWNrIGhhcyBubyBuYW1lXG4gIC8vIHlldCBhbmQgd2FzIG5ldmVyIGFza2VkIGZvci4gUmV0dXJucyB0aGUgbnVtYmVyIG9mIHRoZSByZXF1ZXN0IHdob3NlXG4gIC8vIGFuc3dlciB0aGUgY2FsbGVyIHRha2VzOiB0aGUgb25lIHNlbnQsIGVsc2UgdGhlIGxhdGVzdC5cbiAgcHJpdmF0ZSBfYXNrKFxuICAgIHN0cmVhbTogUmVwb3J0RmlsdGVyT3B0aW9uc1N0cmVhbSxcbiAgICBncm91cDogUmVwb3J0RmlsdGVyR3JvdXAsXG4gICAgcmVwb3J0OiBSZXBvcnQsXG4gICAgaG9zdDogUmVwb3J0RmlsdGVyLFxuICAgIG5hcnJvd2VkOiBib29sZWFuLFxuICApOiBudW1iZXIge1xuICAgIGNvbnN0IGJvZHkgPSBuYXJyb3dlZCA/IHRoaXMuX3JlcXVlc3QoZ3JvdXAsIHJlcG9ydCwgaG9zdCkgOiBudWxsO1xuICAgIC8vIFRoZSBob3N0IG1lbWJlciBpcyBwYXJ0IG9mIGl0OiBhIHJlcG9ydCBlZGl0IHRoYXQgbW92ZXMgdGhlIGdyb3VwJ3NcbiAgICAvLyBsaXN0IHRvIGFub3RoZXIgbWVtYmVyIG9yIGNvbHVtbiBsaXN0cyBhZ2Fpbi5cbiAgICBjb25zdCBzaWduYXR1cmUgPSBKU09OLnN0cmluZ2lmeShbaG9zdC5pZCwgaG9zdC5maWx0ZXJDb2x1bW4sIGJvZHk/LmZpbHRlcnMgPz8gbnVsbCwgYm9keT8ubWF0Y2hBbnlHcm91cElkcyA/PyBbXV0pO1xuICAgIGNvbnN0IHVubmFtZWQgPSAoYm9keT8uc2VsZWN0ZWQgPz8gW10pXG4gICAgICAuZmlsdGVyKCh2YWx1ZSkgPT4gdGhpcy5sYWJlbChncm91cC5pZCwgdmFsdWUpID09PSBudWxsICYmICF0aGlzLl9hc2tlZEZvcihncm91cC5pZCkuaGFzKFN0cmluZyh2YWx1ZSkpKTtcblxuICAgIGlmIChzaWduYXR1cmUgPT09IHN0cmVhbS5zaWduYXR1cmUgJiYgIXVubmFtZWQubGVuZ3RoKSB7XG4gICAgICByZXR1cm4gc3RyZWFtLnNlcTtcbiAgICB9XG5cbiAgICB1bm5hbWVkLmZvckVhY2goKHZhbHVlKSA9PiB0aGlzLl9hc2tlZEZvcihncm91cC5pZCkuYWRkKFN0cmluZyh2YWx1ZSkpKTtcbiAgICBzdHJlYW0uc2lnbmF0dXJlID0gc2lnbmF0dXJlO1xuICAgIHN0cmVhbS5zZXEgKz0gMTtcbiAgICBzdHJlYW0ucmVxdWVzdHMkLm5leHQoeyBzZXE6IHN0cmVhbS5zZXEsIGZldGNoOiB0aGlzLl9mZXRjaChzdHJlYW0sIGdyb3VwLmlkLCByZXBvcnQuaWQsIGhvc3QuaWQsIGJvZHkpIH0pO1xuXG4gICAgcmV0dXJuIHN0cmVhbS5zZXE7XG4gIH1cblxuICAvLyBUaGUgbmFycm93ZWQgcmVxdWVzdCBmb3IgdGhlIGdyb3VwOiB3aGF0IGl0cyBob3N0IHRpbGUncyBkYXRhIHJlcXVlc3RcbiAgLy8gY2FycmllcyBub3csIG1pbnVzIHRoZSBlbnRyaWVzIHRoYXQgbXVzdCBub3QgbmFycm93IHRoZSBncm91cCdzIGxpc3QuXG4gIHByaXZhdGUgX3JlcXVlc3QoZ3JvdXA6IFJlcG9ydEZpbHRlckdyb3VwLCByZXBvcnQ6IFJlcG9ydCwgaG9zdDogUmVwb3J0RmlsdGVyKTogUmVwb3J0RmlsdGVyT3B0aW9uc1JlcXVlc3Qge1xuICAgIGNvbnN0IHRpbGUgPSByZXBvcnRDb21wb25lbnRzKHJlcG9ydCkuZmluZCgoY29tcG9uZW50KSA9PiBjb21wb25lbnQuaWQgPT09IGhvc3QuY29tcG9uZW50SWQpID8/IG51bGw7XG4gICAgY29uc3Qgc2VsZWN0ZWQgPSBncm91cFBpY2tzKHRoaXMuX2ZpbHRlclN0YXRlLnZhbHVlKGdyb3VwLmlkKSk7XG5cbiAgICBpZiAoIXRpbGUpIHtcbiAgICAgIHJldHVybiB7IGZpbHRlcnM6IFtdLCAuLi4oc2VsZWN0ZWQubGVuZ3RoID8geyBzZWxlY3RlZCB9IDoge30pIH07XG4gICAgfVxuXG4gICAgY29uc3Qgc25hcHNob3QgPSB0aGlzLl9maWx0ZXJTdGF0ZS5zbmFwc2hvdCgpO1xuICAgIC8vIEEgZ3JvdXAgd2hvc2Ugb25seSBtZW1iZXJzIGFyZSBpbmxpbmUgdmFsdWVzIGxpc3RzIHRocm91Z2ggYSB2YWx1ZSxcbiAgICAvLyB3aGljaCBjb21iaW5lcyBpdHMgZ3JvdXBzIGJ5IHRoZSB0aWxlIHJ1bGUgb3ZlciBpdHMgb3duIHBhZ2UuXG4gICAgY29uc3QgbWF0Y2hBbnlHcm91cElkcyA9IHRpbGUudHlwZSA9PT0gJ3ZhbHVlJ1xuICAgICAgPyB2YWx1ZXNNYXRjaEFueUdyb3VwSWRzKHJlcG9ydCwgdGlsZVBhZ2VJZChyZXBvcnQsIHRpbGUsIHNuYXBzaG90KSwgc25hcHNob3QpXG4gICAgICA6IHRpbGVEYXRhU3RhdGUocmVwb3J0LCB0aWxlLCBzbmFwc2hvdCkubWF0Y2hBbnlHcm91cElkcyA/PyBbXTtcbiAgICAvLyBVbmRlciAnYW55JyBhbm90aGVyIGdyb3VwIHRoaXMgb25lIGNvbWJpbmVzIHdpdGggZG9lcyBub3QgbGltaXQgd2hpY2hcbiAgICAvLyBvZiBpdHMgdmFsdWVzIGNhbiBzaG93IHJvd3MsIHNvIHRoZSBsaXN0IGxlYXZlcyBpdCBvdXQuXG4gICAgY29uc3QgY29tYmluZWQgPSBtYXRjaEFueUdyb3VwSWRzLmxlbmd0aCAmJiBpc01hdGNoQW55R3JvdXAoZ3JvdXAsIHRpbGVQYWdlSWQocmVwb3J0LCB0aWxlLCBzbmFwc2hvdCkpXG4gICAgICA/IG1hdGNoQW55R3JvdXBJZHNcbiAgICAgIDogW107XG4gICAgY29uc3QgZ3JvdXBPZiA9IG5ldyBNYXAoKHRpbGUuZmlsdGVycyA/PyBbXSkubWFwKChtZW1iZXIpID0+IFttZW1iZXIuaWQsIG1lbWJlci5maWx0ZXJHcm91cElkXSkpO1xuICAgIGNvbnN0IGZpbHRlcnMgPSB0aGlzLl9maWx0ZXJTdGF0ZS5yZXNvbHZlRm9yQ29tcG9uZW50KHRpbGUpXG4gICAgICAuZmlsdGVyKChlbnRyeSkgPT4ge1xuICAgICAgICBjb25zdCBncm91cElkID0gZ3JvdXBPZi5nZXQoZW50cnkuZmlsdGVySWQpID8/IG51bGw7XG5cbiAgICAgICAgcmV0dXJuICFpc0Nyb3NzRW50cnkoZW50cnkpICYmIGdyb3VwSWQgIT09IGdyb3VwLmlkICYmICFjb21iaW5lZC5pbmNsdWRlcyhncm91cElkKTtcbiAgICAgIH0pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGZpbHRlcnMsXG4gICAgICAuLi4obWF0Y2hBbnlHcm91cElkcy5sZW5ndGggPyB7IG1hdGNoQW55R3JvdXBJZHMgfSA6IHt9KSxcbiAgICAgIC4uLihzZWxlY3RlZC5sZW5ndGggPyB7IHNlbGVjdGVkIH0gOiB7fSksXG4gICAgfTtcbiAgfVxuXG4gIC8vIE9uZSByZXF1ZXN0J3MgYW5zd2VyIGFzIGEgbGlzdC4gQSBmYWlsZWQgcmVxdWVzdCBhbnN3ZXJzIGFuIGVtcHR5IGxpc3RcbiAgLy8gbWFya2VkIGZhaWxlZCwgYW5kIGNsZWFycyB0aGUgc2lnbmF0dXJlLCBzbyB0aGUgbmV4dCBhc2sgZmV0Y2hlcyBhZ2Fpbi5cbiAgcHJpdmF0ZSBfZmV0Y2goXG4gICAgc3RyZWFtOiBSZXBvcnRGaWx0ZXJPcHRpb25zU3RyZWFtLFxuICAgIGdyb3VwSWQ6IG51bWJlcixcbiAgICByZXBvcnRJZDogbnVtYmVyLFxuICAgIGZpbHRlcklkOiBudW1iZXIsXG4gICAgYm9keTogUmVwb3J0RmlsdGVyT3B0aW9uc1JlcXVlc3QgfCBudWxsLFxuICApOiBPYnNlcnZhYmxlPFJlcG9ydEZpbHRlck9wdGlvbnNMaXN0PiB7XG4gICAgY29uc3Qgc2VxID0gc3RyZWFtLnNlcTtcbiAgICAvLyBBbiBhbnN3ZXIgdGhhdCBsYW5kcyBhZnRlciB0aGUgcmVwb3J0IGxvYWRlZCBhZ2FpbiB0ZWFjaGVzIG5vIG5hbWUuXG4gICAgY29uc3QgbG9hZGVkID0gdGhpcy5fZmlsdGVyU3RhdGUucmVwb3J0KCk7XG4gICAgY29uc3QgYW5zd2VyJDogT2JzZXJ2YWJsZTxSZXBvcnRGaWx0ZXJPcHRpb25zPiA9IGJvZHlcbiAgICAgID8gdGhpcy5fcmVwb3J0RGF0YS5maWx0ZXJPcHRpb25zTmFycm93ZWQocmVwb3J0SWQsIGZpbHRlcklkLCBib2R5KVxuICAgICAgOiB0aGlzLl9yZXBvcnREYXRhLmZpbHRlck9wdGlvbnMocmVwb3J0SWQsIGZpbHRlcklkKVxuICAgICAgICAucGlwZShtYXAoKG9wdGlvbnM6IFJlcG9ydEZpbHRlck9wdGlvbltdKSA9PiAoeyBvcHRpb25zLCB0cnVuY2F0ZWQ6IGZhbHNlLCBuYXJyb3dlZEJ5OiBbXSwgc2VsZWN0ZWQ6IFtdIH0pKSk7XG5cbiAgICByZXR1cm4gYW5zd2VyJFxuICAgICAgLnBpcGUoXG4gICAgICAgIHRhcCgoYW5zd2VyKSA9PiB7XG4gICAgICAgICAgaWYgKHRoaXMuX2ZpbHRlclN0YXRlLnJlcG9ydCgpID09PSBsb2FkZWQpIHtcbiAgICAgICAgICAgIHRoaXMuX3JlbWVtYmVyKGdyb3VwSWQsIFsuLi4oYW5zd2VyPy5vcHRpb25zID8/IFtdKSwgLi4uKGFuc3dlcj8uc2VsZWN0ZWQgPz8gW10pXSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KSxcbiAgICAgICAgbWFwKChhbnN3ZXIpID0+ICh7XG4gICAgICAgICAgc2VxLFxuICAgICAgICAgIHRydW5jYXRlZDogISFhbnN3ZXI/LnRydW5jYXRlZCxcbiAgICAgICAgICBmYWlsZWQ6IGZhbHNlLFxuICAgICAgICAgIG9wdGlvbnM6IChhbnN3ZXI/Lm9wdGlvbnMgPz8gW10pLm1hcCgob3B0aW9uKSA9PiAoeyBuYW1lOiBvcHRpb24ubGFiZWwsIHZhbHVlOiBvcHRpb24udmFsdWUgfSkpLFxuICAgICAgICB9KSksXG4gICAgICAgIGNhdGNoRXJyb3IoKCkgPT4ge1xuICAgICAgICAgIHN0cmVhbS5zaWduYXR1cmUgPSBudWxsO1xuXG4gICAgICAgICAgcmV0dXJuIG9mKHsgc2VxLCB0cnVuY2F0ZWQ6IGZhbHNlLCBmYWlsZWQ6IHRydWUsIG9wdGlvbnM6IFtdIH0pO1xuICAgICAgICB9KSxcbiAgICAgICk7XG4gIH1cblxuICAvLyBUaGUgZ3JvdXAncyBzdHJlYW0sIG9wZW5lZCBvbiBpdHMgZmlyc3QgYXNrLiBJdCBpcyBzdWJzY3JpYmVkIHRvIGhlcmUsXG4gIC8vIGZvciB0aGUgbGlmZSBvZiB0aGUgcmVwb3J0IHZpZXcsIHNvIGFuIGFuc3dlciBpcyBrZXB0IGZvciB0aGUgbmV4dCBhc2tcbiAgLy8gZXZlbiB3aGVuIHRoZSBjb250cm9sIHRoYXQgYXNrZWQgaGFzIG1vdmVkIG9uLiBXaGVuIHRoZSB2aWV3IGdvZXMsIHRoZVxuICAvLyBzdHJlYW0gZW5kczogYSByZXF1ZXN0IHN0aWxsIGluIGZsaWdodCBpcyBkcm9wcGVkLCB3aG9ldmVyIHN0aWxsIGxpc3RlbnMuXG4gIHByaXZhdGUgX3N0cmVhbShncm91cElkOiBudW1iZXIpOiBSZXBvcnRGaWx0ZXJPcHRpb25zU3RyZWFtIHtcbiAgICBjb25zdCBleGlzdGluZyA9IHRoaXMuX3N0cmVhbXMuZ2V0KGdyb3VwSWQpO1xuICAgIGlmIChleGlzdGluZykge1xuICAgICAgcmV0dXJuIGV4aXN0aW5nO1xuICAgIH1cblxuICAgIGNvbnN0IHJlcXVlc3RzJCA9IG5ldyBTdWJqZWN0PFJlcG9ydEZpbHRlck9wdGlvbnNBc2s+KCk7XG4gICAgY29uc3Qgc3RyZWFtOiBSZXBvcnRGaWx0ZXJPcHRpb25zU3RyZWFtID0ge1xuICAgICAgc2lnbmF0dXJlOiBudWxsLFxuICAgICAgc2VxOiAwLFxuICAgICAgdHJ1bmNhdGVkOiBmYWxzZSxcbiAgICAgIGZhaWxlZDogZmFsc2UsXG4gICAgICByZXF1ZXN0cyQsXG4gICAgICBsaXN0cyQ6IHJlcXVlc3RzJFxuICAgICAgICAucGlwZShcbiAgICAgICAgICBzd2l0Y2hNYXAoKHJlcXVlc3QpID0+IHJlcXVlc3QuZmV0Y2gpLFxuICAgICAgICAgIHRhcCgobGlzdCkgPT4ge1xuICAgICAgICAgICAgc3RyZWFtLnRydW5jYXRlZCA9IGxpc3QudHJ1bmNhdGVkO1xuICAgICAgICAgICAgc3RyZWFtLmZhaWxlZCA9IGxpc3QuZmFpbGVkO1xuICAgICAgICAgIH0pLFxuICAgICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSxcbiAgICAgICAgICBzaGFyZVJlcGxheSh7IGJ1ZmZlclNpemU6IDEsIHJlZkNvdW50OiBmYWxzZSB9KSxcbiAgICAgICAgKSxcbiAgICB9O1xuXG4gICAgLy8gRW5kcyB3aXRoIHRoZSBzdHJlYW0sIHdoZW4gdGhlIHZpZXcgZ29lcy5cbiAgICBzdHJlYW0ubGlzdHMkLnN1YnNjcmliZSgpO1xuICAgIHRoaXMuX3N0cmVhbXMuc2V0KGdyb3VwSWQsIHN0cmVhbSk7XG5cbiAgICByZXR1cm4gc3RyZWFtO1xuICB9XG5cbiAgLy8gQSBuZXcgbG9hZCBvZiB0aGUgcmVwb3J0IChpbml0KCkgcmVhZCBhbm90aGVyIHJlcG9ydCBvYmplY3QpIGRyb3BzIHdoYXRcbiAgLy8gdGhlIGxhc3QgbG9hZCBsZWFybmVkOiBldmVyeSBzaWduYXR1cmUsIHNvIGVhY2ggbGlzdCBpcyBmZXRjaGVkIGFnYWluIG9uXG4gIC8vIGl0cyBuZXh0IGFzaywgYW5kIGV2ZXJ5IG5hbWUgYW5kIGFza2VkIHBpY2suXG4gIHByaXZhdGUgX3N5bmNMb2FkKCk6IHZvaWQge1xuICAgIGNvbnN0IGxvYWRlZCA9IHRoaXMuX2ZpbHRlclN0YXRlLnJlcG9ydCgpO1xuICAgIGlmIChsb2FkZWQgPT09IHRoaXMuX2xvYWRlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX2xvYWRlZCA9IGxvYWRlZDtcbiAgICB0aGlzLl9zdHJlYW1zLmZvckVhY2goKHN0cmVhbSkgPT4ge1xuICAgICAgc3RyZWFtLnNpZ25hdHVyZSA9IG51bGw7XG4gICAgfSk7XG4gICAgdGhpcy5fbGFiZWxzLmNsZWFyKCk7XG4gICAgdGhpcy5fYXNrZWQuY2xlYXIoKTtcbiAgfVxuXG4gIHByaXZhdGUgX3JlbWVtYmVyKGdyb3VwSWQ6IG51bWJlciwgb3B0aW9uczogUmVwb3J0RmlsdGVyT3B0aW9uW10pOiB2b2lkIHtcbiAgICBjb25zdCBsYWJlbHMgPSB0aGlzLl9sYWJlbHMuZ2V0KGdyb3VwSWQpID8/IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG5cbiAgICBmb3IgKGNvbnN0IG9wdGlvbiBvZiBvcHRpb25zKSB7XG4gICAgICBpZiAob3B0aW9uICYmIHR5cGVvZiBvcHRpb24ubGFiZWwgPT09ICdzdHJpbmcnKSB7XG4gICAgICAgIGxhYmVscy5zZXQoU3RyaW5nKG9wdGlvbi52YWx1ZSksIG9wdGlvbi5sYWJlbCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5fbGFiZWxzLnNldChncm91cElkLCBsYWJlbHMpO1xuICB9XG5cbiAgcHJpdmF0ZSBfYXNrZWRGb3IoZ3JvdXBJZDogbnVtYmVyKTogU2V0PHN0cmluZz4ge1xuICAgIGNvbnN0IGFza2VkID0gdGhpcy5fYXNrZWQuZ2V0KGdyb3VwSWQpID8/IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAgIHRoaXMuX2Fza2VkLnNldChncm91cElkLCBhc2tlZCk7XG5cbiAgICByZXR1cm4gYXNrZWQ7XG4gIH1cbn1cblxuXG4vLyBUaGUgbWVtYmVyIHdob3NlIGxpc3QgYSBncm91cCBzaG93cy4gVGhlIG5hcnJvd2VkIFBPU1QgbmFtZXMgdGhlIHNlcnZlcidzXG4vLyBob3N0OiB0aGUgZmlyc3QgZW5hYmxlZCBtZW1iZXIgd2l0aCBvcHRpb25zLCBlbHNlIHRoZSBmaXJzdCB3aXRoIG9wdGlvbnMuXG4vLyBUaGUgb3B0aW9ucyBHRVQga2VlcHMgaXRzIG9sZGVyIHJ1bGUsIHRoZSBmaXJzdCBtZW1iZXIgd2l0aCBvcHRpb25zLCBhc1xuLy8gbG9hZEdyb3VwT3B0aW9ucyBkb2VzLCBzbyBhbiBvbGRlciBzZXJ2ZXIgaXMgYXNrZWQgd2hhdCBpdCBhbHdheXMgd2FzLlxuZnVuY3Rpb24gb3B0aW9uc0hvc3QoZ3JvdXA6IFJlcG9ydEZpbHRlckdyb3VwLCBuYXJyb3dlZDogYm9vbGVhbik6IFJlcG9ydEZpbHRlciB8IG51bGwge1xuICBjb25zdCBtZW1iZXJzID0gKGdyb3VwLmZpbHRlcnMgPz8gW10pLmZpbHRlcigobWVtYmVyKSA9PiBtZW1iZXIuaGFzT3B0aW9ucyk7XG5cbiAgcmV0dXJuIChuYXJyb3dlZCA/IG1lbWJlcnMuZmluZCgobWVtYmVyKSA9PiBtZW1iZXIuZW5hYmxlZCkgOiBudWxsKSA/PyBtZW1iZXJzWzBdID8/IG51bGw7XG59XG5cbi8vIEEgY3Jvc3MtZmlsdGVyIGVudHJ5IHJpZGVzIGluIHRoZSBzYW1lIGZpbHRlcnMgYXJyYXkgYXMgdGhlIGdyb3VwIGVudHJpZXNcbi8vIGFuZCBjYXJyaWVzIGl0cyBjcm9zc0ZpbHRlcklkLiBJdCBuZXZlciBuYXJyb3dzIGEgbGlzdDogYSBjbGljayBpcyBhXG4vLyB0ZW1wb3JhcnkgbG9vaywgYW5kIHRoZSBjaGlwIG9mIHRoZSBjcm9zcy1maWx0ZXIgYWxyZWFkeSBzaG93cyBpdC5cbmZ1bmN0aW9uIGlzQ3Jvc3NFbnRyeShlbnRyeTogUmVzb2x2ZWRGaWx0ZXJWYWx1ZSk6IGJvb2xlYW4ge1xuICByZXR1cm4gJ2Nyb3NzRmlsdGVySWQnIGluIGVudHJ5O1xufVxuXG4vLyBBIHNlbGVjdCBncm91cCdzIHBpY2tzLCBrZXB0IG9yIGxlZnQgb3V0LCB0aGF0IGEgcmVxdWVzdCBjYW4gbmFtZTogdGV4dFxuLy8gYW5kIG51bWJlcnMsIGF0IG1vc3QgU0VMRUNURURfQ0FQLlxuZnVuY3Rpb24gZ3JvdXBQaWNrcyh2YWx1ZTogRmlsdGVyR3JvdXBWYWx1ZSB8IHVuZGVmaW5lZCk6IChzdHJpbmcgfCBudW1iZXIpW10ge1xuICByZXR1cm4gWy4uLih2YWx1ZT8udmFsdWVzID8/IFtdKSwgLi4uKHZhbHVlPy5leGNsdWRlVmFsdWVzID8/IFtdKV1cbiAgICAuZmlsdGVyKChwaWNrKTogcGljayBpcyBzdHJpbmcgfCBudW1iZXIgPT4gdHlwZW9mIHBpY2sgPT09ICdzdHJpbmcnIHx8IHR5cGVvZiBwaWNrID09PSAnbnVtYmVyJylcbiAgICAuc2xpY2UoMCwgU0VMRUNURURfQ0FQKTtcbn1cbiJdfQ==