@jax-data-science/sci-image-visualizer 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/index.mjs +7 -1
- package/esm2022/lib/contracts/image.contract.mjs +1 -1
- package/esm2022/lib/contracts/region-editor-api.contract.mjs +1 -1
- package/esm2022/lib/contracts/region-store.contract.mjs +1 -1
- package/esm2022/lib/contracts/section-view.contract.mjs +2 -0
- package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
- package/esm2022/lib/contracts/viz-config.mjs +1 -1
- package/esm2022/lib/geometry/loft.mjs +128 -0
- package/esm2022/lib/geometry/polylabel.mjs +156 -0
- package/esm2022/lib/geometry/reconstruct.mjs +315 -0
- package/esm2022/lib/geometry/reslice-image.mjs +57 -0
- package/esm2022/lib/geometry/section.mjs +215 -0
- package/esm2022/lib/implementations/napari-js/napari-loading-badge.mjs +11 -7
- package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +20 -3
- package/esm2022/lib/implementations/napari-js/napari-region-mesh-pointer.mjs +100 -0
- package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +28 -5
- package/esm2022/lib/implementations/napari-js/napari-scene.mjs +1 -1
- package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +9 -2
- package/esm2022/lib/implementations/napari-js/napari-tool-bridge.mjs +5 -2
- package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +81 -1
- package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +129 -0
- package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +115 -4
- package/esm2022/lib/implementations/napari-js/napari-volume-slice-planes.mjs +103 -0
- package/esm2022/lib/implementations/napari-js/region-overlay/region-svg-renderer.mjs +15 -3
- package/esm2022/lib/implementations/osd/osd-region-overlay-draw.mjs +18 -7
- package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +38 -8
- package/esm2022/lib/implementations/tile-server/tile-protocol.mjs +1 -1
- package/esm2022/lib/models/class-preset.mjs +1 -1
- package/esm2022/lib/models/polygon-factory.mjs +17 -1
- package/esm2022/lib/models/region-geojson.mjs +44 -6
- package/esm2022/lib/models/region.mjs +1 -1
- package/esm2022/lib/region-editor/class-tree/class-tree.component.mjs +156 -0
- package/esm2022/lib/region-editor/class-tree/class-tree.mjs +108 -0
- package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +77 -13
- package/esm2022/lib/region-editor/region-editor.component.mjs +527 -42
- package/esm2022/lib/region-editor/region-metrics.mjs +20 -2
- package/esm2022/lib/region-editor/region-persistence.service.mjs +36 -10
- package/esm2022/lib/region-editor/region-table/region-table.component.mjs +24 -8
- package/esm2022/lib/region-overlay/region-geometry.mjs +3 -3
- package/esm2022/lib/region-overlay/region-source-layer.mjs +378 -0
- package/esm2022/lib/region-overlay/region-style.mjs +97 -0
- package/esm2022/lib/region-source/http-region-source.mjs +104 -0
- package/esm2022/lib/region-source/region-source-ops.mjs +53 -0
- package/esm2022/lib/region-source/region-source-worker.mjs +10 -0
- package/esm2022/lib/region-source/region-source.mjs +67 -0
- package/esm2022/lib/region-source/region-tiles.mjs +708 -0
- package/esm2022/lib/region-source/worker-region-source.mjs +229 -0
- package/esm2022/lib/routing-visualizer.service.mjs +418 -22
- package/esm2022/lib/section-pane/section-pane.component.mjs +299 -0
- package/esm2022/lib/store/class-color.util.mjs +10 -5
- package/esm2022/lib/store/class-signatures.mjs +63 -0
- package/esm2022/lib/store/region-scope-cache.mjs +5 -1
- package/esm2022/lib/store/region-source-scope.mjs +171 -0
- package/esm2022/lib/store/region-store.service.mjs +724 -12
- package/esm2022/lib/store/visualizer-store.service.mjs +33 -6
- package/esm2022/lib/toolbar/region-tools/region-tools.component.mjs +8 -2
- package/esm2022/lib/toolbar/stack-controls/stack-controls.component.mjs +55 -15
- package/esm2022/lib/toolbar/toolbar.component.mjs +19 -5
- package/esm2022/lib/visualizer/region-load.mjs +67 -4
- package/esm2022/lib/visualizer/volume-sections.mjs +175 -0
- package/esm2022/lib/visualizer.component.mjs +128 -6
- package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BKQhpbHv.mjs} +7239 -1153
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BKQhpbHv.mjs.map +1 -0
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-z1IN-F7w.mjs} +4 -4
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-z1IN-F7w.mjs.map} +1 -1
- package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.mjs +12 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs +3 -3
- package/fesm2022/region-source.worker.js +1067 -0
- package/index.d.ts +6 -0
- package/lib/contracts/image.contract.d.ts +4 -0
- package/lib/contracts/region-editor-api.contract.d.ts +84 -0
- package/lib/contracts/region-store.contract.d.ts +22 -0
- package/lib/contracts/section-view.contract.d.ts +44 -0
- package/lib/contracts/visualizer.contract.d.ts +10 -0
- package/lib/contracts/viz-config.d.ts +8 -0
- package/lib/geometry/loft.d.ts +22 -0
- package/lib/geometry/polylabel.d.ts +23 -0
- package/lib/geometry/reconstruct.d.ts +54 -0
- package/lib/geometry/reslice-image.d.ts +33 -0
- package/lib/geometry/section.d.ts +52 -0
- package/lib/implementations/napari-js/napari-loading-badge.d.ts +4 -2
- package/lib/implementations/napari-js/napari-loading-state.d.ts +8 -1
- package/lib/implementations/napari-js/napari-region-mesh-pointer.d.ts +32 -0
- package/lib/implementations/napari-js/napari-region-overlay.d.ts +6 -1
- package/lib/implementations/napari-js/napari-scene.d.ts +33 -0
- package/lib/implementations/napari-js/napari-spatial-hover.d.ts +3 -1
- package/lib/implementations/napari-js/napari-visualizer.service.d.ts +48 -0
- package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +66 -0
- package/lib/implementations/napari-js/napari-volume-scene.d.ts +45 -1
- package/lib/implementations/napari-js/napari-volume-slice-planes.d.ts +43 -0
- package/lib/implementations/osd/osd-region-overlay-draw.d.ts +4 -3
- package/lib/implementations/osd/osd-region-overlay.d.ts +10 -3
- package/lib/implementations/tile-server/tile-protocol.d.ts +3 -0
- package/lib/models/class-preset.d.ts +7 -0
- package/lib/models/polygon-factory.d.ts +5 -0
- package/lib/models/region-geojson.d.ts +40 -0
- package/lib/models/region.d.ts +19 -0
- package/lib/region-editor/class-tree/class-tree.component.d.ts +78 -0
- package/lib/region-editor/class-tree/class-tree.d.ts +31 -0
- package/lib/region-editor/classes-panel/classes-panel.component.d.ts +36 -6
- package/lib/region-editor/region-editor.component.d.ts +133 -17
- package/lib/region-editor/region-metrics.d.ts +8 -0
- package/lib/region-editor/region-persistence.service.d.ts +12 -4
- package/lib/region-editor/region-table/region-table.component.d.ts +10 -4
- package/lib/region-overlay/region-geometry.d.ts +4 -3
- package/lib/region-overlay/region-source-layer.d.ts +96 -0
- package/lib/region-overlay/region-style.d.ts +52 -0
- package/lib/region-source/http-region-source.d.ts +45 -0
- package/lib/region-source/region-source-ops.d.ts +89 -0
- package/lib/region-source/region-source-worker.d.ts +7 -0
- package/lib/region-source/region-source.d.ts +82 -0
- package/lib/region-source/region-tiles.d.ts +289 -0
- package/lib/region-source/worker-region-source.d.ts +65 -0
- package/lib/routing-visualizer.service.d.ts +138 -1
- package/lib/section-pane/section-pane.component.d.ts +47 -0
- package/lib/store/class-color.util.d.ts +6 -3
- package/lib/store/class-signatures.d.ts +11 -0
- package/lib/store/region-scope-cache.d.ts +2 -0
- package/lib/store/region-source-scope.d.ts +68 -0
- package/lib/store/region-store.service.d.ts +206 -2
- package/lib/store/visualizer-store.service.d.ts +10 -0
- package/lib/toolbar/region-tools/region-tools.component.d.ts +3 -1
- package/lib/toolbar/stack-controls/stack-controls.component.d.ts +20 -9
- package/lib/toolbar/toolbar.component.d.ts +9 -2
- package/lib/visualizer/region-load.d.ts +23 -4
- package/lib/visualizer/volume-sections.d.ts +64 -0
- package/lib/visualizer.component.d.ts +31 -0
- package/package.json +2 -2
- package/src/lib/assets/slice.svg +23 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs.map +0 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, DestroyRef, ElementRef, EventEmitter, Inject, Injector, Input, NgZone, Optional, Output, ViewChild, computed, signal, } from '@angular/core';
|
|
2
2
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
3
3
|
import { CommonModule } from '@angular/common';
|
|
4
|
+
import { HttpClient } from '@angular/common/http';
|
|
4
5
|
import { FormsModule } from '@angular/forms';
|
|
5
6
|
import { Observable } from 'rxjs';
|
|
6
7
|
import { MessageService, SharedModule } from 'primeng/api';
|
|
@@ -20,7 +21,7 @@ import { VIZ_TOAST_KEY, VIZ_ALERT_TOAST_KEY } from './toast-outlets';
|
|
|
20
21
|
import { VisualizerStore } from './store/visualizer-store.service';
|
|
21
22
|
import { SliceScrubber } from './render-orchestrator';
|
|
22
23
|
import { ImageRenderSession, errorMessage } from './render-session';
|
|
23
|
-
import { PlotType, getPlotTypeDescriptor, isBuiltinPlotType, isNapari3d, isSpatialOmics, isSpatialOmics3d, rendererOwnsWheel, NAPARI_DEFAULT_DECIMATE, } from './contracts/plot-type';
|
|
24
|
+
import { PlotType, getPlotTypeDescriptor, isBuiltinPlotType, isNapari3d, isSpatialOmics, isSpatialOmics3d, rendererOwnsWheel, NAPARI_DEFAULT_DECIMATE, isNapariVolume, isNapariIsosurface, } from './contracts/plot-type';
|
|
24
25
|
import { PLOT_TYPE_CONTRIBUTIONS, } from './contracts/plot-type-contribution.contract';
|
|
25
26
|
import { computePlotTypeMenu, reconcilePlotType } from './plot-mode/plot-type-menu';
|
|
26
27
|
import { ToolParamsModel } from './plot-mode/tool-params-model';
|
|
@@ -42,6 +43,7 @@ import { ToolModes } from './visualizer/tool-modes';
|
|
|
42
43
|
import { ViewerShortcuts } from './visualizer/viewer-shortcuts';
|
|
43
44
|
import { FloatingDragDirective } from './visualizer/floating-drag.directive';
|
|
44
45
|
import { IntensityInsetComponent } from './intensity-inset/intensity-inset.component';
|
|
46
|
+
import { SectionPaneComponent } from './section-pane/section-pane.component';
|
|
45
47
|
import { SpatialDatasetBinder } from './visualizer/spatial-dataset-binder';
|
|
46
48
|
import { ToolbarComponent } from './toolbar/toolbar.component';
|
|
47
49
|
import { RegionEditorComponent } from './region-editor/region-editor.component';
|
|
@@ -197,6 +199,96 @@ export class VisualizerComponent {
|
|
|
197
199
|
get isSpatial3dMode() {
|
|
198
200
|
return isSpatialOmics3d(this.basePlotType);
|
|
199
201
|
}
|
|
202
|
+
/** True in a napari volume or isosurface view, where the Region Editor shows regions in 3D. */
|
|
203
|
+
get isVolumeView() {
|
|
204
|
+
return isNapariVolume(this.basePlotType) || isNapariIsosurface(this.basePlotType);
|
|
205
|
+
}
|
|
206
|
+
get sliceEditorShown() {
|
|
207
|
+
return this.sliceEditor && this.isVolumeView;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Split the volume view with the slice editor, or close it. The editor opens on the displayed
|
|
211
|
+
* slice and takes the drawing tools; closing it leaves the selection tool armed (it picks the
|
|
212
|
+
* surfaces in 3D) and disarms any other.
|
|
213
|
+
*/
|
|
214
|
+
async toggleSliceEditor() {
|
|
215
|
+
this.sliceEditor = !this.sliceEditor;
|
|
216
|
+
this.cdr.detectChanges(); // the pane's div, before the backend looks it up
|
|
217
|
+
this.plotService.relayout(); // the 3D view is a quarter of the area now, or all of it again
|
|
218
|
+
if (!this.sliceEditor) {
|
|
219
|
+
await this.plotService.setSliceEditor?.(null);
|
|
220
|
+
if (this.tools.active !== null && this.tools.active !== 'select')
|
|
221
|
+
this.tools.apply(null);
|
|
222
|
+
this.changed();
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
// The regions edited are the displayed slice's.
|
|
226
|
+
this.plotService.setDisplaySlice(this.zIndex);
|
|
227
|
+
const shown = await this.plotService.setSliceEditor?.(this.sliceDivName);
|
|
228
|
+
// The armed tool now acts in the pane.
|
|
229
|
+
if (shown && this.tools.active !== null)
|
|
230
|
+
this.tools.apply(this.tools.active);
|
|
231
|
+
this.changed();
|
|
232
|
+
}
|
|
233
|
+
/** A point picked in a section: the slice and the other section's plane move there. */
|
|
234
|
+
onSectionPick(axis, at) {
|
|
235
|
+
// Through x, across is the slice and down is y; through y, across is x and down the slice.
|
|
236
|
+
const slice = Math.floor(axis === 'x' ? at.u : at.v);
|
|
237
|
+
if (axis === 'x')
|
|
238
|
+
this.plotService.setSectionPlane?.('y', at.v);
|
|
239
|
+
else
|
|
240
|
+
this.plotService.setSectionPlane?.('x', at.u);
|
|
241
|
+
this.onZSlide(Math.min(this.maxIndex, Math.max(0, slice)));
|
|
242
|
+
}
|
|
243
|
+
/** Drag a divider of the slice editor: the vertical one sets the columns, the horizontal one the rows. */
|
|
244
|
+
startPaneResize(event, axis) {
|
|
245
|
+
const divider = event.currentTarget;
|
|
246
|
+
const panes = divider.parentElement;
|
|
247
|
+
if (!panes)
|
|
248
|
+
return;
|
|
249
|
+
event.preventDefault();
|
|
250
|
+
divider.setPointerCapture(event.pointerId);
|
|
251
|
+
const move = (e) => {
|
|
252
|
+
const box = panes.getBoundingClientRect();
|
|
253
|
+
if (axis === 'x' && box.width > 0)
|
|
254
|
+
this.setSplit('x', ((e.clientX - box.left) / box.width) * 100);
|
|
255
|
+
if (axis === 'y' && box.height > 0)
|
|
256
|
+
this.setSplit('y', ((e.clientY - box.top) / box.height) * 100);
|
|
257
|
+
};
|
|
258
|
+
const end = () => {
|
|
259
|
+
divider.removeEventListener('pointermove', move);
|
|
260
|
+
divider.removeEventListener('pointerup', end);
|
|
261
|
+
divider.removeEventListener('pointercancel', end);
|
|
262
|
+
};
|
|
263
|
+
divider.addEventListener('pointermove', move);
|
|
264
|
+
divider.addEventListener('pointerup', end);
|
|
265
|
+
divider.addEventListener('pointercancel', end);
|
|
266
|
+
}
|
|
267
|
+
/** A divider's keyboard: ← → move the vertical one, ↑ ↓ the horizontal one, by 5%. */
|
|
268
|
+
nudgePaneSize(event, axis) {
|
|
269
|
+
const keys = axis === 'x' ? ['ArrowLeft', 'ArrowRight'] : ['ArrowUp', 'ArrowDown'];
|
|
270
|
+
const step = event.key === keys[0] ? -5 : event.key === keys[1] ? 5 : 0;
|
|
271
|
+
if (!step)
|
|
272
|
+
return;
|
|
273
|
+
event.preventDefault();
|
|
274
|
+
event.stopPropagation(); // not a slice step
|
|
275
|
+
this.setSplit(axis, (axis === 'x' ? this.splitX : this.splitY) + step);
|
|
276
|
+
}
|
|
277
|
+
setSplit(axis, percent) {
|
|
278
|
+
const value = Math.round(Math.min(80, Math.max(20, percent)));
|
|
279
|
+
if (axis === 'x')
|
|
280
|
+
this.splitX = value;
|
|
281
|
+
else
|
|
282
|
+
this.splitY = value;
|
|
283
|
+
this.changed();
|
|
284
|
+
// The 3D view follows its cell once the grid has its new tracks.
|
|
285
|
+
if (this.relayoutFrame === null && typeof requestAnimationFrame !== 'undefined') {
|
|
286
|
+
this.relayoutFrame = requestAnimationFrame(() => {
|
|
287
|
+
this.relayoutFrame = null;
|
|
288
|
+
this.plotService.relayout();
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
}
|
|
200
292
|
/** True for the Image plot type, which renders as a natively pan/zoom-able
|
|
201
293
|
* raster — so the backend-agnostic zoom/pan toolbar tools are hidden. The
|
|
202
294
|
* component drives this off the plot type, not the active backend. */
|
|
@@ -344,7 +436,9 @@ export class VisualizerComponent {
|
|
|
344
436
|
this.state.setImageLoading(false);
|
|
345
437
|
},
|
|
346
438
|
landed: (info) => {
|
|
347
|
-
|
|
439
|
+
// The host's HttpClient carries a server-side region source's requests: its interceptors (auth) apply.
|
|
440
|
+
const http = this.injector?.get(HttpClient, null) ?? undefined;
|
|
441
|
+
applyImageRois(info, this.plotService, this.zIndex, this.vizConfig?.regionSourceMinChars, http);
|
|
348
442
|
this.contributions.activate();
|
|
349
443
|
},
|
|
350
444
|
setImageLoading: (loading) => this.state.setImageLoading(loading),
|
|
@@ -391,6 +485,17 @@ export class VisualizerComponent {
|
|
|
391
485
|
}
|
|
392
486
|
return this.toolbarPos;
|
|
393
487
|
};
|
|
488
|
+
/** Whether the user split the volume view with the slice editor (off by default; kept while
|
|
489
|
+
* the view shows other plot types, so a volume view opens split again). */
|
|
490
|
+
this.sliceEditor = false;
|
|
491
|
+
/** The slice editor's pane: the displayed slice, with every region tool, top right. */
|
|
492
|
+
this.sliceDivName = `${this.plotDivName}-slice`;
|
|
493
|
+
/** The left column's and the top row's shares of the slice editor (%). */
|
|
494
|
+
this.splitX = 50;
|
|
495
|
+
this.splitY = 50;
|
|
496
|
+
/** The sections through x and y shown below (nulls until the volume is cut). */
|
|
497
|
+
this.sections = { x: null, y: null };
|
|
498
|
+
this.relayoutFrame = null;
|
|
394
499
|
/** Isosurface band as a 0–255 slider position, mapped onto the volume's real
|
|
395
500
|
* intensity range by the renderer. Defaults to the full range. */
|
|
396
501
|
this.isoRange = [0, 255];
|
|
@@ -531,6 +636,22 @@ export class VisualizerComponent {
|
|
|
531
636
|
this.mirror(this.state.isImageLoading$(), (v) => this.imgLoading.set(v));
|
|
532
637
|
this.mirror(this.plotService.getStackLoadingProgress(), (v) => this.loadingPercentage.set(v));
|
|
533
638
|
this.mirror(this.plotService.isStackLoading(), (v) => this.stackLoading.set(v));
|
|
639
|
+
// The slice editor: its sections, and the slice picked by dragging the z plane in the volume.
|
|
640
|
+
const sections$ = this.plotService.getSectionViews$?.();
|
|
641
|
+
if (sections$) {
|
|
642
|
+
this.mirror(sections$, (v) => {
|
|
643
|
+
this.sections = v;
|
|
644
|
+
this.changed();
|
|
645
|
+
});
|
|
646
|
+
}
|
|
647
|
+
const sliceDrag$ = this.plotService.getSliceDrag$?.();
|
|
648
|
+
if (sliceDrag$) {
|
|
649
|
+
this.mirror(sliceDrag$, (z) => {
|
|
650
|
+
this.onZScrub(Math.min(this.maxIndex, Math.max(0, z)));
|
|
651
|
+
// From a DOM listener, not a template event: the slider and badge must be marked to follow.
|
|
652
|
+
this.changed();
|
|
653
|
+
});
|
|
654
|
+
}
|
|
534
655
|
this.mirror(this.state.getImageLoadingMessage$(), (v) => this.loadingMessage.set(v));
|
|
535
656
|
this.mirror(this.state.getCacheProgress$(), (v) => this.cacheProgress.set(v));
|
|
536
657
|
this.mirror(this.state.isZoom$(), (v) => this.zoom.set(v));
|
|
@@ -674,7 +795,7 @@ export class VisualizerComponent {
|
|
|
674
795
|
plotDivName: this.plotDivName,
|
|
675
796
|
hostElement: this.hostRef?.nativeElement ?? null,
|
|
676
797
|
activeDragMode: () => this.activeDragMode,
|
|
677
|
-
canStepSlice: () => !!this.imageInfo?.isStack && this.isImageView,
|
|
798
|
+
canStepSlice: () => !!this.imageInfo?.isStack && (this.isImageView || this.sliceEditorShown),
|
|
678
799
|
wheelZooms: () => !rendererOwnsWheel(this.basePlotType) && this.isHeatmap,
|
|
679
800
|
stepSlice: marked((delta) => this.stepSlice(delta)),
|
|
680
801
|
resolveSamPrompt: marked((commit) => {
|
|
@@ -1094,7 +1215,7 @@ export class VisualizerComponent {
|
|
|
1094
1215
|
this.contributions.attachToolDialogSlot(ref?.nativeElement);
|
|
1095
1216
|
}
|
|
1096
1217
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: VisualizerComponent, deps: [{ token: IMAGE_STATE_PORT }, { token: VISUALIZER }, { token: i1.MessageService }, { token: i0.NgZone }, { token: i0.ChangeDetectorRef }, { token: i2.VisualizerStore }, { token: i3.SamToolService }, { token: i4.CellSegmentToolService }, { token: i5.SamPointToolService }, { token: i6.RegionOpsService }, { token: VIZ_CONFIG, optional: true }, { token: TOOLBAR_TOOLS, optional: true }, { token: SPATIAL_DATA_PORT, optional: true }, { token: PLOT_TYPE_CONTRIBUTIONS, optional: true }, { token: i0.Injector, optional: true }, { token: i0.ElementRef, optional: true }, { token: i0.DestroyRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1097
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: VisualizerComponent, isStandalone: true, selector: "visualizer", inputs: { toolbarTools: "toolbarTools", testMode: "testMode" }, outputs: { isStackEvent: "isStackEvent", isGrayscaleEvent: "isGrayscaleEvent" }, viewQueries: [{ propertyName: "contextMenu", first: true, predicate: ["cm"], descendants: true }, { propertyName: "plotModePanelSlot", first: true, predicate: ["plotModePanelSlot"], descendants: true }, { propertyName: "inset", first: true, predicate: IntensityInsetComponent, descendants: true, static: true }, { propertyName: "toolDialogSlot", first: true, predicate: ["toolDialogSlot"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<!-- SAM toast: live status + encoder-download progress bar (jit-ui#90). Sticky\n while a segment runs; stays open until the bar reaches 100% and the run ends. -->\n<p-toast [key]=\"samToastKey\" position=\"bottom-right\">\n <ng-template let-message pTemplate=\"message\">\n <div style=\"flex: 1; min-width: 16rem\">\n <div class=\"font-bold mb-1\">{{ message.summary }}</div>\n <div>{{ segmentation.status || message.detail }}</div>\n <p-progressBar\n *ngIf=\"segmentation.downloading\"\n [value]=\"segmentation.progress\"\n styleClass=\"mt-2 sam-progress\"\n ></p-progressBar>\n <p-progressBar\n *ngIf=\"segmentation.busy && !segmentation.downloading\"\n mode=\"indeterminate\"\n styleClass=\"mt-2\"\n [style]=\"{ height: '4px' }\"\n ></p-progressBar>\n </div>\n </ng-template>\n</p-toast>\n\n<!-- Result/error notices from the library itself (segmentation outcome, region\n validation). Rendered here so they do not depend on the host mounting a\n keyless <p-toast> \u2014 without this the messages went nowhere in any host but\n jit-ui, and a failed run looked like a button that did nothing. -->\n<p-toast [key]=\"resultToastKey\" position=\"bottom-right\"></p-toast>\n\n<!-- Shared outlets for notices raised where there is no per-instance key to use:\n the root-provided PlotlyService and the region-editor dialog. Rendered by a\n single visualizer (ownsSharedToasts) so a message from the root service is\n not shown once per live viewer. -->\n<p-toast *ngIf=\"ownsSharedToasts\" [key]=\"vizToastKey\"></p-toast>\n<p-toast *ngIf=\"ownsSharedToasts\" [key]=\"vizAlertToastKey\" position=\"center\"></p-toast>\n\n<!-- Toolbar dock: docked across the top by default; drag the handle to detach\n it into a floating, movable window (frees the top row for the image). -->\n<div\n class=\"toolbar-dock\"\n [class.floating]=\"toolbarFloating\"\n [style.left.px]=\"toolbarFloating ? toolbarPos.x : null\"\n [style.top.px]=\"toolbarFloating ? toolbarPos.y : null\"\n>\n <div\n class=\"toolbar-drag-handle\"\n [vizFloatingDrag]=\"toolbarDragOrigin\"\n (vizFloatingDragMove)=\"toolbarPos = $event\"\n pTooltip=\"Drag to float the toolbar\"\n tooltipPosition=\"bottom\"\n >\n <i class=\"pi pi-bars\"></i>\n </div>\n <plotting-toolbar\n [imageInfo]=\"imageInfo\"\n [hasSpatialDataset]=\"hasSpatialDataset\"\n [plotTypeOptions]=\"plotTypeMenu\"\n [selectedPlotType]=\"selectedPlotTypeId\"\n [basePlotType]=\"basePlotType\"\n [isoRange]=\"isoRange\"\n [maxIndex]=\"maxIndex\"\n [zIndex]=\"zIndex\"\n [isHeatmap]=\"isHeatmap\"\n [is3dRegions]=\"isSpatial3dMode\"\n [activeDragMode]=\"activeDragMode\"\n [activeSurface3dMode]=\"activeSurface3dMode\"\n [axesVisible]=\"axesVisible\"\n [wireframeActive]=\"wireframeActive\"\n [resolutionScale]=\"resolutionScale\"\n [wandSensitivity]=\"wandSensitivity\"\n [brushSize]=\"brushSize\"\n [samModels]=\"samModels\"\n [samModelId]=\"samModelId\"\n [contributedTools]=\"contributedTools\"\n [dialogTools]=\"dialogTools\"\n [openDialogToolId]=\"openDialogToolId\"\n (toggleDialogTool)=\"toggleDialogTool($event)\"\n [toolModelIds]=\"toolParams.toolModelIds\"\n [vertexEraserRadius]=\"vertexEraserRadius\"\n [canUndo]=\"regionActions.canUndo\"\n [canRedo]=\"regionActions.canRedo\"\n [tools]=\"toolbarTools\"\n [imageSmoothingEnabled]=\"imageSmoothingEnabled\"\n (selectPlotType)=\"onSelectPlotType($event)\"\n (toggleImageSmoothing)=\"onToggleImageSmoothing()\"\n (addProfileLine)=\"addProfileLine()\"\n (isoRangeChange)=\"onIsoRangeChange($event)\"\n (openChannelHistogram)=\"openChannelHistogram()\"\n (openSpatialControls)=\"openSpatialControls()\"\n (openRegionEditor)=\"openRegionEditor()\"\n (selectStackOption)=\"selectStackOption($event)\"\n (zScrub)=\"onZScrub($event)\"\n (zSlide)=\"onZSlide($event)\"\n (zIndexInput)=\"zIndex = $event; updateZIndex()\"\n (reloadAndPlot)=\"reloadAndPlot()\"\n (downloadImage)=\"downloadImage()\"\n (autoscaleImage)=\"autoscaleImage()\"\n (toggleDragMode)=\"toggleDragMode($event)\"\n (zoomIn)=\"zoomIn()\"\n (zoomOut)=\"zoomOut()\"\n (toggleSurface3dMode)=\"toggleSurface3dMode($event)\"\n (resetSurfaceCamera)=\"resetSurfaceCamera()\"\n (toggleAxes)=\"toggleAxes()\"\n (toggleWireframe)=\"toggleWireframe()\"\n (selectResolution)=\"selectResolution($event)\"\n (deleteRegion)=\"deleteRegion()\"\n (undoRegion)=\"undoRegion()\"\n (redoRegion)=\"redoRegion()\"\n (segmentRegions)=\"segmentRegions()\"\n (segmentCellpose)=\"segmentCellpose()\"\n (samModelChange)=\"onSamModelChange($event)\"\n (runTool)=\"runTool($event)\"\n (toolModelChange)=\"onToolModelChange($event)\"\n (openToolParams)=\"openToolParams($event)\"\n (wandSensitivityChange)=\"onWandSensitivityChange($event)\"\n (brushSizeChange)=\"onBrushSizeChange($event)\"\n (vertexEraserRadiusChange)=\"onVertexEraserRadiusChange($event)\"\n >\n <!-- Host-projected custom toolbar buttons, forwarded into the toolbar. -->\n <ng-content></ng-content>\n </plotting-toolbar>\n <p-button\n *ngIf=\"toolbarFloating\"\n class=\"toolbar-dock-btn\"\n icon=\"pi pi-thumbtack\"\n size=\"small\"\n [text]=\"true\"\n pTooltip=\"Dock to top\"\n tooltipPosition=\"bottom\"\n (onClick)=\"dockToolbar()\"\n >\n </p-button>\n</div>\n\n<p-contextMenu #cm [model]=\"contextMenuItems\" appendTo=\"body\"></p-contextMenu>\n<!-- No `h-full` here: PrimeFlex's height:100% !important made #plot as tall as\n the whole host, so under the docked toolbar its bottom toolbar-height strip\n (incl. the OSD scale bar at bottom-left) was clipped by the host's\n overflow:hidden. The component stylesheet sizes it (.viz-plot { flex: 1 }). -->\n<div class=\"w-full relative viz-plot\" [id]=\"plotDivName\">\n <div *ngIf=\"imgLoading() || stackLoading() || isCaching()\" class=\"loading-overlay\">\n <!-- Determinate stack/volume progress takes precedence: while it's active show ONLY the\n progress bar + \"Loading frames...\", not the generic spinner/\"Loading image...\" on top of\n it (both were rendering at once for napari volume/isosurface loads). -->\n <ng-container *ngIf=\"stackLoading(); else imgLoadingTpl\">\n <p-progressBar class=\"progress\" [value]=\"loadingPercentage()\"></p-progressBar>\n <span class=\"text-loading\">Loading frames...</span>\n </ng-container>\n <ng-template #imgLoadingTpl>\n <!-- Cache-copy progress is shown whenever a cache download is active (isCaching), independent\n of `imgLoading`, so it's never dropped/masked mid-download. -->\n <ng-container *ngIf=\"isCaching(); else spinnerLoading\">\n <!-- Stage-aware message comes from CacheProgressService updating\n imageLoadingMessage$ (\"Caching image...\" during the GCS download,\n then \"Generating preview...\" during per-slice thumbnail gen). Once the\n download hits 100% the remaining work (server preview/tile generation)\n has no determinate progress, so fall through to the spinner template\n rather than parking a full bar under \"Loading image...\". -->\n <p-progressBar class=\"progress\" [value]=\"cacheProgress()\"></p-progressBar>\n <span class=\"text-loading\">{{ loadingMessage() }}</span>\n </ng-container>\n <ng-template #spinnerLoading>\n <div *ngIf=\"imgLoading()\" class=\"spinner\"></div>\n <span *ngIf=\"imgLoading() && !zoom()\" class=\"text-loading\">{{ loadingMessage() }}</span>\n <span *ngIf=\"imgLoading() && zoom()\" class=\"zoom-text-loading\">{{ loadingMessage() }}</span>\n </ng-template>\n </ng-template>\n <p-button\n *ngIf=\"stackLoading() || imgLoading()\"\n class=\"cancel-loading\"\n label=\"Cancel\"\n (onClick)=\"cancelLoading()\"\n >\n </p-button>\n </div>\n <!-- Translucent \"sharpening\" overlay shown after the small-tier preview is\n on screen while the large-tier render is still loading in the\n background. Lets the user see the blurry image underneath but makes\n it clear something is still loading so they don't mistake the\n low-res render for the final image. -->\n <div *ngIf=\"render.sharpening && !imgLoading() && !stackLoading() && !isCaching()\" class=\"sharpening-overlay\">\n <div class=\"spinner\"></div>\n <span class=\"text-loading\">Sharpening preview...</span>\n </div>\n</div>\n\n<!-- Floating, draggable intensity-profile inset, shown while any intensity line\n exists. Kept OUTSIDE the plot div and fixed to the viewport, so it floats over\n the whole page rather than being clipped to the canvas. -->\n<viz-intensity-inset\n [divId]=\"intensityInsetDiv\"\n [plotDivName]=\"plotDivName\"\n [zIndex]=\"zIndex\"\n [imageView]=\"isImageView\"\n [imageInfo]=\"imageInfo\"\n></viz-intensity-inset>\n\n<!-- Channels & Histogram: non-modal floating dialog opened from the toolbar. -->\n<channel-histogram [(visible)]=\"showChannelHistogram\"></channel-histogram>\n\n<!-- Spatial-omics controls. Renders its own empty state when no dataset (or no\n SPATIAL_DATA_PORT) is present, so it is always safe to host. -->\n<spatial-controls [(visible)]=\"showSpatialControls\" [is3d]=\"isSpatial3dMode\"></spatial-controls>\n\n<!-- Side panel of the active contributed plot mode (PLOT_TYPE_CONTRIBUTIONS),\n in the same right-hand area as the spatial controls and the Region Editor.\n Exists only while the mode's session is live; there is no close button,\n because leaving the mode is what ends it. A component panel gets\n PLOT_MODE_CONTEXT / PLOT_MODE_SESSION from its injector; a `mount` panel's\n host element is attached to the slot below (see plotModePanelSlot). -->\n<p-dialog\n *ngIf=\"plotModePanel as panel\"\n [header]=\"panel.title\"\n [visible]=\"true\"\n [modal]=\"false\"\n [closable]=\"false\"\n [resizable]=\"true\"\n [draggable]=\"true\"\n appendTo=\"body\"\n position=\"right\"\n styleClass=\"plot-mode-panel\"\n [style]=\"{ width: '22rem', maxHeight: '85vh' }\"\n [contentStyle]=\"{ overflow: 'auto' }\"\n>\n <ng-container *ngIf=\"panel.component\">\n <ng-container *ngComponentOutlet=\"panel.component; injector: panel.injector ?? undefined\"></ng-container>\n </ng-container>\n <div *ngIf=\"panel.host\" #plotModePanelSlot class=\"plot-mode-panel-slot\"></div>\n</p-dialog>\n\n<!-- An open dialog tool (TOOLBAR_TOOLS, kind: 'dialog'). Non-modal so the user can\n keep working on the image, e.g. painting with the brush the tool armed. The\n tool renders its body into a host element attached to the slot below (see\n toolDialogSlot); closing the dialog ends the tool's session. -->\n<p-dialog\n *ngIf=\"toolDialog as dlg\"\n [header]=\"dlg.title\"\n [visible]=\"true\"\n (visibleChange)=\"$event || closeDialogTool()\"\n [modal]=\"false\"\n [closable]=\"true\"\n [resizable]=\"true\"\n [draggable]=\"true\"\n appendTo=\"body\"\n position=\"right\"\n styleClass=\"tool-dialog\"\n [style]=\"{ width: dlg.width, maxHeight: '85vh' }\"\n [contentStyle]=\"{ overflow: 'auto' }\"\n>\n <div #toolDialogSlot class=\"tool-dialog-slot\"></div>\n</p-dialog>\n\n<!-- Region Editor: non-modal, draggable, resizable floating dialog opened from\n the toolbar (formerly the right-panel Regions tab). Modeless so regions can\n still be drawn/selected on the plot while it's open; stays linked to this\n plotting instance via the root RegionStore singleton. Opens over the right\n side of the view. -->\n<p-dialog\n header=\"Region Editor\"\n [(visible)]=\"showRegionEditor\"\n [modal]=\"false\"\n [resizable]=\"true\"\n [draggable]=\"true\"\n [maximizable]=\"true\"\n appendTo=\"body\"\n position=\"right\"\n [style]=\"{ width: regionEditorWidth, height: '85vh' }\"\n [contentStyle]=\"{ overflow: 'auto' }\"\n>\n <region-editor></region-editor>\n</p-dialog>\n\n<!-- Simplify (Douglas\u2013Peucker): custom px-threshold picker for the selected\n region(s), opened from the right-click \"Simplify \u25B8 Custom\u2026\" action. -->\n<p-dialog\n header=\"Simplify region(s)\"\n [(visible)]=\"displaySimplifyDialog\"\n [modal]=\"true\"\n [style]=\"{ width: '22rem' }\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n>\n <div class=\"flex flex-column gap-2\">\n <span\n >Altitude threshold: <b>{{ regionActions.simplifyThreshold }} px</b></span\n >\n <p-slider [(ngModel)]=\"regionActions.simplifyThreshold\" [min]=\"1\" [max]=\"20\" [step]=\"1\"></p-slider>\n <small>Vertices within this distance of the line between their neighbours are removed.</small>\n </div>\n <ng-template pTemplate=\"footer\">\n <p-button label=\"Cancel\" [text]=\"true\" (onClick)=\"displaySimplifyDialog = false\"></p-button>\n <p-button\n label=\"Apply\"\n icon=\"pi pi-check\"\n (onClick)=\"simplifyRegions(regionActions.simplifyThreshold)\"\n ></p-button>\n </ng-template>\n</p-dialog>\n\n<!-- Parameters for whichever contributed tool is open. One dialog for all of\n them: a tool declares its fields (ToolParamSpec) and this renders them, so\n the toolbar can lay every tool out the same way and a plugin needs no\n PrimeNG of its own. Defaults come from the active checkpoint, since they\n encode what it was trained for. -->\n<p-dialog\n *ngIf=\"toolParams.openParams as open\"\n [header]=\"open.tool.label + ' parameters'\"\n [visible]=\"true\"\n (visibleChange)=\"closeToolParams()\"\n [modal]=\"true\"\n [style]=\"{ width: '30rem' }\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n appendTo=\"body\"\n>\n <div class=\"grid formgrid p-fluid\">\n <ng-container *ngFor=\"let f of open.fields\">\n <div class=\"field\" [ngClass]=\"f.spec.type === 'boolean' ? 'col-12' : 'col-6'\">\n <ng-container *ngIf=\"f.number as n\">\n <label class=\"text-sm\" [pTooltip]=\"n.tooltip || ''\">{{ n.label }}</label>\n <p-inputNumber\n [ngModel]=\"open.values[n.id]\"\n (ngModelChange)=\"open.values[n.id] = $event\"\n [min]=\"n.min\"\n [max]=\"n.max\"\n [step]=\"n.step\"\n [minFractionDigits]=\"n.fractionDigits\"\n [showButtons]=\"true\"\n ></p-inputNumber>\n </ng-container>\n\n <ng-container *ngIf=\"f.select as sel\">\n <label class=\"text-sm\" [pTooltip]=\"sel.tooltip || ''\">{{ sel.label }}</label>\n <p-dropdown\n [options]=\"sel.options\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [ngModel]=\"open.values[sel.id]\"\n (ngModelChange)=\"open.values[sel.id] = $event\"\n appendTo=\"body\"\n ></p-dropdown>\n </ng-container>\n\n <!-- Checkbox label sits beside the box and may run to a sentence, so\n it does not get the stacked label the other types use. -->\n <div *ngIf=\"f.spec.type === 'boolean'\" class=\"flex align-items-center gap-2\">\n <p-checkbox\n [ngModel]=\"open.values[f.spec.id]\"\n (ngModelChange)=\"open.values[f.spec.id] = $event\"\n [binary]=\"true\"\n [inputId]=\"open.tool.id + '-' + f.spec.id\"\n ></p-checkbox>\n <label [for]=\"open.tool.id + '-' + f.spec.id\" class=\"text-sm mb-0\" [pTooltip]=\"f.spec.tooltip || ''\">{{\n f.spec.label\n }}</label>\n </div>\n </div>\n </ng-container>\n </div>\n <ng-template pTemplate=\"footer\">\n <p-button\n label=\"Reset to model defaults\"\n [text]=\"true\"\n size=\"small\"\n (onClick)=\"resetToolParams(open.tool.id)\"\n ></p-button>\n <p-button label=\"Close\" size=\"small\" (onClick)=\"closeToolParams()\"></p-button>\n </ng-template>\n</p-dialog>\n", styles: [":host{display:flex;flex-direction:column;height:100%;overflow:hidden}.viz-plot{flex:1;min-height:0;height:auto!important}.toolbar-dock{display:flex;align-items:stretch;width:100%}.toolbar-dock plotting-toolbar{flex:1;min-width:0}.toolbar-dock.floating{position:fixed;z-index:1000;width:auto;max-width:calc(100% - 16px);background:var(--surface-card, #ffffff);border:1px solid var(--surface-border, #cccccc);border-radius:6px;box-shadow:0 4px 16px #0000004d}.toolbar-dock.floating plotting-toolbar{flex:0 1 auto}.toolbar-dock.floating .toolbar-drag-handle{border-radius:6px 0 0 6px}.toolbar-drag-handle{display:flex;align-items:center;justify-content:center;padding:0 .4rem;cursor:move;color:var(--primary-color);background:var(--surface-100, rgba(0, 0, 0, .04));border-right:1px solid var(--surface-border, #cccccc);-webkit-user-select:none;user-select:none}.toolbar-dock-btn{align-self:center}:host ::ng-deep .navigator{margin-bottom:80px!important;margin-right:12px!important}kbd{background:#e8e8e8;border:1px solid #bbb;border-radius:3px;padding:1px 5px;font-family:monospace;font-size:.85em}.toolbar-separator{border-left:1px solid var(--surface-border);height:1.5rem;margin:0 .25rem;align-self:center}.progress{position:absolute;width:50%;left:25%;top:55%}.text-loading{position:absolute;margin:0 auto;left:45%;top:60%;font-weight:700}.zoom-text-loading{position:absolute;margin:0 auto;left:35%;top:60%;font-weight:700;display:inline-block;width:350px}.cancel-loading{position:absolute;margin:0 auto;left:46%;top:70%}.spinner{position:absolute;left:45%;top:45%;height:100px;width:100px;margin:0 auto;-webkit-animation:rotation .6s infinite linear;-moz-animation:rotation .6s infinite linear;-o-animation:rotation .6s infinite linear;animation:rotation .6s infinite linear;border-left:6px solid rgba(0,174,239,.15);border-right:6px solid rgba(0,174,239,.15);border-bottom:6px solid rgba(0,174,239,.15);border-top:6px solid rgb(82,107,178);border-radius:100%}.loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#ffffff80;z-index:1000}.sharpening-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#ffffff2e;pointer-events:none;z-index:1000}.sharpening-overlay .spinner{height:60px;width:60px;border-width:4px;left:calc(50% - 30px);top:calc(50% - 60px)}.sharpening-overlay .text-loading{position:absolute;left:0;right:0;width:auto;text-align:center;top:calc(50% + 35px);font-size:.9rem;color:#526bb2}@-webkit-keyframes rotation{0%{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(359deg)}}@-moz-keyframes rotation{0%{-moz-transform:rotate(0deg)}to{-moz-transform:rotate(359deg)}}@-o-keyframes rotation{0%{-o-transform:rotate(0deg)}to{-o-transform:rotate(359deg)}}@keyframes rotation{0%{transform:rotate(0)}to{transform:rotate(359deg)}}::ng-deep .context-menu-active>.p-menuitem-content{background-color:var(--primary-color)!important}::ng-deep .context-menu-active>.p-menuitem-content .p-menuitem-icon,::ng-deep .context-menu-active>.p-menuitem-content .p-menuitem-text{color:#fff!important}::ng-deep .context-menu-active>.p-menuitem-content .zoom-box-off-icon,::ng-deep .context-menu-active>.p-menuitem-content .wand-icon,::ng-deep .context-menu-active>.p-menuitem-content .polyline-icon,::ng-deep .context-menu-active>.p-menuitem-content .polygon-vertices-icon,::ng-deep .context-menu-active>.p-menuitem-content .vertex-add-icon,::ng-deep .context-menu-active>.p-menuitem-content .vertex-delete-icon,::ng-deep .context-menu-active>.p-menuitem-content .region-move-icon,::ng-deep .context-menu-active>.p-menuitem-content .to-bezier-icon,::ng-deep .context-menu-active>.p-menuitem-content .to-polygon-icon{filter:brightness(0) invert(1)}::ng-deep .zoom-box-off-icon{background:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 100\" fill=\"black\" fill-rule=\"evenodd\">%0A <!-- Rectangle outline -->%0A <rect x=\"2\" y=\"2\" width=\"56\" height=\"56\"/>%0A <rect x=\"9\" y=\"9\" width=\"42\" height=\"42\"/>%0A <!-- Magnifying glass ring -->%0A <circle cx=\"70\" cy=\"70\" r=\"23\"/>%0A <circle cx=\"70\" cy=\"70\" r=\"14\"/>%0A <!-- Handle -->%0A <polygon points=\"81,81 97,97 92,100 77,85\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .wand-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<svg%0A viewBox=\"0 0 100 100\"%0A fill=\"black\"%0A fill-rule=\"evenodd\"%0A version=\"1.1\"%0A id=\"svg4\"%0A sodipodi:docname=\"wand.svg\"%0A inkscape:version=\"1.4.3 (0d15f75, 2025-12-25)\"%0A xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"%0A xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"%0A xmlns=\"http://www.w3.org/2000/svg\"%0A xmlns:svg=\"http://www.w3.org/2000/svg\">%0A <defs%0A id=\"defs4\" />%0A <sodipodi:namedview%0A id=\"namedview4\"%0A pagecolor=\"%23ffffff\"%0A bordercolor=\"%23000000\"%0A borderopacity=\"0.25\"%0A inkscape:showpageshadow=\"2\"%0A inkscape:pageopacity=\"0.0\"%0A inkscape:pagecheckerboard=\"0\"%0A inkscape:deskcolor=\"%23d1d1d1\"%0A inkscape:zoom=\"8.74\"%0A inkscape:cx=\"50\"%0A inkscape:cy=\"49.942792\"%0A inkscape:window-width=\"1024\"%0A inkscape:window-height=\"1186\"%0A inkscape:window-x=\"3560\"%0A inkscape:window-y=\"131\"%0A inkscape:window-maximized=\"0\"%0A inkscape:current-layer=\"svg4\" />%0A <!-- Wand handle: thin diagonal stick from lower-left to upper-right -->%0A <polygon%0A points=\"12,92 78,26 74,22 8,88 \"%0A id=\"polygon1\"%0A transform=\"matrix(1.0375192,0.05799445,0.25179496,0.91871864,-17.85351,5.6289793)\" />%0A <!-- 4-pointed star at the wand tip -->%0A <polygon%0A points=\"62,34 76,30 80,6 84,30 98,34 84,38 80,62 76,38 \"%0A id=\"polygon2\"%0A transform=\"matrix(1.3082889,0,0,1.0245178,-38.907958,-1.4056881)\" />%0A <!-- Small sparkle to the upper-left -->%0A <polygon%0A points=\"46,30 36,32 34,42 32,32 22,30 32,28 34,18 36,28 \"%0A id=\"polygon3\"%0A transform=\"translate(-9.610984,-6.7505721)\" />%0A <!-- Small sparkle to the lower-right -->%0A <polygon%0A points=\"62,80 70,82 62,84 60,92 58,84 50,82 58,80 60,72 \"%0A id=\"polygon4\"%0A transform=\"translate(0,-1.6018307)\" />%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .brush-icon{background:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 640\"><!--!Font Awesome Free 7.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d=\"M512.5 74.3L291.1 222C262 241.4 243.5 272.9 240.5 307.3C302.8 320.1 351.9 369.2 364.8 431.6C399.3 428.6 430.7 410.1 450.1 381L597.7 159.5C604.4 149.4 608 137.6 608 125.4C608 91.5 580.5 64 546.6 64C534.5 64 522.6 67.6 512.5 74.3zM320 464C320 402.1 269.9 352 208 352C146.1 352 96 402.1 96 464C96 467.9 96.2 471.8 96.6 475.6C98.4 493.1 86.4 512 68.8 512L64 512C46.3 512 32 526.3 32 544C32 561.7 46.3 576 64 576L208 576C269.9 576 320 525.9 320 464z\"/></svg>') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .polyline-icon{background:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\">%0A <polyline points=\"1,14 5,3 10,11 15,2\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .polygon-vertices-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Polygon (click-to-place) tool icon: a traced polyline with vertex dots. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <g transform=\"matrix(1.4740709,0,0,1.4740709,-6.0268793,-6.8086826)\">%0A <polyline points=\"23.877,16.627 14.657,10.767 5.25,21.551 12.757,29.397\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"1.6\"%0A stroke-linejoin=\"round\" stroke-linecap=\"round\"/>%0A <circle cx=\"23.877\" cy=\"16.627\" r=\"1.9\"/>%0A <circle cx=\"14.657\" cy=\"10.767\" r=\"1.9\"/>%0A <circle cx=\"5.25\" cy=\"21.551\" r=\"1.9\"/>%0A <circle cx=\"12.757\" cy=\"29.397\" r=\"1.9\"/>%0A </g>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .vertex-add-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Add-vertex tool icon: a region blob with three corner vertices and a plus glyph. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <g transform=\"matrix(1.5222969,0,0,1.5222969,-8.2143505,-7.6146399)\">%0A <path d=\"m 9.35834,12.33267 c 1.78,-2.53 4.93,-3.56 7.86,-3.98 3.98,-0.72 8.33,0.08 11.52,2.67 2.62,1.98 4.71,5.1 4.53,8.49 -0.29,2.27 -2.5,3.81 -4.66,4.01 -2.75,0.43 -5.54,0.07 -8.28,-0.26 -3.99,-0.68 -8.05,-2.16 -10.93,-5.12 -1.32,-1.63 -1.39,-4.17 -0.04,-5.81 z\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"1.6\" stroke-miterlimit=\"10\"/>%0A <circle cx=\"8.294\" cy=\"15.248\" r=\"2.63\"/>%0A <circle cx=\"19.781\" cy=\"8.287\" r=\"2.63\"/>%0A <circle cx=\"25.044\" cy=\"23.748\" r=\"2.63\"/>%0A </g>%0A <path d=\"M 9.65,29.0 H 5.85 v 5.3 H 0.55 v 3.4 H 5.85 v 5.3 H 9.65 V 37.7 H 14.95 V 34.3 H 9.65 Z\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .vertex-delete-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Delete-vertex tool icon: a region blob with three corner vertices and a minus glyph. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <g transform=\"matrix(1.5222969,0,0,1.5222969,-8.2143505,-7.6146399)\">%0A <path d=\"m 9.35834,12.33267 c 1.78,-2.53 4.93,-3.56 7.86,-3.98 3.98,-0.72 8.33,0.08 11.52,2.67 2.62,1.98 4.71,5.1 4.53,8.49 -0.29,2.27 -2.5,3.81 -4.66,4.01 -2.75,0.43 -5.54,0.07 -8.28,-0.26 -3.99,-0.68 -8.05,-2.16 -10.93,-5.12 -1.32,-1.63 -1.39,-4.17 -0.04,-5.81 z\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"1.6\" stroke-miterlimit=\"10\"/>%0A <circle cx=\"8.294\" cy=\"15.248\" r=\"2.63\"/>%0A <circle cx=\"19.781\" cy=\"8.287\" r=\"2.63\"/>%0A <circle cx=\"25.044\" cy=\"23.748\" r=\"2.63\"/>%0A </g>%0A <path d=\"M 0.55,34.3 v 3.4 H 14.95 V 34.3 Z\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .region-move-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Region-move tool icon: a region blob with a drag arrow. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <path d=\"m 17.115582,8.9648664 c 1.707597,-3.3276806 4.729468,-4.6824281 7.540287,-5.2348498 3.827703,-0.947008 7.991169,0.1052238 11.051414,3.5118228 2.523022,2.604273 4.518416,6.7079726 4.345738,11.1668036 -0.278204,2.985704 -2.398311,5.011251 -4.470451,5.274308 -2.638142,0.565574 -5.314655,0.09206 -7.943203,-0.341976 C 23.811664,22.446579 19.916808,20.499952 17.153955,16.606696 15.89724,14.462775 15.820494,11.12194 17.115585,8.9648664 Z\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"2.1\" stroke-miterlimit=\"10\"/>%0A <path d=\"m 26.741429,13.966963 6.746922,16.786269 3.229398,-4.060758 3.583857,3.583857 2.761195,-2.761196 -3.583856,-3.571852 4.060758,-3.2354 z\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .to-bezier-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Convert-to-bezier tool icon: a smooth curve through two anchor points with control handles. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <!-- smooth cubic curve between the two anchors -->%0A <path d=\"M 7,34 C 7,16 37,28 37,10\" fill=\"none\" stroke=\"%23000000\" stroke-width=\"2.4\"%0A stroke-linecap=\"round\"/>%0A <!-- control handles -->%0A <line x1=\"7\" y1=\"34\" x2=\"7\" y2=\"22\" stroke=\"%23000000\" stroke-width=\"1.4\"/>%0A <line x1=\"37\" y1=\"10\" x2=\"37\" y2=\"22\" stroke=\"%23000000\" stroke-width=\"1.4\"/>%0A <circle cx=\"7\" cy=\"22\" r=\"2.2\"/>%0A <circle cx=\"37\" cy=\"22\" r=\"2.2\"/>%0A <!-- anchor points -->%0A <rect x=\"4\" y=\"31\" width=\"6\" height=\"6\" rx=\"1\"/>%0A <rect x=\"34\" y=\"7\" width=\"6\" height=\"6\" rx=\"1\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .to-polygon-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Convert-to-polygon tool icon: endpoints joined by straight segments through a vertex. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <!-- straight-segment path through the vertices -->%0A <polyline points=\"7,34 22,12 37,10\" fill=\"none\" stroke=\"%23000000\" stroke-width=\"2.4\"%0A stroke-linecap=\"round\" stroke-linejoin=\"round\"/>%0A <!-- vertices -->%0A <rect x=\"4\" y=\"31\" width=\"6\" height=\"6\" rx=\"1\"/>%0A <rect x=\"19\" y=\"9\" width=\"6\" height=\"6\" rx=\"1\"/>%0A <rect x=\"34\" y=\"7\" width=\"6\" height=\"6\" rx=\"1\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}:host ::ng-deep .sam-progress .p-progressbar-value{transition:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i7.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "directive", type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: SharedModule }, { kind: "directive", type: i1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i9.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "style", "styleClass", "badgeClass", "ariaLabel", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i10.Checkbox, selector: "p-checkbox", inputs: ["value", "name", "disabled", "binary", "label", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "styleClass", "labelStyleClass", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: ContextMenuModule }, { kind: "component", type: i11.ContextMenu, selector: "p-contextMenu", inputs: ["model", "triggerEvent", "target", "global", "style", "styleClass", "appendTo", "autoZIndex", "baseZIndex", "id", "ariaLabel", "ariaLabelledBy", "pressDelay"], outputs: ["onShow", "onHide"] }, { kind: "directive", type: i12.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i13.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "visible", "style", "position"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: DropdownModule }, { kind: "component", type: i14.Dropdown, selector: "p-dropdown", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "autoShowPanelOnPrintableCharacterKeyDown", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: InputNumberModule }, { kind: "component", type: i15.InputNumber, selector: "p-inputNumber", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "style", "placeholder", "size", "maxlength", "tabindex", "title", "ariaLabelledBy", "ariaLabel", "ariaRequired", "name", "required", "autocomplete", "min", "max", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "step", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "variant", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "showClear", "autofocus", "disabled"], outputs: ["onInput", "onFocus", "onBlur", "onKeyDown", "onClear"] }, { kind: "ngmodule", type: ProgressBarModule }, { kind: "component", type: i16.ProgressBar, selector: "p-progressBar", inputs: ["value", "showValue", "styleClass", "style", "unit", "mode", "color"] }, { kind: "ngmodule", type: SliderModule }, { kind: "component", type: i17.Slider, selector: "p-slider", inputs: ["animate", "disabled", "min", "max", "orientation", "step", "range", "style", "styleClass", "ariaLabel", "ariaLabelledBy", "tabindex", "autofocus"], outputs: ["onChange", "onSlideEnd"] }, { kind: "ngmodule", type: ToastModule }, { kind: "component", type: i18.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "style", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: FloatingDragDirective, selector: "[vizFloatingDrag]", inputs: ["vizFloatingDrag"], outputs: ["vizFloatingDragMove"] }, { kind: "component", type: ToolbarComponent, selector: "plotting-toolbar", inputs: ["imageInfo", "hasSpatialDataset", "plotTypeOptions", "selectedPlotType", "basePlotType", "isoRange", "maxIndex", "zIndex", "isHeatmap", "is3dRegions", "activeDragMode", "activeSurface3dMode", "axesVisible", "wireframeActive", "resolutionScale", "wandSensitivity", "brushSize", "vertexEraserRadius", "canUndo", "canRedo", "stackOptions", "tools", "imageSmoothingEnabled", "samModels", "samModelId", "contributedTools", "dialogTools", "openDialogToolId", "toolModelIds"], outputs: ["selectPlotType", "addProfileLine", "toggleImageSmoothing", "isoRangeChange", "openChannelHistogram", "openSpatialControls", "openRegionEditor", "selectStackOption", "zScrub", "zSlide", "zIndexInput", "reloadAndPlot", "downloadImage", "autoscaleImage", "toggleDragMode", "zoomIn", "zoomOut", "toggleSurface3dMode", "resetSurfaceCamera", "toggleAxes", "toggleWireframe", "selectResolution", "deleteRegion", "undoRegion", "redoRegion", "segmentRegions", "segmentCellpose", "runTool", "toggleDialogTool", "toolModelChange", "openToolParams", "samModelChange", "wandSensitivityChange", "brushSizeChange", "vertexEraserRadiusChange"] }, { kind: "component", type: IntensityInsetComponent, selector: "viz-intensity-inset", inputs: ["divId", "plotDivName", "zIndex", "imageView", "imageInfo"] }, { kind: "component", type: ChannelHistogramComponent, selector: "channel-histogram", inputs: ["visible"], outputs: ["visibleChange"] }, { kind: "component", type: SpatialControlsComponent, selector: "spatial-controls", inputs: ["visible", "is3d"], outputs: ["visibleChange"] }, { kind: "component", type: RegionEditorComponent, selector: "region-editor" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1218
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: VisualizerComponent, isStandalone: true, selector: "visualizer", inputs: { toolbarTools: "toolbarTools", testMode: "testMode" }, outputs: { isStackEvent: "isStackEvent", isGrayscaleEvent: "isGrayscaleEvent" }, viewQueries: [{ propertyName: "contextMenu", first: true, predicate: ["cm"], descendants: true }, { propertyName: "plotModePanelSlot", first: true, predicate: ["plotModePanelSlot"], descendants: true }, { propertyName: "inset", first: true, predicate: IntensityInsetComponent, descendants: true, static: true }, { propertyName: "toolDialogSlot", first: true, predicate: ["toolDialogSlot"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<!-- SAM toast: live status + encoder-download progress bar (jit-ui#90). Sticky\n while a segment runs; stays open until the bar reaches 100% and the run ends. -->\n<p-toast [key]=\"samToastKey\" position=\"bottom-right\">\n <ng-template let-message pTemplate=\"message\">\n <div style=\"flex: 1; min-width: 16rem\">\n <div class=\"font-bold mb-1\">{{ message.summary }}</div>\n <div>{{ segmentation.status || message.detail }}</div>\n <p-progressBar\n *ngIf=\"segmentation.downloading\"\n [value]=\"segmentation.progress\"\n styleClass=\"mt-2 sam-progress\"\n ></p-progressBar>\n <p-progressBar\n *ngIf=\"segmentation.busy && !segmentation.downloading\"\n mode=\"indeterminate\"\n styleClass=\"mt-2\"\n [style]=\"{ height: '4px' }\"\n ></p-progressBar>\n </div>\n </ng-template>\n</p-toast>\n\n<!-- Result/error notices from the library itself (segmentation outcome, region\n validation). Rendered here so they do not depend on the host mounting a\n keyless <p-toast> \u2014 without this the messages went nowhere in any host but\n jit-ui, and a failed run looked like a button that did nothing. -->\n<p-toast [key]=\"resultToastKey\" position=\"bottom-right\"></p-toast>\n\n<!-- Shared outlets for notices raised where there is no per-instance key to use:\n the root-provided PlotlyService and the region-editor dialog. Rendered by a\n single visualizer (ownsSharedToasts) so a message from the root service is\n not shown once per live viewer. -->\n<p-toast *ngIf=\"ownsSharedToasts\" [key]=\"vizToastKey\"></p-toast>\n<p-toast *ngIf=\"ownsSharedToasts\" [key]=\"vizAlertToastKey\" position=\"center\"></p-toast>\n\n<!-- Toolbar dock: docked across the top by default; drag the handle to detach\n it into a floating, movable window (frees the top row for the image). -->\n<div\n class=\"toolbar-dock\"\n [class.floating]=\"toolbarFloating\"\n [style.left.px]=\"toolbarFloating ? toolbarPos.x : null\"\n [style.top.px]=\"toolbarFloating ? toolbarPos.y : null\"\n>\n <div\n class=\"toolbar-drag-handle\"\n [vizFloatingDrag]=\"toolbarDragOrigin\"\n (vizFloatingDragMove)=\"toolbarPos = $event\"\n pTooltip=\"Drag to float the toolbar\"\n tooltipPosition=\"bottom\"\n >\n <i class=\"pi pi-bars\"></i>\n </div>\n <plotting-toolbar\n [imageInfo]=\"imageInfo\"\n [hasSpatialDataset]=\"hasSpatialDataset\"\n [plotTypeOptions]=\"plotTypeMenu\"\n [selectedPlotType]=\"selectedPlotTypeId\"\n [basePlotType]=\"basePlotType\"\n [isoRange]=\"isoRange\"\n [maxIndex]=\"maxIndex\"\n [zIndex]=\"zIndex\"\n [isHeatmap]=\"isHeatmap\"\n [is3dRegions]=\"isSpatial3dMode\"\n [isVolumeView]=\"isVolumeView\"\n [sliceEditor]=\"sliceEditor\"\n [activeDragMode]=\"activeDragMode\"\n [activeSurface3dMode]=\"activeSurface3dMode\"\n [axesVisible]=\"axesVisible\"\n [wireframeActive]=\"wireframeActive\"\n [resolutionScale]=\"resolutionScale\"\n [wandSensitivity]=\"wandSensitivity\"\n [brushSize]=\"brushSize\"\n [samModels]=\"samModels\"\n [samModelId]=\"samModelId\"\n [contributedTools]=\"contributedTools\"\n [dialogTools]=\"dialogTools\"\n [openDialogToolId]=\"openDialogToolId\"\n (toggleDialogTool)=\"toggleDialogTool($event)\"\n [toolModelIds]=\"toolParams.toolModelIds\"\n [vertexEraserRadius]=\"vertexEraserRadius\"\n [canUndo]=\"regionActions.canUndo\"\n [canRedo]=\"regionActions.canRedo\"\n [tools]=\"toolbarTools\"\n [imageSmoothingEnabled]=\"imageSmoothingEnabled\"\n (selectPlotType)=\"onSelectPlotType($event)\"\n (toggleImageSmoothing)=\"onToggleImageSmoothing()\"\n (addProfileLine)=\"addProfileLine()\"\n (isoRangeChange)=\"onIsoRangeChange($event)\"\n (openChannelHistogram)=\"openChannelHistogram()\"\n (openSpatialControls)=\"openSpatialControls()\"\n (openRegionEditor)=\"openRegionEditor()\"\n (toggleSliceEditor)=\"toggleSliceEditor()\"\n (selectStackOption)=\"selectStackOption($event)\"\n (zScrub)=\"onZScrub($event)\"\n (zSlide)=\"onZSlide($event)\"\n (zIndexInput)=\"zIndex = $event; updateZIndex()\"\n (reloadAndPlot)=\"reloadAndPlot()\"\n (downloadImage)=\"downloadImage()\"\n (autoscaleImage)=\"autoscaleImage()\"\n (toggleDragMode)=\"toggleDragMode($event)\"\n (zoomIn)=\"zoomIn()\"\n (zoomOut)=\"zoomOut()\"\n (toggleSurface3dMode)=\"toggleSurface3dMode($event)\"\n (resetSurfaceCamera)=\"resetSurfaceCamera()\"\n (toggleAxes)=\"toggleAxes()\"\n (toggleWireframe)=\"toggleWireframe()\"\n (selectResolution)=\"selectResolution($event)\"\n (deleteRegion)=\"deleteRegion()\"\n (undoRegion)=\"undoRegion()\"\n (redoRegion)=\"redoRegion()\"\n (segmentRegions)=\"segmentRegions()\"\n (segmentCellpose)=\"segmentCellpose()\"\n (samModelChange)=\"onSamModelChange($event)\"\n (runTool)=\"runTool($event)\"\n (toolModelChange)=\"onToolModelChange($event)\"\n (openToolParams)=\"openToolParams($event)\"\n (wandSensitivityChange)=\"onWandSensitivityChange($event)\"\n (brushSizeChange)=\"onBrushSizeChange($event)\"\n (vertexEraserRadiusChange)=\"onVertexEraserRadiusChange($event)\"\n >\n <!-- Host-projected custom toolbar buttons, forwarded into the toolbar. -->\n <ng-content></ng-content>\n </plotting-toolbar>\n <p-button\n *ngIf=\"toolbarFloating\"\n class=\"toolbar-dock-btn\"\n icon=\"pi pi-thumbtack\"\n size=\"small\"\n [text]=\"true\"\n pTooltip=\"Dock to top\"\n tooltipPosition=\"bottom\"\n (onClick)=\"dockToolbar()\"\n >\n </p-button>\n</div>\n\n<p-contextMenu #cm [model]=\"contextMenuItems\" appendTo=\"body\"></p-contextMenu>\n<!-- No `h-full` here: PrimeFlex's height:100% !important made #plot as tall as\n the whole host, so under the docked toolbar its bottom toolbar-height strip\n (incl. the OSD scale bar at bottom-left) was clipped by the host's\n overflow:hidden. The component stylesheet sizes it (.viz-plot { flex: 1 }). -->\n<!-- The plot, and while a volume view is split, the slice editor's pane on its left (its own\n viewer, with every region tool) with a divider to resize the two. The plot div keeps its\n place in the DOM either way: the backends find it by id, and a viewer mounted in it stays. -->\n<div\n class=\"viz-panes\"\n [class.viz-quad]=\"sliceEditorShown\"\n [style.grid-template-columns]=\"sliceEditorShown ? splitX + '% 6px minmax(0, 1fr)' : null\"\n [style.grid-template-rows]=\"sliceEditorShown ? splitY + '% 6px minmax(0, 1fr)' : null\"\n>\n <!-- The slice editor: the volume (the plot) top left, the slice being edited (Z) top right,\n the sections through x and y below, in their axis colours. -->\n <ng-container *ngIf=\"sliceEditorShown\">\n <div class=\"viz-cell viz-cell-z\">\n <div class=\"viz-slice-pane\" [id]=\"sliceDivName\"></div>\n <span class=\"viz-pane-badge viz-pane-badge-z\">Z \u00B7 slice {{ zIndex }}</span>\n </div>\n <div class=\"viz-cell viz-cell-x\">\n <viz-section-pane axis=\"x\" [view]=\"sections.x\" (pick)=\"onSectionPick('x', $event)\"></viz-section-pane>\n </div>\n <div class=\"viz-cell viz-cell-y\">\n <viz-section-pane axis=\"y\" [view]=\"sections.y\" (pick)=\"onSectionPick('y', $event)\"></viz-section-pane>\n </div>\n <div\n class=\"viz-pane-divider viz-pane-divider-v\"\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label=\"Resize the panes across\"\n [attr.aria-valuenow]=\"splitX\"\n aria-valuemin=\"20\"\n aria-valuemax=\"80\"\n tabindex=\"0\"\n (pointerdown)=\"startPaneResize($event, 'x')\"\n (keydown)=\"nudgePaneSize($event, 'x')\"\n ></div>\n <div\n class=\"viz-pane-divider viz-pane-divider-h\"\n role=\"separator\"\n aria-orientation=\"horizontal\"\n aria-label=\"Resize the panes down\"\n [attr.aria-valuenow]=\"splitY\"\n aria-valuemin=\"20\"\n aria-valuemax=\"80\"\n tabindex=\"0\"\n (pointerdown)=\"startPaneResize($event, 'y')\"\n (keydown)=\"nudgePaneSize($event, 'y')\"\n ></div>\n </ng-container>\n <div class=\"w-full relative viz-plot\" [id]=\"plotDivName\">\n <div *ngIf=\"imgLoading() || stackLoading() || isCaching()\" class=\"loading-overlay\">\n <!-- Determinate stack/volume progress takes precedence: while it's active show ONLY the\n progress bar + \"Loading frames...\", not the generic spinner/\"Loading image...\" on top of\n it (both were rendering at once for napari volume/isosurface loads). -->\n <ng-container *ngIf=\"stackLoading(); else imgLoadingTpl\">\n <p-progressBar class=\"progress\" [value]=\"loadingPercentage()\"></p-progressBar>\n <span class=\"text-loading\">Loading frames...</span>\n </ng-container>\n <ng-template #imgLoadingTpl>\n <!-- Cache-copy progress is shown whenever a cache download is active (isCaching), independent\n of `imgLoading`, so it's never dropped/masked mid-download. -->\n <ng-container *ngIf=\"isCaching(); else spinnerLoading\">\n <!-- Stage-aware message comes from CacheProgressService updating\n imageLoadingMessage$ (\"Caching image...\" during the GCS download,\n then \"Generating preview...\" during per-slice thumbnail gen). Once the\n download hits 100% the remaining work (server preview/tile generation)\n has no determinate progress, so fall through to the spinner template\n rather than parking a full bar under \"Loading image...\". -->\n <p-progressBar class=\"progress\" [value]=\"cacheProgress()\"></p-progressBar>\n <span class=\"text-loading\">{{ loadingMessage() }}</span>\n </ng-container>\n <ng-template #spinnerLoading>\n <div *ngIf=\"imgLoading()\" class=\"spinner\"></div>\n <span *ngIf=\"imgLoading() && !zoom()\" class=\"text-loading\">{{ loadingMessage() }}</span>\n <span *ngIf=\"imgLoading() && zoom()\" class=\"zoom-text-loading\">{{ loadingMessage() }}</span>\n </ng-template>\n </ng-template>\n <p-button\n *ngIf=\"stackLoading() || imgLoading()\"\n class=\"cancel-loading\"\n label=\"Cancel\"\n (onClick)=\"cancelLoading()\"\n >\n </p-button>\n </div>\n <!-- Translucent \"sharpening\" overlay shown after the small-tier preview is\n on screen while the large-tier render is still loading in the\n background. Lets the user see the blurry image underneath but makes\n it clear something is still loading so they don't mistake the\n low-res render for the final image. -->\n <div *ngIf=\"render.sharpening && !imgLoading() && !stackLoading() && !isCaching()\" class=\"sharpening-overlay\">\n <div class=\"spinner\"></div>\n <span class=\"text-loading\">Sharpening preview...</span>\n </div>\n </div>\n</div>\n\n<!-- Floating, draggable intensity-profile inset, shown while any intensity line\n exists. Kept OUTSIDE the plot div and fixed to the viewport, so it floats over\n the whole page rather than being clipped to the canvas. -->\n<viz-intensity-inset\n [divId]=\"intensityInsetDiv\"\n [plotDivName]=\"plotDivName\"\n [zIndex]=\"zIndex\"\n [imageView]=\"isImageView\"\n [imageInfo]=\"imageInfo\"\n></viz-intensity-inset>\n\n<!-- Channels & Histogram: non-modal floating dialog opened from the toolbar. -->\n<channel-histogram [(visible)]=\"showChannelHistogram\"></channel-histogram>\n\n<!-- Spatial-omics controls. Renders its own empty state when no dataset (or no\n SPATIAL_DATA_PORT) is present, so it is always safe to host. -->\n<spatial-controls [(visible)]=\"showSpatialControls\" [is3d]=\"isSpatial3dMode\"></spatial-controls>\n\n<!-- Side panel of the active contributed plot mode (PLOT_TYPE_CONTRIBUTIONS),\n in the same right-hand area as the spatial controls and the Region Editor.\n Exists only while the mode's session is live; there is no close button,\n because leaving the mode is what ends it. A component panel gets\n PLOT_MODE_CONTEXT / PLOT_MODE_SESSION from its injector; a `mount` panel's\n host element is attached to the slot below (see plotModePanelSlot). -->\n<p-dialog\n *ngIf=\"plotModePanel as panel\"\n [header]=\"panel.title\"\n [visible]=\"true\"\n [modal]=\"false\"\n [closable]=\"false\"\n [resizable]=\"true\"\n [draggable]=\"true\"\n appendTo=\"body\"\n position=\"right\"\n styleClass=\"plot-mode-panel\"\n [style]=\"{ width: '22rem', maxHeight: '85vh' }\"\n [contentStyle]=\"{ overflow: 'auto' }\"\n>\n <ng-container *ngIf=\"panel.component\">\n <ng-container *ngComponentOutlet=\"panel.component; injector: panel.injector ?? undefined\"></ng-container>\n </ng-container>\n <div *ngIf=\"panel.host\" #plotModePanelSlot class=\"plot-mode-panel-slot\"></div>\n</p-dialog>\n\n<!-- An open dialog tool (TOOLBAR_TOOLS, kind: 'dialog'). Non-modal so the user can\n keep working on the image, e.g. painting with the brush the tool armed. The\n tool renders its body into a host element attached to the slot below (see\n toolDialogSlot); closing the dialog ends the tool's session. -->\n<p-dialog\n *ngIf=\"toolDialog as dlg\"\n [header]=\"dlg.title\"\n [visible]=\"true\"\n (visibleChange)=\"$event || closeDialogTool()\"\n [modal]=\"false\"\n [closable]=\"true\"\n [resizable]=\"true\"\n [draggable]=\"true\"\n appendTo=\"body\"\n position=\"right\"\n styleClass=\"tool-dialog\"\n [style]=\"{ width: dlg.width, maxHeight: '85vh' }\"\n [contentStyle]=\"{ overflow: 'auto' }\"\n>\n <div #toolDialogSlot class=\"tool-dialog-slot\"></div>\n</p-dialog>\n\n<!-- Region Editor: non-modal, draggable, resizable floating dialog opened from\n the toolbar (formerly the right-panel Regions tab). Modeless so regions can\n still be drawn/selected on the plot while it's open; stays linked to this\n plotting instance via the root RegionStore singleton. Opens over the right\n side of the view. -->\n<p-dialog\n header=\"Region Editor\"\n [(visible)]=\"showRegionEditor\"\n [modal]=\"false\"\n [resizable]=\"true\"\n [draggable]=\"true\"\n [maximizable]=\"true\"\n appendTo=\"body\"\n position=\"right\"\n [style]=\"{ width: regionEditorWidth, height: '85vh' }\"\n [contentStyle]=\"{ overflow: 'auto' }\"\n>\n <region-editor [active]=\"showRegionEditor\"></region-editor>\n</p-dialog>\n\n<!-- Simplify (Douglas\u2013Peucker): custom px-threshold picker for the selected\n region(s), opened from the right-click \"Simplify \u25B8 Custom\u2026\" action. -->\n<p-dialog\n header=\"Simplify region(s)\"\n [(visible)]=\"displaySimplifyDialog\"\n [modal]=\"true\"\n [style]=\"{ width: '22rem' }\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n>\n <div class=\"flex flex-column gap-2\">\n <span\n >Altitude threshold: <b>{{ regionActions.simplifyThreshold }} px</b></span\n >\n <p-slider [(ngModel)]=\"regionActions.simplifyThreshold\" [min]=\"1\" [max]=\"20\" [step]=\"1\"></p-slider>\n <small>Vertices within this distance of the line between their neighbours are removed.</small>\n </div>\n <ng-template pTemplate=\"footer\">\n <p-button label=\"Cancel\" [text]=\"true\" (onClick)=\"displaySimplifyDialog = false\"></p-button>\n <p-button\n label=\"Apply\"\n icon=\"pi pi-check\"\n (onClick)=\"simplifyRegions(regionActions.simplifyThreshold)\"\n ></p-button>\n </ng-template>\n</p-dialog>\n\n<!-- Parameters for whichever contributed tool is open. One dialog for all of\n them: a tool declares its fields (ToolParamSpec) and this renders them, so\n the toolbar can lay every tool out the same way and a plugin needs no\n PrimeNG of its own. Defaults come from the active checkpoint, since they\n encode what it was trained for. -->\n<p-dialog\n *ngIf=\"toolParams.openParams as open\"\n [header]=\"open.tool.label + ' parameters'\"\n [visible]=\"true\"\n (visibleChange)=\"closeToolParams()\"\n [modal]=\"true\"\n [style]=\"{ width: '30rem' }\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n appendTo=\"body\"\n>\n <div class=\"grid formgrid p-fluid\">\n <ng-container *ngFor=\"let f of open.fields\">\n <div class=\"field\" [ngClass]=\"f.spec.type === 'boolean' ? 'col-12' : 'col-6'\">\n <ng-container *ngIf=\"f.number as n\">\n <label class=\"text-sm\" [pTooltip]=\"n.tooltip || ''\">{{ n.label }}</label>\n <p-inputNumber\n [ngModel]=\"open.values[n.id]\"\n (ngModelChange)=\"open.values[n.id] = $event\"\n [min]=\"n.min\"\n [max]=\"n.max\"\n [step]=\"n.step\"\n [minFractionDigits]=\"n.fractionDigits\"\n [showButtons]=\"true\"\n ></p-inputNumber>\n </ng-container>\n\n <ng-container *ngIf=\"f.select as sel\">\n <label class=\"text-sm\" [pTooltip]=\"sel.tooltip || ''\">{{ sel.label }}</label>\n <p-dropdown\n [options]=\"sel.options\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [ngModel]=\"open.values[sel.id]\"\n (ngModelChange)=\"open.values[sel.id] = $event\"\n appendTo=\"body\"\n ></p-dropdown>\n </ng-container>\n\n <!-- Checkbox label sits beside the box and may run to a sentence, so\n it does not get the stacked label the other types use. -->\n <div *ngIf=\"f.spec.type === 'boolean'\" class=\"flex align-items-center gap-2\">\n <p-checkbox\n [ngModel]=\"open.values[f.spec.id]\"\n (ngModelChange)=\"open.values[f.spec.id] = $event\"\n [binary]=\"true\"\n [inputId]=\"open.tool.id + '-' + f.spec.id\"\n ></p-checkbox>\n <label [for]=\"open.tool.id + '-' + f.spec.id\" class=\"text-sm mb-0\" [pTooltip]=\"f.spec.tooltip || ''\">{{\n f.spec.label\n }}</label>\n </div>\n </div>\n </ng-container>\n </div>\n <ng-template pTemplate=\"footer\">\n <p-button\n label=\"Reset to model defaults\"\n [text]=\"true\"\n size=\"small\"\n (onClick)=\"resetToolParams(open.tool.id)\"\n ></p-button>\n <p-button label=\"Close\" size=\"small\" (onClick)=\"closeToolParams()\"></p-button>\n </ng-template>\n</p-dialog>\n", styles: [":host{display:flex;flex-direction:column;height:100%;overflow:hidden}.viz-panes{flex:1;min-height:0;display:flex}.viz-plot{flex:1 1 0;min-width:0;min-height:0;height:auto!important}.viz-panes.viz-quad{display:grid}.viz-panes.viz-quad>.viz-plot{grid-area:1/1/2/2;min-height:0;overflow:hidden}.viz-cell{position:relative;min-width:0;min-height:0;overflow:hidden}.viz-cell-z{grid-area:1/3/2/4}.viz-cell-x{grid-area:3/1/4/2}.viz-cell-y{grid-area:3/3/4/4}.viz-slice-pane{position:absolute;inset:0}.viz-pane-badge{position:absolute;top:6px;left:6px;z-index:10;padding:1px 8px;border-radius:4px;color:#fff;font:600 12px/1.6 system-ui,sans-serif;pointer-events:none}.viz-pane-badge-z{background:#668cff}.viz-pane-divider{background:var(--surface-border, #cccccc);touch-action:none}.viz-pane-divider:hover,.viz-pane-divider:focus-visible{background:var(--primary-color, #3b82f6);outline:none}.viz-pane-divider-v{grid-area:1/2/4/3;cursor:col-resize}.viz-pane-divider-h{grid-area:2/1/3/4;cursor:row-resize}.toolbar-dock{display:flex;align-items:stretch;width:100%}.toolbar-dock plotting-toolbar{flex:1;min-width:0}.toolbar-dock.floating{position:fixed;z-index:1000;width:auto;max-width:calc(100% - 16px);background:var(--surface-card, #ffffff);border:1px solid var(--surface-border, #cccccc);border-radius:6px;box-shadow:0 4px 16px #0000004d}.toolbar-dock.floating plotting-toolbar{flex:0 1 auto}.toolbar-dock.floating .toolbar-drag-handle{border-radius:6px 0 0 6px}.toolbar-drag-handle{display:flex;align-items:center;justify-content:center;padding:0 .4rem;cursor:move;color:var(--primary-color);background:var(--surface-100, rgba(0, 0, 0, .04));border-right:1px solid var(--surface-border, #cccccc);-webkit-user-select:none;user-select:none}.toolbar-dock-btn{align-self:center}:host ::ng-deep .navigator{margin-bottom:80px!important;margin-right:12px!important}kbd{background:#e8e8e8;border:1px solid #bbb;border-radius:3px;padding:1px 5px;font-family:monospace;font-size:.85em}.toolbar-separator{border-left:1px solid var(--surface-border);height:1.5rem;margin:0 .25rem;align-self:center}.progress{position:absolute;width:50%;left:25%;top:55%}.text-loading{position:absolute;margin:0 auto;left:45%;top:60%;font-weight:700}.zoom-text-loading{position:absolute;margin:0 auto;left:35%;top:60%;font-weight:700;display:inline-block;width:350px}.cancel-loading{position:absolute;margin:0 auto;left:46%;top:70%}.spinner{position:absolute;left:45%;top:45%;height:100px;width:100px;margin:0 auto;-webkit-animation:rotation .6s infinite linear;-moz-animation:rotation .6s infinite linear;-o-animation:rotation .6s infinite linear;animation:rotation .6s infinite linear;border-left:6px solid rgba(0,174,239,.15);border-right:6px solid rgba(0,174,239,.15);border-bottom:6px solid rgba(0,174,239,.15);border-top:6px solid rgb(82,107,178);border-radius:100%}.loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#ffffff80;z-index:1000}.sharpening-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#ffffff2e;pointer-events:none;z-index:1000}.sharpening-overlay .spinner{height:60px;width:60px;border-width:4px;left:calc(50% - 30px);top:calc(50% - 60px)}.sharpening-overlay .text-loading{position:absolute;left:0;right:0;width:auto;text-align:center;top:calc(50% + 35px);font-size:.9rem;color:#526bb2}@-webkit-keyframes rotation{0%{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(359deg)}}@-moz-keyframes rotation{0%{-moz-transform:rotate(0deg)}to{-moz-transform:rotate(359deg)}}@-o-keyframes rotation{0%{-o-transform:rotate(0deg)}to{-o-transform:rotate(359deg)}}@keyframes rotation{0%{transform:rotate(0)}to{transform:rotate(359deg)}}::ng-deep .context-menu-active>.p-menuitem-content{background-color:var(--primary-color)!important}::ng-deep .context-menu-active>.p-menuitem-content .p-menuitem-icon,::ng-deep .context-menu-active>.p-menuitem-content .p-menuitem-text{color:#fff!important}::ng-deep .context-menu-active>.p-menuitem-content .zoom-box-off-icon,::ng-deep .context-menu-active>.p-menuitem-content .wand-icon,::ng-deep .context-menu-active>.p-menuitem-content .polyline-icon,::ng-deep .context-menu-active>.p-menuitem-content .polygon-vertices-icon,::ng-deep .context-menu-active>.p-menuitem-content .vertex-add-icon,::ng-deep .context-menu-active>.p-menuitem-content .vertex-delete-icon,::ng-deep .context-menu-active>.p-menuitem-content .region-move-icon,::ng-deep .context-menu-active>.p-menuitem-content .to-bezier-icon,::ng-deep .context-menu-active>.p-menuitem-content .to-polygon-icon{filter:brightness(0) invert(1)}::ng-deep .zoom-box-off-icon{background:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 100\" fill=\"black\" fill-rule=\"evenodd\">%0A <!-- Rectangle outline -->%0A <rect x=\"2\" y=\"2\" width=\"56\" height=\"56\"/>%0A <rect x=\"9\" y=\"9\" width=\"42\" height=\"42\"/>%0A <!-- Magnifying glass ring -->%0A <circle cx=\"70\" cy=\"70\" r=\"23\"/>%0A <circle cx=\"70\" cy=\"70\" r=\"14\"/>%0A <!-- Handle -->%0A <polygon points=\"81,81 97,97 92,100 77,85\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .wand-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<svg%0A viewBox=\"0 0 100 100\"%0A fill=\"black\"%0A fill-rule=\"evenodd\"%0A version=\"1.1\"%0A id=\"svg4\"%0A sodipodi:docname=\"wand.svg\"%0A inkscape:version=\"1.4.3 (0d15f75, 2025-12-25)\"%0A xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"%0A xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"%0A xmlns=\"http://www.w3.org/2000/svg\"%0A xmlns:svg=\"http://www.w3.org/2000/svg\">%0A <defs%0A id=\"defs4\" />%0A <sodipodi:namedview%0A id=\"namedview4\"%0A pagecolor=\"%23ffffff\"%0A bordercolor=\"%23000000\"%0A borderopacity=\"0.25\"%0A inkscape:showpageshadow=\"2\"%0A inkscape:pageopacity=\"0.0\"%0A inkscape:pagecheckerboard=\"0\"%0A inkscape:deskcolor=\"%23d1d1d1\"%0A inkscape:zoom=\"8.74\"%0A inkscape:cx=\"50\"%0A inkscape:cy=\"49.942792\"%0A inkscape:window-width=\"1024\"%0A inkscape:window-height=\"1186\"%0A inkscape:window-x=\"3560\"%0A inkscape:window-y=\"131\"%0A inkscape:window-maximized=\"0\"%0A inkscape:current-layer=\"svg4\" />%0A <!-- Wand handle: thin diagonal stick from lower-left to upper-right -->%0A <polygon%0A points=\"12,92 78,26 74,22 8,88 \"%0A id=\"polygon1\"%0A transform=\"matrix(1.0375192,0.05799445,0.25179496,0.91871864,-17.85351,5.6289793)\" />%0A <!-- 4-pointed star at the wand tip -->%0A <polygon%0A points=\"62,34 76,30 80,6 84,30 98,34 84,38 80,62 76,38 \"%0A id=\"polygon2\"%0A transform=\"matrix(1.3082889,0,0,1.0245178,-38.907958,-1.4056881)\" />%0A <!-- Small sparkle to the upper-left -->%0A <polygon%0A points=\"46,30 36,32 34,42 32,32 22,30 32,28 34,18 36,28 \"%0A id=\"polygon3\"%0A transform=\"translate(-9.610984,-6.7505721)\" />%0A <!-- Small sparkle to the lower-right -->%0A <polygon%0A points=\"62,80 70,82 62,84 60,92 58,84 50,82 58,80 60,72 \"%0A id=\"polygon4\"%0A transform=\"translate(0,-1.6018307)\" />%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .brush-icon{background:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 640\"><!--!Font Awesome Free 7.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d=\"M512.5 74.3L291.1 222C262 241.4 243.5 272.9 240.5 307.3C302.8 320.1 351.9 369.2 364.8 431.6C399.3 428.6 430.7 410.1 450.1 381L597.7 159.5C604.4 149.4 608 137.6 608 125.4C608 91.5 580.5 64 546.6 64C534.5 64 522.6 67.6 512.5 74.3zM320 464C320 402.1 269.9 352 208 352C146.1 352 96 402.1 96 464C96 467.9 96.2 471.8 96.6 475.6C98.4 493.1 86.4 512 68.8 512L64 512C46.3 512 32 526.3 32 544C32 561.7 46.3 576 64 576L208 576C269.9 576 320 525.9 320 464z\"/></svg>') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .polyline-icon{background:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\">%0A <polyline points=\"1,14 5,3 10,11 15,2\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .polygon-vertices-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Polygon (click-to-place) tool icon: a traced polyline with vertex dots. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <g transform=\"matrix(1.4740709,0,0,1.4740709,-6.0268793,-6.8086826)\">%0A <polyline points=\"23.877,16.627 14.657,10.767 5.25,21.551 12.757,29.397\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"1.6\"%0A stroke-linejoin=\"round\" stroke-linecap=\"round\"/>%0A <circle cx=\"23.877\" cy=\"16.627\" r=\"1.9\"/>%0A <circle cx=\"14.657\" cy=\"10.767\" r=\"1.9\"/>%0A <circle cx=\"5.25\" cy=\"21.551\" r=\"1.9\"/>%0A <circle cx=\"12.757\" cy=\"29.397\" r=\"1.9\"/>%0A </g>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .vertex-add-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Add-vertex tool icon: a region blob with three corner vertices and a plus glyph. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <g transform=\"matrix(1.5222969,0,0,1.5222969,-8.2143505,-7.6146399)\">%0A <path d=\"m 9.35834,12.33267 c 1.78,-2.53 4.93,-3.56 7.86,-3.98 3.98,-0.72 8.33,0.08 11.52,2.67 2.62,1.98 4.71,5.1 4.53,8.49 -0.29,2.27 -2.5,3.81 -4.66,4.01 -2.75,0.43 -5.54,0.07 -8.28,-0.26 -3.99,-0.68 -8.05,-2.16 -10.93,-5.12 -1.32,-1.63 -1.39,-4.17 -0.04,-5.81 z\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"1.6\" stroke-miterlimit=\"10\"/>%0A <circle cx=\"8.294\" cy=\"15.248\" r=\"2.63\"/>%0A <circle cx=\"19.781\" cy=\"8.287\" r=\"2.63\"/>%0A <circle cx=\"25.044\" cy=\"23.748\" r=\"2.63\"/>%0A </g>%0A <path d=\"M 9.65,29.0 H 5.85 v 5.3 H 0.55 v 3.4 H 5.85 v 5.3 H 9.65 V 37.7 H 14.95 V 34.3 H 9.65 Z\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .vertex-delete-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Delete-vertex tool icon: a region blob with three corner vertices and a minus glyph. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <g transform=\"matrix(1.5222969,0,0,1.5222969,-8.2143505,-7.6146399)\">%0A <path d=\"m 9.35834,12.33267 c 1.78,-2.53 4.93,-3.56 7.86,-3.98 3.98,-0.72 8.33,0.08 11.52,2.67 2.62,1.98 4.71,5.1 4.53,8.49 -0.29,2.27 -2.5,3.81 -4.66,4.01 -2.75,0.43 -5.54,0.07 -8.28,-0.26 -3.99,-0.68 -8.05,-2.16 -10.93,-5.12 -1.32,-1.63 -1.39,-4.17 -0.04,-5.81 z\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"1.6\" stroke-miterlimit=\"10\"/>%0A <circle cx=\"8.294\" cy=\"15.248\" r=\"2.63\"/>%0A <circle cx=\"19.781\" cy=\"8.287\" r=\"2.63\"/>%0A <circle cx=\"25.044\" cy=\"23.748\" r=\"2.63\"/>%0A </g>%0A <path d=\"M 0.55,34.3 v 3.4 H 14.95 V 34.3 Z\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .region-move-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Region-move tool icon: a region blob with a drag arrow. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <path d=\"m 17.115582,8.9648664 c 1.707597,-3.3276806 4.729468,-4.6824281 7.540287,-5.2348498 3.827703,-0.947008 7.991169,0.1052238 11.051414,3.5118228 2.523022,2.604273 4.518416,6.7079726 4.345738,11.1668036 -0.278204,2.985704 -2.398311,5.011251 -4.470451,5.274308 -2.638142,0.565574 -5.314655,0.09206 -7.943203,-0.341976 C 23.811664,22.446579 19.916808,20.499952 17.153955,16.606696 15.89724,14.462775 15.820494,11.12194 17.115585,8.9648664 Z\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"2.1\" stroke-miterlimit=\"10\"/>%0A <path d=\"m 26.741429,13.966963 6.746922,16.786269 3.229398,-4.060758 3.583857,3.583857 2.761195,-2.761196 -3.583856,-3.571852 4.060758,-3.2354 z\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .to-bezier-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Convert-to-bezier tool icon: a smooth curve through two anchor points with control handles. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <!-- smooth cubic curve between the two anchors -->%0A <path d=\"M 7,34 C 7,16 37,28 37,10\" fill=\"none\" stroke=\"%23000000\" stroke-width=\"2.4\"%0A stroke-linecap=\"round\"/>%0A <!-- control handles -->%0A <line x1=\"7\" y1=\"34\" x2=\"7\" y2=\"22\" stroke=\"%23000000\" stroke-width=\"1.4\"/>%0A <line x1=\"37\" y1=\"10\" x2=\"37\" y2=\"22\" stroke=\"%23000000\" stroke-width=\"1.4\"/>%0A <circle cx=\"7\" cy=\"22\" r=\"2.2\"/>%0A <circle cx=\"37\" cy=\"22\" r=\"2.2\"/>%0A <!-- anchor points -->%0A <rect x=\"4\" y=\"31\" width=\"6\" height=\"6\" rx=\"1\"/>%0A <rect x=\"34\" y=\"7\" width=\"6\" height=\"6\" rx=\"1\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .to-polygon-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Convert-to-polygon tool icon: endpoints joined by straight segments through a vertex. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <!-- straight-segment path through the vertices -->%0A <polyline points=\"7,34 22,12 37,10\" fill=\"none\" stroke=\"%23000000\" stroke-width=\"2.4\"%0A stroke-linecap=\"round\" stroke-linejoin=\"round\"/>%0A <!-- vertices -->%0A <rect x=\"4\" y=\"31\" width=\"6\" height=\"6\" rx=\"1\"/>%0A <rect x=\"19\" y=\"9\" width=\"6\" height=\"6\" rx=\"1\"/>%0A <rect x=\"34\" y=\"7\" width=\"6\" height=\"6\" rx=\"1\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}:host ::ng-deep .sam-progress .p-progressbar-value{transition:none}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i7.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i7.NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }, { kind: "directive", type: i7.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i7.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i8.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i8.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: SharedModule }, { kind: "directive", type: i1.PrimeTemplate, selector: "[pTemplate]", inputs: ["type", "pTemplate"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i9.Button, selector: "p-button", inputs: ["type", "iconPos", "icon", "badge", "label", "disabled", "loading", "loadingIcon", "raised", "rounded", "text", "plain", "severity", "outlined", "link", "tabindex", "size", "style", "styleClass", "badgeClass", "ariaLabel", "autofocus"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "ngmodule", type: CheckboxModule }, { kind: "component", type: i10.Checkbox, selector: "p-checkbox", inputs: ["value", "name", "disabled", "binary", "label", "ariaLabelledBy", "ariaLabel", "tabindex", "inputId", "style", "styleClass", "labelStyleClass", "formControl", "checkboxIcon", "readonly", "required", "autofocus", "trueValue", "falseValue", "variant"], outputs: ["onChange", "onFocus", "onBlur"] }, { kind: "ngmodule", type: ContextMenuModule }, { kind: "component", type: i11.ContextMenu, selector: "p-contextMenu", inputs: ["model", "triggerEvent", "target", "global", "style", "styleClass", "appendTo", "autoZIndex", "baseZIndex", "id", "ariaLabel", "ariaLabelledBy", "pressDelay"], outputs: ["onShow", "onHide"] }, { kind: "directive", type: i12.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "ngmodule", type: DialogModule }, { kind: "component", type: i13.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "maskStyle", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "visible", "style", "position"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: DropdownModule }, { kind: "component", type: i14.Dropdown, selector: "p-dropdown", inputs: ["id", "scrollHeight", "filter", "name", "style", "panelStyle", "styleClass", "panelStyleClass", "readonly", "required", "editable", "appendTo", "tabindex", "placeholder", "loadingIcon", "filterPlaceholder", "filterLocale", "variant", "inputId", "dataKey", "filterBy", "filterFields", "autofocus", "resetFilterOnHide", "checkmark", "dropdownIcon", "loading", "optionLabel", "optionValue", "optionDisabled", "optionGroupLabel", "optionGroupChildren", "autoDisplayFirst", "group", "showClear", "emptyFilterMessage", "emptyMessage", "lazy", "virtualScroll", "virtualScrollItemSize", "virtualScrollOptions", "overlayOptions", "ariaFilterLabel", "ariaLabel", "ariaLabelledBy", "filterMatchMode", "maxlength", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "focusOnHover", "selectOnFocus", "autoOptionFocus", "autofocusFilter", "autoShowPanelOnPrintableCharacterKeyDown", "disabled", "itemSize", "autoZIndex", "baseZIndex", "showTransitionOptions", "hideTransitionOptions", "filterValue", "options"], outputs: ["onChange", "onFilter", "onFocus", "onBlur", "onClick", "onShow", "onHide", "onClear", "onLazyLoad"] }, { kind: "ngmodule", type: InputNumberModule }, { kind: "component", type: i15.InputNumber, selector: "p-inputNumber", inputs: ["showButtons", "format", "buttonLayout", "inputId", "styleClass", "style", "placeholder", "size", "maxlength", "tabindex", "title", "ariaLabelledBy", "ariaLabel", "ariaRequired", "name", "required", "autocomplete", "min", "max", "incrementButtonClass", "decrementButtonClass", "incrementButtonIcon", "decrementButtonIcon", "readonly", "step", "allowEmpty", "locale", "localeMatcher", "mode", "currency", "currencyDisplay", "useGrouping", "variant", "minFractionDigits", "maxFractionDigits", "prefix", "suffix", "inputStyle", "inputStyleClass", "showClear", "autofocus", "disabled"], outputs: ["onInput", "onFocus", "onBlur", "onKeyDown", "onClear"] }, { kind: "ngmodule", type: ProgressBarModule }, { kind: "component", type: i16.ProgressBar, selector: "p-progressBar", inputs: ["value", "showValue", "styleClass", "style", "unit", "mode", "color"] }, { kind: "ngmodule", type: SliderModule }, { kind: "component", type: i17.Slider, selector: "p-slider", inputs: ["animate", "disabled", "min", "max", "orientation", "step", "range", "style", "styleClass", "ariaLabel", "ariaLabelledBy", "tabindex", "autofocus"], outputs: ["onChange", "onSlideEnd"] }, { kind: "ngmodule", type: ToastModule }, { kind: "component", type: i18.Toast, selector: "p-toast", inputs: ["key", "autoZIndex", "baseZIndex", "life", "style", "styleClass", "position", "preventOpenDuplicates", "preventDuplicates", "showTransformOptions", "hideTransformOptions", "showTransitionOptions", "hideTransitionOptions", "breakpoints"], outputs: ["onClose"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: FloatingDragDirective, selector: "[vizFloatingDrag]", inputs: ["vizFloatingDrag"], outputs: ["vizFloatingDragMove"] }, { kind: "component", type: ToolbarComponent, selector: "plotting-toolbar", inputs: ["imageInfo", "hasSpatialDataset", "plotTypeOptions", "selectedPlotType", "basePlotType", "isoRange", "maxIndex", "zIndex", "isHeatmap", "is3dRegions", "isVolumeView", "sliceEditor", "activeDragMode", "activeSurface3dMode", "axesVisible", "wireframeActive", "resolutionScale", "wandSensitivity", "brushSize", "vertexEraserRadius", "canUndo", "canRedo", "stackOptions", "tools", "imageSmoothingEnabled", "samModels", "samModelId", "contributedTools", "dialogTools", "openDialogToolId", "toolModelIds"], outputs: ["selectPlotType", "addProfileLine", "toggleImageSmoothing", "isoRangeChange", "openChannelHistogram", "openSpatialControls", "openRegionEditor", "toggleSliceEditor", "selectStackOption", "zScrub", "zSlide", "zIndexInput", "reloadAndPlot", "downloadImage", "autoscaleImage", "toggleDragMode", "zoomIn", "zoomOut", "toggleSurface3dMode", "resetSurfaceCamera", "toggleAxes", "toggleWireframe", "selectResolution", "deleteRegion", "undoRegion", "redoRegion", "segmentRegions", "segmentCellpose", "runTool", "toggleDialogTool", "toolModelChange", "openToolParams", "samModelChange", "wandSensitivityChange", "brushSizeChange", "vertexEraserRadiusChange"] }, { kind: "component", type: IntensityInsetComponent, selector: "viz-intensity-inset", inputs: ["divId", "plotDivName", "zIndex", "imageView", "imageInfo"] }, { kind: "component", type: SectionPaneComponent, selector: "viz-section-pane", inputs: ["axis", "view"], outputs: ["pick"] }, { kind: "component", type: ChannelHistogramComponent, selector: "channel-histogram", inputs: ["visible"], outputs: ["visibleChange"] }, { kind: "component", type: SpatialControlsComponent, selector: "spatial-controls", inputs: ["visible", "is3d"], outputs: ["visibleChange"] }, { kind: "component", type: RegionEditorComponent, selector: "region-editor", inputs: ["active"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1098
1219
|
}
|
|
1099
1220
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: VisualizerComponent, decorators: [{
|
|
1100
1221
|
type: Component,
|
|
@@ -1115,10 +1236,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
|
|
|
1115
1236
|
FloatingDragDirective,
|
|
1116
1237
|
ToolbarComponent,
|
|
1117
1238
|
IntensityInsetComponent,
|
|
1239
|
+
SectionPaneComponent,
|
|
1118
1240
|
ChannelHistogramComponent,
|
|
1119
1241
|
SpatialControlsComponent,
|
|
1120
1242
|
RegionEditorComponent,
|
|
1121
|
-
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- SAM toast: live status + encoder-download progress bar (jit-ui#90). Sticky\n while a segment runs; stays open until the bar reaches 100% and the run ends. -->\n<p-toast [key]=\"samToastKey\" position=\"bottom-right\">\n <ng-template let-message pTemplate=\"message\">\n <div style=\"flex: 1; min-width: 16rem\">\n <div class=\"font-bold mb-1\">{{ message.summary }}</div>\n <div>{{ segmentation.status || message.detail }}</div>\n <p-progressBar\n *ngIf=\"segmentation.downloading\"\n [value]=\"segmentation.progress\"\n styleClass=\"mt-2 sam-progress\"\n ></p-progressBar>\n <p-progressBar\n *ngIf=\"segmentation.busy && !segmentation.downloading\"\n mode=\"indeterminate\"\n styleClass=\"mt-2\"\n [style]=\"{ height: '4px' }\"\n ></p-progressBar>\n </div>\n </ng-template>\n</p-toast>\n\n<!-- Result/error notices from the library itself (segmentation outcome, region\n validation). Rendered here so they do not depend on the host mounting a\n keyless <p-toast> \u2014 without this the messages went nowhere in any host but\n jit-ui, and a failed run looked like a button that did nothing. -->\n<p-toast [key]=\"resultToastKey\" position=\"bottom-right\"></p-toast>\n\n<!-- Shared outlets for notices raised where there is no per-instance key to use:\n the root-provided PlotlyService and the region-editor dialog. Rendered by a\n single visualizer (ownsSharedToasts) so a message from the root service is\n not shown once per live viewer. -->\n<p-toast *ngIf=\"ownsSharedToasts\" [key]=\"vizToastKey\"></p-toast>\n<p-toast *ngIf=\"ownsSharedToasts\" [key]=\"vizAlertToastKey\" position=\"center\"></p-toast>\n\n<!-- Toolbar dock: docked across the top by default; drag the handle to detach\n it into a floating, movable window (frees the top row for the image). -->\n<div\n class=\"toolbar-dock\"\n [class.floating]=\"toolbarFloating\"\n [style.left.px]=\"toolbarFloating ? toolbarPos.x : null\"\n [style.top.px]=\"toolbarFloating ? toolbarPos.y : null\"\n>\n <div\n class=\"toolbar-drag-handle\"\n [vizFloatingDrag]=\"toolbarDragOrigin\"\n (vizFloatingDragMove)=\"toolbarPos = $event\"\n pTooltip=\"Drag to float the toolbar\"\n tooltipPosition=\"bottom\"\n >\n <i class=\"pi pi-bars\"></i>\n </div>\n <plotting-toolbar\n [imageInfo]=\"imageInfo\"\n [hasSpatialDataset]=\"hasSpatialDataset\"\n [plotTypeOptions]=\"plotTypeMenu\"\n [selectedPlotType]=\"selectedPlotTypeId\"\n [basePlotType]=\"basePlotType\"\n [isoRange]=\"isoRange\"\n [maxIndex]=\"maxIndex\"\n [zIndex]=\"zIndex\"\n [isHeatmap]=\"isHeatmap\"\n [is3dRegions]=\"isSpatial3dMode\"\n [activeDragMode]=\"activeDragMode\"\n [activeSurface3dMode]=\"activeSurface3dMode\"\n [axesVisible]=\"axesVisible\"\n [wireframeActive]=\"wireframeActive\"\n [resolutionScale]=\"resolutionScale\"\n [wandSensitivity]=\"wandSensitivity\"\n [brushSize]=\"brushSize\"\n [samModels]=\"samModels\"\n [samModelId]=\"samModelId\"\n [contributedTools]=\"contributedTools\"\n [dialogTools]=\"dialogTools\"\n [openDialogToolId]=\"openDialogToolId\"\n (toggleDialogTool)=\"toggleDialogTool($event)\"\n [toolModelIds]=\"toolParams.toolModelIds\"\n [vertexEraserRadius]=\"vertexEraserRadius\"\n [canUndo]=\"regionActions.canUndo\"\n [canRedo]=\"regionActions.canRedo\"\n [tools]=\"toolbarTools\"\n [imageSmoothingEnabled]=\"imageSmoothingEnabled\"\n (selectPlotType)=\"onSelectPlotType($event)\"\n (toggleImageSmoothing)=\"onToggleImageSmoothing()\"\n (addProfileLine)=\"addProfileLine()\"\n (isoRangeChange)=\"onIsoRangeChange($event)\"\n (openChannelHistogram)=\"openChannelHistogram()\"\n (openSpatialControls)=\"openSpatialControls()\"\n (openRegionEditor)=\"openRegionEditor()\"\n (selectStackOption)=\"selectStackOption($event)\"\n (zScrub)=\"onZScrub($event)\"\n (zSlide)=\"onZSlide($event)\"\n (zIndexInput)=\"zIndex = $event; updateZIndex()\"\n (reloadAndPlot)=\"reloadAndPlot()\"\n (downloadImage)=\"downloadImage()\"\n (autoscaleImage)=\"autoscaleImage()\"\n (toggleDragMode)=\"toggleDragMode($event)\"\n (zoomIn)=\"zoomIn()\"\n (zoomOut)=\"zoomOut()\"\n (toggleSurface3dMode)=\"toggleSurface3dMode($event)\"\n (resetSurfaceCamera)=\"resetSurfaceCamera()\"\n (toggleAxes)=\"toggleAxes()\"\n (toggleWireframe)=\"toggleWireframe()\"\n (selectResolution)=\"selectResolution($event)\"\n (deleteRegion)=\"deleteRegion()\"\n (undoRegion)=\"undoRegion()\"\n (redoRegion)=\"redoRegion()\"\n (segmentRegions)=\"segmentRegions()\"\n (segmentCellpose)=\"segmentCellpose()\"\n (samModelChange)=\"onSamModelChange($event)\"\n (runTool)=\"runTool($event)\"\n (toolModelChange)=\"onToolModelChange($event)\"\n (openToolParams)=\"openToolParams($event)\"\n (wandSensitivityChange)=\"onWandSensitivityChange($event)\"\n (brushSizeChange)=\"onBrushSizeChange($event)\"\n (vertexEraserRadiusChange)=\"onVertexEraserRadiusChange($event)\"\n >\n <!-- Host-projected custom toolbar buttons, forwarded into the toolbar. -->\n <ng-content></ng-content>\n </plotting-toolbar>\n <p-button\n *ngIf=\"toolbarFloating\"\n class=\"toolbar-dock-btn\"\n icon=\"pi pi-thumbtack\"\n size=\"small\"\n [text]=\"true\"\n pTooltip=\"Dock to top\"\n tooltipPosition=\"bottom\"\n (onClick)=\"dockToolbar()\"\n >\n </p-button>\n</div>\n\n<p-contextMenu #cm [model]=\"contextMenuItems\" appendTo=\"body\"></p-contextMenu>\n<!-- No `h-full` here: PrimeFlex's height:100% !important made #plot as tall as\n the whole host, so under the docked toolbar its bottom toolbar-height strip\n (incl. the OSD scale bar at bottom-left) was clipped by the host's\n overflow:hidden. The component stylesheet sizes it (.viz-plot { flex: 1 }). -->\n<div class=\"w-full relative viz-plot\" [id]=\"plotDivName\">\n <div *ngIf=\"imgLoading() || stackLoading() || isCaching()\" class=\"loading-overlay\">\n <!-- Determinate stack/volume progress takes precedence: while it's active show ONLY the\n progress bar + \"Loading frames...\", not the generic spinner/\"Loading image...\" on top of\n it (both were rendering at once for napari volume/isosurface loads). -->\n <ng-container *ngIf=\"stackLoading(); else imgLoadingTpl\">\n <p-progressBar class=\"progress\" [value]=\"loadingPercentage()\"></p-progressBar>\n <span class=\"text-loading\">Loading frames...</span>\n </ng-container>\n <ng-template #imgLoadingTpl>\n <!-- Cache-copy progress is shown whenever a cache download is active (isCaching), independent\n of `imgLoading`, so it's never dropped/masked mid-download. -->\n <ng-container *ngIf=\"isCaching(); else spinnerLoading\">\n <!-- Stage-aware message comes from CacheProgressService updating\n imageLoadingMessage$ (\"Caching image...\" during the GCS download,\n then \"Generating preview...\" during per-slice thumbnail gen). Once the\n download hits 100% the remaining work (server preview/tile generation)\n has no determinate progress, so fall through to the spinner template\n rather than parking a full bar under \"Loading image...\". -->\n <p-progressBar class=\"progress\" [value]=\"cacheProgress()\"></p-progressBar>\n <span class=\"text-loading\">{{ loadingMessage() }}</span>\n </ng-container>\n <ng-template #spinnerLoading>\n <div *ngIf=\"imgLoading()\" class=\"spinner\"></div>\n <span *ngIf=\"imgLoading() && !zoom()\" class=\"text-loading\">{{ loadingMessage() }}</span>\n <span *ngIf=\"imgLoading() && zoom()\" class=\"zoom-text-loading\">{{ loadingMessage() }}</span>\n </ng-template>\n </ng-template>\n <p-button\n *ngIf=\"stackLoading() || imgLoading()\"\n class=\"cancel-loading\"\n label=\"Cancel\"\n (onClick)=\"cancelLoading()\"\n >\n </p-button>\n </div>\n <!-- Translucent \"sharpening\" overlay shown after the small-tier preview is\n on screen while the large-tier render is still loading in the\n background. Lets the user see the blurry image underneath but makes\n it clear something is still loading so they don't mistake the\n low-res render for the final image. -->\n <div *ngIf=\"render.sharpening && !imgLoading() && !stackLoading() && !isCaching()\" class=\"sharpening-overlay\">\n <div class=\"spinner\"></div>\n <span class=\"text-loading\">Sharpening preview...</span>\n </div>\n</div>\n\n<!-- Floating, draggable intensity-profile inset, shown while any intensity line\n exists. Kept OUTSIDE the plot div and fixed to the viewport, so it floats over\n the whole page rather than being clipped to the canvas. -->\n<viz-intensity-inset\n [divId]=\"intensityInsetDiv\"\n [plotDivName]=\"plotDivName\"\n [zIndex]=\"zIndex\"\n [imageView]=\"isImageView\"\n [imageInfo]=\"imageInfo\"\n></viz-intensity-inset>\n\n<!-- Channels & Histogram: non-modal floating dialog opened from the toolbar. -->\n<channel-histogram [(visible)]=\"showChannelHistogram\"></channel-histogram>\n\n<!-- Spatial-omics controls. Renders its own empty state when no dataset (or no\n SPATIAL_DATA_PORT) is present, so it is always safe to host. -->\n<spatial-controls [(visible)]=\"showSpatialControls\" [is3d]=\"isSpatial3dMode\"></spatial-controls>\n\n<!-- Side panel of the active contributed plot mode (PLOT_TYPE_CONTRIBUTIONS),\n in the same right-hand area as the spatial controls and the Region Editor.\n Exists only while the mode's session is live; there is no close button,\n because leaving the mode is what ends it. A component panel gets\n PLOT_MODE_CONTEXT / PLOT_MODE_SESSION from its injector; a `mount` panel's\n host element is attached to the slot below (see plotModePanelSlot). -->\n<p-dialog\n *ngIf=\"plotModePanel as panel\"\n [header]=\"panel.title\"\n [visible]=\"true\"\n [modal]=\"false\"\n [closable]=\"false\"\n [resizable]=\"true\"\n [draggable]=\"true\"\n appendTo=\"body\"\n position=\"right\"\n styleClass=\"plot-mode-panel\"\n [style]=\"{ width: '22rem', maxHeight: '85vh' }\"\n [contentStyle]=\"{ overflow: 'auto' }\"\n>\n <ng-container *ngIf=\"panel.component\">\n <ng-container *ngComponentOutlet=\"panel.component; injector: panel.injector ?? undefined\"></ng-container>\n </ng-container>\n <div *ngIf=\"panel.host\" #plotModePanelSlot class=\"plot-mode-panel-slot\"></div>\n</p-dialog>\n\n<!-- An open dialog tool (TOOLBAR_TOOLS, kind: 'dialog'). Non-modal so the user can\n keep working on the image, e.g. painting with the brush the tool armed. The\n tool renders its body into a host element attached to the slot below (see\n toolDialogSlot); closing the dialog ends the tool's session. -->\n<p-dialog\n *ngIf=\"toolDialog as dlg\"\n [header]=\"dlg.title\"\n [visible]=\"true\"\n (visibleChange)=\"$event || closeDialogTool()\"\n [modal]=\"false\"\n [closable]=\"true\"\n [resizable]=\"true\"\n [draggable]=\"true\"\n appendTo=\"body\"\n position=\"right\"\n styleClass=\"tool-dialog\"\n [style]=\"{ width: dlg.width, maxHeight: '85vh' }\"\n [contentStyle]=\"{ overflow: 'auto' }\"\n>\n <div #toolDialogSlot class=\"tool-dialog-slot\"></div>\n</p-dialog>\n\n<!-- Region Editor: non-modal, draggable, resizable floating dialog opened from\n the toolbar (formerly the right-panel Regions tab). Modeless so regions can\n still be drawn/selected on the plot while it's open; stays linked to this\n plotting instance via the root RegionStore singleton. Opens over the right\n side of the view. -->\n<p-dialog\n header=\"Region Editor\"\n [(visible)]=\"showRegionEditor\"\n [modal]=\"false\"\n [resizable]=\"true\"\n [draggable]=\"true\"\n [maximizable]=\"true\"\n appendTo=\"body\"\n position=\"right\"\n [style]=\"{ width: regionEditorWidth, height: '85vh' }\"\n [contentStyle]=\"{ overflow: 'auto' }\"\n>\n <region-editor></region-editor>\n</p-dialog>\n\n<!-- Simplify (Douglas\u2013Peucker): custom px-threshold picker for the selected\n region(s), opened from the right-click \"Simplify \u25B8 Custom\u2026\" action. -->\n<p-dialog\n header=\"Simplify region(s)\"\n [(visible)]=\"displaySimplifyDialog\"\n [modal]=\"true\"\n [style]=\"{ width: '22rem' }\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n>\n <div class=\"flex flex-column gap-2\">\n <span\n >Altitude threshold: <b>{{ regionActions.simplifyThreshold }} px</b></span\n >\n <p-slider [(ngModel)]=\"regionActions.simplifyThreshold\" [min]=\"1\" [max]=\"20\" [step]=\"1\"></p-slider>\n <small>Vertices within this distance of the line between their neighbours are removed.</small>\n </div>\n <ng-template pTemplate=\"footer\">\n <p-button label=\"Cancel\" [text]=\"true\" (onClick)=\"displaySimplifyDialog = false\"></p-button>\n <p-button\n label=\"Apply\"\n icon=\"pi pi-check\"\n (onClick)=\"simplifyRegions(regionActions.simplifyThreshold)\"\n ></p-button>\n </ng-template>\n</p-dialog>\n\n<!-- Parameters for whichever contributed tool is open. One dialog for all of\n them: a tool declares its fields (ToolParamSpec) and this renders them, so\n the toolbar can lay every tool out the same way and a plugin needs no\n PrimeNG of its own. Defaults come from the active checkpoint, since they\n encode what it was trained for. -->\n<p-dialog\n *ngIf=\"toolParams.openParams as open\"\n [header]=\"open.tool.label + ' parameters'\"\n [visible]=\"true\"\n (visibleChange)=\"closeToolParams()\"\n [modal]=\"true\"\n [style]=\"{ width: '30rem' }\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n appendTo=\"body\"\n>\n <div class=\"grid formgrid p-fluid\">\n <ng-container *ngFor=\"let f of open.fields\">\n <div class=\"field\" [ngClass]=\"f.spec.type === 'boolean' ? 'col-12' : 'col-6'\">\n <ng-container *ngIf=\"f.number as n\">\n <label class=\"text-sm\" [pTooltip]=\"n.tooltip || ''\">{{ n.label }}</label>\n <p-inputNumber\n [ngModel]=\"open.values[n.id]\"\n (ngModelChange)=\"open.values[n.id] = $event\"\n [min]=\"n.min\"\n [max]=\"n.max\"\n [step]=\"n.step\"\n [minFractionDigits]=\"n.fractionDigits\"\n [showButtons]=\"true\"\n ></p-inputNumber>\n </ng-container>\n\n <ng-container *ngIf=\"f.select as sel\">\n <label class=\"text-sm\" [pTooltip]=\"sel.tooltip || ''\">{{ sel.label }}</label>\n <p-dropdown\n [options]=\"sel.options\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [ngModel]=\"open.values[sel.id]\"\n (ngModelChange)=\"open.values[sel.id] = $event\"\n appendTo=\"body\"\n ></p-dropdown>\n </ng-container>\n\n <!-- Checkbox label sits beside the box and may run to a sentence, so\n it does not get the stacked label the other types use. -->\n <div *ngIf=\"f.spec.type === 'boolean'\" class=\"flex align-items-center gap-2\">\n <p-checkbox\n [ngModel]=\"open.values[f.spec.id]\"\n (ngModelChange)=\"open.values[f.spec.id] = $event\"\n [binary]=\"true\"\n [inputId]=\"open.tool.id + '-' + f.spec.id\"\n ></p-checkbox>\n <label [for]=\"open.tool.id + '-' + f.spec.id\" class=\"text-sm mb-0\" [pTooltip]=\"f.spec.tooltip || ''\">{{\n f.spec.label\n }}</label>\n </div>\n </div>\n </ng-container>\n </div>\n <ng-template pTemplate=\"footer\">\n <p-button\n label=\"Reset to model defaults\"\n [text]=\"true\"\n size=\"small\"\n (onClick)=\"resetToolParams(open.tool.id)\"\n ></p-button>\n <p-button label=\"Close\" size=\"small\" (onClick)=\"closeToolParams()\"></p-button>\n </ng-template>\n</p-dialog>\n", styles: [":host{display:flex;flex-direction:column;height:100%;overflow:hidden}.viz-plot{flex:1;min-height:0;height:auto!important}.toolbar-dock{display:flex;align-items:stretch;width:100%}.toolbar-dock plotting-toolbar{flex:1;min-width:0}.toolbar-dock.floating{position:fixed;z-index:1000;width:auto;max-width:calc(100% - 16px);background:var(--surface-card, #ffffff);border:1px solid var(--surface-border, #cccccc);border-radius:6px;box-shadow:0 4px 16px #0000004d}.toolbar-dock.floating plotting-toolbar{flex:0 1 auto}.toolbar-dock.floating .toolbar-drag-handle{border-radius:6px 0 0 6px}.toolbar-drag-handle{display:flex;align-items:center;justify-content:center;padding:0 .4rem;cursor:move;color:var(--primary-color);background:var(--surface-100, rgba(0, 0, 0, .04));border-right:1px solid var(--surface-border, #cccccc);-webkit-user-select:none;user-select:none}.toolbar-dock-btn{align-self:center}:host ::ng-deep .navigator{margin-bottom:80px!important;margin-right:12px!important}kbd{background:#e8e8e8;border:1px solid #bbb;border-radius:3px;padding:1px 5px;font-family:monospace;font-size:.85em}.toolbar-separator{border-left:1px solid var(--surface-border);height:1.5rem;margin:0 .25rem;align-self:center}.progress{position:absolute;width:50%;left:25%;top:55%}.text-loading{position:absolute;margin:0 auto;left:45%;top:60%;font-weight:700}.zoom-text-loading{position:absolute;margin:0 auto;left:35%;top:60%;font-weight:700;display:inline-block;width:350px}.cancel-loading{position:absolute;margin:0 auto;left:46%;top:70%}.spinner{position:absolute;left:45%;top:45%;height:100px;width:100px;margin:0 auto;-webkit-animation:rotation .6s infinite linear;-moz-animation:rotation .6s infinite linear;-o-animation:rotation .6s infinite linear;animation:rotation .6s infinite linear;border-left:6px solid rgba(0,174,239,.15);border-right:6px solid rgba(0,174,239,.15);border-bottom:6px solid rgba(0,174,239,.15);border-top:6px solid rgb(82,107,178);border-radius:100%}.loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#ffffff80;z-index:1000}.sharpening-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#ffffff2e;pointer-events:none;z-index:1000}.sharpening-overlay .spinner{height:60px;width:60px;border-width:4px;left:calc(50% - 30px);top:calc(50% - 60px)}.sharpening-overlay .text-loading{position:absolute;left:0;right:0;width:auto;text-align:center;top:calc(50% + 35px);font-size:.9rem;color:#526bb2}@-webkit-keyframes rotation{0%{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(359deg)}}@-moz-keyframes rotation{0%{-moz-transform:rotate(0deg)}to{-moz-transform:rotate(359deg)}}@-o-keyframes rotation{0%{-o-transform:rotate(0deg)}to{-o-transform:rotate(359deg)}}@keyframes rotation{0%{transform:rotate(0)}to{transform:rotate(359deg)}}::ng-deep .context-menu-active>.p-menuitem-content{background-color:var(--primary-color)!important}::ng-deep .context-menu-active>.p-menuitem-content .p-menuitem-icon,::ng-deep .context-menu-active>.p-menuitem-content .p-menuitem-text{color:#fff!important}::ng-deep .context-menu-active>.p-menuitem-content .zoom-box-off-icon,::ng-deep .context-menu-active>.p-menuitem-content .wand-icon,::ng-deep .context-menu-active>.p-menuitem-content .polyline-icon,::ng-deep .context-menu-active>.p-menuitem-content .polygon-vertices-icon,::ng-deep .context-menu-active>.p-menuitem-content .vertex-add-icon,::ng-deep .context-menu-active>.p-menuitem-content .vertex-delete-icon,::ng-deep .context-menu-active>.p-menuitem-content .region-move-icon,::ng-deep .context-menu-active>.p-menuitem-content .to-bezier-icon,::ng-deep .context-menu-active>.p-menuitem-content .to-polygon-icon{filter:brightness(0) invert(1)}::ng-deep .zoom-box-off-icon{background:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 100\" fill=\"black\" fill-rule=\"evenodd\">%0A <!-- Rectangle outline -->%0A <rect x=\"2\" y=\"2\" width=\"56\" height=\"56\"/>%0A <rect x=\"9\" y=\"9\" width=\"42\" height=\"42\"/>%0A <!-- Magnifying glass ring -->%0A <circle cx=\"70\" cy=\"70\" r=\"23\"/>%0A <circle cx=\"70\" cy=\"70\" r=\"14\"/>%0A <!-- Handle -->%0A <polygon points=\"81,81 97,97 92,100 77,85\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .wand-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<svg%0A viewBox=\"0 0 100 100\"%0A fill=\"black\"%0A fill-rule=\"evenodd\"%0A version=\"1.1\"%0A id=\"svg4\"%0A sodipodi:docname=\"wand.svg\"%0A inkscape:version=\"1.4.3 (0d15f75, 2025-12-25)\"%0A xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"%0A xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"%0A xmlns=\"http://www.w3.org/2000/svg\"%0A xmlns:svg=\"http://www.w3.org/2000/svg\">%0A <defs%0A id=\"defs4\" />%0A <sodipodi:namedview%0A id=\"namedview4\"%0A pagecolor=\"%23ffffff\"%0A bordercolor=\"%23000000\"%0A borderopacity=\"0.25\"%0A inkscape:showpageshadow=\"2\"%0A inkscape:pageopacity=\"0.0\"%0A inkscape:pagecheckerboard=\"0\"%0A inkscape:deskcolor=\"%23d1d1d1\"%0A inkscape:zoom=\"8.74\"%0A inkscape:cx=\"50\"%0A inkscape:cy=\"49.942792\"%0A inkscape:window-width=\"1024\"%0A inkscape:window-height=\"1186\"%0A inkscape:window-x=\"3560\"%0A inkscape:window-y=\"131\"%0A inkscape:window-maximized=\"0\"%0A inkscape:current-layer=\"svg4\" />%0A <!-- Wand handle: thin diagonal stick from lower-left to upper-right -->%0A <polygon%0A points=\"12,92 78,26 74,22 8,88 \"%0A id=\"polygon1\"%0A transform=\"matrix(1.0375192,0.05799445,0.25179496,0.91871864,-17.85351,5.6289793)\" />%0A <!-- 4-pointed star at the wand tip -->%0A <polygon%0A points=\"62,34 76,30 80,6 84,30 98,34 84,38 80,62 76,38 \"%0A id=\"polygon2\"%0A transform=\"matrix(1.3082889,0,0,1.0245178,-38.907958,-1.4056881)\" />%0A <!-- Small sparkle to the upper-left -->%0A <polygon%0A points=\"46,30 36,32 34,42 32,32 22,30 32,28 34,18 36,28 \"%0A id=\"polygon3\"%0A transform=\"translate(-9.610984,-6.7505721)\" />%0A <!-- Small sparkle to the lower-right -->%0A <polygon%0A points=\"62,80 70,82 62,84 60,92 58,84 50,82 58,80 60,72 \"%0A id=\"polygon4\"%0A transform=\"translate(0,-1.6018307)\" />%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .brush-icon{background:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 640\"><!--!Font Awesome Free 7.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d=\"M512.5 74.3L291.1 222C262 241.4 243.5 272.9 240.5 307.3C302.8 320.1 351.9 369.2 364.8 431.6C399.3 428.6 430.7 410.1 450.1 381L597.7 159.5C604.4 149.4 608 137.6 608 125.4C608 91.5 580.5 64 546.6 64C534.5 64 522.6 67.6 512.5 74.3zM320 464C320 402.1 269.9 352 208 352C146.1 352 96 402.1 96 464C96 467.9 96.2 471.8 96.6 475.6C98.4 493.1 86.4 512 68.8 512L64 512C46.3 512 32 526.3 32 544C32 561.7 46.3 576 64 576L208 576C269.9 576 320 525.9 320 464z\"/></svg>') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .polyline-icon{background:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\">%0A <polyline points=\"1,14 5,3 10,11 15,2\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .polygon-vertices-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Polygon (click-to-place) tool icon: a traced polyline with vertex dots. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <g transform=\"matrix(1.4740709,0,0,1.4740709,-6.0268793,-6.8086826)\">%0A <polyline points=\"23.877,16.627 14.657,10.767 5.25,21.551 12.757,29.397\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"1.6\"%0A stroke-linejoin=\"round\" stroke-linecap=\"round\"/>%0A <circle cx=\"23.877\" cy=\"16.627\" r=\"1.9\"/>%0A <circle cx=\"14.657\" cy=\"10.767\" r=\"1.9\"/>%0A <circle cx=\"5.25\" cy=\"21.551\" r=\"1.9\"/>%0A <circle cx=\"12.757\" cy=\"29.397\" r=\"1.9\"/>%0A </g>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .vertex-add-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Add-vertex tool icon: a region blob with three corner vertices and a plus glyph. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <g transform=\"matrix(1.5222969,0,0,1.5222969,-8.2143505,-7.6146399)\">%0A <path d=\"m 9.35834,12.33267 c 1.78,-2.53 4.93,-3.56 7.86,-3.98 3.98,-0.72 8.33,0.08 11.52,2.67 2.62,1.98 4.71,5.1 4.53,8.49 -0.29,2.27 -2.5,3.81 -4.66,4.01 -2.75,0.43 -5.54,0.07 -8.28,-0.26 -3.99,-0.68 -8.05,-2.16 -10.93,-5.12 -1.32,-1.63 -1.39,-4.17 -0.04,-5.81 z\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"1.6\" stroke-miterlimit=\"10\"/>%0A <circle cx=\"8.294\" cy=\"15.248\" r=\"2.63\"/>%0A <circle cx=\"19.781\" cy=\"8.287\" r=\"2.63\"/>%0A <circle cx=\"25.044\" cy=\"23.748\" r=\"2.63\"/>%0A </g>%0A <path d=\"M 9.65,29.0 H 5.85 v 5.3 H 0.55 v 3.4 H 5.85 v 5.3 H 9.65 V 37.7 H 14.95 V 34.3 H 9.65 Z\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .vertex-delete-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Delete-vertex tool icon: a region blob with three corner vertices and a minus glyph. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <g transform=\"matrix(1.5222969,0,0,1.5222969,-8.2143505,-7.6146399)\">%0A <path d=\"m 9.35834,12.33267 c 1.78,-2.53 4.93,-3.56 7.86,-3.98 3.98,-0.72 8.33,0.08 11.52,2.67 2.62,1.98 4.71,5.1 4.53,8.49 -0.29,2.27 -2.5,3.81 -4.66,4.01 -2.75,0.43 -5.54,0.07 -8.28,-0.26 -3.99,-0.68 -8.05,-2.16 -10.93,-5.12 -1.32,-1.63 -1.39,-4.17 -0.04,-5.81 z\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"1.6\" stroke-miterlimit=\"10\"/>%0A <circle cx=\"8.294\" cy=\"15.248\" r=\"2.63\"/>%0A <circle cx=\"19.781\" cy=\"8.287\" r=\"2.63\"/>%0A <circle cx=\"25.044\" cy=\"23.748\" r=\"2.63\"/>%0A </g>%0A <path d=\"M 0.55,34.3 v 3.4 H 14.95 V 34.3 Z\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .region-move-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Region-move tool icon: a region blob with a drag arrow. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <path d=\"m 17.115582,8.9648664 c 1.707597,-3.3276806 4.729468,-4.6824281 7.540287,-5.2348498 3.827703,-0.947008 7.991169,0.1052238 11.051414,3.5118228 2.523022,2.604273 4.518416,6.7079726 4.345738,11.1668036 -0.278204,2.985704 -2.398311,5.011251 -4.470451,5.274308 -2.638142,0.565574 -5.314655,0.09206 -7.943203,-0.341976 C 23.811664,22.446579 19.916808,20.499952 17.153955,16.606696 15.89724,14.462775 15.820494,11.12194 17.115585,8.9648664 Z\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"2.1\" stroke-miterlimit=\"10\"/>%0A <path d=\"m 26.741429,13.966963 6.746922,16.786269 3.229398,-4.060758 3.583857,3.583857 2.761195,-2.761196 -3.583856,-3.571852 4.060758,-3.2354 z\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .to-bezier-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Convert-to-bezier tool icon: a smooth curve through two anchor points with control handles. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <!-- smooth cubic curve between the two anchors -->%0A <path d=\"M 7,34 C 7,16 37,28 37,10\" fill=\"none\" stroke=\"%23000000\" stroke-width=\"2.4\"%0A stroke-linecap=\"round\"/>%0A <!-- control handles -->%0A <line x1=\"7\" y1=\"34\" x2=\"7\" y2=\"22\" stroke=\"%23000000\" stroke-width=\"1.4\"/>%0A <line x1=\"37\" y1=\"10\" x2=\"37\" y2=\"22\" stroke=\"%23000000\" stroke-width=\"1.4\"/>%0A <circle cx=\"7\" cy=\"22\" r=\"2.2\"/>%0A <circle cx=\"37\" cy=\"22\" r=\"2.2\"/>%0A <!-- anchor points -->%0A <rect x=\"4\" y=\"31\" width=\"6\" height=\"6\" rx=\"1\"/>%0A <rect x=\"34\" y=\"7\" width=\"6\" height=\"6\" rx=\"1\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .to-polygon-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Convert-to-polygon tool icon: endpoints joined by straight segments through a vertex. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <!-- straight-segment path through the vertices -->%0A <polyline points=\"7,34 22,12 37,10\" fill=\"none\" stroke=\"%23000000\" stroke-width=\"2.4\"%0A stroke-linecap=\"round\" stroke-linejoin=\"round\"/>%0A <!-- vertices -->%0A <rect x=\"4\" y=\"31\" width=\"6\" height=\"6\" rx=\"1\"/>%0A <rect x=\"19\" y=\"9\" width=\"6\" height=\"6\" rx=\"1\"/>%0A <rect x=\"34\" y=\"7\" width=\"6\" height=\"6\" rx=\"1\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}:host ::ng-deep .sam-progress .p-progressbar-value{transition:none}\n"] }]
|
|
1243
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, template: "<!-- SAM toast: live status + encoder-download progress bar (jit-ui#90). Sticky\n while a segment runs; stays open until the bar reaches 100% and the run ends. -->\n<p-toast [key]=\"samToastKey\" position=\"bottom-right\">\n <ng-template let-message pTemplate=\"message\">\n <div style=\"flex: 1; min-width: 16rem\">\n <div class=\"font-bold mb-1\">{{ message.summary }}</div>\n <div>{{ segmentation.status || message.detail }}</div>\n <p-progressBar\n *ngIf=\"segmentation.downloading\"\n [value]=\"segmentation.progress\"\n styleClass=\"mt-2 sam-progress\"\n ></p-progressBar>\n <p-progressBar\n *ngIf=\"segmentation.busy && !segmentation.downloading\"\n mode=\"indeterminate\"\n styleClass=\"mt-2\"\n [style]=\"{ height: '4px' }\"\n ></p-progressBar>\n </div>\n </ng-template>\n</p-toast>\n\n<!-- Result/error notices from the library itself (segmentation outcome, region\n validation). Rendered here so they do not depend on the host mounting a\n keyless <p-toast> \u2014 without this the messages went nowhere in any host but\n jit-ui, and a failed run looked like a button that did nothing. -->\n<p-toast [key]=\"resultToastKey\" position=\"bottom-right\"></p-toast>\n\n<!-- Shared outlets for notices raised where there is no per-instance key to use:\n the root-provided PlotlyService and the region-editor dialog. Rendered by a\n single visualizer (ownsSharedToasts) so a message from the root service is\n not shown once per live viewer. -->\n<p-toast *ngIf=\"ownsSharedToasts\" [key]=\"vizToastKey\"></p-toast>\n<p-toast *ngIf=\"ownsSharedToasts\" [key]=\"vizAlertToastKey\" position=\"center\"></p-toast>\n\n<!-- Toolbar dock: docked across the top by default; drag the handle to detach\n it into a floating, movable window (frees the top row for the image). -->\n<div\n class=\"toolbar-dock\"\n [class.floating]=\"toolbarFloating\"\n [style.left.px]=\"toolbarFloating ? toolbarPos.x : null\"\n [style.top.px]=\"toolbarFloating ? toolbarPos.y : null\"\n>\n <div\n class=\"toolbar-drag-handle\"\n [vizFloatingDrag]=\"toolbarDragOrigin\"\n (vizFloatingDragMove)=\"toolbarPos = $event\"\n pTooltip=\"Drag to float the toolbar\"\n tooltipPosition=\"bottom\"\n >\n <i class=\"pi pi-bars\"></i>\n </div>\n <plotting-toolbar\n [imageInfo]=\"imageInfo\"\n [hasSpatialDataset]=\"hasSpatialDataset\"\n [plotTypeOptions]=\"plotTypeMenu\"\n [selectedPlotType]=\"selectedPlotTypeId\"\n [basePlotType]=\"basePlotType\"\n [isoRange]=\"isoRange\"\n [maxIndex]=\"maxIndex\"\n [zIndex]=\"zIndex\"\n [isHeatmap]=\"isHeatmap\"\n [is3dRegions]=\"isSpatial3dMode\"\n [isVolumeView]=\"isVolumeView\"\n [sliceEditor]=\"sliceEditor\"\n [activeDragMode]=\"activeDragMode\"\n [activeSurface3dMode]=\"activeSurface3dMode\"\n [axesVisible]=\"axesVisible\"\n [wireframeActive]=\"wireframeActive\"\n [resolutionScale]=\"resolutionScale\"\n [wandSensitivity]=\"wandSensitivity\"\n [brushSize]=\"brushSize\"\n [samModels]=\"samModels\"\n [samModelId]=\"samModelId\"\n [contributedTools]=\"contributedTools\"\n [dialogTools]=\"dialogTools\"\n [openDialogToolId]=\"openDialogToolId\"\n (toggleDialogTool)=\"toggleDialogTool($event)\"\n [toolModelIds]=\"toolParams.toolModelIds\"\n [vertexEraserRadius]=\"vertexEraserRadius\"\n [canUndo]=\"regionActions.canUndo\"\n [canRedo]=\"regionActions.canRedo\"\n [tools]=\"toolbarTools\"\n [imageSmoothingEnabled]=\"imageSmoothingEnabled\"\n (selectPlotType)=\"onSelectPlotType($event)\"\n (toggleImageSmoothing)=\"onToggleImageSmoothing()\"\n (addProfileLine)=\"addProfileLine()\"\n (isoRangeChange)=\"onIsoRangeChange($event)\"\n (openChannelHistogram)=\"openChannelHistogram()\"\n (openSpatialControls)=\"openSpatialControls()\"\n (openRegionEditor)=\"openRegionEditor()\"\n (toggleSliceEditor)=\"toggleSliceEditor()\"\n (selectStackOption)=\"selectStackOption($event)\"\n (zScrub)=\"onZScrub($event)\"\n (zSlide)=\"onZSlide($event)\"\n (zIndexInput)=\"zIndex = $event; updateZIndex()\"\n (reloadAndPlot)=\"reloadAndPlot()\"\n (downloadImage)=\"downloadImage()\"\n (autoscaleImage)=\"autoscaleImage()\"\n (toggleDragMode)=\"toggleDragMode($event)\"\n (zoomIn)=\"zoomIn()\"\n (zoomOut)=\"zoomOut()\"\n (toggleSurface3dMode)=\"toggleSurface3dMode($event)\"\n (resetSurfaceCamera)=\"resetSurfaceCamera()\"\n (toggleAxes)=\"toggleAxes()\"\n (toggleWireframe)=\"toggleWireframe()\"\n (selectResolution)=\"selectResolution($event)\"\n (deleteRegion)=\"deleteRegion()\"\n (undoRegion)=\"undoRegion()\"\n (redoRegion)=\"redoRegion()\"\n (segmentRegions)=\"segmentRegions()\"\n (segmentCellpose)=\"segmentCellpose()\"\n (samModelChange)=\"onSamModelChange($event)\"\n (runTool)=\"runTool($event)\"\n (toolModelChange)=\"onToolModelChange($event)\"\n (openToolParams)=\"openToolParams($event)\"\n (wandSensitivityChange)=\"onWandSensitivityChange($event)\"\n (brushSizeChange)=\"onBrushSizeChange($event)\"\n (vertexEraserRadiusChange)=\"onVertexEraserRadiusChange($event)\"\n >\n <!-- Host-projected custom toolbar buttons, forwarded into the toolbar. -->\n <ng-content></ng-content>\n </plotting-toolbar>\n <p-button\n *ngIf=\"toolbarFloating\"\n class=\"toolbar-dock-btn\"\n icon=\"pi pi-thumbtack\"\n size=\"small\"\n [text]=\"true\"\n pTooltip=\"Dock to top\"\n tooltipPosition=\"bottom\"\n (onClick)=\"dockToolbar()\"\n >\n </p-button>\n</div>\n\n<p-contextMenu #cm [model]=\"contextMenuItems\" appendTo=\"body\"></p-contextMenu>\n<!-- No `h-full` here: PrimeFlex's height:100% !important made #plot as tall as\n the whole host, so under the docked toolbar its bottom toolbar-height strip\n (incl. the OSD scale bar at bottom-left) was clipped by the host's\n overflow:hidden. The component stylesheet sizes it (.viz-plot { flex: 1 }). -->\n<!-- The plot, and while a volume view is split, the slice editor's pane on its left (its own\n viewer, with every region tool) with a divider to resize the two. The plot div keeps its\n place in the DOM either way: the backends find it by id, and a viewer mounted in it stays. -->\n<div\n class=\"viz-panes\"\n [class.viz-quad]=\"sliceEditorShown\"\n [style.grid-template-columns]=\"sliceEditorShown ? splitX + '% 6px minmax(0, 1fr)' : null\"\n [style.grid-template-rows]=\"sliceEditorShown ? splitY + '% 6px minmax(0, 1fr)' : null\"\n>\n <!-- The slice editor: the volume (the plot) top left, the slice being edited (Z) top right,\n the sections through x and y below, in their axis colours. -->\n <ng-container *ngIf=\"sliceEditorShown\">\n <div class=\"viz-cell viz-cell-z\">\n <div class=\"viz-slice-pane\" [id]=\"sliceDivName\"></div>\n <span class=\"viz-pane-badge viz-pane-badge-z\">Z \u00B7 slice {{ zIndex }}</span>\n </div>\n <div class=\"viz-cell viz-cell-x\">\n <viz-section-pane axis=\"x\" [view]=\"sections.x\" (pick)=\"onSectionPick('x', $event)\"></viz-section-pane>\n </div>\n <div class=\"viz-cell viz-cell-y\">\n <viz-section-pane axis=\"y\" [view]=\"sections.y\" (pick)=\"onSectionPick('y', $event)\"></viz-section-pane>\n </div>\n <div\n class=\"viz-pane-divider viz-pane-divider-v\"\n role=\"separator\"\n aria-orientation=\"vertical\"\n aria-label=\"Resize the panes across\"\n [attr.aria-valuenow]=\"splitX\"\n aria-valuemin=\"20\"\n aria-valuemax=\"80\"\n tabindex=\"0\"\n (pointerdown)=\"startPaneResize($event, 'x')\"\n (keydown)=\"nudgePaneSize($event, 'x')\"\n ></div>\n <div\n class=\"viz-pane-divider viz-pane-divider-h\"\n role=\"separator\"\n aria-orientation=\"horizontal\"\n aria-label=\"Resize the panes down\"\n [attr.aria-valuenow]=\"splitY\"\n aria-valuemin=\"20\"\n aria-valuemax=\"80\"\n tabindex=\"0\"\n (pointerdown)=\"startPaneResize($event, 'y')\"\n (keydown)=\"nudgePaneSize($event, 'y')\"\n ></div>\n </ng-container>\n <div class=\"w-full relative viz-plot\" [id]=\"plotDivName\">\n <div *ngIf=\"imgLoading() || stackLoading() || isCaching()\" class=\"loading-overlay\">\n <!-- Determinate stack/volume progress takes precedence: while it's active show ONLY the\n progress bar + \"Loading frames...\", not the generic spinner/\"Loading image...\" on top of\n it (both were rendering at once for napari volume/isosurface loads). -->\n <ng-container *ngIf=\"stackLoading(); else imgLoadingTpl\">\n <p-progressBar class=\"progress\" [value]=\"loadingPercentage()\"></p-progressBar>\n <span class=\"text-loading\">Loading frames...</span>\n </ng-container>\n <ng-template #imgLoadingTpl>\n <!-- Cache-copy progress is shown whenever a cache download is active (isCaching), independent\n of `imgLoading`, so it's never dropped/masked mid-download. -->\n <ng-container *ngIf=\"isCaching(); else spinnerLoading\">\n <!-- Stage-aware message comes from CacheProgressService updating\n imageLoadingMessage$ (\"Caching image...\" during the GCS download,\n then \"Generating preview...\" during per-slice thumbnail gen). Once the\n download hits 100% the remaining work (server preview/tile generation)\n has no determinate progress, so fall through to the spinner template\n rather than parking a full bar under \"Loading image...\". -->\n <p-progressBar class=\"progress\" [value]=\"cacheProgress()\"></p-progressBar>\n <span class=\"text-loading\">{{ loadingMessage() }}</span>\n </ng-container>\n <ng-template #spinnerLoading>\n <div *ngIf=\"imgLoading()\" class=\"spinner\"></div>\n <span *ngIf=\"imgLoading() && !zoom()\" class=\"text-loading\">{{ loadingMessage() }}</span>\n <span *ngIf=\"imgLoading() && zoom()\" class=\"zoom-text-loading\">{{ loadingMessage() }}</span>\n </ng-template>\n </ng-template>\n <p-button\n *ngIf=\"stackLoading() || imgLoading()\"\n class=\"cancel-loading\"\n label=\"Cancel\"\n (onClick)=\"cancelLoading()\"\n >\n </p-button>\n </div>\n <!-- Translucent \"sharpening\" overlay shown after the small-tier preview is\n on screen while the large-tier render is still loading in the\n background. Lets the user see the blurry image underneath but makes\n it clear something is still loading so they don't mistake the\n low-res render for the final image. -->\n <div *ngIf=\"render.sharpening && !imgLoading() && !stackLoading() && !isCaching()\" class=\"sharpening-overlay\">\n <div class=\"spinner\"></div>\n <span class=\"text-loading\">Sharpening preview...</span>\n </div>\n </div>\n</div>\n\n<!-- Floating, draggable intensity-profile inset, shown while any intensity line\n exists. Kept OUTSIDE the plot div and fixed to the viewport, so it floats over\n the whole page rather than being clipped to the canvas. -->\n<viz-intensity-inset\n [divId]=\"intensityInsetDiv\"\n [plotDivName]=\"plotDivName\"\n [zIndex]=\"zIndex\"\n [imageView]=\"isImageView\"\n [imageInfo]=\"imageInfo\"\n></viz-intensity-inset>\n\n<!-- Channels & Histogram: non-modal floating dialog opened from the toolbar. -->\n<channel-histogram [(visible)]=\"showChannelHistogram\"></channel-histogram>\n\n<!-- Spatial-omics controls. Renders its own empty state when no dataset (or no\n SPATIAL_DATA_PORT) is present, so it is always safe to host. -->\n<spatial-controls [(visible)]=\"showSpatialControls\" [is3d]=\"isSpatial3dMode\"></spatial-controls>\n\n<!-- Side panel of the active contributed plot mode (PLOT_TYPE_CONTRIBUTIONS),\n in the same right-hand area as the spatial controls and the Region Editor.\n Exists only while the mode's session is live; there is no close button,\n because leaving the mode is what ends it. A component panel gets\n PLOT_MODE_CONTEXT / PLOT_MODE_SESSION from its injector; a `mount` panel's\n host element is attached to the slot below (see plotModePanelSlot). -->\n<p-dialog\n *ngIf=\"plotModePanel as panel\"\n [header]=\"panel.title\"\n [visible]=\"true\"\n [modal]=\"false\"\n [closable]=\"false\"\n [resizable]=\"true\"\n [draggable]=\"true\"\n appendTo=\"body\"\n position=\"right\"\n styleClass=\"plot-mode-panel\"\n [style]=\"{ width: '22rem', maxHeight: '85vh' }\"\n [contentStyle]=\"{ overflow: 'auto' }\"\n>\n <ng-container *ngIf=\"panel.component\">\n <ng-container *ngComponentOutlet=\"panel.component; injector: panel.injector ?? undefined\"></ng-container>\n </ng-container>\n <div *ngIf=\"panel.host\" #plotModePanelSlot class=\"plot-mode-panel-slot\"></div>\n</p-dialog>\n\n<!-- An open dialog tool (TOOLBAR_TOOLS, kind: 'dialog'). Non-modal so the user can\n keep working on the image, e.g. painting with the brush the tool armed. The\n tool renders its body into a host element attached to the slot below (see\n toolDialogSlot); closing the dialog ends the tool's session. -->\n<p-dialog\n *ngIf=\"toolDialog as dlg\"\n [header]=\"dlg.title\"\n [visible]=\"true\"\n (visibleChange)=\"$event || closeDialogTool()\"\n [modal]=\"false\"\n [closable]=\"true\"\n [resizable]=\"true\"\n [draggable]=\"true\"\n appendTo=\"body\"\n position=\"right\"\n styleClass=\"tool-dialog\"\n [style]=\"{ width: dlg.width, maxHeight: '85vh' }\"\n [contentStyle]=\"{ overflow: 'auto' }\"\n>\n <div #toolDialogSlot class=\"tool-dialog-slot\"></div>\n</p-dialog>\n\n<!-- Region Editor: non-modal, draggable, resizable floating dialog opened from\n the toolbar (formerly the right-panel Regions tab). Modeless so regions can\n still be drawn/selected on the plot while it's open; stays linked to this\n plotting instance via the root RegionStore singleton. Opens over the right\n side of the view. -->\n<p-dialog\n header=\"Region Editor\"\n [(visible)]=\"showRegionEditor\"\n [modal]=\"false\"\n [resizable]=\"true\"\n [draggable]=\"true\"\n [maximizable]=\"true\"\n appendTo=\"body\"\n position=\"right\"\n [style]=\"{ width: regionEditorWidth, height: '85vh' }\"\n [contentStyle]=\"{ overflow: 'auto' }\"\n>\n <region-editor [active]=\"showRegionEditor\"></region-editor>\n</p-dialog>\n\n<!-- Simplify (Douglas\u2013Peucker): custom px-threshold picker for the selected\n region(s), opened from the right-click \"Simplify \u25B8 Custom\u2026\" action. -->\n<p-dialog\n header=\"Simplify region(s)\"\n [(visible)]=\"displaySimplifyDialog\"\n [modal]=\"true\"\n [style]=\"{ width: '22rem' }\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n>\n <div class=\"flex flex-column gap-2\">\n <span\n >Altitude threshold: <b>{{ regionActions.simplifyThreshold }} px</b></span\n >\n <p-slider [(ngModel)]=\"regionActions.simplifyThreshold\" [min]=\"1\" [max]=\"20\" [step]=\"1\"></p-slider>\n <small>Vertices within this distance of the line between their neighbours are removed.</small>\n </div>\n <ng-template pTemplate=\"footer\">\n <p-button label=\"Cancel\" [text]=\"true\" (onClick)=\"displaySimplifyDialog = false\"></p-button>\n <p-button\n label=\"Apply\"\n icon=\"pi pi-check\"\n (onClick)=\"simplifyRegions(regionActions.simplifyThreshold)\"\n ></p-button>\n </ng-template>\n</p-dialog>\n\n<!-- Parameters for whichever contributed tool is open. One dialog for all of\n them: a tool declares its fields (ToolParamSpec) and this renders them, so\n the toolbar can lay every tool out the same way and a plugin needs no\n PrimeNG of its own. Defaults come from the active checkpoint, since they\n encode what it was trained for. -->\n<p-dialog\n *ngIf=\"toolParams.openParams as open\"\n [header]=\"open.tool.label + ' parameters'\"\n [visible]=\"true\"\n (visibleChange)=\"closeToolParams()\"\n [modal]=\"true\"\n [style]=\"{ width: '30rem' }\"\n [draggable]=\"false\"\n [resizable]=\"false\"\n appendTo=\"body\"\n>\n <div class=\"grid formgrid p-fluid\">\n <ng-container *ngFor=\"let f of open.fields\">\n <div class=\"field\" [ngClass]=\"f.spec.type === 'boolean' ? 'col-12' : 'col-6'\">\n <ng-container *ngIf=\"f.number as n\">\n <label class=\"text-sm\" [pTooltip]=\"n.tooltip || ''\">{{ n.label }}</label>\n <p-inputNumber\n [ngModel]=\"open.values[n.id]\"\n (ngModelChange)=\"open.values[n.id] = $event\"\n [min]=\"n.min\"\n [max]=\"n.max\"\n [step]=\"n.step\"\n [minFractionDigits]=\"n.fractionDigits\"\n [showButtons]=\"true\"\n ></p-inputNumber>\n </ng-container>\n\n <ng-container *ngIf=\"f.select as sel\">\n <label class=\"text-sm\" [pTooltip]=\"sel.tooltip || ''\">{{ sel.label }}</label>\n <p-dropdown\n [options]=\"sel.options\"\n optionLabel=\"label\"\n optionValue=\"value\"\n [ngModel]=\"open.values[sel.id]\"\n (ngModelChange)=\"open.values[sel.id] = $event\"\n appendTo=\"body\"\n ></p-dropdown>\n </ng-container>\n\n <!-- Checkbox label sits beside the box and may run to a sentence, so\n it does not get the stacked label the other types use. -->\n <div *ngIf=\"f.spec.type === 'boolean'\" class=\"flex align-items-center gap-2\">\n <p-checkbox\n [ngModel]=\"open.values[f.spec.id]\"\n (ngModelChange)=\"open.values[f.spec.id] = $event\"\n [binary]=\"true\"\n [inputId]=\"open.tool.id + '-' + f.spec.id\"\n ></p-checkbox>\n <label [for]=\"open.tool.id + '-' + f.spec.id\" class=\"text-sm mb-0\" [pTooltip]=\"f.spec.tooltip || ''\">{{\n f.spec.label\n }}</label>\n </div>\n </div>\n </ng-container>\n </div>\n <ng-template pTemplate=\"footer\">\n <p-button\n label=\"Reset to model defaults\"\n [text]=\"true\"\n size=\"small\"\n (onClick)=\"resetToolParams(open.tool.id)\"\n ></p-button>\n <p-button label=\"Close\" size=\"small\" (onClick)=\"closeToolParams()\"></p-button>\n </ng-template>\n</p-dialog>\n", styles: [":host{display:flex;flex-direction:column;height:100%;overflow:hidden}.viz-panes{flex:1;min-height:0;display:flex}.viz-plot{flex:1 1 0;min-width:0;min-height:0;height:auto!important}.viz-panes.viz-quad{display:grid}.viz-panes.viz-quad>.viz-plot{grid-area:1/1/2/2;min-height:0;overflow:hidden}.viz-cell{position:relative;min-width:0;min-height:0;overflow:hidden}.viz-cell-z{grid-area:1/3/2/4}.viz-cell-x{grid-area:3/1/4/2}.viz-cell-y{grid-area:3/3/4/4}.viz-slice-pane{position:absolute;inset:0}.viz-pane-badge{position:absolute;top:6px;left:6px;z-index:10;padding:1px 8px;border-radius:4px;color:#fff;font:600 12px/1.6 system-ui,sans-serif;pointer-events:none}.viz-pane-badge-z{background:#668cff}.viz-pane-divider{background:var(--surface-border, #cccccc);touch-action:none}.viz-pane-divider:hover,.viz-pane-divider:focus-visible{background:var(--primary-color, #3b82f6);outline:none}.viz-pane-divider-v{grid-area:1/2/4/3;cursor:col-resize}.viz-pane-divider-h{grid-area:2/1/3/4;cursor:row-resize}.toolbar-dock{display:flex;align-items:stretch;width:100%}.toolbar-dock plotting-toolbar{flex:1;min-width:0}.toolbar-dock.floating{position:fixed;z-index:1000;width:auto;max-width:calc(100% - 16px);background:var(--surface-card, #ffffff);border:1px solid var(--surface-border, #cccccc);border-radius:6px;box-shadow:0 4px 16px #0000004d}.toolbar-dock.floating plotting-toolbar{flex:0 1 auto}.toolbar-dock.floating .toolbar-drag-handle{border-radius:6px 0 0 6px}.toolbar-drag-handle{display:flex;align-items:center;justify-content:center;padding:0 .4rem;cursor:move;color:var(--primary-color);background:var(--surface-100, rgba(0, 0, 0, .04));border-right:1px solid var(--surface-border, #cccccc);-webkit-user-select:none;user-select:none}.toolbar-dock-btn{align-self:center}:host ::ng-deep .navigator{margin-bottom:80px!important;margin-right:12px!important}kbd{background:#e8e8e8;border:1px solid #bbb;border-radius:3px;padding:1px 5px;font-family:monospace;font-size:.85em}.toolbar-separator{border-left:1px solid var(--surface-border);height:1.5rem;margin:0 .25rem;align-self:center}.progress{position:absolute;width:50%;left:25%;top:55%}.text-loading{position:absolute;margin:0 auto;left:45%;top:60%;font-weight:700}.zoom-text-loading{position:absolute;margin:0 auto;left:35%;top:60%;font-weight:700;display:inline-block;width:350px}.cancel-loading{position:absolute;margin:0 auto;left:46%;top:70%}.spinner{position:absolute;left:45%;top:45%;height:100px;width:100px;margin:0 auto;-webkit-animation:rotation .6s infinite linear;-moz-animation:rotation .6s infinite linear;-o-animation:rotation .6s infinite linear;animation:rotation .6s infinite linear;border-left:6px solid rgba(0,174,239,.15);border-right:6px solid rgba(0,174,239,.15);border-bottom:6px solid rgba(0,174,239,.15);border-top:6px solid rgb(82,107,178);border-radius:100%}.loading-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#ffffff80;z-index:1000}.sharpening-overlay{position:absolute;top:0;left:0;width:100%;height:100%;background-color:#ffffff2e;pointer-events:none;z-index:1000}.sharpening-overlay .spinner{height:60px;width:60px;border-width:4px;left:calc(50% - 30px);top:calc(50% - 60px)}.sharpening-overlay .text-loading{position:absolute;left:0;right:0;width:auto;text-align:center;top:calc(50% + 35px);font-size:.9rem;color:#526bb2}@-webkit-keyframes rotation{0%{-webkit-transform:rotate(0deg)}to{-webkit-transform:rotate(359deg)}}@-moz-keyframes rotation{0%{-moz-transform:rotate(0deg)}to{-moz-transform:rotate(359deg)}}@-o-keyframes rotation{0%{-o-transform:rotate(0deg)}to{-o-transform:rotate(359deg)}}@keyframes rotation{0%{transform:rotate(0)}to{transform:rotate(359deg)}}::ng-deep .context-menu-active>.p-menuitem-content{background-color:var(--primary-color)!important}::ng-deep .context-menu-active>.p-menuitem-content .p-menuitem-icon,::ng-deep .context-menu-active>.p-menuitem-content .p-menuitem-text{color:#fff!important}::ng-deep .context-menu-active>.p-menuitem-content .zoom-box-off-icon,::ng-deep .context-menu-active>.p-menuitem-content .wand-icon,::ng-deep .context-menu-active>.p-menuitem-content .polyline-icon,::ng-deep .context-menu-active>.p-menuitem-content .polygon-vertices-icon,::ng-deep .context-menu-active>.p-menuitem-content .vertex-add-icon,::ng-deep .context-menu-active>.p-menuitem-content .vertex-delete-icon,::ng-deep .context-menu-active>.p-menuitem-content .region-move-icon,::ng-deep .context-menu-active>.p-menuitem-content .to-bezier-icon,::ng-deep .context-menu-active>.p-menuitem-content .to-polygon-icon{filter:brightness(0) invert(1)}::ng-deep .zoom-box-off-icon{background:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 100 100\" fill=\"black\" fill-rule=\"evenodd\">%0A <!-- Rectangle outline -->%0A <rect x=\"2\" y=\"2\" width=\"56\" height=\"56\"/>%0A <rect x=\"9\" y=\"9\" width=\"42\" height=\"42\"/>%0A <!-- Magnifying glass ring -->%0A <circle cx=\"70\" cy=\"70\" r=\"23\"/>%0A <circle cx=\"70\" cy=\"70\" r=\"14\"/>%0A <!-- Handle -->%0A <polygon points=\"81,81 97,97 92,100 77,85\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .wand-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<svg%0A viewBox=\"0 0 100 100\"%0A fill=\"black\"%0A fill-rule=\"evenodd\"%0A version=\"1.1\"%0A id=\"svg4\"%0A sodipodi:docname=\"wand.svg\"%0A inkscape:version=\"1.4.3 (0d15f75, 2025-12-25)\"%0A xmlns:inkscape=\"http://www.inkscape.org/namespaces/inkscape\"%0A xmlns:sodipodi=\"http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd\"%0A xmlns=\"http://www.w3.org/2000/svg\"%0A xmlns:svg=\"http://www.w3.org/2000/svg\">%0A <defs%0A id=\"defs4\" />%0A <sodipodi:namedview%0A id=\"namedview4\"%0A pagecolor=\"%23ffffff\"%0A bordercolor=\"%23000000\"%0A borderopacity=\"0.25\"%0A inkscape:showpageshadow=\"2\"%0A inkscape:pageopacity=\"0.0\"%0A inkscape:pagecheckerboard=\"0\"%0A inkscape:deskcolor=\"%23d1d1d1\"%0A inkscape:zoom=\"8.74\"%0A inkscape:cx=\"50\"%0A inkscape:cy=\"49.942792\"%0A inkscape:window-width=\"1024\"%0A inkscape:window-height=\"1186\"%0A inkscape:window-x=\"3560\"%0A inkscape:window-y=\"131\"%0A inkscape:window-maximized=\"0\"%0A inkscape:current-layer=\"svg4\" />%0A <!-- Wand handle: thin diagonal stick from lower-left to upper-right -->%0A <polygon%0A points=\"12,92 78,26 74,22 8,88 \"%0A id=\"polygon1\"%0A transform=\"matrix(1.0375192,0.05799445,0.25179496,0.91871864,-17.85351,5.6289793)\" />%0A <!-- 4-pointed star at the wand tip -->%0A <polygon%0A points=\"62,34 76,30 80,6 84,30 98,34 84,38 80,62 76,38 \"%0A id=\"polygon2\"%0A transform=\"matrix(1.3082889,0,0,1.0245178,-38.907958,-1.4056881)\" />%0A <!-- Small sparkle to the upper-left -->%0A <polygon%0A points=\"46,30 36,32 34,42 32,32 22,30 32,28 34,18 36,28 \"%0A id=\"polygon3\"%0A transform=\"translate(-9.610984,-6.7505721)\" />%0A <!-- Small sparkle to the lower-right -->%0A <polygon%0A points=\"62,80 70,82 62,84 60,92 58,84 50,82 58,80 60,72 \"%0A id=\"polygon4\"%0A transform=\"translate(0,-1.6018307)\" />%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .brush-icon{background:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 640 640\"><!--!Font Awesome Free 7.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.--><path d=\"M512.5 74.3L291.1 222C262 241.4 243.5 272.9 240.5 307.3C302.8 320.1 351.9 369.2 364.8 431.6C399.3 428.6 430.7 410.1 450.1 381L597.7 159.5C604.4 149.4 608 137.6 608 125.4C608 91.5 580.5 64 546.6 64C534.5 64 522.6 67.6 512.5 74.3zM320 464C320 402.1 269.9 352 208 352C146.1 352 96 402.1 96 464C96 467.9 96.2 471.8 96.6 475.6C98.4 493.1 86.4 512 68.8 512L64 512C46.3 512 32 526.3 32 544C32 561.7 46.3 576 64 576L208 576C269.9 576 320 525.9 320 464z\"/></svg>') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .polyline-icon{background:url('data:image/svg+xml,<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 16 16\" width=\"16\" height=\"16\">%0A <polyline points=\"1,14 5,3 10,11 15,2\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .polygon-vertices-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Polygon (click-to-place) tool icon: a traced polyline with vertex dots. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <g transform=\"matrix(1.4740709,0,0,1.4740709,-6.0268793,-6.8086826)\">%0A <polyline points=\"23.877,16.627 14.657,10.767 5.25,21.551 12.757,29.397\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"1.6\"%0A stroke-linejoin=\"round\" stroke-linecap=\"round\"/>%0A <circle cx=\"23.877\" cy=\"16.627\" r=\"1.9\"/>%0A <circle cx=\"14.657\" cy=\"10.767\" r=\"1.9\"/>%0A <circle cx=\"5.25\" cy=\"21.551\" r=\"1.9\"/>%0A <circle cx=\"12.757\" cy=\"29.397\" r=\"1.9\"/>%0A </g>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .vertex-add-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Add-vertex tool icon: a region blob with three corner vertices and a plus glyph. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <g transform=\"matrix(1.5222969,0,0,1.5222969,-8.2143505,-7.6146399)\">%0A <path d=\"m 9.35834,12.33267 c 1.78,-2.53 4.93,-3.56 7.86,-3.98 3.98,-0.72 8.33,0.08 11.52,2.67 2.62,1.98 4.71,5.1 4.53,8.49 -0.29,2.27 -2.5,3.81 -4.66,4.01 -2.75,0.43 -5.54,0.07 -8.28,-0.26 -3.99,-0.68 -8.05,-2.16 -10.93,-5.12 -1.32,-1.63 -1.39,-4.17 -0.04,-5.81 z\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"1.6\" stroke-miterlimit=\"10\"/>%0A <circle cx=\"8.294\" cy=\"15.248\" r=\"2.63\"/>%0A <circle cx=\"19.781\" cy=\"8.287\" r=\"2.63\"/>%0A <circle cx=\"25.044\" cy=\"23.748\" r=\"2.63\"/>%0A </g>%0A <path d=\"M 9.65,29.0 H 5.85 v 5.3 H 0.55 v 3.4 H 5.85 v 5.3 H 9.65 V 37.7 H 14.95 V 34.3 H 9.65 Z\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .vertex-delete-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Delete-vertex tool icon: a region blob with three corner vertices and a minus glyph. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <g transform=\"matrix(1.5222969,0,0,1.5222969,-8.2143505,-7.6146399)\">%0A <path d=\"m 9.35834,12.33267 c 1.78,-2.53 4.93,-3.56 7.86,-3.98 3.98,-0.72 8.33,0.08 11.52,2.67 2.62,1.98 4.71,5.1 4.53,8.49 -0.29,2.27 -2.5,3.81 -4.66,4.01 -2.75,0.43 -5.54,0.07 -8.28,-0.26 -3.99,-0.68 -8.05,-2.16 -10.93,-5.12 -1.32,-1.63 -1.39,-4.17 -0.04,-5.81 z\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"1.6\" stroke-miterlimit=\"10\"/>%0A <circle cx=\"8.294\" cy=\"15.248\" r=\"2.63\"/>%0A <circle cx=\"19.781\" cy=\"8.287\" r=\"2.63\"/>%0A <circle cx=\"25.044\" cy=\"23.748\" r=\"2.63\"/>%0A </g>%0A <path d=\"M 0.55,34.3 v 3.4 H 14.95 V 34.3 Z\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .region-move-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Region-move tool icon: a region blob with a drag arrow. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <path d=\"m 17.115582,8.9648664 c 1.707597,-3.3276806 4.729468,-4.6824281 7.540287,-5.2348498 3.827703,-0.947008 7.991169,0.1052238 11.051414,3.5118228 2.523022,2.604273 4.518416,6.7079726 4.345738,11.1668036 -0.278204,2.985704 -2.398311,5.011251 -4.470451,5.274308 -2.638142,0.565574 -5.314655,0.09206 -7.943203,-0.341976 C 23.811664,22.446579 19.916808,20.499952 17.153955,16.606696 15.89724,14.462775 15.820494,11.12194 17.115585,8.9648664 Z\"%0A fill=\"none\" stroke=\"%23000000\" stroke-width=\"2.1\" stroke-miterlimit=\"10\"/>%0A <path d=\"m 26.741429,13.966963 6.746922,16.786269 3.229398,-4.060758 3.583857,3.583857 2.761195,-2.761196 -3.583856,-3.571852 4.060758,-3.2354 z\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .to-bezier-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Convert-to-bezier tool icon: a smooth curve through two anchor points with control handles. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <!-- smooth cubic curve between the two anchors -->%0A <path d=\"M 7,34 C 7,16 37,28 37,10\" fill=\"none\" stroke=\"%23000000\" stroke-width=\"2.4\"%0A stroke-linecap=\"round\"/>%0A <!-- control handles -->%0A <line x1=\"7\" y1=\"34\" x2=\"7\" y2=\"22\" stroke=\"%23000000\" stroke-width=\"1.4\"/>%0A <line x1=\"37\" y1=\"10\" x2=\"37\" y2=\"22\" stroke=\"%23000000\" stroke-width=\"1.4\"/>%0A <circle cx=\"7\" cy=\"22\" r=\"2.2\"/>%0A <circle cx=\"37\" cy=\"22\" r=\"2.2\"/>%0A <!-- anchor points -->%0A <rect x=\"4\" y=\"31\" width=\"6\" height=\"6\" rx=\"1\"/>%0A <rect x=\"34\" y=\"7\" width=\"6\" height=\"6\" rx=\"1\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}::ng-deep .to-polygon-icon{background:url('data:image/svg+xml,<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>%0A<!-- Convert-to-polygon tool icon: endpoints joined by straight segments through a vertex. -->%0A<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 44 44\" width=\"44\" height=\"44\" fill=\"%23000000\">%0A <!-- straight-segment path through the vertices -->%0A <polyline points=\"7,34 22,12 37,10\" fill=\"none\" stroke=\"%23000000\" stroke-width=\"2.4\"%0A stroke-linecap=\"round\" stroke-linejoin=\"round\"/>%0A <!-- vertices -->%0A <rect x=\"4\" y=\"31\" width=\"6\" height=\"6\" rx=\"1\"/>%0A <rect x=\"19\" y=\"9\" width=\"6\" height=\"6\" rx=\"1\"/>%0A <rect x=\"34\" y=\"7\" width=\"6\" height=\"6\" rx=\"1\"/>%0A</svg>%0A') no-repeat center center;background-size:contain;width:1.25rem;height:1.25rem;display:inline-block;filter:brightness(0) invert(47%) sepia(98%) saturate(567%) hue-rotate(181deg) brightness(103%) contrast(98%)}:host ::ng-deep .sam-progress .p-progressbar-value{transition:none}\n"] }]
|
|
1122
1244
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
1123
1245
|
type: Inject,
|
|
1124
1246
|
args: [IMAGE_STATE_PORT]
|
|
@@ -1170,4 +1292,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
|
|
|
1170
1292
|
type: ViewChild,
|
|
1171
1293
|
args: ['toolDialogSlot']
|
|
1172
1294
|
}] } });
|
|
1173
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlzdWFsaXplci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3Zpc3VhbGl6ZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vc3JjL2xpYi92aXN1YWxpemVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFFTCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsVUFBVSxFQUNWLFlBQVksRUFDWixNQUFNLEVBQ04sUUFBUSxFQUNSLEtBQUssRUFDTCxNQUFNLEVBSU4sUUFBUSxFQUNSLE1BQU0sRUFFTixTQUFTLEVBQ1QsUUFBUSxFQUNSLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRTdDLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFbEMsT0FBTyxFQUFZLGNBQWMsRUFBRSxZQUFZLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDckUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsV0FBVyxFQUFFLGlCQUFpQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDckUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxx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QixNQUFNOzJCQUFDLFVBQVU7OzBCQVNqQixRQUFROzswQkFBSSxNQUFNOzJCQUFDLFVBQVU7OzBCQUk3QixRQUFROzswQkFBSSxNQUFNOzJCQUFDLGFBQWE7OzBCQUdoQyxRQUFROzswQkFBSSxNQUFNOzJCQUFDLGlCQUFpQjs7MEJBR3BDLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsdUJBQXVCOzswQkFHMUMsUUFBUTs7MEJBRVIsUUFBUTtrRUFoVlgsWUFBWTtzQkFEWCxNQUFNO2dCQUlQLGdCQUFnQjtzQkFEZixNQUFNO2dCQU1ILFlBQVk7c0JBRGYsS0FBSztnQkFjTixRQUFRO3NCQURQLEtBQUs7Z0JBMENXLFdBQVc7c0JBQTNCLFNBQVM7dUJBQUMsSUFBSTtnQkFrTFgsaUJBQWlCO3NCQURwQixTQUFTO3VCQUFDLG1CQUFtQjtnQkE4QndCLEtBQUs7c0JBQTFELFNBQVM7dUJBQUMsdUJBQXVCLEVBQUUsRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFO2dCQW15QmhELGNBQWM7c0JBRGpCLFNBQVM7dUJBQUMsZ0JBQWdCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIERlc3Ryb3lSZWYsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5qZWN0LFxuICBJbmplY3RvcixcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgT3B0aW9uYWwsXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVmlld0NoaWxkLFxuICBjb21wdXRlZCxcbiAgc2lnbmFsLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcblxuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBNZW51SXRlbSwgTWVzc2FnZVNlcnZpY2UsIFNoYXJlZE1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvYXBpJztcbmltcG9ydCB7IEJ1dHRvbk1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvYnV0dG9uJztcbmltcG9ydCB7IENoZWNrYm94TW9kdWxlIH0gZnJvbSAncHJpbWVuZy9jaGVja2JveCc7XG5pbXBvcnQgeyBDb250ZXh0TWVudSwgQ29udGV4dE1lbnVNb2R1bGUgfSBmcm9tICdwcmltZW5nL2NvbnRleHRtZW51JztcbmltcG9ydCB7IERpYWxvZ01vZHVsZSB9IGZyb20gJ3ByaW1lbmcvZGlhbG9nJztcbmltcG9ydCB7IERyb3Bkb3duTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9kcm9wZG93bic7XG5pbXBvcnQgeyBJbnB1dE51bWJlck1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvaW5wdXRudW1iZXInO1xuaW1wb3J0IHsgUHJvZ3Jlc3NCYXJNb2R1bGUgfSBmcm9tICdwcmltZW5nL3Byb2dyZXNzYmFyJztcbmltcG9ydCB7IFNsaWRlck1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvc2xpZGVyJztcbmltcG9ydCB7IFRvYXN0TW9kdWxlIH0gZnJvbSAncHJpbWVuZy90b2FzdCc7XG5pbXBvcnQgeyBUb29sdGlwTW9kdWxlIH0gZnJvbSAncHJpbWVuZy90b29sdGlwJztcbmltcG9ydCB7IElJbWFnZUluZm8gfSBmcm9tICcuL2NvbnRyYWN0cy9pbWFnZS5jb250cmFjdCc7XG5pbXBvcnQgeyBJbWFnZVN0YXRlUG9ydCwgSU1BR0VfU1RBVEVfUE9SVCB9IGZyb20gJy4vY29udHJhY3RzL3BvcnRzL2ltYWdlLXN0YXRlLnBvcnQnO1xuaW1wb3J0IHsgUG9seWdvbiB9IGZyb20gJy4vbW9kZWxzL3JlZ2lvbic7XG5pbXBvcnQgeyBSZWdpb25PcHNTZXJ2aWNlIH0gZnJvbSAnLi9yZWdpb24tb3BzLnNlcnZpY2UnO1xuaW1wb3J0IHsgVklaX1RPQVNUX0tFWSwgVklaX0FMRVJUX1RPQVNUX0tFWSB9IGZyb20gJy4vdG9hc3Qtb3V0bGV0cyc7XG5pbXBvcnQgeyBWaXN1YWxpemVyU3RvcmUgfSBmcm9tICcuL3N0b3JlL3Zpc3VhbGl6ZXItc3RvcmUuc2VydmljZSc7XG5pbXBvcnQgeyBTbGljZVNjcnViYmVyIH0gZnJvbSAnLi9yZW5kZXItb3JjaGVzdHJhdG9yJztcbmltcG9ydCB7IEltYWdlUmVuZGVyU2Vzc2lvbiwgZXJyb3JNZXNzYWdlIH0gZnJvbSAnLi9yZW5kZXItc2Vzc2lvbic7XG5pbXBvcnQge1xuICBQbG90VHlwZSxcbiAgUGxvdFR5cGVEZXNjcmlwdG9yLFxuICBQbG90VHlwZUlkLFxuICBnZXRQbG90VHlwZURlc2NyaXB0b3IsXG4gIGlzQnVpbHRpblBsb3RUeXBlLFxuICBpc05hcGFyaTNkLFxuICBpc1NwYXRpYWxPbWljcyxcbiAgaXNTcGF0aWFsT21pY3MzZCxcbiAgcmVuZGVyZXJPd25zV2hlZWwsXG4gIE5BUEFSSV9ERUZBVUxUX0RFQ0lNQVRFLFxufSBmcm9tICcuL2NvbnRyYWN0cy9wbG90LXR5cGUnO1xuaW1wb3J0IHtcbiAgUExPVF9UWVBFX0NPTlRSSUJVVElPTlMsXG4gIFBsb3RUeXBlQ29udHJpYnV0aW9uLFxuICBQbG90VHlwZU9wdGlvbixcbn0gZnJvbSAnLi9jb250cmFjdHMvcGxvdC10eXBlLWNvbnRyaWJ1dGlvbi5jb250cmFjdCc7XG5pbXBvcnQgeyBQbG90TW9kZUNvbnRyb2xsZXIgfSBmcm9tICcuL3Bsb3QtbW9kZS9wbG90LW1vZGUtY29udHJvbGxlcic7XG5pbXBvcnQgeyBjb21wdXRlUGxvdFR5cGVNZW51LCByZWNvbmNpbGVQbG90VHlwZSB9IGZyb20gJy4vcGxvdC1tb2RlL3Bsb3QtdHlwZS1tZW51JztcbmltcG9ydCB7IFRvb2xQYXJhbXNNb2RlbCB9IGZyb20gJy4vcGxvdC1tb2RlL3Rvb2wtcGFyYW1zLW1vZGVsJztcbmltcG9ydCB7IENvbnRyaWJ1dGlvbkhvc3QsIFBsb3RNb2RlUGFuZWxWaWV3LCBUb29sRGlhbG9nVmlldyB9IGZyb20gJy4vcGxvdC1tb2RlL2NvbnRyaWJ1dGlvbi1ob3N0JztcbmltcG9ydCB7IElWaXN1YWxpemVyLCBWSVNVQUxJWkVSLCBWaXN1YWxpemVySGFuZGxlIH0gZnJvbSAnLi9jb250cmFjdHMvdmlzdWFsaXplci5jb250cmFjdCc7XG5pbXBvcnQgeyBTQU1fTU9ERUxTLCBnZXREZWZhdWx0U2FtTW9kZWxJZCwgaXNTYW1Nb2RlbFJlYWR5IH0gZnJvbSAnLi90b29sYmFyL3NlZ21lbnRhdGlvbi9zYW0tbW9kZWwtcmVnaXN0cnknO1xuaW1wb3J0IHsgU2FtVG9vbFNlcnZpY2UgfSBmcm9tICcuL3Rvb2xiYXIvc2VnbWVudGF0aW9uL3NhbS10b29sLnNlcnZpY2UnO1xuaW1wb3J0IHsgU2FtUG9pbnRUb29sU2VydmljZSB9IGZyb20gJy4vdG9vbGJhci9zZWdtZW50YXRpb24vc2FtLXBvaW50LXRvb2wuc2VydmljZSc7XG5pbXBvcnQgeyBDZWxsU2VnbWVudFRvb2xTZXJ2aWNlIH0gZnJvbSAnLi90b29sYmFyL3NlZ21lbnRhdGlvbi9jZWxsLXNlZ21lbnQtdG9vbC5zZXJ2aWNlJztcbmltcG9ydCB7IFNlZ21lbnRhdGlvblJ1bm5lciB9IGZyb20gJy4vdG9vbGJhci9zZWdtZW50YXRpb24vc2VnbWVudGF0aW9uLXJ1bm5lcic7XG5pbXBvcnQge1xuICBUT09MQkFSX1RPT0xTLFxuICBUb29sYmFyQ29udHJpYnV0aW9uLFxuICBUb29sYmFyRGlhbG9nVG9vbENvbnRyaWJ1dGlvbixcbiAgVG9vbGJhclRvb2xDb250cmlidXRpb24sXG4gIHZpc2libGVUb29sQ29udHJpYnV0aW9ucyxcbn0gZnJvbSAnLi9jb250cmFjdHMvdG9vbGJhci10b29sLmNvbnRyYWN0JztcbmltcG9ydCB7IFRvb2xiYXJUb29sVmlzaWJpbGl0eSwgQUxMX1RPT0xCQVJfVE9PTFMgfSBmcm9tICcuL2NvbnRyYWN0cy90b29sYmFyLWNvbmZpZyc7XG5pbXBvcnQgeyBWSVpfQ09ORklHLCBWaXpDb25maWcgfSBmcm9tICcuL2NvbnRyYWN0cy92aXotY29uZmlnJztcbmltcG9ydCB7IFNQQVRJQUxfREFUQV9QT1JULCBTcGF0aWFsRGF0YVBvcnQgfSBmcm9tICcuL2NvbnRyYWN0cy9wb3J0cy9zcGF0aWFsLWRhdGEucG9ydCc7XG5pbXBvcnQgeyBhcHBseUltYWdlUm9pcyB9IGZyb20gJy4vdmlzdWFsaXplci9yZWdpb24tbG9hZCc7XG5pbXBvcnQgeyBDb250ZXh0TWVudUFjdGlvbnMsIENvbnRleHRNZW51U3RhdGUsIGJ1aWxkQ29udGV4dE1lbnUgfSBmcm9tICcuL3Zpc3VhbGl6ZXIvdmlzdWFsaXplci1jb250ZXh0LW1lbnUnO1xuaW1wb3J0IHsgUmVnaW9uQWN0aW9ucyB9IGZyb20gJy4vdmlzdWFsaXplci9yZWdpb24tYWN0aW9ucyc7XG5pbXBvcnQgeyBUb29sTW9kZXMgfSBmcm9tICcuL3Zpc3VhbGl6ZXIvdG9vbC1tb2Rlcyc7XG5pbXBvcnQgeyBTaG9ydGN1dEhvc3QsIFZpZXdlclNob3J0Y3V0cyB9IGZyb20gJy4vdmlzdWFsaXplci92aWV3ZXItc2hvcnRjdXRzJztcbmltcG9ydCB7IEZsb2F0aW5nRHJhZ0RpcmVjdGl2ZSwgRmxvYXRpbmdQb3MgfSBmcm9tICcuL3Zpc3VhbGl6ZXIvZmxvYXRpbmctZHJhZy5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgSW50ZW5zaXR5SW5zZXRDb21wb25lbnQgfSBmcm9tICcuL2ludGVuc2l0eS1pbnNldC9pbnRlbnNpdHktaW5zZXQuY29tcG9uZW50JztcbmltcG9ydCB7IFNwYXRpYWxEYXRhc2V0QmluZGVyIH0gZnJvbSAnLi92aXN1YWxpemVyL3NwYXRpYWwtZGF0YXNldC1iaW5kZXInO1xuaW1wb3J0IHsgVG9vbGJhckNvbXBvbmVudCB9IGZyb20gJy4vdG9vbGJhci90b29sYmFyLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBSZWdpb25FZGl0b3JDb21wb25lbnQgfSBmcm9tICcuL3JlZ2lvbi1lZGl0b3IvcmVnaW9uLWVkaXRvci5jb21wb25lbnQnO1xuaW1wb3J0IHsgQ2hhbm5lbEhpc3RvZ3JhbUNvbXBvbmVudCB9IGZyb20gJy4vY2hhbm5lbC1oaXN0b2dyYW0vY2hhbm5lbC1oaXN0b2dyYW0uY29tcG9uZW50JztcbmltcG9ydCB7IFNwYXRpYWxDb250cm9sc0NvbXBvbmVudCB9IGZyb20gJy4vc3BhdGlhbC1jb250cm9scy9zcGF0aWFsLWNvbnRyb2xzLmNvbXBvbmVudCc7XG5cbi8qKiBQZXItaW5zdGFuY2UgcGxvdC1kaXYgaWQgc291cmNlLiBUaGUgbW91bnQgZWxlbWVudCdzIGlkIG11c3QgYmUgdW5pcXVlIHNvIHR3b1xuICogIGxpdmUgdmlld2VycyAoZS5nLiB0aGUgbWFpbiBkaWFncmFtICsgYSBtb2RhbCBwcmV2aWV3KSBkb24ndCBjb2xsaWRlIG9uIHRoZVxuICogIHNhbWUgRE9NIGlkIOKAlCBgZ2V0RWxlbWVudEJ5SWRgIHdvdWxkIG90aGVyd2lzZSByZXR1cm4gd2hpY2hldmVyIGNhbWUgZmlyc3QuXG4gKiAgU3R5bGluZyBoYW5ncyBvZmYgdGhlIGAudml6LXBsb3RgIGNsYXNzIGluc3RlYWQgb2YgdGhlIGlkLiAqL1xubGV0IHBsb3RJbnN0YW5jZVNlcSA9IDA7XG5cbi8qKlxuICogVGhlIHZpZXdlciAoYDx2aXN1YWxpemVyPmApOiB0aGUgcGxvdCBzdXJmYWNlLCBpdHMgdG9vbGJhciwgdGhlIGxvYWRpbmcgb3ZlcmxheSBhbmRcbiAqIHRoZSBkaWFsb2dzIGl0IG9wZW5zIChDaGFubmVscyAmIEhpc3RvZ3JhbSwgc3BhdGlhbC1vbWljcyBjb250cm9scywgUmVnaW9uIEVkaXRvcixcbiAqIGNvbnRyaWJ1dGVkIG1vZGVzIGFuZCB0b29scykuIEl0IG9yY2hlc3RyYXRlcyByZW5kZXJpbmcgdGhyb3VnaCB0aGUgYFZJU1VBTElaRVJgXG4gKiBjb250cmFjdCBhbmQgcmVhZHMgdGhlIGltYWdlIGZyb20gdGhlIGhvc3QncyBgSU1BR0VfU1RBVEVfUE9SVGAuXG4gKlxuICogT25QdXNoLiBUZW1wbGF0ZSBldmVudHMgcmUtcmVuZGVyIGl0OyBzdGF0ZSB0aGF0IGxhbmRzIGFzeW5jaHJvbm91c2x5IGdvZXMgdGhyb3VnaFxuICoge0BsaW5rIGNoYW5nZWR9IChvciBhIHNpZ25hbDogdGhlIGxvYWRpbmcgb3ZlcmxheSksIGFuZCB0aGUgY29sbGFib3JhdG9ycyB0aGF0IG11c3RcbiAqIHJlbmRlciBzeW5jaHJvbm91c2x5ICh0aGUgcmVuZGVyIHNlc3Npb24ncyBvdmVybGF5LCBhIGNvbnRyaWJ1dGVkIHBhbmVsJ3Mgc2xvdCwgdGhlXG4gKiBjb250ZXh0IG1lbnUgYmVmb3JlIGl0IG9wZW5zKSBzdGlsbCBjYWxsIGBkZXRlY3RDaGFuZ2VzKClgLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd2aXN1YWxpemVyJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZSxcbiAgICBGb3Jtc01vZHVsZSxcbiAgICBTaGFyZWRNb2R1bGUsXG4gICAgQnV0dG9uTW9kdWxlLFxuICAgIENoZWNrYm94TW9kdWxlLFxuICAgIENvbnRleHRNZW51TW9kdWxlLFxuICAgIERpYWxvZ01vZHVsZSxcbiAgICBEcm9wZG93bk1vZHVsZSxcbiAgICBJbnB1dE51bWJlck1vZHVsZSxcbiAgICBQcm9ncmVzc0Jhck1vZHVsZSxcbiAgICBTbGlkZXJNb2R1bGUsXG4gICAgVG9hc3RNb2R1bGUsXG4gICAgVG9vbHRpcE1vZHVsZSxcbiAgICBGbG9hdGluZ0RyYWdEaXJlY3RpdmUsXG4gICAgVG9vbGJhckNvbXBvbmVudCxcbiAgICBJbnRlbnNpdHlJbnNldENvbXBvbmVudCxcbiAgICBDaGFubmVsSGlzdG9ncmFtQ29tcG9uZW50LFxuICAgIFNwYXRpYWxDb250cm9sc0NvbXBvbmVudCxcbiAgICBSZWdpb25FZGl0b3JDb21wb25lbnQsXG4gIF0sXG4gIHRlbXBsYXRlVXJsOiAnLi92aXN1YWxpemVyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vdmlzdWFsaXplci5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgVmlzdWFsaXplckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzLCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3ksIENvbnRleHRNZW51QWN0aW9ucyB7XG4gIC8qKiBQZXItaW5zdGFuY2UgdG9hc3Qga2V5LiBNZXNzYWdlU2VydmljZSBpcyBhIGdsb2JhbCBzaW5nbGV0b24sIHNvIHR3byBsaXZlXG4gICAqICBgPHZpc3VhbGl6ZXI+YCBpbnN0YW5jZXMgKG1haW4gdmlld2VyICsgcGlwZWxpbmUtZGlhbG9nIHByZXZpZXcpIHNoYXJpbmdcbiAgICogIG9uZSBrZXkgd291bGQgZWFjaCByZW5kZXIgdGhlIHNhbWUgbWVzc2FnZSDigJQgYSBkdXBsaWNhdGUgdG9hc3QuIEEgdW5pcXVlXG4gICAqICBrZXkgcGVyIGluc3RhbmNlIHNjb3BlcyB0aGUgdG9hc3QgdG8gdGhlIGNvbXBvbmVudCB0aGF0IHJhaXNlZCBpdC4gKi9cbiAgcHJpdmF0ZSBzdGF0aWMgbmV4dFRvYXN0SWQgPSAwO1xuXG4gIC8qKlxuICAgKiBUaGUgbGlicmFyeSBhbHNvIHJhaXNlcyBub3RpY2VzIGZyb20gcGxhY2VzIHRoYXQgaGF2ZSBubyBpbnN0YW5jZSBvZiB0aGVpclxuICAgKiBvd24gdG8ga2V5IGFnYWluc3Q6IHtAbGluayBQbG90bHlTZXJ2aWNlfSBpcyBgcHJvdmlkZWRJbjogJ3Jvb3QnYCwgYW5kIHRoZVxuICAgKiByZWdpb24gZWRpdG9yIGlzIGEgY2hpbGQgZGlhbG9nLiBUaG9zZSB1c2UgdGhlIGZpeGVkXG4gICAqIHtAbGluayBWSVpfVE9BU1RfS0VZfSAvIHtAbGluayBWSVpfQUxFUlRfVE9BU1RfS0VZfSBvdXRsZXRzLlxuICAgKlxuICAgKiBGb3IgdGhlIHNhbWUgcmVhc29uIHRoZSBwZXItaW5zdGFuY2Uga2V5IGFib3ZlIGV4aXN0cywgZXhhY3RseSBPTkUgbW91bnRlZFxuICAgKiB2aXN1YWxpemVyIG1heSByZW5kZXIgdGhvc2Ugc2hhcmVkIG91dGxldHMg4oCUIG90aGVyd2lzZSBhIG1lc3NhZ2UgZnJvbSB0aGVcbiAgICogcm9vdCBzZXJ2aWNlIHdvdWxkIGJlIHNob3duIG9uY2UgcGVyIGxpdmUgdmlld2VyIChqaXQtdWkgcnVucyBhIG1haW4gdmlld1xuICAgKiBhbmQgYSBwaXBlbGluZS1wcmV2aWV3IGF0IHRoZSBzYW1lIHRpbWUpLiBUaGUgZmlyc3QgdG8gaW5pdCBjbGFpbXMgdGhlbSBhbmRcbiAgICogcmVsZWFzZXMgb24gZGVzdHJveSwgc28gdGhlIHN1cnZpdmluZyB2aWV3ZXIgcGlja3MgdGhlbSB1cC5cbiAgICovXG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IGxpdmVJbnN0YW5jZXMgPSBuZXcgU2V0PFZpc3VhbGl6ZXJDb21wb25lbnQ+KCk7XG4gIHByb3RlY3RlZCByZWFkb25seSB2aXpUb2FzdEtleSA9IFZJWl9UT0FTVF9LRVk7XG4gIHByb3RlY3RlZCByZWFkb25seSB2aXpBbGVydFRvYXN0S2V5ID0gVklaX0FMRVJUX1RPQVNUX0tFWTtcbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhpcyBpbnN0YW5jZSByZW5kZXJzIHRoZSBzaGFyZWQgb3V0bGV0cy4gVGhlIG93bmVyIGlzIHNpbXBseSB0aGVcbiAgICogb2xkZXN0IGxpdmUgdmlzdWFsaXplciDigJQgYSBgU2V0YCBpdGVyYXRlcyBpbiBpbnNlcnRpb24gb3JkZXIsIHNvIHdoZW4gdGhlXG4gICAqIG93bmVyIGlzIGRlc3Ryb3llZCB0aGUgbmV4dCBvbmUgdGFrZXMgb3ZlciBvbiBpdHMgZm9sbG93aW5nIGNoYW5nZS1kZXRlY3Rpb25cbiAgICogcGFzcy4gVHJhY2tpbmcgYSBzZXQgcmF0aGVyIHRoYW4gYSBzaW5nbGUgb3duZXIgbWF0dGVyczogd2l0aCBhIGxvbmVcbiAgICogYG93bmVyYCByZWZlcmVuY2UsIHRlYXJpbmcgZG93biB0aGUgb3duZXIgd2hpbGUgYSBzaWJsaW5nIHdhcyBhbHJlYWR5XG4gICAqIGluaXRpYWxpc2VkIHdvdWxkIGxlYXZlIG5vYm9keSByZW5kZXJpbmcgdGhlIG91dGxldHMsIGFuZCBldmVyeSBub3RpY2UgZnJvbVxuICAgKiB0aGUgcm9vdCBzZXJ2aWNlIHdvdWxkIHNpbGVudGx5IHZhbmlzaCBhZ2Fpbi5cbiAgICovXG4gIHByb3RlY3RlZCBnZXQgb3duc1NoYXJlZFRvYXN0cygpOiBib29sZWFuIHtcbiAgICBjb25zdCBvbGRlc3QgPSBWaXN1YWxpemVyQ29tcG9uZW50LmxpdmVJbnN0YW5jZXMudmFsdWVzKCkubmV4dCgpO1xuICAgIHJldHVybiAhb2xkZXN0LmRvbmUgJiYgb2xkZXN0LnZhbHVlID09PSB0aGlzO1xuICB9XG5cbiAgLyoqIEVhY2ggbmV3IGltYWdlOiB3aGV0aGVyIGl0IGlzIGEgei1zdGFjay4gKi9cbiAgQE91dHB1dCgpXG4gIGlzU3RhY2tFdmVudCA9IG5ldyBFdmVudEVtaXR0ZXIoZmFsc2UpO1xuICAvKiogRWFjaCBuZXcgaW1hZ2U6IHdoZXRoZXIgaXQgaXMgc2luZ2xlLWNoYW5uZWwgKGdyYXlzY2FsZSkuICovXG4gIEBPdXRwdXQoKVxuICBpc0dyYXlzY2FsZUV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcihmYWxzZSk7XG5cbiAgLyoqIFdoaWNoIHRvb2xiYXIgZ3JvdXBzIHRvIHNob3cuIEEgcGFydGlhbCBvdmVycmlkZSBtZXJnZXMgb3ZlciB0aGUgZnVsbCBzZXQsXG4gICAqICBzbyBgeyBzcGVjaWFsVG9vbHM6IGZhbHNlIH1gIGhpZGVzIG9ubHkgdGhhdCBncm91cC4gRGVmYXVsdHMgdG8gZXZlcnl0aGluZy4gKi9cbiAgQElucHV0KClcbiAgc2V0IHRvb2xiYXJUb29scyh2OiBUb29sYmFyVG9vbFZpc2liaWxpdHkgfCB1bmRlZmluZWQpIHtcbiAgICB0aGlzLl90b29sYmFyVG9vbHMgPSB7IC4uLkFMTF9UT09MQkFSX1RPT0xTLCAuLi4odiA/PyB7fSkgfTtcbiAgfVxuXG4gIGdldCB0b29sYmFyVG9vbHMoKTogUmVxdWlyZWQ8VG9vbGJhclRvb2xWaXNpYmlsaXR5PiB7XG4gICAgcmV0dXJuIHRoaXMuX3Rvb2xiYXJUb29scztcbiAgfVxuICBwcml2YXRlIF90b29sYmFyVG9vbHM6IFJlcXVpcmVkPFRvb2xiYXJUb29sVmlzaWJpbGl0eT4gPSBBTExfVE9PTEJBUl9UT09MUztcblxuICAvKiogRXhwb3NlIHRlc3Qtb25seSBwbG90IG1vZGVzIGluIHRoZSBzZWxlY3RvciAoZS5nLiB0aGUgbmFwYXJpIGBJbWFnZWBcbiAgICogIG1vZGUsIG90aGVyd2lzZSBoaWRkZW4pLiBUaGUgaG9zdCBhcHAgc2V0cyB0aGlzIGZyb20gYSBgP3Rlc3Q9MWAgVVJMXG4gICAqICB0b2dnbGUuIE9mZiBieSBkZWZhdWx0LCBzbyBwcm9kdWN0aW9uIHVzZXJzIG5ldmVyIHNlZSB0aGVtLiAqL1xuICBASW5wdXQoKVxuICB0ZXN0TW9kZSA9IGZhbHNlO1xuXG4gIC8qKiBJbWFnZS1zbW9vdGhpbmcgc3RhdGUgZm9yIHRoZSB0b29sYmFyJ3MgU21vb3RoZW4gdG9nZ2xlIChPU0Qgb25seSkuXG4gICAqICBEZWZhdWx0cyB0byBgZmFsc2VgIHNvIE9TRCBzaG93cyByYXcgcGl4ZWxzIChuZWFyZXN0LW5laWdoYm91cikuICovXG4gIHByb3RlY3RlZCBpbWFnZVNtb290aGluZ0VuYWJsZWQgPSBmYWxzZTtcbiAgZmlsZU5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBsb2FkZWRGaWxlTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBwcm90ZWN0ZWQgaW1hZ2VJbmZvOiBJSW1hZ2VJbmZvIHwgdW5kZWZpbmVkO1xuXG4gIC8vIOKUgOKUgCBUaGUgbG9hZGluZyBvdmVybGF5LCBhcyBzaWduYWxzOiBpdCBpcyBmZWQgYnkgdGhlIGhvc3QncyBhbmQgdGhlIGJhY2tlbmRzJyBzdHJlYW1zXG4gIC8vIGFuZCBieSB0aGUgcmVuZGVyIHNlc3Npb24sIGFsbCBvZiB3aGljaCBsYW5kIG91dHNpZGUgdGhpcyB2aWV3J3MgdGVtcGxhdGUgZXZlbnRzLiDilIDilIBcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGxvYWRpbmdNZXNzYWdlID0gc2lnbmFsKCdMb2FkaW5nIGltYWdlLi4uJyk7XG4gIC8qKiBUaGUgaG9zdCBpcyBsb2FkaW5nIGF0IHpvb20gKHRoZSBvdmVybGF5IG1lc3NhZ2UgbW92ZXMgb3V0IG9mIHRoZSB3YXkpLiAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgem9vbSA9IHNpZ25hbChmYWxzZSk7XG4gIHByb3RlY3RlZCByZWFkb25seSBzdGFja0xvYWRpbmcgPSBzaWduYWwoZmFsc2UpO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgaW1nTG9hZGluZyA9IHNpZ25hbChmYWxzZSk7XG4gIHByb3RlY3RlZCByZWFkb25seSBsb2FkaW5nUGVyY2VudGFnZSA9IHNpZ25hbCgwKTtcbiAgLy8gTm9uLW51bGwgKDAuLjEwMCkgd2hpbGUgaml0LXNlcnZpY2UgaXMgY29weWluZyB0aGUgc291cmNlIGZpbGUgaW50byB0aGVcbiAgLy8gbG9jYWwgY2FjaGUgUFZDIG9uIGZpcnN0IGNsaWNrLiBXaGVuIHNldCwgdGhlIGxvYWRpbmcgb3ZlcmxheSBzd2FwcyB0aGVcbiAgLy8gc3Bpbm5lciBmb3IgYSBkZXRlcm1pbmF0ZSBwcm9ncmVzcyBiYXIgd2l0aCBhIFwiQ2FjaGluZyBpbWFnZVwiIG1lc3NhZ2UuXG4gIHByb3RlY3RlZCByZWFkb25seSBjYWNoZVByb2dyZXNzID0gc2lnbmFsPG51bWJlciB8IG51bGw+KG51bGwpO1xuICAvKiogQSBqaXQtc2VydmljZSBjYWNoZSBjb3B5IGlzIGFjdGl2ZWx5IGluIHByb2dyZXNzIChkZXRlcm1pbmF0ZSAwLi45OSkuIERyaXZlcyB0aGUgY2FjaGVcbiAgICogIHByb2dyZXNzIGJhciBpbmRlcGVuZGVudGx5IG9mIGBpbWdMb2FkaW5nYCBzbyB0aGUgYmFyIGNhbid0IGJlIGRyb3BwZWQg4oCUIG9yIG1hc2tlZCBieSB0aGVcbiAgICogIFwiU2hhcnBlbmluZyBwcmV2aWV3Li4uXCIgb3ZlcmxheSDigJQgbWlkLWRvd25sb2FkIGlmIHRoZSBsb2FkaW5nIGZsYWcgZmxpcHMgZWFybHkuICovXG4gIHByb3RlY3RlZCByZWFkb25seSBpc0NhY2hpbmcgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgY29uc3QgcCA9IHRoaXMuY2FjaGVQcm9ncmVzcygpO1xuICAgIHJldHVybiBwICE9PSBudWxsICYmIHAgPCAxMDA7XG4gIH0pO1xuXG4gIC8qKiBFbWl0cyBvbmNlIHdoZW4gdGhpcyB2aWV3IGlzIGRlc3Ryb3llZDsgdGhlIGNvbGxhYm9yYXRvcnMgZW5kIHRoZWlyIHN1YnNjcmlwdGlvbnMgb24gaXQuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgZGVzdHJveWVkJCA9IG5ldyBPYnNlcnZhYmxlPHZvaWQ+KChzdWJzY3JpYmVyKSA9PlxuICAgIHRoaXMuZGVzdHJveVJlZi5vbkRlc3Ryb3koKCkgPT4ge1xuICAgICAgc3Vic2NyaWJlci5uZXh0KCk7XG4gICAgICBzdWJzY3JpYmVyLmNvbXBsZXRlKCk7XG4gICAgfSksXG4gICk7XG4gIC8qKiBIb3N0IGltYWdlLWluZm8gb2JqZWN0cyB3aG9zZSBvbmUtc2hvdCBgaW5pdGlhbFpJbmRleGAgd2FzIGFscmVhZHkgYXBwbGllZC4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBjb25zdW1lZFNsaWNlSGludHMgPSBuZXcgV2Vha1NldDxJSW1hZ2VJbmZvPigpO1xuICBwcm90ZWN0ZWQgekluZGV4ID0gMDtcbiAgcHJvdGVjdGVkIG1heEluZGV4ID0gMDtcblxuICBAVmlld0NoaWxkKCdjbScpIGNvbnRleHRNZW51ITogQ29udGV4dE1lbnU7XG4gIHByb3RlY3RlZCBjb250ZXh0TWVudUl0ZW1zOiBNZW51SXRlbVtdID0gW107XG5cbiAgLyoqIFRoZSBhcm1lZCB0b29sIG1vZGUgYW5kIHRoZSB0b29sYmFyJ3MgdG9vbCBzZXR0aW5ncy4gKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHRvb2xzID0gbmV3IFRvb2xNb2RlcyhcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLFxuICAgIHRoaXMuc2Vzc2lvbixcbiAgICB0aGlzLm5nWm9uZSxcbiAgICAobW9kZSkgPT4ge1xuICAgICAgaWYgKG1vZGUgIT09ICdzYW1Qb2ludCcpIHRoaXMuc2VnbWVudGF0aW9uLmhpZGUoKTtcbiAgICB9LCAvLyBsZWF2aW5nIHBvaW50IG1vZGUgZHJvcHMgaXRzIHRvYXN0XG4gICAgKCkgPT4gdGhpcy5jaGFuZ2VkKCksXG4gICk7XG4gIHByb3RlY3RlZCBnZXQgYWN0aXZlRHJhZ01vZGUoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMudG9vbHMuYWN0aXZlO1xuICB9XG4gIHByb3RlY3RlZCBzZXQgYWN0aXZlRHJhZ01vZGUobW9kZTogc3RyaW5nIHwgbnVsbCkge1xuICAgIHRoaXMudG9vbHMuYWN0aXZlID0gbW9kZTtcbiAgfVxuICBwcm90ZWN0ZWQgZ2V0IHdhbmRTZW5zaXRpdml0eSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnRvb2xzLndhbmRTZW5zaXRpdml0eTtcbiAgfVxuICBwcm90ZWN0ZWQgc2V0IHdhbmRTZW5zaXRpdml0eSh2OiBudW1iZXIpIHtcbiAgICB0aGlzLnRvb2xzLndhbmRTZW5zaXRpdml0eSA9IHY7XG4gIH1cbiAgcHJvdGVjdGVkIGdldCBicnVzaFNpemUoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy50b29scy5icnVzaFNpemU7XG4gIH1cbiAgcHJvdGVjdGVkIGdldCB2ZXJ0ZXhFcmFzZXJSYWRpdXMoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy50b29scy52ZXJ0ZXhFcmFzZXJSYWRpdXM7XG4gIH1cbiAgcHJvdGVjdGVkIHNldCB2ZXJ0ZXhFcmFzZXJSYWRpdXModjogbnVtYmVyKSB7XG4gICAgdGhpcy50b29scy52ZXJ0ZXhFcmFzZXJSYWRpdXMgPSB2O1xuICB9XG5cbiAgLyoqIFJlZ2lvbiBzZXQtb3BlcmF0aW9ucyBvbiB0aGUgc2VsZWN0aW9uLCBhbmQgdGhlIHN0b3JlIG1pcnJvcnMgdGhleSByZWFkIChqaXQtdWkjODUpLiAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgcmVnaW9uQWN0aW9ucyA9IG5ldyBSZWdpb25BY3Rpb25zKFxuICAgIHRoaXMucGxvdFNlcnZpY2UsXG4gICAgdGhpcy5yZWdpb25PcHMsXG4gICAgKCkgPT4gdGhpcy5pbWFnZUluZm8/LnRydWVJbWFnZVNpemUsXG4gICAgKG0pID0+IHRoaXMubWVzc2FnZVNlcnZpY2UuYWRkKHsga2V5OiB0aGlzLnJlc3VsdFRvYXN0S2V5LCAuLi5tIH0pLFxuICApO1xuICAvKiogQ3VzdG9tLXRocmVzaG9sZCBTaW1wbGlmeSBkaWFsb2cgdmlzaWJpbGl0eSAoc2VlIHtAbGluayBSZWdpb25BY3Rpb25zfSkuICovXG4gIHByb3RlY3RlZCBnZXQgZGlzcGxheVNpbXBsaWZ5RGlhbG9nKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnJlZ2lvbkFjdGlvbnMuZGlzcGxheVNpbXBsaWZ5RGlhbG9nO1xuICB9XG4gIHByb3RlY3RlZCBzZXQgZGlzcGxheVNpbXBsaWZ5RGlhbG9nKHY6IGJvb2xlYW4pIHtcbiAgICB0aGlzLnJlZ2lvbkFjdGlvbnMuZGlzcGxheVNpbXBsaWZ5RGlhbG9nID0gdjtcbiAgfVxuXG4gIC8qKiBTQU0gbW9kZWwgcGlja2VyIG9wdGlvbnMgKyBjdXJyZW50IHNlbGVjdGlvbiAoaml0LXVpIzkwIFAxKS4gT25seSBtb2RlbHNcbiAgICogIHdpdGggYSBob3N0ZWQgT05OWCBwYWlyIChjb25maWd1cmVkIHZpYSBzZXRTYW1Nb2RlbFVybHMgYXQgYXBwIGluaXQpIGFyZVxuICAgKiAgb2ZmZXJlZCwgc28gdGhlIHBpY2tlciBjYW4ndCBzZWxlY3QgYSBtb2RlbCB0aGF0IGNhbid0IHJ1bi4gKi9cbiAgcHJvdGVjdGVkIHNhbU1vZGVscyA9IFNBTV9NT0RFTFMuZmlsdGVyKGlzU2FtTW9kZWxSZWFkeSkubWFwKChtKSA9PiAoeyBpZDogbS5pZCwgbGFiZWw6IG0ubGFiZWwgfSkpO1xuICBwcm90ZWN0ZWQgc2FtTW9kZWxJZCA9IGdldERlZmF1bHRTYW1Nb2RlbElkKCk7XG5cbiAgLyoqXG4gICAqIE5vLXByb21wdCB0b29scyByZWdpc3RlcmVkIHRocm91Z2gge0BsaW5rIFRPT0xCQVJfVE9PTFN9LCBmaWx0ZXJlZCB0byB0aG9zZVxuICAgKiB3aXRoIGNvbmZpZ3VyZWQgbW9kZWxzIGFuZCBzb3J0ZWQuIFRoaXMgbGlicmFyeSByZWdpc3RlcnMgbm9uZSDigJQgYSBob3N0XG4gICAqIHN1cHBsaWVzIHRoZW0g4oCUIHNvIGFuIG9wZW4gYnVpbGQgaGFzIGFuIGVtcHR5IGFycmF5IGhlcmUgYW5kIHRoZSB0b29sYmFyXG4gICAqIGFuZCBoZWxwIGRpYWxvZyBzaW1wbHkgb21pdCB0aGF0IGdyb3VwLlxuICAgKi9cbiAgcHJvdGVjdGVkIGNvbnRyaWJ1dGVkVG9vbHM6IFRvb2xiYXJUb29sQ29udHJpYnV0aW9uW10gPSBbXTtcbiAgLyoqIENoZWNrcG9pbnRzIGFuZCBwYXJhbWV0ZXIgdmFsdWVzIG9mIHtAbGluayBjb250cmlidXRlZFRvb2xzfSwgYW5kIHRoZWlyIGRpYWxvZy4gKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHRvb2xQYXJhbXM6IFRvb2xQYXJhbXNNb2RlbDtcbiAgLyoqIENvbnRyaWJ1dGVkIHBsb3QgbW9kZXMgYW5kIGRpYWxvZyB0b29scywgYW5kIHRoZWlyIGxpdmUgc2Vzc2lvbnMuICovXG4gIHJlYWRvbmx5IGNvbnRyaWJ1dGlvbnM6IENvbnRyaWJ1dGlvbkhvc3Q7XG4gIC8qKiBEaWFsb2cgdG9vbHMgcmVnaXN0ZXJlZCB0aHJvdWdoIHtAbGluayBUT09MQkFSX1RPT0xTfSAoYGtpbmQ6ICdkaWFsb2cnYCkuICovXG4gIHByb3RlY3RlZCBnZXQgZGlhbG9nVG9vbHMoKTogVG9vbGJhckRpYWxvZ1Rvb2xDb250cmlidXRpb25bXSB7XG4gICAgcmV0dXJuIHRoaXMuY29udHJpYnV0aW9ucy5kaWFsb2dUb29scztcbiAgfVxuICAvKiogVGhlIGRpYWxvZyB0b29sIHRoZSB1c2VyIGhhcyBvcGVuIChpdHMgc2Vzc2lvbiBtYXkgYmUgYmV0d2VlbiByZW5kZXJzKS4gKi9cbiAgcHJvdGVjdGVkIGdldCBvcGVuRGlhbG9nVG9vbElkKCk6IHN0cmluZyB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLmNvbnRyaWJ1dGlvbnMub3BlbkRpYWxvZ1Rvb2xJZDtcbiAgfVxuICAvKiogVGhlIG9wZW4gZGlhbG9nIHRvb2wncyBsaXZlIGRpYWxvZywgYXMgdGhlIHRlbXBsYXRlIHJlbmRlcnMgaXQuICovXG4gIHByb3RlY3RlZCBnZXQgdG9vbERpYWxvZygpOiBUb29sRGlhbG9nVmlldyB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLmNvbnRyaWJ1dGlvbnMudG9vbERpYWxvZztcbiAgfVxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgc2FtVG9hc3RLZXkgPSBgc2FtLSR7VmlzdWFsaXplckNvbXBvbmVudC5uZXh0VG9hc3RJZCsrfWA7XG4gIC8qKlxuICAgKiBPdXRsZXQgZm9yIHRoZSBsaWJyYXJ5J3Mgb3duIHJlc3VsdC9lcnJvciBub3RpY2VzLCBrZXllZCB0byB0aGlzIGluc3RhbmNlIHNvIHRoZXlcbiAgICogZG8gbm90IGRlcGVuZCBvbiB0aGUgaG9zdCBtb3VudGluZyBhIGtleWxlc3MgYDxwLXRvYXN0PmAgKG1vc3QgaG9zdHMgZG9uJ3QsIGFuZCBhXG4gICAqIGZhaWxlZCBzZWdtZW50YXRpb24gdGhlbiBsb29rZWQgbGlrZSBhIGRlYWQgYnV0dG9uKS4gRGVsaWJlcmF0ZWx5IE5PVCB0aGUgc3RpY2t5XG4gICAqIHRvYXN0J3Mga2V5OiB0aGF0IGlzIGNsZWFyZWQgd2hlbiBhIHJ1biBzZXR0bGVzLCB3aGljaCB3b3VsZCB3aXBlIHRoZSByZXN1bHQuXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgcmVzdWx0VG9hc3RLZXkgPSBgJHt0aGlzLnNhbVRvYXN0S2V5fS1yZXN1bHRgO1xuICAvKiogU2VnbWVudGF0aW9uIHJ1bnMgYW5kIHRoZWlyIHN0aWNreSBwcm9ncmVzcyB0b2FzdC4gKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHNlZ21lbnRhdGlvbiA9IG5ldyBTZWdtZW50YXRpb25SdW5uZXIoXG4gICAgdGhpcy5tZXNzYWdlU2VydmljZSxcbiAgICB0aGlzLnNhbVRvYXN0S2V5LFxuICAgIHRoaXMucmVzdWx0VG9hc3RLZXksXG4gICAgKCkgPT4gdGhpcy5jaGFuZ2VkKCksXG4gICk7XG5cbiAgLyoqIENoYW5uZWxzICYgSGlzdG9ncmFtIGRpYWxvZyB2aXNpYmlsaXR5IChvcGVuZWQgZnJvbSB0aGUgdG9vbGJhcikuICovXG4gIHByb3RlY3RlZCBzaG93Q2hhbm5lbEhpc3RvZ3JhbSA9IGZhbHNlO1xuICAvKiogU3BhdGlhbC1vbWljcyBjb250cm9scyBkaWFsb2cgdmlzaWJpbGl0eSAodG9vbGJhciBidXR0b24pLiAqL1xuICBwcm90ZWN0ZWQgc2hvd1NwYXRpYWxDb250cm9scyA9IGZhbHNlO1xuICAvKiogUmVnaW9uIEVkaXRvciBkaWFsb2cgdmlzaWJpbGl0eSAob3BlbmVkIGZyb20gdGhlIHRvb2xiYXIpLiAqL1xuICBwcm90ZWN0ZWQgc2hvd1JlZ2lvbkVkaXRvciA9IGZhbHNlO1xuICAvKiogUmVnaW9uIEVkaXRvciBkaWFsb2cgd2lkdGguIE9uIG9wZW4gaXQgaXMgc2V0IHRvIHRoZSBjb25maWd1cmVkIGhvc3RcbiAgICogIGVsZW1lbnQncyBjdXJyZW50IHdpZHRoLCBvciDigJQgd2hlbiBubyBzZWxlY3RvciBpcyBjb25maWd1cmVkIC8gdGhlIGVsZW1lbnRcbiAgICogIGlzbid0IGZvdW5kIOKAlCB0byBhIHF1YXJ0ZXIgb2YgdGhlIHBhZ2UgKHNlZSBvcGVuUmVnaW9uRWRpdG9yKS4gKi9cbiAgcHJvdGVjdGVkIHJlZ2lvbkVkaXRvcldpZHRoID0gJzI1dncnO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgcGxvdERpdk5hbWUgPSBgdml6LXBsb3QtJHtwbG90SW5zdGFuY2VTZXErK31gO1xuICAvKiogVGhlIHJlbmRlciBwaXBlbGluZTogdGhlIG5ld2VzdCBpbWFnZSAob3IgaW1hZ2UtbGVzcyBkYXRhc2V0KSBhbHdheXMgd2lucy4gKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHJlbmRlcjogSW1hZ2VSZW5kZXJTZXNzaW9uID0gbmV3IEltYWdlUmVuZGVyU2Vzc2lvbih7XG4gICAgcGxvdERpdk5hbWU6IHRoaXMucGxvdERpdk5hbWUsXG4gICAgdmlzdWFsaXplcjogdGhpcy5wbG90U2VydmljZSxcbiAgICB6SW5kZXg6ICgpID0+IHRoaXMuekluZGV4LFxuICAgIHBsb3RUeXBlOiAoKSA9PiB0aGlzLnBsb3RUeXBlLFxuICAgIGlzSGVhdG1hcDogKCkgPT4gdGhpcy5pc0hlYXRtYXAsXG4gICAgaXNDYWNoaW5nOiAoKSA9PiB0aGlzLmlzQ2FjaGluZygpLFxuICAgIGJlZm9yZVJlc2V0OiAoKSA9PiB0aGlzLmNvbnRyaWJ1dGlvbnMuZW5kU2Vzc2lvbnMoKSxcbiAgICBwcmVwYXJlOiAoaW5mbykgPT4gdGhpcy5sYXlPdXRTbGljZXMoaW5mbyksXG4gICAgcmVsZWFzZU92ZXJsYXk6IChpbmZvKSA9PiB7XG4gICAgICBpZiAoaW5mby5pc1N0YWNrICYmIGluZm8uc2hvd1N0YWNrKSB0aGlzLnN0YWNrTG9hZGluZy5zZXQoZmFsc2UpO1xuICAgICAgdGhpcy5zdGF0ZS5zZXRJbWFnZUxvYWRpbmcoZmFsc2UpO1xuICAgIH0sXG4gICAgbGFuZGVkOiAoaW5mbykgPT4ge1xuICAgICAgYXBwbHlJbWFnZVJvaXMoaW5mbywgdGhpcy5wbG90U2VydmljZSwgdGhpcy56SW5kZXgpO1xuICAgICAgdGhpcy5jb250cmlidXRpb25zLmFjdGl2YXRlKCk7XG4gICAgfSxcbiAgICBzZXRJbWFnZUxvYWRpbmc6IChsb2FkaW5nKSA9PiB0aGlzLnN0YXRlLnNldEltYWdlTG9hZGluZyhsb2FkaW5nKSxcbiAgICBhbGVydDogKHNldmVyaXR5LCBzdW1tYXJ5LCBkZXRhaWwpID0+XG4gICAgICB0aGlzLm1lc3NhZ2VTZXJ2aWNlLmFkZCh7IGtleTogdGhpcy52aXpBbGVydFRvYXN0S2V5LCBzZXZlcml0eSwgc3VtbWFyeSwgZGV0YWlsIH0pLFxuICAgIGRldGVjdENoYW5nZXM6ICgpID0+IHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKSxcbiAgfSk7XG4gIHBsb3RUeXBlID0gUGxvdFR5cGUuSU1BR0U7XG4gIHByb3RlY3RlZCBpc0hlYXRtYXAgPSB0cnVlO1xuICBwcm90ZWN0ZWQgYWN0aXZlU3VyZmFjZTNkTW9kZSA9ICd0dXJudGFibGUnO1xuICAvKiogV2hldGhlciB0aGUgbmFwYXJpIDNEIGNvb3JkaW5hdGUtYXhlcyAvIHNjYWxlIGdpem1vIGlzIHNob3duICh2b2x1bWUvaXNvc3VyZmFjZSkuICovXG4gIHByb3RlY3RlZCBheGVzVmlzaWJsZSA9IHRydWU7XG4gIHByb3RlY3RlZCB3aXJlZnJhbWVBY3RpdmUgPSBmYWxzZTtcbiAgLyoqIG5hcGFyaSAzRCBkZWNpbWF0ZSBmYWN0b3IgKDEgPSBGdWxsIOKApiA4ID0g4oWbOyBkZWZhdWx0IMK9KTsgY2hhbmdpbmcgaXQgcmUtcGxvdHMuICovXG4gIHByb3RlY3RlZCByZXNvbHV0aW9uU2NhbGUgPSBOQVBBUklfREVGQVVMVF9ERUNJTUFURTtcblxuICAvKiogVGhlIHNlbGVjdG9yJ3MgZW50cmllczogdGhlIGJ1aWx0LWluIHBsb3QgdHlwZXMgdGhlIGFjdGl2ZSBiYWNrZW5kXG4gICAqICBhZHZlcnRpc2VzICgzRCBnYXRlZCBieSBjYXBhYmlsaXR5KSwgdGhlbiBhbnkgY29udHJpYnV0ZWQgbW9kZXNcbiAgICogICh7QGxpbmsgUExPVF9UWVBFX0NPTlRSSUJVVElPTlN9KS4gKi9cbiAgcHJvdGVjdGVkIHBsb3RUeXBlTWVudTogUGxvdFR5cGVPcHRpb25bXSA9IFtdO1xuICAvKipcbiAgICogVGhlIGJ1aWx0LWluIHBsb3QgdHlwZXMgb24gb2ZmZXIg4oCUIHtAbGluayBwbG90VHlwZU1lbnV9IHdpdGhvdXQgY29udHJpYnV0ZWRcbiAgICogbW9kZXMuIEtlcHQgd2l0aCBpdHMgb3JpZ2luYWwgdHlwZSBzbyBleGlzdGluZyByZWFkZXJzIGFyZSB1bmFmZmVjdGVkLlxuICAgKi9cbiAgcHJvdGVjdGVkIHBsb3RUeXBlT3B0aW9uczogUGxvdFR5cGVEZXNjcmlwdG9yW10gPSBbXTtcbiAgLyoqXG4gICAqIFdoYXQgdGhlIHNlbGVjdG9yIHNob3dzOiBhIGJ1aWx0LWluIHR5cGUgb3IgYSBjb250cmlidXRlZCBtb2RlJ3MgaWQuIEV2ZXJ5XG4gICAqIHJlbmRlcmluZyBhbmQgdG9vbCBkZWNpc2lvbiBnb2VzIHRocm91Z2gge0BsaW5rIGJhc2VQbG90VHlwZX0gaW5zdGVhZCwgc28gYVxuICAgKiBjb250cmlidXRlZCBtb2RlIGJlaGF2ZXMgZXhhY3RseSBsaWtlIHRoZSBidWlsdC1pbiB0eXBlIGl0IHJpZGVzIG9uLlxuICAgKi9cbiAgcHJvdGVjdGVkIHNlbGVjdGVkUGxvdFR5cGVJZDogUGxvdFR5cGVJZCA9IFBsb3RUeXBlLklNQUdFO1xuXG4gIC8qKlxuICAgKiBUaGUgYnVpbHQtaW4gcGxvdCB0eXBlIGJlaW5nIHJlbmRlcmVkLiBXaXRoIG5vIGNvbnRyaWJ1dGVkIG1vZGUgYWN0aXZlIHRoaXNcbiAgICogaXMgdGhlIHNlbGVjdGlvbiBpdHNlbGY7IGR1cmluZyBvbmUgaXQgaXMgdGhlIG1vZGUncyBgYmFzZVR5cGVgLiBLZXB0IHdpdGggaXRzXG4gICAqIG9yaWdpbmFsIGBQbG90VHlwZWAgdHlwZSBmb3IgZXhpc3RpbmcgcmVhZGVycyDigJQgdXNlIHtAbGluayBzZWxlY3RlZFBsb3RUeXBlSWR9XG4gICAqIGZvciB0aGUgc2VsZWN0b3IncyBpZC4gQXNzaWduaW5nIHNlbGVjdHMgdGhhdCBidWlsdC1pbiB0eXBlLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldCBzZWxlY3RlZFBsb3RUeXBlKCk6IFBsb3RUeXBlIHtcbiAgICByZXR1cm4gdGhpcy5iYXNlUGxvdFR5cGU7XG4gIH1cbiAgcHJvdGVjdGVkIHNldCBzZWxlY3RlZFBsb3RUeXBlKHR5cGU6IFBsb3RUeXBlKSB7XG4gICAgdGhpcy5zZWxlY3RlZFBsb3RUeXBlSWQgPSB0eXBlO1xuICB9XG5cbiAgLyoqIENvbnRyaWJ1dGVkIHBsb3QgbW9kZXMgYW5kIHRoZWlyIHNpbmdsZSBsaXZlIHNlc3Npb24uICovXG4gIGdldCBwbG90TW9kZXMoKTogUGxvdE1vZGVDb250cm9sbGVyIHtcbiAgICByZXR1cm4gdGhpcy5jb250cmlidXRpb25zLnBsb3RNb2RlcztcbiAgfVxuICAvKiogVGhlIGxpdmUgY29udHJpYnV0ZWQgbW9kZSdzIHNpZGUgcGFuZWw7IG51bGwgd2hpbGUgbm8gY29udHJpYnV0ZWQgc2Vzc2lvbiBpcyBsaXZlLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IHBsb3RNb2RlUGFuZWwoKTogUGxvdE1vZGVQYW5lbFZpZXcgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5jb250cmlidXRpb25zLnBsb3RNb2RlUGFuZWw7XG4gIH1cblxuICAvKiogV2hlcmUgYSBgbW91bnRgIHBhbmVsJ3MgaG9zdCBlbGVtZW50IGlzIGF0dGFjaGVkIG9uY2UgdGhlIGRpYWxvZyByZW5kZXJzLiAqL1xuICBAVmlld0NoaWxkKCdwbG90TW9kZVBhbmVsU2xvdCcpXG4gIHNldCBwbG90TW9kZVBhbmVsU2xvdChyZWY6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+IHwgdW5kZWZpbmVkKSB7XG4gICAgdGhpcy5jb250cmlidXRpb25zLmF0dGFjaFBhbmVsU2xvdChyZWY/Lm5hdGl2ZUVsZW1lbnQpO1xuICB9XG5cbiAgLyoqIFRoZSBidWlsdC1pbiB0eXBlIGFjdHVhbGx5IHJlbmRlcmVkIGZvciB7QGxpbmsgc2VsZWN0ZWRQbG90VHlwZUlkfTogaXRzZWxmXG4gICAqICBmb3IgYSBidWlsdC1pbiB0eXBlLCBgYmFzZVR5cGVgIGZvciBhIGNvbnRyaWJ1dGVkIG1vZGUuICovXG4gIHByb3RlY3RlZCBnZXQgYmFzZVBsb3RUeXBlKCk6IFBsb3RUeXBlIHtcbiAgICByZXR1cm4gdGhpcy5wbG90TW9kZXMuYmFzZVR5cGVPZih0aGlzLnNlbGVjdGVkUGxvdFR5cGVJZCk7XG4gIH1cblxuICAvKiogRGl2IHRoZSBmbG9hdGluZyBpbnRlbnNpdHktcHJvZmlsZSBpbnNldCBpcyBjaGFydGVkIGludG8uIFBlciBpbnN0YW5jZSwgbGlrZVxuICAgKiAge0BsaW5rIHBsb3REaXZOYW1lfTogdGhlIGJhY2tlbmQgcmVzb2x2ZXMgaXQgYnkgaWQsIHNvIGEgZml4ZWQgaWQgbWFkZSB0d28gbGl2ZVxuICAgKiAgdmlld2VycyBkcmF3IGJvdGggaW5zZXRzIGludG8gd2hpY2hldmVyIGRpdiBjYW1lIGZpcnN0IGluIHRoZSBkb2N1bWVudC4gKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGludGVuc2l0eUluc2V0RGl2ID0gYCR7dGhpcy5wbG90RGl2TmFtZX0taW5zZXRgO1xuXG4gIC8qKiBUb29sYmFyIGRvY2tpbmc6IGRvY2tlZCBhY3Jvc3MgdGhlIHRvcCBieSBkZWZhdWx0OyBkcmFnZ2luZyBpdHMgaGFuZGxlXG4gICAqICBkZXRhY2hlcyBpdCBpbnRvIGEgZmxvYXRpbmcsIG1vdmFibGUgd2luZG93IChmcmVlcyB0aGUgdG9wIHJvdyBmb3IgdGhlXG4gICAqICB2aXN1YWxpemF0aW9uKS4gKi9cbiAgcHJvdGVjdGVkIHRvb2xiYXJGbG9hdGluZyA9IGZhbHNlO1xuICBwcm90ZWN0ZWQgdG9vbGJhclBvcyA9IHsgeDogOCwgeTogOCB9O1xuICAvKiogV2hlcmUgYSB0b29sYmFyLWhhbmRsZSBkcmFnIHN0YXJ0cyBmcm9tOiBncmFiYmluZyB0aGUgZG9ja2VkIHRvb2xiYXIgZmxvYXRzIGl0LiAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgdG9vbGJhckRyYWdPcmlnaW4gPSAoKTogRmxvYXRpbmdQb3MgPT4ge1xuICAgIGlmICghdGhpcy50b29sYmFyRmxvYXRpbmcpIHtcbiAgICAgIHRoaXMudG9vbGJhckZsb2F0aW5nID0gdHJ1ZTtcbiAgICAgIHRoaXMudG9vbGJhclBvcyA9IHsgeDogOCwgeTogOCB9O1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy50b29sYmFyUG9zO1xuICB9O1xuICAvKiogVGhlIGZsb2F0aW5nIGludGVuc2l0eS1wcm9maWxlIGluc2V0IChhbHdheXMgbW91bnRlZDsgc2hvd3MgaXRzZWxmIHdoaWxlIGxpbmVzIGV4aXN0KS4gKi9cbiAgQFZpZXdDaGlsZChJbnRlbnNpdHlJbnNldENvbXBvbmVudCwgeyBzdGF0aWM6IHRydWUgfSkgaW5zZXQ/OiBJbnRlbnNpdHlJbnNldENvbXBvbmVudDtcblxuICAvKiogVHJ1ZSB3aGlsZSB0aGUgM0Qgc3BhdGlhbCBjbG91ZCBpcyB0aGUgYWN0aXZlIG1vZGUuIFRoZSBjb250cm9scyBkcm9wIHRoZSBST0lcbiAgICogIHNlbGVjdGlvbiB0aGVyZTogcmVnaW9uIHRvb2xzIGFyZSBzY3JlZW4tc3BhY2UsIGFuZCBhZ2FpbnN0IGFuIG9yYml0aW5nXG4gICAqICBjYW1lcmEgYSBkcmF3biByZWN0YW5nbGUgaGFzIG5vIGZpeGVkIG1lYW5pbmcgaW4gdGhlIGRhdGEuICovXG4gIHByb3RlY3RlZCBnZXQgaXNTcGF0aWFsM2RNb2RlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBpc1NwYXRpYWxPbWljczNkKHRoaXMuYmFzZVBsb3RUeXBlKTtcbiAgfVxuXG4gIC8qKiBUcnVlIGZvciB0aGUgSW1hZ2UgcGxvdCB0eXBlLCB3aGljaCByZW5kZXJzIGFzIGEgbmF0aXZlbHkgcGFuL3pvb20tYWJsZVxuICAgKiAgcmFzdGVyIOKAlCBzbyB0aGUgYmFja2VuZC1hZ25vc3RpYyB6b29tL3BhbiB0b29sYmFyIHRvb2xzIGFyZSBoaWRkZW4uIFRoZVxuICAgKiAgY29tcG9uZW50IGRyaXZlcyB0aGlzIG9mZiB0aGUgcGxvdCB0eXBlLCBub3QgdGhlIGFjdGl2ZSBiYWNrZW5kLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGlzSW1hZ2VWaWV3KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmJhc2VQbG90VHlwZSA9PT0gUGxvdFR5cGUuSU1BR0U7XG4gIH1cblxuICAvKiogSXNvc3VyZmFjZSBiYW5kIGFzIGEgMOKAkzI1NSBzbGlkZXIgcG9zaXRpb24sIG1hcHBlZCBvbnRvIHRoZSB2b2x1bWUncyByZWFsXG4gICAqICBpbnRlbnNpdHkgcmFuZ2UgYnkgdGhlIHJlbmRlcmVyLiBEZWZhdWx0cyB0byB0aGUgZnVsbCByYW5nZS4gKi9cbiAgcHJvdGVjdGVkIGlzb1JhbmdlOiBudW1iZXJbXSA9IFswLCAyNTVdO1xuXG4gIC8qKiBUaGUgc3BhdGlhbC1vbWljcyBkYXRhc2V0IG9uIG9mZmVyIGFuZCB0aGUgZ2F0ZXMgaXQgcHV0cyBvbiB0aGUgc2VsZWN0b3IuICovXG4gIHByb3RlY3RlZCByZWFkb25seSBzcGF0aWFsOiBTcGF0aWFsRGF0YXNldEJpbmRlcjtcbiAgLyoqIFdoZXRoZXIgYSBzcGF0aWFsLW9taWNzIGRhdGFzZXQgaXMgcHVibGlzaGVkIG9uIGBTUEFUSUFMX0RBVEFfUE9SVGAg4oCUIGdhdGVzIHRoZVxuICAgKiAgc3BhdGlhbCBwbG90IHR5cGVzOyB0aGUgdG9vbGJhciBvZmZlcnMgdGhlIHBsb3QgbW9kZXMgZm9yIGFuIGltYWdlLWxlc3Mgb25lIHRvby4gKi9cbiAgcHJvdGVjdGVkIGdldCBoYXNTcGF0aWFsRGF0YXNldCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zcGF0aWFsLmhhc0RhdGFzZXQ7XG4gIH1cblxuICAvKiogS2V5Ym9hcmQsIHdoZWVsIGFuZCBjb250ZXh0LW1lbnUgaGFuZGxpbmc7IGNyZWF0ZWQgb25jZSB0aGUgdmlldyBleGlzdHMuICovXG4gIHByaXZhdGUgc2hvcnRjdXRzPzogVmlld2VyU2hvcnRjdXRzO1xuXG4gIC8qKiBEZWJvdW5jZWQgei1zbGljZSBzY3J1YmJpbmcgKHNlZSBTbGljZVNjcnViYmVyIOKAlCByZWZhY3RvcmluZyBwbGFuIFN0ZXAgNykuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgc2NydWJiZXIgPSBuZXcgU2xpY2VTY3J1YmJlcigoeikgPT4ge1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0WkluZGV4KHopO1xuICAgIC8vIEluIGEgcGVyLXNsaWNlIHotc3RhY2sgc2Vzc2lvbiB0aGUgc3RvcmUgc3dhcHMgdGhlIGxpdmUgcmVnaW9uIHNldCB0byB0aGlzXG4gICAgLy8gc2xpY2UgKHByZXNlcnZpbmcgZWRpdHMgbWFkZSBvbiB0aGUgcHJldmlvdXMgb25lKTsgb3V0c2lkZSBzdGFjayBtb2RlIHRoaXNcbiAgICAvLyBqdXN0IHJlY29yZHMgdGhlIHNsaWNlLCBsZWF2aW5nIHNpbmdsZS1wbGFuZSByZWdpb25zIHVudG91Y2hlZCAoaml0LXVpIzkzKS5cbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldERpc3BsYXlTbGljZSh6KTtcbiAgfSk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgLy8gVGhlIGNvbnN0cnVjdG9yIHBhcmFtZXRlcnMgYmVsb3cgYXJlIHRoZSBpbmplY3Rpb24gcG9pbnRzOyBub25lIGlzIHB1YmxpYyBBUEkuXG4gICAgQEluamVjdChJTUFHRV9TVEFURV9QT1JUKSBwcml2YXRlIHN0YXRlOiBJbWFnZVN0YXRlUG9ydCxcbiAgICBASW5qZWN0KFZJU1VBTElaRVIpIHB1YmxpYyBwbG90U2VydmljZTogSVZpc3VhbGl6ZXIsXG4gICAgcHVibGljIG1lc3NhZ2VTZXJ2aWNlOiBNZXNzYWdlU2VydmljZSxcbiAgICBwcml2YXRlIG5nWm9uZTogTmdab25lLFxuICAgIHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBwcml2YXRlIHNlc3Npb246IFZpc3VhbGl6ZXJTdG9yZSxcbiAgICBwcml2YXRlIHNhbVRvb2w6IFNhbVRvb2xTZXJ2aWNlLFxuICAgIHByaXZhdGUgY2VsbFNlZ21lbnRUb29sOiBDZWxsU2VnbWVudFRvb2xTZXJ2aWNlLFxuICAgIHByaXZhdGUgc2FtUG9pbnRUb29sOiBTYW1Qb2ludFRvb2xTZXJ2aWNlLFxuICAgIHByaXZhdGUgcmVnaW9uT3BzOiBSZWdpb25PcHNTZXJ2aWNlLFxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoVklaX0NPTkZJRykgcHJpdmF0ZSB2aXpDb25maWc/OiBWaXpDb25maWcsXG4gICAgLy8gQSBjb25zdHJ1Y3RvciBwYXJhbWV0ZXIgcmF0aGVyIHRoYW4gYSBmaWVsZCBgaW5qZWN0KClgOiB0aGlzIGNvbXBvbmVudCBpc1xuICAgIC8vIGFsc28gY29uc3RydWN0ZWQgZGlyZWN0bHkgd2l0aCBgbmV3YCBpbiBpdHMgb3duIHNwZWNzLCB3aGljaCBpcyBvdXRzaWRlXG4gICAgLy8gYW4gaW5qZWN0aW9uIGNvbnRleHQgYW5kIHdvdWxkIHRocm93IE5HMDIwMyBvbiBhIGZpZWxkIGluaXRpYWxpemVyLlxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoVE9PTEJBUl9UT09MUykgdG9vbENvbnRyaWJ1dGlvbnM/OiByZWFkb25seSBUb29sYmFyQ29udHJpYnV0aW9uW10sXG4gICAgLy8gT3B0aW9uYWwgbGlrZSB0aGUgcmVzdDogYSBob3N0IHRoYXQgc2hvd3Mgb25seSBpbWFnZXMgbmV2ZXIgcHJvdmlkZXMgaXQsXG4gICAgLy8gYW5kIHRoZSBzcGF0aWFsIHBsb3QgdHlwZXMgc2ltcGx5IHN0YXkgaGlkZGVuLlxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoU1BBVElBTF9EQVRBX1BPUlQpIHByaXZhdGUgc3BhdGlhbERhdGE/OiBTcGF0aWFsRGF0YVBvcnQsXG4gICAgLy8gQ29udHJpYnV0ZWQgcGxvdCBtb2Rlcy4gTGlrZSBUT09MQkFSX1RPT0xTIHRoZSB0b2tlbiBoYXMgbm8gZmFjdG9yeSwgc28gYVxuICAgIC8vIGhvc3QgdGhhdCBwcm92aWRlcyBub25lIGdldHMgbnVsbCBoZXJlIGFuZCB0aGUgc2VsZWN0b3IgaXMgdW5jaGFuZ2VkLlxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoUExPVF9UWVBFX0NPTlRSSUJVVElPTlMpIHBsb3RUeXBlQ29udHJpYnV0aW9ucz86IHJlYWRvbmx5IFBsb3RUeXBlQ29udHJpYnV0aW9uW10sXG4gICAgLy8gUGFyZW50IG9mIGEgY29udHJpYnV0ZWQgcGFuZWwgY29tcG9uZW50J3MgaW5qZWN0b3IuIE9wdGlvbmFsIG9ubHkgc28gdGhlXG4gICAgLy8gc3BlY3MgY2FuIGNvbnN0cnVjdCB0aGlzIGNvbXBvbmVudCB3aXRoIGBuZXdgLlxuICAgIEBPcHRpb25hbCgpIHByaXZhdGUgaW5qZWN0b3I/OiBJbmplY3RvcixcbiAgICAvLyBUaGUgYDx2aXN1YWxpemVyPmAgZWxlbWVudDoga2V5Ym9hcmQgc2hvcnRjdXRzIGFyZSBzY29wZWQgdG8gaXQgKENPUkUtMikuXG4gICAgQE9wdGlvbmFsKCkgcHJpdmF0ZSBob3N0UmVmPzogRWxlbWVudFJlZjxIVE1MRWxlbWVudD4sXG4gICAgLy8gRW5kcyB0aGUgc3Vic2NyaXB0aW9ucyAoYHRha2VVbnRpbERlc3Ryb3llZGApLiBBIHBhcmFtZXRlciwgbGlrZSB0aGUgcmVzdCwgc28gdGhlXG4gICAgLy8gc3BlY3MnIGBuZXdgIGNhbiBwYXNzIG9uZTsgQW5ndWxhciBhbHdheXMgcHJvdmlkZXMgaXQuXG4gICAgcHJpdmF0ZSByZWFkb25seSBkZXN0cm95UmVmOiBEZXN0cm95UmVmID0gdW5kZWZpbmVkIGFzIHVua25vd24gYXMgRGVzdHJveVJlZixcbiAgKSB7XG4gICAgdGhpcy5jb250cmlidXRlZFRvb2xzID0gdmlzaWJsZVRvb2xDb250cmlidXRpb25zKHRvb2xDb250cmlidXRpb25zKTtcbiAgICB0aGlzLnRvb2xQYXJhbXMgPSBuZXcgVG9vbFBhcmFtc01vZGVsKHRoaXMuY29udHJpYnV0ZWRUb29scyk7XG4gICAgdGhpcy5jb250cmlidXRpb25zID0gbmV3IENvbnRyaWJ1dGlvbkhvc3QocGxvdFR5cGVDb250cmlidXRpb25zLCB0b29sQ29udHJpYnV0aW9ucywge1xuICAgICAgdmlzdWFsaXplcjogdGhpcy5wbG90U2VydmljZSxcbiAgICAgIHpvbmU6IHRoaXMubmdab25lLFxuICAgICAgdG9vbHM6IHRoaXMudG9vbHMucGxvdE1vZGVUb29scyxcbiAgICAgIGluamVjdG9yOiB0aGlzLmluamVjdG9yLFxuICAgICAgaW1hZ2VJbmZvJDogKCkgPT4gdGhpcy5zdGF0ZS5nZXRJbWFnZUluZm8kKCksXG4gICAgICBzZWxlY3RlZElkOiAoKSA9PiB0aGlzLnNlbGVjdGVkUGxvdFR5cGVJZCxcbiAgICAgIHJlbmRlcmVkVHlwZTogKCkgPT4gdGhpcy5wbG90VHlwZSxcbiAgICAgIHNlbGVjdEJhc2U6IChiYXNlKSA9PiB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRQbG90VHlwZUlkID0gYmFzZTtcbiAgICAgICAgdGhpcy5wbG90VHlwZSA9IGJhc2U7XG4gICAgICB9LFxuICAgICAgbm90aWZ5OiAobSkgPT4gdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoeyBrZXk6IHRoaXMucmVzdWx0VG9hc3RLZXksIC4uLm0gfSksXG4gICAgICBkZXRlY3RDaGFuZ2VzOiAoKSA9PiB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCksXG4gICAgfSk7XG4gICAgdGhpcy5zcGF0aWFsID0gbmV3IFNwYXRpYWxEYXRhc2V0QmluZGVyKHRoaXMuc3BhdGlhbERhdGEsIHtcbiAgICAgIGdhdGVzQ2hhbmdlZDogKCkgPT4gdGhpcy5jb21wdXRlUGxvdFR5cGVPcHRpb25zKCksXG4gICAgICBzZWxlY3RlZElkOiAoKSA9PiB0aGlzLnNlbGVjdGVkUGxvdFR5cGVJZCxcbiAgICAgIGJhc2VQbG90VHlwZTogKCkgPT4gdGhpcy5iYXNlUGxvdFR5cGUsXG4gICAgICBoYXNJbWFnZTogKCkgPT4gISF0aGlzLmltYWdlSW5mbyxcbiAgICAgIHNlbGVjdFBsb3RUeXBlOiAodHlwZSkgPT4gdGhpcy5vblNlbGVjdFBsb3RUeXBlKHR5cGUpLFxuICAgICAgcmVwbG90OiAoKSA9PiB0aGlzLnJlbG9hZEFuZFBsb3QoKSxcbiAgICAgIHB1Ymxpc2hJbWFnZTogKGluZm8pID0+IHRoaXMuc3RhdGUuc2V0SW1hZ2VJbmZvKGluZm8pLFxuICAgICAgc2V0SW1hZ2VMb2FkaW5nOiAobG9hZGluZykgPT4gdGhpcy5zdGF0ZS5zZXRJbWFnZUxvYWRpbmcobG9hZGluZyksXG4gICAgICBzZXR0bGVkOiAoKSA9PiB7XG4gICAgICAgIHRoaXMucmVjb25jaWxlU2VsZWN0ZWRQbG90VHlwZSgpO1xuICAgICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICAgIH0sXG4gICAgICBkZXRlY3RDaGFuZ2VzOiAoKSA9PiB0aGlzLmNoYW5nZWQoKSxcbiAgICB9KTtcbiAgICB0aGlzLmNvbXB1dGVQbG90VHlwZU9wdGlvbnMoKTtcbiAgfVxuXG4gIC8qKiBGb2xsb3cgdGhlIHNwYXRpYWwtb21pY3MgZGF0YXNldDogYSBkYXRhc2V0IGFwcGVhcmluZywgc3dpdGNoaW5nIG9yIGJlaW5nIGNsZWFyZWRcbiAgICogIHJlLWdhdGVzIHRoZSBzZWxlY3RvciBleGFjdGx5IGFzIHRoZSBpbWFnZSBzdHJlYW0gYW5kIHRoZSB0ZXN0LW1vZGUgdG9nZ2xlIGRvLiAqL1xuICBwcml2YXRlIHdhdGNoU3BhdGlhbERhdGFzZXQoKTogdm9pZCB7XG4gICAgdGhpcy5zcGF0aWFsLmJpbmQodGhpcy5kZXN0cm95ZWQkKTtcbiAgfVxuXG4gIC8qKiBSZWNvbXB1dGUgdGhlIHNlbGVjdG9yJ3MgZW50cmllcyBmb3IgdGhlIGN1cnJlbnQgaW1hZ2UsIGRhdGFzZXQgYW5kIHRlc3QgbW9kZVxuICAgKiAgKHNlZSB7QGxpbmsgY29tcHV0ZVBsb3RUeXBlTWVudX0pLiAqL1xuICBwcml2YXRlIGNvbXB1dGVQbG90VHlwZU9wdGlvbnMoKSB7XG4gICAgY29uc3QgeyBidWlsdEluLCBtZW51IH0gPSBjb21wdXRlUGxvdFR5cGVNZW51KHtcbiAgICAgIGRlc2NyaXB0b3JzOiB0aGlzLnBsb3RTZXJ2aWNlLmdldFBsb3RUeXBlRGVzY3JpcHRvcnMoKSxcbiAgICAgIGNvbnRyaWJ1dGlvbnM6IHRoaXMucGxvdE1vZGVzLmRlc2NyaXB0b3JzKCksXG4gICAgICBjYXBzOiB0aGlzLnBsb3RTZXJ2aWNlLmNhcGFiaWxpdGllcyxcbiAgICAgIGltYWdlSW5mbzogdGhpcy5pbWFnZUluZm8sXG4gICAgICBzcGF0aWFsOiB0aGlzLnNwYXRpYWwsXG4gICAgICB0ZXN0TW9kZTogdGhpcy50ZXN0TW9kZSxcbiAgICB9KTtcbiAgICB0aGlzLnBsb3RUeXBlT3B0aW9ucyA9IGJ1aWx0SW47XG4gICAgdGhpcy5wbG90VHlwZU1lbnUgPSBtZW51O1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIC8vIFRoZSBjb25zdHJ1Y3RvciBjb21wdXRlcyB0aGUgb3B0aW9ucyB3aXRoIHRlc3RNb2RlIHN0aWxsIGF0IGl0cyBkZWZhdWx0O1xuICAgIC8vIHJlY29tcHV0ZSBvbmNlIHRoZSBob3N0IGJpbmRzIGl0IChhbmQgb24gYW55IGxhdGVyIGNoYW5nZSkgc28gdGhlIHNlbGVjdG9yXG4gICAgLy8gcmVmbGVjdHMgdGVzdCBtb2RlIGltbWVkaWF0ZWx5LCB3aXRob3V0IHdhaXRpbmcgZm9yIGFuIGltYWdlIHRvIChyZSlsb2FkLlxuICAgIGlmIChjaGFuZ2VzWyd0ZXN0TW9kZSddKSB7XG4gICAgICB0aGlzLmNvbXB1dGVQbG90VHlwZU9wdGlvbnMoKTtcbiAgICAgIC8vIElmIHRlc3QgbW9kZSBpcyB0dXJuZWQgb2ZmIHdoaWxlIGEgdGVzdC1vbmx5IHR5cGUgKGUuZy4gTkFQQVJJX0lNQUdFKSBpc1xuICAgICAgLy8gYWN0aXZlLCB0aGF0IHR5cGUgaXMgbm8gbG9uZ2VyIG9mZmVyZWQg4oCUIGZhbGwgYmFjayB0byBJbWFnZS5cbiAgICAgIHRoaXMucmVjb25jaWxlU2VsZWN0ZWRQbG90VHlwZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgaG9zdCBwdWJsaXNoZWQgTk8gaW1hZ2Ug4oCUIGEgc3BhdGlhbCBkYXRhc2V0IHRoYXQgYnJpbmdzIG5vbmUgZG9lcyB0aGlzLlxuICAgKlxuICAgKiBXaXRob3V0IGhhbmRsaW5nIHRoZSBlbXB0eSBlbWlzc2lvbiwgYGltYWdlSW5mb2Aga2VlcHMgdGhlIExBU1QgaW1hZ2UncyBtZXRhZGF0YTogdGhlXG4gICAqIHNlbGVjdG9yIGdvZXMgb24gb2ZmZXJpbmcgcGl4ZWwgbW9kZXMgZm9yIHBpeGVscyB0aGF0IGFyZSBnb25lLCBhbmQgZXZlcnlcbiAgICogYGlzU3RhY2tgL2Bpc0dyYXlzY2FsZWAgZGVjaXNpb24gaXMgbWFkZSBhZ2FpbnN0IGEgZmlsZSB0aGF0IGlzIG5vIGxvbmdlciBsb2FkZWQuXG4gICAqL1xuICBwcml2YXRlIG9uSW1hZ2VDbGVhcmVkKCk6IHZvaWQge1xuICAgIC8vIFRoZSBpbWFnZSBhIGNvbnRyaWJ1dGVkIG1vZGUgd2FzIGRyYXdpbmcgb3ZlciBpcyBnb25lLiBBbiBvcGVuIGRpYWxvZ1xuICAgIC8vIHRvb2wgc3RheXMgb3BlbiBhbmQgcmVzdGFydHMgb25jZSB0aGUgbmV4dCBpbWFnZSBoYXMgcGxvdHRlZC5cbiAgICB0aGlzLmNvbnRyaWJ1dGlvbnMuZW5kU2Vzc2lvbnMoKTtcbiAgICB0aGlzLmltYWdlSW5mbyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmxvYWRlZEZpbGVOYW1lID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuY29tcHV0ZVBsb3RUeXBlT3B0aW9ucygpO1xuICAgIC8vIERlbGliZXJhdGVseSBOT1QgcmVjb25jaWxpbmcgdGhlIHNlbGVjdGVkIHR5cGUgaGVyZS4gUmVjb25jaWxpbmcgY2FsbHNcbiAgICAvLyBgc2V0UGxvdFR5cGVgLCB3aGljaCBkcml2ZXMgYSByZS1wbG90IOKAlCBhbmQgdGhlcmUgaXMgbm90aGluZyB0byBwbG90LCBzbyB0aGVcbiAgICAvLyBQbG90bHkgYmFja2VuZCByZWFkIGl0cyBvd24gbm93LXVuc2V0IGBpbWFnZUluZm9gIGFuZCB0aHJld1xuICAgIC8vIChcImNhbid0IGFjY2VzcyBwcm9wZXJ0eSBpc0dyYXlzY2FsZVwiKSwgYWJvcnRpbmcgdGhlIGxvYWQgd2l0aCBubyBvYnNlcnZhdGlvbnNcbiAgICAvLyBkcmF3bi4gSWdub3JpbmcgdGhlIGVtcHR5IGVtaXNzaW9uIGVudGlyZWx5IGlzIHdoYXQgdXNlZCB0byBhdm9pZCB0aGF0LlxuICAgIC8vXG4gICAgLy8gTm90aGluZyBpcyBsZWZ0IHN0cmFuZGVkOiBhbiBpbWFnZSBpcyBjbGVhcmVkIGJlY2F1c2UgYSBzcGF0aWFsIGRhdGFzZXQgdGhhdFxuICAgIC8vIGJyaW5ncyBub25lIGlzIGJlaW5nIG9wZW5lZCwgYW5kIHRoYXQgZGF0YXNldCdzIG93biBzdWJzY3JpcHRpb24gc2VsZWN0cyB0aGVcbiAgICAvLyBtb2RlIGl0cyBjb29yZGluYXRlcyBzdXBwb3J0IGEgbW9tZW50IGxhdGVyLlxuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9XG5cbiAgLyoqIElmIHRoZSBhY3RpdmUgcGxvdCB0eXBlIGlzIG5vIGxvbmdlciBpbiB0aGUgb2ZmZXJlZCBvcHRpb25zIChlLmcuIHRlc3QgbW9kZVxuICAgKiAgdHVybmVkIG9mZiB3aGlsZSBhIHRlc3Qtb25seSB0eXBlIHdhcyBhY3RpdmUsIG9yIGEgc2NhbGFyIHR5cGUgY2FycmllZCBvbnRvXG4gICAqICBhbiBSR0IgaW1hZ2UpLCBmYWxsIGJhY2sgdG8gdGhlIGRlZmF1bHQgMkQgSW1hZ2Ugdmlldy4gKi9cbiAgcHJpdmF0ZSByZWNvbmNpbGVTZWxlY3RlZFBsb3RUeXBlKCk6IHZvaWQge1xuICAgIGNvbnN0IGZhbGxiYWNrID0gcmVjb25jaWxlUGxvdFR5cGUodGhpcy5wbG90VHlwZU1lbnUsIHRoaXMuc2VsZWN0ZWRQbG90VHlwZUlkKTtcbiAgICBpZiAoIWZhbGxiYWNrKSByZXR1cm47XG4gICAgLy8gTGVhdmluZyBhIGNvbnRyaWJ1dGVkIG1vZGUgKGl0cyBnYXRlcyBzdG9wcGVkIHBhc3NpbmcsIG9yIGl0cyBwcm92aWRlciBpc1xuICAgIC8vIGdvbmUpOiBpdHMgc2Vzc2lvbiBlbmRzIGJlZm9yZSBhbnl0aGluZyBlbHNlIGRyYXdzLlxuICAgIHRoaXMucGxvdE1vZGVzLmRlYWN0aXZhdGUoKTtcbiAgICBjb25zdCBiYXNlID0gdGhpcy5wbG90TW9kZXMuYmFzZVR5cGVPZihmYWxsYmFjayk7XG4gICAgaWYgKGJhc2UgIT09IFBsb3RUeXBlLklNQUdFKSB0aGlzLmNsb3NlRGlhbG9nVG9vbCgpO1xuICAgIHRoaXMuc2VsZWN0ZWRQbG90VHlwZUlkID0gZmFsbGJhY2s7XG4gICAgdGhpcy5wbG90VHlwZSA9IGJhc2U7XG4gICAgdGhpcy5pc0hlYXRtYXAgPSBiYXNlID09PSBQbG90VHlwZS5JTUFHRTtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldFBsb3RUeXBlKGJhc2UpO1xuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgLy8gSm9pbiB0aGUgbGl2ZSBzZXQ7IHRoZSBvbGRlc3QgbWVtYmVyIHJlbmRlcnMgdGhlIHNoYXJlZCBub3RpY2Ugb3V0bGV0cy5cbiAgICBWaXN1YWxpemVyQ29tcG9uZW50LmxpdmVJbnN0YW5jZXMuYWRkKHRoaXMpO1xuICAgIHRoaXMuc3RhdGUuc2V0RGlhZ3JhbSh0aGlzLmhvc3RIYW5kbGUpO1xuICAgIHRoaXMud2F0Y2hTcGF0aWFsRGF0YXNldCgpO1xuICAgIC8vIE9TRCBhbmQgbmFwYXJpLWpzIGVtaXQgdGhpcyBmcm9tIHRoZWlyIG93biBcImZpdCB0byB2aWV3XCI6IGRpc2FybSB0aGUgdG9vbCBvblxuICAgIC8vIHRoZSBiYWNrZW5kIHRvbywgbm90IG9ubHkgdGhlIHRvb2xiYXIncyBoaWdobGlnaHQuXG4gICAgdGhpcy5wbG90U2VydmljZVxuICAgICAgLmdldEF1dG9zY2FsZUV2ZW50KClcbiAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLmRlc3Ryb3lSZWYpKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB0aGlzLnRvb2xzLmFwcGx5KG51bGwpKTtcbiAgICAvLyBMb2FkaW5nL292ZXJsYXkgVUkgbWlycm9ycyAoc2lnbmFsczogdGhleSByZS1yZW5kZXIgdGhlIHZpZXcgdGhlbXNlbHZlcykuXG4gICAgdGhpcy5taXJyb3IodGhpcy5zdGF0ZS5pc0ltYWdlTG9hZGluZyQoKSwgKHYpID0+IHRoaXMuaW1nTG9hZGluZy5zZXQodikpO1xuICAgIHRoaXMubWlycm9yKHRoaXMucGxvdFNlcnZpY2UuZ2V0U3RhY2tMb2FkaW5nUHJvZ3Jlc3MoKSwgKHYpID0+IHRoaXMubG9hZGluZ1BlcmNlbnRhZ2Uuc2V0KHYpKTtcbiAgICB0aGlzLm1pcnJvcih0aGlzLnBsb3RTZXJ2aWNlLmlzU3RhY2tMb2FkaW5nKCksICh2KSA9PiB0aGlzLnN0YWNrTG9hZGluZy5zZXQodikpO1xuICAgIHRoaXMubWlycm9yKHRoaXMuc3RhdGUuZ2V0SW1hZ2VMb2FkaW5nTWVzc2FnZSQoKSwgKHYpID0+IHRoaXMubG9hZGluZ01lc3NhZ2Uuc2V0KHYpKTtcbiAgICB0aGlzLm1pcnJvcih0aGlzLnN0YXRlLmdldENhY2hlUHJvZ3Jlc3MkKCksICh2KSA9PiB0aGlzLmNhY2hlUHJvZ3Jlc3Muc2V0KHYpKTtcbiAgICB0aGlzLm1pcnJvcih0aGlzLnN0YXRlLmlzWm9vbSQoKSwgKHYpID0+IHRoaXMuem9vbS5zZXQodikpO1xuICAgIHRoaXMubWlycm9yKHRoaXMuc3RhdGUuZ2V0RmlsZW5hbWUkKCksICh2KSA9PiB7XG4gICAgICBpZiAodikgdGhpcy5maWxlTmFtZSA9IHY7XG4gICAgfSk7XG4gICAgdGhpcy5yZWdpb25BY3Rpb25zLmJpbmQodGhpcy5kZXN0cm95ZWQkLCAoKSA9PiB0aGlzLmNoYW5nZWQoKSk7XG4gICAgdGhpcy5zZWdtZW50YXRpb24uYmluZFBvaW50VG9vbCh0aGlzLnNhbVBvaW50VG9vbCwgdGhpcy5kZXN0cm95ZWQkKTtcbiAgICB0aGlzLm1pcnJvcih0aGlzLnN0YXRlLmdldFBhbmVsV2lkdGgkKCksICgpID0+IHtcbiAgICAgIHRoaXMucGxvdFNlcnZpY2UucmVsYXlvdXQoKTtcbiAgICAgIC8vIFRoZSBpbnRlbnNpdHkgaW5zZXQgaXMgYSBzZXBhcmF0ZSBjaGFydCBpbiBhIGZsb2F0aW5nIHBhbmVsOyByZWZsb3cgaXQgdG9vLlxuICAgICAgdGhpcy5pbnNldD8ucmVmbG93KCk7XG4gICAgfSk7XG4gICAgdGhpcy5zdGF0ZVxuICAgICAgLmdldEltYWdlSW5mbyQoKVxuICAgICAgLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuZGVzdHJveVJlZikpXG4gICAgICAuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dDogKGltZ0luZm8pID0+IHtcbiAgICAgICAgICBpZiAoIWltZ0luZm8pIHtcbiAgICAgICAgICAgIHRoaXMub25JbWFnZUNsZWFyZWQoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gVGhlIHNlbGVjdG9yLCB0aGUgc3RhY2sgY29udHJvbHMgYW5kIHRoZSBpbnNldCBhbGwgZm9sbG93IHRoZSBpbWFnZS5cbiAgICAgICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICAgICAgICBpZiAoaW1nSW5mbykge1xuICAgICAgICAgICAgdGhpcy5pbWFnZUluZm8gPSBpbWdJbmZvO1xuICAgICAgICAgICAgLy8gU3RhY2stb25seSBwbG90IHR5cGVzIChpc29zdXJmYWNlLCBzY2F0dGVyM2QpIGRlcGVuZCBvbiB3aGV0aGVyIHRoaXNcbiAgICAgICAgICAgIC8vIGZpbGUgaXMgYSBzdGFjayDigJQgcmVjb21wdXRlIHRoZSBzZWxlY3RvciBvcHRpb25zLlxuICAgICAgICAgICAgdGhpcy5jb21wdXRlUGxvdFR5cGVPcHRpb25zKCk7XG4gICAgICAgICAgICAvLyBJZiB0aGUgYWN0aXZlIHBsb3QgdHlwZSBpc24ndCB2YWxpZCBmb3IgdGhpcyBpbWFnZSAoZS5nLiBhIHNjYWxhclxuICAgICAgICAgICAgLy8gdHlwZSBsaWtlIENvbnRvdXIgY2FycmllZCBvdmVyIHRvIGFuIFJHQiBpbWFnZSksIGZhbGwgYmFjayB0byBJbWFnZS5cbiAgICAgICAgICAgIHRoaXMucmVjb25jaWxlU2VsZWN0ZWRQbG90VHlwZSgpO1xuICAgICAgICAgICAgLy8gUmVhZCBmcm9tIGBpbWdJbmZvYCwgdGhlIHZhbHVlIHRoaXMgZW1pc3Npb24gY2FycmllZCwgcmF0aGVyIHRoYW4gZnJvbSB0aGVcbiAgICAgICAgICAgIC8vIGZpZWxkLiBIYW5kbGluZyB0aGUgZW1wdHkgZW1pc3Npb24gbWVhbnMgdGhlIGZpZWxkIENBTiBiZSBudWxsZWQgcGFydC13YXlcbiAgICAgICAgICAgIC8vIHRocm91Z2ggdGhpcyBicmFuY2g6IGByZWNvbmNpbGVTZWxlY3RlZFBsb3RUeXBlYCBtYXkgY2FsbCBgc2V0UGxvdFR5cGVgLFxuICAgICAgICAgICAgLy8gd2hpY2ggY2FuIG1ha2UgdGhlIGhvc3QgcHVibGlzaCBhIG5ldyBpbWFnZSBzdGF0ZSwgcmUtZW50ZXJpbmcgdGhpcyB2ZXJ5XG4gICAgICAgICAgICAvLyBzdWJzY3JpcHRpb24uIFJlYWRpbmcgdGhlIGZpZWxkIHRoZW4gdGhyZXcgb24gYGlzR3JheXNjYWxlYCBhbmQgYWJvcnRlZCB0aGVcbiAgICAgICAgICAgIC8vIGhhbmRsZXIsIHNvIHRoZSBvYnNlcnZhdGlvbnMgd2VyZSBuZXZlciBkcmF3bi5cbiAgICAgICAgICAgIHRoaXMuaXNHcmF5c2NhbGVFdmVudC5lbWl0KGltZ0luZm8uaXNHcmF5c2NhbGUpO1xuICAgICAgICAgICAgdGhpcy5pc1N0YWNrRXZlbnQuZW1pdChpbWdJbmZvLmlzU3RhY2spO1xuICAgICAgICAgICAgLy8gUmVzZXQgdG8gdGhlIGRlZmF1bHQgMkQgSW1hZ2UgdmlldyB3aGVuIGEgZGlmZmVyZW50IGltYWdlIGlzXG4gICAgICAgICAgICAvLyBzZWxlY3RlZCB3aGlsZSBhIDNEIHR5cGUgaXMgYWN0aXZlLlxuICAgICAgICAgICAgaWYgKCF0aGlzLmlzSGVhdG1hcCAmJiBpbWdJbmZvLmZpbGVOYW1lICE9PSB0aGlzLmxvYWRlZEZpbGVOYW1lKSB7XG4gICAgICAgICAgICAgIHRoaXMuaXNIZWF0bWFwID0gdHJ1ZTtcbiAgICAgICAgICAgICAgdGhpcy5wbG90VHlwZSA9IFBsb3RUeXBlLklNQUdFO1xuICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkUGxvdFR5cGVJZCA9IFBsb3RUeXBlLklNQUdFO1xuICAgICAgICAgICAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldFBsb3RUeXBlKHRoaXMucGxvdFR5cGUpO1xuICAgICAgICAgICAgICB0aGlzLmFjdGl2ZVN1cmZhY2UzZE1vZGUgPSAndHVybnRhYmxlJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMubG9hZGVkRmlsZU5hbWUgPSBpbWdJbmZvLmZpbGVOYW1lO1xuICAgICAgICAgICAgdGhpcy5wbG90U2VydmljZS5zZXRJbWFnZU1ldGEoaW1nSW5mby5pbWFnZU1ldGEsIGltZ0luZm8uZmlsZU5hbWUpO1xuICAgICAgICAgICAgLy8gQSBuZXdlciBpbWFnZSBhbHdheXMgcHJlZW1wdHMgYW4gaW4tZmxpZ2h0IHJlbmRlciAoc2VlIEltYWdlUmVuZGVyU2Vzc2lvbikuXG4gICAgICAgICAgICBpZiAoaW1nSW5mby51cmxzKSB0aGlzLnJlbmRlci5yZW5kZXIoaW1nSW5mbyk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKGVycjogdW5rbm93bikgPT4ge1xuICAgICAgICAgIGNvbnN0IG1zZyA9IGVycm9yTWVzc2FnZShlcnIpO1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIG9jY3VyZWQgd2hlbiBnZXR0aW5nIGltYWdlIGluZm8nLCBlcnIpO1xuICAgICAgICAgIHRoaXMubWVzc2FnZVNlcnZpY2UuYWRkKHtcbiAgICAgICAgICAgIGtleTogdGhpcy52aXpBbGVydFRvYXN0S2V5LFxuICAgICAgICAgICAgc3RpY2t5OiB0cnVlLFxuICAgICAgICAgICAgc2V2ZXJpdHk6ICdlcnJvcicsXG4gICAgICAgICAgICBzdW1tYXJ5OiAnQW4gZXJyb3Igb2NjdXJlZCcsXG4gICAgICAgICAgICBkZXRhaWw6IGBUaGUgZm9sbG93aW5nIGVycm9yIG9jY3VyZWQgd2hpbGUgZ2V0dGluZyBpbWFnZSBpbmZvOiAke21zZ30uXG4gICAgICAgICAgICAgICAgICAgUGxlYXNlIHRyeSB0byBvcGVuIHRoZSBpbWFnZSBhZ2FpbiB0aHJvdWdoIHRoZSBmaWxlIG5hdmlnYXRvci5gLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHRoaXMuc3RhY2tMb2FkaW5nLnNldChmYWxzZSk7XG4gICAgICAgICAgdGhpcy5zdGF0ZS5zZXRJbWFnZUxvYWRpbmcoZmFsc2UpO1xuICAgICAgICAgIHRoaXMucmVuZGVyLnJ1bm5pbmcgPSBmYWxzZTtcbiAgICAgICAgICB0aGlzLnBsb3RTZXJ2aWNlLnJlc2V0KCk7XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGb2xsb3cgYHNvdXJjZWAgdW50aWwgZGVzdHJveS4gSG9zdCBzdHJlYW1zIGNhbiBlbWl0IG91dHNpZGUgdGhlIEFuZ3VsYXIgem9uZSAoYVxuICAgKiBzZXJ2ZXJsZXNzIGhvc3QgY2xlYXJzIGl0cyBsb2FkaW5nIGZsYWcgZnJvbSBhbiBpbWFnZSBkZWNvZGUgb3IgYW4gT3BlblNlYWRyYWdvblxuICAgKiBjYWxsYmFjayk7IHNldHRpbmcgYSBzaWduYWwgdGhlcmUgbWFya3MgdGhpcyBPblB1c2ggdmlldyBidXQgc2NoZWR1bGVzIG5vIGNoYW5nZVxuICAgKiBkZXRlY3Rpb24sIHNvIHRoZSB1cGRhdGUgaXMgYXBwbGllZCBpbnNpZGUgdGhlIHpvbmUsIGFzIHtAbGluayBjaGFuZ2VkfSBkb2VzLlxuICAgKi9cbiAgcHJpdmF0ZSBtaXJyb3I8VD4oc291cmNlOiBPYnNlcnZhYmxlPFQ+LCBhcHBseTogKHZhbHVlOiBUKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgc291cmNlLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuZGVzdHJveVJlZikpLnN1YnNjcmliZSgodmFsdWUpID0+IHtcbiAgICAgIGlmIChOZ1pvbmUuaXNJbkFuZ3VsYXJab25lKCkpIGFwcGx5KHZhbHVlKTtcbiAgICAgIGVsc2UgdGhpcy5uZ1pvbmUucnVuKCgpID0+IGFwcGx5KHZhbHVlKSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogU3RhdGUgdGhpcyB2aWV3IHNob3dzIGNoYW5nZWQgb3V0c2lkZSBvbmUgb2YgaXRzIHRlbXBsYXRlIGV2ZW50cyAoYSBzdHJlYW0sIGFcbiAgICogcmVzb2x2ZWQgcHJvbWlzZSwgYSBob3N0IGNhbGwpOiBtYXJrIHRoZSBPblB1c2ggdmlldyBmb3IgY2hlY2ssIHJlLWVudGVyaW5nIHRoZVxuICAgKiB6b25lIHdoZW4gaXQgY2hhbmdlZCBvdXRzaWRlIGl0IHNvIGEgY2hhbmdlLWRldGVjdGlvbiBwYXNzIGZvbGxvd3MuXG4gICAqL1xuICBwcml2YXRlIGNoYW5nZWQoKTogdm9pZCB7XG4gICAgaWYgKE5nWm9uZS5pc0luQW5ndWxhclpvbmUoKSkgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgZWxzZSB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy5jZHIubWFya0ZvckNoZWNrKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIExheSBhIG5ldyBpbWFnZSBvdXQgb25jZSB0aGUgb2xkIHZpZXcgaXMgZ29uZTogdGhlIHN0YWNrIGZsYWcsIHRoZSBzbGljZSBib3VuZHMgKG9uZVxuICAgKiB1cmwgcGVyIHNsaWNlLCBzbyB0aGUgbGFzdCBpbmRleCBpcyBsZW5ndGgtMSksIGFuZCB0aGUgb25lLXNob3QgYGluaXRpYWxaSW5kZXhgIGhpbnRcbiAgICogKGUuZy4gdGhlIGZpbGUgdGhlIHVzZXIgY2xpY2tlZCB3aXRoaW4gYSBudW1iZXJlZCBzZXJpZXMpLiBUaGUgaGludCBpcyBjb25zdW1lZCBzb1xuICAgKiByZS1kZWxpdmVyaW5nIHRoZSBzYW1lIGluZm8gKGEgcGxvdC10eXBlIHN3aXRjaCwgcmVsb2FkQW5kUGxvdCkgZG9lcyBub3QgcmVzZXQgdGhlXG4gICAqIHVzZXIncyBzY3J1YjsgdGhlIGhvc3QncyBvYmplY3QgaXMgbmV2ZXIgd3JpdHRlbiB0byAoYSBob3N0IHN0b3JlIG1heSBmcmVlemUgaXQpIOKAlFxuICAgKiB0aGUgY29tcG9uZW50IGtlZXBzIGEgY29weSB3aXRob3V0IHRoZSBoaW50LCBhbmQgcmVtZW1iZXJzIHRoZSBob3N0IG9iamVjdC5cbiAgICovXG4gIHByaXZhdGUgbGF5T3V0U2xpY2VzKGluZm86IElJbWFnZUluZm8pOiB2b2lkIHtcbiAgICB0aGlzLnN0YWNrTG9hZGluZy5zZXQoaW5mby5pc1N0YWNrICYmIGluZm8uc2hvd1N0YWNrKTtcbiAgICB0aGlzLm1heEluZGV4ID0gaW5mby51cmxzLmxlbmd0aCA+IDEgPyBpbmZvLnVybHMubGVuZ3RoIC0gMSA6IDA7XG4gICAgaWYgKGluZm8uaW5pdGlhbFpJbmRleCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoIXRoaXMuY29uc3VtZWRTbGljZUhpbnRzLmhhcyhpbmZvKSkge1xuICAgICAgICB0aGlzLmNvbnN1bWVkU2xpY2VIaW50cy5hZGQoaW5mbyk7XG4gICAgICAgIHRoaXMuekluZGV4ID0gaW5mby5pbml0aWFsWkluZGV4O1xuICAgICAgfVxuICAgICAgdGhpcy5pbWFnZUluZm8gPSB7IC4uLmluZm8sIGluaXRpYWxaSW5kZXg6IHVuZGVmaW5lZCB9O1xuICAgIH1cbiAgICB0aGlzLnVwZGF0ZVpJbmRleCgpO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIC8vIFdpbmRvdyBsaXN0ZW5lcnMgYXJlIHJlZ2lzdGVyZWQgT1VUU0lERSB0aGUgQW5ndWxhciB6b25lOiB6b25lLXBhdGNoZWQsIGV2ZXJ5XG4gICAgLy8gbW91c2Vtb3ZlIGFueXdoZXJlIGluIHRoZSBob3N0IGFwcCByYW4gYXBwLXdpZGUgY2hhbmdlIGRldGVjdGlvbi4gRWFjaCBoYW5kbGVyXG4gICAgLy8gcmUtZW50ZXJzIHRoZSB6b25lIChuZ1pvbmUucnVuKSBvbmx5IHdoZW4gaXQgYWN0dWFsbHkgY2hhbmdlcyB2aWV3IHN0YXRlLlxuICAgIHRoaXMuc2hvcnRjdXRzID0gbmV3IFZpZXdlclNob3J0Y3V0cyh0aGlzLnNob3J0Y3V0SG9zdCgpLCB0aGlzLm5nWm9uZSk7XG4gICAgdGhpcy5zaG9ydGN1dHMuYXR0YWNoKCk7XG4gICAgdGhpcy5vblZpZXdSZWFkeSgpO1xuICB9XG5cbiAgLyoqIFRoZSBwbG90IGRpdiBleGlzdHMgbm93OiBydW4gYW4gaW1hZ2UtbGVzcyBkcmF3IHRoYXQgYXJyaXZlZCBiZWZvcmUgaXQgZGlkLiAqL1xuICBwcml2YXRlIG9uVmlld1JlYWR5KCk6IHZvaWQge1xuICAgIHRoaXMucmVuZGVyLnZpZXdJc1JlYWR5KHRoaXMuc3BhdGlhbC5kYXRhc2V0LCAhIXRoaXMuaW1hZ2VJbmZvKTtcbiAgfVxuXG4gIC8qKiBXaGF0IHRoZSBrZXlib2FyZCwgd2hlZWwgYW5kIGNvbnRleHQtbWVudSBzaG9ydGN1dHMgYWN0IG9uLiBUaGVpciBsaXN0ZW5lcnMgbGl2ZVxuICAgKiAgb3V0c2lkZSB0aGlzIHZpZXcsIHNvIGV2ZXJ5IGFjdGlvbiB0aGF0IGNoYW5nZXMgd2hhdCBpdCBzaG93cyBtYXJrcyBpdCBmb3IgY2hlY2suICovXG4gIHByaXZhdGUgc2hvcnRjdXRIb3N0KCk6IFNob3J0Y3V0SG9zdCB7XG4gICAgY29uc3QgbWFya2VkID1cbiAgICAgIDxBIGV4dGVuZHMgdW5rbm93bltdPihhY3Q6ICguLi5hcmdzOiBBKSA9PiB2b2lkKSA9PlxuICAgICAgKC4uLmFyZ3M6IEEpOiB2b2lkID0+IHtcbiAgICAgICAgYWN0KC4uLmFyZ3MpO1xuICAgICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICAgIH07XG4gICAgcmV0dXJuIHtcbiAgICAgIHBsb3REaXZOYW1lOiB0aGlzLnBsb3REaXZOYW1lLFxuICAgICAgaG9zdEVsZW1lbnQ6IHRoaXMuaG9zdFJlZj8ubmF0aXZlRWxlbWVudCA/PyBudWxsLFxuICAgICAgYWN0aXZlRHJhZ01vZGU6ICgpID0+IHRoaXMuYWN0aXZlRHJhZ01vZGUsXG4gICAgICBjYW5TdGVwU2xpY2U6ICgpID0+ICEhdGhpcy5pbWFnZUluZm8/LmlzU3RhY2sgJiYgdGhpcy5pc0ltYWdlVmlldyxcbiAgICAgIHdoZWVsWm9vbXM6ICgpID0+ICFyZW5kZXJlck93bnNXaGVlbCh0aGlzLmJhc2VQbG90VHlwZSkgJiYgdGhpcy5pc0hlYXRtYXAsXG4gICAgICBzdGVwU2xpY2U6IG1hcmtlZCgoZGVsdGE6IG51bWJlcikgPT4gdGhpcy5zdGVwU2xpY2UoZGVsdGEpKSxcbiAgICAgIHJlc29sdmVTYW1Qcm9tcHQ6IG1hcmtlZCgoY29tbWl0OiBib29sZWFuKSA9PiB7XG4gICAgICAgIGlmIChjb21taXQpIHRoaXMucGxvdFNlcnZpY2UuY29tbWl0U2FtUG9pbnRzKCk7XG4gICAgICAgIGVsc2UgdGhpcy5wbG90U2VydmljZS5jbGVhclNhbVBvaW50cygpO1xuICAgICAgICB0aGlzLnNlZ21lbnRhdGlvbi5oaWRlKCk7IC8vIHByb21wdCByZXNvbHZlZCDihpIgZGlzbWlzcyB0aGUgc3RhdHVzIHRvYXN0XG4gICAgICB9KSxcbiAgICAgIHVuZG86IG1hcmtlZCgoKSA9PiB0aGlzLnVuZG9SZWdpb24oKSksXG4gICAgICByZWRvOiBtYXJrZWQoKCkgPT4gdGhpcy5yZWRvUmVnaW9uKCkpLFxuICAgICAgZGVsZXRlUmVnaW9uOiBtYXJrZWQoKCkgPT4gdGhpcy5kZWxldGVSZWdpb24oKSksXG4gICAgICB6b29tSW46IG1hcmtlZCgoKSA9PiB0aGlzLnpvb21JbigpKSxcbiAgICAgIHpvb21PdXQ6IG1hcmtlZCgoKSA9PiB0aGlzLnpvb21PdXQoKSksXG4gICAgICB0b2dnbGVEcmFnTW9kZTogbWFya2VkKChtb2RlOiBzdHJpbmcpID0+IHRoaXMudG9nZ2xlRHJhZ01vZGUobW9kZSkpLFxuICAgICAgb3BlbkNvbnRleHRNZW51OiAoZXZlbnQpID0+IHtcbiAgICAgICAgdGhpcy5jb250ZXh0TWVudUl0ZW1zID0gdGhpcy5idWlsZENvbnRleHRNZW51SXRlbXMoKTtcbiAgICAgICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgICB0aGlzLmNvbnRleHRNZW51LnNob3coZXZlbnQpO1xuICAgICAgfSxcbiAgICB9O1xuICB9XG5cbiAgLyoqIFNuYXAgdGhlIGZsb2F0aW5nIHRvb2xiYXIgYmFjayB0byBpdHMgZG9ja2VkIHBvc2l0aW9uIGFjcm9zcyB0aGUgdG9wLiAqL1xuICBwcm90ZWN0ZWQgZG9ja1Rvb2xiYXIoKSB7XG4gICAgdGhpcy50b29sYmFyRmxvYXRpbmcgPSBmYWxzZTtcbiAgfVxuXG4gIC8qKiBUb29sYmFyIFwiSW50ZW5zaXR5XCIgZ3JvdXA6IGFkZCBhbm90aGVyIGxpbmUgUk9JIChuZXh0IGJyaWdodCBjb2xvdXIpLiAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgYWRkUHJvZmlsZUxpbmUoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcmVnaW9uID0gYXdhaXQgdGhpcy5pbnNldD8uYWRkUHJvZmlsZUxpbmUoKTtcbiAgICAvLyBPU0Qgb25seSBkcmF3cyBhIHNlbGVjdGVkIHJlZ2lvbidzIGhhbmRsZXMgaW4gYW4gZWRpdCBtb2RlLCBzbyBhIGxpbmUgaW5cbiAgICAvLyAnbm9uZScgbW9kZSBsb29rcyB1bnNlbGVjdGVkLiBTd2l0Y2ggdG8gJ3NlbGVjdCcgc28gdGhlIG5ldyBsaW5lIHNob3dzIGl0c1xuICAgIC8vIGVuZHBvaW50IGhhbmRsZXMgYW5kIGNhbiBiZSBkcmFnZ2VkL2RlbGV0ZWQgcmlnaHQgYXdheS5cbiAgICBpZiAocmVnaW9uICYmIHRoaXMuaXNJbWFnZVZpZXcgJiYgdGhpcy5hY3RpdmVEcmFnTW9kZSAhPT0gJ3NlbGVjdCcpIHRoaXMudG9nZ2xlRHJhZ01vZGUoJ3NlbGVjdCcpO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgLy8gQSBjb250cmlidXRlZCBtb2RlJ3Mgc2Vzc2lvbiBlbmRzIGZpcnN0LCB3aGlsZSB0aGUgdmlld2VyIGl0IGRyZXcgb3ZlclxuICAgIC8vIHN0aWxsIGV4aXN0cy4gVGhlIHBhbmVsIGdvZXMgd2l0aCB0aGlzIHZpZXcsIHNvIG5vIGNoYW5nZSBkZXRlY3Rpb24uXG4gICAgdGhpcy5jb250cmlidXRpb25zLmRlc3Ryb3koKTtcbiAgICAvLyBMZWF2ZSB0aGUgbGl2ZSBzZXQgc28gdGhlIG5leHQtb2xkZXN0IHZpc3VhbGl6ZXIgcGlja3MgdXAgdGhlIG91dGxldHMg4oCUIG9uIGl0c1xuICAgIC8vIG5leHQgY2hlY2ssIHdoaWNoIGFuIE9uUHVzaCBzaWJsaW5nIG5lZWRzIGFza2luZyBmb3IuXG4gICAgVmlzdWFsaXplckNvbXBvbmVudC5saXZlSW5zdGFuY2VzLmRlbGV0ZSh0aGlzKTtcbiAgICBmb3IgKGNvbnN0IG90aGVyIG9mIFZpc3VhbGl6ZXJDb21wb25lbnQubGl2ZUluc3RhbmNlcykgb3RoZXIuY2hhbmdlZCgpO1xuICAgIHRoaXMuc3RhdGUuc2V0RGlhZ3JhbShudWxsKTtcbiAgICB0aGlzLnJlbmRlci5jYW5jZWwoKTtcbiAgICB0aGlzLnNwYXRpYWwuZGlzcG9zZSgpO1xuICAgIHRoaXMuc2NydWJiZXIuY2FuY2VsKCk7XG4gICAgdGhpcy5zaG9ydGN1dHM/LmRldGFjaCgpO1xuICAgIHRoaXMucGxvdFNlcnZpY2UuZGV0YWNoKCk7XG4gIH1cblxuICAvKiogV2hhdCB0aGUgaG9zdCBnZXRzIHRocm91Z2ggYHNldERpYWdyYW1gIOKAlCBzZWUge0BsaW5rIFZpc3VhbGl6ZXJIYW5kbGV9LiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGhvc3RIYW5kbGU6IFZpc3VhbGl6ZXJIYW5kbGUgPSB7XG4gICAgdmlzdWFsaXplcjogdGhpcy5wbG90U2VydmljZSxcbiAgICBwbG90U2VydmljZTogdGhpcy5wbG90U2VydmljZSxcbiAgICBoYXNSZWdpb25zOiAoKSA9PiB0aGlzLmhhc1JlZ2lvbnMoKSxcbiAgICBnZXRSZWdpb25Qb2x5Z29uczogKCkgPT4gdGhpcy5nZXRSZWdpb25Qb2x5Z29ucygpLFxuICB9O1xuXG4gIHB1YmxpYyBoYXNSZWdpb25zKCk6IGJvb2xlYW4ge1xuICAgIC8vIFRoZSBjb250cmFjdCdzIGZyYW1ld29yay1uZXV0cmFsIHJlZ2lvbiBhY2Nlc3NvcjogdGhlIGNvbXBvbmVudCBvbmx5IG5lZWRzIHRvXG4gICAgLy8ga25vdyB3aGV0aGVyIGFueSByZWdpb24gZXhpc3RzLCBuZXZlciBhIGJhY2tlbmQncyB3aXJlIGZvcm1hdC5cbiAgICByZXR1cm4gdGhpcy5wbG90U2VydmljZS5nZXRSZWdpb25zKCkubGVuZ3RoID4gMDtcbiAgfVxuXG4gIC8qKiBUaGUgY3VycmVudCByZWdpb25zIGFzIHBvbHlnb25zIChhbHNvIG9uIHRoZSBob3N0IGhhbmRsZSkuICovXG4gIHB1YmxpYyBnZXRSZWdpb25Qb2x5Z29ucygpOiBQb2x5Z29uW10ge1xuICAgIHJldHVybiB0aGlzLnBsb3RTZXJ2aWNlLmdldFJlZ2lvblBvbHlnb25zKCk7XG4gIH1cblxuICAvKiogT3BlbiB0aGUgQ2hhbm5lbHMgJiBIaXN0b2dyYW0gZGlhbG9nICh0b29sYmFyIGJ1dHRvbikuICovXG4gIHByb3RlY3RlZCBvcGVuQ2hhbm5lbEhpc3RvZ3JhbSgpIHtcbiAgICB0aGlzLnNob3dDaGFubmVsSGlzdG9ncmFtID0gdHJ1ZTtcbiAgfVxuXG4gIC8qKiBUb29sYmFyIOKGkiBvcGVuIHRoZSBzcGF0aWFsLW9taWNzIGNvbnRyb2xzLiAqL1xuICBwcm90ZWN0ZWQgb3BlblNwYXRpYWxDb250cm9scygpOiB2b2lkIHtcbiAgICB0aGlzLnNob3dTcGF0aWFsQ29udHJvbHMgPSB0cnVlO1xuICB9XG5cbiAgLyoqIE9wZW4gdGhlIFJlZ2lvbiBFZGl0b3IgZGlhbG9nICh0b29sYmFyIGJ1dHRvbikuIFRoZSBlZGl0b3Igc3RheXMgbGlua2VkIHRvXG4gICAqICB0aGlzIHBsb3R0aW5nIGluc3RhbmNlIHRocm91Z2ggdGhlIHJvb3QgUmVnaW9uU3RvcmUgc2luZ2xldG9uLCBzbyBpdCB3b3Jrc1xuICAgKiAgdGhlIHNhbWUgYXMgdGhlIGZvcm1lciByaWdodC1wYW5lbCBSZWdpb25zIHRhYi4gKi9cbiAgcHJvdGVjdGVkIG9wZW5SZWdpb25FZGl0b3IoKSB7XG4gICAgLy8gU2l6ZSB0aGUgZGlhbG9nIHRvIG1hdGNoIHRoZSBob3N0J3MgY29uZmlndXJlZCBlbGVtZW50IChlLmcuIHRoZSBhcHAnc1xuICAgIC8vIHJpZ2h0IHBhbmVsKSBhdCBvcGVuIHRpbWUuIE1lYXN1cmVkIG9uY2Ug4oCUIGl0IGludGVudGlvbmFsbHkgZG9lcyBub3RcbiAgICAvLyB0cmFjayBsYXRlciBicm93c2VyL3NwbGl0IHJlc2l6ZXMuIEZhbGxzIGJhY2sgdG8gYSBxdWFydGVyIG9mIHRoZSBwYWdlXG4gICAgLy8gd2hlbiBubyBzZWxlY3RvciBpcyBjb25maWd1cmVkIG9yIHRoZSBlbGVtZW50IGlzbid0IHByZXNlbnQuXG4gICAgY29uc3Qgc2VsZWN0b3IgPSB0aGlzLnZpekNvbmZpZz8ucmVnaW9uRWRpdG9yV2lkdGhTZWxlY3RvcjtcbiAgICBjb25zdCB3aWR0aCA9IHNlbGVjdG9yXG4gICAgICA/IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3I8SFRNTEVsZW1lbnQ+KHNlbGVjdG9yKT8uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkud2lkdGhcbiAgICAgIDogdW5kZWZpbmVkO1xuICAgIHRoaXMucmVnaW9uRWRpdG9yV2lkdGggPSB3aWR0aCAmJiB3aWR0aCA+IDAgPyBgJHtNYXRoLnJvdW5kKHdpZHRoKX1weGAgOiAnMjV2dyc7XG4gICAgdGhpcy5zaG93UmVnaW9uRWRpdG9yID0gdHJ1ZTtcbiAgfVxuXG4gIC8qKiBUaGUgdG9vbGJhcidzIFNpbmdsZSBpbWFnZSAvIFN0YWNrIHRvZ2dsZS4gKi9cbiAgcHJvdGVjdGVkIHNlbGVjdFN0YWNrT3B0aW9uKHNlbGVjdGVkU3RhY2tPcHRpb246IHsgbmFtZTogc3RyaW5nOyB2YWw6IHN0cmluZyB9KSB7XG4gICAgY29uc3Qgc2hvd3N0YWNrID0gc2VsZWN0ZWRTdGFja09wdGlvbi52YWwgPT09ICd0cnVlJztcbiAgICB0aGlzLnN0YWNrTG9hZGluZy5zZXQoc2hvd3N0YWNrKTtcbiAgICB0aGlzLnN0YXRlLnNldEltYWdlTG9hZGluZyghc2hvd3N0YWNrKTtcbiAgICAvLyBTdGFjayBtb2RlIGlzIGFsd2F5cyBhIDJEIGhlYXRtYXAg4oCUIHJlc2V0IHN1cmZhY2UgbW9kZSBpZiBhY3RpdmVcbiAgICBpZiAoIXRoaXMuaXNIZWF0bWFwKSB7XG4gICAgICB0aGlzLmlzSGVhdG1hcCA9IHRydWU7XG4gICAgICB0aGlzLnBsb3RUeXBlID0gUGxvdFR5cGUuSEVBVE1BUDtcbiAgICAgIHRoaXMuc2VsZWN0ZWRQbG90VHlwZUlkID0gUGxvdFR5cGUuSEVBVE1BUDtcbiAgICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0UGxvdFR5cGUodGhpcy5wbG90VHlwZSk7XG4gICAgfVxuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0U2hvd1N0YWNrKHNob3dzdGFjayk7XG4gIH1cblxuICAvKiogQ2xhbXAgdGhlIHNsaWNlIGluZGV4IGludG8gWzAsIG1heEluZGV4XSBhbmQgcHVzaCBpdCB0byB0aGUgcmVuZGVyZXIuICovXG4gIHByb3RlY3RlZCB1cGRhdGVaSW5kZXgoKSB7XG4gICAgaWYgKHRoaXMuekluZGV4ID4gdGhpcy5tYXhJbmRleCkge1xuICAgICAgdGhpcy56SW5kZXggPSB0aGlzLm1heEluZGV4O1xuICAgIH1cbiAgICBpZiAodGhpcy56SW5kZXggPCAwKSB7XG4gICAgICB0aGlzLnpJbmRleCA9IDA7XG4gICAgfVxuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0WkluZGV4KHRoaXMuekluZGV4KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaXZlIHotc2xpY2Ugc2NydWIgZm9yIHRoZSBJbWFnZSB2aWV3OiB0aGUgcmVuZGVyZXIgc3dhcHMgdGhlIGRpc3BsYXllZFxuICAgKiBzbGljZSBpbiBwbGFjZSAobm8gcmUtbW91bnQpLCBzbyBkcmFnZ2luZyB0aGUgc2xpZGVyIHN0ZXBzIHRocm91Z2ggdGhlXG4gICAqIHN0YWNrIHRoZSBzYW1lIHdheSB0aGUgaGVhdG1hcCBmcmFtZSBzbGlkZXIgZG9lcy5cbiAgICovXG4gIHByb3RlY3RlZCBvblpTbGlkZSh6OiBudW1iZXIgfCB1bmRlZmluZWQpIHtcbiAgICBpZiAoeiA9PT0gdW5kZWZpbmVkKSByZXR1cm47XG4gICAgdGhpcy56SW5kZXggPSB6O1xuICAgIHRoaXMuc2NydWJiZXIuY29tbWl0KHopO1xuICAgIC8vIEtlZXAgdGhlIGludGVuc2l0eSBpbnNldCBzYW1wbGluZyB0aGUgZGlzcGxheWVkIHNsaWNlIChJbWFnZSB2aWV3KS5cbiAgICB0aGlzLmluc2V0Py5zbGljZUNvbW1pdHRlZCh6KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMaXZlIChkZWJvdW5jZWQpIHNjcnViIHdoaWxlIGRyYWdnaW5nIHRoZSBJbWFnZS12aWV3IHotc2xpZGVyOiB1cGRhdGUgdGhlXG4gICAqIHNsaWNlIGFzIHRoZSB1c2VyIGRyYWdzLCBidXQgY29hbGVzY2UgcmFwaWQgY2hhbmdlcyBzbyB3ZSBkb24ndCBmaXJlIGFcbiAgICogc2xpY2Ugc3dhcCBvbiBldmVyeSBwaXhlbC4gVGhlIGZpbmFsIHZhbHVlIGFsc28gbGFuZHMgdmlhIG9uWlNsaWRlIChvblNsaWRlRW5kKS5cbiAgICovXG4gIHByb3RlY3RlZCBvblpTY3J1Yih6OiBudW1iZXIgfCB1bmRlZmluZWQpIHtcbiAgICBpZiAoeiA9PT0gdW5kZWZpbmVkKSByZXR1cm47XG4gICAgdGhpcy56SW5kZXggPSB6O1xuICAgIHRoaXMuc2NydWJiZXIuc2NydWIoeik7XG4gIH1cblxuICAvKiogTW92ZSB0aGUgZGlzcGxheWVkIHNsaWNlIGJ5IGBkZWx0YWAsIGNsYW1wZWQgdG8gdGhlIHN0YWNrIGJvdW5kcy4gKi9cbiAgc3RlcFNsaWNlKGRlbHRhOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBuZXh0ID0gTWF0aC5taW4odGhpcy5tYXhJbmRleCwgTWF0aC5tYXgoMCwgdGhpcy56SW5kZXggKyBkZWx0YSkpO1xuICAgIGlmIChuZXh0ID09PSB0aGlzLnpJbmRleCkgcmV0dXJuO1xuICAgIHRoaXMub25aU2xpZGUobmV4dCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgcmVsb2FkQW5kUGxvdCgpIHtcbiAgICB0aGlzLnN0YXRlLnNldEltYWdlTG9hZGluZyh0cnVlKTtcbiAgICAvLyBSZS1kcml2ZSB0aGUgcmVuZGVyIHBpcGVsaW5lIGZyb20gdGhlIGN1cnJlbnQgaW1hZ2UgaW5mbyAodGhlIHNvdXJjZSBvZlxuICAgIC8vIHRydXRoLCB3aXRoIHJlYWwgdXJscy9maWxlTmFtZSkuIERvbid0IHVzZSBwbG90U2VydmljZS5yZWxvYWRBbmRQbG90KCk6XG4gICAgLy8gdGhhdCByZWJ1aWxkcyB0aGUgaW5mbyBmcm9tIHRoZSByZW5kZXJlcidzIGludGVybmFsIHN0YXRlLCB3aGljaCBjYW4gYmVcbiAgICAvLyBzdGFsZSAoZS5nLiBhZnRlciBzd2l0Y2hpbmcgcGxvdCB0eXBlIEltYWdlIC0+IEhlYXRtYXApIGFuZCByZS1lbWl0XG4gICAgLy8gZW1wdHkvb2xkIHVybHMsIGZhaWxpbmcgdG8gaGFuZCB0aGUgZGl2IG92ZXIgdG8gdGhlIG5ldyByZW5kZXJlci5cbiAgICBpZiAodGhpcy5pbWFnZUluZm8pIHtcbiAgICAgIHRoaXMuc3RhdGUuc2V0SW1hZ2VJbmZvKHRoaXMuaW1hZ2VJbmZvKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuc3BhdGlhbC5kYXRhc2V0ICYmIChpc1NwYXRpYWxPbWljcyh0aGlzLnBsb3RUeXBlKSB8fCBpc1NwYXRpYWxPbWljczNkKHRoaXMucGxvdFR5cGUpKSkge1xuICAgICAgLy8gQSBzcGF0aWFsIGRhdGFzZXQgdGhhdCBicmluZ3Mgbm8gaW1hZ2UsIG9wZW5lZCB3aXRoIG5vIGltYWdlIGxvYWRlZCAoYSBob3N0J3NcbiAgICAgIC8vIGZpcnN0IHZpZXcpOiB0aGVyZSBpcyBubyBpbWFnZSBpbmZvIHRvIHJlLWRyaXZlLCBzbyBkcmF3IHRoZSBzcGF0aWFsIG1vZGUgaXRzZWxmLlxuICAgICAgdm9pZCB0aGlzLnJlbmRlci5wbG90V2l0aG91dEltYWdlKHRoaXMuc3BhdGlhbC5kYXRhc2V0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5wbG90U2VydmljZS5yZWxvYWRBbmRQbG90KCk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGNhbmNlbExvYWRpbmcoKSB7XG4gICAgLy8gU3RvcCBhbnkgaW4tZmxpZ2h0IGZyYW1lIHN0cmVhbWluZyAobmFwYXJpLWpzIHZvbHVtZS9zdXJmYWNlIHByZWxvYWQpIHNvIHRoZSBmZXRjaCBsb29wc1xuICAgIC8vIGFjdHVhbGx5IGFib3J0IOKAlCBjbGVhcmluZyB0aGUgZmxhZyBhbG9uZSBvbmx5IHJvdXRlZCB0byBQbG90bHkgYW5kIGxlZnQgbmFwYXJpIGZldGNoaW5nLlxuICAgIHRoaXMucGxvdFNlcnZpY2UuY2FuY2VsTG9hZGluZz8uKCk7XG4gICAgLy8gVGhlIGNhbmNlbGxlZCByZW5kZXIgaXMgc3VwZXJzZWRlZCwgbm90IGp1c3QgYWJvcnRlZDogaXRzIGFib3J0ZWQgbG9hZCBtdXN0IG5vdFxuICAgIC8vIGNvbWUgYmFjayBhcyBcIkNvdWxkIG5vdCBkcmF3IHRoZSBpbWFnZVwiLCBub3IgYXBwbHkgUk9JcyBmb3IgYW4gaW1hZ2UgbGVmdCB1bnNob3duLlxuICAgIHRoaXMucmVuZGVyLmNhbmNlbCgpO1xuICAgIHRoaXMuc3RhY2tMb2FkaW5nLnNldChmYWxzZSk7XG4gICAgdGhpcy5pbWdMb2FkaW5nLnNldChmYWxzZSk7XG4gICAgdGhpcy5zdGF0ZS5zZXRJbWFnZUxvYWRpbmcoZmFsc2UpO1xuICAgIHRoaXMuekluZGV4ID0gMDtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldFpJbmRleCh0aGlzLnpJbmRleCk7XG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRTdGFja0xvYWRpbmcoZmFsc2UpO1xuICB9XG5cbiAgcHJvdGVjdGVkIGRvd25sb2FkSW1hZ2UoKSB7XG4gICAgdGhpcy5wbG90U2VydmljZS5kb3dubG9hZEltYWdlKCk7XG4gIH1cblxuICBhdXRvc2NhbGVJbWFnZSgpIHtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLmZpdFRvVmlldygpO1xuICB9XG5cbiAgLyoqIFRvb2xiYXIgcGl4ZWwvc21vb3RoIHRvZ2dsZTogZmxpcCBzbW9vdGhpbmcgYW5kIGFwcGx5IHRvIHRoZSBhY3RpdmUgYmFja2VuZC4gKi9cbiAgcHJvdGVjdGVkIG9uVG9nZ2xlSW1hZ2VTbW9vdGhpbmcoKTogdm9pZCB7XG4gICAgdGhpcy5pbWFnZVNtb290aGluZ0VuYWJsZWQgPSAhdGhpcy5pbWFnZVNtb290aGluZ0VuYWJsZWQ7XG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRJbWFnZVNtb290aGluZ0VuYWJsZWQodGhpcy5pbWFnZVNtb290aGluZ0VuYWJsZWQpO1xuICB9XG5cbiAgcmVzZXRBeGVzKCkge1xuICAgIHRoaXMucGxvdFNlcnZpY2UucmVzZXRBeGVzKCk7XG4gIH1cblxuICB0b2dnbGVEcmFnTW9kZShtb2RlOiBzdHJpbmcpIHtcbiAgICB0aGlzLnRvb2xzLnRvZ2dsZShtb2RlKTtcbiAgfVxuXG4gIC8qKiBMaXZlLXVwZGF0ZSB0aGUgaXNvc3VyZmFjZSBhcyB0aGUgcmFuZ2Ugc2xpZGVyIG1vdmVzLiBUaGUgY29udHJvbCBpcyBvbmx5XG4gICAqICBhdmFpbGFibGUgd2hlbiB0aGUgYWN0aXZlIGJhY2tlbmQgcmVuZGVycyBpc29zdXJmYWNlcyAoSVNPU1VSRkFDRSBtb2RlKS4gKi9cbiAgcHJvdGVjdGVkIG9uSXNvUmFuZ2VDaGFuZ2UodmFsdWVzOiBudW1iZXJbXSB8IHVuZGVmaW5lZCkge1xuICAgIGlmICghdmFsdWVzIHx8IHZhbHVlcy5sZW5ndGggPCAyKSByZXR1cm47XG4gICAgdGhpcy5pc29SYW5nZSA9IHZhbHVlcztcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLmdldElzb3N1cmZhY2VDb250cm9scygpPy5zZXRJc29SYW5nZSh2YWx1ZXNbMF0sIHZhbHVlc1sxXSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb25XYW5kU2Vuc2l0aXZpdHlDaGFuZ2UodmFsdWU6IG51bWJlciB8IHVuZGVmaW5lZCkge1xuICAgIHRoaXMudG9vbHMuc2V0V2FuZFNlbnNpdGl2aXR5KHZhbHVlKTtcbiAgfVxuICBwcm90ZWN0ZWQgb25CcnVzaFNpemVDaGFuZ2UodmFsdWU6IG51bWJlciB8IHVuZGVmaW5lZCkge1xuICAgIHRoaXMudG9vbHMuc2V0QnJ1c2hTaXplKHZhbHVlKTtcbiAgfVxuICBwcm90ZWN0ZWQgb25WZXJ0ZXhFcmFzZXJSYWRpdXNDaGFuZ2UodmFsdWU6IG51bWJlciB8IHVuZGVmaW5lZCkge1xuICAgIHRoaXMudG9vbHMuc2V0VmVydGV4RXJhc2VyUmFkaXVzKHZhbHVlKTtcbiAgfVxuXG4gIHpvb21JbigpIHtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnpvb21JbigpO1xuICB9XG5cbiAgem9vbU91dCgpIHtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnpvb21PdXQoKTtcbiAgfVxuXG4gIGRlbGV0ZVJlZ2lvbigpIHtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLmRlbGV0ZUFjdGl2ZVNoYXBlKCk7XG4gIH1cblxuICAvKiogVW5kbyB0aGUgbW9zdCByZWNlbnQgcmVnaW9uIGFjdGlvbiAoaml0LXVpIzg1KS4gVXAgdG8gMTAgc3RlcHMgYmFjay4gKi9cbiAgcHJvdGVjdGVkIHVuZG9SZWdpb24oKSB7XG4gICAgdGhpcy5wbG90U2VydmljZS51bmRvKCk7XG4gIH1cblxuICAvKiogUmVkbyB0aGUgbW9zdCByZWNlbnRseSB1bmRvbmUgcmVnaW9uIGFjdGlvbiAoaml0LXVpIzg1KS4gKi9cbiAgcHJvdGVjdGVkIHJlZG9SZWdpb24oKSB7XG4gICAgdGhpcy5wbG90U2VydmljZS5yZWRvKCk7XG4gIH1cblxuICAvLyDilIDilIAgUmVnaW9uIHNldC1vcGVyYXRpb25zIG9uIHRoZSBjdXJyZW50IHNlbGVjdGlvbiAoaml0LXVpIzg1KSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgc2VsZWN0QWxsUmVnaW9ucygpOiB2b2lkIHtcbiAgICB0aGlzLnJlZ2lvbkFjdGlvbnMuc2VsZWN0QWxsKCk7XG4gIH1cbiAgbWVyZ2VSZWdpb25zKCk6IHZvaWQge1xuICAgIHRoaXMucmVnaW9uQWN0aW9ucy5tZXJnZSgpO1xuICB9XG4gIHVuZ3JvdXBSZWdpb25zKCk6IHZvaWQge1xuICAgIHRoaXMucmVnaW9uQWN0aW9ucy51bmdyb3VwKCk7XG4gIH1cbiAgaW52ZXJzZVJlZ2lvbnMoKTogdm9pZCB7XG4gICAgdGhpcy5yZWdpb25BY3Rpb25zLmludmVyc2UoKTtcbiAgfVxuICBzaW1wbGlmeVJlZ2lvbnModGhyZXNob2xkUHg6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMucmVnaW9uQWN0aW9ucy5zaW1wbGlmeSh0aHJlc2hvbGRQeCk7XG4gIH1cbiAgb3BlblNpbXBsaWZ5RGlhbG9nKCk6IHZvaWQge1xuICAgIHRoaXMucmVnaW9uQWN0aW9ucy5vcGVuU2ltcGxpZnlEaWFsb2coKTtcbiAgfVxuXG4gIC8qKiBCb3gtcHJvbXB0ZWQgU0FNIHNlZ21lbnRhdGlvbiBvZiB0aGUgZHJhd24gcmVjdGFuZ2xlcyAoaml0LXVpIzkwKS4gQSBzdGlja3lcbiAgICogIGBzYW1gIHRvYXN0IHNob3dzIGxpdmUgc3RhdHVzICsgYSBkb3dubG9hZCBwcm9ncmVzcyBiYXIgKGZpcnN0IHJ1biBwdWxscyB0aGVcbiAgICogIGVuY29kZXIsIH4xNzAgTUIpOyBpdCBzdGF5cyBvcGVuIHVudGlsIHRoZSBydW4gZmluaXNoZXMgKGJhciBoaXRzIDEwMCUpLiAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgc2VnbWVudFJlZ2lvbnMoKSB7XG4gICAgYXdhaXQgdGhpcy5zZWdtZW50YXRpb24ucnVuKCdTQU0nLCB0aGlzLnNhbVRvb2wsICgpID0+IHRoaXMucGxvdFNlcnZpY2Uuc2VnbWVudFJlY3RhbmdsZXMoKSk7XG4gIH1cblxuICAvKiogQXV0by1zZWdtZW50IGNlbGxzIGluc2lkZSBlYWNoIGRyYXduIHJlY3RhbmdsZSB3aXRoIGNlbGxwb3NlLVNBTSwgY2xpZW50LXNpZGVcbiAgICogIChqaXQtdWkjOTApLiBFYWNoIGJveCBpcyBjcm9wcGVkIChicm93c2VyIHNsaWRlLWNyb3ApIHRoZW4gcnVuIHRocm91Z2ggdGhlXG4gICAqICBjZWxscG9zZS1qcyBtb2RlbDsgdGhlIHNhbWUgc3RpY2t5IGBzYW1gIHRvYXN0ICsgcHJvZ3Jlc3MgYmFyIGlzIHJldXNlZC4gKi9cbiAgcHJvdGVjdGVkIGFzeW5jIHNlZ21lbnRDZWxscG9zZSgpIHtcbiAgICBhd2FpdCB0aGlzLnNlZ21lbnRhdGlvbi5ydW4oJ0NlbGxwb3NlJywgdGhpcy5jZWxsU2VnbWVudFRvb2wsICgpID0+XG4gICAgICB0aGlzLnBsb3RTZXJ2aWNlLnNlZ21lbnRSZWN0YW5nbGVzQ2VsbHBvc2UoKSxcbiAgICApO1xuICB9XG5cbiAgLy8g4pSA4pSAIGNvbnRyaWJ1dGVkIHRvb2wgcGFyYW1ldGVycyAoc2VlIFRvb2xQYXJhbXNNb2RlbCkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gIHBhcmFtc0Zvcih0b29sSWQ6IHN0cmluZyk6IFJlY29yZDxzdHJpbmcsIHVua25vd24+IHtcbiAgICByZXR1cm4gdGhpcy50b29sUGFyYW1zLnBhcmFtc0Zvcih0b29sSWQpO1xuICB9XG4gIHByb3RlY3RlZCBvblRvb2xNb2RlbENoYW5nZShlOiB7IHRvb2xJZDogc3RyaW5nOyBtb2RlbElkOiBzdHJpbmcgfSk6IHZvaWQge1xuICAgIHRoaXMudG9vbFBhcmFtcy5zZXRNb2RlbChlLnRvb2xJZCwgZS5tb2RlbElkKTtcbiAgfVxuICBwcm90ZWN0ZWQgb3BlblRvb2xQYXJhbXModG9vbElkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnRvb2xQYXJhbXMub3Blbih0b29sSWQpO1xuICB9XG4gIHByb3RlY3RlZCBjbG9zZVRvb2xQYXJhbXMoKTogdm9pZCB7XG4gICAgdGhpcy50b29sUGFyYW1zLmNsb3NlKCk7XG4gIH1cbiAgcHJvdGVjdGVkIHJlc2V0VG9vbFBhcmFtcyh0b29sSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMudG9vbFBhcmFtcy5yZXNldCh0b29sSWQpO1xuICB9XG5cbiAgLyoqIFJ1biBhIGNvbnRyaWJ1dGVkIHRvb2wgb3ZlciB0aGUgY3VycmVudCB2aWV3LiBObyBwcm9tcHQ6IHRoZXNlIHN3ZWVwIHRoZVxuICAgKiAgd2hvbGUgdmlldyByYXRoZXIgdGhhbiBiZWluZyBwb2ludGVkIGF0IHNvbWV0aGluZy4gUmV1c2VzIHRoZSBzaGFyZWRcbiAgICogIHNlZ21lbnRhdGlvbiB0b2FzdCBzbyBwcm9ncmVzcyByZWFkcyB0aGUgc2FtZSBhcyB0aGUgU0FNL2NlbGxwb3NlIHRvb2xzLiAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgcnVuVG9vbCh0b29sSWQ6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHRvb2wgPSB0aGlzLnRvb2xQYXJhbXMuZmluZCh0b29sSWQpO1xuICAgIGlmICghdG9vbCkgcmV0dXJuO1xuICAgIGNvbnN0IHBhcmFtcyA9IHRoaXMudG9vbFBhcmFtcy5ydW5QYXJhbXModG9vbCk7XG4gICAgYXdhaXQgdGhpcy5zZWdtZW50YXRpb24ucnVuKHRvb2wubGFiZWwsIHRvb2wucHJvZ3Jlc3MsICgpID0+IHRvb2wucnVuKHRoaXMucGxvdFNlcnZpY2UsIHBhcmFtcykpO1xuICB9XG5cbiAgLyoqIFBpY2sgdGhlIFNBTSBtb2RlbCB0aGUgc2VnbWVudCB0b29scyB1c2UgKGppdC11aSM5MCBQMSkuICovXG4gIHByb3RlY3RlZCBvblNhbU1vZGVsQ2hhbmdlKGlkOiBzdHJpbmcpIHtcbiAgICB0aGlzLnNhbU1vZGVsSWQgPSBpZDtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldFNhbU1vZGVsKGlkKTtcbiAgfVxuXG4gIC8qKiBDb252ZXJ0IHRoZSBzZWxlY3RlZCByZWdpb24gdG8gYSBzbW9vdGggYmV6aWVyIGN1cnZlLiAqL1xuICB0b0JlemllclJlZ2lvbigpIHtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLmdldFJlZ2lvbk92ZXJsYXkoKT8uc2V0U2VsZWN0ZWRCZXppZXIodHJ1ZSk7XG4gIH1cblxuICAvKiogQ29udmVydCB0aGUgc2VsZWN0ZWQgcmVnaW9uIGJhY2sgdG8gYSBzdHJhaWdodC1lZGdlZCBwb2x5Z29uLiAqL1xuICB0b1BvbHlnb25SZWdpb24oKSB7XG4gICAgdGhpcy5wbG90U2VydmljZS5nZXRSZWdpb25PdmVybGF5KCk/LnNldFNlbGVjdGVkQmV6aWVyKGZhbHNlKTtcbiAgfVxuXG4gIC8qKiBUaGUgcmlnaHQtY2xpY2sgbWVudSBmb3IgdGhlIGN1cnJlbnQgdmlldywgYXJtZWQgbW9kZSBhbmQgc2VsZWN0aW9uLiAqL1xuICBwcml2YXRlIGJ1aWxkQ29udGV4dE1lbnVJdGVtcygpOiBNZW51SXRlbVtdIHtcbiAgICByZXR1cm4gYnVpbGRDb250ZXh0TWVudSh0aGlzLmNvbnRleHRNZW51U3RhdGUoKSwgdGhpcyk7XG4gIH1cblxuICBwcml2YXRlIGNvbnRleHRNZW51U3RhdGUoKTogQ29udGV4dE1lbnVTdGF0ZSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIGlzSGVhdG1hcDogdGhpcy5pc0hlYXRtYXAsXG4gICAgICBiYXNlUGxvdFR5cGU6IHRoaXMuYmFzZVBsb3RUeXBlLFxuICAgICAgYWN0aXZlRHJhZ01vZGU6IHRoaXMuYWN0aXZlRHJhZ01vZGUsXG4gICAgICBhY3RpdmVTdXJmYWNlM2RNb2RlOiB0aGlzLmFjdGl2ZVN1cmZhY2UzZE1vZGUsXG4gICAgICByZWdpb25zOiB0aGlzLnBsb3RTZXJ2aWNlLmdldFJlZ2lvbnMoKSxcbiAgICAgIHNlbGVjdGVkSW5kaWNlczogdGhpcy5yZWdpb25BY3Rpb25zLnNlbGVjdGVkSW5kaWNlcyxcbiAgICAgIGNhblVuZ3JvdXA6IChyKSA9PiB0aGlzLnJlZ2lvbk9wcy5jYW5Vbmdyb3VwKHIpLFxuICAgIH07XG4gIH1cblxuICAvKiogM0Qgc2NlbmUgaW50ZXJhY3Rpb24gbW9kZSAob3JiaXQgLyB0dXJudGFibGUgLyBwYW4gLyB6b29tKTsgbm8tb3Agb24gYSAyRC1vbmx5IGJhY2tlbmQuICovXG4gIHRvZ2dsZVN1cmZhY2UzZE1vZGUobW9kZTogc3RyaW5nKSB7XG4gICAgdGhpcy5hY3RpdmVTdXJmYWNlM2RNb2RlID0gbW9kZTtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLmdldFN1cmZhY2UzZENvbnRyb2xzKCk/LnNldFN1cmZhY2VEcmFnTW9kZShtb2RlKTtcbiAgfVxuXG4gIHJlc2V0U3VyZmFjZUNhbWVyYSgpIHtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLmdldFN1cmZhY2UzZENvbnRyb2xzKCk/LnJlc2V0U3VyZmFjZUNhbWVyYSgpO1xuICB9XG5cbiAgLyoqIFRvZ2dsZSB0aGUgbmFwYXJpIDNEIGNvb3JkaW5hdGUtYXhlcyAvIHNjYWxlIGdpem1vICh2b2x1bWUvaXNvc3VyZmFjZSkuIE5vLW9wIG9uIGJhY2tlbmRzXG4gICAqICB0aGF0IGRvbid0IHJlbmRlciBvbmUgKHRoZSBjb250cm9sIG1ldGhvZCBpcyBvcHRpb25hbCkuICovXG4gIHByb3RlY3RlZCB0b2dnbGVBeGVzKCkge1xuICAgIHRoaXMuYXhlc1Zpc2libGUgPSAhdGhpcy5heGVzVmlzaWJsZTtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLmdldFN1cmZhY2UzZENvbnRyb2xzKCk/LnNldEF4ZXNWaXNpYmxlPy4odGhpcy5heGVzVmlzaWJsZSk7XG4gIH1cblxuICAvKiogVG9nZ2xlIHRoZSBuYXBhcmkgc3VyZmFjZSB3aXJlZnJhbWUgKGVkZ2VzIHZzIGZpbGxlZCkuIE5vLW9wIG9uIGJhY2tlbmRzIHdpdGhvdXQgYSBzdXJmYWNlLiAqL1xuICBwcm90ZWN0ZWQgdG9nZ2xlV2lyZWZyYW1lKCkge1xuICAgIHRoaXMud2lyZWZyYW1lQWN0aXZlID0gIXRoaXMud2lyZWZyYW1lQWN0aXZlO1xuICAgIHRoaXMucGxvdFNlcnZpY2UuZ2V0U3VyZmFjZTNkQ29udHJvbHMoKT8uc2V0V2lyZWZyYW1lPy4odGhpcy53aXJlZnJhbWVBY3RpdmUpO1xuICB9XG5cbiAgLyoqIENoYW5nZSB0aGUgbmFwYXJpIDNEIGRlY2ltYXRlIGZhY3Rvci4gRGVjaW1hdGlvbiBjaGFuZ2VzIHRoZSBmZXRjaGVkL2Fzc2VtYmxlZCBkYXRhLCBzbyB0aGlzXG4gICAqICByZS1wbG90cyB0aGUgY3VycmVudCAzRCB0eXBlIGF0IHRoZSBuZXcgcmVzb2x1dGlvbiAodW5saWtlIGF4ZXMvd2lyZWZyYW1lLCB3aGljaCBhcmUgbGl2ZSkuICovXG4gIHByb3RlY3RlZCBzZWxlY3RSZXNvbHV0aW9uKHNjYWxlOiBudW1iZXIpIHtcbiAgICBpZiAoc2NhbGUgPT09IHRoaXMucmVzb2x1dGlvblNjYWxlKSByZXR1cm47XG4gICAgdGhpcy5yZXNvbHV0aW9uU2NhbGUgPSBzY2FsZTtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldFJlc29sdXRpb25TY2FsZT8uKHNjYWxlKTtcbiAgICB0aGlzLnJlbG9hZEFuZFBsb3QoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTd2l0Y2ggdGhlIGFjdGl2ZSBwbG90IHR5cGUgKGhlYXRtYXAsIHN1cmZhY2UsIGNvbnRvdXIsIHNjYXR0ZXIsIGxpbmUsXG4gICAqIHNjYXR0ZXIzZCwgaXNvc3VyZmFjZSkuIEtlZXBzIGBpc0hlYXRtYXBgIGFzIHRoZSAyRC12cy0zRCBmbGFnIHRoZSByZXN0IG9mXG4gICAqIHRoZSB0b29sYmFyL2NvbnRleHQtbWVudSBsb2dpYyByZWxpZXMgb24sIGRlYWN0aXZhdGVzIDJELW9ubHkgdG9vbHMgd2hlblxuICAgKiBtb3ZpbmcgdG8gYSAzRCB0eXBlLCB0aGVuIHJlLXBsb3RzLlxuICAgKi9cbiAgb25TZWxlY3RQbG90VHlwZShzZWxlY3RlZDogUGxvdFR5cGVJZCkge1xuICAgIC8vIEFsc28gY2FsbGVkIGJ5IHRoZSBob3N0IGRpcmVjdGx5LCBvdXRzaWRlIHRoaXMgdmlldydzIGV2ZW50czogdGhlIHNlbGVjdG9yLCB0aGVcbiAgICAvLyB0b29sYmFyJ3MgdG9vbCBncm91cHMgYW5kIHRoZSBkaWFsb2dzIGFsbCBmb2xsb3cgdGhlIHR5cGUuXG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgLy8gQSBjb250cmlidXRlZCBpZCB3aG9zZSBwcm92aWRlciBpcyBnb25lIChlLmcuIHJlc3RvcmVkIGZyb20gYSBwcmV2aW91c1xuICAgIC8vIHNlc3Npb24pIGhhcyBub3RoaW5nIHRvIGFjdGl2YXRlIOKAlCB0YWtlIHRoZSBkZWZhdWx0IEltYWdlIHZpZXcgaW5zdGVhZC5cbiAgICBpZiAoIWlzQnVpbHRpblBsb3RUeXBlKHNlbGVjdGVkKSAmJiAhdGhpcy5wbG90TW9kZXMuZmluZChzZWxlY3RlZCkpIHtcbiAgICAgIGNvbnNvbGUud2FybihgW3Zpc3VhbGl6ZXJdIHVua25vd24gcGxvdCB0eXBlICcke3NlbGVjdGVkfScg4oCUIHNob3dpbmcgJyR7UGxvdFR5cGUuSU1BR0V9JyBpbnN0ZWFkLmApO1xuICAgICAgc2VsZWN0ZWQgPSBQbG90VHlwZS5JTUFHRTtcbiAgICB9XG4gICAgLy8gQW4gZXhwbGljaXQgY2hvaWNlIHJldHJpZXMgYSBtb2RlIHdob3NlIGVhcmxpZXIgY2xlYW51cCBmYWlsZWQ7IG9ubHlcbiAgICAvLyBhdXRvbWF0aWMgcmUtYWN0aXZhdGlvbnMgKHJlLXJlbmRlciwgaW1hZ2Ugc3dpdGNoKSBmYWxsIGJhY2sgZm9yIHRoYXQuXG4gICAgdGhpcy5wbG90TW9kZXMuY2xlYXJDbGVhbnVwRmFpbHVyZXMoKTtcbiAgICAvLyBXaGF0ZXZlciB3YXMgc2VsZWN0ZWQgYmVmb3JlLCBhIGNvbnRyaWJ1dGVkIHNlc3Npb24gZW5kcyBiZWZvcmUgdGhlIG5leHRcbiAgICAvLyBtb2RlIGRyYXdzLiAoUmUtc2VsZWN0aW5nIHRoZSBzYW1lIGNvbnRyaWJ1dGVkIG1vZGUgcmUtcGxvdHMsIHNvIGl0IGdldHMgYVxuICAgIC8vIGZyZXNoIHNlc3Npb24gdG9vLilcbiAgICB0aGlzLnBsb3RNb2Rlcy5kZWFjdGl2YXRlKCk7XG4gICAgLy8gRXZlcnl0aGluZyBiZWxvdyBkZWNpZGVzIGhvdyB0byBSRU5ERVIsIHNvIGl0IHdvcmtzIG9uIHRoZSBidWlsdC1pbiB0eXBlXG4gICAgLy8gdGhhdCBkcmF3cyBgc2VsZWN0ZWRgOiBhIGNvbnRyaWJ1dGVkIG1vZGUgYmVoYXZlcyBleGFjdGx5IGxpa2UgaXRzIGJhc2UuXG4gICAgY29uc3QgdHlwZSA9IHRoaXMucGxvdE1vZGVzLmJhc2VUeXBlT2Yoc2VsZWN0ZWQpO1xuICAgIC8vIEEgZGlhbG9nIHRvb2wgZHJhd3Mgb3ZlciB0aGUgSW1hZ2UgdmlldzogbGVhdmluZyBpdCBjbG9zZXMgdGhlIGRpYWxvZy4gU3RheWluZ1xuICAgIC8vIG9uIGl0LCB0aGUgc2Vzc2lvbiBlbmRzIGhlcmUgYW5kIHJlc3RhcnRzIG9uY2UgdGhlIHJlLXBsb3QgbGFuZHMuXG4gICAgaWYgKHR5cGUgPT09IFBsb3RUeXBlLklNQUdFKSB0aGlzLmNvbnRyaWJ1dGlvbnMudG9vbERpYWxvZ3MuZGVhY3RpdmF0ZSgpO1xuICAgIGVsc2UgdGhpcy5jbG9zZURpYWxvZ1Rvb2woKTtcbiAgICB0aGlzLnBsb3RUeXBlID0gdHlwZTtcbiAgICB0aGlzLnNlbGVjdGVkUGxvdFR5cGVJZCA9IHNlbGVjdGVkO1xuICAgIGNvbnN0IGRlc2NyaXB0b3IgPSBpc0J1aWx0aW5QbG90VHlwZShzZWxlY3RlZClcbiAgICAgID8gdGhpcy5wbG90VHlwZU1lbnUuZmluZCgoZCkgPT4gZC50eXBlID09PSB0eXBlKVxuICAgICAgOiBnZXRQbG90VHlwZURlc2NyaXB0b3IodHlwZSk7XG4gICAgY29uc3QgaXMzZCA9IGRlc2NyaXB0b3I/LmRpbWVuc2lvbnMgPT09ICczZCc7XG4gICAgdGhpcy5pc0hlYXRtYXAgPSAhaXMzZDtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldFBsb3RUeXBlKHR5cGUpO1xuICAgIC8vIFN3aXRjaGluZyBwbG90IHR5cGUgY2FuY2VscyB0aGUgYWN0aXZlIHRvb2wg4oCUIG5vdCBldmVyeSB0eXBlIHN1cHBvcnRzIHRoZVxuICAgIC8vIHNhbWUgdG9vbHMgKGxpbmUvc2NhdHRlciBjaGFydHMgYW5kIDNEIHNjZW5lcyBoYXZlIG5vIGJveCB6b29tIG9yIHJlZ2lvblxuICAgIC8vIGRyYXdpbmcpLCBzbyBsZWF2aW5nIGEgdG9vbCBhcm1lZCB3b3VsZCBtaXNiZWhhdmUgb24gdGhlIG5ldyBwbG90LlxuICAgIHRoaXMudG9vbHMuZGVhY3RpdmF0ZSgpO1xuICAgIGlmIChpczNkKSB7XG4gICAgICB0aGlzLmFjdGl2ZVN1cmZhY2UzZE1vZGUgPSAndHVybnRhYmxlJztcbiAgICB9XG4gICAgLy8gbmFwYXJpLWpzIHZvbHVtZS9pc29zdXJmYWNlIGFzc2VtYmxlIHRoZWlyIG93biAzRCB0ZXh0dXJlIGZyb20gdGhlIHNsaWNlIGVuZHBvaW50LCBzb1xuICAgIC8vIHRoZXkgdGFrZSB0aGUgbm9ybWFsIHJlLXBsb3QgcGF0aCDigJQgTk9UIFBsb3RseSdzIHN0YWNrLWZyYW1lIGxvYWRlciAod2hvc2UgXCJMb2FkaW5nXG4gICAgLy8gZnJhbWVzXCIgb3ZlcmxheSB3b3VsZCBuZXZlciBjbGVhciwgc2luY2UgUGxvdGx5IGlzbid0IHRoZSBhY3RpdmUgYmFja2VuZCkgKGppdC11aSMxMDIpLlxuICAgIGNvbnN0IGlzTmFwYXJpID0gdHlwZSA9PT0gUGxvdFR5cGUuTkFQQVJJX0lNQUdFIHx8IGlzTmFwYXJpM2QodHlwZSk7XG4gICAgaWYgKGRlc2NyaXB0b3I/LnJlcXVpcmVzU3RhY2sgJiYgIWlzTmFwYXJpKSB7XG4gICAgICAvLyBWb2x1bWUgdHlwZXMgKGlzb3N1cmZhY2UsIHNjYXR0ZXIzZCkgbmVlZCB0aGUgd2hvbGUgei1zdGFjayBsb2FkZWQgYXMgYVxuICAgICAgLy8gM0QgYXJyYXksIGFuZCB0aGV5IGFsd2F5cyByZW5kZXIgb24gUGxvdGx5LiBEcml2ZSB0aGUgc3RhY2sgcmVsb2FkXG4gICAgICAvLyBkaXJlY3RseSB0aHJvdWdoIHRoZSBpbWFnZS1pbmZvIHN0cmVhbSByYXRoZXIgdGhhbiB0aGUgYWN0aXZlIHJlbmRlcmVyJ3NcbiAgICAgIC8vIHNldFNob3dTdGFjazogd2hlbiBPcGVuU2VhZHJhZ29uIG93bnMgdGhlIEltYWdlIHZpZXcgaXRzIHNldFNob3dTdGFjayBpc1xuICAgICAgLy8gYSBuby1vcCwgc28gdGhlIHJlbG9hZCBuZXZlciBmaXJlZCBhbmQgdGhlIGxvYWRlciBzcHVuIGZvcmV2ZXIuIFdlIGFybVxuICAgICAgLy8gUGxvdGx5J3Mgc3RhY2stbG9hZGluZyBmbGFnIChrZWVwcyBpdHMgZnJhbWUtZmV0Y2ggbG9vcCBhbGl2ZSkgYW5kXG4gICAgICAvLyByZS1lbWl0IHRoZSBpbWFnZSBpbmZvIHdpdGggc2hvd1N0YWNrIG9uIHNvIHRoZSBwaXBlbGluZSByZWxvYWRzIG9uXG4gICAgICAvLyBQbG90bHkgcmVnYXJkbGVzcyBvZiB3aGljaCBiYWNrZW5kIHdhcyBvbiBzY3JlZW4uXG4gICAgICB0aGlzLnN0YWNrTG9hZGluZy5zZXQodHJ1ZSk7XG4gICAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldFN0YWNrTG9hZGluZyh0cnVlKTtcbiAgICAgIGlmICh0aGlzLmltYWdlSW5mbykge1xuICAgICAgICAvLyBBIGNvcHk6IHRoZSBpbWFnZSBpbmZvIG1heSBiZSB0aGUgaG9zdCdzIG93biAocG9zc2libHkgZnJvemVuKSBvYmplY3QuXG4gICAgICAgIHRoaXMuc3RhdGUuc2V0SW1hZ2VJbmZvKHsgLi4udGhpcy5pbWFnZUluZm8sIHNob3dTdGFjazogdHJ1ZSB9KTtcbiAgICAgIH1cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5yZWxvYWRBbmRQbG90KCk7XG4gIH1cblxuICAvLyDilIDilIAgZGlhbG9nIHRvb2xzIChUT09MQkFSX1RPT0xTLCBraW5kOiAnZGlhbG9nJykg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqIFRoZSB0b29sYmFyIGJ1dHRvbjogb3BlbiB0aGUgdG9vbCdzIGRpYWxvZywgb3IgY2xvc2UgaXQgaWYgaXQgaXMgb3Blbi4gKi9cbiAgcHJvdGVjdGVkIHRvZ2dsZURpYWxvZ1Rvb2woaWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuY29udHJpYnV0aW9ucy50b2dnbGVEaWFsb2dUb29sKGlkKTtcbiAgfVxuXG4gIC8qKiBDbG9zZSB0aGUgb3BlbiBkaWFsb2cgdG9vbDogaXRzIGJvZHkgaXMgdG9ybiBkb3duLCB0aGVuIGl0cyBzZXNzaW9uIGVuZHMuICovXG4gIHByb3RlY3RlZCBjbG9zZURpYWxvZ1Rvb2woKTogdm9pZCB7XG4gICAgdGhpcy5jb250cmlidXRpb25zLmNsb3NlRGlhbG9nVG9vbCgpO1xuICB9XG5cbiAgLyoqIFdoZXJlIHRoZSBvcGVuIGRpYWxvZyB0b29sJ3MgaG9zdCBlbGVtZW50IGlzIGF0dGFjaGVkIG9uY2UgaXRzIGRpYWxvZyByZW5kZXJzLiAqL1xuICBAVmlld0NoaWxkKCd0b29sRGlhbG9nU2xvdCcpXG4gIHNldCB0b29sRGlhbG9nU2xvdChyZWY6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+IHwgdW5kZWZpbmVkKSB7XG4gICAgdGhpcy5jb250cmlidXRpb25zLmF0dGFjaFRvb2xEaWFsb2dTbG90KHJlZj8ubmF0aXZlRWxlbWVudCk7XG4gIH1cbn1cbiIsIjwhLS0gU0FNIHRvYXN0OiBsaXZlIHN0YXR1cyArIGVuY29kZXItZG93bmxvYWQgcHJvZ3Jlc3MgYmFyIChqaXQtdWkjOTApLiBTdGlja3lcbiAgICAgd2hpbGUgYSBzZWdtZW50IHJ1bnM7IHN0YXlzIG9wZW4gdW50aWwgdGhlIGJhciByZWFjaGVzIDEwMCUgYW5kIHRoZSBydW4gZW5kcy4gLS0+XG48cC10b2FzdCBba2V5XT1cInNhbVRvYXN0S2V5XCIgcG9zaXRpb249XCJib3R0b20tcmlnaHRcIj5cbiAgPG5nLXRlbXBsYXRlIGxldC1tZXNzYWdlIHBUZW1wbGF0ZT1cIm1lc3NhZ2VcIj5cbiAgICA8ZGl2IHN0eWxlPVwiZmxleDogMTsgbWluLXdpZHRoOiAxNnJlbVwiPlxuICAgICAgPGRpdiBjbGFzcz1cImZvbnQtYm9sZCBtYi0xXCI+e3sgbWVzc2FnZS5zdW1tYXJ5IH19PC9kaXY+XG4gICAgICA8ZGl2Pnt7IHNlZ21lbnRhdGlvbi5zdGF0dXMgfHwgbWVzc2FnZS5kZXRhaWwgfX08L2Rpdj5cbiAgICAgIDxwLXByb2dyZXNzQmFyXG4gICAgICAgICpuZ0lmPVwic2VnbWVudGF0aW9uLmRvd25sb2FkaW5nXCJcbiAgICAgICAgW3ZhbHVlXT1cInNlZ21lbnRhdGlvbi5wcm9ncmVzc1wiXG4gICAgICAgIHN0eWxlQ2xhc3M9XCJtdC0yIHNhbS1wcm9ncmVzc1wiXG4gICAgICA+PC9wLXByb2dyZXNzQmFyPlxuICAgICAgPHAtcHJvZ3Jlc3NCYXJcbiAgICAgICAgKm5nSWY9XCJzZWdtZW50YXRpb24uYnVzeSAmJiAhc2VnbWVudGF0aW9uLmRvd25sb2FkaW5nXCJcbiAgICAgICAgbW9kZT1cImluZGV0ZXJtaW5hdGVcIlxuICAgICAgICBzdHlsZUNsYXNzPVwibXQtMlwiXG4gICAgICAgIFtzdHlsZV09XCJ7IGhlaWdodDogJzRweCcgfVwiXG4gICAgICA+PC9wLXByb2dyZXNzQmFyPlxuICAgIDwvZGl2PlxuICA8L25nLXRlbXBsYXRlPlxuPC9wLXRvYXN0PlxuXG48IS0tIFJlc3VsdC9lcnJvciBub3RpY2VzIGZyb20gdGhlIGxpYnJhcnkgaXRzZWxmIChzZWdtZW50YXRpb24gb3V0Y29tZSwgcmVnaW9uXG4gICAgIHZhbGlkYXRpb24pLiBSZW5kZXJlZCBoZXJlIHNvIHRoZXkgZG8gbm90IGRlcGVuZCBvbiB0aGUgaG9zdCBtb3VudGluZyBhXG4gICAgIGtleWxlc3MgPHAtdG9hc3Q+IOKAlCB3aXRob3V0IHRoaXMgdGhlIG1lc3NhZ2VzIHdlbnQgbm93aGVyZSBpbiBhbnkgaG9zdCBidXRcbiAgICAgaml0LXVpLCBhbmQgYSBmYWlsZWQgcnVuIGxvb2tlZCBsaWtlIGEgYnV0dG9uIHRoYXQgZGlkIG5vdGhpbmcuIC0tPlxuPHAtdG9hc3QgW2tleV09XCJyZXN1bHRUb2FzdEtleVwiIHBvc2l0aW9uPVwiYm90dG9tLXJpZ2h0XCI+PC9wLXRvYXN0PlxuXG48IS0tIFNoYXJlZCBvdXRsZXRzIGZvciBub3RpY2VzIHJhaXNlZCB3aGVyZSB0aGVyZSBpcyBubyBwZXItaW5zdGFuY2Uga2V5IHRvIHVzZTpcbiAgICAgdGhlIHJvb3QtcHJvdmlkZWQgUGxvdGx5U2VydmljZSBhbmQgdGhlIHJlZ2lvbi1lZGl0b3IgZGlhbG9nLiBSZW5kZXJlZCBieSBhXG4gICAgIHNpbmdsZSB2aXN1YWxpemVyIChvd25zU2hhcmVkVG9hc3RzKSBzbyBhIG1lc3NhZ2UgZnJvbSB0aGUgcm9vdCBzZXJ2aWNlIGlzXG4gICAgIG5vdCBzaG93biBvbmNlIHBlciBsaXZlIHZpZXdlci4gLS0+XG48cC10b2FzdCAqbmdJZj1cIm93bnNTaGFyZWRUb2FzdHNcIiBba2V5XT1cInZpelRvYXN0S2V5XCI+PC9wLXRvYXN0PlxuPHAtdG9hc3QgKm5nSWY9XCJvd25zU2hhcmVkVG9hc3RzXCIgW2tleV09XCJ2aXpBbGVydFRvYXN0S2V5XCIgcG9zaXRpb249XCJjZW50ZXJcIj48L3AtdG9hc3Q+XG5cbjwhLS0gVG9vbGJhciBkb2NrOiBkb2NrZWQgYWNyb3NzIHRoZSB0b3AgYnkgZGVmYXVsdDsgZHJhZyB0aGUgaGFuZGxlIHRvIGRldGFjaFxuICAgICBpdCBpbnRvIGEgZmxvYXRpbmcsIG1vdmFibGUgd2luZG93IChmcmVlcyB0aGUgdG9wIHJvdyBmb3IgdGhlIGltYWdlKS4gLS0+XG48ZGl2XG4gIGNsYXNzPVwidG9vbGJhci1kb2NrXCJcbiAgW2NsYXNzLmZsb2F0aW5nXT1cInRvb2xiYXJGbG9hdGluZ1wiXG4gIFtzdHlsZS5sZWZ0LnB4XT1cInRvb2xiYXJGbG9hdGluZyA/IHRvb2xiYXJQb3MueCA6IG51bGxcIlxuICBbc3R5bGUudG9wLnB4XT1cInRvb2xiYXJGbG9hdGluZyA/IHRvb2xiYXJQb3MueSA6IG51bGxcIlxuPlxuICA8ZGl2XG4gICAgY2xhc3M9XCJ0b29sYmFyLWRyYWctaGFuZGxlXCJcbiAgICBbdml6RmxvYXRpbmdEcmFnXT1cInRvb2xiYXJEcmFnT3JpZ2luXCJcbiAgICAodml6RmxvYXRpbmdEcmFnTW92ZSk9XCJ0b29sYmFyUG9zID0gJGV2ZW50XCJcbiAgICBwVG9vbHRpcD1cIkRyYWcgdG8gZmxvYXQgdGhlIHRvb2xiYXJcIlxuICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gID5cbiAgICA8aSBjbGFzcz1cInBpIHBpLWJhcnNcIj48L2k+XG4gIDwvZGl2PlxuICA8cGxvdHRpbmctdG9vbGJhclxuICAgIFtpbWFnZUluZm9dPVwiaW1hZ2VJbmZvXCJcbiAgICBbaGFzU3BhdGlhbERhdGFzZXRdPVwiaGFzU3BhdGlhbERhdGFzZXRcIlxuICAgIFtwbG90VHlwZU9wdGlvbnNdPVwicGxvdFR5cGVNZW51XCJcbiAgICBbc2VsZWN0ZWRQbG90VHlwZV09XCJzZWxlY3RlZFBsb3RUeXBlSWRcIlxuICAgIFtiYXNlUGxvdFR5cGVdPVwiYmFzZVBsb3RUeXBlXCJcbiAgICBbaXNvUmFuZ2VdPVwiaXNvUmFuZ2VcIlxuICAgIFttYXhJbmRleF09XCJtYXhJbmRleFwiXG4gICAgW3pJbmRleF09XCJ6SW5kZXhcIlxuICAgIFtpc0hlYXRtYXBdPVwiaXNIZWF0bWFwXCJcbiAgICBbaXMzZFJlZ2lvbnNdPVwiaXNTcGF0aWFsM2RNb2RlXCJcbiAgICBbYWN0aXZlRHJhZ01vZGVdPVwiYWN0aXZlRHJhZ01vZGVcIlxuICAgIFthY3RpdmVTdXJmYWNlM2RNb2RlXT1cImFjdGl2ZVN1cmZhY2UzZE1vZGVcIlxuICAgIFtheGVzVmlzaWJsZV09XCJheGVzVmlzaWJsZVwiXG4gICAgW3dpcmVmcmFtZUFjdGl2ZV09XCJ3aXJlZnJhbWVBY3RpdmVcIlxuICAgIFtyZXNvbHV0aW9uU2NhbGVdPVwicmVzb2x1dGlvblNjYWxlXCJcbiAgICBbd2FuZFNlbnNpdGl2aXR5XT1cIndhbmRTZW5zaXRpdml0eVwiXG4gICAgW2JydXNoU2l6ZV09XCJicnVzaFNpemVcIlxuICAgIFtzYW1Nb2RlbHNdPVwic2FtTW9kZWxzXCJcbiAgICBbc2FtTW9kZWxJZF09XCJzYW1Nb2RlbElkXCJcbiAgICBbY29udHJpYnV0ZWRUb29sc109XCJjb250cmlidXRlZFRvb2xzXCJcbiAgICBbZGlhbG9nVG9vbHNdPVwiZGlhbG9nVG9vbHNcIlxuICAgIFtvcGVuRGlhbG9nVG9vbElkXT1cIm9wZW5EaWFsb2dUb29sSWRcIlxuICAgICh0b2dnbGVEaWFsb2dUb29sKT1cInRvZ2dsZURpYWxvZ1Rvb2woJGV2ZW50KVwiXG4gICAgW3Rvb2xNb2RlbElkc109XCJ0b29sUGFyYW1zLnRvb2xNb2RlbElkc1wiXG4gICAgW3ZlcnRleEVyYXNlclJhZGl1c109XCJ2ZXJ0ZXhFcmFzZXJSYWRpdXNcIlxuICAgIFtjYW5VbmRvXT1cInJlZ2lvbkFjdGlvbnMuY2FuVW5kb1wiXG4gICAgW2NhblJlZG9dPVwicmVnaW9uQWN0aW9ucy5jYW5SZWRvXCJcbiAgICBbdG9vbHNdPVwidG9vbGJhclRvb2xzXCJcbiAgICBbaW1hZ2VTbW9vdGhpbmdFbmFibGVkXT1cImltYWdlU21vb3RoaW5nRW5hYmxlZFwiXG4gICAgKHNlbGVjdFBsb3RUeXBlKT1cIm9uU2VsZWN0UGxvdFR5cGUoJGV2ZW50KVwiXG4gICAgKHRvZ2dsZUltYWdlU21vb3RoaW5nKT1cIm9uVG9nZ2xlSW1hZ2VTbW9vdGhpbmcoKVwiXG4gICAgKGFkZFByb2ZpbGVMaW5lKT1cImFkZFByb2ZpbGVMaW5lKClcIlxuICAgIChpc29SYW5nZUNoYW5nZSk9XCJvbklzb1JhbmdlQ2hhbmdlKCRldmVudClcIlxuICAgIChvcGVuQ2hhbm5lbEhpc3RvZ3JhbSk9XCJvcGVuQ2hhbm5lbEhpc3RvZ3JhbSgpXCJcbiAgICAob3BlblNwYXRpYWxDb250cm9scyk9XCJvcGVuU3BhdGlhbENvbnRyb2xzKClcIlxuICAgIChvcGVuUmVnaW9uRWRpdG9yKT1cIm9wZW5SZWdpb25FZGl0b3IoKVwiXG4gICAgKHNlbGVjdFN0YWNrT3B0aW9uKT1cInNlbGVjdFN0YWNrT3B0aW9uKCRldmVudClcIlxuICAgICh6U2NydWIpPVwib25aU2NydWIoJGV2ZW50KVwiXG4gICAgKHpTbGlkZSk9XCJvblpTbGlkZSgkZXZlbnQpXCJcbiAgICAoekluZGV4SW5wdXQpPVwiekluZGV4ID0gJGV2ZW50OyB1cGRhdGVaSW5kZXgoKVwiXG4gICAgKHJlbG9hZEFuZFBsb3QpPVwicmVsb2FkQW5kUGxvdCgpXCJcbiAgICAoZG93bmxvYWRJbWFnZSk9XCJkb3dubG9hZEltYWdlKClcIlxuICAgIChhdXRvc2NhbGVJbWFnZSk9XCJhdXRvc2NhbGVJbWFnZSgpXCJcbiAgICAodG9nZ2xlRHJhZ01vZGUpPVwidG9nZ2xlRHJhZ01vZGUoJGV2ZW50KVwiXG4gICAgKHpvb21Jbik9XCJ6b29tSW4oKVwiXG4gICAgKHpvb21PdXQpPVwiem9vbU91dCgpXCJcbiAgICAodG9nZ2xlU3VyZmFjZTNkTW9kZSk9XCJ0b2dnbGVTdXJmYWNlM2RNb2RlKCRldmVudClcIlxuICAgIChyZXNldFN1cmZhY2VDYW1lcmEpPVwicmVzZXRTdXJmYWNlQ2FtZXJhKClcIlxuICAgICh0b2dnbGVBeGVzKT1cInRvZ2dsZUF4ZXMoKVwiXG4gICAgKHRvZ2dsZVdpcmVmcmFtZSk9XCJ0b2dnbGVXaXJlZnJhbWUoKVwiXG4gICAgKHNlbGVjdFJlc29sdXRpb24pPVwic2VsZWN0UmVzb2x1dGlvbigkZXZlbnQpXCJcbiAgICAoZGVsZXRlUmVnaW9uKT1cImRlbGV0ZVJlZ2lvbigpXCJcbiAgICAodW5kb1JlZ2lvbik9XCJ1bmRvUmVnaW9uKClcIlxuICAgIChyZWRvUmVnaW9uKT1cInJlZG9SZWdpb24oKVwiXG4gICAgKHNlZ21lbnRSZWdpb25zKT1cInNlZ21lbnRSZWdpb25zKClcIlxuICAgIChzZWdtZW50Q2VsbHBvc2UpPVwic2VnbWVudENlbGxwb3NlKClcIlxuICAgIChzYW1Nb2RlbENoYW5nZSk9XCJvblNhbU1vZGVsQ2hhbmdlKCRldmVudClcIlxuICAgIChydW5Ub29sKT1cInJ1blRvb2woJGV2ZW50KVwiXG4gICAgKHRvb2xNb2RlbENoYW5nZSk9XCJvblRvb2xNb2RlbENoYW5nZSgkZXZlbnQpXCJcbiAgICAob3BlblRvb2xQYXJhbXMpPVwib3BlblRvb2xQYXJhbXMoJGV2ZW50KVwiXG4gICAgKHdhbmRTZW5zaXRpdml0eUNoYW5nZSk9XCJvbldhbmRTZW5zaXRpdml0eUNoYW5nZSgkZXZlbnQpXCJcbiAgICAoYnJ1c2hTaXplQ2hhbmdlKT1cIm9uQnJ1c2hTaXplQ2hhbmdlKCRldmVudClcIlxuICAgICh2ZXJ0ZXhFcmFzZXJSYWRpdXNDaGFuZ2UpPVwib25WZXJ0ZXhFcmFzZXJSYWRpdXNDaGFuZ2UoJGV2ZW50KVwiXG4gID5cbiAgICA8IS0tIEhvc3QtcHJvamVjdGVkIGN1c3RvbSB0b29sYmFyIGJ1dHRvbnMsIGZvcndhcmRlZCBpbnRvIHRoZSB0b29sYmFyLiAtLT5cbiAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XG4gIDwvcGxvdHRpbmctdG9vbGJhcj5cbiAgPHAtYnV0dG9uXG4gICAgKm5nSWY9XCJ0b29sYmFyRmxvYXRpbmdcIlxuICAgIGNsYXNzPVwidG9vbGJhci1kb2NrLWJ0blwiXG4gICAgaWNvbj1cInBpIHBpLXRodW1idGFja1wiXG4gICAgc2l6ZT1cInNtYWxsXCJcbiAgICBbdGV4dF09XCJ0cnVlXCJcbiAgICBwVG9vbHRpcD1cIkRvY2sgdG8gdG9wXCJcbiAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICAgIChvbkNsaWNrKT1cImRvY2tUb29sYmFyKClcIlxuICA+XG4gIDwvcC1idXR0b24+XG48L2Rpdj5cblxuPHAtY29udGV4dE1lbnUgI2NtIFttb2RlbF09XCJjb250ZXh0TWVudUl0ZW1zXCIgYXBwZW5kVG89XCJib2R5XCI+PC9wLWNvbnRleHRNZW51PlxuPCEtLSBObyBgaC1mdWxsYCBoZXJlOiBQcmltZUZsZXgncyBoZWlnaHQ6MTAwJSAhaW1wb3J0YW50IG1hZGUgI3Bsb3QgYXMgdGFsbCBhc1xuICAgICB0aGUgd2hvbGUgaG9zdCwgc28gdW5kZXIgdGhlIGRvY2tlZCB0b29sYmFyIGl0cyBib3R0b20gdG9vbGJhci1oZWlnaHQgc3RyaXBcbiAgICAgKGluY2wuIHRoZSBPU0Qgc2NhbGUgYmFyIGF0IGJvdHRvbS1sZWZ0KSB3YXMgY2xpcHBlZCBieSB0aGUgaG9zdCdzXG4gICAgIG92ZXJmbG93OmhpZGRlbi4gVGhlIGNvbXBvbmVudCBzdHlsZXNoZWV0IHNpemVzIGl0ICgudml6LXBsb3QgeyBmbGV4OiAxIH0pLiAtLT5cbjxkaXYgY2xhc3M9XCJ3LWZ1bGwgcmVsYXRpdmUgdml6LXBsb3RcIiBbaWRdPVwicGxvdERpdk5hbWVcIj5cbiAgPGRpdiAqbmdJZj1cImltZ0xvYWRpbmcoKSB8fCBzdGFja0xvYWRpbmcoKSB8fCBpc0NhY2hpbmcoKVwiIGNsYXNzPVwibG9hZGluZy1vdmVybGF5XCI+XG4gICAgPCEtLSBEZXRlcm1pbmF0ZSBzdGFjay92b2x1bWUgcHJvZ3Jlc3MgdGFrZXMgcHJlY2VkZW5jZTogd2hpbGUgaXQncyBhY3RpdmUgc2hvdyBPTkxZIHRoZVxuICAgICAgICAgcHJvZ3Jlc3MgYmFyICsgXCJMb2FkaW5nIGZyYW1lcy4uLlwiLCBub3QgdGhlIGdlbmVyaWMgc3Bpbm5lci9cIkxvYWRpbmcgaW1hZ2UuLi5cIiBvbiB0b3Agb2ZcbiAgICAgICAgIGl0IChib3RoIHdlcmUgcmVuZGVyaW5nIGF0IG9uY2UgZm9yIG5hcGFyaSB2b2x1bWUvaXNvc3VyZmFjZSBsb2FkcykuIC0tPlxuICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJzdGFja0xvYWRpbmcoKTsgZWxzZSBpbWdMb2FkaW5nVHBsXCI+XG4gICAgICA8cC1wcm9ncmVzc0JhciBjbGFzcz1cInByb2dyZXNzXCIgW3ZhbHVlXT1cImxvYWRpbmdQZXJjZW50YWdlKClcIj48L3AtcHJvZ3Jlc3NCYXI+XG4gICAgICA8c3BhbiBjbGFzcz1cInRleHQtbG9hZGluZ1wiPkxvYWRpbmcgZnJhbWVzLi4uPC9zcGFuPlxuICAgIDwvbmctY29udGFpbmVyPlxuICAgIDxuZy10ZW1wbGF0ZSAjaW1nTG9hZGluZ1RwbD5cbiAgICAgIDwhLS0gQ2FjaGUtY29weSBwcm9ncmVzcyBpcyBzaG93biB3aGVuZXZlciBhIGNhY2hlIGRvd25sb2FkIGlzIGFjdGl2ZSAoaXNDYWNoaW5nKSwgaW5kZXBlbmRlbnRcbiAgICAgICAgICAgb2YgYGltZ0xvYWRpbmdgLCBzbyBpdCdzIG5ldmVyIGRyb3BwZWQvbWFza2VkIG1pZC1kb3dubG9hZC4gLS0+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNDYWNoaW5nKCk7IGVsc2Ugc3Bpbm5lckxvYWRpbmdcIj5cbiAgICAgICAgPCEtLSBTdGFnZS1hd2FyZSBtZXNzYWdlIGNvbWVzIGZyb20gQ2FjaGVQcm9ncmVzc1NlcnZpY2UgdXBkYXRpbmdcbiAgICAgICAgICAgICBpbWFnZUxvYWRpbmdNZXNzYWdlJCAoXCJDYWNoaW5nIGltYWdlLi4uXCIgZHVyaW5nIHRoZSBHQ1MgZG93bmxvYWQsXG4gICAgICAgICAgICAgdGhlbiBcIkdlbmVyYXRpbmcgcHJldmlldy4uLlwiIGR1cmluZyBwZXItc2xpY2UgdGh1bWJuYWlsIGdlbikuIE9uY2UgdGhlXG4gICAgICAgICAgICAgZG93bmxvYWQgaGl0cyAxMDAlIHRoZSByZW1haW5pbmcgd29yayAoc2VydmVyIHByZXZpZXcvdGlsZSBnZW5lcmF0aW9uKVxuICAgICAgICAgICAgIGhhcyBubyBkZXRlcm1pbmF0ZSBwcm9ncmVzcywgc28gZmFsbCB0aHJvdWdoIHRvIHRoZSBzcGlubmVyIHRlbXBsYXRlXG4gICAgICAgICAgICAgcmF0aGVyIHRoYW4gcGFya2luZyBhIGZ1bGwgYmFyIHVuZGVyIFwiTG9hZGluZyBpbWFnZS4uLlwiLiAtLT5cbiAgICAgICAgPHAtcHJvZ3Jlc3NCYXIgY2xhc3M9XCJwcm9ncmVzc1wiIFt2YWx1ZV09XCJjYWNoZVByb2dyZXNzKClcIj48L3AtcHJvZ3Jlc3NCYXI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1sb2FkaW5nXCI+e3sgbG9hZGluZ01lc3NhZ2UoKSB9fTwvc3Bhbj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPG5nLXRlbXBsYXRlICNzcGlubmVyTG9hZGluZz5cbiAgICAgICAgPGRpdiAqbmdJZj1cImltZ0xvYWRpbmcoKVwiIGNsYXNzPVwic3Bpbm5lclwiPjwvZGl2PlxuICAgICAgICA8c3BhbiAqbmdJZj1cImltZ0xvYWRpbmcoKSAmJiAhem9vbSgpXCIgY2xhc3M9XCJ0ZXh0LWxvYWRpbmdcIj57eyBsb2FkaW5nTWVzc2FnZSgpIH19PC9zcGFuPlxuICAgICAgICA8c3BhbiAqbmdJZj1cImltZ0xvYWRpbmcoKSAmJiB6b29tKClcIiBjbGFzcz1cInpvb20tdGV4dC1sb2FkaW5nXCI+e3sgbG9hZGluZ01lc3NhZ2UoKSB9fTwvc3Bhbj5cbiAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgICA8cC1idXR0b25cbiAgICAgICpuZ0lmPVwic3RhY2tMb2FkaW5nKCkgfHwgaW1nTG9hZGluZygpXCJcbiAgICAgIGNsYXNzPVwiY2FuY2VsLWxvYWRpbmdcIlxuICAgICAgbGFiZWw9XCJDYW5jZWxcIlxuICAgICAgKG9uQ2xpY2spPVwiY2FuY2VsTG9hZGluZygpXCJcbiAgICA+XG4gICAgPC9wLWJ1dHRvbj5cbiAgPC9kaXY+XG4gIDwhLS0gVHJhbnNsdWNlbnQgXCJzaGFycGVuaW5nXCIgb3ZlcmxheSBzaG93biBhZnRlciB0aGUgc21hbGwtdGllciBwcmV2aWV3IGlzXG4gICAgICAgb24gc2NyZWVuIHdoaWxlIHRoZSBsYXJnZS10aWVyIHJlbmRlciBpcyBzdGlsbCBsb2FkaW5nIGluIHRoZVxuICAgICAgIGJhY2tncm91bmQuIExldHMgdGhlIHVzZXIgc2VlIHRoZSBibHVycnkgaW1hZ2UgdW5kZXJuZWF0aCBidXQgbWFrZXNcbiAgICAgICBpdCBjbGVhciBzb21ldGhpbmcgaXMgc3RpbGwgbG9hZGluZyBzbyB0aGV5IGRvbid0IG1pc3Rha2UgdGhlXG4gICAgICAgbG93LXJlcyByZW5kZXIgZm9yIHRoZSBmaW5hbCBpbWFnZS4gLS0+XG4gIDxkaXYgKm5nSWY9XCJyZW5kZXIuc2hhcnBlbmluZyAmJiAhaW1nTG9hZGluZygpICYmICFzdGFja0xvYWRpbmcoKSAmJiAhaXNDYWNoaW5nKClcIiBjbGFzcz1cInNoYXJwZW5pbmctb3ZlcmxheVwiPlxuICAgIDxkaXYgY2xhc3M9XCJzcGlubmVyXCI+PC9kaXY+XG4gICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LWxvYWRpbmdcIj5TaGFycGVuaW5nIHByZXZpZXcuLi48L3NwYW4+XG4gIDwvZGl2PlxuPC9kaXY+XG5cbjwhLS0gRmxvYXRpbmcsIGRyYWdnYWJsZSBpbnRlbnNpdHktcHJvZmlsZSBpbnNldCwgc2hvd24gd2hpbGUgYW55IGludGVuc2l0eSBsaW5lXG4gICAgIGV4aXN0cy4gS2VwdCBPVVRTSURFIHRoZSBwbG90IGRpdiBhbmQgZml4ZWQgdG8gdGhlIHZpZXdwb3J0LCBzbyBpdCBmbG9hdHMgb3ZlclxuICAgICB0aGUgd2hvbGUgcGFnZSByYXRoZXIgdGhhbiBiZWluZyBjbGlwcGVkIHRvIHRoZSBjYW52YXMuIC0tPlxuPHZpei1pbnRlbnNpdHktaW5zZXRcbiAgW2RpdklkXT1cImludGVuc2l0eUluc2V0RGl2XCJcbiAgW3Bsb3REaXZOYW1lXT1cInBsb3REaXZOYW1lXCJcbiAgW3pJbmRleF09XCJ6SW5kZXhcIlxuICBbaW1hZ2VWaWV3XT1cImlzSW1hZ2VWaWV3XCJcbiAgW2ltYWdlSW5mb109XCJpbWFnZUluZm9cIlxuPjwvdml6LWludGVuc2l0eS1pbnNldD5cblxuPCEtLSBDaGFubmVscyAmIEhpc3RvZ3JhbTogbm9uLW1vZGFsIGZsb2F0aW5nIGRpYWxvZyBvcGVuZWQgZnJvbSB0aGUgdG9vbGJhci4gLS0+XG48Y2hhbm5lbC1oaXN0b2dyYW0gWyh2aXNpYmxlKV09XCJzaG93Q2hhbm5lbEhpc3RvZ3JhbVwiPjwvY2hhbm5lbC1oaXN0b2dyYW0+XG5cbjwhLS0gU3BhdGlhbC1vbWljcyBjb250cm9scy4gUmVuZGVycyBpdHMgb3duIGVtcHR5IHN0YXRlIHdoZW4gbm8gZGF0YXNldCAob3Igbm9cbiAgICAgU1BBVElBTF9EQVRBX1BPUlQpIGlzIHByZXNlbnQsIHNvIGl0IGlzIGFsd2F5cyBzYWZlIHRvIGhvc3QuIC0tPlxuPHNwYXRpYWwtY29udHJvbHMgWyh2aXNpYmxlKV09XCJzaG93U3BhdGlhbENvbnRyb2xzXCIgW2lzM2RdPVwiaXNTcGF0aWFsM2RNb2RlXCI+PC9zcGF0aWFsLWNvbnRyb2xzPlxuXG48IS0tIFNpZGUgcGFuZWwgb2YgdGhlIGFjdGl2ZSBjb250cmlidXRlZCBwbG90IG1vZGUgKFBMT1RfVFlQRV9DT05UUklCVVRJT05TKSxcbiAgICAgaW4gdGhlIHNhbWUgcmlnaHQtaGFuZCBhcmVhIGFzIHRoZSBzcGF0aWFsIGNvbnRyb2xzIGFuZCB0aGUgUmVnaW9uIEVkaXRvci5cbiAgICAgRXhpc3RzIG9ubHkgd2hpbGUgdGhlIG1vZGUncyBzZXNzaW9uIGlzIGxpdmU7IHRoZXJlIGlzIG5vIGNsb3NlIGJ1dHRvbixcbiAgICAgYmVjYXVzZSBsZWF2aW5nIHRoZSBtb2RlIGlzIHdoYXQgZW5kcyBpdC4gQSBjb21wb25lbnQgcGFuZWwgZ2V0c1xuICAgICBQTE9UX01PREVfQ09OVEVYVCAvIFBMT1RfTU9ERV9TRVNTSU9OIGZyb20gaXRzIGluamVjdG9yOyBhIGBtb3VudGAgcGFuZWwnc1xuICAgICBob3N0IGVsZW1lbnQgaXMgYXR0YWNoZWQgdG8gdGhlIHNsb3QgYmVsb3cgKHNlZSBwbG90TW9kZVBhbmVsU2xvdCkuIC0tPlxuPHAtZGlhbG9nXG4gICpuZ0lmPVwicGxvdE1vZGVQYW5lbCBhcyBwYW5lbFwiXG4gIFtoZWFkZXJdPVwicGFuZWwudGl0bGVcIlxuICBbdmlzaWJsZV09XCJ0cnVlXCJcbiAgW21vZGFsXT1cImZhbHNlXCJcbiAgW2Nsb3NhYmxlXT1cImZhbHNlXCJcbiAgW3Jlc2l6YWJsZV09XCJ0cnVlXCJcbiAgW2RyYWdnYWJsZV09XCJ0cnVlXCJcbiAgYXBwZW5kVG89XCJib2R5XCJcbiAgcG9zaXRpb249XCJyaWdodFwiXG4gIHN0eWxlQ2xhc3M9XCJwbG90LW1vZGUtcGFuZWxcIlxuICBbc3R5bGVdPVwieyB3aWR0aDogJzIycmVtJywgbWF4SGVpZ2h0OiAnODV2aCcgfVwiXG4gIFtjb250ZW50U3R5bGVdPVwieyBvdmVyZmxvdzogJ2F1dG8nIH1cIlxuPlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwicGFuZWwuY29tcG9uZW50XCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdDb21wb25lbnRPdXRsZXQ9XCJwYW5lbC5jb21wb25lbnQ7IGluamVjdG9yOiBwYW5lbC5pbmplY3RvciA/PyB1bmRlZmluZWRcIj48L25nLWNvbnRhaW5lcj5cbiAgPC9uZy1jb250YWluZXI+XG4gIDxkaXYgKm5nSWY9XCJwYW5lbC5ob3N0XCIgI3Bsb3RNb2RlUGFuZWxTbG90IGNsYXNzPVwicGxvdC1tb2RlLXBhbmVsLXNsb3RcIj48L2Rpdj5cbjwvcC1kaWFsb2c+XG5cbjwhLS0gQW4gb3BlbiBkaWFsb2cgdG9vbCAoVE9PTEJBUl9UT09MUywga2luZDogJ2RpYWxvZycpLiBOb24tbW9kYWwgc28gdGhlIHVzZXIgY2FuXG4gICAgIGtlZXAgd29ya2luZyBvbiB0aGUgaW1hZ2UsIGUuZy4gcGFpbnRpbmcgd2l0aCB0aGUgYnJ1c2ggdGhlIHRvb2wgYXJtZWQuIFRoZVxuICAgICB0b29sIHJlbmRlcnMgaXRzIGJvZHkgaW50byBhIGhvc3QgZWxlbWVudCBhdHRhY2hlZCB0byB0aGUgc2xvdCBiZWxvdyAoc2VlXG4gICAgIHRvb2xEaWFsb2dTbG90KTsgY2xvc2luZyB0aGUgZGlhbG9nIGVuZHMgdGhlIHRvb2wncyBzZXNzaW9uLiAtLT5cbjxwLWRpYWxvZ1xuICAqbmdJZj1cInRvb2xEaWFsb2cgYXMgZGxnXCJcbiAgW2hlYWRlcl09XCJkbGcudGl0bGVcIlxuICBbdmlzaWJsZV09XCJ0cnVlXCJcbiAgKHZpc2libGVDaGFuZ2UpPVwiJGV2ZW50IHx8IGNsb3NlRGlhbG9nVG9vbCgpXCJcbiAgW21vZGFsXT1cImZhbHNlXCJcbiAgW2Nsb3NhYmxlXT1cInRydWVcIlxuICBbcmVzaXphYmxlXT1cInRydWVcIlxuICBbZHJhZ2dhYmxlXT1cInRydWVcIlxuICBhcHBlbmRUbz1cImJvZHlcIlxuICBwb3NpdGlvbj1cInJpZ2h0XCJcbiAgc3R5bGVDbGFzcz1cInRvb2wtZGlhbG9nXCJcbiAgW3N0eWxlXT1cInsgd2lkdGg6IGRsZy53aWR0aCwgbWF4SGVpZ2h0OiAnODV2aCcgfVwiXG4gIFtjb250ZW50U3R5bGVdPVwieyBvdmVyZmxvdzogJ2F1dG8nIH1cIlxuPlxuICA8ZGl2ICN0b29sRGlhbG9nU2xvdCBjbGFzcz1cInRvb2wtZGlhbG9nLXNsb3RcIj48L2Rpdj5cbjwvcC1kaWFsb2c+XG5cbjwhLS0gUmVnaW9uIEVkaXRvcjogbm9uLW1vZGFsLCBkcmFnZ2FibGUsIHJlc2l6YWJsZSBmbG9hdGluZyBkaWFsb2cgb3BlbmVkIGZyb21cbiAgICAgdGhlIHRvb2xiYXIgKGZvcm1lcmx5IHRoZSByaWdodC1wYW5lbCBSZWdpb25zIHRhYikuIE1vZGVsZXNzIHNvIHJlZ2lvbnMgY2FuXG4gICAgIHN0aWxsIGJlIGRyYXduL3NlbGVjdGVkIG9uIHRoZSBwbG90IHdoaWxlIGl0J3Mgb3Blbjsgc3RheXMgbGlua2VkIHRvIHRoaXNcbiAgICAgcGxvdHRpbmcgaW5zdGFuY2UgdmlhIHRoZSByb290IFJlZ2lvblN0b3JlIHNpbmdsZXRvbi4gT3BlbnMgb3ZlciB0aGUgcmlnaHRcbiAgICAgc2lkZSBvZiB0aGUgdmlldy4gLS0+XG48cC1kaWFsb2dcbiAgaGVhZGVyPVwiUmVnaW9uIEVkaXRvclwiXG4gIFsodmlzaWJsZSldPVwic2hvd1JlZ2lvbkVkaXRvclwiXG4gIFttb2RhbF09XCJmYWxzZVwiXG4gIFtyZXNpemFibGVdPVwidHJ1ZVwiXG4gIFtkcmFnZ2FibGVdPVwidHJ1ZVwiXG4gIFttYXhpbWl6YWJsZV09XCJ0cnVlXCJcbiAgYXBwZW5kVG89XCJib2R5XCJcbiAgcG9zaXRpb249XCJyaWdodFwiXG4gIFtzdHlsZV09XCJ7IHdpZHRoOiByZWdpb25FZGl0b3JXaWR0aCwgaGVpZ2h0OiAnODV2aCcgfVwiXG4gIFtjb250ZW50U3R5bGVdPVwieyBvdmVyZmxvdzogJ2F1dG8nIH1cIlxuPlxuICA8cmVnaW9uLWVkaXRvcj48L3JlZ2lvbi1lZGl0b3I+XG48L3AtZGlhbG9nPlxuXG48IS0tIFNpbXBsaWZ5IChEb3VnbGFz4oCTUGV1Y2tlcik6IGN1c3RvbSBweC10aHJlc2hvbGQgcGlja2VyIGZvciB0aGUgc2VsZWN0ZWRcbiAgICAgcmVnaW9uKHMpLCBvcGVuZWQgZnJvbSB0aGUgcmlnaHQtY2xpY2sgXCJTaW1wbGlmeSDilrggQ3VzdG9t4oCmXCIgYWN0aW9uLiAtLT5cbjxwLWRpYWxvZ1xuICBoZWFkZXI9XCJTaW1wbGlmeSByZWdpb24ocylcIlxuICBbKHZpc2libGUpXT1cImRpc3BsYXlTaW1wbGlmeURpYWxvZ1wiXG4gIFttb2RhbF09XCJ0cnVlXCJcbiAgW3N0eWxlXT1cInsgd2lkdGg6ICcyMnJlbScgfVwiXG4gIFtkcmFnZ2FibGVdPVwiZmFsc2VcIlxuICBbcmVzaXphYmxlXT1cImZhbHNlXCJcbj5cbiAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1jb2x1bW4gZ2FwLTJcIj5cbiAgICA8c3BhblxuICAgICAgPkFsdGl0dWRlIHRocmVzaG9sZDogPGI+e3sgcmVnaW9uQWN0aW9ucy5zaW1wbGlmeVRocmVzaG9sZCB9fSBweDwvYj48L3NwYW5cbiAgICA+XG4gICAgPHAtc2xpZGVyIFsobmdNb2RlbCldPVwicmVnaW9uQWN0aW9ucy5zaW1wbGlmeVRocmVzaG9sZFwiIFttaW5dPVwiMVwiIFttYXhdPVwiMjBcIiBbc3RlcF09XCIxXCI+PC9wLXNsaWRlcj5cbiAgICA8c21hbGw+VmVydGljZXMgd2l0aGluIHRoaXMgZGlzdGFuY2Ugb2YgdGhlIGxpbmUgYmV0d2VlbiB0aGVpciBuZWlnaGJvdXJzIGFyZSByZW1vdmVkLjwvc21hbGw+XG4gIDwvZGl2PlxuICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiZm9vdGVyXCI+XG4gICAgPHAtYnV0dG9uIGxhYmVsPVwiQ2FuY2VsXCIgW3RleHRdPVwidHJ1ZVwiIChvbkNsaWNrKT1cImRpc3BsYXlTaW1wbGlmeURpYWxvZyA9IGZhbHNlXCI+PC9wLWJ1dHRvbj5cbiAgICA8cC1idXR0b25cbiAgICAgIGxhYmVsPVwiQXBwbHlcIlxuICAgICAgaWNvbj1cInBpIHBpLWNoZWNrXCJcbiAgICAgIChvbkNsaWNrKT1cInNpbXBsaWZ5UmVnaW9ucyhyZWdpb25BY3Rpb25zLnNpbXBsaWZ5VGhyZXNob2xkKVwiXG4gICAgPjwvcC1idXR0b24+XG4gIDwvbmctdGVtcGxhdGU+XG48L3AtZGlhbG9nPlxuXG48IS0tIFBhcmFtZXRlcnMgZm9yIHdoaWNoZXZlciBjb250cmlidXRlZCB0b29sIGlzIG9wZW4uIE9uZSBkaWFsb2cgZm9yIGFsbCBvZlxuICAgICB0aGVtOiBhIHRvb2wgZGVjbGFyZXMgaXRzIGZpZWxkcyAoVG9vbFBhcmFtU3BlYykgYW5kIHRoaXMgcmVuZGVycyB0aGVtLCBzb1xuICAgICB0aGUgdG9vbGJhciBjYW4gbGF5IGV2ZXJ5IHRvb2wgb3V0IHRoZSBzYW1lIHdheSBhbmQgYSBwbHVnaW4gbmVlZHMgbm9cbiAgICAgUHJpbWVORyBvZiBpdHMgb3duLiBEZWZhdWx0cyBjb21lIGZyb20gdGhlIGFjdGl2ZSBjaGVja3BvaW50LCBzaW5jZSB0aGV5XG4gICAgIGVuY29kZSB3aGF0IGl0IHdhcyB0cmFpbmVkIGZvci4gLS0+XG48cC1kaWFsb2dcbiAgKm5nSWY9XCJ0b29sUGFyYW1zLm9wZW5QYXJhbXMgYXMgb3BlblwiXG4gIFtoZWFkZXJdPVwib3Blbi50b29sLmxhYmVsICsgJyBwYXJhbWV0ZXJzJ1wiXG4gIFt2aXNpYmxlXT1cInRydWVcIlxuICAodmlzaWJsZUNoYW5nZSk9XCJjbG9zZVRvb2xQYXJhbXMoKVwiXG4gIFttb2RhbF09XCJ0cnVlXCJcbiAgW3N0eWxlXT1cInsgd2lkdGg6ICczMHJlbScgfVwiXG4gIFtkcmFnZ2FibGVdPVwiZmFsc2VcIlxuICBbcmVzaXphYmxlXT1cImZhbHNlXCJcbiAgYXBwZW5kVG89XCJib2R5XCJcbj5cbiAgPGRpdiBjbGFzcz1cImdyaWQgZm9ybWdyaWQgcC1mbHVpZFwiPlxuICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGYgb2Ygb3Blbi5maWVsZHNcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZFwiIFtuZ0NsYXNzXT1cImYuc3BlYy50eXBlID09PSAnYm9vbGVhbicgPyAnY29sLTEyJyA6ICdjb2wtNidcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImYubnVtYmVyIGFzIG5cIj5cbiAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJ0ZXh0LXNtXCIgW3BUb29sdGlwXT1cIm4udG9vbHRpcCB8fCAnJ1wiPnt7IG4ubGFiZWwgfX08L2xhYmVsPlxuICAgICAgICAgIDxwLWlucHV0TnVtYmVyXG4gICAgICAgICAgICBbbmdNb2RlbF09XCJvcGVuLnZhbHVlc1tuLmlkXVwiXG4gICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJvcGVuLnZhbHVlc1tuLmlkXSA9ICRldmVudFwiXG4gICAgICAgICAgICBbbWluXT1cIm4ubWluXCJcbiAgICAgICAgICAgIFttYXhdPVwibi5tYXhcIlxuICAgICAgICAgICAgW3N0ZXBdPVwibi5zdGVwXCJcbiAgICAgICAgICAgIFttaW5GcmFjdGlvbkRpZ2l0c109XCJuLmZyYWN0aW9uRGlnaXRzXCJcbiAgICAgICAgICAgIFtzaG93QnV0dG9uc109XCJ0cnVlXCJcbiAgICAgICAgICA+PC9wLWlucHV0TnVtYmVyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZi5zZWxlY3QgYXMgc2VsXCI+XG4gICAgICAgICAgPGxhYmVsIGNsYXNzPVwidGV4dC1zbVwiIFtwVG9vbHRpcF09XCJzZWwudG9vbHRpcCB8fCAnJ1wiPnt7IHNlbC5sYWJlbCB9fTwvbGFiZWw+XG4gICAgICAgICAgPHAtZHJvcGRvd25cbiAgICAgICAgICAgIFtvcHRpb25zXT1cInNlbC5vcHRpb25zXCJcbiAgICAgICAgICAgIG9wdGlvbkxhYmVsPVwibGFiZWxcIlxuICAgICAgICAgICAgb3B0aW9uVmFsdWU9XCJ2YWx1ZVwiXG4gICAgICAgICAgICBbbmdNb2RlbF09XCJvcGVuLnZhbHVlc1tzZWwuaWRdXCJcbiAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIm9wZW4udmFsdWVzW3NlbC5pZF0gPSAkZXZlbnRcIlxuICAgICAgICAgICAgYXBwZW5kVG89XCJib2R5XCJcbiAgICAgICAgICA+PC9wLWRyb3Bkb3duPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8IS0tIENoZWNrYm94IGxhYmVsIHNpdHMgYmVzaWRlIHRoZSBib3ggYW5kIG1heSBydW4gdG8gYSBzZW50ZW5jZSwgc29cbiAgICAgICAgICAgICBpdCBkb2VzIG5vdCBnZXQgdGhlIHN0YWNrZWQgbGFiZWwgdGhlIG90aGVyIHR5cGVzIHVzZS4gLS0+XG4gICAgICAgIDxkaXYgKm5nSWY9XCJmLnNwZWMudHlwZSA9PT0gJ2Jvb2xlYW4nXCIgY2xhc3M9XCJmbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBnYXAtMlwiPlxuICAgICAgICAgIDxwLWNoZWNrYm94XG4gICAgICAgICAgICBbbmdNb2RlbF09XCJvcGVuLnZhbHVlc1tmLnNwZWMuaWRdXCJcbiAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIm9wZW4udmFsdWVzW2Yuc3BlYy5pZF0gPSAkZXZlbnRcIlxuICAgICAgICAgICAgW2JpbmFyeV09XCJ0cnVlXCJcbiAgICAgICAgICAgIFtpbnB1dElkXT1cIm9wZW4udG9vbC5pZCArICctJyArIGYuc3BlYy5pZFwiXG4gICAgICAgICAgPjwvcC1jaGVja2JveD5cbiAgICAgICAgICA8bGFiZWwgW2Zvcl09XCJvcGVuLnRvb2wuaWQgKyAnLScgKyBmLnNwZWMuaWRcIiBjbGFzcz1cInRleHQtc20gbWItMFwiIFtwVG9vbHRpcF09XCJmLnNwZWMudG9vbHRpcCB8fCAnJ1wiPnt7XG4gICAgICAgICAgICBmLnNwZWMubGFiZWxcbiAgICAgICAgICB9fTwvbGFiZWw+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9uZy1jb250YWluZXI+XG4gIDwvZGl2PlxuICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiZm9vdGVyXCI+XG4gICAgPHAtYnV0dG9uXG4gICAgICBsYWJlbD1cIlJlc2V0IHRvIG1vZGVsIGRlZmF1bHRzXCJcbiAgICAgIFt0ZXh0XT1cInRydWVcIlxuICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgIChvbkNsaWNrKT1cInJlc2V0VG9vbFBhcmFtcyhvcGVuLnRvb2wuaWQpXCJcbiAgICA+PC9wLWJ1dHRvbj5cbiAgICA8cC1idXR0b24gbGFiZWw9XCJDbG9zZVwiIHNpemU9XCJzbWFsbFwiIChvbkNsaWNrKT1cImNsb3NlVG9vbFBhcmFtcygpXCI+PC9wLWJ1dHRvbj5cbiAgPC9uZy10ZW1wbGF0ZT5cbjwvcC1kaWFsb2c+XG4iXX0=
|
|
1295
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlzdWFsaXplci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3Zpc3VhbGl6ZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vc3JjL2xpYi92aXN1YWxpemVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFFTCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsVUFBVSxFQUNWLFlBQVksRUFDWixNQUFNLEVBQ04sUUFBUSxFQUNSLEtBQUssRUFDTCxNQUFNLEVBSU4sUUFBUSxFQUNSLE1BQU0sRUFFTixTQUFTLEVBQ1QsUUFBUSxFQUNSLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUU3QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRWxDLE9BQU8sRUFBWSxjQUFjLEVBQUUsWUFBWSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3JFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3JFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDbEQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0scUJB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QWdCIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQWZ0ZXJWaWV3SW5pdCxcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIERlc3Ryb3lSZWYsXG4gIEVsZW1lbnRSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5qZWN0LFxuICBJbmplY3RvcixcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25DaGFuZ2VzLFxuICBPbkRlc3Ryb3ksXG4gIE9uSW5pdCxcbiAgT3B0aW9uYWwsXG4gIE91dHB1dCxcbiAgU2ltcGxlQ2hhbmdlcyxcbiAgVmlld0NoaWxkLFxuICBjb21wdXRlZCxcbiAgc2lnbmFsLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHsgRm9ybXNNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5cbmltcG9ydCB7IE9ic2VydmFibGUgfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgTWVudUl0ZW0sIE1lc3NhZ2VTZXJ2aWNlLCBTaGFyZWRNb2R1bGUgfSBmcm9tICdwcmltZW5nL2FwaSc7XG5pbXBvcnQgeyBCdXR0b25Nb2R1bGUgfSBmcm9tICdwcmltZW5nL2J1dHRvbic7XG5pbXBvcnQgeyBDaGVja2JveE1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvY2hlY2tib3gnO1xuaW1wb3J0IHsgQ29udGV4dE1lbnUsIENvbnRleHRNZW51TW9kdWxlIH0gZnJvbSAncHJpbWVuZy9jb250ZXh0bWVudSc7XG5pbXBvcnQgeyBEaWFsb2dNb2R1bGUgfSBmcm9tICdwcmltZW5nL2RpYWxvZyc7XG5pbXBvcnQgeyBEcm9wZG93bk1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvZHJvcGRvd24nO1xuaW1wb3J0IHsgSW5wdXROdW1iZXJNb2R1bGUgfSBmcm9tICdwcmltZW5nL2lucHV0bnVtYmVyJztcbmltcG9ydCB7IFByb2dyZXNzQmFyTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9wcm9ncmVzc2Jhcic7XG5pbXBvcnQgeyBTbGlkZXJNb2R1bGUgfSBmcm9tICdwcmltZW5nL3NsaWRlcic7XG5pbXBvcnQgeyBUb2FzdE1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvdG9hc3QnO1xuaW1wb3J0IHsgVG9vbHRpcE1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvdG9vbHRpcCc7XG5pbXBvcnQgeyBJSW1hZ2VJbmZvIH0gZnJvbSAnLi9jb250cmFjdHMvaW1hZ2UuY29udHJhY3QnO1xuaW1wb3J0IHsgSW1hZ2VTdGF0ZVBvcnQsIElNQUdFX1NUQVRFX1BPUlQgfSBmcm9tICcuL2NvbnRyYWN0cy9wb3J0cy9pbWFnZS1zdGF0ZS5wb3J0JztcbmltcG9ydCB7IFBvbHlnb24gfSBmcm9tICcuL21vZGVscy9yZWdpb24nO1xuaW1wb3J0IHsgUmVnaW9uT3BzU2VydmljZSB9IGZyb20gJy4vcmVnaW9uLW9wcy5zZXJ2aWNlJztcbmltcG9ydCB7IFZJWl9UT0FTVF9LRVksIFZJWl9BTEVSVF9UT0FTVF9LRVkgfSBmcm9tICcuL3RvYXN0LW91dGxldHMnO1xuaW1wb3J0IHsgVmlzdWFsaXplclN0b3JlIH0gZnJvbSAnLi9zdG9yZS92aXN1YWxpemVyLXN0b3JlLnNlcnZpY2UnO1xuaW1wb3J0IHsgU2xpY2VTY3J1YmJlciB9IGZyb20gJy4vcmVuZGVyLW9yY2hlc3RyYXRvcic7XG5pbXBvcnQgeyBJbWFnZVJlbmRlclNlc3Npb24sIGVycm9yTWVzc2FnZSB9IGZyb20gJy4vcmVuZGVyLXNlc3Npb24nO1xuaW1wb3J0IHtcbiAgUGxvdFR5cGUsXG4gIFBsb3RUeXBlRGVzY3JpcHRvcixcbiAgUGxvdFR5cGVJZCxcbiAgZ2V0UGxvdFR5cGVEZXNjcmlwdG9yLFxuICBpc0J1aWx0aW5QbG90VHlwZSxcbiAgaXNOYXBhcmkzZCxcbiAgaXNTcGF0aWFsT21pY3MsXG4gIGlzU3BhdGlhbE9taWNzM2QsXG4gIHJlbmRlcmVyT3duc1doZWVsLFxuICBOQVBBUklfREVGQVVMVF9ERUNJTUFURSxcbiAgaXNOYXBhcmlWb2x1bWUsXG4gIGlzTmFwYXJpSXNvc3VyZmFjZSxcbn0gZnJvbSAnLi9jb250cmFjdHMvcGxvdC10eXBlJztcbmltcG9ydCB7XG4gIFBMT1RfVFlQRV9DT05UUklCVVRJT05TLFxuICBQbG90VHlwZUNvbnRyaWJ1dGlvbixcbiAgUGxvdFR5cGVPcHRpb24sXG59IGZyb20gJy4vY29udHJhY3RzL3Bsb3QtdHlwZS1jb250cmlidXRpb24uY29udHJhY3QnO1xuaW1wb3J0IHsgUGxvdE1vZGVDb250cm9sbGVyIH0gZnJvbSAnLi9wbG90LW1vZGUvcGxvdC1tb2RlLWNvbnRyb2xsZXInO1xuaW1wb3J0IHsgY29tcHV0ZVBsb3RUeXBlTWVudSwgcmVjb25jaWxlUGxvdFR5cGUgfSBmcm9tICcuL3Bsb3QtbW9kZS9wbG90LXR5cGUtbWVudSc7XG5pbXBvcnQgeyBUb29sUGFyYW1zTW9kZWwgfSBmcm9tICcuL3Bsb3QtbW9kZS90b29sLXBhcmFtcy1tb2RlbCc7XG5pbXBvcnQgeyBDb250cmlidXRpb25Ib3N0LCBQbG90TW9kZVBhbmVsVmlldywgVG9vbERpYWxvZ1ZpZXcgfSBmcm9tICcuL3Bsb3QtbW9kZS9jb250cmlidXRpb24taG9zdCc7XG5pbXBvcnQgeyBJVmlzdWFsaXplciwgVklTVUFMSVpFUiwgVmlzdWFsaXplckhhbmRsZSB9IGZyb20gJy4vY29udHJhY3RzL3Zpc3VhbGl6ZXIuY29udHJhY3QnO1xuaW1wb3J0IHsgU0FNX01PREVMUywgZ2V0RGVmYXVsdFNhbU1vZGVsSWQsIGlzU2FtTW9kZWxSZWFkeSB9IGZyb20gJy4vdG9vbGJhci9zZWdtZW50YXRpb24vc2FtLW1vZGVsLXJlZ2lzdHJ5JztcbmltcG9ydCB7IFNhbVRvb2xTZXJ2aWNlIH0gZnJvbSAnLi90b29sYmFyL3NlZ21lbnRhdGlvbi9zYW0tdG9vbC5zZXJ2aWNlJztcbmltcG9ydCB7IFNhbVBvaW50VG9vbFNlcnZpY2UgfSBmcm9tICcuL3Rvb2xiYXIvc2VnbWVudGF0aW9uL3NhbS1wb2ludC10b29sLnNlcnZpY2UnO1xuaW1wb3J0IHsgQ2VsbFNlZ21lbnRUb29sU2VydmljZSB9IGZyb20gJy4vdG9vbGJhci9zZWdtZW50YXRpb24vY2VsbC1zZWdtZW50LXRvb2wuc2VydmljZSc7XG5pbXBvcnQgeyBTZWdtZW50YXRpb25SdW5uZXIgfSBmcm9tICcuL3Rvb2xiYXIvc2VnbWVudGF0aW9uL3NlZ21lbnRhdGlvbi1ydW5uZXInO1xuaW1wb3J0IHtcbiAgVE9PTEJBUl9UT09MUyxcbiAgVG9vbGJhckNvbnRyaWJ1dGlvbixcbiAgVG9vbGJhckRpYWxvZ1Rvb2xDb250cmlidXRpb24sXG4gIFRvb2xiYXJUb29sQ29udHJpYnV0aW9uLFxuICB2aXNpYmxlVG9vbENvbnRyaWJ1dGlvbnMsXG59IGZyb20gJy4vY29udHJhY3RzL3Rvb2xiYXItdG9vbC5jb250cmFjdCc7XG5pbXBvcnQgeyBUb29sYmFyVG9vbFZpc2liaWxpdHksIEFMTF9UT09MQkFSX1RPT0xTIH0gZnJvbSAnLi9jb250cmFjdHMvdG9vbGJhci1jb25maWcnO1xuaW1wb3J0IHsgVklaX0NPTkZJRywgVml6Q29uZmlnIH0gZnJvbSAnLi9jb250cmFjdHMvdml6LWNvbmZpZyc7XG5pbXBvcnQgeyBTUEFUSUFMX0RBVEFfUE9SVCwgU3BhdGlhbERhdGFQb3J0IH0gZnJvbSAnLi9jb250cmFjdHMvcG9ydHMvc3BhdGlhbC1kYXRhLnBvcnQnO1xuaW1wb3J0IHsgYXBwbHlJbWFnZVJvaXMgfSBmcm9tICcuL3Zpc3VhbGl6ZXIvcmVnaW9uLWxvYWQnO1xuaW1wb3J0IHsgQ29udGV4dE1lbnVBY3Rpb25zLCBDb250ZXh0TWVudVN0YXRlLCBidWlsZENvbnRleHRNZW51IH0gZnJvbSAnLi92aXN1YWxpemVyL3Zpc3VhbGl6ZXItY29udGV4dC1tZW51JztcbmltcG9ydCB7IFJlZ2lvbkFjdGlvbnMgfSBmcm9tICcuL3Zpc3VhbGl6ZXIvcmVnaW9uLWFjdGlvbnMnO1xuaW1wb3J0IHsgVG9vbE1vZGVzIH0gZnJvbSAnLi92aXN1YWxpemVyL3Rvb2wtbW9kZXMnO1xuaW1wb3J0IHsgU2hvcnRjdXRIb3N0LCBWaWV3ZXJTaG9ydGN1dHMgfSBmcm9tICcuL3Zpc3VhbGl6ZXIvdmlld2VyLXNob3J0Y3V0cyc7XG5pbXBvcnQgeyBGbG9hdGluZ0RyYWdEaXJlY3RpdmUsIEZsb2F0aW5nUG9zIH0gZnJvbSAnLi92aXN1YWxpemVyL2Zsb2F0aW5nLWRyYWcuZGlyZWN0aXZlJztcbmltcG9ydCB7IEludGVuc2l0eUluc2V0Q29tcG9uZW50IH0gZnJvbSAnLi9pbnRlbnNpdHktaW5zZXQvaW50ZW5zaXR5LWluc2V0LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTZWN0aW9uUGFuZUNvbXBvbmVudCB9IGZyb20gJy4vc2VjdGlvbi1wYW5lL3NlY3Rpb24tcGFuZS5jb21wb25lbnQnO1xuaW1wb3J0IHR5cGUgeyBTZWN0aW9uQXhpcywgU2VjdGlvblZpZXdzIH0gZnJvbSAnLi9jb250cmFjdHMvc2VjdGlvbi12aWV3LmNvbnRyYWN0JztcbmltcG9ydCB7IFNwYXRpYWxEYXRhc2V0QmluZGVyIH0gZnJvbSAnLi92aXN1YWxpemVyL3NwYXRpYWwtZGF0YXNldC1iaW5kZXInO1xuaW1wb3J0IHsgVG9vbGJhckNvbXBvbmVudCB9IGZyb20gJy4vdG9vbGJhci90b29sYmFyLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBSZWdpb25FZGl0b3JDb21wb25lbnQgfSBmcm9tICcuL3JlZ2lvbi1lZGl0b3IvcmVnaW9uLWVkaXRvci5jb21wb25lbnQnO1xuaW1wb3J0IHsgQ2hhbm5lbEhpc3RvZ3JhbUNvbXBvbmVudCB9IGZyb20gJy4vY2hhbm5lbC1oaXN0b2dyYW0vY2hhbm5lbC1oaXN0b2dyYW0uY29tcG9uZW50JztcbmltcG9ydCB7IFNwYXRpYWxDb250cm9sc0NvbXBvbmVudCB9IGZyb20gJy4vc3BhdGlhbC1jb250cm9scy9zcGF0aWFsLWNvbnRyb2xzLmNvbXBvbmVudCc7XG5cbi8qKiBQZXItaW5zdGFuY2UgcGxvdC1kaXYgaWQgc291cmNlLiBUaGUgbW91bnQgZWxlbWVudCdzIGlkIG11c3QgYmUgdW5pcXVlIHNvIHR3b1xuICogIGxpdmUgdmlld2VycyAoZS5nLiB0aGUgbWFpbiBkaWFncmFtICsgYSBtb2RhbCBwcmV2aWV3KSBkb24ndCBjb2xsaWRlIG9uIHRoZVxuICogIHNhbWUgRE9NIGlkIOKAlCBgZ2V0RWxlbWVudEJ5SWRgIHdvdWxkIG90aGVyd2lzZSByZXR1cm4gd2hpY2hldmVyIGNhbWUgZmlyc3QuXG4gKiAgU3R5bGluZyBoYW5ncyBvZmYgdGhlIGAudml6LXBsb3RgIGNsYXNzIGluc3RlYWQgb2YgdGhlIGlkLiAqL1xubGV0IHBsb3RJbnN0YW5jZVNlcSA9IDA7XG5cbi8qKlxuICogVGhlIHZpZXdlciAoYDx2aXN1YWxpemVyPmApOiB0aGUgcGxvdCBzdXJmYWNlLCBpdHMgdG9vbGJhciwgdGhlIGxvYWRpbmcgb3ZlcmxheSBhbmRcbiAqIHRoZSBkaWFsb2dzIGl0IG9wZW5zIChDaGFubmVscyAmIEhpc3RvZ3JhbSwgc3BhdGlhbC1vbWljcyBjb250cm9scywgUmVnaW9uIEVkaXRvcixcbiAqIGNvbnRyaWJ1dGVkIG1vZGVzIGFuZCB0b29scykuIEl0IG9yY2hlc3RyYXRlcyByZW5kZXJpbmcgdGhyb3VnaCB0aGUgYFZJU1VBTElaRVJgXG4gKiBjb250cmFjdCBhbmQgcmVhZHMgdGhlIGltYWdlIGZyb20gdGhlIGhvc3QncyBgSU1BR0VfU1RBVEVfUE9SVGAuXG4gKlxuICogT25QdXNoLiBUZW1wbGF0ZSBldmVudHMgcmUtcmVuZGVyIGl0OyBzdGF0ZSB0aGF0IGxhbmRzIGFzeW5jaHJvbm91c2x5IGdvZXMgdGhyb3VnaFxuICoge0BsaW5rIGNoYW5nZWR9IChvciBhIHNpZ25hbDogdGhlIGxvYWRpbmcgb3ZlcmxheSksIGFuZCB0aGUgY29sbGFib3JhdG9ycyB0aGF0IG11c3RcbiAqIHJlbmRlciBzeW5jaHJvbm91c2x5ICh0aGUgcmVuZGVyIHNlc3Npb24ncyBvdmVybGF5LCBhIGNvbnRyaWJ1dGVkIHBhbmVsJ3Mgc2xvdCwgdGhlXG4gKiBjb250ZXh0IG1lbnUgYmVmb3JlIGl0IG9wZW5zKSBzdGlsbCBjYWxsIGBkZXRlY3RDaGFuZ2VzKClgLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd2aXN1YWxpemVyJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZSxcbiAgICBGb3Jtc01vZHVsZSxcbiAgICBTaGFyZWRNb2R1bGUsXG4gICAgQnV0dG9uTW9kdWxlLFxuICAgIENoZWNrYm94TW9kdWxlLFxuICAgIENvbnRleHRNZW51TW9kdWxlLFxuICAgIERpYWxvZ01vZHVsZSxcbiAgICBEcm9wZG93bk1vZHVsZSxcbiAgICBJbnB1dE51bWJlck1vZHVsZSxcbiAgICBQcm9ncmVzc0Jhck1vZHVsZSxcbiAgICBTbGlkZXJNb2R1bGUsXG4gICAgVG9hc3RNb2R1bGUsXG4gICAgVG9vbHRpcE1vZHVsZSxcbiAgICBGbG9hdGluZ0RyYWdEaXJlY3RpdmUsXG4gICAgVG9vbGJhckNvbXBvbmVudCxcbiAgICBJbnRlbnNpdHlJbnNldENvbXBvbmVudCxcbiAgICBTZWN0aW9uUGFuZUNvbXBvbmVudCxcbiAgICBDaGFubmVsSGlzdG9ncmFtQ29tcG9uZW50LFxuICAgIFNwYXRpYWxDb250cm9sc0NvbXBvbmVudCxcbiAgICBSZWdpb25FZGl0b3JDb21wb25lbnQsXG4gIF0sXG4gIHRlbXBsYXRlVXJsOiAnLi92aXN1YWxpemVyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vdmlzdWFsaXplci5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgVmlzdWFsaXplckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzLCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3ksIENvbnRleHRNZW51QWN0aW9ucyB7XG4gIC8qKiBQZXItaW5zdGFuY2UgdG9hc3Qga2V5LiBNZXNzYWdlU2VydmljZSBpcyBhIGdsb2JhbCBzaW5nbGV0b24sIHNvIHR3byBsaXZlXG4gICAqICBgPHZpc3VhbGl6ZXI+YCBpbnN0YW5jZXMgKG1haW4gdmlld2VyICsgcGlwZWxpbmUtZGlhbG9nIHByZXZpZXcpIHNoYXJpbmdcbiAgICogIG9uZSBrZXkgd291bGQgZWFjaCByZW5kZXIgdGhlIHNhbWUgbWVzc2FnZSDigJQgYSBkdXBsaWNhdGUgdG9hc3QuIEEgdW5pcXVlXG4gICAqICBrZXkgcGVyIGluc3RhbmNlIHNjb3BlcyB0aGUgdG9hc3QgdG8gdGhlIGNvbXBvbmVudCB0aGF0IHJhaXNlZCBpdC4gKi9cbiAgcHJpdmF0ZSBzdGF0aWMgbmV4dFRvYXN0SWQgPSAwO1xuXG4gIC8qKlxuICAgKiBUaGUgbGlicmFyeSBhbHNvIHJhaXNlcyBub3RpY2VzIGZyb20gcGxhY2VzIHRoYXQgaGF2ZSBubyBpbnN0YW5jZSBvZiB0aGVpclxuICAgKiBvd24gdG8ga2V5IGFnYWluc3Q6IHtAbGluayBQbG90bHlTZXJ2aWNlfSBpcyBgcHJvdmlkZWRJbjogJ3Jvb3QnYCwgYW5kIHRoZVxuICAgKiByZWdpb24gZWRpdG9yIGlzIGEgY2hpbGQgZGlhbG9nLiBUaG9zZSB1c2UgdGhlIGZpeGVkXG4gICAqIHtAbGluayBWSVpfVE9BU1RfS0VZfSAvIHtAbGluayBWSVpfQUxFUlRfVE9BU1RfS0VZfSBvdXRsZXRzLlxuICAgKlxuICAgKiBGb3IgdGhlIHNhbWUgcmVhc29uIHRoZSBwZXItaW5zdGFuY2Uga2V5IGFib3ZlIGV4aXN0cywgZXhhY3RseSBPTkUgbW91bnRlZFxuICAgKiB2aXN1YWxpemVyIG1heSByZW5kZXIgdGhvc2Ugc2hhcmVkIG91dGxldHMg4oCUIG90aGVyd2lzZSBhIG1lc3NhZ2UgZnJvbSB0aGVcbiAgICogcm9vdCBzZXJ2aWNlIHdvdWxkIGJlIHNob3duIG9uY2UgcGVyIGxpdmUgdmlld2VyIChqaXQtdWkgcnVucyBhIG1haW4gdmlld1xuICAgKiBhbmQgYSBwaXBlbGluZS1wcmV2aWV3IGF0IHRoZSBzYW1lIHRpbWUpLiBUaGUgZmlyc3QgdG8gaW5pdCBjbGFpbXMgdGhlbSBhbmRcbiAgICogcmVsZWFzZXMgb24gZGVzdHJveSwgc28gdGhlIHN1cnZpdmluZyB2aWV3ZXIgcGlja3MgdGhlbSB1cC5cbiAgICovXG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IGxpdmVJbnN0YW5jZXMgPSBuZXcgU2V0PFZpc3VhbGl6ZXJDb21wb25lbnQ+KCk7XG4gIHByb3RlY3RlZCByZWFkb25seSB2aXpUb2FzdEtleSA9IFZJWl9UT0FTVF9LRVk7XG4gIHByb3RlY3RlZCByZWFkb25seSB2aXpBbGVydFRvYXN0S2V5ID0gVklaX0FMRVJUX1RPQVNUX0tFWTtcbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhpcyBpbnN0YW5jZSByZW5kZXJzIHRoZSBzaGFyZWQgb3V0bGV0cy4gVGhlIG93bmVyIGlzIHNpbXBseSB0aGVcbiAgICogb2xkZXN0IGxpdmUgdmlzdWFsaXplciDigJQgYSBgU2V0YCBpdGVyYXRlcyBpbiBpbnNlcnRpb24gb3JkZXIsIHNvIHdoZW4gdGhlXG4gICAqIG93bmVyIGlzIGRlc3Ryb3llZCB0aGUgbmV4dCBvbmUgdGFrZXMgb3ZlciBvbiBpdHMgZm9sbG93aW5nIGNoYW5nZS1kZXRlY3Rpb25cbiAgICogcGFzcy4gVHJhY2tpbmcgYSBzZXQgcmF0aGVyIHRoYW4gYSBzaW5nbGUgb3duZXIgbWF0dGVyczogd2l0aCBhIGxvbmVcbiAgICogYG93bmVyYCByZWZlcmVuY2UsIHRlYXJpbmcgZG93biB0aGUgb3duZXIgd2hpbGUgYSBzaWJsaW5nIHdhcyBhbHJlYWR5XG4gICAqIGluaXRpYWxpc2VkIHdvdWxkIGxlYXZlIG5vYm9keSByZW5kZXJpbmcgdGhlIG91dGxldHMsIGFuZCBldmVyeSBub3RpY2UgZnJvbVxuICAgKiB0aGUgcm9vdCBzZXJ2aWNlIHdvdWxkIHNpbGVudGx5IHZhbmlzaCBhZ2Fpbi5cbiAgICovXG4gIHByb3RlY3RlZCBnZXQgb3duc1NoYXJlZFRvYXN0cygpOiBib29sZWFuIHtcbiAgICBjb25zdCBvbGRlc3QgPSBWaXN1YWxpemVyQ29tcG9uZW50LmxpdmVJbnN0YW5jZXMudmFsdWVzKCkubmV4dCgpO1xuICAgIHJldHVybiAhb2xkZXN0LmRvbmUgJiYgb2xkZXN0LnZhbHVlID09PSB0aGlzO1xuICB9XG5cbiAgLyoqIEVhY2ggbmV3IGltYWdlOiB3aGV0aGVyIGl0IGlzIGEgei1zdGFjay4gKi9cbiAgQE91dHB1dCgpXG4gIGlzU3RhY2tFdmVudCA9IG5ldyBFdmVudEVtaXR0ZXIoZmFsc2UpO1xuICAvKiogRWFjaCBuZXcgaW1hZ2U6IHdoZXRoZXIgaXQgaXMgc2luZ2xlLWNoYW5uZWwgKGdyYXlzY2FsZSkuICovXG4gIEBPdXRwdXQoKVxuICBpc0dyYXlzY2FsZUV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcihmYWxzZSk7XG5cbiAgLyoqIFdoaWNoIHRvb2xiYXIgZ3JvdXBzIHRvIHNob3cuIEEgcGFydGlhbCBvdmVycmlkZSBtZXJnZXMgb3ZlciB0aGUgZnVsbCBzZXQsXG4gICAqICBzbyBgeyBzcGVjaWFsVG9vbHM6IGZhbHNlIH1gIGhpZGVzIG9ubHkgdGhhdCBncm91cC4gRGVmYXVsdHMgdG8gZXZlcnl0aGluZy4gKi9cbiAgQElucHV0KClcbiAgc2V0IHRvb2xiYXJUb29scyh2OiBUb29sYmFyVG9vbFZpc2liaWxpdHkgfCB1bmRlZmluZWQpIHtcbiAgICB0aGlzLl90b29sYmFyVG9vbHMgPSB7IC4uLkFMTF9UT09MQkFSX1RPT0xTLCAuLi4odiA/PyB7fSkgfTtcbiAgfVxuXG4gIGdldCB0b29sYmFyVG9vbHMoKTogUmVxdWlyZWQ8VG9vbGJhclRvb2xWaXNpYmlsaXR5PiB7XG4gICAgcmV0dXJuIHRoaXMuX3Rvb2xiYXJUb29scztcbiAgfVxuICBwcml2YXRlIF90b29sYmFyVG9vbHM6IFJlcXVpcmVkPFRvb2xiYXJUb29sVmlzaWJpbGl0eT4gPSBBTExfVE9PTEJBUl9UT09MUztcblxuICAvKiogRXhwb3NlIHRlc3Qtb25seSBwbG90IG1vZGVzIGluIHRoZSBzZWxlY3RvciAoZS5nLiB0aGUgbmFwYXJpIGBJbWFnZWBcbiAgICogIG1vZGUsIG90aGVyd2lzZSBoaWRkZW4pLiBUaGUgaG9zdCBhcHAgc2V0cyB0aGlzIGZyb20gYSBgP3Rlc3Q9MWAgVVJMXG4gICAqICB0b2dnbGUuIE9mZiBieSBkZWZhdWx0LCBzbyBwcm9kdWN0aW9uIHVzZXJzIG5ldmVyIHNlZSB0aGVtLiAqL1xuICBASW5wdXQoKVxuICB0ZXN0TW9kZSA9IGZhbHNlO1xuXG4gIC8qKiBJbWFnZS1zbW9vdGhpbmcgc3RhdGUgZm9yIHRoZSB0b29sYmFyJ3MgU21vb3RoZW4gdG9nZ2xlIChPU0Qgb25seSkuXG4gICAqICBEZWZhdWx0cyB0byBgZmFsc2VgIHNvIE9TRCBzaG93cyByYXcgcGl4ZWxzIChuZWFyZXN0LW5laWdoYm91cikuICovXG4gIHByb3RlY3RlZCBpbWFnZVNtb290aGluZ0VuYWJsZWQgPSBmYWxzZTtcbiAgZmlsZU5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBsb2FkZWRGaWxlTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBwcm90ZWN0ZWQgaW1hZ2VJbmZvOiBJSW1hZ2VJbmZvIHwgdW5kZWZpbmVkO1xuXG4gIC8vIOKUgOKUgCBUaGUgbG9hZGluZyBvdmVybGF5LCBhcyBzaWduYWxzOiBpdCBpcyBmZWQgYnkgdGhlIGhvc3QncyBhbmQgdGhlIGJhY2tlbmRzJyBzdHJlYW1zXG4gIC8vIGFuZCBieSB0aGUgcmVuZGVyIHNlc3Npb24sIGFsbCBvZiB3aGljaCBsYW5kIG91dHNpZGUgdGhpcyB2aWV3J3MgdGVtcGxhdGUgZXZlbnRzLiDilIDilIBcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGxvYWRpbmdNZXNzYWdlID0gc2lnbmFsKCdMb2FkaW5nIGltYWdlLi4uJyk7XG4gIC8qKiBUaGUgaG9zdCBpcyBsb2FkaW5nIGF0IHpvb20gKHRoZSBvdmVybGF5IG1lc3NhZ2UgbW92ZXMgb3V0IG9mIHRoZSB3YXkpLiAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgem9vbSA9IHNpZ25hbChmYWxzZSk7XG4gIHByb3RlY3RlZCByZWFkb25seSBzdGFja0xvYWRpbmcgPSBzaWduYWwoZmFsc2UpO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgaW1nTG9hZGluZyA9IHNpZ25hbChmYWxzZSk7XG4gIHByb3RlY3RlZCByZWFkb25seSBsb2FkaW5nUGVyY2VudGFnZSA9IHNpZ25hbCgwKTtcbiAgLy8gTm9uLW51bGwgKDAuLjEwMCkgd2hpbGUgaml0LXNlcnZpY2UgaXMgY29weWluZyB0aGUgc291cmNlIGZpbGUgaW50byB0aGVcbiAgLy8gbG9jYWwgY2FjaGUgUFZDIG9uIGZpcnN0IGNsaWNrLiBXaGVuIHNldCwgdGhlIGxvYWRpbmcgb3ZlcmxheSBzd2FwcyB0aGVcbiAgLy8gc3Bpbm5lciBmb3IgYSBkZXRlcm1pbmF0ZSBwcm9ncmVzcyBiYXIgd2l0aCBhIFwiQ2FjaGluZyBpbWFnZVwiIG1lc3NhZ2UuXG4gIHByb3RlY3RlZCByZWFkb25seSBjYWNoZVByb2dyZXNzID0gc2lnbmFsPG51bWJlciB8IG51bGw+KG51bGwpO1xuICAvKiogQSBqaXQtc2VydmljZSBjYWNoZSBjb3B5IGlzIGFjdGl2ZWx5IGluIHByb2dyZXNzIChkZXRlcm1pbmF0ZSAwLi45OSkuIERyaXZlcyB0aGUgY2FjaGVcbiAgICogIHByb2dyZXNzIGJhciBpbmRlcGVuZGVudGx5IG9mIGBpbWdMb2FkaW5nYCBzbyB0aGUgYmFyIGNhbid0IGJlIGRyb3BwZWQg4oCUIG9yIG1hc2tlZCBieSB0aGVcbiAgICogIFwiU2hhcnBlbmluZyBwcmV2aWV3Li4uXCIgb3ZlcmxheSDigJQgbWlkLWRvd25sb2FkIGlmIHRoZSBsb2FkaW5nIGZsYWcgZmxpcHMgZWFybHkuICovXG4gIHByb3RlY3RlZCByZWFkb25seSBpc0NhY2hpbmcgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgY29uc3QgcCA9IHRoaXMuY2FjaGVQcm9ncmVzcygpO1xuICAgIHJldHVybiBwICE9PSBudWxsICYmIHAgPCAxMDA7XG4gIH0pO1xuXG4gIC8qKiBFbWl0cyBvbmNlIHdoZW4gdGhpcyB2aWV3IGlzIGRlc3Ryb3llZDsgdGhlIGNvbGxhYm9yYXRvcnMgZW5kIHRoZWlyIHN1YnNjcmlwdGlvbnMgb24gaXQuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgZGVzdHJveWVkJCA9IG5ldyBPYnNlcnZhYmxlPHZvaWQ+KChzdWJzY3JpYmVyKSA9PlxuICAgIHRoaXMuZGVzdHJveVJlZi5vbkRlc3Ryb3koKCkgPT4ge1xuICAgICAgc3Vic2NyaWJlci5uZXh0KCk7XG4gICAgICBzdWJzY3JpYmVyLmNvbXBsZXRlKCk7XG4gICAgfSksXG4gICk7XG4gIC8qKiBIb3N0IGltYWdlLWluZm8gb2JqZWN0cyB3aG9zZSBvbmUtc2hvdCBgaW5pdGlhbFpJbmRleGAgd2FzIGFscmVhZHkgYXBwbGllZC4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBjb25zdW1lZFNsaWNlSGludHMgPSBuZXcgV2Vha1NldDxJSW1hZ2VJbmZvPigpO1xuICBwcm90ZWN0ZWQgekluZGV4ID0gMDtcbiAgcHJvdGVjdGVkIG1heEluZGV4ID0gMDtcblxuICBAVmlld0NoaWxkKCdjbScpIGNvbnRleHRNZW51ITogQ29udGV4dE1lbnU7XG4gIHByb3RlY3RlZCBjb250ZXh0TWVudUl0ZW1zOiBNZW51SXRlbVtdID0gW107XG5cbiAgLyoqIFRoZSBhcm1lZCB0b29sIG1vZGUgYW5kIHRoZSB0b29sYmFyJ3MgdG9vbCBzZXR0aW5ncy4gKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHRvb2xzID0gbmV3IFRvb2xNb2RlcyhcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLFxuICAgIHRoaXMuc2Vzc2lvbixcbiAgICB0aGlzLm5nWm9uZSxcbiAgICAobW9kZSkgPT4ge1xuICAgICAgaWYgKG1vZGUgIT09ICdzYW1Qb2ludCcpIHRoaXMuc2VnbWVudGF0aW9uLmhpZGUoKTtcbiAgICB9LCAvLyBsZWF2aW5nIHBvaW50IG1vZGUgZHJvcHMgaXRzIHRvYXN0XG4gICAgKCkgPT4gdGhpcy5jaGFuZ2VkKCksXG4gICk7XG4gIHByb3RlY3RlZCBnZXQgYWN0aXZlRHJhZ01vZGUoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMudG9vbHMuYWN0aXZlO1xuICB9XG4gIHByb3RlY3RlZCBzZXQgYWN0aXZlRHJhZ01vZGUobW9kZTogc3RyaW5nIHwgbnVsbCkge1xuICAgIHRoaXMudG9vbHMuYWN0aXZlID0gbW9kZTtcbiAgfVxuICBwcm90ZWN0ZWQgZ2V0IHdhbmRTZW5zaXRpdml0eSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnRvb2xzLndhbmRTZW5zaXRpdml0eTtcbiAgfVxuICBwcm90ZWN0ZWQgc2V0IHdhbmRTZW5zaXRpdml0eSh2OiBudW1iZXIpIHtcbiAgICB0aGlzLnRvb2xzLndhbmRTZW5zaXRpdml0eSA9IHY7XG4gIH1cbiAgcHJvdGVjdGVkIGdldCBicnVzaFNpemUoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy50b29scy5icnVzaFNpemU7XG4gIH1cbiAgcHJvdGVjdGVkIGdldCB2ZXJ0ZXhFcmFzZXJSYWRpdXMoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy50b29scy52ZXJ0ZXhFcmFzZXJSYWRpdXM7XG4gIH1cbiAgcHJvdGVjdGVkIHNldCB2ZXJ0ZXhFcmFzZXJSYWRpdXModjogbnVtYmVyKSB7XG4gICAgdGhpcy50b29scy52ZXJ0ZXhFcmFzZXJSYWRpdXMgPSB2O1xuICB9XG5cbiAgLyoqIFJlZ2lvbiBzZXQtb3BlcmF0aW9ucyBvbiB0aGUgc2VsZWN0aW9uLCBhbmQgdGhlIHN0b3JlIG1pcnJvcnMgdGhleSByZWFkIChqaXQtdWkjODUpLiAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgcmVnaW9uQWN0aW9ucyA9IG5ldyBSZWdpb25BY3Rpb25zKFxuICAgIHRoaXMucGxvdFNlcnZpY2UsXG4gICAgdGhpcy5yZWdpb25PcHMsXG4gICAgKCkgPT4gdGhpcy5pbWFnZUluZm8/LnRydWVJbWFnZVNpemUsXG4gICAgKG0pID0+IHRoaXMubWVzc2FnZVNlcnZpY2UuYWRkKHsga2V5OiB0aGlzLnJlc3VsdFRvYXN0S2V5LCAuLi5tIH0pLFxuICApO1xuICAvKiogQ3VzdG9tLXRocmVzaG9sZCBTaW1wbGlmeSBkaWFsb2cgdmlzaWJpbGl0eSAoc2VlIHtAbGluayBSZWdpb25BY3Rpb25zfSkuICovXG4gIHByb3RlY3RlZCBnZXQgZGlzcGxheVNpbXBsaWZ5RGlhbG9nKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnJlZ2lvbkFjdGlvbnMuZGlzcGxheVNpbXBsaWZ5RGlhbG9nO1xuICB9XG4gIHByb3RlY3RlZCBzZXQgZGlzcGxheVNpbXBsaWZ5RGlhbG9nKHY6IGJvb2xlYW4pIHtcbiAgICB0aGlzLnJlZ2lvbkFjdGlvbnMuZGlzcGxheVNpbXBsaWZ5RGlhbG9nID0gdjtcbiAgfVxuXG4gIC8qKiBTQU0gbW9kZWwgcGlja2VyIG9wdGlvbnMgKyBjdXJyZW50IHNlbGVjdGlvbiAoaml0LXVpIzkwIFAxKS4gT25seSBtb2RlbHNcbiAgICogIHdpdGggYSBob3N0ZWQgT05OWCBwYWlyIChjb25maWd1cmVkIHZpYSBzZXRTYW1Nb2RlbFVybHMgYXQgYXBwIGluaXQpIGFyZVxuICAgKiAgb2ZmZXJlZCwgc28gdGhlIHBpY2tlciBjYW4ndCBzZWxlY3QgYSBtb2RlbCB0aGF0IGNhbid0IHJ1bi4gKi9cbiAgcHJvdGVjdGVkIHNhbU1vZGVscyA9IFNBTV9NT0RFTFMuZmlsdGVyKGlzU2FtTW9kZWxSZWFkeSkubWFwKChtKSA9PiAoeyBpZDogbS5pZCwgbGFiZWw6IG0ubGFiZWwgfSkpO1xuICBwcm90ZWN0ZWQgc2FtTW9kZWxJZCA9IGdldERlZmF1bHRTYW1Nb2RlbElkKCk7XG5cbiAgLyoqXG4gICAqIE5vLXByb21wdCB0b29scyByZWdpc3RlcmVkIHRocm91Z2gge0BsaW5rIFRPT0xCQVJfVE9PTFN9LCBmaWx0ZXJlZCB0byB0aG9zZVxuICAgKiB3aXRoIGNvbmZpZ3VyZWQgbW9kZWxzIGFuZCBzb3J0ZWQuIFRoaXMgbGlicmFyeSByZWdpc3RlcnMgbm9uZSDigJQgYSBob3N0XG4gICAqIHN1cHBsaWVzIHRoZW0g4oCUIHNvIGFuIG9wZW4gYnVpbGQgaGFzIGFuIGVtcHR5IGFycmF5IGhlcmUgYW5kIHRoZSB0b29sYmFyXG4gICAqIGFuZCBoZWxwIGRpYWxvZyBzaW1wbHkgb21pdCB0aGF0IGdyb3VwLlxuICAgKi9cbiAgcHJvdGVjdGVkIGNvbnRyaWJ1dGVkVG9vbHM6IFRvb2xiYXJUb29sQ29udHJpYnV0aW9uW10gPSBbXTtcbiAgLyoqIENoZWNrcG9pbnRzIGFuZCBwYXJhbWV0ZXIgdmFsdWVzIG9mIHtAbGluayBjb250cmlidXRlZFRvb2xzfSwgYW5kIHRoZWlyIGRpYWxvZy4gKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHRvb2xQYXJhbXM6IFRvb2xQYXJhbXNNb2RlbDtcbiAgLyoqIENvbnRyaWJ1dGVkIHBsb3QgbW9kZXMgYW5kIGRpYWxvZyB0b29scywgYW5kIHRoZWlyIGxpdmUgc2Vzc2lvbnMuICovXG4gIHJlYWRvbmx5IGNvbnRyaWJ1dGlvbnM6IENvbnRyaWJ1dGlvbkhvc3Q7XG4gIC8qKiBEaWFsb2cgdG9vbHMgcmVnaXN0ZXJlZCB0aHJvdWdoIHtAbGluayBUT09MQkFSX1RPT0xTfSAoYGtpbmQ6ICdkaWFsb2cnYCkuICovXG4gIHByb3RlY3RlZCBnZXQgZGlhbG9nVG9vbHMoKTogVG9vbGJhckRpYWxvZ1Rvb2xDb250cmlidXRpb25bXSB7XG4gICAgcmV0dXJuIHRoaXMuY29udHJpYnV0aW9ucy5kaWFsb2dUb29scztcbiAgfVxuICAvKiogVGhlIGRpYWxvZyB0b29sIHRoZSB1c2VyIGhhcyBvcGVuIChpdHMgc2Vzc2lvbiBtYXkgYmUgYmV0d2VlbiByZW5kZXJzKS4gKi9cbiAgcHJvdGVjdGVkIGdldCBvcGVuRGlhbG9nVG9vbElkKCk6IHN0cmluZyB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLmNvbnRyaWJ1dGlvbnMub3BlbkRpYWxvZ1Rvb2xJZDtcbiAgfVxuICAvKiogVGhlIG9wZW4gZGlhbG9nIHRvb2wncyBsaXZlIGRpYWxvZywgYXMgdGhlIHRlbXBsYXRlIHJlbmRlcnMgaXQuICovXG4gIHByb3RlY3RlZCBnZXQgdG9vbERpYWxvZygpOiBUb29sRGlhbG9nVmlldyB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLmNvbnRyaWJ1dGlvbnMudG9vbERpYWxvZztcbiAgfVxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgc2FtVG9hc3RLZXkgPSBgc2FtLSR7VmlzdWFsaXplckNvbXBvbmVudC5uZXh0VG9hc3RJZCsrfWA7XG4gIC8qKlxuICAgKiBPdXRsZXQgZm9yIHRoZSBsaWJyYXJ5J3Mgb3duIHJlc3VsdC9lcnJvciBub3RpY2VzLCBrZXllZCB0byB0aGlzIGluc3RhbmNlIHNvIHRoZXlcbiAgICogZG8gbm90IGRlcGVuZCBvbiB0aGUgaG9zdCBtb3VudGluZyBhIGtleWxlc3MgYDxwLXRvYXN0PmAgKG1vc3QgaG9zdHMgZG9uJ3QsIGFuZCBhXG4gICAqIGZhaWxlZCBzZWdtZW50YXRpb24gdGhlbiBsb29rZWQgbGlrZSBhIGRlYWQgYnV0dG9uKS4gRGVsaWJlcmF0ZWx5IE5PVCB0aGUgc3RpY2t5XG4gICAqIHRvYXN0J3Mga2V5OiB0aGF0IGlzIGNsZWFyZWQgd2hlbiBhIHJ1biBzZXR0bGVzLCB3aGljaCB3b3VsZCB3aXBlIHRoZSByZXN1bHQuXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgcmVzdWx0VG9hc3RLZXkgPSBgJHt0aGlzLnNhbVRvYXN0S2V5fS1yZXN1bHRgO1xuICAvKiogU2VnbWVudGF0aW9uIHJ1bnMgYW5kIHRoZWlyIHN0aWNreSBwcm9ncmVzcyB0b2FzdC4gKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHNlZ21lbnRhdGlvbiA9IG5ldyBTZWdtZW50YXRpb25SdW5uZXIoXG4gICAgdGhpcy5tZXNzYWdlU2VydmljZSxcbiAgICB0aGlzLnNhbVRvYXN0S2V5LFxuICAgIHRoaXMucmVzdWx0VG9hc3RLZXksXG4gICAgKCkgPT4gdGhpcy5jaGFuZ2VkKCksXG4gICk7XG5cbiAgLyoqIENoYW5uZWxzICYgSGlzdG9ncmFtIGRpYWxvZyB2aXNpYmlsaXR5IChvcGVuZWQgZnJvbSB0aGUgdG9vbGJhcikuICovXG4gIHByb3RlY3RlZCBzaG93Q2hhbm5lbEhpc3RvZ3JhbSA9IGZhbHNlO1xuICAvKiogU3BhdGlhbC1vbWljcyBjb250cm9scyBkaWFsb2cgdmlzaWJpbGl0eSAodG9vbGJhciBidXR0b24pLiAqL1xuICBwcm90ZWN0ZWQgc2hvd1NwYXRpYWxDb250cm9scyA9IGZhbHNlO1xuICAvKiogUmVnaW9uIEVkaXRvciBkaWFsb2cgdmlzaWJpbGl0eSAob3BlbmVkIGZyb20gdGhlIHRvb2xiYXIpLiAqL1xuICBwcm90ZWN0ZWQgc2hvd1JlZ2lvbkVkaXRvciA9IGZhbHNlO1xuICAvKiogUmVnaW9uIEVkaXRvciBkaWFsb2cgd2lkdGguIE9uIG9wZW4gaXQgaXMgc2V0IHRvIHRoZSBjb25maWd1cmVkIGhvc3RcbiAgICogIGVsZW1lbnQncyBjdXJyZW50IHdpZHRoLCBvciDigJQgd2hlbiBubyBzZWxlY3RvciBpcyBjb25maWd1cmVkIC8gdGhlIGVsZW1lbnRcbiAgICogIGlzbid0IGZvdW5kIOKAlCB0byBhIHF1YXJ0ZXIgb2YgdGhlIHBhZ2UgKHNlZSBvcGVuUmVnaW9uRWRpdG9yKS4gKi9cbiAgcHJvdGVjdGVkIHJlZ2lvbkVkaXRvcldpZHRoID0gJzI1dncnO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgcGxvdERpdk5hbWUgPSBgdml6LXBsb3QtJHtwbG90SW5zdGFuY2VTZXErK31gO1xuICAvKiogVGhlIHJlbmRlciBwaXBlbGluZTogdGhlIG5ld2VzdCBpbWFnZSAob3IgaW1hZ2UtbGVzcyBkYXRhc2V0KSBhbHdheXMgd2lucy4gKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHJlbmRlcjogSW1hZ2VSZW5kZXJTZXNzaW9uID0gbmV3IEltYWdlUmVuZGVyU2Vzc2lvbih7XG4gICAgcGxvdERpdk5hbWU6IHRoaXMucGxvdERpdk5hbWUsXG4gICAgdmlzdWFsaXplcjogdGhpcy5wbG90U2VydmljZSxcbiAgICB6SW5kZXg6ICgpID0+IHRoaXMuekluZGV4LFxuICAgIHBsb3RUeXBlOiAoKSA9PiB0aGlzLnBsb3RUeXBlLFxuICAgIGlzSGVhdG1hcDogKCkgPT4gdGhpcy5pc0hlYXRtYXAsXG4gICAgaXNDYWNoaW5nOiAoKSA9PiB0aGlzLmlzQ2FjaGluZygpLFxuICAgIGJlZm9yZVJlc2V0OiAoKSA9PiB0aGlzLmNvbnRyaWJ1dGlvbnMuZW5kU2Vzc2lvbnMoKSxcbiAgICBwcmVwYXJlOiAoaW5mbykgPT4gdGhpcy5sYXlPdXRTbGljZXMoaW5mbyksXG4gICAgcmVsZWFzZU92ZXJsYXk6IChpbmZvKSA9PiB7XG4gICAgICBpZiAoaW5mby5pc1N0YWNrICYmIGluZm8uc2hvd1N0YWNrKSB0aGlzLnN0YWNrTG9hZGluZy5zZXQoZmFsc2UpO1xuICAgICAgdGhpcy5zdGF0ZS5zZXRJbWFnZUxvYWRpbmcoZmFsc2UpO1xuICAgIH0sXG4gICAgbGFuZGVkOiAoaW5mbykgPT4ge1xuICAgICAgLy8gVGhlIGhvc3QncyBIdHRwQ2xpZW50IGNhcnJpZXMgYSBzZXJ2ZXItc2lkZSByZWdpb24gc291cmNlJ3MgcmVxdWVzdHM6IGl0cyBpbnRlcmNlcHRvcnMgKGF1dGgpIGFwcGx5LlxuICAgICAgY29uc3QgaHR0cCA9IHRoaXMuaW5qZWN0b3I/LmdldChIdHRwQ2xpZW50LCBudWxsKSA/PyB1bmRlZmluZWQ7XG4gICAgICBhcHBseUltYWdlUm9pcyhpbmZvLCB0aGlzLnBsb3RTZXJ2aWNlLCB0aGlzLnpJbmRleCwgdGhpcy52aXpDb25maWc/LnJlZ2lvblNvdXJjZU1pbkNoYXJzLCBodHRwKTtcbiAgICAgIHRoaXMuY29udHJpYnV0aW9ucy5hY3RpdmF0ZSgpO1xuICAgIH0sXG4gICAgc2V0SW1hZ2VMb2FkaW5nOiAobG9hZGluZykgPT4gdGhpcy5zdGF0ZS5zZXRJbWFnZUxvYWRpbmcobG9hZGluZyksXG4gICAgYWxlcnQ6IChzZXZlcml0eSwgc3VtbWFyeSwgZGV0YWlsKSA9PlxuICAgICAgdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoeyBrZXk6IHRoaXMudml6QWxlcnRUb2FzdEtleSwgc2V2ZXJpdHksIHN1bW1hcnksIGRldGFpbCB9KSxcbiAgICBkZXRlY3RDaGFuZ2VzOiAoKSA9PiB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCksXG4gIH0pO1xuICBwbG90VHlwZSA9IFBsb3RUeXBlLklNQUdFO1xuICBwcm90ZWN0ZWQgaXNIZWF0bWFwID0gdHJ1ZTtcbiAgcHJvdGVjdGVkIGFjdGl2ZVN1cmZhY2UzZE1vZGUgPSAndHVybnRhYmxlJztcbiAgLyoqIFdoZXRoZXIgdGhlIG5hcGFyaSAzRCBjb29yZGluYXRlLWF4ZXMgLyBzY2FsZSBnaXptbyBpcyBzaG93biAodm9sdW1lL2lzb3N1cmZhY2UpLiAqL1xuICBwcm90ZWN0ZWQgYXhlc1Zpc2libGUgPSB0cnVlO1xuICBwcm90ZWN0ZWQgd2lyZWZyYW1lQWN0aXZlID0gZmFsc2U7XG4gIC8qKiBuYXBhcmkgM0QgZGVjaW1hdGUgZmFjdG9yICgxID0gRnVsbCDigKYgOCA9IOKFmzsgZGVmYXVsdCDCvSk7IGNoYW5naW5nIGl0IHJlLXBsb3RzLiAqL1xuICBwcm90ZWN0ZWQgcmVzb2x1dGlvblNjYWxlID0gTkFQQVJJX0RFRkFVTFRfREVDSU1BVEU7XG5cbiAgLyoqIFRoZSBzZWxlY3RvcidzIGVudHJpZXM6IHRoZSBidWlsdC1pbiBwbG90IHR5cGVzIHRoZSBhY3RpdmUgYmFja2VuZFxuICAgKiAgYWR2ZXJ0aXNlcyAoM0QgZ2F0ZWQgYnkgY2FwYWJpbGl0eSksIHRoZW4gYW55IGNvbnRyaWJ1dGVkIG1vZGVzXG4gICAqICAoe0BsaW5rIFBMT1RfVFlQRV9DT05UUklCVVRJT05TfSkuICovXG4gIHByb3RlY3RlZCBwbG90VHlwZU1lbnU6IFBsb3RUeXBlT3B0aW9uW10gPSBbXTtcbiAgLyoqXG4gICAqIFRoZSBidWlsdC1pbiBwbG90IHR5cGVzIG9uIG9mZmVyIOKAlCB7QGxpbmsgcGxvdFR5cGVNZW51fSB3aXRob3V0IGNvbnRyaWJ1dGVkXG4gICAqIG1vZGVzLiBLZXB0IHdpdGggaXRzIG9yaWdpbmFsIHR5cGUgc28gZXhpc3RpbmcgcmVhZGVycyBhcmUgdW5hZmZlY3RlZC5cbiAgICovXG4gIHByb3RlY3RlZCBwbG90VHlwZU9wdGlvbnM6IFBsb3RUeXBlRGVzY3JpcHRvcltdID0gW107XG4gIC8qKlxuICAgKiBXaGF0IHRoZSBzZWxlY3RvciBzaG93czogYSBidWlsdC1pbiB0eXBlIG9yIGEgY29udHJpYnV0ZWQgbW9kZSdzIGlkLiBFdmVyeVxuICAgKiByZW5kZXJpbmcgYW5kIHRvb2wgZGVjaXNpb24gZ29lcyB0aHJvdWdoIHtAbGluayBiYXNlUGxvdFR5cGV9IGluc3RlYWQsIHNvIGFcbiAgICogY29udHJpYnV0ZWQgbW9kZSBiZWhhdmVzIGV4YWN0bHkgbGlrZSB0aGUgYnVpbHQtaW4gdHlwZSBpdCByaWRlcyBvbi5cbiAgICovXG4gIHByb3RlY3RlZCBzZWxlY3RlZFBsb3RUeXBlSWQ6IFBsb3RUeXBlSWQgPSBQbG90VHlwZS5JTUFHRTtcblxuICAvKipcbiAgICogVGhlIGJ1aWx0LWluIHBsb3QgdHlwZSBiZWluZyByZW5kZXJlZC4gV2l0aCBubyBjb250cmlidXRlZCBtb2RlIGFjdGl2ZSB0aGlzXG4gICAqIGlzIHRoZSBzZWxlY3Rpb24gaXRzZWxmOyBkdXJpbmcgb25lIGl0IGlzIHRoZSBtb2RlJ3MgYGJhc2VUeXBlYC4gS2VwdCB3aXRoIGl0c1xuICAgKiBvcmlnaW5hbCBgUGxvdFR5cGVgIHR5cGUgZm9yIGV4aXN0aW5nIHJlYWRlcnMg4oCUIHVzZSB7QGxpbmsgc2VsZWN0ZWRQbG90VHlwZUlkfVxuICAgKiBmb3IgdGhlIHNlbGVjdG9yJ3MgaWQuIEFzc2lnbmluZyBzZWxlY3RzIHRoYXQgYnVpbHQtaW4gdHlwZS5cbiAgICovXG4gIHByb3RlY3RlZCBnZXQgc2VsZWN0ZWRQbG90VHlwZSgpOiBQbG90VHlwZSB7XG4gICAgcmV0dXJuIHRoaXMuYmFzZVBsb3RUeXBlO1xuICB9XG4gIHByb3RlY3RlZCBzZXQgc2VsZWN0ZWRQbG90VHlwZSh0eXBlOiBQbG90VHlwZSkge1xuICAgIHRoaXMuc2VsZWN0ZWRQbG90VHlwZUlkID0gdHlwZTtcbiAgfVxuXG4gIC8qKiBDb250cmlidXRlZCBwbG90IG1vZGVzIGFuZCB0aGVpciBzaW5nbGUgbGl2ZSBzZXNzaW9uLiAqL1xuICBnZXQgcGxvdE1vZGVzKCk6IFBsb3RNb2RlQ29udHJvbGxlciB7XG4gICAgcmV0dXJuIHRoaXMuY29udHJpYnV0aW9ucy5wbG90TW9kZXM7XG4gIH1cbiAgLyoqIFRoZSBsaXZlIGNvbnRyaWJ1dGVkIG1vZGUncyBzaWRlIHBhbmVsOyBudWxsIHdoaWxlIG5vIGNvbnRyaWJ1dGVkIHNlc3Npb24gaXMgbGl2ZS4gKi9cbiAgcHJvdGVjdGVkIGdldCBwbG90TW9kZVBhbmVsKCk6IFBsb3RNb2RlUGFuZWxWaWV3IHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuY29udHJpYnV0aW9ucy5wbG90TW9kZVBhbmVsO1xuICB9XG5cbiAgLyoqIFdoZXJlIGEgYG1vdW50YCBwYW5lbCdzIGhvc3QgZWxlbWVudCBpcyBhdHRhY2hlZCBvbmNlIHRoZSBkaWFsb2cgcmVuZGVycy4gKi9cbiAgQFZpZXdDaGlsZCgncGxvdE1vZGVQYW5lbFNsb3QnKVxuICBzZXQgcGxvdE1vZGVQYW5lbFNsb3QocmVmOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PiB8IHVuZGVmaW5lZCkge1xuICAgIHRoaXMuY29udHJpYnV0aW9ucy5hdHRhY2hQYW5lbFNsb3QocmVmPy5uYXRpdmVFbGVtZW50KTtcbiAgfVxuXG4gIC8qKiBUaGUgYnVpbHQtaW4gdHlwZSBhY3R1YWxseSByZW5kZXJlZCBmb3Ige0BsaW5rIHNlbGVjdGVkUGxvdFR5cGVJZH06IGl0c2VsZlxuICAgKiAgZm9yIGEgYnVpbHQtaW4gdHlwZSwgYGJhc2VUeXBlYCBmb3IgYSBjb250cmlidXRlZCBtb2RlLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGJhc2VQbG90VHlwZSgpOiBQbG90VHlwZSB7XG4gICAgcmV0dXJuIHRoaXMucGxvdE1vZGVzLmJhc2VUeXBlT2YodGhpcy5zZWxlY3RlZFBsb3RUeXBlSWQpO1xuICB9XG5cbiAgLyoqIERpdiB0aGUgZmxvYXRpbmcgaW50ZW5zaXR5LXByb2ZpbGUgaW5zZXQgaXMgY2hhcnRlZCBpbnRvLiBQZXIgaW5zdGFuY2UsIGxpa2VcbiAgICogIHtAbGluayBwbG90RGl2TmFtZX06IHRoZSBiYWNrZW5kIHJlc29sdmVzIGl0IGJ5IGlkLCBzbyBhIGZpeGVkIGlkIG1hZGUgdHdvIGxpdmVcbiAgICogIHZpZXdlcnMgZHJhdyBib3RoIGluc2V0cyBpbnRvIHdoaWNoZXZlciBkaXYgY2FtZSBmaXJzdCBpbiB0aGUgZG9jdW1lbnQuICovXG4gIHByb3RlY3RlZCByZWFkb25seSBpbnRlbnNpdHlJbnNldERpdiA9IGAke3RoaXMucGxvdERpdk5hbWV9LWluc2V0YDtcblxuICAvKiogVG9vbGJhciBkb2NraW5nOiBkb2NrZWQgYWNyb3NzIHRoZSB0b3AgYnkgZGVmYXVsdDsgZHJhZ2dpbmcgaXRzIGhhbmRsZVxuICAgKiAgZGV0YWNoZXMgaXQgaW50byBhIGZsb2F0aW5nLCBtb3ZhYmxlIHdpbmRvdyAoZnJlZXMgdGhlIHRvcCByb3cgZm9yIHRoZVxuICAgKiAgdmlzdWFsaXphdGlvbikuICovXG4gIHByb3RlY3RlZCB0b29sYmFyRmxvYXRpbmcgPSBmYWxzZTtcbiAgcHJvdGVjdGVkIHRvb2xiYXJQb3MgPSB7IHg6IDgsIHk6IDggfTtcbiAgLyoqIFdoZXJlIGEgdG9vbGJhci1oYW5kbGUgZHJhZyBzdGFydHMgZnJvbTogZ3JhYmJpbmcgdGhlIGRvY2tlZCB0b29sYmFyIGZsb2F0cyBpdC4gKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHRvb2xiYXJEcmFnT3JpZ2luID0gKCk6IEZsb2F0aW5nUG9zID0+IHtcbiAgICBpZiAoIXRoaXMudG9vbGJhckZsb2F0aW5nKSB7XG4gICAgICB0aGlzLnRvb2xiYXJGbG9hdGluZyA9IHRydWU7XG4gICAgICB0aGlzLnRvb2xiYXJQb3MgPSB7IHg6IDgsIHk6IDggfTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudG9vbGJhclBvcztcbiAgfTtcbiAgLyoqIFRoZSBmbG9hdGluZyBpbnRlbnNpdHktcHJvZmlsZSBpbnNldCAoYWx3YXlzIG1vdW50ZWQ7IHNob3dzIGl0c2VsZiB3aGlsZSBsaW5lcyBleGlzdCkuICovXG4gIEBWaWV3Q2hpbGQoSW50ZW5zaXR5SW5zZXRDb21wb25lbnQsIHsgc3RhdGljOiB0cnVlIH0pIGluc2V0PzogSW50ZW5zaXR5SW5zZXRDb21wb25lbnQ7XG5cbiAgLyoqIFRydWUgd2hpbGUgdGhlIDNEIHNwYXRpYWwgY2xvdWQgaXMgdGhlIGFjdGl2ZSBtb2RlLiBUaGUgY29udHJvbHMgZHJvcCB0aGUgUk9JXG4gICAqICBzZWxlY3Rpb24gdGhlcmU6IHJlZ2lvbiB0b29scyBhcmUgc2NyZWVuLXNwYWNlLCBhbmQgYWdhaW5zdCBhbiBvcmJpdGluZ1xuICAgKiAgY2FtZXJhIGEgZHJhd24gcmVjdGFuZ2xlIGhhcyBubyBmaXhlZCBtZWFuaW5nIGluIHRoZSBkYXRhLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGlzU3BhdGlhbDNkTW9kZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gaXNTcGF0aWFsT21pY3MzZCh0aGlzLmJhc2VQbG90VHlwZSk7XG4gIH1cblxuICAvKiogVHJ1ZSBpbiBhIG5hcGFyaSB2b2x1bWUgb3IgaXNvc3VyZmFjZSB2aWV3LCB3aGVyZSB0aGUgUmVnaW9uIEVkaXRvciBzaG93cyByZWdpb25zIGluIDNELiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGlzVm9sdW1lVmlldygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gaXNOYXBhcmlWb2x1bWUodGhpcy5iYXNlUGxvdFR5cGUpIHx8IGlzTmFwYXJpSXNvc3VyZmFjZSh0aGlzLmJhc2VQbG90VHlwZSk7XG4gIH1cblxuICAvKiogV2hldGhlciB0aGUgdXNlciBzcGxpdCB0aGUgdm9sdW1lIHZpZXcgd2l0aCB0aGUgc2xpY2UgZWRpdG9yIChvZmYgYnkgZGVmYXVsdDsga2VwdCB3aGlsZVxuICAgKiAgdGhlIHZpZXcgc2hvd3Mgb3RoZXIgcGxvdCB0eXBlcywgc28gYSB2b2x1bWUgdmlldyBvcGVucyBzcGxpdCBhZ2FpbikuICovXG4gIHByb3RlY3RlZCBzbGljZUVkaXRvciA9IGZhbHNlO1xuICAvKiogVGhlIHNsaWNlIGVkaXRvcidzIHBhbmU6IHRoZSBkaXNwbGF5ZWQgc2xpY2UsIHdpdGggZXZlcnkgcmVnaW9uIHRvb2wsIHRvcCByaWdodC4gKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHNsaWNlRGl2TmFtZSA9IGAke3RoaXMucGxvdERpdk5hbWV9LXNsaWNlYDtcbiAgLyoqIFRoZSBsZWZ0IGNvbHVtbidzIGFuZCB0aGUgdG9wIHJvdydzIHNoYXJlcyBvZiB0aGUgc2xpY2UgZWRpdG9yICglKS4gKi9cbiAgcHJvdGVjdGVkIHNwbGl0WCA9IDUwO1xuICBwcm90ZWN0ZWQgc3BsaXRZID0gNTA7XG4gIC8qKiBUaGUgc2VjdGlvbnMgdGhyb3VnaCB4IGFuZCB5IHNob3duIGJlbG93IChudWxscyB1bnRpbCB0aGUgdm9sdW1lIGlzIGN1dCkuICovXG4gIHByb3RlY3RlZCBzZWN0aW9uczogU2VjdGlvblZpZXdzID0geyB4OiBudWxsLCB5OiBudWxsIH07XG4gIHByb3RlY3RlZCBnZXQgc2xpY2VFZGl0b3JTaG93bigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zbGljZUVkaXRvciAmJiB0aGlzLmlzVm9sdW1lVmlldztcbiAgfVxuXG4gIC8qKlxuICAgKiBTcGxpdCB0aGUgdm9sdW1lIHZpZXcgd2l0aCB0aGUgc2xpY2UgZWRpdG9yLCBvciBjbG9zZSBpdC4gVGhlIGVkaXRvciBvcGVucyBvbiB0aGUgZGlzcGxheWVkXG4gICAqIHNsaWNlIGFuZCB0YWtlcyB0aGUgZHJhd2luZyB0b29sczsgY2xvc2luZyBpdCBsZWF2ZXMgdGhlIHNlbGVjdGlvbiB0b29sIGFybWVkIChpdCBwaWNrcyB0aGVcbiAgICogc3VyZmFjZXMgaW4gM0QpIGFuZCBkaXNhcm1zIGFueSBvdGhlci5cbiAgICovXG4gIHByb3RlY3RlZCBhc3luYyB0b2dnbGVTbGljZUVkaXRvcigpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICB0aGlzLnNsaWNlRWRpdG9yID0gIXRoaXMuc2xpY2VFZGl0b3I7XG4gICAgdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpOyAvLyB0aGUgcGFuZSdzIGRpdiwgYmVmb3JlIHRoZSBiYWNrZW5kIGxvb2tzIGl0IHVwXG4gICAgdGhpcy5wbG90U2VydmljZS5yZWxheW91dCgpOyAvLyB0aGUgM0QgdmlldyBpcyBhIHF1YXJ0ZXIgb2YgdGhlIGFyZWEgbm93LCBvciBhbGwgb2YgaXQgYWdhaW5cbiAgICBpZiAoIXRoaXMuc2xpY2VFZGl0b3IpIHtcbiAgICAgIGF3YWl0IHRoaXMucGxvdFNlcnZpY2Uuc2V0U2xpY2VFZGl0b3I/LihudWxsKTtcbiAgICAgIGlmICh0aGlzLnRvb2xzLmFjdGl2ZSAhPT0gbnVsbCAmJiB0aGlzLnRvb2xzLmFjdGl2ZSAhPT0gJ3NlbGVjdCcpIHRoaXMudG9vbHMuYXBwbHkobnVsbCk7XG4gICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gVGhlIHJlZ2lvbnMgZWRpdGVkIGFyZSB0aGUgZGlzcGxheWVkIHNsaWNlJ3MuXG4gICAgdGhpcy5wbG90U2VydmljZS5zZXREaXNwbGF5U2xpY2UodGhpcy56SW5kZXgpO1xuICAgIGNvbnN0IHNob3duID0gYXdhaXQgdGhpcy5wbG90U2VydmljZS5zZXRTbGljZUVkaXRvcj8uKHRoaXMuc2xpY2VEaXZOYW1lKTtcbiAgICAvLyBUaGUgYXJtZWQgdG9vbCBub3cgYWN0cyBpbiB0aGUgcGFuZS5cbiAgICBpZiAoc2hvd24gJiYgdGhpcy50b29scy5hY3RpdmUgIT09IG51bGwpIHRoaXMudG9vbHMuYXBwbHkodGhpcy50b29scy5hY3RpdmUpO1xuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9XG5cbiAgLyoqIEEgcG9pbnQgcGlja2VkIGluIGEgc2VjdGlvbjogdGhlIHNsaWNlIGFuZCB0aGUgb3RoZXIgc2VjdGlvbidzIHBsYW5lIG1vdmUgdGhlcmUuICovXG4gIHByb3RlY3RlZCBvblNlY3Rpb25QaWNrKGF4aXM6IFNlY3Rpb25BeGlzLCBhdDogeyB1OiBudW1iZXI7IHY6IG51bWJlciB9KTogdm9pZCB7XG4gICAgLy8gVGhyb3VnaCB4LCBhY3Jvc3MgaXMgdGhlIHNsaWNlIGFuZCBkb3duIGlzIHk7IHRocm91Z2ggeSwgYWNyb3NzIGlzIHggYW5kIGRvd24gdGhlIHNsaWNlLlxuICAgIGNvbnN0IHNsaWNlID0gTWF0aC5mbG9vcihheGlzID09PSAneCcgPyBhdC51IDogYXQudik7XG4gICAgaWYgKGF4aXMgPT09ICd4JykgdGhpcy5wbG90U2VydmljZS5zZXRTZWN0aW9uUGxhbmU/LigneScsIGF0LnYpO1xuICAgIGVsc2UgdGhpcy5wbG90U2VydmljZS5zZXRTZWN0aW9uUGxhbmU/LigneCcsIGF0LnUpO1xuICAgIHRoaXMub25aU2xpZGUoTWF0aC5taW4odGhpcy5tYXhJbmRleCwgTWF0aC5tYXgoMCwgc2xpY2UpKSk7XG4gIH1cblxuICAvKiogRHJhZyBhIGRpdmlkZXIgb2YgdGhlIHNsaWNlIGVkaXRvcjogdGhlIHZlcnRpY2FsIG9uZSBzZXRzIHRoZSBjb2x1bW5zLCB0aGUgaG9yaXpvbnRhbCBvbmUgdGhlIHJvd3MuICovXG4gIHByb3RlY3RlZCBzdGFydFBhbmVSZXNpemUoZXZlbnQ6IFBvaW50ZXJFdmVudCwgYXhpczogJ3gnIHwgJ3knKTogdm9pZCB7XG4gICAgY29uc3QgZGl2aWRlciA9IGV2ZW50LmN1cnJlbnRUYXJnZXQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgY29uc3QgcGFuZXMgPSBkaXZpZGVyLnBhcmVudEVsZW1lbnQ7XG4gICAgaWYgKCFwYW5lcykgcmV0dXJuO1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZGl2aWRlci5zZXRQb2ludGVyQ2FwdHVyZShldmVudC5wb2ludGVySWQpO1xuICAgIGNvbnN0IG1vdmUgPSAoZTogUG9pbnRlckV2ZW50KSA9PiB7XG4gICAgICBjb25zdCBib3ggPSBwYW5lcy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIGlmIChheGlzID09PSAneCcgJiYgYm94LndpZHRoID4gMCkgdGhpcy5zZXRTcGxpdCgneCcsICgoZS5jbGllbnRYIC0gYm94LmxlZnQpIC8gYm94LndpZHRoKSAqIDEwMCk7XG4gICAgICBpZiAoYXhpcyA9PT0gJ3knICYmIGJveC5oZWlnaHQgPiAwKSB0aGlzLnNldFNwbGl0KCd5JywgKChlLmNsaWVudFkgLSBib3gudG9wKSAvIGJveC5oZWlnaHQpICogMTAwKTtcbiAgICB9O1xuICAgIGNvbnN0IGVuZCA9ICgpID0+IHtcbiAgICAgIGRpdmlkZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcm1vdmUnLCBtb3ZlKTtcbiAgICAgIGRpdmlkZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcnVwJywgZW5kKTtcbiAgICAgIGRpdmlkZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcmNhbmNlbCcsIGVuZCk7XG4gICAgfTtcbiAgICBkaXZpZGVyLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJtb3ZlJywgbW92ZSk7XG4gICAgZGl2aWRlci5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVydXAnLCBlbmQpO1xuICAgIGRpdmlkZXIuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcmNhbmNlbCcsIGVuZCk7XG4gIH1cblxuICAvKiogQSBkaXZpZGVyJ3Mga2V5Ym9hcmQ6IOKGkCDihpIgbW92ZSB0aGUgdmVydGljYWwgb25lLCDihpEg4oaTIHRoZSBob3Jpem9udGFsIG9uZSwgYnkgNSUuICovXG4gIHByb3RlY3RlZCBudWRnZVBhbmVTaXplKGV2ZW50OiBLZXlib2FyZEV2ZW50LCBheGlzOiAneCcgfCAneScpOiB2b2lkIHtcbiAgICBjb25zdCBrZXlzID0gYXhpcyA9PT0gJ3gnID8gWydBcnJvd0xlZnQnLCAnQXJyb3dSaWdodCddIDogWydBcnJvd1VwJywgJ0Fycm93RG93biddO1xuICAgIGNvbnN0IHN0ZXAgPSBldmVudC5rZXkgPT09IGtleXNbMF0gPyAtNSA6IGV2ZW50LmtleSA9PT0ga2V5c1sxXSA/IDUgOiAwO1xuICAgIGlmICghc3RlcCkgcmV0dXJuO1xuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7IC8vIG5vdCBhIHNsaWNlIHN0ZXBcbiAgICB0aGlzLnNldFNwbGl0KGF4aXMsIChheGlzID09PSAneCcgPyB0aGlzLnNwbGl0WCA6IHRoaXMuc3BsaXRZKSArIHN0ZXApO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRTcGxpdChheGlzOiAneCcgfCAneScsIHBlcmNlbnQ6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHZhbHVlID0gTWF0aC5yb3VuZChNYXRoLm1pbig4MCwgTWF0aC5tYXgoMjAsIHBlcmNlbnQpKSk7XG4gICAgaWYgKGF4aXMgPT09ICd4JykgdGhpcy5zcGxpdFggPSB2YWx1ZTtcbiAgICBlbHNlIHRoaXMuc3BsaXRZID0gdmFsdWU7XG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgLy8gVGhlIDNEIHZpZXcgZm9sbG93cyBpdHMgY2VsbCBvbmNlIHRoZSBncmlkIGhhcyBpdHMgbmV3IHRyYWNrcy5cbiAgICBpZiAodGhpcy5yZWxheW91dEZyYW1lID09PSBudWxsICYmIHR5cGVvZiByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICB0aGlzLnJlbGF5b3V0RnJhbWUgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUoKCkgPT4ge1xuICAgICAgICB0aGlzLnJlbGF5b3V0RnJhbWUgPSBudWxsO1xuICAgICAgICB0aGlzLnBsb3RTZXJ2aWNlLnJlbGF5b3V0KCk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbiAgcHJpdmF0ZSByZWxheW91dEZyYW1lOiBudW1iZXIgfCBudWxsID0gbnVsbDtcblxuICAvKiogVHJ1ZSBmb3IgdGhlIEltYWdlIHBsb3QgdHlwZSwgd2hpY2ggcmVuZGVycyBhcyBhIG5hdGl2ZWx5IHBhbi96b29tLWFibGVcbiAgICogIHJhc3RlciDigJQgc28gdGhlIGJhY2tlbmQtYWdub3N0aWMgem9vbS9wYW4gdG9vbGJhciB0b29scyBhcmUgaGlkZGVuLiBUaGVcbiAgICogIGNvbXBvbmVudCBkcml2ZXMgdGhpcyBvZmYgdGhlIHBsb3QgdHlwZSwgbm90IHRoZSBhY3RpdmUgYmFja2VuZC4gKi9cbiAgcHJvdGVjdGVkIGdldCBpc0ltYWdlVmlldygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5iYXNlUGxvdFR5cGUgPT09IFBsb3RUeXBlLklNQUdFO1xuICB9XG5cbiAgLyoqIElzb3N1cmZhY2UgYmFuZCBhcyBhIDDigJMyNTUgc2xpZGVyIHBvc2l0aW9uLCBtYXBwZWQgb250byB0aGUgdm9sdW1lJ3MgcmVhbFxuICAgKiAgaW50ZW5zaXR5IHJhbmdlIGJ5IHRoZSByZW5kZXJlci4gRGVmYXVsdHMgdG8gdGhlIGZ1bGwgcmFuZ2UuICovXG4gIHByb3RlY3RlZCBpc29SYW5nZTogbnVtYmVyW10gPSBbMCwgMjU1XTtcblxuICAvKiogVGhlIHNwYXRpYWwtb21pY3MgZGF0YXNldCBvbiBvZmZlciBhbmQgdGhlIGdhdGVzIGl0IHB1dHMgb24gdGhlIHNlbGVjdG9yLiAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgc3BhdGlhbDogU3BhdGlhbERhdGFzZXRCaW5kZXI7XG4gIC8qKiBXaGV0aGVyIGEgc3BhdGlhbC1vbWljcyBkYXRhc2V0IGlzIHB1Ymxpc2hlZCBvbiBgU1BBVElBTF9EQVRBX1BPUlRgIOKAlCBnYXRlcyB0aGVcbiAgICogIHNwYXRpYWwgcGxvdCB0eXBlczsgdGhlIHRvb2xiYXIgb2ZmZXJzIHRoZSBwbG90IG1vZGVzIGZvciBhbiBpbWFnZS1sZXNzIG9uZSB0b28uICovXG4gIHByb3RlY3RlZCBnZXQgaGFzU3BhdGlhbERhdGFzZXQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuc3BhdGlhbC5oYXNEYXRhc2V0O1xuICB9XG5cbiAgLyoqIEtleWJvYXJkLCB3aGVlbCBhbmQgY29udGV4dC1tZW51IGhhbmRsaW5nOyBjcmVhdGVkIG9uY2UgdGhlIHZpZXcgZXhpc3RzLiAqL1xuICBwcml2YXRlIHNob3J0Y3V0cz86IFZpZXdlclNob3J0Y3V0cztcblxuICAvKiogRGVib3VuY2VkIHotc2xpY2Ugc2NydWJiaW5nIChzZWUgU2xpY2VTY3J1YmJlciDigJQgcmVmYWN0b3JpbmcgcGxhbiBTdGVwIDcpLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHNjcnViYmVyID0gbmV3IFNsaWNlU2NydWJiZXIoKHopID0+IHtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldFpJbmRleCh6KTtcbiAgICAvLyBJbiBhIHBlci1zbGljZSB6LXN0YWNrIHNlc3Npb24gdGhlIHN0b3JlIHN3YXBzIHRoZSBsaXZlIHJlZ2lvbiBzZXQgdG8gdGhpc1xuICAgIC8vIHNsaWNlIChwcmVzZXJ2aW5nIGVkaXRzIG1hZGUgb24gdGhlIHByZXZpb3VzIG9uZSk7IG91dHNpZGUgc3RhY2sgbW9kZSB0aGlzXG4gICAgLy8ganVzdCByZWNvcmRzIHRoZSBzbGljZSwgbGVhdmluZyBzaW5nbGUtcGxhbmUgcmVnaW9ucyB1bnRvdWNoZWQgKGppdC11aSM5MykuXG4gICAgdGhpcy5wbG90U2VydmljZS5zZXREaXNwbGF5U2xpY2Uoeik7XG4gIH0pO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIC8vIFRoZSBjb25zdHJ1Y3RvciBwYXJhbWV0ZXJzIGJlbG93IGFyZSB0aGUgaW5qZWN0aW9uIHBvaW50czsgbm9uZSBpcyBwdWJsaWMgQVBJLlxuICAgIEBJbmplY3QoSU1BR0VfU1RBVEVfUE9SVCkgcHJpdmF0ZSBzdGF0ZTogSW1hZ2VTdGF0ZVBvcnQsXG4gICAgQEluamVjdChWSVNVQUxJWkVSKSBwdWJsaWMgcGxvdFNlcnZpY2U6IElWaXN1YWxpemVyLFxuICAgIHB1YmxpYyBtZXNzYWdlU2VydmljZTogTWVzc2FnZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZSxcbiAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHJpdmF0ZSBzZXNzaW9uOiBWaXN1YWxpemVyU3RvcmUsXG4gICAgcHJpdmF0ZSBzYW1Ub29sOiBTYW1Ub29sU2VydmljZSxcbiAgICBwcml2YXRlIGNlbGxTZWdtZW50VG9vbDogQ2VsbFNlZ21lbnRUb29sU2VydmljZSxcbiAgICBwcml2YXRlIHNhbVBvaW50VG9vbDogU2FtUG9pbnRUb29sU2VydmljZSxcbiAgICBwcml2YXRlIHJlZ2lvbk9wczogUmVnaW9uT3BzU2VydmljZSxcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFZJWl9DT05GSUcpIHByaXZhdGUgdml6Q29uZmlnPzogVml6Q29uZmlnLFxuICAgIC8vIEEgY29uc3RydWN0b3IgcGFyYW1ldGVyIHJhdGhlciB0aGFuIGEgZmllbGQgYGluamVjdCgpYDogdGhpcyBjb21wb25lbnQgaXNcbiAgICAvLyBhbHNvIGNvbnN0cnVjdGVkIGRpcmVjdGx5IHdpdGggYG5ld2AgaW4gaXRzIG93biBzcGVjcywgd2hpY2ggaXMgb3V0c2lkZVxuICAgIC8vIGFuIGluamVjdGlvbiBjb250ZXh0IGFuZCB3b3VsZCB0aHJvdyBORzAyMDMgb24gYSBmaWVsZCBpbml0aWFsaXplci5cbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFRPT0xCQVJfVE9PTFMpIHRvb2xDb250cmlidXRpb25zPzogcmVhZG9ubHkgVG9vbGJhckNvbnRyaWJ1dGlvbltdLFxuICAgIC8vIE9wdGlvbmFsIGxpa2UgdGhlIHJlc3Q6IGEgaG9zdCB0aGF0IHNob3dzIG9ubHkgaW1hZ2VzIG5ldmVyIHByb3ZpZGVzIGl0LFxuICAgIC8vIGFuZCB0aGUgc3BhdGlhbCBwbG90IHR5cGVzIHNpbXBseSBzdGF5IGhpZGRlbi5cbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFNQQVRJQUxfREFUQV9QT1JUKSBwcml2YXRlIHNwYXRpYWxEYXRhPzogU3BhdGlhbERhdGFQb3J0LFxuICAgIC8vIENvbnRyaWJ1dGVkIHBsb3QgbW9kZXMuIExpa2UgVE9PTEJBUl9UT09MUyB0aGUgdG9rZW4gaGFzIG5vIGZhY3RvcnksIHNvIGFcbiAgICAvLyBob3N0IHRoYXQgcHJvdmlkZXMgbm9uZSBnZXRzIG51bGwgaGVyZSBhbmQgdGhlIHNlbGVjdG9yIGlzIHVuY2hhbmdlZC5cbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFBMT1RfVFlQRV9DT05UUklCVVRJT05TKSBwbG90VHlwZUNvbnRyaWJ1dGlvbnM/OiByZWFkb25seSBQbG90VHlwZUNvbnRyaWJ1dGlvbltdLFxuICAgIC8vIFBhcmVudCBvZiBhIGNvbnRyaWJ1dGVkIHBhbmVsIGNvbXBvbmVudCdzIGluamVjdG9yLiBPcHRpb25hbCBvbmx5IHNvIHRoZVxuICAgIC8vIHNwZWNzIGNhbiBjb25zdHJ1Y3QgdGhpcyBjb21wb25lbnQgd2l0aCBgbmV3YC5cbiAgICBAT3B0aW9uYWwoKSBwcml2YXRlIGluamVjdG9yPzogSW5qZWN0b3IsXG4gICAgLy8gVGhlIGA8dmlzdWFsaXplcj5gIGVsZW1lbnQ6IGtleWJvYXJkIHNob3J0Y3V0cyBhcmUgc2NvcGVkIHRvIGl0IChDT1JFLTIpLlxuICAgIEBPcHRpb25hbCgpIHByaXZhdGUgaG9zdFJlZj86IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+LFxuICAgIC8vIEVuZHMgdGhlIHN1YnNjcmlwdGlvbnMgKGB0YWtlVW50aWxEZXN0cm95ZWRgKS4gQSBwYXJhbWV0ZXIsIGxpa2UgdGhlIHJlc3QsIHNvIHRoZVxuICAgIC8vIHNwZWNzJyBgbmV3YCBjYW4gcGFzcyBvbmU7IEFuZ3VsYXIgYWx3YXlzIHByb3ZpZGVzIGl0LlxuICAgIHByaXZhdGUgcmVhZG9ubHkgZGVzdHJveVJlZjogRGVzdHJveVJlZiA9IHVuZGVmaW5lZCBhcyB1bmtub3duIGFzIERlc3Ryb3lSZWYsXG4gICkge1xuICAgIHRoaXMuY29udHJpYnV0ZWRUb29scyA9IHZpc2libGVUb29sQ29udHJpYnV0aW9ucyh0b29sQ29udHJpYnV0aW9ucyk7XG4gICAgdGhpcy50b29sUGFyYW1zID0gbmV3IFRvb2xQYXJhbXNNb2RlbCh0aGlzLmNvbnRyaWJ1dGVkVG9vbHMpO1xuICAgIHRoaXMuY29udHJpYnV0aW9ucyA9IG5ldyBDb250cmlidXRpb25Ib3N0KHBsb3RUeXBlQ29udHJpYnV0aW9ucywgdG9vbENvbnRyaWJ1dGlvbnMsIHtcbiAgICAgIHZpc3VhbGl6ZXI6IHRoaXMucGxvdFNlcnZpY2UsXG4gICAgICB6b25lOiB0aGlzLm5nWm9uZSxcbiAgICAgIHRvb2xzOiB0aGlzLnRvb2xzLnBsb3RNb2RlVG9vbHMsXG4gICAgICBpbmplY3RvcjogdGhpcy5pbmplY3RvcixcbiAgICAgIGltYWdlSW5mbyQ6ICgpID0+IHRoaXMuc3RhdGUuZ2V0SW1hZ2VJbmZvJCgpLFxuICAgICAgc2VsZWN0ZWRJZDogKCkgPT4gdGhpcy5zZWxlY3RlZFBsb3RUeXBlSWQsXG4gICAgICByZW5kZXJlZFR5cGU6ICgpID0+IHRoaXMucGxvdFR5cGUsXG4gICAgICBzZWxlY3RCYXNlOiAoYmFzZSkgPT4ge1xuICAgICAgICB0aGlzLnNlbGVjdGVkUGxvdFR5cGVJZCA9IGJhc2U7XG4gICAgICAgIHRoaXMucGxvdFR5cGUgPSBiYXNlO1xuICAgICAgfSxcbiAgICAgIG5vdGlmeTogKG0pID0+IHRoaXMubWVzc2FnZVNlcnZpY2UuYWRkKHsga2V5OiB0aGlzLnJlc3VsdFRvYXN0S2V5LCAuLi5tIH0pLFxuICAgICAgZGV0ZWN0Q2hhbmdlczogKCkgPT4gdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpLFxuICAgIH0pO1xuICAgIHRoaXMuc3BhdGlhbCA9IG5ldyBTcGF0aWFsRGF0YXNldEJpbmRlcih0aGlzLnNwYXRpYWxEYXRhLCB7XG4gICAgICBnYXRlc0NoYW5nZWQ6ICgpID0+IHRoaXMuY29tcHV0ZVBsb3RUeXBlT3B0aW9ucygpLFxuICAgICAgc2VsZWN0ZWRJZDogKCkgPT4gdGhpcy5zZWxlY3RlZFBsb3RUeXBlSWQsXG4gICAgICBiYXNlUGxvdFR5cGU6ICgpID0+IHRoaXMuYmFzZVBsb3RUeXBlLFxuICAgICAgaGFzSW1hZ2U6ICgpID0+ICEhdGhpcy5pbWFnZUluZm8sXG4gICAgICBzZWxlY3RQbG90VHlwZTogKHR5cGUpID0+IHRoaXMub25TZWxlY3RQbG90VHlwZSh0eXBlKSxcbiAgICAgIHJlcGxvdDogKCkgPT4gdGhpcy5yZWxvYWRBbmRQbG90KCksXG4gICAgICBwdWJsaXNoSW1hZ2U6IChpbmZvKSA9PiB0aGlzLnN0YXRlLnNldEltYWdlSW5mbyhpbmZvKSxcbiAgICAgIHNldEltYWdlTG9hZGluZzogKGxvYWRpbmcpID0+IHRoaXMuc3RhdGUuc2V0SW1hZ2VMb2FkaW5nKGxvYWRpbmcpLFxuICAgICAgc2V0dGxlZDogKCkgPT4ge1xuICAgICAgICB0aGlzLnJlY29uY2lsZVNlbGVjdGVkUGxvdFR5cGUoKTtcbiAgICAgICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgICB9LFxuICAgICAgZGV0ZWN0Q2hhbmdlczogKCkgPT4gdGhpcy5jaGFuZ2VkKCksXG4gICAgfSk7XG4gICAgdGhpcy5jb21wdXRlUGxvdFR5cGVPcHRpb25zKCk7XG4gIH1cblxuICAvKiogRm9sbG93IHRoZSBzcGF0aWFsLW9taWNzIGRhdGFzZXQ6IGEgZGF0YXNldCBhcHBlYXJpbmcsIHN3aXRjaGluZyBvciBiZWluZyBjbGVhcmVkXG4gICAqICByZS1nYXRlcyB0aGUgc2VsZWN0b3IgZXhhY3RseSBhcyB0aGUgaW1hZ2Ugc3RyZWFtIGFuZCB0aGUgdGVzdC1tb2RlIHRvZ2dsZSBkby4gKi9cbiAgcHJpdmF0ZSB3YXRjaFNwYXRpYWxEYXRhc2V0KCk6IHZvaWQge1xuICAgIHRoaXMuc3BhdGlhbC5iaW5kKHRoaXMuZGVzdHJveWVkJCk7XG4gIH1cblxuICAvKiogUmVjb21wdXRlIHRoZSBzZWxlY3RvcidzIGVudHJpZXMgZm9yIHRoZSBjdXJyZW50IGltYWdlLCBkYXRhc2V0IGFuZCB0ZXN0IG1vZGVcbiAgICogIChzZWUge0BsaW5rIGNvbXB1dGVQbG90VHlwZU1lbnV9KS4gKi9cbiAgcHJpdmF0ZSBjb21wdXRlUGxvdFR5cGVPcHRpb25zKCkge1xuICAgIGNvbnN0IHsgYnVpbHRJbiwgbWVudSB9ID0gY29tcHV0ZVBsb3RUeXBlTWVudSh7XG4gICAgICBkZXNjcmlwdG9yczogdGhpcy5wbG90U2VydmljZS5nZXRQbG90VHlwZURlc2NyaXB0b3JzKCksXG4gICAgICBjb250cmlidXRpb25zOiB0aGlzLnBsb3RNb2Rlcy5kZXNjcmlwdG9ycygpLFxuICAgICAgY2FwczogdGhpcy5wbG90U2VydmljZS5jYXBhYmlsaXRpZXMsXG4gICAgICBpbWFnZUluZm86IHRoaXMuaW1hZ2VJbmZvLFxuICAgICAgc3BhdGlhbDogdGhpcy5zcGF0aWFsLFxuICAgICAgdGVzdE1vZGU6IHRoaXMudGVzdE1vZGUsXG4gICAgfSk7XG4gICAgdGhpcy5wbG90VHlwZU9wdGlvbnMgPSBidWlsdEluO1xuICAgIHRoaXMucGxvdFR5cGVNZW51ID0gbWVudTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICAvLyBUaGUgY29uc3RydWN0b3IgY29tcHV0ZXMgdGhlIG9wdGlvbnMgd2l0aCB0ZXN0TW9kZSBzdGlsbCBhdCBpdHMgZGVmYXVsdDtcbiAgICAvLyByZWNvbXB1dGUgb25jZSB0aGUgaG9zdCBiaW5kcyBpdCAoYW5kIG9uIGFueSBsYXRlciBjaGFuZ2UpIHNvIHRoZSBzZWxlY3RvclxuICAgIC8vIHJlZmxlY3RzIHRlc3QgbW9kZSBpbW1lZGlhdGVseSwgd2l0aG91dCB3YWl0aW5nIGZvciBhbiBpbWFnZSB0byAocmUpbG9hZC5cbiAgICBpZiAoY2hhbmdlc1sndGVzdE1vZGUnXSkge1xuICAgICAgdGhpcy5jb21wdXRlUGxvdFR5cGVPcHRpb25zKCk7XG4gICAgICAvLyBJZiB0ZXN0IG1vZGUgaXMgdHVybmVkIG9mZiB3aGlsZSBhIHRlc3Qtb25seSB0eXBlIChlLmcuIE5BUEFSSV9JTUFHRSkgaXNcbiAgICAgIC8vIGFjdGl2ZSwgdGhhdCB0eXBlIGlzIG5vIGxvbmdlciBvZmZlcmVkIOKAlCBmYWxsIGJhY2sgdG8gSW1hZ2UuXG4gICAgICB0aGlzLnJlY29uY2lsZVNlbGVjdGVkUGxvdFR5cGUoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVGhlIGhvc3QgcHVibGlzaGVkIE5PIGltYWdlIOKAlCBhIHNwYXRpYWwgZGF0YXNldCB0aGF0IGJyaW5ncyBub25lIGRvZXMgdGhpcy5cbiAgICpcbiAgICogV2l0aG91dCBoYW5kbGluZyB0aGUgZW1wdHkgZW1pc3Npb24sIGBpbWFnZUluZm9gIGtlZXBzIHRoZSBMQVNUIGltYWdlJ3MgbWV0YWRhdGE6IHRoZVxuICAgKiBzZWxlY3RvciBnb2VzIG9uIG9mZmVyaW5nIHBpeGVsIG1vZGVzIGZvciBwaXhlbHMgdGhhdCBhcmUgZ29uZSwgYW5kIGV2ZXJ5XG4gICAqIGBpc1N0YWNrYC9gaXNHcmF5c2NhbGVgIGRlY2lzaW9uIGlzIG1hZGUgYWdhaW5zdCBhIGZpbGUgdGhhdCBpcyBubyBsb25nZXIgbG9hZGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBvbkltYWdlQ2xlYXJlZCgpOiB2b2lkIHtcbiAgICAvLyBUaGUgaW1hZ2UgYSBjb250cmlidXRlZCBtb2RlIHdhcyBkcmF3aW5nIG92ZXIgaXMgZ29uZS4gQW4gb3BlbiBkaWFsb2dcbiAgICAvLyB0b29sIHN0YXlzIG9wZW4gYW5kIHJlc3RhcnRzIG9uY2UgdGhlIG5leHQgaW1hZ2UgaGFzIHBsb3R0ZWQuXG4gICAgdGhpcy5jb250cmlidXRpb25zLmVuZFNlc3Npb25zKCk7XG4gICAgdGhpcy5pbWFnZUluZm8gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5sb2FkZWRGaWxlTmFtZSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmNvbXB1dGVQbG90VHlwZU9wdGlvbnMoKTtcbiAgICAvLyBEZWxpYmVyYXRlbHkgTk9UIHJlY29uY2lsaW5nIHRoZSBzZWxlY3RlZCB0eXBlIGhlcmUuIFJlY29uY2lsaW5nIGNhbGxzXG4gICAgLy8gYHNldFBsb3RUeXBlYCwgd2hpY2ggZHJpdmVzIGEgcmUtcGxvdCDigJQgYW5kIHRoZXJlIGlzIG5vdGhpbmcgdG8gcGxvdCwgc28gdGhlXG4gICAgLy8gUGxvdGx5IGJhY2tlbmQgcmVhZCBpdHMgb3duIG5vdy11bnNldCBgaW1hZ2VJbmZvYCBhbmQgdGhyZXdcbiAgICAvLyAoXCJjYW4ndCBhY2Nlc3MgcHJvcGVydHkgaXNHcmF5c2NhbGVcIiksIGFib3J0aW5nIHRoZSBsb2FkIHdpdGggbm8gb2JzZXJ2YXRpb25zXG4gICAgLy8gZHJhd24uIElnbm9yaW5nIHRoZSBlbXB0eSBlbWlzc2lvbiBlbnRpcmVseSBpcyB3aGF0IHVzZWQgdG8gYXZvaWQgdGhhdC5cbiAgICAvL1xuICAgIC8vIE5vdGhpbmcgaXMgbGVmdCBzdHJhbmRlZDogYW4gaW1hZ2UgaXMgY2xlYXJlZCBiZWNhdXNlIGEgc3BhdGlhbCBkYXRhc2V0IHRoYXRcbiAgICAvLyBicmluZ3Mgbm9uZSBpcyBiZWluZyBvcGVuZWQsIGFuZCB0aGF0IGRhdGFzZXQncyBvd24gc3Vic2NyaXB0aW9uIHNlbGVjdHMgdGhlXG4gICAgLy8gbW9kZSBpdHMgY29vcmRpbmF0ZXMgc3VwcG9ydCBhIG1vbWVudCBsYXRlci5cbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfVxuXG4gIC8qKiBJZiB0aGUgYWN0aXZlIHBsb3QgdHlwZSBpcyBubyBsb25nZXIgaW4gdGhlIG9mZmVyZWQgb3B0aW9ucyAoZS5nLiB0ZXN0IG1vZGVcbiAgICogIHR1cm5lZCBvZmYgd2hpbGUgYSB0ZXN0LW9ubHkgdHlwZSB3YXMgYWN0aXZlLCBvciBhIHNjYWxhciB0eXBlIGNhcnJpZWQgb250b1xuICAgKiAgYW4gUkdCIGltYWdlKSwgZmFsbCBiYWNrIHRvIHRoZSBkZWZhdWx0IDJEIEltYWdlIHZpZXcuICovXG4gIHByaXZhdGUgcmVjb25jaWxlU2VsZWN0ZWRQbG90VHlwZSgpOiB2b2lkIHtcbiAgICBjb25zdCBmYWxsYmFjayA9IHJlY29uY2lsZVBsb3RUeXBlKHRoaXMucGxvdFR5cGVNZW51LCB0aGlzLnNlbGVjdGVkUGxvdFR5cGVJZCk7XG4gICAgaWYgKCFmYWxsYmFjaykgcmV0dXJuO1xuICAgIC8vIExlYXZpbmcgYSBjb250cmlidXRlZCBtb2RlIChpdHMgZ2F0ZXMgc3RvcHBlZCBwYXNzaW5nLCBvciBpdHMgcHJvdmlkZXIgaXNcbiAgICAvLyBnb25lKTogaXRzIHNlc3Npb24gZW5kcyBiZWZvcmUgYW55dGhpbmcgZWxzZSBkcmF3cy5cbiAgICB0aGlzLnBsb3RNb2Rlcy5kZWFjdGl2YXRlKCk7XG4gICAgY29uc3QgYmFzZSA9IHRoaXMucGxvdE1vZGVzLmJhc2VUeXBlT2YoZmFsbGJhY2spO1xuICAgIGlmIChiYXNlICE9PSBQbG90VHlwZS5JTUFHRSkgdGhpcy5jbG9zZURpYWxvZ1Rvb2woKTtcbiAgICB0aGlzLnNlbGVjdGVkUGxvdFR5cGVJZCA9IGZhbGxiYWNrO1xuICAgIHRoaXMucGxvdFR5cGUgPSBiYXNlO1xuICAgIHRoaXMuaXNIZWF0bWFwID0gYmFzZSA9PT0gUGxvdFR5cGUuSU1BR0U7XG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRQbG90VHlwZShiYXNlKTtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIC8vIEpvaW4gdGhlIGxpdmUgc2V0OyB0aGUgb2xkZXN0IG1lbWJlciByZW5kZXJzIHRoZSBzaGFyZWQgbm90aWNlIG91dGxldHMuXG4gICAgVmlzdWFsaXplckNvbXBvbmVudC5saXZlSW5zdGFuY2VzLmFkZCh0aGlzKTtcbiAgICB0aGlzLnN0YXRlLnNldERpYWdyYW0odGhpcy5ob3N0SGFuZGxlKTtcbiAgICB0aGlzLndhdGNoU3BhdGlhbERhdGFzZXQoKTtcbiAgICAvLyBPU0QgYW5kIG5hcGFyaS1qcyBlbWl0IHRoaXMgZnJvbSB0aGVpciBvd24gXCJmaXQgdG8gdmlld1wiOiBkaXNhcm0gdGhlIHRvb2wgb25cbiAgICAvLyB0aGUgYmFja2VuZCB0b28sIG5vdCBvbmx5IHRoZSB0b29sYmFyJ3MgaGlnaGxpZ2h0LlxuICAgIHRoaXMucGxvdFNlcnZpY2VcbiAgICAgIC5nZXRBdXRvc2NhbGVFdmVudCgpXG4gICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSlcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy50b29scy5hcHBseShudWxsKSk7XG4gICAgLy8gTG9hZGluZy9vdmVybGF5IFVJIG1pcnJvcnMgKHNpZ25hbHM6IHRoZXkgcmUtcmVuZGVyIHRoZSB2aWV3IHRoZW1zZWx2ZXMpLlxuICAgIHRoaXMubWlycm9yKHRoaXMuc3RhdGUuaXNJbWFnZUxvYWRpbmckKCksICh2KSA9PiB0aGlzLmltZ0xvYWRpbmcuc2V0KHYpKTtcbiAgICB0aGlzLm1pcnJvcih0aGlzLnBsb3RTZXJ2aWNlLmdldFN0YWNrTG9hZGluZ1Byb2dyZXNzKCksICh2KSA9PiB0aGlzLmxvYWRpbmdQZXJjZW50YWdlLnNldCh2KSk7XG4gICAgdGhpcy5taXJyb3IodGhpcy5wbG90U2VydmljZS5pc1N0YWNrTG9hZGluZygpLCAodikgPT4gdGhpcy5zdGFja0xvYWRpbmcuc2V0KHYpKTtcbiAgICAvLyBUaGUgc2xpY2UgZWRpdG9yOiBpdHMgc2VjdGlvbnMsIGFuZCB0aGUgc2xpY2UgcGlja2VkIGJ5IGRyYWdnaW5nIHRoZSB6IHBsYW5lIGluIHRoZSB2b2x1bWUuXG4gICAgY29uc3Qgc2VjdGlvbnMkID0gdGhpcy5wbG90U2VydmljZS5nZXRTZWN0aW9uVmlld3MkPy4oKTtcbiAgICBpZiAoc2VjdGlvbnMkKSB7XG4gICAgICB0aGlzLm1pcnJvcihzZWN0aW9ucyQsICh2KSA9PiB7XG4gICAgICAgIHRoaXMuc2VjdGlvbnMgPSB2O1xuICAgICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBjb25zdCBzbGljZURyYWckID0gdGhpcy5wbG90U2VydmljZS5nZXRTbGljZURyYWckPy4oKTtcbiAgICBpZiAoc2xpY2VEcmFnJCkge1xuICAgICAgdGhpcy5taXJyb3Ioc2xpY2VEcmFnJCwgKHopID0+IHtcbiAgICAgICAgdGhpcy5vblpTY3J1YihNYXRoLm1pbih0aGlzLm1heEluZGV4LCBNYXRoLm1heCgwLCB6KSkpO1xuICAgICAgICAvLyBGcm9tIGEgRE9NIGxpc3RlbmVyLCBub3QgYSB0ZW1wbGF0ZSBldmVudDogdGhlIHNsaWRlciBhbmQgYmFkZ2UgbXVzdCBiZSBtYXJrZWQgdG8gZm9sbG93LlxuICAgICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICB0aGlzLm1pcnJvcih0aGlzLnN0YXRlLmdldEltYWdlTG9hZGluZ01lc3NhZ2UkKCksICh2KSA9PiB0aGlzLmxvYWRpbmdNZXNzYWdlLnNldCh2KSk7XG4gICAgdGhpcy5taXJyb3IodGhpcy5zdGF0ZS5nZXRDYWNoZVByb2dyZXNzJCgpLCAodikgPT4gdGhpcy5jYWNoZVByb2dyZXNzLnNldCh2KSk7XG4gICAgdGhpcy5taXJyb3IodGhpcy5zdGF0ZS5pc1pvb20kKCksICh2KSA9PiB0aGlzLnpvb20uc2V0KHYpKTtcbiAgICB0aGlzLm1pcnJvcih0aGlzLnN0YXRlLmdldEZpbGVuYW1lJCgpLCAodikgPT4ge1xuICAgICAgaWYgKHYpIHRoaXMuZmlsZU5hbWUgPSB2O1xuICAgIH0pO1xuICAgIHRoaXMucmVnaW9uQWN0aW9ucy5iaW5kKHRoaXMuZGVzdHJveWVkJCwgKCkgPT4gdGhpcy5jaGFuZ2VkKCkpO1xuICAgIHRoaXMuc2VnbWVudGF0aW9uLmJpbmRQb2ludFRvb2wodGhpcy5zYW1Qb2ludFRvb2wsIHRoaXMuZGVzdHJveWVkJCk7XG4gICAgdGhpcy5taXJyb3IodGhpcy5zdGF0ZS5nZXRQYW5lbFdpZHRoJCgpLCAoKSA9PiB7XG4gICAgICB0aGlzLnBsb3RTZXJ2aWNlLnJlbGF5b3V0KCk7XG4gICAgICAvLyBUaGUgaW50ZW5zaXR5IGluc2V0IGlzIGEgc2VwYXJhdGUgY2hhcnQgaW4gYSBmbG9hdGluZyBwYW5lbDsgcmVmbG93IGl0IHRvby5cbiAgICAgIHRoaXMuaW5zZXQ/LnJlZmxvdygpO1xuICAgIH0pO1xuICAgIHRoaXMuc3RhdGVcbiAgICAgIC5nZXRJbWFnZUluZm8kKClcbiAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLmRlc3Ryb3lSZWYpKVxuICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChpbWdJbmZvKSA9PiB7XG4gICAgICAgICAgaWYgKCFpbWdJbmZvKSB7XG4gICAgICAgICAgICB0aGlzLm9uSW1hZ2VDbGVhcmVkKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIFRoZSBzZWxlY3RvciwgdGhlIHN0YWNrIGNvbnRyb2xzIGFuZCB0aGUgaW5zZXQgYWxsIGZvbGxvdyB0aGUgaW1hZ2UuXG4gICAgICAgICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgICAgICAgaWYgKGltZ0luZm8pIHtcbiAgICAgICAgICAgIHRoaXMuaW1hZ2VJbmZvID0gaW1nSW5mbztcbiAgICAgICAgICAgIC8vIFN0YWNrLW9ubHkgcGxvdCB0eXBlcyAoaXNvc3VyZmFjZSwgc2NhdHRlcjNkKSBkZXBlbmQgb24gd2hldGhlciB0aGlzXG4gICAgICAgICAgICAvLyBmaWxlIGlzIGEgc3RhY2sg4oCUIHJlY29tcHV0ZSB0aGUgc2VsZWN0b3Igb3B0aW9ucy5cbiAgICAgICAgICAgIHRoaXMuY29tcHV0ZVBsb3RUeXBlT3B0aW9ucygpO1xuICAgICAgICAgICAgLy8gSWYgdGhlIGFjdGl2ZSBwbG90IHR5cGUgaXNuJ3QgdmFsaWQgZm9yIHRoaXMgaW1hZ2UgKGUuZy4gYSBzY2FsYXJcbiAgICAgICAgICAgIC8vIHR5cGUgbGlrZSBDb250b3VyIGNhcnJpZWQgb3ZlciB0byBhbiBSR0IgaW1hZ2UpLCBmYWxsIGJhY2sgdG8gSW1hZ2UuXG4gICAgICAgICAgICB0aGlzLnJlY29uY2lsZVNlbGVjdGVkUGxvdFR5cGUoKTtcbiAgICAgICAgICAgIC8vIFJlYWQgZnJvbSBgaW1nSW5mb2AsIHRoZSB2YWx1ZSB0aGlzIGVtaXNzaW9uIGNhcnJpZWQsIHJhdGhlciB0aGFuIGZyb20gdGhlXG4gICAgICAgICAgICAvLyBmaWVsZC4gSGFuZGxpbmcgdGhlIGVtcHR5IGVtaXNzaW9uIG1lYW5zIHRoZSBmaWVsZCBDQU4gYmUgbnVsbGVkIHBhcnQtd2F5XG4gICAgICAgICAgICAvLyB0aHJvdWdoIHRoaXMgYnJhbmNoOiBgcmVjb25jaWxlU2VsZWN0ZWRQbG90VHlwZWAgbWF5IGNhbGwgYHNldFBsb3RUeXBlYCxcbiAgICAgICAgICAgIC8vIHdoaWNoIGNhbiBtYWtlIHRoZSBob3N0IHB1Ymxpc2ggYSBuZXcgaW1hZ2Ugc3RhdGUsIHJlLWVudGVyaW5nIHRoaXMgdmVyeVxuICAgICAgICAgICAgLy8gc3Vic2NyaXB0aW9uLiBSZWFkaW5nIHRoZSBmaWVsZCB0aGVuIHRocmV3IG9uIGBpc0dyYXlzY2FsZWAgYW5kIGFib3J0ZWQgdGhlXG4gICAgICAgICAgICAvLyBoYW5kbGVyLCBzbyB0aGUgb2JzZXJ2YXRpb25zIHdlcmUgbmV2ZXIgZHJhd24uXG4gICAgICAgICAgICB0aGlzLmlzR3JheXNjYWxlRXZlbnQuZW1pdChpbWdJbmZvLmlzR3JheXNjYWxlKTtcbiAgICAgICAgICAgIHRoaXMuaXNTdGFja0V2ZW50LmVtaXQoaW1nSW5mby5pc1N0YWNrKTtcbiAgICAgICAgICAgIC8vIFJlc2V0IHRvIHRoZSBkZWZhdWx0IDJEIEltYWdlIHZpZXcgd2hlbiBhIGRpZmZlcmVudCBpbWFnZSBpc1xuICAgICAgICAgICAgLy8gc2VsZWN0ZWQgd2hpbGUgYSAzRCB0eXBlIGlzIGFjdGl2ZS5cbiAgICAgICAgICAgIGlmICghdGhpcy5pc0hlYXRtYXAgJiYgaW1nSW5mby5maWxlTmFtZSAhPT0gdGhpcy5sb2FkZWRGaWxlTmFtZSkge1xuICAgICAgICAgICAgICB0aGlzLmlzSGVhdG1hcCA9IHRydWU7XG4gICAgICAgICAgICAgIHRoaXMucGxvdFR5cGUgPSBQbG90VHlwZS5JTUFHRTtcbiAgICAgICAgICAgICAgdGhpcy5zZWxlY3RlZFBsb3RUeXBlSWQgPSBQbG90VHlwZS5JTUFHRTtcbiAgICAgICAgICAgICAgdGhpcy5wbG90U2VydmljZS5zZXRQbG90VHlwZSh0aGlzLnBsb3RUeXBlKTtcbiAgICAgICAgICAgICAgdGhpcy5hY3RpdmVTdXJmYWNlM2RNb2RlID0gJ3R1cm50YWJsZSc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmxvYWRlZEZpbGVOYW1lID0gaW1nSW5mby5maWxlTmFtZTtcbiAgICAgICAgICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0SW1hZ2VNZXRhKGltZ0luZm8uaW1hZ2VNZXRhLCBpbWdJbmZvLmZpbGVOYW1lKTtcbiAgICAgICAgICAgIC8vIEEgbmV3ZXIgaW1hZ2UgYWx3YXlzIHByZWVtcHRzIGFuIGluLWZsaWdodCByZW5kZXIgKHNlZSBJbWFnZVJlbmRlclNlc3Npb24pLlxuICAgICAgICAgICAgaWYgKGltZ0luZm8udXJscykgdGhpcy5yZW5kZXIucmVuZGVyKGltZ0luZm8pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IChlcnI6IHVua25vd24pID0+IHtcbiAgICAgICAgICBjb25zdCBtc2cgPSBlcnJvck1lc3NhZ2UoZXJyKTtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBvY2N1cmVkIHdoZW4gZ2V0dGluZyBpbWFnZSBpbmZvJywgZXJyKTtcbiAgICAgICAgICB0aGlzLm1lc3NhZ2VTZXJ2aWNlLmFkZCh7XG4gICAgICAgICAgICBrZXk6IHRoaXMudml6QWxlcnRUb2FzdEtleSxcbiAgICAgICAgICAgIHN0aWNreTogdHJ1ZSxcbiAgICAgICAgICAgIHNldmVyaXR5OiAnZXJyb3InLFxuICAgICAgICAgICAgc3VtbWFyeTogJ0FuIGVycm9yIG9jY3VyZWQnLFxuICAgICAgICAgICAgZGV0YWlsOiBgVGhlIGZvbGxvd2luZyBlcnJvciBvY2N1cmVkIHdoaWxlIGdldHRpbmcgaW1hZ2UgaW5mbzogJHttc2d9LlxuICAgICAgICAgICAgICAgICAgIFBsZWFzZSB0cnkgdG8gb3BlbiB0aGUgaW1hZ2UgYWdhaW4gdGhyb3VnaCB0aGUgZmlsZSBuYXZpZ2F0b3IuYCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICB0aGlzLnN0YWNrTG9hZGluZy5zZXQoZmFsc2UpO1xuICAgICAgICAgIHRoaXMuc3RhdGUuc2V0SW1hZ2VMb2FkaW5nKGZhbHNlKTtcbiAgICAgICAgICB0aGlzLnJlbmRlci5ydW5uaW5nID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy5wbG90U2VydmljZS5yZXNldCgpO1xuICAgICAgICB9LFxuICAgICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRm9sbG93IGBzb3VyY2VgIHVudGlsIGRlc3Ryb3kuIEhvc3Qgc3RyZWFtcyBjYW4gZW1pdCBvdXRzaWRlIHRoZSBBbmd1bGFyIHpvbmUgKGFcbiAgICogc2VydmVybGVzcyBob3N0IGNsZWFycyBpdHMgbG9hZGluZyBmbGFnIGZyb20gYW4gaW1hZ2UgZGVjb2RlIG9yIGFuIE9wZW5TZWFkcmFnb25cbiAgICogY2FsbGJhY2spOyBzZXR0aW5nIGEgc2lnbmFsIHRoZXJlIG1hcmtzIHRoaXMgT25QdXNoIHZpZXcgYnV0IHNjaGVkdWxlcyBubyBjaGFuZ2VcbiAgICogZGV0ZWN0aW9uLCBzbyB0aGUgdXBkYXRlIGlzIGFwcGxpZWQgaW5zaWRlIHRoZSB6b25lLCBhcyB7QGxpbmsgY2hhbmdlZH0gZG9lcy5cbiAgICovXG4gIHByaXZhdGUgbWlycm9yPFQ+KHNvdXJjZTogT2JzZXJ2YWJsZTxUPiwgYXBwbHk6ICh2YWx1ZTogVCkgPT4gdm9pZCk6IHZvaWQge1xuICAgIHNvdXJjZS5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLmRlc3Ryb3lSZWYpKS5zdWJzY3JpYmUoKHZhbHVlKSA9PiB7XG4gICAgICBpZiAoTmdab25lLmlzSW5Bbmd1bGFyWm9uZSgpKSBhcHBseSh2YWx1ZSk7XG4gICAgICBlbHNlIHRoaXMubmdab25lLnJ1bigoKSA9PiBhcHBseSh2YWx1ZSkpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXRlIHRoaXMgdmlldyBzaG93cyBjaGFuZ2VkIG91dHNpZGUgb25lIG9mIGl0cyB0ZW1wbGF0ZSBldmVudHMgKGEgc3RyZWFtLCBhXG4gICAqIHJlc29sdmVkIHByb21pc2UsIGEgaG9zdCBjYWxsKTogbWFyayB0aGUgT25QdXNoIHZpZXcgZm9yIGNoZWNrLCByZS1lbnRlcmluZyB0aGVcbiAgICogem9uZSB3aGVuIGl0IGNoYW5nZWQgb3V0c2lkZSBpdCBzbyBhIGNoYW5nZS1kZXRlY3Rpb24gcGFzcyBmb2xsb3dzLlxuICAgKi9cbiAgcHJpdmF0ZSBjaGFuZ2VkKCk6IHZvaWQge1xuICAgIGlmIChOZ1pvbmUuaXNJbkFuZ3VsYXJab25lKCkpIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIGVsc2UgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMYXkgYSBuZXcgaW1hZ2Ugb3V0IG9uY2UgdGhlIG9sZCB2aWV3IGlzIGdvbmU6IHRoZSBzdGFjayBmbGFnLCB0aGUgc2xpY2UgYm91bmRzIChvbmVcbiAgICogdXJsIHBlciBzbGljZSwgc28gdGhlIGxhc3QgaW5kZXggaXMgbGVuZ3RoLTEpLCBhbmQgdGhlIG9uZS1zaG90IGBpbml0aWFsWkluZGV4YCBoaW50XG4gICAqIChlLmcuIHRoZSBmaWxlIHRoZSB1c2VyIGNsaWNrZWQgd2l0aGluIGEgbnVtYmVyZWQgc2VyaWVzKS4gVGhlIGhpbnQgaXMgY29uc3VtZWQgc29cbiAgICogcmUtZGVsaXZlcmluZyB0aGUgc2FtZSBpbmZvIChhIHBsb3QtdHlwZSBzd2l0Y2gsIHJlbG9hZEFuZFBsb3QpIGRvZXMgbm90IHJlc2V0IHRoZVxuICAgKiB1c2VyJ3Mgc2NydWI7IHRoZSBob3N0J3Mgb2JqZWN0IGlzIG5ldmVyIHdyaXR0ZW4gdG8gKGEgaG9zdCBzdG9yZSBtYXkgZnJlZXplIGl0KSDigJRcbiAgICogdGhlIGNvbXBvbmVudCBrZWVwcyBhIGNvcHkgd2l0aG91dCB0aGUgaGludCwgYW5kIHJlbWVtYmVycyB0aGUgaG9zdCBvYmplY3QuXG4gICAqL1xuICBwcml2YXRlIGxheU91dFNsaWNlcyhpbmZvOiBJSW1hZ2VJbmZvKTogdm9pZCB7XG4gICAgdGhpcy5zdGFja0xvYWRpbmcuc2V0KGluZm8uaXNTdGFjayAmJiBpbmZvLnNob3dTdGFjayk7XG4gICAgdGhpcy5tYXhJbmRleCA9IGluZm8udXJscy5sZW5ndGggPiAxID8gaW5mby51cmxzLmxlbmd0aCAtIDEgOiAwO1xuICAgIGlmIChpbmZvLmluaXRpYWxaSW5kZXggIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKCF0aGlzLmNvbnN1bWVkU2xpY2VIaW50cy5oYXMoaW5mbykpIHtcbiAgICAgICAgdGhpcy5jb25zdW1lZFNsaWNlSGludHMuYWRkKGluZm8pO1xuICAgICAgICB0aGlzLnpJbmRleCA9IGluZm8uaW5pdGlhbFpJbmRleDtcbiAgICAgIH1cbiAgICAgIHRoaXMuaW1hZ2VJbmZvID0geyAuLi5pbmZvLCBpbml0aWFsWkluZGV4OiB1bmRlZmluZWQgfTtcbiAgICB9XG4gICAgdGhpcy51cGRhdGVaSW5kZXgoKTtcbiAgfVxuXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpIHtcbiAgICAvLyBXaW5kb3cgbGlzdGVuZXJzIGFyZSByZWdpc3RlcmVkIE9VVFNJREUgdGhlIEFuZ3VsYXIgem9uZTogem9uZS1wYXRjaGVkLCBldmVyeVxuICAgIC8vIG1vdXNlbW92ZSBhbnl3aGVyZSBpbiB0aGUgaG9zdCBhcHAgcmFuIGFwcC13aWRlIGNoYW5nZSBkZXRlY3Rpb24uIEVhY2ggaGFuZGxlclxuICAgIC8vIHJlLWVudGVycyB0aGUgem9uZSAobmdab25lLnJ1bikgb25seSB3aGVuIGl0IGFjdHVhbGx5IGNoYW5nZXMgdmlldyBzdGF0ZS5cbiAgICB0aGlzLnNob3J0Y3V0cyA9IG5ldyBWaWV3ZXJTaG9ydGN1dHModGhpcy5zaG9ydGN1dEhvc3QoKSwgdGhpcy5uZ1pvbmUpO1xuICAgIHRoaXMuc2hvcnRjdXRzLmF0dGFjaCgpO1xuICAgIHRoaXMub25WaWV3UmVhZHkoKTtcbiAgfVxuXG4gIC8qKiBUaGUgcGxvdCBkaXYgZXhpc3RzIG5vdzogcnVuIGFuIGltYWdlLWxlc3MgZHJhdyB0aGF0IGFycml2ZWQgYmVmb3JlIGl0IGRpZC4gKi9cbiAgcHJpdmF0ZSBvblZpZXdSZWFkeSgpOiB2b2lkIHtcbiAgICB0aGlzLnJlbmRlci52aWV3SXNSZWFkeSh0aGlzLnNwYXRpYWwuZGF0YXNldCwgISF0aGlzLmltYWdlSW5mbyk7XG4gIH1cblxuICAvKiogV2hhdCB0aGUga2V5Ym9hcmQsIHdoZWVsIGFuZCBjb250ZXh0LW1lbnUgc2hvcnRjdXRzIGFjdCBvbi4gVGhlaXIgbGlzdGVuZXJzIGxpdmVcbiAgICogIG91dHNpZGUgdGhpcyB2aWV3LCBzbyBldmVyeSBhY3Rpb24gdGhhdCBjaGFuZ2VzIHdoYXQgaXQgc2hvd3MgbWFya3MgaXQgZm9yIGNoZWNrLiAqL1xuICBwcml2YXRlIHNob3J0Y3V0SG9zdCgpOiBTaG9ydGN1dEhvc3Qge1xuICAgIGNvbnN0IG1hcmtlZCA9XG4gICAgICA8QSBleHRlbmRzIHVua25vd25bXT4oYWN0OiAoLi4uYXJnczogQSkgPT4gdm9pZCkgPT5cbiAgICAgICguLi5hcmdzOiBBKTogdm9pZCA9PiB7XG4gICAgICAgIGFjdCguLi5hcmdzKTtcbiAgICAgICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgICB9O1xuICAgIHJldHVybiB7XG4gICAgICBwbG90RGl2TmFtZTogdGhpcy5wbG90RGl2TmFtZSxcbiAgICAgIGhvc3RFbGVtZW50OiB0aGlzLmhvc3RSZWY/Lm5hdGl2ZUVsZW1lbnQgPz8gbnVsbCxcbiAgICAgIGFjdGl2ZURyYWdNb2RlOiAoKSA9PiB0aGlzLmFjdGl2ZURyYWdNb2RlLFxuICAgICAgY2FuU3RlcFNsaWNlOiAoKSA9PiAhIXRoaXMuaW1hZ2VJbmZvPy5pc1N0YWNrICYmICh0aGlzLmlzSW1hZ2VWaWV3IHx8IHRoaXMuc2xpY2VFZGl0b3JTaG93biksXG4gICAgICB3aGVlbFpvb21zOiAoKSA9PiAhcmVuZGVyZXJPd25zV2hlZWwodGhpcy5iYXNlUGxvdFR5cGUpICYmIHRoaXMuaXNIZWF0bWFwLFxuICAgICAgc3RlcFNsaWNlOiBtYXJrZWQoKGRlbHRhOiBudW1iZXIpID0+IHRoaXMuc3RlcFNsaWNlKGRlbHRhKSksXG4gICAgICByZXNvbHZlU2FtUHJvbXB0OiBtYXJrZWQoKGNvbW1pdDogYm9vbGVhbikgPT4ge1xuICAgICAgICBpZiAoY29tbWl0KSB0aGlzLnBsb3RTZXJ2aWNlLmNvbW1pdFNhbVBvaW50cygpO1xuICAgICAgICBlbHNlIHRoaXMucGxvdFNlcnZpY2UuY2xlYXJTYW1Qb2ludHMoKTtcbiAgICAgICAgdGhpcy5zZWdtZW50YXRpb24uaGlkZSgpOyAvLyBwcm9tcHQgcmVzb2x2ZWQg4oaSIGRpc21pc3MgdGhlIHN0YXR1cyB0b2FzdFxuICAgICAgfSksXG4gICAgICB1bmRvOiBtYXJrZWQoKCkgPT4gdGhpcy51bmRvUmVnaW9uKCkpLFxuICAgICAgcmVkbzogbWFya2VkKCgpID0+IHRoaXMucmVkb1JlZ2lvbigpKSxcbiAgICAgIGRlbGV0ZVJlZ2lvbjogbWFya2VkKCgpID0+IHRoaXMuZGVsZXRlUmVnaW9uKCkpLFxuICAgICAgem9vbUluOiBtYXJrZWQoKCkgPT4gdGhpcy56b29tSW4oKSksXG4gICAgICB6b29tT3V0OiBtYXJrZWQoKCkgPT4gdGhpcy56b29tT3V0KCkpLFxuICAgICAgdG9nZ2xlRHJhZ01vZGU6IG1hcmtlZCgobW9kZTogc3RyaW5nKSA9PiB0aGlzLnRvZ2dsZURyYWdNb2RlKG1vZGUpKSxcbiAgICAgIG9wZW5Db250ZXh0TWVudTogKGV2ZW50KSA9PiB7XG4gICAgICAgIHRoaXMuY29udGV4dE1lbnVJdGVtcyA9IHRoaXMuYnVpbGRDb250ZXh0TWVudUl0ZW1zKCk7XG4gICAgICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTtcbiAgICAgICAgdGhpcy5jb250ZXh0TWVudS5zaG93KGV2ZW50KTtcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIC8qKiBTbmFwIHRoZSBmbG9hdGluZyB0b29sYmFyIGJhY2sgdG8gaXRzIGRvY2tlZCBwb3NpdGlvbiBhY3Jvc3MgdGhlIHRvcC4gKi9cbiAgcHJvdGVjdGVkIGRvY2tUb29sYmFyKCkge1xuICAgIHRoaXMudG9vbGJhckZsb2F0aW5nID0gZmFsc2U7XG4gIH1cblxuICAvKiogVG9vbGJhciBcIkludGVuc2l0eVwiIGdyb3VwOiBhZGQgYW5vdGhlciBsaW5lIFJPSSAobmV4dCBicmlnaHQgY29sb3VyKS4gKi9cbiAgcHJvdGVjdGVkIGFzeW5jIGFkZFByb2ZpbGVMaW5lKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHJlZ2lvbiA9IGF3YWl0IHRoaXMuaW5zZXQ/LmFkZFByb2ZpbGVMaW5lKCk7XG4gICAgLy8gT1NEIG9ubHkgZHJhd3MgYSBzZWxlY3RlZCByZWdpb24ncyBoYW5kbGVzIGluIGFuIGVkaXQgbW9kZSwgc28gYSBsaW5lIGluXG4gICAgLy8gJ25vbmUnIG1vZGUgbG9va3MgdW5zZWxlY3RlZC4gU3dpdGNoIHRvICdzZWxlY3QnIHNvIHRoZSBuZXcgbGluZSBzaG93cyBpdHNcbiAgICAvLyBlbmRwb2ludCBoYW5kbGVzIGFuZCBjYW4gYmUgZHJhZ2dlZC9kZWxldGVkIHJpZ2h0IGF3YXkuXG4gICAgaWYgKHJlZ2lvbiAmJiB0aGlzLmlzSW1hZ2VWaWV3ICYmIHRoaXMuYWN0aXZlRHJhZ01vZGUgIT09ICdzZWxlY3QnKSB0aGlzLnRvZ2dsZURyYWdNb2RlKCdzZWxlY3QnKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIC8vIEEgY29udHJpYnV0ZWQgbW9kZSdzIHNlc3Npb24gZW5kcyBmaXJzdCwgd2hpbGUgdGhlIHZpZXdlciBpdCBkcmV3IG92ZXJcbiAgICAvLyBzdGlsbCBleGlzdHMuIFRoZSBwYW5lbCBnb2VzIHdpdGggdGhpcyB2aWV3LCBzbyBubyBjaGFuZ2UgZGV0ZWN0aW9uLlxuICAgIHRoaXMuY29udHJpYnV0aW9ucy5kZXN0cm95KCk7XG4gICAgLy8gTGVhdmUgdGhlIGxpdmUgc2V0IHNvIHRoZSBuZXh0LW9sZGVzdCB2aXN1YWxpemVyIHBpY2tzIHVwIHRoZSBvdXRsZXRzIOKAlCBvbiBpdHNcbiAgICAvLyBuZXh0IGNoZWNrLCB3aGljaCBhbiBPblB1c2ggc2libGluZyBuZWVkcyBhc2tpbmcgZm9yLlxuICAgIFZpc3VhbGl6ZXJDb21wb25lbnQubGl2ZUluc3RhbmNlcy5kZWxldGUodGhpcyk7XG4gICAgZm9yIChjb25zdCBvdGhlciBvZiBWaXN1YWxpemVyQ29tcG9uZW50LmxpdmVJbnN0YW5jZXMpIG90aGVyLmNoYW5nZWQoKTtcbiAgICB0aGlzLnN0YXRlLnNldERpYWdyYW0obnVsbCk7XG4gICAgdGhpcy5yZW5kZXIuY2FuY2VsKCk7XG4gICAgdGhpcy5zcGF0aWFsLmRpc3Bvc2UoKTtcbiAgICB0aGlzLnNjcnViYmVyLmNhbmNlbCgpO1xuICAgIHRoaXMuc2hvcnRjdXRzPy5kZXRhY2goKTtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLmRldGFjaCgpO1xuICB9XG5cbiAgLyoqIFdoYXQgdGhlIGhvc3QgZ2V0cyB0aHJvdWdoIGBzZXREaWFncmFtYCDigJQgc2VlIHtAbGluayBWaXN1YWxpemVySGFuZGxlfS4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBob3N0SGFuZGxlOiBWaXN1YWxpemVySGFuZGxlID0ge1xuICAgIHZpc3VhbGl6ZXI6IHRoaXMucGxvdFNlcnZpY2UsXG4gICAgcGxvdFNlcnZpY2U6IHRoaXMucGxvdFNlcnZpY2UsXG4gICAgaGFzUmVnaW9uczogKCkgPT4gdGhpcy5oYXNSZWdpb25zKCksXG4gICAgZ2V0UmVnaW9uUG9seWdvbnM6ICgpID0+IHRoaXMuZ2V0UmVnaW9uUG9seWdvbnMoKSxcbiAgfTtcblxuICBwdWJsaWMgaGFzUmVnaW9ucygpOiBib29sZWFuIHtcbiAgICAvLyBUaGUgY29udHJhY3QncyBmcmFtZXdvcmstbmV1dHJhbCByZWdpb24gYWNjZXNzb3I6IHRoZSBjb21wb25lbnQgb25seSBuZWVkcyB0b1xuICAgIC8vIGtub3cgd2hldGhlciBhbnkgcmVnaW9uIGV4aXN0cywgbmV2ZXIgYSBiYWNrZW5kJ3Mgd2lyZSBmb3JtYXQuXG4gICAgcmV0dXJuIHRoaXMucGxvdFNlcnZpY2UuZ2V0UmVnaW9ucygpLmxlbmd0aCA+IDA7XG4gIH1cblxuICAvKiogVGhlIGN1cnJlbnQgcmVnaW9ucyBhcyBwb2x5Z29ucyAoYWxzbyBvbiB0aGUgaG9zdCBoYW5kbGUpLiAqL1xuICBwdWJsaWMgZ2V0UmVnaW9uUG9seWdvbnMoKTogUG9seWdvbltdIHtcbiAgICByZXR1cm4gdGhpcy5wbG90U2VydmljZS5nZXRSZWdpb25Qb2x5Z29ucygpO1xuICB9XG5cbiAgLyoqIE9wZW4gdGhlIENoYW5uZWxzICYgSGlzdG9ncmFtIGRpYWxvZyAodG9vbGJhciBidXR0b24pLiAqL1xuICBwcm90ZWN0ZWQgb3BlbkNoYW5uZWxIaXN0b2dyYW0oKSB7XG4gICAgdGhpcy5zaG93Q2hhbm5lbEhpc3RvZ3JhbSA9IHRydWU7XG4gIH1cblxuICAvKiogVG9vbGJhciDihpIgb3BlbiB0aGUgc3BhdGlhbC1vbWljcyBjb250cm9scy4gKi9cbiAgcHJvdGVjdGVkIG9wZW5TcGF0aWFsQ29udHJvbHMoKTogdm9pZCB7XG4gICAgdGhpcy5zaG93U3BhdGlhbENvbnRyb2xzID0gdHJ1ZTtcbiAgfVxuXG4gIC8qKiBPcGVuIHRoZSBSZWdpb24gRWRpdG9yIGRpYWxvZyAodG9vbGJhciBidXR0b24pLiBUaGUgZWRpdG9yIHN0YXlzIGxpbmtlZCB0b1xuICAgKiAgdGhpcyBwbG90dGluZyBpbnN0YW5jZSB0aHJvdWdoIHRoZSByb290IFJlZ2lvblN0b3JlIHNpbmdsZXRvbiwgc28gaXQgd29ya3NcbiAgICogIHRoZSBzYW1lIGFzIHRoZSBmb3JtZXIgcmlnaHQtcGFuZWwgUmVnaW9ucyB0YWIuICovXG4gIHByb3RlY3RlZCBvcGVuUmVnaW9uRWRpdG9yKCkge1xuICAgIC8vIFNpemUgdGhlIGRpYWxvZyB0byBtYXRjaCB0aGUgaG9zdCdzIGNvbmZpZ3VyZWQgZWxlbWVudCAoZS5nLiB0aGUgYXBwJ3NcbiAgICAvLyByaWdodCBwYW5lbCkgYXQgb3BlbiB0aW1lLiBNZWFzdXJlZCBvbmNlIOKAlCBpdCBpbnRlbnRpb25hbGx5IGRvZXMgbm90XG4gICAgLy8gdHJhY2sgbGF0ZXIgYnJvd3Nlci9zcGxpdCByZXNpemVzLiBGYWxscyBiYWNrIHRvIGEgcXVhcnRlciBvZiB0aGUgcGFnZVxuICAgIC8vIHdoZW4gbm8gc2VsZWN0b3IgaXMgY29uZmlndXJlZCBvciB0aGUgZWxlbWVudCBpc24ndCBwcmVzZW50LlxuICAgIGNvbnN0IHNlbGVjdG9yID0gdGhpcy52aXpDb25maWc/LnJlZ2lvbkVkaXRvcldpZHRoU2VsZWN0b3I7XG4gICAgY29uc3Qgd2lkdGggPSBzZWxlY3RvclxuICAgICAgPyBkb2N1bWVudC5xdWVyeVNlbGVjdG9yPEhUTUxFbGVtZW50PihzZWxlY3Rvcik/LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLndpZHRoXG4gICAgICA6IHVuZGVmaW5lZDtcbiAgICB0aGlzLnJlZ2lvbkVkaXRvcldpZHRoID0gd2lkdGggJiYgd2lkdGggPiAwID8gYCR7TWF0aC5yb3VuZCh3aWR0aCl9cHhgIDogJzI1dncnO1xuICAgIHRoaXMuc2hvd1JlZ2lvbkVkaXRvciA9IHRydWU7XG4gIH1cblxuICAvKiogVGhlIHRvb2xiYXIncyBTaW5nbGUgaW1hZ2UgLyBTdGFjayB0b2dnbGUuICovXG4gIHByb3RlY3RlZCBzZWxlY3RTdGFja09wdGlvbihzZWxlY3RlZFN0YWNrT3B0aW9uOiB7IG5hbWU6IHN0cmluZzsgdmFsOiBzdHJpbmcgfSkge1xuICAgIGNvbnN0IHNob3dzdGFjayA9IHNlbGVjdGVkU3RhY2tPcHRpb24udmFsID09PSAndHJ1ZSc7XG4gICAgdGhpcy5zdGFja0xvYWRpbmcuc2V0KHNob3dzdGFjayk7XG4gICAgdGhpcy5zdGF0ZS5zZXRJbWFnZUxvYWRpbmcoIXNob3dzdGFjayk7XG4gICAgLy8gU3RhY2sgbW9kZSBpcyBhbHdheXMgYSAyRCBoZWF0bWFwIOKAlCByZXNldCBzdXJmYWNlIG1vZGUgaWYgYWN0aXZlXG4gICAgaWYgKCF0aGlzLmlzSGVhdG1hcCkge1xuICAgICAgdGhpcy5pc0hlYXRtYXAgPSB0cnVlO1xuICAgICAgdGhpcy5wbG90VHlwZSA9IFBsb3RUeXBlLkhFQVRNQVA7XG4gICAgICB0aGlzLnNlbGVjdGVkUGxvdFR5cGVJZCA9IFBsb3RUeXBlLkhFQVRNQVA7XG4gICAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldFBsb3RUeXBlKHRoaXMucGxvdFR5cGUpO1xuICAgIH1cbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldFNob3dTdGFjayhzaG93c3RhY2spO1xuICB9XG5cbiAgLyoqIENsYW1wIHRoZSBzbGljZSBpbmRleCBpbnRvIFswLCBtYXhJbmRleF0gYW5kIHB1c2ggaXQgdG8gdGhlIHJlbmRlcmVyLiAqL1xuICBwcm90ZWN0ZWQgdXBkYXRlWkluZGV4KCkge1xuICAgIGlmICh0aGlzLnpJbmRleCA+IHRoaXMubWF4SW5kZXgpIHtcbiAgICAgIHRoaXMuekluZGV4ID0gdGhpcy5tYXhJbmRleDtcbiAgICB9XG4gICAgaWYgKHRoaXMuekluZGV4IDwgMCkge1xuICAgICAgdGhpcy56SW5kZXggPSAwO1xuICAgIH1cbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldFpJbmRleCh0aGlzLnpJbmRleCk7XG4gIH1cblxuICAvKipcbiAgICogTGl2ZSB6LXNsaWNlIHNjcnViIGZvciB0aGUgSW1hZ2UgdmlldzogdGhlIHJlbmRlcmVyIHN3YXBzIHRoZSBkaXNwbGF5ZWRcbiAgICogc2xpY2UgaW4gcGxhY2UgKG5vIHJlLW1vdW50KSwgc28gZHJhZ2dpbmcgdGhlIHNsaWRlciBzdGVwcyB0aHJvdWdoIHRoZVxuICAgKiBzdGFjayB0aGUgc2FtZSB3YXkgdGhlIGhlYXRtYXAgZnJhbWUgc2xpZGVyIGRvZXMuXG4gICAqL1xuICBwcm90ZWN0ZWQgb25aU2xpZGUoejogbnVtYmVyIHwgdW5kZWZpbmVkKSB7XG4gICAgaWYgKHogPT09IHVuZGVmaW5lZCkgcmV0dXJuO1xuICAgIHRoaXMuekluZGV4ID0gejtcbiAgICB0aGlzLnNjcnViYmVyLmNvbW1pdCh6KTtcbiAgICAvLyBLZWVwIHRoZSBpbnRlbnNpdHkgaW5zZXQgc2FtcGxpbmcgdGhlIGRpc3BsYXllZCBzbGljZSAoSW1hZ2UgdmlldykuXG4gICAgdGhpcy5pbnNldD8uc2xpY2VDb21taXR0ZWQoeik7XG4gIH1cblxuICAvKipcbiAgICogTGl2ZSAoZGVib3VuY2VkKSBzY3J1YiB3aGlsZSBkcmFnZ2luZyB0aGUgSW1hZ2UtdmlldyB6LXNsaWRlcjogdXBkYXRlIHRoZVxuICAgKiBzbGljZSBhcyB0aGUgdXNlciBkcmFncywgYnV0IGNvYWxlc2NlIHJhcGlkIGNoYW5nZXMgc28gd2UgZG9uJ3QgZmlyZSBhXG4gICAqIHNsaWNlIHN3YXAgb24gZXZlcnkgcGl4ZWwuIFRoZSBmaW5hbCB2YWx1ZSBhbHNvIGxhbmRzIHZpYSBvblpTbGlkZSAob25TbGlkZUVuZCkuXG4gICAqL1xuICBwcm90ZWN0ZWQgb25aU2NydWIoejogbnVtYmVyIHwgdW5kZWZpbmVkKSB7XG4gICAgaWYgKHogPT09IHVuZGVmaW5lZCkgcmV0dXJuO1xuICAgIHRoaXMuekluZGV4ID0gejtcbiAgICB0aGlzLnNjcnViYmVyLnNjcnViKHopO1xuICB9XG5cbiAgLyoqIE1vdmUgdGhlIGRpc3BsYXllZCBzbGljZSBieSBgZGVsdGFgLCBjbGFtcGVkIHRvIHRoZSBzdGFjayBib3VuZHMuICovXG4gIHN0ZXBTbGljZShkZWx0YTogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgbmV4dCA9IE1hdGgubWluKHRoaXMubWF4SW5kZXgsIE1hdGgubWF4KDAsIHRoaXMuekluZGV4ICsgZGVsdGEpKTtcbiAgICBpZiAobmV4dCA9PT0gdGhpcy56SW5kZXgpIHJldHVybjtcbiAgICB0aGlzLm9uWlNsaWRlKG5leHQpO1xuICB9XG5cbiAgcHJvdGVjdGVkIHJlbG9hZEFuZFBsb3QoKSB7XG4gICAgdGhpcy5zdGF0ZS5zZXRJbWFnZUxvYWRpbmcodHJ1ZSk7XG4gICAgLy8gUmUtZHJpdmUgdGhlIHJlbmRlciBwaXBlbGluZSBmcm9tIHRoZSBjdXJyZW50IGltYWdlIGluZm8gKHRoZSBzb3VyY2Ugb2ZcbiAgICAvLyB0cnV0aCwgd2l0aCByZWFsIHVybHMvZmlsZU5hbWUpLiBEb24ndCB1c2UgcGxvdFNlcnZpY2UucmVsb2FkQW5kUGxvdCgpOlxuICAgIC8vIHRoYXQgcmVidWlsZHMgdGhlIGluZm8gZnJvbSB0aGUgcmVuZGVyZXIncyBpbnRlcm5hbCBzdGF0ZSwgd2hpY2ggY2FuIGJlXG4gICAgLy8gc3RhbGUgKGUuZy4gYWZ0ZXIgc3dpdGNoaW5nIHBsb3QgdHlwZSBJbWFnZSAtPiBIZWF0bWFwKSBhbmQgcmUtZW1pdFxuICAgIC8vIGVtcHR5L29sZCB1cmxzLCBmYWlsaW5nIHRvIGhhbmQgdGhlIGRpdiBvdmVyIHRvIHRoZSBuZXcgcmVuZGVyZXIuXG4gICAgaWYgKHRoaXMuaW1hZ2VJbmZvKSB7XG4gICAgICB0aGlzLnN0YXRlLnNldEltYWdlSW5mbyh0aGlzLmltYWdlSW5mbyk7XG4gICAgfSBlbHNlIGlmICh0aGlzLnNwYXRpYWwuZGF0YXNldCAmJiAoaXNTcGF0aWFsT21pY3ModGhpcy5wbG90VHlwZSkgfHwgaXNTcGF0aWFsT21pY3MzZCh0aGlzLnBsb3RUeXBlKSkpIHtcbiAgICAgIC8vIEEgc3BhdGlhbCBkYXRhc2V0IHRoYXQgYnJpbmdzIG5vIGltYWdlLCBvcGVuZWQgd2l0aCBubyBpbWFnZSBsb2FkZWQgKGEgaG9zdCdzXG4gICAgICAvLyBmaXJzdCB2aWV3KTogdGhlcmUgaXMgbm8gaW1hZ2UgaW5mbyB0byByZS1kcml2ZSwgc28gZHJhdyB0aGUgc3BhdGlhbCBtb2RlIGl0c2VsZi5cbiAgICAgIHZvaWQgdGhpcy5yZW5kZXIucGxvdFdpdGhvdXRJbWFnZSh0aGlzLnNwYXRpYWwuZGF0YXNldCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucGxvdFNlcnZpY2UucmVsb2FkQW5kUGxvdCgpO1xuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBjYW5jZWxMb2FkaW5nKCkge1xuICAgIC8vIFN0b3AgYW55IGluLWZsaWdodCBmcmFtZSBzdHJlYW1pbmcgKG5hcGFyaS1qcyB2b2x1bWUvc3VyZmFjZSBwcmVsb2FkKSBzbyB0aGUgZmV0Y2ggbG9vcHNcbiAgICAvLyBhY3R1YWxseSBhYm9ydCDigJQgY2xlYXJpbmcgdGhlIGZsYWcgYWxvbmUgb25seSByb3V0ZWQgdG8gUGxvdGx5IGFuZCBsZWZ0IG5hcGFyaSBmZXRjaGluZy5cbiAgICB0aGlzLnBsb3RTZXJ2aWNlLmNhbmNlbExvYWRpbmc/LigpO1xuICAgIC8vIFRoZSBjYW5jZWxsZWQgcmVuZGVyIGlzIHN1cGVyc2VkZWQsIG5vdCBqdXN0IGFib3J0ZWQ6IGl0cyBhYm9ydGVkIGxvYWQgbXVzdCBub3RcbiAgICAvLyBjb21lIGJhY2sgYXMgXCJDb3VsZCBub3QgZHJhdyB0aGUgaW1hZ2VcIiwgbm9yIGFwcGx5IFJPSXMgZm9yIGFuIGltYWdlIGxlZnQgdW5zaG93bi5cbiAgICB0aGlzLnJlbmRlci5jYW5jZWwoKTtcbiAgICB0aGlzLnN0YWNrTG9hZGluZy5zZXQoZmFsc2UpO1xuICAgIHRoaXMuaW1nTG9hZGluZy5zZXQoZmFsc2UpO1xuICAgIHRoaXMuc3RhdGUuc2V0SW1hZ2VMb2FkaW5nKGZhbHNlKTtcbiAgICB0aGlzLnpJbmRleCA9IDA7XG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRaSW5kZXgodGhpcy56SW5kZXgpO1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0U3RhY2tMb2FkaW5nKGZhbHNlKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBkb3dubG9hZEltYWdlKCkge1xuICAgIHRoaXMucGxvdFNlcnZpY2UuZG93bmxvYWRJbWFnZSgpO1xuICB9XG5cbiAgYXV0b3NjYWxlSW1hZ2UoKSB7XG4gICAgdGhpcy5wbG90U2VydmljZS5maXRUb1ZpZXcoKTtcbiAgfVxuXG4gIC8qKiBUb29sYmFyIHBpeGVsL3Ntb290aCB0b2dnbGU6IGZsaXAgc21vb3RoaW5nIGFuZCBhcHBseSB0byB0aGUgYWN0aXZlIGJhY2tlbmQuICovXG4gIHByb3RlY3RlZCBvblRvZ2dsZUltYWdlU21vb3RoaW5nKCk6IHZvaWQge1xuICAgIHRoaXMuaW1hZ2VTbW9vdGhpbmdFbmFibGVkID0gIXRoaXMuaW1hZ2VTbW9vdGhpbmdFbmFibGVkO1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0SW1hZ2VTbW9vdGhpbmdFbmFibGVkKHRoaXMuaW1hZ2VTbW9vdGhpbmdFbmFibGVkKTtcbiAgfVxuXG4gIHJlc2V0QXhlcygpIHtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnJlc2V0QXhlcygpO1xuICB9XG5cbiAgdG9nZ2xlRHJhZ01vZGUobW9kZTogc3RyaW5nKSB7XG4gICAgdGhpcy50b29scy50b2dnbGUobW9kZSk7XG4gIH1cblxuICAvKiogTGl2ZS11cGRhdGUgdGhlIGlzb3N1cmZhY2UgYXMgdGhlIHJhbmdlIHNsaWRlciBtb3Zlcy4gVGhlIGNvbnRyb2wgaXMgb25seVxuICAgKiAgYXZhaWxhYmxlIHdoZW4gdGhlIGFjdGl2ZSBiYWNrZW5kIHJlbmRlcnMgaXNvc3VyZmFjZXMgKElTT1NVUkZBQ0UgbW9kZSkuICovXG4gIHByb3RlY3RlZCBvbklzb1JhbmdlQ2hhbmdlKHZhbHVlczogbnVtYmVyW10gfCB1bmRlZmluZWQpIHtcbiAgICBpZiAoIXZhbHVlcyB8fCB2YWx1ZXMubGVuZ3RoIDwgMikgcmV0dXJuO1xuICAgIHRoaXMuaXNvUmFuZ2UgPSB2YWx1ZXM7XG4gICAgdGhpcy5wbG90U2VydmljZS5nZXRJc29zdXJmYWNlQ29udHJvbHMoKT8uc2V0SXNvUmFuZ2UodmFsdWVzWzBdLCB2YWx1ZXNbMV0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIG9uV2FuZFNlbnNpdGl2aXR5Q2hhbmdlKHZhbHVlOiBudW1iZXIgfCB1bmRlZmluZWQpIHtcbiAgICB0aGlzLnRvb2xzLnNldFdhbmRTZW5zaXRpdml0eSh2YWx1ZSk7XG4gIH1cbiAgcHJvdGVjdGVkIG9uQnJ1c2hTaXplQ2hhbmdlKHZhbHVlOiBudW1iZXIgfCB1bmRlZmluZWQpIHtcbiAgICB0aGlzLnRvb2xzLnNldEJydXNoU2l6ZSh2YWx1ZSk7XG4gIH1cbiAgcHJvdGVjdGVkIG9uVmVydGV4RXJhc2VyUmFkaXVzQ2hhbmdlKHZhbHVlOiBudW1iZXIgfCB1bmRlZmluZWQpIHtcbiAgICB0aGlzLnRvb2xzLnNldFZlcnRleEVyYXNlclJhZGl1cyh2YWx1ZSk7XG4gIH1cblxuICB6b29tSW4oKSB7XG4gICAgdGhpcy5wbG90U2VydmljZS56b29tSW4oKTtcbiAgfVxuXG4gIHpvb21PdXQoKSB7XG4gICAgdGhpcy5wbG90U2VydmljZS56b29tT3V0KCk7XG4gIH1cblxuICBkZWxldGVSZWdpb24oKSB7XG4gICAgdGhpcy5wbG90U2VydmljZS5kZWxldGVBY3RpdmVTaGFwZSgpO1xuICB9XG5cbiAgLyoqIFVuZG8gdGhlIG1vc3QgcmVjZW50IHJlZ2lvbiBhY3Rpb24gKGppdC11aSM4NSkuIFVwIHRvIDEwIHN0ZXBzIGJhY2suICovXG4gIHByb3RlY3RlZCB1bmRvUmVnaW9uKCkge1xuICAgIHRoaXMucGxvdFNlcnZpY2UudW5kbygpO1xuICB9XG5cbiAgLyoqIFJlZG8gdGhlIG1vc3QgcmVjZW50bHkgdW5kb25lIHJlZ2lvbiBhY3Rpb24gKGppdC11aSM4NSkuICovXG4gIHByb3RlY3RlZCByZWRvUmVnaW9uKCkge1xuICAgIHRoaXMucGxvdFNlcnZpY2UucmVkbygpO1xuICB9XG5cbiAgLy8g4pSA4pSAIFJlZ2lvbiBzZXQtb3BlcmF0aW9ucyBvbiB0aGUgY3VycmVudCBzZWxlY3Rpb24gKGppdC11aSM4NSkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gIHNlbGVjdEFsbFJlZ2lvbnMoKTogdm9pZCB7XG4gICAgdGhpcy5yZWdpb25BY3Rpb25zLnNlbGVjdEFsbCgpO1xuICB9XG4gIG1lcmdlUmVnaW9ucygpOiB2b2lkIHtcbiAgICB0aGlzLnJlZ2lvbkFjdGlvbnMubWVyZ2UoKTtcbiAgfVxuICB1bmdyb3VwUmVnaW9ucygpOiB2b2lkIHtcbiAgICB0aGlzLnJlZ2lvbkFjdGlvbnMudW5ncm91cCgpO1xuICB9XG4gIGludmVyc2VSZWdpb25zKCk6IHZvaWQge1xuICAgIHRoaXMucmVnaW9uQWN0aW9ucy5pbnZlcnNlKCk7XG4gIH1cbiAgc2ltcGxpZnlSZWdpb25zKHRocmVzaG9sZFB4OiBudW1iZXIpOiB2b2lkIHtcbiAgICB0aGlzLnJlZ2lvbkFjdGlvbnMuc2ltcGxpZnkodGhyZXNob2xkUHgpO1xuICB9XG4gIG9wZW5TaW1wbGlmeURpYWxvZygpOiB2b2lkIHtcbiAgICB0aGlzLnJlZ2lvbkFjdGlvbnMub3BlblNpbXBsaWZ5RGlhbG9nKCk7XG4gIH1cblxuICAvKiogQm94LXByb21wdGVkIFNBTSBzZWdtZW50YXRpb24gb2YgdGhlIGRyYXduIHJlY3RhbmdsZXMgKGppdC11aSM5MCkuIEEgc3RpY2t5XG4gICAqICBgc2FtYCB0b2FzdCBzaG93cyBsaXZlIHN0YXR1cyArIGEgZG93bmxvYWQgcHJvZ3Jlc3MgYmFyIChmaXJzdCBydW4gcHVsbHMgdGhlXG4gICAqICBlbmNvZGVyLCB+MTcwIE1CKTsgaXQgc3RheXMgb3BlbiB1bnRpbCB0aGUgcnVuIGZpbmlzaGVzIChiYXIgaGl0cyAxMDAlKS4gKi9cbiAgcHJvdGVjdGVkIGFzeW5jIHNlZ21lbnRSZWdpb25zKCkge1xuICAgIGF3YWl0IHRoaXMuc2VnbWVudGF0aW9uLnJ1bignU0FNJywgdGhpcy5zYW1Ub29sLCAoKSA9PiB0aGlzLnBsb3RTZXJ2aWNlLnNlZ21lbnRSZWN0YW5nbGVzKCkpO1xuICB9XG5cbiAgLyoqIEF1dG8tc2VnbWVudCBjZWxscyBpbnNpZGUgZWFjaCBkcmF3biByZWN0YW5nbGUgd2l0aCBjZWxscG9zZS1TQU0sIGNsaWVudC1zaWRlXG4gICAqICAoaml0LXVpIzkwKS4gRWFjaCBib3ggaXMgY3JvcHBlZCAoYnJvd3NlciBzbGlkZS1jcm9wKSB0aGVuIHJ1biB0aHJvdWdoIHRoZVxuICAgKiAgY2VsbHBvc2UtanMgbW9kZWw7IHRoZSBzYW1lIHN0aWNreSBgc2FtYCB0b2FzdCArIHByb2dyZXNzIGJhciBpcyByZXVzZWQuICovXG4gIHByb3RlY3RlZCBhc3luYyBzZWdtZW50Q2VsbHBvc2UoKSB7XG4gICAgYXdhaXQgdGhpcy5zZWdtZW50YXRpb24ucnVuKCdDZWxscG9zZScsIHRoaXMuY2VsbFNlZ21lbnRUb29sLCAoKSA9PlxuICAgICAgdGhpcy5wbG90U2VydmljZS5zZWdtZW50UmVjdGFuZ2xlc0NlbGxwb3NlKCksXG4gICAgKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBjb250cmlidXRlZCB0b29sIHBhcmFtZXRlcnMgKHNlZSBUb29sUGFyYW1zTW9kZWwpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICBwYXJhbXNGb3IodG9vbElkOiBzdHJpbmcpOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiB7XG4gICAgcmV0dXJuIHRoaXMudG9vbFBhcmFtcy5wYXJhbXNGb3IodG9vbElkKTtcbiAgfVxuICBwcm90ZWN0ZWQgb25Ub29sTW9kZWxDaGFuZ2UoZTogeyB0b29sSWQ6IHN0cmluZzsgbW9kZWxJZDogc3RyaW5nIH0pOiB2b2lkIHtcbiAgICB0aGlzLnRvb2xQYXJhbXMuc2V0TW9kZWwoZS50b29sSWQsIGUubW9kZWxJZCk7XG4gIH1cbiAgcHJvdGVjdGVkIG9wZW5Ub29sUGFyYW1zKHRvb2xJZDogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy50b29sUGFyYW1zLm9wZW4odG9vbElkKTtcbiAgfVxuICBwcm90ZWN0ZWQgY2xvc2VUb29sUGFyYW1zKCk6IHZvaWQge1xuICAgIHRoaXMudG9vbFBhcmFtcy5jbG9zZSgpO1xuICB9XG4gIHByb3RlY3RlZCByZXNldFRvb2xQYXJhbXModG9vbElkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnRvb2xQYXJhbXMucmVzZXQodG9vbElkKTtcbiAgfVxuXG4gIC8qKiBSdW4gYSBjb250cmlidXRlZCB0b29sIG92ZXIgdGhlIGN1cnJlbnQgdmlldy4gTm8gcHJvbXB0OiB0aGVzZSBzd2VlcCB0aGVcbiAgICogIHdob2xlIHZpZXcgcmF0aGVyIHRoYW4gYmVpbmcgcG9pbnRlZCBhdCBzb21ldGhpbmcuIFJldXNlcyB0aGUgc2hhcmVkXG4gICAqICBzZWdtZW50YXRpb24gdG9hc3Qgc28gcHJvZ3Jlc3MgcmVhZHMgdGhlIHNhbWUgYXMgdGhlIFNBTS9jZWxscG9zZSB0b29scy4gKi9cbiAgcHJvdGVjdGVkIGFzeW5jIHJ1blRvb2wodG9vbElkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB0b29sID0gdGhpcy50b29sUGFyYW1zLmZpbmQodG9vbElkKTtcbiAgICBpZiAoIXRvb2wpIHJldHVybjtcbiAgICBjb25zdCBwYXJhbXMgPSB0aGlzLnRvb2xQYXJhbXMucnVuUGFyYW1zKHRvb2wpO1xuICAgIGF3YWl0IHRoaXMuc2VnbWVudGF0aW9uLnJ1bih0b29sLmxhYmVsLCB0b29sLnByb2dyZXNzLCAoKSA9PiB0b29sLnJ1bih0aGlzLnBsb3RTZXJ2aWNlLCBwYXJhbXMpKTtcbiAgfVxuXG4gIC8qKiBQaWNrIHRoZSBTQU0gbW9kZWwgdGhlIHNlZ21lbnQgdG9vbHMgdXNlIChqaXQtdWkjOTAgUDEpLiAqL1xuICBwcm90ZWN0ZWQgb25TYW1Nb2RlbENoYW5nZShpZDogc3RyaW5nKSB7XG4gICAgdGhpcy5zYW1Nb2RlbElkID0gaWQ7XG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRTYW1Nb2RlbChpZCk7XG4gIH1cblxuICAvKiogQ29udmVydCB0aGUgc2VsZWN0ZWQgcmVnaW9uIHRvIGEgc21vb3RoIGJlemllciBjdXJ2ZS4gKi9cbiAgdG9CZXppZXJSZWdpb24oKSB7XG4gICAgdGhpcy5wbG90U2VydmljZS5nZXRSZWdpb25PdmVybGF5KCk/LnNldFNlbGVjdGVkQmV6aWVyKHRydWUpO1xuICB9XG5cbiAgLyoqIENvbnZlcnQgdGhlIHNlbGVjdGVkIHJlZ2lvbiBiYWNrIHRvIGEgc3RyYWlnaHQtZWRnZWQgcG9seWdvbi4gKi9cbiAgdG9Qb2x5Z29uUmVnaW9uKCkge1xuICAgIHRoaXMucGxvdFNlcnZpY2UuZ2V0UmVnaW9uT3ZlcmxheSgpPy5zZXRTZWxlY3RlZEJlemllcihmYWxzZSk7XG4gIH1cblxuICAvKiogVGhlIHJpZ2h0LWNsaWNrIG1lbnUgZm9yIHRoZSBjdXJyZW50IHZpZXcsIGFybWVkIG1vZGUgYW5kIHNlbGVjdGlvbi4gKi9cbiAgcHJpdmF0ZSBidWlsZENvbnRleHRNZW51SXRlbXMoKTogTWVudUl0ZW1bXSB7XG4gICAgcmV0dXJuIGJ1aWxkQ29udGV4dE1lbnUodGhpcy5jb250ZXh0TWVudVN0YXRlKCksIHRoaXMpO1xuICB9XG5cbiAgcHJpdmF0ZSBjb250ZXh0TWVudVN0YXRlKCk6IENvbnRleHRNZW51U3RhdGUge1xuICAgIHJldHVybiB7XG4gICAgICBpc0hlYXRtYXA6IHRoaXMuaXNIZWF0bWFwLFxuICAgICAgYmFzZVBsb3RUeXBlOiB0aGlzLmJhc2VQbG90VHlwZSxcbiAgICAgIGFjdGl2ZURyYWdNb2RlOiB0aGlzLmFjdGl2ZURyYWdNb2RlLFxuICAgICAgYWN0aXZlU3VyZmFjZTNkTW9kZTogdGhpcy5hY3RpdmVTdXJmYWNlM2RNb2RlLFxuICAgICAgcmVnaW9uczogdGhpcy5wbG90U2VydmljZS5nZXRSZWdpb25zKCksXG4gICAgICBzZWxlY3RlZEluZGljZXM6IHRoaXMucmVnaW9uQWN0aW9ucy5zZWxlY3RlZEluZGljZXMsXG4gICAgICBjYW5Vbmdyb3VwOiAocikgPT4gdGhpcy5yZWdpb25PcHMuY2FuVW5ncm91cChyKSxcbiAgICB9O1xuICB9XG5cbiAgLyoqIDNEIHNjZW5lIGludGVyYWN0aW9uIG1vZGUgKG9yYml0IC8gdHVybnRhYmxlIC8gcGFuIC8gem9vbSk7IG5vLW9wIG9uIGEgMkQtb25seSBiYWNrZW5kLiAqL1xuICB0b2dnbGVTdXJmYWNlM2RNb2RlKG1vZGU6IHN0cmluZykge1xuICAgIHRoaXMuYWN0aXZlU3VyZmFjZTNkTW9kZSA9IG1vZGU7XG4gICAgdGhpcy5wbG90U2VydmljZS5nZXRTdXJmYWNlM2RDb250cm9scygpPy5zZXRTdXJmYWNlRHJhZ01vZGUobW9kZSk7XG4gIH1cblxuICByZXNldFN1cmZhY2VDYW1lcmEoKSB7XG4gICAgdGhpcy5wbG90U2VydmljZS5nZXRTdXJmYWNlM2RDb250cm9scygpPy5yZXNldFN1cmZhY2VDYW1lcmEoKTtcbiAgfVxuXG4gIC8qKiBUb2dnbGUgdGhlIG5hcGFyaSAzRCBjb29yZGluYXRlLWF4ZXMgLyBzY2FsZSBnaXptbyAodm9sdW1lL2lzb3N1cmZhY2UpLiBOby1vcCBvbiBiYWNrZW5kc1xuICAgKiAgdGhhdCBkb24ndCByZW5kZXIgb25lICh0aGUgY29udHJvbCBtZXRob2QgaXMgb3B0aW9uYWwpLiAqL1xuICBwcm90ZWN0ZWQgdG9nZ2xlQXhlcygpIHtcbiAgICB0aGlzLmF4ZXNWaXNpYmxlID0gIXRoaXMuYXhlc1Zpc2libGU7XG4gICAgdGhpcy5wbG90U2VydmljZS5nZXRTdXJmYWNlM2RDb250cm9scygpPy5zZXRBeGVzVmlzaWJsZT8uKHRoaXMuYXhlc1Zpc2libGUpO1xuICB9XG5cbiAgLyoqIFRvZ2dsZSB0aGUgbmFwYXJpIHN1cmZhY2Ugd2lyZWZyYW1lIChlZGdlcyB2cyBmaWxsZWQpLiBOby1vcCBvbiBiYWNrZW5kcyB3aXRob3V0IGEgc3VyZmFjZS4gKi9cbiAgcHJvdGVjdGVkIHRvZ2dsZVdpcmVmcmFtZSgpIHtcbiAgICB0aGlzLndpcmVmcmFtZUFjdGl2ZSA9ICF0aGlzLndpcmVmcmFtZUFjdGl2ZTtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLmdldFN1cmZhY2UzZENvbnRyb2xzKCk/LnNldFdpcmVmcmFtZT8uKHRoaXMud2lyZWZyYW1lQWN0aXZlKTtcbiAgfVxuXG4gIC8qKiBDaGFuZ2UgdGhlIG5hcGFyaSAzRCBkZWNpbWF0ZSBmYWN0b3IuIERlY2ltYXRpb24gY2hhbmdlcyB0aGUgZmV0Y2hlZC9hc3NlbWJsZWQgZGF0YSwgc28gdGhpc1xuICAgKiAgcmUtcGxvdHMgdGhlIGN1cnJlbnQgM0QgdHlwZSBhdCB0aGUgbmV3IHJlc29sdXRpb24gKHVubGlrZSBheGVzL3dpcmVmcmFtZSwgd2hpY2ggYXJlIGxpdmUpLiAqL1xuICBwcm90ZWN0ZWQgc2VsZWN0UmVzb2x1dGlvbihzY2FsZTogbnVtYmVyKSB7XG4gICAgaWYgKHNjYWxlID09PSB0aGlzLnJlc29sdXRpb25TY2FsZSkgcmV0dXJuO1xuICAgIHRoaXMucmVzb2x1dGlvblNjYWxlID0gc2NhbGU7XG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRSZXNvbHV0aW9uU2NhbGU/LihzY2FsZSk7XG4gICAgdGhpcy5yZWxvYWRBbmRQbG90KCk7XG4gIH1cblxuICAvKipcbiAgICogU3dpdGNoIHRoZSBhY3RpdmUgcGxvdCB0eXBlIChoZWF0bWFwLCBzdXJmYWNlLCBjb250b3VyLCBzY2F0dGVyLCBsaW5lLFxuICAgKiBzY2F0dGVyM2QsIGlzb3N1cmZhY2UpLiBLZWVwcyBgaXNIZWF0bWFwYCBhcyB0aGUgMkQtdnMtM0QgZmxhZyB0aGUgcmVzdCBvZlxuICAgKiB0aGUgdG9vbGJhci9jb250ZXh0LW1lbnUgbG9naWMgcmVsaWVzIG9uLCBkZWFjdGl2YXRlcyAyRC1vbmx5IHRvb2xzIHdoZW5cbiAgICogbW92aW5nIHRvIGEgM0QgdHlwZSwgdGhlbiByZS1wbG90cy5cbiAgICovXG4gIG9uU2VsZWN0UGxvdFR5cGUoc2VsZWN0ZWQ6IFBsb3RUeXBlSWQpIHtcbiAgICAvLyBBbHNvIGNhbGxlZCBieSB0aGUgaG9zdCBkaXJlY3RseSwgb3V0c2lkZSB0aGlzIHZpZXcncyBldmVudHM6IHRoZSBzZWxlY3RvciwgdGhlXG4gICAgLy8gdG9vbGJhcidzIHRvb2wgZ3JvdXBzIGFuZCB0aGUgZGlhbG9ncyBhbGwgZm9sbG93IHRoZSB0eXBlLlxuICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgIC8vIEEgY29udHJpYnV0ZWQgaWQgd2hvc2UgcHJvdmlkZXIgaXMgZ29uZSAoZS5nLiByZXN0b3JlZCBmcm9tIGEgcHJldmlvdXNcbiAgICAvLyBzZXNzaW9uKSBoYXMgbm90aGluZyB0byBhY3RpdmF0ZSDigJQgdGFrZSB0aGUgZGVmYXVsdCBJbWFnZSB2aWV3IGluc3RlYWQuXG4gICAgaWYgKCFpc0J1aWx0aW5QbG90VHlwZShzZWxlY3RlZCkgJiYgIXRoaXMucGxvdE1vZGVzLmZpbmQoc2VsZWN0ZWQpKSB7XG4gICAgICBjb25zb2xlLndhcm4oYFt2aXN1YWxpemVyXSB1bmtub3duIHBsb3QgdHlwZSAnJHtzZWxlY3RlZH0nIOKAlCBzaG93aW5nICcke1Bsb3RUeXBlLklNQUdFfScgaW5zdGVhZC5gKTtcbiAgICAgIHNlbGVjdGVkID0gUGxvdFR5cGUuSU1BR0U7XG4gICAgfVxuICAgIC8vIEFuIGV4cGxpY2l0IGNob2ljZSByZXRyaWVzIGEgbW9kZSB3aG9zZSBlYXJsaWVyIGNsZWFudXAgZmFpbGVkOyBvbmx5XG4gICAgLy8gYXV0b21hdGljIHJlLWFjdGl2YXRpb25zIChyZS1yZW5kZXIsIGltYWdlIHN3aXRjaCkgZmFsbCBiYWNrIGZvciB0aGF0LlxuICAgIHRoaXMucGxvdE1vZGVzLmNsZWFyQ2xlYW51cEZhaWx1cmVzKCk7XG4gICAgLy8gV2hhdGV2ZXIgd2FzIHNlbGVjdGVkIGJlZm9yZSwgYSBjb250cmlidXRlZCBzZXNzaW9uIGVuZHMgYmVmb3JlIHRoZSBuZXh0XG4gICAgLy8gbW9kZSBkcmF3cy4gKFJlLXNlbGVjdGluZyB0aGUgc2FtZSBjb250cmlidXRlZCBtb2RlIHJlLXBsb3RzLCBzbyBpdCBnZXRzIGFcbiAgICAvLyBmcmVzaCBzZXNzaW9uIHRvby4pXG4gICAgdGhpcy5wbG90TW9kZXMuZGVhY3RpdmF0ZSgpO1xuICAgIC8vIEV2ZXJ5dGhpbmcgYmVsb3cgZGVjaWRlcyBob3cgdG8gUkVOREVSLCBzbyBpdCB3b3JrcyBvbiB0aGUgYnVpbHQtaW4gdHlwZVxuICAgIC8vIHRoYXQgZHJhd3MgYHNlbGVjdGVkYDogYSBjb250cmlidXRlZCBtb2RlIGJlaGF2ZXMgZXhhY3RseSBsaWtlIGl0cyBiYXNlLlxuICAgIGNvbnN0IHR5cGUgPSB0aGlzLnBsb3RNb2Rlcy5iYXNlVHlwZU9mKHNlbGVjdGVkKTtcbiAgICAvLyBBIGRpYWxvZyB0b29sIGRyYXdzIG92ZXIgdGhlIEltYWdlIHZpZXc6IGxlYXZpbmcgaXQgY2xvc2VzIHRoZSBkaWFsb2cuIFN0YXlpbmdcbiAgICAvLyBvbiBpdCwgdGhlIHNlc3Npb24gZW5kcyBoZXJlIGFuZCByZXN0YXJ0cyBvbmNlIHRoZSByZS1wbG90IGxhbmRzLlxuICAgIGlmICh0eXBlID09PSBQbG90VHlwZS5JTUFHRSkgdGhpcy5jb250cmlidXRpb25zLnRvb2xEaWFsb2dzLmRlYWN0aXZhdGUoKTtcbiAgICBlbHNlIHRoaXMuY2xvc2VEaWFsb2dUb29sKCk7XG4gICAgdGhpcy5wbG90VHlwZSA9IHR5cGU7XG4gICAgdGhpcy5zZWxlY3RlZFBsb3RUeXBlSWQgPSBzZWxlY3RlZDtcbiAgICBjb25zdCBkZXNjcmlwdG9yID0gaXNCdWlsdGluUGxvdFR5cGUoc2VsZWN0ZWQpXG4gICAgICA/IHRoaXMucGxvdFR5cGVNZW51LmZpbmQoKGQpID0+IGQudHlwZSA9PT0gdHlwZSlcbiAgICAgIDogZ2V0UGxvdFR5cGVEZXNjcmlwdG9yKHR5cGUpO1xuICAgIGNvbnN0IGlzM2QgPSBkZXNjcmlwdG9yPy5kaW1lbnNpb25zID09PSAnM2QnO1xuICAgIHRoaXMuaXNIZWF0bWFwID0gIWlzM2Q7XG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRQbG90VHlwZSh0eXBlKTtcbiAgICAvLyBTd2l0Y2hpbmcgcGxvdCB0eXBlIGNhbmNlbHMgdGhlIGFjdGl2ZSB0b29sIOKAlCBub3QgZXZlcnkgdHlwZSBzdXBwb3J0cyB0aGVcbiAgICAvLyBzYW1lIHRvb2xzIChsaW5lL3NjYXR0ZXIgY2hhcnRzIGFuZCAzRCBzY2VuZXMgaGF2ZSBubyBib3ggem9vbSBvciByZWdpb25cbiAgICAvLyBkcmF3aW5nKSwgc28gbGVhdmluZyBhIHRvb2wgYXJtZWQgd291bGQgbWlzYmVoYXZlIG9uIHRoZSBuZXcgcGxvdC5cbiAgICB0aGlzLnRvb2xzLmRlYWN0aXZhdGUoKTtcbiAgICBpZiAoaXMzZCkge1xuICAgICAgdGhpcy5hY3RpdmVTdXJmYWNlM2RNb2RlID0gJ3R1cm50YWJsZSc7XG4gICAgfVxuICAgIC8vIG5hcGFyaS1qcyB2b2x1bWUvaXNvc3VyZmFjZSBhc3NlbWJsZSB0aGVpciBvd24gM0QgdGV4dHVyZSBmcm9tIHRoZSBzbGljZSBlbmRwb2ludCwgc29cbiAgICAvLyB0aGV5IHRha2UgdGhlIG5vcm1hbCByZS1wbG90IHBhdGgg4oCUIE5PVCBQbG90bHkncyBzdGFjay1mcmFtZSBsb2FkZXIgKHdob3NlIFwiTG9hZGluZ1xuICAgIC8vIGZyYW1lc1wiIG92ZXJsYXkgd291bGQgbmV2ZXIgY2xlYXIsIHNpbmNlIFBsb3RseSBpc24ndCB0aGUgYWN0aXZlIGJhY2tlbmQpIChqaXQtdWkjMTAyKS5cbiAgICBjb25zdCBpc05hcGFyaSA9IHR5cGUgPT09IFBsb3RUeXBlLk5BUEFSSV9JTUFHRSB8fCBpc05hcGFyaTNkKHR5cGUpO1xuICAgIGlmIChkZXNjcmlwdG9yPy5yZXF1aXJlc1N0YWNrICYmICFpc05hcGFyaSkge1xuICAgICAgLy8gVm9sdW1lIHR5cGVzIChpc29zdXJmYWNlLCBzY2F0dGVyM2QpIG5lZWQgdGhlIHdob2xlIHotc3RhY2sgbG9hZGVkIGFzIGFcbiAgICAgIC8vIDNEIGFycmF5LCBhbmQgdGhleSBhbHdheXMgcmVuZGVyIG9uIFBsb3RseS4gRHJpdmUgdGhlIHN0YWNrIHJlbG9hZFxuICAgICAgLy8gZGlyZWN0bHkgdGhyb3VnaCB0aGUgaW1hZ2UtaW5mbyBzdHJlYW0gcmF0aGVyIHRoYW4gdGhlIGFjdGl2ZSByZW5kZXJlcidzXG4gICAgICAvLyBzZXRTaG93U3RhY2s6IHdoZW4gT3BlblNlYWRyYWdvbiBvd25zIHRoZSBJbWFnZSB2aWV3IGl0cyBzZXRTaG93U3RhY2sgaXNcbiAgICAgIC8vIGEgbm8tb3AsIHNvIHRoZSByZWxvYWQgbmV2ZXIgZmlyZWQgYW5kIHRoZSBsb2FkZXIgc3B1biBmb3JldmVyLiBXZSBhcm1cbiAgICAgIC8vIFBsb3RseSdzIHN0YWNrLWxvYWRpbmcgZmxhZyAoa2VlcHMgaXRzIGZyYW1lLWZldGNoIGxvb3AgYWxpdmUpIGFuZFxuICAgICAgLy8gcmUtZW1pdCB0aGUgaW1hZ2UgaW5mbyB3aXRoIHNob3dTdGFjayBvbiBzbyB0aGUgcGlwZWxpbmUgcmVsb2FkcyBvblxuICAgICAgLy8gUGxvdGx5IHJlZ2FyZGxlc3Mgb2Ygd2hpY2ggYmFja2VuZCB3YXMgb24gc2NyZWVuLlxuICAgICAgdGhpcy5zdGFja0xvYWRpbmcuc2V0KHRydWUpO1xuICAgICAgdGhpcy5wbG90U2VydmljZS5zZXRTdGFja0xvYWRpbmcodHJ1ZSk7XG4gICAgICBpZiAodGhpcy5pbWFnZUluZm8pIHtcbiAgICAgICAgLy8gQSBjb3B5OiB0aGUgaW1hZ2UgaW5mbyBtYXkgYmUgdGhlIGhvc3QncyBvd24gKHBvc3NpYmx5IGZyb3plbikgb2JqZWN0LlxuICAgICAgICB0aGlzLnN0YXRlLnNldEltYWdlSW5mbyh7IC4uLnRoaXMuaW1hZ2VJbmZvLCBzaG93U3RhY2s6IHRydWUgfSk7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMucmVsb2FkQW5kUGxvdCgpO1xuICB9XG5cbiAgLy8g4pSA4pSAIGRpYWxvZyB0b29scyAoVE9PTEJBUl9UT09MUywga2luZDogJ2RpYWxvZycpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIC8qKiBUaGUgdG9vbGJhciBidXR0b246IG9wZW4gdGhlIHRvb2wncyBkaWFsb2csIG9yIGNsb3NlIGl0IGlmIGl0IGlzIG9wZW4uICovXG4gIHByb3RlY3RlZCB0b2dnbGVEaWFsb2dUb29sKGlkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmNvbnRyaWJ1dGlvbnMudG9nZ2xlRGlhbG9nVG9vbChpZCk7XG4gIH1cblxuICAvKiogQ2xvc2UgdGhlIG9wZW4gZGlhbG9nIHRvb2w6IGl0cyBib2R5IGlzIHRvcm4gZG93biwgdGhlbiBpdHMgc2Vzc2lvbiBlbmRzLiAqL1xuICBwcm90ZWN0ZWQgY2xvc2VEaWFsb2dUb29sKCk6IHZvaWQge1xuICAgIHRoaXMuY29udHJpYnV0aW9ucy5jbG9zZURpYWxvZ1Rvb2woKTtcbiAgfVxuXG4gIC8qKiBXaGVyZSB0aGUgb3BlbiBkaWFsb2cgdG9vbCdzIGhvc3QgZWxlbWVudCBpcyBhdHRhY2hlZCBvbmNlIGl0cyBkaWFsb2cgcmVuZGVycy4gKi9cbiAgQFZpZXdDaGlsZCgndG9vbERpYWxvZ1Nsb3QnKVxuICBzZXQgdG9vbERpYWxvZ1Nsb3QocmVmOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PiB8IHVuZGVmaW5lZCkge1xuICAgIHRoaXMuY29udHJpYnV0aW9ucy5hdHRhY2hUb29sRGlhbG9nU2xvdChyZWY/Lm5hdGl2ZUVsZW1lbnQpO1xuICB9XG59XG4iLCI8IS0tIFNBTSB0b2FzdDogbGl2ZSBzdGF0dXMgKyBlbmNvZGVyLWRvd25sb2FkIHByb2dyZXNzIGJhciAoaml0LXVpIzkwKS4gU3RpY2t5XG4gICAgIHdoaWxlIGEgc2VnbWVudCBydW5zOyBzdGF5cyBvcGVuIHVudGlsIHRoZSBiYXIgcmVhY2hlcyAxMDAlIGFuZCB0aGUgcnVuIGVuZHMuIC0tPlxuPHAtdG9hc3QgW2tleV09XCJzYW1Ub2FzdEtleVwiIHBvc2l0aW9uPVwiYm90dG9tLXJpZ2h0XCI+XG4gIDxuZy10ZW1wbGF0ZSBsZXQtbWVzc2FnZSBwVGVtcGxhdGU9XCJtZXNzYWdlXCI+XG4gICAgPGRpdiBzdHlsZT1cImZsZXg6IDE7IG1pbi13aWR0aDogMTZyZW1cIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJmb250LWJvbGQgbWItMVwiPnt7IG1lc3NhZ2Uuc3VtbWFyeSB9fTwvZGl2PlxuICAgICAgPGRpdj57eyBzZWdtZW50YXRpb24uc3RhdHVzIHx8IG1lc3NhZ2UuZGV0YWlsIH19PC9kaXY+XG4gICAgICA8cC1wcm9ncmVzc0JhclxuICAgICAgICAqbmdJZj1cInNlZ21lbnRhdGlvbi5kb3dubG9hZGluZ1wiXG4gICAgICAgIFt2YWx1ZV09XCJzZWdtZW50YXRpb24ucHJvZ3Jlc3NcIlxuICAgICAgICBzdHlsZUNsYXNzPVwibXQtMiBzYW0tcHJvZ3Jlc3NcIlxuICAgICAgPjwvcC1wcm9ncmVzc0Jhcj5cbiAgICAgIDxwLXByb2dyZXNzQmFyXG4gICAgICAgICpuZ0lmPVwic2VnbWVudGF0aW9uLmJ1c3kgJiYgIXNlZ21lbnRhdGlvbi5kb3dubG9hZGluZ1wiXG4gICAgICAgIG1vZGU9XCJpbmRldGVybWluYXRlXCJcbiAgICAgICAgc3R5bGVDbGFzcz1cIm10LTJcIlxuICAgICAgICBbc3R5bGVdPVwieyBoZWlnaHQ6ICc0cHgnIH1cIlxuICAgICAgPjwvcC1wcm9ncmVzc0Jhcj5cbiAgICA8L2Rpdj5cbiAgPC9uZy10ZW1wbGF0ZT5cbjwvcC10b2FzdD5cblxuPCEtLSBSZXN1bHQvZXJyb3Igbm90aWNlcyBmcm9tIHRoZSBsaWJyYXJ5IGl0c2VsZiAoc2VnbWVudGF0aW9uIG91dGNvbWUsIHJlZ2lvblxuICAgICB2YWxpZGF0aW9uKS4gUmVuZGVyZWQgaGVyZSBzbyB0aGV5IGRvIG5vdCBkZXBlbmQgb24gdGhlIGhvc3QgbW91bnRpbmcgYVxuICAgICBrZXlsZXNzIDxwLXRvYXN0PiDigJQgd2l0aG91dCB0aGlzIHRoZSBtZXNzYWdlcyB3ZW50IG5vd2hlcmUgaW4gYW55IGhvc3QgYnV0XG4gICAgIGppdC11aSwgYW5kIGEgZmFpbGVkIHJ1biBsb29rZWQgbGlrZSBhIGJ1dHRvbiB0aGF0IGRpZCBub3RoaW5nLiAtLT5cbjxwLXRvYXN0IFtrZXldPVwicmVzdWx0VG9hc3RLZXlcIiBwb3NpdGlvbj1cImJvdHRvbS1yaWdodFwiPjwvcC10b2FzdD5cblxuPCEtLSBTaGFyZWQgb3V0bGV0cyBmb3Igbm90aWNlcyByYWlzZWQgd2hlcmUgdGhlcmUgaXMgbm8gcGVyLWluc3RhbmNlIGtleSB0byB1c2U6XG4gICAgIHRoZSByb290LXByb3ZpZGVkIFBsb3RseVNlcnZpY2UgYW5kIHRoZSByZWdpb24tZWRpdG9yIGRpYWxvZy4gUmVuZGVyZWQgYnkgYVxuICAgICBzaW5nbGUgdmlzdWFsaXplciAob3duc1NoYXJlZFRvYXN0cykgc28gYSBtZXNzYWdlIGZyb20gdGhlIHJvb3Qgc2VydmljZSBpc1xuICAgICBub3Qgc2hvd24gb25jZSBwZXIgbGl2ZSB2aWV3ZXIuIC0tPlxuPHAtdG9hc3QgKm5nSWY9XCJvd25zU2hhcmVkVG9hc3RzXCIgW2tleV09XCJ2aXpUb2FzdEtleVwiPjwvcC10b2FzdD5cbjxwLXRvYXN0ICpuZ0lmPVwib3duc1NoYXJlZFRvYXN0c1wiIFtrZXldPVwidml6QWxlcnRUb2FzdEtleVwiIHBvc2l0aW9uPVwiY2VudGVyXCI+PC9wLXRvYXN0PlxuXG48IS0tIFRvb2xiYXIgZG9jazogZG9ja2VkIGFjcm9zcyB0aGUgdG9wIGJ5IGRlZmF1bHQ7IGRyYWcgdGhlIGhhbmRsZSB0byBkZXRhY2hcbiAgICAgaXQgaW50byBhIGZsb2F0aW5nLCBtb3ZhYmxlIHdpbmRvdyAoZnJlZXMgdGhlIHRvcCByb3cgZm9yIHRoZSBpbWFnZSkuIC0tPlxuPGRpdlxuICBjbGFzcz1cInRvb2xiYXItZG9ja1wiXG4gIFtjbGFzcy5mbG9hdGluZ109XCJ0b29sYmFyRmxvYXRpbmdcIlxuICBbc3R5bGUubGVmdC5weF09XCJ0b29sYmFyRmxvYXRpbmcgPyB0b29sYmFyUG9zLnggOiBudWxsXCJcbiAgW3N0eWxlLnRvcC5weF09XCJ0b29sYmFyRmxvYXRpbmcgPyB0b29sYmFyUG9zLnkgOiBudWxsXCJcbj5cbiAgPGRpdlxuICAgIGNsYXNzPVwidG9vbGJhci1kcmFnLWhhbmRsZVwiXG4gICAgW3ZpekZsb2F0aW5nRHJhZ109XCJ0b29sYmFyRHJhZ09yaWdpblwiXG4gICAgKHZpekZsb2F0aW5nRHJhZ01vdmUpPVwidG9vbGJhclBvcyA9ICRldmVudFwiXG4gICAgcFRvb2x0aXA9XCJEcmFnIHRvIGZsb2F0IHRoZSB0b29sYmFyXCJcbiAgICB0b29sdGlwUG9zaXRpb249XCJib3R0b21cIlxuICA+XG4gICAgPGkgY2xhc3M9XCJwaSBwaS1iYXJzXCI+PC9pPlxuICA8L2Rpdj5cbiAgPHBsb3R0aW5nLXRvb2xiYXJcbiAgICBbaW1hZ2VJbmZvXT1cImltYWdlSW5mb1wiXG4gICAgW2hhc1NwYXRpYWxEYXRhc2V0XT1cImhhc1NwYXRpYWxEYXRhc2V0XCJcbiAgICBbcGxvdFR5cGVPcHRpb25zXT1cInBsb3RUeXBlTWVudVwiXG4gICAgW3NlbGVjdGVkUGxvdFR5cGVdPVwic2VsZWN0ZWRQbG90VHlwZUlkXCJcbiAgICBbYmFzZVBsb3RUeXBlXT1cImJhc2VQbG90VHlwZVwiXG4gICAgW2lzb1JhbmdlXT1cImlzb1JhbmdlXCJcbiAgICBbbWF4SW5kZXhdPVwibWF4SW5kZXhcIlxuICAgIFt6SW5kZXhdPVwiekluZGV4XCJcbiAgICBbaXNIZWF0bWFwXT1cImlzSGVhdG1hcFwiXG4gICAgW2lzM2RSZWdpb25zXT1cImlzU3BhdGlhbDNkTW9kZVwiXG4gICAgW2lzVm9sdW1lVmlld109XCJpc1ZvbHVtZVZpZXdcIlxuICAgIFtzbGljZUVkaXRvcl09XCJzbGljZUVkaXRvclwiXG4gICAgW2FjdGl2ZURyYWdNb2RlXT1cImFjdGl2ZURyYWdNb2RlXCJcbiAgICBbYWN0aXZlU3VyZmFjZTNkTW9kZV09XCJhY3RpdmVTdXJmYWNlM2RNb2RlXCJcbiAgICBbYXhlc1Zpc2libGVdPVwiYXhlc1Zpc2libGVcIlxuICAgIFt3aXJlZnJhbWVBY3RpdmVdPVwid2lyZWZyYW1lQWN0aXZlXCJcbiAgICBbcmVzb2x1dGlvblNjYWxlXT1cInJlc29sdXRpb25TY2FsZVwiXG4gICAgW3dhbmRTZW5zaXRpdml0eV09XCJ3YW5kU2Vuc2l0aXZpdHlcIlxuICAgIFticnVzaFNpemVdPVwiYnJ1c2hTaXplXCJcbiAgICBbc2FtTW9kZWxzXT1cInNhbU1vZGVsc1wiXG4gICAgW3NhbU1vZGVsSWRdPVwic2FtTW9kZWxJZFwiXG4gICAgW2NvbnRyaWJ1dGVkVG9vbHNdPVwiY29udHJpYnV0ZWRUb29sc1wiXG4gICAgW2RpYWxvZ1Rvb2xzXT1cImRpYWxvZ1Rvb2xzXCJcbiAgICBbb3BlbkRpYWxvZ1Rvb2xJZF09XCJvcGVuRGlhbG9nVG9vbElkXCJcbiAgICAodG9nZ2xlRGlhbG9nVG9vbCk9XCJ0b2dnbGVEaWFsb2dUb29sKCRldmVudClcIlxuICAgIFt0b29sTW9kZWxJZHNdPVwidG9vbFBhcmFtcy50b29sTW9kZWxJZHNcIlxuICAgIFt2ZXJ0ZXhFcmFzZXJSYWRpdXNdPVwidmVydGV4RXJhc2VyUmFkaXVzXCJcbiAgICBbY2FuVW5kb109XCJyZWdpb25BY3Rpb25zLmNhblVuZG9cIlxuICAgIFtjYW5SZWRvXT1cInJlZ2lvbkFjdGlvbnMuY2FuUmVkb1wiXG4gICAgW3Rvb2xzXT1cInRvb2xiYXJUb29sc1wiXG4gICAgW2ltYWdlU21vb3RoaW5nRW5hYmxlZF09XCJpbWFnZVNtb290aGluZ0VuYWJsZWRcIlxuICAgIChzZWxlY3RQbG90VHlwZSk9XCJvblNlbGVjdFBsb3RUeXBlKCRldmVudClcIlxuICAgICh0b2dnbGVJbWFnZVNtb290aGluZyk9XCJvblRvZ2dsZUltYWdlU21vb3RoaW5nKClcIlxuICAgIChhZGRQcm9maWxlTGluZSk9XCJhZGRQcm9maWxlTGluZSgpXCJcbiAgICAoaXNvUmFuZ2VDaGFuZ2UpPVwib25Jc29SYW5nZUNoYW5nZSgkZXZlbnQpXCJcbiAgICAob3BlbkNoYW5uZWxIaXN0b2dyYW0pPVwib3BlbkNoYW5uZWxIaXN0b2dyYW0oKVwiXG4gICAgKG9wZW5TcGF0aWFsQ29udHJvbHMpPVwib3BlblNwYXRpYWxDb250cm9scygpXCJcbiAgICAob3BlblJlZ2lvbkVkaXRvcik9XCJvcGVuUmVnaW9uRWRpdG9yKClcIlxuICAgICh0b2dnbGVTbGljZUVkaXRvcik9XCJ0b2dnbGVTbGljZUVkaXRvcigpXCJcbiAgICAoc2VsZWN0U3RhY2tPcHRpb24pPVwic2VsZWN0U3RhY2tPcHRpb24oJGV2ZW50KVwiXG4gICAgKHpTY3J1Yik9XCJvblpTY3J1YigkZXZlbnQpXCJcbiAgICAoelNsaWRlKT1cIm9uWlNsaWRlKCRldmVudClcIlxuICAgICh6SW5kZXhJbnB1dCk9XCJ6SW5kZXggPSAkZXZlbnQ7IHVwZGF0ZVpJbmRleCgpXCJcbiAgICAocmVsb2FkQW5kUGxvdCk9XCJyZWxvYWRBbmRQbG90KClcIlxuICAgIChkb3dubG9hZEltYWdlKT1cImRvd25sb2FkSW1hZ2UoKVwiXG4gICAgKGF1dG9zY2FsZUltYWdlKT1cImF1dG9zY2FsZUltYWdlKClcIlxuICAgICh0b2dnbGVEcmFnTW9kZSk9XCJ0b2dnbGVEcmFnTW9kZSgkZXZlbnQpXCJcbiAgICAoem9vbUluKT1cInpvb21JbigpXCJcbiAgICAoem9vbU91dCk9XCJ6b29tT3V0KClcIlxuICAgICh0b2dnbGVTdXJmYWNlM2RNb2RlKT1cInRvZ2dsZVN1cmZhY2UzZE1vZGUoJGV2ZW50KVwiXG4gICAgKHJlc2V0U3VyZmFjZUNhbWVyYSk9XCJyZXNldFN1cmZhY2VDYW1lcmEoKVwiXG4gICAgKHRvZ2dsZUF4ZXMpPVwidG9nZ2xlQXhlcygpXCJcbiAgICAodG9nZ2xlV2lyZWZyYW1lKT1cInRvZ2dsZVdpcmVmcmFtZSgpXCJcbiAgICAoc2VsZWN0UmVzb2x1dGlvbik9XCJzZWxlY3RSZXNvbHV0aW9uKCRldmVudClcIlxuICAgIChkZWxldGVSZWdpb24pPVwiZGVsZXRlUmVnaW9uKClcIlxuICAgICh1bmRvUmVnaW9uKT1cInVuZG9SZWdpb24oKVwiXG4gICAgKHJlZG9SZWdpb24pPVwicmVkb1JlZ2lvbigpXCJcbiAgICAoc2VnbWVudFJlZ2lvbnMpPVwic2VnbWVudFJlZ2lvbnMoKVwiXG4gICAgKHNlZ21lbnRDZWxscG9zZSk9XCJzZWdtZW50Q2VsbHBvc2UoKVwiXG4gICAgKHNhbU1vZGVsQ2hhbmdlKT1cIm9uU2FtTW9kZWxDaGFuZ2UoJGV2ZW50KVwiXG4gICAgKHJ1blRvb2wpPVwicnVuVG9vbCgkZXZlbnQpXCJcbiAgICAodG9vbE1vZGVsQ2hhbmdlKT1cIm9uVG9vbE1vZGVsQ2hhbmdlKCRldmVudClcIlxuICAgIChvcGVuVG9vbFBhcmFtcyk9XCJvcGVuVG9vbFBhcmFtcygkZXZlbnQpXCJcbiAgICAod2FuZFNlbnNpdGl2aXR5Q2hhbmdlKT1cIm9uV2FuZFNlbnNpdGl2aXR5Q2hhbmdlKCRldmVudClcIlxuICAgIChicnVzaFNpemVDaGFuZ2UpPVwib25CcnVzaFNpemVDaGFuZ2UoJGV2ZW50KVwiXG4gICAgKHZlcnRleEVyYXNlclJhZGl1c0NoYW5nZSk9XCJvblZlcnRleEVyYXNlclJhZGl1c0NoYW5nZSgkZXZlbnQpXCJcbiAgPlxuICAgIDwhLS0gSG9zdC1wcm9qZWN0ZWQgY3VzdG9tIHRvb2xiYXIgYnV0dG9ucywgZm9yd2FyZGVkIGludG8gdGhlIHRvb2xiYXIuIC0tPlxuICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbiAgPC9wbG90dGluZy10b29sYmFyPlxuICA8cC1idXR0b25cbiAgICAqbmdJZj1cInRvb2xiYXJGbG9hdGluZ1wiXG4gICAgY2xhc3M9XCJ0b29sYmFyLWRvY2stYnRuXCJcbiAgICBpY29uPVwicGkgcGktdGh1bWJ0YWNrXCJcbiAgICBzaXplPVwic21hbGxcIlxuICAgIFt0ZXh0XT1cInRydWVcIlxuICAgIHBUb29sdGlwPVwiRG9jayB0byB0b3BcIlxuICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgKG9uQ2xpY2spPVwiZG9ja1Rvb2xiYXIoKVwiXG4gID5cbiAgPC9wLWJ1dHRvbj5cbjwvZGl2PlxuXG48cC1jb250ZXh0TWVudSAjY20gW21vZGVsXT1cImNvbnRleHRNZW51SXRlbXNcIiBhcHBlbmRUbz1cImJvZHlcIj48L3AtY29udGV4dE1lbnU+XG48IS0tIE5vIGBoLWZ1bGxgIGhlcmU6IFByaW1lRmxleCdzIGhlaWdodDoxMDAlICFpbXBvcnRhbnQgbWFkZSAjcGxvdCBhcyB0YWxsIGFzXG4gICAgIHRoZSB3aG9sZSBob3N0LCBzbyB1bmRlciB0aGUgZG9ja2VkIHRvb2xiYXIgaXRzIGJvdHRvbSB0b29sYmFyLWhlaWdodCBzdHJpcFxuICAgICAoaW5jbC4gdGhlIE9TRCBzY2FsZSBiYXIgYXQgYm90dG9tLWxlZnQpIHdhcyBjbGlwcGVkIGJ5IHRoZSBob3N0J3NcbiAgICAgb3ZlcmZsb3c6aGlkZGVuLiBUaGUgY29tcG9uZW50IHN0eWxlc2hlZXQgc2l6ZXMgaXQgKC52aXotcGxvdCB7IGZsZXg6IDEgfSkuIC0tPlxuPCEtLSBUaGUgcGxvdCwgYW5kIHdoaWxlIGEgdm9sdW1lIHZpZXcgaXMgc3BsaXQsIHRoZSBzbGljZSBlZGl0b3IncyBwYW5lIG9uIGl0cyBsZWZ0IChpdHMgb3duXG4gICAgIHZpZXdlciwgd2l0aCBldmVyeSByZWdpb24gdG9vbCkgd2l0aCBhIGRpdmlkZXIgdG8gcmVzaXplIHRoZSB0d28uIFRoZSBwbG90IGRpdiBrZWVwcyBpdHNcbiAgICAgcGxhY2UgaW4gdGhlIERPTSBlaXRoZXIgd2F5OiB0aGUgYmFja2VuZHMgZmluZCBpdCBieSBpZCwgYW5kIGEgdmlld2VyIG1vdW50ZWQgaW4gaXQgc3RheXMuIC0tPlxuPGRpdlxuICBjbGFzcz1cInZpei1wYW5lc1wiXG4gIFtjbGFzcy52aXotcXVhZF09XCJzbGljZUVkaXRvclNob3duXCJcbiAgW3N0eWxlLmdyaWQtdGVtcGxhdGUtY29sdW1uc109XCJzbGljZUVkaXRvclNob3duID8gc3BsaXRYICsgJyUgNnB4IG1pbm1heCgwLCAxZnIpJyA6IG51bGxcIlxuICBbc3R5bGUuZ3JpZC10ZW1wbGF0ZS1yb3dzXT1cInNsaWNlRWRpdG9yU2hvd24gPyBzcGxpdFkgKyAnJSA2cHggbWlubWF4KDAsIDFmciknIDogbnVsbFwiXG4+XG4gIDwhLS0gVGhlIHNsaWNlIGVkaXRvcjogdGhlIHZvbHVtZSAodGhlIHBsb3QpIHRvcCBsZWZ0LCB0aGUgc2xpY2UgYmVpbmcgZWRpdGVkIChaKSB0b3AgcmlnaHQsXG4gICAgICAgdGhlIHNlY3Rpb25zIHRocm91Z2ggeCBhbmQgeSBiZWxvdywgaW4gdGhlaXIgYXhpcyBjb2xvdXJzLiAtLT5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInNsaWNlRWRpdG9yU2hvd25cIj5cbiAgICA8ZGl2IGNsYXNzPVwidml6LWNlbGwgdml6LWNlbGwtelwiPlxuICAgICAgPGRpdiBjbGFzcz1cInZpei1zbGljZS1wYW5lXCIgW2lkXT1cInNsaWNlRGl2TmFtZVwiPjwvZGl2PlxuICAgICAgPHNwYW4gY2xhc3M9XCJ2aXotcGFuZS1iYWRnZSB2aXotcGFuZS1iYWRnZS16XCI+WiDCtyBzbGljZSB7eyB6SW5kZXggfX08L3NwYW4+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cInZpei1jZWxsIHZpei1jZWxsLXhcIj5cbiAgICAgIDx2aXotc2VjdGlvbi1wYW5lIGF4aXM9XCJ4XCIgW3ZpZXddPVwic2VjdGlvbnMueFwiIChwaWNrKT1cIm9uU2VjdGlvblBpY2soJ3gnLCAkZXZlbnQpXCI+PC92aXotc2VjdGlvbi1wYW5lPlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJ2aXotY2VsbCB2aXotY2VsbC15XCI+XG4gICAgICA8dml6LXNlY3Rpb24tcGFuZSBheGlzPVwieVwiIFt2aWV3XT1cInNlY3Rpb25zLnlcIiAocGljayk9XCJvblNlY3Rpb25QaWNrKCd5JywgJGV2ZW50KVwiPjwvdml6LXNlY3Rpb24tcGFuZT5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2XG4gICAgICBjbGFzcz1cInZpei1wYW5lLWRpdmlkZXIgdml6LXBhbmUtZGl2aWRlci12XCJcbiAgICAgIHJvbGU9XCJzZXBhcmF0b3JcIlxuICAgICAgYXJpYS1vcmllbnRhdGlvbj1cInZlcnRpY2FsXCJcbiAgICAgIGFyaWEtbGFiZWw9XCJSZXNpemUgdGhlIHBhbmVzIGFjcm9zc1wiXG4gICAgICBbYXR0ci5hcmlhLXZhbHVlbm93XT1cInNwbGl0WFwiXG4gICAgICBhcmlhLXZhbHVlbWluPVwiMjBcIlxuICAgICAgYXJpYS12YWx1ZW1heD1cIjgwXCJcbiAgICAgIHRhYmluZGV4PVwiMFwiXG4gICAgICAocG9pbnRlcmRvd24pPVwic3RhcnRQYW5lUmVzaXplKCRldmVudCwgJ3gnKVwiXG4gICAgICAoa2V5ZG93bik9XCJudWRnZVBhbmVTaXplKCRldmVudCwgJ3gnKVwiXG4gICAgPjwvZGl2PlxuICAgIDxkaXZcbiAgICAgIGNsYXNzPVwidml6LXBhbmUtZGl2aWRlciB2aXotcGFuZS1kaXZpZGVyLWhcIlxuICAgICAgcm9sZT1cInNlcGFyYXRvclwiXG4gICAgICBhcmlhLW9yaWVudGF0aW9uPVwiaG9yaXpvbnRhbFwiXG4gICAgICBhcmlhLWxhYmVsPVwiUmVzaXplIHRoZSBwYW5lcyBkb3duXCJcbiAgICAgIFthdHRyLmFyaWEtdmFsdWVub3ddPVwic3BsaXRZXCJcbiAgICAgIGFyaWEtdmFsdWVtaW49XCIyMFwiXG4gICAgICBhcmlhLXZhbHVlbWF4PVwiODBcIlxuICAgICAgdGFiaW5kZXg9XCIwXCJcbiAgICAgIChwb2ludGVyZG93bik9XCJzdGFydFBhbmVSZXNpemUoJGV2ZW50LCAneScpXCJcbiAgICAgIChrZXlkb3duKT1cIm51ZGdlUGFuZVNpemUoJGV2ZW50LCAneScpXCJcbiAgICA+PC9kaXY+XG4gIDwvbmctY29udGFpbmVyPlxuICA8ZGl2IGNsYXNzPVwidy1mdWxsIHJlbGF0aXZlIHZpei1wbG90XCIgW2lkXT1cInBsb3REaXZOYW1lXCI+XG4gICAgPGRpdiAqbmdJZj1cImltZ0xvYWRpbmcoKSB8fCBzdGFja0xvYWRpbmcoKSB8fCBpc0NhY2hpbmcoKVwiIGNsYXNzPVwibG9hZGluZy1vdmVybGF5XCI+XG4gICAgICA8IS0tIERldGVybWluYXRlIHN0YWNrL3ZvbHVtZSBwcm9ncmVzcyB0YWtlcyBwcmVjZWRlbmNlOiB3aGlsZSBpdCdzIGFjdGl2ZSBzaG93IE9OTFkgdGhlXG4gICAgICAgICBwcm9ncmVzcyBiYXIgKyBcIkxvYWRpbmcgZnJhbWVzLi4uXCIsIG5vdCB0aGUgZ2VuZXJpYyBzcGlubmVyL1wiTG9hZGluZyBpbWFnZS4uLlwiIG9uIHRvcCBvZlxuICAgICAgICAgaXQgKGJvdGggd2VyZSByZW5kZXJpbmcgYXQgb25jZSBmb3IgbmFwYXJpIHZvbHVtZS9pc29zdXJmYWNlIGxvYWRzKS4gLS0+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic3RhY2tMb2FkaW5nKCk7IGVsc2UgaW1nTG9hZGluZ1RwbFwiPlxuICAgICAgICA8cC1wcm9ncmVzc0JhciBjbGFzcz1cInByb2dyZXNzXCIgW3ZhbHVlXT1cImxvYWRpbmdQZXJjZW50YWdlKClcIj48L3AtcHJvZ3Jlc3NCYXI+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1sb2FkaW5nXCI+TG9hZGluZyBmcmFtZXMuLi48L3NwYW4+XG4gICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgIDxuZy10ZW1wbGF0ZSAjaW1nTG9hZGluZ1RwbD5cbiAgICAgICAgPCEtLSBDYWNoZS1jb3B5IHByb2dyZXNzIGlzIHNob3duIHdoZW5ldmVyIGEgY2FjaGUgZG93bmxvYWQgaXMgYWN0aXZlIChpc0NhY2hpbmcpLCBpbmRlcGVuZGVudFxuICAgICAgICAgICBvZiBgaW1nTG9hZGluZ2AsIHNvIGl0J3MgbmV2ZXIgZHJvcHBlZC9tYXNrZWQgbWlkLWRvd25sb2FkLiAtLT5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzQ2FjaGluZygpOyBlbHNlIHNwaW5uZXJMb2FkaW5nXCI+XG4gICAgICAgICAgPCEtLSBTdGFnZS1hd2FyZSBtZXNzYWdlIGNvbWVzIGZyb20gQ2FjaGVQcm9ncmVzc1NlcnZpY2UgdXBkYXRpbmdcbiAgICAgICAgICAgICBpbWFnZUxvYWRpbmdNZXNzYWdlJCAoXCJDYWNoaW5nIGltYWdlLi4uXCIgZHVyaW5nIHRoZSBHQ1MgZG93bmxvYWQsXG4gICAgICAgICAgICAgdGhlbiBcIkdlbmVyYXRpbmcgcHJldmlldy4uLlwiIGR1cmluZyBwZXItc2xpY2UgdGh1bWJuYWlsIGdlbikuIE9uY2UgdGhlXG4gICAgICAgICAgICAgZG93bmxvYWQgaGl0cyAxMDAlIHRoZSByZW1haW5pbmcgd29yayAoc2VydmVyIHByZXZpZXcvdGlsZSBnZW5lcmF0aW9uKVxuICAgICAgICAgICAgIGhhcyBubyBkZXRlcm1pbmF0ZSBwcm9ncmVzcywgc28gZmFsbCB0aHJvdWdoIHRvIHRoZSBzcGlubmVyIHRlbXBsYXRlXG4gICAgICAgICAgICAgcmF0aGVyIHRoYW4gcGFya2luZyBhIGZ1bGwgYmFyIHVuZGVyIFwiTG9hZGluZyBpbWFnZS4uLlwiLiAtLT5cbiAgICAgICAgICA8cC1wcm9ncmVzc0JhciBjbGFzcz1cInByb2dyZXNzXCIgW3ZhbHVlXT1cImNhY2hlUHJvZ3Jlc3MoKVwiPjwvcC1wcm9ncmVzc0Jhcj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cInRleHQtbG9hZGluZ1wiPnt7IGxvYWRpbmdNZXNzYWdlKCkgfX08L3NwYW4+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8bmctdGVtcGxhdGUgI3NwaW5uZXJMb2FkaW5nPlxuICAgICAgICAgIDxkaXYgKm5nSWY9XCJpbWdMb2FkaW5nKClcIiBjbGFzcz1cInNwaW5uZXJcIj48L2Rpdj5cbiAgICAgICAgICA8c3BhbiAqbmdJZj1cImltZ0xvYWRpbmcoKSAmJiAhem9vbSgpXCIgY2xhc3M9XCJ0ZXh0LWxvYWRpbmdcIj57eyBsb2FkaW5nTWVzc2FnZSgpIH19PC9zcGFuPlxuICAgICAgICAgIDxzcGFuICpuZ0lmPVwiaW1nTG9hZGluZygpICYmIHpvb20oKVwiIGNsYXNzPVwiem9vbS10ZXh0LWxvYWRpbmdcIj57eyBsb2FkaW5nTWVzc2FnZSgpIH19PC9zcGFuPlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgIDxwLWJ1dHRvblxuICAgICAgICAqbmdJZj1cInN0YWNrTG9hZGluZygpIHx8IGltZ0xvYWRpbmcoKVwiXG4gICAgICAgIGNsYXNzPVwiY2FuY2VsLWxvYWRpbmdcIlxuICAgICAgICBsYWJlbD1cIkNhbmNlbFwiXG4gICAgICAgIChvbkNsaWNrKT1cImNhbmNlbExvYWRpbmcoKVwiXG4gICAgICA+XG4gICAgICA8L3AtYnV0dG9uPlxuICAgIDwvZGl2PlxuICAgIDwhLS0gVHJhbnNsdWNlbnQgXCJzaGFycGVuaW5nXCIgb3ZlcmxheSBzaG93biBhZnRlciB0aGUgc21hbGwtdGllciBwcmV2aWV3IGlzXG4gICAgICAgb24gc2NyZWVuIHdoaWxlIHRoZSBsYXJnZS10aWVyIHJlbmRlciBpcyBzdGlsbCBsb2FkaW5nIGluIHRoZVxuICAgICAgIGJhY2tncm91bmQuIExldHMgdGhlIHVzZXIgc2VlIHRoZSBibHVycnkgaW1hZ2UgdW5kZXJuZWF0aCBidXQgbWFrZXNcbiAgICAgICBpdCBjbGVhciBzb21ldGhpbmcgaXMgc3RpbGwgbG9hZGluZyBzbyB0aGV5IGRvbid0IG1pc3Rha2UgdGhlXG4gICAgICAgbG93LXJlcyByZW5kZXIgZm9yIHRoZSBmaW5hbCBpbWFnZS4gLS0+XG4gICAgPGRpdiAqbmdJZj1cInJlbmRlci5zaGFycGVuaW5nICYmICFpbWdMb2FkaW5nKCkgJiYgIXN0YWNrTG9hZGluZygpICYmICFpc0NhY2hpbmcoKVwiIGNsYXNzPVwic2hhcnBlbmluZy1vdmVybGF5XCI+XG4gICAgICA8ZGl2IGNsYXNzPVwic3Bpbm5lclwiPjwvZGl2PlxuICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LWxvYWRpbmdcIj5TaGFycGVuaW5nIHByZXZpZXcuLi48L3NwYW4+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9kaXY+XG5cbjwhLS0gRmxvYXRpbmcsIGRyYWdnYWJsZSBpbnRlbnNpdHktcHJvZmlsZSBpbnNldCwgc2hvd24gd2hpbGUgYW55IGludGVuc2l0eSBsaW5lXG4gICAgIGV4aXN0cy4gS2VwdCBPVVRTSURFIHRoZSBwbG90IGRpdiBhbmQgZml4ZWQgdG8gdGhlIHZpZXdwb3J0LCBzbyBpdCBmbG9hdHMgb3ZlclxuICAgICB0aGUgd2hvbGUgcGFnZSByYXRoZXIgdGhhbiBiZWluZyBjbGlwcGVkIHRvIHRoZSBjYW52YXMuIC0tPlxuPHZpei1pbnRlbnNpdHktaW5zZXRcbiAgW2RpdklkXT1cImludGVuc2l0eUluc2V0RGl2XCJcbiAgW3Bsb3REaXZOYW1lXT1cInBsb3REaXZOYW1lXCJcbiAgW3pJbmRleF09XCJ6SW5kZXhcIlxuICBbaW1hZ2VWaWV3XT1cImlzSW1hZ2VWaWV3XCJcbiAgW2ltYWdlSW5mb109XCJpbWFnZUluZm9cIlxuPjwvdml6LWludGVuc2l0eS1pbnNldD5cblxuPCEtLSBDaGFubmVscyAmIEhpc3RvZ3JhbTogbm9uLW1vZGFsIGZsb2F0aW5nIGRpYWxvZyBvcGVuZWQgZnJvbSB0aGUgdG9vbGJhci4gLS0+XG48Y2hhbm5lbC1oaXN0b2dyYW0gWyh2aXNpYmxlKV09XCJzaG93Q2hhbm5lbEhpc3RvZ3JhbVwiPjwvY2hhbm5lbC1oaXN0b2dyYW0+XG5cbjwhLS0gU3BhdGlhbC1vbWljcyBjb250cm9scy4gUmVuZGVycyBpdHMgb3duIGVtcHR5IHN0YXRlIHdoZW4gbm8gZGF0YXNldCAob3Igbm9cbiAgICAgU1BBVElBTF9EQVRBX1BPUlQpIGlzIHByZXNlbnQsIHNvIGl0IGlzIGFsd2F5cyBzYWZlIHRvIGhvc3QuIC0tPlxuPHNwYXRpYWwtY29udHJvbHMgWyh2aXNpYmxlKV09XCJzaG93U3BhdGlhbENvbnRyb2xzXCIgW2lzM2RdPVwiaXNTcGF0aWFsM2RNb2RlXCI+PC9zcGF0aWFsLWNvbnRyb2xzPlxuXG48IS0tIFNpZGUgcGFuZWwgb2YgdGhlIGFjdGl2ZSBjb250cmlidXRlZCBwbG90IG1vZGUgKFBMT1RfVFlQRV9DT05UUklCVVRJT05TKSxcbiAgICAgaW4gdGhlIHNhbWUgcmlnaHQtaGFuZCBhcmVhIGFzIHRoZSBzcGF0aWFsIGNvbnRyb2xzIGFuZCB0aGUgUmVnaW9uIEVkaXRvci5cbiAgICAgRXhpc3RzIG9ubHkgd2hpbGUgdGhlIG1vZGUncyBzZXNzaW9uIGlzIGxpdmU7IHRoZXJlIGlzIG5vIGNsb3NlIGJ1dHRvbixcbiAgICAgYmVjYXVzZSBsZWF2aW5nIHRoZSBtb2RlIGlzIHdoYXQgZW5kcyBpdC4gQSBjb21wb25lbnQgcGFuZWwgZ2V0c1xuICAgICBQTE9UX01PREVfQ09OVEVYVCAvIFBMT1RfTU9ERV9TRVNTSU9OIGZyb20gaXRzIGluamVjdG9yOyBhIGBtb3VudGAgcGFuZWwnc1xuICAgICBob3N0IGVsZW1lbnQgaXMgYXR0YWNoZWQgdG8gdGhlIHNsb3QgYmVsb3cgKHNlZSBwbG90TW9kZVBhbmVsU2xvdCkuIC0tPlxuPHAtZGlhbG9nXG4gICpuZ0lmPVwicGxvdE1vZGVQYW5lbCBhcyBwYW5lbFwiXG4gIFtoZWFkZXJdPVwicGFuZWwudGl0bGVcIlxuICBbdmlzaWJsZV09XCJ0cnVlXCJcbiAgW21vZGFsXT1cImZhbHNlXCJcbiAgW2Nsb3NhYmxlXT1cImZhbHNlXCJcbiAgW3Jlc2l6YWJsZV09XCJ0cnVlXCJcbiAgW2RyYWdnYWJsZV09XCJ0cnVlXCJcbiAgYXBwZW5kVG89XCJib2R5XCJcbiAgcG9zaXRpb249XCJyaWdodFwiXG4gIHN0eWxlQ2xhc3M9XCJwbG90LW1vZGUtcGFuZWxcIlxuICBbc3R5bGVdPVwieyB3aWR0aDogJzIycmVtJywgbWF4SGVpZ2h0OiAnODV2aCcgfVwiXG4gIFtjb250ZW50U3R5bGVdPVwieyBvdmVyZmxvdzogJ2F1dG8nIH1cIlxuPlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwicGFuZWwuY29tcG9uZW50XCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdDb21wb25lbnRPdXRsZXQ9XCJwYW5lbC5jb21wb25lbnQ7IGluamVjdG9yOiBwYW5lbC5pbmplY3RvciA/PyB1bmRlZmluZWRcIj48L25nLWNvbnRhaW5lcj5cbiAgPC9uZy1jb250YWluZXI+XG4gIDxkaXYgKm5nSWY9XCJwYW5lbC5ob3N0XCIgI3Bsb3RNb2RlUGFuZWxTbG90IGNsYXNzPVwicGxvdC1tb2RlLXBhbmVsLXNsb3RcIj48L2Rpdj5cbjwvcC1kaWFsb2c+XG5cbjwhLS0gQW4gb3BlbiBkaWFsb2cgdG9vbCAoVE9PTEJBUl9UT09MUywga2luZDogJ2RpYWxvZycpLiBOb24tbW9kYWwgc28gdGhlIHVzZXIgY2FuXG4gICAgIGtlZXAgd29ya2luZyBvbiB0aGUgaW1hZ2UsIGUuZy4gcGFpbnRpbmcgd2l0aCB0aGUgYnJ1c2ggdGhlIHRvb2wgYXJtZWQuIFRoZVxuICAgICB0b29sIHJlbmRlcnMgaXRzIGJvZHkgaW50byBhIGhvc3QgZWxlbWVudCBhdHRhY2hlZCB0byB0aGUgc2xvdCBiZWxvdyAoc2VlXG4gICAgIHRvb2xEaWFsb2dTbG90KTsgY2xvc2luZyB0aGUgZGlhbG9nIGVuZHMgdGhlIHRvb2wncyBzZXNzaW9uLiAtLT5cbjxwLWRpYWxvZ1xuICAqbmdJZj1cInRvb2xEaWFsb2cgYXMgZGxnXCJcbiAgW2hlYWRlcl09XCJkbGcudGl0bGVcIlxuICBbdmlzaWJsZV09XCJ0cnVlXCJcbiAgKHZpc2libGVDaGFuZ2UpPVwiJGV2ZW50IHx8IGNsb3NlRGlhbG9nVG9vbCgpXCJcbiAgW21vZGFsXT1cImZhbHNlXCJcbiAgW2Nsb3NhYmxlXT1cInRydWVcIlxuICBbcmVzaXphYmxlXT1cInRydWVcIlxuICBbZHJhZ2dhYmxlXT1cInRydWVcIlxuICBhcHBlbmRUbz1cImJvZHlcIlxuICBwb3NpdGlvbj1cInJpZ2h0XCJcbiAgc3R5bGVDbGFzcz1cInRvb2wtZGlhbG9nXCJcbiAgW3N0eWxlXT1cInsgd2lkdGg6IGRsZy53aWR0aCwgbWF4SGVpZ2h0OiAnODV2aCcgfVwiXG4gIFtjb250ZW50U3R5bGVdPVwieyBvdmVyZmxvdzogJ2F1dG8nIH1cIlxuPlxuICA8ZGl2ICN0b29sRGlhbG9nU2xvdCBjbGFzcz1cInRvb2wtZGlhbG9nLXNsb3RcIj48L2Rpdj5cbjwvcC1kaWFsb2c+XG5cbjwhLS0gUmVnaW9uIEVkaXRvcjogbm9uLW1vZGFsLCBkcmFnZ2FibGUsIHJlc2l6YWJsZSBmbG9hdGluZyBkaWFsb2cgb3BlbmVkIGZyb21cbiAgICAgdGhlIHRvb2xiYXIgKGZvcm1lcmx5IHRoZSByaWdodC1wYW5lbCBSZWdpb25zIHRhYikuIE1vZGVsZXNzIHNvIHJlZ2lvbnMgY2FuXG4gICAgIHN0aWxsIGJlIGRyYXduL3NlbGVjdGVkIG9uIHRoZSBwbG90IHdoaWxlIGl0J3Mgb3Blbjsgc3RheXMgbGlua2VkIHRvIHRoaXNcbiAgICAgcGxvdHRpbmcgaW5zdGFuY2UgdmlhIHRoZSByb290IFJlZ2lvblN0b3JlIHNpbmdsZXRvbi4gT3BlbnMgb3ZlciB0aGUgcmlnaHRcbiAgICAgc2lkZSBvZiB0aGUgdmlldy4gLS0+XG48cC1kaWFsb2dcbiAgaGVhZGVyPVwiUmVnaW9uIEVkaXRvclwiXG4gIFsodmlzaWJsZSldPVwic2hvd1JlZ2lvbkVkaXRvclwiXG4gIFttb2RhbF09XCJmYWxzZVwiXG4gIFtyZXNpemFibGVdPVwidHJ1ZVwiXG4gIFtkcmFnZ2FibGVdPVwidHJ1ZVwiXG4gIFttYXhpbWl6YWJsZV09XCJ0cnVlXCJcbiAgYXBwZW5kVG89XCJib2R5XCJcbiAgcG9zaXRpb249XCJyaWdodFwiXG4gIFtzdHlsZV09XCJ7IHdpZHRoOiByZWdpb25FZGl0b3JXaWR0aCwgaGVpZ2h0OiAnODV2aCcgfVwiXG4gIFtjb250ZW50U3R5bGVdPVwieyBvdmVyZmxvdzogJ2F1dG8nIH1cIlxuPlxuICA8cmVnaW9uLWVkaXRvciBbYWN0aXZlXT1cInNob3dSZWdpb25FZGl0b3JcIj48L3JlZ2lvbi1lZGl0b3I+XG48L3AtZGlhbG9nPlxuXG48IS0tIFNpbXBsaWZ5IChEb3VnbGFz4oCTUGV1Y2tlcik6IGN1c3RvbSBweC10aHJlc2hvbGQgcGlja2VyIGZvciB0aGUgc2VsZWN0ZWRcbiAgICAgcmVnaW9uKHMpLCBvcGVuZWQgZnJvbSB0aGUgcmlnaHQtY2xpY2sgXCJTaW1wbGlmeSDilrggQ3VzdG9t4oCmXCIgYWN0aW9uLiAtLT5cbjxwLWRpYWxvZ1xuICBoZWFkZXI9XCJTaW1wbGlmeSByZWdpb24ocylcIlxuICBbKHZpc2libGUpXT1cImRpc3BsYXlTaW1wbGlmeURpYWxvZ1wiXG4gIFttb2RhbF09XCJ0cnVlXCJcbiAgW3N0eWxlXT1cInsgd2lkdGg6ICcyMnJlbScgfVwiXG4gIFtkcmFnZ2FibGVdPVwiZmFsc2VcIlxuICBbcmVzaXphYmxlXT1cImZhbHNlXCJcbj5cbiAgPGRpdiBjbGFzcz1cImZsZXggZmxleC1jb2x1bW4gZ2FwLTJcIj5cbiAgICA8c3BhblxuICAgICAgPkFsdGl0dWRlIHRocmVzaG9sZDogPGI+e3sgcmVnaW9uQWN0aW9ucy5zaW1wbGlmeVRocmVzaG9sZCB9fSBweDwvYj48L3NwYW5cbiAgICA+XG4gICAgPHAtc2xpZGVyIFsobmdNb2RlbCldPVwicmVnaW9uQWN0aW9ucy5zaW1wbGlmeVRocmVzaG9sZFwiIFttaW5dPVwiMVwiIFttYXhdPVwiMjBcIiBbc3RlcF09XCIxXCI+PC9wLXNsaWRlcj5cbiAgICA8c21hbGw+VmVydGljZXMgd2l0aGluIHRoaXMgZGlzdGFuY2Ugb2YgdGhlIGxpbmUgYmV0d2VlbiB0aGVpciBuZWlnaGJvdXJzIGFyZSByZW1vdmVkLjwvc21hbGw+XG4gIDwvZGl2PlxuICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiZm9vdGVyXCI+XG4gICAgPHAtYnV0dG9uIGxhYmVsPVwiQ2FuY2VsXCIgW3RleHRdPVwidHJ1ZVwiIChvbkNsaWNrKT1cImRpc3BsYXlTaW1wbGlmeURpYWxvZyA9IGZhbHNlXCI+PC9wLWJ1dHRvbj5cbiAgICA8cC1idXR0b25cbiAgICAgIGxhYmVsPVwiQXBwbHlcIlxuICAgICAgaWNvbj1cInBpIHBpLWNoZWNrXCJcbiAgICAgIChvbkNsaWNrKT1cInNpbXBsaWZ5UmVnaW9ucyhyZWdpb25BY3Rpb25zLnNpbXBsaWZ5VGhyZXNob2xkKVwiXG4gICAgPjwvcC1idXR0b24+XG4gIDwvbmctdGVtcGxhdGU+XG48L3AtZGlhbG9nPlxuXG48IS0tIFBhcmFtZXRlcnMgZm9yIHdoaWNoZXZlciBjb250cmlidXRlZCB0b29sIGlzIG9wZW4uIE9uZSBkaWFsb2cgZm9yIGFsbCBvZlxuICAgICB0aGVtOiBhIHRvb2wgZGVjbGFyZXMgaXRzIGZpZWxkcyAoVG9vbFBhcmFtU3BlYykgYW5kIHRoaXMgcmVuZGVycyB0aGVtLCBzb1xuICAgICB0aGUgdG9vbGJhciBjYW4gbGF5IGV2ZXJ5IHRvb2wgb3V0IHRoZSBzYW1lIHdheSBhbmQgYSBwbHVnaW4gbmVlZHMgbm9cbiAgICAgUHJpbWVORyBvZiBpdHMgb3duLiBEZWZhdWx0cyBjb21lIGZyb20gdGhlIGFjdGl2ZSBjaGVja3BvaW50LCBzaW5jZSB0aGV5XG4gICAgIGVuY29kZSB3aGF0IGl0IHdhcyB0cmFpbmVkIGZvci4gLS0+XG48cC1kaWFsb2dcbiAgKm5nSWY9XCJ0b29sUGFyYW1zLm9wZW5QYXJhbXMgYXMgb3BlblwiXG4gIFtoZWFkZXJdPVwib3Blbi50b29sLmxhYmVsICsgJyBwYXJhbWV0ZXJzJ1wiXG4gIFt2aXNpYmxlXT1cInRydWVcIlxuICAodmlzaWJsZUNoYW5nZSk9XCJjbG9zZVRvb2xQYXJhbXMoKVwiXG4gIFttb2RhbF09XCJ0cnVlXCJcbiAgW3N0eWxlXT1cInsgd2lkdGg6ICczMHJlbScgfVwiXG4gIFtkcmFnZ2FibGVdPVwiZmFsc2VcIlxuICBbcmVzaXphYmxlXT1cImZhbHNlXCJcbiAgYXBwZW5kVG89XCJib2R5XCJcbj5cbiAgPGRpdiBjbGFzcz1cImdyaWQgZm9ybWdyaWQgcC1mbHVpZFwiPlxuICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGYgb2Ygb3Blbi5maWVsZHNcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJmaWVsZFwiIFtuZ0NsYXNzXT1cImYuc3BlYy50eXBlID09PSAnYm9vbGVhbicgPyAnY29sLTEyJyA6ICdjb2wtNidcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImYubnVtYmVyIGFzIG5cIj5cbiAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJ0ZXh0LXNtXCIgW3BUb29sdGlwXT1cIm4udG9vbHRpcCB8fCAnJ1wiPnt7IG4ubGFiZWwgfX08L2xhYmVsPlxuICAgICAgICAgIDxwLWlucHV0TnVtYmVyXG4gICAgICAgICAgICBbbmdNb2RlbF09XCJvcGVuLnZhbHVlc1tuLmlkXVwiXG4gICAgICAgICAgICAobmdNb2RlbENoYW5nZSk9XCJvcGVuLnZhbHVlc1tuLmlkXSA9ICRldmVudFwiXG4gICAgICAgICAgICBbbWluXT1cIm4ubWluXCJcbiAgICAgICAgICAgIFttYXhdPVwibi5tYXhcIlxuICAgICAgICAgICAgW3N0ZXBdPVwibi5zdGVwXCJcbiAgICAgICAgICAgIFttaW5GcmFjdGlvbkRpZ2l0c109XCJuLmZyYWN0aW9uRGlnaXRzXCJcbiAgICAgICAgICAgIFtzaG93QnV0dG9uc109XCJ0cnVlXCJcbiAgICAgICAgICA+PC9wLWlucHV0TnVtYmVyPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZi5zZWxlY3QgYXMgc2VsXCI+XG4gICAgICAgICAgPGxhYmVsIGNsYXNzPVwidGV4dC1zbVwiIFtwVG9vbHRpcF09XCJzZWwudG9vbHRpcCB8fCAnJ1wiPnt7IHNlbC5sYWJlbCB9fTwvbGFiZWw+XG4gICAgICAgICAgPHAtZHJvcGRvd25cbiAgICAgICAgICAgIFtvcHRpb25zXT1cInNlbC5vcHRpb25zXCJcbiAgICAgICAgICAgIG9wdGlvbkxhYmVsPVwibGFiZWxcIlxuICAgICAgICAgICAgb3B0aW9uVmFsdWU9XCJ2YWx1ZVwiXG4gICAgICAgICAgICBbbmdNb2RlbF09XCJvcGVuLnZhbHVlc1tzZWwuaWRdXCJcbiAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIm9wZW4udmFsdWVzW3NlbC5pZF0gPSAkZXZlbnRcIlxuICAgICAgICAgICAgYXBwZW5kVG89XCJib2R5XCJcbiAgICAgICAgICA+PC9wLWRyb3Bkb3duPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cblxuICAgICAgICA8IS0tIENoZWNrYm94IGxhYmVsIHNpdHMgYmVzaWRlIHRoZSBib3ggYW5kIG1heSBydW4gdG8gYSBzZW50ZW5jZSwgc29cbiAgICAgICAgICAgICBpdCBkb2VzIG5vdCBnZXQgdGhlIHN0YWNrZWQgbGFiZWwgdGhlIG90aGVyIHR5cGVzIHVzZS4gLS0+XG4gICAgICAgIDxkaXYgKm5nSWY9XCJmLnNwZWMudHlwZSA9PT0gJ2Jvb2xlYW4nXCIgY2xhc3M9XCJmbGV4IGFsaWduLWl0ZW1zLWNlbnRlciBnYXAtMlwiPlxuICAgICAgICAgIDxwLWNoZWNrYm94XG4gICAgICAgICAgICBbbmdNb2RlbF09XCJvcGVuLnZhbHVlc1tmLnNwZWMuaWRdXCJcbiAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIm9wZW4udmFsdWVzW2Yuc3BlYy5pZF0gPSAkZXZlbnRcIlxuICAgICAgICAgICAgW2JpbmFyeV09XCJ0cnVlXCJcbiAgICAgICAgICAgIFtpbnB1dElkXT1cIm9wZW4udG9vbC5pZCArICctJyArIGYuc3BlYy5pZFwiXG4gICAgICAgICAgPjwvcC1jaGVja2JveD5cbiAgICAgICAgICA8bGFiZWwgW2Zvcl09XCJvcGVuLnRvb2wuaWQgKyAnLScgKyBmLnNwZWMuaWRcIiBjbGFzcz1cInRleHQtc20gbWItMFwiIFtwVG9vbHRpcF09XCJmLnNwZWMudG9vbHRpcCB8fCAnJ1wiPnt7XG4gICAgICAgICAgICBmLnNwZWMubGFiZWxcbiAgICAgICAgICB9fTwvbGFiZWw+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9uZy1jb250YWluZXI+XG4gIDwvZGl2PlxuICA8bmctdGVtcGxhdGUgcFRlbXBsYXRlPVwiZm9vdGVyXCI+XG4gICAgPHAtYnV0dG9uXG4gICAgICBsYWJlbD1cIlJlc2V0IHRvIG1vZGVsIGRlZmF1bHRzXCJcbiAgICAgIFt0ZXh0XT1cInRydWVcIlxuICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgIChvbkNsaWNrKT1cInJlc2V0VG9vbFBhcmFtcyhvcGVuLnRvb2wuaWQpXCJcbiAgICA+PC9wLWJ1dHRvbj5cbiAgICA8cC1idXR0b24gbGFiZWw9XCJDbG9zZVwiIHNpemU9XCJzbWFsbFwiIChvbkNsaWNrKT1cImNsb3NlVG9vbFBhcmFtcygpXCI+PC9wLWJ1dHRvbj5cbiAgPC9uZy10ZW1wbGF0ZT5cbjwvcC1kaWFsb2c+XG4iXX0=
|