@ogidor/dashboard 1.0.2 → 1.0.4

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.
@@ -1,218 +1,288 @@
1
1
  import { Injectable } from '@angular/core';
2
- import { BehaviorSubject, Subject } from 'rxjs';
2
+ import { BehaviorSubject } from 'rxjs';
3
3
  import * as i0 from "@angular/core";
4
4
  export class DashboardStateService {
5
- constructor() {
6
- this.STORAGE_KEY = 'xtb_dashboard_layout';
5
+ constructor(zone) {
6
+ this.zone = zone;
7
+ /**
8
+ * Shared key — stores page list + widget metadata (no positions).
9
+ * Read and written by every window.
10
+ */
11
+ this.SHARED_KEY = 'ogidor_shared';
12
+ this.CHANNEL_NAME = 'ogidor_dashboard_sync';
13
+ this.channel = typeof BroadcastChannel !== 'undefined'
14
+ ? new BroadcastChannel(this.CHANNEL_NAME) : null;
7
15
  this.initialPages = [
8
- {
9
- id: 'page-1',
10
- name: 'Default Workspace',
11
- widgets: [
12
- {
13
- id: 'w-1',
14
- type: 'LINE',
15
- x: 0,
16
- y: 0,
17
- cols: 4,
18
- rows: 4,
19
- title: 'Market Trend',
20
- data: { series: [{ name: 'Price', data: [30, 40, 35, 50, 49, 60, 70, 91, 125] }] }
21
- },
22
- {
23
- id: 'w-2',
24
- type: 'DONUT',
25
- x: 4,
26
- y: 0,
27
- cols: 2,
28
- rows: 4,
29
- title: 'Asset Allocation',
30
- data: { series: [44, 55, 41, 17, 15] }
31
- }
32
- ]
33
- }
16
+ { id: 'page-1', name: 'Default Workspace', widgets: [] }
34
17
  ];
35
18
  this.pagesSubject = new BehaviorSubject(this.initialPages);
36
19
  this.activePageIdSubject = new BehaviorSubject(this.initialPages[0].id);
37
- /**
38
- * Emits whenever a widget's data is updated programmatically.
39
- * Key = widget id, value = new data payload.
40
- */
41
- this.widgetDataSubject = new Subject();
42
- this.widgetData$ = this.widgetDataSubject.asObservable();
43
20
  this.pages$ = this.pagesSubject.asObservable();
44
21
  this.activePageId$ = this.activePageIdSubject.asObservable();
45
- const saved = localStorage.getItem(this.STORAGE_KEY);
46
- if (saved) {
22
+ // Determine whether we are a pop-out window
23
+ const hash = typeof window !== 'undefined'
24
+ ? window.location.hash.replace('#', '').trim() : '';
25
+ this.positionsKey = hash ? `ogidor_positions_${hash}` : 'ogidor_positions_main';
26
+ // 1. Load the shared structural state
27
+ const shared = localStorage.getItem(this.SHARED_KEY);
28
+ if (shared) {
47
29
  try {
48
- this.loadLayout(JSON.parse(saved));
30
+ this._applyShared(JSON.parse(shared), false);
49
31
  }
50
32
  catch (e) {
51
- console.error('Failed to load saved layout', e);
33
+ console.error('[Dashboard] bad shared state', e);
52
34
  }
53
35
  }
36
+ // 2. Overlay this window's saved positions on top
37
+ this._restorePositions();
38
+ // 3. Listen for structural changes broadcast by other windows
39
+ if (this.channel) {
40
+ this.channel.onmessage = (ev) => {
41
+ this.zone.run(() => this._onSyncEvent(ev.data));
42
+ };
43
+ }
54
44
  }
45
+ ngOnDestroy() { this.channel?.close(); }
46
+ // ── Page actions ──────────────────────────────────────────────
55
47
  getActivePage() {
56
48
  return this.pagesSubject.value.find(p => p.id === this.activePageIdSubject.value);
57
49
  }
58
- setActivePage(id) {
59
- this.activePageIdSubject.next(id);
60
- }
50
+ setActivePage(id) { this.activePageIdSubject.next(id); }
61
51
  addPage(name) {
62
- const newPage = {
63
- id: `page-${Date.now()}`,
64
- name,
65
- widgets: []
66
- };
67
- const updatedPages = [...this.pagesSubject.value, newPage];
68
- this.pagesSubject.next(updatedPages);
69
- this.activePageIdSubject.next(newPage.id);
70
- this.saveToLocalStorage();
52
+ const page = { id: `page-${Date.now()}`, name, widgets: [] };
53
+ this.pagesSubject.next([...this.pagesSubject.value, page]);
54
+ this.activePageIdSubject.next(page.id);
55
+ this._saveShared();
56
+ this._broadcast({ type: 'PAGE_ADDED', page });
71
57
  }
72
58
  removePage(id) {
73
59
  const pages = this.pagesSubject.value;
74
60
  if (pages.length <= 1)
75
61
  return;
76
- const updatedPages = pages.filter(p => p.id !== id);
77
- this.pagesSubject.next(updatedPages);
62
+ const updated = pages.filter(p => p.id !== id);
63
+ this.pagesSubject.next(updated);
78
64
  if (this.activePageIdSubject.value === id) {
79
- this.activePageIdSubject.next(updatedPages[0].id);
65
+ this.activePageIdSubject.next(updated[0].id);
80
66
  }
81
- this.saveToLocalStorage();
67
+ this._saveShared();
68
+ this._broadcast({ type: 'PAGE_REMOVED', pageId: id });
82
69
  }
83
- addWidget(type) {
70
+ // ── Widget structural actions (synced to all windows) ─────────
71
+ addWidget(widget) {
84
72
  const activePage = this.getActivePage();
85
73
  if (!activePage)
86
- return;
74
+ throw new Error('No active page');
87
75
  const newWidget = {
88
76
  id: `widget-${Date.now()}`,
89
- type,
90
- x: 0, y: 0,
91
- cols: type === 'DONUT' ? 2 : 4,
92
- rows: 4,
93
- title: `${type.charAt(0) + type.slice(1).toLowerCase()} Chart`,
94
- data: this.getDefaultDataForType(type)
77
+ x: 0, y: 0, cols: 4, rows: 3,
78
+ ...widget,
95
79
  };
96
- activePage.widgets.push(newWidget);
97
- this.updatePages(this.pagesSubject.value);
80
+ activePage.widgets = [...activePage.widgets, newWidget];
81
+ this.pagesSubject.next([...this.pagesSubject.value]);
82
+ this._saveShared();
83
+ this._savePositions(); // register default position locally
84
+ this._broadcast({ type: 'WIDGET_ADDED', pageId: activePage.id, widget: newWidget });
85
+ return newWidget;
98
86
  }
99
- addWidgetWithData(type, title, data) {
87
+ updateWidget(widgetId, patch) {
88
+ const pages = this.pagesSubject.value;
89
+ for (const page of pages) {
90
+ const w = page.widgets.find(w => w.id === widgetId);
91
+ if (w) {
92
+ Object.assign(w, patch);
93
+ this.pagesSubject.next([...pages]);
94
+ this._saveShared();
95
+ this._broadcast({ type: 'WIDGET_META', widgetId, patch });
96
+ return;
97
+ }
98
+ }
99
+ }
100
+ removeWidget(widgetId) {
100
101
  const activePage = this.getActivePage();
101
102
  if (!activePage)
102
103
  return;
103
- const newWidget = {
104
- id: `widget-${Date.now()}`,
105
- type,
106
- x: 0, y: 0,
107
- cols: type === 'DONUT' ? 3 : 6,
108
- rows: 4,
109
- title,
110
- data
111
- };
112
- activePage.widgets.push(newWidget);
113
- this.updatePages(this.pagesSubject.value);
114
- }
115
- getDefaultDataForType(type) {
116
- if (type === 'DONUT') {
117
- return { series: [30, 20, 50] };
118
- }
119
- return {
120
- series: [{
121
- name: 'Sample Data',
122
- data: Array.from({ length: 10 }, () => Math.floor(Math.random() * 100))
123
- }]
124
- };
104
+ const pageId = activePage.id;
105
+ activePage.widgets = activePage.widgets.filter(w => w.id !== widgetId);
106
+ this.pagesSubject.next([...this.pagesSubject.value]);
107
+ this._saveShared();
108
+ this._savePositions();
109
+ this._broadcast({ type: 'WIDGET_REMOVED', pageId, widgetId });
125
110
  }
111
+ // ── Position actions (local to THIS window only) ──────────────
112
+ /**
113
+ * Update a widget's grid position/size.
114
+ * Saved only for this window — never broadcast to others.
115
+ */
126
116
  updateWidgetPosition(pageId, widgetId, x, y, cols, rows) {
127
117
  const pages = this.pagesSubject.value;
128
- const page = pages.find(p => p.id === pageId);
129
- if (page) {
130
- const widget = page.widgets.find(w => w.id === widgetId);
131
- if (widget) {
132
- widget.x = x;
133
- widget.y = y;
134
- widget.cols = cols;
135
- widget.rows = rows;
136
- this.updatePages(pages);
137
- }
118
+ const widget = pages.find(p => p.id === pageId)?.widgets.find(w => w.id === widgetId);
119
+ if (widget) {
120
+ widget.x = x;
121
+ widget.y = y;
122
+ widget.cols = cols;
123
+ widget.rows = rows;
124
+ this.pagesSubject.next([...pages]);
125
+ this._savePositions(); // local only — intentionally no _saveShared / no broadcast
138
126
  }
139
127
  }
140
- removeWidget(widgetId) {
141
- const activePage = this.getActivePage();
142
- if (activePage) {
143
- activePage.widgets = activePage.widgets.filter(w => w.id !== widgetId);
144
- this.updatePages(this.pagesSubject.value);
145
- }
128
+ // ── Serialization ─────────────────────────────────────────────
129
+ serializeLayout() {
130
+ return JSON.stringify({
131
+ pages: this.pagesSubject.value,
132
+ activePageId: this.activePageIdSubject.value,
133
+ });
134
+ }
135
+ loadLayout(config) {
136
+ if (!config?.pages)
137
+ return;
138
+ this._applyShared(config, true);
139
+ this._saveShared();
140
+ this._savePositions();
141
+ }
142
+ popOutPage(pageId) {
143
+ const url = `${window.location.origin}${window.location.pathname}#${pageId}`;
144
+ window.open(url, `workspace_${pageId}`, 'width=1280,height=800,menubar=no,toolbar=no,location=no,status=no');
146
145
  }
146
+ // ── Private helpers ───────────────────────────────────────────
147
147
  /**
148
- * Push new data into a widget by its id.
149
- * The widget's chart will re-render immediately.
150
- *
151
- * @param widgetId The `id` of the target widget.
152
- * @param data New data — `LineBarData` for LINE/BAR, `DonutData` for DONUT.
148
+ * Save page list + widget metadata (titles, cardColor, data) — no positions.
153
149
  */
154
- updateWidgetData(widgetId, data) {
155
- const pages = this.pagesSubject.value;
156
- for (const page of pages) {
157
- const widget = page.widgets.find(w => w.id === widgetId);
158
- if (widget) {
159
- widget.data = data;
160
- this.widgetDataSubject.next({ widgetId, data });
161
- this.updatePages(pages);
162
- return;
150
+ _saveShared() {
151
+ const stripped = this.pagesSubject.value.map(p => ({
152
+ ...p,
153
+ widgets: p.widgets.map(({ id, title, cardColor, data, cols, rows }) =>
154
+ // Keep default cols/rows so new windows get a sensible first-open layout.
155
+ // x/y are intentionally omitted from shared state.
156
+ ({ id, title, cardColor, data, x: 0, y: 0, cols, rows })),
157
+ }));
158
+ localStorage.setItem(this.SHARED_KEY, JSON.stringify({
159
+ pages: stripped,
160
+ activePageId: this.activePageIdSubject.value,
161
+ }));
162
+ }
163
+ /**
164
+ * Save this window's grid positions (x, y, cols, rows) per widget.
165
+ */
166
+ _savePositions() {
167
+ const positions = {};
168
+ for (const page of this.pagesSubject.value) {
169
+ for (const w of page.widgets) {
170
+ positions[`${page.id}:${w.id}`] = { x: w.x, y: w.y, cols: w.cols, rows: w.rows };
163
171
  }
164
172
  }
165
- console.warn(`[Dashboard] updateWidgetData: widget "${widgetId}" not found.`);
173
+ localStorage.setItem(this.positionsKey, JSON.stringify(positions));
166
174
  }
167
- updateWidgetMeta(widgetId, meta) {
168
- const pages = this.pagesSubject.value;
169
- for (const page of pages) {
170
- const widget = page.widgets.find(w => w.id === widgetId);
171
- if (widget) {
172
- if (meta.title !== undefined)
173
- widget.title = meta.title;
174
- if (meta.colors !== undefined)
175
- widget.colors = meta.colors;
176
- if (meta.cardColor !== undefined)
177
- widget.cardColor = meta.cardColor;
178
- if (meta.data !== undefined) {
179
- widget.data = meta.data;
180
- this.widgetDataSubject.next({ widgetId, data: meta.data });
175
+ /**
176
+ * Overlay the positions saved for THIS window on top of the current pages.
177
+ */
178
+ _restorePositions() {
179
+ const raw = localStorage.getItem(this.positionsKey);
180
+ if (!raw)
181
+ return;
182
+ try {
183
+ const positions = JSON.parse(raw);
184
+ const pages = this.pagesSubject.value;
185
+ for (const page of pages) {
186
+ for (const w of page.widgets) {
187
+ const pos = positions[`${page.id}:${w.id}`];
188
+ if (pos) {
189
+ w.x = pos.x;
190
+ w.y = pos.y;
191
+ w.cols = pos.cols;
192
+ w.rows = pos.rows;
193
+ }
181
194
  }
182
- this.updatePages(pages);
183
- return;
184
195
  }
196
+ this.pagesSubject.next([...pages]);
197
+ }
198
+ catch (e) {
199
+ console.error('[Dashboard] bad positions state', e);
185
200
  }
186
201
  }
187
- updatePages(pages) {
188
- this.pagesSubject.next([...pages]);
189
- this.saveToLocalStorage();
190
- }
191
- serializeLayout() {
192
- const config = {
193
- pages: this.pagesSubject.value,
194
- activePageId: this.activePageIdSubject.value
195
- };
196
- return JSON.stringify(config);
202
+ /**
203
+ * Apply a shared config object (page list + metadata) without touching
204
+ * this window's saved positions.
205
+ */
206
+ _applyShared(config, overwritePositions) {
207
+ if (!config?.pages)
208
+ return;
209
+ this.pagesSubject.next(config.pages);
210
+ if (config.activePageId)
211
+ this.activePageIdSubject.next(config.activePageId);
212
+ if (!overwritePositions)
213
+ this._restorePositions();
197
214
  }
198
- loadLayout(config) {
199
- if (config && config.pages) {
200
- this.pagesSubject.next(config.pages);
201
- if (config.activePageId) {
202
- this.activePageIdSubject.next(config.activePageId);
215
+ /**
216
+ * Handle a structural sync event arriving from another window.
217
+ * Position changes are never sent so we never receive them here.
218
+ */
219
+ _onSyncEvent(event) {
220
+ // Work on a shallow clone of pages so Angular detects the change
221
+ const pages = this.pagesSubject.value.map(p => ({
222
+ ...p, widgets: [...p.widgets]
223
+ }));
224
+ switch (event.type) {
225
+ case 'PAGE_ADDED':
226
+ if (!pages.find(p => p.id === event.page.id)) {
227
+ pages.push({ ...event.page, widgets: [...event.page.widgets] });
228
+ this.pagesSubject.next(pages);
229
+ this._saveShared();
230
+ }
231
+ break;
232
+ case 'PAGE_REMOVED': {
233
+ const updated = pages.filter(p => p.id !== event.pageId);
234
+ if (updated.length !== pages.length) {
235
+ this.pagesSubject.next(updated);
236
+ if (this.activePageIdSubject.value === event.pageId) {
237
+ this.activePageIdSubject.next(updated[0]?.id ?? '');
238
+ }
239
+ this._saveShared();
240
+ }
241
+ break;
242
+ }
243
+ case 'WIDGET_ADDED': {
244
+ const page = pages.find(p => p.id === event.pageId);
245
+ if (page && !page.widgets.find(w => w.id === event.widget.id)) {
246
+ page.widgets = [...page.widgets, { ...event.widget }];
247
+ this.pagesSubject.next(pages);
248
+ this._saveShared();
249
+ // Don't touch positions — this window will keep its own layout for
250
+ // existing widgets; the new one starts at its default position.
251
+ }
252
+ break;
253
+ }
254
+ case 'WIDGET_REMOVED': {
255
+ const page = pages.find(p => p.id === event.pageId);
256
+ if (page) {
257
+ page.widgets = page.widgets.filter(w => w.id !== event.widgetId);
258
+ this.pagesSubject.next(pages);
259
+ this._saveShared();
260
+ this._savePositions();
261
+ }
262
+ break;
263
+ }
264
+ case 'WIDGET_META': {
265
+ for (const page of pages) {
266
+ const w = page.widgets.find(w => w.id === event.widgetId);
267
+ if (w) {
268
+ Object.assign(w, event.patch);
269
+ this.pagesSubject.next(pages);
270
+ this._saveShared();
271
+ break;
272
+ }
273
+ }
274
+ break;
203
275
  }
204
276
  }
205
277
  }
206
- saveToLocalStorage() {
207
- localStorage.setItem(this.STORAGE_KEY, this.serializeLayout());
278
+ _broadcast(event) {
279
+ this.channel?.postMessage(event);
208
280
  }
209
281
  }
210
- DashboardStateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DashboardStateService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
282
+ DashboardStateService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DashboardStateService, deps: [{ token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Injectable });
211
283
  DashboardStateService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DashboardStateService, providedIn: 'root' });
212
284
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.10", ngImport: i0, type: DashboardStateService, decorators: [{
213
285
  type: Injectable,
214
- args: [{
215
- providedIn: 'root'
216
- }]
217
- }], ctorParameters: function () { return []; } });
218
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGFzaGJvYXJkLXN0YXRlLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXBwL2Rhc2hib2FyZC1zdGF0ZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLGVBQWUsRUFBRSxPQUFPLEVBQUUsTUFBTSxNQUFNLENBQUM7O0FBTWhELE1BQU0sT0FBTyxxQkFBcUI7SUE2Q2hDO1FBNUNpQixnQkFBVyxHQUFHLHNCQUFzQixDQUFDO1FBRTlDLGlCQUFZLEdBQVc7WUFDN0I7Z0JBQ0UsRUFBRSxFQUFFLFFBQVE7Z0JBQ1osSUFBSSxFQUFFLG1CQUFtQjtnQkFDekIsT0FBTyxFQUFFO29CQUNQO3dCQUNFLEVBQUUsRUFBRSxLQUFLO3dCQUNULElBQUksRUFBRSxNQUFNO3dCQUNaLENBQUMsRUFBRSxDQUFDO3dCQUNKLENBQUMsRUFBRSxDQUFDO3dCQUNKLElBQUksRUFBRSxDQUFDO3dCQUNQLElBQUksRUFBRSxDQUFDO3dCQUNQLEtBQUssRUFBRSxjQUFjO3dCQUNyQixJQUFJLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUU7cUJBQ25GO29CQUNEO3dCQUNFLEVBQUUsRUFBRSxLQUFLO3dCQUNULElBQUksRUFBRSxPQUFPO3dCQUNiLENBQUMsRUFBRSxDQUFDO3dCQUNKLENBQUMsRUFBRSxDQUFDO3dCQUNKLElBQUksRUFBRSxDQUFDO3dCQUNQLElBQUksRUFBRSxDQUFDO3dCQUNQLEtBQUssRUFBRSxrQkFBa0I7d0JBQ3pCLElBQUksRUFBRSxFQUFF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RSxDQUFDO0lBQzVCLENBQUM7SUFFRCxlQUFlO1FBQ2IsTUFBTSxNQUFNLEdBQW9CO1lBQzlCLEtBQUssRUFBRSxJQUFJLENBQUMsWUFBWSxDQUFDLEtBQUs7WUFDOUIsWUFBWSxFQUFFLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLO1NBQzdDLENBQUM7UUFDRixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDaEMsQ0FBQztJQUVELFVBQVUsQ0FBQyxNQUFXO1FBQ3BCLElBQUksTUFBTSxJQUFJLE1BQU0sQ0FBQyxLQUFLLEVBQUU7WUFDMUIsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3JDLElBQUksTUFBTSxDQUFDLFlBQVksRUFBRTtnQkFDdkIsSUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLENBQUM7YUFDcEQ7U0FDRjtJQUNILENBQUM7SUFFTyxrQkFBa0I7UUFDeEIsWUFBWSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQyxDQUFDO0lBQ2pFLENBQUM7O21IQS9OVSxxQkFBcUI7dUhBQXJCLHFCQUFxQixjQUZwQixNQUFNOzRGQUVQLHFCQUFxQjtrQkFIakMsVUFBVTttQkFBQztvQkFDVixVQUFVLEVBQUUsTUFBTTtpQkFDbkIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IFBhZ2UsIFdpZGdldCwgRGFzaGJvYXJkQ29uZmlnLCBXaWRnZXRUeXBlLCBMaW5lQmFyRGF0YSwgRG9udXREYXRhIH0gZnJvbSAnLi9tb2RlbHMnO1xuXG5ASW5qZWN0YWJsZSh7XG4gIHByb3ZpZGVkSW46ICdyb290J1xufSlcbmV4cG9ydCBjbGFzcyBEYXNoYm9hcmRTdGF0ZVNlcnZpY2Uge1xuICBwcml2YXRlIHJlYWRvbmx5IFNUT1JBR0VfS0VZID0gJ3h0Yl9kYXNoYm9hcmRfbGF5b3V0JztcbiAgXG4gIHByaXZhdGUgaW5pdGlhbFBhZ2VzOiBQYWdlW10gPSBbXG4gICAge1xuICAgICAgaWQ6ICdwYWdlLTEnLFxuICAgICAgbmFtZTogJ0RlZmF1bHQgV29ya3NwYWNlJyxcbiAgICAgIHdpZGdldHM6IFtcbiAgICAgICAge1xuICAgICAgICAgIGlkOiAndy0xJyxcbiAgICAgICAgICB0eXBlOiAnTElORScsXG4gICAgICAgICAgeDogMCxcbiAgICAgICAgICB5OiAwLFxuICAgICAgICAgIGNvbHM6IDQsXG4gICAgICAgICAgcm93czogNCxcbiAgICAgICAgICB0aXRsZTogJ01hcmtldCBUcmVuZCcsXG4gICAgICAgICAgZGF0YTogeyBzZXJpZXM6IFt7IG5hbWU6ICdQcmljZScsIGRhdGE6IFszMCwgNDAsIDM1LCA1MCwgNDksIDYwLCA3MCwgOTEsIDEyNV0gfV0gfVxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgaWQ6ICd3LTInLFxuICAgICAgICAgIHR5cGU6ICdET05VVCcsXG4gICAgICAgICAgeDogNCxcbiAgICAgICAgICB5OiAwLFxuICAgICAgICAgIGNvbHM6IDIsXG4gICAgICAgICAgcm93czogNCxcbiAgICAgICAgICB0aXRsZTogJ0Fzc2V0IEFsbG9jYXRpb24nLFxuICAgICAgICAgIGRhdGE6IHsgc2VyaWVzOiBbNDQsIDU1LCA0MSwgMTcsIDE1XSB9XG4gICAgICAgIH1cbiAgICAgIF1cbiAgICB9XG4gIF07XG5cbiAgcHJpdmF0ZSBwYWdlc1N1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFBhZ2VbXT4odGhpcy5pbml0aWFsUGFnZXMpO1xuICBwcml2YXRlIGFjdGl2ZVBhZ2VJZFN1YmplY3QgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PHN0cmluZz4odGhpcy5pbml0aWFsUGFnZXNbMF0uaWQpO1xuXG4gIC8qKlxuICAgKiBFbWl0cyB3aGVuZXZlciBhIHdpZGdldCdzIGRhdGEgaXMgdXBkYXRlZCBwcm9ncmFtbWF0aWNhbGx5LlxuICAgKiBLZXkgPSB3aWRnZXQgaWQsIHZhbHVlID0gbmV3IGRhdGEgcGF5bG9hZC5cbiAgICovXG4gIHByaXZhdGUgd2lkZ2V0RGF0YVN1YmplY3QgPSBuZXcgU3ViamVjdDx7IHdpZGdldElkOiBzdHJpbmc7IGRhdGE6IExpbmVCYXJEYXRhIHwgRG9udXREYXRhIH0+KCk7XG4gIHdpZGdldERhdGEkID0gdGhpcy53aWRnZXREYXRhU3ViamVjdC5hc09ic2VydmFibGUoKTtcblxuICBwYWdlcyQgPSB0aGlzLnBhZ2VzU3ViamVjdC5hc09ic2VydmFibGUoKTtcbiAgYWN0aXZlUGFnZUlkJCA9IHRoaXMuYWN0aXZlUGFnZUlkU3ViamVjdC5hc09ic2VydmFibGUoKTtcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBjb25zdCBzYXZlZCA9IGxvY2FsU3RvcmFnZS5nZXRJdGVtKHRoaXMuU1RPUkFHRV9LRVkpO1xuICAgIGlmIChzYXZlZCkge1xuICAgICAgdHJ5IHtcbiAgICAgICAgdGhpcy5sb2FkTGF5b3V0KEpTT04ucGFyc2Uoc2F2ZWQpKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcignRmFpbGVkIHRvIGxvYWQgc2F2ZWQgbGF5b3V0JywgZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2V0QWN0aXZlUGFnZSgpOiBQYWdlIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5wYWdlc1N1YmplY3QudmFsdWUuZmluZChwID0+IHAuaWQgPT09IHRoaXMuYWN0aXZlUGFnZUlkU3ViamVjdC52YWx1ZSk7XG4gIH1cblxuICBzZXRBY3RpdmVQYWdlKGlkOiBzdHJpbmcpIHtcbiAgICB0aGlzLmFjdGl2ZVBhZ2VJZFN1YmplY3QubmV4dChpZCk7XG4gIH1cblxuICBhZGRQYWdlKG5hbWU6IHN0cmluZykge1xuICAgIGNvbnN0IG5ld1BhZ2U6IFBhZ2UgPSB7XG4gICAgICBpZDogYHBhZ2UtJHtEYXRlLm5vdygpfWAsXG4gICAgICBuYW1lLFxuICAgICAgd2lkZ2V0czogW11cbiAgICB9O1xuICAgIGNvbnN0IHVwZGF0ZWRQYWdlcyA9IFsuLi50aGlzLnBhZ2VzU3ViamVjdC52YWx1ZSwgbmV3UGFnZV07XG4gICAgdGhpcy5wYWdlc1N1YmplY3QubmV4dCh1cGRhdGVkUGFnZXMpO1xuICAgIHRoaXMuYWN0aXZlUGFnZUlkU3ViamVjdC5uZXh0KG5ld1BhZ2UuaWQpO1xuICAgIHRoaXMuc2F2ZVRvTG9jYWxTdG9yYWdlKCk7XG4gIH1cblxuICByZW1vdmVQYWdlKGlkOiBzdHJpbmcpIHtcbiAgICBjb25zdCBwYWdlcyA9IHRoaXMucGFnZXNTdWJqZWN0LnZhbHVlO1xuICAgIGlmIChwYWdlcy5sZW5ndGggPD0gMSkgcmV0dXJuO1xuXG4gICAgY29uc3QgdXBkYXRlZFBhZ2VzID0gcGFnZXMuZmlsdGVyKHAgPT4gcC5pZCAhPT0gaWQpO1xuICAgIHRoaXMucGFnZXNTdWJqZWN0Lm5leHQodXBkYXRlZFBhZ2VzKTtcbiAgICBcbiAgICBpZiAodGhpcy5hY3RpdmVQYWdlSWRTdWJqZWN0LnZhbHVlID09PSBpZCkge1xuICAgICAgdGhpcy5hY3RpdmVQYWdlSWRTdWJqZWN0Lm5leHQodXBkYXRlZFBhZ2VzWzBdLmlkKTtcbiAgICB9XG4gICAgdGhpcy5zYXZlVG9Mb2NhbFN0b3JhZ2UoKTtcbiAgfVxuXG4gIGFkZFdpZGdldCh0eXBlOiBXaWRnZXRUeXBlKSB7XG4gICAgY29uc3QgYWN0aXZlUGFnZSA9IHRoaXMuZ2V0QWN0aXZlUGFnZSgpO1xuICAgIGlmICghYWN0aXZlUGFnZSkgcmV0dXJuO1xuXG4gICAgY29uc3QgbmV3V2lkZ2V0OiBXaWRnZXQgPSB7XG4gICAgICBpZDogYHdpZGdldC0ke0RhdGUubm93KCl9YCxcbiAgICAgIHR5cGUsXG4gICAgICB4OiAwLCB5OiAwLFxuICAgICAgY29sczogdHlwZSA9PT0gJ0RPTlVUJyA/IDIgOiA0LFxuICAgICAgcm93czogNCxcbiAgICAgIHRpdGxlOiBgJHt0eXBlLmNoYXJBdCgwKSArIHR5cGUuc2xpY2UoMSkudG9Mb3dlckNhc2UoKX0gQ2hhcnRgLFxuICAgICAgZGF0YTogdGhpcy5nZXREZWZhdWx0RGF0YUZvclR5cGUodHlwZSlcbiAgICB9O1xuXG4gICAgYWN0aXZlUGFnZS53aWRnZXRzLnB1c2gobmV3V2lkZ2V0KTtcbiAgICB0aGlzLnVwZGF0ZVBhZ2VzKHRoaXMucGFnZXNTdWJqZWN0LnZhbHVlKTtcbiAgfVxuXG4gIGFkZFdpZGdldFdpdGhEYXRhKHR5cGU6IFdpZGdldFR5cGUsIHRpdGxlOiBzdHJpbmcsIGRhdGE6IExpbmVCYXJEYXRhIHwgRG9udXREYXRhKSB7XG4gICAgY29uc3QgYWN0aXZlUGFnZSA9IHRoaXMuZ2V0QWN0aXZlUGFnZSgpO1xuICAgIGlmICghYWN0aXZlUGFnZSkgcmV0dXJuO1xuXG4gICAgY29uc3QgbmV3V2lkZ2V0OiBXaWRnZXQgPSB7XG4gICAgICBpZDogYHdpZGdldC0ke0RhdGUubm93KCl9YCxcbiAgICAgIHR5cGUsXG4gICAgICB4OiAwLCB5OiAwLFxuICAgICAgY29sczogdHlwZSA9PT0gJ0RPTlVUJyA/IDMgOiA2LFxuICAgICAgcm93czogNCxcbiAgICAgIHRpdGxlLFxuICAgICAgZGF0YVxuICAgIH07XG5cbiAgICBhY3RpdmVQYWdlLndpZGdldHMucHVzaChuZXdXaWRnZXQpO1xuICAgIHRoaXMudXBkYXRlUGFnZXModGhpcy5wYWdlc1N1YmplY3QudmFsdWUpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXREZWZhdWx0RGF0YUZvclR5cGUodHlwZTogV2lkZ2V0VHlwZSkge1xuICAgIGlmICh0eXBlID09PSAnRE9OVVQnKSB7XG4gICAgICByZXR1cm4geyBzZXJpZXM6IFszMCwgMjAsIDUwXSB9O1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgc2VyaWVzOiBbe1xuICAgICAgICBuYW1lOiAnU2FtcGxlIERhdGEnLFxuICAgICAgICBkYXRhOiBBcnJheS5mcm9tKHsgbGVuZ3RoOiAxMCB9LCAoKSA9PiBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAxMDApKVxuICAgICAgfV1cbiAgICB9O1xuICB9XG5cbiAgdXBkYXRlV2lkZ2V0UG9zaXRpb24ocGFnZUlkOiBzdHJpbmcsIHdpZGdldElkOiBzdHJpbmcsIHg6IG51bWJlciwgeTogbnVtYmVyLCBjb2xzOiBudW1iZXIsIHJvd3M6IG51bWJlcikge1xuICAgIGNvbnN0IHBhZ2VzID0gdGhpcy5wYWdlc1N1YmplY3QudmFsdWU7XG4gICAgY29uc3QgcGFnZSA9IHBhZ2VzLmZpbmQocCA9PiBwLmlkID09PSBwYWdlSWQpO1xuICAgIGlmIChwYWdlKSB7XG4gICAgICBjb25zdCB3aWRnZXQgPSBwYWdlLndpZGdldHMuZmluZCh3ID0+IHcuaWQgPT09IHdpZGdldElkKTtcbiAgICAgIGlmICh3aWRnZXQpIHtcbiAgICAgICAgd2lkZ2V0LnggPSB4O1xuICAgICAgICB3aWRnZXQueSA9IHk7XG4gICAgICAgIHdpZGdldC5jb2xzID0gY29scztcbiAgICAgICAgd2lkZ2V0LnJvd3MgPSByb3dzO1xuICAgICAgICB0aGlzLnVwZGF0ZVBhZ2VzKHBhZ2VzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZW1vdmVXaWRnZXQod2lkZ2V0SWQ6IHN0cmluZykge1xuICAgIGNvbnN0IGFjdGl2ZVBhZ2UgPSB0aGlzLmdldEFjdGl2ZVBhZ2UoKTtcbiAgICBpZiAoYWN0aXZlUGFnZSkge1xuICAgICAgYWN0aXZlUGFnZS53aWRnZXRzID0gYWN0aXZlUGFnZS53aWRnZXRzLmZpbHRlcih3ID0+IHcuaWQgIT09IHdpZGdldElkKTtcbiAgICAgIHRoaXMudXBkYXRlUGFnZXModGhpcy5wYWdlc1N1YmplY3QudmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBQdXNoIG5ldyBkYXRhIGludG8gYSB3aWRnZXQgYnkgaXRzIGlkLlxuICAgKiBUaGUgd2lkZ2V0J3MgY2hhcnQgd2lsbCByZS1yZW5kZXIgaW1tZWRpYXRlbHkuXG4gICAqXG4gICAqIEBwYXJhbSB3aWRnZXRJZCAgVGhlIGBpZGAgb2YgdGhlIHRhcmdldCB3aWRnZXQuXG4gICAqIEBwYXJhbSBkYXRhICAgICAgTmV3IGRhdGEg4oCUIGBMaW5lQmFyRGF0YWAgZm9yIExJTkUvQkFSLCBgRG9udXREYXRhYCBmb3IgRE9OVVQuXG4gICAqL1xuICB1cGRhdGVXaWRnZXREYXRhKHdpZGdldElkOiBzdHJpbmcsIGRhdGE6IExpbmVCYXJEYXRhIHwgRG9udXREYXRhKSB7XG4gICAgY29uc3QgcGFnZXMgPSB0aGlzLnBhZ2VzU3ViamVjdC52YWx1ZTtcbiAgICBmb3IgKGNvbnN0IHBhZ2Ugb2YgcGFnZXMpIHtcbiAgICAgIGNvbnN0IHdpZGdldCA9IHBhZ2Uud2lkZ2V0cy5maW5kKHcgPT4gdy5pZCA9PT0gd2lkZ2V0SWQpO1xuICAgICAgaWYgKHdpZGdldCkge1xuICAgICAgICB3aWRnZXQuZGF0YSA9IGRhdGE7XG4gICAgICAgIHRoaXMud2lkZ2V0RGF0YVN1YmplY3QubmV4dCh7IHdpZGdldElkLCBkYXRhIH0pO1xuICAgICAgICB0aGlzLnVwZGF0ZVBhZ2VzKHBhZ2VzKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgICBjb25zb2xlLndhcm4oYFtEYXNoYm9hcmRdIHVwZGF0ZVdpZGdldERhdGE6IHdpZGdldCBcIiR7d2lkZ2V0SWR9XCIgbm90IGZvdW5kLmApO1xuICB9XG5cbiAgdXBkYXRlV2lkZ2V0TWV0YSh3aWRnZXRJZDogc3RyaW5nLCBtZXRhOiB7IHRpdGxlPzogc3RyaW5nOyBjb2xvcnM/OiBzdHJpbmdbXTsgY2FyZENvbG9yPzogc3RyaW5nOyBkYXRhPzogTGluZUJhckRhdGEgfCBEb251dERhdGEgfSkge1xuICAgIGNvbnN0IHBhZ2VzID0gdGhpcy5wYWdlc1N1YmplY3QudmFsdWU7XG4gICAgZm9yIChjb25zdCBwYWdlIG9mIHBhZ2VzKSB7XG4gICAgICBjb25zdCB3aWRnZXQgPSBwYWdlLndpZGdldHMuZmluZCh3ID0+IHcuaWQgPT09IHdpZGdldElkKTtcbiAgICAgIGlmICh3aWRnZXQpIHtcbiAgICAgICAgaWYgKG1ldGEudGl0bGUgICAgICE9PSB1bmRlZmluZWQpIHdpZGdldC50aXRsZSAgICAgPSBtZXRhLnRpdGxlO1xuICAgICAgICBpZiAobWV0YS5jb2xvcnMgICAgIT09IHVuZGVmaW5lZCkgd2lkZ2V0LmNvbG9ycyAgICA9IG1ldGEuY29sb3JzO1xuICAgICAgICBpZiAobWV0YS5jYXJkQ29sb3IgIT09IHVuZGVmaW5lZCkgd2lkZ2V0LmNhcmRDb2xvciA9IG1ldGEuY2FyZENvbG9yO1xuICAgICAgICBpZiAobWV0YS5kYXRhICAgICAgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIHdpZGdldC5kYXRhID0gbWV0YS5kYXRhO1xuICAgICAgICAgIHRoaXMud2lkZ2V0RGF0YVN1YmplY3QubmV4dCh7IHdpZGdldElkLCBkYXRhOiBtZXRhLmRhdGEgfSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy51cGRhdGVQYWdlcyhwYWdlcyk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZVBhZ2VzKHBhZ2VzOiBQYWdlW10pIHtcbiAgICB0aGlzLnBhZ2VzU3ViamVjdC5uZXh0KFsuLi5wYWdlc10pO1xuICAgIHRoaXMuc2F2ZVRvTG9jYWxTdG9yYWdlKCk7XG4gIH1cblxuICBzZXJpYWxpemVMYXlvdXQoKTogc3RyaW5nIHtcbiAgICBjb25zdCBjb25maWc6IERhc2hib2FyZENvbmZpZyA9IHtcbiAgICAgIHBhZ2VzOiB0aGlzLnBhZ2VzU3ViamVjdC52YWx1ZSxcbiAgICAgIGFjdGl2ZVBhZ2VJZDogdGhpcy5hY3RpdmVQYWdlSWRTdWJqZWN0LnZhbHVlXG4gICAgfTtcbiAgICByZXR1cm4gSlNPTi5zdHJpbmdpZnkoY29uZmlnKTtcbiAgfVxuXG4gIGxvYWRMYXlvdXQoY29uZmlnOiBhbnkpIHtcbiAgICBpZiAoY29uZmlnICYmIGNvbmZpZy5wYWdlcykge1xuICAgICAgdGhpcy5wYWdlc1N1YmplY3QubmV4dChjb25maWcucGFnZXMpO1xuICAgICAgaWYgKGNvbmZpZy5hY3RpdmVQYWdlSWQpIHtcbiAgICAgICAgdGhpcy5hY3RpdmVQYWdlSWRTdWJqZWN0Lm5leHQoY29uZmlnLmFjdGl2ZVBhZ2VJZCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBzYXZlVG9Mb2NhbFN0b3JhZ2UoKSB7XG4gICAgbG9jYWxTdG9yYWdlLnNldEl0ZW0odGhpcy5TVE9SQUdFX0tFWSwgdGhpcy5zZXJpYWxpemVMYXlvdXQoKSk7XG4gIH1cbn1cbiJdfQ==
286
+ args: [{ providedIn: 'root' }]
287
+ }], ctorParameters: function () { return [{ type: i0.NgZone }]; } });
288
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGFzaGJvYXJkLXN0YXRlLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXBwL2Rhc2hib2FyZC1zdGF0ZS5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQXFCLE1BQU0sZUFBZSxDQUFDO0FBQzlELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxNQUFNLENBQUM7O0FBY3ZDLE1BQU0sT0FBTyxxQkFBcUI7SUE4QmhDLFlBQW9CLElBQVk7UUFBWixTQUFJLEdBQUosSUFBSSxDQUFRO1FBN0JoQzs7O1dBR0c7UUFDYyxlQUFVLEdBQUcsZUFBZSxDQUFDO1FBVzdCLGlCQUFZLEdBQUcsdUJBQXVCLENBQUM7UUFDaEQsWUFBTyxHQUFHLE9BQU8sZ0JBQWdCLEtBQUssV0FBVztZQUN2RCxDQUFDLENBQUMsSUFBSSxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUVsQyxpQkFBWSxHQUFXO1lBQ3RDLEVBQUUsRUFBRSxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsbUJBQW1CLEVBQUUsT0FBTyxFQUFFLEVBQUUsRUFBRTtTQUN6RCxDQUFDO1FBRU0saUJBQVksR0FBUyxJQUFJLGVBQWUsQ0FBUyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUM7UUFDcEUsd0JBQW1CLEdBQUcsSUFBSSxlQUFlLENBQVMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUVuRixXQUFNLEdBQVUsSUFBSSxDQUFDLFlBQVksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNqRCxrQkFBYSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUd0RCw0Q0FBNEM7UUFDNUMsTUFBTSxJQUFJLEdBQUcsT0FBTyxNQUFNLEtBQUssV0FBVztZQUN4QyxDQUFDLENBQUMsTUFBTSxD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QUMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO29CQUMxRCxJQUFJLENBQUMsRUFBRTt3QkFDTCxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7d0JBQzlCLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO3dCQUM5QixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7d0JBQ25CLE1BQU07cUJBQ1A7aUJBQ0Y7Z0JBQ0QsTUFBTTthQUNQO1NBQ0Y7SUFDSCxDQUFDO0lBRU8sVUFBVSxDQUFDLEtBQWdCO1FBQ2pDLElBQUksQ0FBQyxPQUFPLEVBQUUsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ25DLENBQUM7O21IQTlTVSxxQkFBcUI7dUhBQXJCLHFCQUFxQixjQURSLE1BQU07NEZBQ25CLHFCQUFxQjtrQkFEakMsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBOZ1pvbmUsIE9uRGVzdHJveSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBQYWdlLCBXaWRnZXQsIERhc2hib2FyZENvbmZpZyB9IGZyb20gJy4vbW9kZWxzJztcblxudHlwZSBQb3NpdGlvbk1hcCA9IFJlY29yZDxzdHJpbmcsIHsgeDogbnVtYmVyOyB5OiBudW1iZXI7IGNvbHM6IG51bWJlcjsgcm93czogbnVtYmVyIH0+O1xuXG50eXBlIFN5bmNFdmVudCA9XG4gIHwgeyB0eXBlOiAnUEFHRV9BRERFRCc7ICAgIHBhZ2U6IFBhZ2UgfVxuICB8IHsgdHlwZTogJ1BBR0VfUkVNT1ZFRCc7ICBwYWdlSWQ6IHN0cmluZyB9XG4gIHwgeyB0eXBlOiAnUEFHRV9SRU5BTUVEJzsgIHBhZ2VJZDogc3RyaW5nOyBuYW1lOiBzdHJpbmcgfVxuICB8IHsgdHlwZTogJ1dJREdFVF9BRERFRCc7ICBwYWdlSWQ6IHN0cmluZzsgd2lkZ2V0OiBXaWRnZXQgfVxuICB8IHsgdHlwZTogJ1dJREdFVF9SRU1PVkVEJztwYWdlSWQ6IHN0cmluZzsgd2lkZ2V0SWQ6IHN0cmluZyB9XG4gIHwgeyB0eXBlOiAnV0lER0VUX01FVEEnOyAgIHdpZGdldElkOiBzdHJpbmc7IHBhdGNoOiBQYXJ0aWFsPE9taXQ8V2lkZ2V0LCdpZCd8J3gnfCd5J3wnY29scyd8J3Jvd3MnPj4gfTtcblxuQEluamVjdGFibGUoeyBwcm92aWRlZEluOiAncm9vdCcgfSlcbmV4cG9ydCBjbGFzcyBEYXNoYm9hcmRTdGF0ZVNlcnZpY2UgaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICAvKipcbiAgICogU2hhcmVkIGtleSDigJQgc3RvcmVzIHBhZ2UgbGlzdCArIHdpZGdldCBtZXRhZGF0YSAobm8gcG9zaXRpb25zKS5cbiAgICogUmVhZCBhbmQgd3JpdHRlbiBieSBldmVyeSB3aW5kb3cuXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IFNIQVJFRF9LRVkgPSAnb2dpZG9yX3NoYXJlZCc7XG5cbiAgLyoqXG4gICAqIFBlci13aW5kb3cgcG9zaXRpb25zIGtleSDigJQgc3RvcmVzIHtwYWdlSWQ6d2lkZ2V0SWQg4oaSIHt4LHksY29scyxyb3dzfX0uXG4gICAqIFBvcC1vdXQgd2luZG93cyBnZXQgYSBrZXkgc2NvcGVkIHRvIHRoZWlyIHBhZ2VJZCBzbyB0aGV5IG5ldmVyIG92ZXJ3cml0ZVxuICAgKiB0aGUgbWFpbiB3aW5kb3cgb3IgZWFjaCBvdGhlci5cbiAgICogICBtYWluIHdpbmRvdyAg4oaSIG9naWRvcl9wb3NpdGlvbnNfbWFpblxuICAgKiAgIHBvcC1vdXQgI2FiYyDihpIgb2dpZG9yX3Bvc2l0aW9uc19hYmNcbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgcG9zaXRpb25zS2V5OiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBDSEFOTkVMX05BTUUgPSAnb2dpZG9yX2Rhc2hib2FyZF9zeW5jJztcbiAgcHJpdmF0ZSBjaGFubmVsID0gdHlwZW9mIEJyb2FkY2FzdENoYW5uZWwgIT09ICd1bmRlZmluZWQnXG4gICAgPyBuZXcgQnJvYWRjYXN0Q2hhbm5lbCh0aGlzLkNIQU5ORUxfTkFNRSkgOiBudWxsO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgaW5pdGlhbFBhZ2VzOiBQYWdlW10gPSBbXG4gICAgeyBpZDogJ3BhZ2UtMScsIG5hbWU6ICdEZWZhdWx0IFdvcmtzcGFjZScsIHdpZGdldHM6IFtdIH1cbiAgXTtcblxuICBwcml2YXRlIHBhZ2VzU3ViamVjdCAgICAgICA9IG5ldyBCZWhhdmlvclN1YmplY3Q8UGFnZVtdPih0aGlzLmluaXRpYWxQYWdlcyk7XG4gIHByaXZhdGUgYWN0aXZlUGFnZUlkU3ViamVjdCA9IG5ldyBCZWhhdmlvclN1YmplY3Q8c3RyaW5nPih0aGlzLmluaXRpYWxQYWdlc1swXS5pZCk7XG5cbiAgcGFnZXMkICAgICAgICA9IHRoaXMucGFnZXNTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICBhY3RpdmVQYWdlSWQkID0gdGhpcy5hY3RpdmVQYWdlSWRTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgem9uZTogTmdab25lKSB7XG4gICAgLy8gRGV0ZXJtaW5lIHdoZXRoZXIgd2UgYXJlIGEgcG9wLW91dCB3aW5kb3dcbiAgICBjb25zdCBoYXNoID0gdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCdcbiAgICAgID8gd2luZG93LmxvY2F0aW9uLmhhc2gucmVwbGFjZSgnIycsICcnKS50cmltKCkgOiAnJztcbiAgICB0aGlzLnBvc2l0aW9uc0tleSA9IGhhc2ggPyBgb2dpZG9yX3Bvc2l0aW9uc18ke2hhc2h9YCA6ICdvZ2lkb3JfcG9zaXRpb25zX21haW4nO1xuXG4gICAgLy8gMS4gTG9hZCB0aGUgc2hhcmVkIHN0cnVjdHVyYWwgc3RhdGVcbiAgICBjb25zdCBzaGFyZWQgPSBsb2NhbFN0b3JhZ2UuZ2V0SXRlbSh0aGlzLlNIQVJFRF9LRVkpO1xuICAgIGlmIChzaGFyZWQpIHtcbiAgICAgIHRyeSB7IHRoaXMuX2FwcGx5U2hhcmVkKEpTT04ucGFyc2Uoc2hhcmVkKSwgZmFsc2UpOyB9XG4gICAgICBjYXRjaCAoZSkgeyBjb25zb2xlLmVycm9yKCdbRGFzaGJvYXJkXSBiYWQgc2hhcmVkIHN0YXRlJywgZSk7IH1cbiAgICB9XG5cbiAgICAvLyAyLiBPdmVybGF5IHRoaXMgd2luZG93J3Mgc2F2ZWQgcG9zaXRpb25zIG9uIHRvcFxuICAgIHRoaXMuX3Jlc3RvcmVQb3NpdGlvbnMoKTtcblxuICAgIC8vIDMuIExpc3RlbiBmb3Igc3RydWN0dXJhbCBjaGFuZ2VzIGJyb2FkY2FzdCBieSBvdGhlciB3aW5kb3dzXG4gICAgaWYgKHRoaXMuY2hhbm5lbCkge1xuICAgICAgdGhpcy5jaGFubmVsLm9ubWVzc2FnZSA9IChldjogTWVzc2FnZUV2ZW50PFN5bmNFdmVudD4pID0+IHtcbiAgICAgICAgdGhpcy56b25lLnJ1bigoKSA9PiB0aGlzLl9vblN5bmNFdmVudChldi5kYXRhKSk7XG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIG5nT25EZXN0cm95KCkgeyB0aGlzLmNoYW5uZWw/LmNsb3NlKCk7IH1cblxuICAvLyDilIDilIAgUGFnZSBhY3Rpb25zIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIGdldEFjdGl2ZVBhZ2UoKTogUGFnZSB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMucGFnZXNTdWJqZWN0LnZhbHVlLmZpbmQocCA9PiBwLmlkID09PSB0aGlzLmFjdGl2ZVBhZ2VJZFN1YmplY3QudmFsdWUpO1xuICB9XG5cbiAgc2V0QWN0aXZlUGFnZShpZDogc3RyaW5nKSB7IHRoaXMuYWN0aXZlUGFnZUlkU3ViamVjdC5uZXh0KGlkKTsgfVxuXG4gIGFkZFBhZ2UobmFtZTogc3RyaW5nKSB7XG4gICAgY29uc3QgcGFnZTogUGFnZSA9IHsgaWQ6IGBwYWdlLSR7RGF0ZS5ub3coKX1gLCBuYW1lLCB3aWRnZXRzOiBbXSB9O1xuICAgIHRoaXMucGFnZXNTdWJqZWN0Lm5leHQoWy4uLnRoaXMucGFnZXNTdWJqZWN0LnZhbHVlLCBwYWdlXSk7XG4gICAgdGhpcy5hY3RpdmVQYWdlSWRTdWJqZWN0Lm5leHQocGFnZS5pZCk7XG4gICAgdGhpcy5fc2F2ZVNoYXJlZCgpO1xuICAgIHRoaXMuX2Jyb2FkY2FzdCh7IHR5cGU6ICdQQUdFX0FEREVEJywgcGFnZSB9KTtcbiAgfVxuXG4gIHJlbW92ZVBhZ2UoaWQ6IHN0cmluZykge1xuICAgIGNvbnN0IHBhZ2VzID0gdGhpcy5wYWdlc1N1YmplY3QudmFsdWU7XG4gICAgaWYgKHBhZ2VzLmxlbmd0aCA8PSAxKSByZXR1cm47XG4gICAgY29uc3QgdXBkYXRlZCA9IHBhZ2VzLmZpbHRlcihwID0+IHAuaWQgIT09IGlkKTtcbiAgICB0aGlzLnBhZ2VzU3ViamVjdC5uZXh0KHVwZGF0ZWQpO1xuICAgIGlmICh0aGlzLmFjdGl2ZVBhZ2VJZFN1YmplY3QudmFsdWUgPT09IGlkKSB7XG4gICAgICB0aGlzLmFjdGl2ZVBhZ2VJZFN1YmplY3QubmV4dCh1cGRhdGVkWzBdLmlkKTtcbiAgICB9XG4gICAgdGhpcy5fc2F2ZVNoYXJlZCgpO1xuICAgIHRoaXMuX2Jyb2FkY2FzdCh7IHR5cGU6ICdQQUdFX1JFTU9WRUQnLCBwYWdlSWQ6IGlkIH0pO1xuICB9XG5cbiAgLy8g4pSA4pSAIFdpZGdldCBzdHJ1Y3R1cmFsIGFjdGlvbnMgKHN5bmNlZCB0byBhbGwgd2luZG93cykg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgYWRkV2lkZ2V0KHdpZGdldDogUGFydGlhbDxXaWRnZXQ+ICYgeyB0aXRsZTogc3RyaW5nIH0pOiBXaWRnZXQge1xuICAgIGNvbnN0IGFjdGl2ZVBhZ2UgPSB0aGlzLmdldEFjdGl2ZVBhZ2UoKTtcbiAgICBpZiAoIWFjdGl2ZVBhZ2UpIHRocm93IG5ldyBFcnJvcignTm8gYWN0aXZlIHBhZ2UnKTtcbiAgICBjb25zdCBuZXdXaWRnZXQ6IFdpZGdldCA9IHtcbiAgICAgIGlkOiBgd2lkZ2V0LSR7RGF0ZS5ub3coKX1gLFxuICAgICAgeDogMCwgeTogMCwgY29sczogNCwgcm93czogMyxcbiAgICAgIC4uLndpZGdldCxcbiAgICB9O1xuICAgIGFjdGl2ZVBhZ2Uud2lkZ2V0cyA9IFsuLi5hY3RpdmVQYWdlLndpZGdldHMsIG5ld1dpZGdldF07XG4gICAgdGhpcy5wYWdlc1N1YmplY3QubmV4dChbLi4udGhpcy5wYWdlc1N1YmplY3QudmFsdWVdKTtcbiAgICB0aGlzLl9zYXZlU2hhcmVkKCk7XG4gICAgdGhpcy5fc2F2ZVBvc2l0aW9ucygpOyAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gcmVnaXN0ZXIgZGVmYXVsdCBwb3NpdGlvbiBsb2NhbGx5XG4gICAgdGhpcy5fYnJvYWRjYXN0KHsgdHlwZTogJ1dJREdFVF9BRERFRCcsIHBhZ2VJZDogYWN0aXZlUGFnZS5pZCwgd2lkZ2V0OiBuZXdXaWRnZXQgfSk7XG4gICAgcmV0dXJuIG5ld1dpZGdldDtcbiAgfVxuXG4gIHVwZGF0ZVdpZGdldCh3aWRnZXRJZDogc3RyaW5nLCBwYXRjaDogUGFydGlhbDxPbWl0PFdpZGdldCwnaWQnfCd4J3wneSd8J2NvbHMnfCdyb3dzJz4+KSB7XG4gICAgY29uc3QgcGFnZXMgPSB0aGlzLnBhZ2VzU3ViamVjdC52YWx1ZTtcbiAgICBmb3IgKGNvbnN0IHBhZ2Ugb2YgcGFnZXMpIHtcbiAgICAgIGNvbnN0IHcgPSBwYWdlLndpZGdldHMuZmluZCh3ID0+IHcuaWQgPT09IHdpZGdldElkKTtcbiAgICAgIGlmICh3KSB7XG4gICAgICAgIE9iamVjdC5hc3NpZ24odywgcGF0Y2gpO1xuICAgICAgICB0aGlzLnBhZ2VzU3ViamVjdC5uZXh0KFsuLi5wYWdlc10pO1xuICAgICAgICB0aGlzLl9zYXZlU2hhcmVkKCk7XG4gICAgICAgIHRoaXMuX2Jyb2FkY2FzdCh7IHR5cGU6ICdXSURHRVRfTUVUQScsIHdpZGdldElkLCBwYXRjaCB9KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJlbW92ZVdpZGdldCh3aWRnZXRJZDogc3RyaW5nKSB7XG4gICAgY29uc3QgYWN0aXZlUGFnZSA9IHRoaXMuZ2V0QWN0aXZlUGFnZSgpO1xuICAgIGlmICghYWN0aXZlUGFnZSkgcmV0dXJuO1xuICAgIGNvbnN0IHBhZ2VJZCA9IGFjdGl2ZVBhZ2UuaWQ7XG4gICAgYWN0aXZlUGFnZS53aWRnZXRzID0gYWN0aXZlUGFnZS53aWRnZXRzLmZpbHRlcih3ID0+IHcuaWQgIT09IHdpZGdldElkKTtcbiAgICB0aGlzLnBhZ2VzU3ViamVjdC5uZXh0KFsuLi50aGlzLnBhZ2VzU3ViamVjdC52YWx1ZV0pO1xuICAgIHRoaXMuX3NhdmVTaGFyZWQoKTtcbiAgICB0aGlzLl9zYXZlUG9zaXRpb25zKCk7XG4gICAgdGhpcy5fYnJvYWRjYXN0KHsgdHlwZTogJ1dJREdFVF9SRU1PVkVEJywgcGFnZUlkLCB3aWRnZXRJZCB9KTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBQb3NpdGlvbiBhY3Rpb25zIChsb2NhbCB0byBUSElTIHdpbmRvdyBvbmx5KSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAvKipcbiAgICogVXBkYXRlIGEgd2lkZ2V0J3MgZ3JpZCBwb3NpdGlvbi9zaXplLlxuICAgKiBTYXZlZCBvbmx5IGZvciB0aGlzIHdpbmRvdyDigJQgbmV2ZXIgYnJvYWRjYXN0IHRvIG90aGVycy5cbiAgICovXG4gIHVwZGF0ZVdpZGdldFBvc2l0aW9uKHBhZ2VJZDogc3RyaW5nLCB3aWRnZXRJZDogc3RyaW5nLCB4OiBudW1iZXIsIHk6IG51bWJlciwgY29sczogbnVtYmVyLCByb3dzOiBudW1iZXIpIHtcbiAgICBjb25zdCBwYWdlcyA9IHRoaXMucGFnZXNTdWJqZWN0LnZhbHVlO1xuICAgIGNvbnN0IHdpZGdldCA9IHBhZ2VzLmZpbmQocCA9PiBwLmlkID09PSBwYWdlSWQpPy53aWRnZXRzLmZpbmQodyA9PiB3LmlkID09PSB3aWRnZXRJZCk7XG4gICAgaWYgKHdpZGdldCkge1xuICAgICAgd2lkZ2V0LnggPSB4OyB3aWRnZXQueSA9IHk7IHdpZGdldC5jb2xzID0gY29sczsgd2lkZ2V0LnJvd3MgPSByb3dzO1xuICAgICAgdGhpcy5wYWdlc1N1YmplY3QubmV4dChbLi4ucGFnZXNdKTtcbiAgICAgIHRoaXMuX3NhdmVQb3NpdGlvbnMoKTsgICAgICAgICAgLy8gbG9jYWwgb25seSDigJQgaW50ZW50aW9uYWxseSBubyBfc2F2ZVNoYXJlZCAvIG5vIGJyb2FkY2FzdFxuICAgIH1cbiAgfVxuXG4gIC8vIOKUgOKUgCBTZXJpYWxpemF0aW9uIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHNlcmlhbGl6ZUxheW91dCgpOiBzdHJpbmcge1xuICAgIHJldHVybiBKU09OLnN0cmluZ2lmeSh7XG4gICAgICBwYWdlczogdGhpcy5wYWdlc1N1YmplY3QudmFsdWUsXG4gICAgICBhY3RpdmVQYWdlSWQ6IHRoaXMuYWN0aXZlUGFnZUlkU3ViamVjdC52YWx1ZSxcbiAgICB9IGFzIERhc2hib2FyZENvbmZpZyk7XG4gIH1cblxuICBsb2FkTGF5b3V0KGNvbmZpZzogYW55KSB7XG4gICAgaWYgKCFjb25maWc/LnBhZ2VzKSByZXR1cm47XG4gICAgdGhpcy5fYXBwbHlTaGFyZWQoY29uZmlnLCB0cnVlKTtcbiAgICB0aGlzLl9zYXZlU2hhcmVkKCk7XG4gICAgdGhpcy5fc2F2ZVBvc2l0aW9ucygpO1xuICB9XG5cbiAgcG9wT3V0UGFnZShwYWdlSWQ6IHN0cmluZykge1xuICAgIGNvbnN0IHVybCA9IGAke3dpbmRvdy5sb2NhdGlvbi5vcmlnaW59JHt3aW5kb3cubG9jYXRpb24ucGF0aG5hbWV9IyR7cGFnZUlkfWA7XG4gICAgd2luZG93Lm9wZW4odXJsLCBgd29ya3NwYWNlXyR7cGFnZUlkfWAsXG4gICAgICAnd2lkdGg9MTI4MCxoZWlnaHQ9ODAwLG1lbnViYXI9bm8sdG9vbGJhcj1ubyxsb2NhdGlvbj1ubyxzdGF0dXM9bm8nKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBQcml2YXRlIGhlbHBlcnMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqXG4gICAqIFNhdmUgcGFnZSBsaXN0ICsgd2lkZ2V0IG1ldGFkYXRhICh0aXRsZXMsIGNhcmRDb2xvciwgZGF0YSkg4oCUIG5vIHBvc2l0aW9ucy5cbiAgICovXG4gIHByaXZhdGUgX3NhdmVTaGFyZWQoKSB7XG4gICAgY29uc3Qgc3RyaXBwZWQgPSB0aGlzLnBhZ2VzU3ViamVjdC52YWx1ZS5tYXAocCA9PiAoe1xuICAgICAgLi4ucCxcbiAgICAgIHdpZGdldHM6IHAud2lkZ2V0cy5tYXAoKHsgaWQsIHRpdGxlLCBjYXJkQ29sb3IsIGRhdGEsIGNvbHMsIHJvd3MgfSkgPT5cbiAgICAgICAgLy8gS2VlcCBkZWZhdWx0IGNvbHMvcm93cyBzbyBuZXcgd2luZG93cyBnZXQgYSBzZW5zaWJsZSBmaXJzdC1vcGVuIGxheW91dC5cbiAgICAgICAgLy8geC95IGFyZSBpbnRlbnRpb25hbGx5IG9taXR0ZWQgZnJvbSBzaGFyZWQgc3RhdGUuXG4gICAgICAgICh7IGlkLCB0aXRsZSwgY2FyZENvbG9yLCBkYXRhLCB4OiAwLCB5OiAwLCBjb2xzLCByb3dzIH0pXG4gICAgICApLFxuICAgIH0pKTtcbiAgICBsb2NhbFN0b3JhZ2Uuc2V0SXRlbSh0aGlzLlNIQVJFRF9LRVksIEpTT04uc3RyaW5naWZ5KHtcbiAgICAgIHBhZ2VzOiBzdHJpcHBlZCxcbiAgICAgIGFjdGl2ZVBhZ2VJZDogdGhpcy5hY3RpdmVQYWdlSWRTdWJqZWN0LnZhbHVlLFxuICAgIH0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTYXZlIHRoaXMgd2luZG93J3MgZ3JpZCBwb3NpdGlvbnMgKHgsIHksIGNvbHMsIHJvd3MpIHBlciB3aWRnZXQuXG4gICAqL1xuICBwcml2YXRlIF9zYXZlUG9zaXRpb25zKCkge1xuICAgIGNvbnN0IHBvc2l0aW9uczogUG9zaXRpb25NYXAgPSB7fTtcbiAgICBmb3IgKGNvbnN0IHBhZ2Ugb2YgdGhpcy5wYWdlc1N1YmplY3QudmFsdWUpIHtcbiAgICAgIGZvciAoY29uc3QgdyBvZiBwYWdlLndpZGdldHMpIHtcbiAgICAgICAgcG9zaXRpb25zW2Ake3BhZ2UuaWR9OiR7dy5pZH1gXSA9IHsgeDogdy54LCB5OiB3LnksIGNvbHM6IHcuY29scywgcm93czogdy5yb3dzIH07XG4gICAgICB9XG4gICAgfVxuICAgIGxvY2FsU3RvcmFnZS5zZXRJdGVtKHRoaXMucG9zaXRpb25zS2V5LCBKU09OLnN0cmluZ2lmeShwb3NpdGlvbnMpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBPdmVybGF5IHRoZSBwb3NpdGlvbnMgc2F2ZWQgZm9yIFRISVMgd2luZG93IG9uIHRvcCBvZiB0aGUgY3VycmVudCBwYWdlcy5cbiAgICovXG4gIHByaXZhdGUgX3Jlc3RvcmVQb3NpdGlvbnMoKSB7XG4gICAgY29uc3QgcmF3ID0gbG9jYWxTdG9yYWdlLmdldEl0ZW0odGhpcy5wb3NpdGlvbnNLZXkpO1xuICAgIGlmICghcmF3KSByZXR1cm47XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHBvc2l0aW9uczogUG9zaXRpb25NYXAgPSBKU09OLnBhcnNlKHJhdyk7XG4gICAgICBjb25zdCBwYWdlcyA9IHRoaXMucGFnZXNTdWJqZWN0LnZhbHVlO1xuICAgICAgZm9yIChjb25zdCBwYWdlIG9mIHBhZ2VzKSB7XG4gICAgICAgIGZvciAoY29uc3QgdyBvZiBwYWdlLndpZGdldHMpIHtcbiAgICAgICAgICBjb25zdCBwb3MgPSBwb3NpdGlvbnNbYCR7cGFnZS5pZH06JHt3LmlkfWBdO1xuICAgICAgICAgIGlmIChwb3MpIHsgdy54ID0gcG9zLng7IHcueSA9IHBvcy55OyB3LmNvbHMgPSBwb3MuY29sczsgdy5yb3dzID0gcG9zLnJvd3M7IH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhpcy5wYWdlc1N1YmplY3QubmV4dChbLi4ucGFnZXNdKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBjb25zb2xlLmVycm9yKCdbRGFzaGJvYXJkXSBiYWQgcG9zaXRpb25zIHN0YXRlJywgZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFwcGx5IGEgc2hhcmVkIGNvbmZpZyBvYmplY3QgKHBhZ2UgbGlzdCArIG1ldGFkYXRhKSB3aXRob3V0IHRvdWNoaW5nXG4gICAqIHRoaXMgd2luZG93J3Mgc2F2ZWQgcG9zaXRpb25zLlxuICAgKi9cbiAgcHJpdmF0ZSBfYXBwbHlTaGFyZWQoY29uZmlnOiBhbnksIG92ZXJ3cml0ZVBvc2l0aW9uczogYm9vbGVhbikge1xuICAgIGlmICghY29uZmlnPy5wYWdlcykgcmV0dXJuO1xuICAgIHRoaXMucGFnZXNTdWJqZWN0Lm5leHQoY29uZmlnLnBhZ2VzKTtcbiAgICBpZiAoY29uZmlnLmFjdGl2ZVBhZ2VJZCkgdGhpcy5hY3RpdmVQYWdlSWRTdWJqZWN0Lm5leHQoY29uZmlnLmFjdGl2ZVBhZ2VJZCk7XG4gICAgaWYgKCFvdmVyd3JpdGVQb3NpdGlvbnMpIHRoaXMuX3Jlc3RvcmVQb3NpdGlvbnMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIYW5kbGUgYSBzdHJ1Y3R1cmFsIHN5bmMgZXZlbnQgYXJyaXZpbmcgZnJvbSBhbm90aGVyIHdpbmRvdy5cbiAgICogUG9zaXRpb24gY2hhbmdlcyBhcmUgbmV2ZXIgc2VudCBzbyB3ZSBuZXZlciByZWNlaXZlIHRoZW0gaGVyZS5cbiAgICovXG4gIHByaXZhdGUgX29uU3luY0V2ZW50KGV2ZW50OiBTeW5jRXZlbnQpIHtcbiAgICAvLyBXb3JrIG9uIGEgc2hhbGxvdyBjbG9uZSBvZiBwYWdlcyBzbyBBbmd1bGFyIGRldGVjdHMgdGhlIGNoYW5nZVxuICAgIGNvbnN0IHBhZ2VzOiBQYWdlW10gPSB0aGlzLnBhZ2VzU3ViamVjdC52YWx1ZS5tYXAocCA9PiAoe1xuICAgICAgLi4ucCwgd2lkZ2V0czogWy4uLnAud2lkZ2V0c11cbiAgICB9KSk7XG5cbiAgICBzd2l0Y2ggKGV2ZW50LnR5cGUpIHtcblxuICAgICAgY2FzZSAnUEFHRV9BRERFRCc6XG4gICAgICAgIGlmICghcGFnZXMuZmluZChwID0+IHAuaWQgPT09IGV2ZW50LnBhZ2UuaWQpKSB7XG4gICAgICAgICAgcGFnZXMucHVzaCh7IC4uLmV2ZW50LnBhZ2UsIHdpZGdldHM6IFsuLi5ldmVudC5wYWdlLndpZGdldHNdIH0pO1xuICAgICAgICAgIHRoaXMucGFnZXNTdWJqZWN0Lm5leHQocGFnZXMpO1xuICAgICAgICAgIHRoaXMuX3NhdmVTaGFyZWQoKTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnUEFHRV9SRU1PVkVEJzoge1xuICAgICAgICBjb25zdCB1cGRhdGVkID0gcGFnZXMuZmlsdGVyKHAgPT4gcC5pZCAhPT0gZXZlbnQucGFnZUlkKTtcbiAgICAgICAgaWYgKHVwZGF0ZWQubGVuZ3RoICE9PSBwYWdlcy5sZW5ndGgpIHtcbiAgICAgICAgICB0aGlzLnBhZ2VzU3ViamVjdC5uZXh0KHVwZGF0ZWQpO1xuICAgICAgICAgIGlmICh0aGlzLmFjdGl2ZVBhZ2VJZFN1YmplY3QudmFsdWUgPT09IGV2ZW50LnBhZ2VJZCkge1xuICAgICAgICAgICAgdGhpcy5hY3RpdmVQYWdlSWRTdWJqZWN0Lm5leHQodXBkYXRlZFswXT8uaWQgPz8gJycpO1xuICAgICAgICAgIH1cbiAgICAgICAgICB0aGlzLl9zYXZlU2hhcmVkKCk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGNhc2UgJ1dJREdFVF9BRERFRCc6IHtcbiAgICAgICAgY29uc3QgcGFnZSA9IHBhZ2VzLmZpbmQocCA9PiBwLmlkID09PSBldmVudC5wYWdlSWQpO1xuICAgICAgICBpZiAocGFnZSAmJiAhcGFnZS53aWRnZXRzLmZpbmQodyA9PiB3LmlkID09PSBldmVudC53aWRnZXQuaWQpKSB7XG4gICAgICAgICAgcGFnZS53aWRnZXRzID0gWy4uLnBhZ2Uud2lkZ2V0cywgeyAuLi5ldmVudC53aWRnZXQgfV07XG4gICAgICAgICAgdGhpcy5wYWdlc1N1YmplY3QubmV4dChwYWdlcyk7XG4gICAgICAgICAgdGhpcy5fc2F2ZVNoYXJlZCgpO1xuICAgICAgICAgIC8vIERvbid0IHRvdWNoIHBvc2l0aW9ucyDigJQgdGhpcyB3aW5kb3cgd2lsbCBrZWVwIGl0cyBvd24gbGF5b3V0IGZvclxuICAgICAgICAgIC8vIGV4aXN0aW5nIHdpZGdldHM7IHRoZSBuZXcgb25lIHN0YXJ0cyBhdCBpdHMgZGVmYXVsdCBwb3NpdGlvbi5cbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgY2FzZSAnV0lER0VUX1JFTU9WRUQnOiB7XG4gICAgICAgIGNvbnN0IHBhZ2UgPSBwYWdlcy5maW5kKHAgPT4gcC5pZCA9PT0gZXZlbnQucGFnZUlkKTtcbiAgICAgICAgaWYgKHBhZ2UpIHtcbiAgICAgICAgICBwYWdlLndpZGdldHMgPSBwYWdlLndpZGdldHMuZmlsdGVyKHcgPT4gdy5pZCAhPT0gZXZlbnQud2lkZ2V0SWQpO1xuICAgICAgICAgIHRoaXMucGFnZXNTdWJqZWN0Lm5leHQocGFnZXMpO1xuICAgICAgICAgIHRoaXMuX3NhdmVTaGFyZWQoKTtcbiAgICAgICAgICB0aGlzLl9zYXZlUG9zaXRpb25zKCk7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIGNhc2UgJ1dJREdFVF9NRVRBJzoge1xuICAgICAgICBmb3IgKGNvbnN0IHBhZ2Ugb2YgcGFnZXMpIHtcbiAgICAgICAgICBjb25zdCB3ID0gcGFnZS53aWRnZXRzLmZpbmQodyA9PiB3LmlkID09PSBldmVudC53aWRnZXRJZCk7XG4gICAgICAgICAgaWYgKHcpIHtcbiAgICAgICAgICAgIE9iamVjdC5hc3NpZ24odywgZXZlbnQucGF0Y2gpO1xuICAgICAgICAgICAgdGhpcy5wYWdlc1N1YmplY3QubmV4dChwYWdlcyk7XG4gICAgICAgICAgICB0aGlzLl9zYXZlU2hhcmVkKCk7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfYnJvYWRjYXN0KGV2ZW50OiBTeW5jRXZlbnQpIHtcbiAgICB0aGlzLmNoYW5uZWw/LnBvc3RNZXNzYWdlKGV2ZW50KTtcbiAgfVxufVxuIl19