@firestitch/report 18.8.1 → 18.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (208) 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/component-text/component-text.component.d.ts +47 -2
  6. package/app/reports/components/component-text/value-embed.plugin.d.ts +67 -0
  7. package/app/reports/components/report-canvas/report-canvas.component.d.ts +37 -9
  8. package/app/reports/components/report-component/report-component.component.d.ts +45 -2
  9. package/app/reports/components/report-view-picker/report-view-picker.component.d.ts +21 -0
  10. package/app/reports/data/report.data.d.ts +18 -2
  11. package/app/reports/dialogs/component-settings/component-settings.component.d.ts +25 -2
  12. package/app/reports/dialogs/report-settings/report-settings.component.d.ts +15 -6
  13. package/app/reports/dialogs/report-view/report-view-dialog.component.d.ts +13 -0
  14. package/app/reports/drill-crumbs.d.ts +12 -0
  15. package/app/reports/enums/report-value-formula.enum.d.ts +6 -0
  16. package/app/reports/export/report-export-collector.service.d.ts +35 -4
  17. package/app/reports/export/report-export.service.d.ts +3 -1
  18. package/app/reports/export/report-filter-lines.d.ts +18 -0
  19. package/app/reports/export/report-pdf.service.d.ts +18 -2
  20. package/app/reports/export/report-pptx.service.d.ts +15 -2
  21. package/app/reports/export/report-text-layout.service.d.ts +35 -0
  22. package/app/reports/filter-settings-rules.d.ts +33 -0
  23. package/app/reports/format.d.ts +2 -1
  24. package/app/reports/interfaces/canvas-landing-input.interface.d.ts +8 -0
  25. package/app/reports/interfaces/component-data-applied.interface.d.ts +13 -0
  26. package/app/reports/interfaces/component-data-drill.interface.d.ts +22 -0
  27. package/app/reports/interfaces/filter-bar-placement.type.d.ts +1 -0
  28. package/app/reports/interfaces/filter-component-toggle-state.interface.d.ts +4 -0
  29. package/app/reports/interfaces/filter-settings-option.interface.d.ts +4 -0
  30. package/app/reports/interfaces/filter-type-select-state.interface.d.ts +5 -0
  31. package/app/reports/interfaces/report-chart-hit.interface.d.ts +5 -0
  32. package/app/reports/interfaces/report-chat-viewer-cross-filter-field.interface.d.ts +4 -0
  33. package/app/reports/interfaces/report-chat-viewer-cross-filter.interface.d.ts +7 -0
  34. package/app/reports/interfaces/report-chat-viewer-detail.interface.d.ts +4 -0
  35. package/app/reports/interfaces/report-chat-viewer-drill-step.interface.d.ts +5 -0
  36. package/app/reports/interfaces/report-chat-viewer-drill.interface.d.ts +5 -0
  37. package/app/reports/interfaces/report-chat-viewer-filter.interface.d.ts +3 -0
  38. package/app/reports/interfaces/report-chat-viewer-selection.interface.d.ts +5 -0
  39. package/app/reports/interfaces/report-chat-viewer-state.interface.d.ts +12 -0
  40. package/app/reports/interfaces/report-drill-crumb.interface.d.ts +6 -0
  41. package/app/reports/interfaces/report-drill-refusal.type.d.ts +1 -0
  42. package/app/reports/interfaces/report-drill-step.interface.d.ts +5 -0
  43. package/app/reports/interfaces/report-export-line-kind.type.d.ts +1 -0
  44. package/app/reports/interfaces/report-export-line.interface.d.ts +8 -0
  45. package/app/reports/interfaces/report-export-lines-input.interface.d.ts +9 -0
  46. package/app/reports/interfaces/report-export-snapshot.interface.d.ts +15 -0
  47. package/app/reports/interfaces/report-filter-line-context.interface.d.ts +8 -0
  48. package/app/reports/interfaces/report-filter-line-form.type.d.ts +1 -0
  49. package/app/reports/interfaces/report-filter-match.type.d.ts +1 -0
  50. package/app/reports/interfaces/report-filter-option-pair.interface.d.ts +4 -0
  51. package/app/reports/interfaces/report-filter-options-ask.interface.d.ts +6 -0
  52. package/app/reports/interfaces/report-filter-options-list.interface.d.ts +7 -0
  53. package/app/reports/interfaces/report-filter-options-request.interface.d.ts +6 -0
  54. package/app/reports/interfaces/report-filter-options-stream.interface.d.ts +11 -0
  55. package/app/reports/interfaces/report-filter-options.interface.d.ts +7 -0
  56. package/app/reports/interfaces/report-filter-skip.type.d.ts +1 -0
  57. package/app/reports/interfaces/report-mark-action.type.d.ts +1 -0
  58. package/app/reports/interfaces/report-mark-click.interface.d.ts +13 -0
  59. package/app/reports/interfaces/report-mark-context.interface.d.ts +6 -0
  60. package/app/reports/interfaces/report-mark-decision.interface.d.ts +6 -0
  61. package/app/reports/interfaces/report-mark-event.interface.d.ts +11 -0
  62. package/app/reports/interfaces/report-mark-point.interface.d.ts +8 -0
  63. package/app/reports/interfaces/report-temporary-state.interface.d.ts +4 -0
  64. package/app/reports/interfaces/report-tile-state.interface.d.ts +8 -0
  65. package/app/reports/interfaces/report-url-link.interface.d.ts +4 -0
  66. package/app/reports/interfaces/report-url-value-name.type.d.ts +1 -0
  67. package/app/reports/interfaces/report-url-write.interface.d.ts +4 -0
  68. package/app/reports/interfaces/report-view-config.interface.d.ts +11 -0
  69. package/app/reports/interfaces/report-view-create.interface.d.ts +7 -0
  70. package/app/reports/interfaces/report-view-deleted.interface.d.ts +4 -0
  71. package/app/reports/interfaces/report-view-dialog-data.interface.d.ts +7 -0
  72. package/app/reports/interfaces/report-view-dropped.interface.d.ts +5 -0
  73. package/app/reports/interfaces/report-view-menu-item.interface.d.ts +10 -0
  74. package/app/reports/interfaces/report-view-summary.interface.d.ts +11 -0
  75. package/app/reports/interfaces/report-view.interface.d.ts +7 -0
  76. package/app/reports/interfaces/report-viewer-feature.type.d.ts +1 -0
  77. package/app/reports/interfaces/report-views.interface.d.ts +7 -0
  78. package/app/reports/interfaces/report.interface.d.ts +48 -5
  79. package/app/reports/interfaces/tile-load-result.interface.d.ts +4 -0
  80. package/app/reports/layout.d.ts +2 -0
  81. package/app/reports/mark-click.d.ts +20 -0
  82. package/app/reports/option-builder.d.ts +12 -1
  83. package/app/reports/report-chat-viewer-state.d.ts +8 -0
  84. package/app/reports/report-date-presets.d.ts +2 -0
  85. package/app/reports/report-filter-items.d.ts +27 -22
  86. package/app/reports/report-tile.d.ts +2 -0
  87. package/app/reports/report-url-state.d.ts +27 -10
  88. package/app/reports/report-view-config.d.ts +36 -0
  89. package/app/reports/report-view-menu.d.ts +15 -0
  90. package/app/reports/report-viewer-features.d.ts +5 -0
  91. package/app/reports/services/report-filter-options.service.d.ts +26 -0
  92. package/app/reports/services/report-filter-state.service.d.ts +65 -2
  93. package/app/reports/services/report-view.service.d.ts +51 -0
  94. package/app/reports/text.d.ts +50 -0
  95. package/app/reports/tile-data-state.d.ts +7 -0
  96. package/app/reports/tile-loads.d.ts +4 -0
  97. package/app/reports/values.d.ts +17 -0
  98. package/app/reports/views/report/fs-ai-report.component.d.ts +9 -1
  99. package/app/reports/views/report/report.component.d.ts +6 -0
  100. package/esm2022/app/reports/anchor-at-point.mjs +49 -0
  101. package/esm2022/app/reports/canvas-landing-page.mjs +25 -0
  102. package/esm2022/app/reports/components/component-chart/component-chart.component.mjs +97 -5
  103. package/esm2022/app/reports/components/component-kpi/component-kpi.component.mjs +11 -4
  104. package/esm2022/app/reports/components/component-list/component-list.component.mjs +7 -1
  105. package/esm2022/app/reports/components/component-text/component-text.component.mjs +213 -16
  106. package/esm2022/app/reports/components/component-text/value-embed.plugin.mjs +484 -0
  107. package/esm2022/app/reports/components/report-canvas/report-canvas.component.mjs +296 -55
  108. package/esm2022/app/reports/components/report-component/report-component.component.mjs +318 -76
  109. package/esm2022/app/reports/components/report-view-picker/report-view-picker.component.mjs +115 -0
  110. package/esm2022/app/reports/data/report.data.mjs +103 -8
  111. package/esm2022/app/reports/dialogs/component-settings/component-settings.component.mjs +210 -44
  112. package/esm2022/app/reports/dialogs/report-settings/report-settings.component.mjs +86 -90
  113. package/esm2022/app/reports/dialogs/report-view/report-view-dialog.component.mjs +52 -0
  114. package/esm2022/app/reports/drill-crumbs.mjs +73 -0
  115. package/esm2022/app/reports/enums/report-value-formula.enum.mjs +14 -0
  116. package/esm2022/app/reports/export/report-export-collector.service.mjs +299 -125
  117. package/esm2022/app/reports/export/report-export.service.mjs +57 -19
  118. package/esm2022/app/reports/export/report-filter-lines.mjs +235 -0
  119. package/esm2022/app/reports/export/report-pdf.service.mjs +315 -71
  120. package/esm2022/app/reports/export/report-pptx.service.mjs +293 -71
  121. package/esm2022/app/reports/export/report-text-layout.service.mjs +241 -0
  122. package/esm2022/app/reports/filter-settings-rules.mjs +283 -0
  123. package/esm2022/app/reports/format.mjs +13 -30
  124. package/esm2022/app/reports/interfaces/canvas-landing-input.interface.mjs +2 -0
  125. package/esm2022/app/reports/interfaces/component-data-applied.interface.mjs +2 -0
  126. package/esm2022/app/reports/interfaces/component-data-drill.interface.mjs +2 -0
  127. package/esm2022/app/reports/interfaces/filter-bar-placement.type.mjs +2 -0
  128. package/esm2022/app/reports/interfaces/filter-component-toggle-state.interface.mjs +2 -0
  129. package/esm2022/app/reports/interfaces/filter-settings-option.interface.mjs +2 -0
  130. package/esm2022/app/reports/interfaces/filter-type-select-state.interface.mjs +2 -0
  131. package/esm2022/app/reports/interfaces/report-chart-hit.interface.mjs +2 -0
  132. package/esm2022/app/reports/interfaces/report-chat-viewer-cross-filter-field.interface.mjs +2 -0
  133. package/esm2022/app/reports/interfaces/report-chat-viewer-cross-filter.interface.mjs +2 -0
  134. package/esm2022/app/reports/interfaces/report-chat-viewer-detail.interface.mjs +2 -0
  135. package/esm2022/app/reports/interfaces/report-chat-viewer-drill-step.interface.mjs +2 -0
  136. package/esm2022/app/reports/interfaces/report-chat-viewer-drill.interface.mjs +2 -0
  137. package/esm2022/app/reports/interfaces/report-chat-viewer-filter.interface.mjs +1 -1
  138. package/esm2022/app/reports/interfaces/report-chat-viewer-selection.interface.mjs +2 -0
  139. package/esm2022/app/reports/interfaces/report-chat-viewer-state.interface.mjs +1 -1
  140. package/esm2022/app/reports/interfaces/report-drill-crumb.interface.mjs +2 -0
  141. package/esm2022/app/reports/interfaces/report-drill-refusal.type.mjs +2 -0
  142. package/esm2022/app/reports/interfaces/report-drill-step.interface.mjs +2 -0
  143. package/esm2022/app/reports/interfaces/report-export-line-kind.type.mjs +2 -0
  144. package/esm2022/app/reports/interfaces/report-export-line.interface.mjs +2 -0
  145. package/esm2022/app/reports/interfaces/report-export-lines-input.interface.mjs +2 -0
  146. package/esm2022/app/reports/interfaces/report-export-snapshot.interface.mjs +2 -0
  147. package/esm2022/app/reports/interfaces/report-filter-line-context.interface.mjs +2 -0
  148. package/esm2022/app/reports/interfaces/report-filter-line-form.type.mjs +2 -0
  149. package/esm2022/app/reports/interfaces/report-filter-match.type.mjs +2 -0
  150. package/esm2022/app/reports/interfaces/report-filter-option-pair.interface.mjs +2 -0
  151. package/esm2022/app/reports/interfaces/report-filter-options-ask.interface.mjs +2 -0
  152. package/esm2022/app/reports/interfaces/report-filter-options-list.interface.mjs +2 -0
  153. package/esm2022/app/reports/interfaces/report-filter-options-request.interface.mjs +2 -0
  154. package/esm2022/app/reports/interfaces/report-filter-options-stream.interface.mjs +2 -0
  155. package/esm2022/app/reports/interfaces/report-filter-options.interface.mjs +2 -0
  156. package/esm2022/app/reports/interfaces/report-filter-skip.type.mjs +2 -0
  157. package/esm2022/app/reports/interfaces/report-mark-action.type.mjs +2 -0
  158. package/esm2022/app/reports/interfaces/report-mark-click.interface.mjs +2 -0
  159. package/esm2022/app/reports/interfaces/report-mark-context.interface.mjs +2 -0
  160. package/esm2022/app/reports/interfaces/report-mark-decision.interface.mjs +2 -0
  161. package/esm2022/app/reports/interfaces/report-mark-event.interface.mjs +2 -0
  162. package/esm2022/app/reports/interfaces/report-mark-point.interface.mjs +2 -0
  163. package/esm2022/app/reports/interfaces/report-temporary-state.interface.mjs +2 -0
  164. package/esm2022/app/reports/interfaces/report-tile-state.interface.mjs +2 -0
  165. package/esm2022/app/reports/interfaces/report-url-link.interface.mjs +2 -0
  166. package/esm2022/app/reports/interfaces/report-url-value-name.type.mjs +2 -0
  167. package/esm2022/app/reports/interfaces/report-url-write.interface.mjs +2 -0
  168. package/esm2022/app/reports/interfaces/report-view-config.interface.mjs +2 -0
  169. package/esm2022/app/reports/interfaces/report-view-create.interface.mjs +2 -0
  170. package/esm2022/app/reports/interfaces/report-view-deleted.interface.mjs +2 -0
  171. package/esm2022/app/reports/interfaces/report-view-dialog-data.interface.mjs +2 -0
  172. package/esm2022/app/reports/interfaces/report-view-dropped.interface.mjs +2 -0
  173. package/esm2022/app/reports/interfaces/report-view-menu-item.interface.mjs +2 -0
  174. package/esm2022/app/reports/interfaces/report-view-summary.interface.mjs +2 -0
  175. package/esm2022/app/reports/interfaces/report-view.interface.mjs +2 -0
  176. package/esm2022/app/reports/interfaces/report-viewer-feature.type.mjs +2 -0
  177. package/esm2022/app/reports/interfaces/report-views.interface.mjs +2 -0
  178. package/esm2022/app/reports/interfaces/report.interface.mjs +1 -1
  179. package/esm2022/app/reports/interfaces/tile-load-result.interface.mjs +2 -0
  180. package/esm2022/app/reports/layout.mjs +11 -1
  181. package/esm2022/app/reports/mark-click.mjs +193 -0
  182. package/esm2022/app/reports/option-builder.mjs +159 -15
  183. package/esm2022/app/reports/report-chat-viewer-state.mjs +34 -0
  184. package/esm2022/app/reports/report-date-presets.mjs +18 -0
  185. package/esm2022/app/reports/report-filter-items.mjs +343 -72
  186. package/esm2022/app/reports/report-tile.mjs +12 -0
  187. package/esm2022/app/reports/report-url-state.mjs +596 -108
  188. package/esm2022/app/reports/report-view-config.mjs +697 -0
  189. package/esm2022/app/reports/report-view-menu.mjs +119 -0
  190. package/esm2022/app/reports/report-viewer-features.mjs +42 -0
  191. package/esm2022/app/reports/services/report-filter-options.service.mjs +238 -0
  192. package/esm2022/app/reports/services/report-filter-state.service.mjs +715 -71
  193. package/esm2022/app/reports/services/report-view.service.mjs +358 -0
  194. package/esm2022/app/reports/text.mjs +293 -85
  195. package/esm2022/app/reports/tile-data-state.mjs +127 -0
  196. package/esm2022/app/reports/tile-loads.mjs +38 -0
  197. package/esm2022/app/reports/values.mjs +183 -0
  198. package/esm2022/app/reports/views/report/fs-ai-report.component.mjs +180 -46
  199. package/esm2022/app/reports/views/report/report.component.mjs +106 -23
  200. package/esm2022/public_api.mjs +24 -1
  201. package/fesm2022/{firestitch-report-echarts-CFnbJx44.mjs → firestitch-report-echarts-UBg8Wlhd.mjs} +2 -2
  202. package/fesm2022/{firestitch-report-echarts-CFnbJx44.mjs.map → firestitch-report-echarts-UBg8Wlhd.mjs.map} +1 -1
  203. package/fesm2022/{firestitch-report-firestitch-report-CSylkyko.mjs → firestitch-report-firestitch-report-B1keNrcK.mjs} +11315 -4201
  204. package/fesm2022/firestitch-report-firestitch-report-B1keNrcK.mjs.map +1 -0
  205. package/fesm2022/firestitch-report.mjs +1 -1
  206. package/package.json +1 -1
  207. package/public_api.d.ts +23 -0
  208. package/fesm2022/firestitch-report-firestitch-report-CSylkyko.mjs.map +0 -1
@@ -0,0 +1,358 @@
1
+ import { HttpContext } from '@angular/common/http';
2
+ import { DestroyRef, Injectable, computed, inject, signal } from '@angular/core';
3
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
4
+ import { DisplayApiError, ProcessApiError } from '@firestitch/api';
5
+ import { FsMessage } from '@firestitch/message';
6
+ import { EMPTY, of } from 'rxjs';
7
+ import { catchError, map, switchMap, tap } from 'rxjs/operators';
8
+ import { ReportData } from '../data/report.data';
9
+ import { listSortTerms } from '../list-config';
10
+ import { URL_TOO_LONG_MESSAGE, hasReportUrlState, paramsToViewConfig, readReportUrlLink, reportParamsToClear, urlValueNames, viewConfigToParams, } from '../report-url-state';
11
+ import { REPORT_VIEW_CONFIG_VERSION, VIEW_NOT_AVAILABLE_MESSAGE, toStoredGroupValue, viewConfigDiff, viewDroppedCount, viewDroppedMessage, withStoredKeys, } from '../report-view-config';
12
+ import { ReportFilterStateService } from './report-filter-state.service';
13
+ import * as i0 from "@angular/core";
14
+ // The open report's saved views, per open report beside the state service:
15
+ // the list the viewer may see, the view that is open, the order a report
16
+ // opens in, the calls that change a view, and the link the screen writes.
17
+ // The viewer state stays ReportFilterStateService's: this service puts a
18
+ // view on screen through apply() and reads the screen through snapshot(),
19
+ // base and viewChanged. Nothing here runs for a report whose server does not
20
+ // list 'views' (serves()); such a report keeps the link it always had.
21
+ //
22
+ // The order a report opens in (open(), on its first load only):
23
+ // 1. A link that carries state (any owned key, match or rv). rv names the shared
24
+ // view it is a diff from; one the viewer cannot open leaves the diff on
25
+ // the report's defaults, with a note. rpv never changes the screen: when
26
+ // the viewer owns that view it is the open view, and the screen is
27
+ // compared with it. The tiles wait for that one view only; the list loads
28
+ // behind them. A link with rpv and no state (the owner's view was open on
29
+ // the report's defaults) is a link for the owner only; for anyone else
30
+ // it is no link.
31
+ // 2. Else the viewer's default view.
32
+ // 3. Else the report's authored defaults.
33
+ // A page in the link beats a view's page.
34
+ //
35
+ // The link (urlParams): while a shared view is open, rv and what differs
36
+ // from it; while one of the viewer's own views is open, or when the screen
37
+ // went back to something a link cannot say on top of the shared view (see
38
+ // viewConfigDiff), everything that differs from the report's defaults, and
39
+ // rpv when the viewer owns the open view. Sharing the open view, or no
40
+ // longer sharing it, writes the link again.
41
+ export class ReportViewService {
42
+ // The views the viewer may see, names and flags only: its own first, then
43
+ // the ones others share. Empty until the list is read.
44
+ views = computed(() => this._views());
45
+ // The viewer may share its views with everyone.
46
+ canShare = computed(() => this._canShare());
47
+ // The open view, with its config as it was read or saved; null while the
48
+ // screen is on the report's defaults.
49
+ openView = computed(() => this._openView());
50
+ // Whether the screen differs from the open view; false with none open.
51
+ viewChanged = computed(() => !!this._openView() && this._filterState.viewChanged());
52
+ _reportData = inject(ReportData);
53
+ _filterState = inject(ReportFilterStateService);
54
+ _message = inject(FsMessage);
55
+ _destroyRef = inject(DestroyRef);
56
+ _views = signal([]);
57
+ _canShare = signal(false);
58
+ _openView = signal(null);
59
+ // The report the views belong to.
60
+ _reportId = null;
61
+ // The note that the screen is too long for a link shows once per report.
62
+ _tooLongShown = false;
63
+ // Whether the open report's server keeps saved views.
64
+ serves(report) {
65
+ return !!report?.viewerFeatures?.includes('views');
66
+ }
67
+ // A report's first load, in the open order above: the state service is
68
+ // set up for `report` (init) and the screen opened on a link (`params`,
69
+ // the URL's query params), a default view or the report's defaults.
70
+ // `pageId` is the page the link names, which beats a view's page. Ends
71
+ // once the screen is set; the list may still be loading behind it.
72
+ open(report, params, pageId) {
73
+ this._start(report);
74
+ const page = pageId ? { v: REPORT_VIEW_CONFIG_VERSION, pageId } : null;
75
+ const link = readReportUrlLink(params);
76
+ const state = hasReportUrlState(params, report.filterGroups ?? []);
77
+ if (!state && !link.personalViewId) {
78
+ return this._openDefault(report, page);
79
+ }
80
+ const linkDiff = { ...paramsToViewConfig(params, report.filterGroups ?? []), ...page };
81
+ const viewId = link.viewId ?? link.personalViewId;
82
+ return (viewId ? this._readView(report.id, viewId) : of(null))
83
+ .pipe(switchMap((view) => {
84
+ // A link that names only a personal view (its screen was the
85
+ // report's defaults) is the owner's link; for anyone else it says
86
+ // nothing, and the report opens as it would with no link.
87
+ if (!state && !view?.mine) {
88
+ return this._openDefault(report, page);
89
+ }
90
+ this._filterState.init(report);
91
+ this._openLink(link, view, linkDiff);
92
+ this._readViews(report)
93
+ .pipe(takeUntilDestroyed(this._destroyRef))
94
+ .subscribe();
95
+ return of(undefined);
96
+ }));
97
+ }
98
+ // A later load of the open report (a chat edit, a settings save): the
99
+ // screen and the open view stay, and the list is read again behind them so
100
+ // it names what the server holds now.
101
+ refresh(report) {
102
+ this._start(report);
103
+ this._readViews(report)
104
+ .pipe(takeUntilDestroyed(this._destroyRef))
105
+ .subscribe();
106
+ }
107
+ // Opens a view picked from the list; its config is read now.
108
+ pick(reportViewId) {
109
+ return this._reportData.view(this._reportId, reportViewId)
110
+ .pipe(tap((view) => this._openOn(view, () => this._filterState.apply(view.config))));
111
+ }
112
+ // Closes the open view and puts the screen on the report's defaults.
113
+ openDefaults() {
114
+ this._openView.set(null);
115
+ this._filterState.apply(null);
116
+ }
117
+ // Saves the screen as a new view, which becomes the open view. The screen
118
+ // is already the view, so nothing is applied again.
119
+ saveAsNew(view) {
120
+ return this._reportData.createView(this._reportId, { ...view, config: this._filterState.snapshot() })
121
+ .pipe(tap((saved) => {
122
+ this._openView.set(saved);
123
+ this._putRow(saved);
124
+ this._filterState.setBaseToScreen();
125
+ this._message.success('View saved');
126
+ }));
127
+ }
128
+ // Saves the screen over the open view, keeping the keys this viewer does
129
+ // not know (withStoredKeys).
130
+ saveChanges() {
131
+ const open = this._openView();
132
+ if (!open) {
133
+ return EMPTY;
134
+ }
135
+ return this._reportData.updateView(this._reportId, open.id, { config: withStoredKeys(open.config, this._filterState.snapshot()) })
136
+ .pipe(tap((saved) => {
137
+ this._openView.set(saved);
138
+ this._putRow(saved);
139
+ this._filterState.setBaseToScreen();
140
+ this._message.success('View saved');
141
+ }));
142
+ }
143
+ rename(name) {
144
+ return this._changeOpen((reportViewId) => this._reportData.updateView(this._reportId, reportViewId, { name }));
145
+ }
146
+ // Shares the open view with everyone who may open the report, or stops.
147
+ share(shared) {
148
+ return this._changeOpen((reportViewId) => this._reportData.shareView(this._reportId, reportViewId, shared));
149
+ }
150
+ // Makes the open view the viewer's default, or stops opening it by default.
151
+ setDefault(personalDefault) {
152
+ return this._changeOpen((reportViewId) => this._reportData.setViewDefault(this._reportId, reportViewId, personalDefault));
153
+ }
154
+ // Deletes the open view. The screen stays; the report's defaults become
155
+ // what it is compared with.
156
+ deleteOpen() {
157
+ const open = this._openView();
158
+ if (!open) {
159
+ return EMPTY;
160
+ }
161
+ return this._reportData.deleteView(this._reportId, open.id)
162
+ .pipe(tap(() => {
163
+ this._openView.set(null);
164
+ this._views.update((views) => views.filter((view) => view.id !== open.id));
165
+ this._filterState.clearBase();
166
+ this._message.success('View deleted');
167
+ }));
168
+ }
169
+ // The query params that make the URL carry the screen (see the class
170
+ // comment), spread over the owned keys `current` carries so the ones the
171
+ // screen no longer needs are removed. The host adds its page key.
172
+ // A select's value is named by `name`, else by the name `current` carries
173
+ // for it.
174
+ urlParams(current, name = () => null) {
175
+ const currentName = urlValueNames(current, this._reportGroups());
176
+ const write = this._linkWrite((groupId, value) => name(groupId, value) ?? currentName(groupId, value));
177
+ if (write.tooLong && !this._tooLongShown) {
178
+ this._tooLongShown = true;
179
+ this._message.warning(URL_TOO_LONG_MESSAGE);
180
+ }
181
+ return { ...reportParamsToClear(current, this._reportGroups()), ...write.params };
182
+ }
183
+ // Starts over for another report: no list and no open view.
184
+ _start(report) {
185
+ if (report.id === this._reportId) {
186
+ return;
187
+ }
188
+ this._reportId = report.id;
189
+ this._views.set([]);
190
+ this._canShare.set(false);
191
+ this._openView.set(null);
192
+ this._tooLongShown = false;
193
+ }
194
+ // No link: the viewer's default view, else the report's defaults, once the
195
+ // list is read.
196
+ _openDefault(report, page) {
197
+ return this._readViews(report)
198
+ .pipe(tap((list) => {
199
+ this._filterState.init(report);
200
+ if (list?.myDefault) {
201
+ this._openOn(list.myDefault, () => this._filterState.apply(list.myDefault.config, page));
202
+ }
203
+ }), map(() => undefined));
204
+ }
205
+ // A link with state: on the shared view rv names, else on the report's
206
+ // defaults; rpv's view is the open view only when the viewer owns it.
207
+ _openLink(link, view, linkDiff) {
208
+ if (link.viewId && view) {
209
+ this._openOn(view, () => this._filterState.apply(view.config, linkDiff));
210
+ return;
211
+ }
212
+ if (!link.viewId && view?.mine) {
213
+ this._openOn(view, () => this._filterState.apply(null, linkDiff, view.config));
214
+ return;
215
+ }
216
+ this._openView.set(null);
217
+ this._filterState.apply(null, linkDiff);
218
+ if (link.viewId) {
219
+ this._message.warning(VIEW_NOT_AVAILABLE_MESSAGE);
220
+ }
221
+ }
222
+ // Makes `view` the open view, puts it on screen (`applyView`), and says
223
+ // how many of its settings no longer apply (and to save it, when the
224
+ // viewer may).
225
+ _openOn(view, applyView) {
226
+ this._openView.set(view);
227
+ applyView();
228
+ const note = viewDroppedMessage(viewDroppedCount(view, this._filterState.base()), view.canChange);
229
+ if (note) {
230
+ this._message.warning(note);
231
+ }
232
+ }
233
+ // Runs a change on the open view and takes its answer as the open view
234
+ // and its row in the list. A change of who may see the view (shared, or
235
+ // whose it is) changes the key a link names it by, so the URL is written
236
+ // again.
237
+ _changeOpen(change) {
238
+ const open = this._openView();
239
+ if (!open) {
240
+ return EMPTY;
241
+ }
242
+ return change(open.id)
243
+ .pipe(tap((view) => {
244
+ this._openView.set(view);
245
+ this._putRow(view);
246
+ if (view.shared !== open.shared || view.mine !== open.mine) {
247
+ this._filterState.rewriteUrl();
248
+ }
249
+ }));
250
+ }
251
+ // A view's row in the list, replaced or added. A new default clears the
252
+ // flag on the viewer's other views, as the server does. A new row keeps
253
+ // the list's order: the viewer's own views first, then the ones others
254
+ // share.
255
+ _putRow(view) {
256
+ const summary = viewSummary(view);
257
+ this._views.update((views) => {
258
+ const rows = views.map((row) => (view.personalDefault && row.personalDefault ? { ...row, personalDefault: false } : row));
259
+ const index = rows.findIndex((row) => row.id === view.id);
260
+ if (index >= 0) {
261
+ return rows.map((row, at) => (at === index ? summary : row));
262
+ }
263
+ const othersAt = view.mine ? rows.findIndex((row) => !row.mine) : -1;
264
+ return othersAt < 0
265
+ ? [...rows, summary]
266
+ : [...rows.slice(0, othersAt), summary, ...rows.slice(othersAt)];
267
+ });
268
+ }
269
+ // The list, read for `report`; null when it cannot be read. Its answer is
270
+ // kept only while the report is still the open one.
271
+ _readViews(report) {
272
+ return this._reportData.views(report.id, { context: new HttpContext().set(DisplayApiError, false) })
273
+ .pipe(catchError(() => of(null)), tap((list) => {
274
+ if (list && report.id === this._reportId) {
275
+ this._views.set(list.views ?? []);
276
+ this._canShare.set(!!list.canShare);
277
+ }
278
+ }));
279
+ }
280
+ // A view a link names; null when the viewer cannot open it. The server
281
+ // answers 'View not found' for one it cannot see, which must not move the
282
+ // host to its not-found page.
283
+ _readView(reportId, reportViewId) {
284
+ return this._reportData.view(reportId, reportViewId, { context: new HttpContext().set(ProcessApiError, false) })
285
+ .pipe(catchError(() => of(null)));
286
+ }
287
+ // The params the screen writes (see the class comment).
288
+ _linkWrite(name) {
289
+ const open = this._openView();
290
+ const screen = this._filterState.snapshot();
291
+ const authored = this._filterState.authoredConfig();
292
+ const authoredSort = (componentId) => this._authoredSort(componentId);
293
+ if (open?.shared) {
294
+ // A group the view holds that the base let go of (its authored default
295
+ // changed while the view was open, and the screen took the new one)
296
+ // is still the view's value when a link opens the view, so it is
297
+ // compared with that value and written when the screen differs.
298
+ const base = this._filterState.base();
299
+ const linkBase = { ...base, groups: { ...open.config?.groups, ...base.groups } };
300
+ const diff = viewConfigDiff(linkBase, screen, authored, authoredSort);
301
+ if (diff) {
302
+ return viewConfigToParams(this._linkDays(diff), this._reportGroups(), { viewId: open.id }, name);
303
+ }
304
+ }
305
+ const full = viewConfigDiff(authored, screen, authored, authoredSort) ?? screen;
306
+ const link = open?.mine ? { personalViewId: open.id } : {};
307
+ return viewConfigToParams(this._linkDays(full), this._reportGroups(), link, name);
308
+ }
309
+ // `config` with each rolling range (a relative name, which a view keeps) as
310
+ // the days it gives today in the report's zone: a link carries days, never a
311
+ // preset name. A name the report does not know is left as it is, and the
312
+ // link leaves that group out.
313
+ _linkDays(config) {
314
+ if (!config.groups) {
315
+ return config;
316
+ }
317
+ const groups = Object.entries(config.groups)
318
+ .map(([groupId, value]) => [groupId, this._groupDays(value)]);
319
+ return { ...config, groups: Object.fromEntries(groups) };
320
+ }
321
+ _groupDays(value) {
322
+ const range = value?.relative ? this._filterState.resolveRelative(value.relative) : null;
323
+ return range ? toStoredGroupValue('dateRange', { start: range.start, end: range.end }) : value;
324
+ }
325
+ // Every filter group of the open report: the link keys each by its label.
326
+ _reportGroups() {
327
+ return this._filterState.report()?.filterGroups ?? [];
328
+ }
329
+ // A list's authored first sort term, or null for any other component.
330
+ _authoredSort(componentId) {
331
+ const report = this._filterState.report();
332
+ const component = [
333
+ ...(report?.pages ?? []).flatMap((page) => page.components ?? []),
334
+ ...(report?.master?.components ?? []),
335
+ ].find((candidate) => candidate.id === componentId);
336
+ return component?.type === 'list' ? listSortTerms(component.config)[0] ?? null : null;
337
+ }
338
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportViewService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
339
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportViewService });
340
+ }
341
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportViewService, decorators: [{
342
+ type: Injectable
343
+ }] });
344
+ // A view's row as the list holds it: names and flags, no config.
345
+ function viewSummary(view) {
346
+ return {
347
+ id: view.id,
348
+ name: view.name,
349
+ shared: view.shared,
350
+ mine: view.mine,
351
+ personalDefault: view.personalDefault,
352
+ ownerName: view.ownerName,
353
+ canChange: view.canChange,
354
+ canDelete: view.canDelete,
355
+ modifyDate: view.modifyDate,
356
+ };
357
+ }
358
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LXZpZXcuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvcmVwb3J0cy9zZXJ2aWNlcy9yZXBvcnQtdmlldy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNuRCxPQUFPLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBRSxRQUFRLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNqRixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUdoRSxPQUFPLEVBQUUsZUFBZSxFQUFFLGVBQWUsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ25FLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUVoRCxPQUFPLEVBQUUsS0FBSyxFQUFjLEVBQUUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUM3QyxPQUFPLEVBQUUsVUFBVSxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFakUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBV2pELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUMvQyxPQUFPLEVBQ0wsb0JBQW9CLEVBQUUsaUJBQWlCLEVBQUUsa0JBQWtCLEVBQUUsaUJBQWlCLEVBQUUsbUJBQW1CLEVBQ25HLGFBQWEsRUFBRSxrQkFBa0IsR0FDbEMsTUFBTSxxQkFBcUIsQ0FBQztBQUM3QixPQUFPLEVBQ0wsMEJBQTBCLEVBQUUsMEJBQTBCLEVBQUUsa0JBQWtCLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUM1RyxrQkFBa0IsRUFBRSxjQUFjLEdBQ25DLE1BQU0sdUJBQXVCLENBQUM7QUFDL0IsT0FBTyxFQUFFLHdCQUF3QixFQUFFLE1BQU0s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QyxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDeEYsQ0FBQzt3R0ExWFUsaUJBQWlCOzRHQUFqQixpQkFBaUI7OzRGQUFqQixpQkFBaUI7a0JBRDdCLFVBQVU7O0FBK1hYLGlFQUFpRTtBQUNqRSxTQUFTLFdBQVcsQ0FBQyxJQUFnQjtJQUNuQyxPQUFPO1FBQ0wsRUFBRSxFQUFFLElBQUksQ0FBQyxFQUFFO1FBQ1gsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJO1FBQ2YsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNO1FBQ25CLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSTtRQUNmLGVBQWUsRUFBRSxJQUFJLENBQUMsZUFBZTtRQUNyQyxTQUFTLEVBQUUsSUFBSSxDQUFDLFNBQVM7UUFDekIsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTO1FBQ3pCLFNBQVMsRUFBRSxJQUFJLENBQUMsU0FBUztRQUN6QixVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVU7S0FDNUIsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBIdHRwQ29udGV4dCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IERlc3Ryb3lSZWYsIEluamVjdGFibGUsIGNvbXB1dGVkLCBpbmplY3QsIHNpZ25hbCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgUGFyYW1NYXAsIFBhcmFtcyB9IGZyb20gJ0Bhbmd1bGFyL3JvdXRlcic7XG5cbmltcG9ydCB7IERpc3BsYXlBcGlFcnJvciwgUHJvY2Vzc0FwaUVycm9yIH0gZnJvbSAnQGZpcmVzdGl0Y2gvYXBpJztcbmltcG9ydCB7IEZzTWVzc2FnZSB9IGZyb20gJ0BmaXJlc3RpdGNoL21lc3NhZ2UnO1xuXG5pbXBvcnQgeyBFTVBUWSwgT2JzZXJ2YWJsZSwgb2YgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IGNhdGNoRXJyb3IsIG1hcCwgc3dpdGNoTWFwLCB0YXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IFJlcG9ydERhdGEgfSBmcm9tICcuLi9kYXRhL3JlcG9ydC5kYXRhJztcbmltcG9ydCB7IFJlcG9ydFVybExpbmsgfSBmcm9tICcuLi9pbnRlcmZhY2VzL3JlcG9ydC11cmwtbGluay5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgUmVwb3J0VXJsVmFsdWVOYW1lIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZXBvcnQtdXJsLXZhbHVlLW5hbWUudHlwZSc7XG5pbXBvcnQgeyBSZXBvcnRVcmxXcml0ZSB9IGZyb20gJy4uL2ludGVyZmFjZXMvcmVwb3J0LXVybC13cml0ZS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgUmVwb3J0Vmlld0NvbmZpZyB9IGZyb20gJy4uL2ludGVyZmFjZXMvcmVwb3J0LXZpZXctY29uZmlnLmludGVyZmFjZSc7XG5pbXBvcnQgeyBSZXBvcnRWaWV3Q3JlYXRlIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZXBvcnQtdmlldy1jcmVhdGUuaW50ZXJmYWNlJztcbmltcG9ydCB7IFJlcG9ydFZpZXdEZWxldGVkIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZXBvcnQtdmlldy1kZWxldGVkLmludGVyZmFjZSc7XG5pbXBvcnQgeyBSZXBvcnRWaWV3U3VtbWFyeSB9IGZyb20gJy4uL2ludGVyZmFjZXMvcmVwb3J0LXZpZXctc3VtbWFyeS5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgUmVwb3J0VmlldyB9IGZyb20gJy4uL2ludGVyZmFjZXMvcmVwb3J0LXZpZXcuaW50ZXJmYWNlJztcbmltcG9ydCB7IFJlcG9ydFZpZXdzIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZXBvcnQtdmlld3MuaW50ZXJmYWNlJztcbmltcG9ydCB7IEZpbHRlckdyb3VwRGVmYXVsdCwgUmVwb3J0LCBSZXBvcnRGaWx0ZXJHcm91cCwgUmVwb3J0U29ydCB9IGZyb20gJy4uL2ludGVyZmFjZXMvcmVwb3J0LmludGVyZmFjZSc7XG5pbXBvcnQgeyBsaXN0U29ydFRlcm1zIH0gZnJvbSAnLi4vbGlzdC1jb25maWcnO1xuaW1wb3J0IHtcbiAgVVJMX1RPT19MT05HX01FU1NBR0UsIGhhc1JlcG9ydFVybFN0YXRlLCBwYXJhbXNUb1ZpZXdDb25maWcsIHJlYWRSZXBvcnRVcmxMaW5rLCByZXBvcnRQYXJhbXNUb0NsZWFyLFxuICB1cmxWYWx1ZU5hbWVzLCB2aWV3Q29uZmlnVG9QYXJhbXMsXG59IGZyb20gJy4uL3JlcG9ydC11cmwtc3RhdGUnO1xuaW1wb3J0IHtcbiAgUkVQT1JUX1ZJRVdfQ09ORklHX1ZFUlNJT04sIFZJRVdfTk9UX0FWQUlMQUJMRV9NRVNTQUdFLCB0b1N0b3JlZEdyb3VwVmFsdWUsIHZpZXdDb25maWdEaWZmLCB2aWV3RHJvcHBlZENvdW50LFxuICB2aWV3RHJvcHBlZE1lc3NhZ2UsIHdpdGhTdG9yZWRLZXlzLFxufSBmcm9tICcuLi9yZXBvcnQtdmlldy1jb25maWcnO1xuaW1wb3J0IHsgUmVwb3J0RmlsdGVyU3RhdGVTZXJ2aWNlIH0gZnJvbSAnLi9yZXBvcnQtZmlsdGVyLXN0YXRlLnNlcnZpY2UnO1xuXG5cbi8vIFRoZSBvcGVuIHJlcG9ydCdzIHNhdmVkIHZpZXdzLCBwZXIgb3BlbiByZXBvcnQgYmVzaWRlIHRoZSBzdGF0ZSBzZXJ2aWNlOlxuLy8gdGhlIGxpc3QgdGhlIHZpZXdlciBtYXkgc2VlLCB0aGUgdmlldyB0aGF0IGlzIG9wZW4sIHRoZSBvcmRlciBhIHJlcG9ydFxuLy8gb3BlbnMgaW4sIHRoZSBjYWxscyB0aGF0IGNoYW5nZSBhIHZpZXcsIGFuZCB0aGUgbGluayB0aGUgc2NyZWVuIHdyaXRlcy5cbi8vIFRoZSB2aWV3ZXIgc3RhdGUgc3RheXMgUmVwb3J0RmlsdGVyU3RhdGVTZXJ2aWNlJ3M6IHRoaXMgc2VydmljZSBwdXRzIGFcbi8vIHZpZXcgb24gc2NyZWVuIHRocm91Z2ggYXBwbHkoKSBhbmQgcmVhZHMgdGhlIHNjcmVlbiB0aHJvdWdoIHNuYXBzaG90KCksXG4vLyBiYXNlIGFuZCB2aWV3Q2hhbmdlZC4gTm90aGluZyBoZXJlIHJ1bnMgZm9yIGEgcmVwb3J0IHdob3NlIHNlcnZlciBkb2VzIG5vdFxuLy8gbGlzdCAndmlld3MnIChzZXJ2ZXMoKSk7IHN1Y2ggYSByZXBvcnQga2VlcHMgdGhlIGxpbmsgaXQgYWx3YXlzIGhhZC5cbi8vXG4vLyBUaGUgb3JkZXIgYSByZXBvcnQgb3BlbnMgaW4gKG9wZW4oKSwgb24gaXRzIGZpcnN0IGxvYWQgb25seSk6XG4vLyAxLiBBIGxpbmsgdGhhdCBjYXJyaWVzIHN0YXRlIChhbnkgb3duZWQga2V5LCBtYXRjaCBvciBydikuIHJ2IG5hbWVzIHRoZSBzaGFyZWRcbi8vICAgIHZpZXcgaXQgaXMgYSBkaWZmIGZyb207IG9uZSB0aGUgdmlld2VyIGNhbm5vdCBvcGVuIGxlYXZlcyB0aGUgZGlmZiBvblxuLy8gICAgdGhlIHJlcG9ydCdzIGRlZmF1bHRzLCB3aXRoIGEgbm90ZS4gcnB2IG5ldmVyIGNoYW5nZXMgdGhlIHNjcmVlbjogd2hlblxuLy8gICAgdGhlIHZpZXdlciBvd25zIHRoYXQgdmlldyBpdCBpcyB0aGUgb3BlbiB2aWV3LCBhbmQgdGhlIHNjcmVlbiBpc1xuLy8gICAgY29tcGFyZWQgd2l0aCBpdC4gVGhlIHRpbGVzIHdhaXQgZm9yIHRoYXQgb25lIHZpZXcgb25seTsgdGhlIGxpc3QgbG9hZHNcbi8vICAgIGJlaGluZCB0aGVtLiBBIGxpbmsgd2l0aCBycHYgYW5kIG5vIHN0YXRlICh0aGUgb3duZXIncyB2aWV3IHdhcyBvcGVuIG9uXG4vLyAgICB0aGUgcmVwb3J0J3MgZGVmYXVsdHMpIGlzIGEgbGluayBmb3IgdGhlIG93bmVyIG9ubHk7IGZvciBhbnlvbmUgZWxzZVxuLy8gICAgaXQgaXMgbm8gbGluay5cbi8vIDIuIEVsc2UgdGhlIHZpZXdlcidzIGRlZmF1bHQgdmlldy5cbi8vIDMuIEVsc2UgdGhlIHJlcG9ydCdzIGF1dGhvcmVkIGRlZmF1bHRzLlxuLy8gQSBwYWdlIGluIHRoZSBsaW5rIGJlYXRzIGEgdmlldydzIHBhZ2UuXG4vL1xuLy8gVGhlIGxpbmsgKHVybFBhcmFtcyk6IHdoaWxlIGEgc2hhcmVkIHZpZXcgaXMgb3BlbiwgcnYgYW5kIHdoYXQgZGlmZmVyc1xuLy8gZnJvbSBpdDsgd2hpbGUgb25lIG9mIHRoZSB2aWV3ZXIncyBvd24gdmlld3MgaXMgb3Blbiwgb3Igd2hlbiB0aGUgc2NyZWVuXG4vLyB3ZW50IGJhY2sgdG8gc29tZXRoaW5nIGEgbGluayBjYW5ub3Qgc2F5IG9uIHRvcCBvZiB0aGUgc2hhcmVkIHZpZXcgKHNlZVxuLy8gdmlld0NvbmZpZ0RpZmYpLCBldmVyeXRoaW5nIHRoYXQgZGlmZmVycyBmcm9tIHRoZSByZXBvcnQncyBkZWZhdWx0cywgYW5kXG4vLyBycHYgd2hlbiB0aGUgdmlld2VyIG93bnMgdGhlIG9wZW4gdmlldy4gU2hhcmluZyB0aGUgb3BlbiB2aWV3LCBvciBub1xuLy8gbG9uZ2VyIHNoYXJpbmcgaXQsIHdyaXRlcyB0aGUgbGluayBhZ2Fpbi5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBSZXBvcnRWaWV3U2VydmljZSB7XG5cbiAgLy8gVGhlIHZpZXdzIHRoZSB2aWV3ZXIgbWF5IHNlZSwgbmFtZXMgYW5kIGZsYWdzIG9ubHk6IGl0cyBvd24gZmlyc3QsIHRoZW5cbiAgLy8gdGhlIG9uZXMgb3RoZXJzIHNoYXJlLiBFbXB0eSB1bnRpbCB0aGUgbGlzdCBpcyByZWFkLlxuICBwdWJsaWMgcmVhZG9ubHkgdmlld3MgPSBjb21wdXRlZCgoKSA9PiB0aGlzLl92aWV3cygpKTtcblxuICAvLyBUaGUgdmlld2VyIG1heSBzaGFyZSBpdHMgdmlld3Mgd2l0aCBldmVyeW9uZS5cbiAgcHVibGljIHJlYWRvbmx5IGNhblNoYXJlID0gY29tcHV0ZWQoKCkgPT4gdGhpcy5fY2FuU2hhcmUoKSk7XG5cbiAgLy8gVGhlIG9wZW4gdmlldywgd2l0aCBpdHMgY29uZmlnIGFzIGl0IHdhcyByZWFkIG9yIHNhdmVkOyBudWxsIHdoaWxlIHRoZVxuICAvLyBzY3JlZW4gaXMgb24gdGhlIHJlcG9ydCdzIGRlZmF1bHRzLlxuICBwdWJsaWMgcmVhZG9ubHkgb3BlblZpZXcgPSBjb21wdXRlZCgoKSA9PiB0aGlzLl9vcGVuVmlldygpKTtcblxuICAvLyBXaGV0aGVyIHRoZSBzY3JlZW4gZGlmZmVycyBmcm9tIHRoZSBvcGVuIHZpZXc7IGZhbHNlIHdpdGggbm9uZSBvcGVuLlxuICBwdWJsaWMgcmVhZG9ubHkgdmlld0NoYW5nZWQgPSBjb21wdXRlZCgoKSA9PiAhIXRoaXMuX29wZW5WaWV3KCkgJiYgdGhpcy5fZmlsdGVyU3RhdGUudmlld0NoYW5nZWQoKSk7XG5cbiAgcHJpdmF0ZSBfcmVwb3J0RGF0YSA9IGluamVjdChSZXBvcnREYXRhKTtcbiAgcHJpdmF0ZSBfZmlsdGVyU3RhdGUgPSBpbmplY3QoUmVwb3J0RmlsdGVyU3RhdGVTZXJ2aWNlKTtcbiAgcHJpdmF0ZSBfbWVzc2FnZSA9IGluamVjdChGc01lc3NhZ2UpO1xuICBwcml2YXRlIF9kZXN0cm95UmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuXG4gIHByaXZhdGUgX3ZpZXdzID0gc2lnbmFsPFJlcG9ydFZpZXdTdW1tYXJ5W10+KFtdKTtcbiAgcHJpdmF0ZSBfY2FuU2hhcmUgPSBzaWduYWwoZmFsc2UpO1xuICBwcml2YXRlIF9vcGVuVmlldyA9IHNpZ25hbDxSZXBvcnRWaWV3IHwgbnVsbD4obnVsbCk7XG5cbiAgLy8gVGhlIHJlcG9ydCB0aGUgdmlld3MgYmVsb25nIHRvLlxuICBwcml2YXRlIF9yZXBvcnRJZDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG5cbiAgLy8gVGhlIG5vdGUgdGhhdCB0aGUgc2NyZWVuIGlzIHRvbyBsb25nIGZvciBhIGxpbmsgc2hvd3Mgb25jZSBwZXIgcmVwb3J0LlxuICBwcml2YXRlIF90b29Mb25nU2hvd24gPSBmYWxzZTtcblxuICAvLyBXaGV0aGVyIHRoZSBvcGVuIHJlcG9ydCdzIHNlcnZlciBrZWVwcyBzYXZlZCB2aWV3cy5cbiAgcHVibGljIHNlcnZlcyhyZXBvcnQ6IFJlcG9ydCB8IG51bGwpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISFyZXBvcnQ/LnZpZXdlckZlYXR1cmVzPy5pbmNsdWRlcygndmlld3MnKTtcbiAgfVxuXG4gIC8vIEEgcmVwb3J0J3MgZmlyc3QgbG9hZCwgaW4gdGhlIG9wZW4gb3JkZXIgYWJvdmU6IHRoZSBzdGF0ZSBzZXJ2aWNlIGlzXG4gIC8vIHNldCB1cCBmb3IgYHJlcG9ydGAgKGluaXQpIGFuZCB0aGUgc2NyZWVuIG9wZW5lZCBvbiBhIGxpbmsgKGBwYXJhbXNgLFxuICAvLyB0aGUgVVJMJ3MgcXVlcnkgcGFyYW1zKSwgYSBkZWZhdWx0IHZpZXcgb3IgdGhlIHJlcG9ydCdzIGRlZmF1bHRzLlxuICAvLyBgcGFnZUlkYCBpcyB0aGUgcGFnZSB0aGUgbGluayBuYW1lcywgd2hpY2ggYmVhdHMgYSB2aWV3J3MgcGFnZS4gRW5kc1xuICAvLyBvbmNlIHRoZSBzY3JlZW4gaXMgc2V0OyB0aGUgbGlzdCBtYXkgc3RpbGwgYmUgbG9hZGluZyBiZWhpbmQgaXQuXG4gIHB1YmxpYyBvcGVuKHJlcG9ydDogUmVwb3J0LCBwYXJhbXM6IFBhcmFtcywgcGFnZUlkOiBudW1iZXIgfCBudWxsKTogT2JzZXJ2YWJsZTx2b2lkPiB7XG4gICAgdGhpcy5fc3RhcnQocmVwb3J0KTtcbiAgICBjb25zdCBwYWdlOiBSZXBvcnRWaWV3Q29uZmlnIHwgbnVsbCA9IHBhZ2VJZCA/IHsgdjogUkVQT1JUX1ZJRVdfQ09ORklHX1ZFUlNJT04sIHBhZ2VJZCB9IDogbnVsbDtcbiAgICBjb25zdCBsaW5rID0gcmVhZFJlcG9ydFVybExpbmsocGFyYW1zKTtcbiAgICBjb25zdCBzdGF0ZSA9IGhhc1JlcG9ydFVybFN0YXRlKHBhcmFtcywgcmVwb3J0LmZpbHRlckdyb3VwcyA/PyBbXSk7XG5cbiAgICBpZiAoIXN0YXRlICYmICFsaW5rLnBlcnNvbmFsVmlld0lkKSB7XG4gICAgICByZXR1cm4gdGhpcy5fb3BlbkRlZmF1bHQocmVwb3J0LCBwYWdlKTtcbiAgICB9XG5cbiAgICBjb25zdCBsaW5rRGlmZjogUmVwb3J0Vmlld0NvbmZpZyA9IHsgLi4ucGFyYW1zVG9WaWV3Q29uZmlnKHBhcmFtcywgcmVwb3J0LmZpbHRlckdyb3VwcyA/PyBbXSksIC4uLnBhZ2UgfTtcbiAgICBjb25zdCB2aWV3SWQgPSBsaW5rLnZpZXdJZCA/PyBsaW5rLnBlcnNvbmFsVmlld0lkO1xuXG4gICAgcmV0dXJuICh2aWV3SWQgPyB0aGlzLl9yZWFkVmlldyhyZXBvcnQuaWQsIHZpZXdJZCkgOiBvZihudWxsKSlcbiAgICAgIC5waXBlKFxuICAgICAgICBzd2l0Y2hNYXAoKHZpZXcpID0+IHtcbiAgICAgICAgICAvLyBBIGxpbmsgdGhhdCBuYW1lcyBvbmx5IGEgcGVyc29uYWwgdmlldyAoaXRzIHNjcmVlbiB3YXMgdGhlXG4gICAgICAgICAgLy8gcmVwb3J0J3MgZGVmYXVsdHMpIGlzIHRoZSBvd25lcidzIGxpbms7IGZvciBhbnlvbmUgZWxzZSBpdCBzYXlzXG4gICAgICAgICAgLy8gbm90aGluZywgYW5kIHRoZSByZXBvcnQgb3BlbnMgYXMgaXQgd291bGQgd2l0aCBubyBsaW5rLlxuICAgICAgICAgIGlmICghc3RhdGUgJiYgIXZpZXc/Lm1pbmUpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9vcGVuRGVmYXVsdChyZXBvcnQsIHBhZ2UpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHRoaXMuX2ZpbHRlclN0YXRlLmluaXQocmVwb3J0KTtcbiAgICAgICAgICB0aGlzLl9vcGVuTGluayhsaW5rLCB2aWV3LCBsaW5rRGlmZik7XG4gICAgICAgICAgdGhpcy5fcmVhZFZpZXdzKHJlcG9ydClcbiAgICAgICAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSlcbiAgICAgICAgICAgIC5zdWJzY3JpYmUoKTtcblxuICAgICAgICAgIHJldHVybiBvZih1bmRlZmluZWQpO1xuICAgICAgICB9KSxcbiAgICAgICk7XG4gIH1cblxuICAvLyBBIGxhdGVyIGxvYWQgb2YgdGhlIG9wZW4gcmVwb3J0IChhIGNoYXQgZWRpdCwgYSBzZXR0aW5ncyBzYXZlKTogdGhlXG4gIC8vIHNjcmVlbiBhbmQgdGhlIG9wZW4gdmlldyBzdGF5LCBhbmQgdGhlIGxpc3QgaXMgcmVhZCBhZ2FpbiBiZWhpbmQgdGhlbSBzb1xuICAvLyBpdCBuYW1lcyB3aGF0IHRoZSBzZXJ2ZXIgaG9sZHMgbm93LlxuICBwdWJsaWMgcmVmcmVzaChyZXBvcnQ6IFJlcG9ydCk6IHZvaWQge1xuICAgIHRoaXMuX3N0YXJ0KHJlcG9ydCk7XG4gICAgdGhpcy5fcmVhZFZpZXdzKHJlcG9ydClcbiAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSlcbiAgICAgIC5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIC8vIE9wZW5zIGEgdmlldyBwaWNrZWQgZnJvbSB0aGUgbGlzdDsgaXRzIGNvbmZpZyBpcyByZWFkIG5vdy5cbiAgcHVibGljIHBpY2socmVwb3J0Vmlld0lkOiBudW1iZXIpOiBPYnNlcnZhYmxlPFJlcG9ydFZpZXc+IHtcbiAgICByZXR1cm4gdGhpcy5fcmVwb3J0RGF0YS52aWV3KHRoaXMuX3JlcG9ydElkLCByZXBvcnRWaWV3SWQpXG4gICAgICAucGlwZShcbiAgICAgICAgdGFwKCh2aWV3KSA9PiB0aGlzLl9vcGVuT24odmlldywgKCkgPT4gdGhpcy5fZmlsdGVyU3RhdGUuYXBwbHkodmlldy5jb25maWcpKSksXG4gICAgICApO1xuICB9XG5cbiAgLy8gQ2xvc2VzIHRoZSBvcGVuIHZpZXcgYW5kIHB1dHMgdGhlIHNjcmVlbiBvbiB0aGUgcmVwb3J0J3MgZGVmYXVsdHMuXG4gIHB1YmxpYyBvcGVuRGVmYXVsdHMoKTogdm9pZCB7XG4gICAgdGhpcy5fb3BlblZpZXcuc2V0KG51bGwpO1xuICAgIHRoaXMuX2ZpbHRlclN0YXRlLmFwcGx5KG51bGwpO1xuICB9XG5cbiAgLy8gU2F2ZXMgdGhlIHNjcmVlbiBhcyBhIG5ldyB2aWV3LCB3aGljaCBiZWNvbWVzIHRoZSBvcGVuIHZpZXcuIFRoZSBzY3JlZW5cbiAgLy8gaXMgYWxyZWFkeSB0aGUgdmlldywgc28gbm90aGluZyBpcyBhcHBsaWVkIGFnYWluLlxuICBwdWJsaWMgc2F2ZUFzTmV3KHZpZXc6IE9taXQ8UmVwb3J0Vmlld0NyZWF0ZSwgJ2NvbmZpZyc+KTogT2JzZXJ2YWJsZTxSZXBvcnRWaWV3PiB7XG4gICAgcmV0dXJuIHRoaXMuX3JlcG9ydERhdGEuY3JlYXRlVmlldyh0aGlzLl9yZXBvcnRJZCwgeyAuLi52aWV3LCBjb25maWc6IHRoaXMuX2ZpbHRlclN0YXRlLnNuYXBzaG90KCkgfSlcbiAgICAgIC5waXBlKFxuICAgICAgICB0YXAoKHNhdmVkKSA9PiB7XG4gICAgICAgICAgdGhpcy5fb3BlblZpZXcuc2V0KHNhdmVkKTtcbiAgICAgICAgICB0aGlzLl9wdXRSb3coc2F2ZWQpO1xuICAgICAgICAgIHRoaXMuX2ZpbHRlclN0YXRlLnNldEJhc2VUb1NjcmVlbigpO1xuICAgICAgICAgIHRoaXMuX21lc3NhZ2Uuc3VjY2VzcygnVmlldyBzYXZlZCcpO1xuICAgICAgICB9KSxcbiAgICAgICk7XG4gIH1cblxuICAvLyBTYXZlcyB0aGUgc2NyZWVuIG92ZXIgdGhlIG9wZW4gdmlldywga2VlcGluZyB0aGUga2V5cyB0aGlzIHZpZXdlciBkb2VzXG4gIC8vIG5vdCBrbm93ICh3aXRoU3RvcmVkS2V5cykuXG4gIHB1YmxpYyBzYXZlQ2hhbmdlcygpOiBPYnNlcnZhYmxlPFJlcG9ydFZpZXc+IHtcbiAgICBjb25zdCBvcGVuID0gdGhpcy5fb3BlblZpZXcoKTtcbiAgICBpZiAoIW9wZW4pIHtcbiAgICAgIHJldHVybiBFTVBUWTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fcmVwb3J0RGF0YS51cGRhdGVWaWV3KHRoaXMuX3JlcG9ydElkLCBvcGVuLmlkLCB7IGNvbmZpZzogd2l0aFN0b3JlZEtleXMob3Blbi5jb25maWcsIHRoaXMuX2ZpbHRlclN0YXRlLnNuYXBzaG90KCkpIH0pXG4gICAgICAucGlwZShcbiAgICAgICAgdGFwKChzYXZlZCkgPT4ge1xuICAgICAgICAgIHRoaXMuX29wZW5WaWV3LnNldChzYXZlZCk7XG4gICAgICAgICAgdGhpcy5fcHV0Um93KHNhdmVkKTtcbiAgICAgICAgICB0aGlzLl9maWx0ZXJTdGF0ZS5zZXRCYXNlVG9TY3JlZW4oKTtcbiAgICAgICAgICB0aGlzLl9tZXNzYWdlLnN1Y2Nlc3MoJ1ZpZXcgc2F2ZWQnKTtcbiAgICAgICAgfSksXG4gICAgICApO1xuICB9XG5cbiAgcHVibGljIHJlbmFtZShuYW1lOiBzdHJpbmcpOiBPYnNlcnZhYmxlPFJlcG9ydFZpZXc+IHtcbiAgICByZXR1cm4gdGhpcy5fY2hhbmdlT3BlbigocmVwb3J0Vmlld0lkKSA9PiB0aGlzLl9yZXBvcnREYXRhLnVwZGF0ZVZpZXcodGhpcy5fcmVwb3J0SWQsIHJlcG9ydFZpZXdJZCwgeyBuYW1lIH0pKTtcbiAgfVxuXG4gIC8vIFNoYXJlcyB0aGUgb3BlbiB2aWV3IHdpdGggZXZlcnlvbmUgd2hvIG1heSBvcGVuIHRoZSByZXBvcnQsIG9yIHN0b3BzLlxuICBwdWJsaWMgc2hhcmUoc2hhcmVkOiBib29sZWFuKTogT2JzZXJ2YWJsZTxSZXBvcnRWaWV3PiB7XG4gICAgcmV0dXJuIHRoaXMuX2NoYW5nZU9wZW4oKHJlcG9ydFZpZXdJZCkgPT4gdGhpcy5fcmVwb3J0RGF0YS5zaGFyZVZpZXcodGhpcy5fcmVwb3J0SWQsIHJlcG9ydFZpZXdJZCwgc2hhcmVkKSk7XG4gIH1cblxuICAvLyBNYWtlcyB0aGUgb3BlbiB2aWV3IHRoZSB2aWV3ZXIncyBkZWZhdWx0LCBvciBzdG9wcyBvcGVuaW5nIGl0IGJ5IGRlZmF1bHQuXG4gIHB1YmxpYyBzZXREZWZhdWx0KHBlcnNvbmFsRGVmYXVsdDogYm9vbGVhbik6IE9ic2VydmFibGU8UmVwb3J0Vmlldz4ge1xuICAgIHJldHVybiB0aGlzLl9jaGFuZ2VPcGVuKChyZXBvcnRWaWV3SWQpID0+IHRoaXMuX3JlcG9ydERhdGEuc2V0Vmlld0RlZmF1bHQodGhpcy5fcmVwb3J0SWQsIHJlcG9ydFZpZXdJZCwgcGVyc29uYWxEZWZhdWx0KSk7XG4gIH1cblxuICAvLyBEZWxldGVzIHRoZSBvcGVuIHZpZXcuIFRoZSBzY3JlZW4gc3RheXM7IHRoZSByZXBvcnQncyBkZWZhdWx0cyBiZWNvbWVcbiAgLy8gd2hhdCBpdCBpcyBjb21wYXJlZCB3aXRoLlxuICBwdWJsaWMgZGVsZXRlT3BlbigpOiBPYnNlcnZhYmxlPFJlcG9ydFZpZXdEZWxldGVkPiB7XG4gICAgY29uc3Qgb3BlbiA9IHRoaXMuX29wZW5WaWV3KCk7XG4gICAgaWYgKCFvcGVuKSB7XG4gICAgICByZXR1cm4gRU1QVFk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3JlcG9ydERhdGEuZGVsZXRlVmlldyh0aGlzLl9yZXBvcnRJZCwgb3Blbi5pZClcbiAgICAgIC5waXBlKFxuICAgICAgICB0YXAoKCkgPT4ge1xuICAgICAgICAgIHRoaXMuX29wZW5WaWV3LnNldChudWxsKTtcbiAgICAgICAgICB0aGlzLl92aWV3cy51cGRhdGUoKHZpZXdzKSA9PiB2aWV3cy5maWx0ZXIoKHZpZXcpID0+IHZpZXcuaWQgIT09IG9wZW4uaWQpKTtcbiAgICAgICAgICB0aGlzLl9maWx0ZXJTdGF0ZS5jbGVhckJhc2UoKTtcbiAgICAgICAgICB0aGlzLl9tZXNzYWdlLnN1Y2Nlc3MoJ1ZpZXcgZGVsZXRlZCcpO1xuICAgICAgICB9KSxcbiAgICAgICk7XG4gIH1cblxuICAvLyBUaGUgcXVlcnkgcGFyYW1zIHRoYXQgbWFrZSB0aGUgVVJMIGNhcnJ5IHRoZSBzY3JlZW4gKHNlZSB0aGUgY2xhc3NcbiAgLy8gY29tbWVudCksIHNwcmVhZCBvdmVyIHRoZSBvd25lZCBrZXlzIGBjdXJyZW50YCBjYXJyaWVzIHNvIHRoZSBvbmVzIHRoZVxuICAvLyBzY3JlZW4gbm8gbG9uZ2VyIG5lZWRzIGFyZSByZW1vdmVkLiBUaGUgaG9zdCBhZGRzIGl0cyBwYWdlIGtleS5cbiAgLy8gQSBzZWxlY3QncyB2YWx1ZSBpcyBuYW1lZCBieSBgbmFtZWAsIGVsc2UgYnkgdGhlIG5hbWUgYGN1cnJlbnRgIGNhcnJpZXNcbiAgLy8gZm9yIGl0LlxuICBwdWJsaWMgdXJsUGFyYW1zKGN1cnJlbnQ6IFBhcmFtTWFwLCBuYW1lOiBSZXBvcnRVcmxWYWx1ZU5hbWUgPSAoKSA9PiBudWxsKTogUGFyYW1zIHtcbiAgICBjb25zdCBjdXJyZW50TmFtZSA9IHVybFZhbHVlTmFtZXMoY3VycmVudCwgdGhpcy5fcmVwb3J0R3JvdXBzKCkpO1xuICAgIGNvbnN0IHdyaXRlID0gdGhpcy5fbGlua1dyaXRlKChncm91cElkLCB2YWx1ZSkgPT4gbmFtZShncm91cElkLCB2YWx1ZSkgPz8gY3VycmVudE5hbWUoZ3JvdXBJZCwgdmFsdWUpKTtcblxuICAgIGlmICh3cml0ZS50b29Mb25nICYmICF0aGlzLl90b29Mb25nU2hvd24pIHtcbiAgICAgIHRoaXMuX3Rvb0xvbmdTaG93biA9IHRydWU7XG4gICAgICB0aGlzLl9tZXNzYWdlLndhcm5pbmcoVVJMX1RPT19MT05HX01FU1NBR0UpO1xuICAgIH1cblxuICAgIHJldHVybiB7IC4uLnJlcG9ydFBhcmFtc1RvQ2xlYXIoY3VycmVudCwgdGhpcy5fcmVwb3J0R3JvdXBzKCkpLCAuLi53cml0ZS5wYXJhbXMgfTtcbiAgfVxuXG4gIC8vIFN0YXJ0cyBvdmVyIGZvciBhbm90aGVyIHJlcG9ydDogbm8gbGlzdCBhbmQgbm8gb3BlbiB2aWV3LlxuICBwcml2YXRlIF9zdGFydChyZXBvcnQ6IFJlcG9ydCk6IHZvaWQge1xuICAgIGlmIChyZXBvcnQuaWQgPT09IHRoaXMuX3JlcG9ydElkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fcmVwb3J0SWQgPSByZXBvcnQuaWQ7XG4gICAgdGhpcy5fdmlld3Muc2V0KFtdKTtcbiAgICB0aGlzLl9jYW5TaGFyZS5zZXQoZmFsc2UpO1xuICAgIHRoaXMuX29wZW5WaWV3LnNldChudWxsKTtcbiAgICB0aGlzLl90b29Mb25nU2hvd24gPSBmYWxzZTtcbiAgfVxuXG4gIC8vIE5vIGxpbms6IHRoZSB2aWV3ZXIncyBkZWZhdWx0IHZpZXcsIGVsc2UgdGhlIHJlcG9ydCdzIGRlZmF1bHRzLCBvbmNlIHRoZVxuICAvLyBsaXN0IGlzIHJlYWQuXG4gIHByaXZhdGUgX29wZW5EZWZhdWx0KHJlcG9ydDogUmVwb3J0LCBwYWdlOiBSZXBvcnRWaWV3Q29uZmlnIHwgbnVsbCk6IE9ic2VydmFibGU8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLl9yZWFkVmlld3MocmVwb3J0KVxuICAgICAgLnBpcGUoXG4gICAgICAgIHRhcCgobGlzdCkgPT4ge1xuICAgICAgICAgIHRoaXMuX2ZpbHRlclN0YXRlLmluaXQocmVwb3J0KTtcbiAgICAgICAgICBpZiAobGlzdD8ubXlEZWZhdWx0KSB7XG4gICAgICAgICAgICB0aGlzLl9vcGVuT24obGlzdC5teURlZmF1bHQsICgpID0+IHRoaXMuX2ZpbHRlclN0YXRlLmFwcGx5KGxpc3QubXlEZWZhdWx0LmNvbmZpZywgcGFnZSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSksXG4gICAgICAgIG1hcCgoKSA9PiB1bmRlZmluZWQpLFxuICAgICAgKTtcbiAgfVxuXG4gIC8vIEEgbGluayB3aXRoIHN0YXRlOiBvbiB0aGUgc2hhcmVkIHZpZXcgcnYgbmFtZXMsIGVsc2Ugb24gdGhlIHJlcG9ydCdzXG4gIC8vIGRlZmF1bHRzOyBycHYncyB2aWV3IGlzIHRoZSBvcGVuIHZpZXcgb25seSB3aGVuIHRoZSB2aWV3ZXIgb3ducyBpdC5cbiAgcHJpdmF0ZSBfb3BlbkxpbmsobGluazogUmVwb3J0VXJsTGluaywgdmlldzogUmVwb3J0VmlldyB8IG51bGwsIGxpbmtEaWZmOiBSZXBvcnRWaWV3Q29uZmlnKTogdm9pZCB7XG4gICAgaWYgKGxpbmsudmlld0lkICYmIHZpZXcpIHtcbiAgICAgIHRoaXMuX29wZW5Pbih2aWV3LCAoKSA9PiB0aGlzLl9maWx0ZXJTdGF0ZS5hcHBseSh2aWV3LmNvbmZpZywgbGlua0RpZmYpKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICghbGluay52aWV3SWQgJiYgdmlldz8ubWluZSkge1xuICAgICAgdGhpcy5fb3Blbk9uKHZpZXcsICgpID0+IHRoaXMuX2ZpbHRlclN0YXRlLmFwcGx5KG51bGwsIGxpbmtEaWZmLCB2aWV3LmNvbmZpZykpO1xuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fb3BlblZpZXcuc2V0KG51bGwpO1xuICAgIHRoaXMuX2ZpbHRlclN0YXRlLmFwcGx5KG51bGwsIGxpbmtEaWZmKTtcblxuICAgIGlmIChsaW5rLnZpZXdJZCkge1xuICAgICAgdGhpcy5fbWVzc2FnZS53YXJuaW5nKFZJRVdfTk9UX0FWQUlMQUJMRV9NRVNTQUdFKTtcbiAgICB9XG4gIH1cblxuICAvLyBNYWtlcyBgdmlld2AgdGhlIG9wZW4gdmlldywgcHV0cyBpdCBvbiBzY3JlZW4gKGBhcHBseVZpZXdgKSwgYW5kIHNheXNcbiAgLy8gaG93IG1hbnkgb2YgaXRzIHNldHRpbmdzIG5vIGxvbmdlciBhcHBseSAoYW5kIHRvIHNhdmUgaXQsIHdoZW4gdGhlXG4gIC8vIHZpZXdlciBtYXkpLlxuICBwcml2YXRlIF9vcGVuT24odmlldzogUmVwb3J0VmlldywgYXBwbHlWaWV3OiAoKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgdGhpcy5fb3BlblZpZXcuc2V0KHZpZXcpO1xuICAgIGFwcGx5VmlldygpO1xuXG4gICAgY29uc3Qgbm90ZSA9IHZpZXdEcm9wcGVkTWVzc2FnZSh2aWV3RHJvcHBlZENvdW50KHZpZXcsIHRoaXMuX2ZpbHRlclN0YXRlLmJhc2UoKSksIHZpZXcuY2FuQ2hhbmdlKTtcbiAgICBpZiAobm90ZSkge1xuICAgICAgdGhpcy5fbWVzc2FnZS53YXJuaW5nKG5vdGUpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFJ1bnMgYSBjaGFuZ2Ugb24gdGhlIG9wZW4gdmlldyBhbmQgdGFrZXMgaXRzIGFuc3dlciBhcyB0aGUgb3BlbiB2aWV3XG4gIC8vIGFuZCBpdHMgcm93IGluIHRoZSBsaXN0LiBBIGNoYW5nZSBvZiB3aG8gbWF5IHNlZSB0aGUgdmlldyAoc2hhcmVkLCBvclxuICAvLyB3aG9zZSBpdCBpcykgY2hhbmdlcyB0aGUga2V5IGEgbGluayBuYW1lcyBpdCBieSwgc28gdGhlIFVSTCBpcyB3cml0dGVuXG4gIC8vIGFnYWluLlxuICBwcml2YXRlIF9jaGFuZ2VPcGVuKGNoYW5nZTogKHJlcG9ydFZpZXdJZDogbnVtYmVyKSA9PiBPYnNlcnZhYmxlPFJlcG9ydFZpZXc+KTogT2JzZXJ2YWJsZTxSZXBvcnRWaWV3PiB7XG4gICAgY29uc3Qgb3BlbiA9IHRoaXMuX29wZW5WaWV3KCk7XG4gICAgaWYgKCFvcGVuKSB7XG4gICAgICByZXR1cm4gRU1QVFk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNoYW5nZShvcGVuLmlkKVxuICAgICAgLnBpcGUoXG4gICAgICAgIHRhcCgodmlldykgPT4ge1xuICAgICAgICAgIHRoaXMuX29wZW5WaWV3LnNldCh2aWV3KTtcbiAgICAgICAgICB0aGlzLl9wdXRSb3codmlldyk7XG5cbiAgICAgICAgICBpZiAodmlldy5zaGFyZWQgIT09IG9wZW4uc2hhcmVkIHx8IHZpZXcubWluZSAhPT0gb3Blbi5taW5lKSB7XG4gICAgICAgICAgICB0aGlzLl9maWx0ZXJTdGF0ZS5yZXdyaXRlVXJsKCk7XG4gICAgICAgICAgfVxuICAgICAgICB9KSxcbiAgICAgICk7XG4gIH1cblxuICAvLyBBIHZpZXcncyByb3cgaW4gdGhlIGxpc3QsIHJlcGxhY2VkIG9yIGFkZGVkLiBBIG5ldyBkZWZhdWx0IGNsZWFycyB0aGVcbiAgLy8gZmxhZyBvbiB0aGUgdmlld2VyJ3Mgb3RoZXIgdmlld3MsIGFzIHRoZSBzZXJ2ZXIgZG9lcy4gQSBuZXcgcm93IGtlZXBzXG4gIC8vIHRoZSBsaXN0J3Mgb3JkZXI6IHRoZSB2aWV3ZXIncyBvd24gdmlld3MgZmlyc3QsIHRoZW4gdGhlIG9uZXMgb3RoZXJzXG4gIC8vIHNoYXJlLlxuICBwcml2YXRlIF9wdXRSb3codmlldzogUmVwb3J0Vmlldyk6IHZvaWQge1xuICAgIGNvbnN0IHN1bW1hcnkgPSB2aWV3U3VtbWFyeSh2aWV3KTtcblxuICAgIHRoaXMuX3ZpZXdzLnVwZGF0ZSgodmlld3MpID0+IHtcbiAgICAgIGNvbnN0IHJvd3MgPSB2aWV3cy5tYXAoKHJvdykgPT4gKHZpZXcucGVyc29uYWxEZWZhdWx0ICYmIHJvdy5wZXJzb25hbERlZmF1bHQgPyB7IC4uLnJvdywgcGVyc29uYWxEZWZhdWx0OiBmYWxzZSB9IDogcm93KSk7XG4gICAgICBjb25zdCBpbmRleCA9IHJvd3MuZmluZEluZGV4KChyb3cpID0+IHJvdy5pZCA9PT0gdmlldy5pZCk7XG5cbiAgICAgIGlmIChpbmRleCA+PSAwKSB7XG4gICAgICAgIHJldHVybiByb3dzLm1hcCgocm93LCBhdCkgPT4gKGF0ID09PSBpbmRleCA/IHN1bW1hcnkgOiByb3cpKTtcbiAgICAgIH1cblxuICAgICAgY29uc3Qgb3RoZXJzQXQgPSB2aWV3Lm1pbmUgPyByb3dzLmZpbmRJbmRleCgocm93KSA9PiAhcm93Lm1pbmUpIDogLTE7XG5cbiAgICAgIHJldHVybiBvdGhlcnNBdCA8IDBcbiAgICAgICAgPyBbLi4ucm93cywgc3VtbWFyeV1cbiAgICAgICAgOiBbLi4ucm93cy5zbGljZSgwLCBvdGhlcnNBdCksIHN1bW1hcnksIC4uLnJvd3Muc2xpY2Uob3RoZXJzQXQpXTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIFRoZSBsaXN0LCByZWFkIGZvciBgcmVwb3J0YDsgbnVsbCB3aGVuIGl0IGNhbm5vdCBiZSByZWFkLiBJdHMgYW5zd2VyIGlzXG4gIC8vIGtlcHQgb25seSB3aGlsZSB0aGUgcmVwb3J0IGlzIHN0aWxsIHRoZSBvcGVuIG9uZS5cbiAgcHJpdmF0ZSBfcmVhZFZpZXdzKHJlcG9ydDogUmVwb3J0KTogT2JzZXJ2YWJsZTxSZXBvcnRWaWV3cyB8IG51bGw+IHtcbiAgICByZXR1cm4gdGhpcy5fcmVwb3J0RGF0YS52aWV3cyhyZXBvcnQuaWQsIHsgY29udGV4dDogbmV3IEh0dHBDb250ZXh0KCkuc2V0KERpc3BsYXlBcGlFcnJvciwgZmFsc2UpIH0pXG4gICAgICAucGlwZShcbiAgICAgICAgY2F0Y2hFcnJvcigoKSA9PiBvZihudWxsKSksXG4gICAgICAgIHRhcCgobGlzdCkgPT4ge1xuICAgICAgICAgIGlmIChsaXN0ICYmIHJlcG9ydC5pZCA9PT0gdGhpcy5fcmVwb3J0SWQpIHtcbiAgICAgICAgICAgIHRoaXMuX3ZpZXdzLnNldChsaXN0LnZpZXdzID8/IFtdKTtcbiAgICAgICAgICAgIHRoaXMuX2NhblNoYXJlLnNldCghIWxpc3QuY2FuU2hhcmUpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSksXG4gICAgICApO1xuICB9XG5cbiAgLy8gQSB2aWV3IGEgbGluayBuYW1lczsgbnVsbCB3aGVuIHRoZSB2aWV3ZXIgY2Fubm90IG9wZW4gaXQuIFRoZSBzZXJ2ZXJcbiAgLy8gYW5zd2VycyAnVmlldyBub3QgZm91bmQnIGZvciBvbmUgaXQgY2Fubm90IHNlZSwgd2hpY2ggbXVzdCBub3QgbW92ZSB0aGVcbiAgLy8gaG9zdCB0byBpdHMgbm90LWZvdW5kIHBhZ2UuXG4gIHByaXZhdGUgX3JlYWRWaWV3KHJlcG9ydElkOiBudW1iZXIsIHJlcG9ydFZpZXdJZDogbnVtYmVyKTogT2JzZXJ2YWJsZTxSZXBvcnRWaWV3IHwgbnVsbD4ge1xuICAgIHJldHVybiB0aGlzLl9yZXBvcnREYXRhLnZpZXcocmVwb3J0SWQsIHJlcG9ydFZpZXdJZCwgeyBjb250ZXh0OiBuZXcgSHR0cENvbnRleHQoKS5zZXQoUHJvY2Vzc0FwaUVycm9yLCBmYWxzZSkgfSlcbiAgICAgIC5waXBlKGNhdGNoRXJyb3IoKCkgPT4gb2YobnVsbCkpKTtcbiAgfVxuXG4gIC8vIFRoZSBwYXJhbXMgdGhlIHNjcmVlbiB3cml0ZXMgKHNlZSB0aGUgY2xhc3MgY29tbWVudCkuXG4gIHByaXZhdGUgX2xpbmtXcml0ZShuYW1lOiBSZXBvcnRVcmxWYWx1ZU5hbWUpOiBSZXBvcnRVcmxXcml0ZSB7XG4gICAgY29uc3Qgb3BlbiA9IHRoaXMuX29wZW5WaWV3KCk7XG4gICAgY29uc3Qgc2NyZWVuID0gdGhpcy5fZmlsdGVyU3RhdGUuc25hcHNob3QoKTtcbiAgICBjb25zdCBhdXRob3JlZCA9IHRoaXMuX2ZpbHRlclN0YXRlLmF1dGhvcmVkQ29uZmlnKCk7XG4gICAgY29uc3QgYXV0aG9yZWRTb3J0ID0gKGNvbXBvbmVudElkOiBudW1iZXIpID0+IHRoaXMuX2F1dGhvcmVkU29ydChjb21wb25lbnRJZCk7XG5cbiAgICBpZiAob3Blbj8uc2hhcmVkKSB7XG4gICAgICAvLyBBIGdyb3VwIHRoZSB2aWV3IGhvbGRzIHRoYXQgdGhlIGJhc2UgbGV0IGdvIG9mIChpdHMgYXV0aG9yZWQgZGVmYXVsdFxuICAgICAgLy8gY2hhbmdlZCB3aGlsZSB0aGUgdmlldyB3YXMgb3BlbiwgYW5kIHRoZSBzY3JlZW4gdG9vayB0aGUgbmV3IG9uZSlcbiAgICAgIC8vIGlzIHN0aWxsIHRoZSB2aWV3J3MgdmFsdWUgd2hlbiBhIGxpbmsgb3BlbnMgdGhlIHZpZXcsIHNvIGl0IGlzXG4gICAgICAvLyBjb21wYXJlZCB3aXRoIHRoYXQgdmFsdWUgYW5kIHdyaXR0ZW4gd2hlbiB0aGUgc2NyZWVuIGRpZmZlcnMuXG4gICAgICBjb25zdCBiYXNlID0gdGhpcy5fZmlsdGVyU3RhdGUuYmFzZSgpO1xuICAgICAgY29uc3QgbGlua0Jhc2U6IFJlcG9ydFZpZXdDb25maWcgPSB7IC4uLmJhc2UsIGdyb3VwczogeyAuLi5vcGVuLmNvbmZpZz8uZ3JvdXBzLCAuLi5iYXNlLmdyb3VwcyB9IH07XG4gICAgICBjb25zdCBkaWZmID0gdmlld0NvbmZpZ0RpZmYobGlua0Jhc2UsIHNjcmVlbiwgYXV0aG9yZWQsIGF1dGhvcmVkU29ydCk7XG5cbiAgICAgIGlmIChkaWZmKSB7XG4gICAgICAgIHJldHVybiB2aWV3Q29uZmlnVG9QYXJhbXModGhpcy5fbGlua0RheXMoZGlmZiksIHRoaXMuX3JlcG9ydEdyb3VwcygpLCB7IHZpZXdJZDogb3Blbi5pZCB9LCBuYW1lKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBmdWxsID0gdmlld0NvbmZpZ0RpZmYoYXV0aG9yZWQsIHNjcmVlbiwgYXV0aG9yZWQsIGF1dGhvcmVkU29ydCkgPz8gc2NyZWVuO1xuXG4gICAgY29uc3QgbGluayA9IG9wZW4/Lm1pbmUgPyB7IHBlcnNvbmFsVmlld0lkOiBvcGVuLmlkIH0gOiB7fTtcblxuICAgIHJldHVybiB2aWV3Q29uZmlnVG9QYXJhbXModGhpcy5fbGlua0RheXMoZnVsbCksIHRoaXMuX3JlcG9ydEdyb3VwcygpLCBsaW5rLCBuYW1lKTtcbiAgfVxuXG4gIC8vIGBjb25maWdgIHdpdGggZWFjaCByb2xsaW5nIHJhbmdlIChhIHJlbGF0aXZlIG5hbWUsIHdoaWNoIGEgdmlldyBrZWVwcykgYXNcbiAgLy8gdGhlIGRheXMgaXQgZ2l2ZXMgdG9kYXkgaW4gdGhlIHJlcG9ydCdzIHpvbmU6IGEgbGluayBjYXJyaWVzIGRheXMsIG5ldmVyIGFcbiAgLy8gcHJlc2V0IG5hbWUuIEEgbmFtZSB0aGUgcmVwb3J0IGRvZXMgbm90IGtub3cgaXMgbGVmdCBhcyBpdCBpcywgYW5kIHRoZVxuICAvLyBsaW5rIGxlYXZlcyB0aGF0IGdyb3VwIG91dC5cbiAgcHJpdmF0ZSBfbGlua0RheXMoY29uZmlnOiBSZXBvcnRWaWV3Q29uZmlnKTogUmVwb3J0Vmlld0NvbmZpZyB7XG4gICAgaWYgKCFjb25maWcuZ3JvdXBzKSB7XG4gICAgICByZXR1cm4gY29uZmlnO1xuICAgIH1cblxuICAgIGNvbnN0IGdyb3VwcyA9IE9iamVjdC5lbnRyaWVzKGNvbmZpZy5ncm91cHMpXG4gICAgICAubWFwKChbZ3JvdXBJZCwgdmFsdWVdKSA9PiBbZ3JvdXBJZCwgdGhpcy5fZ3JvdXBEYXlzKHZhbHVlKV0pO1xuXG4gICAgcmV0dXJuIHsgLi4uY29uZmlnLCBncm91cHM6IE9iamVjdC5mcm9tRW50cmllcyhncm91cHMpIH07XG4gIH1cblxuICBwcml2YXRlIF9ncm91cERheXModmFsdWU6IEZpbHRlckdyb3VwRGVmYXVsdCB8IG51bGwpOiBGaWx0ZXJHcm91cERlZmF1bHQgfCBudWxsIHtcbiAgICBjb25zdCByYW5nZSA9IHZhbHVlPy5yZWxhdGl2ZSA/IHRoaXMuX2ZpbHRlclN0YXRlLnJlc29sdmVSZWxhdGl2ZSh2YWx1ZS5yZWxhdGl2ZSkgOiBudWxsO1xuXG4gICAgcmV0dXJuIHJhbmdlID8gdG9TdG9yZWRHcm91cFZhbHVlKCdkYXRlUmFuZ2UnLCB7IHN0YXJ0OiByYW5nZS5zdGFydCwgZW5kOiByYW5nZS5lbmQgfSkgOiB2YWx1ZTtcbiAgfVxuXG4gIC8vIEV2ZXJ5IGZpbHRlciBncm91cCBvZiB0aGUgb3BlbiByZXBvcnQ6IHRoZSBsaW5rIGtleXMgZWFjaCBieSBpdHMgbGFiZWwuXG4gIHByaXZhdGUgX3JlcG9ydEdyb3VwcygpOiBSZXBvcnRGaWx0ZXJHcm91cFtdIHtcbiAgICByZXR1cm4gdGhpcy5fZmlsdGVyU3RhdGUucmVwb3J0KCk/LmZpbHRlckdyb3VwcyA/PyBbXTtcbiAgfVxuXG4gIC8vIEEgbGlzdCdzIGF1dGhvcmVkIGZpcnN0IHNvcnQgdGVybSwgb3IgbnVsbCBmb3IgYW55IG90aGVyIGNvbXBvbmVudC5cbiAgcHJpdmF0ZSBfYXV0aG9yZWRTb3J0KGNvbXBvbmVudElkOiBudW1iZXIpOiBSZXBvcnRTb3J0IHwgbnVsbCB7XG4gICAgY29uc3QgcmVwb3J0ID0gdGhpcy5fZmlsdGVyU3RhdGUucmVwb3J0KCk7XG4gICAgY29uc3QgY29tcG9uZW50ID0gW1xuICAgICAgLi4uKHJlcG9ydD8ucGFnZXMgPz8gW10pLmZsYXRNYXAoKHBhZ2UpID0+IHBhZ2UuY29tcG9uZW50cyA/PyBbXSksXG4gICAgICAuLi4ocmVwb3J0Py5tYXN0ZXI/LmNvbXBvbmVudHMgPz8gW10pLFxuICAgIF0uZmluZCgoY2FuZGlkYXRlKSA9PiBjYW5kaWRhdGUuaWQgPT09IGNvbXBvbmVudElkKTtcblxuICAgIHJldHVybiBjb21wb25lbnQ/LnR5cGUgPT09ICdsaXN0JyA/IGxpc3RTb3J0VGVybXMoY29tcG9uZW50LmNvbmZpZylbMF0gPz8gbnVsbCA6IG51bGw7XG4gIH1cbn1cblxuXG4vLyBBIHZpZXcncyByb3cgYXMgdGhlIGxpc3QgaG9sZHMgaXQ6IG5hbWVzIGFuZCBmbGFncywgbm8gY29uZmlnLlxuZnVuY3Rpb24gdmlld1N1bW1hcnkodmlldzogUmVwb3J0Vmlldyk6IFJlcG9ydFZpZXdTdW1tYXJ5IHtcbiAgcmV0dXJuIHtcbiAgICBpZDogdmlldy5pZCxcbiAgICBuYW1lOiB2aWV3Lm5hbWUsXG4gICAgc2hhcmVkOiB2aWV3LnNoYXJlZCxcbiAgICBtaW5lOiB2aWV3Lm1pbmUsXG4gICAgcGVyc29uYWxEZWZhdWx0OiB2aWV3LnBlcnNvbmFsRGVmYXVsdCxcbiAgICBvd25lck5hbWU6IHZpZXcub3duZXJOYW1lLFxuICAgIGNhbkNoYW5nZTogdmlldy5jYW5DaGFuZ2UsXG4gICAgY2FuRGVsZXRlOiB2aWV3LmNhbkRlbGV0ZSxcbiAgICBtb2RpZnlEYXRlOiB2aWV3Lm1vZGlmeURhdGUsXG4gIH07XG59XG4iXX0=