@firestitch/report 18.2.2 → 18.3.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 (35) hide show
  1. package/app/reports/components/component-text/component-text.component.d.ts +34 -0
  2. package/app/reports/components/report-canvas/report-canvas.component.d.ts +17 -5
  3. package/app/reports/components/report-component/report-component.component.d.ts +11 -1
  4. package/app/reports/data/report.data.d.ts +12 -1
  5. package/app/reports/dialogs/report-settings/report-settings.component.d.ts +3 -0
  6. package/app/reports/export/report-export-collector.service.d.ts +1 -0
  7. package/app/reports/export/report-pdf.service.d.ts +7 -0
  8. package/app/reports/export/report-pptx.service.d.ts +2 -0
  9. package/app/reports/interfaces/report.interface.d.ts +16 -2
  10. package/app/reports/layout.d.ts +1 -0
  11. package/app/reports/text.d.ts +29 -0
  12. package/app/reports/views/report/fs-ai-report.component.d.ts +3 -0
  13. package/app/reports/views/report/report.component.d.ts +3 -0
  14. package/app/reports/views/reports/fs-ai-reports.component.d.ts +1 -1
  15. package/esm2022/app/reports/components/component-text/component-text.component.mjs +186 -0
  16. package/esm2022/app/reports/components/report-canvas/report-canvas.component.mjs +128 -17
  17. package/esm2022/app/reports/components/report-component/report-component.component.mjs +71 -7
  18. package/esm2022/app/reports/data/report.data.mjs +20 -9
  19. package/esm2022/app/reports/dialogs/report-settings/report-settings.component.mjs +17 -5
  20. package/esm2022/app/reports/export/report-export-collector.service.mjs +12 -2
  21. package/esm2022/app/reports/export/report-pdf.service.mjs +156 -4
  22. package/esm2022/app/reports/export/report-pptx.service.mjs +76 -5
  23. package/esm2022/app/reports/interfaces/report.interface.mjs +1 -1
  24. package/esm2022/app/reports/layout.mjs +4 -1
  25. package/esm2022/app/reports/text.mjs +221 -0
  26. package/esm2022/app/reports/views/report/fs-ai-report.component.mjs +14 -3
  27. package/esm2022/app/reports/views/report/report.component.mjs +18 -3
  28. package/esm2022/app/reports/views/reports/fs-ai-reports.component.mjs +11 -5
  29. package/fesm2022/{firestitch-report-echarts-BLtDCank.mjs → firestitch-report-echarts-Dg5PjbjT.mjs} +2 -2
  30. package/fesm2022/{firestitch-report-echarts-BLtDCank.mjs.map → firestitch-report-echarts-Dg5PjbjT.mjs.map} +1 -1
  31. package/fesm2022/{firestitch-report-firestitch-report-eTeJyMPo.mjs → firestitch-report-firestitch-report-JORFp_xa.mjs} +925 -62
  32. package/fesm2022/firestitch-report-firestitch-report-JORFp_xa.mjs.map +1 -0
  33. package/fesm2022/firestitch-report.mjs +1 -1
  34. package/package.json +1 -1
  35. package/fesm2022/firestitch-report-firestitch-report-eTeJyMPo.mjs.map +0 -1
@@ -1,7 +1,6 @@
1
- import { ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, ElementRef, EventEmitter, Input, Output, QueryList, ViewChild, ViewChildren, inject, } from '@angular/core';
1
+ import { ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, ElementRef, EventEmitter, Input, Output, QueryList, ViewChild, ViewChildren, inject, signal, } from '@angular/core';
2
2
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
3
3
  import { DragDropModule, moveItemInArray } from '@angular/cdk/drag-drop';
4
- import { MatButton } from '@angular/material/button';
5
4
  import { MatIcon } from '@angular/material/icon';
6
5
  import { MatTooltip } from '@angular/material/tooltip';
7
6
  import { FsMenuModule } from '@firestitch/menu';
@@ -28,6 +27,13 @@ export const PX_PER_INCH = 96;
28
27
  // alignment guides (edges + centers of siblings and the page) with snapping.
29
28
  // Flow layout: components flow into rows (flowWidth % of the content width),
30
29
  // drag reorders, east/south handles resize width%/height.
30
+ //
31
+ // Header and footer: the report's master components (report.master) are drawn
32
+ // on a layer UNDER every page's own components, like a PowerPoint slide master,
33
+ // unless the page hides them. In edit mode the host toolbar's "Header & footer"
34
+ // (toggleMasterMode) switches which layer is live: the page's components dim
35
+ // and the master's become the ones that drag, resize and snap. The header/footer bands (config.headerFooter)
36
+ // are drawn as guides while editing and are snap lines for both layers.
31
37
  export class ReportCanvasComponent {
32
38
  report;
33
39
  editMode = false;
@@ -41,9 +47,6 @@ export class ReportCanvasComponent {
41
47
  // The report's structure changed here (a page was added) — the host re-fetches
42
48
  // it (it owns the assembled report + filter state).
43
49
  reportChanged = new EventEmitter();
44
- // The viewer dismissed edit mode from the on-canvas badge — the host owns the
45
- // editMode flag, so it flips it off (mirrors the menu's "Done editing layout").
46
- editDone = new EventEmitter();
47
50
  // The page on screen changed — the host reflects it in the URL so a refresh
48
51
  // comes back to the same page. Carries the page id, never the index.
49
52
  pageChanged = new EventEmitter();
@@ -57,6 +60,8 @@ export class ReportCanvasComponent {
57
60
  flowPadding = FLOW_PADDING;
58
61
  activePageIndex = 0;
59
62
  zoom = 1;
63
+ // Editing the header and footer (the master layer) rather than the page.
64
+ masterMode = signal(false);
60
65
  groups = new Map();
61
66
  selectedComponentId = null;
62
67
  // The snapper handed to every component (stable identity for OnPush).
@@ -71,12 +76,18 @@ export class ReportCanvasComponent {
71
76
  _cdRef = inject(ChangeDetectorRef);
72
77
  _destroyRef = inject(DestroyRef);
73
78
  _fitted = false;
79
+ _tokens = null;
74
80
  _previousPageCount = 0;
75
81
  // The page id last announced through pageChanged, so a re-render that lands on
76
82
  // the same page stays quiet — hosts reload on this and an unchanged page is
77
83
  // not news.
78
84
  _emittedPageId = null;
79
- ngOnChanges() {
85
+ ngOnChanges(changes) {
86
+ // Leaving edit mode always returns to the page layer, so the next edit
87
+ // session starts where people expect.
88
+ if (changes.editMode && !this.editMode) {
89
+ this.masterMode.set(false);
90
+ }
80
91
  this.groups = new Map((this.report?.filterGroups ?? []).map((group) => [group.id, group]));
81
92
  const pageCount = this.report?.pages?.length ?? 0;
82
93
  // A page was just added (the host re-fetched the report) — land on it.
@@ -127,6 +138,96 @@ export class ReportCanvasComponent {
127
138
  get activePage() {
128
139
  return this.report?.pages?.[this.activePageIndex] ?? null;
129
140
  }
141
+ // The header/footer bands, in inches (0 = no band).
142
+ get bands() {
143
+ return this.report?.config?.headerFooter ?? { headerHeight: 0, footerHeight: 0 };
144
+ }
145
+ get masterComponents() {
146
+ return this.report?.master?.components ?? [];
147
+ }
148
+ // The master draws unless the page hides it — and always while it is the
149
+ // layer being edited, so a page that hides it can still be used to edit it.
150
+ get isMasterShown() {
151
+ return this.masterMode() || !this.activePage?.masterHidden;
152
+ }
153
+ // Which layer the edit gestures reach.
154
+ get isPageEditing() {
155
+ return this.editMode && !this.masterMode();
156
+ }
157
+ get isMasterEditing() {
158
+ return this.editMode && this.masterMode();
159
+ }
160
+ // What {{page.number}} / {{page.name}} / {{report.name}} fill with on the
161
+ // page on screen — the master's footer numbers each page by its position.
162
+ // The same object is handed back until one of the three changes: every text
163
+ // block takes it as an input, and a fresh object per check would make each
164
+ // of them repaint its html on every change-detection pass.
165
+ get tokens() {
166
+ const page = this.activePage;
167
+ const pageNumber = this.activePageIndex + 1;
168
+ const pageName = page ? this.pageLabel(page, this.activePageIndex) : '';
169
+ const reportName = this.report?.name ?? '';
170
+ const tokens = this._tokens;
171
+ if (tokens?.pageNumber !== pageNumber || tokens.pageName !== pageName || tokens.reportName !== reportName) {
172
+ this._tokens = { pageNumber, pageName, reportName };
173
+ }
174
+ return this._tokens;
175
+ }
176
+ toggleMasterMode() {
177
+ this.masterMode.update((value) => !value);
178
+ this.selectedComponentId = null;
179
+ }
180
+ // Drop a text block where it will be found: into the footer (or header) band
181
+ // while editing the header and footer, below the header band on a page. The
182
+ // host re-fetches the report and it appears; double-press opens its editor.
183
+ addText() {
184
+ if (!this.report) {
185
+ return;
186
+ }
187
+ const { headerHeight, footerHeight } = this.bands;
188
+ const pageWidth = this.report.pageWidth;
189
+ const pageHeight = this.report.pageHeight;
190
+ const isMaster = this.masterMode();
191
+ let geometry = { x: 0.5, y: headerHeight + 0.5, w: Math.min(5, pageWidth - 1), h: 0.8 };
192
+ if (isMaster) {
193
+ const bandHeight = footerHeight || headerHeight || 0.5;
194
+ const y = footerHeight
195
+ ? pageHeight - footerHeight
196
+ : (headerHeight ? 0 : pageHeight - bandHeight);
197
+ geometry = { x: 0.5, y: y + 0.05, w: Math.min(4, pageWidth - 1), h: Math.max(0.3, bandHeight - 0.1) };
198
+ }
199
+ this._reportData.addText(this.report.id, {
200
+ ...geometry,
201
+ pageId: isMaster ? undefined : this.activePage?.id,
202
+ })
203
+ .pipe(takeUntilDestroyed(this._destroyRef))
204
+ .subscribe(() => this.reportChanged.emit());
205
+ }
206
+ // A text block deleted itself from its menu: drop it from whichever layer it
207
+ // was on without re-fetching the report (nothing else depends on it).
208
+ onComponentRemoved(componentId) {
209
+ const layers = [this.activePage?.components, this.report?.master?.components];
210
+ for (const components of layers) {
211
+ const index = components?.findIndex((component) => component.id === componentId) ?? -1;
212
+ if (index > -1) {
213
+ components.splice(index, 1);
214
+ }
215
+ }
216
+ this.selectedComponentId = null;
217
+ this._message.success('Deleted text');
218
+ this._cdRef.markForCheck();
219
+ }
220
+ // Show or hide the header and footer on one page, from its tab's kebab.
221
+ toggleMasterHidden(page) {
222
+ const masterHidden = !page.masterHidden;
223
+ this._reportData.updatePage(this.report.id, page.id, { masterHidden })
224
+ .pipe(takeUntilDestroyed(this._destroyRef))
225
+ .subscribe(() => {
226
+ page.masterHidden = masterHidden;
227
+ this._message.success(masterHidden ? 'Header & footer hidden on this page' : 'Header & footer shown on this page');
228
+ this._cdRef.markForCheck();
229
+ });
230
+ }
130
231
  // Flow render order (the assembler already sorts, but a local reorder
131
232
  // mid-session must hold without a re-fetch).
132
233
  get flowComponents() {
@@ -166,7 +267,7 @@ export class ReportCanvasComponent {
166
267
  required: true,
167
268
  })
168
269
  .pipe(switchMap((name) => this._reportData
169
- .updatePage(this.report.id, page.id, name)
270
+ .updatePage(this.report.id, page.id, { name })
170
271
  .pipe(map(() => name))), takeUntilDestroyed(this._destroyRef))
171
272
  .subscribe((name) => {
172
273
  page.name = name;
@@ -294,7 +395,9 @@ export class ReportCanvasComponent {
294
395
  // Where the pointer landed among the flowed components: before the first
295
396
  // component whose center the pointer is above/left of.
296
397
  _flowDropIndex(ordered, clientX, clientY) {
297
- const hosts = Array.from(this._viewport.nativeElement.querySelectorAll('app-report-component')).filter((host) => !host.classList.contains('flow-dragging'));
398
+ // Flow items only the header/footer blocks on the master layer are
399
+ // components too, but they are not in the flow.
400
+ const hosts = Array.from(this._viewport.nativeElement.querySelectorAll('app-report-component.flow-item')).filter((host) => !host.classList.contains('flow-dragging'));
298
401
  for (let index = 0; index < hosts.length && index < ordered.length; index++) {
299
402
  const rect = hosts[index].getBoundingClientRect();
300
403
  if (clientY < rect.top + rect.height / 2
@@ -371,12 +474,23 @@ export class ReportCanvasComponent {
371
474
  this._renderGuides(guides);
372
475
  return result;
373
476
  }
374
- // Alignment candidates: the page's edges + center, and every sibling's
375
- // edges + centers.
477
+ // Alignment candidates: the page's edges + center, the header/footer band
478
+ // lines, and every sibling's edges + centers — siblings on the SAME layer,
479
+ // since a page component aligns with the page and a header block with the
480
+ // header.
376
481
  _candidates(moving) {
377
482
  const vertical = [0, this.report.pageWidth / 2, this.report.pageWidth];
378
483
  const horizontal = [0, this.report.pageHeight / 2, this.report.pageHeight];
379
- for (const component of this.activePage?.components ?? []) {
484
+ const { headerHeight, footerHeight } = this.bands;
485
+ if (headerHeight) {
486
+ horizontal.push(headerHeight);
487
+ }
488
+ if (footerHeight) {
489
+ horizontal.push(this.report.pageHeight - footerHeight);
490
+ }
491
+ const isMaster = this.masterComponents.some((component) => component.id === moving.id);
492
+ const siblings = isMaster ? this.masterComponents : (this.activePage?.components ?? []);
493
+ for (const component of siblings) {
380
494
  if (component.id === moving.id) {
381
495
  continue;
382
496
  }
@@ -435,19 +549,18 @@ export class ReportCanvasComponent {
435
549
  this._guides?.nativeElement?.replaceChildren();
436
550
  }
437
551
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportCanvasComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
438
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ReportCanvasComponent, isStandalone: true, selector: "app-report-canvas", inputs: { report: "report", editMode: "editMode", pageId: "pageId" }, outputs: { componentSettings: "componentSettings", reportChanged: "reportChanged", editDone: "editDone", pageChanged: "pageChanged" }, viewQueries: [{ propertyName: "zoomPan", first: true, predicate: FsZoomPanComponent, descendants: true }, { propertyName: "_viewport", first: true, predicate: ["viewport"], descendants: true, static: true }, { propertyName: "_guides", first: true, predicate: ["guides"], descendants: true }, { propertyName: "_renderedComponents", predicate: ReportComponentComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"canvas\">\n <div\n #viewport\n class=\"page-viewport\"\n (pointerdown)=\"onCanvasPointerDown()\">\n <fs-zoom-pan\n [zoomMin]=\"0.1\"\n [zoomMax]=\"3\"\n (zoomed)=\"onZoomed($event)\">\n @if (activePage; as page) {\n <div\n class=\"page\"\n [class.flow]=\"isFlow\"\n [class.editing]=\"editMode\"\n [style.width.px]=\"report.pageWidth * PX\"\n [style.height.px]=\"report.pageHeight * PX\"\n [style.padding.px]=\"isFlow ? flowPadding * PX : 0\"\n [style.--canvas-zoom]=\"zoom\"\n [style.--report-heading-size.px]=\"headingSizePx\">\n @if (isFlow) {\n @for (component of flowComponents; track component.id) {\n <app-report-component\n class=\"flow-item\"\n [reportId]=\"report.id\"\n [component]=\"component\"\n [groups]=\"groups\"\n [editMode]=\"editMode\"\n [layout]=\"'flow'\"\n [zoom]=\"zoom\"\n [snapper]=\"snapper\"\n [selected]=\"component.id === selectedComponentId\"\n [style.width.%]=\"component.flowWidth\"\n [style.height.px]=\"component.autoHeight ? null : component.h * PX\"\n (selectComponent)=\"selectComponent($event)\"\n (positionChanged)=\"onPositionChanged($event)\"\n (flowReorder)=\"onFlowReorder($event)\"\n (openSettings)=\"componentSettings.emit($event)\">\n </app-report-component>\n }\n } @else {\n @for (component of page.components; track component.id) {\n <app-report-component\n [reportId]=\"report.id\"\n [component]=\"component\"\n [groups]=\"groups\"\n [editMode]=\"editMode\"\n [layout]=\"'freeform'\"\n [zoom]=\"zoom\"\n [snapper]=\"snapper\"\n [selected]=\"component.id === selectedComponentId\"\n [style.left.px]=\"component.x * PX\"\n [style.top.px]=\"component.y * PX\"\n [style.width.px]=\"component.w * PX\"\n [style.height.px]=\"component.autoHeight ? null : component.h * PX\"\n (selectComponent)=\"selectComponent($event)\"\n (positionChanged)=\"onPositionChanged($event)\"\n (openSettings)=\"componentSettings.emit($event)\">\n </app-report-component>\n }\n }\n\n <div\n #guides\n class=\"guides\">\n </div>\n\n @if (!page.components.length) {\n <div class=\"page-empty\">\n Ask the assistant to add a chart, list or KPI to this page.\n </div>\n }\n </div>\n }\n </fs-zoom-pan>\n\n @if (editMode) {\n <button\n mat-flat-button\n type=\"button\"\n color=\"primary\"\n class=\"edit-done\"\n matTooltip=\"Exit layout editing\"\n (click)=\"editDone.emit()\">\n <mat-icon>check</mat-icon>\n Done editing\n </button>\n }\n </div>\n\n <div class=\"canvas-toolbar\">\n <!-- Tabs are one horizontal drop list: dragging a chip reorders the pages.\n The drop INDEX is computed along X (orientation), but the preview is\n deliberately left unbounded on both axes \u2014 pinning it to the row with\n cdkDragBoundary means the chip you are dragging covers the chips you\n are dragging it past, and you cannot see where it is going to land.\n Every page gets a chip, including a lone one: the chip is what tells\n you which page you are on, and a report that hid it left you unable to\n tell page 1 of 1 from a page that failed to load. Deleting the last\n page is refused server-side, so the kebab is safe to expose here. -->\n <div\n class=\"page-tabs\"\n cdkDropList\n cdkDropListOrientation=\"horizontal\"\n (cdkDropListDropped)=\"onPageDropped($event)\">\n @for (page of report?.pages ?? []; track page.id; let index = $index) {\n <!-- The chip is the drag handle AND the tab: clicking selects,\n dragging reorders. The kebab lives inside it, so the whole\n control stays one chip instead of growing a second button. -->\n <div\n cdkDrag\n class=\"page-tab\"\n [class.active]=\"index === activePageIndex\"\n (click)=\"selectPage(index)\">\n <span class=\"page-tab-label\">{{ pageLabel(page, index) }}</span>\n <!-- The kebab opens the menu rather than starting a drag or\n switching pages, so it swallows its own click. -->\n <span\n class=\"page-tab-menu\"\n [fsMenuTriggerFor]=\"pageMenu\"\n (click)=\"$event.stopPropagation()\"\n (mousedown)=\"$event.stopPropagation()\">\n <mat-icon>more_vert</mat-icon>\n </span>\n </div>\n <!-- Outside the chip: cdkDrag clones its host into the drag preview,\n and a menu overlay anchored to a cloned trigger opens detached\n from the real tab. -->\n <fs-menu #pageMenu>\n <ng-template\n fs-menu-item\n (click)=\"renamePage(page)\">\n Edit name\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"deletePage(page)\">\n Delete\n </ng-template>\n </fs-menu>\n }\n <button\n type=\"button\"\n class=\"page-tab add-page\"\n matTooltip=\"Add page\"\n (click)=\"addPage()\">\n <mat-icon>add</mat-icon>\n Page\n </button>\n </div>\n\n <div class=\"zoom-controls\">\n <button\n type=\"button\"\n class=\"zoom-button\"\n matTooltip=\"Zoom out\"\n (click)=\"zoomOut()\">\n <mat-icon>remove</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"zoom-label\"\n matTooltip=\"Zoom to 100%\"\n (click)=\"zoomActual()\">\n {{ (zoom * 100).toFixed(0) }}%\n </button>\n <button\n type=\"button\"\n class=\"zoom-button\"\n matTooltip=\"Zoom in\"\n (click)=\"zoomIn()\">\n <mat-icon>add</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"zoom-button\"\n matTooltip=\"Fit page\"\n (click)=\"zoomFit()\">\n <mat-icon>fit_screen</mat-icon>\n </button>\n </div>\n </div>\n</div>\n", styles: [":host{display:flex;flex-direction:column;min-width:0;min-height:0;flex:1;margin-top:10px}.canvas{display:flex;flex-direction:column;gap:8px;flex:1;min-height:0}.canvas-toolbar{display:flex;align-items:center;justify-content:space-between;gap:8px}.canvas-toolbar .page-tabs{display:flex;align-items:center;gap:4px;flex-wrap:wrap}.canvas-toolbar .page-tabs fs-menu{display:none}.canvas-toolbar .page-tabs .page-tab{display:inline-flex;align-items:center;box-sizing:border-box;border:1px solid #e4e7eb;border-radius:16px;background:#fff;padding:4px 6px 4px 14px;font-size:12px;line-height:16px;color:#52606d;cursor:pointer}.canvas-toolbar .page-tabs .page-tab.active{background:var(--brand-primary-color, #3b82f6);border-color:var(--brand-primary-color, #3b82f6);color:#fff}.canvas-toolbar .page-tabs .page-tab .page-tab-label{white-space:nowrap}.canvas-toolbar .page-tabs .page-tab .page-tab-menu{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:16px;height:16px;margin-left:2px;border-radius:50%;opacity:.75}.canvas-toolbar .page-tabs .page-tab .page-tab-menu mat-icon{font-size:14px;width:14px;height:14px;line-height:14px}.canvas-toolbar .page-tabs .page-tab .page-tab-menu:hover{background:#0f172a14;opacity:1}.canvas-toolbar .page-tabs .page-tab.active .page-tab-menu:hover{background:#ffffff38}.canvas-toolbar .page-tabs .page-tab.add-page{gap:2px;padding:4px 14px 4px 8px;border-style:dashed;color:#52606d}.canvas-toolbar .page-tabs .page-tab.add-page mat-icon{font-size:16px;width:16px;height:16px}.canvas-toolbar .page-tabs .page-tab.cdk-drag-placeholder{background:transparent;border-style:dashed;border-color:#cbd2d9}.canvas-toolbar .page-tabs .page-tab.cdk-drag-placeholder .page-tab-label,.canvas-toolbar .page-tabs .page-tab.cdk-drag-placeholder .page-tab-menu{visibility:hidden}.canvas-toolbar .page-tabs .cdk-drag-animating,.canvas-toolbar .page-tabs.cdk-drop-list-dragging .page-tab:not(.cdk-drag-placeholder){transition:transform .18s cubic-bezier(0,0,.2,1)}.canvas-toolbar .zoom-controls{display:flex;align-items:center;gap:2px;margin-left:auto;border:1px solid #e4e7eb;border-radius:18px;background:#fff;padding:2px 6px}.canvas-toolbar .zoom-controls .zoom-button{display:flex;align-items:center;justify-content:center;border:none;border-radius:50%;background:transparent;color:#52606d;cursor:pointer}.canvas-toolbar .zoom-controls .zoom-button:hover{background:#f0f4f8}.canvas-toolbar .zoom-controls .zoom-button mat-icon{font-size:18px;width:18px;height:18px}.canvas-toolbar .zoom-controls .zoom-label{border:none;background:transparent;font-size:12px;color:#52606d;min-width:44px;cursor:pointer}.canvas-toolbar .zoom-controls .zoom-label:hover{color:#1f2933}.page-tab.cdk-drag-preview{display:inline-flex;align-items:center;box-sizing:border-box;border:1px solid #e4e7eb;border-radius:16px;background:#fff;padding:4px 6px 4px 14px;font-size:12px;line-height:16px;color:#52606d;box-shadow:0 3px 10px #0f172a3d}.page-tab.cdk-drag-preview.active{background:var(--brand-primary-color, #3b82f6);border-color:var(--brand-primary-color, #3b82f6);color:#fff}.page-tab.cdk-drag-preview .page-tab-label{white-space:nowrap}.page-tab.cdk-drag-preview .page-tab-menu{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:16px;height:16px;margin-left:2px;border-radius:50%;opacity:.75}.page-tab.cdk-drag-preview .page-tab-menu mat-icon{font-size:14px;width:14px;height:14px;line-height:14px}.page-viewport{position:relative;flex:1;min-height:420px;border:1px solid #e4e7eb;border-radius:8px;background:#eef1f5;overflow:hidden}.page-viewport fs-zoom-pan{width:100%;height:100%}.edit-done{position:absolute;top:12px;right:12px;z-index:40;border-radius:999px;box-shadow:0 2px 10px #0f172a2e}.page{position:relative;background:#fff;border-radius:2px;box-shadow:0 2px 12px #0f172a1f,0 0 0 1px #0f172a0a;box-sizing:border-box}.page.flow{display:flex;flex-wrap:wrap;align-content:flex-start;align-items:flex-start}.page.editing{background-image:radial-gradient(circle,#d8dee6 1px,transparent 1px);background-size:24px 24px}.guides{position:absolute;inset:0;pointer-events:none;z-index:30}.guides ::ng-deep .guide{position:absolute;background:#2196f3}.guides ::ng-deep .guide.guide-v{top:0;bottom:0;width:calc(1.25px / var(--canvas-zoom, 1))}.guides ::ng-deep .guide.guide-h{left:0;right:0;height:calc(1.25px / var(--canvas-zoom, 1))}.page-empty{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:#9aa5b1;font-size:14px;pointer-events:none}\n"], dependencies: [{ kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: FsMenuModule }, { kind: "component", type: i2.FsMenuComponent, selector: "fs-menu", inputs: ["class", "buttonClass", "buttonType", "buttonColor"], outputs: ["opened", "closed"] }, { kind: "directive", type: i2.FsMenuItemDirective, selector: "fs-menu-group,[fs-menu-item]" }, { kind: "directive", type: i2.FsMenuTriggerDirective, selector: "[fsMenuTriggerFor]", inputs: ["fsMenuTriggerFor"] }, { kind: "ngmodule", type: FsZoomPanModule }, { kind: "component", type: i3.FsZoomPanComponent, selector: "fs-zoom-pan", inputs: ["zoomMax", "zoomMin", "zoomScale", "zoomDefault", "zoomFactor", "top", "left"], outputs: ["moved", "zoomed"] }, { kind: "component", type: ReportComponentComponent, selector: "app-report-component", inputs: ["reportId", "component", "groups", "editMode", "layout", "zoom", "snapper", "selected"], outputs: ["selectComponent", "positionChanged", "flowReorder", "openSettings"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
552
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: ReportCanvasComponent, isStandalone: true, selector: "app-report-canvas", inputs: { report: "report", editMode: "editMode", pageId: "pageId" }, outputs: { componentSettings: "componentSettings", reportChanged: "reportChanged", pageChanged: "pageChanged" }, viewQueries: [{ propertyName: "zoomPan", first: true, predicate: FsZoomPanComponent, descendants: true }, { propertyName: "_viewport", first: true, predicate: ["viewport"], descendants: true, static: true }, { propertyName: "_guides", first: true, predicate: ["guides"], descendants: true }, { propertyName: "_renderedComponents", predicate: ReportComponentComponent, descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"canvas\">\n <div\n #viewport\n class=\"page-viewport\"\n (pointerdown)=\"onCanvasPointerDown()\">\n <fs-zoom-pan\n [zoomMin]=\"0.1\"\n [zoomMax]=\"3\"\n (zoomed)=\"onZoomed($event)\">\n @if (activePage; as page) {\n <div\n class=\"page\"\n [class.flow]=\"isFlow\"\n [class.editing]=\"editMode\"\n [class.master-editing]=\"isMasterEditing\"\n [style.width.px]=\"report.pageWidth * PX\"\n [style.height.px]=\"report.pageHeight * PX\"\n [style.padding.px]=\"isFlow ? flowPadding * PX : 0\"\n [style.--canvas-zoom]=\"zoom\"\n [style.--report-heading-size.px]=\"headingSizePx\">\n <!-- The header and footer: the master's components, always freeform,\n drawn under the page's own. Out of the flow (absolute), so a flow\n page's rows are laid out as if it were not there. -->\n @if (isMasterShown && masterComponents.length) {\n <div\n class=\"master-layer\"\n [class.editable]=\"isMasterEditing\">\n @for (component of masterComponents; track component.id) {\n <app-report-component\n [reportId]=\"report.id\"\n [component]=\"component\"\n [groups]=\"groups\"\n [editMode]=\"isMasterEditing\"\n [layout]=\"'freeform'\"\n [zoom]=\"zoom\"\n [snapper]=\"snapper\"\n [tokens]=\"tokens\"\n [selected]=\"component.id === selectedComponentId\"\n [style.left.px]=\"component.x * PX\"\n [style.top.px]=\"component.y * PX\"\n [style.width.px]=\"component.w * PX\"\n [style.height.px]=\"component.autoHeight ? null : component.h * PX\"\n (selectComponent)=\"selectComponent($event)\"\n (positionChanged)=\"onPositionChanged($event)\"\n (removed)=\"onComponentRemoved($event)\"\n (openSettings)=\"componentSettings.emit($event)\">\n </app-report-component>\n }\n </div>\n }\n\n <!-- The header and footer bands, as guides while editing. -->\n @if (editMode) {\n @if (bands.headerHeight) {\n <div\n class=\"band band-header\"\n [style.height.px]=\"bands.headerHeight * PX\">\n @if (isMasterEditing) {\n <span class=\"band-label small\">Header</span>\n }\n </div>\n }\n @if (bands.footerHeight) {\n <div\n class=\"band band-footer\"\n [style.height.px]=\"bands.footerHeight * PX\">\n @if (isMasterEditing) {\n <span class=\"band-label small\">Footer</span>\n }\n </div>\n }\n }\n\n @if (isFlow) {\n @for (component of flowComponents; track component.id) {\n <app-report-component\n class=\"flow-item\"\n [reportId]=\"report.id\"\n [component]=\"component\"\n [groups]=\"groups\"\n [editMode]=\"isPageEditing\"\n [layout]=\"'flow'\"\n [zoom]=\"zoom\"\n [snapper]=\"snapper\"\n [tokens]=\"tokens\"\n [selected]=\"component.id === selectedComponentId\"\n [style.width.%]=\"component.flowWidth\"\n [style.height.px]=\"component.autoHeight ? null : component.h * PX\"\n (selectComponent)=\"selectComponent($event)\"\n (positionChanged)=\"onPositionChanged($event)\"\n (flowReorder)=\"onFlowReorder($event)\"\n (removed)=\"onComponentRemoved($event)\"\n (openSettings)=\"componentSettings.emit($event)\">\n </app-report-component>\n }\n } @else {\n @for (component of page.components; track component.id) {\n <app-report-component\n [reportId]=\"report.id\"\n [component]=\"component\"\n [groups]=\"groups\"\n [editMode]=\"isPageEditing\"\n [layout]=\"'freeform'\"\n [zoom]=\"zoom\"\n [snapper]=\"snapper\"\n [tokens]=\"tokens\"\n [selected]=\"component.id === selectedComponentId\"\n [style.left.px]=\"component.x * PX\"\n [style.top.px]=\"component.y * PX\"\n [style.width.px]=\"component.w * PX\"\n [style.height.px]=\"component.autoHeight ? null : component.h * PX\"\n (selectComponent)=\"selectComponent($event)\"\n (positionChanged)=\"onPositionChanged($event)\"\n (removed)=\"onComponentRemoved($event)\"\n (openSettings)=\"componentSettings.emit($event)\">\n </app-report-component>\n }\n }\n\n <div\n #guides\n class=\"guides\">\n </div>\n\n @if (!page.components.length && !masterMode()) {\n <div class=\"page-empty\">\n Ask the assistant to add a chart, list or KPI to this page.\n </div>\n }\n </div>\n }\n </fs-zoom-pan>\n </div>\n\n <div class=\"canvas-toolbar\">\n <!-- Tabs are one horizontal drop list: dragging a chip reorders the pages.\n The drop INDEX is computed along X (orientation), but the preview is\n deliberately left unbounded on both axes \u2014 pinning it to the row with\n cdkDragBoundary means the chip you are dragging covers the chips you\n are dragging it past, and you cannot see where it is going to land.\n Every page gets a chip, including a lone one: the chip is what tells\n you which page you are on, and a report that hid it left you unable to\n tell page 1 of 1 from a page that failed to load. Deleting the last\n page is refused server-side, so the kebab is safe to expose here. -->\n <div\n class=\"page-tabs\"\n cdkDropList\n cdkDropListOrientation=\"horizontal\"\n (cdkDropListDropped)=\"onPageDropped($event)\">\n @for (page of report?.pages ?? []; track page.id; let index = $index) {\n <!-- The chip is the drag handle AND the tab: clicking selects,\n dragging reorders. The kebab lives inside it, so the whole\n control stays one chip instead of growing a second button. -->\n <div\n cdkDrag\n class=\"page-tab\"\n [class.active]=\"index === activePageIndex\"\n (click)=\"selectPage(index)\">\n <span class=\"page-tab-label\">{{ pageLabel(page, index) }}</span>\n <!-- The kebab opens the menu rather than starting a drag or\n switching pages, so it swallows its own click. -->\n <span\n class=\"page-tab-menu\"\n [fsMenuTriggerFor]=\"pageMenu\"\n (click)=\"$event.stopPropagation()\"\n (mousedown)=\"$event.stopPropagation()\">\n <mat-icon>more_vert</mat-icon>\n </span>\n </div>\n <!-- Outside the chip: cdkDrag clones its host into the drag preview,\n and a menu overlay anchored to a cloned trigger opens detached\n from the real tab. -->\n <fs-menu #pageMenu>\n <ng-template\n fs-menu-item\n (click)=\"renamePage(page)\">\n Edit name\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"toggleMasterHidden(page)\">\n {{ page.masterHidden ? 'Show header & footer' : 'Hide header & footer' }}\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"deletePage(page)\">\n Delete\n </ng-template>\n </fs-menu>\n }\n <button\n type=\"button\"\n class=\"page-tab add-page\"\n matTooltip=\"Add page\"\n (click)=\"addPage()\">\n <mat-icon>add</mat-icon>\n Page\n </button>\n </div>\n\n <div class=\"zoom-controls\">\n <button\n type=\"button\"\n class=\"zoom-button\"\n matTooltip=\"Zoom out\"\n (click)=\"zoomOut()\">\n <mat-icon>remove</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"zoom-label\"\n matTooltip=\"Zoom to 100%\"\n (click)=\"zoomActual()\">\n {{ (zoom * 100).toFixed(0) }}%\n </button>\n <button\n type=\"button\"\n class=\"zoom-button\"\n matTooltip=\"Zoom in\"\n (click)=\"zoomIn()\">\n <mat-icon>add</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"zoom-button\"\n matTooltip=\"Fit page\"\n (click)=\"zoomFit()\">\n <mat-icon>fit_screen</mat-icon>\n </button>\n </div>\n </div>\n</div>\n", styles: [":host{display:flex;flex-direction:column;min-width:0;min-height:0;flex:1;margin-top:10px}.canvas{display:flex;flex-direction:column;gap:8px;flex:1;min-height:0}.canvas-toolbar{display:flex;align-items:center;justify-content:space-between;gap:8px}.canvas-toolbar .page-tabs{display:flex;align-items:center;gap:4px;flex-wrap:wrap}.canvas-toolbar .page-tabs fs-menu{display:none}.canvas-toolbar .page-tabs .page-tab{display:inline-flex;align-items:center;box-sizing:border-box;border:1px solid #e4e7eb;border-radius:16px;background:#fff;padding:4px 6px 4px 14px;font-size:12px;line-height:16px;color:#52606d;cursor:pointer}.canvas-toolbar .page-tabs .page-tab.active{background:var(--brand-primary-color, #3b82f6);border-color:var(--brand-primary-color, #3b82f6);color:#fff}.canvas-toolbar .page-tabs .page-tab .page-tab-label{white-space:nowrap}.canvas-toolbar .page-tabs .page-tab .page-tab-menu{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:16px;height:16px;margin-left:2px;border-radius:50%;opacity:.75}.canvas-toolbar .page-tabs .page-tab .page-tab-menu mat-icon{font-size:14px;width:14px;height:14px;line-height:14px}.canvas-toolbar .page-tabs .page-tab .page-tab-menu:hover{background:#0f172a14;opacity:1}.canvas-toolbar .page-tabs .page-tab.active .page-tab-menu:hover{background:#ffffff38}.canvas-toolbar .page-tabs .page-tab.add-page{gap:2px;padding:4px 14px 4px 8px;border-style:dashed;color:#52606d}.canvas-toolbar .page-tabs .page-tab.add-page mat-icon{font-size:16px;width:16px;height:16px}.canvas-toolbar .page-tabs .page-tab.cdk-drag-placeholder{background:transparent;border-style:dashed;border-color:#cbd2d9}.canvas-toolbar .page-tabs .page-tab.cdk-drag-placeholder .page-tab-label,.canvas-toolbar .page-tabs .page-tab.cdk-drag-placeholder .page-tab-menu{visibility:hidden}.canvas-toolbar .page-tabs .cdk-drag-animating,.canvas-toolbar .page-tabs.cdk-drop-list-dragging .page-tab:not(.cdk-drag-placeholder){transition:transform .18s cubic-bezier(0,0,.2,1)}.canvas-toolbar .zoom-controls{display:flex;align-items:center;gap:2px;margin-left:auto;border:1px solid #e4e7eb;border-radius:18px;background:#fff;padding:2px 6px}.canvas-toolbar .zoom-controls .zoom-button{display:flex;align-items:center;justify-content:center;border:none;border-radius:50%;background:transparent;color:#52606d;cursor:pointer}.canvas-toolbar .zoom-controls .zoom-button:hover{background:#f0f4f8}.canvas-toolbar .zoom-controls .zoom-button mat-icon{font-size:18px;width:18px;height:18px}.canvas-toolbar .zoom-controls .zoom-label{border:none;background:transparent;font-size:12px;color:#52606d;min-width:44px;cursor:pointer}.canvas-toolbar .zoom-controls .zoom-label:hover{color:#1f2933}.page-tab.cdk-drag-preview{display:inline-flex;align-items:center;box-sizing:border-box;border:1px solid #e4e7eb;border-radius:16px;background:#fff;padding:4px 6px 4px 14px;font-size:12px;line-height:16px;color:#52606d;box-shadow:0 3px 10px #0f172a3d}.page-tab.cdk-drag-preview.active{background:var(--brand-primary-color, #3b82f6);border-color:var(--brand-primary-color, #3b82f6);color:#fff}.page-tab.cdk-drag-preview .page-tab-label{white-space:nowrap}.page-tab.cdk-drag-preview .page-tab-menu{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:16px;height:16px;margin-left:2px;border-radius:50%;opacity:.75}.page-tab.cdk-drag-preview .page-tab-menu mat-icon{font-size:14px;width:14px;height:14px;line-height:14px}.page-viewport{position:relative;flex:1;min-height:420px;border:1px solid #e4e7eb;border-radius:8px;background:#eef1f5;overflow:hidden}.page-viewport fs-zoom-pan{width:100%;height:100%}.page{position:relative;background:#fff;border-radius:2px;box-shadow:0 2px 12px #0f172a1f,0 0 0 1px #0f172a0a;box-sizing:border-box}.page.flow{display:flex;flex-wrap:wrap;align-content:flex-start;align-items:flex-start}.page.editing{background-image:radial-gradient(circle,#d8dee6 1px,transparent 1px);background-size:24px 24px}.page.master-editing>app-report-component{opacity:.35;pointer-events:none}.master-layer{position:absolute;inset:0;pointer-events:none}.master-layer.editable{z-index:10}.master-layer.editable app-report-component{pointer-events:auto}.band{position:absolute;left:0;right:0;z-index:5;pointer-events:none;background:#2196f30a;border-color:#2196f373;border-style:dashed;border-width:0}.band.band-header{top:0;border-bottom-width:calc(1px / var(--canvas-zoom, 1))}.band.band-footer{bottom:0;border-top-width:calc(1px / var(--canvas-zoom, 1))}.band .band-label{position:absolute;top:calc(10px / var(--canvas-zoom, 1));left:calc(10px / var(--canvas-zoom, 1));transform:scale(calc(1 / var(--canvas-zoom, 1)));transform-origin:top left;color:#2196f3cc;font-weight:600;text-transform:uppercase;letter-spacing:.06em}.guides{position:absolute;inset:0;pointer-events:none;z-index:30}.guides ::ng-deep .guide{position:absolute;background:#2196f3}.guides ::ng-deep .guide.guide-v{top:0;bottom:0;width:calc(1.25px / var(--canvas-zoom, 1))}.guides ::ng-deep .guide.guide-h{left:0;right:0;height:calc(1.25px / var(--canvas-zoom, 1))}.page-empty{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:#9aa5b1;font-size:14px;pointer-events:none}\n"], dependencies: [{ kind: "ngmodule", type: DragDropModule }, { kind: "directive", type: i1.CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: i1.CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "component", type: MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "directive", type: MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "ngmodule", type: FsMenuModule }, { kind: "component", type: i2.FsMenuComponent, selector: "fs-menu", inputs: ["class", "buttonClass", "buttonType", "buttonColor"], outputs: ["opened", "closed"] }, { kind: "directive", type: i2.FsMenuItemDirective, selector: "fs-menu-group,[fs-menu-item]" }, { kind: "directive", type: i2.FsMenuTriggerDirective, selector: "[fsMenuTriggerFor]", inputs: ["fsMenuTriggerFor"] }, { kind: "ngmodule", type: FsZoomPanModule }, { kind: "component", type: i3.FsZoomPanComponent, selector: "fs-zoom-pan", inputs: ["zoomMax", "zoomMin", "zoomScale", "zoomDefault", "zoomFactor", "top", "left"], outputs: ["moved", "zoomed"] }, { kind: "component", type: ReportComponentComponent, selector: "app-report-component", inputs: ["reportId", "component", "groups", "editMode", "layout", "zoom", "snapper", "selected", "tokens"], outputs: ["selectComponent", "positionChanged", "flowReorder", "openSettings", "removed"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
439
553
  }
440
554
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ReportCanvasComponent, decorators: [{
441
555
  type: Component,
442
556
  args: [{ selector: 'app-report-canvas', changeDetection: ChangeDetectionStrategy.OnPush, standalone: true, imports: [
443
557
  DragDropModule,
444
- MatButton,
445
558
  MatIcon,
446
559
  MatTooltip,
447
560
  FsMenuModule,
448
561
  FsZoomPanModule,
449
562
  ReportComponentComponent,
450
- ], template: "<div class=\"canvas\">\n <div\n #viewport\n class=\"page-viewport\"\n (pointerdown)=\"onCanvasPointerDown()\">\n <fs-zoom-pan\n [zoomMin]=\"0.1\"\n [zoomMax]=\"3\"\n (zoomed)=\"onZoomed($event)\">\n @if (activePage; as page) {\n <div\n class=\"page\"\n [class.flow]=\"isFlow\"\n [class.editing]=\"editMode\"\n [style.width.px]=\"report.pageWidth * PX\"\n [style.height.px]=\"report.pageHeight * PX\"\n [style.padding.px]=\"isFlow ? flowPadding * PX : 0\"\n [style.--canvas-zoom]=\"zoom\"\n [style.--report-heading-size.px]=\"headingSizePx\">\n @if (isFlow) {\n @for (component of flowComponents; track component.id) {\n <app-report-component\n class=\"flow-item\"\n [reportId]=\"report.id\"\n [component]=\"component\"\n [groups]=\"groups\"\n [editMode]=\"editMode\"\n [layout]=\"'flow'\"\n [zoom]=\"zoom\"\n [snapper]=\"snapper\"\n [selected]=\"component.id === selectedComponentId\"\n [style.width.%]=\"component.flowWidth\"\n [style.height.px]=\"component.autoHeight ? null : component.h * PX\"\n (selectComponent)=\"selectComponent($event)\"\n (positionChanged)=\"onPositionChanged($event)\"\n (flowReorder)=\"onFlowReorder($event)\"\n (openSettings)=\"componentSettings.emit($event)\">\n </app-report-component>\n }\n } @else {\n @for (component of page.components; track component.id) {\n <app-report-component\n [reportId]=\"report.id\"\n [component]=\"component\"\n [groups]=\"groups\"\n [editMode]=\"editMode\"\n [layout]=\"'freeform'\"\n [zoom]=\"zoom\"\n [snapper]=\"snapper\"\n [selected]=\"component.id === selectedComponentId\"\n [style.left.px]=\"component.x * PX\"\n [style.top.px]=\"component.y * PX\"\n [style.width.px]=\"component.w * PX\"\n [style.height.px]=\"component.autoHeight ? null : component.h * PX\"\n (selectComponent)=\"selectComponent($event)\"\n (positionChanged)=\"onPositionChanged($event)\"\n (openSettings)=\"componentSettings.emit($event)\">\n </app-report-component>\n }\n }\n\n <div\n #guides\n class=\"guides\">\n </div>\n\n @if (!page.components.length) {\n <div class=\"page-empty\">\n Ask the assistant to add a chart, list or KPI to this page.\n </div>\n }\n </div>\n }\n </fs-zoom-pan>\n\n @if (editMode) {\n <button\n mat-flat-button\n type=\"button\"\n color=\"primary\"\n class=\"edit-done\"\n matTooltip=\"Exit layout editing\"\n (click)=\"editDone.emit()\">\n <mat-icon>check</mat-icon>\n Done editing\n </button>\n }\n </div>\n\n <div class=\"canvas-toolbar\">\n <!-- Tabs are one horizontal drop list: dragging a chip reorders the pages.\n The drop INDEX is computed along X (orientation), but the preview is\n deliberately left unbounded on both axes \u2014 pinning it to the row with\n cdkDragBoundary means the chip you are dragging covers the chips you\n are dragging it past, and you cannot see where it is going to land.\n Every page gets a chip, including a lone one: the chip is what tells\n you which page you are on, and a report that hid it left you unable to\n tell page 1 of 1 from a page that failed to load. Deleting the last\n page is refused server-side, so the kebab is safe to expose here. -->\n <div\n class=\"page-tabs\"\n cdkDropList\n cdkDropListOrientation=\"horizontal\"\n (cdkDropListDropped)=\"onPageDropped($event)\">\n @for (page of report?.pages ?? []; track page.id; let index = $index) {\n <!-- The chip is the drag handle AND the tab: clicking selects,\n dragging reorders. The kebab lives inside it, so the whole\n control stays one chip instead of growing a second button. -->\n <div\n cdkDrag\n class=\"page-tab\"\n [class.active]=\"index === activePageIndex\"\n (click)=\"selectPage(index)\">\n <span class=\"page-tab-label\">{{ pageLabel(page, index) }}</span>\n <!-- The kebab opens the menu rather than starting a drag or\n switching pages, so it swallows its own click. -->\n <span\n class=\"page-tab-menu\"\n [fsMenuTriggerFor]=\"pageMenu\"\n (click)=\"$event.stopPropagation()\"\n (mousedown)=\"$event.stopPropagation()\">\n <mat-icon>more_vert</mat-icon>\n </span>\n </div>\n <!-- Outside the chip: cdkDrag clones its host into the drag preview,\n and a menu overlay anchored to a cloned trigger opens detached\n from the real tab. -->\n <fs-menu #pageMenu>\n <ng-template\n fs-menu-item\n (click)=\"renamePage(page)\">\n Edit name\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"deletePage(page)\">\n Delete\n </ng-template>\n </fs-menu>\n }\n <button\n type=\"button\"\n class=\"page-tab add-page\"\n matTooltip=\"Add page\"\n (click)=\"addPage()\">\n <mat-icon>add</mat-icon>\n Page\n </button>\n </div>\n\n <div class=\"zoom-controls\">\n <button\n type=\"button\"\n class=\"zoom-button\"\n matTooltip=\"Zoom out\"\n (click)=\"zoomOut()\">\n <mat-icon>remove</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"zoom-label\"\n matTooltip=\"Zoom to 100%\"\n (click)=\"zoomActual()\">\n {{ (zoom * 100).toFixed(0) }}%\n </button>\n <button\n type=\"button\"\n class=\"zoom-button\"\n matTooltip=\"Zoom in\"\n (click)=\"zoomIn()\">\n <mat-icon>add</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"zoom-button\"\n matTooltip=\"Fit page\"\n (click)=\"zoomFit()\">\n <mat-icon>fit_screen</mat-icon>\n </button>\n </div>\n </div>\n</div>\n", styles: [":host{display:flex;flex-direction:column;min-width:0;min-height:0;flex:1;margin-top:10px}.canvas{display:flex;flex-direction:column;gap:8px;flex:1;min-height:0}.canvas-toolbar{display:flex;align-items:center;justify-content:space-between;gap:8px}.canvas-toolbar .page-tabs{display:flex;align-items:center;gap:4px;flex-wrap:wrap}.canvas-toolbar .page-tabs fs-menu{display:none}.canvas-toolbar .page-tabs .page-tab{display:inline-flex;align-items:center;box-sizing:border-box;border:1px solid #e4e7eb;border-radius:16px;background:#fff;padding:4px 6px 4px 14px;font-size:12px;line-height:16px;color:#52606d;cursor:pointer}.canvas-toolbar .page-tabs .page-tab.active{background:var(--brand-primary-color, #3b82f6);border-color:var(--brand-primary-color, #3b82f6);color:#fff}.canvas-toolbar .page-tabs .page-tab .page-tab-label{white-space:nowrap}.canvas-toolbar .page-tabs .page-tab .page-tab-menu{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:16px;height:16px;margin-left:2px;border-radius:50%;opacity:.75}.canvas-toolbar .page-tabs .page-tab .page-tab-menu mat-icon{font-size:14px;width:14px;height:14px;line-height:14px}.canvas-toolbar .page-tabs .page-tab .page-tab-menu:hover{background:#0f172a14;opacity:1}.canvas-toolbar .page-tabs .page-tab.active .page-tab-menu:hover{background:#ffffff38}.canvas-toolbar .page-tabs .page-tab.add-page{gap:2px;padding:4px 14px 4px 8px;border-style:dashed;color:#52606d}.canvas-toolbar .page-tabs .page-tab.add-page mat-icon{font-size:16px;width:16px;height:16px}.canvas-toolbar .page-tabs .page-tab.cdk-drag-placeholder{background:transparent;border-style:dashed;border-color:#cbd2d9}.canvas-toolbar .page-tabs .page-tab.cdk-drag-placeholder .page-tab-label,.canvas-toolbar .page-tabs .page-tab.cdk-drag-placeholder .page-tab-menu{visibility:hidden}.canvas-toolbar .page-tabs .cdk-drag-animating,.canvas-toolbar .page-tabs.cdk-drop-list-dragging .page-tab:not(.cdk-drag-placeholder){transition:transform .18s cubic-bezier(0,0,.2,1)}.canvas-toolbar .zoom-controls{display:flex;align-items:center;gap:2px;margin-left:auto;border:1px solid #e4e7eb;border-radius:18px;background:#fff;padding:2px 6px}.canvas-toolbar .zoom-controls .zoom-button{display:flex;align-items:center;justify-content:center;border:none;border-radius:50%;background:transparent;color:#52606d;cursor:pointer}.canvas-toolbar .zoom-controls .zoom-button:hover{background:#f0f4f8}.canvas-toolbar .zoom-controls .zoom-button mat-icon{font-size:18px;width:18px;height:18px}.canvas-toolbar .zoom-controls .zoom-label{border:none;background:transparent;font-size:12px;color:#52606d;min-width:44px;cursor:pointer}.canvas-toolbar .zoom-controls .zoom-label:hover{color:#1f2933}.page-tab.cdk-drag-preview{display:inline-flex;align-items:center;box-sizing:border-box;border:1px solid #e4e7eb;border-radius:16px;background:#fff;padding:4px 6px 4px 14px;font-size:12px;line-height:16px;color:#52606d;box-shadow:0 3px 10px #0f172a3d}.page-tab.cdk-drag-preview.active{background:var(--brand-primary-color, #3b82f6);border-color:var(--brand-primary-color, #3b82f6);color:#fff}.page-tab.cdk-drag-preview .page-tab-label{white-space:nowrap}.page-tab.cdk-drag-preview .page-tab-menu{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:16px;height:16px;margin-left:2px;border-radius:50%;opacity:.75}.page-tab.cdk-drag-preview .page-tab-menu mat-icon{font-size:14px;width:14px;height:14px;line-height:14px}.page-viewport{position:relative;flex:1;min-height:420px;border:1px solid #e4e7eb;border-radius:8px;background:#eef1f5;overflow:hidden}.page-viewport fs-zoom-pan{width:100%;height:100%}.edit-done{position:absolute;top:12px;right:12px;z-index:40;border-radius:999px;box-shadow:0 2px 10px #0f172a2e}.page{position:relative;background:#fff;border-radius:2px;box-shadow:0 2px 12px #0f172a1f,0 0 0 1px #0f172a0a;box-sizing:border-box}.page.flow{display:flex;flex-wrap:wrap;align-content:flex-start;align-items:flex-start}.page.editing{background-image:radial-gradient(circle,#d8dee6 1px,transparent 1px);background-size:24px 24px}.guides{position:absolute;inset:0;pointer-events:none;z-index:30}.guides ::ng-deep .guide{position:absolute;background:#2196f3}.guides ::ng-deep .guide.guide-v{top:0;bottom:0;width:calc(1.25px / var(--canvas-zoom, 1))}.guides ::ng-deep .guide.guide-h{left:0;right:0;height:calc(1.25px / var(--canvas-zoom, 1))}.page-empty{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:#9aa5b1;font-size:14px;pointer-events:none}\n"] }]
563
+ ], template: "<div class=\"canvas\">\n <div\n #viewport\n class=\"page-viewport\"\n (pointerdown)=\"onCanvasPointerDown()\">\n <fs-zoom-pan\n [zoomMin]=\"0.1\"\n [zoomMax]=\"3\"\n (zoomed)=\"onZoomed($event)\">\n @if (activePage; as page) {\n <div\n class=\"page\"\n [class.flow]=\"isFlow\"\n [class.editing]=\"editMode\"\n [class.master-editing]=\"isMasterEditing\"\n [style.width.px]=\"report.pageWidth * PX\"\n [style.height.px]=\"report.pageHeight * PX\"\n [style.padding.px]=\"isFlow ? flowPadding * PX : 0\"\n [style.--canvas-zoom]=\"zoom\"\n [style.--report-heading-size.px]=\"headingSizePx\">\n <!-- The header and footer: the master's components, always freeform,\n drawn under the page's own. Out of the flow (absolute), so a flow\n page's rows are laid out as if it were not there. -->\n @if (isMasterShown && masterComponents.length) {\n <div\n class=\"master-layer\"\n [class.editable]=\"isMasterEditing\">\n @for (component of masterComponents; track component.id) {\n <app-report-component\n [reportId]=\"report.id\"\n [component]=\"component\"\n [groups]=\"groups\"\n [editMode]=\"isMasterEditing\"\n [layout]=\"'freeform'\"\n [zoom]=\"zoom\"\n [snapper]=\"snapper\"\n [tokens]=\"tokens\"\n [selected]=\"component.id === selectedComponentId\"\n [style.left.px]=\"component.x * PX\"\n [style.top.px]=\"component.y * PX\"\n [style.width.px]=\"component.w * PX\"\n [style.height.px]=\"component.autoHeight ? null : component.h * PX\"\n (selectComponent)=\"selectComponent($event)\"\n (positionChanged)=\"onPositionChanged($event)\"\n (removed)=\"onComponentRemoved($event)\"\n (openSettings)=\"componentSettings.emit($event)\">\n </app-report-component>\n }\n </div>\n }\n\n <!-- The header and footer bands, as guides while editing. -->\n @if (editMode) {\n @if (bands.headerHeight) {\n <div\n class=\"band band-header\"\n [style.height.px]=\"bands.headerHeight * PX\">\n @if (isMasterEditing) {\n <span class=\"band-label small\">Header</span>\n }\n </div>\n }\n @if (bands.footerHeight) {\n <div\n class=\"band band-footer\"\n [style.height.px]=\"bands.footerHeight * PX\">\n @if (isMasterEditing) {\n <span class=\"band-label small\">Footer</span>\n }\n </div>\n }\n }\n\n @if (isFlow) {\n @for (component of flowComponents; track component.id) {\n <app-report-component\n class=\"flow-item\"\n [reportId]=\"report.id\"\n [component]=\"component\"\n [groups]=\"groups\"\n [editMode]=\"isPageEditing\"\n [layout]=\"'flow'\"\n [zoom]=\"zoom\"\n [snapper]=\"snapper\"\n [tokens]=\"tokens\"\n [selected]=\"component.id === selectedComponentId\"\n [style.width.%]=\"component.flowWidth\"\n [style.height.px]=\"component.autoHeight ? null : component.h * PX\"\n (selectComponent)=\"selectComponent($event)\"\n (positionChanged)=\"onPositionChanged($event)\"\n (flowReorder)=\"onFlowReorder($event)\"\n (removed)=\"onComponentRemoved($event)\"\n (openSettings)=\"componentSettings.emit($event)\">\n </app-report-component>\n }\n } @else {\n @for (component of page.components; track component.id) {\n <app-report-component\n [reportId]=\"report.id\"\n [component]=\"component\"\n [groups]=\"groups\"\n [editMode]=\"isPageEditing\"\n [layout]=\"'freeform'\"\n [zoom]=\"zoom\"\n [snapper]=\"snapper\"\n [tokens]=\"tokens\"\n [selected]=\"component.id === selectedComponentId\"\n [style.left.px]=\"component.x * PX\"\n [style.top.px]=\"component.y * PX\"\n [style.width.px]=\"component.w * PX\"\n [style.height.px]=\"component.autoHeight ? null : component.h * PX\"\n (selectComponent)=\"selectComponent($event)\"\n (positionChanged)=\"onPositionChanged($event)\"\n (removed)=\"onComponentRemoved($event)\"\n (openSettings)=\"componentSettings.emit($event)\">\n </app-report-component>\n }\n }\n\n <div\n #guides\n class=\"guides\">\n </div>\n\n @if (!page.components.length && !masterMode()) {\n <div class=\"page-empty\">\n Ask the assistant to add a chart, list or KPI to this page.\n </div>\n }\n </div>\n }\n </fs-zoom-pan>\n </div>\n\n <div class=\"canvas-toolbar\">\n <!-- Tabs are one horizontal drop list: dragging a chip reorders the pages.\n The drop INDEX is computed along X (orientation), but the preview is\n deliberately left unbounded on both axes \u2014 pinning it to the row with\n cdkDragBoundary means the chip you are dragging covers the chips you\n are dragging it past, and you cannot see where it is going to land.\n Every page gets a chip, including a lone one: the chip is what tells\n you which page you are on, and a report that hid it left you unable to\n tell page 1 of 1 from a page that failed to load. Deleting the last\n page is refused server-side, so the kebab is safe to expose here. -->\n <div\n class=\"page-tabs\"\n cdkDropList\n cdkDropListOrientation=\"horizontal\"\n (cdkDropListDropped)=\"onPageDropped($event)\">\n @for (page of report?.pages ?? []; track page.id; let index = $index) {\n <!-- The chip is the drag handle AND the tab: clicking selects,\n dragging reorders. The kebab lives inside it, so the whole\n control stays one chip instead of growing a second button. -->\n <div\n cdkDrag\n class=\"page-tab\"\n [class.active]=\"index === activePageIndex\"\n (click)=\"selectPage(index)\">\n <span class=\"page-tab-label\">{{ pageLabel(page, index) }}</span>\n <!-- The kebab opens the menu rather than starting a drag or\n switching pages, so it swallows its own click. -->\n <span\n class=\"page-tab-menu\"\n [fsMenuTriggerFor]=\"pageMenu\"\n (click)=\"$event.stopPropagation()\"\n (mousedown)=\"$event.stopPropagation()\">\n <mat-icon>more_vert</mat-icon>\n </span>\n </div>\n <!-- Outside the chip: cdkDrag clones its host into the drag preview,\n and a menu overlay anchored to a cloned trigger opens detached\n from the real tab. -->\n <fs-menu #pageMenu>\n <ng-template\n fs-menu-item\n (click)=\"renamePage(page)\">\n Edit name\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"toggleMasterHidden(page)\">\n {{ page.masterHidden ? 'Show header & footer' : 'Hide header & footer' }}\n </ng-template>\n <ng-template\n fs-menu-item\n (click)=\"deletePage(page)\">\n Delete\n </ng-template>\n </fs-menu>\n }\n <button\n type=\"button\"\n class=\"page-tab add-page\"\n matTooltip=\"Add page\"\n (click)=\"addPage()\">\n <mat-icon>add</mat-icon>\n Page\n </button>\n </div>\n\n <div class=\"zoom-controls\">\n <button\n type=\"button\"\n class=\"zoom-button\"\n matTooltip=\"Zoom out\"\n (click)=\"zoomOut()\">\n <mat-icon>remove</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"zoom-label\"\n matTooltip=\"Zoom to 100%\"\n (click)=\"zoomActual()\">\n {{ (zoom * 100).toFixed(0) }}%\n </button>\n <button\n type=\"button\"\n class=\"zoom-button\"\n matTooltip=\"Zoom in\"\n (click)=\"zoomIn()\">\n <mat-icon>add</mat-icon>\n </button>\n <button\n type=\"button\"\n class=\"zoom-button\"\n matTooltip=\"Fit page\"\n (click)=\"zoomFit()\">\n <mat-icon>fit_screen</mat-icon>\n </button>\n </div>\n </div>\n</div>\n", styles: [":host{display:flex;flex-direction:column;min-width:0;min-height:0;flex:1;margin-top:10px}.canvas{display:flex;flex-direction:column;gap:8px;flex:1;min-height:0}.canvas-toolbar{display:flex;align-items:center;justify-content:space-between;gap:8px}.canvas-toolbar .page-tabs{display:flex;align-items:center;gap:4px;flex-wrap:wrap}.canvas-toolbar .page-tabs fs-menu{display:none}.canvas-toolbar .page-tabs .page-tab{display:inline-flex;align-items:center;box-sizing:border-box;border:1px solid #e4e7eb;border-radius:16px;background:#fff;padding:4px 6px 4px 14px;font-size:12px;line-height:16px;color:#52606d;cursor:pointer}.canvas-toolbar .page-tabs .page-tab.active{background:var(--brand-primary-color, #3b82f6);border-color:var(--brand-primary-color, #3b82f6);color:#fff}.canvas-toolbar .page-tabs .page-tab .page-tab-label{white-space:nowrap}.canvas-toolbar .page-tabs .page-tab .page-tab-menu{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:16px;height:16px;margin-left:2px;border-radius:50%;opacity:.75}.canvas-toolbar .page-tabs .page-tab .page-tab-menu mat-icon{font-size:14px;width:14px;height:14px;line-height:14px}.canvas-toolbar .page-tabs .page-tab .page-tab-menu:hover{background:#0f172a14;opacity:1}.canvas-toolbar .page-tabs .page-tab.active .page-tab-menu:hover{background:#ffffff38}.canvas-toolbar .page-tabs .page-tab.add-page{gap:2px;padding:4px 14px 4px 8px;border-style:dashed;color:#52606d}.canvas-toolbar .page-tabs .page-tab.add-page mat-icon{font-size:16px;width:16px;height:16px}.canvas-toolbar .page-tabs .page-tab.cdk-drag-placeholder{background:transparent;border-style:dashed;border-color:#cbd2d9}.canvas-toolbar .page-tabs .page-tab.cdk-drag-placeholder .page-tab-label,.canvas-toolbar .page-tabs .page-tab.cdk-drag-placeholder .page-tab-menu{visibility:hidden}.canvas-toolbar .page-tabs .cdk-drag-animating,.canvas-toolbar .page-tabs.cdk-drop-list-dragging .page-tab:not(.cdk-drag-placeholder){transition:transform .18s cubic-bezier(0,0,.2,1)}.canvas-toolbar .zoom-controls{display:flex;align-items:center;gap:2px;margin-left:auto;border:1px solid #e4e7eb;border-radius:18px;background:#fff;padding:2px 6px}.canvas-toolbar .zoom-controls .zoom-button{display:flex;align-items:center;justify-content:center;border:none;border-radius:50%;background:transparent;color:#52606d;cursor:pointer}.canvas-toolbar .zoom-controls .zoom-button:hover{background:#f0f4f8}.canvas-toolbar .zoom-controls .zoom-button mat-icon{font-size:18px;width:18px;height:18px}.canvas-toolbar .zoom-controls .zoom-label{border:none;background:transparent;font-size:12px;color:#52606d;min-width:44px;cursor:pointer}.canvas-toolbar .zoom-controls .zoom-label:hover{color:#1f2933}.page-tab.cdk-drag-preview{display:inline-flex;align-items:center;box-sizing:border-box;border:1px solid #e4e7eb;border-radius:16px;background:#fff;padding:4px 6px 4px 14px;font-size:12px;line-height:16px;color:#52606d;box-shadow:0 3px 10px #0f172a3d}.page-tab.cdk-drag-preview.active{background:var(--brand-primary-color, #3b82f6);border-color:var(--brand-primary-color, #3b82f6);color:#fff}.page-tab.cdk-drag-preview .page-tab-label{white-space:nowrap}.page-tab.cdk-drag-preview .page-tab-menu{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:16px;height:16px;margin-left:2px;border-radius:50%;opacity:.75}.page-tab.cdk-drag-preview .page-tab-menu mat-icon{font-size:14px;width:14px;height:14px;line-height:14px}.page-viewport{position:relative;flex:1;min-height:420px;border:1px solid #e4e7eb;border-radius:8px;background:#eef1f5;overflow:hidden}.page-viewport fs-zoom-pan{width:100%;height:100%}.page{position:relative;background:#fff;border-radius:2px;box-shadow:0 2px 12px #0f172a1f,0 0 0 1px #0f172a0a;box-sizing:border-box}.page.flow{display:flex;flex-wrap:wrap;align-content:flex-start;align-items:flex-start}.page.editing{background-image:radial-gradient(circle,#d8dee6 1px,transparent 1px);background-size:24px 24px}.page.master-editing>app-report-component{opacity:.35;pointer-events:none}.master-layer{position:absolute;inset:0;pointer-events:none}.master-layer.editable{z-index:10}.master-layer.editable app-report-component{pointer-events:auto}.band{position:absolute;left:0;right:0;z-index:5;pointer-events:none;background:#2196f30a;border-color:#2196f373;border-style:dashed;border-width:0}.band.band-header{top:0;border-bottom-width:calc(1px / var(--canvas-zoom, 1))}.band.band-footer{bottom:0;border-top-width:calc(1px / var(--canvas-zoom, 1))}.band .band-label{position:absolute;top:calc(10px / var(--canvas-zoom, 1));left:calc(10px / var(--canvas-zoom, 1));transform:scale(calc(1 / var(--canvas-zoom, 1)));transform-origin:top left;color:#2196f3cc;font-weight:600;text-transform:uppercase;letter-spacing:.06em}.guides{position:absolute;inset:0;pointer-events:none;z-index:30}.guides ::ng-deep .guide{position:absolute;background:#2196f3}.guides ::ng-deep .guide.guide-v{top:0;bottom:0;width:calc(1.25px / var(--canvas-zoom, 1))}.guides ::ng-deep .guide.guide-h{left:0;right:0;height:calc(1.25px / var(--canvas-zoom, 1))}.page-empty{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;color:#9aa5b1;font-size:14px;pointer-events:none}\n"] }]
451
564
  }], propDecorators: { report: [{
452
565
  type: Input
453
566
  }], editMode: [{
@@ -458,8 +571,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
458
571
  type: Output
459
572
  }], reportChanged: [{
460
573
  type: Output
461
- }], editDone: [{
462
- type: Output
463
574
  }], pageChanged: [{
464
575
  type: Output
465
576
  }], zoomPan: [{
@@ -475,4 +586,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
475
586
  type: ViewChild,
476
587
  args: ['guides', { static: false }]
477
588
  }] } });
478
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LWNhbnZhcy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL3JlcG9ydHMvY29tcG9uZW50cy9yZXBvcnQtY2FudmFzL3JlcG9ydC1jYW52YXMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2NvbXBvbmVudHMvcmVwb3J0LWNhbnZhcy9yZXBvcnQtY2FudmFzLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDVSx1QkFBdUIsRUFBRSxpQkFBaUIsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUNoRixVQUFVLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBYSxNQUFNLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsTUFBTSxHQUMvRixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUVoRSxPQUFPLEVBQWUsY0FBYyxFQUFFLGVBQWUsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ3RGLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDakQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBRXZELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNoRCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxlQUFlLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUUzRSxPQUFPLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUV0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QU0sRUFBRSxLQUFLLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gIEFmdGVyVmlld0luaXQsIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDaGFuZ2VEZXRlY3RvclJlZiwgQ29tcG9uZW50LCBEZXN0cm95UmVmLFxyXG4gIEVsZW1lbnRSZWYsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE9uQ2hhbmdlcywgT3V0cHV0LCBRdWVyeUxpc3QsIFZpZXdDaGlsZCwgVmlld0NoaWxkcmVuLCBpbmplY3QsXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcclxuXHJcbmltcG9ydCB7IENka0RyYWdEcm9wLCBEcmFnRHJvcE1vZHVsZSwgbW92ZUl0ZW1JbkFycmF5IH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2RyYWctZHJvcCc7XHJcbmltcG9ydCB7IE1hdEJ1dHRvbiB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2J1dHRvbic7XHJcbmltcG9ydCB7IE1hdEljb24gfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pY29uJztcclxuaW1wb3J0IHsgTWF0VG9vbHRpcCB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL3Rvb2x0aXAnO1xyXG5cclxuaW1wb3J0IHsgRnNNZW51TW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvbWVudSc7XHJcbmltcG9ydCB7IEZzTWVzc2FnZSB9IGZyb20gJ0BmaXJlc3RpdGNoL21lc3NhZ2UnO1xyXG5pbXBvcnQgeyBGc1Byb21wdCB9IGZyb20gJ0BmaXJlc3RpdGNoL3Byb21wdCc7XHJcbmltcG9ydCB7IEZzWm9vbVBhbkNvbXBvbmVudCwgRnNab29tUGFuTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvem9vbS1wYW4nO1xyXG5cclxuaW1wb3J0IHsgbWFwLCBzd2l0Y2hNYXAgfSBmcm9tICdyeGpzJztcclxuXHJcbmltcG9ydCB7IFJlcG9ydERhdGEgfSBmcm9tICcuLi8uLi9kYXRhL3JlcG9ydC5kYXRhJztcclxuaW1wb3J0IHtcclxuICBDb21wb25lbnRTZXR0aW5ncywgUmVwb3J0LCBSZXBvcnRDb21wb25lbnQsIFJlcG9ydEZpbHRlckdyb3VwLCBSZXBvcnRQYWdlLFxyXG59IGZyb20gJy4uLy4uL2ludGVyZmFjZXMvcmVwb3J0LmludGVyZmFjZSc7XHJcbmltcG9ydCB7IERFRkFVTFRfSEVBRElOR19TSVpFLCBGTE9XX1BBRERJTkcgfSBmcm9tICcuLi8uLi9sYXlvdXQnO1xyXG5pbXBvcnQgeyBSZXBvcnRDb21wb25lbnRDb21wb25lbnQgfSBmcm9tICcuLi9yZXBvcnQtY29tcG9uZW50L3JlcG9ydC1jb21wb25lbnQuY29tcG9uZW50JztcclxuXHJcblxyXG4vLyBTY3JlZW4gZGVuc2l0eSBvZiB0aGUgY2FudmFzOiA5NiBDU1MgcHggcGVyIGluY2ggKHRoZSBDU1MgcmVmZXJlbmNlIHBpeGVsKSxcclxuLy8gYmVmb3JlIHpvb20uIEFsbCBnZW9tZXRyeSBzdGF5cyBpbiBpbmNoZXM7IG9ubHkgcmVuZGVyaW5nIG11bHRpcGxpZXMgYnkgaXQuXHJcbmV4cG9ydCBjb25zdCBQWF9QRVJfSU5DSCA9IDk2O1xyXG5cclxuLy8gT25lIHNtYXJ0IGd1aWRlIGxpbmUsIGluIHBhZ2UgaW5jaGVzLlxyXG5leHBvcnQgaW50ZXJmYWNlIEd1aWRlTGluZSB7XHJcbiAgb3JpZW50YXRpb246ICd2JyB8ICdoJztcclxuICBwb3NpdGlvbjogbnVtYmVyO1xyXG59XHJcblxyXG4vLyBUaGUgc25hcHBpbmcgY29udHJhY3QgaGFuZGVkIHRvIGVhY2ggY29tcG9uZW50J3MgZHJhZyBsb29wLiBJbXBsZW1lbnRlZCBieVxyXG4vLyB0aGUgY2FudmFzIGJlY2F1c2Ugb25seSBpdCBzZWVzIGV2ZXJ5IGNvbXBvbmVudCAoYWxpZ25tZW50IGNhbmRpZGF0ZXMpIGFuZFxyXG4vLyBvd25zIHRoZSBndWlkZXMgb3ZlcmxheS5cclxuZXhwb3J0IGludGVyZmFjZSBDYW52YXNTbmFwcGVyIHtcclxuICBzbmFwTW92ZShjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudCwgeDogbnVtYmVyLCB5OiBudW1iZXIpOiB7IHg6IG51bWJlcjsgeTogbnVtYmVyIH07XHJcbiAgc25hcFJlc2l6ZShjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudCwgZ2VvbWV0cnk6IHsgeDogbnVtYmVyOyB5OiBudW1iZXI7IHc6IG51bWJlcjsgaDogbnVtYmVyIH0sIGhhbmRsZTogc3RyaW5nKTogeyB4OiBudW1iZXI7IHk6IG51bWJlcjsgdzogbnVtYmVyOyBoOiBudW1iZXIgfTtcclxuICBjbGVhcigpOiB2b2lkO1xyXG59XHJcblxyXG4vLyBUaGUgZml4ZWQtc2l6ZSBwYWdlIGNhbnZhcyDigJQgdGhlIFBvd2VyUG9pbnQgbW9kZWwuIFBhZ2VzIGFyZSB0YWJzIChvbmx5IHRoZVxyXG4vLyBBQ1RJVkUgcGFnZSdzIGNvbXBvbmVudHMgZXhpc3Qg4oaSIG9ubHkgdGhleSBmZXRjaCk7IHRoZSBwYWdlIGlzIGFcclxuLy8gcGFnZVdpZHRow5dwYWdlSGVpZ2h0IElOQ0hFUyBzaGVldCByZW5kZXJlZCBhdCA5NnB4L2luIGluc2lkZSBmcy16b29tLXBhblxyXG4vLyAod2hlZWwgem9vbSwgYmFja2dyb3VuZCBkcmFnIHBhbiwgdG9vbGJhciBidXR0b25zKS5cclxuLy9cclxuLy8gRnJlZWZvcm0gbGF5b3V0OiBjb21wb25lbnRzIGFyZSBhYnNvbHV0ZWx5IHBvc2l0aW9uZWQ7IGRyYWdnaW5nIGdldHMgc21hcnRcclxuLy8gYWxpZ25tZW50IGd1aWRlcyAoZWRnZXMgKyBjZW50ZXJzIG9mIHNpYmxpbmdzIGFuZCB0aGUgcGFnZSkgd2l0aCBzbmFwcGluZy5cclxuLy8gRmxvdyBsYXlvdXQ6IGNvbXBvbmVudHMgZmxvdyBpbnRvIHJvd3MgKGZsb3dXaWR0aCAlIG9mIHRoZSBjb250ZW50IHdpZHRoKSxcclxuLy8gZHJhZyByZW9yZGVycywgZWFzdC9zb3V0aCBoYW5kbGVzIHJlc2l6ZSB3aWR0aCUvaGVpZ2h0LlxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2FwcC1yZXBvcnQtY2FudmFzJyxcclxuICB0ZW1wbGF0ZVVybDogJy4vcmVwb3J0LWNhbnZhcy5jb21wb25lbnQuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJy4vcmVwb3J0LWNhbnZhcy5jb21wb25lbnQuc2NzcyddLFxyXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxyXG4gIHN0YW5kYWxvbmU6IHRydWUsXHJcbiAgaW1wb3J0czogW1xyXG4gICAgRHJhZ0Ryb3BNb2R1bGUsXHJcbiAgICBNYXRCdXR0b24sXHJcbiAgICBNYXRJY29uLFxyXG4gICAgTWF0VG9vbHRpcCxcclxuICAgIEZzTWVudU1vZHVsZSxcclxuICAgIEZzWm9vbVBhbk1vZHVsZSxcclxuICAgIFJlcG9ydENvbXBvbmVudENvbXBvbmVudCxcclxuICBdLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgUmVwb3J0Q2FudmFzQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzLCBBZnRlclZpZXdJbml0IHtcclxuXHJcbiAgQElucHV0KCkgcHVibGljIHJlcG9ydDogUmVwb3J0O1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBlZGl0TW9kZSA9IGZhbHNlO1xyXG5cclxuICAvLyBUaGUgcGFnZSB0aGUgaG9zdCB3YW50cyBvbiBzY3JlZW4sIGJ5IHBhZ2UgaWQgKGEgZGVlcCBsaW5rKS4gS2V5ZWQgb24gaWRcclxuICAvLyByYXRoZXIgdGhhbiBpbmRleCBzbyBhIGxpbmsgc3Vydml2ZXMgcGFnZXMgYmVpbmcgcmVvcmRlcmVkIG9yIGRlbGV0ZWQ7IGFuXHJcbiAgLy8gaWQgdGhhdCBubyBsb25nZXIgcmVzb2x2ZXMgZmFsbHMgYmFjayB0byB0aGUgZmlyc3QgcGFnZS5cclxuICBASW5wdXQoKSBwdWJsaWMgcGFnZUlkOiBudW1iZXIgfCBudWxsID0gbnVsbDtcclxuXHJcbiAgLy8gQSBjb21wb25lbnQgYXNrZWQgZm9yIGl0cyBzZXR0aW5ncyBkaWFsb2cg4oCUIHRoZSBwYWdlLWxldmVsIGhvc3Qgb3BlbnMgaXRcclxuICAvLyAoaXQgb3ducyBNYXREaWFsb2cgKyB0aGUgcG9zdC1zYXZlIHJlbG9hZCkuXHJcbiAgQE91dHB1dCgpIHB1YmxpYyBjb21wb25lbnRTZXR0aW5ncyA9IG5ldyBFdmVudEVtaXR0ZXI8UmVwb3J0Q29tcG9uZW50PigpO1xyXG5cclxuICAvLyBUaGUgcmVwb3J0J3Mgc3RydWN0dXJlIGNoYW5nZWQgaGVyZSAoYSBwYWdlIHdhcyBhZGRlZCkg4oCUIHRoZSBob3N0IHJlLWZldGNoZXNcclxuICAvLyBpdCAoaXQgb3ducyB0aGUgYXNzZW1ibGVkIHJlcG9ydCArIGZpbHRlciBzdGF0ZSkuXHJcbiAgQE91dHB1dCgpIHB1YmxpYyByZXBvcnRDaGFuZ2VkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xyXG5cclxuICAvLyBUaGUgdmlld2VyIGRpc21pc3NlZCBlZGl0IG1vZGUgZnJvbSB0aGUgb24tY2FudmFzIGJhZGdlIOKAlCB0aGUgaG9zdCBvd25zIHRoZVxyXG4gIC8vIGVkaXRNb2RlIGZsYWcsIHNvIGl0IGZsaXBzIGl0IG9mZiAobWlycm9ycyB0aGUgbWVudSdzIFwiRG9uZSBlZGl0aW5nIGxheW91dFwiKS5cclxuICBAT3V0cHV0KCkgcHVibGljIGVkaXREb25lID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xyXG5cclxuICAvLyBUaGUgcGFnZSBvbiBzY3JlZW4gY2hhbmdlZCDigJQgdGhlIGhvc3QgcmVmbGVjdHMgaXQgaW4gdGhlIFVSTCBzbyBhIHJlZnJlc2hcclxuICAvLyBjb21lcyBiYWNrIHRvIHRoZSBzYW1lIHBhZ2UuIENhcnJpZXMgdGhlIHBhZ2UgaWQsIG5ldmVyIHRoZSBpbmRleC5cclxuICBAT3V0cHV0KCkgcHVibGljIHBhZ2VDaGFuZ2VkID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXIgfCBudWxsPigpO1xyXG5cclxuICBAVmlld0NoaWxkKEZzWm9vbVBhbkNvbXBvbmVudClcclxuICBwdWJsaWMgem9vbVBhbjogRnNab29tUGFuQ29tcG9uZW50O1xyXG5cclxuICAvLyBUaGUgcmVuZGVyZWQgY29tcG9uZW50cyBvZiB0aGUgYWN0aXZlIHBhZ2Ug4oCUIG9ubHkgdGhlIGNhbnZhcyBjYW4gcmVhY2ggdGhlXHJcbiAgLy8gb25lIGluc3RhbmNlIGEgc2V0dGluZ3Mgc2F2ZSBhcHBsaWVzIHRvLlxyXG4gIEBWaWV3Q2hpbGRyZW4oUmVwb3J0Q29tcG9uZW50Q29tcG9uZW50KVxyXG4gIHByaXZhdGUgX3JlbmRlcmVkQ29tcG9uZW50czogUXVlcnlMaXN0PFJlcG9ydENvbXBvbmVudENvbXBvbmVudD47XHJcblxyXG4gIEBWaWV3Q2hpbGQoJ3ZpZXdwb3J0JywgeyBzdGF0aWM6IHRydWUgfSlcclxuICBwcml2YXRlIF92aWV3cG9ydDogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD47XHJcblxyXG4gIEBWaWV3Q2hpbGQoJ2d1aWRlcycsIHsgc3RhdGljOiBmYWxzZSB9KVxyXG4gIHByaXZhdGUgX2d1aWRlczogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD47XHJcblxyXG4gIHB1YmxpYyByZWFkb25seSBQWCA9IFBYX1BFUl9JTkNIO1xyXG4gIHB1YmxpYyByZWFkb25seSBmbG93UGFkZGluZyA9IEZMT1dfUEFERElORztcclxuXHJcbiAgcHVibGljIGFjdGl2ZVBhZ2VJbmRleCA9IDA7XHJcbiAgcHVibGljIHpvb20gPSAxO1xyXG4gIHB1YmxpYyBncm91cHMgPSBuZXcgTWFwPG51bWJlciwgUmVwb3J0RmlsdGVyR3JvdXA+KCk7XHJcbiAgcHVibGljIHNlbGVjdGVkQ29tcG9uZW50SWQ6IG51bWJlciB8IG51bGwgPSBudWxsO1xyXG5cclxuICAvLyBUaGUgc25hcHBlciBoYW5kZWQgdG8gZXZlcnkgY29tcG9uZW50IChzdGFibGUgaWRlbnRpdHkgZm9yIE9uUHVzaCkuXHJcbiAgcHVibGljIHJlYWRvbmx5IHNuYXBwZXI6IENhbnZhc1NuYXBwZXIgPSB7XHJcbiAgICBzbmFwTW92ZTogKGNvbXBvbmVudCwgeCwgeSkgPT4gdGhpcy5fc25hcE1vdmUoY29tcG9uZW50LCB4LCB5KSxcclxuICAgIHNuYXBSZXNpemU6IChjb21wb25lbnQsIGdlb21ldHJ5LCBoYW5kbGUpID0+IHRoaXMuX3NuYXBSZXNpemUoY29tcG9uZW50LCBnZW9tZXRyeSwgaGFuZGxlKSxcclxuICAgIGNsZWFyOiAoKSA9PiB0aGlzLl9jbGVhckd1aWRlcygpLFxyXG4gIH07XHJcblxyXG4gIHByaXZhdGUgX3JlcG9ydERhdGEgPSBpbmplY3QoUmVwb3J0RGF0YSk7XHJcbiAgcHJpdmF0ZSBfcHJvbXB0ID0gaW5qZWN0KEZzUHJvbXB0KTtcclxuICBwcml2YXRlIF9tZXNzYWdlID0gaW5qZWN0KEZzTWVzc2FnZSk7XHJcbiAgcHJpdmF0ZSBfY2RSZWYgPSBpbmplY3QoQ2hhbmdlRGV0ZWN0b3JSZWYpO1xyXG4gIHByaXZhdGUgX2Rlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZik7XHJcbiAgcHJpdmF0ZSBfZml0dGVkID0gZmFsc2U7XHJcbiAgcHJpdmF0ZSBfcHJldmlvdXNQYWdlQ291bnQgPSAwO1xyXG5cclxuICAvLyBUaGUgcGFnZSBpZCBsYXN0IGFubm91bmNlZCB0aHJvdWdoIHBhZ2VDaGFuZ2VkLCBzbyBhIHJlLXJlbmRlciB0aGF0IGxhbmRzIG9uXHJcbiAgLy8gdGhlIHNhbWUgcGFnZSBzdGF5cyBxdWlldCDigJQgaG9zdHMgcmVsb2FkIG9uIHRoaXMgYW5kIGFuIHVuY2hhbmdlZCBwYWdlIGlzXHJcbiAgLy8gbm90IG5ld3MuXHJcbiAgcHJpdmF0ZSBfZW1pdHRlZFBhZ2VJZDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XHJcblxyXG4gIHB1YmxpYyBuZ09uQ2hhbmdlcygpOiB2b2lkIHtcclxuICAgIHRoaXMuZ3JvdXBzID0gbmV3IE1hcCgodGhpcy5yZXBvcnQ/LmZpbHRlckdyb3VwcyA/PyBbXSkubWFwKChncm91cCkgPT4gW2dyb3VwLmlkLCBncm91cF0pKTtcclxuXHJcbiAgICBjb25zdCBwYWdlQ291bnQgPSB0aGlzLnJlcG9ydD8ucGFnZXM/Lmxlbmd0aCA/PyAwO1xyXG5cclxuICAgIC8vIEEgcGFnZSB3YXMganVzdCBhZGRlZCAodGhlIGhvc3QgcmUtZmV0Y2hlZCB0aGUgcmVwb3J0KSDigJQgbGFuZCBvbiBpdC5cclxuICAgIGNvbnN0IHBhZ2VBZGRlZCA9IHBhZ2VDb3VudCA+IHRoaXMuX3ByZXZpb3VzUGFnZUNvdW50ICYmIHRoaXMuX3ByZXZpb3VzUGFnZUNvdW50ID4gMDtcclxuICAgIGlmIChwYWdlQWRkZWQpIHtcclxuICAgICAgdGhpcy5hY3RpdmVQYWdlSW5kZXggPSBwYWdlQ291bnQgLSAxO1xyXG4gICAgfVxyXG4gICAgdGhpcy5fcHJldmlvdXNQYWdlQ291bnQgPSBwYWdlQ291bnQ7XHJcblxyXG4gICAgLy8gSG9ub3VyIGFuIGluY29taW5nIGRlZXAgbGluaywgYnV0IG5ldmVyIG92ZXIgYSBqdXN0LWFkZGVkIHBhZ2U6IGFkZGluZyBhXHJcbiAgICAvLyBwYWdlIGlzIGEgZGVsaWJlcmF0ZSBhY3QgaW4gdGhpcyB0YWIsIHdoaWxlIHBhZ2VJZCBpcyB0aGUgc3RhbGUgdmFsdWUgdGhlXHJcbiAgICAvLyBob3N0IGlzIHN0aWxsIGhvbGRpbmcgZnJvbSB0aGUgVVJMLiBBbiBpZCB0aGF0IGRvZXMgbm90IHJlc29sdmUgaXMgbGVmdFxyXG4gICAgLy8gYWxvbmUgcmF0aGVyIHRoYW4gZm9yY2VkIHRvIHRoZSBmaXJzdCBwYWdlIOKAlCB0aGUgcmVwb3J0IG1heSBzdGlsbCBiZVxyXG4gICAgLy8gbG9hZGluZywgYW5kIHRoZSBjbGFtcCBiZWxvdyBpcyB0aGUgcmVhbCBndWFyZC5cclxuICAgIGlmICghcGFnZUFkZGVkICYmIHRoaXMucGFnZUlkICE9IG51bGwpIHtcclxuICAgICAgY29uc3QgaW5kZXggPSB0aGlzLnJlcG9ydD8ucGFnZXM/LmZpbmRJbmRleCgocGFnZSkgPT4gcGFnZS5pZCA9PT0gdGhpcy5wYWdlSWQpID8/IC0xO1xyXG5cclxuICAgICAgaWYgKGluZGV4ID4gLTEpIHtcclxuICAgICAgICB0aGlzLmFjdGl2ZVBhZ2VJbmRleCA9IGluZGV4O1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgaWYgKHRoaXMuYWN0aXZlUGFnZUluZGV4ID49IHBhZ2VDb3VudCkge1xyXG4gICAgICB0aGlzLmFjdGl2ZVBhZ2VJbmRleCA9IDA7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gVGVsbCB0aGUgaG9zdCB3aGljaCBwYWdlIGlzIG9wZW4gd2hlbmV2ZXIgdGhhdCBjaGFuZ2VzIOKAlCBpbmNsdWRpbmcgdGhlXHJcbiAgICAvLyBGSVJTVCB0aW1lIHRoZSByZXBvcnQgcmVuZGVycywgbm90IG9ubHkgd2hlbiBzb21lb25lIGNsaWNrcyBhIHBhZ2UuXHJcbiAgICAvLyBIb3N0cyBiaW5kIHRoaW5ncyB0byB0aGUgb3BlbiBwYWdlICh0aGUgcmVwb3J0IGNoYXQgc2NvcGVzIGl0c1xyXG4gICAgLy8gY29udmVyc2F0aW9ucyB0byBpdCksIGFuZCB3aXRob3V0IHRoaXMgdGhleSB3b3VsZCBzaXQgb24gbm8gcGFnZSBhdCBhbGxcclxuICAgIC8vIHVudGlsIHRoZSBmaXJzdCBtYW51YWwgcGFnZSBjbGljay5cclxuICAgIGNvbnN0IGFjdGl2ZVBhZ2VJZCA9IHRoaXMuYWN0aXZlUGFnZT8uaWQgPz8gbnVsbDtcclxuICAgIGlmIChhY3RpdmVQYWdlSWQgIT09IHRoaXMuX2VtaXR0ZWRQYWdlSWQpIHtcclxuICAgICAgdGhpcy5fZW1pdHRlZFBhZ2VJZCA9IGFjdGl2ZVBhZ2VJZDtcclxuICAgICAgdGhpcy5wYWdlQ2hhbmdlZC5lbWl0KGFjdGl2ZVBhZ2VJZCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvLyBSZXBvcnQgaGVhZGluZyBzaXplIGluIHB4IChjb25maWcgaXMgcG9pbnRzOyB0aGUgY2FudmFzIHJlbmRlcnMgYXRcclxuICAvLyA5NnB4L2luLCBzbyBwb2ludHMgw5cgOTYvNzIpLiBJbmhlcml0ZWQgYnkgY29tcG9uZW50IHRpdGxlcyB2aWEgYSBDU1MgdmFyLlxyXG4gIHB1YmxpYyBnZXQgaGVhZGluZ1NpemVQeCgpOiBudW1iZXIge1xyXG4gICAgY29uc3QgcG9pbnRzID0gdGhpcy5yZXBvcnQ/LmNvbmZpZz8uc3R5bGVzPy5oZWFkaW5nPy5zaXplID8/IERFRkFVTFRfSEVBRElOR19TSVpFO1xyXG5cclxuICAgIHJldHVybiBwb2ludHMgKiAoUFhfUEVSX0lOQ0ggLyA3Mik7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgbmdBZnRlclZpZXdJbml0KCk6IHZvaWQge1xyXG4gICAgLy8gRml0IHRoZSBwYWdlIHRvIHRoZSB2aWV3cG9ydCBvbmNlIG9uIGZpcnN0IHJlbmRlcjsgYWZ0ZXIgdGhhdCB0aGVcclxuICAgIC8vIHZpZXdlcidzIHpvb20gY2hvaWNlIGlzIHJlc3BlY3RlZCBhY3Jvc3MgcmUtcmVuZGVycy5cclxuICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy56b29tRml0KCkpO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldCBpc0Zsb3coKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5yZXBvcnQ/LmxheW91dCA9PT0gJ2Zsb3cnO1xyXG4gIH1cclxuXHJcbiAgcHVibGljIGdldCBhY3RpdmVQYWdlKCk6IFJlcG9ydFBhZ2UgfCBudWxsIHtcclxuICAgIHJldHVybiB0aGlzLnJlcG9ydD8ucGFnZXM/Llt0aGlzLmFjdGl2ZVBhZ2VJbmRleF0gPz8gbnVsbDtcclxuICB9XHJcblxyXG4gIC8vIEZsb3cgcmVuZGVyIG9yZGVyICh0aGUgYXNzZW1ibGVyIGFscmVhZHkgc29ydHMsIGJ1dCBhIGxvY2FsIHJlb3JkZXJcclxuICAvLyBtaWQtc2Vzc2lvbiBtdXN0IGhvbGQgd2l0aG91dCBhIHJlLWZldGNoKS5cclxuICBwdWJsaWMgZ2V0IGZsb3dDb21wb25lbnRzKCk6IFJlcG9ydENvbXBvbmVudFtdIHtcclxuICAgIHJldHVybiBbLi4uKHRoaXMuYWN0aXZlUGFnZT8uY29tcG9uZW50cyA/PyBbXSldLnNvcnQoKGEsIGIpID0+IGEub3JkZXIgLSBiLm9yZGVyKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBzZWxlY3RQYWdlKGluZGV4OiBudW1iZXIpOiB2b2lkIHtcclxuICAgIHRoaXMuYWN0aXZlUGFnZUluZGV4ID0gaW5kZXg7XHJcbiAgICB0aGlzLnNlbGVjdGVkQ29tcG9uZW50SWQgPSBudWxsO1xyXG5cclxuICAgIC8vIEtlcHQgaW4gc3RlcCB3aXRoIHRoZSBuZ09uQ2hhbmdlcyBhbm5vdW5jZW1lbnQgc28gdGhlIHR3byBjYW4ndCBkaXNhZ3JlZVxyXG4gICAgLy8gYWJvdXQgd2hhdCB0aGUgaG9zdCB3YXMgbGFzdCB0b2xkLlxyXG4gICAgdGhpcy5fZW1pdHRlZFBhZ2VJZCA9IHRoaXMuYWN0aXZlUGFnZT8uaWQgPz8gbnVsbDtcclxuICAgIHRoaXMucGFnZUNoYW5nZWQuZW1pdCh0aGlzLl9lbWl0dGVkUGFnZUlkKTtcclxuICB9XHJcblxyXG4gIC8vIEFwcGVuZCBhIGJsYW5rIHBhZ2U7IHRoZSBob3N0IHJlLWZldGNoZXMgdGhlIHJlcG9ydCBhbmQgbmdPbkNoYW5nZXMgbGFuZHNcclxuICAvLyB0aGUgdmlldyBvbiB0aGUgbmV3IChsYXN0KSBwYWdlLlxyXG4gIHB1YmxpYyBhZGRQYWdlKCk6IHZvaWQge1xyXG4gICAgaWYgKCF0aGlzLnJlcG9ydCkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5fcmVwb3J0RGF0YS5hZGRQYWdlKHRoaXMucmVwb3J0LmlkKVxyXG4gICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fZGVzdHJveVJlZikpXHJcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5yZXBvcnRDaGFuZ2VkLmVtaXQoKSk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgcGFnZUxhYmVsKHBhZ2U6IFJlcG9ydFBhZ2UsIGluZGV4OiBudW1iZXIpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIHBhZ2UubmFtZSB8fCBgUGFnZSAke2luZGV4ICsgMX1gO1xyXG4gIH1cclxuXHJcbiAgLy8gUmVuYW1lIGZyb20gdGhlIHRhYidzIGtlYmFiLiBUaGUgcGFnZSBsaXN0IGlzIHBhdGNoZWQgaW4gcGxhY2UgcmF0aGVyIHRoYW5cclxuICAvLyByZS1mZXRjaGluZyB0aGUgcmVwb3J0OiBub3RoaW5nIGVsc2Ugb24gdGhlIGNhbnZhcyBkZXBlbmRzIG9uIGEgcGFnZSdzXHJcbiAgLy8gbmFtZSwgYW5kIGEgcmUtZmV0Y2ggd291bGQgcmUtcnVuIGV2ZXJ5IGNvbXBvbmVudCdzIHF1ZXJ5IHRvIHJlcGFpbnQgYVxyXG4gIC8vIGNoaXAncyBsYWJlbC5cclxuICBwdWJsaWMgcmVuYW1lUGFnZShwYWdlOiBSZXBvcnRQYWdlKTogdm9pZCB7XHJcbiAgICB0aGlzLl9wcm9tcHQuaW5wdXQoe1xyXG4gICAgICB0aXRsZTogJ0VkaXQgUGFnZSBOYW1lJyxcclxuICAgICAgbGFiZWw6ICdOYW1lJyxcclxuICAgICAgZGVmYXVsdDogcGFnZS5uYW1lID8/ICcnLFxyXG4gICAgICBjb21taXRMYWJlbDogJ1NhdmUnLFxyXG4gICAgICByZXF1aXJlZDogdHJ1ZSxcclxuICAgIH0pXHJcbiAgICAgIC5waXBlKFxyXG4gICAgICAgIHN3aXRjaE1hcCgobmFtZTogc3RyaW5nKSA9PiB0aGlzLl9yZXBvcnREYXRhXHJcbiAgICAgICAgICAudXBkYXRlUGFnZSh0aGlzLnJlcG9ydC5pZCwgcGFnZS5pZCwgbmFtZSlcclxuICAgICAgICAgIC5waXBlKG1hcCgoKSA9PiBuYW1lKSkpLFxyXG4gICAgICAgIHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSxcclxuICAgICAgKVxyXG4gICAgICAuc3Vic2NyaWJlKChuYW1lOiBzdHJpbmcpID0+IHtcclxuICAgICAgICBwYWdlLm5hbWUgPSBuYW1lO1xyXG4gICAgICAgIHRoaXMuX21lc3NhZ2Uuc3VjY2VzcygnU2F2ZWQgcGFnZSBuYW1lJyk7XHJcbiAgICAgICAgdGhpcy5fY2RSZWYubWFya0ZvckNoZWNrKCk7XHJcbiAgICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgLy8gRGVsZXRlIGZyb20gdGhlIHRhYidzIGtlYmFiLiBUaGUgY29uZmlybSBuYW1lcyB0aGUgcGFnZSBhbmQgc2F5cyB0aGVcclxuICAvLyBjb21wb25lbnRzIGdvIHdpdGggaXQg4oCUIHRoZSBzZXJ2ZXIgcmVmdXNlcyB0aGUgbGFzdCBwYWdlLCBhbmQgdGhhdCByZWZ1c2FsXHJcbiAgLy8gc3VyZmFjZXMgYXMgdGhlIEFQSSBlcnJvciBtZXNzYWdlIHJhdGhlciB0aGFuIGJlaW5nIHNlY29uZC1ndWVzc2VkIGhlcmUuXHJcbiAgcHVibGljIGRlbGV0ZVBhZ2UocGFnZTogUmVwb3J0UGFnZSk6IHZvaWQge1xyXG4gICAgdGhpcy5fcHJvbXB0LmNvbmZpcm0oe1xyXG4gICAgICB0aXRsZTogJ0NvbmZpcm0nLFxyXG4gICAgICB0ZW1wbGF0ZTogYEFyZSB5b3Ugc3VyZSB5b3Ugd291bGQgbGlrZSB0byBkZWxldGUgXCIke3RoaXMucGFnZUxhYmVsKHBhZ2UsIHRoaXMucmVwb3J0LnBhZ2VzLmluZGV4T2YocGFnZSkpfVwiIGFuZCBldmVyeXRoaW5nIG9uIGl0P2AsXHJcbiAgICB9KVxyXG4gICAgICAucGlwZShcclxuICAgICAgICBzd2l0Y2hNYXAoKCkgPT4gdGhpcy5fcmVwb3J0RGF0YS5kZWxldGVQYWdlKHRoaXMucmVwb3J0LmlkLCBwYWdlLmlkKSksXHJcbiAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpLFxyXG4gICAgICApXHJcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5yZXBvcnQucGFnZXMuaW5kZXhPZihwYWdlKTtcclxuICAgICAgICB0aGlzLnJlcG9ydC5wYWdlcy5zcGxpY2UoaW5kZXgsIDEpO1xyXG5cclxuICAgICAgICAvLyBMYW5kIG9uIHRoZSBuZWlnaGJvdXIgcmF0aGVyIHRoYW4gc25hcHBpbmcgYmFjayB0byB0aGUgZmlyc3QgcGFnZSDigJRcclxuICAgICAgICAvLyBkZWxldGluZyBwYWdlIDQgb2YgNiBzaG91bGQgbGVhdmUgeW91IGxvb2tpbmcgYXQgd2hhdCBpcyBub3cgcGFnZSA0LlxyXG4gICAgICAgIHRoaXMuYWN0aXZlUGFnZUluZGV4ID0gTWF0aC5taW4oaW5kZXgsIHRoaXMucmVwb3J0LnBhZ2VzLmxlbmd0aCAtIDEpO1xyXG4gICAgICAgIHRoaXMuX3ByZXZpb3VzUGFnZUNvdW50ID0gdGhpcy5yZXBvcnQucGFnZXMubGVuZ3RoO1xyXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRDb21wb25lbnRJZCA9IG51bGw7XHJcblxyXG4gICAgICAgIC8vIFRoZSBpZCBpbiB0aGUgVVJMIGp1c3Qgc3RvcHBlZCBleGlzdGluZyDigJQgcmVwbGFjZSBpdCB3aXRoIHRoZVxyXG4gICAgICAgIC8vIG5laWdoYm91ciB3ZSBsYW5kZWQgb24sIG9yIGEgcmVmcmVzaCB3b3VsZCA0MDQgaXRzIHdheSB0byBwYWdlIG9uZS5cclxuICAgICAgICB0aGlzLnBhZ2VDaGFuZ2VkLmVtaXQodGhpcy5hY3RpdmVQYWdlPy5pZCA/PyBudWxsKTtcclxuXHJcbiAgICAgICAgdGhpcy5fbWVzc2FnZS5zdWNjZXNzKCdEZWxldGVkIHBhZ2UnKTtcclxuICAgICAgICB0aGlzLl9jZFJlZi5tYXJrRm9yQ2hlY2soKTtcclxuICAgICAgfSk7XHJcbiAgfVxyXG5cclxuICAvLyBBIHRhYiB3YXMgZHJhZ2dlZCB0byBhIG5ldyBzbG90OiByZW9yZGVyIGxvY2FsbHkgc28gdGhlIGNoaXBzIHNldHRsZVxyXG4gIC8vIGltbWVkaWF0ZWx5LCBrZWVwIHRoZSB2aWV3ZXIgb24gdGhlIHBhZ2UgdGhleSB3ZXJlIGxvb2tpbmcgYXQsIGFuZCBwZXJzaXN0XHJcbiAgLy8gdGhlIHdob2xlIHNlcXVlbmNlIGluIG9uZSBQVVQuXHJcbiAgcHVibGljIG9uUGFnZURyb3BwZWQoZXZlbnQ6IENka0RyYWdEcm9wPHVua25vd24+KTogdm9pZCB7XHJcbiAgICBpZiAoZXZlbnQucHJldmlvdXNJbmRleCA9PT0gZXZlbnQuY3VycmVudEluZGV4KSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBhY3RpdmVQYWdlID0gdGhpcy5hY3RpdmVQYWdlO1xyXG5cclxuICAgIG1vdmVJdGVtSW5BcnJheSh0aGlzLnJlcG9ydC5wYWdlcywgZXZlbnQucHJldmlvdXNJbmRleCwgZXZlbnQuY3VycmVudEluZGV4KTtcclxuXHJcbiAgICBjb25zdCBwb3NpdGlvbnMgPSB0aGlzLnJlcG9ydC5wYWdlcy5tYXAoKHBhZ2UsIG9yZGVyKSA9PiB7XHJcbiAgICAgIHBhZ2Uub3JkZXIgPSBvcmRlcjtcclxuXHJcbiAgICAgIHJldHVybiB7IHBhZ2VJZDogcGFnZS5pZCwgb3JkZXIgfTtcclxuICAgIH0pO1xyXG5cclxuICAgIHRoaXMuYWN0aXZlUGFnZUluZGV4ID0gYWN0aXZlUGFnZVxyXG4gICAgICA/IHRoaXMucmVwb3J0LnBhZ2VzLmluZGV4T2YoYWN0aXZlUGFnZSlcclxuICAgICAgOiB0aGlzLmFjdGl2ZVBhZ2VJbmRleDtcclxuXHJcbiAgICB0aGlzLl9yZXBvcnREYXRhLnNhdmVQYWdlUG9zaXRpb25zKHRoaXMucmVwb3J0LmlkLCBwb3NpdGlvbnMpXHJcbiAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSlcclxuICAgICAgLnN1YnNjcmliZSgpO1xyXG4gIH1cclxuXHJcbiAgLy8gSGFuZCBwcmVzZW50YXRpb24gc2V0dGluZ3MgKHRpdGxlLCBwYWRkaW5nKSBzYXZlZCBpbiB0aGUgc2V0dGluZ3MgZGlhbG9nIHRvXHJcbiAgLy8gdGhlIG9uZSBjb21wb25lbnQgdGhleSBiZWxvbmcgdG8uIE5vdGhpbmcgaGVyZSBmZWVkcyB0aGUgcXVlcnksIHNvIHRoYXRcclxuICAvLyBjb21wb25lbnQgcmVwYWludHMgYW5kIGV2ZXJ5IG90aGVyIG9uZSBvbiB0aGUgcGFnZSBpcyBsZWZ0IGFsb25lLlxyXG4gIHB1YmxpYyBhcHBseUNvbXBvbmVudFNldHRpbmdzKGNvbXBvbmVudElkOiBudW1iZXIsIHNldHRpbmdzOiBDb21wb25lbnRTZXR0aW5ncyk6IHZvaWQge1xyXG4gICAgdGhpcy5fcmVuZGVyZWRDb21wb25lbnRzXHJcbiAgICAgIC5maW5kKChyZW5kZXJlZCkgPT4gcmVuZGVyZWQuY29tcG9uZW50LmlkID09PSBjb21wb25lbnRJZClcclxuICAgICAgPy5hcHBseVNldHRpbmdzKHNldHRpbmdzKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBzZWxlY3RDb21wb25lbnQoY29tcG9uZW50SWQ6IG51bWJlciB8IG51bGwpOiB2b2lkIHtcclxuICAgIHRoaXMuc2VsZWN0ZWRDb21wb25lbnRJZCA9IGNvbXBvbmVudElkO1xyXG4gICAgdGhpcy5fY2RSZWYubWFya0ZvckNoZWNrKCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgb25DYW52YXNQb2ludGVyRG93bigpOiB2b2lkIHtcclxuICAgIC8vIEJhY2tncm91bmQgY2xpY2sgKHBhbiBzdGFydCkgZGVzZWxlY3RzLlxyXG4gICAgaWYgKHRoaXMuc2VsZWN0ZWRDb21wb25lbnRJZCAhPT0gbnVsbCkge1xyXG4gICAgICB0aGlzLnNlbGVjdENvbXBvbmVudChudWxsKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIC0tLS0tIHpvb20gdG9vbGJhciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cclxuXHJcbiAgcHVibGljIG9uWm9vbWVkKHNjYWxlOiBudW1iZXIpOiB2b2lkIHtcclxuICAgIHRoaXMuem9vbSA9IHNjYWxlO1xyXG4gICAgdGhpcy5fY2RSZWYubWFya0ZvckNoZWNrKCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgem9vbUluKCk6IHZvaWQge1xyXG4gICAgdGhpcy56b29tUGFuPy56b29tSW4oKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyB6b29tT3V0KCk6IHZvaWQge1xyXG4gICAgdGhpcy56b29tUGFuPy56b29tT3V0KCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgem9vbUZpdCgpOiB2b2lkIHtcclxuICAgIGNvbnN0IHZpZXdwb3J0ID0gdGhpcy5fdmlld3BvcnQ/Lm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICBpZiAoIXZpZXdwb3J0IHx8ICF0aGlzLnJlcG9ydD8ucGFnZVdpZHRoIHx8ICF0aGlzLnpvb21QYW4pIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGZpdCA9IE1hdGgubWluKFxyXG4gICAgICAodmlld3BvcnQuY2xpZW50V2lkdGggLSAzMikgLyAodGhpcy5yZXBvcnQucGFnZVdpZHRoICogUFhfUEVSX0lOQ0gpLFxyXG4gICAgICAodmlld3BvcnQuY2xpZW50SGVpZ2h0IC0gMzIpIC8gKHRoaXMucmVwb3J0LnBhZ2VIZWlnaHQgKiBQWF9QRVJfSU5DSCksXHJcbiAgICApO1xyXG5cclxuICAgIHRoaXMuem9vbVBhbi56b29tKE1hdGgubWluKDEuNSwgTWF0aC5tYXgoMC4xLCBmaXQpKSk7XHJcbiAgICB0aGlzLnpvb21QYW4ubW92ZSgxNiwgMTYpO1xyXG4gICAgdGhpcy5fZml0dGVkID0gdHJ1ZTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyB6b29tQWN0dWFsKCk6IHZvaWQge1xyXG4gICAgdGhpcy56b29tUGFuPy56b29tKDEpO1xyXG4gIH1cclxuXHJcbiAgLy8gLS0tLS0gcGVyc2lzdGVuY2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxyXG5cclxuICAvLyBBIGZyZWVmb3JtIGRyYWcvcmVzaXplIG9yIGEgZmxvdyB3aWR0aCByZXNpemUgbGFuZGVkIOKAlCBvbmUgUFVUIHBlciBnZXN0dXJlLlxyXG4gIHB1YmxpYyBvblBvc2l0aW9uQ2hhbmdlZChwb3NpdGlvbjogeyBjb21wb25lbnRJZDogbnVtYmVyIH0gJiBSZWNvcmQ8c3RyaW5nLCBudW1iZXI+KTogdm9pZCB7XHJcbiAgICB0aGlzLl9jbGVhckd1aWRlcygpO1xyXG4gICAgdGhpcy5fcmVwb3J0RGF0YS5zYXZlUG9zaXRpb25zKHRoaXMucmVwb3J0LmlkLCBbcG9zaXRpb24gYXMgYW55XSlcclxuICAgICAgLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpKVxyXG4gICAgICAuc3Vic2NyaWJlKCk7XHJcbiAgfVxyXG5cclxuICAvLyBBIGZsb3cgZHJhZyBkcm9wcGVkOiByZW9yZGVyIHRoZSBwYWdlJ3MgY29tcG9uZW50cyBhcm91bmQgdGhlIG1vdmVkIG9uZVxyXG4gIC8vIGFuZCBwZXJzaXN0IGV2ZXJ5IG9yZGVyIGluIG9uZSBQVVQuXHJcbiAgcHVibGljIG9uRmxvd1Jlb3JkZXIoZXZlbnQ6IHsgY29tcG9uZW50SWQ6IG51bWJlcjsgY2xpZW50WDogbnVtYmVyOyBjbGllbnRZOiBudW1iZXIgfSk6IHZvaWQge1xyXG4gICAgY29uc3QgcGFnZSA9IHRoaXMuYWN0aXZlUGFnZTtcclxuICAgIGlmICghcGFnZSkge1xyXG4gICAgICByZXR1cm47XHJcbiAgICB9XHJcblxyXG4gICAgY29uc3Qgb3JkZXJlZCA9IHRoaXMuZmxvd0NvbXBvbmVudHMuZmlsdGVyKChjb21wb25lbnQpID0+IGNvbXBvbmVudC5pZCAhPT0gZXZlbnQuY29tcG9uZW50SWQpO1xyXG4gICAgY29uc3QgbW92ZWQgPSBwYWdlLmNvbXBvbmVudHMuZmluZCgoY29tcG9uZW50KSA9PiBjb21wb25lbnQuaWQgPT09IGV2ZW50LmNvbXBvbmVudElkKTtcclxuICAgIGlmICghbW92ZWQpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5fZmxvd0Ryb3BJbmRleChvcmRlcmVkLCBldmVudC5jbGllbnRYLCBldmVudC5jbGllbnRZKTtcclxuICAgIG9yZGVyZWQuc3BsaWNlKGluZGV4LCAwLCBtb3ZlZCk7XHJcblxyXG4gICAgY29uc3QgcG9zaXRpb25zID0gb3JkZXJlZC5tYXAoKGNvbXBvbmVudCwgb3JkZXIpID0+IHtcclxuICAgICAgY29tcG9uZW50Lm9yZGVyID0gb3JkZXI7XHJcblxyXG4gICAgICByZXR1cm4geyBjb21wb25lbnRJZDogY29tcG9uZW50LmlkLCBvcmRlciB9O1xyXG4gICAgfSk7XHJcblxyXG4gICAgdGhpcy5fY2RSZWYubWFya0ZvckNoZWNrKCk7XHJcbiAgICB0aGlzLl9yZXBvcnREYXRhLnNhdmVQb3NpdGlvbnModGhpcy5yZXBvcnQuaWQsIHBvc2l0aW9ucylcclxuICAgICAgLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpKVxyXG4gICAgICAuc3Vic2NyaWJlKCk7XHJcbiAgfVxyXG5cclxuICAvLyBXaGVyZSB0aGUgcG9pbnRlciBsYW5kZWQgYW1vbmcgdGhlIGZsb3dlZCBjb21wb25lbnRzOiBiZWZvcmUgdGhlIGZpcnN0XHJcbiAgLy8gY29tcG9uZW50IHdob3NlIGNlbnRlciB0aGUgcG9pbnRlciBpcyBhYm92ZS9sZWZ0IG9mLlxyXG4gIHByaXZhdGUgX2Zsb3dEcm9wSW5kZXgob3JkZXJlZDogUmVwb3J0Q29tcG9uZW50W10sIGNsaWVudFg6IG51bWJlciwgY2xpZW50WTogbnVtYmVyKTogbnVtYmVyIHtcclxuICAgIGNvbnN0IGhvc3RzID0gQXJyYXkuZnJvbShcclxuICAgICAgdGhpcy5fdmlld3BvcnQubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yQWxsPEhUTUxFbGVtZW50PignYXBwLXJlcG9ydC1jb21wb25lbnQnKSxcclxuICAgICkuZmlsdGVyKChob3N0KSA9PiAhaG9zdC5jbGFzc0xpc3QuY29udGFpbnMoJ2Zsb3ctZHJhZ2dpbmcnKSk7XHJcblxyXG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGhvc3RzLmxlbmd0aCAmJiBpbmRleCA8IG9yZGVyZWQubGVuZ3RoOyBpbmRleCsrKSB7XHJcbiAgICAgIGNvbnN0IHJlY3QgPSBob3N0c1tpbmRleF0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgICAgIGlmIChjbGllbnRZIDwgcmVjdC50b3AgKyByZWN0LmhlaWdodCAvIDJcclxuICAgICAgICB8fCAoY2xpZW50WSA8IHJlY3QuYm90dG9tICYmIGNsaWVudFggPCByZWN0LmxlZnQgKyByZWN0LndpZHRoIC8gMikpIHtcclxuICAgICAgICByZXR1cm4gaW5kZXg7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gb3JkZXJlZC5sZW5ndGg7XHJcbiAgfVxyXG5cclxuICAvLyAtLS0tLSBzbWFydCBndWlkZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXHJcblxyXG4gIC8vIFBpeGVsIGZlZWwgb2YgdGhlIHNuYXAsIGNvbnZlcnRlZCB0byBpbmNoZXMgYXQgdGhlIGN1cnJlbnQgem9vbS5cclxuICBwcml2YXRlIGdldCBfc25hcFRocmVzaG9sZCgpOiBudW1iZXIge1xyXG4gICAgcmV0dXJuIDggLyAoUFhfUEVSX0lOQ0ggKiBNYXRoLm1heCgwLjEsIHRoaXMuem9vbSkpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfc25hcE1vdmUoY29tcG9uZW50OiBSZXBvcnRDb21wb25lbnQsIHg6IG51bWJlciwgeTogbnVtYmVyKTogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9IHtcclxuICAgIGNvbnN0IHsgdmVydGljYWwsIGhvcml6b250YWwgfSA9IHRoaXMuX2NhbmRpZGF0ZXMoY29tcG9uZW50KTtcclxuICAgIGNvbnN0IGd1aWRlczogR3VpZGVMaW5lW10gPSBbXTtcclxuXHJcbiAgICBjb25zdCBzbmFwcGVkWCA9IHRoaXMuX3NuYXBBeGlzKFxyXG4gICAgICBbXHJcbiAgICAgICAgeyBvZmZzZXQ6IDAsIHZhbHVlOiB4IH0sXHJcbiAgICAgICAgeyBvZmZzZXQ6IGNvbXBvbmVudC53IC8gMiwgdmFsdWU6IHggKyBjb21wb25lbnQudyAvIDIgfSxcclxuICAgICAgICB7IG9mZnNldDogY29tcG9uZW50LncsIHZhbHVlOiB4ICsgY29tcG9uZW50LncgfSxcclxuICAgICAgXSxcclxuICAgICAgdmVydGljYWwsXHJcbiAgICApO1xyXG4gICAgaWYgKHNuYXBwZWRYICE9PSBudWxsKSB7XHJcbiAgICAgIHggPSBzbmFwcGVkWC5iYXNlO1xyXG4gICAgICBndWlkZXMucHVzaCh7IG9yaWVudGF0aW9uOiAndicsIHBvc2l0aW9uOiBzbmFwcGVkWC5ndWlkZSB9KTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCBzbmFwcGVkWSA9IHRoaXMuX3NuYXBBeGlzKFxyXG4gICAgICBbXHJcbiAgICAgICAgeyBvZmZzZXQ6IDAsIHZhbHVlOiB5IH0sXHJcbiAgICAgICAgeyBvZmZzZXQ6IGNvbXBvbmVudC5oIC8gMiwgdmFsdWU6IHkgKyBjb21wb25lbnQuaCAvIDIgfSxcclxuICAgICAgICB7IG9mZnNldDogY29tcG9uZW50LmgsIHZhbHVlOiB5ICsgY29tcG9uZW50LmggfSxcclxuICAgICAgXSxcclxuICAgICAgaG9yaXpvbnRhbCxcclxuICAgICk7XHJcbiAgICBpZiAoc25hcHBlZFkgIT09IG51bGwpIHtcclxuICAgICAgeSA9IHNuYXBwZWRZLmJhc2U7XHJcbiAgICAgIGd1aWRlcy5wdXNoKHsgb3JpZW50YXRpb246ICdoJywgcG9zaXRpb246IHNuYXBwZWRZLmd1aWRlIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuX3JlbmRlckd1aWRlcyhndWlkZXMpO1xyXG5cclxuICAgIHJldHVybiB7IHgsIHkgfTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgX3NuYXBSZXNpemUoXHJcbiAgICBjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudCxcclxuICAgIGdlb21ldHJ5OiB7IHg6IG51bWJlcjsgeTogbnVtYmVyOyB3OiBudW1iZXI7IGg6IG51bWJlciB9LFxyXG4gICAgaGFuZGxlOiBzdHJpbmcsXHJcbiAgKTogeyB4OiBudW1iZXI7IHk6IG51bWJlcjsgdzogbnVtYmVyOyBoOiBudW1iZXIgfSB7XHJcbiAgICBjb25zdCB7IHZlcnRpY2FsLCBob3Jpem9udGFsIH0gPSB0aGlzLl9jYW5kaWRhdGVzKGNvbXBvbmVudCk7XHJcbiAgICBjb25zdCBndWlkZXM6IEd1aWRlTGluZVtdID0gW107XHJcbiAgICBjb25zdCByZXN1bHQgPSB7IC4uLmdlb21ldHJ5IH07XHJcblxyXG4gICAgLy8gT25seSB0aGUgZWRnZXMgdGhlIGhhbmRsZSBtb3ZlcyBwYXJ0aWNpcGF0ZSBpbiBzbmFwcGluZy5cclxuICAgIGlmIChoYW5kbGUuaW5jbHVkZXMoJ2UnKSkge1xyXG4gICAgICBjb25zdCBzbmFwcGVkID0gdGhpcy5fbmVhcmVzdChnZW9tZXRyeS54ICsgZ2VvbWV0cnkudywgdmVydGljYWwpO1xyXG4gICAgICBpZiAoc25hcHBlZCAhPT0gbnVsbCkge1xyXG4gICAgICAgIHJlc3VsdC53ID0gc25hcHBlZCAtIGdlb21ldHJ5Lng7XHJcbiAgICAgICAgZ3VpZGVzLnB1c2goeyBvcmllbnRhdGlvbjogJ3YnLCBwb3NpdGlvbjogc25hcHBlZCB9KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKGhhbmRsZS5pbmNsdWRlcygndycpKSB7XHJcbiAgICAgIGNvbnN0IHNuYXBwZWQgPSB0aGlzLl9uZWFyZXN0KGdlb21ldHJ5LngsIHZlcnRpY2FsKTtcclxuICAgICAgaWYgKHNuYXBwZWQgIT09IG51bGwpIHtcclxuICAgICAgICByZXN1bHQudyA9IGdlb21ldHJ5LnggKyBnZW9tZXRyeS53IC0gc25hcHBlZDtcclxuICAgICAgICByZXN1bHQueCA9IHNuYXBwZWQ7XHJcbiAgICAgICAgZ3VpZGVzLnB1c2goeyBvcmllbnRhdGlvbjogJ3YnLCBwb3NpdGlvbjogc25hcHBlZCB9KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgaWYgKGhhbmRsZS5pbmNsdWRlcygncycpKSB7XHJcbiAgICAgIGNvbnN0IHNuYXBwZWQgPSB0aGlzLl9uZWFyZXN0KGdlb21ldHJ5LnkgKyBnZW9tZXRyeS5oLCBob3Jpem9udGFsKTtcclxuICAgICAgaWYgKHNuYXBwZWQgIT09IG51bGwpIHtcclxuICAgICAgICByZXN1bHQuaCA9IHNuYXBwZWQgLSBnZW9tZXRyeS55O1xyXG4gICAgICAgIGd1aWRlcy5wdXNoKHsgb3JpZW50YXRpb246ICdoJywgcG9zaXRpb246IHNuYXBwZWQgfSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGlmIChoYW5kbGUuaW5jbHVkZXMoJ24nKSkge1xyXG4gICAgICBjb25zdCBzbmFwcGVkID0gdGhpcy5fbmVhcmVzdChnZW9tZXRyeS55LCBob3Jpem9udGFsKTtcclxuICAgICAgaWYgKHNuYXBwZWQgIT09IG51bGwpIHtcclxuICAgICAgICByZXN1bHQuaCA9IGdlb21ldHJ5LnkgKyBnZW9tZXRyeS5oIC0gc25hcHBlZDtcclxuICAgICAgICByZXN1bHQueSA9IHNuYXBwZWQ7XHJcbiAgICAgICAgZ3VpZGVzLnB1c2goeyBvcmllbnRhdGlvbjogJ2gnLCBwb3NpdGlvbjogc25hcHBlZCB9KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuX3JlbmRlckd1aWRlcyhndWlkZXMpO1xyXG5cclxuICAgIHJldHVybiByZXN1bHQ7XHJcbiAgfVxyXG5cclxuICAvLyBBbGlnbm1lbnQgY2FuZGlkYXRlczogdGhlIHBhZ2UncyBlZGdlcyArIGNlbnRlciwgYW5kIGV2ZXJ5IHNpYmxpbmcnc1xyXG4gIC8vIGVkZ2VzICsgY2VudGVycy5cclxuICBwcml2YXRlIF9jYW5kaWRhdGVzKG1vdmluZzogUmVwb3J0Q29tcG9uZW50KTogeyB2ZXJ0aWNhbDogbnVtYmVyW107IGhvcml6b250YWw6IG51bWJlcltdIH0ge1xyXG4gICAgY29uc3QgdmVydGljYWwgPSBbMCwgdGhpcy5yZXBvcnQucGFnZVdpZHRoIC8gMiwgdGhpcy5yZXBvcnQucGFnZVdpZHRoXTtcclxuICAgIGNvbnN0IGhvcml6b250YWwgPSBbMCwgdGhpcy5yZXBvcnQucGFnZUhlaWdodCAvIDIsIHRoaXMucmVwb3J0LnBhZ2VIZWlnaHRdO1xyXG5cclxuICAgIGZvciAoY29uc3QgY29tcG9uZW50IG9mIHRoaXMuYWN0aXZlUGFnZT8uY29tcG9uZW50cyA/PyBbXSkge1xyXG4gICAgICBpZiAoY29tcG9uZW50LmlkID09PSBtb3ZpbmcuaWQpIHtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmVydGljYWwucHVzaChjb21wb25lbnQueCwgY29tcG9uZW50LnggKyBjb21wb25lbnQudyAvIDIsIGNvbXBvbmVudC54ICsgY29tcG9uZW50LncpO1xyXG4gICAgICBob3Jpem9udGFsLnB1c2goY29tcG9uZW50LnksIGNvbXBvbmVudC55ICsgY29tcG9uZW50LmggLyAyLCBjb21wb25lbnQueSArIGNvbXBvbmVudC5oKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4geyB2ZXJ0aWNhbCwgaG9yaXpvbnRhbCB9O1xyXG4gIH1cclxuXHJcbiAgLy8gU25hcCBvbmUgYXhpczogb2YgdGhlIG1vdmluZyBib3gncyB0aHJlZSBsaW5lcyAoZWRnZS9jZW50ZXIvZWRnZSksIGZpbmRcclxuICAvLyB0aGUgY2xvc2VzdCBjYW5kaWRhdGUgd2l0aGluIHRocmVzaG9sZCBhbmQgcmV0dXJuIHRoZSBhZGp1c3RlZCBiYXNlXHJcbiAgLy8gY29vcmRpbmF0ZSBwbHVzIHRoZSBndWlkZSB0byBkcmF3LlxyXG4gIHByaXZhdGUgX3NuYXBBeGlzKFxyXG4gICAgbGluZXM6IHsgb2Zmc2V0OiBudW1iZXI7IHZhbHVlOiBudW1iZXIgfVtdLFxyXG4gICAgY2FuZGlkYXRlczogbnVtYmVyW10sXHJcbiAgKTogeyBiYXNlOiBudW1iZXI7IGd1aWRlOiBudW1iZXIgfSB8IG51bGwge1xyXG4gICAgbGV0IGJlc3Q6IHsgYmFzZTogbnVtYmVyOyBndWlkZTogbnVtYmVyOyBkaXN0YW5jZTogbnVtYmVyIH0gfCBudWxsID0gbnVsbDtcclxuXHJcbiAgICBmb3IgKGNvbnN0IGxpbmUgb2YgbGluZXMpIHtcclxuICAgICAgZm9yIChjb25zdCBjYW5kaWRhdGUgb2YgY2FuZGlkYXRlcykge1xyXG4gICAgICAgIGNvbnN0IGRpc3RhbmNlID0gTWF0aC5hYnMoY2FuZGlkYXRlIC0gbGluZS52YWx1ZSk7XHJcbiAgICAgICAgaWYgKGRpc3RhbmNlIDw9IHRoaXMuX3NuYXBUaHJlc2hvbGQgJiYgKCFiZXN0IHx8IGRpc3RhbmNlIDwgYmVzdC5kaXN0YW5jZSkpIHtcclxuICAgICAgICAgIGJlc3QgPSB7IGJhc2U6IGNhbmRpZGF0ZSAtIGxpbmUub2Zmc2V0LCBndWlkZTogY2FuZGlkYXRlLCBkaXN0YW5jZSB9O1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBiZXN0ID8geyBiYXNlOiBiZXN0LmJhc2UsIGd1aWRlOiBiZXN0Lmd1aWRlIH0gOiBudWxsO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfbmVhcmVzdCh2YWx1ZTogbnVtYmVyLCBjYW5kaWRhdGVzOiBudW1iZXJbXSk6IG51bWJlciB8IG51bGwge1xyXG4gICAgbGV0IGJlc3Q6IG51bWJlciB8IG51bGwgPSBudWxsO1xyXG4gICAgbGV0IGJlc3REaXN0YW5jZSA9IHRoaXMuX3NuYXBUaHJlc2hvbGQ7XHJcblxyXG4gICAgZm9yIChjb25zdCBjYW5kaWRhdGUgb2YgY2FuZGlkYXRlcykge1xyXG4gICAgICBjb25zdCBkaXN0YW5jZSA9IE1hdGguYWJzKGNhbmRpZGF0ZSAtIHZhbHVlKTtcclxuICAgICAgaWYgKGRpc3RhbmNlIDw9IGJlc3REaXN0YW5jZSkge1xyXG4gICAgICAgIGJlc3QgPSBjYW5kaWRhdGU7XHJcbiAgICAgICAgYmVzdERpc3RhbmNlID0gZGlzdGFuY2U7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gYmVzdDtcclxuICB9XHJcblxyXG4gIC8vIFRoZSBndWlkZXMgb3ZlcmxheSBpcyBkcmF3biBpbXBlcmF0aXZlbHkg4oCUIHRoZSBkcmFnIGxvb3AgcnVucyBvdXRzaWRlXHJcbiAgLy8gQW5ndWxhciBhbmQgcmVwYWludHMgb24gZXZlcnkgcG9pbnRlcm1vdmUuXHJcbiAgcHJpdmF0ZSBfcmVuZGVyR3VpZGVzKGd1aWRlczogR3VpZGVMaW5lW10pOiB2b2lkIHtcclxuICAgIGNvbnN0IGhvc3QgPSB0aGlzLl9ndWlkZXM/Lm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICBpZiAoIWhvc3QpIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIGhvc3QucmVwbGFjZUNoaWxkcmVuKC4uLmd1aWRlcy5tYXAoKGd1aWRlKSA9PiB7XHJcbiAgICAgIGNvbnN0IGxpbmUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcclxuICAgICAgbGluZS5jbGFzc05hbWUgPSBgZ3VpZGUgZ3VpZGUtJHtndWlkZS5vcmllbnRhdGlvbn1gO1xyXG4gICAgICBpZiAoZ3VpZGUub3JpZW50YXRpb24gPT09ICd2Jykge1xyXG4gICAgICAgIGxpbmUuc3R5bGUubGVmdCA9IGAke2d1aWRlLnBvc2l0aW9uICogUFhfUEVSX0lOQ0h9cHhgO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGxpbmUuc3R5bGUudG9wID0gYCR7Z3VpZGUucG9zaXRpb24gKiBQWF9QRVJfSU5DSH1weGA7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiBsaW5lO1xyXG4gICAgfSkpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBfY2xlYXJHdWlkZXMoKTogdm9pZCB7XHJcbiAgICB0aGlzLl9ndWlkZXM/Lm5hdGl2ZUVsZW1lbnQ/LnJlcGxhY2VDaGlsZHJlbigpO1xyXG4gIH1cclxufVxyXG4iLCI8ZGl2IGNsYXNzPVwiY2FudmFzXCI+XG4gIDxkaXZcbiAgICAjdmlld3BvcnRcbiAgICBjbGFzcz1cInBhZ2Utdmlld3BvcnRcIlxuICAgIChwb2ludGVyZG93bik9XCJvbkNhbnZhc1BvaW50ZXJEb3duKClcIj5cbiAgICA8ZnMtem9vbS1wYW5cbiAgICAgIFt6b29tTWluXT1cIjAuMVwiXG4gICAgICBbem9vbU1heF09XCIzXCJcbiAgICAgICh6b29tZWQpPVwib25ab29tZWQoJGV2ZW50KVwiPlxuICAgICAgQGlmIChhY3RpdmVQYWdlOyBhcyBwYWdlKSB7XG4gICAgICAgIDxkaXZcbiAgICAgICAgICBjbGFzcz1cInBhZ2VcIlxuICAgICAgICAgIFtjbGFzcy5mbG93XT1cImlzRmxvd1wiXG4gICAgICAgICAgW2NsYXNzLmVkaXRpbmddPVwiZWRpdE1vZGVcIlxuICAgICAgICAgIFtzdHlsZS53aWR0aC5weF09XCJyZXBvcnQucGFnZVdpZHRoICogUFhcIlxuICAgICAgICAgIFtzdHlsZS5oZWlnaHQucHhdPVwicmVwb3J0LnBhZ2VIZWlnaHQgKiBQWFwiXG4gICAgICAgICAgW3N0eWxlLnBhZGRpbmcucHhdPVwiaXNGbG93ID8gZmxvd1BhZGRpbmcgKiBQWCA6IDBcIlxuICAgICAgICAgIFtzdHlsZS4tLWNhbnZhcy16b29tXT1cInpvb21cIlxuICAgICAgICAgIFtzdHlsZS4tLXJlcG9ydC1oZWFkaW5nLXNpemUucHhdPVwiaGVhZGluZ1NpemVQeFwiPlxuICAgICAgICAgIEBpZiAoaXNGbG93KSB7XG4gICAgICAgICAgICBAZm9yIChjb21wb25lbnQgb2YgZmxvd0NvbXBvbmVudHM7IHRyYWNrIGNvbXBvbmVudC5pZCkge1xuICAgICAgICAgICAgICA8YXBwLXJlcG9ydC1jb21wb25lbnRcbiAgICAgICAgICAgICAgICBjbGFzcz1cImZsb3ctaXRlbVwiXG4gICAgICAgICAgICAgICAgW3JlcG9ydElkXT1cInJlcG9ydC5pZFwiXG4gICAgICAgICAgICAgICAgW2NvbXBvbmVudF09XCJjb21wb25lbnRcIlxuICAgICAgICAgICAgICAgIFtncm91cHNdPVwiZ3JvdXBzXCJcbiAgICAgICAgICAgICAgICBbZWRpdE1vZGVdPVwiZWRpdE1vZGVcIlxuICAgICAgICAgICAgICAgIFtsYXlvdXRdPVwiJ2Zsb3cnXCJcbiAgICAgICAgICAgICAgICBbem9vbV09XCJ6b29tXCJcbiAgICAgICAgICAgICAgICBbc25hcHBlcl09XCJzbmFwcGVyXCJcbiAgICAgICAgICAgICAgICBbc2VsZWN0ZWRdPVwiY29tcG9uZW50LmlkID09PSBzZWxlY3RlZENvbXBvbmVudElkXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGguJV09XCJjb21wb25lbnQuZmxvd1dpZHRoXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUuaGVpZ2h0LnB4XT1cImNvbXBvbmVudC5hdXRvSGVpZ2h0ID8gbnVsbCA6IGNvbXBvbmVudC5oICogUFhcIlxuICAgICAgICAgICAgICAgIChzZWxlY3RDb21wb25lbnQpPVwic2VsZWN0Q29tcG9uZW50KCRldmVudClcIlxuICAgICAgICAgICAgICAgIChwb3NpdGlvbkNoYW5nZWQpPVwib25Qb3NpdGlvbkNoYW5nZWQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgKGZsb3dSZW9yZGVyKT1cIm9uRmxvd1Jlb3JkZXIoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgKG9wZW5TZXR0aW5ncyk9XCJjb21wb25lbnRTZXR0aW5ncy5lbWl0KCRldmVudClcIj5cbiAgICAgICAgICAgICAgPC9hcHAtcmVwb3J0LWNvbXBvbmVudD5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IEBlbHNlIHtcbiAgICAgICAgICAgIEBmb3IgKGNvbXBvbmVudCBvZiBwYWdlLmNvbXBvbmVudHM7IHRyYWNrIGNvbXBvbmVudC5pZCkge1xuICAgICAgICAgICAgICA8YXBwLXJlcG9ydC1jb21wb25lbnRcbiAgICAgICAgICAgICAgICBbcmVwb3J0SWRdPVwicmVwb3J0LmlkXCJcbiAgICAgICAgICAgICAgICBbY29tcG9uZW50XT1cImNvbXBvbmVudFwiXG4gICAgICAgICAgICAgICAgW2dyb3Vwc109XCJncm91cHNcIlxuICAgICAgICAgICAgICAgIFtlZGl0TW9kZV09XCJlZGl0TW9kZVwiXG4gICAgICAgICAgICAgICAgW2xheW91dF09XCInZnJlZWZvcm0nXCJcbiAgICAgICAgICAgICAgICBbem9vbV09XCJ6b29tXCJcbiAgICAgICAgICAgICAgICBbc25hcHBlcl09XCJzbmFwcGVyXCJcbiAgICAgICAgICAgICAgICBbc2VsZWN0ZWRdPVwiY29tcG9uZW50LmlkID09PSBzZWxlY3RlZENvbXBvbmVudElkXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUubGVmdC5weF09XCJjb21wb25lbnQueCAqIFBYXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUudG9wLnB4XT1cImNvbXBvbmVudC55ICogUFhcIlxuICAgICAgICAgICAgICAgIFtzdHlsZS53aWR0aC5weF09XCJjb21wb25lbnQudyAqIFBYXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUuaGVpZ2h0LnB4XT1cImNvbXBvbmVudC5hdXRvSGVpZ2h0ID8gbnVsbCA6IGNvbXBvbmVudC5oICogUFhcIlxuICAgICAgICAgICAgICAgIChzZWxlY3RDb21wb25lbnQpPVwic2VsZWN0Q29tcG9uZW50KCRldmVudClcIlxuICAgICAgICAgICAgICAgIChwb3NpdGlvbkNoYW5nZWQpPVwib25Qb3NpdGlvbkNoYW5nZWQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgKG9wZW5TZXR0aW5ncyk9XCJjb21wb25lbnRTZXR0aW5ncy5lbWl0KCRldmVudClcIj5cbiAgICAgICAgICAgICAgPC9hcHAtcmVwb3J0LWNvbXBvbmVudD5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAjZ3VpZGVzXG4gICAgICAgICAgICBjbGFzcz1cImd1aWRlc1wiPlxuICAgICAgICAgIDwvZGl2PlxuXG4gICAgICAgICAgQGlmICghcGFnZS5jb21wb25lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInBhZ2UtZW1wdHlcIj5cbiAgICAgICAgICAgICAgQXNrIHRoZSBhc3Npc3RhbnQgdG8gYWRkIGEgY2hhcnQsIGxpc3Qgb3IgS1BJIHRvIHRoaXMgcGFnZS5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIH1cbiAgICAgICAgPC9kaXY+XG4gICAgICB9XG4gICAgPC9mcy16b29tLXBhbj5cblxuICAgIEBpZiAoZWRpdE1vZGUpIHtcbiAgICAgIDxidXR0b25cbiAgICAgICAgbWF0LWZsYXQtYnV0dG9uXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBjb2xvcj1cInByaW1hcnlcIlxuICAgICAgICBjbGFzcz1cImVkaXQtZG9uZVwiXG4gICAgICAgIG1hdFRvb2x0aXA9XCJFeGl0IGxheW91dCBlZGl0aW5nXCJcbiAgICAgICAgKGNsaWNrKT1cImVkaXREb25lLmVtaXQoKVwiPlxuICAgICAgICA8bWF0LWljb24+Y2hlY2s8L21hdC1pY29uPlxuICAgICAgICBEb25lIGVkaXRpbmdcbiAgICAgIDwvYnV0dG9uPlxuICAgIH1cbiAgPC9kaXY+XG5cbiAgPGRpdiBjbGFzcz1cImNhbnZhcy10b29sYmFyXCI+XG4gICAgPCEtLSBUYWJzIGFyZSBvbmUgaG9yaXpvbnRhbCBkcm9wIGxpc3Q6IGRyYWdnaW5nIGEgY2hpcCByZW9yZGVycyB0aGUgcGFnZXMuXG4gICAgICAgICBUaGUgZHJvcCBJTkRFWCBpcyBjb21wdXRlZCBhbG9uZyBYIChvcmllbnRhdGlvbiksIGJ1dCB0aGUgcHJldmlldyBpc1xuICAgICAgICAgZGVsaWJlcmF0ZWx5IGxlZnQgdW5ib3VuZGVkIG9uIGJvdGggYXhlcyDigJQgcGlubmluZyBpdCB0byB0aGUgcm93IHdpdGhcbiAgICAgICAgIGNka0RyYWdCb3VuZGFyeSBtZWFucyB0aGUgY2hpcCB5b3UgYXJlIGRyYWdnaW5nIGNvdmVycyB0aGUgY2hpcHMgeW91XG4gICAgICAgICBhcmUgZHJhZ2dpbmcgaXQgcGFzdCwgYW5kIHlvdSBjYW5ub3Qgc2VlIHdoZXJlIGl0IGlzIGdvaW5nIHRvIGxhbmQuXG4gICAgICAgICBFdmVyeSBwYWdlIGdldHMgYSBjaGlwLCBpbmNsdWRpbmcgYSBsb25lIG9uZTogdGhlIGNoaXAgaXMgd2hhdCB0ZWxsc1xuICAgICAgICAgeW91IHdoaWNoIHBhZ2UgeW91IGFyZSBvbiwgYW5kIGEgcmVwb3J0IHRoYXQgaGlkIGl0IGxlZnQgeW91IHVuYWJsZSB0b1xuICAgICAgICAgdGVsbCBwYWdlIDEgb2YgMSBmcm9tIGEgcGFnZSB0aGF0IGZhaWxlZCB0byBsb2FkLiBEZWxldGluZyB0aGUgbGFzdFxuICAgICAgICAgcGFnZSBpcyByZWZ1c2VkIHNlcnZlci1zaWRlLCBzbyB0aGUga2ViYWIgaXMgc2FmZSB0byBleHBvc2UgaGVyZS4gLS0+XG4gICAgPGRpdlxuICAgICAgY2xhc3M9XCJwYWdlLXRhYnNcIlxuICAgICAgY2RrRHJvcExpc3RcbiAgICAgIGNka0Ryb3BMaXN0T3JpZW50YXRpb249XCJob3Jpem9udGFsXCJcbiAgICAgIChjZGtEcm9wTGlzdERyb3BwZWQpPVwib25QYWdlRHJvcHBlZCgkZXZlbnQpXCI+XG4gICAgICBAZm9yIChwYWdlIG9mIHJlcG9ydD8ucGFnZXMgPz8gW107IHRyYWNrIHBhZ2UuaWQ7IGxldCBpbmRleCA9ICRpbmRleCkge1xuICAgICAgICA8IS0tIFRoZSBjaGlwIGlzIHRoZSBkcmFnIGhhbmRsZSBBTkQgdGhlIHRhYjogY2xpY2tpbmcgc2VsZWN0cyxcbiAgICAgICAgICAgICBkcmFnZ2luZyByZW9yZGVycy4gVGhlIGtlYmFiIGxpdmVzIGluc2lkZSBpdCwgc28gdGhlIHdob2xlXG4gICAgICAgICAgICAgY29udHJvbCBzdGF5cyBvbmUgY2hpcCBpbnN0ZWFkIG9mIGdyb3dpbmcgYSBzZWNvbmQgYnV0dG9uLiAtLT5cbiAgICAgICAgPGRpdlxuICAgICAgICAgIGNka0RyYWdcbiAgICAgICAgICBjbGFzcz1cInBhZ2UtdGFiXCJcbiAgICAgICAgICBbY2xhc3MuYWN0aXZlXT1cImluZGV4ID09PSBhY3RpdmVQYWdlSW5kZXhcIlxuICAgICAgICAgIChjbGljayk9XCJzZWxlY3RQYWdlKGluZGV4KVwiPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwicGFnZS10YWItbGFiZWxcIj57eyBwYWdlTGFiZWwocGFnZSwgaW5kZXgpIH19PC9zcGFuPlxuICAgICAgICAgIDwhLS0gVGhlIGtlYmFiIG9wZW5zIHRoZSBtZW51IHJhdGhlciB0aGFuIHN0YXJ0aW5nIGEgZHJhZyBvclxuICAgICAgICAgICAgICAgc3dpdGNoaW5nIHBhZ2VzLCBzbyBpdCBzd2FsbG93cyBpdHMgb3duIGNsaWNrLiAtLT5cbiAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgY2xhc3M9XCJwYWdlLXRhYi1tZW51XCJcbiAgICAgICAgICAgIFtmc01lbnVUcmlnZ2VyRm9yXT1cInBhZ2VNZW51XCJcbiAgICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgICAgICAgKG1vdXNlZG93bik9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIj5cbiAgICAgICAgICAgIDxtYXQtaWNvbj5tb3JlX3ZlcnQ8L21hdC1pY29uPlxuICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDwhLS0gT3V0c2lkZSB0aGUgY2hpcDogY2RrRHJhZyBjbG9uZXMgaXRzIGhvc3QgaW50byB0aGUgZHJhZyBwcmV2aWV3LFxuICAgICAgICAgICAgIGFuZCBhIG1lbnUgb3ZlcmxheSBhbmNob3JlZCB0byBhIGNsb25lZCB0cmlnZ2VyIG9wZW5zIGRldGFjaGVkXG4gICAgICAgICAgICAgZnJvbSB0aGUgcmVhbCB0YWIuIC0tPlxuICAgICAgICA8ZnMtbWVudSAjcGFnZU1lbnU+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICBmcy1tZW51LWl0ZW1cbiAgICAgICAgICAgIChjbGljayk9XCJyZW5hbWVQYWdlKHBhZ2UpXCI+XG4gICAgICAgICAgICBFZGl0IG5hbWVcbiAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgZnMtbWVudS1pdGVtXG4gICAgICAgICAgICAoY2xpY2spPVwiZGVsZXRlUGFnZShwYWdlKVwiPlxuICAgICAgICAgICAgRGVsZXRlXG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC9mcy1tZW51PlxuICAgICAgfVxuICAgICAgPGJ1dHRvblxuICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgY2xhc3M9XCJwYWdlLXRhYiBhZGQtcGFnZVwiXG4gICAgICAgIG1hdFRvb2x0aXA9XCJBZGQgcGFnZVwiXG4gICAgICAgIChjbGljayk9XCJhZGRQYWdlKClcIj5cbiAgICAgICAgPG1hdC1pY29uPmFkZDwvbWF0LWljb24+XG4gICAgICAgIFBhZ2VcbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuXG4gICAgPGRpdiBjbGFzcz1cInpvb20tY29udHJvbHNcIj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIGNsYXNzPVwiem9vbS1idXR0b25cIlxuICAgICAgICBtYXRUb29sdGlwPVwiWm9vbSBvdXRcIlxuICAgICAgICAoY2xpY2spPVwiem9vbU91dCgpXCI+XG4gICAgICAgIDxtYXQtaWNvbj5yZW1vdmU8L21hdC1pY29uPlxuICAgICAgPC9idXR0b24+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBjbGFzcz1cInpvb20tbGFiZWxcIlxuICAgICAgICBtYXRUb29sdGlwPVwiWm9vbSB0byAxMDAlXCJcbiAgICAgICAgKGNsaWNrKT1cInpvb21BY3R1YWwoKVwiPlxuICAgICAgICB7eyAoem9vbSAqIDEwMCkudG9GaXhlZCgwKSB9fSVcbiAgICAgIDwvYnV0dG9uPlxuICAgICAgPGJ1dHRvblxuICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgY2xhc3M9XCJ6b29tLWJ1dHRvblwiXG4gICAgICAgIG1hdFRvb2x0aXA9XCJab29tIGluXCJcbiAgICAgICAgKGNsaWNrKT1cInpvb21JbigpXCI+XG4gICAgICAgIDxtYXQtaWNvbj5hZGQ8L21hdC1pY29uPlxuICAgICAgPC9idXR0b24+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBjbGFzcz1cInpvb20tYnV0dG9uXCJcbiAgICAgICAgbWF0VG9vbHRpcD1cIkZpdCBwYWdlXCJcbiAgICAgICAgKGNsaWNrKT1cInpvb21GaXQoKVwiPlxuICAgICAgICA8bWF0LWljb24+Zml0X3NjcmVlbjwvbWF0LWljb24+XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==
589
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVwb3J0LWNhbnZhcy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL3JlcG9ydHMvY29tcG9uZW50cy9yZXBvcnQtY2FudmFzL3JlcG9ydC1jYW52YXMuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2FwcC9yZXBvcnRzL2NvbXBvbmVudHMvcmVwb3J0LWNhbnZhcy9yZXBvcnQtY2FudmFzLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFDVSx1QkFBdUIsRUFBRSxpQkFBaUIsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUNoRixVQUFVLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBYSxNQUFNLEVBQUUsU0FBUyxFQUFpQixTQUFTLEVBQUUsWUFBWSxFQUNyRyxNQUFNLEVBQUUsTUFBTSxHQUNmLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRWhFLE9BQU8sRUFBZSxjQUFjLEVBQUUsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDdEYsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ2pELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUV2RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsZUFBZSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFM0UsT0FBTyxFQUFFLEdBQUcsRUFBRSxTQUFTLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFdEMsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHdCQUF3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YSxFQUFFLGVBQWUsRUFBRSxDQUFDO0lBQ2pELENBQUM7d0dBNW9CVSxxQkFBcUI7NEZBQXJCLHFCQUFxQiw2U0FzQnJCLGtCQUFrQixtUUFLZix3QkFBd0IscUVDeEd4Qyw2K1JBd09BLHVxS0RuS0ksY0FBYyw2L0JBQ2QsT0FBTywySUFDUCxVQUFVLGdSQUNWLFlBQVksdVpBQ1osZUFBZSxtT0FDZix3QkFBd0I7OzRGQUdmLHFCQUFxQjtrQkFmakMsU0FBUzsrQkFDRSxtQkFBbUIsbUJBR1osdUJBQXVCLENBQUMsTUFBTSxjQUNuQyxJQUFJLFdBQ1A7d0JBQ1AsY0FBYzt3QkFDZCxPQUFPO3dCQUNQLFVBQVU7d0JBQ1YsWUFBWTt3QkFDWixlQUFlO3dCQUNmLHdCQUF3QjtxQkFDekI7OEJBSWUsTUFBTTtzQkFBckIsS0FBSztnQkFDVSxRQUFRO3NCQUF2QixLQUFLO2dCQUtVLE1BQU07c0JBQXJCLEtBQUs7Z0JBSVcsaUJBQWlCO3NCQUFqQyxNQUFNO2dCQUlVLGFBQWE7c0JBQTdCLE1BQU07Z0JBSVUsV0FBVztzQkFBM0IsTUFBTTtnQkFHQSxPQUFPO3NCQURiLFNBQVM7dUJBQUMsa0JBQWtCO2dCQU1yQixtQkFBbUI7c0JBRDFCLFlBQVk7dUJBQUMsd0JBQXdCO2dCQUk5QixTQUFTO3NCQURoQixTQUFTO3VCQUFDLFVBQVUsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBSS9CLE9BQU87c0JBRGQsU0FBUzt1QkFBQyxRQUFRLEVBQUUsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCwgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIERlc3Ryb3lSZWYsXG4gIEVsZW1lbnRSZWYsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE9uQ2hhbmdlcywgT3V0cHV0LCBRdWVyeUxpc3QsIFNpbXBsZUNoYW5nZXMsIFZpZXdDaGlsZCwgVmlld0NoaWxkcmVuLFxuICBpbmplY3QsIHNpZ25hbCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyB0YWtlVW50aWxEZXN0cm95ZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5cbmltcG9ydCB7IENka0RyYWdEcm9wLCBEcmFnRHJvcE1vZHVsZSwgbW92ZUl0ZW1JbkFycmF5IH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2RyYWctZHJvcCc7XG5pbXBvcnQgeyBNYXRJY29uIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaWNvbic7XG5pbXBvcnQgeyBNYXRUb29sdGlwIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvdG9vbHRpcCc7XG5cbmltcG9ydCB7IEZzTWVudU1vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL21lbnUnO1xuaW1wb3J0IHsgRnNNZXNzYWdlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvbWVzc2FnZSc7XG5pbXBvcnQgeyBGc1Byb21wdCB9IGZyb20gJ0BmaXJlc3RpdGNoL3Byb21wdCc7XG5pbXBvcnQgeyBGc1pvb21QYW5Db21wb25lbnQsIEZzWm9vbVBhbk1vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL3pvb20tcGFuJztcblxuaW1wb3J0IHsgbWFwLCBzd2l0Y2hNYXAgfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgUmVwb3J0RGF0YSB9IGZyb20gJy4uLy4uL2RhdGEvcmVwb3J0LmRhdGEnO1xuaW1wb3J0IHtcbiAgQ29tcG9uZW50U2V0dGluZ3MsIFJlcG9ydCwgUmVwb3J0Q29tcG9uZW50LCBSZXBvcnRGaWx0ZXJHcm91cCwgUmVwb3J0SGVhZGVyRm9vdGVyLCBSZXBvcnRQYWdlLFxufSBmcm9tICcuLi8uLi9pbnRlcmZhY2VzL3JlcG9ydC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgREVGQVVMVF9IRUFESU5HX1NJWkUsIEZMT1dfUEFERElORyB9IGZyb20gJy4uLy4uL2xheW91dCc7XG5pbXBvcnQgeyBUZXh0VG9rZW5Db250ZXh0IH0gZnJvbSAnLi4vLi4vdGV4dCc7XG5pbXBvcnQgeyBSZXBvcnRDb21wb25lbnRDb21wb25lbnQgfSBmcm9tICcuLi9yZXBvcnQtY29tcG9uZW50L3JlcG9ydC1jb21wb25lbnQuY29tcG9uZW50JztcblxuXG4vLyBTY3JlZW4gZGVuc2l0eSBvZiB0aGUgY2FudmFzOiA5NiBDU1MgcHggcGVyIGluY2ggKHRoZSBDU1MgcmVmZXJlbmNlIHBpeGVsKSxcbi8vIGJlZm9yZSB6b29tLiBBbGwgZ2VvbWV0cnkgc3RheXMgaW4gaW5jaGVzOyBvbmx5IHJlbmRlcmluZyBtdWx0aXBsaWVzIGJ5IGl0LlxuZXhwb3J0IGNvbnN0IFBYX1BFUl9JTkNIID0gOTY7XG5cbi8vIE9uZSBzbWFydCBndWlkZSBsaW5lLCBpbiBwYWdlIGluY2hlcy5cbmV4cG9ydCBpbnRlcmZhY2UgR3VpZGVMaW5lIHtcbiAgb3JpZW50YXRpb246ICd2JyB8ICdoJztcbiAgcG9zaXRpb246IG51bWJlcjtcbn1cblxuLy8gVGhlIHNuYXBwaW5nIGNvbnRyYWN0IGhhbmRlZCB0byBlYWNoIGNvbXBvbmVudCdzIGRyYWcgbG9vcC4gSW1wbGVtZW50ZWQgYnlcbi8vIHRoZSBjYW52YXMgYmVjYXVzZSBvbmx5IGl0IHNlZXMgZXZlcnkgY29tcG9uZW50IChhbGlnbm1lbnQgY2FuZGlkYXRlcykgYW5kXG4vLyBvd25zIHRoZSBndWlkZXMgb3ZlcmxheS5cbmV4cG9ydCBpbnRlcmZhY2UgQ2FudmFzU25hcHBlciB7XG4gIHNuYXBNb3ZlKGNvbXBvbmVudDogUmVwb3J0Q29tcG9uZW50LCB4OiBudW1iZXIsIHk6IG51bWJlcik6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfTtcbiAgc25hcFJlc2l6ZShjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudCwgZ2VvbWV0cnk6IHsgeDogbnVtYmVyOyB5OiBudW1iZXI7IHc6IG51bWJlcjsgaDogbnVtYmVyIH0sIGhhbmRsZTogc3RyaW5nKTogeyB4OiBudW1iZXI7IHk6IG51bWJlcjsgdzogbnVtYmVyOyBoOiBudW1iZXIgfTtcbiAgY2xlYXIoKTogdm9pZDtcbn1cblxuLy8gVGhlIGZpeGVkLXNpemUgcGFnZSBjYW52YXMg4oCUIHRoZSBQb3dlclBvaW50IG1vZGVsLiBQYWdlcyBhcmUgdGFicyAob25seSB0aGVcbi8vIEFDVElWRSBwYWdlJ3MgY29tcG9uZW50cyBleGlzdCDihpIgb25seSB0aGV5IGZldGNoKTsgdGhlIHBhZ2UgaXMgYVxuLy8gcGFnZVdpZHRow5dwYWdlSGVpZ2h0IElOQ0hFUyBzaGVldCByZW5kZXJlZCBhdCA5NnB4L2luIGluc2lkZSBmcy16b29tLXBhblxuLy8gKHdoZWVsIHpvb20sIGJhY2tncm91bmQgZHJhZyBwYW4sIHRvb2xiYXIgYnV0dG9ucykuXG4vL1xuLy8gRnJlZWZvcm0gbGF5b3V0OiBjb21wb25lbnRzIGFyZSBhYnNvbHV0ZWx5IHBvc2l0aW9uZWQ7IGRyYWdnaW5nIGdldHMgc21hcnRcbi8vIGFsaWdubWVudCBndWlkZXMgKGVkZ2VzICsgY2VudGVycyBvZiBzaWJsaW5ncyBhbmQgdGhlIHBhZ2UpIHdpdGggc25hcHBpbmcuXG4vLyBGbG93IGxheW91dDogY29tcG9uZW50cyBmbG93IGludG8gcm93cyAoZmxvd1dpZHRoICUgb2YgdGhlIGNvbnRlbnQgd2lkdGgpLFxuLy8gZHJhZyByZW9yZGVycywgZWFzdC9zb3V0aCBoYW5kbGVzIHJlc2l6ZSB3aWR0aCUvaGVpZ2h0LlxuLy9cbi8vIEhlYWRlciBhbmQgZm9vdGVyOiB0aGUgcmVwb3J0J3MgbWFzdGVyIGNvbXBvbmVudHMgKHJlcG9ydC5tYXN0ZXIpIGFyZSBkcmF3blxuLy8gb24gYSBsYXllciBVTkRFUiBldmVyeSBwYWdlJ3Mgb3duIGNvbXBvbmVudHMsIGxpa2UgYSBQb3dlclBvaW50IHNsaWRlIG1hc3Rlcixcbi8vIHVubGVzcyB0aGUgcGFnZSBoaWRlcyB0aGVtLiBJbiBlZGl0IG1vZGUgdGhlIGhvc3QgdG9vbGJhcidzIFwiSGVhZGVyICYgZm9vdGVyXCJcbi8vICh0b2dnbGVNYXN0ZXJNb2RlKSBzd2l0Y2hlcyB3aGljaCBsYXllciBpcyBsaXZlOiB0aGUgcGFnZSdzIGNvbXBvbmVudHMgZGltXG4vLyBhbmQgdGhlIG1hc3RlcidzIGJlY29tZSB0aGUgb25lcyB0aGF0IGRyYWcsIHJlc2l6ZSBhbmQgc25hcC4gVGhlIGhlYWRlci9mb290ZXIgYmFuZHMgKGNvbmZpZy5oZWFkZXJGb290ZXIpXG4vLyBhcmUgZHJhd24gYXMgZ3VpZGVzIHdoaWxlIGVkaXRpbmcgYW5kIGFyZSBzbmFwIGxpbmVzIGZvciBib3RoIGxheWVycy5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ2FwcC1yZXBvcnQtY2FudmFzJyxcbiAgdGVtcGxhdGVVcmw6ICcuL3JlcG9ydC1jYW52YXMuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9yZXBvcnQtY2FudmFzLmNvbXBvbmVudC5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgRHJhZ0Ryb3BNb2R1bGUsXG4gICAgTWF0SWNvbixcbiAgICBNYXRUb29sdGlwLFxuICAgIEZzTWVudU1vZHVsZSxcbiAgICBGc1pvb21QYW5Nb2R1bGUsXG4gICAgUmVwb3J0Q29tcG9uZW50Q29tcG9uZW50LFxuICBdLFxufSlcbmV4cG9ydCBjbGFzcyBSZXBvcnRDYW52YXNDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMsIEFmdGVyVmlld0luaXQge1xuXG4gIEBJbnB1dCgpIHB1YmxpYyByZXBvcnQ6IFJlcG9ydDtcbiAgQElucHV0KCkgcHVibGljIGVkaXRNb2RlID0gZmFsc2U7XG5cbiAgLy8gVGhlIHBhZ2UgdGhlIGhvc3Qgd2FudHMgb24gc2NyZWVuLCBieSBwYWdlIGlkIChhIGRlZXAgbGluaykuIEtleWVkIG9uIGlkXG4gIC8vIHJhdGhlciB0aGFuIGluZGV4IHNvIGEgbGluayBzdXJ2aXZlcyBwYWdlcyBiZWluZyByZW9yZGVyZWQgb3IgZGVsZXRlZDsgYW5cbiAgLy8gaWQgdGhhdCBubyBsb25nZXIgcmVzb2x2ZXMgZmFsbHMgYmFjayB0byB0aGUgZmlyc3QgcGFnZS5cbiAgQElucHV0KCkgcHVibGljIHBhZ2VJZDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG5cbiAgLy8gQSBjb21wb25lbnQgYXNrZWQgZm9yIGl0cyBzZXR0aW5ncyBkaWFsb2cg4oCUIHRoZSBwYWdlLWxldmVsIGhvc3Qgb3BlbnMgaXRcbiAgLy8gKGl0IG93bnMgTWF0RGlhbG9nICsgdGhlIHBvc3Qtc2F2ZSByZWxvYWQpLlxuICBAT3V0cHV0KCkgcHVibGljIGNvbXBvbmVudFNldHRpbmdzID0gbmV3IEV2ZW50RW1pdHRlcjxSZXBvcnRDb21wb25lbnQ+KCk7XG5cbiAgLy8gVGhlIHJlcG9ydCdzIHN0cnVjdHVyZSBjaGFuZ2VkIGhlcmUgKGEgcGFnZSB3YXMgYWRkZWQpIOKAlCB0aGUgaG9zdCByZS1mZXRjaGVzXG4gIC8vIGl0IChpdCBvd25zIHRoZSBhc3NlbWJsZWQgcmVwb3J0ICsgZmlsdGVyIHN0YXRlKS5cbiAgQE91dHB1dCgpIHB1YmxpYyByZXBvcnRDaGFuZ2VkID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIC8vIFRoZSBwYWdlIG9uIHNjcmVlbiBjaGFuZ2VkIOKAlCB0aGUgaG9zdCByZWZsZWN0cyBpdCBpbiB0aGUgVVJMIHNvIGEgcmVmcmVzaFxuICAvLyBjb21lcyBiYWNrIHRvIHRoZSBzYW1lIHBhZ2UuIENhcnJpZXMgdGhlIHBhZ2UgaWQsIG5ldmVyIHRoZSBpbmRleC5cbiAgQE91dHB1dCgpIHB1YmxpYyBwYWdlQ2hhbmdlZCA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyIHwgbnVsbD4oKTtcblxuICBAVmlld0NoaWxkKEZzWm9vbVBhbkNvbXBvbmVudClcbiAgcHVibGljIHpvb21QYW46IEZzWm9vbVBhbkNvbXBvbmVudDtcblxuICAvLyBUaGUgcmVuZGVyZWQgY29tcG9uZW50cyBvZiB0aGUgYWN0aXZlIHBhZ2Ug4oCUIG9ubHkgdGhlIGNhbnZhcyBjYW4gcmVhY2ggdGhlXG4gIC8vIG9uZSBpbnN0YW5jZSBhIHNldHRpbmdzIHNhdmUgYXBwbGllcyB0by5cbiAgQFZpZXdDaGlsZHJlbihSZXBvcnRDb21wb25lbnRDb21wb25lbnQpXG4gIHByaXZhdGUgX3JlbmRlcmVkQ29tcG9uZW50czogUXVlcnlMaXN0PFJlcG9ydENvbXBvbmVudENvbXBvbmVudD47XG5cbiAgQFZpZXdDaGlsZCgndmlld3BvcnQnLCB7IHN0YXRpYzogdHJ1ZSB9KVxuICBwcml2YXRlIF92aWV3cG9ydDogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD47XG5cbiAgQFZpZXdDaGlsZCgnZ3VpZGVzJywgeyBzdGF0aWM6IGZhbHNlIH0pXG4gIHByaXZhdGUgX2d1aWRlczogRWxlbWVudFJlZjxIVE1MRGl2RWxlbWVudD47XG5cbiAgcHVibGljIHJlYWRvbmx5IFBYID0gUFhfUEVSX0lOQ0g7XG4gIHB1YmxpYyByZWFkb25seSBmbG93UGFkZGluZyA9IEZMT1dfUEFERElORztcblxuICBwdWJsaWMgYWN0aXZlUGFnZUluZGV4ID0gMDtcbiAgcHVibGljIHpvb20gPSAxO1xuXG4gIC8vIEVkaXRpbmcgdGhlIGhlYWRlciBhbmQgZm9vdGVyICh0aGUgbWFzdGVyIGxheWVyKSByYXRoZXIgdGhhbiB0aGUgcGFnZS5cbiAgcHVibGljIHJlYWRvbmx5IG1hc3Rlck1vZGUgPSBzaWduYWwoZmFsc2UpO1xuICBwdWJsaWMgZ3JvdXBzID0gbmV3IE1hcDxudW1iZXIsIFJlcG9ydEZpbHRlckdyb3VwPigpO1xuICBwdWJsaWMgc2VsZWN0ZWRDb21wb25lbnRJZDogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG5cbiAgLy8gVGhlIHNuYXBwZXIgaGFuZGVkIHRvIGV2ZXJ5IGNvbXBvbmVudCAoc3RhYmxlIGlkZW50aXR5IGZvciBPblB1c2gpLlxuICBwdWJsaWMgcmVhZG9ubHkgc25hcHBlcjogQ2FudmFzU25hcHBlciA9IHtcbiAgICBzbmFwTW92ZTogKGNvbXBvbmVudCwgeCwgeSkgPT4gdGhpcy5fc25hcE1vdmUoY29tcG9uZW50LCB4LCB5KSxcbiAgICBzbmFwUmVzaXplOiAoY29tcG9uZW50LCBnZW9tZXRyeSwgaGFuZGxlKSA9PiB0aGlzLl9zbmFwUmVzaXplKGNvbXBvbmVudCwgZ2VvbWV0cnksIGhhbmRsZSksXG4gICAgY2xlYXI6ICgpID0+IHRoaXMuX2NsZWFyR3VpZGVzKCksXG4gIH07XG5cbiAgcHJpdmF0ZSBfcmVwb3J0RGF0YSA9IGluamVjdChSZXBvcnREYXRhKTtcbiAgcHJpdmF0ZSBfcHJvbXB0ID0gaW5qZWN0KEZzUHJvbXB0KTtcbiAgcHJpdmF0ZSBfbWVzc2FnZSA9IGluamVjdChGc01lc3NhZ2UpO1xuICBwcml2YXRlIF9jZFJlZiA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG4gIHByaXZhdGUgX2Rlc3Ryb3lSZWYgPSBpbmplY3QoRGVzdHJveVJlZik7XG4gIHByaXZhdGUgX2ZpdHRlZCA9IGZhbHNlO1xuICBwcml2YXRlIF90b2tlbnM6IFRleHRUb2tlbkNvbnRleHQgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBfcHJldmlvdXNQYWdlQ291bnQgPSAwO1xuXG4gIC8vIFRoZSBwYWdlIGlkIGxhc3QgYW5ub3VuY2VkIHRocm91Z2ggcGFnZUNoYW5nZWQsIHNvIGEgcmUtcmVuZGVyIHRoYXQgbGFuZHMgb25cbiAgLy8gdGhlIHNhbWUgcGFnZSBzdGF5cyBxdWlldCDigJQgaG9zdHMgcmVsb2FkIG9uIHRoaXMgYW5kIGFuIHVuY2hhbmdlZCBwYWdlIGlzXG4gIC8vIG5vdCBuZXdzLlxuICBwcml2YXRlIF9lbWl0dGVkUGFnZUlkOiBudW1iZXIgfCBudWxsID0gbnVsbDtcblxuICBwdWJsaWMgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIC8vIExlYXZpbmcgZWRpdCBtb2RlIGFsd2F5cyByZXR1cm5zIHRvIHRoZSBwYWdlIGxheWVyLCBzbyB0aGUgbmV4dCBlZGl0XG4gICAgLy8gc2Vzc2lvbiBzdGFydHMgd2hlcmUgcGVvcGxlIGV4cGVjdC5cbiAgICBpZiAoY2hhbmdlcy5lZGl0TW9kZSAmJiAhdGhpcy5lZGl0TW9kZSkge1xuICAgICAgdGhpcy5tYXN0ZXJNb2RlLnNldChmYWxzZSk7XG4gICAgfVxuXG4gICAgdGhpcy5ncm91cHMgPSBuZXcgTWFwKCh0aGlzLnJlcG9ydD8uZmlsdGVyR3JvdXBzID8/IFtdKS5tYXAoKGdyb3VwKSA9PiBbZ3JvdXAuaWQsIGdyb3VwXSkpO1xuXG4gICAgY29uc3QgcGFnZUNvdW50ID0gdGhpcy5yZXBvcnQ/LnBhZ2VzPy5sZW5ndGggPz8gMDtcblxuICAgIC8vIEEgcGFnZSB3YXMganVzdCBhZGRlZCAodGhlIGhvc3QgcmUtZmV0Y2hlZCB0aGUgcmVwb3J0KSDigJQgbGFuZCBvbiBpdC5cbiAgICBjb25zdCBwYWdlQWRkZWQgPSBwYWdlQ291bnQgPiB0aGlzLl9wcmV2aW91c1BhZ2VDb3VudCAmJiB0aGlzLl9wcmV2aW91c1BhZ2VDb3VudCA+IDA7XG4gICAgaWYgKHBhZ2VBZGRlZCkge1xuICAgICAgdGhpcy5hY3RpdmVQYWdlSW5kZXggPSBwYWdlQ291bnQgLSAxO1xuICAgIH1cbiAgICB0aGlzLl9wcmV2aW91c1BhZ2VDb3VudCA9IHBhZ2VDb3VudDtcblxuICAgIC8vIEhvbm91ciBhbiBpbmNvbWluZyBkZWVwIGxpbmssIGJ1dCBuZXZlciBvdmVyIGEganVzdC1hZGRlZCBwYWdlOiBhZGRpbmcgYVxuICAgIC8vIHBhZ2UgaXMgYSBkZWxpYmVyYXRlIGFjdCBpbiB0aGlzIHRhYiwgd2hpbGUgcGFnZUlkIGlzIHRoZSBzdGFsZSB2YWx1ZSB0aGVcbiAgICAvLyBob3N0IGlzIHN0aWxsIGhvbGRpbmcgZnJvbSB0aGUgVVJMLiBBbiBpZCB0aGF0IGRvZXMgbm90IHJlc29sdmUgaXMgbGVmdFxuICAgIC8vIGFsb25lIHJhdGhlciB0aGFuIGZvcmNlZCB0byB0aGUgZmlyc3QgcGFnZSDigJQgdGhlIHJlcG9ydCBtYXkgc3RpbGwgYmVcbiAgICAvLyBsb2FkaW5nLCBhbmQgdGhlIGNsYW1wIGJlbG93IGlzIHRoZSByZWFsIGd1YXJkLlxuICAgIGlmICghcGFnZUFkZGVkICYmIHRoaXMucGFnZUlkICE9IG51bGwpIHtcbiAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5yZXBvcnQ/LnBhZ2VzPy5maW5kSW5kZXgoKHBhZ2UpID0+IHBhZ2UuaWQgPT09IHRoaXMucGFnZUlkKSA/PyAtMTtcblxuICAgICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgICAgdGhpcy5hY3RpdmVQYWdlSW5kZXggPSBpbmRleDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5hY3RpdmVQYWdlSW5kZXggPj0gcGFnZUNvdW50KSB7XG4gICAgICB0aGlzLmFjdGl2ZVBhZ2VJbmRleCA9IDA7XG4gICAgfVxuXG4gICAgLy8gVGVsbCB0aGUgaG9zdCB3aGljaCBwYWdlIGlzIG9wZW4gd2hlbmV2ZXIgdGhhdCBjaGFuZ2VzIOKAlCBpbmNsdWRpbmcgdGhlXG4gICAgLy8gRklSU1QgdGltZSB0aGUgcmVwb3J0IHJlbmRlcnMsIG5vdCBvbmx5IHdoZW4gc29tZW9uZSBjbGlja3MgYSBwYWdlLlxuICAgIC8vIEhvc3RzIGJpbmQgdGhpbmdzIHRvIHRoZSBvcGVuIHBhZ2UgKHRoZSByZXBvcnQgY2hhdCBzY29wZXMgaXRzXG4gICAgLy8gY29udmVyc2F0aW9ucyB0byBpdCksIGFuZCB3aXRob3V0IHRoaXMgdGhleSB3b3VsZCBzaXQgb24gbm8gcGFnZSBhdCBhbGxcbiAgICAvLyB1bnRpbCB0aGUgZmlyc3QgbWFudWFsIHBhZ2UgY2xpY2suXG4gICAgY29uc3QgYWN0aXZlUGFnZUlkID0gdGhpcy5hY3RpdmVQYWdlPy5pZCA/PyBudWxsO1xuICAgIGlmIChhY3RpdmVQYWdlSWQgIT09IHRoaXMuX2VtaXR0ZWRQYWdlSWQpIHtcbiAgICAgIHRoaXMuX2VtaXR0ZWRQYWdlSWQgPSBhY3RpdmVQYWdlSWQ7XG4gICAgICB0aGlzLnBhZ2VDaGFuZ2VkLmVtaXQoYWN0aXZlUGFnZUlkKTtcbiAgICB9XG4gIH1cblxuICAvLyBSZXBvcnQgaGVhZGluZyBzaXplIGluIHB4IChjb25maWcgaXMgcG9pbnRzOyB0aGUgY2FudmFzIHJlbmRlcnMgYXRcbiAgLy8gOTZweC9pbiwgc28gcG9pbnRzIMOXIDk2LzcyKS4gSW5oZXJpdGVkIGJ5IGNvbXBvbmVudCB0aXRsZXMgdmlhIGEgQ1NTIHZhci5cbiAgcHVibGljIGdldCBoZWFkaW5nU2l6ZVB4KCk6IG51bWJlciB7XG4gICAgY29uc3QgcG9pbnRzID0gdGhpcy5yZXBvcnQ/LmNvbmZpZz8uc3R5bGVzPy5oZWFkaW5nPy5zaXplID8/IERFRkFVTFRfSEVBRElOR19TSVpFO1xuXG4gICAgcmV0dXJuIHBvaW50cyAqIChQWF9QRVJfSU5DSCAvIDcyKTtcbiAgfVxuXG4gIHB1YmxpYyBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XG4gICAgLy8gRml0IHRoZSBwYWdlIHRvIHRoZSB2aWV3cG9ydCBvbmNlIG9uIGZpcnN0IHJlbmRlcjsgYWZ0ZXIgdGhhdCB0aGVcbiAgICAvLyB2aWV3ZXIncyB6b29tIGNob2ljZSBpcyByZXNwZWN0ZWQgYWNyb3NzIHJlLXJlbmRlcnMuXG4gICAgc2V0VGltZW91dCgoKSA9PiB0aGlzLnpvb21GaXQoKSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGlzRmxvdygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5yZXBvcnQ/LmxheW91dCA9PT0gJ2Zsb3cnO1xuICB9XG5cbiAgcHVibGljIGdldCBhY3RpdmVQYWdlKCk6IFJlcG9ydFBhZ2UgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5yZXBvcnQ/LnBhZ2VzPy5bdGhpcy5hY3RpdmVQYWdlSW5kZXhdID8/IG51bGw7XG4gIH1cblxuICAvLyBUaGUgaGVhZGVyL2Zvb3RlciBiYW5kcywgaW4gaW5jaGVzICgwID0gbm8gYmFuZCkuXG4gIHB1YmxpYyBnZXQgYmFuZHMoKTogUmVwb3J0SGVhZGVyRm9vdGVyIHtcbiAgICByZXR1cm4gdGhpcy5yZXBvcnQ/LmNvbmZpZz8uaGVhZGVyRm9vdGVyID8/IHsgaGVhZGVySGVpZ2h0OiAwLCBmb290ZXJIZWlnaHQ6IDAgfTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgbWFzdGVyQ29tcG9uZW50cygpOiBSZXBvcnRDb21wb25lbnRbXSB7XG4gICAgcmV0dXJuIHRoaXMucmVwb3J0Py5tYXN0ZXI/LmNvbXBvbmVudHMgPz8gW107XG4gIH1cblxuICAvLyBUaGUgbWFzdGVyIGRyYXdzIHVubGVzcyB0aGUgcGFnZSBoaWRlcyBpdCDigJQgYW5kIGFsd2F5cyB3aGlsZSBpdCBpcyB0aGVcbiAgLy8gbGF5ZXIgYmVpbmcgZWRpdGVkLCBzbyBhIHBhZ2UgdGhhdCBoaWRlcyBpdCBjYW4gc3RpbGwgYmUgdXNlZCB0byBlZGl0IGl0LlxuICBwdWJsaWMgZ2V0IGlzTWFzdGVyU2hvd24oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubWFzdGVyTW9kZSgpIHx8ICF0aGlzLmFjdGl2ZVBhZ2U/Lm1hc3RlckhpZGRlbjtcbiAgfVxuXG4gIC8vIFdoaWNoIGxheWVyIHRoZSBlZGl0IGdlc3R1cmVzIHJlYWNoLlxuICBwdWJsaWMgZ2V0IGlzUGFnZUVkaXRpbmcoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZWRpdE1vZGUgJiYgIXRoaXMubWFzdGVyTW9kZSgpO1xuICB9XG5cbiAgcHVibGljIGdldCBpc01hc3RlckVkaXRpbmcoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZWRpdE1vZGUgJiYgdGhpcy5tYXN0ZXJNb2RlKCk7XG4gIH1cblxuICAvLyBXaGF0IHt7cGFnZS5udW1iZXJ9fSAvIHt7cGFnZS5uYW1lfX0gLyB7e3JlcG9ydC5uYW1lfX0gZmlsbCB3aXRoIG9uIHRoZVxuICAvLyBwYWdlIG9uIHNjcmVlbiDigJQgdGhlIG1hc3RlcidzIGZvb3RlciBudW1iZXJzIGVhY2ggcGFnZSBieSBpdHMgcG9zaXRpb24uXG4gIC8vIFRoZSBzYW1lIG9iamVjdCBpcyBoYW5kZWQgYmFjayB1bnRpbCBvbmUgb2YgdGhlIHRocmVlIGNoYW5nZXM6IGV2ZXJ5IHRleHRcbiAgLy8gYmxvY2sgdGFrZXMgaXQgYXMgYW4gaW5wdXQsIGFuZCBhIGZyZXNoIG9iamVjdCBwZXIgY2hlY2sgd291bGQgbWFrZSBlYWNoXG4gIC8vIG9mIHRoZW0gcmVwYWludCBpdHMgaHRtbCBvbiBldmVyeSBjaGFuZ2UtZGV0ZWN0aW9uIHBhc3MuXG4gIHB1YmxpYyBnZXQgdG9rZW5zKCk6IFRleHRUb2tlbkNvbnRleHQge1xuICAgIGNvbnN0IHBhZ2UgPSB0aGlzLmFjdGl2ZVBhZ2U7XG4gICAgY29uc3QgcGFnZU51bWJlciA9IHRoaXMuYWN0aXZlUGFnZUluZGV4ICsgMTtcbiAgICBjb25zdCBwYWdlTmFtZSA9IHBhZ2UgPyB0aGlzLnBhZ2VMYWJlbChwYWdlLCB0aGlzLmFjdGl2ZVBhZ2VJbmRleCkgOiAnJztcbiAgICBjb25zdCByZXBvcnROYW1lID0gdGhpcy5yZXBvcnQ/Lm5hbWUgPz8gJyc7XG5cbiAgICBjb25zdCB0b2tlbnMgPSB0aGlzLl90b2tlbnM7XG4gICAgaWYgKHRva2Vucz8ucGFnZU51bWJlciAhPT0gcGFnZU51bWJlciB8fCB0b2tlbnMucGFnZU5hbWUgIT09IHBhZ2VOYW1lIHx8IHRva2Vucy5yZXBvcnROYW1lICE9PSByZXBvcnROYW1lKSB7XG4gICAgICB0aGlzLl90b2tlbnMgPSB7IHBhZ2VOdW1iZXIsIHBhZ2VOYW1lLCByZXBvcnROYW1lIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3Rva2VucztcbiAgfVxuXG4gIHB1YmxpYyB0b2dnbGVNYXN0ZXJNb2RlKCk6IHZvaWQge1xuICAgIHRoaXMubWFzdGVyTW9kZS51cGRhdGUoKHZhbHVlKSA9PiAhdmFsdWUpO1xuICAgIHRoaXMuc2VsZWN0ZWRDb21wb25lbnRJZCA9IG51bGw7XG4gIH1cblxuICAvLyBEcm9wIGEgdGV4dCBibG9jayB3aGVyZSBpdCB3aWxsIGJlIGZvdW5kOiBpbnRvIHRoZSBmb290ZXIgKG9yIGhlYWRlcikgYmFuZFxuICAvLyB3aGlsZSBlZGl0aW5nIHRoZSBoZWFkZXIgYW5kIGZvb3RlciwgYmVsb3cgdGhlIGhlYWRlciBiYW5kIG9uIGEgcGFnZS4gVGhlXG4gIC8vIGhvc3QgcmUtZmV0Y2hlcyB0aGUgcmVwb3J0IGFuZCBpdCBhcHBlYXJzOyBkb3VibGUtcHJlc3Mgb3BlbnMgaXRzIGVkaXRvci5cbiAgcHVibGljIGFkZFRleHQoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnJlcG9ydCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHsgaGVhZGVySGVpZ2h0LCBmb290ZXJIZWlnaHQgfSA9IHRoaXMuYmFuZHM7XG4gICAgY29uc3QgcGFnZVdpZHRoID0gdGhpcy5yZXBvcnQucGFnZVdpZHRoO1xuICAgIGNvbnN0IHBhZ2VIZWlnaHQgPSB0aGlzLnJlcG9ydC5wYWdlSGVpZ2h0O1xuICAgIGNvbnN0IGlzTWFzdGVyID0gdGhpcy5tYXN0ZXJNb2RlKCk7XG5cbiAgICBsZXQgZ2VvbWV0cnkgPSB7IHg6IDAuNSwgeTogaGVhZGVySGVpZ2h0ICsgMC41LCB3OiBNYXRoLm1pbig1LCBwYWdlV2lkdGggLSAxKSwgaDogMC44IH07XG4gICAgaWYgKGlzTWFzdGVyKSB7XG4gICAgICBjb25zdCBiYW5kSGVpZ2h0ID0gZm9vdGVySGVpZ2h0IHx8IGhlYWRlckhlaWdodCB8fCAwLjU7XG4gICAgICBjb25zdCB5ID0gZm9vdGVySGVpZ2h0XG4gICAgICAgID8gcGFnZUhlaWdodCAtIGZvb3RlckhlaWdodFxuICAgICAgICA6IChoZWFkZXJIZWlnaHQgPyAwIDogcGFnZUhlaWdodCAtIGJhbmRIZWlnaHQpO1xuICAgICAgZ2VvbWV0cnkgPSB7IHg6IDAuNSwgeTogeSArIDAuMDUsIHc6IE1hdGgubWluKDQsIHBhZ2VXaWR0aCAtIDEpLCBoOiBNYXRoLm1heCgwLjMsIGJhbmRIZWlnaHQgLSAwLjEpIH07XG4gICAgfVxuXG4gICAgdGhpcy5fcmVwb3J0RGF0YS5hZGRUZXh0KHRoaXMucmVwb3J0LmlkLCB7XG4gICAgICAuLi5nZW9tZXRyeSxcbiAgICAgIHBhZ2VJZDogaXNNYXN0ZXIgPyB1bmRlZmluZWQgOiB0aGlzLmFjdGl2ZVBhZ2U/LmlkLFxuICAgIH0pXG4gICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fZGVzdHJveVJlZikpXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHRoaXMucmVwb3J0Q2hhbmdlZC5lbWl0KCkpO1xuICB9XG5cbiAgLy8gQSB0ZXh0IGJsb2NrIGRlbGV0ZWQgaXRzZWxmIGZyb20gaXRzIG1lbnU6IGRyb3AgaXQgZnJvbSB3aGljaGV2ZXIgbGF5ZXIgaXRcbiAgLy8gd2FzIG9uIHdpdGhvdXQgcmUtZmV0Y2hpbmcgdGhlIHJlcG9ydCAobm90aGluZyBlbHNlIGRlcGVuZHMgb24gaXQpLlxuICBwdWJsaWMgb25Db21wb25lbnRSZW1vdmVkKGNvbXBvbmVudElkOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBsYXllcnMgPSBbdGhpcy5hY3RpdmVQYWdlPy5jb21wb25lbnRzLCB0aGlzLnJlcG9ydD8ubWFzdGVyPy5jb21wb25lbnRzXTtcbiAgICBmb3IgKGNvbnN0IGNvbXBvbmVudHMgb2YgbGF5ZXJzKSB7XG4gICAgICBjb25zdCBpbmRleCA9IGNvbXBvbmVudHM/LmZpbmRJbmRleCgoY29tcG9uZW50KSA9PiBjb21wb25lbnQuaWQgPT09IGNvbXBvbmVudElkKSA/PyAtMTtcbiAgICAgIGlmIChpbmRleCA+IC0xKSB7XG4gICAgICAgIGNvbXBvbmVudHMuc3BsaWNlKGluZGV4LCAxKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnNlbGVjdGVkQ29tcG9uZW50SWQgPSBudWxsO1xuICAgIHRoaXMuX21lc3NhZ2Uuc3VjY2VzcygnRGVsZXRlZCB0ZXh0Jyk7XG4gICAgdGhpcy5fY2RSZWYubWFya0ZvckNoZWNrKCk7XG4gIH1cblxuICAvLyBTaG93IG9yIGhpZGUgdGhlIGhlYWRlciBhbmQgZm9vdGVyIG9uIG9uZSBwYWdlLCBmcm9tIGl0cyB0YWIncyBrZWJhYi5cbiAgcHVibGljIHRvZ2dsZU1hc3RlckhpZGRlbihwYWdlOiBSZXBvcnRQYWdlKTogdm9pZCB7XG4gICAgY29uc3QgbWFzdGVySGlkZGVuID0gIXBhZ2UubWFzdGVySGlkZGVuO1xuXG4gICAgdGhpcy5fcmVwb3J0RGF0YS51cGRhdGVQYWdlKHRoaXMucmVwb3J0LmlkLCBwYWdlLmlkLCB7IG1hc3RlckhpZGRlbiB9KVxuICAgICAgLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHBhZ2UubWFzdGVySGlkZGVuID0gbWFzdGVySGlkZGVuO1xuICAgICAgICB0aGlzLl9tZXNzYWdlLnN1Y2Nlc3MobWFzdGVySGlkZGVuID8gJ0hlYWRlciAmIGZvb3RlciBoaWRkZW4gb24gdGhpcyBwYWdlJyA6ICdIZWFkZXIgJiBmb290ZXIgc2hvd24gb24gdGhpcyBwYWdlJyk7XG4gICAgICAgIHRoaXMuX2NkUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSk7XG4gIH1cblxuICAvLyBGbG93IHJlbmRlciBvcmRlciAodGhlIGFzc2VtYmxlciBhbHJlYWR5IHNvcnRzLCBidXQgYSBsb2NhbCByZW9yZGVyXG4gIC8vIG1pZC1zZXNzaW9uIG11c3QgaG9sZCB3aXRob3V0IGEgcmUtZmV0Y2gpLlxuICBwdWJsaWMgZ2V0IGZsb3dDb21wb25lbnRzKCk6IFJlcG9ydENvbXBvbmVudFtdIHtcbiAgICByZXR1cm4gWy4uLih0aGlzLmFjdGl2ZVBhZ2U/LmNvbXBvbmVudHMgPz8gW10pXS5zb3J0KChhLCBiKSA9PiBhLm9yZGVyIC0gYi5vcmRlcik7XG4gIH1cblxuICBwdWJsaWMgc2VsZWN0UGFnZShpbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5hY3RpdmVQYWdlSW5kZXggPSBpbmRleDtcbiAgICB0aGlzLnNlbGVjdGVkQ29tcG9uZW50SWQgPSBudWxsO1xuXG4gICAgLy8gS2VwdCBpbiBzdGVwIHdpdGggdGhlIG5nT25DaGFuZ2VzIGFubm91bmNlbWVudCBzbyB0aGUgdHdvIGNhbid0IGRpc2FncmVlXG4gICAgLy8gYWJvdXQgd2hhdCB0aGUgaG9zdCB3YXMgbGFzdCB0b2xkLlxuICAgIHRoaXMuX2VtaXR0ZWRQYWdlSWQgPSB0aGlzLmFjdGl2ZVBhZ2U/LmlkID8/IG51bGw7XG4gICAgdGhpcy5wYWdlQ2hhbmdlZC5lbWl0KHRoaXMuX2VtaXR0ZWRQYWdlSWQpO1xuICB9XG5cbiAgLy8gQXBwZW5kIGEgYmxhbmsgcGFnZTsgdGhlIGhvc3QgcmUtZmV0Y2hlcyB0aGUgcmVwb3J0IGFuZCBuZ09uQ2hhbmdlcyBsYW5kc1xuICAvLyB0aGUgdmlldyBvbiB0aGUgbmV3IChsYXN0KSBwYWdlLlxuICBwdWJsaWMgYWRkUGFnZSgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMucmVwb3J0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5fcmVwb3J0RGF0YS5hZGRQYWdlKHRoaXMucmVwb3J0LmlkKVxuICAgICAgLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB0aGlzLnJlcG9ydENoYW5nZWQuZW1pdCgpKTtcbiAgfVxuXG4gIHB1YmxpYyBwYWdlTGFiZWwocGFnZTogUmVwb3J0UGFnZSwgaW5kZXg6IG51bWJlcik6IHN0cmluZyB7XG4gICAgcmV0dXJuIHBhZ2UubmFtZSB8fCBgUGFnZSAke2luZGV4ICsgMX1gO1xuICB9XG5cbiAgLy8gUmVuYW1lIGZyb20gdGhlIHRhYidzIGtlYmFiLiBUaGUgcGFnZSBsaXN0IGlzIHBhdGNoZWQgaW4gcGxhY2UgcmF0aGVyIHRoYW5cbiAgLy8gcmUtZmV0Y2hpbmcgdGhlIHJlcG9ydDogbm90aGluZyBlbHNlIG9uIHRoZSBjYW52YXMgZGVwZW5kcyBvbiBhIHBhZ2Unc1xuICAvLyBuYW1lLCBhbmQgYSByZS1mZXRjaCB3b3VsZCByZS1ydW4gZXZlcnkgY29tcG9uZW50J3MgcXVlcnkgdG8gcmVwYWludCBhXG4gIC8vIGNoaXAncyBsYWJlbC5cbiAgcHVibGljIHJlbmFtZVBhZ2UocGFnZTogUmVwb3J0UGFnZSk6IHZvaWQge1xuICAgIHRoaXMuX3Byb21wdC5pbnB1dCh7XG4gICAgICB0aXRsZTogJ0VkaXQgUGFnZSBOYW1lJyxcbiAgICAgIGxhYmVsOiAnTmFtZScsXG4gICAgICBkZWZhdWx0OiBwYWdlLm5hbWUgPz8gJycsXG4gICAgICBjb21taXRMYWJlbDogJ1NhdmUnLFxuICAgICAgcmVxdWlyZWQ6IHRydWUsXG4gICAgfSlcbiAgICAgIC5waXBlKFxuICAgICAgICBzd2l0Y2hNYXAoKG5hbWU6IHN0cmluZykgPT4gdGhpcy5fcmVwb3J0RGF0YVxuICAgICAgICAgIC51cGRhdGVQYWdlKHRoaXMucmVwb3J0LmlkLCBwYWdlLmlkLCB7IG5hbWUgfSlcbiAgICAgICAgICAucGlwZShtYXAoKCkgPT4gbmFtZSkpKSxcbiAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgobmFtZTogc3RyaW5nKSA9PiB7XG4gICAgICAgIHBhZ2UubmFtZSA9IG5hbWU7XG4gICAgICAgIHRoaXMuX21lc3NhZ2Uuc3VjY2VzcygnU2F2ZWQgcGFnZSBuYW1lJyk7XG4gICAgICAgIHRoaXMuX2NkUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSk7XG4gIH1cblxuICAvLyBEZWxldGUgZnJvbSB0aGUgdGFiJ3Mga2ViYWIuIFRoZSBjb25maXJtIG5hbWVzIHRoZSBwYWdlIGFuZCBzYXlzIHRoZVxuICAvLyBjb21wb25lbnRzIGdvIHdpdGggaXQg4oCUIHRoZSBzZXJ2ZXIgcmVmdXNlcyB0aGUgbGFzdCBwYWdlLCBhbmQgdGhhdCByZWZ1c2FsXG4gIC8vIHN1cmZhY2VzIGFzIHRoZSBBUEkgZXJyb3IgbWVzc2FnZSByYXRoZXIgdGhhbiBiZWluZyBzZWNvbmQtZ3Vlc3NlZCBoZXJlLlxuICBwdWJsaWMgZGVsZXRlUGFnZShwYWdlOiBSZXBvcnRQYWdlKTogdm9pZCB7XG4gICAgdGhpcy5fcHJvbXB0LmNvbmZpcm0oe1xuICAgICAgdGl0bGU6ICdDb25maXJtJyxcbiAgICAgIHRlbXBsYXRlOiBgQXJlIHlvdSBzdXJlIHlvdSB3b3VsZCBsaWtlIHRvIGRlbGV0ZSBcIiR7dGhpcy5wYWdlTGFiZWwocGFnZSwgdGhpcy5yZXBvcnQucGFnZXMuaW5kZXhPZihwYWdlKSl9XCIgYW5kIGV2ZXJ5dGhpbmcgb24gaXQ/YCxcbiAgICB9KVxuICAgICAgLnBpcGUoXG4gICAgICAgIHN3aXRjaE1hcCgoKSA9PiB0aGlzLl9yZXBvcnREYXRhLmRlbGV0ZVBhZ2UodGhpcy5yZXBvcnQuaWQsIHBhZ2UuaWQpKSxcbiAgICAgICAgdGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIGNvbnN0IGluZGV4ID0gdGhpcy5yZXBvcnQucGFnZXMuaW5kZXhPZihwYWdlKTtcbiAgICAgICAgdGhpcy5yZXBvcnQucGFnZXMuc3BsaWNlKGluZGV4LCAxKTtcblxuICAgICAgICAvLyBMYW5kIG9uIHRoZSBuZWlnaGJvdXIgcmF0aGVyIHRoYW4gc25hcHBpbmcgYmFjayB0byB0aGUgZmlyc3QgcGFnZSDigJRcbiAgICAgICAgLy8gZGVsZXRpbmcgcGFnZSA0IG9mIDYgc2hvdWxkIGxlYXZlIHlvdSBsb29raW5nIGF0IHdoYXQgaXMgbm93IHBhZ2UgNC5cbiAgICAgICAgdGhpcy5hY3RpdmVQYWdlSW5kZXggPSBNYXRoLm1pbihpbmRleCwgdGhpcy5yZXBvcnQucGFnZXMubGVuZ3RoIC0gMSk7XG4gICAgICAgIHRoaXMuX3ByZXZpb3VzUGFnZUNvdW50ID0gdGhpcy5yZXBvcnQucGFnZXMubGVuZ3RoO1xuICAgICAgICB0aGlzLnNlbGVjdGVkQ29tcG9uZW50SWQgPSBudWxsO1xuXG4gICAgICAgIC8vIFRoZSBpZCBpbiB0aGUgVVJMIGp1c3Qgc3RvcHBlZCBleGlzdGluZyDigJQgcmVwbGFjZSBpdCB3aXRoIHRoZVxuICAgICAgICAvLyBuZWlnaGJvdXIgd2UgbGFuZGVkIG9uLCBvciBhIHJlZnJlc2ggd291bGQgNDA0IGl0cyB3YXkgdG8gcGFnZSBvbmUuXG4gICAgICAgIHRoaXMucGFnZUNoYW5nZWQuZW1pdCh0aGlzLmFjdGl2ZVBhZ2U/LmlkID8/IG51bGwpO1xuXG4gICAgICAgIHRoaXMuX21lc3NhZ2Uuc3VjY2VzcygnRGVsZXRlZCBwYWdlJyk7XG4gICAgICAgIHRoaXMuX2NkUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSk7XG4gIH1cblxuICAvLyBBIHRhYiB3YXMgZHJhZ2dlZCB0byBhIG5ldyBzbG90OiByZW9yZGVyIGxvY2FsbHkgc28gdGhlIGNoaXBzIHNldHRsZVxuICAvLyBpbW1lZGlhdGVseSwga2VlcCB0aGUgdmlld2VyIG9uIHRoZSBwYWdlIHRoZXkgd2VyZSBsb29raW5nIGF0LCBhbmQgcGVyc2lzdFxuICAvLyB0aGUgd2hvbGUgc2VxdWVuY2UgaW4gb25lIFBVVC5cbiAgcHVibGljIG9uUGFnZURyb3BwZWQoZXZlbnQ6IENka0RyYWdEcm9wPHVua25vd24+KTogdm9pZCB7XG4gICAgaWYgKGV2ZW50LnByZXZpb3VzSW5kZXggPT09IGV2ZW50LmN1cnJlbnRJbmRleCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGFjdGl2ZVBhZ2UgPSB0aGlzLmFjdGl2ZVBhZ2U7XG5cbiAgICBtb3ZlSXRlbUluQXJyYXkodGhpcy5yZXBvcnQucGFnZXMsIGV2ZW50LnByZXZpb3VzSW5kZXgsIGV2ZW50LmN1cnJlbnRJbmRleCk7XG5cbiAgICBjb25zdCBwb3NpdGlvbnMgPSB0aGlzLnJlcG9ydC5wYWdlcy5tYXAoKHBhZ2UsIG9yZGVyKSA9PiB7XG4gICAgICBwYWdlLm9yZGVyID0gb3JkZXI7XG5cbiAgICAgIHJldHVybiB7IHBhZ2VJZDogcGFnZS5pZCwgb3JkZXIgfTtcbiAgICB9KTtcblxuICAgIHRoaXMuYWN0aXZlUGFnZUluZGV4ID0gYWN0aXZlUGFnZVxuICAgICAgPyB0aGlzLnJlcG9ydC5wYWdlcy5pbmRleE9mKGFjdGl2ZVBhZ2UpXG4gICAgICA6IHRoaXMuYWN0aXZlUGFnZUluZGV4O1xuXG4gICAgdGhpcy5fcmVwb3J0RGF0YS5zYXZlUGFnZVBvc2l0aW9ucyh0aGlzLnJlcG9ydC5pZCwgcG9zaXRpb25zKVxuICAgICAgLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuX2Rlc3Ryb3lSZWYpKVxuICAgICAgLnN1YnNjcmliZSgpO1xuICB9XG5cbiAgLy8gSGFuZCBwcmVzZW50YXRpb24gc2V0dGluZ3MgKHRpdGxlLCBwYWRkaW5nKSBzYXZlZCBpbiB0aGUgc2V0dGluZ3MgZGlhbG9nIHRvXG4gIC8vIHRoZSBvbmUgY29tcG9uZW50IHRoZXkgYmVsb25nIHRvLiBOb3RoaW5nIGhlcmUgZmVlZHMgdGhlIHF1ZXJ5LCBzbyB0aGF0XG4gIC8vIGNvbXBvbmVudCByZXBhaW50cyBhbmQgZXZlcnkgb3RoZXIgb25lIG9uIHRoZSBwYWdlIGlzIGxlZnQgYWxvbmUuXG4gIHB1YmxpYyBhcHBseUNvbXBvbmVudFNldHRpbmdzKGNvbXBvbmVudElkOiBudW1iZXIsIHNldHRpbmdzOiBDb21wb25lbnRTZXR0aW5ncyk6IHZvaWQge1xuICAgIHRoaXMuX3JlbmRlcmVkQ29tcG9uZW50c1xuICAgICAgLmZpbmQoKHJlbmRlcmVkKSA9PiByZW5kZXJlZC5jb21wb25lbnQuaWQgPT09IGNvbXBvbmVudElkKVxuICAgICAgPy5hcHBseVNldHRpbmdzKHNldHRpbmdzKTtcbiAgfVxuXG4gIHB1YmxpYyBzZWxlY3RDb21wb25lbnQoY29tcG9uZW50SWQ6IG51bWJlciB8IG51bGwpOiB2b2lkIHtcbiAgICB0aGlzLnNlbGVjdGVkQ29tcG9uZW50SWQgPSBjb21wb25lbnRJZDtcbiAgICB0aGlzLl9jZFJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgfVxuXG4gIHB1YmxpYyBvbkNhbnZhc1BvaW50ZXJEb3duKCk6IHZvaWQge1xuICAgIC8vIEJhY2tncm91bmQgY2xpY2sgKHBhbiBzdGFydCkgZGVzZWxlY3RzLlxuICAgIGlmICh0aGlzLnNlbGVjdGVkQ29tcG9uZW50SWQgIT09IG51bGwpIHtcbiAgICAgIHRoaXMuc2VsZWN0Q29tcG9uZW50KG51bGwpO1xuICAgIH1cbiAgfVxuXG4gIC8vIC0tLS0tIHpvb20gdG9vbGJhciAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICBwdWJsaWMgb25ab29tZWQoc2NhbGU6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuem9vbSA9IHNjYWxlO1xuICAgIHRoaXMuX2NkUmVmLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgcHVibGljIHpvb21JbigpOiB2b2lkIHtcbiAgICB0aGlzLnpvb21QYW4/Lnpvb21JbigpO1xuICB9XG5cbiAgcHVibGljIHpvb21PdXQoKTogdm9pZCB7XG4gICAgdGhpcy56b29tUGFuPy56b29tT3V0KCk7XG4gIH1cblxuICBwdWJsaWMgem9vbUZpdCgpOiB2b2lkIHtcbiAgICBjb25zdCB2aWV3cG9ydCA9IHRoaXMuX3ZpZXdwb3J0Py5uYXRpdmVFbGVtZW50O1xuICAgIGlmICghdmlld3BvcnQgfHwgIXRoaXMucmVwb3J0Py5wYWdlV2lkdGggfHwgIXRoaXMuem9vbVBhbikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGZpdCA9IE1hdGgubWluKFxuICAgICAgKHZpZXdwb3J0LmNsaWVudFdpZHRoIC0gMzIpIC8gKHRoaXMucmVwb3J0LnBhZ2VXaWR0aCAqIFBYX1BFUl9JTkNIKSxcbiAgICAgICh2aWV3cG9ydC5jbGllbnRIZWlnaHQgLSAzMikgLyAodGhpcy5yZXBvcnQucGFnZUhlaWdodCAqIFBYX1BFUl9JTkNIKSxcbiAgICApO1xuXG4gICAgdGhpcy56b29tUGFuLnpvb20oTWF0aC5taW4oMS41LCBNYXRoLm1heCgwLjEsIGZpdCkpKTtcbiAgICB0aGlzLnpvb21QYW4ubW92ZSgxNiwgMTYpO1xuICAgIHRoaXMuX2ZpdHRlZCA9IHRydWU7XG4gIH1cblxuICBwdWJsaWMgem9vbUFjdHVhbCgpOiB2b2lkIHtcbiAgICB0aGlzLnpvb21QYW4/Lnpvb20oMSk7XG4gIH1cblxuICAvLyAtLS0tLSBwZXJzaXN0ZW5jZSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgLy8gQSBmcmVlZm9ybSBkcmFnL3Jlc2l6ZSBvciBhIGZsb3cgd2lkdGggcmVzaXplIGxhbmRlZCDigJQgb25lIFBVVCBwZXIgZ2VzdHVyZS5cbiAgcHVibGljIG9uUG9zaXRpb25DaGFuZ2VkKHBvc2l0aW9uOiB7IGNvbXBvbmVudElkOiBudW1iZXIgfSAmIFJlY29yZDxzdHJpbmcsIG51bWJlcj4pOiB2b2lkIHtcbiAgICB0aGlzLl9jbGVhckd1aWRlcygpO1xuICAgIHRoaXMuX3JlcG9ydERhdGEuc2F2ZVBvc2l0aW9ucyh0aGlzLnJlcG9ydC5pZCwgW3Bvc2l0aW9uIGFzIGFueV0pXG4gICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5fZGVzdHJveVJlZikpXG4gICAgICAuc3Vic2NyaWJlKCk7XG4gIH1cblxuICAvLyBBIGZsb3cgZHJhZyBkcm9wcGVkOiByZW9yZGVyIHRoZSBwYWdlJ3MgY29tcG9uZW50cyBhcm91bmQgdGhlIG1vdmVkIG9uZVxuICAvLyBhbmQgcGVyc2lzdCBldmVyeSBvcmRlciBpbiBvbmUgUFVULlxuICBwdWJsaWMgb25GbG93UmVvcmRlcihldmVudDogeyBjb21wb25lbnRJZDogbnVtYmVyOyBjbGllbnRYOiBudW1iZXI7IGNsaWVudFk6IG51bWJlciB9KTogdm9pZCB7XG4gICAgY29uc3QgcGFnZSA9IHRoaXMuYWN0aXZlUGFnZTtcbiAgICBpZiAoIXBhZ2UpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBvcmRlcmVkID0gdGhpcy5mbG93Q29tcG9uZW50cy5maWx0ZXIoKGNvbXBvbmVudCkgPT4gY29tcG9uZW50LmlkICE9PSBldmVudC5jb21wb25lbnRJZCk7XG4gICAgY29uc3QgbW92ZWQgPSBwYWdlLmNvbXBvbmVudHMuZmluZCgoY29tcG9uZW50KSA9PiBjb21wb25lbnQuaWQgPT09IGV2ZW50LmNvbXBvbmVudElkKTtcbiAgICBpZiAoIW1vdmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgaW5kZXggPSB0aGlzLl9mbG93RHJvcEluZGV4KG9yZGVyZWQsIGV2ZW50LmNsaWVudFgsIGV2ZW50LmNsaWVudFkpO1xuICAgIG9yZGVyZWQuc3BsaWNlKGluZGV4LCAwLCBtb3ZlZCk7XG5cbiAgICBjb25zdCBwb3NpdGlvbnMgPSBvcmRlcmVkLm1hcCgoY29tcG9uZW50LCBvcmRlcikgPT4ge1xuICAgICAgY29tcG9uZW50Lm9yZGVyID0gb3JkZXI7XG5cbiAgICAgIHJldHVybiB7IGNvbXBvbmVudElkOiBjb21wb25lbnQuaWQsIG9yZGVyIH07XG4gICAgfSk7XG5cbiAgICB0aGlzLl9jZFJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgICB0aGlzLl9yZXBvcnREYXRhLnNhdmVQb3NpdGlvbnModGhpcy5yZXBvcnQuaWQsIHBvc2l0aW9ucylcbiAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLl9kZXN0cm95UmVmKSlcbiAgICAgIC5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIC8vIFdoZXJlIHRoZSBwb2ludGVyIGxhbmRlZCBhbW9uZyB0aGUgZmxvd2VkIGNvbXBvbmVudHM6IGJlZm9yZSB0aGUgZmlyc3RcbiAgLy8gY29tcG9uZW50IHdob3NlIGNlbnRlciB0aGUgcG9pbnRlciBpcyBhYm92ZS9sZWZ0IG9mLlxuICBwcml2YXRlIF9mbG93RHJvcEluZGV4KG9yZGVyZWQ6IFJlcG9ydENvbXBvbmVudFtdLCBjbGllbnRYOiBudW1iZXIsIGNsaWVudFk6IG51bWJlcik6IG51bWJlciB7XG4gICAgLy8gRmxvdyBpdGVtcyBvbmx5IOKAlCB0aGUgaGVhZGVyL2Zvb3RlciBibG9ja3Mgb24gdGhlIG1hc3RlciBsYXllciBhcmVcbiAgICAvLyBjb21wb25lbnRzIHRvbywgYnV0IHRoZXkgYXJlIG5vdCBpbiB0aGUgZmxvdy5cbiAgICBjb25zdCBob3N0cyA9IEFycmF5LmZyb20oXG4gICAgICB0aGlzLl92aWV3cG9ydC5uYXRpdmVFbGVtZW50LnF1ZXJ5U2VsZWN0b3JBbGw8SFRNTEVsZW1lbnQ+KCdhcHAtcmVwb3J0LWNvbXBvbmVudC5mbG93LWl0ZW0nKSxcbiAgICApLmZpbHRlcigoaG9zdCkgPT4gIWhvc3QuY2xhc3NMaXN0LmNvbnRhaW5zKCdmbG93LWRyYWdnaW5nJykpO1xuXG4gICAgZm9yIChsZXQgaW5kZXggPSAwOyBpbmRleCA8IGhvc3RzLmxlbmd0aCAmJiBpbmRleCA8IG9yZGVyZWQubGVuZ3RoOyBpbmRleCsrKSB7XG4gICAgICBjb25zdCByZWN0ID0gaG9zdHNbaW5kZXhdLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgaWYgKGNsaWVudFkgPCByZWN0LnRvcCArIHJlY3QuaGVpZ2h0IC8gMlxuICAgICAgICB8fCAoY2xpZW50WSA8IHJlY3QuYm90dG9tICYmIGNsaWVudFggPCByZWN0LmxlZnQgKyByZWN0LndpZHRoIC8gMikpIHtcbiAgICAgICAgcmV0dXJuIGluZGV4O1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBvcmRlcmVkLmxlbmd0aDtcbiAgfVxuXG4gIC8vIC0tLS0tIHNtYXJ0IGd1aWRlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICAvLyBQaXhlbCBmZWVsIG9mIHRoZSBzbmFwLCBjb252ZXJ0ZWQgdG8gaW5jaGVzIGF0IHRoZSBjdXJyZW50IHpvb20uXG4gIHByaXZhdGUgZ2V0IF9zbmFwVGhyZXNob2xkKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIDggLyAoUFhfUEVSX0lOQ0ggKiBNYXRoLm1heCgwLjEsIHRoaXMuem9vbSkpO1xuICB9XG5cbiAgcHJpdmF0ZSBfc25hcE1vdmUoY29tcG9uZW50OiBSZXBvcnRDb21wb25lbnQsIHg6IG51bWJlciwgeTogbnVtYmVyKTogeyB4OiBudW1iZXI7IHk6IG51bWJlciB9IHtcbiAgICBjb25zdCB7IHZlcnRpY2FsLCBob3Jpem9udGFsIH0gPSB0aGlzLl9jYW5kaWRhdGVzKGNvbXBvbmVudCk7XG4gICAgY29uc3QgZ3VpZGVzOiBHdWlkZUxpbmVbXSA9IFtdO1xuXG4gICAgY29uc3Qgc25hcHBlZFggPSB0aGlzLl9zbmFwQXhpcyhcbiAgICAgIFtcbiAgICAgICAgeyBvZmZzZXQ6IDAsIHZhbHVlOiB4IH0sXG4gICAgICAgIHsgb2Zmc2V0OiBjb21wb25lbnQudyAvIDIsIHZhbHVlOiB4ICsgY29tcG9uZW50LncgLyAyIH0sXG4gICAgICAgIHsgb2Zmc2V0OiBjb21wb25lbnQudywgdmFsdWU6IHggKyBjb21wb25lbnQudyB9LFxuICAgICAgXSxcbiAgICAgIHZlcnRpY2FsLFxuICAgICk7XG4gICAgaWYgKHNuYXBwZWRYICE9PSBudWxsKSB7XG4gICAgICB4ID0gc25hcHBlZFguYmFzZTtcbiAgICAgIGd1aWRlcy5wdXNoKHsgb3JpZW50YXRpb246ICd2JywgcG9zaXRpb246IHNuYXBwZWRYLmd1aWRlIH0pO1xuICAgIH1cblxuICAgIGNvbnN0IHNuYXBwZWRZID0gdGhpcy5fc25hcEF4aXMoXG4gICAgICBbXG4gICAgICAgIHsgb2Zmc2V0OiAwLCB2YWx1ZTogeSB9LFxuICAgICAgICB7IG9mZnNldDogY29tcG9uZW50LmggLyAyLCB2YWx1ZTogeSArIGNvbXBvbmVudC5oIC8gMiB9LFxuICAgICAgICB7IG9mZnNldDogY29tcG9uZW50LmgsIHZhbHVlOiB5ICsgY29tcG9uZW50LmggfSxcbiAgICAgIF0sXG4gICAgICBob3Jpem9udGFsLFxuICAgICk7XG4gICAgaWYgKHNuYXBwZWRZICE9PSBudWxsKSB7XG4gICAgICB5ID0gc25hcHBlZFkuYmFzZTtcbiAgICAgIGd1aWRlcy5wdXNoKHsgb3JpZW50YXRpb246ICdoJywgcG9zaXRpb246IHNuYXBwZWRZLmd1aWRlIH0pO1xuICAgIH1cblxuICAgIHRoaXMuX3JlbmRlckd1aWRlcyhndWlkZXMpO1xuXG4gICAgcmV0dXJuIHsgeCwgeSB9O1xuICB9XG5cbiAgcHJpdmF0ZSBfc25hcFJlc2l6ZShcbiAgICBjb21wb25lbnQ6IFJlcG9ydENvbXBvbmVudCxcbiAgICBnZW9tZXRyeTogeyB4OiBudW1iZXI7IHk6IG51bWJlcjsgdzogbnVtYmVyOyBoOiBudW1iZXIgfSxcbiAgICBoYW5kbGU6IHN0cmluZyxcbiAgKTogeyB4OiBudW1iZXI7IHk6IG51bWJlcjsgdzogbnVtYmVyOyBoOiBudW1iZXIgfSB7XG4gICAgY29uc3QgeyB2ZXJ0aWNhbCwgaG9yaXpvbnRhbCB9ID0gdGhpcy5fY2FuZGlkYXRlcyhjb21wb25lbnQpO1xuICAgIGNvbnN0IGd1aWRlczogR3VpZGVMaW5lW10gPSBbXTtcbiAgICBjb25zdCByZXN1bHQgPSB7IC4uLmdlb21ldHJ5IH07XG5cbiAgICAvLyBPbmx5IHRoZSBlZGdlcyB0aGUgaGFuZGxlIG1vdmVzIHBhcnRpY2lwYXRlIGluIHNuYXBwaW5nLlxuICAgIGlmIChoYW5kbGUuaW5jbHVkZXMoJ2UnKSkge1xuICAgICAgY29uc3Qgc25hcHBlZCA9IHRoaXMuX25lYXJlc3QoZ2VvbWV0cnkueCArIGdlb21ldHJ5LncsIHZlcnRpY2FsKTtcbiAgICAgIGlmIChzbmFwcGVkICE9PSBudWxsKSB7XG4gICAgICAgIHJlc3VsdC53ID0gc25hcHBlZCAtIGdlb21ldHJ5Lng7XG4gICAgICAgIGd1aWRlcy5wdXNoKHsgb3JpZW50YXRpb246ICd2JywgcG9zaXRpb246IHNuYXBwZWQgfSk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChoYW5kbGUuaW5jbHVkZXMoJ3cnKSkge1xuICAgICAgY29uc3Qgc25hcHBlZCA9IHRoaXMuX25lYXJlc3QoZ2VvbWV0cnkueCwgdmVydGljYWwpO1xuICAgICAgaWYgKHNuYXBwZWQgIT09IG51bGwpIHtcbiAgICAgICAgcmVzdWx0LncgPSBnZW9tZXRyeS54ICsgZ2VvbWV0cnkudyAtIHNuYXBwZWQ7XG4gICAgICAgIHJlc3VsdC54ID0gc25hcHBlZDtcbiAgICAgICAgZ3VpZGVzLnB1c2goeyBvcmllbnRhdGlvbjogJ3YnLCBwb3NpdGlvbjogc25hcHBlZCB9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGhhbmRsZS5pbmNsdWRlcygncycpKSB7XG4gICAgICBjb25zdCBzbmFwcGVkID0gdGhpcy5fbmVhcmVzdChnZW9tZXRyeS55ICsgZ2VvbWV0cnkuaCwgaG9yaXpvbnRhbCk7XG4gICAgICBpZiAoc25hcHBlZCAhPT0gbnVsbCkge1xuICAgICAgICByZXN1bHQuaCA9IHNuYXBwZWQgLSBnZW9tZXRyeS55O1xuICAgICAgICBndWlkZXMucHVzaCh7IG9yaWVudGF0aW9uOiAnaCcsIHBvc2l0aW9uOiBzbmFwcGVkIH0pO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaGFuZGxlLmluY2x1ZGVzKCduJykpIHtcbiAgICAgIGNvbnN0IHNuYXBwZWQgPSB0aGlzLl9uZWFyZXN0KGdlb21ldHJ5LnksIGhvcml6b250YWwpO1xuICAgICAgaWYgKHNuYXBwZWQgIT09IG51bGwpIHtcbiAgICAgICAgcmVzdWx0LmggPSBnZW9tZXRyeS55ICsgZ2VvbWV0cnkuaCAtIHNuYXBwZWQ7XG4gICAgICAgIHJlc3VsdC55ID0gc25hcHBlZDtcbiAgICAgICAgZ3VpZGVzLnB1c2goeyBvcmllbnRhdGlvbjogJ2gnLCBwb3NpdGlvbjogc25hcHBlZCB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLl9yZW5kZXJHdWlkZXMoZ3VpZGVzKTtcblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvLyBBbGlnbm1lbnQgY2FuZGlkYXRlczogdGhlIHBhZ2UncyBlZGdlcyArIGNlbnRlciwgdGhlIGhlYWRlci9mb290ZXIgYmFuZFxuICAvLyBsaW5lcywgYW5kIGV2ZXJ5IHNpYmxpbmcncyBlZGdlcyArIGNlbnRlcnMg4oCUIHNpYmxpbmdzIG9uIHRoZSBTQU1FIGxheWVyLFxuICAvLyBzaW5jZSBhIHBhZ2UgY29tcG9uZW50IGFsaWducyB3aXRoIHRoZSBwYWdlIGFuZCBhIGhlYWRlciBibG9jayB3aXRoIHRoZVxuICAvLyBoZWFkZXIuXG4gIHByaXZhdGUgX2NhbmRpZGF0ZXMobW92aW5nOiBSZXBvcnRDb21wb25lbnQpOiB7IHZlcnRpY2FsOiBudW1iZXJbXTsgaG9yaXpvbnRhbDogbnVtYmVyW10gfSB7XG4gICAgY29uc3QgdmVydGljYWwgPSBbMCwgdGhpcy5yZXBvcnQucGFnZVdpZHRoIC8gMiwgdGhpcy5yZXBvcnQucGFnZVdpZHRoXTtcbiAgICBjb25zdCBob3Jpem9udGFsID0gWzAsIHRoaXMucmVwb3J0LnBhZ2VIZWlnaHQgLyAyLCB0aGlzLnJlcG9ydC5wYWdlSGVpZ2h0XTtcblxuICAgIGNvbnN0IHsgaGVhZGVySGVpZ2h0LCBmb290ZXJIZWlnaHQgfSA9IHRoaXMuYmFuZHM7XG4gICAgaWYgKGhlYWRlckhlaWdodCkge1xuICAgICAgaG9yaXpvbnRhbC5wdXNoKGhlYWRlckhlaWdodCk7XG4gICAgfVxuICAgIGlmIChmb290ZXJIZWlnaHQpIHtcbiAgICAgIGhvcml6b250YWwucHVzaCh0aGlzLnJlcG9ydC5wYWdlSGVpZ2h0IC0gZm9vdGVySGVpZ2h0KTtcbiAgICB9XG5cbiAgICBjb25zdCBpc01hc3RlciA9IHRoaXMubWFzdGVyQ29tcG9uZW50cy5zb21lKChjb21wb25lbnQpID0+IGNvbXBvbmVudC5pZCA9PT0gbW92aW5nLmlkKTtcbiAgICBjb25zdCBzaWJsaW5ncyA9IGlzTWFzdGVyID8gdGhpcy5tYXN0ZXJDb21wb25lbnRzIDogKHRoaXMuYWN0aXZlUGFnZT8uY29tcG9uZW50cyA/PyBbXSk7XG5cbiAgICBmb3IgKGNvbnN0IGNvbXBvbmVudCBvZiBzaWJsaW5ncykge1xuICAgICAgaWYgKGNvbXBvbmVudC5pZCA9PT0gbW92aW5nLmlkKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICB2ZXJ0aWNhbC5wdXNoKGNvbXBvbmVudC54LCBjb21wb25lbnQueCArIGNvbXBvbmVudC53IC8gMiwgY29tcG9uZW50LnggKyBjb21wb25lbnQudyk7XG4gICAgICBob3Jpem9udGFsLnB1c2goY29tcG9uZW50LnksIGNvbXBvbmVudC55ICsgY29tcG9uZW50LmggLyAyLCBjb21wb25lbnQueSArIGNvbXBvbmVudC5oKTtcbiAgICB9XG5cbiAgICByZXR1cm4geyB2ZXJ0aWNhbCwgaG9yaXpvbnRhbCB9O1xuICB9XG5cbiAgLy8gU25hcCBvbmUgYXhpczogb2YgdGhlIG1vdmluZyBib3gncyB0aHJlZSBsaW5lcyAoZWRnZS9jZW50ZXIvZWRnZSksIGZpbmRcbiAgLy8gdGhlIGNsb3Nlc3QgY2FuZGlkYXRlIHdpdGhpbiB0aHJlc2hvbGQgYW5kIHJldHVybiB0aGUgYWRqdXN0ZWQgYmFzZVxuICAvLyBjb29yZGluYXRlIHBsdXMgdGhlIGd1aWRlIHRvIGRyYXcuXG4gIHByaXZhdGUgX3NuYXBBeGlzKFxuICAgIGxpbmVzOiB7IG9mZnNldDogbnVtYmVyOyB2YWx1ZTogbnVtYmVyIH1bXSxcbiAgICBjYW5kaWRhdGVzOiBudW1iZXJbXSxcbiAgKTogeyBiYXNlOiBudW1iZXI7IGd1aWRlOiBudW1iZXIgfSB8IG51bGwge1xuICAgIGxldCBiZXN0OiB7IGJhc2U6IG51bWJlcjsgZ3VpZGU6IG51bWJlcjsgZGlzdGFuY2U6IG51bWJlciB9IHwgbnVsbCA9IG51bGw7XG5cbiAgICBmb3IgKGNvbnN0IGxpbmUgb2YgbGluZXMpIHtcbiAgICAgIGZvciAoY29uc3QgY2FuZGlkYXRlIG9mIGNhbmRpZGF0ZXMpIHtcbiAgICAgICAgY29uc3QgZGlzdGFuY2UgPSBNYXRoLmFicyhjYW5kaWRhdGUgLSBsaW5lLnZhbHVlKTtcbiAgICAgICAgaWYgKGRpc3RhbmNlIDw9IHRoaXMuX3NuYXBUaHJlc2hvbGQgJiYgKCFiZXN0IHx8IGRpc3RhbmNlIDwgYmVzdC5kaXN0YW5jZSkpIHtcbiAgICAgICAgICBiZXN0ID0geyBiYXNlOiBjYW5kaWRhdGUgLSBsaW5lLm9mZnNldCwgZ3VpZGU6IGNhbmRpZGF0ZSwgZGlzdGFuY2UgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBiZXN0ID8geyBiYXNlOiBiZXN0LmJhc2UsIGd1aWRlOiBiZXN0Lmd1aWRlIH0gOiBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBfbmVhcmVzdCh2YWx1ZTogbnVtYmVyLCBjYW5kaWRhdGVzOiBudW1iZXJbXSk6IG51bWJlciB8IG51bGwge1xuICAgIGxldCBiZXN0OiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgICBsZXQgYmVzdERpc3RhbmNlID0gdGhpcy5fc25hcFRocmVzaG9sZDtcblxuICAgIGZvciAoY29uc3QgY2FuZGlkYXRlIG9mIGNhbmRpZGF0ZXMpIHtcbiAgICAgIGNvbnN0IGRpc3RhbmNlID0gTWF0aC5hYnMoY2FuZGlkYXRlIC0gdmFsdWUpO1xuICAgICAgaWYgKGRpc3RhbmNlIDw9IGJlc3REaXN0YW5jZSkge1xuICAgICAgICBiZXN0ID0gY2FuZGlkYXRlO1xuICAgICAgICBiZXN0RGlzdGFuY2UgPSBkaXN0YW5jZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gYmVzdDtcbiAgfVxuXG4gIC8vIFRoZSBndWlkZXMgb3ZlcmxheSBpcyBkcmF3biBpbXBlcmF0aXZlbHkg4oCUIHRoZSBkcmFnIGxvb3AgcnVucyBvdXRzaWRlXG4gIC8vIEFuZ3VsYXIgYW5kIHJlcGFpbnRzIG9uIGV2ZXJ5IHBvaW50ZXJtb3ZlLlxuICBwcml2YXRlIF9yZW5kZXJHdWlkZXMoZ3VpZGVzOiBHdWlkZUxpbmVbXSk6IHZvaWQge1xuICAgIGNvbnN0IGhvc3QgPSB0aGlzLl9ndWlkZXM/Lm5hdGl2ZUVsZW1lbnQ7XG4gICAgaWYgKCFob3N0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgaG9zdC5yZXBsYWNlQ2hpbGRyZW4oLi4uZ3VpZGVzLm1hcCgoZ3VpZGUpID0+IHtcbiAgICAgIGNvbnN0IGxpbmUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICAgIGxpbmUuY2xhc3NOYW1lID0gYGd1aWRlIGd1aWRlLSR7Z3VpZGUub3JpZW50YXRpb259YDtcbiAgICAgIGlmIChndWlkZS5vcmllbnRhdGlvbiA9PT0gJ3YnKSB7XG4gICAgICAgIGxpbmUuc3R5bGUubGVmdCA9IGAke2d1aWRlLnBvc2l0aW9uICogUFhfUEVSX0lOQ0h9cHhgO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGluZS5zdHlsZS50b3AgPSBgJHtndWlkZS5wb3NpdGlvbiAqIFBYX1BFUl9JTkNIfXB4YDtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGxpbmU7XG4gICAgfSkpO1xuICB9XG5cbiAgcHJpdmF0ZSBfY2xlYXJHdWlkZXMoKTogdm9pZCB7XG4gICAgdGhpcy5fZ3VpZGVzPy5uYXRpdmVFbGVtZW50Py5yZXBsYWNlQ2hpbGRyZW4oKTtcbiAgfVxufVxuIiwiPGRpdiBjbGFzcz1cImNhbnZhc1wiPlxuICA8ZGl2XG4gICAgI3ZpZXdwb3J0XG4gICAgY2xhc3M9XCJwYWdlLXZpZXdwb3J0XCJcbiAgICAocG9pbnRlcmRvd24pPVwib25DYW52YXNQb2ludGVyRG93bigpXCI+XG4gICAgPGZzLXpvb20tcGFuXG4gICAgICBbem9vbU1pbl09XCIwLjFcIlxuICAgICAgW3pvb21NYXhdPVwiM1wiXG4gICAgICAoem9vbWVkKT1cIm9uWm9vbWVkKCRldmVudClcIj5cbiAgICAgIEBpZiAoYWN0aXZlUGFnZTsgYXMgcGFnZSkge1xuICAgICAgICA8ZGl2XG4gICAgICAgICAgY2xhc3M9XCJwYWdlXCJcbiAgICAgICAgICBbY2xhc3MuZmxvd109XCJpc0Zsb3dcIlxuICAgICAgICAgIFtjbGFzcy5lZGl0aW5nXT1cImVkaXRNb2RlXCJcbiAgICAgICAgICBbY2xhc3MubWFzdGVyLWVkaXRpbmddPVwiaXNNYXN0ZXJFZGl0aW5nXCJcbiAgICAgICAgICBbc3R5bGUud2lkdGgucHhdPVwicmVwb3J0LnBhZ2VXaWR0aCAqIFBYXCJcbiAgICAgICAgICBbc3R5bGUuaGVpZ2h0LnB4XT1cInJlcG9ydC5wYWdlSGVpZ2h0ICogUFhcIlxuICAgICAgICAgIFtzdHlsZS5wYWRkaW5nLnB4XT1cImlzRmxvdyA/IGZsb3dQYWRkaW5nICogUFggOiAwXCJcbiAgICAgICAgICBbc3R5bGUuLS1jYW52YXMtem9vbV09XCJ6b29tXCJcbiAgICAgICAgICBbc3R5bGUuLS1yZXBvcnQtaGVhZGluZy1zaXplLnB4XT1cImhlYWRpbmdTaXplUHhcIj5cbiAgICAgICAgICA8IS0tIFRoZSBoZWFkZXIgYW5kIGZvb3RlcjogdGhlIG1hc3RlcidzIGNvbXBvbmVudHMsIGFsd2F5cyBmcmVlZm9ybSxcbiAgICAgICAgICAgICAgIGRyYXduIHVuZGVyIHRoZSBwYWdlJ3Mgb3duLiBPdXQgb2YgdGhlIGZsb3cgKGFic29sdXRlKSwgc28gYSBmbG93XG4gICAgICAgICAgICAgICBwYWdlJ3Mgcm93cyBhcmUgbGFpZCBvdXQgYXMgaWYgaXQgd2VyZSBub3QgdGhlcmUuIC0tPlxuICAgICAgICAgIEBpZiAoaXNNYXN0ZXJTaG93biAmJiBtYXN0ZXJDb21wb25lbnRzLmxlbmd0aCkge1xuICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICBjbGFzcz1cIm1hc3Rlci1sYXllclwiXG4gICAgICAgICAgICAgIFtjbGFzcy5lZGl0YWJsZV09XCJpc01hc3RlckVkaXRpbmdcIj5cbiAgICAgICAgICAgICAgQGZvciAoY29tcG9uZW50IG9mIG1hc3RlckNvbXBvbmVudHM7IHRyYWNrIGNvbXBvbmVudC5pZCkge1xuICAgICAgICAgICAgICAgIDxhcHAtcmVwb3J0LWNvbXBvbmVudFxuICAgICAgICAgICAgICAgICAgW3JlcG9ydElkXT1cInJlcG9ydC5pZFwiXG4gICAgICAgICAgICAgICAgICBbY29tcG9uZW50XT1cImNvbXBvbmVudFwiXG4gICAgICAgICAgICAgICAgICBbZ3JvdXBzXT1cImdyb3Vwc1wiXG4gICAgICAgICAgICAgICAgICBbZWRpdE1vZGVdPVwiaXNNYXN0ZXJFZGl0aW5nXCJcbiAgICAgICAgICAgICAgICAgIFtsYXlvdXRdPVwiJ2ZyZWVmb3JtJ1wiXG4gICAgICAgICAgICAgICAgICBbem9vbV09XCJ6b29tXCJcbiAgICAgICAgICAgICAgICAgIFtzbmFwcGVyXT1cInNuYXBwZXJcIlxuICAgICAgICAgICAgICAgICAgW3Rva2Vuc109XCJ0b2tlbnNcIlxuICAgICAgICAgICAgICAgICAgW3NlbGVjdGVkXT1cImNvbXBvbmVudC5pZCA9PT0gc2VsZWN0ZWRDb21wb25lbnRJZFwiXG4gICAgICAgICAgICAgICAgICBbc3R5bGUubGVmdC5weF09XCJjb21wb25lbnQueCAqIFBYXCJcbiAgICAgICAgICAgICAgICAgIFtzdHlsZS50b3AucHhdPVwiY29tcG9uZW50LnkgKiBQWFwiXG4gICAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGgucHhdPVwiY29tcG9uZW50LncgKiBQWFwiXG4gICAgICAgICAgICAgICAgICBbc3R5bGUuaGVpZ2h0LnB4XT1cImNvbXBvbmVudC5hdXRvSGVpZ2h0ID8gbnVsbCA6IGNvbXBvbmVudC5oICogUFhcIlxuICAgICAgICAgICAgICAgICAgKHNlbGVjdENvbXBvbmVudCk9XCJzZWxlY3RDb21wb25lbnQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgICAocG9zaXRpb25DaGFuZ2VkKT1cIm9uUG9zaXRpb25DaGFuZ2VkKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgKHJlbW92ZWQpPVwib25Db21wb25lbnRSZW1vdmVkKCRldmVudClcIlxuICAgICAgICAgICAgICAgICAgKG9wZW5TZXR0aW5ncyk9XCJjb21wb25lbnRTZXR0aW5ncy5lbWl0KCRldmVudClcIj5cbiAgICAgICAgICAgICAgICA8L2FwcC1yZXBvcnQtY29tcG9uZW50PlxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICB9XG5cbiAgICAgICAgICA8IS0tIFRoZSBoZWFkZXIgYW5kIGZvb3RlciBiYW5kcywgYXMgZ3VpZGVzIHdoaWxlIGVkaXRpbmcuIC0tPlxuICAgICAgICAgIEBpZiAoZWRpdE1vZGUpIHtcbiAgICAgICAgICAgIEBpZiAoYmFuZHMuaGVhZGVySGVpZ2h0KSB7XG4gICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICBjbGFzcz1cImJhbmQgYmFuZC1oZWFkZXJcIlxuICAgICAgICAgICAgICAgIFtzdHlsZS5oZWlnaHQucHhdPVwiYmFuZHMuaGVhZGVySGVpZ2h0ICogUFhcIj5cbiAgICAgICAgICAgICAgICBAaWYgKGlzTWFzdGVyRWRpdGluZykge1xuICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJiYW5kLWxhYmVsIHNtYWxsXCI+SGVhZGVyPC9zcGFuPlxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBAaWYgKGJhbmRzLmZvb3RlckhlaWdodCkge1xuICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgY2xhc3M9XCJiYW5kIGJhbmQtZm9vdGVyXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUuaGVpZ2h0LnB4XT1cImJhbmRzLmZvb3RlckhlaWdodCAqIFBYXCI+XG4gICAgICAgICAgICAgICAgQGlmIChpc01hc3RlckVkaXRpbmcpIHtcbiAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPVwiYmFuZC1sYWJlbCBzbWFsbFwiPkZvb3Rlcjwvc3Bhbj5cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIEBpZiAoaXNGbG93KSB7XG4gICAgICAgICAgICBAZm9yIChjb21wb25lbnQgb2YgZmxvd0NvbXBvbmVudHM7IHRyYWNrIGNvbXBvbmVudC5pZCkge1xuICAgICAgICAgICAgICA8YXBwLXJlcG9ydC1jb21wb25lbnRcbiAgICAgICAgICAgICAgICBjbGFzcz1cImZsb3ctaXRlbVwiXG4gICAgICAgICAgICAgICAgW3JlcG9ydElkXT1cInJlcG9ydC5pZFwiXG4gICAgICAgICAgICAgICAgW2NvbXBvbmVudF09XCJjb21wb25lbnRcIlxuICAgICAgICAgICAgICAgIFtncm91cHNdPVwiZ3JvdXBzXCJcbiAgICAgICAgICAgICAgICBbZWRpdE1vZGVdPVwiaXNQYWdlRWRpdGluZ1wiXG4gICAgICAgICAgICAgICAgW2xheW91dF09XCInZmxvdydcIlxuICAgICAgICAgICAgICAgIFt6b29tXT1cInpvb21cIlxuICAgICAgICAgICAgICAgIFtzbmFwcGVyXT1cInNuYXBwZXJcIlxuICAgICAgICAgICAgICAgIFt0b2tlbnNdPVwidG9rZW5zXCJcbiAgICAgICAgICAgICAgICBbc2VsZWN0ZWRdPVwiY29tcG9uZW50LmlkID09PSBzZWxlY3RlZENvbXBvbmVudElkXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGguJV09XCJjb21wb25lbnQuZmxvd1dpZHRoXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUuaGVpZ2h0LnB4XT1cImNvbXBvbmVudC5hdXRvSGVpZ2h0ID8gbnVsbCA6IGNvbXBvbmVudC5oICogUFhcIlxuICAgICAgICAgICAgICAgIChzZWxlY3RDb21wb25lbnQpPVwic2VsZWN0Q29tcG9uZW50KCRldmVudClcIlxuICAgICAgICAgICAgICAgIChwb3NpdGlvbkNoYW5nZWQpPVwib25Qb3NpdGlvbkNoYW5nZWQoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgKGZsb3dSZW9yZGVyKT1cIm9uRmxvd1Jlb3JkZXIoJGV2ZW50KVwiXG4gICAgICAgICAgICAgICAgKHJlbW92ZWQpPVwib25Db21wb25lbnRSZW1vdmVkKCRldmVudClcIlxuICAgICAgICAgICAgICAgIChvcGVuU2V0dGluZ3MpPVwiY29tcG9uZW50U2V0dGluZ3MuZW1pdCgkZXZlbnQpXCI+XG4gICAgICAgICAgICAgIDwvYXBwLXJlcG9ydC1jb21wb25lbnQ+XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBAZWxzZSB7XG4gICAgICAgICAgICBAZm9yIChjb21wb25lbnQgb2YgcGFnZS5jb21wb25lbnRzOyB0cmFjayBjb21wb25lbnQuaWQpIHtcbiAgICAgICAgICAgICAgPGFwcC1yZXBvcnQtY29tcG9uZW50XG4gICAgICAgICAgICAgICAgW3JlcG9ydElkXT1cInJlcG9ydC5pZFwiXG4gICAgICAgICAgICAgICAgW2NvbXBvbmVudF09XCJjb21wb25lbnRcIlxuICAgICAgICAgICAgICAgIFtncm91cHNdPVwiZ3JvdXBzXCJcbiAgICAgICAgICAgICAgICBbZWRpdE1vZGVdPVwiaXNQYWdlRWRpdGluZ1wiXG4gICAgICAgICAgICAgICAgW2xheW91dF09XCInZnJlZWZvcm0nXCJcbiAgICAgICAgICAgICAgICBbem9vbV09XCJ6b29tXCJcbiAgICAgICAgICAgICAgICBbc25hcHBlcl09XCJzbmFwcGVyXCJcbiAgICAgICAgICAgICAgICBbdG9rZW5zXT1cInRva2Vuc1wiXG4gICAgICAgICAgICAgICAgW3NlbGVjdGVkXT1cImNvbXBvbmVudC5pZCA9PT0gc2VsZWN0ZWRDb21wb25lbnRJZFwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLmxlZnQucHhdPVwiY29tcG9uZW50LnggKiBQWFwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLnRvcC5weF09XCJjb21wb25lbnQueSAqIFBYXCJcbiAgICAgICAgICAgICAgICBbc3R5bGUud2lkdGgucHhdPVwiY29tcG9uZW50LncgKiBQWFwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLmhlaWdodC5weF09XCJjb21wb25lbnQuYXV0b0hlaWdodCA/IG51bGwgOiBjb21wb25lbnQuaCAqIFBYXCJcbiAgICAgICAgICAgICAgICAoc2VsZWN0Q29tcG9uZW50KT1cInNlbGVjdENvbXBvbmVudCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAocG9zaXRpb25DaGFuZ2VkKT1cIm9uUG9zaXRpb25DaGFuZ2VkKCRldmVudClcIlxuICAgICAgICAgICAgICAgIChyZW1vdmVkKT1cIm9uQ29tcG9uZW50UmVtb3ZlZCgkZXZlbnQpXCJcbiAgICAgICAgICAgICAgICAob3BlblNldHRpbmdzKT1cImNvbXBvbmVudFNldHRpbmdzLmVtaXQoJGV2ZW50KVwiPlxuICAgICAgICAgICAgICA8L2FwcC1yZXBvcnQtY29tcG9uZW50PlxuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cblxuICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICNndWlkZXNcbiAgICAgICAgICAgIGNsYXNzPVwiZ3VpZGVzXCI+XG4gICAgICAgICAgPC9kaXY+XG5cbiAgICAgICAgICBAaWYgKCFwYWdlLmNvbXBvbmVudHMubGVuZ3RoICYmICFtYXN0ZXJNb2RlKCkpIHtcbiAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJwYWdlLWVtcHR5XCI+XG4gICAgICAgICAgICAgIEFzayB0aGUgYXNzaXN0YW50IHRvIGFkZCBhIGNoYXJ0LCBsaXN0IG9yIEtQSSB0byB0aGlzIHBhZ2UuXG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICB9XG4gICAgICAgIDwvZGl2PlxuICAgICAgfVxuICAgIDwvZnMtem9vbS1wYW4+XG4gIDwvZGl2PlxuXG4gIDxkaXYgY2xhc3M9XCJjYW52YXMtdG9vbGJhclwiPlxuICAgIDwhLS0gVGFicyBhcmUgb25lIGhvcml6b250YWwgZHJvcCBsaXN0OiBkcmFnZ2luZyBhIGNoaXAgcmVvcmRlcnMgdGhlIHBhZ2VzLlxuICAgICAgICAgVGhlIGRyb3AgSU5ERVggaXMgY29tcHV0ZWQgYWxvbmcgWCAob3JpZW50YXRpb24pLCBidXQgdGhlIHByZXZpZXcgaXNcbiAgICAgICAgIGRlbGliZXJhdGVseSBsZWZ0IHVuYm91bmRlZCBvbiBib3RoIGF4ZXMg4oCUIHBpbm5pbmcgaXQgdG8gdGhlIHJvdyB3aXRoXG4gICAgICAgICBjZGtEcmFnQm91bmRhcnkgbWVhbnMgdGhlIGNoaXAgeW91IGFyZSBkcmFnZ2luZyBjb3ZlcnMgdGhlIGNoaXBzIHlvdVxuICAgICAgICAgYXJlIGRyYWdnaW5nIGl0IHBhc3QsIGFuZCB5b3UgY2Fubm90IHNlZSB3aGVyZSBpdCBpcyBnb2luZyB0byBsYW5kLlxuICAgICAgICAgRXZlcnkgcGFnZSBnZXRzIGEgY2hpcCwgaW5jbHVkaW5nIGEgbG9uZSBvbmU6IHRoZSBjaGlwIGlzIHdoYXQgdGVsbHNcbiAgICAgICAgIHlvdSB3aGljaCBwYWdlIHlvdSBhcmUgb24sIGFuZCBhIHJlcG9ydCB0aGF0IGhpZCBpdCBsZWZ0IHlvdSB1bmFibGUgdG9cbiAgICAgICAgIHRlbGwgcGFnZSAxIG9mIDEgZnJvbSBhIHBhZ2UgdGhhdCBmYWlsZWQgdG8gbG9hZC4gRGVsZXRpbmcgdGhlIGxhc3RcbiAgICAgICAgIHBhZ2UgaXMgcmVmdXNlZCBzZXJ2ZXItc2lkZSwgc28gdGhlIGtlYmFiIGlzIHNhZmUgdG8gZXhwb3NlIGhlcmUuIC0tPlxuICAgIDxkaXZcbiAgICAgIGNsYXNzPVwicGFnZS10YWJzXCJcbiAgICAgIGNka0Ryb3BMaXN0XG4gICAgICBjZGtEcm9wTGlzdE9yaWVudGF0aW9uPVwiaG9yaXpvbnRhbFwiXG4gICAgICAoY2RrRHJvcExpc3REcm9wcGVkKT1cIm9uUGFnZURyb3BwZWQoJGV2ZW50KVwiPlxuICAgICAgQGZvciAocGFnZSBvZiByZXBvcnQ/LnBhZ2VzID8/IFtdOyB0cmFjayBwYWdlLmlkOyBsZXQgaW5kZXggPSAkaW5kZXgpIHtcbiAgICAgICAgPCEtLSBUaGUgY2hpcCBpcyB0aGUgZHJhZyBoYW5kbGUgQU5EIHRoZSB0YWI6IGNsaWNraW5nIHNlbGVjdHMsXG4gICAgICAgICAgICAgZHJhZ2dpbmcgcmVvcmRlcnMuIFRoZSBrZWJhYiBsaXZlcyBpbnNpZGUgaXQsIHNvIHRoZSB3aG9sZVxuICAgICAgICAgICAgIGNvbnRyb2wgc3RheXMgb25lIGNoaXAgaW5zdGVhZCBvZiBncm93aW5nIGEgc2Vjb25kIGJ1dHRvbi4gLS0+XG4gICAgICAgIDxkaXZcbiAgICAgICAgICBjZGtEcmFnXG4gICAgICAgICAgY2xhc3M9XCJwYWdlLXRhYlwiXG4gICAgICAgICAgW2NsYXNzLmFjdGl2ZV09XCJpbmRleCA9PT0gYWN0aXZlUGFnZUluZGV4XCJcbiAgICAgICAgICAoY2xpY2spPVwic2VsZWN0UGFnZShpbmRleClcIj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInBhZ2UtdGFiLWxhYmVsXCI+e3sgcGFnZUxhYmVsKHBhZ2UsIGluZGV4KSB9fTwvc3Bhbj5cbiAgICAgICAgICA8IS0tIFRoZSBrZWJhYiBvcGVucyB0aGUgbWVudSByYXRoZXIgdGhhbiBzdGFydGluZyBhIGRyYWcgb3JcbiAgICAgICAgICAgICAgIHN3aXRjaGluZyBwYWdlcywgc28gaXQgc3dhbGxvd3MgaXRzIG93biBjbGljay4gLS0+XG4gICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgIGNsYXNzPVwicGFnZS10YWItbWVudVwiXG4gICAgICAgICAgICBbZnNNZW51VHJpZ2dlckZvcl09XCJwYWdlTWVudVwiXG4gICAgICAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAgICAgIChtb3VzZWRvd24pPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCI+XG4gICAgICAgICAgICA8bWF0LWljb24+bW9yZV92ZXJ0PC9tYXQtaWNvbj5cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8IS0tIE91dHNpZGUgdGhlIGNoaXA6IGNka0RyYWcgY2xvbmVzIGl0cyBob3N0IGludG8gdGhlIGRyYWcgcHJldmlldyxcbiAgICAgICAgICAgICBhbmQgYSBtZW51IG92ZXJsYXkgYW5jaG9yZWQgdG8gYSBjbG9uZWQgdHJpZ2dlciBvcGVucyBkZXRhY2hlZFxuICAgICAgICAgICAgIGZyb20gdGhlIHJlYWwgdGFiLiAtLT5cbiAgICAgICAgPGZzLW1lbnUgI3BhZ2VNZW51PlxuICAgICAgICAgIDxuZy10ZW1wbGF0ZVxuICAgICAgICAgICAgZnMtbWVudS1pdGVtXG4gICAgICAgICAgICAoY2xpY2spPVwicmVuYW1lUGFnZShwYWdlKVwiPlxuICAgICAgICAgICAgRWRpdCBuYW1lXG4gICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgIGZzLW1lbnUtaXRlbVxuICAgICAgICAgICAgKGNsaWNrKT1cInRvZ2dsZU1hc3RlckhpZGRlbihwYWdlKVwiPlxuICAgICAgICAgICAge3sgcGFnZS5tYXN0ZXJIaWRkZW4gPyAnU2hvdyBoZWFkZXIgJiBmb290ZXInIDogJ0hpZGUgaGVhZGVyICYgZm9vdGVyJyB9fVxuICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICBmcy1tZW51LWl0ZW1cbiAgICAgICAgICAgIChjbGljayk9XCJkZWxldGVQYWdlKHBhZ2UpXCI+XG4gICAgICAgICAgICBEZWxldGVcbiAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICA8L2ZzLW1lbnU+XG4gICAgICB9XG4gICAgICA8YnV0dG9uXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBjbGFzcz1cInBhZ2UtdGFiIGFkZC1wYWdlXCJcbiAgICAgICAgbWF0VG9vbHRpcD1cIkFkZCBwYWdlXCJcbiAgICAgICAgKGNsaWNrKT1cImFkZFBhZ2UoKVwiPlxuICAgICAgICA8bWF0LWljb24+YWRkPC9tYXQtaWNvbj5cbiAgICAgICAgUGFnZVxuICAgICAgPC9idXR0b24+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiem9vbS1jb250cm9sc1wiPlxuICAgICAgPGJ1dHRvblxuICAgICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICAgY2xhc3M9XCJ6b29tLWJ1dHRvblwiXG4gICAgICAgIG1hdFRvb2x0aXA9XCJab29tIG91dFwiXG4gICAgICAgIChjbGljayk9XCJ6b29tT3V0KClcIj5cbiAgICAgICAgPG1hdC1pY29uPnJlbW92ZTwvbWF0LWljb24+XG4gICAgICA8L2J1dHRvbj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIGNsYXNzPVwiem9vbS1sYWJlbFwiXG4gICAgICAgIG1hdFRvb2x0aXA9XCJab29tIHRvIDEwMCVcIlxuICAgICAgICAoY2xpY2spPVwiem9vbUFjdHVhbCgpXCI+XG4gICAgICAgIHt7ICh6b29tICogMTAwKS50b0ZpeGVkKDApIH19JVxuICAgICAgPC9idXR0b24+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBjbGFzcz1cInpvb20tYnV0dG9uXCJcbiAgICAgICAgbWF0VG9vbHRpcD1cIlpvb20gaW5cIlxuICAgICAgICAoY2xpY2spPVwiem9vbUluKClcIj5cbiAgICAgICAgPG1hdC1pY29uPmFkZDwvbWF0LWljb24+XG4gICAgICA8L2J1dHRvbj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIGNsYXNzPVwiem9vbS1idXR0b25cIlxuICAgICAgICBtYXRUb29sdGlwPVwiRml0IHBhZ2VcIlxuICAgICAgICAoY2xpY2spPVwiem9vbUZpdCgpXCI+XG4gICAgICAgIDxtYXQtaWNvbj5maXRfc2NyZWVuPC9tYXQtaWNvbj5cbiAgICAgIDwvYnV0dG9uPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbjwvZGl2PlxuIl19