@firestitch/report 18.5.0 → 18.6.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 (63) hide show
  1. package/app/reports/components/component-kpi/component-kpi.component.d.ts +2 -1
  2. package/app/reports/components/component-list/component-list.component.d.ts +3 -7
  3. package/app/reports/components/report-canvas/report-canvas.component.d.ts +5 -4
  4. package/app/reports/components/report-component/report-component.component.d.ts +7 -6
  5. package/app/reports/components/timezone-select/timezone-select.component.d.ts +4 -6
  6. package/app/reports/consts/report-week.const.d.ts +2 -0
  7. package/app/reports/data/report-ai-chat.data.d.ts +12 -0
  8. package/app/reports/data/report.data.d.ts +3 -3
  9. package/app/reports/dialogs/component-settings/component-settings.component.d.ts +6 -6
  10. package/app/reports/dialogs/report-settings/report-settings.component.d.ts +5 -0
  11. package/app/reports/export/report-export-collector.service.d.ts +14 -2
  12. package/app/reports/export/report-pdf.service.d.ts +14 -1
  13. package/app/reports/export/report-pptx.service.d.ts +2 -1
  14. package/app/reports/format.d.ts +8 -1
  15. package/app/reports/interfaces/report-chat-viewer-filter.interface.d.ts +7 -0
  16. package/app/reports/interfaces/report-chat-viewer-state.interface.d.ts +7 -0
  17. package/app/reports/interfaces/report.interface.d.ts +18 -2
  18. package/app/reports/option-builder.d.ts +2 -1
  19. package/app/reports/pipes/report-date.pipe.d.ts +7 -0
  20. package/app/reports/report-filter-items.d.ts +5 -0
  21. package/app/reports/report-url-state.d.ts +15 -0
  22. package/app/reports/services/report-filter-state.service.d.ts +27 -2
  23. package/app/reports/theme/typography.d.ts +2 -0
  24. package/app/reports/views/report/fs-ai-report.component.d.ts +16 -8
  25. package/app/reports/views/report/report.component.d.ts +6 -6
  26. package/esm2022/app/reports/components/component-kpi/component-kpi.component.mjs +7 -4
  27. package/esm2022/app/reports/components/component-list/component-list.component.mjs +34 -131
  28. package/esm2022/app/reports/components/report-canvas/report-canvas.component.mjs +57 -44
  29. package/esm2022/app/reports/components/report-component/report-component.component.mjs +57 -35
  30. package/esm2022/app/reports/components/timezone-select/timezone-select.component.mjs +23 -23
  31. package/esm2022/app/reports/consts/report-week.const.mjs +7 -0
  32. package/esm2022/app/reports/data/report-ai-chat.data.mjs +25 -0
  33. package/esm2022/app/reports/data/report.data.mjs +22 -9
  34. package/esm2022/app/reports/dialogs/component-settings/component-settings.component.mjs +25 -26
  35. package/esm2022/app/reports/dialogs/global-settings/global-settings.component.mjs +2 -2
  36. package/esm2022/app/reports/dialogs/report-settings/report-settings.component.mjs +38 -13
  37. package/esm2022/app/reports/export/report-export-collector.service.mjs +95 -29
  38. package/esm2022/app/reports/export/report-export.service.mjs +11 -8
  39. package/esm2022/app/reports/export/report-pdf.service.mjs +245 -84
  40. package/esm2022/app/reports/export/report-pptx.service.mjs +64 -48
  41. package/esm2022/app/reports/format.mjs +126 -9
  42. package/esm2022/app/reports/interfaces/report-chat-viewer-filter.interface.mjs +2 -0
  43. package/esm2022/app/reports/interfaces/report-chat-viewer-state.interface.mjs +2 -0
  44. package/esm2022/app/reports/interfaces/report.interface.mjs +1 -1
  45. package/esm2022/app/reports/option-builder.mjs +146 -15
  46. package/esm2022/app/reports/pipes/report-date.pipe.mjs +21 -0
  47. package/esm2022/app/reports/report-filter-items.mjs +42 -10
  48. package/esm2022/app/reports/report-url-state.mjs +148 -0
  49. package/esm2022/app/reports/services/report-filter-state.service.mjs +339 -64
  50. package/esm2022/app/reports/theme/echarts.mjs +6 -5
  51. package/esm2022/app/reports/theme/typography.mjs +6 -0
  52. package/esm2022/app/reports/views/report/fs-ai-report.component.mjs +198 -90
  53. package/esm2022/app/reports/views/report/report.component.mjs +68 -62
  54. package/fesm2022/{firestitch-report-echarts-CtKYuRcT.mjs → firestitch-report-echarts-Djtmaxj1.mjs} +6 -6
  55. package/fesm2022/firestitch-report-echarts-Djtmaxj1.mjs.map +1 -0
  56. package/fesm2022/{firestitch-report-firestitch-report-Df1IXrEs.mjs → firestitch-report-firestitch-report-D3zseBZc.mjs} +1781 -738
  57. package/fesm2022/firestitch-report-firestitch-report-D3zseBZc.mjs.map +1 -0
  58. package/fesm2022/firestitch-report.mjs +1 -1
  59. package/package.json +1 -1
  60. package/app/reports/dialogs/report-settings/report-settings-default.d.ts +0 -2
  61. package/esm2022/app/reports/dialogs/report-settings/report-settings-default.mjs +0 -22
  62. package/fesm2022/firestitch-report-echarts-CtKYuRcT.mjs.map +0 -1
  63. package/fesm2022/firestitch-report-firestitch-report-Df1IXrEs.mjs.map +0 -1
@@ -1,8 +1,12 @@
1
- import { Injectable } from '@angular/core';
1
+ import { Injectable, signal } from '@angular/core';
2
2
  import { Subject } from 'rxjs';
3
3
  import { filter as rxFilter } from 'rxjs/operators';
4
4
  import { endOfWeek, startOfMonth, startOfQuarter, startOfWeek, startOfYear, subDays, subMonths, subWeeks, } from 'date-fns';
5
+ import { REPORT_WEEK_STARTS_ON } from '../consts/report-week.const';
6
+ import { getZonedNow, resolveReportTimezone } from '../format';
7
+ import { GRANULARITY_OPTIONS, } from '../interfaces/report.interface';
5
8
  import { dateBoundString } from '../report-filter-items';
9
+ import { decodeFilterValue, decodeSort } from '../report-url-state';
6
10
  import * as i0 from "@angular/core";
7
11
  // Whether two stored filter-group defaults are the same. Compared on the fields a
8
12
  // default can actually carry, so key order in the payload can't read as a change.
@@ -17,6 +21,18 @@ export function sameDefault(a, b) {
17
21
  && (a.values ?? []).length === (b.values ?? []).length
18
22
  && (a.values ?? []).every((value, index) => value === (b.values ?? [])[index]);
19
23
  }
24
+ // Whether two list sorts order the rows the same way. No direction reads as
25
+ // ascending, the way the list applies it.
26
+ function sameSort(a, b) {
27
+ return !!b
28
+ && a.column === b.column
29
+ && (a.direction ?? 'asc') === (b.direction ?? 'asc');
30
+ }
31
+ // Whether two date-range values cover the same calendar days.
32
+ function sameDays(a, b) {
33
+ return dateBoundString(a.start) === dateBoundString(b.start)
34
+ && dateBoundString(a.end) === dateBoundString(b.end);
35
+ }
20
36
  // A stable signature for a group's stored default. The report toolbar keys its
21
37
  // fs-filter on this, because fs-filter reads its config once at init — without a
22
38
  // key change it keeps rendering the values it was created with even after the
@@ -34,72 +50,107 @@ export function defaultSignature(group) {
34
50
  (groupDefault.values ?? []).join(','),
35
51
  ].join('~');
36
52
  }
37
- // Session filter state for the open report. Filter VALUES are never persisted
38
- // — this service holds them per filter GROUP (the propagation unit), resolves
39
- // them into per-component member-filter values for each data request, and
40
- // notifies the components whose groups changed so only they refetch.
53
+ // Viewer filter state for the open report. Filter VALUES are never saved to
54
+ // the report — this service holds them per filter GROUP (the propagation unit),
55
+ // resolves them into per-component member-filter values for each data request,
56
+ // and notifies the components whose groups changed so only they refetch.
57
+ //
58
+ // It is also the one source of the viewer state the report URL carries (group
59
+ // values, the group-by grain, list sorts): urlSnapshot() says what differs from
60
+ // the authored defaults, init() restores it, and urlChanges() tells the host's
61
+ // single URL writer when to write.
41
62
  //
42
- // Also session-scoped: per-filter enable/disable toggles from a component's
43
- // filter menu (the `enabled` column is the authored default; a viewer's toggle
44
- // shouldn't write to the report).
63
+ // Session-only, never in the URL: per-filter enable/disable toggles from a
64
+ // component's filter menu (the `enabled` column is the authored default; a
65
+ // viewer's toggle shouldn't write to the report).
45
66
  export class ReportFilterStateService {
67
+ // The open report's effective zone (resolveReportTimezone). Relative presets
68
+ // resolve against today in it, and date cells render in it.
69
+ timezone = signal('UTC');
46
70
  _values = new Map();
47
71
  _groups = new Map();
48
72
  _sessionDisabled = new Set();
49
- // The report's group-by control: a single session-wide bucket override for all
73
+ // Groups that have a default the viewer cleared. Without this a reload of the
74
+ // report (a chat edit, a dialog) would find no value for the group and seed
75
+ // its default straight back. A change to the stored default releases it.
76
+ _cleared = new Set();
77
+ // The report's group-by control: a single report-wide bucket override for all
50
78
  // time-series charts. Unset = each chart uses its authored granularity. Never
51
- // persisted (it dies with this report view), and carried in the data request's
79
+ // saved to the report (the URL carries it), and carried in the data request's
52
80
  // `state`, so it propagates through to the PDF/PowerPoint exports too. Named
53
81
  // for the `frequency` wire key it travels under, not for the control's label.
54
82
  _frequency = null;
55
83
  _frequencyChanged$ = new Subject();
84
+ // Each list's viewer-chosen sort, by component id. Held here rather than only
85
+ // in the list's FsList so it survives the list being recreated (a page switch,
86
+ // a reload after an edit) and so every consumer of viewer state reads one place.
87
+ _listSorts = new Map();
56
88
  // Emits the group id that changed; components listen filtered to their own
57
89
  // group ids. null = everything changed (re-init).
58
90
  _changed$ = new Subject();
91
+ // Fires whenever anything the URL carries may have changed.
92
+ _urlChanged$ = new Subject();
59
93
  // Seed groups + their defaults when a report loads. Existing session values
60
94
  // for still-existing groups survive a structure re-fetch (a chat edit
61
- // shouldn't reset the viewer's filters) — UNLESS the group's stored default
62
- // itself changed, which only happens when an operator saved a new default in
63
- // report settings. That is an explicit instruction to re-seed, so it wins over
64
- // the surviving session value; without it the bar keeps showing whatever it was
65
- // first seeded with until a full page reload.
66
- init(report) {
95
+ // shouldn't reset the viewer's filters), and so does a group the viewer
96
+ // cleared — UNLESS the group's stored default itself changed, which only
97
+ // happens when an operator saved a new default in report settings or the
98
+ // agent set one. That is an explicit instruction to re-seed, so it wins over
99
+ // the surviving session value; without it the bar keeps showing whatever it
100
+ // was first seeded with until a full page reload.
101
+ //
102
+ // A change of the report's zone moves "today", so a value still carrying its
103
+ // group default's preset name is resolved again in the new zone. A value the
104
+ // viewer picked, or one carrying another preset name, is kept as it is.
105
+ //
106
+ // `restore` is the viewer state read from the URL. The host passes it only on
107
+ // the first load of a report; a reload after a chat or dialog edit passes
108
+ // null, so the in-memory state wins. Params that name a group, list or column
109
+ // the report no longer has, or that do not decode, are ignored.
110
+ init(report, restore = null) {
111
+ const previousTimezone = this.timezone();
112
+ // Set first: the defaults seeded below resolve their relative presets in it.
113
+ this.timezone.set(resolveReportTimezone(report));
114
+ const timezoneChanged = previousTimezone !== this.timezone();
67
115
  const previousGroups = this._groups;
68
116
  this._groups = new Map();
69
- const validIds = new Set();
70
117
  for (const group of report.filterGroups ?? []) {
71
118
  this._groups.set(group.id, group);
72
- validIds.add(group.id);
73
- const defaultChanged = !sameDefault(previousGroups.get(group.id)?.config?.default ?? null, group.config?.default ?? null);
74
- if (!this._values.has(group.id) || defaultChanged) {
75
- const defaultValue = this._defaultValue(group);
76
- if (defaultValue) {
77
- this._values.set(group.id, defaultValue);
78
- }
79
- else if (defaultChanged) {
80
- // The default was cleared, so the value it seeded goes with it.
81
- this._values.delete(group.id);
82
- }
83
- }
119
+ this._seed(group, previousGroups.get(group.id) ?? null, timezoneChanged);
84
120
  }
85
- for (const groupId of [...this._values.keys()]) {
86
- if (!validIds.has(groupId)) {
87
- this._values.delete(groupId);
88
- }
121
+ if (restore) {
122
+ this._restore(report, restore);
89
123
  }
124
+ this._prune(report);
90
125
  this._changed$.next(null);
126
+ this._urlChanged$.next();
91
127
  }
92
128
  value(groupId) {
93
129
  return this._values.get(groupId);
94
130
  }
131
+ // A bar's value for a group. A date range keeps the stored preset name only
132
+ // while its days are still the stored days: the bars re-set every group they
133
+ // show whenever any one of them changes, and an untouched rolling range must
134
+ // keep its name rather than turn into two fixed dates. Any other range, a
135
+ // picker shortcut included, is stored as the fixed dates it shows.
95
136
  setValue(groupId, value) {
96
137
  if (value === null) {
97
138
  this._values.delete(groupId);
139
+ if (this._groups.get(groupId)?.config?.default) {
140
+ this._cleared.add(groupId);
141
+ }
98
142
  }
99
143
  else {
100
- this._values.set(groupId, value);
144
+ this._values.set(groupId, this._withPreset(this._values.get(groupId), value));
145
+ this._cleared.delete(groupId);
101
146
  }
102
147
  this._changed$.next(groupId);
148
+ this._urlChanged$.next();
149
+ }
150
+ // A relative preset name as today's range in the report's zone, or null for
151
+ // a name it does not know. The URL codec decodes preset names through this.
152
+ resolveRelative(name) {
153
+ return this._relativeRange(name);
103
154
  }
104
155
  // The active group-by grain, or null when the viewer hasn't chosen one.
105
156
  frequency() {
@@ -108,6 +159,7 @@ export class ReportFilterStateService {
108
159
  setFrequency(frequency) {
109
160
  this._frequency = frequency;
110
161
  this._frequencyChanged$.next();
162
+ this._urlChanged$.next();
111
163
  }
112
164
  // Fires whenever the group-by grain changes — every time-series chart listens
113
165
  // so it refetches and re-buckets (the override isn't scoped to any filter
@@ -115,6 +167,54 @@ export class ReportFilterStateService {
115
167
  frequencyChanges() {
116
168
  return this._frequencyChanged$.asObservable();
117
169
  }
170
+ // The sort the viewer last fetched a list with, or null when it hasn't sorted
171
+ // (the list then falls back to its authored sort).
172
+ listSort(componentId) {
173
+ return this._listSorts.get(componentId) ?? null;
174
+ }
175
+ // Records a list's sort. Deliberately emits no change: the list sets this from
176
+ // the fetch that already ran with that sort, so a notification would only make
177
+ // it refetch the same rows. Only the URL hears about it.
178
+ setListSort(componentId, sort) {
179
+ if (sort) {
180
+ this._listSorts.set(componentId, sort);
181
+ }
182
+ else {
183
+ this._listSorts.delete(componentId);
184
+ }
185
+ this._urlChanged$.next();
186
+ }
187
+ // Fires whenever the viewer state the URL carries may have changed: a group
188
+ // value, the grain, a list sort, or a (re)load of the report.
189
+ urlChanges() {
190
+ return this._urlChanged$.asObservable();
191
+ }
192
+ // The viewer state the URL should carry for `report`: only what differs from
193
+ // the authored defaults, so an untouched report has a bare URL and keeps
194
+ // following its defaults when they change. A group the viewer cleared is
195
+ // null. A date range is compared on its days against its default resolved
196
+ // today, so a value that is the default under another preset name (thisYear
197
+ // against a yearToDate default) is still the default.
198
+ urlSnapshot(report) {
199
+ const groups = new Map();
200
+ for (const group of this._groups.values()) {
201
+ const value = this._values.get(group.id);
202
+ if (this._cleared.has(group.id)) {
203
+ groups.set(group.id, null);
204
+ }
205
+ else if (value && !this._isDefault(group, value)) {
206
+ groups.set(group.id, value);
207
+ }
208
+ }
209
+ const listSorts = new Map();
210
+ for (const component of this._listComponents(report)) {
211
+ const sort = this._listSorts.get(component.id);
212
+ if (sort && !sameSort(sort, component.config?.sort ?? null)) {
213
+ listSorts.set(component.id, sort);
214
+ }
215
+ }
216
+ return { groups, listSorts, frequency: this._frequency };
217
+ }
118
218
  isFilterDisabled(filterId) {
119
219
  return this._sessionDisabled.has(filterId);
120
220
  }
@@ -144,28 +244,28 @@ export class ReportFilterStateService {
144
244
  continue;
145
245
  }
146
246
  const value = this._values.get(filter.filterGroupId);
147
- if (!value) {
148
- continue;
149
- }
150
- const entry = { filterId: filter.id };
151
- if (value.start) {
152
- entry.start = dateBoundString(value.start);
153
- }
154
- if (value.end) {
155
- entry.end = dateBoundString(value.end);
156
- }
157
- if (value.values?.length) {
158
- entry.values = value.values;
159
- }
160
- if (value.value?.trim()) {
161
- entry.value = value.value.trim();
162
- }
163
- if (entry.start || entry.end || entry.values || entry.value) {
164
- resolved.push(entry);
247
+ const fields = value ? this._resolvedFields(value) : null;
248
+ if (fields) {
249
+ resolved.push({ filterId: filter.id, ...fields });
165
250
  }
166
251
  }
167
252
  return resolved;
168
253
  }
254
+ // What the viewer has set, one entry per filter group, for the report chat:
255
+ // the agent reads it to know what is on screen. Group order, not the order
256
+ // the values were set in, so the same state always reads the same. A group
257
+ // with nothing in it is left out, and a saved default counts until the
258
+ // viewer changes it. Per-filter toggles are a component's own business, so
259
+ // they are not part of it.
260
+ viewerFilters() {
261
+ return [...this._values.entries()]
262
+ .sort(([a], [b]) => a - b)
263
+ .map(([groupId, value]) => {
264
+ const fields = this._resolvedFields(value);
265
+ return fields ? { groupId, ...fields } : null;
266
+ })
267
+ .filter((entry) => entry !== null);
268
+ }
169
269
  // Every component's resolved values in one array — what a report-level export
170
270
  // carries so each file in the archive is filtered exactly as the screen is.
171
271
  // Filter ids are unique per component, so the backend picks each component's
@@ -177,10 +277,179 @@ export class ReportFilterStateService {
177
277
  .flatMap((page) => (page.components ?? [])
178
278
  .flatMap((component) => this.resolveForComponent(component)));
179
279
  }
280
+ // A group value as the fields a request carries: date bounds as calendar
281
+ // days, select values when any are picked, keyword text trimmed. Null when
282
+ // all of them are empty. The preset name is URL state only, so it is left
283
+ // behind.
284
+ _resolvedFields(value) {
285
+ const fields = {};
286
+ if (value.start) {
287
+ fields.start = dateBoundString(value.start);
288
+ }
289
+ if (value.end) {
290
+ fields.end = dateBoundString(value.end);
291
+ }
292
+ if (value.values?.length) {
293
+ fields.values = value.values;
294
+ }
295
+ if (value.value?.trim()) {
296
+ fields.value = value.value.trim();
297
+ }
298
+ return fields.start || fields.end || fields.values || fields.value
299
+ ? fields
300
+ : null;
301
+ }
302
+ // Seeds one group on (re)load; see init(). `previous` is the group as the
303
+ // last load had it, or null when it is new.
304
+ _seed(group, previous, timezoneChanged) {
305
+ const defaultChanged = !sameDefault(previous?.config?.default ?? null, group.config?.default ?? null);
306
+ if (defaultChanged) {
307
+ this._cleared.delete(group.id);
308
+ }
309
+ if (this._cleared.has(group.id)) {
310
+ return;
311
+ }
312
+ const value = this._values.get(group.id);
313
+ const presetToResolve = timezoneChanged
314
+ && !!value?.preset
315
+ && value.preset === group.config?.default?.relative;
316
+ if (value && !defaultChanged && !presetToResolve) {
317
+ return;
318
+ }
319
+ const defaultValue = this._defaultValue(group);
320
+ if (defaultValue) {
321
+ this._values.set(group.id, defaultValue);
322
+ }
323
+ else if (defaultChanged) {
324
+ // The default was cleared, so the value it seeded goes with it.
325
+ this._values.delete(group.id);
326
+ }
327
+ }
328
+ // Applies the viewer state read from the URL on top of the seeded defaults.
329
+ _restore(report, restore) {
330
+ this._restoreGroups(restore);
331
+ this._restoreListSorts(report, restore);
332
+ // The URL is the whole truth on a first load: no grain in it means the
333
+ // authored ones. The host still drops a grain the report does not offer.
334
+ this._frequency = GRANULARITY_OPTIONS
335
+ .find((option) => option.value === restore.groupBy)?.value ?? null;
336
+ }
337
+ // The URL's group values. An empty one is an explicit clear of the group.
338
+ _restoreGroups(restore) {
339
+ restore.groups.forEach((raw, groupId) => {
340
+ const group = this._groups.get(groupId);
341
+ const value = group
342
+ ? decodeFilterValue(group.type, raw, (name) => this.resolveRelative(name))
343
+ : undefined;
344
+ if (value === null) {
345
+ this._values.delete(groupId);
346
+ if (group?.config?.default) {
347
+ this._cleared.add(groupId);
348
+ }
349
+ }
350
+ else if (value) {
351
+ this._values.set(groupId, value);
352
+ this._cleared.delete(groupId);
353
+ }
354
+ });
355
+ }
356
+ // The URL's list sorts, each kept only for a list the report has and a
357
+ // column that list can be sorted by.
358
+ _restoreListSorts(report, restore) {
359
+ const lists = new Map(this._listComponents(report).map((component) => [component.id, component]));
360
+ restore.listSorts.forEach((raw, componentId) => {
361
+ const component = lists.get(componentId);
362
+ const sort = decodeSort(raw);
363
+ if (component && sort && this._sortableColumns(component).includes(sort.column)) {
364
+ this._listSorts.set(componentId, sort);
365
+ }
366
+ });
367
+ }
368
+ // Drops state kept for groups, lists and filters the report no longer has.
369
+ // A list sort also goes when its column does: the agent can remove or rename
370
+ // it, and the recreated list would send a column the query does not know.
371
+ _prune(report) {
372
+ for (const groupId of [...this._values.keys(), ...this._cleared]) {
373
+ if (!this._groups.has(groupId)) {
374
+ this._values.delete(groupId);
375
+ this._cleared.delete(groupId);
376
+ }
377
+ }
378
+ const lists = new Map(this._listComponents(report).map((component) => [component.id, component]));
379
+ this._listSorts.forEach((sort, componentId) => {
380
+ const component = lists.get(componentId);
381
+ if (!component || !this._sortableColumns(component).includes(sort.column)) {
382
+ this._listSorts.delete(componentId);
383
+ }
384
+ });
385
+ const filterIds = new Set(this._components(report)
386
+ .flatMap((component) => (component.filters ?? []).map((filter) => filter.id)));
387
+ this._sessionDisabled.forEach((filterId) => {
388
+ if (!filterIds.has(filterId)) {
389
+ this._sessionDisabled.delete(filterId);
390
+ }
391
+ });
392
+ }
393
+ // The value a bar sets, keeping the stored preset name while the days are
394
+ // still the stored days (see setValue).
395
+ _withPreset(stored, value) {
396
+ const fixed = { ...value };
397
+ delete fixed.preset;
398
+ return stored?.preset && sameDays(stored, fixed)
399
+ ? { ...fixed, preset: stored.preset }
400
+ : fixed;
401
+ }
402
+ // Whether a value is the group's authored default, by type: a date range on
403
+ // its days (the default resolved today), a select on its values in any
404
+ // order, a keyword on its text.
405
+ _isDefault(group, value) {
406
+ const defaultValue = this._defaultValue(group);
407
+ if (!defaultValue) {
408
+ return false;
409
+ }
410
+ switch (group.type) {
411
+ case 'dateRange':
412
+ // An untouched rolling default still carries its preset name. Its days
413
+ // were resolved when it was seeded, and after midnight they no longer
414
+ // match today's, but it is still the default and stays out of the URL.
415
+ if (value.preset && value.preset === group.config?.default?.relative) {
416
+ return true;
417
+ }
418
+ return sameDays(value, defaultValue);
419
+ case 'select': {
420
+ const values = (value.values ?? []).map(String).sort();
421
+ const defaults = (defaultValue.values ?? []).map(String).sort();
422
+ return values.length === defaults.length
423
+ && values.every((item, index) => item === defaults[index]);
424
+ }
425
+ default:
426
+ return (value.value ?? '').trim() === (defaultValue.value ?? '').trim();
427
+ }
428
+ }
429
+ // Every component of the report: its pages' and its header and footer's.
430
+ _components(report) {
431
+ return [
432
+ ...(report.pages ?? []).flatMap((page) => page.components ?? []),
433
+ ...(report.master?.components ?? []),
434
+ ];
435
+ }
436
+ _listComponents(report) {
437
+ return this._components(report)
438
+ .filter((component) => component.type === 'list');
439
+ }
440
+ // The columns a list can be sorted by: every authored column, or a
441
+ // cross-tab's row column only (its pivot columns come and go with the data).
442
+ _sortableColumns(component) {
443
+ const config = component.config;
444
+ if (config?.pivotBy?.column) {
445
+ return config.rowBy?.column ? [config.rowBy.column] : [];
446
+ }
447
+ return (config?.columns ?? []).map((column) => column.column);
448
+ }
180
449
  // A group's authored default, mapped to a session value by type. Relative
181
450
  // date presets resolve against "now" each time the report opens, so a saved
182
- // "last 12 months" stays relative; a fixed range, select values and keyword
183
- // text seed verbatim.
451
+ // "last 12 months" stays relative and carries its preset name; a fixed
452
+ // range, select values and keyword text seed verbatim.
184
453
  _defaultValue(group) {
185
454
  const groupDefault = group.config?.default;
186
455
  if (!groupDefault) {
@@ -188,7 +457,7 @@ export class ReportFilterStateService {
188
457
  }
189
458
  if (groupDefault.relative) {
190
459
  const range = this._relativeRange(groupDefault.relative);
191
- return range ? { start: range.start, end: range.end } : null;
460
+ return range ? { start: range.start, end: range.end, preset: groupDefault.relative } : null;
192
461
  }
193
462
  if (groupDefault.start || groupDefault.end) {
194
463
  return {
@@ -204,22 +473,28 @@ export class ReportFilterStateService {
204
473
  }
205
474
  return null;
206
475
  }
476
+ // A relative preset as a calendar-day range. "Today" is the day in the
477
+ // report's effective zone, not the browser's, so every viewer seeds the same
478
+ // range. The server twin is ReportRelativeRangeEnum (framework/Report/Enum),
479
+ // and ReportRelativeRangeEnumTest pins the table both sides must produce.
207
480
  _relativeRange(relative) {
208
- const now = new Date();
481
+ const now = getZonedNow(this.timezone());
209
482
  switch (relative) {
210
- // A calendar week, Sunday to Saturday, in whole days — not the rolling
483
+ // A calendar week, Monday to Sunday (REPORT_WEEK_STARTS_ON, the same week
484
+ // the server's weekly buckets use), in whole days — not the rolling
211
485
  // seven days `last7Days` gives, which never lines up with the week a
212
486
  // partner has already been sent. `lastWeek` is the one a weekly report
213
- // wants: it ends at endOfWeek rather than at `now`, because the week it
214
- // names has closed. `thisWeek` follows every other preset here and runs
215
- // up to now, so it is deliberately a part-finished week.
487
+ // wants: it ends on the previous week's Sunday rather than at `now`,
488
+ // because the week it names has closed. `thisWeek` follows every other
489
+ // preset here and runs up to now, so it is deliberately a part-finished
490
+ // week (on a Sunday it is the whole Monday-to-Sunday week).
216
491
  case 'thisWeek':
217
- return { start: startOfWeek(now, { weekStartsOn: 0 }), end: now };
492
+ return { start: startOfWeek(now, { weekStartsOn: REPORT_WEEK_STARTS_ON }), end: now };
218
493
  case 'lastWeek': {
219
494
  const previous = subWeeks(now, 1);
220
495
  return {
221
- start: startOfWeek(previous, { weekStartsOn: 0 }),
222
- end: endOfWeek(previous, { weekStartsOn: 0 }),
496
+ start: startOfWeek(previous, { weekStartsOn: REPORT_WEEK_STARTS_ON }),
497
+ end: endOfWeek(previous, { weekStartsOn: REPORT_WEEK_STARTS_ON }),
223
498
  };
224
499
  }
225
500
  case 'last7Days':
@@ -249,4 +524,4 @@ export class ReportFilterStateService {
249
524
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportFilterStateService, decorators: [{
250
525
  type: Injectable
251
526
  }] });
252
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LWZpbHRlci1zdGF0ZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL3NlcnZpY2VzL3JlcG9ydC1maWx0ZXItc3RhdGUuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTNDLE9BQU8sRUFBYyxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDM0MsT0FBTyxFQUFFLE1BQU0sSUFBSSxRQUFRLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUVwRCxPQUFPLEVBQ0wsU0FBUyxFQUFFLFlBQVksRUFBRSxjQUFjLEVBQUUsV0FBVyxFQUFFLFdBQVcsRUFDakUsT0FBTyxFQUFFLFNBQVMsRUFBRSxRQUFRLEdBQzdCLE1BQU0sVUFBVSxDQUFDO0FBV2xCLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQzs7QUFHekQsa0ZBQWtGO0FBQ2xGLGtGQUFrRjtBQUNsRixNQUFNLFVBQVUsV0FBVyxDQUN6QixDQUE0QixFQUM1QixDQUE0QjtJQUU1QixJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDYixPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ2xCLENBQUM7SUFFRCxPQUFPLENBQUMsQ0FBQyxLQUFLLEtBQUssQ0FBQyxDQUFDLEtBQUs7V0FDckIsQ0FBQyxDQUFDLEdBQUcsS0FBSyxDQUFDLENBQUMsR0FBRztXQUNmLENBQUMsQ0FBQyxLQUFLLEtBQUssQ0FBQyxDQUFDLEtBQUs7V0FDbkIsQ0FBQyxDQUFDLFFBQVEsS0FBSyxDQUFDLENBQUMsUUFBUTtXQUN6QixDQUFDLENBQUMsQ0FBQyxNQUFNLElBQUksRUFBRSxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQyxDQUFDLE1BQU0sSUFBSSxFQUFFLENBQUMsQ0FBQyxN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RSxjQUFjLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO1lBQ2xELEtBQUssVUFBVSxDQUFDO1lBQ2hCLEtBQUssWUFBWTtnQkFDZixPQUFPLEVBQUUsS0FBSyxFQUFFLFdBQVcsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7WUFDL0M7Z0JBQ0UsT0FBTyxJQUFJLENBQUM7UUFDaEIsQ0FBQztJQUNILENBQUM7d0dBbFBVLHdCQUF3Qjs0R0FBeEIsd0JBQXdCOzs0RkFBeEIsd0JBQXdCO2tCQURwQyxVQUFVIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBmaWx0ZXIgYXMgcnhGaWx0ZXIgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7XG4gIGVuZE9mV2Vlaywgc3RhcnRPZk1vbnRoLCBzdGFydE9mUXVhcnRlciwgc3RhcnRPZldlZWssIHN0YXJ0T2ZZZWFyLFxuICBzdWJEYXlzLCBzdWJNb250aHMsIHN1YldlZWtzLFxufSBmcm9tICdkYXRlLWZucyc7XG5cbmltcG9ydCB7XG4gIENoYXJ0R3JhbnVsYXJpdHksXG4gIEZpbHRlckdyb3VwRGVmYXVsdCxcbiAgRmlsdGVyR3JvdXBWYWx1ZSxcbiAgUmVwb3J0LFxuICBSZXBvcnRDb21wb25lbnQsXG4gIFJlcG9ydEZpbHRlckdyb3VwLFxuICBSZXNvbHZlZEZpbHRlclZhbHVlLFxufSBmcm9tICcuLi9pbnRlcmZhY2VzL3JlcG9ydC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgZGF0ZUJvdW5kU3RyaW5nIH0gZnJvbSAnLi4vcmVwb3J0LWZpbHRlci1pdGVtcyc7XG5cblxuLy8gV2hldGhlciB0d28gc3RvcmVkIGZpbHRlci1ncm91cCBkZWZhdWx0cyBhcmUgdGhlIHNhbWUuIENvbXBhcmVkIG9uIHRoZSBmaWVsZHMgYVxuLy8gZGVmYXVsdCBjYW4gYWN0dWFsbHkgY2FycnksIHNvIGtleSBvcmRlciBpbiB0aGUgcGF5bG9hZCBjYW4ndCByZWFkIGFzIGEgY2hhbmdlLlxuZXhwb3J0IGZ1bmN0aW9uIHNhbWVEZWZhdWx0KFxuICBhOiBGaWx0ZXJHcm91cERlZmF1bHQgfCBudWxsLFxuICBiOiBGaWx0ZXJHcm91cERlZmF1bHQgfCBudWxsLFxuKTogYm9vbGVhbiB7XG4gIGlmICghYSB8fCAhYikge1xuICAgIHJldHVybiAhYSAmJiAhYjtcbiAgfVxuXG4gIHJldHVybiBhLnN0YXJ0ID09PSBiLnN0YXJ0XG4gICAgJiYgYS5lbmQgPT09IGIuZW5kXG4gICAgJiYgYS52YWx1ZSA9PT0gYi52YWx1ZVxuICAgICYmIGEucmVsYXRpdmUgPT09IGIucmVsYXRpdmVcbiAgICAmJiAoYS52YWx1ZXMgPz8gW10pLmxlbmd0aCA9PT0gKGIudmFsdWVzID8/IFtdKS5sZW5ndGhcbiAgICAmJiAoYS52YWx1ZXMgPz8gW10pLmV2ZXJ5KCh2YWx1ZSwgaW5kZXgpID0+IHZhbHVlID09PSAoYi52YWx1ZXMgPz8gW10pW2luZGV4XSk7XG59XG5cblxuLy8gQSBzdGFibGUgc2lnbmF0dXJlIGZvciBhIGdyb3VwJ3Mgc3RvcmVkIGRlZmF1bHQuIFRoZSByZXBvcnQgdG9vbGJhciBrZXlzIGl0c1xuLy8gZnMtZmlsdGVyIG9uIHRoaXMsIGJlY2F1c2UgZnMtZmlsdGVyIHJlYWRzIGl0cyBjb25maWcgb25jZSBhdCBpbml0IOKAlCB3aXRob3V0IGFcbi8vIGtleSBjaGFuZ2UgaXQga2VlcHMgcmVuZGVyaW5nIHRoZSB2YWx1ZXMgaXQgd2FzIGNyZWF0ZWQgd2l0aCBldmVuIGFmdGVyIHRoZVxuLy8gY29uZmlnIGJlaGluZCBpdCBoYXMgYmVlbiByZWJ1aWx0LlxuZXhwb3J0IGZ1bmN0aW9uIGRlZmF1bHRTaWduYXR1cmUoZ3JvdXA6IFJlcG9ydEZpbHRlckdyb3VwKTogc3RyaW5nIHtcbiAgY29uc3QgZ3JvdXBEZWZhdWx0ID0gZ3JvdXAuY29uZmlnPy5kZWZhdWx0O1xuXG4gIGlmICghZ3JvdXBEZWZhdWx0KSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgcmV0dXJuIFtcbiAgICBncm91cERlZmF1bHQuc3RhcnQgPz8gJycsXG4gICAgZ3JvdXBEZWZhdWx0LmVuZCA/PyAnJyxcbiAgICBncm91cERlZmF1bHQudmFsdWUgPz8gJycsXG4gICAgZ3JvdXBEZWZhdWx0LnJlbGF0aXZlID8/ICcnLFxuICAgIChncm91cERlZmF1bHQudmFsdWVzID8/IFtdKS5qb2luKCcsJyksXG4gIF0uam9pbignficpO1xufVxuXG5cbi8vIFNlc3Npb24gZmlsdGVyIHN0YXRlIGZvciB0aGUgb3BlbiByZXBvcnQuIEZpbHRlciBWQUxVRVMgYXJlIG5ldmVyIHBlcnNpc3RlZFxuLy8g4oCUIHRoaXMgc2VydmljZSBob2xkcyB0aGVtIHBlciBmaWx0ZXIgR1JPVVAgKHRoZSBwcm9wYWdhdGlvbiB1bml0KSwgcmVzb2x2ZXNcbi8vIHRoZW0gaW50byBwZXItY29tcG9uZW50IG1lbWJlci1maWx0ZXIgdmFsdWVzIGZvciBlYWNoIGRhdGEgcmVxdWVzdCwgYW5kXG4vLyBub3RpZmllcyB0aGUgY29tcG9uZW50cyB3aG9zZSBncm91cHMgY2hhbmdlZCBzbyBvbmx5IHRoZXkgcmVmZXRjaC5cbi8vXG4vLyBBbHNvIHNlc3Npb24tc2NvcGVkOiBwZXItZmlsdGVyIGVuYWJsZS9kaXNhYmxlIHRvZ2dsZXMgZnJvbSBhIGNvbXBvbmVudCdzXG4vLyBmaWx0ZXIgbWVudSAodGhlIGBlbmFibGVkYCBjb2x1bW4gaXMgdGhlIGF1dGhvcmVkIGRlZmF1bHQ7IGEgdmlld2VyJ3MgdG9nZ2xlXG4vLyBzaG91bGRuJ3Qgd3JpdGUgdG8gdGhlIHJlcG9ydCkuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgUmVwb3J0RmlsdGVyU3RhdGVTZXJ2aWNlIHtcblxuICBwcml2YXRlIF92YWx1ZXMgPSBuZXcgTWFwPG51bWJlciwgRmlsdGVyR3JvdXBWYWx1ZT4oKTtcbiAgcHJpdmF0ZSBfZ3JvdXBzID0gbmV3IE1hcDxudW1iZXIsIFJlcG9ydEZpbHRlckdyb3VwPigpO1xuICBwcml2YXRlIF9zZXNzaW9uRGlzYWJsZWQgPSBuZXcgU2V0PG51bWJlcj4oKTtcblxuICAvLyBUaGUgcmVwb3J0J3MgZ3JvdXAtYnkgY29udHJvbDogYSBzaW5nbGUgc2Vzc2lvbi13aWRlIGJ1Y2tldCBvdmVycmlkZSBmb3IgYWxsXG4gIC8vIHRpbWUtc2VyaWVzIGNoYXJ0cy4gVW5zZXQgPSBlYWNoIGNoYXJ0IHVzZXMgaXRzIGF1dGhvcmVkIGdyYW51bGFyaXR5LiBOZXZlclxuICAvLyBwZXJzaXN0ZWQgKGl0IGRpZXMgd2l0aCB0aGlzIHJlcG9ydCB2aWV3KSwgYW5kIGNhcnJpZWQgaW4gdGhlIGRhdGEgcmVxdWVzdCdzXG4gIC8vIGBzdGF0ZWAsIHNvIGl0IHByb3BhZ2F0ZXMgdGhyb3VnaCB0byB0aGUgUERGL1Bvd2VyUG9pbnQgZXhwb3J0cyB0b28uIE5hbWVkXG4gIC8vIGZvciB0aGUgYGZyZXF1ZW5jeWAgd2lyZSBrZXkgaXQgdHJhdmVscyB1bmRlciwgbm90IGZvciB0aGUgY29udHJvbCdzIGxhYmVsLlxuICBwcml2YXRlIF9mcmVxdWVuY3k6IENoYXJ0R3JhbnVsYXJpdHkgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBfZnJlcXVlbmN5Q2hhbmdlZCQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIC8vIEVtaXRzIHRoZSBncm91cCBpZCB0aGF0IGNoYW5nZWQ7IGNvbXBvbmVudHMgbGlzdGVuIGZpbHRlcmVkIHRvIHRoZWlyIG93blxuICAvLyBncm91cCBpZHMuIG51bGwgPSBldmVyeXRoaW5nIGNoYW5nZWQgKHJlLWluaXQpLlxuICBwcml2YXRlIF9jaGFuZ2VkJCA9IG5ldyBTdWJqZWN0PG51bWJlciB8IG51bGw+KCk7XG5cbiAgLy8gU2VlZCBncm91cHMgKyB0aGVpciBkZWZhdWx0cyB3aGVuIGEgcmVwb3J0IGxvYWRzLiBFeGlzdGluZyBzZXNzaW9uIHZhbHVlc1xuICAvLyBmb3Igc3RpbGwtZXhpc3RpbmcgZ3JvdXBzIHN1cnZpdmUgYSBzdHJ1Y3R1cmUgcmUtZmV0Y2ggKGEgY2hhdCBlZGl0XG4gIC8vIHNob3VsZG4ndCByZXNldCB0aGUgdmlld2VyJ3MgZmlsdGVycykg4oCUIFVOTEVTUyB0aGUgZ3JvdXAncyBzdG9yZWQgZGVmYXVsdFxuICAvLyBpdHNlbGYgY2hhbmdlZCwgd2hpY2ggb25seSBoYXBwZW5zIHdoZW4gYW4gb3BlcmF0b3Igc2F2ZWQgYSBuZXcgZGVmYXVsdCBpblxuICAvLyByZXBvcnQgc2V0dGluZ3MuIFRoYXQgaXMgYW4gZXhwbGljaXQgaW5zdHJ1Y3Rpb24gdG8gcmUtc2VlZCwgc28gaXQgd2lucyBvdmVyXG4gIC8vIHRoZSBzdXJ2aXZpbmcgc2Vzc2lvbiB2YWx1ZTsgd2l0aG91dCBpdCB0aGUgYmFyIGtlZXBzIHNob3dpbmcgd2hhdGV2ZXIgaXQgd2FzXG4gIC8vIGZpcnN0IHNlZWRlZCB3aXRoIHVudGlsIGEgZnVsbCBwYWdlIHJlbG9hZC5cbiAgcHVibGljIGluaXQocmVwb3J0OiBSZXBvcnQpOiB2b2lkIHtcbiAgICBjb25zdCBwcmV2aW91c0dyb3VwcyA9IHRoaXMuX2dyb3VwcztcbiAgICB0aGlzLl9ncm91cHMgPSBuZXcgTWFwPG51bWJlciwgUmVwb3J0RmlsdGVyR3JvdXA+KCk7XG5cbiAgICBjb25zdCB2YWxpZElkcyA9IG5ldyBTZXQ8bnVtYmVyPigpO1xuICAgIGZvciAoY29uc3QgZ3JvdXAgb2YgcmVwb3J0LmZpbHRlckdyb3VwcyA/PyBbXSkge1xuICAgICAgdGhpcy5fZ3JvdXBzLnNldChncm91cC5pZCwgZ3JvdXApO1xuICAgICAgdmFsaWRJZHMuYWRkKGdyb3VwLmlkKTtcblxuICAgICAgY29uc3QgZGVmYXVsdENoYW5nZWQgPSAhc2FtZURlZmF1bHQoXG4gICAgICAgIHByZXZpb3VzR3JvdXBzLmdldChncm91cC5pZCk/LmNvbmZpZz8uZGVmYXVsdCA/PyBudWxsLFxuICAgICAgICBncm91cC5jb25maWc/LmRlZmF1bHQgPz8gbnVsbCxcbiAgICAgICk7XG5cbiAgICAgIGlmICghdGhpcy5fdmFsdWVzLmhhcyhncm91cC5pZCkgfHwgZGVmYXVsdENoYW5nZWQpIHtcbiAgICAgICAgY29uc3QgZGVmYXVsdFZhbHVlID0gdGhpcy5fZGVmYXVsdFZhbHVlKGdyb3VwKTtcblxuICAgICAgICBpZiAoZGVmYXVsdFZhbHVlKSB7XG4gICAgICAgICAgdGhpcy5fdmFsdWVzLnNldChncm91cC5pZCwgZGVmYXVsdFZhbHVlKTtcbiAgICAgICAgfSBlbHNlIGlmIChkZWZhdWx0Q2hhbmdlZCkge1xuICAgICAgICAgIC8vIFRoZSBkZWZhdWx0IHdhcyBjbGVhcmVkLCBzbyB0aGUgdmFsdWUgaXQgc2VlZGVkIGdvZXMgd2l0aCBpdC5cbiAgICAgICAgICB0aGlzLl92YWx1ZXMuZGVsZXRlKGdyb3VwLmlkKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgZ3JvdXBJZCBvZiBbLi4udGhpcy5fdmFsdWVzLmtleXMoKV0pIHtcbiAgICAgIGlmICghdmFsaWRJZHMuaGFzKGdyb3VwSWQpKSB7XG4gICAgICAgIHRoaXMuX3ZhbHVlcy5kZWxldGUoZ3JvdXBJZCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5fY2hhbmdlZCQubmV4dChudWxsKTtcbiAgfVxuXG4gIHB1YmxpYyB2YWx1ZShncm91cElkOiBudW1iZXIpOiBGaWx0ZXJHcm91cFZhbHVlIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5fdmFsdWVzLmdldChncm91cElkKTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRWYWx1ZShncm91cElkOiBudW1iZXIsIHZhbHVlOiBGaWx0ZXJHcm91cFZhbHVlIHwgbnVsbCk6IHZvaWQge1xuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgdGhpcy5fdmFsdWVzLmRlbGV0ZShncm91cElkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fdmFsdWVzLnNldChncm91cElkLCB2YWx1ZSk7XG4gICAgfVxuXG4gICAgdGhpcy5fY2hhbmdlZCQubmV4dChncm91cElkKTtcbiAgfVxuXG4gIC8vIFRoZSBhY3RpdmUgZ3JvdXAtYnkgZ3JhaW4sIG9yIG51bGwgd2hlbiB0aGUgdmlld2VyIGhhc24ndCBjaG9zZW4gb25lLlxuICBwdWJsaWMgZnJlcXVlbmN5KCk6IENoYXJ0R3JhbnVsYXJpdHkgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5fZnJlcXVlbmN5O1xuICB9XG5cbiAgcHVibGljIHNldEZyZXF1ZW5jeShmcmVxdWVuY3k6IENoYXJ0R3JhbnVsYXJpdHkgfCBudWxsKTogdm9pZCB7XG4gICAgdGhpcy5fZnJlcXVlbmN5ID0gZnJlcXVlbmN5O1xuICAgIHRoaXMuX2ZyZXF1ZW5jeUNoYW5nZWQkLm5leHQoKTtcbiAgfVxuXG4gIC8vIEZpcmVzIHdoZW5ldmVyIHRoZSBncm91cC1ieSBncmFpbiBjaGFuZ2VzIOKAlCBldmVyeSB0aW1lLXNlcmllcyBjaGFydCBsaXN0ZW5zXG4gIC8vIHNvIGl0IHJlZmV0Y2hlcyBhbmQgcmUtYnVja2V0cyAodGhlIG92ZXJyaWRlIGlzbid0IHNjb3BlZCB0byBhbnkgZmlsdGVyXG4gIC8vIGdyb3VwLCBzbyBjaGFuZ2VzRm9yKCkgY2FuJ3QgY2FycnkgaXQpLlxuICBwdWJsaWMgZnJlcXVlbmN5Q2hhbmdlcygpOiBPYnNlcnZhYmxlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5fZnJlcXVlbmN5Q2hhbmdlZCQuYXNPYnNlcnZhYmxlKCk7XG4gIH1cblxuICBwdWJsaWMgaXNGaWx0ZXJEaXNhYmxlZChmaWx0ZXJJZDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuX3Nlc3Npb25EaXNhYmxlZC5oYXMoZmlsdGVySWQpO1xuICB9XG5cbiAgcHVibGljIHRvZ2dsZUZpbHRlcihmaWx0ZXJJZDogbnVtYmVyLCBncm91cElkOiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fc2Vzc2lvbkRpc2FibGVkLmhhcyhmaWx0ZXJJZCkpIHtcbiAgICAgIHRoaXMuX3Nlc3Npb25EaXNhYmxlZC5kZWxldGUoZmlsdGVySWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl9zZXNzaW9uRGlzYWJsZWQuYWRkKGZpbHRlcklkKTtcbiAgICB9XG5cbiAgICB0aGlzLl9jaGFuZ2VkJC5uZXh0KGdyb3VwSWQpO1xuICB9XG5cbiAgLy8gTm90aWZpY2F0aW9ucyByZWxldmFudCB0byBPTkUgY29tcG9uZW50OiBhbnkgY2hhbmdlIHRvIGEgZ3JvdXAgb25lIG9mIGl0c1xuICAvLyBmaWx0ZXJzIGJlbG9uZ3MgdG8gKG9yIGEgZnVsbCByZS1pbml0KS5cbiAgcHVibGljIGNoYW5nZXNGb3IoY29tcG9uZW50OiBSZXBvcnRDb21wb25lbnQpOiBPYnNlcnZhYmxlPG51bWJlciB8IG51bGw+IHtcbiAgICBjb25zdCBncm91cElkcyA9IG5ldyBTZXQoKGNvbXBvbmVudC5maWx0ZXJzID8/IFtdKS5tYXAoKGZpbHRlcikgPT4gZmlsdGVyLmZpbHRlckdyb3VwSWQpKTtcblxuICAgIHJldHVybiB0aGlzLl9jaGFuZ2VkJC5hc09ic2VydmFibGUoKVxuICAgICAgLnBpcGUoXG4gICAgICAgIHJ4RmlsdGVyKChncm91cElkKSA9PiBncm91cElkID09PSBudWxsIHx8IGdyb3VwSWRzLmhhcyhncm91cElkKSksXG4gICAgICApO1xuICB9XG5cbiAgLy8gVGhlIGdyb3VwIHZhbHVlcyByZXNvbHZlZCBpbnRvIHRoaXMgY29tcG9uZW50J3MgbWVtYmVyLWZpbHRlciB2YWx1ZXMg4oCUXG4gIC8vIHdoYXQgdGhlIGRhdGEgcmVxdWVzdCBjYXJyaWVzLiBEaXNhYmxlZCBmaWx0ZXJzIChhdXRob3JlZCBvciBzZXNzaW9uKSBhcmVcbiAgLy8gc2tpcHBlZCBlbnRpcmVseS5cbiAgcHVibGljIHJlc29sdmVGb3JDb21wb25lbnQoY29tcG9uZW50OiBSZXBvcnRDb21wb25lbnQpOiBSZXNvbHZlZEZpbHRlclZhbHVlW10ge1xuICAgIGNvbnN0IHJlc29sdmVkOiBSZXNvbHZlZEZpbHRlclZhbHVlW10gPSBbXTtcblxuICAgIGZvciAoY29uc3QgZmlsdGVyIG9mIGNvbXBvbmVudC5maWx0ZXJzID8/IFtdKSB7XG4gICAgICBpZiAoIWZpbHRlci5lbmFibGVkIHx8IHRoaXMuX3Nlc3Npb25EaXNhYmxlZC5oYXMoZmlsdGVyLmlkKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLl92YWx1ZXMuZ2V0KGZpbHRlci5maWx0ZXJHcm91cElkKTtcbiAgICAgIGlmICghdmFsdWUpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGVudHJ5OiBSZXNvbHZlZEZpbHRlclZhbHVlID0geyBmaWx0ZXJJZDogZmlsdGVyLmlkIH07XG5cbiAgICAgIGlmICh2YWx1ZS5zdGFydCkge1xuICAgICAgICBlbnRyeS5zdGFydCA9IGRhdGVCb3VuZFN0cmluZyh2YWx1ZS5zdGFydCk7XG4gICAgICB9XG4gICAgICBpZiAodmFsdWUuZW5kKSB7XG4gICAgICAgIGVudHJ5LmVuZCA9IGRhdGVCb3VuZFN0cmluZyh2YWx1ZS5lbmQpO1xuICAgICAgfVxuICAgICAgaWYgKHZhbHVlLnZhbHVlcz8ubGVuZ3RoKSB7XG4gICAgICAgIGVudHJ5LnZhbHVlcyA9IHZhbHVlLnZhbHVlcztcbiAgICAgIH1cbiAgICAgIGlmICh2YWx1ZS52YWx1ZT8udHJpbSgpKSB7XG4gICAgICAgIGVudHJ5LnZhbHVlID0gdmFsdWUudmFsdWUudHJpbSgpO1xuICAgICAgfVxuXG4gICAgICBpZiAoZW50cnkuc3RhcnQgfHwgZW50cnkuZW5kIHx8IGVudHJ5LnZhbHVlcyB8fCBlbnRyeS52YWx1ZSkge1xuICAgICAgICByZXNvbHZlZC5wdXNoKGVudHJ5KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzb2x2ZWQ7XG4gIH1cblxuICAvLyBFdmVyeSBjb21wb25lbnQncyByZXNvbHZlZCB2YWx1ZXMgaW4gb25lIGFycmF5IOKAlCB3aGF0IGEgcmVwb3J0LWxldmVsIGV4cG9ydFxuICAvLyBjYXJyaWVzIHNvIGVhY2ggZmlsZSBpbiB0aGUgYXJjaGl2ZSBpcyBmaWx0ZXJlZCBleGFjdGx5IGFzIHRoZSBzY3JlZW4gaXMuXG4gIC8vIEZpbHRlciBpZHMgYXJlIHVuaXF1ZSBwZXIgY29tcG9uZW50LCBzbyB0aGUgYmFja2VuZCBwaWNrcyBlYWNoIGNvbXBvbmVudCdzXG4gIC8vIG93biBvdXQgb2YgdGhlIHBpbGUuIEEgcGFnZSBpZCBuYXJyb3dzIGl0IHRvIHRoYXQgcGFnZS5cbiAgcHVibGljIHJlc29sdmVGb3JSZXBvcnQocmVwb3J0OiBSZXBvcnQsIHBhZ2VJZDogbnVtYmVyIHwgbnVsbCA9IG51bGwpOiBSZXNvbHZlZEZpbHRlclZhbHVlW10ge1xuICAgIGNvbnN0IHBhZ2VzID0gKHJlcG9ydC5wYWdlcyA/PyBbXSlcbiAgICAgIC5maWx0ZXIoKHBhZ2UpID0+ICFwYWdlSWQgfHwgcGFnZS5pZCA9PT0gcGFnZUlkKTtcblxuICAgIHJldHVybiBwYWdlc1xuICAgICAgLmZsYXRNYXAoKHBhZ2UpID0+IChwYWdlLmNvbXBvbmVudHMgPz8gW10pXG4gICAgICAgIC5mbGF0TWFwKChjb21wb25lbnQpID0+IHRoaXMucmVzb2x2ZUZvckNvbXBvbmVudChjb21wb25lbnQpKSk7XG4gIH1cblxuICAvLyBBIGdyb3VwJ3MgYXV0aG9yZWQgZGVmYXVsdCwgbWFwcGVkIHRvIGEgc2Vzc2lvbiB2YWx1ZSBieSB0eXBlLiBSZWxhdGl2ZVxuICAvLyBkYXRlIHByZXNldHMgcmVzb2x2ZSBhZ2FpbnN0IFwibm93XCIgZWFjaCB0aW1lIHRoZSByZXBvcnQgb3BlbnMsIHNvIGEgc2F2ZWRcbiAgLy8gXCJsYXN0IDEyIG1vbnRoc1wiIHN0YXlzIHJlbGF0aXZlOyBhIGZpeGVkIHJhbmdlLCBzZWxlY3QgdmFsdWVzIGFuZCBrZXl3b3JkXG4gIC8vIHRleHQgc2VlZCB2ZXJiYXRpbS5cbiAgcHJpdmF0ZSBfZGVmYXVsdFZhbHVlKGdyb3VwOiBSZXBvcnRGaWx0ZXJHcm91cCk6IEZpbHRlckdyb3VwVmFsdWUgfCBudWxsIHtcbiAgICBjb25zdCBncm91cERlZmF1bHQgPSBncm91cC5jb25maWc/LmRlZmF1bHQ7XG4gICAgaWYgKCFncm91cERlZmF1bHQpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGlmIChncm91cERlZmF1bHQucmVsYXRpdmUpIHtcbiAgICAgIGNvbnN0IHJhbmdlID0gdGhpcy5fcmVsYXRpdmVSYW5nZShncm91cERlZmF1bHQucmVsYXRpdmUpO1xuXG4gICAgICByZXR1cm4gcmFuZ2UgPyB7IHN0YXJ0OiByYW5nZS5zdGFydCwgZW5kOiByYW5nZS5lbmQgfSA6IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKGdyb3VwRGVmYXVsdC5zdGFydCB8fCBncm91cERlZmF1bHQuZW5kKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdGFydDogZ3JvdXBEZWZhdWx0LnN0YXJ0ID8/IG51bGwsXG4gICAgICAgIGVuZDogZ3JvdXBEZWZhdWx0LmVuZCA/PyBudWxsLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoZ3JvdXBEZWZhdWx0LnZhbHVlcz8ubGVuZ3RoKSB7XG4gICAgICByZXR1cm4geyB2YWx1ZXM6IGdyb3VwRGVmYXVsdC52YWx1ZXMgfTtcbiAgICB9XG5cbiAgICBpZiAoZ3JvdXBEZWZhdWx0LnZhbHVlKSB7XG4gICAgICByZXR1cm4geyB2YWx1ZTogZ3JvdXBEZWZhdWx0LnZhbHVlIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwcml2YXRlIF9yZWxhdGl2ZVJhbmdlKHJlbGF0aXZlOiBzdHJpbmcpOiB7IHN0YXJ0OiBEYXRlOyBlbmQ6IERhdGUgfSB8IG51bGwge1xuICAgIGNvbnN0IG5vdyA9IG5ldyBEYXRlKCk7XG5cbiAgICBzd2l0Y2ggKHJlbGF0aXZlKSB7XG4gICAgICAvLyBBIGNhbGVuZGFyIHdlZWssIFN1bmRheSB0byBTYXR1cmRheSwgaW4gd2hvbGUgZGF5cyDigJQgbm90IHRoZSByb2xsaW5nXG4gICAgICAvLyBzZXZlbiBkYXlzIGBsYXN0N0RheXNgIGdpdmVzLCB3aGljaCBuZXZlciBsaW5lcyB1cCB3aXRoIHRoZSB3ZWVrIGFcbiAgICAgIC8vIHBhcnRuZXIgaGFzIGFscmVhZHkgYmVlbiBzZW50LiBgbGFzdFdlZWtgIGlzIHRoZSBvbmUgYSB3ZWVrbHkgcmVwb3J0XG4gICAgICAvLyB3YW50czogaXQgZW5kcyBhdCBlbmRPZldlZWsgcmF0aGVyIHRoYW4gYXQgYG5vd2AsIGJlY2F1c2UgdGhlIHdlZWsgaXRcbiAgICAgIC8vIG5hbWVzIGhhcyBjbG9zZWQuIGB0aGlzV2Vla2AgZm9sbG93cyBldmVyeSBvdGhlciBwcmVzZXQgaGVyZSBhbmQgcnVuc1xuICAgICAgLy8gdXAgdG8gbm93LCBzbyBpdCBpcyBkZWxpYmVyYXRlbHkgYSBwYXJ0LWZpbmlzaGVkIHdlZWsuXG4gICAgICBjYXNlICd0aGlzV2Vlayc6XG4gICAgICAgIHJldHVybiB7IHN0YXJ0OiBzdGFydE9mV2Vlayhub3csIHsgd2Vla1N0YXJ0c09uOiAwIH0pLCBlbmQ6IG5vdyB9O1xuICAgICAgY2FzZSAnbGFzdFdlZWsnOiB7XG4gICAgICAgIGNvbnN0IHByZXZpb3VzID0gc3ViV2Vla3Mobm93LCAxKTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHN0YXJ0OiBzdGFydE9mV2VlayhwcmV2aW91cywgeyB3ZWVrU3RhcnRzT246IDAgfSksXG4gICAgICAgICAgZW5kOiBlbmRPZldlZWsocHJldmlvdXMsIHsgd2Vla1N0YXJ0c09uOiAwIH0pLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgICAgY2FzZSAnbGFzdDdEYXlzJzpcbiAgICAgICAgcmV0dXJuIHsgc3RhcnQ6IHN1YkRheXMobm93LCA3KSwgZW5kOiBub3cgfTtcbiAgICAgIGNhc2UgJ2xhc3QzMERheXMnOlxuICAgICAgICByZXR1cm4geyBzdGFydDogc3ViRGF5cyhub3csIDMwKSwgZW5kOiBub3cgfTtcbiAgICAgIGNhc2UgJ2xhc3QzTW9udGhzJzpcbiAgICAgICAgcmV0dXJuIHsgc3RhcnQ6IHN1Yk1vbnRocyhub3csIDMpLCBlbmQ6IG5vdyB9O1xuICAgICAgY2FzZSAnbGFzdDZNb250aHMnOlxuICAgICAgICByZXR1cm4geyBzdGFydDogc3ViTW9udGhzKG5vdywgNiksIGVuZDogbm93IH07XG4gICAgICBjYXNlICdsYXN0MTJNb250aHMnOlxuICAgICAgICByZXR1cm4geyBzdGFydDogc3ViTW9udGhzKG5vdywgMTIpLCBlbmQ6IG5vdyB9O1xuICAgICAgY2FzZSAndGhpc01vbnRoJzpcbiAgICAgICAgcmV0dXJuIHsgc3RhcnQ6IHN0YXJ0T2ZNb250aChub3cpLCBlbmQ6IG5vdyB9O1xuICAgICAgY2FzZSAndGhpc1F1YXJ0ZXInOlxuICAgICAgICByZXR1cm4geyBzdGFydDogc3RhcnRPZlF1YXJ0ZXIobm93KSwgZW5kOiBub3cgfTtcbiAgICAgIGNhc2UgJ3RoaXNZZWFyJzpcbiAgICAgIGNhc2UgJ3llYXJUb0RhdGUnOlxuICAgICAgICByZXR1cm4geyBzdGFydDogc3RhcnRPZlllYXIobm93KSwgZW5kOiBub3cgfTtcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgfVxufVxuIl19
527
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LWZpbHRlci1zdGF0ZS5zZXJ2aWNlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL3NlcnZpY2VzL3JlcG9ydC1maWx0ZXItc3RhdGUuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUVuRCxPQUFPLEVBQWMsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxNQUFNLElBQUksUUFBUSxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFcEQsT0FBTyxFQUNMLFNBQVMsRUFBRSxZQUFZLEVBQUUsY0FBYyxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQ2pFLE9BQU8sRUFBRSxTQUFTLEVBQUUsUUFBUSxHQUM3QixNQUFNLFVBQVUsQ0FBQztBQUVsQixPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUNwRSxPQUFPLEVBQUUsV0FBVyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRS9ELE9BQU8sRUFJTCxtQkFBbUIsR0FRcEIsTUFBTSxnQ0FBZ0MsQ0FBQztBQUN4QyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDekQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLFVBQVUsRUFBRSxNQUFNLHFCQUFxQixDQUFDOztBQUdwRSxrRkFBa0Y7QUFDbEYsa0ZBQWtGO0FBQ2xGLE1BQU0sVUFBVSxXQUFXLENBQ3pCLENBQTRCLEVBQzVCLENBQTRCO0lBRTVCLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUNiLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7SUFDbEIsQ0FBQztJQUVELE9BQU8sQ0FBQyxDQUFDLEtBQUssS0FBSyxDQUFDLENBQUMsS0FBSztXQUNyQixDQUFD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O2dCQUNmLE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7WUFDL0MsS0FBSyxhQUFhO2dCQUNoQixPQUFPLEVBQUUsS0FBSyxFQUFFLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO1lBQ2hELEtBQUssYUFBYTtnQkFDaEIsT0FBTyxFQUFFLEtBQUssRUFBRSxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztZQUNoRCxLQUFLLGNBQWM7Z0JBQ2pCLE9BQU8sRUFBRSxLQUFLLEVBQUUsU0FBUyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7WUFDakQsS0FBSyxXQUFXO2dCQUNkLE9BQU8sRUFBRSxLQUFLLEVBQUUsWUFBWSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztZQUNoRCxLQUFLLGFBQWE7Z0JBQ2hCLE9BQU8sRUFBRSxLQUFLLEVBQUUsY0FBYyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztZQUNsRCxLQUFLLFVBQVUsQ0FBQztZQUNoQixLQUFLLFlBQVk7Z0JBQ2YsT0FBTyxFQUFFLEtBQUssRUFBRSxXQUFXLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLEdBQUcsRUFBRSxDQUFDO1lBQy9DO2dCQUNFLE9BQU8sSUFBSSxDQUFDO1FBQ2hCLENBQUM7SUFDSCxDQUFDO3dHQXBpQlUsd0JBQXdCOzRHQUF4Qix3QkFBd0I7OzRGQUF4Qix3QkFBd0I7a0JBRHBDLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBzaWduYWwgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZmlsdGVyIGFzIHJ4RmlsdGVyIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuXG5pbXBvcnQge1xuICBlbmRPZldlZWssIHN0YXJ0T2ZNb250aCwgc3RhcnRPZlF1YXJ0ZXIsIHN0YXJ0T2ZXZWVrLCBzdGFydE9mWWVhcixcbiAgc3ViRGF5cywgc3ViTW9udGhzLCBzdWJXZWVrcyxcbn0gZnJvbSAnZGF0ZS1mbnMnO1xuXG5pbXBvcnQgeyBSRVBPUlRfV0VFS19TVEFSVFNfT04gfSBmcm9tICcuLi9jb25zdHMvcmVwb3J0LXdlZWsuY29uc3QnO1xuaW1wb3J0IHsgZ2V0Wm9uZWROb3csIHJlc29sdmVSZXBvcnRUaW1lem9uZSB9IGZyb20gJy4uL2Zvcm1hdCc7XG5pbXBvcnQgeyBSZXBvcnRDaGF0Vmlld2VyRmlsdGVyIH0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZXBvcnQtY2hhdC12aWV3ZXItZmlsdGVyLmludGVyZmFjZSc7XG5pbXBvcnQge1xuICBDaGFydEdyYW51bGFyaXR5LFxuICBGaWx0ZXJHcm91cERlZmF1bHQsXG4gIEZpbHRlckdyb3VwVmFsdWUsXG4gIEdSQU5VTEFSSVRZX09QVElPTlMsXG4gIFJlcG9ydCxcbiAgUmVwb3J0Q29tcG9uZW50LFxuICBSZXBvcnRGaWx0ZXJHcm91cCxcbiAgUmVwb3J0U29ydCxcbiAgUmVwb3J0VXJsUGFyYW1zLFxuICBSZXBvcnRVcmxTbmFwc2hvdCxcbiAgUmVzb2x2ZWRGaWx0ZXJWYWx1ZSxcbn0gZnJvbSAnLi4vaW50ZXJmYWNlcy9yZXBvcnQuaW50ZXJmYWNlJztcbmltcG9ydCB7IGRhdGVCb3VuZFN0cmluZyB9IGZyb20gJy4uL3JlcG9ydC1maWx0ZXItaXRlbXMnO1xuaW1wb3J0IHsgZGVjb2RlRmlsdGVyVmFsdWUsIGRlY29kZVNvcnQgfSBmcm9tICcuLi9yZXBvcnQtdXJsLXN0YXRlJztcblxuXG4vLyBXaGV0aGVyIHR3byBzdG9yZWQgZmlsdGVyLWdyb3VwIGRlZmF1bHRzIGFyZSB0aGUgc2FtZS4gQ29tcGFyZWQgb24gdGhlIGZpZWxkcyBhXG4vLyBkZWZhdWx0IGNhbiBhY3R1YWxseSBjYXJyeSwgc28ga2V5IG9yZGVyIGluIHRoZSBwYXlsb2FkIGNhbid0IHJlYWQgYXMgYSBjaGFuZ2UuXG5leHBvcnQgZnVuY3Rpb24gc2FtZURlZmF1bHQoXG4gIGE6IEZpbHRlckdyb3VwRGVmYXVsdCB8IG51bGwsXG4gIGI6IEZpbHRlckdyb3VwRGVmYXVsdCB8IG51bGwsXG4pOiBib29sZWFuIHtcbiAgaWYgKCFhIHx8ICFiKSB7XG4gICAgcmV0dXJuICFhICYmICFiO1xuICB9XG5cbiAgcmV0dXJuIGEuc3RhcnQgPT09IGIuc3RhcnRcbiAgICAmJiBhLmVuZCA9PT0gYi5lbmRcbiAgICAmJiBhLnZhbHVlID09PSBiLnZhbHVlXG4gICAgJiYgYS5yZWxhdGl2ZSA9PT0gYi5yZWxhdGl2ZVxuICAgICYmIChhLnZhbHVlcyA/PyBbXSkubGVuZ3RoID09PSAoYi52YWx1ZXMgPz8gW10pLmxlbmd0aFxuICAgICYmIChhLnZhbHVlcyA/PyBbXSkuZXZlcnkoKHZhbHVlLCBpbmRleCkgPT4gdmFsdWUgPT09IChiLnZhbHVlcyA/PyBbXSlbaW5kZXhdKTtcbn1cblxuXG4vLyBXaGV0aGVyIHR3byBsaXN0IHNvcnRzIG9yZGVyIHRoZSByb3dzIHRoZSBzYW1lIHdheS4gTm8gZGlyZWN0aW9uIHJlYWRzIGFzXG4vLyBhc2NlbmRpbmcsIHRoZSB3YXkgdGhlIGxpc3QgYXBwbGllcyBpdC5cbmZ1bmN0aW9uIHNhbWVTb3J0KGE6IFJlcG9ydFNvcnQsIGI6IFJlcG9ydFNvcnQgfCBudWxsKTogYm9vbGVhbiB7XG4gIHJldHVybiAhIWJcbiAgICAmJiBhLmNvbHVtbiA9PT0gYi5jb2x1bW5cbiAgICAmJiAoYS5kaXJlY3Rpb24gPz8gJ2FzYycpID09PSAoYi5kaXJlY3Rpb24gPz8gJ2FzYycpO1xufVxuXG5cbi8vIFdoZXRoZXIgdHdvIGRhdGUtcmFuZ2UgdmFsdWVzIGNvdmVyIHRoZSBzYW1lIGNhbGVuZGFyIGRheXMuXG5mdW5jdGlvbiBzYW1lRGF5cyhhOiBGaWx0ZXJHcm91cFZhbHVlLCBiOiBGaWx0ZXJHcm91cFZhbHVlKTogYm9vbGVhbiB7XG4gIHJldHVybiBkYXRlQm91bmRTdHJpbmcoYS5zdGFydCkgPT09IGRhdGVCb3VuZFN0cmluZyhiLnN0YXJ0KVxuICAgICYmIGRhdGVCb3VuZFN0cmluZyhhLmVuZCkgPT09IGRhdGVCb3VuZFN0cmluZyhiLmVuZCk7XG59XG5cblxuLy8gQSBzdGFibGUgc2lnbmF0dXJlIGZvciBhIGdyb3VwJ3Mgc3RvcmVkIGRlZmF1bHQuIFRoZSByZXBvcnQgdG9vbGJhciBrZXlzIGl0c1xuLy8gZnMtZmlsdGVyIG9uIHRoaXMsIGJlY2F1c2UgZnMtZmlsdGVyIHJlYWRzIGl0cyBjb25maWcgb25jZSBhdCBpbml0IOKAlCB3aXRob3V0IGFcbi8vIGtleSBjaGFuZ2UgaXQga2VlcHMgcmVuZGVyaW5nIHRoZSB2YWx1ZXMgaXQgd2FzIGNyZWF0ZWQgd2l0aCBldmVuIGFmdGVyIHRoZVxuLy8gY29uZmlnIGJlaGluZCBpdCBoYXMgYmVlbiByZWJ1aWx0LlxuZXhwb3J0IGZ1bmN0aW9uIGRlZmF1bHRTaWduYXR1cmUoZ3JvdXA6IFJlcG9ydEZpbHRlckdyb3VwKTogc3RyaW5nIHtcbiAgY29uc3QgZ3JvdXBEZWZhdWx0ID0gZ3JvdXAuY29uZmlnPy5kZWZhdWx0O1xuXG4gIGlmICghZ3JvdXBEZWZhdWx0KSB7XG4gICAgcmV0dXJuICcnO1xuICB9XG5cbiAgcmV0dXJuIFtcbiAgICBncm91cERlZmF1bHQuc3RhcnQgPz8gJycsXG4gICAgZ3JvdXBEZWZhdWx0LmVuZCA/PyAnJyxcbiAgICBncm91cERlZmF1bHQudmFsdWUgPz8gJycsXG4gICAgZ3JvdXBEZWZhdWx0LnJlbGF0aXZlID8/ICcnLFxuICAgIChncm91cERlZmF1bHQudmFsdWVzID8/IFtdKS5qb2luKCcsJyksXG4gIF0uam9pbignficpO1xufVxuXG5cbi8vIFZpZXdlciBmaWx0ZXIgc3RhdGUgZm9yIHRoZSBvcGVuIHJlcG9ydC4gRmlsdGVyIFZBTFVFUyBhcmUgbmV2ZXIgc2F2ZWQgdG9cbi8vIHRoZSByZXBvcnQg4oCUIHRoaXMgc2VydmljZSBob2xkcyB0aGVtIHBlciBmaWx0ZXIgR1JPVVAgKHRoZSBwcm9wYWdhdGlvbiB1bml0KSxcbi8vIHJlc29sdmVzIHRoZW0gaW50byBwZXItY29tcG9uZW50IG1lbWJlci1maWx0ZXIgdmFsdWVzIGZvciBlYWNoIGRhdGEgcmVxdWVzdCxcbi8vIGFuZCBub3RpZmllcyB0aGUgY29tcG9uZW50cyB3aG9zZSBncm91cHMgY2hhbmdlZCBzbyBvbmx5IHRoZXkgcmVmZXRjaC5cbi8vXG4vLyBJdCBpcyBhbHNvIHRoZSBvbmUgc291cmNlIG9mIHRoZSB2aWV3ZXIgc3RhdGUgdGhlIHJlcG9ydCBVUkwgY2FycmllcyAoZ3JvdXBcbi8vIHZhbHVlcywgdGhlIGdyb3VwLWJ5IGdyYWluLCBsaXN0IHNvcnRzKTogdXJsU25hcHNob3QoKSBzYXlzIHdoYXQgZGlmZmVycyBmcm9tXG4vLyB0aGUgYXV0aG9yZWQgZGVmYXVsdHMsIGluaXQoKSByZXN0b3JlcyBpdCwgYW5kIHVybENoYW5nZXMoKSB0ZWxscyB0aGUgaG9zdCdzXG4vLyBzaW5nbGUgVVJMIHdyaXRlciB3aGVuIHRvIHdyaXRlLlxuLy9cbi8vIFNlc3Npb24tb25seSwgbmV2ZXIgaW4gdGhlIFVSTDogcGVyLWZpbHRlciBlbmFibGUvZGlzYWJsZSB0b2dnbGVzIGZyb20gYVxuLy8gY29tcG9uZW50J3MgZmlsdGVyIG1lbnUgKHRoZSBgZW5hYmxlZGAgY29sdW1uIGlzIHRoZSBhdXRob3JlZCBkZWZhdWx0OyBhXG4vLyB2aWV3ZXIncyB0b2dnbGUgc2hvdWxkbid0IHdyaXRlIHRvIHRoZSByZXBvcnQpLlxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFJlcG9ydEZpbHRlclN0YXRlU2VydmljZSB7XG5cbiAgLy8gVGhlIG9wZW4gcmVwb3J0J3MgZWZmZWN0aXZlIHpvbmUgKHJlc29sdmVSZXBvcnRUaW1lem9uZSkuIFJlbGF0aXZlIHByZXNldHNcbiAgLy8gcmVzb2x2ZSBhZ2FpbnN0IHRvZGF5IGluIGl0LCBhbmQgZGF0ZSBjZWxscyByZW5kZXIgaW4gaXQuXG4gIHB1YmxpYyByZWFkb25seSB0aW1lem9uZSA9IHNpZ25hbDxzdHJpbmc+KCdVVEMnKTtcblxuICBwcml2YXRlIF92YWx1ZXMgPSBuZXcgTWFwPG51bWJlciwgRmlsdGVyR3JvdXBWYWx1ZT4oKTtcbiAgcHJpdmF0ZSBfZ3JvdXBzID0gbmV3IE1hcDxudW1iZXIsIFJlcG9ydEZpbHRlckdyb3VwPigpO1xuICBwcml2YXRlIF9zZXNzaW9uRGlzYWJsZWQgPSBuZXcgU2V0PG51bWJlcj4oKTtcblxuICAvLyBHcm91cHMgdGhhdCBoYXZlIGEgZGVmYXVsdCB0aGUgdmlld2VyIGNsZWFyZWQuIFdpdGhvdXQgdGhpcyBhIHJlbG9hZCBvZiB0aGVcbiAgLy8gcmVwb3J0IChhIGNoYXQgZWRpdCwgYSBkaWFsb2cpIHdvdWxkIGZpbmQgbm8gdmFsdWUgZm9yIHRoZSBncm91cCBhbmQgc2VlZFxuICAvLyBpdHMgZGVmYXVsdCBzdHJhaWdodCBiYWNrLiBBIGNoYW5nZSB0byB0aGUgc3RvcmVkIGRlZmF1bHQgcmVsZWFzZXMgaXQuXG4gIHByaXZhdGUgX2NsZWFyZWQgPSBuZXcgU2V0PG51bWJlcj4oKTtcblxuICAvLyBUaGUgcmVwb3J0J3MgZ3JvdXAtYnkgY29udHJvbDogYSBzaW5nbGUgcmVwb3J0LXdpZGUgYnVja2V0IG92ZXJyaWRlIGZvciBhbGxcbiAgLy8gdGltZS1zZXJpZXMgY2hhcnRzLiBVbnNldCA9IGVhY2ggY2hhcnQgdXNlcyBpdHMgYXV0aG9yZWQgZ3JhbnVsYXJpdHkuIE5ldmVyXG4gIC8vIHNhdmVkIHRvIHRoZSByZXBvcnQgKHRoZSBVUkwgY2FycmllcyBpdCksIGFuZCBjYXJyaWVkIGluIHRoZSBkYXRhIHJlcXVlc3Qnc1xuICAvLyBgc3RhdGVgLCBzbyBpdCBwcm9wYWdhdGVzIHRocm91Z2ggdG8gdGhlIFBERi9Qb3dlclBvaW50IGV4cG9ydHMgdG9vLiBOYW1lZFxuICAvLyBmb3IgdGhlIGBmcmVxdWVuY3lgIHdpcmUga2V5IGl0IHRyYXZlbHMgdW5kZXIsIG5vdCBmb3IgdGhlIGNvbnRyb2wncyBsYWJlbC5cbiAgcHJpdmF0ZSBfZnJlcXVlbmN5OiBDaGFydEdyYW51bGFyaXR5IHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgX2ZyZXF1ZW5jeUNoYW5nZWQkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICAvLyBFYWNoIGxpc3QncyB2aWV3ZXItY2hvc2VuIHNvcnQsIGJ5IGNvbXBvbmVudCBpZC4gSGVsZCBoZXJlIHJhdGhlciB0aGFuIG9ubHlcbiAgLy8gaW4gdGhlIGxpc3QncyBGc0xpc3Qgc28gaXQgc3Vydml2ZXMgdGhlIGxpc3QgYmVpbmcgcmVjcmVhdGVkIChhIHBhZ2Ugc3dpdGNoLFxuICAvLyBhIHJlbG9hZCBhZnRlciBhbiBlZGl0KSBhbmQgc28gZXZlcnkgY29uc3VtZXIgb2Ygdmlld2VyIHN0YXRlIHJlYWRzIG9uZSBwbGFjZS5cbiAgcHJpdmF0ZSBfbGlzdFNvcnRzID0gbmV3IE1hcDxudW1iZXIsIFJlcG9ydFNvcnQ+KCk7XG5cbiAgLy8gRW1pdHMgdGhlIGdyb3VwIGlkIHRoYXQgY2hhbmdlZDsgY29tcG9uZW50cyBsaXN0ZW4gZmlsdGVyZWQgdG8gdGhlaXIgb3duXG4gIC8vIGdyb3VwIGlkcy4gbnVsbCA9IGV2ZXJ5dGhpbmcgY2hhbmdlZCAocmUtaW5pdCkuXG4gIHByaXZhdGUgX2NoYW5nZWQkID0gbmV3IFN1YmplY3Q8bnVtYmVyIHwgbnVsbD4oKTtcblxuICAvLyBGaXJlcyB3aGVuZXZlciBhbnl0aGluZyB0aGUgVVJMIGNhcnJpZXMgbWF5IGhhdmUgY2hhbmdlZC5cbiAgcHJpdmF0ZSBfdXJsQ2hhbmdlZCQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG4gIC8vIFNlZWQgZ3JvdXBzICsgdGhlaXIgZGVmYXVsdHMgd2hlbiBhIHJlcG9ydCBsb2Fkcy4gRXhpc3Rpbmcgc2Vzc2lvbiB2YWx1ZXNcbiAgLy8gZm9yIHN0aWxsLWV4aXN0aW5nIGdyb3VwcyBzdXJ2aXZlIGEgc3RydWN0dXJlIHJlLWZldGNoIChhIGNoYXQgZWRpdFxuICAvLyBzaG91bGRuJ3QgcmVzZXQgdGhlIHZpZXdlcidzIGZpbHRlcnMpLCBhbmQgc28gZG9lcyBhIGdyb3VwIHRoZSB2aWV3ZXJcbiAgLy8gY2xlYXJlZCDigJQgVU5MRVNTIHRoZSBncm91cCdzIHN0b3JlZCBkZWZhdWx0IGl0c2VsZiBjaGFuZ2VkLCB3aGljaCBvbmx5XG4gIC8vIGhhcHBlbnMgd2hlbiBhbiBvcGVyYXRvciBzYXZlZCBhIG5ldyBkZWZhdWx0IGluIHJlcG9ydCBzZXR0aW5ncyBvciB0aGVcbiAgLy8gYWdlbnQgc2V0IG9uZS4gVGhhdCBpcyBhbiBleHBsaWNpdCBpbnN0cnVjdGlvbiB0byByZS1zZWVkLCBzbyBpdCB3aW5zIG92ZXJcbiAgLy8gdGhlIHN1cnZpdmluZyBzZXNzaW9uIHZhbHVlOyB3aXRob3V0IGl0IHRoZSBiYXIga2VlcHMgc2hvd2luZyB3aGF0ZXZlciBpdFxuICAvLyB3YXMgZmlyc3Qgc2VlZGVkIHdpdGggdW50aWwgYSBmdWxsIHBhZ2UgcmVsb2FkLlxuICAvL1xuICAvLyBBIGNoYW5nZSBvZiB0aGUgcmVwb3J0J3Mgem9uZSBtb3ZlcyBcInRvZGF5XCIsIHNvIGEgdmFsdWUgc3RpbGwgY2FycnlpbmcgaXRzXG4gIC8vIGdyb3VwIGRlZmF1bHQncyBwcmVzZXQgbmFtZSBpcyByZXNvbHZlZCBhZ2FpbiBpbiB0aGUgbmV3IHpvbmUuIEEgdmFsdWUgdGhlXG4gIC8vIHZpZXdlciBwaWNrZWQsIG9yIG9uZSBjYXJyeWluZyBhbm90aGVyIHByZXNldCBuYW1lLCBpcyBrZXB0IGFzIGl0IGlzLlxuICAvL1xuICAvLyBgcmVzdG9yZWAgaXMgdGhlIHZpZXdlciBzdGF0ZSByZWFkIGZyb20gdGhlIFVSTC4gVGhlIGhvc3QgcGFzc2VzIGl0IG9ubHkgb25cbiAgLy8gdGhlIGZpcnN0IGxvYWQgb2YgYSByZXBvcnQ7IGEgcmVsb2FkIGFmdGVyIGEgY2hhdCBvciBkaWFsb2cgZWRpdCBwYXNzZXNcbiAgLy8gbnVsbCwgc28gdGhlIGluLW1lbW9yeSBzdGF0ZSB3aW5zLiBQYXJhbXMgdGhhdCBuYW1lIGEgZ3JvdXAsIGxpc3Qgb3IgY29sdW1uXG4gIC8vIHRoZSByZXBvcnQgbm8gbG9uZ2VyIGhhcywgb3IgdGhhdCBkbyBub3QgZGVjb2RlLCBhcmUgaWdub3JlZC5cbiAgcHVibGljIGluaXQocmVwb3J0OiBSZXBvcnQsIHJlc3RvcmU6IFJlcG9ydFVybFBhcmFtcyB8IG51bGwgPSBudWxsKTogdm9pZCB7XG4gICAgY29uc3QgcHJldmlvdXNUaW1lem9uZSA9IHRoaXMudGltZXpvbmUoKTtcblxuICAgIC8vIFNldCBmaXJzdDogdGhlIGRlZmF1bHRzIHNlZWRlZCBiZWxvdyByZXNvbHZlIHRoZWlyIHJlbGF0aXZlIHByZXNldHMgaW4gaXQuXG4gICAgdGhpcy50aW1lem9uZS5zZXQocmVzb2x2ZVJlcG9ydFRpbWV6b25lKHJlcG9ydCkpO1xuXG4gICAgY29uc3QgdGltZXpvbmVDaGFuZ2VkID0gcHJldmlvdXNUaW1lem9uZSAhPT0gdGhpcy50aW1lem9uZSgpO1xuICAgIGNvbnN0IHByZXZpb3VzR3JvdXBzID0gdGhpcy5fZ3JvdXBzO1xuICAgIHRoaXMuX2dyb3VwcyA9IG5ldyBNYXA8bnVtYmVyLCBSZXBvcnRGaWx0ZXJHcm91cD4oKTtcblxuICAgIGZvciAoY29uc3QgZ3JvdXAgb2YgcmVwb3J0LmZpbHRlckdyb3VwcyA/PyBbXSkge1xuICAgICAgdGhpcy5fZ3JvdXBzLnNldChncm91cC5pZCwgZ3JvdXApO1xuICAgICAgdGhpcy5fc2VlZChncm91cCwgcHJldmlvdXNHcm91cHMuZ2V0KGdyb3VwLmlkKSA/PyBudWxsLCB0aW1lem9uZUNoYW5nZWQpO1xuICAgIH1cblxuICAgIGlmIChyZXN0b3JlKSB7XG4gICAgICB0aGlzLl9yZXN0b3JlKHJlcG9ydCwgcmVzdG9yZSk7XG4gICAgfVxuXG4gICAgdGhpcy5fcHJ1bmUocmVwb3J0KTtcblxuICAgIHRoaXMuX2NoYW5nZWQkLm5leHQobnVsbCk7XG4gICAgdGhpcy5fdXJsQ2hhbmdlZCQubmV4dCgpO1xuICB9XG5cbiAgcHVibGljIHZhbHVlKGdyb3VwSWQ6IG51bWJlcik6IEZpbHRlckdyb3VwVmFsdWUgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLl92YWx1ZXMuZ2V0KGdyb3VwSWQpO1xuICB9XG5cbiAgLy8gQSBiYXIncyB2YWx1ZSBmb3IgYSBncm91cC4gQSBkYXRlIHJhbmdlIGtlZXBzIHRoZSBzdG9yZWQgcHJlc2V0IG5hbWUgb25seVxuICAvLyB3aGlsZSBpdHMgZGF5cyBhcmUgc3RpbGwgdGhlIHN0b3JlZCBkYXlzOiB0aGUgYmFycyByZS1zZXQgZXZlcnkgZ3JvdXAgdGhleVxuICAvLyBzaG93IHdoZW5ldmVyIGFueSBvbmUgb2YgdGhlbSBjaGFuZ2VzLCBhbmQgYW4gdW50b3VjaGVkIHJvbGxpbmcgcmFuZ2UgbXVzdFxuICAvLyBrZWVwIGl0cyBuYW1lIHJhdGhlciB0aGFuIHR1cm4gaW50byB0d28gZml4ZWQgZGF0ZXMuIEFueSBvdGhlciByYW5nZSwgYVxuICAvLyBwaWNrZXIgc2hvcnRjdXQgaW5jbHVkZWQsIGlzIHN0b3JlZCBhcyB0aGUgZml4ZWQgZGF0ZXMgaXQgc2hvd3MuXG4gIHB1YmxpYyBzZXRWYWx1ZShncm91cElkOiBudW1iZXIsIHZhbHVlOiBGaWx0ZXJHcm91cFZhbHVlIHwgbnVsbCk6IHZvaWQge1xuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgdGhpcy5fdmFsdWVzLmRlbGV0ZShncm91cElkKTtcblxuICAgICAgaWYgKHRoaXMuX2dyb3Vwcy5nZXQoZ3JvdXBJZCk/LmNvbmZpZz8uZGVmYXVsdCkge1xuICAgICAgICB0aGlzLl9jbGVhcmVkLmFkZChncm91cElkKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fdmFsdWVzLnNldChncm91cElkLCB0aGlzLl93aXRoUHJlc2V0KHRoaXMuX3ZhbHVlcy5nZXQoZ3JvdXBJZCksIHZhbHVlKSk7XG4gICAgICB0aGlzLl9jbGVhcmVkLmRlbGV0ZShncm91cElkKTtcbiAgICB9XG5cbiAgICB0aGlzLl9jaGFuZ2VkJC5uZXh0KGdyb3VwSWQpO1xuICAgIHRoaXMuX3VybENoYW5nZWQkLm5leHQoKTtcbiAgfVxuXG4gIC8vIEEgcmVsYXRpdmUgcHJlc2V0IG5hbWUgYXMgdG9kYXkncyByYW5nZSBpbiB0aGUgcmVwb3J0J3Mgem9uZSwgb3IgbnVsbCBmb3JcbiAgLy8gYSBuYW1lIGl0IGRvZXMgbm90IGtub3cuIFRoZSBVUkwgY29kZWMgZGVjb2RlcyBwcmVzZXQgbmFtZXMgdGhyb3VnaCB0aGlzLlxuICBwdWJsaWMgcmVzb2x2ZVJlbGF0aXZlKG5hbWU6IHN0cmluZyk6IHsgc3RhcnQ6IERhdGU7IGVuZDogRGF0ZSB9IHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuX3JlbGF0aXZlUmFuZ2UobmFtZSk7XG4gIH1cblxuICAvLyBUaGUgYWN0aXZlIGdyb3VwLWJ5IGdyYWluLCBvciBudWxsIHdoZW4gdGhlIHZpZXdlciBoYXNuJ3QgY2hvc2VuIG9uZS5cbiAgcHVibGljIGZyZXF1ZW5jeSgpOiBDaGFydEdyYW51bGFyaXR5IHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuX2ZyZXF1ZW5jeTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRGcmVxdWVuY3koZnJlcXVlbmN5OiBDaGFydEdyYW51bGFyaXR5IHwgbnVsbCk6IHZvaWQge1xuICAgIHRoaXMuX2ZyZXF1ZW5jeSA9IGZyZXF1ZW5jeTtcbiAgICB0aGlzLl9mcmVxdWVuY3lDaGFuZ2VkJC5uZXh0KCk7XG4gICAgdGhpcy5fdXJsQ2hhbmdlZCQubmV4dCgpO1xuICB9XG5cbiAgLy8gRmlyZXMgd2hlbmV2ZXIgdGhlIGdyb3VwLWJ5IGdyYWluIGNoYW5nZXMg4oCUIGV2ZXJ5IHRpbWUtc2VyaWVzIGNoYXJ0IGxpc3RlbnNcbiAgLy8gc28gaXQgcmVmZXRjaGVzIGFuZCByZS1idWNrZXRzICh0aGUgb3ZlcnJpZGUgaXNuJ3Qgc2NvcGVkIHRvIGFueSBmaWx0ZXJcbiAgLy8gZ3JvdXAsIHNvIGNoYW5nZXNGb3IoKSBjYW4ndCBjYXJyeSBpdCkuXG4gIHB1YmxpYyBmcmVxdWVuY3lDaGFuZ2VzKCk6IE9ic2VydmFibGU8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLl9mcmVxdWVuY3lDaGFuZ2VkJC5hc09ic2VydmFibGUoKTtcbiAgfVxuXG4gIC8vIFRoZSBzb3J0IHRoZSB2aWV3ZXIgbGFzdCBmZXRjaGVkIGEgbGlzdCB3aXRoLCBvciBudWxsIHdoZW4gaXQgaGFzbid0IHNvcnRlZFxuICAvLyAodGhlIGxpc3QgdGhlbiBmYWxscyBiYWNrIHRvIGl0cyBhdXRob3JlZCBzb3J0KS5cbiAgcHVibGljIGxpc3RTb3J0KGNvbXBvbmVudElkOiBudW1iZXIpOiBSZXBvcnRTb3J0IHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuX2xpc3RTb3J0cy5nZXQoY29tcG9uZW50SWQpID8/IG51bGw7XG4gIH1cblxuICAvLyBSZWNvcmRzIGEgbGlzdCdzIHNvcnQuIERlbGliZXJhdGVseSBlbWl0cyBubyBjaGFuZ2U6IHRoZSBsaXN0IHNldHMgdGhpcyBmcm9tXG4gIC8vIHRoZSBmZXRjaCB0aGF0IGFscmVhZHkgcmFuIHdpdGggdGhhdCBzb3J0LCBzbyBhIG5vdGlmaWNhdGlvbiB3b3VsZCBvbmx5IG1ha2VcbiAgLy8gaXQgcmVmZXRjaCB0aGUgc2FtZSByb3dzLiBPbmx5IHRoZSBVUkwgaGVhcnMgYWJvdXQgaXQuXG4gIHB1YmxpYyBzZXRMaXN0U29ydChjb21wb25lbnRJZDogbnVtYmVyLCBzb3J0OiBSZXBvcnRTb3J0IHwgbnVsbCk6IHZvaWQge1xuICAgIGlmIChzb3J0KSB7XG4gICAgICB0aGlzLl9saXN0U29ydHMuc2V0KGNvbXBvbmVudElkLCBzb3J0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fbGlzdFNvcnRzLmRlbGV0ZShjb21wb25lbnRJZCk7XG4gICAgfVxuXG4gICAgdGhpcy5fdXJsQ2hhbmdlZCQubmV4dCgpO1xuICB9XG5cbiAgLy8gRmlyZXMgd2hlbmV2ZXIgdGhlIHZpZXdlciBzdGF0ZSB0aGUgVVJMIGNhcnJpZXMgbWF5IGhhdmUgY2hhbmdlZDogYSBncm91cFxuICAvLyB2YWx1ZSwgdGhlIGdyYWluLCBhIGxpc3Qgc29ydCwgb3IgYSAocmUpbG9hZCBvZiB0aGUgcmVwb3J0LlxuICBwdWJsaWMgdXJsQ2hhbmdlcygpOiBPYnNlcnZhYmxlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5fdXJsQ2hhbmdlZCQuYXNPYnNlcnZhYmxlKCk7XG4gIH1cblxuICAvLyBUaGUgdmlld2VyIHN0YXRlIHRoZSBVUkwgc2hvdWxkIGNhcnJ5IGZvciBgcmVwb3J0YDogb25seSB3aGF0IGRpZmZlcnMgZnJvbVxuICAvLyB0aGUgYXV0aG9yZWQgZGVmYXVsdHMsIHNvIGFuIHVudG91Y2hlZCByZXBvcnQgaGFzIGEgYmFyZSBVUkwgYW5kIGtlZXBzXG4gIC8vIGZvbGxvd2luZyBpdHMgZGVmYXVsdHMgd2hlbiB0aGV5IGNoYW5nZS4gQSBncm91cCB0aGUgdmlld2VyIGNsZWFyZWQgaXNcbiAgLy8gbnVsbC4gQSBkYXRlIHJhbmdlIGlzIGNvbXBhcmVkIG9uIGl0cyBkYXlzIGFnYWluc3QgaXRzIGRlZmF1bHQgcmVzb2x2ZWRcbiAgLy8gdG9kYXksIHNvIGEgdmFsdWUgdGhhdCBpcyB0aGUgZGVmYXVsdCB1bmRlciBhbm90aGVyIHByZXNldCBuYW1lICh0aGlzWWVhclxuICAvLyBhZ2FpbnN0IGEgeWVhclRvRGF0ZSBkZWZhdWx0KSBpcyBzdGlsbCB0aGUgZGVmYXVsdC5cbiAgcHVibGljIHVybFNuYXBzaG90KHJlcG9ydDogUmVwb3J0KTogUmVwb3J0VXJsU25hcHNob3Qge1xuICAgIGNvbnN0IGdyb3VwcyA9IG5ldyBNYXA8bnVtYmVyLCBGaWx0ZXJHcm91cFZhbHVlIHwgbnVsbD4oKTtcblxuICAgIGZvciAoY29uc3QgZ3JvdXAgb2YgdGhpcy5fZ3JvdXBzLnZhbHVlcygpKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuX3ZhbHVlcy5nZXQoZ3JvdXAuaWQpO1xuXG4gICAgICBpZiAodGhpcy5fY2xlYXJlZC5oYXMoZ3JvdXAuaWQpKSB7XG4gICAgICAgIGdyb3Vwcy5zZXQoZ3JvdXAuaWQsIG51bGwpO1xuICAgICAgfSBlbHNlIGlmICh2YWx1ZSAmJiAhdGhpcy5faXNEZWZhdWx0KGdyb3VwLCB2YWx1ZSkpIHtcbiAgICAgICAgZ3JvdXBzLnNldChncm91cC5pZCwgdmFsdWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGxpc3RTb3J0cyA9IG5ldyBNYXA8bnVtYmVyLCBSZXBvcnRTb3J0PigpO1xuXG4gICAgZm9yIChjb25zdCBjb21wb25lbnQgb2YgdGhpcy5fbGlzdENvbXBvbmVudHMocmVwb3J0KSkge1xuICAgICAgY29uc3Qgc29ydCA9IHRoaXMuX2xpc3RTb3J0cy5nZXQoY29tcG9uZW50LmlkKTtcblxuICAgICAgaWYgKHNvcnQgJiYgIXNhbWVTb3J0KHNvcnQsIGNvbXBvbmVudC5jb25maWc/LnNvcnQgPz8gbnVsbCkpIHtcbiAgICAgICAgbGlzdFNvcnRzLnNldChjb21wb25lbnQuaWQsIHNvcnQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7IGdyb3VwcywgbGlzdFNvcnRzLCBmcmVxdWVuY3k6IHRoaXMuX2ZyZXF1ZW5jeSB9O1xuICB9XG5cbiAgcHVibGljIGlzRmlsdGVyRGlzYWJsZWQoZmlsdGVySWQ6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9zZXNzaW9uRGlzYWJsZWQuaGFzKGZpbHRlcklkKTtcbiAgfVxuXG4gIHB1YmxpYyB0b2dnbGVGaWx0ZXIoZmlsdGVySWQ6IG51bWJlciwgZ3JvdXBJZDogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX3Nlc3Npb25EaXNhYmxlZC5oYXMoZmlsdGVySWQpKSB7XG4gICAgICB0aGlzLl9zZXNzaW9uRGlzYWJsZWQuZGVsZXRlKGZpbHRlcklkKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fc2Vzc2lvbkRpc2FibGVkLmFkZChmaWx0ZXJJZCk7XG4gICAgfVxuXG4gICAgdGhpcy5fY2hhbmdlZCQubmV4dChncm91cElkKTtcbiAgfVxuXG4gIC8vIE5vdGlmaWNhdGlvbnMgcmVsZXZhbnQgdG8gT05FIGNvbXBvbmVudDogYW55IGNoYW5nZSB0byBhIGdyb3VwIG9uZSBvZiBpdHNcbiAgLy8gZmlsdGVycyBiZWxvbmdzIHRvIChvciBhIGZ1bGwgcmUtaW5pdCkuXG4gIHB1YmxpYyBjaGFuZ2VzRm9yKGNvbXBvbmVudDogUmVwb3J0Q29tcG9uZW50KTogT2JzZXJ2YWJsZTxudW1iZXIgfCBudWxsPiB7XG4gICAgY29uc3QgZ3JvdXBJZHMgPSBuZXcgU2V0KChjb21wb25lbnQuZmlsdGVycyA/PyBbXSkubWFwKChmaWx0ZXIpID0+IGZpbHRlci5maWx0ZXJHcm91cElkKSk7XG5cbiAgICByZXR1cm4gdGhpcy5fY2hhbmdlZCQuYXNPYnNlcnZhYmxlKClcbiAgICAgIC5waXBlKFxuICAgICAgICByeEZpbHRlcigoZ3JvdXBJZCkgPT4gZ3JvdXBJZCA9PT0gbnVsbCB8fCBncm91cElkcy5oYXMoZ3JvdXBJZCkpLFxuICAgICAgKTtcbiAgfVxuXG4gIC8vIFRoZSBncm91cCB2YWx1ZXMgcmVzb2x2ZWQgaW50byB0aGlzIGNvbXBvbmVudCdzIG1lbWJlci1maWx0ZXIgdmFsdWVzIOKAlFxuICAvLyB3aGF0IHRoZSBkYXRhIHJlcXVlc3QgY2Fycmllcy4gRGlzYWJsZWQgZmlsdGVycyAoYXV0aG9yZWQgb3Igc2Vzc2lvbikgYXJlXG4gIC8vIHNraXBwZWQgZW50aXJlbHkuXG4gIHB1YmxpYyByZXNvbHZlRm9yQ29tcG9uZW50KGNvbXBvbmVudDogUmVwb3J0Q29tcG9uZW50KTogUmVzb2x2ZWRGaWx0ZXJWYWx1ZVtdIHtcbiAgICBjb25zdCByZXNvbHZlZDogUmVzb2x2ZWRGaWx0ZXJWYWx1ZVtdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IGZpbHRlciBvZiBjb21wb25lbnQuZmlsdGVycyA/PyBbXSkge1xuICAgICAgaWYgKCFmaWx0ZXIuZW5hYmxlZCB8fCB0aGlzLl9zZXNzaW9uRGlzYWJsZWQuaGFzKGZpbHRlci5pZCkpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5fdmFsdWVzLmdldChmaWx0ZXIuZmlsdGVyR3JvdXBJZCk7XG4gICAgICBjb25zdCBmaWVsZHMgPSB2YWx1ZSA/IHRoaXMuX3Jlc29sdmVkRmllbGRzKHZhbHVlKSA6IG51bGw7XG5cbiAgICAgIGlmIChmaWVsZHMpIHtcbiAgICAgICAgcmVzb2x2ZWQucHVzaCh7IGZpbHRlcklkOiBmaWx0ZXIuaWQsIC4uLmZpZWxkcyB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVzb2x2ZWQ7XG4gIH1cblxuICAvLyBXaGF0IHRoZSB2aWV3ZXIgaGFzIHNldCwgb25lIGVudHJ5IHBlciBmaWx0ZXIgZ3JvdXAsIGZvciB0aGUgcmVwb3J0IGNoYXQ6XG4gIC8vIHRoZSBhZ2VudCByZWFkcyBpdCB0byBrbm93IHdoYXQgaXMgb24gc2NyZWVuLiBHcm91cCBvcmRlciwgbm90IHRoZSBvcmRlclxuICAvLyB0aGUgdmFsdWVzIHdlcmUgc2V0IGluLCBzbyB0aGUgc2FtZSBzdGF0ZSBhbHdheXMgcmVhZHMgdGhlIHNhbWUuIEEgZ3JvdXBcbiAgLy8gd2l0aCBub3RoaW5nIGluIGl0IGlzIGxlZnQgb3V0LCBhbmQgYSBzYXZlZCBkZWZhdWx0IGNvdW50cyB1bnRpbCB0aGVcbiAgLy8gdmlld2VyIGNoYW5nZXMgaXQuIFBlci1maWx0ZXIgdG9nZ2xlcyBhcmUgYSBjb21wb25lbnQncyBvd24gYnVzaW5lc3MsIHNvXG4gIC8vIHRoZXkgYXJlIG5vdCBwYXJ0IG9mIGl0LlxuICBwdWJsaWMgdmlld2VyRmlsdGVycygpOiBSZXBvcnRDaGF0Vmlld2VyRmlsdGVyW10ge1xuICAgIHJldHVybiBbLi4udGhpcy5fdmFsdWVzLmVudHJpZXMoKV1cbiAgICAgIC5zb3J0KChbYV0sIFtiXSkgPT4gYSAtIGIpXG4gICAgICAubWFwKChbZ3JvdXBJZCwgdmFsdWVdKSA9PiB7XG4gICAgICAgIGNvbnN0IGZpZWxkcyA9IHRoaXMuX3Jlc29sdmVkRmllbGRzKHZhbHVlKTtcblxuICAgICAgICByZXR1cm4gZmllbGRzID8geyBncm91cElkLCAuLi5maWVsZHMgfSA6IG51bGw7XG4gICAgICB9KVxuICAgICAgLmZpbHRlcigoZW50cnkpOiBlbnRyeSBpcyBSZXBvcnRDaGF0Vmlld2VyRmlsdGVyID0+IGVudHJ5ICE9PSBudWxsKTtcbiAgfVxuXG4gIC8vIEV2ZXJ5IGNvbXBvbmVudCdzIHJlc29sdmVkIHZhbHVlcyBpbiBvbmUgYXJyYXkg4oCUIHdoYXQgYSByZXBvcnQtbGV2ZWwgZXhwb3J0XG4gIC8vIGNhcnJpZXMgc28gZWFjaCBmaWxlIGluIHRoZSBhcmNoaXZlIGlzIGZpbHRlcmVkIGV4YWN0bHkgYXMgdGhlIHNjcmVlbiBpcy5cbiAgLy8gRmlsdGVyIGlkcyBhcmUgdW5pcXVlIHBlciBjb21wb25lbnQsIHNvIHRoZSBiYWNrZW5kIHBpY2tzIGVhY2ggY29tcG9uZW50J3NcbiAgLy8gb3duIG91dCBvZiB0aGUgcGlsZS4gQSBwYWdlIGlkIG5hcnJvd3MgaXQgdG8gdGhhdCBwYWdlLlxuICBwdWJsaWMgcmVzb2x2ZUZvclJlcG9ydChyZXBvcnQ6IFJlcG9ydCwgcGFnZUlkOiBudW1iZXIgfCBudWxsID0gbnVsbCk6IFJlc29sdmVkRmlsdGVyVmFsdWVbXSB7XG4gICAgY29uc3QgcGFnZXMgPSAocmVwb3J0LnBhZ2VzID8/IFtdKVxuICAgICAgLmZpbHRlcigocGFnZSkgPT4gIXBhZ2VJZCB8fCBwYWdlLmlkID09PSBwYWdlSWQpO1xuXG4gICAgcmV0dXJuIHBhZ2VzXG4gICAgICAuZmxhdE1hcCgocGFnZSkgPT4gKHBhZ2UuY29tcG9uZW50cyA/PyBbXSlcbiAgICAgICAgLmZsYXRNYXAoKGNvbXBvbmVudCkgPT4gdGhpcy5yZXNvbHZlRm9yQ29tcG9uZW50KGNvbXBvbmVudCkpKTtcbiAgfVxuXG4gIC8vIEEgZ3JvdXAgdmFsdWUgYXMgdGhlIGZpZWxkcyBhIHJlcXVlc3QgY2FycmllczogZGF0ZSBib3VuZHMgYXMgY2FsZW5kYXJcbiAgLy8gZGF5cywgc2VsZWN0IHZhbHVlcyB3aGVuIGFueSBhcmUgcGlja2VkLCBrZXl3b3JkIHRleHQgdHJpbW1lZC4gTnVsbCB3aGVuXG4gIC8vIGFsbCBvZiB0aGVtIGFyZSBlbXB0eS4gVGhlIHByZXNldCBuYW1lIGlzIFVSTCBzdGF0ZSBvbmx5LCBzbyBpdCBpcyBsZWZ0XG4gIC8vIGJlaGluZC5cbiAgcHJpdmF0ZSBfcmVzb2x2ZWRGaWVsZHModmFsdWU6IEZpbHRlckdyb3VwVmFsdWUpOiBPbWl0PFJlc29sdmVkRmlsdGVyVmFsdWUsICdmaWx0ZXJJZCc+IHwgbnVsbCB7XG4gICAgY29uc3QgZmllbGRzOiBPbWl0PFJlc29sdmVkRmlsdGVyVmFsdWUsICdmaWx0ZXJJZCc+ID0ge307XG5cbiAgICBpZiAodmFsdWUuc3RhcnQpIHtcbiAgICAgIGZpZWxkcy5zdGFydCA9IGRhdGVCb3VuZFN0cmluZyh2YWx1ZS5zdGFydCk7XG4gICAgfVxuICAgIGlmICh2YWx1ZS5lbmQpIHtcbiAgICAgIGZpZWxkcy5lbmQgPSBkYXRlQm91bmRTdHJpbmcodmFsdWUuZW5kKTtcbiAgICB9XG4gICAgaWYgKHZhbHVlLnZhbHVlcz8ubGVuZ3RoKSB7XG4gICAgICBmaWVsZHMudmFsdWVzID0gdmFsdWUudmFsdWVzO1xuICAgIH1cbiAgICBpZiAodmFsdWUudmFsdWU/LnRyaW0oKSkge1xuICAgICAgZmllbGRzLnZhbHVlID0gdmFsdWUudmFsdWUudHJpbSgpO1xuICAgIH1cblxuICAgIHJldHVybiBmaWVsZHMuc3RhcnQgfHwgZmllbGRzLmVuZCB8fCBmaWVsZHMudmFsdWVzIHx8IGZpZWxkcy52YWx1ZVxuICAgICAgPyBmaWVsZHNcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIC8vIFNlZWRzIG9uZSBncm91cCBvbiAocmUpbG9hZDsgc2VlIGluaXQoKS4gYHByZXZpb3VzYCBpcyB0aGUgZ3JvdXAgYXMgdGhlXG4gIC8vIGxhc3QgbG9hZCBoYWQgaXQsIG9yIG51bGwgd2hlbiBpdCBpcyBuZXcuXG4gIHByaXZhdGUgX3NlZWQoXG4gICAgZ3JvdXA6IFJlcG9ydEZpbHRlckdyb3VwLFxuICAgIHByZXZpb3VzOiBSZXBvcnRGaWx0ZXJHcm91cCB8IG51bGwsXG4gICAgdGltZXpvbmVDaGFuZ2VkOiBib29sZWFuLFxuICApOiB2b2lkIHtcbiAgICBjb25zdCBkZWZhdWx0Q2hhbmdlZCA9ICFzYW1lRGVmYXVsdChwcmV2aW91cz8uY29uZmlnPy5kZWZhdWx0ID8/IG51bGwsIGdyb3VwLmNvbmZpZz8uZGVmYXVsdCA/PyBudWxsKTtcblxuICAgIGlmIChkZWZhdWx0Q2hhbmdlZCkge1xuICAgICAgdGhpcy5fY2xlYXJlZC5kZWxldGUoZ3JvdXAuaWQpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9jbGVhcmVkLmhhcyhncm91cC5pZCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuX3ZhbHVlcy5nZXQoZ3JvdXAuaWQpO1xuICAgIGNvbnN0IHByZXNldFRvUmVzb2x2ZSA9IHRpbWV6b25lQ2hhbmdlZFxuICAgICAgJiYgISF2YWx1ZT8ucHJlc2V0XG4gICAgICAmJiB2YWx1ZS5wcmVzZXQgPT09IGdyb3VwLmNvbmZpZz8uZGVmYXVsdD8ucmVsYXRpdmU7XG5cbiAgICBpZiAodmFsdWUgJiYgIWRlZmF1bHRDaGFuZ2VkICYmICFwcmVzZXRUb1Jlc29sdmUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBkZWZhdWx0VmFsdWUgPSB0aGlzLl9kZWZhdWx0VmFsdWUoZ3JvdXApO1xuXG4gICAgaWYgKGRlZmF1bHRWYWx1ZSkge1xuICAgICAgdGhpcy5fdmFsdWVzLnNldChncm91cC5pZCwgZGVmYXVsdFZhbHVlKTtcbiAgICB9IGVsc2UgaWYgKGRlZmF1bHRDaGFuZ2VkKSB7XG4gICAgICAvLyBUaGUgZGVmYXVsdCB3YXMgY2xlYXJlZCwgc28gdGhlIHZhbHVlIGl0IHNlZWRlZCBnb2VzIHdpdGggaXQuXG4gICAgICB0aGlzLl92YWx1ZXMuZGVsZXRlKGdyb3VwLmlkKTtcbiAgICB9XG4gIH1cblxuICAvLyBBcHBsaWVzIHRoZSB2aWV3ZXIgc3RhdGUgcmVhZCBmcm9tIHRoZSBVUkwgb24gdG9wIG9mIHRoZSBzZWVkZWQgZGVmYXVsdHMuXG4gIHByaXZhdGUgX3Jlc3RvcmUocmVwb3J0OiBSZXBvcnQsIHJlc3RvcmU6IFJlcG9ydFVybFBhcmFtcyk6IHZvaWQge1xuICAgIHRoaXMuX3Jlc3RvcmVHcm91cHMocmVzdG9yZSk7XG4gICAgdGhpcy5fcmVzdG9yZUxpc3RTb3J0cyhyZXBvcnQsIHJlc3RvcmUpO1xuXG4gICAgLy8gVGhlIFVSTCBpcyB0aGUgd2hvbGUgdHJ1dGggb24gYSBmaXJzdCBsb2FkOiBubyBncmFpbiBpbiBpdCBtZWFucyB0aGVcbiAgICAvLyBhdXRob3JlZCBvbmVzLiBUaGUgaG9zdCBzdGlsbCBkcm9wcyBhIGdyYWluIHRoZSByZXBvcnQgZG9lcyBub3Qgb2ZmZXIuXG4gICAgdGhpcy5fZnJlcXVlbmN5ID0gR1JBTlVMQVJJVFlfT1BUSU9OU1xuICAgICAgLmZpbmQoKG9wdGlvbikgPT4gb3B0aW9uLnZhbHVlID09PSByZXN0b3JlLmdyb3VwQnkpPy52YWx1ZSA/PyBudWxsO1xuICB9XG5cbiAgLy8gVGhlIFVSTCdzIGdyb3VwIHZhbHVlcy4gQW4gZW1wdHkgb25lIGlzIGFuIGV4cGxpY2l0IGNsZWFyIG9mIHRoZSBncm91cC5cbiAgcHJpdmF0ZSBfcmVzdG9yZUdyb3VwcyhyZXN0b3JlOiBSZXBvcnRVcmxQYXJhbXMpOiB2b2lkIHtcbiAgICByZXN0b3JlLmdyb3Vwcy5mb3JFYWNoKChyYXcsIGdyb3VwSWQpID0+IHtcbiAgICAgIGNvbnN0IGdyb3VwID0gdGhpcy5fZ3JvdXBzLmdldChncm91cElkKTtcbiAgICAgIGNvbnN0IHZhbHVlID0gZ3JvdXBcbiAgICAgICAgPyBkZWNvZGVGaWx0ZXJWYWx1ZShncm91cC50eXBlLCByYXcsIChuYW1lKSA9PiB0aGlzLnJlc29sdmVSZWxhdGl2ZShuYW1lKSlcbiAgICAgICAgOiB1bmRlZmluZWQ7XG5cbiAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkge1xuICAgICAgICB0aGlzLl92YWx1ZXMuZGVsZXRlKGdyb3VwSWQpO1xuXG4gICAgICAgIGlmIChncm91cD8uY29uZmlnPy5kZWZhdWx0KSB7XG4gICAgICAgICAgdGhpcy5fY2xlYXJlZC5hZGQoZ3JvdXBJZCk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAodmFsdWUpIHtcbiAgICAgICAgdGhpcy5fdmFsdWVzLnNldChncm91cElkLCB2YWx1ZSk7XG4gICAgICAgIHRoaXMuX2NsZWFyZWQuZGVsZXRlKGdyb3VwSWQpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gVGhlIFVSTCdzIGxpc3Qgc29ydHMsIGVhY2gga2VwdCBvbmx5IGZvciBhIGxpc3QgdGhlIHJlcG9ydCBoYXMgYW5kIGFcbiAgLy8gY29sdW1uIHRoYXQgbGlzdCBjYW4gYmUgc29ydGVkIGJ5LlxuICBwcml2YXRlIF9yZXN0b3JlTGlzdFNvcnRzKHJlcG9ydDogUmVwb3J0LCByZXN0b3JlOiBSZXBvcnRVcmxQYXJhbXMpOiB2b2lkIHtcbiAgICBjb25zdCBsaXN0cyA9IG5ldyBNYXAodGhpcy5fbGlzdENvbXBvbmVudHMocmVwb3J0KS5tYXAoKGNvbXBvbmVudCkgPT4gW2NvbXBvbmVudC5pZCwgY29tcG9uZW50XSkpO1xuXG4gICAgcmVzdG9yZS5saXN0U29ydHMuZm9yRWFjaCgocmF3LCBjb21wb25lbnRJZCkgPT4ge1xuICAgICAgY29uc3QgY29tcG9uZW50ID0gbGlzdHMuZ2V0KGNvbXBvbmVudElkKTtcbiAgICAgIGNvbnN0IHNvcnQgPSBkZWNvZGVTb3J0KHJhdyk7XG5cbiAgICAgIGlmIChjb21wb25lbnQgJiYgc29ydCAmJiB0aGlzLl9zb3J0YWJsZUNvbHVtbnMoY29tcG9uZW50KS5pbmNsdWRlcyhzb3J0LmNvbHVtbikpIHtcbiAgICAgICAgdGhpcy5fbGlzdFNvcnRzLnNldChjb21wb25lbnRJZCwgc29ydCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBEcm9wcyBzdGF0ZSBrZXB0IGZvciBncm91cHMsIGxpc3RzIGFuZCBmaWx0ZXJzIHRoZSByZXBvcnQgbm8gbG9uZ2VyIGhhcy5cbiAgLy8gQSBsaXN0IHNvcnQgYWxzbyBnb2VzIHdoZW4gaXRzIGNvbHVtbiBkb2VzOiB0aGUgYWdlbnQgY2FuIHJlbW92ZSBvciByZW5hbWVcbiAgLy8gaXQsIGFuZCB0aGUgcmVjcmVhdGVkIGxpc3Qgd291bGQgc2VuZCBhIGNvbHVtbiB0aGUgcXVlcnkgZG9lcyBub3Qga25vdy5cbiAgcHJpdmF0ZSBfcHJ1bmUocmVwb3J0OiBSZXBvcnQpOiB2b2lkIHtcbiAgICBmb3IgKGNvbnN0IGdyb3VwSWQgb2YgWy4uLnRoaXMuX3ZhbHVlcy5rZXlzKCksIC4uLnRoaXMuX2NsZWFyZWRdKSB7XG4gICAgICBpZiAoIXRoaXMuX2dyb3Vwcy5oYXMoZ3JvdXBJZCkpIHtcbiAgICAgICAgdGhpcy5fdmFsdWVzLmRlbGV0ZShncm91cElkKTtcbiAgICAgICAgdGhpcy5fY2xlYXJlZC5kZWxldGUoZ3JvdXBJZCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgbGlzdHMgPSBuZXcgTWFwKHRoaXMuX2xpc3RDb21wb25lbnRzKHJlcG9ydCkubWFwKChjb21wb25lbnQpID0+IFtjb21wb25lbnQuaWQsIGNvbXBvbmVudF0pKTtcblxuICAgIHRoaXMuX2xpc3RTb3J0cy5mb3JFYWNoKChzb3J0LCBjb21wb25lbnRJZCkgPT4ge1xuICAgICAgY29uc3QgY29tcG9uZW50ID0gbGlzdHMuZ2V0KGNvbXBvbmVudElkKTtcblxuICAgICAgaWYgKCFjb21wb25lbnQgfHwgIXRoaXMuX3NvcnRhYmxlQ29sdW1ucyhjb21wb25lbnQpLmluY2x1ZGVzKHNvcnQuY29sdW1uKSkge1xuICAgICAgICB0aGlzLl9saXN0U29ydHMuZGVsZXRlKGNvbXBvbmVudElkKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIGNvbnN0IGZpbHRlcklkcyA9IG5ldyBTZXQodGhpcy5fY29tcG9uZW50cyhyZXBvcnQpXG4gICAgICAuZmxhdE1hcCgoY29tcG9uZW50KSA9PiAoY29tcG9uZW50LmZpbHRlcnMgPz8gW10pLm1hcCgoZmlsdGVyKSA9PiBmaWx0ZXIuaWQpKSk7XG5cbiAgICB0aGlzLl9zZXNzaW9uRGlzYWJsZWQuZm9yRWFjaCgoZmlsdGVySWQpID0+IHtcbiAgICAgIGlmICghZmlsdGVySWRzLmhhcyhmaWx0ZXJJZCkpIHtcbiAgICAgICAgdGhpcy5fc2Vzc2lvbkRpc2FibGVkLmRlbGV0ZShmaWx0ZXJJZCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvLyBUaGUgdmFsdWUgYSBiYXIgc2V0cywga2VlcGluZyB0aGUgc3RvcmVkIHByZXNldCBuYW1lIHdoaWxlIHRoZSBkYXlzIGFyZVxuICAvLyBzdGlsbCB0aGUgc3RvcmVkIGRheXMgKHNlZSBzZXRWYWx1ZSkuXG4gIHByaXZhdGUgX3dpdGhQcmVzZXQoc3RvcmVkOiBGaWx0ZXJHcm91cFZhbHVlIHwgdW5kZWZpbmVkLCB2YWx1ZTogRmlsdGVyR3JvdXBWYWx1ZSk6IEZpbHRlckdyb3VwVmFsdWUge1xuICAgIGNvbnN0IGZpeGVkOiBGaWx0ZXJHcm91cFZhbHVlID0geyAuLi52YWx1ZSB9O1xuICAgIGRlbGV0ZSBmaXhlZC5wcmVzZXQ7XG5cbiAgICByZXR1cm4gc3RvcmVkPy5wcmVzZXQgJiYgc2FtZURheXMoc3RvcmVkLCBmaXhlZClcbiAgICAgID8geyAuLi5maXhlZCwgcHJlc2V0OiBzdG9yZWQucHJlc2V0IH1cbiAgICAgIDogZml4ZWQ7XG4gIH1cblxuICAvLyBXaGV0aGVyIGEgdmFsdWUgaXMgdGhlIGdyb3VwJ3MgYXV0aG9yZWQgZGVmYXVsdCwgYnkgdHlwZTogYSBkYXRlIHJhbmdlIG9uXG4gIC8vIGl0cyBkYXlzICh0aGUgZGVmYXVsdCByZXNvbHZlZCB0b2RheSksIGEgc2VsZWN0IG9uIGl0cyB2YWx1ZXMgaW4gYW55XG4gIC8vIG9yZGVyLCBhIGtleXdvcmQgb24gaXRzIHRleHQuXG4gIHByaXZhdGUgX2lzRGVmYXVsdChncm91cDogUmVwb3J0RmlsdGVyR3JvdXAsIHZhbHVlOiBGaWx0ZXJHcm91cFZhbHVlKTogYm9vbGVhbiB7XG4gICAgY29uc3QgZGVmYXVsdFZhbHVlID0gdGhpcy5fZGVmYXVsdFZhbHVlKGdyb3VwKTtcbiAgICBpZiAoIWRlZmF1bHRWYWx1ZSkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIHN3aXRjaCAoZ3JvdXAudHlwZSkge1xuICAgICAgY2FzZSAnZGF0ZVJhbmdlJzpcbiAgICAgICAgLy8gQW4gdW50b3VjaGVkIHJvbGxpbmcgZGVmYXVsdCBzdGlsbCBjYXJyaWVzIGl0cyBwcmVzZXQgbmFtZS4gSXRzIGRheXNcbiAgICAgICAgLy8gd2VyZSByZXNvbHZlZCB3aGVuIGl0IHdhcyBzZWVkZWQsIGFuZCBhZnRlciBtaWRuaWdodCB0aGV5IG5vIGxvbmdlclxuICAgICAgICAvLyBtYXRjaCB0b2RheSdzLCBidXQgaXQgaXMgc3RpbGwgdGhlIGRlZmF1bHQgYW5kIHN0YXlzIG91dCBvZiB0aGUgVVJMLlxuICAgICAgICBpZiAodmFsdWUucHJlc2V0ICYmIHZhbHVlLnByZXNldCA9PT0gZ3JvdXAuY29uZmlnPy5kZWZhdWx0Py5yZWxhdGl2ZSkge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHNhbWVEYXlzKHZhbHVlLCBkZWZhdWx0VmFsdWUpO1xuXG4gICAgICBjYXNlICdzZWxlY3QnOiB7XG4gICAgICAgIGNvbnN0IHZhbHVlcyA9ICh2YWx1ZS52YWx1ZXMgPz8gW10pLm1hcChTdHJpbmcpLnNvcnQoKTtcbiAgICAgICAgY29uc3QgZGVmYXVsdHMgPSAoZGVmYXVsdFZhbHVlLnZhbHVlcyA/PyBbXSkubWFwKFN0cmluZykuc29ydCgpO1xuXG4gICAgICAgIHJldHVybiB2YWx1ZXMubGVuZ3RoID09PSBkZWZhdWx0cy5sZW5ndGhcbiAgICAgICAgICAmJiB2YWx1ZXMuZXZlcnkoKGl0ZW0sIGluZGV4KSA9PiBpdGVtID09PSBkZWZhdWx0c1tpbmRleF0pO1xuICAgICAgfVxuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gKHZhbHVlLnZhbHVlID8/ICcnKS50cmltKCkgPT09IChkZWZhdWx0VmFsdWUudmFsdWUgPz8gJycpLnRyaW0oKTtcbiAgICB9XG4gIH1cblxuICAvLyBFdmVyeSBjb21wb25lbnQgb2YgdGhlIHJlcG9ydDogaXRzIHBhZ2VzJyBhbmQgaXRzIGhlYWRlciBhbmQgZm9vdGVyJ3MuXG4gIHByaXZhdGUgX2NvbXBvbmVudHMocmVwb3J0OiBSZXBvcnQpOiBSZXBvcnRDb21wb25lbnRbXSB7XG4gICAgcmV0dXJuIFtcbiAgICAgIC4uLihyZXBvcnQucGFnZXMgPz8gW10pLmZsYXRNYXAoKHBhZ2UpID0+IHBhZ2UuY29tcG9uZW50cyA/PyBbXSksXG4gICAgICAuLi4ocmVwb3J0Lm1hc3Rlcj8uY29tcG9uZW50cyA/PyBbXSksXG4gICAgXTtcbiAgfVxuXG4gIHByaXZhdGUgX2xpc3RDb21wb25lbnRzKHJlcG9ydDogUmVwb3J0KTogUmVwb3J0Q29tcG9uZW50W10ge1xuICAgIHJldHVybiB0aGlzLl9jb21wb25lbnRzKHJlcG9ydClcbiAgICAgIC5maWx0ZXIoKGNvbXBvbmVudCkgPT4gY29tcG9uZW50LnR5cGUgPT09ICdsaXN0Jyk7XG4gIH1cblxuICAvLyBUaGUgY29sdW1ucyBhIGxpc3QgY2FuIGJlIHNvcnRlZCBieTogZXZlcnkgYXV0aG9yZWQgY29sdW1uLCBvciBhXG4gIC8vIGNyb3NzLXRhYidzIHJvdyBjb2x1bW4gb25seSAoaXRzIHBpdm90IGNvbHVtbnMgY29tZSBhbmQgZ28gd2l0aCB0aGUgZGF0YSkuXG4gIHByaXZhdGUgX3NvcnRhYmxlQ29sdW1ucyhjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudCk6IHN0cmluZ1tdIHtcbiAgICBjb25zdCBjb25maWcgPSBjb21wb25lbnQuY29uZmlnO1xuXG4gICAgaWYgKGNvbmZpZz8ucGl2b3RCeT8uY29sdW1uKSB7XG4gICAgICByZXR1cm4gY29uZmlnLnJvd0J5Py5jb2x1bW4gPyBbY29uZmlnLnJvd0J5LmNvbHVtbl0gOiBbXTtcbiAgICB9XG5cbiAgICByZXR1cm4gKGNvbmZpZz8uY29sdW1ucyA/PyBbXSkubWFwKChjb2x1bW4pID0+IGNvbHVtbi5jb2x1bW4pO1xuICB9XG5cbiAgLy8gQSBncm91cCdzIGF1dGhvcmVkIGRlZmF1bHQsIG1hcHBlZCB0byBhIHNlc3Npb24gdmFsdWUgYnkgdHlwZS4gUmVsYXRpdmVcbiAgLy8gZGF0ZSBwcmVzZXRzIHJlc29sdmUgYWdhaW5zdCBcIm5vd1wiIGVhY2ggdGltZSB0aGUgcmVwb3J0IG9wZW5zLCBzbyBhIHNhdmVkXG4gIC8vIFwibGFzdCAxMiBtb250aHNcIiBzdGF5cyByZWxhdGl2ZSBhbmQgY2FycmllcyBpdHMgcHJlc2V0IG5hbWU7IGEgZml4ZWRcbiAgLy8gcmFuZ2UsIHNlbGVjdCB2YWx1ZXMgYW5kIGtleXdvcmQgdGV4dCBzZWVkIHZlcmJhdGltLlxuICBwcml2YXRlIF9kZWZhdWx0VmFsdWUoZ3JvdXA6IFJlcG9ydEZpbHRlckdyb3VwKTogRmlsdGVyR3JvdXBWYWx1ZSB8IG51bGwge1xuICAgIGNvbnN0IGdyb3VwRGVmYXVsdCA9IGdyb3VwLmNvbmZpZz8uZGVmYXVsdDtcbiAgICBpZiAoIWdyb3VwRGVmYXVsdCkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuXG4gICAgaWYgKGdyb3VwRGVmYXVsdC5yZWxhdGl2ZSkge1xuICAgICAgY29uc3QgcmFuZ2UgPSB0aGlzLl9yZWxhdGl2ZVJhbmdlKGdyb3VwRGVmYXVsdC5yZWxhdGl2ZSk7XG5cbiAgICAgIHJldHVybiByYW5nZSA/IHsgc3RhcnQ6IHJhbmdlLnN0YXJ0LCBlbmQ6IHJhbmdlLmVuZCwgcHJlc2V0OiBncm91cERlZmF1bHQucmVsYXRpdmUgfSA6IG51bGw7XG4gICAgfVxuXG4gICAgaWYgKGdyb3VwRGVmYXVsdC5zdGFydCB8fCBncm91cERlZmF1bHQuZW5kKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBzdGFydDogZ3JvdXBEZWZhdWx0LnN0YXJ0ID8/IG51bGwsXG4gICAgICAgIGVuZDogZ3JvdXBEZWZhdWx0LmVuZCA/PyBudWxsLFxuICAgICAgfTtcbiAgICB9XG5cbiAgICBpZiAoZ3JvdXBEZWZhdWx0LnZhbHVlcz8ubGVuZ3RoKSB7XG4gICAgICByZXR1cm4geyB2YWx1ZXM6IGdyb3VwRGVmYXVsdC52YWx1ZXMgfTtcbiAgICB9XG5cbiAgICBpZiAoZ3JvdXBEZWZhdWx0LnZhbHVlKSB7XG4gICAgICByZXR1cm4geyB2YWx1ZTogZ3JvdXBEZWZhdWx0LnZhbHVlIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvLyBBIHJlbGF0aXZlIHByZXNldCBhcyBhIGNhbGVuZGFyLWRheSByYW5nZS4gXCJUb2RheVwiIGlzIHRoZSBkYXkgaW4gdGhlXG4gIC8vIHJlcG9ydCdzIGVmZmVjdGl2ZSB6b25lLCBub3QgdGhlIGJyb3dzZXIncywgc28gZXZlcnkgdmlld2VyIHNlZWRzIHRoZSBzYW1lXG4gIC8vIHJhbmdlLiBUaGUgc2VydmVyIHR3aW4gaXMgUmVwb3J0UmVsYXRpdmVSYW5nZUVudW0gKGZyYW1ld29yay9SZXBvcnQvRW51bSksXG4gIC8vIGFuZCBSZXBvcnRSZWxhdGl2ZVJhbmdlRW51bVRlc3QgcGlucyB0aGUgdGFibGUgYm90aCBzaWRlcyBtdXN0IHByb2R1Y2UuXG4gIHByaXZhdGUgX3JlbGF0aXZlUmFuZ2UocmVsYXRpdmU6IHN0cmluZyk6IHsgc3RhcnQ6IERhdGU7IGVuZDogRGF0ZSB9IHwgbnVsbCB7XG4gICAgY29uc3Qgbm93ID0gZ2V0Wm9uZWROb3codGhpcy50aW1lem9uZSgpKTtcblxuICAgIHN3aXRjaCAocmVsYXRpdmUpIHtcbiAgICAgIC8vIEEgY2FsZW5kYXIgd2VlaywgTW9uZGF5IHRvIFN1bmRheSAoUkVQT1JUX1dFRUtfU1RBUlRTX09OLCB0aGUgc2FtZSB3ZWVrXG4gICAgICAvLyB0aGUgc2VydmVyJ3Mgd2Vla2x5IGJ1Y2tldHMgdXNlKSwgaW4gd2hvbGUgZGF5cyDigJQgbm90IHRoZSByb2xsaW5nXG4gICAgICAvLyBzZXZlbiBkYXlzIGBsYXN0N0RheXNgIGdpdmVzLCB3aGljaCBuZXZlciBsaW5lcyB1cCB3aXRoIHRoZSB3ZWVrIGFcbiAgICAgIC8vIHBhcnRuZXIgaGFzIGFscmVhZHkgYmVlbiBzZW50LiBgbGFzdFdlZWtgIGlzIHRoZSBvbmUgYSB3ZWVrbHkgcmVwb3J0XG4gICAgICAvLyB3YW50czogaXQgZW5kcyBvbiB0aGUgcHJldmlvdXMgd2VlaydzIFN1bmRheSByYXRoZXIgdGhhbiBhdCBgbm93YCxcbiAgICAgIC8vIGJlY2F1c2UgdGhlIHdlZWsgaXQgbmFtZXMgaGFzIGNsb3NlZC4gYHRoaXNXZWVrYCBmb2xsb3dzIGV2ZXJ5IG90aGVyXG4gICAgICAvLyBwcmVzZXQgaGVyZSBhbmQgcnVucyB1cCB0byBub3csIHNvIGl0IGlzIGRlbGliZXJhdGVseSBhIHBhcnQtZmluaXNoZWRcbiAgICAgIC8vIHdlZWsgKG9uIGEgU3VuZGF5IGl0IGlzIHRoZSB3aG9sZSBNb25kYXktdG8tU3VuZGF5IHdlZWspLlxuICAgICAgY2FzZSAndGhpc1dlZWsnOlxuICAgICAgICByZXR1cm4geyBzdGFydDogc3RhcnRPZldlZWsobm93LCB7IHdlZWtTdGFydHNPbjogUkVQT1JUX1dFRUtfU1RBUlRTX09OIH0pLCBlbmQ6IG5vdyB9O1xuICAgICAgY2FzZSAnbGFzdFdlZWsnOiB7XG4gICAgICAgIGNvbnN0IHByZXZpb3VzID0gc3ViV2Vla3Mobm93LCAxKTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHN0YXJ0OiBzdGFydE9mV2VlayhwcmV2aW91cywgeyB3ZWVrU3RhcnRzT246IFJFUE9SVF9XRUVLX1NUQVJUU19PTiB9KSxcbiAgICAgICAgICBlbmQ6IGVuZE9mV2VlayhwcmV2aW91cywgeyB3ZWVrU3RhcnRzT246IFJFUE9SVF9XRUVLX1NUQVJUU19PTiB9KSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICAgIGNhc2UgJ2xhc3Q3RGF5cyc6XG4gICAgICAgIHJldHVybiB7IHN0YXJ0OiBzdWJEYXlzKG5vdywgNyksIGVuZDogbm93IH07XG4gICAgICBjYXNlICdsYXN0MzBEYXlzJzpcbiAgICAgICAgcmV0dXJuIHsgc3RhcnQ6IHN1YkRheXMobm93LCAzMCksIGVuZDogbm93IH07XG4gICAgICBjYXNlICdsYXN0M01vbnRocyc6XG4gICAgICAgIHJldHVybiB7IHN0YXJ0OiBzdWJNb250aHMobm93LCAzKSwgZW5kOiBub3cgfTtcbiAgICAgIGNhc2UgJ2xhc3Q2TW9udGhzJzpcbiAgICAgICAgcmV0dXJuIHsgc3RhcnQ6IHN1Yk1vbnRocyhub3csIDYpLCBlbmQ6IG5vdyB9O1xuICAgICAgY2FzZSAnbGFzdDEyTW9udGhzJzpcbiAgICAgICAgcmV0dXJuIHsgc3RhcnQ6IHN1Yk1vbnRocyhub3csIDEyKSwgZW5kOiBub3cgfTtcbiAgICAgIGNhc2UgJ3RoaXNNb250aCc6XG4gICAgICAgIHJldHVybiB7IHN0YXJ0OiBzdGFydE9mTW9udGgobm93KSwgZW5kOiBub3cgfTtcbiAgICAgIGNhc2UgJ3RoaXNRdWFydGVyJzpcbiAgICAgICAgcmV0dXJuIHsgc3RhcnQ6IHN0YXJ0T2ZRdWFydGVyKG5vdyksIGVuZDogbm93IH07XG4gICAgICBjYXNlICd0aGlzWWVhcic6XG4gICAgICBjYXNlICd5ZWFyVG9EYXRlJzpcbiAgICAgICAgcmV0dXJuIHsgc3RhcnQ6IHN0YXJ0T2ZZZWFyKG5vdyksIGVuZDogbm93IH07XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cbn1cbiJdfQ==