@jax-data-science/sci-image-visualizer 0.17.0 → 0.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/lib/contracts/display-types.mjs +3 -2
- package/esm2022/lib/contracts/image.contract.mjs +1 -1
- package/esm2022/lib/contracts/ports/spatial-data.port.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/spatial-dataset.contract.mjs +1 -1
- package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
- package/esm2022/lib/geometry/cell-meshes.mjs +37 -0
- package/esm2022/lib/geometry/place.mjs +47 -0
- package/esm2022/lib/implementations/napari-js/napari-camera-depth.mjs +93 -0
- package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +1 -1
- package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +2 -2
- package/esm2022/lib/implementations/napari-js/napari-scene.mjs +1 -1
- package/esm2022/lib/implementations/napari-js/napari-spatial-2d-scene.mjs +81 -15
- package/esm2022/lib/implementations/napari-js/napari-spatial-3d-cells.mjs +746 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-3d-scene.mjs +325 -18
- package/esm2022/lib/implementations/napari-js/napari-spatial-3d-transcripts.mjs +182 -24
- package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +95 -5
- package/esm2022/lib/implementations/napari-js/napari-spatial-scene.mjs +15 -1
- package/esm2022/lib/implementations/napari-js/napari-spatial-tiles.mjs +30 -2
- package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +40 -1
- package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +111 -28
- package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +14 -2
- package/esm2022/lib/implementations/napari-js/spatial-tiles/cell-layers.mjs +180 -48
- package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-layers.mjs +28 -8
- package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +2 -2
- package/esm2022/lib/implementations/spatial-data-http/spatial-data-http.service.mjs +10 -1
- package/esm2022/lib/region-editor/class-tree/class-tree.component.mjs +30 -3
- package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +15 -3
- package/esm2022/lib/region-editor/region-editor.component.mjs +24 -4
- package/esm2022/lib/region-source/region-source-ops.mjs +7 -1
- package/esm2022/lib/region-source/region-tiles.mjs +1 -1
- package/esm2022/lib/region-source/worker-region-source.mjs +24 -1
- package/esm2022/lib/routing-visualizer.service.mjs +404 -7
- package/esm2022/lib/spatial/observations-in-selection.mjs +83 -0
- package/esm2022/lib/spatial/plane-cells.mjs +119 -0
- package/esm2022/lib/spatial/spatial-controls.facade.mjs +298 -5
- package/esm2022/lib/spatial/spatial-encoding.mjs +35 -3
- package/esm2022/lib/spatial/spatial-hover.mjs +34 -1
- package/esm2022/lib/spatial/spatial-planes.mjs +49 -0
- package/esm2022/lib/spatial/spatial-selection.mjs +2 -2
- package/esm2022/lib/spatial/spatial-tile-merge.mjs +38 -1
- package/esm2022/lib/spatial/transcripts-in-selection.mjs +208 -0
- package/esm2022/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.mjs +42 -65
- package/esm2022/lib/spatial-controls/spatial-color-by/spatial-color-by.component.mjs +187 -0
- package/esm2022/lib/spatial-controls/spatial-controls.component.mjs +47 -12
- package/esm2022/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.mjs +3 -3
- package/esm2022/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.mjs +38 -10
- package/esm2022/lib/spatial-controls/spatial-key/spatial-key.component.mjs +3 -3
- package/esm2022/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.mjs +3 -3
- package/esm2022/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.mjs +79 -57
- package/esm2022/lib/spatial-controls/spatial-selection-observations/spatial-selection-observations.component.mjs +101 -0
- package/esm2022/lib/spatial-controls/spatial-selection-transcripts/spatial-selection-transcripts.component.mjs +94 -0
- package/esm2022/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.mjs +9 -3
- package/esm2022/lib/store/region-source-scope.mjs +10 -1
- package/esm2022/lib/store/region-store.service.mjs +33 -2
- package/esm2022/lib/toolbar/toolbar.component.mjs +10 -3
- package/esm2022/lib/visualizer/spatial-region-set.mjs +95 -0
- package/esm2022/lib/visualizer.component.mjs +40 -4
- package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-DHrHO2ay.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-YrNqv8wH.mjs} +4521 -759
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-YrNqv8wH.mjs.map +1 -0
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-CKEUwNta.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-Dph35S7m.mjs} +2 -2
- package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-CKEUwNta.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-Dph35S7m.mjs.map} +1 -1
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs +1 -1
- package/fesm2022/region-source.worker.js +84 -2
- package/lib/contracts/display-types.d.ts +90 -4
- package/lib/contracts/image.contract.d.ts +6 -0
- package/lib/contracts/ports/spatial-data.port.d.ts +7 -0
- package/lib/contracts/region-editor-api.contract.d.ts +9 -0
- package/lib/contracts/region-store.contract.d.ts +6 -0
- package/lib/contracts/spatial-dataset.contract.d.ts +7 -1
- package/lib/contracts/visualizer.contract.d.ts +43 -1
- package/lib/geometry/cell-meshes.d.ts +27 -0
- package/lib/geometry/place.d.ts +45 -0
- package/lib/implementations/napari-js/napari-camera-depth.d.ts +23 -0
- package/lib/implementations/napari-js/napari-loading-state.d.ts +1 -1
- package/lib/implementations/napari-js/napari-scene.d.ts +12 -0
- package/lib/implementations/napari-js/napari-spatial-2d-scene.d.ts +19 -3
- package/lib/implementations/napari-js/napari-spatial-3d-cells.d.ts +141 -0
- package/lib/implementations/napari-js/napari-spatial-3d-scene.d.ts +87 -0
- package/lib/implementations/napari-js/napari-spatial-3d-transcripts.d.ts +49 -8
- package/lib/implementations/napari-js/napari-spatial-hover.d.ts +22 -0
- package/lib/implementations/napari-js/napari-spatial-scene.d.ts +12 -0
- package/lib/implementations/napari-js/napari-spatial-tiles.d.ts +15 -0
- package/lib/implementations/napari-js/napari-visualizer.service.d.ts +27 -1
- package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +38 -19
- package/lib/implementations/napari-js/napari-volume-scene.d.ts +2 -0
- package/lib/implementations/napari-js/spatial-tiles/cell-layers.d.ts +53 -0
- package/lib/implementations/napari-js/spatial-tiles/transcript-layers.d.ts +11 -2
- package/lib/implementations/spatial-data-http/spatial-data-http.service.d.ts +7 -0
- package/lib/region-editor/class-tree/class-tree.component.d.ts +16 -1
- package/lib/region-editor/classes-panel/classes-panel.component.d.ts +10 -1
- package/lib/region-editor/region-editor.component.d.ts +4 -0
- package/lib/region-source/region-source-ops.d.ts +12 -0
- package/lib/region-source/region-tiles.d.ts +8 -0
- package/lib/region-source/worker-region-source.d.ts +18 -0
- package/lib/routing-visualizer.service.d.ts +140 -1
- package/lib/spatial/observations-in-selection.d.ts +43 -0
- package/lib/spatial/plane-cells.d.ts +37 -0
- package/lib/spatial/spatial-controls.facade.d.ts +59 -0
- package/lib/spatial/spatial-encoding.d.ts +14 -1
- package/lib/spatial/spatial-hover.d.ts +23 -0
- package/lib/spatial/spatial-planes.d.ts +22 -0
- package/lib/spatial/spatial-selection.d.ts +2 -1
- package/lib/spatial/spatial-tile-merge.d.ts +9 -0
- package/lib/spatial/transcripts-in-selection.d.ts +95 -0
- package/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.d.ts +19 -28
- package/lib/spatial-controls/spatial-color-by/spatial-color-by.component.d.ts +64 -0
- package/lib/spatial-controls/spatial-controls.component.d.ts +17 -2
- package/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.d.ts +16 -6
- package/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.d.ts +26 -23
- package/lib/spatial-controls/spatial-selection-observations/spatial-selection-observations.component.d.ts +48 -0
- package/lib/spatial-controls/spatial-selection-transcripts/spatial-selection-transcripts.component.d.ts +43 -0
- package/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.d.ts +3 -1
- package/lib/store/region-source-scope.d.ts +4 -0
- package/lib/store/region-store.service.d.ts +21 -0
- package/lib/toolbar/toolbar.component.d.ts +6 -1
- package/lib/visualizer/spatial-region-set.d.ts +55 -0
- package/lib/visualizer.component.d.ts +14 -0
- package/package.json +1 -1
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-DHrHO2ay.mjs.map +0 -1
|
@@ -45,6 +45,7 @@ import { FloatingDragDirective } from './visualizer/floating-drag.directive';
|
|
|
45
45
|
import { IntensityInsetComponent } from './intensity-inset/intensity-inset.component';
|
|
46
46
|
import { SectionPaneComponent } from './section-pane/section-pane.component';
|
|
47
47
|
import { SpatialDatasetBinder } from './visualizer/spatial-dataset-binder';
|
|
48
|
+
import { SpatialRegionSetLink } from './visualizer/spatial-region-set';
|
|
48
49
|
import { ToolbarComponent } from './toolbar/toolbar.component';
|
|
49
50
|
import { RegionEditorComponent } from './region-editor/region-editor.component';
|
|
50
51
|
import { ChannelHistogramComponent } from './channel-histogram/channel-histogram.component';
|
|
@@ -378,6 +379,11 @@ export class VisualizerComponent {
|
|
|
378
379
|
this.consumedSliceHints = new WeakSet();
|
|
379
380
|
this.zIndex = 0;
|
|
380
381
|
this.maxIndex = 0;
|
|
382
|
+
/**
|
|
383
|
+
* Planes of the spatial dataset's region set slicing the image, an image of one plane (see
|
|
384
|
+
* `IVisualizer.getDatasetPlanes$`): the slider then runs over them. 0 without.
|
|
385
|
+
*/
|
|
386
|
+
this.datasetPlanes = 0;
|
|
381
387
|
this.contextMenuItems = [];
|
|
382
388
|
/** The armed tool mode and the toolbar's tool settings. */
|
|
383
389
|
this.tools = new ToolModes(this.plotService, this.session, this.ngZone, (mode) => {
|
|
@@ -439,6 +445,8 @@ export class VisualizerComponent {
|
|
|
439
445
|
// The host's HttpClient carries a server-side region source's requests: its interceptors (auth) apply.
|
|
440
446
|
const http = this.injector?.get(HttpClient, null) ?? undefined;
|
|
441
447
|
applyImageRois(info, this.plotService, this.zIndex, this.vizConfig?.regionSourceMinChars, http);
|
|
448
|
+
// After the image's own regions: a spatial dataset's region set joins them (its cells in 3D).
|
|
449
|
+
this.regionSetLink.imageLanded(info);
|
|
442
450
|
this.contributions.activate();
|
|
443
451
|
},
|
|
444
452
|
setImageLoading: (loading) => this.state.setImageLoading(loading),
|
|
@@ -533,6 +541,7 @@ export class VisualizerComponent {
|
|
|
533
541
|
notify: (m) => this.messageService.add({ key: this.resultToastKey, ...m }),
|
|
534
542
|
detectChanges: () => this.cdr.detectChanges(),
|
|
535
543
|
});
|
|
544
|
+
this.regionSetLink = new SpatialRegionSetLink(this.spatialData, this.plotService);
|
|
536
545
|
this.spatial = new SpatialDatasetBinder(this.spatialData, {
|
|
537
546
|
gatesChanged: () => this.computePlotTypeOptions(),
|
|
538
547
|
selectedId: () => this.selectedPlotTypeId,
|
|
@@ -554,6 +563,33 @@ export class VisualizerComponent {
|
|
|
554
563
|
* re-gates the selector exactly as the image stream and the test-mode toggle do. */
|
|
555
564
|
watchSpatialDataset() {
|
|
556
565
|
this.spatial.bind(this.destroyed$);
|
|
566
|
+
this.regionSetLink.bind(this.destroyed$);
|
|
567
|
+
const planes$ = this.plotService.getDatasetPlanes$?.();
|
|
568
|
+
if (planes$) {
|
|
569
|
+
this.mirror(planes$, (planes) => {
|
|
570
|
+
this.datasetPlanes = planes?.length ?? 0;
|
|
571
|
+
this.layOutPlanes();
|
|
572
|
+
this.changed();
|
|
573
|
+
});
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
/**
|
|
577
|
+
* The slider over the dataset's planes, on an image of one plane: its bounds are the planes'
|
|
578
|
+
* (none left: back to the image's one), the slice kept within them.
|
|
579
|
+
*/
|
|
580
|
+
layOutPlanes() {
|
|
581
|
+
if (this.imageInfo?.isStack)
|
|
582
|
+
return;
|
|
583
|
+
const max = this.planeMaxIndex();
|
|
584
|
+
if (max === this.maxIndex)
|
|
585
|
+
return;
|
|
586
|
+
this.maxIndex = max;
|
|
587
|
+
if (this.zIndex > max)
|
|
588
|
+
this.onZSlide(max);
|
|
589
|
+
}
|
|
590
|
+
/** The last slice index the dataset's planes give an image of one plane (0 without). */
|
|
591
|
+
planeMaxIndex() {
|
|
592
|
+
return this.datasetPlanes > 1 ? this.datasetPlanes - 1 : 0;
|
|
557
593
|
}
|
|
558
594
|
/** Recompute the selector's entries for the current image, dataset and test mode
|
|
559
595
|
* (see {@link computePlotTypeMenu}). */
|
|
@@ -764,7 +800,7 @@ export class VisualizerComponent {
|
|
|
764
800
|
*/
|
|
765
801
|
layOutSlices(info) {
|
|
766
802
|
this.stackLoading.set(info.isStack && info.showStack);
|
|
767
|
-
this.maxIndex = info.urls.length > 1 ? info.urls.length - 1 : 0;
|
|
803
|
+
this.maxIndex = info.urls.length > 1 ? info.urls.length - 1 : info.isStack ? 0 : this.planeMaxIndex();
|
|
768
804
|
if (info.initialZIndex !== undefined) {
|
|
769
805
|
if (!this.consumedSliceHints.has(info)) {
|
|
770
806
|
this.consumedSliceHints.add(info);
|
|
@@ -1241,7 +1277,7 @@ export class VisualizerComponent {
|
|
|
1241
1277
|
this.contributions.attachToolDialogSlot(ref?.nativeElement);
|
|
1242
1278
|
}
|
|
1243
1279
|
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 }); }
|
|
1244
|
-
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 }); }
|
|
1280
|
+
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 [planeSlices]=\"datasetPlanes > 1 && !imageInfo?.isStack\"\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", "planeSlices", "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 }); }
|
|
1245
1281
|
}
|
|
1246
1282
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: VisualizerComponent, decorators: [{
|
|
1247
1283
|
type: Component,
|
|
@@ -1266,7 +1302,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
|
|
|
1266
1302
|
ChannelHistogramComponent,
|
|
1267
1303
|
SpatialControlsComponent,
|
|
1268
1304
|
RegionEditorComponent,
|
|
1269
|
-
], 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"] }]
|
|
1305
|
+
], 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 [planeSlices]=\"datasetPlanes > 1 && !imageInfo?.isStack\"\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"] }]
|
|
1270
1306
|
}], ctorParameters: () => [{ type: undefined, decorators: [{
|
|
1271
1307
|
type: Inject,
|
|
1272
1308
|
args: [IMAGE_STATE_PORT]
|
|
@@ -1318,4 +1354,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
|
|
|
1318
1354
|
type: ViewChild,
|
|
1319
1355
|
args: ['toolDialogSlot']
|
|
1320
1356
|
}] } });
|
|
1321
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlzdWFsaXplci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3Zpc3VhbGl6ZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vc3JjL2xpYi92aXN1YWxpemVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFFTCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsVUFBVSxFQUNWLFlBQVksRUFDWixNQUFNLEVBQ04sUUFBUSxFQUNSLEtBQUssRUFDTCxNQUFNLEVBSU4sUUFBUSxFQUNSLE1BQU0sRUFFTixTQUFTLEVBQ1QsUUFBUSxFQUNSLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUU3QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRWxDLE9BQU8sRUFBWSxjQUFjLEVBQUUsWUFBWSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3JFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3JFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDbEQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0scUJB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QUNqQixZQUFZO3dCQUNaLFdBQVc7d0JBQ1gsYUFBYTt3QkFDYixxQkFBcUI7d0JBQ3JCLGdCQUFnQjt3QkFDaEIsdUJBQXVCO3dCQUN2QixvQkFBb0I7d0JBQ3BCLHlCQUF5Qjt3QkFDekIsd0JBQXdCO3dCQUN4QixxQkFBcUI7cUJBQ3RCLG1CQUdnQix1QkFBdUIsQ0FBQyxNQUFNOzswQkFxYzVDLE1BQU07MkJBQUMsZ0JBQWdCOzswQkFDdkIsTUFBTTsyQkFBQyxVQUFVOzswQkFTakIsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxVQUFVOzswQkFJN0IsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxhQUFhOzswQkFHaEMsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyxpQkFBaUI7OzBCQUdwQyxRQUFROzswQkFBSSxNQUFNOzJCQUFDLHVCQUF1Qjs7MEJBRzFDLFFBQVE7OzBCQUVSLFFBQVE7a0VBdGJYLFlBQVk7c0JBRFgsTUFBTTtnQkFJUCxnQkFBZ0I7c0JBRGYsTUFBTTtnQkFNSCxZQUFZO3NCQURmLEtBQUs7Z0JBY04sUUFBUTtzQkFEUCxLQUFLO2dCQTBDVyxXQUFXO3NCQUEzQixTQUFTO3VCQUFDLElBQUk7Z0JBb0xYLGlCQUFpQjtzQkFEcEIsU0FBUzt1QkFBQyxtQkFBbUI7Z0JBOEJ3QixLQUFLO3NCQUExRCxTQUFTO3VCQUFDLHVCQUF1QixFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTtnQkErNkJoRCxjQUFjO3NCQURqQixTQUFTO3VCQUFDLGdCQUFnQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIEFmdGVyVmlld0luaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBEZXN0cm95UmVmLFxuICBFbGVtZW50UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEluamVjdCxcbiAgSW5qZWN0b3IsXG4gIElucHV0LFxuICBOZ1pvbmUsXG4gIE9uQ2hhbmdlcyxcbiAgT25EZXN0cm95LFxuICBPbkluaXQsXG4gIE9wdGlvbmFsLFxuICBPdXRwdXQsXG4gIFNpbXBsZUNoYW5nZXMsXG4gIFZpZXdDaGlsZCxcbiAgY29tcHV0ZWQsXG4gIHNpZ25hbCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyB0YWtlVW50aWxEZXN0cm95ZWQgfSBmcm9tICdAYW5ndWxhci9jb3JlL3J4anMtaW50ZXJvcCc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgSHR0cENsaWVudCB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbi9odHRwJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuXG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IE1lbnVJdGVtLCBNZXNzYWdlU2VydmljZSwgU2hhcmVkTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9hcGknO1xuaW1wb3J0IHsgQnV0dG9uTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9idXR0b24nO1xuaW1wb3J0IHsgQ2hlY2tib3hNb2R1bGUgfSBmcm9tICdwcmltZW5nL2NoZWNrYm94JztcbmltcG9ydCB7IENvbnRleHRNZW51LCBDb250ZXh0TWVudU1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvY29udGV4dG1lbnUnO1xuaW1wb3J0IHsgRGlhbG9nTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9kaWFsb2cnO1xuaW1wb3J0IHsgRHJvcGRvd25Nb2R1bGUgfSBmcm9tICdwcmltZW5nL2Ryb3Bkb3duJztcbmltcG9ydCB7IElucHV0TnVtYmVyTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9pbnB1dG51bWJlcic7XG5pbXBvcnQgeyBQcm9ncmVzc0Jhck1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvcHJvZ3Jlc3NiYXInO1xuaW1wb3J0IHsgU2xpZGVyTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9zbGlkZXInO1xuaW1wb3J0IHsgVG9hc3RNb2R1bGUgfSBmcm9tICdwcmltZW5nL3RvYXN0JztcbmltcG9ydCB7IFRvb2x0aXBNb2R1bGUgfSBmcm9tICdwcmltZW5nL3Rvb2x0aXAnO1xuaW1wb3J0IHsgSUltYWdlSW5mbyB9IGZyb20gJy4vY29udHJhY3RzL2ltYWdlLmNvbnRyYWN0JztcbmltcG9ydCB7IEltYWdlU3RhdGVQb3J0LCBJTUFHRV9TVEFURV9QT1JUIH0gZnJvbSAnLi9jb250cmFjdHMvcG9ydHMvaW1hZ2Utc3RhdGUucG9ydCc7XG5pbXBvcnQgeyBQb2x5Z29uIH0gZnJvbSAnLi9tb2RlbHMvcmVnaW9uJztcbmltcG9ydCB7IFJlZ2lvbk9wc1NlcnZpY2UgfSBmcm9tICcuL3JlZ2lvbi1vcHMuc2VydmljZSc7XG5pbXBvcnQgeyBWSVpfVE9BU1RfS0VZLCBWSVpfQUxFUlRfVE9BU1RfS0VZIH0gZnJvbSAnLi90b2FzdC1vdXRsZXRzJztcbmltcG9ydCB7IFZpc3VhbGl6ZXJTdG9yZSB9IGZyb20gJy4vc3RvcmUvdmlzdWFsaXplci1zdG9yZS5zZXJ2aWNlJztcbmltcG9ydCB7IFNsaWNlU2NydWJiZXIgfSBmcm9tICcuL3JlbmRlci1vcmNoZXN0cmF0b3InO1xuaW1wb3J0IHsgSW1hZ2VSZW5kZXJTZXNzaW9uLCBlcnJvck1lc3NhZ2UgfSBmcm9tICcuL3JlbmRlci1zZXNzaW9uJztcbmltcG9ydCB7XG4gIFBsb3RUeXBlLFxuICBQbG90VHlwZURlc2NyaXB0b3IsXG4gIFBsb3RUeXBlSWQsXG4gIGdldFBsb3RUeXBlRGVzY3JpcHRvcixcbiAgaXNCdWlsdGluUGxvdFR5cGUsXG4gIGlzTmFwYXJpM2QsXG4gIGlzU3BhdGlhbE9taWNzLFxuICBpc1NwYXRpYWxPbWljczNkLFxuICByZW5kZXJlck93bnNXaGVlbCxcbiAgTkFQQVJJX0RFRkFVTFRfREVDSU1BVEUsXG4gIGlzTmFwYXJpVm9sdW1lLFxuICBpc05hcGFyaUlzb3N1cmZhY2UsXG59IGZyb20gJy4vY29udHJhY3RzL3Bsb3QtdHlwZSc7XG5pbXBvcnQge1xuICBQTE9UX1RZUEVfQ09OVFJJQlVUSU9OUyxcbiAgUGxvdFR5cGVDb250cmlidXRpb24sXG4gIFBsb3RUeXBlT3B0aW9uLFxufSBmcm9tICcuL2NvbnRyYWN0cy9wbG90LXR5cGUtY29udHJpYnV0aW9uLmNvbnRyYWN0JztcbmltcG9ydCB7IFBsb3RNb2RlQ29udHJvbGxlciB9IGZyb20gJy4vcGxvdC1tb2RlL3Bsb3QtbW9kZS1jb250cm9sbGVyJztcbmltcG9ydCB7IGNvbXB1dGVQbG90VHlwZU1lbnUsIHJlY29uY2lsZVBsb3RUeXBlIH0gZnJvbSAnLi9wbG90LW1vZGUvcGxvdC10eXBlLW1lbnUnO1xuaW1wb3J0IHsgVG9vbFBhcmFtc01vZGVsIH0gZnJvbSAnLi9wbG90LW1vZGUvdG9vbC1wYXJhbXMtbW9kZWwnO1xuaW1wb3J0IHsgQ29udHJpYnV0aW9uSG9zdCwgUGxvdE1vZGVQYW5lbFZpZXcsIFRvb2xEaWFsb2dWaWV3IH0gZnJvbSAnLi9wbG90LW1vZGUvY29udHJpYnV0aW9uLWhvc3QnO1xuaW1wb3J0IHsgSVZpc3VhbGl6ZXIsIFZJU1VBTElaRVIsIFZpc3VhbGl6ZXJIYW5kbGUgfSBmcm9tICcuL2NvbnRyYWN0cy92aXN1YWxpemVyLmNvbnRyYWN0JztcbmltcG9ydCB7IFNBTV9NT0RFTFMsIGdldERlZmF1bHRTYW1Nb2RlbElkLCBpc1NhbU1vZGVsUmVhZHkgfSBmcm9tICcuL3Rvb2xiYXIvc2VnbWVudGF0aW9uL3NhbS1tb2RlbC1yZWdpc3RyeSc7XG5pbXBvcnQgeyBTYW1Ub29sU2VydmljZSB9IGZyb20gJy4vdG9vbGJhci9zZWdtZW50YXRpb24vc2FtLXRvb2wuc2VydmljZSc7XG5pbXBvcnQgeyBTYW1Qb2ludFRvb2xTZXJ2aWNlIH0gZnJvbSAnLi90b29sYmFyL3NlZ21lbnRhdGlvbi9zYW0tcG9pbnQtdG9vbC5zZXJ2aWNlJztcbmltcG9ydCB7IENlbGxTZWdtZW50VG9vbFNlcnZpY2UgfSBmcm9tICcuL3Rvb2xiYXIvc2VnbWVudGF0aW9uL2NlbGwtc2VnbWVudC10b29sLnNlcnZpY2UnO1xuaW1wb3J0IHsgU2VnbWVudGF0aW9uUnVubmVyIH0gZnJvbSAnLi90b29sYmFyL3NlZ21lbnRhdGlvbi9zZWdtZW50YXRpb24tcnVubmVyJztcbmltcG9ydCB7XG4gIFRPT0xCQVJfVE9PTFMsXG4gIFRvb2xiYXJDb250cmlidXRpb24sXG4gIFRvb2xiYXJEaWFsb2dUb29sQ29udHJpYnV0aW9uLFxuICBUb29sYmFyVG9vbENvbnRyaWJ1dGlvbixcbiAgdmlzaWJsZVRvb2xDb250cmlidXRpb25zLFxufSBmcm9tICcuL2NvbnRyYWN0cy90b29sYmFyLXRvb2wuY29udHJhY3QnO1xuaW1wb3J0IHsgVG9vbGJhclRvb2xWaXNpYmlsaXR5LCBBTExfVE9PTEJBUl9UT09MUyB9IGZyb20gJy4vY29udHJhY3RzL3Rvb2xiYXItY29uZmlnJztcbmltcG9ydCB7IFZJWl9DT05GSUcsIFZpekNvbmZpZyB9IGZyb20gJy4vY29udHJhY3RzL3Zpei1jb25maWcnO1xuaW1wb3J0IHsgU1BBVElBTF9EQVRBX1BPUlQsIFNwYXRpYWxEYXRhUG9ydCB9IGZyb20gJy4vY29udHJhY3RzL3BvcnRzL3NwYXRpYWwtZGF0YS5wb3J0JztcbmltcG9ydCB7IGFwcGx5SW1hZ2VSb2lzIH0gZnJvbSAnLi92aXN1YWxpemVyL3JlZ2lvbi1sb2FkJztcbmltcG9ydCB7IENvbnRleHRNZW51QWN0aW9ucywgQ29udGV4dE1lbnVTdGF0ZSwgYnVpbGRDb250ZXh0TWVudSB9IGZyb20gJy4vdmlzdWFsaXplci92aXN1YWxpemVyLWNvbnRleHQtbWVudSc7XG5pbXBvcnQgeyBSZWdpb25BY3Rpb25zIH0gZnJvbSAnLi92aXN1YWxpemVyL3JlZ2lvbi1hY3Rpb25zJztcbmltcG9ydCB7IFRvb2xNb2RlcyB9IGZyb20gJy4vdmlzdWFsaXplci90b29sLW1vZGVzJztcbmltcG9ydCB7IFNob3J0Y3V0SG9zdCwgVmlld2VyU2hvcnRjdXRzIH0gZnJvbSAnLi92aXN1YWxpemVyL3ZpZXdlci1zaG9ydGN1dHMnO1xuaW1wb3J0IHsgRmxvYXRpbmdEcmFnRGlyZWN0aXZlLCBGbG9hdGluZ1BvcyB9IGZyb20gJy4vdmlzdWFsaXplci9mbG9hdGluZy1kcmFnLmRpcmVjdGl2ZSc7XG5pbXBvcnQgeyBJbnRlbnNpdHlJbnNldENvbXBvbmVudCB9IGZyb20gJy4vaW50ZW5zaXR5LWluc2V0L2ludGVuc2l0eS1pbnNldC5jb21wb25lbnQnO1xuaW1wb3J0IHsgU2VjdGlvblBhbmVDb21wb25lbnQgfSBmcm9tICcuL3NlY3Rpb24tcGFuZS9zZWN0aW9uLXBhbmUuY29tcG9uZW50JztcbmltcG9ydCB0eXBlIHsgU2VjdGlvbkF4aXMsIFNlY3Rpb25WaWV3cyB9IGZyb20gJy4vY29udHJhY3RzL3NlY3Rpb24tdmlldy5jb250cmFjdCc7XG5pbXBvcnQgeyBTcGF0aWFsRGF0YXNldEJpbmRlciB9IGZyb20gJy4vdmlzdWFsaXplci9zcGF0aWFsLWRhdGFzZXQtYmluZGVyJztcbmltcG9ydCB7IFRvb2xiYXJDb21wb25lbnQgfSBmcm9tICcuL3Rvb2xiYXIvdG9vbGJhci5jb21wb25lbnQnO1xuaW1wb3J0IHsgUmVnaW9uRWRpdG9yQ29tcG9uZW50IH0gZnJvbSAnLi9yZWdpb24tZWRpdG9yL3JlZ2lvbi1lZGl0b3IuY29tcG9uZW50JztcbmltcG9ydCB7IENoYW5uZWxIaXN0b2dyYW1Db21wb25lbnQgfSBmcm9tICcuL2NoYW5uZWwtaGlzdG9ncmFtL2NoYW5uZWwtaGlzdG9ncmFtLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTcGF0aWFsQ29udHJvbHNDb21wb25lbnQgfSBmcm9tICcuL3NwYXRpYWwtY29udHJvbHMvc3BhdGlhbC1jb250cm9scy5jb21wb25lbnQnO1xuXG4vKiogUGVyLWluc3RhbmNlIHBsb3QtZGl2IGlkIHNvdXJjZS4gVGhlIG1vdW50IGVsZW1lbnQncyBpZCBtdXN0IGJlIHVuaXF1ZSBzbyB0d29cbiAqICBsaXZlIHZpZXdlcnMgKGUuZy4gdGhlIG1haW4gZGlhZ3JhbSArIGEgbW9kYWwgcHJldmlldykgZG9uJ3QgY29sbGlkZSBvbiB0aGVcbiAqICBzYW1lIERPTSBpZCDigJQgYGdldEVsZW1lbnRCeUlkYCB3b3VsZCBvdGhlcndpc2UgcmV0dXJuIHdoaWNoZXZlciBjYW1lIGZpcnN0LlxuICogIFN0eWxpbmcgaGFuZ3Mgb2ZmIHRoZSBgLnZpei1wbG90YCBjbGFzcyBpbnN0ZWFkIG9mIHRoZSBpZC4gKi9cbmxldCBwbG90SW5zdGFuY2VTZXEgPSAwO1xuXG4vKipcbiAqIFRoZSB2aWV3ZXIgKGA8dmlzdWFsaXplcj5gKTogdGhlIHBsb3Qgc3VyZmFjZSwgaXRzIHRvb2xiYXIsIHRoZSBsb2FkaW5nIG92ZXJsYXkgYW5kXG4gKiB0aGUgZGlhbG9ncyBpdCBvcGVucyAoQ2hhbm5lbHMgJiBIaXN0b2dyYW0sIHNwYXRpYWwtb21pY3MgY29udHJvbHMsIFJlZ2lvbiBFZGl0b3IsXG4gKiBjb250cmlidXRlZCBtb2RlcyBhbmQgdG9vbHMpLiBJdCBvcmNoZXN0cmF0ZXMgcmVuZGVyaW5nIHRocm91Z2ggdGhlIGBWSVNVQUxJWkVSYFxuICogY29udHJhY3QgYW5kIHJlYWRzIHRoZSBpbWFnZSBmcm9tIHRoZSBob3N0J3MgYElNQUdFX1NUQVRFX1BPUlRgLlxuICpcbiAqIE9uUHVzaC4gVGVtcGxhdGUgZXZlbnRzIHJlLXJlbmRlciBpdDsgc3RhdGUgdGhhdCBsYW5kcyBhc3luY2hyb25vdXNseSBnb2VzIHRocm91Z2hcbiAqIHtAbGluayBjaGFuZ2VkfSAob3IgYSBzaWduYWw6IHRoZSBsb2FkaW5nIG92ZXJsYXkpLCBhbmQgdGhlIGNvbGxhYm9yYXRvcnMgdGhhdCBtdXN0XG4gKiByZW5kZXIgc3luY2hyb25vdXNseSAodGhlIHJlbmRlciBzZXNzaW9uJ3Mgb3ZlcmxheSwgYSBjb250cmlidXRlZCBwYW5lbCdzIHNsb3QsIHRoZVxuICogY29udGV4dCBtZW51IGJlZm9yZSBpdCBvcGVucykgc3RpbGwgY2FsbCBgZGV0ZWN0Q2hhbmdlcygpYC5cbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAndmlzdWFsaXplcicsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBDb21tb25Nb2R1bGUsXG4gICAgRm9ybXNNb2R1bGUsXG4gICAgU2hhcmVkTW9kdWxlLFxuICAgIEJ1dHRvbk1vZHVsZSxcbiAgICBDaGVja2JveE1vZHVsZSxcbiAgICBDb250ZXh0TWVudU1vZHVsZSxcbiAgICBEaWFsb2dNb2R1bGUsXG4gICAgRHJvcGRvd25Nb2R1bGUsXG4gICAgSW5wdXROdW1iZXJNb2R1bGUsXG4gICAgUHJvZ3Jlc3NCYXJNb2R1bGUsXG4gICAgU2xpZGVyTW9kdWxlLFxuICAgIFRvYXN0TW9kdWxlLFxuICAgIFRvb2x0aXBNb2R1bGUsXG4gICAgRmxvYXRpbmdEcmFnRGlyZWN0aXZlLFxuICAgIFRvb2xiYXJDb21wb25lbnQsXG4gICAgSW50ZW5zaXR5SW5zZXRDb21wb25lbnQsXG4gICAgU2VjdGlvblBhbmVDb21wb25lbnQsXG4gICAgQ2hhbm5lbEhpc3RvZ3JhbUNvbXBvbmVudCxcbiAgICBTcGF0aWFsQ29udHJvbHNDb21wb25lbnQsXG4gICAgUmVnaW9uRWRpdG9yQ29tcG9uZW50LFxuICBdLFxuICB0ZW1wbGF0ZVVybDogJy4vdmlzdWFsaXplci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3Zpc3VhbGl6ZXIuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIFZpc3VhbGl6ZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcywgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95LCBDb250ZXh0TWVudUFjdGlvbnMge1xuICAvKiogUGVyLWluc3RhbmNlIHRvYXN0IGtleS4gTWVzc2FnZVNlcnZpY2UgaXMgYSBnbG9iYWwgc2luZ2xldG9uLCBzbyB0d28gbGl2ZVxuICAgKiAgYDx2aXN1YWxpemVyPmAgaW5zdGFuY2VzIChtYWluIHZpZXdlciArIHBpcGVsaW5lLWRpYWxvZyBwcmV2aWV3KSBzaGFyaW5nXG4gICAqICBvbmUga2V5IHdvdWxkIGVhY2ggcmVuZGVyIHRoZSBzYW1lIG1lc3NhZ2Ug4oCUIGEgZHVwbGljYXRlIHRvYXN0LiBBIHVuaXF1ZVxuICAgKiAga2V5IHBlciBpbnN0YW5jZSBzY29wZXMgdGhlIHRvYXN0IHRvIHRoZSBjb21wb25lbnQgdGhhdCByYWlzZWQgaXQuICovXG4gIHByaXZhdGUgc3RhdGljIG5leHRUb2FzdElkID0gMDtcblxuICAvKipcbiAgICogVGhlIGxpYnJhcnkgYWxzbyByYWlzZXMgbm90aWNlcyBmcm9tIHBsYWNlcyB0aGF0IGhhdmUgbm8gaW5zdGFuY2Ugb2YgdGhlaXJcbiAgICogb3duIHRvIGtleSBhZ2FpbnN0OiB7QGxpbmsgUGxvdGx5U2VydmljZX0gaXMgYHByb3ZpZGVkSW46ICdyb290J2AsIGFuZCB0aGVcbiAgICogcmVnaW9uIGVkaXRvciBpcyBhIGNoaWxkIGRpYWxvZy4gVGhvc2UgdXNlIHRoZSBmaXhlZFxuICAgKiB7QGxpbmsgVklaX1RPQVNUX0tFWX0gLyB7QGxpbmsgVklaX0FMRVJUX1RPQVNUX0tFWX0gb3V0bGV0cy5cbiAgICpcbiAgICogRm9yIHRoZSBzYW1lIHJlYXNvbiB0aGUgcGVyLWluc3RhbmNlIGtleSBhYm92ZSBleGlzdHMsIGV4YWN0bHkgT05FIG1vdW50ZWRcbiAgICogdmlzdWFsaXplciBtYXkgcmVuZGVyIHRob3NlIHNoYXJlZCBvdXRsZXRzIOKAlCBvdGhlcndpc2UgYSBtZXNzYWdlIGZyb20gdGhlXG4gICAqIHJvb3Qgc2VydmljZSB3b3VsZCBiZSBzaG93biBvbmNlIHBlciBsaXZlIHZpZXdlciAoaml0LXVpIHJ1bnMgYSBtYWluIHZpZXdcbiAgICogYW5kIGEgcGlwZWxpbmUtcHJldmlldyBhdCB0aGUgc2FtZSB0aW1lKS4gVGhlIGZpcnN0IHRvIGluaXQgY2xhaW1zIHRoZW0gYW5kXG4gICAqIHJlbGVhc2VzIG9uIGRlc3Ryb3ksIHNvIHRoZSBzdXJ2aXZpbmcgdmlld2VyIHBpY2tzIHRoZW0gdXAuXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyByZWFkb25seSBsaXZlSW5zdGFuY2VzID0gbmV3IFNldDxWaXN1YWxpemVyQ29tcG9uZW50PigpO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgdml6VG9hc3RLZXkgPSBWSVpfVE9BU1RfS0VZO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgdml6QWxlcnRUb2FzdEtleSA9IFZJWl9BTEVSVF9UT0FTVF9LRVk7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoaXMgaW5zdGFuY2UgcmVuZGVycyB0aGUgc2hhcmVkIG91dGxldHMuIFRoZSBvd25lciBpcyBzaW1wbHkgdGhlXG4gICAqIG9sZGVzdCBsaXZlIHZpc3VhbGl6ZXIg4oCUIGEgYFNldGAgaXRlcmF0ZXMgaW4gaW5zZXJ0aW9uIG9yZGVyLCBzbyB3aGVuIHRoZVxuICAgKiBvd25lciBpcyBkZXN0cm95ZWQgdGhlIG5leHQgb25lIHRha2VzIG92ZXIgb24gaXRzIGZvbGxvd2luZyBjaGFuZ2UtZGV0ZWN0aW9uXG4gICAqIHBhc3MuIFRyYWNraW5nIGEgc2V0IHJhdGhlciB0aGFuIGEgc2luZ2xlIG93bmVyIG1hdHRlcnM6IHdpdGggYSBsb25lXG4gICAqIGBvd25lcmAgcmVmZXJlbmNlLCB0ZWFyaW5nIGRvd24gdGhlIG93bmVyIHdoaWxlIGEgc2libGluZyB3YXMgYWxyZWFkeVxuICAgKiBpbml0aWFsaXNlZCB3b3VsZCBsZWF2ZSBub2JvZHkgcmVuZGVyaW5nIHRoZSBvdXRsZXRzLCBhbmQgZXZlcnkgbm90aWNlIGZyb21cbiAgICogdGhlIHJvb3Qgc2VydmljZSB3b3VsZCBzaWxlbnRseSB2YW5pc2ggYWdhaW4uXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IG93bnNTaGFyZWRUb2FzdHMoKTogYm9vbGVhbiB7XG4gICAgY29uc3Qgb2xkZXN0ID0gVmlzdWFsaXplckNvbXBvbmVudC5saXZlSW5zdGFuY2VzLnZhbHVlcygpLm5leHQoKTtcbiAgICByZXR1cm4gIW9sZGVzdC5kb25lICYmIG9sZGVzdC52YWx1ZSA9PT0gdGhpcztcbiAgfVxuXG4gIC8qKiBFYWNoIG5ldyBpbWFnZTogd2hldGhlciBpdCBpcyBhIHotc3RhY2suICovXG4gIEBPdXRwdXQoKVxuICBpc1N0YWNrRXZlbnQgPSBuZXcgRXZlbnRFbWl0dGVyKGZhbHNlKTtcbiAgLyoqIEVhY2ggbmV3IGltYWdlOiB3aGV0aGVyIGl0IGlzIHNpbmdsZS1jaGFubmVsIChncmF5c2NhbGUpLiAqL1xuICBAT3V0cHV0KClcbiAgaXNHcmF5c2NhbGVFdmVudCA9IG5ldyBFdmVudEVtaXR0ZXIoZmFsc2UpO1xuXG4gIC8qKiBXaGljaCB0b29sYmFyIGdyb3VwcyB0byBzaG93LiBBIHBhcnRpYWwgb3ZlcnJpZGUgbWVyZ2VzIG92ZXIgdGhlIGZ1bGwgc2V0LFxuICAgKiAgc28gYHsgc3BlY2lhbFRvb2xzOiBmYWxzZSB9YCBoaWRlcyBvbmx5IHRoYXQgZ3JvdXAuIERlZmF1bHRzIHRvIGV2ZXJ5dGhpbmcuICovXG4gIEBJbnB1dCgpXG4gIHNldCB0b29sYmFyVG9vbHModjogVG9vbGJhclRvb2xWaXNpYmlsaXR5IHwgdW5kZWZpbmVkKSB7XG4gICAgdGhpcy5fdG9vbGJhclRvb2xzID0geyAuLi5BTExfVE9PTEJBUl9UT09MUywgLi4uKHYgPz8ge30pIH07XG4gIH1cblxuICBnZXQgdG9vbGJhclRvb2xzKCk6IFJlcXVpcmVkPFRvb2xiYXJUb29sVmlzaWJpbGl0eT4ge1xuICAgIHJldHVybiB0aGlzLl90b29sYmFyVG9vbHM7XG4gIH1cbiAgcHJpdmF0ZSBfdG9vbGJhclRvb2xzOiBSZXF1aXJlZDxUb29sYmFyVG9vbFZpc2liaWxpdHk+ID0gQUxMX1RPT0xCQVJfVE9PTFM7XG5cbiAgLyoqIEV4cG9zZSB0ZXN0LW9ubHkgcGxvdCBtb2RlcyBpbiB0aGUgc2VsZWN0b3IgKGUuZy4gdGhlIG5hcGFyaSBgSW1hZ2VgXG4gICAqICBtb2RlLCBvdGhlcndpc2UgaGlkZGVuKS4gVGhlIGhvc3QgYXBwIHNldHMgdGhpcyBmcm9tIGEgYD90ZXN0PTFgIFVSTFxuICAgKiAgdG9nZ2xlLiBPZmYgYnkgZGVmYXVsdCwgc28gcHJvZHVjdGlvbiB1c2VycyBuZXZlciBzZWUgdGhlbS4gKi9cbiAgQElucHV0KClcbiAgdGVzdE1vZGUgPSBmYWxzZTtcblxuICAvKiogSW1hZ2Utc21vb3RoaW5nIHN0YXRlIGZvciB0aGUgdG9vbGJhcidzIFNtb290aGVuIHRvZ2dsZSAoT1NEIG9ubHkpLlxuICAgKiAgRGVmYXVsdHMgdG8gYGZhbHNlYCBzbyBPU0Qgc2hvd3MgcmF3IHBpeGVscyAobmVhcmVzdC1uZWlnaGJvdXIpLiAqL1xuICBwcm90ZWN0ZWQgaW1hZ2VTbW9vdGhpbmdFbmFibGVkID0gZmFsc2U7XG4gIGZpbGVOYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgbG9hZGVkRmlsZU5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgcHJvdGVjdGVkIGltYWdlSW5mbzogSUltYWdlSW5mbyB8IHVuZGVmaW5lZDtcblxuICAvLyDilIDilIAgVGhlIGxvYWRpbmcgb3ZlcmxheSwgYXMgc2lnbmFsczogaXQgaXMgZmVkIGJ5IHRoZSBob3N0J3MgYW5kIHRoZSBiYWNrZW5kcycgc3RyZWFtc1xuICAvLyBhbmQgYnkgdGhlIHJlbmRlciBzZXNzaW9uLCBhbGwgb2Ygd2hpY2ggbGFuZCBvdXRzaWRlIHRoaXMgdmlldydzIHRlbXBsYXRlIGV2ZW50cy4g4pSA4pSAXG4gIHByb3RlY3RlZCByZWFkb25seSBsb2FkaW5nTWVzc2FnZSA9IHNpZ25hbCgnTG9hZGluZyBpbWFnZS4uLicpO1xuICAvKiogVGhlIGhvc3QgaXMgbG9hZGluZyBhdCB6b29tICh0aGUgb3ZlcmxheSBtZXNzYWdlIG1vdmVzIG91dCBvZiB0aGUgd2F5KS4gKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHpvb20gPSBzaWduYWwoZmFsc2UpO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgc3RhY2tMb2FkaW5nID0gc2lnbmFsKGZhbHNlKTtcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGltZ0xvYWRpbmcgPSBzaWduYWwoZmFsc2UpO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgbG9hZGluZ1BlcmNlbnRhZ2UgPSBzaWduYWwoMCk7XG4gIC8vIE5vbi1udWxsICgwLi4xMDApIHdoaWxlIGppdC1zZXJ2aWNlIGlzIGNvcHlpbmcgdGhlIHNvdXJjZSBmaWxlIGludG8gdGhlXG4gIC8vIGxvY2FsIGNhY2hlIFBWQyBvbiBmaXJzdCBjbGljay4gV2hlbiBzZXQsIHRoZSBsb2FkaW5nIG92ZXJsYXkgc3dhcHMgdGhlXG4gIC8vIHNwaW5uZXIgZm9yIGEgZGV0ZXJtaW5hdGUgcHJvZ3Jlc3MgYmFyIHdpdGggYSBcIkNhY2hpbmcgaW1hZ2VcIiBtZXNzYWdlLlxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgY2FjaGVQcm9ncmVzcyA9IHNpZ25hbDxudW1iZXIgfCBudWxsPihudWxsKTtcbiAgLyoqIEEgaml0LXNlcnZpY2UgY2FjaGUgY29weSBpcyBhY3RpdmVseSBpbiBwcm9ncmVzcyAoZGV0ZXJtaW5hdGUgMC4uOTkpLiBEcml2ZXMgdGhlIGNhY2hlXG4gICAqICBwcm9ncmVzcyBiYXIgaW5kZXBlbmRlbnRseSBvZiBgaW1nTG9hZGluZ2Agc28gdGhlIGJhciBjYW4ndCBiZSBkcm9wcGVkIOKAlCBvciBtYXNrZWQgYnkgdGhlXG4gICAqICBcIlNoYXJwZW5pbmcgcHJldmlldy4uLlwiIG92ZXJsYXkg4oCUIG1pZC1kb3dubG9hZCBpZiB0aGUgbG9hZGluZyBmbGFnIGZsaXBzIGVhcmx5LiAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgaXNDYWNoaW5nID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IHAgPSB0aGlzLmNhY2hlUHJvZ3Jlc3MoKTtcbiAgICByZXR1cm4gcCAhPT0gbnVsbCAmJiBwIDwgMTAwO1xuICB9KTtcblxuICAvKiogRW1pdHMgb25jZSB3aGVuIHRoaXMgdmlldyBpcyBkZXN0cm95ZWQ7IHRoZSBjb2xsYWJvcmF0b3JzIGVuZCB0aGVpciBzdWJzY3JpcHRpb25zIG9uIGl0LiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGRlc3Ryb3llZCQgPSBuZXcgT2JzZXJ2YWJsZTx2b2lkPigoc3Vic2NyaWJlcikgPT5cbiAgICB0aGlzLmRlc3Ryb3lSZWYub25EZXN0cm95KCgpID0+IHtcbiAgICAgIHN1YnNjcmliZXIubmV4dCgpO1xuICAgICAgc3Vic2NyaWJlci5jb21wbGV0ZSgpO1xuICAgIH0pLFxuICApO1xuICAvKiogSG9zdCBpbWFnZS1pbmZvIG9iamVjdHMgd2hvc2Ugb25lLXNob3QgYGluaXRpYWxaSW5kZXhgIHdhcyBhbHJlYWR5IGFwcGxpZWQuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgY29uc3VtZWRTbGljZUhpbnRzID0gbmV3IFdlYWtTZXQ8SUltYWdlSW5mbz4oKTtcbiAgcHJvdGVjdGVkIHpJbmRleCA9IDA7XG4gIHByb3RlY3RlZCBtYXhJbmRleCA9IDA7XG5cbiAgQFZpZXdDaGlsZCgnY20nKSBjb250ZXh0TWVudSE6IENvbnRleHRNZW51O1xuICBwcm90ZWN0ZWQgY29udGV4dE1lbnVJdGVtczogTWVudUl0ZW1bXSA9IFtdO1xuXG4gIC8qKiBUaGUgYXJtZWQgdG9vbCBtb2RlIGFuZCB0aGUgdG9vbGJhcidzIHRvb2wgc2V0dGluZ3MuICovXG4gIHByb3RlY3RlZCByZWFkb25seSB0b29scyA9IG5ldyBUb29sTW9kZXMoXG4gICAgdGhpcy5wbG90U2VydmljZSxcbiAgICB0aGlzLnNlc3Npb24sXG4gICAgdGhpcy5uZ1pvbmUsXG4gICAgKG1vZGUpID0+IHtcbiAgICAgIGlmIChtb2RlICE9PSAnc2FtUG9pbnQnKSB0aGlzLnNlZ21lbnRhdGlvbi5oaWRlKCk7XG4gICAgfSwgLy8gbGVhdmluZyBwb2ludCBtb2RlIGRyb3BzIGl0cyB0b2FzdFxuICAgICgpID0+IHRoaXMuY2hhbmdlZCgpLFxuICApO1xuICBwcm90ZWN0ZWQgZ2V0IGFjdGl2ZURyYWdNb2RlKCk6IHN0cmluZyB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLnRvb2xzLmFjdGl2ZTtcbiAgfVxuICBwcm90ZWN0ZWQgc2V0IGFjdGl2ZURyYWdNb2RlKG1vZGU6IHN0cmluZyB8IG51bGwpIHtcbiAgICB0aGlzLnRvb2xzLmFjdGl2ZSA9IG1vZGU7XG4gIH1cbiAgcHJvdGVjdGVkIGdldCB3YW5kU2Vuc2l0aXZpdHkoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy50b29scy53YW5kU2Vuc2l0aXZpdHk7XG4gIH1cbiAgcHJvdGVjdGVkIHNldCB3YW5kU2Vuc2l0aXZpdHkodjogbnVtYmVyKSB7XG4gICAgdGhpcy50b29scy53YW5kU2Vuc2l0aXZpdHkgPSB2O1xuICB9XG4gIHByb3RlY3RlZCBnZXQgYnJ1c2hTaXplKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMudG9vbHMuYnJ1c2hTaXplO1xuICB9XG4gIHByb3RlY3RlZCBnZXQgdmVydGV4RXJhc2VyUmFkaXVzKCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMudG9vbHMudmVydGV4RXJhc2VyUmFkaXVzO1xuICB9XG4gIHByb3RlY3RlZCBzZXQgdmVydGV4RXJhc2VyUmFkaXVzKHY6IG51bWJlcikge1xuICAgIHRoaXMudG9vbHMudmVydGV4RXJhc2VyUmFkaXVzID0gdjtcbiAgfVxuXG4gIC8qKiBSZWdpb24gc2V0LW9wZXJhdGlvbnMgb24gdGhlIHNlbGVjdGlvbiwgYW5kIHRoZSBzdG9yZSBtaXJyb3JzIHRoZXkgcmVhZCAoaml0LXVpIzg1KS4gKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHJlZ2lvbkFjdGlvbnMgPSBuZXcgUmVnaW9uQWN0aW9ucyhcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLFxuICAgIHRoaXMucmVnaW9uT3BzLFxuICAgICgpID0+IHRoaXMuaW1hZ2VJbmZvPy50cnVlSW1hZ2VTaXplLFxuICAgIChtKSA9PiB0aGlzLm1lc3NhZ2VTZXJ2aWNlLmFkZCh7IGtleTogdGhpcy5yZXN1bHRUb2FzdEtleSwgLi4ubSB9KSxcbiAgKTtcbiAgLyoqIEN1c3RvbS10aHJlc2hvbGQgU2ltcGxpZnkgZGlhbG9nIHZpc2liaWxpdHkgKHNlZSB7QGxpbmsgUmVnaW9uQWN0aW9uc30pLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGRpc3BsYXlTaW1wbGlmeURpYWxvZygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5yZWdpb25BY3Rpb25zLmRpc3BsYXlTaW1wbGlmeURpYWxvZztcbiAgfVxuICBwcm90ZWN0ZWQgc2V0IGRpc3BsYXlTaW1wbGlmeURpYWxvZyh2OiBib29sZWFuKSB7XG4gICAgdGhpcy5yZWdpb25BY3Rpb25zLmRpc3BsYXlTaW1wbGlmeURpYWxvZyA9IHY7XG4gIH1cblxuICAvKiogU0FNIG1vZGVsIHBpY2tlciBvcHRpb25zICsgY3VycmVudCBzZWxlY3Rpb24gKGppdC11aSM5MCBQMSkuIE9ubHkgbW9kZWxzXG4gICAqICB3aXRoIGEgaG9zdGVkIE9OTlggcGFpciAoY29uZmlndXJlZCB2aWEgc2V0U2FtTW9kZWxVcmxzIGF0IGFwcCBpbml0KSBhcmVcbiAgICogIG9mZmVyZWQsIHNvIHRoZSBwaWNrZXIgY2FuJ3Qgc2VsZWN0IGEgbW9kZWwgdGhhdCBjYW4ndCBydW4uICovXG4gIHByb3RlY3RlZCBzYW1Nb2RlbHMgPSBTQU1fTU9ERUxTLmZpbHRlcihpc1NhbU1vZGVsUmVhZHkpLm1hcCgobSkgPT4gKHsgaWQ6IG0uaWQsIGxhYmVsOiBtLmxhYmVsIH0pKTtcbiAgcHJvdGVjdGVkIHNhbU1vZGVsSWQgPSBnZXREZWZhdWx0U2FtTW9kZWxJZCgpO1xuXG4gIC8qKlxuICAgKiBOby1wcm9tcHQgdG9vbHMgcmVnaXN0ZXJlZCB0aHJvdWdoIHtAbGluayBUT09MQkFSX1RPT0xTfSwgZmlsdGVyZWQgdG8gdGhvc2VcbiAgICogd2l0aCBjb25maWd1cmVkIG1vZGVscyBhbmQgc29ydGVkLiBUaGlzIGxpYnJhcnkgcmVnaXN0ZXJzIG5vbmUg4oCUIGEgaG9zdFxuICAgKiBzdXBwbGllcyB0aGVtIOKAlCBzbyBhbiBvcGVuIGJ1aWxkIGhhcyBhbiBlbXB0eSBhcnJheSBoZXJlIGFuZCB0aGUgdG9vbGJhclxuICAgKiBhbmQgaGVscCBkaWFsb2cgc2ltcGx5IG9taXQgdGhhdCBncm91cC5cbiAgICovXG4gIHByb3RlY3RlZCBjb250cmlidXRlZFRvb2xzOiBUb29sYmFyVG9vbENvbnRyaWJ1dGlvbltdID0gW107XG4gIC8qKiBDaGVja3BvaW50cyBhbmQgcGFyYW1ldGVyIHZhbHVlcyBvZiB7QGxpbmsgY29udHJpYnV0ZWRUb29sc30sIGFuZCB0aGVpciBkaWFsb2cuICovXG4gIHByb3RlY3RlZCByZWFkb25seSB0b29sUGFyYW1zOiBUb29sUGFyYW1zTW9kZWw7XG4gIC8qKiBDb250cmlidXRlZCBwbG90IG1vZGVzIGFuZCBkaWFsb2cgdG9vbHMsIGFuZCB0aGVpciBsaXZlIHNlc3Npb25zLiAqL1xuICByZWFkb25seSBjb250cmlidXRpb25zOiBDb250cmlidXRpb25Ib3N0O1xuICAvKiogRGlhbG9nIHRvb2xzIHJlZ2lzdGVyZWQgdGhyb3VnaCB7QGxpbmsgVE9PTEJBUl9UT09MU30gKGBraW5kOiAnZGlhbG9nJ2ApLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGRpYWxvZ1Rvb2xzKCk6IFRvb2xiYXJEaWFsb2dUb29sQ29udHJpYnV0aW9uW10ge1xuICAgIHJldHVybiB0aGlzLmNvbnRyaWJ1dGlvbnMuZGlhbG9nVG9vbHM7XG4gIH1cbiAgLyoqIFRoZSBkaWFsb2cgdG9vbCB0aGUgdXNlciBoYXMgb3BlbiAoaXRzIHNlc3Npb24gbWF5IGJlIGJldHdlZW4gcmVuZGVycykuICovXG4gIHByb3RlY3RlZCBnZXQgb3BlbkRpYWxvZ1Rvb2xJZCgpOiBzdHJpbmcgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5jb250cmlidXRpb25zLm9wZW5EaWFsb2dUb29sSWQ7XG4gIH1cbiAgLyoqIFRoZSBvcGVuIGRpYWxvZyB0b29sJ3MgbGl2ZSBkaWFsb2csIGFzIHRoZSB0ZW1wbGF0ZSByZW5kZXJzIGl0LiAqL1xuICBwcm90ZWN0ZWQgZ2V0IHRvb2xEaWFsb2coKTogVG9vbERpYWxvZ1ZpZXcgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5jb250cmlidXRpb25zLnRvb2xEaWFsb2c7XG4gIH1cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHNhbVRvYXN0S2V5ID0gYHNhbS0ke1Zpc3VhbGl6ZXJDb21wb25lbnQubmV4dFRvYXN0SWQrK31gO1xuICAvKipcbiAgICogT3V0bGV0IGZvciB0aGUgbGlicmFyeSdzIG93biByZXN1bHQvZXJyb3Igbm90aWNlcywga2V5ZWQgdG8gdGhpcyBpbnN0YW5jZSBzbyB0aGV5XG4gICAqIGRvIG5vdCBkZXBlbmQgb24gdGhlIGhvc3QgbW91bnRpbmcgYSBrZXlsZXNzIGA8cC10b2FzdD5gIChtb3N0IGhvc3RzIGRvbid0LCBhbmQgYVxuICAgKiBmYWlsZWQgc2VnbWVudGF0aW9uIHRoZW4gbG9va2VkIGxpa2UgYSBkZWFkIGJ1dHRvbikuIERlbGliZXJhdGVseSBOT1QgdGhlIHN0aWNreVxuICAgKiB0b2FzdCdzIGtleTogdGhhdCBpcyBjbGVhcmVkIHdoZW4gYSBydW4gc2V0dGxlcywgd2hpY2ggd291bGQgd2lwZSB0aGUgcmVzdWx0LlxuICAgKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHJlc3VsdFRvYXN0S2V5ID0gYCR7dGhpcy5zYW1Ub2FzdEtleX0tcmVzdWx0YDtcbiAgLyoqIFNlZ21lbnRhdGlvbiBydW5zIGFuZCB0aGVpciBzdGlja3kgcHJvZ3Jlc3MgdG9hc3QuICovXG4gIHByb3RlY3RlZCByZWFkb25seSBzZWdtZW50YXRpb24gPSBuZXcgU2VnbWVudGF0aW9uUnVubmVyKFxuICAgIHRoaXMubWVzc2FnZVNlcnZpY2UsXG4gICAgdGhpcy5zYW1Ub2FzdEtleSxcbiAgICB0aGlzLnJlc3VsdFRvYXN0S2V5LFxuICAgICgpID0+IHRoaXMuY2hhbmdlZCgpLFxuICApO1xuXG4gIC8qKiBDaGFubmVscyAmIEhpc3RvZ3JhbSBkaWFsb2cgdmlzaWJpbGl0eSAob3BlbmVkIGZyb20gdGhlIHRvb2xiYXIpLiAqL1xuICBwcm90ZWN0ZWQgc2hvd0NoYW5uZWxIaXN0b2dyYW0gPSBmYWxzZTtcbiAgLyoqIFNwYXRpYWwtb21pY3MgY29udHJvbHMgZGlhbG9nIHZpc2liaWxpdHkgKHRvb2xiYXIgYnV0dG9uKS4gKi9cbiAgcHJvdGVjdGVkIHNob3dTcGF0aWFsQ29udHJvbHMgPSBmYWxzZTtcbiAgLyoqIFJlZ2lvbiBFZGl0b3IgZGlhbG9nIHZpc2liaWxpdHkgKG9wZW5lZCBmcm9tIHRoZSB0b29sYmFyKS4gKi9cbiAgcHJvdGVjdGVkIHNob3dSZWdpb25FZGl0b3IgPSBmYWxzZTtcbiAgLyoqIFJlZ2lvbiBFZGl0b3IgZGlhbG9nIHdpZHRoLiBPbiBvcGVuIGl0IGlzIHNldCB0byB0aGUgY29uZmlndXJlZCBob3N0XG4gICAqICBlbGVtZW50J3MgY3VycmVudCB3aWR0aCwgb3Ig4oCUIHdoZW4gbm8gc2VsZWN0b3IgaXMgY29uZmlndXJlZCAvIHRoZSBlbGVtZW50XG4gICAqICBpc24ndCBmb3VuZCDigJQgdG8gYSBxdWFydGVyIG9mIHRoZSBwYWdlIChzZWUgb3BlblJlZ2lvbkVkaXRvcikuICovXG4gIHByb3RlY3RlZCByZWdpb25FZGl0b3JXaWR0aCA9ICcyNXZ3JztcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHBsb3REaXZOYW1lID0gYHZpei1wbG90LSR7cGxvdEluc3RhbmNlU2VxKyt9YDtcbiAgLyoqIFRoZSByZW5kZXIgcGlwZWxpbmU6IHRoZSBuZXdlc3QgaW1hZ2UgKG9yIGltYWdlLWxlc3MgZGF0YXNldCkgYWx3YXlzIHdpbnMuICovXG4gIHByb3RlY3RlZCByZWFkb25seSByZW5kZXI6IEltYWdlUmVuZGVyU2Vzc2lvbiA9IG5ldyBJbWFnZVJlbmRlclNlc3Npb24oe1xuICAgIHBsb3REaXZOYW1lOiB0aGlzLnBsb3REaXZOYW1lLFxuICAgIHZpc3VhbGl6ZXI6IHRoaXMucGxvdFNlcnZpY2UsXG4gICAgekluZGV4OiAoKSA9PiB0aGlzLnpJbmRleCxcbiAgICBwbG90VHlwZTogKCkgPT4gdGhpcy5wbG90VHlwZSxcbiAgICBpc0hlYXRtYXA6ICgpID0+IHRoaXMuaXNIZWF0bWFwLFxuICAgIGlzQ2FjaGluZzogKCkgPT4gdGhpcy5pc0NhY2hpbmcoKSxcbiAgICBiZWZvcmVSZXNldDogKCkgPT4gdGhpcy5jb250cmlidXRpb25zLmVuZFNlc3Npb25zKCksXG4gICAgcHJlcGFyZTogKGluZm8pID0+IHRoaXMubGF5T3V0U2xpY2VzKGluZm8pLFxuICAgIHJlbGVhc2VPdmVybGF5OiAoaW5mbykgPT4ge1xuICAgICAgaWYgKGluZm8uaXNTdGFjayAmJiBpbmZvLnNob3dTdGFjaykgdGhpcy5zdGFja0xvYWRpbmcuc2V0KGZhbHNlKTtcbiAgICAgIHRoaXMuc3RhdGUuc2V0SW1hZ2VMb2FkaW5nKGZhbHNlKTtcbiAgICB9LFxuICAgIGxhbmRlZDogKGluZm8pID0+IHtcbiAgICAgIC8vIFRoZSBob3N0J3MgSHR0cENsaWVudCBjYXJyaWVzIGEgc2VydmVyLXNpZGUgcmVnaW9uIHNvdXJjZSdzIHJlcXVlc3RzOiBpdHMgaW50ZXJjZXB0b3JzIChhdXRoKSBhcHBseS5cbiAgICAgIGNvbnN0IGh0dHAgPSB0aGlzLmluamVjdG9yPy5nZXQoSHR0cENsaWVudCwgbnVsbCkgPz8gdW5kZWZpbmVkO1xuICAgICAgYXBwbHlJbWFnZVJvaXMoaW5mbywgdGhpcy5wbG90U2VydmljZSwgdGhpcy56SW5kZXgsIHRoaXMudml6Q29uZmlnPy5yZWdpb25Tb3VyY2VNaW5DaGFycywgaHR0cCk7XG4gICAgICB0aGlzLmNvbnRyaWJ1dGlvbnMuYWN0aXZhdGUoKTtcbiAgICB9LFxuICAgIHNldEltYWdlTG9hZGluZzogKGxvYWRpbmcpID0+IHRoaXMuc3RhdGUuc2V0SW1hZ2VMb2FkaW5nKGxvYWRpbmcpLFxuICAgIGFsZXJ0OiAoc2V2ZXJpdHksIHN1bW1hcnksIGRldGFpbCkgPT5cbiAgICAgIHRoaXMubWVzc2FnZVNlcnZpY2UuYWRkKHsga2V5OiB0aGlzLnZpekFsZXJ0VG9hc3RLZXksIHNldmVyaXR5LCBzdW1tYXJ5LCBkZXRhaWwgfSksXG4gICAgZGV0ZWN0Q2hhbmdlczogKCkgPT4gdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpLFxuICB9KTtcbiAgcGxvdFR5cGUgPSBQbG90VHlwZS5JTUFHRTtcbiAgcHJvdGVjdGVkIGlzSGVhdG1hcCA9IHRydWU7XG4gIHByb3RlY3RlZCBhY3RpdmVTdXJmYWNlM2RNb2RlID0gJ3R1cm50YWJsZSc7XG4gIC8qKiBXaGV0aGVyIHRoZSBuYXBhcmkgM0QgY29vcmRpbmF0ZS1heGVzIC8gc2NhbGUgZ2l6bW8gaXMgc2hvd24gKHZvbHVtZS9pc29zdXJmYWNlKS4gKi9cbiAgcHJvdGVjdGVkIGF4ZXNWaXNpYmxlID0gdHJ1ZTtcbiAgcHJvdGVjdGVkIHdpcmVmcmFtZUFjdGl2ZSA9IGZhbHNlO1xuICAvKiogbmFwYXJpIDNEIGRlY2ltYXRlIGZhY3RvciAoMSA9IEZ1bGwg4oCmIDggPSDihZs7IGRlZmF1bHQgwr0pOyBjaGFuZ2luZyBpdCByZS1wbG90cy4gKi9cbiAgcHJvdGVjdGVkIHJlc29sdXRpb25TY2FsZSA9IE5BUEFSSV9ERUZBVUxUX0RFQ0lNQVRFO1xuXG4gIC8qKiBUaGUgc2VsZWN0b3IncyBlbnRyaWVzOiB0aGUgYnVpbHQtaW4gcGxvdCB0eXBlcyB0aGUgYWN0aXZlIGJhY2tlbmRcbiAgICogIGFkdmVydGlzZXMgKDNEIGdhdGVkIGJ5IGNhcGFiaWxpdHkpLCB0aGVuIGFueSBjb250cmlidXRlZCBtb2Rlc1xuICAgKiAgKHtAbGluayBQTE9UX1RZUEVfQ09OVFJJQlVUSU9OU30pLiAqL1xuICBwcm90ZWN0ZWQgcGxvdFR5cGVNZW51OiBQbG90VHlwZU9wdGlvbltdID0gW107XG4gIC8qKlxuICAgKiBUaGUgYnVpbHQtaW4gcGxvdCB0eXBlcyBvbiBvZmZlciDigJQge0BsaW5rIHBsb3RUeXBlTWVudX0gd2l0aG91dCBjb250cmlidXRlZFxuICAgKiBtb2Rlcy4gS2VwdCB3aXRoIGl0cyBvcmlnaW5hbCB0eXBlIHNvIGV4aXN0aW5nIHJlYWRlcnMgYXJlIHVuYWZmZWN0ZWQuXG4gICAqL1xuICBwcm90ZWN0ZWQgcGxvdFR5cGVPcHRpb25zOiBQbG90VHlwZURlc2NyaXB0b3JbXSA9IFtdO1xuICAvKipcbiAgICogV2hhdCB0aGUgc2VsZWN0b3Igc2hvd3M6IGEgYnVpbHQtaW4gdHlwZSBvciBhIGNvbnRyaWJ1dGVkIG1vZGUncyBpZC4gRXZlcnlcbiAgICogcmVuZGVyaW5nIGFuZCB0b29sIGRlY2lzaW9uIGdvZXMgdGhyb3VnaCB7QGxpbmsgYmFzZVBsb3RUeXBlfSBpbnN0ZWFkLCBzbyBhXG4gICAqIGNvbnRyaWJ1dGVkIG1vZGUgYmVoYXZlcyBleGFjdGx5IGxpa2UgdGhlIGJ1aWx0LWluIHR5cGUgaXQgcmlkZXMgb24uXG4gICAqL1xuICBwcm90ZWN0ZWQgc2VsZWN0ZWRQbG90VHlwZUlkOiBQbG90VHlwZUlkID0gUGxvdFR5cGUuSU1BR0U7XG5cbiAgLyoqXG4gICAqIFRoZSBidWlsdC1pbiBwbG90IHR5cGUgYmVpbmcgcmVuZGVyZWQuIFdpdGggbm8gY29udHJpYnV0ZWQgbW9kZSBhY3RpdmUgdGhpc1xuICAgKiBpcyB0aGUgc2VsZWN0aW9uIGl0c2VsZjsgZHVyaW5nIG9uZSBpdCBpcyB0aGUgbW9kZSdzIGBiYXNlVHlwZWAuIEtlcHQgd2l0aCBpdHNcbiAgICogb3JpZ2luYWwgYFBsb3RUeXBlYCB0eXBlIGZvciBleGlzdGluZyByZWFkZXJzIOKAlCB1c2Uge0BsaW5rIHNlbGVjdGVkUGxvdFR5cGVJZH1cbiAgICogZm9yIHRoZSBzZWxlY3RvcidzIGlkLiBBc3NpZ25pbmcgc2VsZWN0cyB0aGF0IGJ1aWx0LWluIHR5cGUuXG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IHNlbGVjdGVkUGxvdFR5cGUoKTogUGxvdFR5cGUge1xuICAgIHJldHVybiB0aGlzLmJhc2VQbG90VHlwZTtcbiAgfVxuICBwcm90ZWN0ZWQgc2V0IHNlbGVjdGVkUGxvdFR5cGUodHlwZTogUGxvdFR5cGUpIHtcbiAgICB0aGlzLnNlbGVjdGVkUGxvdFR5cGVJZCA9IHR5cGU7XG4gIH1cblxuICAvKiogQ29udHJpYnV0ZWQgcGxvdCBtb2RlcyBhbmQgdGhlaXIgc2luZ2xlIGxpdmUgc2Vzc2lvbi4gKi9cbiAgZ2V0IHBsb3RNb2RlcygpOiBQbG90TW9kZUNvbnRyb2xsZXIge1xuICAgIHJldHVybiB0aGlzLmNvbnRyaWJ1dGlvbnMucGxvdE1vZGVzO1xuICB9XG4gIC8qKiBUaGUgbGl2ZSBjb250cmlidXRlZCBtb2RlJ3Mgc2lkZSBwYW5lbDsgbnVsbCB3aGlsZSBubyBjb250cmlidXRlZCBzZXNzaW9uIGlzIGxpdmUuICovXG4gIHByb3RlY3RlZCBnZXQgcGxvdE1vZGVQYW5lbCgpOiBQbG90TW9kZVBhbmVsVmlldyB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLmNvbnRyaWJ1dGlvbnMucGxvdE1vZGVQYW5lbDtcbiAgfVxuXG4gIC8qKiBXaGVyZSBhIGBtb3VudGAgcGFuZWwncyBob3N0IGVsZW1lbnQgaXMgYXR0YWNoZWQgb25jZSB0aGUgZGlhbG9nIHJlbmRlcnMuICovXG4gIEBWaWV3Q2hpbGQoJ3Bsb3RNb2RlUGFuZWxTbG90JylcbiAgc2V0IHBsb3RNb2RlUGFuZWxTbG90KHJlZjogRWxlbWVudFJlZjxIVE1MRWxlbWVudD4gfCB1bmRlZmluZWQpIHtcbiAgICB0aGlzLmNvbnRyaWJ1dGlvbnMuYXR0YWNoUGFuZWxTbG90KHJlZj8ubmF0aXZlRWxlbWVudCk7XG4gIH1cblxuICAvKiogVGhlIGJ1aWx0LWluIHR5cGUgYWN0dWFsbHkgcmVuZGVyZWQgZm9yIHtAbGluayBzZWxlY3RlZFBsb3RUeXBlSWR9OiBpdHNlbGZcbiAgICogIGZvciBhIGJ1aWx0LWluIHR5cGUsIGBiYXNlVHlwZWAgZm9yIGEgY29udHJpYnV0ZWQgbW9kZS4gKi9cbiAgcHJvdGVjdGVkIGdldCBiYXNlUGxvdFR5cGUoKTogUGxvdFR5cGUge1xuICAgIHJldHVybiB0aGlzLnBsb3RNb2Rlcy5iYXNlVHlwZU9mKHRoaXMuc2VsZWN0ZWRQbG90VHlwZUlkKTtcbiAgfVxuXG4gIC8qKiBEaXYgdGhlIGZsb2F0aW5nIGludGVuc2l0eS1wcm9maWxlIGluc2V0IGlzIGNoYXJ0ZWQgaW50by4gUGVyIGluc3RhbmNlLCBsaWtlXG4gICAqICB7QGxpbmsgcGxvdERpdk5hbWV9OiB0aGUgYmFja2VuZCByZXNvbHZlcyBpdCBieSBpZCwgc28gYSBmaXhlZCBpZCBtYWRlIHR3byBsaXZlXG4gICAqICB2aWV3ZXJzIGRyYXcgYm90aCBpbnNldHMgaW50byB3aGljaGV2ZXIgZGl2IGNhbWUgZmlyc3QgaW4gdGhlIGRvY3VtZW50LiAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgaW50ZW5zaXR5SW5zZXREaXYgPSBgJHt0aGlzLnBsb3REaXZOYW1lfS1pbnNldGA7XG5cbiAgLyoqIFRvb2xiYXIgZG9ja2luZzogZG9ja2VkIGFjcm9zcyB0aGUgdG9wIGJ5IGRlZmF1bHQ7IGRyYWdnaW5nIGl0cyBoYW5kbGVcbiAgICogIGRldGFjaGVzIGl0IGludG8gYSBmbG9hdGluZywgbW92YWJsZSB3aW5kb3cgKGZyZWVzIHRoZSB0b3Agcm93IGZvciB0aGVcbiAgICogIHZpc3VhbGl6YXRpb24pLiAqL1xuICBwcm90ZWN0ZWQgdG9vbGJhckZsb2F0aW5nID0gZmFsc2U7XG4gIHByb3RlY3RlZCB0b29sYmFyUG9zID0geyB4OiA4LCB5OiA4IH07XG4gIC8qKiBXaGVyZSBhIHRvb2xiYXItaGFuZGxlIGRyYWcgc3RhcnRzIGZyb206IGdyYWJiaW5nIHRoZSBkb2NrZWQgdG9vbGJhciBmbG9hdHMgaXQuICovXG4gIHByb3RlY3RlZCByZWFkb25seSB0b29sYmFyRHJhZ09yaWdpbiA9ICgpOiBGbG9hdGluZ1BvcyA9PiB7XG4gICAgaWYgKCF0aGlzLnRvb2xiYXJGbG9hdGluZykge1xuICAgICAgdGhpcy50b29sYmFyRmxvYXRpbmcgPSB0cnVlO1xuICAgICAgdGhpcy50b29sYmFyUG9zID0geyB4OiA4LCB5OiA4IH07XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnRvb2xiYXJQb3M7XG4gIH07XG4gIC8qKiBUaGUgZmxvYXRpbmcgaW50ZW5zaXR5LXByb2ZpbGUgaW5zZXQgKGFsd2F5cyBtb3VudGVkOyBzaG93cyBpdHNlbGYgd2hpbGUgbGluZXMgZXhpc3QpLiAqL1xuICBAVmlld0NoaWxkKEludGVuc2l0eUluc2V0Q29tcG9uZW50LCB7IHN0YXRpYzogdHJ1ZSB9KSBpbnNldD86IEludGVuc2l0eUluc2V0Q29tcG9uZW50O1xuXG4gIC8qKiBUcnVlIHdoaWxlIHRoZSAzRCBzcGF0aWFsIGNsb3VkIGlzIHRoZSBhY3RpdmUgbW9kZS4gVGhlIGNvbnRyb2xzIGRyb3AgdGhlIFJPSVxuICAgKiAgc2VsZWN0aW9uIHRoZXJlOiByZWdpb24gdG9vbHMgYXJlIHNjcmVlbi1zcGFjZSwgYW5kIGFnYWluc3QgYW4gb3JiaXRpbmdcbiAgICogIGNhbWVyYSBhIGRyYXduIHJlY3RhbmdsZSBoYXMgbm8gZml4ZWQgbWVhbmluZyBpbiB0aGUgZGF0YS4gKi9cbiAgcHJvdGVjdGVkIGdldCBpc1NwYXRpYWwzZE1vZGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGlzU3BhdGlhbE9taWNzM2QodGhpcy5iYXNlUGxvdFR5cGUpO1xuICB9XG5cbiAgLyoqIFRydWUgaW4gYSBuYXBhcmkgdm9sdW1lIG9yIGlzb3N1cmZhY2Ugdmlldywgd2hlcmUgdGhlIFJlZ2lvbiBFZGl0b3Igc2hvd3MgcmVnaW9ucyBpbiAzRC4gKi9cbiAgcHJvdGVjdGVkIGdldCBpc1ZvbHVtZVZpZXcoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGlzTmFwYXJpVm9sdW1lKHRoaXMuYmFzZVBsb3RUeXBlKSB8fCBpc05hcGFyaUlzb3N1cmZhY2UodGhpcy5iYXNlUGxvdFR5cGUpO1xuICB9XG5cbiAgLyoqIFdoZXRoZXIgdGhlIHVzZXIgc3BsaXQgdGhlIHZvbHVtZSB2aWV3IHdpdGggdGhlIHNsaWNlIGVkaXRvciAob2ZmIGJ5IGRlZmF1bHQ7IGtlcHQgd2hpbGVcbiAgICogIHRoZSB2aWV3IHNob3dzIG90aGVyIHBsb3QgdHlwZXMsIHNvIGEgdm9sdW1lIHZpZXcgb3BlbnMgc3BsaXQgYWdhaW4pLiAqL1xuICBwcm90ZWN0ZWQgc2xpY2VFZGl0b3IgPSBmYWxzZTtcbiAgLyoqIFRoZSBzbGljZSBlZGl0b3IncyBwYW5lOiB0aGUgZGlzcGxheWVkIHNsaWNlLCB3aXRoIGV2ZXJ5IHJlZ2lvbiB0b29sLCB0b3AgcmlnaHQuICovXG4gIHByb3RlY3RlZCByZWFkb25seSBzbGljZURpdk5hbWUgPSBgJHt0aGlzLnBsb3REaXZOYW1lfS1zbGljZWA7XG4gIC8qKiBUaGUgbGVmdCBjb2x1bW4ncyBhbmQgdGhlIHRvcCByb3cncyBzaGFyZXMgb2YgdGhlIHNsaWNlIGVkaXRvciAoJSkuICovXG4gIHByb3RlY3RlZCBzcGxpdFggPSA1MDtcbiAgcHJvdGVjdGVkIHNwbGl0WSA9IDUwO1xuICAvKiogVGhlIHNlY3Rpb25zIHRocm91Z2ggeCBhbmQgeSBzaG93biBiZWxvdyAobnVsbHMgdW50aWwgdGhlIHZvbHVtZSBpcyBjdXQpLiAqL1xuICBwcm90ZWN0ZWQgc2VjdGlvbnM6IFNlY3Rpb25WaWV3cyA9IHsgeDogbnVsbCwgeTogbnVsbCB9O1xuICBwcm90ZWN0ZWQgZ2V0IHNsaWNlRWRpdG9yU2hvd24oKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuc2xpY2VFZGl0b3IgJiYgdGhpcy5pc1ZvbHVtZVZpZXc7XG4gIH1cblxuICAvKipcbiAgICogU3BsaXQgdGhlIHZvbHVtZSB2aWV3IHdpdGggdGhlIHNsaWNlIGVkaXRvciwgb3IgY2xvc2UgaXQuIFRoZSBlZGl0b3Igb3BlbnMgb24gdGhlIGRpc3BsYXllZFxuICAgKiBzbGljZSBhbmQgdGFrZXMgdGhlIGRyYXdpbmcgdG9vbHM7IGNsb3NpbmcgaXQgbGVhdmVzIHRoZSBzZWxlY3Rpb24gdG9vbCBhcm1lZCAoaXQgcGlja3MgdGhlXG4gICAqIHN1cmZhY2VzIGluIDNEKSBhbmQgZGlzYXJtcyBhbnkgb3RoZXIuXG4gICAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgdG9nZ2xlU2xpY2VFZGl0b3IoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgdGhpcy5zbGljZUVkaXRvciA9ICF0aGlzLnNsaWNlRWRpdG9yO1xuICAgIHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKTsgLy8gdGhlIHBhbmUncyBkaXYsIGJlZm9yZSB0aGUgYmFja2VuZCBsb29rcyBpdCB1cFxuICAgIHRoaXMucGxvdFNlcnZpY2UucmVsYXlvdXQoKTsgLy8gdGhlIDNEIHZpZXcgaXMgYSBxdWFydGVyIG9mIHRoZSBhcmVhIG5vdywgb3IgYWxsIG9mIGl0IGFnYWluXG4gICAgaWYgKCF0aGlzLnNsaWNlRWRpdG9yKSB7XG4gICAgICBhd2FpdCB0aGlzLnBsb3RTZXJ2aWNlLnNldFNsaWNlRWRpdG9yPy4obnVsbCk7XG4gICAgICBpZiAodGhpcy50b29scy5hY3RpdmUgIT09IG51bGwgJiYgdGhpcy50b29scy5hY3RpdmUgIT09ICdzZWxlY3QnKSB0aGlzLnRvb2xzLmFwcGx5KG51bGwpO1xuICAgICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIFRoZSByZWdpb25zIGVkaXRlZCBhcmUgdGhlIGRpc3BsYXllZCBzbGljZSdzLlxuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0RGlzcGxheVNsaWNlKHRoaXMuekluZGV4KTtcbiAgICBjb25zdCBzaG93biA9IGF3YWl0IHRoaXMucGxvdFNlcnZpY2Uuc2V0U2xpY2VFZGl0b3I/Lih0aGlzLnNsaWNlRGl2TmFtZSk7XG4gICAgLy8gVGhlIGFybWVkIHRvb2wgbm93IGFjdHMgaW4gdGhlIHBhbmUuXG4gICAgaWYgKHNob3duICYmIHRoaXMudG9vbHMuYWN0aXZlICE9PSBudWxsKSB0aGlzLnRvb2xzLmFwcGx5KHRoaXMudG9vbHMuYWN0aXZlKTtcbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfVxuXG4gIC8qKiBBIHBvaW50IHBpY2tlZCBpbiBhIHNlY3Rpb246IHRoZSBzbGljZSBhbmQgdGhlIG90aGVyIHNlY3Rpb24ncyBwbGFuZSBtb3ZlIHRoZXJlLiAqL1xuICBwcm90ZWN0ZWQgb25TZWN0aW9uUGljayhheGlzOiBTZWN0aW9uQXhpcywgYXQ6IHsgdTogbnVtYmVyOyB2OiBudW1iZXIgfSk6IHZvaWQge1xuICAgIC8vIFRocm91Z2ggeCwgYWNyb3NzIGlzIHRoZSBzbGljZSBhbmQgZG93biBpcyB5OyB0aHJvdWdoIHksIGFjcm9zcyBpcyB4IGFuZCBkb3duIHRoZSBzbGljZS5cbiAgICBjb25zdCBzbGljZSA9IE1hdGguZmxvb3IoYXhpcyA9PT0gJ3gnID8gYXQudSA6IGF0LnYpO1xuICAgIGlmIChheGlzID09PSAneCcpIHRoaXMucGxvdFNlcnZpY2Uuc2V0U2VjdGlvblBsYW5lPy4oJ3knLCBhdC52KTtcbiAgICBlbHNlIHRoaXMucGxvdFNlcnZpY2Uuc2V0U2VjdGlvblBsYW5lPy4oJ3gnLCBhdC51KTtcbiAgICB0aGlzLm9uWlNsaWRlKE1hdGgubWluKHRoaXMubWF4SW5kZXgsIE1hdGgubWF4KDAsIHNsaWNlKSkpO1xuICB9XG5cbiAgLyoqIERyYWcgYSBkaXZpZGVyIG9mIHRoZSBzbGljZSBlZGl0b3I6IHRoZSB2ZXJ0aWNhbCBvbmUgc2V0cyB0aGUgY29sdW1ucywgdGhlIGhvcml6b250YWwgb25lIHRoZSByb3dzLiAqL1xuICBwcm90ZWN0ZWQgc3RhcnRQYW5lUmVzaXplKGV2ZW50OiBQb2ludGVyRXZlbnQsIGF4aXM6ICd4JyB8ICd5Jyk6IHZvaWQge1xuICAgIGNvbnN0IGRpdmlkZXIgPSBldmVudC5jdXJyZW50VGFyZ2V0IGFzIEhUTUxFbGVtZW50O1xuICAgIGNvbnN0IHBhbmVzID0gZGl2aWRlci5wYXJlbnRFbGVtZW50O1xuICAgIGlmICghcGFuZXMpIHJldHVybjtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGRpdmlkZXIuc2V0UG9pbnRlckNhcHR1cmUoZXZlbnQucG9pbnRlcklkKTtcbiAgICBjb25zdCBtb3ZlID0gKGU6IFBvaW50ZXJFdmVudCkgPT4ge1xuICAgICAgY29uc3QgYm94ID0gcGFuZXMuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBpZiAoYXhpcyA9PT0gJ3gnICYmIGJveC53aWR0aCA+IDApIHRoaXMuc2V0U3BsaXQoJ3gnLCAoKGUuY2xpZW50WCAtIGJveC5sZWZ0KSAvIGJveC53aWR0aCkgKiAxMDApO1xuICAgICAgaWYgKGF4aXMgPT09ICd5JyAmJiBib3guaGVpZ2h0ID4gMCkgdGhpcy5zZXRTcGxpdCgneScsICgoZS5jbGllbnRZIC0gYm94LnRvcCkgLyBib3guaGVpZ2h0KSAqIDEwMCk7XG4gICAgfTtcbiAgICBjb25zdCBlbmQgPSAoKSA9PiB7XG4gICAgICBkaXZpZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJtb3ZlJywgbW92ZSk7XG4gICAgICBkaXZpZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJ1cCcsIGVuZCk7XG4gICAgICBkaXZpZGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJjYW5jZWwnLCBlbmQpO1xuICAgIH07XG4gICAgZGl2aWRlci5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVybW92ZScsIG1vdmUpO1xuICAgIGRpdmlkZXIuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcnVwJywgZW5kKTtcbiAgICBkaXZpZGVyLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJjYW5jZWwnLCBlbmQpO1xuICB9XG5cbiAgLyoqIEEgZGl2aWRlcidzIGtleWJvYXJkOiDihpAg4oaSIG1vdmUgdGhlIHZlcnRpY2FsIG9uZSwg4oaRIOKGkyB0aGUgaG9yaXpvbnRhbCBvbmUsIGJ5IDUlLiAqL1xuICBwcm90ZWN0ZWQgbnVkZ2VQYW5lU2l6ZShldmVudDogS2V5Ym9hcmRFdmVudCwgYXhpczogJ3gnIHwgJ3knKTogdm9pZCB7XG4gICAgY29uc3Qga2V5cyA9IGF4aXMgPT09ICd4JyA/IFsnQXJyb3dMZWZ0JywgJ0Fycm93UmlnaHQnXSA6IFsnQXJyb3dVcCcsICdBcnJvd0Rvd24nXTtcbiAgICBjb25zdCBzdGVwID0gZXZlbnQua2V5ID09PSBrZXlzWzBdID8gLTUgOiBldmVudC5rZXkgPT09IGtleXNbMV0gPyA1IDogMDtcbiAgICBpZiAoIXN0ZXApIHJldHVybjtcbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpOyAvLyBub3QgYSBzbGljZSBzdGVwXG4gICAgdGhpcy5zZXRTcGxpdChheGlzLCAoYXhpcyA9PT0gJ3gnID8gdGhpcy5zcGxpdFggOiB0aGlzLnNwbGl0WSkgKyBzdGVwKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0U3BsaXQoYXhpczogJ3gnIHwgJ3knLCBwZXJjZW50OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCB2YWx1ZSA9IE1hdGgucm91bmQoTWF0aC5taW4oODAsIE1hdGgubWF4KDIwLCBwZXJjZW50KSkpO1xuICAgIGlmIChheGlzID09PSAneCcpIHRoaXMuc3BsaXRYID0gdmFsdWU7XG4gICAgZWxzZSB0aGlzLnNwbGl0WSA9IHZhbHVlO1xuICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgIC8vIFRoZSAzRCB2aWV3IGZvbGxvd3MgaXRzIGNlbGwgb25jZSB0aGUgZ3JpZCBoYXMgaXRzIG5ldyB0cmFja3MuXG4gICAgaWYgKHRoaXMucmVsYXlvdXRGcmFtZSA9PT0gbnVsbCAmJiB0eXBlb2YgcmVxdWVzdEFuaW1hdGlvbkZyYW1lICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgdGhpcy5yZWxheW91dEZyYW1lID0gcmVxdWVzdEFuaW1hdGlvbkZyYW1lKCgpID0+IHtcbiAgICAgICAgdGhpcy5yZWxheW91dEZyYW1lID0gbnVsbDtcbiAgICAgICAgdGhpcy5wbG90U2VydmljZS5yZWxheW91dCgpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIHByaXZhdGUgcmVsYXlvdXRGcmFtZTogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG5cbiAgLyoqIFRydWUgZm9yIHRoZSBJbWFnZSBwbG90IHR5cGUsIHdoaWNoIHJlbmRlcnMgYXMgYSBuYXRpdmVseSBwYW4vem9vbS1hYmxlXG4gICAqICByYXN0ZXIg4oCUIHNvIHRoZSBiYWNrZW5kLWFnbm9zdGljIHpvb20vcGFuIHRvb2xiYXIgdG9vbHMgYXJlIGhpZGRlbi4gVGhlXG4gICAqICBjb21wb25lbnQgZHJpdmVzIHRoaXMgb2ZmIHRoZSBwbG90IHR5cGUsIG5vdCB0aGUgYWN0aXZlIGJhY2tlbmQuICovXG4gIHByb3RlY3RlZCBnZXQgaXNJbWFnZVZpZXcoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuYmFzZVBsb3RUeXBlID09PSBQbG90VHlwZS5JTUFHRTtcbiAgfVxuXG4gIC8qKiBJc29zdXJmYWNlIGJhbmQgYXMgYSAw4oCTMjU1IHNsaWRlciBwb3NpdGlvbiwgbWFwcGVkIG9udG8gdGhlIHZvbHVtZSdzIHJlYWxcbiAgICogIGludGVuc2l0eSByYW5nZSBieSB0aGUgcmVuZGVyZXIuIERlZmF1bHRzIHRvIHRoZSBmdWxsIHJhbmdlLiAqL1xuICBwcm90ZWN0ZWQgaXNvUmFuZ2U6IG51bWJlcltdID0gWzAsIDI1NV07XG5cbiAgLyoqIFRoZSBzcGF0aWFsLW9taWNzIGRhdGFzZXQgb24gb2ZmZXIgYW5kIHRoZSBnYXRlcyBpdCBwdXRzIG9uIHRoZSBzZWxlY3Rvci4gKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IHNwYXRpYWw6IFNwYXRpYWxEYXRhc2V0QmluZGVyO1xuICAvKiogV2hldGhlciBhIHNwYXRpYWwtb21pY3MgZGF0YXNldCBpcyBwdWJsaXNoZWQgb24gYFNQQVRJQUxfREFUQV9QT1JUYCDigJQgZ2F0ZXMgdGhlXG4gICAqICBzcGF0aWFsIHBsb3QgdHlwZXM7IHRoZSB0b29sYmFyIG9mZmVycyB0aGUgcGxvdCBtb2RlcyBmb3IgYW4gaW1hZ2UtbGVzcyBvbmUgdG9vLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGhhc1NwYXRpYWxEYXRhc2V0KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnNwYXRpYWwuaGFzRGF0YXNldDtcbiAgfVxuXG4gIC8qKiBLZXlib2FyZCwgd2hlZWwgYW5kIGNvbnRleHQtbWVudSBoYW5kbGluZzsgY3JlYXRlZCBvbmNlIHRoZSB2aWV3IGV4aXN0cy4gKi9cbiAgcHJpdmF0ZSBzaG9ydGN1dHM/OiBWaWV3ZXJTaG9ydGN1dHM7XG4gIC8qKiBXYWl0cyBmb3IgYSB2aWV3ZXIgY3JlYXRlZCBvdXRzaWRlIHRoZSBkb2N1bWVudCB0byBiZSBhdHRhY2hlZCAoc2VlIHtAbGluayB3aGVuSW5Eb2N1bWVudH0pLiAqL1xuICBwcml2YXRlIGF0dGFjaE9ic2VydmVyOiBSZXNpemVPYnNlcnZlciB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiBEZWJvdW5jZWQgei1zbGljZSBzY3J1YmJpbmcgKHNlZSBTbGljZVNjcnViYmVyIOKAlCByZWZhY3RvcmluZyBwbGFuIFN0ZXAgNykuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgc2NydWJiZXIgPSBuZXcgU2xpY2VTY3J1YmJlcigoeikgPT4ge1xuICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0WkluZGV4KHopO1xuICAgIC8vIEluIGEgcGVyLXNsaWNlIHotc3RhY2sgc2Vzc2lvbiB0aGUgc3RvcmUgc3dhcHMgdGhlIGxpdmUgcmVnaW9uIHNldCB0byB0aGlzXG4gICAgLy8gc2xpY2UgKHByZXNlcnZpbmcgZWRpdHMgbWFkZSBvbiB0aGUgcHJldmlvdXMgb25lKTsgb3V0c2lkZSBzdGFjayBtb2RlIHRoaXNcbiAgICAvLyBqdXN0IHJlY29yZHMgdGhlIHNsaWNlLCBsZWF2aW5nIHNpbmdsZS1wbGFuZSByZWdpb25zIHVudG91Y2hlZCAoaml0LXVpIzkzKS5cbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldERpc3BsYXlTbGljZSh6KTtcbiAgfSk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgLy8gVGhlIGNvbnN0cnVjdG9yIHBhcmFtZXRlcnMgYmVsb3cgYXJlIHRoZSBpbmplY3Rpb24gcG9pbnRzOyBub25lIGlzIHB1YmxpYyBBUEkuXG4gICAgQEluamVjdChJTUFHRV9TVEFURV9QT1JUKSBwcml2YXRlIHN0YXRlOiBJbWFnZVN0YXRlUG9ydCxcbiAgICBASW5qZWN0KFZJU1VBTElaRVIpIHB1YmxpYyBwbG90U2VydmljZTogSVZpc3VhbGl6ZXIsXG4gICAgcHVibGljIG1lc3NhZ2VTZXJ2aWNlOiBNZXNzYWdlU2VydmljZSxcbiAgICBwcml2YXRlIG5nWm9uZTogTmdab25lLFxuICAgIHByaXZhdGUgY2RyOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBwcml2YXRlIHNlc3Npb246IFZpc3VhbGl6ZXJTdG9yZSxcbiAgICBwcml2YXRlIHNhbVRvb2w6IFNhbVRvb2xTZXJ2aWNlLFxuICAgIHByaXZhdGUgY2VsbFNlZ21lbnRUb29sOiBDZWxsU2VnbWVudFRvb2xTZXJ2aWNlLFxuICAgIHByaXZhdGUgc2FtUG9pbnRUb29sOiBTYW1Qb2ludFRvb2xTZXJ2aWNlLFxuICAgIHByaXZhdGUgcmVnaW9uT3BzOiBSZWdpb25PcHNTZXJ2aWNlLFxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoVklaX0NPTkZJRykgcHJpdmF0ZSB2aXpDb25maWc/OiBWaXpDb25maWcsXG4gICAgLy8gQSBjb25zdHJ1Y3RvciBwYXJhbWV0ZXIgcmF0aGVyIHRoYW4gYSBmaWVsZCBgaW5qZWN0KClgOiB0aGlzIGNvbXBvbmVudCBpc1xuICAgIC8vIGFsc28gY29uc3RydWN0ZWQgZGlyZWN0bHkgd2l0aCBgbmV3YCBpbiBpdHMgb3duIHNwZWNzLCB3aGljaCBpcyBvdXRzaWRlXG4gICAgLy8gYW4gaW5qZWN0aW9uIGNvbnRleHQgYW5kIHdvdWxkIHRocm93IE5HMDIwMyBvbiBhIGZpZWxkIGluaXRpYWxpemVyLlxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoVE9PTEJBUl9UT09MUykgdG9vbENvbnRyaWJ1dGlvbnM/OiByZWFkb25seSBUb29sYmFyQ29udHJpYnV0aW9uW10sXG4gICAgLy8gT3B0aW9uYWwgbGlrZSB0aGUgcmVzdDogYSBob3N0IHRoYXQgc2hvd3Mgb25seSBpbWFnZXMgbmV2ZXIgcHJvdmlkZXMgaXQsXG4gICAgLy8gYW5kIHRoZSBzcGF0aWFsIHBsb3QgdHlwZXMgc2ltcGx5IHN0YXkgaGlkZGVuLlxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoU1BBVElBTF9EQVRBX1BPUlQpIHByaXZhdGUgc3BhdGlhbERhdGE/OiBTcGF0aWFsRGF0YVBvcnQsXG4gICAgLy8gQ29udHJpYnV0ZWQgcGxvdCBtb2Rlcy4gTGlrZSBUT09MQkFSX1RPT0xTIHRoZSB0b2tlbiBoYXMgbm8gZmFjdG9yeSwgc28gYVxuICAgIC8vIGhvc3QgdGhhdCBwcm92aWRlcyBub25lIGdldHMgbnVsbCBoZXJlIGFuZCB0aGUgc2VsZWN0b3IgaXMgdW5jaGFuZ2VkLlxuICAgIEBPcHRpb25hbCgpIEBJbmplY3QoUExPVF9UWVBFX0NPTlRSSUJVVElPTlMpIHBsb3RUeXBlQ29udHJpYnV0aW9ucz86IHJlYWRvbmx5IFBsb3RUeXBlQ29udHJpYnV0aW9uW10sXG4gICAgLy8gUGFyZW50IG9mIGEgY29udHJpYnV0ZWQgcGFuZWwgY29tcG9uZW50J3MgaW5qZWN0b3IuIE9wdGlvbmFsIG9ubHkgc28gdGhlXG4gICAgLy8gc3BlY3MgY2FuIGNvbnN0cnVjdCB0aGlzIGNvbXBvbmVudCB3aXRoIGBuZXdgLlxuICAgIEBPcHRpb25hbCgpIHByaXZhdGUgaW5qZWN0b3I/OiBJbmplY3RvcixcbiAgICAvLyBUaGUgYDx2aXN1YWxpemVyPmAgZWxlbWVudDoga2V5Ym9hcmQgc2hvcnRjdXRzIGFyZSBzY29wZWQgdG8gaXQgKENPUkUtMikuXG4gICAgQE9wdGlvbmFsKCkgcHJpdmF0ZSBob3N0UmVmPzogRWxlbWVudFJlZjxIVE1MRWxlbWVudD4sXG4gICAgLy8gRW5kcyB0aGUgc3Vic2NyaXB0aW9ucyAoYHRha2VVbnRpbERlc3Ryb3llZGApLiBBIHBhcmFtZXRlciwgbGlrZSB0aGUgcmVzdCwgc28gdGhlXG4gICAgLy8gc3BlY3MnIGBuZXdgIGNhbiBwYXNzIG9uZTsgQW5ndWxhciBhbHdheXMgcHJvdmlkZXMgaXQuXG4gICAgcHJpdmF0ZSByZWFkb25seSBkZXN0cm95UmVmOiBEZXN0cm95UmVmID0gdW5kZWZpbmVkIGFzIHVua25vd24gYXMgRGVzdHJveVJlZixcbiAgKSB7XG4gICAgdGhpcy5jb250cmlidXRlZFRvb2xzID0gdmlzaWJsZVRvb2xDb250cmlidXRpb25zKHRvb2xDb250cmlidXRpb25zKTtcbiAgICB0aGlzLnRvb2xQYXJhbXMgPSBuZXcgVG9vbFBhcmFtc01vZGVsKHRoaXMuY29udHJpYnV0ZWRUb29scyk7XG4gICAgdGhpcy5jb250cmlidXRpb25zID0gbmV3IENvbnRyaWJ1dGlvbkhvc3QocGxvdFR5cGVDb250cmlidXRpb25zLCB0b29sQ29udHJpYnV0aW9ucywge1xuICAgICAgdmlzdWFsaXplcjogdGhpcy5wbG90U2VydmljZSxcbiAgICAgIHpvbmU6IHRoaXMubmdab25lLFxuICAgICAgdG9vbHM6IHRoaXMudG9vbHMucGxvdE1vZGVUb29scyxcbiAgICAgIGluamVjdG9yOiB0aGlzLmluamVjdG9yLFxuICAgICAgaW1hZ2VJbmZvJDogKCkgPT4gdGhpcy5zdGF0ZS5nZXRJbWFnZUluZm8kKCksXG4gICAgICBzZWxlY3RlZElkOiAoKSA9PiB0aGlzLnNlbGVjdGVkUGxvdFR5cGVJZCxcbiAgICAgIHJlbmRlcmVkVHlwZTogKCkgPT4gdGhpcy5wbG90VHlwZSxcbiAgICAgIHNlbGVjdEJhc2U6IChiYXNlKSA9PiB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWRQbG90VHlwZUlkID0gYmFzZTtcbiAgICAgICAgdGhpcy5wbG90VHlwZSA9IGJhc2U7XG4gICAgICB9LFxuICAgICAgbm90aWZ5OiAobSkgPT4gdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoeyBrZXk6IHRoaXMucmVzdWx0VG9hc3RLZXksIC4uLm0gfSksXG4gICAgICBkZXRlY3RDaGFuZ2VzOiAoKSA9PiB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCksXG4gICAgfSk7XG4gICAgdGhpcy5zcGF0aWFsID0gbmV3IFNwYXRpYWxEYXRhc2V0QmluZGVyKHRoaXMuc3BhdGlhbERhdGEsIHtcbiAgICAgIGdhdGVzQ2hhbmdlZDogKCkgPT4gdGhpcy5jb21wdXRlUGxvdFR5cGVPcHRpb25zKCksXG4gICAgICBzZWxlY3RlZElkOiAoKSA9PiB0aGlzLnNlbGVjdGVkUGxvdFR5cGVJZCxcbiAgICAgIGJhc2VQbG90VHlwZTogKCkgPT4gdGhpcy5iYXNlUGxvdFR5cGUsXG4gICAgICBoYXNJbWFnZTogKCkgPT4gISF0aGlzLmltYWdlSW5mbyxcbiAgICAgIHNlbGVjdFBsb3RUeXBlOiAodHlwZSkgPT4gdGhpcy5vblNlbGVjdFBsb3RUeXBlKHR5cGUpLFxuICAgICAgcmVwbG90OiAoKSA9PiB0aGlzLnJlbG9hZEFuZFBsb3QoKSxcbiAgICAgIHB1Ymxpc2hJbWFnZTogKGluZm8pID0+IHRoaXMuc3RhdGUuc2V0SW1hZ2VJbmZvKGluZm8pLFxuICAgICAgc2V0SW1hZ2VMb2FkaW5nOiAobG9hZGluZykgPT4gdGhpcy5zdGF0ZS5zZXRJbWFnZUxvYWRpbmcobG9hZGluZyksXG4gICAgICBzZXR0bGVkOiAoKSA9PiB7XG4gICAgICAgIHRoaXMucmVjb25jaWxlU2VsZWN0ZWRQbG90VHlwZSgpO1xuICAgICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICAgIH0sXG4gICAgICBkZXRlY3RDaGFuZ2VzOiAoKSA9PiB0aGlzLmNoYW5nZWQoKSxcbiAgICB9KTtcbiAgICB0aGlzLmNvbXB1dGVQbG90VHlwZU9wdGlvbnMoKTtcbiAgfVxuXG4gIC8qKiBGb2xsb3cgdGhlIHNwYXRpYWwtb21pY3MgZGF0YXNldDogYSBkYXRhc2V0IGFwcGVhcmluZywgc3dpdGNoaW5nIG9yIGJlaW5nIGNsZWFyZWRcbiAgICogIHJlLWdhdGVzIHRoZSBzZWxlY3RvciBleGFjdGx5IGFzIHRoZSBpbWFnZSBzdHJlYW0gYW5kIHRoZSB0ZXN0LW1vZGUgdG9nZ2xlIGRvLiAqL1xuICBwcml2YXRlIHdhdGNoU3BhdGlhbERhdGFzZXQoKTogdm9pZCB7XG4gICAgdGhpcy5zcGF0aWFsLmJpbmQodGhpcy5kZXN0cm95ZWQkKTtcbiAgfVxuXG4gIC8qKiBSZWNvbXB1dGUgdGhlIHNlbGVjdG9yJ3MgZW50cmllcyBmb3IgdGhlIGN1cnJlbnQgaW1hZ2UsIGRhdGFzZXQgYW5kIHRlc3QgbW9kZVxuICAgKiAgKHNlZSB7QGxpbmsgY29tcHV0ZVBsb3RUeXBlTWVudX0pLiAqL1xuICBwcml2YXRlIGNvbXB1dGVQbG90VHlwZU9wdGlvbnMoKSB7XG4gICAgY29uc3QgeyBidWlsdEluLCBtZW51IH0gPSBjb21wdXRlUGxvdFR5cGVNZW51KHtcbiAgICAgIGRlc2NyaXB0b3JzOiB0aGlzLnBsb3RTZXJ2aWNlLmdldFBsb3RUeXBlRGVzY3JpcHRvcnMoKSxcbiAgICAgIGNvbnRyaWJ1dGlvbnM6IHRoaXMucGxvdE1vZGVzLmRlc2NyaXB0b3JzKCksXG4gICAgICBjYXBzOiB0aGlzLnBsb3RTZXJ2aWNlLmNhcGFiaWxpdGllcyxcbiAgICAgIGltYWdlSW5mbzogdGhpcy5pbWFnZUluZm8sXG4gICAgICBzcGF0aWFsOiB0aGlzLnNwYXRpYWwsXG4gICAgICB0ZXN0TW9kZTogdGhpcy50ZXN0TW9kZSxcbiAgICB9KTtcbiAgICB0aGlzLnBsb3RUeXBlT3B0aW9ucyA9IGJ1aWx0SW47XG4gICAgdGhpcy5wbG90VHlwZU1lbnUgPSBtZW51O1xuICB9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIC8vIFRoZSBjb25zdHJ1Y3RvciBjb21wdXRlcyB0aGUgb3B0aW9ucyB3aXRoIHRlc3RNb2RlIHN0aWxsIGF0IGl0cyBkZWZhdWx0O1xuICAgIC8vIHJlY29tcHV0ZSBvbmNlIHRoZSBob3N0IGJpbmRzIGl0IChhbmQgb24gYW55IGxhdGVyIGNoYW5nZSkgc28gdGhlIHNlbGVjdG9yXG4gICAgLy8gcmVmbGVjdHMgdGVzdCBtb2RlIGltbWVkaWF0ZWx5LCB3aXRob3V0IHdhaXRpbmcgZm9yIGFuIGltYWdlIHRvIChyZSlsb2FkLlxuICAgIGlmIChjaGFuZ2VzWyd0ZXN0TW9kZSddKSB7XG4gICAgICB0aGlzLmNvbXB1dGVQbG90VHlwZU9wdGlvbnMoKTtcbiAgICAgIC8vIElmIHRlc3QgbW9kZSBpcyB0dXJuZWQgb2ZmIHdoaWxlIGEgdGVzdC1vbmx5IHR5cGUgKGUuZy4gTkFQQVJJX0lNQUdFKSBpc1xuICAgICAgLy8gYWN0aXZlLCB0aGF0IHR5cGUgaXMgbm8gbG9uZ2VyIG9mZmVyZWQg4oCUIGZhbGwgYmFjayB0byBJbWFnZS5cbiAgICAgIHRoaXMucmVjb25jaWxlU2VsZWN0ZWRQbG90VHlwZSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgaG9zdCBwdWJsaXNoZWQgTk8gaW1hZ2Ug4oCUIGEgc3BhdGlhbCBkYXRhc2V0IHRoYXQgYnJpbmdzIG5vbmUgZG9lcyB0aGlzLlxuICAgKlxuICAgKiBXaXRob3V0IGhhbmRsaW5nIHRoZSBlbXB0eSBlbWlzc2lvbiwgYGltYWdlSW5mb2Aga2VlcHMgdGhlIExBU1QgaW1hZ2UncyBtZXRhZGF0YTogdGhlXG4gICAqIHNlbGVjdG9yIGdvZXMgb24gb2ZmZXJpbmcgcGl4ZWwgbW9kZXMgZm9yIHBpeGVscyB0aGF0IGFyZSBnb25lLCBhbmQgZXZlcnlcbiAgICogYGlzU3RhY2tgL2Bpc0dyYXlzY2FsZWAgZGVjaXNpb24gaXMgbWFkZSBhZ2FpbnN0IGEgZmlsZSB0aGF0IGlzIG5vIGxvbmdlciBsb2FkZWQuXG4gICAqL1xuICBwcml2YXRlIG9uSW1hZ2VDbGVhcmVkKCk6IHZvaWQge1xuICAgIC8vIFRoZSBpbWFnZSBhIGNvbnRyaWJ1dGVkIG1vZGUgd2FzIGRyYXdpbmcgb3ZlciBpcyBnb25lLiBBbiBvcGVuIGRpYWxvZ1xuICAgIC8vIHRvb2wgc3RheXMgb3BlbiBhbmQgcmVzdGFydHMgb25jZSB0aGUgbmV4dCBpbWFnZSBoYXMgcGxvdHRlZC5cbiAgICB0aGlzLmNvbnRyaWJ1dGlvbnMuZW5kU2Vzc2lvbnMoKTtcbiAgICB0aGlzLmltYWdlSW5mbyA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmxvYWRlZEZpbGVOYW1lID0gdW5kZWZpbmVkO1xuICAgIHRoaXMuY29tcHV0ZVBsb3RUeXBlT3B0aW9ucygpO1xuICAgIC8vIERlbGliZXJhdGVseSBOT1QgcmVjb25jaWxpbmcgdGhlIHNlbGVjdGVkIHR5cGUgaGVyZS4gUmVjb25jaWxpbmcgY2FsbHNcbiAgICAvLyBgc2V0UGxvdFR5cGVgLCB3aGljaCBkcml2ZXMgYSByZS1wbG90IOKAlCBhbmQgdGhlcmUgaXMgbm90aGluZyB0byBwbG90LCBzbyB0aGVcbiAgICAvLyBQbG90bHkgYmFja2VuZCByZWFkIGl0cyBvd24gbm93LXVuc2V0IGBpbWFnZUluZm9gIGFuZCB0aHJld1xuICAgIC8vIChcImNhbid0IGFjY2VzcyBwcm9wZXJ0eSBpc0dyYXlzY2FsZVwiKSwgYWJvcnRpbmcgdGhlIGxvYWQgd2l0aCBubyBvYnNlcnZhdGlvbnNcbiAgICAvLyBkcmF3bi4gSWdub3JpbmcgdGhlIGVtcHR5IGVtaXNzaW9uIGVudGlyZWx5IGlzIHdoYXQgdXNlZCB0byBhdm9pZCB0aGF0LlxuICAgIC8vXG4gICAgLy8gTm90aGluZyBpcyBsZWZ0IHN0cmFuZGVkOiBhbiBpbWFnZSBpcyBjbGVhcmVkIGJlY2F1c2UgYSBzcGF0aWFsIGRhdGFzZXQgdGhhdFxuICAgIC8vIGJyaW5ncyBub25lIGlzIGJlaW5nIG9wZW5lZCwgYW5kIHRoYXQgZGF0YXNldCdzIG93biBzdWJzY3JpcHRpb24gc2VsZWN0cyB0aGVcbiAgICAvLyBtb2RlIGl0cyBjb29yZGluYXRlcyBzdXBwb3J0IGEgbW9tZW50IGxhdGVyLlxuICAgIHRoaXMuY2hhbmdlZCgpO1xuICB9XG5cbiAgLyoqIElmIHRoZSBhY3RpdmUgcGxvdCB0eXBlIGlzIG5vIGxvbmdlciBpbiB0aGUgb2ZmZXJlZCBvcHRpb25zIChlLmcuIHRlc3QgbW9kZVxuICAgKiAgdHVybmVkIG9mZiB3aGlsZSBhIHRlc3Qtb25seSB0eXBlIHdhcyBhY3RpdmUsIG9yIGEgc2NhbGFyIHR5cGUgY2FycmllZCBvbnRvXG4gICAqICBhbiBSR0IgaW1hZ2UpLCBmYWxsIGJhY2sgdG8gdGhlIGRlZmF1bHQgMkQgSW1hZ2Ugdmlldy4gKi9cbiAgcHJpdmF0ZSByZWNvbmNpbGVTZWxlY3RlZFBsb3RUeXBlKCk6IHZvaWQge1xuICAgIGNvbnN0IGZhbGxiYWNrID0gcmVjb25jaWxlUGxvdFR5cGUodGhpcy5wbG90VHlwZU1lbnUsIHRoaXMuc2VsZWN0ZWRQbG90VHlwZUlkKTtcbiAgICBpZiAoIWZhbGxiYWNrKSByZXR1cm47XG4gICAgLy8gTGVhdmluZyBhIGNvbnRyaWJ1dGVkIG1vZGUgKGl0cyBnYXRlcyBzdG9wcGVkIHBhc3NpbmcsIG9yIGl0cyBwcm92aWRlciBpc1xuICAgIC8vIGdvbmUpOiBpdHMgc2Vzc2lvbiBlbmRzIGJlZm9yZSBhbnl0aGluZyBlbHNlIGRyYXdzLlxuICAgIHRoaXMucGxvdE1vZGVzLmRlYWN0aXZhdGUoKTtcbiAgICBjb25zdCBiYXNlID0gdGhpcy5wbG90TW9kZXMuYmFzZVR5cGVPZihmYWxsYmFjayk7XG4gICAgaWYgKGJhc2UgIT09IFBsb3RUeXBlLklNQUdFKSB0aGlzLmNsb3NlRGlhbG9nVG9vbCgpO1xuICAgIHRoaXMuc2VsZWN0ZWRQbG90VHlwZUlkID0gZmFsbGJhY2s7XG4gICAgdGhpcy5wbG90VHlwZSA9IGJhc2U7XG4gICAgdGhpcy5pc0hlYXRtYXAgPSBiYXNlID09PSBQbG90VHlwZS5JTUFHRTtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldFBsb3RUeXBlKGJhc2UpO1xuICB9XG5cbiAgbmdPbkluaXQoKTogdm9pZCB7XG4gICAgLy8gSm9pbiB0aGUgbGl2ZSBzZXQ7IHRoZSBvbGRlc3QgbWVtYmVyIHJlbmRlcnMgdGhlIHNoYXJlZCBub3RpY2Ugb3V0bGV0cy5cbiAgICBWaXN1YWxpemVyQ29tcG9uZW50LmxpdmVJbnN0YW5jZXMuYWRkKHRoaXMpO1xuICAgIHRoaXMuc3RhdGUuc2V0RGlhZ3JhbSh0aGlzLmhvc3RIYW5kbGUpO1xuICAgIHRoaXMud2F0Y2hTcGF0aWFsRGF0YXNldCgpO1xuICAgIC8vIE9TRCBhbmQgbmFwYXJpLWpzIGVtaXQgdGhpcyBmcm9tIHRoZWlyIG93biBcImZpdCB0byB2aWV3XCI6IGRpc2FybSB0aGUgdG9vbCBvblxuICAgIC8vIHRoZSBiYWNrZW5kIHRvbywgbm90IG9ubHkgdGhlIHRvb2xiYXIncyBoaWdobGlnaHQuXG4gICAgdGhpcy5wbG90U2VydmljZVxuICAgICAgLmdldEF1dG9zY2FsZUV2ZW50KClcbiAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLmRlc3Ryb3lSZWYpKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB0aGlzLnRvb2xzLmFwcGx5KG51bGwpKTtcbiAgICAvLyBMb2FkaW5nL292ZXJsYXkgVUkgbWlycm9ycyAoc2lnbmFsczogdGhleSByZS1yZW5kZXIgdGhlIHZpZXcgdGhlbXNlbHZlcykuXG4gICAgdGhpcy5taXJyb3IodGhpcy5zdGF0ZS5pc0ltYWdlTG9hZGluZyQoKSwgKHYpID0+IHRoaXMuaW1nTG9hZGluZy5zZXQodikpO1xuICAgIHRoaXMubWlycm9yKHRoaXMucGxvdFNlcnZpY2UuZ2V0U3RhY2tMb2FkaW5nUHJvZ3Jlc3MoKSwgKHYpID0+IHRoaXMubG9hZGluZ1BlcmNlbnRhZ2Uuc2V0KHYpKTtcbiAgICB0aGlzLm1pcnJvcih0aGlzLnBsb3RTZXJ2aWNlLmlzU3RhY2tMb2FkaW5nKCksICh2KSA9PiB0aGlzLnN0YWNrTG9hZGluZy5zZXQodikpO1xuICAgIC8vIFRoZSBzbGljZSBlZGl0b3I6IGl0cyBzZWN0aW9ucywgYW5kIHRoZSBzbGljZSBwaWNrZWQgYnkgZHJhZ2dpbmcgdGhlIHogcGxhbmUgaW4gdGhlIHZvbHVtZS5cbiAgICBjb25zdCBzZWN0aW9ucyQgPSB0aGlzLnBsb3RTZXJ2aWNlLmdldFNlY3Rpb25WaWV3cyQ/LigpO1xuICAgIGlmIChzZWN0aW9ucyQpIHtcbiAgICAgIHRoaXMubWlycm9yKHNlY3Rpb25zJCwgKHYpID0+IHtcbiAgICAgICAgdGhpcy5zZWN0aW9ucyA9IHY7XG4gICAgICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIGNvbnN0IHNsaWNlRHJhZyQgPSB0aGlzLnBsb3RTZXJ2aWNlLmdldFNsaWNlRHJhZyQ/LigpO1xuICAgIGlmIChzbGljZURyYWckKSB7XG4gICAgICB0aGlzLm1pcnJvcihzbGljZURyYWckLCAoeikgPT4ge1xuICAgICAgICB0aGlzLm9uWlNjcnViKE1hdGgubWluKHRoaXMubWF4SW5kZXgsIE1hdGgubWF4KDAsIHopKSk7XG4gICAgICAgIC8vIEZyb20gYSBET00gbGlzdGVuZXIsIG5vdCBhIHRlbXBsYXRlIGV2ZW50OiB0aGUgc2xpZGVyIGFuZCBiYWRnZSBtdXN0IGJlIG1hcmtlZCB0byBmb2xsb3cuXG4gICAgICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMubWlycm9yKHRoaXMuc3RhdGUuZ2V0SW1hZ2VMb2FkaW5nTWVzc2FnZSQoKSwgKHYpID0+IHRoaXMubG9hZGluZ01lc3NhZ2Uuc2V0KHYpKTtcbiAgICB0aGlzLm1pcnJvcih0aGlzLnN0YXRlLmdldENhY2hlUHJvZ3Jlc3MkKCksICh2KSA9PiB0aGlzLmNhY2hlUHJvZ3Jlc3Muc2V0KHYpKTtcbiAgICB0aGlzLm1pcnJvcih0aGlzLnN0YXRlLmlzWm9vbSQoKSwgKHYpID0+IHRoaXMuem9vbS5zZXQodikpO1xuICAgIHRoaXMubWlycm9yKHRoaXMuc3RhdGUuZ2V0RmlsZW5hbWUkKCksICh2KSA9PiB7XG4gICAgICBpZiAodikgdGhpcy5maWxlTmFtZSA9IHY7XG4gICAgfSk7XG4gICAgdGhpcy5yZWdpb25BY3Rpb25zLmJpbmQodGhpcy5kZXN0cm95ZWQkLCAoKSA9PiB0aGlzLmNoYW5nZWQoKSk7XG4gICAgdGhpcy5zZWdtZW50YXRpb24uYmluZFBvaW50VG9vbCh0aGlzLnNhbVBvaW50VG9vbCwgdGhpcy5kZXN0cm95ZWQkKTtcbiAgICB0aGlzLm1pcnJvcih0aGlzLnN0YXRlLmdldFBhbmVsV2lkdGgkKCksICgpID0+IHtcbiAgICAgIHRoaXMucGxvdFNlcnZpY2UucmVsYXlvdXQoKTtcbiAgICAgIC8vIFRoZSBpbnRlbnNpdHkgaW5zZXQgaXMgYSBzZXBhcmF0ZSBjaGFydCBpbiBhIGZsb2F0aW5nIHBhbmVsOyByZWZsb3cgaXQgdG9vLlxuICAgICAgdGhpcy5pbnNldD8ucmVmbG93KCk7XG4gICAgfSk7XG4gICAgdGhpcy5zdGF0ZVxuICAgICAgLmdldEltYWdlSW5mbyQoKVxuICAgICAgLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuZGVzdHJveVJlZikpXG4gICAgICAuc3Vic2NyaWJlKHtcbiAgICAgICAgbmV4dDogKGltZ0luZm8pID0+IHtcbiAgICAgICAgICBpZiAoIWltZ0luZm8pIHtcbiAgICAgICAgICAgIHRoaXMub25JbWFnZUNsZWFyZWQoKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG4gICAgICAgICAgLy8gVGhlIHNlbGVjdG9yLCB0aGUgc3RhY2sgY29udHJvbHMgYW5kIHRoZSBpbnNldCBhbGwgZm9sbG93IHRoZSBpbWFnZS5cbiAgICAgICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICAgICAgICBpZiAoaW1nSW5mbykge1xuICAgICAgICAgICAgdGhpcy5pbWFnZUluZm8gPSBpbWdJbmZvO1xuICAgICAgICAgICAgLy8gU3RhY2stb25seSBwbG90IHR5cGVzIChpc29zdXJmYWNlLCBzY2F0dGVyM2QpIGRlcGVuZCBvbiB3aGV0aGVyIHRoaXNcbiAgICAgICAgICAgIC8vIGZpbGUgaXMgYSBzdGFjayDigJQgcmVjb21wdXRlIHRoZSBzZWxlY3RvciBvcHRpb25zLlxuICAgICAgICAgICAgdGhpcy5jb21wdXRlUGxvdFR5cGVPcHRpb25zKCk7XG4gICAgICAgICAgICAvLyBJZiB0aGUgYWN0aXZlIHBsb3QgdHlwZSBpc24ndCB2YWxpZCBmb3IgdGhpcyBpbWFnZSAoZS5nLiBhIHNjYWxhclxuICAgICAgICAgICAgLy8gdHlwZSBsaWtlIENvbnRvdXIgY2FycmllZCBvdmVyIHRvIGFuIFJHQiBpbWFnZSksIGZhbGwgYmFjayB0byBJbWFnZS5cbiAgICAgICAgICAgIHRoaXMucmVjb25jaWxlU2VsZWN0ZWRQbG90VHlwZSgpO1xuICAgICAgICAgICAgLy8gUmVhZCBmcm9tIGBpbWdJbmZvYCwgdGhlIHZhbHVlIHRoaXMgZW1pc3Npb24gY2FycmllZCwgcmF0aGVyIHRoYW4gZnJvbSB0aGVcbiAgICAgICAgICAgIC8vIGZpZWxkLiBIYW5kbGluZyB0aGUgZW1wdHkgZW1pc3Npb24gbWVhbnMgdGhlIGZpZWxkIENBTiBiZSBudWxsZWQgcGFydC13YXlcbiAgICAgICAgICAgIC8vIHRocm91Z2ggdGhpcyBicmFuY2g6IGByZWNvbmNpbGVTZWxlY3RlZFBsb3RUeXBlYCBtYXkgY2FsbCBgc2V0UGxvdFR5cGVgLFxuICAgICAgICAgICAgLy8gd2hpY2ggY2FuIG1ha2UgdGhlIGhvc3QgcHVibGlzaCBhIG5ldyBpbWFnZSBzdGF0ZSwgcmUtZW50ZXJpbmcgdGhpcyB2ZXJ5XG4gICAgICAgICAgICAvLyBzdWJzY3JpcHRpb24uIFJlYWRpbmcgdGhlIGZpZWxkIHRoZW4gdGhyZXcgb24gYGlzR3JheXNjYWxlYCBhbmQgYWJvcnRlZCB0aGVcbiAgICAgICAgICAgIC8vIGhhbmRsZXIsIHNvIHRoZSBvYnNlcnZhdGlvbnMgd2VyZSBuZXZlciBkcmF3bi5cbiAgICAgICAgICAgIHRoaXMuaXNHcmF5c2NhbGVFdmVudC5lbWl0KGltZ0luZm8uaXNHcmF5c2NhbGUpO1xuICAgICAgICAgICAgdGhpcy5pc1N0YWNrRXZlbnQuZW1pdChpbWdJbmZvLmlzU3RhY2spO1xuICAgICAgICAgICAgLy8gUmVzZXQgdG8gdGhlIGRlZmF1bHQgMkQgSW1hZ2UgdmlldyB3aGVuIGEgZGlmZmVyZW50IGltYWdlIGlzXG4gICAgICAgICAgICAvLyBzZWxlY3RlZCB3aGlsZSBhIDNEIHR5cGUgaXMgYWN0aXZlLlxuICAgICAgICAgICAgaWYgKCF0aGlzLmlzSGVhdG1hcCAmJiBpbWdJbmZvLmZpbGVOYW1lICE9PSB0aGlzLmxvYWRlZEZpbGVOYW1lKSB7XG4gICAgICAgICAgICAgIHRoaXMuaXNIZWF0bWFwID0gdHJ1ZTtcbiAgICAgICAgICAgICAgdGhpcy5wbG90VHlwZSA9IFBsb3RUeXBlLklNQUdFO1xuICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkUGxvdFR5cGVJZCA9IFBsb3RUeXBlLklNQUdFO1xuICAgICAgICAgICAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldFBsb3RUeXBlKHRoaXMucGxvdFR5cGUpO1xuICAgICAgICAgICAgICB0aGlzLmFjdGl2ZVN1cmZhY2UzZE1vZGUgPSAndHVybnRhYmxlJztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMubG9hZGVkRmlsZU5hbWUgPSBpbWdJbmZvLmZpbGVOYW1lO1xuICAgICAgICAgICAgdGhpcy5wbG90U2VydmljZS5zZXRJbWFnZU1ldGEoaW1nSW5mby5pbWFnZU1ldGEsIGltZ0luZm8uZmlsZU5hbWUpO1xuICAgICAgICAgICAgLy8gQSBuZXdlciBpbWFnZSBhbHdheXMgcHJlZW1wdHMgYW4gaW4tZmxpZ2h0IHJlbmRlciAoc2VlIEltYWdlUmVuZGVyU2Vzc2lvbikuXG4gICAgICAgICAgICBpZiAoaW1nSW5mby51cmxzKSB0aGlzLnJlbmRlci5yZW5kZXIoaW1nSW5mbyk7XG4gICAgICAgICAgfVxuICAgICAgICB9LFxuICAgICAgICBlcnJvcjogKGVycjogdW5rbm93bikgPT4ge1xuICAgICAgICAgIGNvbnN0IG1zZyA9IGVycm9yTWVzc2FnZShlcnIpO1xuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoJ0Vycm9yIG9jY3VyZWQgd2hlbiBnZXR0aW5nIGltYWdlIGluZm8nLCBlcnIpO1xuICAgICAgICAgIHRoaXMubWVzc2FnZVNlcnZpY2UuYWRkKHtcbiAgICAgICAgICAgIGtleTogdGhpcy52aXpBbGVydFRvYXN0S2V5LFxuICAgICAgICAgICAgc3RpY2t5OiB0cnVlLFxuICAgICAgICAgICAgc2V2ZXJpdHk6ICdlcnJvcicsXG4gICAgICAgICAgICBzdW1tYXJ5OiAnQW4gZXJyb3Igb2NjdXJlZCcsXG4gICAgICAgICAgICBkZXRhaWw6IGBUaGUgZm9sbG93aW5nIGVycm9yIG9jY3VyZWQgd2hpbGUgZ2V0dGluZyBpbWFnZSBpbmZvOiAke21zZ30uXG4gICAgICAgICAgICAgICAgICAgUGxlYXNlIHRyeSB0byBvcGVuIHRoZSBpbWFnZSBhZ2FpbiB0aHJvdWdoIHRoZSBmaWxlIG5hdmlnYXRvci5gLFxuICAgICAgICAgIH0pO1xuICAgICAgICAgIHRoaXMuc3RhY2tMb2FkaW5nLnNldChmYWxzZSk7XG4gICAgICAgICAgdGhpcy5zdGF0ZS5zZXRJbWFnZUxvYWRpbmcoZmFsc2UpO1xuICAgICAgICAgIHRoaXMucmVuZGVyLnJ1bm5pbmcgPSBmYWxzZTtcbiAgICAgICAgICB0aGlzLnBsb3RTZXJ2aWNlLnJlc2V0KCk7XG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGb2xsb3cgYHNvdXJjZWAgdW50aWwgZGVzdHJveS4gSG9zdCBzdHJlYW1zIGNhbiBlbWl0IG91dHNpZGUgdGhlIEFuZ3VsYXIgem9uZSAoYVxuICAgKiBzZXJ2ZXJsZXNzIGhvc3QgY2xlYXJzIGl0cyBsb2FkaW5nIGZsYWcgZnJvbSBhbiBpbWFnZSBkZWNvZGUgb3IgYW4gT3BlblNlYWRyYWdvblxuICAgKiBjYWxsYmFjayk7IHNldHRpbmcgYSBzaWduYWwgdGhlcmUgbWFya3MgdGhpcyBPblB1c2ggdmlldyBidXQgc2NoZWR1bGVzIG5vIGNoYW5nZVxuICAgKiBkZXRlY3Rpb24sIHNvIHRoZSB1cGRhdGUgaXMgYXBwbGllZCBpbnNpZGUgdGhlIHpvbmUsIGFzIHtAbGluayBjaGFuZ2VkfSBkb2VzLlxuICAgKi9cbiAgcHJpdmF0ZSBtaXJyb3I8VD4oc291cmNlOiBPYnNlcnZhYmxlPFQ+LCBhcHBseTogKHZhbHVlOiBUKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgc291cmNlLnBpcGUodGFrZVVudGlsRGVzdHJveWVkKHRoaXMuZGVzdHJveVJlZikpLnN1YnNjcmliZSgodmFsdWUpID0+IHtcbiAgICAgIGlmIChOZ1pvbmUuaXNJbkFuZ3VsYXJab25lKCkpIGFwcGx5KHZhbHVlKTtcbiAgICAgIGVsc2UgdGhpcy5uZ1pvbmUucnVuKCgpID0+IGFwcGx5KHZhbHVlKSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogU3RhdGUgdGhpcyB2aWV3IHNob3dzIGNoYW5nZWQgb3V0c2lkZSBvbmUgb2YgaXRzIHRlbXBsYXRlIGV2ZW50cyAoYSBzdHJlYW0sIGFcbiAgICogcmVzb2x2ZWQgcHJvbWlzZSwgYSBob3N0IGNhbGwpOiBtYXJrIHRoZSBPblB1c2ggdmlldyBmb3IgY2hlY2ssIHJlLWVudGVyaW5nIHRoZVxuICAgKiB6b25lIHdoZW4gaXQgY2hhbmdlZCBvdXRzaWRlIGl0IHNvIGEgY2hhbmdlLWRldGVjdGlvbiBwYXNzIGZvbGxvd3MuXG4gICAqL1xuICBwcml2YXRlIGNoYW5nZWQoKTogdm9pZCB7XG4gICAgaWYgKE5nWm9uZS5pc0luQW5ndWxhclpvbmUoKSkgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgZWxzZSB0aGlzLm5nWm9uZS5ydW4oKCkgPT4gdGhpcy5jZHIubWFya0ZvckNoZWNrKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIExheSBhIG5ldyBpbWFnZSBvdXQgb25jZSB0aGUgb2xkIHZpZXcgaXMgZ29uZTogdGhlIHN0YWNrIGZsYWcsIHRoZSBzbGljZSBib3VuZHMgKG9uZVxuICAgKiB1cmwgcGVyIHNsaWNlLCBzbyB0aGUgbGFzdCBpbmRleCBpcyBsZW5ndGgtMSksIGFuZCB0aGUgb25lLXNob3QgYGluaXRpYWxaSW5kZXhgIGhpbnRcbiAgICogKGUuZy4gdGhlIGZpbGUgdGhlIHVzZXIgY2xpY2tlZCB3aXRoaW4gYSBudW1iZXJlZCBzZXJpZXMpLiBUaGUgaGludCBpcyBjb25zdW1lZCBzb1xuICAgKiByZS1kZWxpdmVyaW5nIHRoZSBzYW1lIGluZm8gKGEgcGxvdC10eXBlIHN3aXRjaCwgcmVsb2FkQW5kUGxvdCkgZG9lcyBub3QgcmVzZXQgdGhlXG4gICAqIHVzZXIncyBzY3J1YjsgdGhlIGhvc3QncyBvYmplY3QgaXMgbmV2ZXIgd3JpdHRlbiB0byAoYSBob3N0IHN0b3JlIG1heSBmcmVlemUgaXQpIOKAlFxuICAgKiB0aGUgY29tcG9uZW50IGtlZXBzIGEgY29weSB3aXRob3V0IHRoZSBoaW50LCBhbmQgcmVtZW1iZXJzIHRoZSBob3N0IG9iamVjdC5cbiAgICovXG4gIHByaXZhdGUgbGF5T3V0U2xpY2VzKGluZm86IElJbWFnZUluZm8pOiB2b2lkIHtcbiAgICB0aGlzLnN0YWNrTG9hZGluZy5zZXQoaW5mby5pc1N0YWNrICYmIGluZm8uc2hvd1N0YWNrKTtcbiAgICB0aGlzLm1heEluZGV4ID0gaW5mby51cmxzLmxlbmd0aCA+IDEgPyBpbmZvLnVybHMubGVuZ3RoIC0gMSA6IDA7XG4gICAgaWYgKGluZm8uaW5pdGlhbFpJbmRleCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoIXRoaXMuY29uc3VtZWRTbGljZUhpbnRzLmhhcyhpbmZvKSkge1xuICAgICAgICB0aGlzLmNvbnN1bWVkU2xpY2VIaW50cy5hZGQoaW5mbyk7XG4gICAgICAgIHRoaXMuekluZGV4ID0gaW5mby5pbml0aWFsWkluZGV4O1xuICAgICAgfVxuICAgICAgdGhpcy5pbWFnZUluZm8gPSB7IC4uLmluZm8sIGluaXRpYWxaSW5kZXg6IHVuZGVmaW5lZCB9O1xuICAgIH1cbiAgICB0aGlzLnVwZGF0ZVpJbmRleCgpO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIC8vIFdpbmRvdyBsaXN0ZW5lcnMgYXJlIHJlZ2lzdGVyZWQgT1VUU0lERSB0aGUgQW5ndWxhciB6b25lOiB6b25lLXBhdGNoZWQsIGV2ZXJ5XG4gICAgLy8gbW91c2Vtb3ZlIGFueXdoZXJlIGluIHRoZSBob3N0IGFwcCByYW4gYXBwLXdpZGUgY2hhbmdlIGRldGVjdGlvbi4gRWFjaCBoYW5kbGVyXG4gICAgLy8gcmUtZW50ZXJzIHRoZSB6b25lIChuZ1pvbmUucnVuKSBvbmx5IHdoZW4gaXQgYWN0dWFsbHkgY2hhbmdlcyB2aWV3IHN0YXRlLlxuICAgIHRoaXMuc2hvcnRjdXRzID0gbmV3IFZpZXdlclNob3J0Y3V0cyh0aGlzLnNob3J0Y3V0SG9zdCgpLCB0aGlzLm5nWm9uZSk7XG4gICAgdGhpcy5zaG9ydGN1dHMuYXR0YWNoKCk7XG4gICAgdGhpcy53aGVuSW5Eb2N1bWVudCgoKSA9PiB0aGlzLm9uVmlld1JlYWR5KCkpO1xuICB9XG5cbiAgLyoqIFRoZSBwbG90IGRpdiBleGlzdHMgbm93OiBydW4gYW4gaW1hZ2UtbGVzcyBkcmF3IHRoYXQgYXJyaXZlZCBiZWZvcmUgaXQgZGlkLiAqL1xuICBwcml2YXRlIG9uVmlld1JlYWR5KCk6IHZvaWQge1xuICAgIHRoaXMucmVuZGVyLnZpZXdJc1JlYWR5KHRoaXMuc3BhdGlhbC5kYXRhc2V0LCAhIXRoaXMuaW1hZ2VJbmZvKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW4gYHJlYWR5YCBvbmNlIHRoaXMgdmlld2VyIGlzIGluIHRoZSBkb2N1bWVudC4gQSBob3N0IG1heSBjcmVhdGUgaXQgZGV0YWNoZWQg4oCUIGEgY2xvc2VkXG4gICAqIGRpYWxvZydzIHByb2plY3RlZCBjb250ZW50LCBzdWNoIGFzIGppdC11aSdzIHBpcGVsaW5lIHByZXZpZXcg4oCUIGFuZCB0aGUgYmFja2VuZHMgZmluZCB0aGVcbiAgICogcGxvdCBkaXYgYnkgaWQsIHNvIGEgZHJhdyB0aGVuIGZvdW5kIG5vIHRhcmdldCBhbmQgYWxlcnRlZCBcInRoZSByZW5kZXJlciBjb3VsZCBub3Qgc3RhcnRcIlxuICAgKiBvdmVyIGFub3RoZXIgdmlld2VyLiBVbnRpbCB0aGVuIGl0cyB2aWV3IGlzIG5vdCByZWFkeSwgYW5kIGFuIGltYWdlLWxlc3MgZHJhdyB3YWl0cy5cbiAgICovXG4gIHByaXZhdGUgd2hlbkluRG9jdW1lbnQocmVhZHk6ICgpID0+IHZvaWQpOiB2b2lkIHtcbiAgICBjb25zdCBlbCA9IHRoaXMuaG9zdFJlZj8ubmF0aXZlRWxlbWVudDtcbiAgICBpZiAoIWVsIHx8IGVsLmlzQ29ubmVjdGVkIHx8IHR5cGVvZiBSZXNpemVPYnNlcnZlciA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJlYWR5KCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIEF0dGFjaGVkIGFuZCBsYWlkIG91dCwgaXRzIHNpemUgY2hhbmdlcyBmcm9tIG5vdGhpbmc6IHRoYXQgaXMgd2hlbiBpdCBjYW4gYmUgZHJhd24gaW50by5cbiAgICBjb25zdCBvYnNlcnZlciA9IG5ldyBSZXNpemVPYnNlcnZlcigoKSA9PiB7XG4gICAgICBpZiAoIWVsLmlzQ29ubmVjdGVkKSByZXR1cm47XG4gICAgICBvYnNlcnZlci5kaXNjb25uZWN0KCk7XG4gICAgICB0aGlzLmF0dGFjaE9ic2VydmVyID0gbnVsbDtcbiAgICAgIHRoaXMubmdab25lLnJ1bihyZWFkeSk7XG4gICAgfSk7XG4gICAgdGhpcy5hdHRhY2hPYnNlcnZlciA9IG9ic2VydmVyO1xuICAgIG9ic2VydmVyLm9ic2VydmUoZWwpO1xuICB9XG5cbiAgLyoqIFdoYXQgdGhlIGtleWJvYXJkLCB3aGVlbCBhbmQgY29udGV4dC1tZW51IHNob3J0Y3V0cyBhY3Qgb24uIFRoZWlyIGxpc3RlbmVycyBsaXZlXG4gICAqICBvdXRzaWRlIHRoaXMgdmlldywgc28gZXZlcnkgYWN0aW9uIHRoYXQgY2hhbmdlcyB3aGF0IGl0IHNob3dzIG1hcmtzIGl0IGZvciBjaGVjay4gKi9cbiAgcHJpdmF0ZSBzaG9ydGN1dEhvc3QoKTogU2hvcnRjdXRIb3N0IHtcbiAgICBjb25zdCBtYXJrZWQgPVxuICAgICAgPEEgZXh0ZW5kcyB1bmtub3duW10+KGFjdDogKC4uLmFyZ3M6IEEpID0+IHZvaWQpID0+XG4gICAgICAoLi4uYXJnczogQSk6IHZvaWQgPT4ge1xuICAgICAgICBhY3QoLi4uYXJncyk7XG4gICAgICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgICAgfTtcbiAgICByZXR1cm4ge1xuICAgICAgcGxvdERpdk5hbWU6IHRoaXMucGxvdERpdk5hbWUsXG4gICAgICBob3N0RWxlbWVudDogdGhpcy5ob3N0UmVmPy5uYXRpdmVFbGVtZW50ID8/IG51bGwsXG4gICAgICBhY3RpdmVEcmFnTW9kZTogKCkgPT4gdGhpcy5hY3RpdmVEcmFnTW9kZSxcbiAgICAgIGNhblN0ZXBTbGljZTogKCkgPT4gISF0aGlzLmltYWdlSW5mbz8uaXNTdGFjayAmJiAodGhpcy5pc0ltYWdlVmlldyB8fCB0aGlzLnNsaWNlRWRpdG9yU2hvd24pLFxuICAgICAgd2hlZWxab29tczogKCkgPT4gIXJlbmRlcmVyT3duc1doZWVsKHRoaXMuYmFzZVBsb3RUeXBlKSAmJiB0aGlzLmlzSGVhdG1hcCxcbiAgICAgIHN0ZXBTbGljZTogbWFya2VkKChkZWx0YTogbnVtYmVyKSA9PiB0aGlzLnN0ZXBTbGljZShkZWx0YSkpLFxuICAgICAgcmVzb2x2ZVNhbVByb21wdDogbWFya2VkKChjb21taXQ6IGJvb2xlYW4pID0+IHtcbiAgICAgICAgaWYgKGNvbW1pdCkgdGhpcy5wbG90U2VydmljZS5jb21taXRTYW1Qb2ludHMoKTtcbiAgICAgICAgZWxzZSB0aGlzLnBsb3RTZXJ2aWNlLmNsZWFyU2FtUG9pbnRzKCk7XG4gICAgICAgIHRoaXMuc2VnbWVudGF0aW9uLmhpZGUoKTsgLy8gcHJvbXB0IHJlc29sdmVkIOKGkiBkaXNtaXNzIHRoZSBzdGF0dXMgdG9hc3RcbiAgICAgIH0pLFxuICAgICAgdW5kbzogbWFya2VkKCgpID0+IHRoaXMudW5kb1JlZ2lvbigpKSxcbiAgICAgIHJlZG86IG1hcmtlZCgoKSA9PiB0aGlzLnJlZG9SZWdpb24oKSksXG4gICAgICBkZWxldGVSZWdpb246IG1hcmtlZCgoKSA9PiB0aGlzLmRlbGV0ZVJlZ2lvbigpKSxcbiAgICAgIHpvb21JbjogbWFya2VkKCgpID0+IHRoaXMuem9vbUluKCkpLFxuICAgICAgem9vbU91dDogbWFya2VkKCgpID0+IHRoaXMuem9vbU91dCgpKSxcbiAgICAgIHRvZ2dsZURyYWdNb2RlOiBtYXJrZWQoKG1vZGU6IHN0cmluZykgPT4gdGhpcy50b2dnbGVEcmFnTW9kZShtb2RlKSksXG4gICAgICBvcGVuQ29udGV4dE1lbnU6IChldmVudCkgPT4ge1xuICAgICAgICB0aGlzLmNvbnRleHRNZW51SXRlbXMgPSB0aGlzLmJ1aWxkQ29udGV4dE1lbnVJdGVtcygpO1xuICAgICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgIHRoaXMuY29udGV4dE1lbnUuc2hvdyhldmVudCk7XG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICAvKiogU25hcCB0aGUgZmxvYXRpbmcgdG9vbGJhciBiYWNrIHRvIGl0cyBkb2NrZWQgcG9zaXRpb24gYWNyb3NzIHRoZSB0b3AuICovXG4gIHByb3RlY3RlZCBkb2NrVG9vbGJhcigpIHtcbiAgICB0aGlzLnRvb2xiYXJGbG9hdGluZyA9IGZhbHNlO1xuICB9XG5cbiAgLyoqIFRvb2xiYXIgXCJJbnRlbnNpdHlcIiBncm91cDogYWRkIGFub3RoZXIgbGluZSBST0kgKG5leHQgYnJpZ2h0IGNvbG91cikuICovXG4gIHByb3RlY3RlZCBhc3luYyBhZGRQcm9maWxlTGluZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCByZWdpb24gPSBhd2FpdCB0aGlzLmluc2V0Py5hZGRQcm9maWxlTGluZSgpO1xuICAgIC8vIE9TRCBvbmx5IGRyYXdzIGEgc2VsZWN0ZWQgcmVnaW9uJ3MgaGFuZGxlcyBpbiBhbiBlZGl0IG1vZGUsIHNvIGEgbGluZSBpblxuICAgIC8vICdub25lJyBtb2RlIGxvb2tzIHVuc2VsZWN0ZWQuIFN3aXRjaCB0byAnc2VsZWN0JyBzbyB0aGUgbmV3IGxpbmUgc2hvd3MgaXRzXG4gICAgLy8gZW5kcG9pbnQgaGFuZGxlcyBhbmQgY2FuIGJlIGRyYWdnZWQvZGVsZXRlZCByaWdodCBhd2F5LlxuICAgIGlmIChyZWdpb24gJiYgdGhpcy5pc0ltYWdlVmlldyAmJiB0aGlzLmFjdGl2ZURyYWdNb2RlICE9PSAnc2VsZWN0JykgdGhpcy50b2dnbGVEcmFnTW9kZSgnc2VsZWN0Jyk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLmF0dGFjaE9ic2VydmVyPy5kaXNjb25uZWN0KCk7XG4gICAgLy8gQSBjb250cmlidXRlZCBtb2RlJ3Mgc2Vzc2lvbiBlbmRzIGZpcnN0LCB3aGlsZSB0aGUgdmlld2VyIGl0IGRyZXcgb3ZlclxuICAgIC8vIHN0aWxsIGV4aXN0cy4gVGhlIHBhbmVsIGdvZXMgd2l0aCB0aGlzIHZpZXcsIHNvIG5vIGNoYW5nZSBkZXRlY3Rpb24uXG4gICAgdGhpcy5jb250cmlidXRpb25zLmRlc3Ryb3koKTtcbiAgICAvLyBMZWF2ZSB0aGUgbGl2ZSBzZXQgc28gdGhlIG5leHQtb2xkZXN0IHZpc3VhbGl6ZXIgcGlja3MgdXAgdGhlIG91dGxldHMg4oCUIG9uIGl0c1xuICAgIC8vIG5leHQgY2hlY2ssIHdoaWNoIGFuIE9uUHVzaCBzaWJsaW5nIG5lZWRzIGFza2luZyBmb3IuXG4gICAgVmlzdWFsaXplckNvbXBvbmVudC5saXZlSW5zdGFuY2VzLmRlbGV0ZSh0aGlzKTtcbiAgICBmb3IgKGNvbnN0IG90aGVyIG9mIFZpc3VhbGl6ZXJDb21wb25lbnQubGl2ZUluc3RhbmNlcykgb3RoZXIuY2hhbmdlZCgpO1xuICAgIHRoaXMuc3RhdGUuc2V0RGlhZ3JhbShudWxsKTtcbiAgICB0aGlzLnJlbmRlci5jYW5jZWwoKTtcbiAgICB0aGlzLnNwYXRpYWwuZGlzcG9zZSgpO1xuICAgIHRoaXMuc2NydWJiZXIuY2FuY2VsKCk7XG4gICAgdGhpcy5zaG9ydGN1dHM/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+XG4gIDwvZGl2PlxuICA8cGxvdHRpbmctdG9vbGJhclxuICAgIFtpbWFnZUluZm9dPVwiaW1hZ2VJbmZvXCJcbiAgICBbaGFzU3BhdGlhbERhdGFzZXRdPVwiaGFzU3BhdGlhbERhdGFzZXRcIlxuICAgIFtwbG90VHlwZU9wdGlvbnNdPVwicGxvdFR5cGVNZW51XCJcbiAgICBbc2VsZWN0ZWRQbG90VHlwZV09XCJzZWxlY3RlZFBsb3RUeXBlSWRcIlxuICAgIFtiYXNlUGxvdFR5cGVdPVwiYmFzZVBsb3RUeXBlXCJcbiAgICBbaXNvUmFuZ2VdPVwiaXNvUmFuZ2VcIlxuICAgIFttYXhJbmRleF09XCJtYXhJbmRleFwiXG4gICAgW3pJbmRleF09XCJ6SW5kZXhcIlxuICAgIFtpc0hlYXRtYXBdPVwiaXNIZWF0bWFwXCJcbiAgICBbaXMzZFJlZ2lvbnNdPVwiaXNTcGF0aWFsM2RNb2RlXCJcbiAgICBbaXNWb2x1bWVWaWV3XT1cImlzVm9sdW1lVmlld1wiXG4gICAgW3NsaWNlRWRpdG9yXT1cInNsaWNlRWRpdG9yXCJcbiAgICBbYWN0aXZlRHJhZ01vZGVdPVwiYWN0aXZlRHJhZ01vZGVcIlxuICAgIFthY3RpdmVTdXJmYWNlM2RNb2RlXT1cImFjdGl2ZVN1cmZhY2UzZE1vZGVcIlxuICAgIFtheGVzVmlzaWJsZV09XCJheGVzVmlzaWJsZVwiXG4gICAgW3dpcmVmcmFtZUFjdGl2ZV09XCJ3aXJlZnJhbWVBY3RpdmVcIlxuICAgIFtyZXNvbHV0aW9uU2NhbGVdPVwicmVzb2x1dGlvblNjYWxlXCJcbiAgICBbd2FuZFNlbnNpdGl2aXR5XT1cIndhbmRTZW5zaXRpdml0eVwiXG4gICAgW2JydXNoU2l6ZV09XCJicnVzaFNpemVcIlxuICAgIFtzYW1Nb2RlbHNdPVwic2FtTW9kZWxzXCJcbiAgICBbc2FtTW9kZWxJZF09XCJzYW1Nb2RlbElkXCJcbiAgICBbY29udHJpYnV0ZWRUb29sc109XCJjb250cmlidXRlZFRvb2xzXCJcbiAgICBbZGlhbG9nVG9vbHNdPVwiZGlhbG9nVG9vbHNcIlxuICAgIFtvcGVuRGlhbG9nVG9vbElkXT1cIm9wZW5EaWFsb2dUb29sSWRcIlxuICAgICh0b2dnbGVEaWFsb2dUb29sKT1cInRvZ2dsZURpYWxvZ1Rvb2woJGV2ZW50KVwiXG4gICAgW3Rvb2xNb2RlbElkc109XCJ0b29sUGFyYW1zLnRvb2xNb2RlbElkc1wiXG4gICAgW3ZlcnRleEVyYXNlclJhZGl1c109XCJ2ZXJ0ZXhFcmFzZXJSYWRpdXNcIlxuICAgIFtjYW5VbmRvXT1cInJlZ2lvbkFjdGlvbnMuY2FuVW5kb1wiXG4gICAgW2NhblJlZG9dPVwicmVnaW9uQWN0aW9ucy5jYW5SZWRvXCJcbiAgICBbdG9vbHNdPVwidG9vbGJhclRvb2xzXCJcbiAgICBbaW1hZ2VTbW9vdGhpbmdFbmFibGVkXT1cImltYWdlU21vb3RoaW5nRW5hYmxlZFwiXG4gICAgKHNlbGVjdFBsb3RUeXBlKT1cIm9uU2VsZWN0UGxvdFR5cGUoJGV2ZW50KVwiXG4gICAgKHRvZ2dsZUltYWdlU21vb3RoaW5nKT1cIm9uVG9nZ2xlSW1hZ2VTbW9vdGhpbmcoKVwiXG4gICAgKGFkZFByb2ZpbGVMaW5lKT1cImFkZFByb2ZpbGVMaW5lKClcIlxuICAgIChpc29SYW5nZUNoYW5nZSk9XCJvbklzb1JhbmdlQ2hhbmdlKCRldmVudClcIlxuICAgIChvcGVuQ2hhbm5lbEhpc3RvZ3JhbSk9XCJvcGVuQ2hhbm5lbEhpc3RvZ3JhbSgpXCJcbiAgICAob3BlblNwYXRpYWxDb250cm9scyk9XCJvcGVuU3BhdGlhbENvbnRyb2xzKClcIlxuICAgIChvcGVuUmVnaW9uRWRpdG9yKT1cIm9wZW5SZWdpb25FZGl0b3IoKVwiXG4gICAgKHRvZ2dsZVNsaWNlRWRpdG9yKT1cInRvZ2dsZVNsaWNlRWRpdG9yKClcIlxuICAgIChzZWxlY3RTdGFja09wdGlvbik9XCJzZWxlY3RTdGFja09wdGlvbigkZXZlbnQpXCJcbiAgICAoelNjcnViKT1cIm9uWlNjcnViKCRldmVudClcIlxuICAgICh6U2xpZGUpPVwib25aU2xpZGUoJGV2ZW50KVwiXG4gICAgKHpJbmRleElucHV0KT1cInpJbmRleCA9ICRldmVudDsgdXBkYXRlWkluZGV4KClcIlxuICAgIChyZWxvYWRBbmRQbG90KT1cInJlbG9hZEFuZFBsb3QoKVwiXG4gICAgKGRvd25sb2FkSW1hZ2UpPVwiZG93bmxvYWRJbWFnZSgpXCJcbiAgICAoYXV0b3NjYWxlSW1hZ2UpPVwiYXV0b3NjYWxlSW1hZ2UoKVwiXG4gICAgKHRvZ2dsZURyYWdNb2RlKT1cInRvZ2dsZURyYWdNb2RlKCRldmVudClcIlxuICAgICh6b29tSW4pPVwiem9vbUluKClcIlxuICAgICh6b29tT3V0KT1cInpvb21PdXQoKVwiXG4gICAgKHRvZ2dsZVN1cmZhY2UzZE1vZGUpPVwidG9nZ2xlU3VyZmFjZTNkTW9kZSgkZXZlbnQpXCJcbiAgICAocmVzZXRTdXJmYWNlQ2FtZXJhKT1cInJlc2V0U3VyZmFjZUNhbWVyYSgpXCJcbiAgICAodG9nZ2xlQXhlcyk9XCJ0b2dnbGVBeGVzKClcIlxuICAgICh0b2dnbGVXaXJlZnJhbWUpPVwidG9nZ2xlV2lyZWZyYW1lKClcIlxuICAgIChzZWxlY3RSZXNvbHV0aW9uKT1cInNlbGVjdFJlc29sdXRpb24oJGV2ZW50KVwiXG4gICAgKGRlbGV0ZVJlZ2lvbik9XCJkZWxldGVSZWdpb24oKVwiXG4gICAgKHVuZG9SZWdpb24pPVwidW5kb1JlZ2lvbigpXCJcbiAgICAocmVkb1JlZ2lvbik9XCJyZWRvUmVnaW9uKClcIlxuICAgIChzZWdtZW50UmVnaW9ucyk9XCJzZWdtZW50UmVnaW9ucygpXCJcbiAgICAoc2VnbWVudENlbGxwb3NlKT1cInNlZ21lbnRDZWxscG9zZSgpXCJcbiAgICAoc2FtTW9kZWxDaGFuZ2UpPVwib25TYW1Nb2RlbENoYW5nZSgkZXZlbnQpXCJcbiAgICAocnVuVG9vbCk9XCJydW5Ub29sKCRldmVudClcIlxuICAgICh0b29sTW9kZWxDaGFuZ2UpPVwib25Ub29sTW9kZWxDaGFuZ2UoJGV2ZW50KVwiXG4gICAgKG9wZW5Ub29sUGFyYW1zKT1cIm9wZW5Ub29sUGFyYW1zKCRldmVudClcIlxuICAgICh3YW5kU2Vuc2l0aXZpdHlDaGFuZ2UpPVwib25XYW5kU2Vuc2l0aXZpdHlDaGFuZ2UoJGV2ZW50KVwiXG4gICAgKGJydXNoU2l6ZUNoYW5nZSk9XCJvbkJydXNoU2l6ZUNoYW5nZSgkZXZlbnQpXCJcbiAgICAodmVydGV4RXJhc2VyUmFkaXVzQ2hhbmdlKT1cIm9uVmVydGV4RXJhc2VyUmFkaXVzQ2hhbmdlKCRldmVudClcIlxuICA+XG4gICAgPCEtLSBIb3N0LXByb2plY3RlZCBjdXN0b20gdG9vbGJhciBidXR0b25zLCBmb3J3YXJkZWQgaW50byB0aGUgdG9vbGJhci4gLS0+XG4gICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuICA8L3Bsb3R0aW5nLXRvb2xiYXI+XG4gIDxwLWJ1dHRvblxuICAgICpuZ0lmPVwidG9vbGJhckZsb2F0aW5nXCJcbiAgICBjbGFzcz1cInRvb2xiYXItZG9jay1idG5cIlxuICAgIGljb249XCJwaSBwaS10aHVtYnRhY2tcIlxuICAgIHNpemU9XCJzbWFsbFwiXG4gICAgW3RleHRdPVwidHJ1ZVwiXG4gICAgcFRvb2x0aXA9XCJEb2NrIHRvIHRvcFwiXG4gICAgdG9vbHRpcFBvc2l0aW9uPVwiYm90dG9tXCJcbiAgICAob25DbGljayk9XCJkb2NrVG9vbGJhcigpXCJcbiAgPlxuICA8L3AtYnV0dG9uPlxuPC9kaXY+XG5cbjxwLWNvbnRleHRNZW51ICNjbSBbbW9kZWxdPVwiY29udGV4dE1lbnVJdGVtc1wiIGFwcGVuZFRvPVwiYm9keVwiPjwvcC1jb250ZXh0TWVudT5cbjwhLS0gTm8gYGgtZnVsbGAgaGVyZTogUHJpbWVGbGV4J3MgaGVpZ2h0OjEwMCUgIWltcG9ydGFudCBtYWRlICNwbG90IGFzIHRhbGwgYXNcbiAgICAgdGhlIHdob2xlIGhvc3QsIHNvIHVuZGVyIHRoZSBkb2NrZWQgdG9vbGJhciBpdHMgYm90dG9tIHRvb2xiYXItaGVpZ2h0IHN0cmlwXG4gICAgIChpbmNsLiB0aGUgT1NEIHNjYWxlIGJhciBhdCBib3R0b20tbGVmdCkgd2FzIGNsaXBwZWQgYnkgdGhlIGhvc3Qnc1xuICAgICBvdmVyZmxvdzpoaWRkZW4uIFRoZSBjb21wb25lbnQgc3R5bGVzaGVldCBzaXplcyBpdCAoLnZpei1wbG90IHsgZmxleDogMSB9KS4gLS0+XG48IS0tIFRoZSBwbG90LCBhbmQgd2hpbGUgYSB2b2x1bWUgdmlldyBpcyBzcGxpdCwgdGhlIHNsaWNlIGVkaXRvcidzIHBhbmUgb24gaXRzIGxlZnQgKGl0cyBvd25cbiAgICAgdmlld2VyLCB3aXRoIGV2ZXJ5IHJlZ2lvbiB0b29sKSB3aXRoIGEgZGl2aWRlciB0byByZXNpemUgdGhlIHR3by4gVGhlIHBsb3QgZGl2IGtlZXBzIGl0c1xuICAgICBwbGFjZSBpbiB0aGUgRE9NIGVpdGhlciB3YXk6IHRoZSBiYWNrZW5kcyBmaW5kIGl0IGJ5IGlkLCBhbmQgYSB2aWV3ZXIgbW91bnRlZCBpbiBpdCBzdGF5cy4gLS0+XG48ZGl2XG4gIGNsYXNzPVwidml6LXBhbmVzXCJcbiAgW2NsYXNzLnZpei1xdWFkXT1cInNsaWNlRWRpdG9yU2hvd25cIlxuICBbc3R5bGUuZ3JpZC10ZW1wbGF0ZS1jb2x1bW5zXT1cInNsaWNlRWRpdG9yU2hvd24gPyBzcGxpdFggKyAnJSA2cHggbWlubWF4KDAsIDFmciknIDogbnVsbFwiXG4gIFtzdHlsZS5ncmlkLXRlbXBsYXRlLXJvd3NdPVwic2xpY2VFZGl0b3JTaG93biA/IHNwbGl0WSArICclIDZweCBtaW5tYXgoMCwgMWZyKScgOiBudWxsXCJcbj5cbiAgPCEtLSBUaGUgc2xpY2UgZWRpdG9yOiB0aGUgdm9sdW1lICh0aGUgcGxvdCkgdG9wIGxlZnQsIHRoZSBzbGljZSBiZWluZyBlZGl0ZWQgKFopIHRvcCByaWdodCxcbiAgICAgICB0aGUgc2VjdGlvbnMgdGhyb3VnaCB4IGFuZCB5IGJlbG93LCBpbiB0aGVpciBheGlzIGNvbG91cnMuIC0tPlxuICA8bmctY29udGFpbmVyICpuZ0lmPVwic2xpY2VFZGl0b3JTaG93blwiPlxuICAgIDxkaXYgY2xhc3M9XCJ2aXotY2VsbCB2aXotY2VsbC16XCI+XG4gICAgICA8ZGl2IGNsYXNzPVwidml6LXNsaWNlLXBhbmVcIiBbaWRdPVwic2xpY2VEaXZOYW1lXCI+PC9kaXY+XG4gICAgICA8c3BhbiBjbGFzcz1cInZpei1wYW5lLWJhZGdlIHZpei1wYW5lLWJhZGdlLXpcIj5aIMK3IHNsaWNlIHt7IHpJbmRleCB9fTwvc3Bhbj5cbiAgICA8L2Rpdj5cbiAgICA8ZGl2IGNsYXNzPVwidml6LWNlbGwgdml6LWNlbGwteFwiPlxuICAgICAgPHZpei1zZWN0aW9uLXBhbmUgYXhpcz1cInhcIiBbdmlld109XCJzZWN0aW9ucy54XCIgKHBpY2spPVwib25TZWN0aW9uUGljaygneCcsICRldmVudClcIj48L3Zpei1zZWN0aW9uLXBhbmU+XG4gICAgPC9kaXY+XG4gICAgPGRpdiBjbGFzcz1cInZpei1jZWxsIHZpei1jZWxsLXlcIj5cbiAgICAgIDx2aXotc2VjdGlvbi1wYW5lIGF4aXM9XCJ5XCIgW3ZpZXddPVwic2VjdGlvbnMueVwiIChwaWNrKT1cIm9uU2VjdGlvblBpY2soJ3knLCAkZXZlbnQpXCI+PC92aXotc2VjdGlvbi1wYW5lPlxuICAgIDwvZGl2PlxuICAgIDxkaXZcbiAgICAgIGNsYXNzPVwidml6LXBhbmUtZGl2aWRlciB2aXotcGFuZS1kaXZpZGVyLXZcIlxuICAgICAgcm9sZT1cInNlcGFyYXRvclwiXG4gICAgICBhcmlhLW9yaWVudGF0aW9uPVwidmVydGljYWxcIlxuICAgICAgYXJpYS1sYWJlbD1cIlJlc2l6ZSB0aGUgcGFuZXMgYWNyb3NzXCJcbiAgICAgIFthdHRyLmFyaWEtdmFsdWVub3ddPVwic3BsaXRYXCJcbiAgICAgIGFyaWEtdmFsdWVtaW49XCIyMFwiXG4gICAgICBhcmlhLXZhbHVlbWF4PVwiODBcIlxuICAgICAgdGFiaW5kZXg9XCIwXCJcbiAgICAgIChwb2ludGVyZG93bik9XCJzdGFydFBhbmVSZXNpemUoJGV2ZW50LCAneCcpXCJcbiAgICAgIChrZXlkb3duKT1cIm51ZGdlUGFuZVNpemUoJGV2ZW50LCAneCcpXCJcbiAgICA+PC9kaXY+XG4gICAgPGRpdlxuICAgICAgY2xhc3M9XCJ2aXotcGFuZS1kaXZpZGVyIHZpei1wYW5lLWRpdmlkZXItaFwiXG4gICAgICByb2xlPVwic2VwYXJhdG9yXCJcbiAgICAgIGFyaWEtb3JpZW50YXRpb249XCJob3Jpem9udGFsXCJcbiAgICAgIGFyaWEtbGFiZWw9XCJSZXNpemUgdGhlIHBhbmVzIGRvd25cIlxuICAgICAgW2F0dHIuYXJpYS12YWx1ZW5vd109XCJzcGxpdFlcIlxuICAgICAgYXJpYS12YWx1ZW1pbj1cIjIwXCJcbiAgICAgIGFyaWEtdmFsdWVtYXg9XCI4MFwiXG4gICAgICB0YWJpbmRleD1cIjBcIlxuICAgICAgKHBvaW50ZXJkb3duKT1cInN0YXJ0UGFuZVJlc2l6ZSgkZXZlbnQsICd5JylcIlxuICAgICAgKGtleWRvd24pPVwibnVkZ2VQYW5lU2l6ZSgkZXZlbnQsICd5JylcIlxuICAgID48L2Rpdj5cbiAgPC9uZy1jb250YWluZXI+XG4gIDxkaXYgY2xhc3M9XCJ3LWZ1bGwgcmVsYXRpdmUgdml6LXBsb3RcIiBbaWRdPVwicGxvdERpdk5hbWVcIj5cbiAgICA8ZGl2ICpuZ0lmPVwiaW1nTG9hZGluZygpIHx8IHN0YWNrTG9hZGluZygpIHx8IGlzQ2FjaGluZygpXCIgY2xhc3M9XCJsb2FkaW5nLW92ZXJsYXlcIj5cbiAgICAgIDwhLS0gRGV0ZXJtaW5hdGUgc3RhY2svdm9sdW1lIHByb2dyZXNzIHRha2VzIHByZWNlZGVuY2U6IHdoaWxlIGl0J3MgYWN0aXZlIHNob3cgT05MWSB0aGVcbiAgICAgICAgIHByb2dyZXNzIGJhciArIFwiTG9hZGluZyBmcmFtZXMuLi5cIiwgbm90IHRoZSBnZW5lcmljIHNwaW5uZXIvXCJMb2FkaW5nIGltYWdlLi4uXCIgb24gdG9wIG9mXG4gICAgICAgICBpdCAoYm90aCB3ZXJlIHJlbmRlcmluZyBhdCBvbmNlIGZvciBuYXBhcmkgdm9sdW1lL2lzb3N1cmZhY2UgbG9hZHMpLiAtLT5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJzdGFja0xvYWRpbmcoKTsgZWxzZSBpbWdMb2FkaW5nVHBsXCI+XG4gICAgICAgIDxwLXByb2dyZXNzQmFyIGNsYXNzPVwicHJvZ3Jlc3NcIiBbdmFsdWVdPVwibG9hZGluZ1BlcmNlbnRhZ2UoKVwiPjwvcC1wcm9ncmVzc0Jhcj5cbiAgICAgICAgPHNwYW4gY2xhc3M9XCJ0ZXh0LWxvYWRpbmdcIj5Mb2FkaW5nIGZyYW1lcy4uLjwvc3Bhbj5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPG5nLXRlbXBsYXRlICNpbWdMb2FkaW5nVHBsPlxuICAgICAgICA8IS0tIENhY2hlLWNvcHkgcHJvZ3Jlc3MgaXMgc2hvd24gd2hlbmV2ZXIgYSBjYWNoZSBkb3dubG9hZCBpcyBhY3RpdmUgKGlzQ2FjaGluZyksIGluZGVwZW5kZW50XG4gICAgICAgICAgIG9mIGBpbWdMb2FkaW5nYCwgc28gaXQncyBuZXZlciBkcm9wcGVkL21hc2tlZCBtaWQtZG93bmxvYWQuIC0tPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNDYWNoaW5nKCk7IGVsc2Ugc3Bpbm5lckxvYWRpbmdcIj5cbiAgICAgICAgICA8IS0tIFN0YWdlLWF3YXJlIG1lc3NhZ2UgY29tZXMgZnJvbSBDYWNoZVByb2dyZXNzU2VydmljZSB1cGRhdGluZ1xuICAgICAgICAgICAgIGltYWdlTG9hZGluZ01lc3NhZ2UkIChcIkNhY2hpbmcgaW1hZ2UuLi5cIiBkdXJpbmcgdGhlIEdDUyBkb3dubG9hZCxcbiAgICAgICAgICAgICB0aGVuIFwiR2VuZXJhdGluZyBwcmV2aWV3Li4uXCIgZHVyaW5nIHBlci1zbGljZSB0aHVtYm5haWwgZ2VuKS4gT25jZSB0aGVcbiAgICAgICAgICAgICBkb3dubG9hZCBoaXRzIDEwMCUgdGhlIHJlbWFpbmluZyB3b3JrIChzZXJ2ZXIgcHJldmlldy90aWxlIGdlbmVyYXRpb24pXG4gICAgICAgICAgICAgaGFzIG5vIGRldGVybWluYXRlIHByb2dyZXNzLCBzbyBmYWxsIHRocm91Z2ggdG8gdGhlIHNwaW5uZXIgdGVtcGxhdGVcbiAgICAgICAgICAgICByYXRoZXIgdGhhbiBwYXJraW5nIGEgZnVsbCBiYXIgdW5kZXIgXCJMb2FkaW5nIGltYWdlLi4uXCIuIC0tPlxuICAgICAgICAgIDxwLXByb2dyZXNzQmFyIGNsYXNzPVwicHJvZ3Jlc3NcIiBbdmFsdWVdPVwiY2FjaGVQcm9ncmVzcygpXCI+PC9wLXByb2dyZXNzQmFyPlxuICAgICAgICAgIDxzcGFuIGNsYXNzPVwidGV4dC1sb2FkaW5nXCI+e3sgbG9hZGluZ01lc3NhZ2UoKSB9fTwvc3Bhbj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjc3Bpbm5lckxvYWRpbmc+XG4gICAgICAgICAgPGRpdiAqbmdJZj1cImltZ0xvYWRpbmcoKVwiIGNsYXNzPVwic3Bpbm5lclwiPjwvZGl2PlxuICAgICAgICAgIDxzcGFuICpuZ0lmPVwiaW1nTG9hZGluZygpICYmICF6b29tKClcIiBjbGFzcz1cInRleHQtbG9hZGluZ1wiPnt7IGxvYWRpbmdNZXNzYWdlKCkgfX08L3NwYW4+XG4gICAgICAgICAgPHNwYW4gKm5nSWY9XCJpbWdMb2FkaW5nKCkgJiYgem9vbSgpXCIgY2xhc3M9XCJ6b29tLXRleHQtbG9hZGluZ1wiPnt7IGxvYWRpbmdNZXNzYWdlKCkgfX08L3NwYW4+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPHAtYnV0dG9uXG4gICAgICAgICpuZ0lmPVwic3RhY2tMb2FkaW5nKCkgfHwgaW1nTG9hZGluZygpXCJcbiAgICAgICAgY2xhc3M9XCJjYW5jZWwtbG9hZGluZ1wiXG4gICAgICAgIGxhYmVsPVwiQ2FuY2VsXCJcbiAgICAgICAgKG9uQ2xpY2spPVwiY2FuY2VsTG9hZGluZygpXCJcbiAgICAgID5cbiAgICAgIDwvcC1idXR0b24+XG4gICAgPC9kaXY+XG4gICAgPCEtLSBUcmFuc2x1Y2VudCBcInNoYXJwZW5pbmdcIiBvdmVybGF5IHNob3duIGFmdGVyIHRoZSBzbWFsbC10aWVyIHByZXZpZXcgaXNcbiAgICAgICBvbiBzY3JlZW4gd2hpbGUgdGhlIGxhcmdlLXRpZXIgcmVuZGVyIGlzIHN0aWxsIGxvYWRpbmcgaW4gdGhlXG4gICAgICAgYmFja2dyb3VuZC4gTGV0cyB0aGUgdXNlciBzZWUgdGhlIGJsdXJyeSBpbWFnZSB1bmRlcm5lYXRoIGJ1dCBtYWtlc1xuICAgICAgIGl0IGNsZWFyIHNvbWV0aGluZyBpcyBzdGlsbCBsb2FkaW5nIHNvIHRoZXkgZG9uJ3QgbWlzdGFrZSB0aGVcbiAgICAgICBsb3ctcmVzIHJlbmRlciBmb3IgdGhlIGZpbmFsIGltYWdlLiAtLT5cbiAgICA8ZGl2ICpuZ0lmPVwicmVuZGVyLnNoYXJwZW5pbmcgJiYgIWltZ0xvYWRpbmcoKSAmJiAhc3RhY2tMb2FkaW5nKCkgJiYgIWlzQ2FjaGluZygpXCIgY2xhc3M9XCJzaGFycGVuaW5nLW92ZXJsYXlcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJzcGlubmVyXCI+PC9kaXY+XG4gICAgICA8c3BhbiBjbGFzcz1cInRleHQtbG9hZGluZ1wiPlNoYXJwZW5pbmcgcHJldmlldy4uLjwvc3Bhbj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj5cblxuPCEtLSBGbG9hdGluZywgZHJhZ2dhYmxlIGludGVuc2l0eS1wcm9maWxlIGluc2V0LCBzaG93biB3aGlsZSBhbnkgaW50ZW5zaXR5IGxpbmVcbiAgICAgZXhpc3RzLiBLZXB0IE9VVFNJREUgdGhlIHBsb3QgZGl2IGFuZCBmaXhlZCB0byB0aGUgdmlld3BvcnQsIHNvIGl0IGZsb2F0cyBvdmVyXG4gICAgIHRoZSB3aG9sZSBwYWdlIHJhdGhlciB0aGFuIGJlaW5nIGNsaXBwZWQgdG8gdGhlIGNhbnZhcy4gLS0+XG48dml6LWludGVuc2l0eS1pbnNldFxuICBbZGl2SWRdPVwiaW50ZW5zaXR5SW5zZXREaXZcIlxuICBbcGxvdERpdk5hbWVdPVwicGxvdERpdk5hbWVcIlxuICBbekluZGV4XT1cInpJbmRleFwiXG4gIFtpbWFnZVZpZXddPVwiaXNJbWFnZVZpZXdcIlxuICBbaW1hZ2VJbmZvXT1cImltYWdlSW5mb1wiXG4+PC92aXotaW50ZW5zaXR5LWluc2V0PlxuXG48IS0tIENoYW5uZWxzICYgSGlzdG9ncmFtOiBub24tbW9kYWwgZmxvYXRpbmcgZGlhbG9nIG9wZW5lZCBmcm9tIHRoZSB0b29sYmFyLiAtLT5cbjxjaGFubmVsLWhpc3RvZ3JhbSBbKHZpc2libGUpXT1cInNob3dDaGFubmVsSGlzdG9ncmFtXCI+PC9jaGFubmVsLWhpc3RvZ3JhbT5cblxuPCEtLSBTcGF0aWFsLW9taWNzIGNvbnRyb2xzLiBSZW5kZXJzIGl0cyBvd24gZW1wdHkgc3RhdGUgd2hlbiBubyBkYXRhc2V0IChvciBub1xuICAgICBTUEFUSUFMX0RBVEFfUE9SVCkgaXMgcHJlc2VudCwgc28gaXQgaXMgYWx3YXlzIHNhZmUgdG8gaG9zdC4gLS0+XG48c3BhdGlhbC1jb250cm9scyBbKHZpc2libGUpXT1cInNob3dTcGF0aWFsQ29udHJvbHNcIiBbaXMzZF09XCJpc1NwYXRpYWwzZE1vZGVcIj48L3NwYXRpYWwtY29udHJvbHM+XG5cbjwhLS0gU2lkZSBwYW5lbCBvZiB0aGUgYWN0aXZlIGNvbnRyaWJ1dGVkIHBsb3QgbW9kZSAoUExPVF9UWVBFX0NPTlRSSUJVVElPTlMpLFxuICAgICBpbiB0aGUgc2FtZSByaWdodC1oYW5kIGFyZWEgYXMgdGhlIHNwYXRpYWwgY29udHJvbHMgYW5kIHRoZSBSZWdpb24gRWRpdG9yLlxuICAgICBFeGlzdHMgb25seSB3aGlsZSB0aGUgbW9kZSdzIHNlc3Npb24gaXMgbGl2ZTsgdGhlcmUgaXMgbm8gY2xvc2UgYnV0dG9uLFxuICAgICBiZWNhdXNlIGxlYXZpbmcgdGhlIG1vZGUgaXMgd2hhdCBlbmRzIGl0LiBBIGNvbXBvbmVudCBwYW5lbCBnZXRzXG4gICAgIFBMT1RfTU9ERV9DT05URVhUIC8gUExPVF9NT0RFX1NFU1NJT04gZnJvbSBpdHMgaW5qZWN0b3I7IGEgYG1vdW50YCBwYW5lbCdzXG4gICAgIGhvc3QgZWxlbWVudCBpcyBhdHRhY2hlZCB0byB0aGUgc2xvdCBiZWxvdyAoc2VlIHBsb3RNb2RlUGFuZWxTbG90KS4gLS0+XG48cC1kaWFsb2dcbiAgKm5nSWY9XCJwbG90TW9kZVBhbmVsIGFzIHBhbmVsXCJcbiAgW2hlYWRlcl09XCJwYW5lbC50aXRsZVwiXG4gIFt2aXNpYmxlXT1cInRydWVcIlxuICBbbW9kYWxdPVwiZmFsc2VcIlxuICBbY2xvc2FibGVdPVwiZmFsc2VcIlxuICBbcmVzaXphYmxlXT1cInRydWVcIlxuICBbZHJhZ2dhYmxlXT1cInRydWVcIlxuICBhcHBlbmRUbz1cImJvZHlcIlxuICBwb3NpdGlvbj1cInJpZ2h0XCJcbiAgc3R5bGVDbGFzcz1cInBsb3QtbW9kZS1wYW5lbFwiXG4gIFtzdHlsZV09XCJ7IHdpZHRoOiAnMjJyZW0nLCBtYXhIZWlnaHQ6ICc4NXZoJyB9XCJcbiAgW2NvbnRlbnRTdHlsZV09XCJ7IG92ZXJmbG93OiAnYXV0bycgfVwiXG4+XG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJwYW5lbC5jb21wb25lbnRcIj5cbiAgICA8bmctY29udGFpbmVyICpuZ0NvbXBvbmVudE91dGxldD1cInBhbmVsLmNvbXBvbmVudDsgaW5qZWN0b3I6IHBhbmVsLmluamVjdG9yID8/IHVuZGVmaW5lZFwiPjwvbmctY29udGFpbmVyPlxuICA8L25nLWNvbnRhaW5lcj5cbiAgPGRpdiAqbmdJZj1cInBhbmVsLmhvc3RcIiAjcGxvdE1vZGVQYW5lbFNsb3QgY2xhc3M9XCJwbG90LW1vZGUtcGFuZWwtc2xvdFwiPjwvZGl2PlxuPC9wLWRpYWxvZz5cblxuPCEtLSBBbiBvcGVuIGRpYWxvZyB0b29sIChUT09MQkFSX1RPT0xTLCBraW5kOiAnZGlhbG9nJykuIE5vbi1tb2RhbCBzbyB0aGUgdXNlciBjYW5cbiAgICAga2VlcCB3b3JraW5nIG9uIHRoZSBpbWFnZSwgZS5nLiBwYWludGluZyB3aXRoIHRoZSBicnVzaCB0aGUgdG9vbCBhcm1lZC4gVGhlXG4gICAgIHRvb2wgcmVuZGVycyBpdHMgYm9keSBpbnRvIGEgaG9zdCBlbGVtZW50IGF0dGFjaGVkIHRvIHRoZSBzbG90IGJlbG93IChzZWVcbiAgICAgdG9vbERpYWxvZ1Nsb3QpOyBjbG9zaW5nIHRoZSBkaWFsb2cgZW5kcyB0aGUgdG9vbCdzIHNlc3Npb24uIC0tPlxuPHAtZGlhbG9nXG4gICpuZ0lmPVwidG9vbERpYWxvZyBhcyBkbGdcIlxuICBbaGVhZGVyXT1cImRsZy50aXRsZVwiXG4gIFt2aXNpYmxlXT1cInRydWVcIlxuICAodmlzaWJsZUNoYW5nZSk9XCIkZXZlbnQgfHwgY2xvc2VEaWFsb2dUb29sKClcIlxuICBbbW9kYWxdPVwiZmFsc2VcIlxuICBbY2xvc2FibGVdPVwidHJ1ZVwiXG4gIFtyZXNpemFibGVdPVwidHJ1ZVwiXG4gIFtkcmFnZ2FibGVdPVwidHJ1ZVwiXG4gIGFwcGVuZFRvPVwiYm9keVwiXG4gIHBvc2l0aW9uPVwicmlnaHRcIlxuICBzdHlsZUNsYXNzPVwidG9vbC1kaWFsb2dcIlxuICBbc3R5bGVdPVwieyB3aWR0aDogZGxnLndpZHRoLCBtYXhIZWlnaHQ6ICc4NXZoJyB9XCJcbiAgW2NvbnRlbnRTdHlsZV09XCJ7IG92ZXJmbG93OiAnYXV0bycgfVwiXG4+XG4gIDxkaXYgI3Rvb2xEaWFsb2dTbG90IGNsYXNzPVwidG9vbC1kaWFsb2ctc2xvdFwiPjwvZGl2PlxuPC9wLWRpYWxvZz5cblxuPCEtLSBSZWdpb24gRWRpdG9yOiBub24tbW9kYWwsIGRyYWdnYWJsZSwgcmVzaXphYmxlIGZsb2F0aW5nIGRpYWxvZyBvcGVuZWQgZnJvbVxuICAgICB0aGUgdG9vbGJhciAoZm9ybWVybHkgdGhlIHJpZ2h0LXBhbmVsIFJlZ2lvbnMgdGFiKS4gTW9kZWxlc3Mgc28gcmVnaW9ucyBjYW5cbiAgICAgc3RpbGwgYmUgZHJhd24vc2VsZWN0ZWQgb24gdGhlIHBsb3Qgd2hpbGUgaXQncyBvcGVuOyBzdGF5cyBsaW5rZWQgdG8gdGhpc1xuICAgICBwbG90dGluZyBpbnN0YW5jZSB2aWEgdGhlIHJvb3QgUmVnaW9uU3RvcmUgc2luZ2xldG9uLiBPcGVucyBvdmVyIHRoZSByaWdodFxuICAgICBzaWRlIG9mIHRoZSB2aWV3LiAtLT5cbjxwLWRpYWxvZ1xuICBoZWFkZXI9XCJSZWdpb24gRWRpdG9yXCJcbiAgWyh2aXNpYmxlKV09XCJzaG93UmVnaW9uRWRpdG9yXCJcbiAgW21vZGFsXT1cImZhbHNlXCJcbiAgW3Jlc2l6YWJsZV09XCJ0cnVlXCJcbiAgW2RyYWdnYWJsZV09XCJ0cnVlXCJcbiAgW21heGltaXphYmxlXT1cInRydWVcIlxuICBhcHBlbmRUbz1cImJvZHlcIlxuICBwb3NpdGlvbj1cInJpZ2h0XCJcbiAgW3N0eWxlXT1cInsgd2lkdGg6IHJlZ2lvbkVkaXRvcldpZHRoLCBoZWlnaHQ6ICc4NXZoJyB9XCJcbiAgW2NvbnRlbnRTdHlsZV09XCJ7IG92ZXJmbG93OiAnYXV0bycgfVwiXG4+XG4gIDxyZWdpb24tZWRpdG9yIFthY3RpdmVdPVwic2hvd1JlZ2lvbkVkaXRvclwiPjwvcmVnaW9uLWVkaXRvcj5cbjwvcC1kaWFsb2c+XG5cbjwhLS0gU2ltcGxpZnkgKERvdWdsYXPigJNQZXVja2VyKTogY3VzdG9tIHB4LXRocmVzaG9sZCBwaWNrZXIgZm9yIHRoZSBzZWxlY3RlZFxuICAgICByZWdpb24ocyksIG9wZW5lZCBmcm9tIHRoZSByaWdodC1jbGljayBcIlNpbXBsaWZ5IOKWuCBDdXN0b23igKZcIiBhY3Rpb24uIC0tPlxuPHAtZGlhbG9nXG4gIGhlYWRlcj1cIlNpbXBsaWZ5IHJlZ2lvbihzKVwiXG4gIFsodmlzaWJsZSldPVwiZGlzcGxheVNpbXBsaWZ5RGlhbG9nXCJcbiAgW21vZGFsXT1cInRydWVcIlxuICBbc3R5bGVdPVwieyB3aWR0aDogJzIycmVtJyB9XCJcbiAgW2RyYWdnYWJsZV09XCJmYWxzZVwiXG4gIFtyZXNpemFibGVdPVwiZmFsc2VcIlxuPlxuICA8ZGl2IGNsYXNzPVwiZmxleCBmbGV4LWNvbHVtbiBnYXAtMlwiPlxuICAgIDxzcGFuXG4gICAgICA+QWx0aXR1ZGUgdGhyZXNob2xkOiA8Yj57eyByZWdpb25BY3Rpb25zLnNpbXBsaWZ5VGhyZXNob2xkIH19IHB4PC9iPjwvc3BhblxuICAgID5cbiAgICA8cC1zbGlkZXIgWyhuZ01vZGVsKV09XCJyZWdpb25BY3Rpb25zLnNpbXBsaWZ5VGhyZXNob2xkXCIgW21pbl09XCIxXCIgW21heF09XCIyMFwiIFtzdGVwXT1cIjFcIj48L3Atc2xpZGVyPlxuICAgIDxzbWFsbD5WZXJ0aWNlcyB3aXRoaW4gdGhpcyBkaXN0YW5jZSBvZiB0aGUgbGluZSBiZXR3ZWVuIHRoZWlyIG5laWdoYm91cnMgYXJlIHJlbW92ZWQuPC9zbWFsbD5cbiAgPC9kaXY+XG4gIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJmb290ZXJcIj5cbiAgICA8cC1idXR0b24gbGFiZWw9XCJDYW5jZWxcIiBbdGV4dF09XCJ0cnVlXCIgKG9uQ2xpY2spPVwiZGlzcGxheVNpbXBsaWZ5RGlhbG9nID0gZmFsc2VcIj48L3AtYnV0dG9uPlxuICAgIDxwLWJ1dHRvblxuICAgICAgbGFiZWw9XCJBcHBseVwiXG4gICAgICBpY29uPVwicGkgcGktY2hlY2tcIlxuICAgICAgKG9uQ2xpY2spPVwic2ltcGxpZnlSZWdpb25zKHJlZ2lvbkFjdGlvbnMuc2ltcGxpZnlUaHJlc2hvbGQpXCJcbiAgICA+PC9wLWJ1dHRvbj5cbiAgPC9uZy10ZW1wbGF0ZT5cbjwvcC1kaWFsb2c+XG5cbjwhLS0gUGFyYW1ldGVycyBmb3Igd2hpY2hldmVyIGNvbnRyaWJ1dGVkIHRvb2wgaXMgb3Blbi4gT25lIGRpYWxvZyBmb3IgYWxsIG9mXG4gICAgIHRoZW06IGEgdG9vbCBkZWNsYXJlcyBpdHMgZmllbGRzIChUb29sUGFyYW1TcGVjKSBhbmQgdGhpcyByZW5kZXJzIHRoZW0sIHNvXG4gICAgIHRoZSB0b29sYmFyIGNhbiBsYXkgZXZlcnkgdG9vbCBvdXQgdGhlIHNhbWUgd2F5IGFuZCBhIHBsdWdpbiBuZWVkcyBub1xuICAgICBQcmltZU5HIG9mIGl0cyBvd24uIERlZmF1bHRzIGNvbWUgZnJvbSB0aGUgYWN0aXZlIGNoZWNrcG9pbnQsIHNpbmNlIHRoZXlcbiAgICAgZW5jb2RlIHdoYXQgaXQgd2FzIHRyYWluZWQgZm9yLiAtLT5cbjxwLWRpYWxvZ1xuICAqbmdJZj1cInRvb2xQYXJhbXMub3BlblBhcmFtcyBhcyBvcGVuXCJcbiAgW2hlYWRlcl09XCJvcGVuLnRvb2wubGFiZWwgKyAnIHBhcmFtZXRlcnMnXCJcbiAgW3Zpc2libGVdPVwidHJ1ZVwiXG4gICh2aXNpYmxlQ2hhbmdlKT1cImNsb3NlVG9vbFBhcmFtcygpXCJcbiAgW21vZGFsXT1cInRydWVcIlxuICBbc3R5bGVdPVwieyB3aWR0aDogJzMwcmVtJyB9XCJcbiAgW2RyYWdnYWJsZV09XCJmYWxzZVwiXG4gIFtyZXNpemFibGVdPVwiZmFsc2VcIlxuICBhcHBlbmRUbz1cImJvZHlcIlxuPlxuICA8ZGl2IGNsYXNzPVwiZ3JpZCBmb3JtZ3JpZCBwLWZsdWlkXCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgZiBvZiBvcGVuLmZpZWxkc1wiPlxuICAgICAgPGRpdiBjbGFzcz1cImZpZWxkXCIgW25nQ2xhc3NdPVwiZi5zcGVjLnR5cGUgPT09ICdib29sZWFuJyA/ICdjb2wtMTInIDogJ2NvbC02J1wiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiZi5udW1iZXIgYXMgblwiPlxuICAgICAgICAgIDxsYWJlbCBjbGFzcz1cInRleHQtc21cIiBbcFRvb2x0aXBdPVwibi50b29sdGlwIHx8ICcnXCI+e3sgbi5sYWJlbCB9fTwvbGFiZWw+XG4gICAgICAgICAgPHAtaW5wdXROdW1iZXJcbiAgICAgICAgICAgIFtuZ01vZGVsXT1cIm9wZW4udmFsdWVzW24uaWRdXCJcbiAgICAgICAgICAgIChuZ01vZGVsQ2hhbmdlKT1cIm9wZW4udmFsdWVzW24uaWRdID0gJGV2ZW50XCJcbiAgICAgICAgICAgIFttaW5dPVwibi5taW5cIlxuICAgICAgICAgICAgW21heF09XCJuLm1heFwiXG4gICAgICAgICAgICBbc3RlcF09XCJuLnN0ZXBcIlxuICAgICAgICAgICAgW21pbkZyYWN0aW9uRGlnaXRzXT1cIm4uZnJhY3Rpb25EaWdpdHNcIlxuICAgICAgICAgICAgW3Nob3dCdXR0b25zXT1cInRydWVcIlxuICAgICAgICAgID48L3AtaW5wdXROdW1iZXI+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJmLnNlbGVjdCBhcyBzZWxcIj5cbiAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJ0ZXh0LXNtXCIgW3BUb29sdGlwXT1cInNlbC50b29sdGlwIHx8ICcnXCI+e3sgc2VsLmxhYmVsIH19PC9sYWJlbD5cbiAgICAgICAgICA8cC1kcm9wZG93blxuICAgICAgICAgICAgW29wdGlvbnNdPVwic2VsLm9wdGlvbnNcIlxuICAgICAgICAgICAgb3B0aW9uTGFiZWw9XCJsYWJlbFwiXG4gICAgICAgICAgICBvcHRpb25WYWx1ZT1cInZhbHVlXCJcbiAgICAgICAgICAgIFtuZ01vZGVsXT1cIm9wZW4udmFsdWVzW3NlbC5pZF1cIlxuICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwib3Blbi52YWx1ZXNbc2VsLmlkXSA9ICRldmVudFwiXG4gICAgICAgICAgICBhcHBlbmRUbz1cImJvZHlcIlxuICAgICAgICAgID48L3AtZHJvcGRvd24+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgIDwhLS0gQ2hlY2tib3ggbGFiZWwgc2l0cyBiZXNpZGUgdGhlIGJveCBhbmQgbWF5IHJ1biB0byBhIHNlbnRlbmNlLCBzb1xuICAgICAgICAgICAgIGl0IGRvZXMgbm90IGdldCB0aGUgc3RhY2tlZCBsYWJlbCB0aGUgb3RoZXIgdHlwZXMgdXNlLiAtLT5cbiAgICAgICAgPGRpdiAqbmdJZj1cImYuc3BlYy50eXBlID09PSAnYm9vbGVhbidcIiBjbGFzcz1cImZsZXggYWxpZ24taXRlbXMtY2VudGVyIGdhcC0yXCI+XG4gICAgICAgICAgPHAtY2hlY2tib3hcbiAgICAgICAgICAgIFtuZ01vZGVsXT1cIm9wZW4udmFsdWVzW2Yuc3BlYy5pZF1cIlxuICAgICAgICAgICAgKG5nTW9kZWxDaGFuZ2UpPVwib3Blbi52YWx1ZXNbZi5zcGVjLmlkXSA9ICRldmVudFwiXG4gICAgICAgICAgICBbYmluYXJ5XT1cInRydWVcIlxuICAgICAgICAgICAgW2lucHV0SWRdPVwib3Blbi50b29sLmlkICsgJy0nICsgZi5zcGVjLmlkXCJcbiAgICAgICAgICA+PC9wLWNoZWNrYm94PlxuICAgICAgICAgIDxsYWJlbCBbZm9yXT1cIm9wZW4udG9vbC5pZCArICctJyArIGYuc3BlYy5pZFwiIGNsYXNzPVwidGV4dC1zbSBtYi0wXCIgW3BUb29sdGlwXT1cImYuc3BlYy50b29sdGlwIHx8ICcnXCI+e3tcbiAgICAgICAgICAgIGYuc3BlYy5sYWJlbFxuICAgICAgICAgIH19PC9sYWJlbD5cbiAgICAgICAgPC9kaXY+XG4gICAgICA8L2Rpdj5cbiAgICA8L25nLWNvbnRhaW5lcj5cbiAgPC9kaXY+XG4gIDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJmb290ZXJcIj5cbiAgICA8cC1idXR0b25cbiAgICAgIGxhYmVsPVwiUmVzZXQgdG8gbW9kZWwgZGVmYXVsdHNcIlxuICAgICAgW3RleHRdPVwidHJ1ZVwiXG4gICAgICBzaXplPVwic21hbGxcIlxuICAgICAgKG9uQ2xpY2spPVwicmVzZXRUb29sUGFyYW1zKG9wZW4udG9vbC5pZClcIlxuICAgID48L3AtYnV0dG9uPlxuICAgIDxwLWJ1dHRvbiBsYWJlbD1cIkNsb3NlXCIgc2l6ZT1cInNtYWxsXCIgKG9uQ2xpY2spPVwiY2xvc2VUb29sUGFyYW1zKClcIj48L3AtYnV0dG9uPlxuICA8L25nLXRlbXBsYXRlPlxuPC9wLWRpYWxvZz5cbiJdfQ==
|
|
1357
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlzdWFsaXplci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvbGliL3Zpc3VhbGl6ZXIuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vc3JjL2xpYi92aXN1YWxpemVyLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFFTCx1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFNBQVMsRUFDVCxVQUFVLEVBQ1YsVUFBVSxFQUNWLFlBQVksRUFDWixNQUFNLEVBQ04sUUFBUSxFQUNSLEtBQUssRUFDTCxNQUFNLEVBSU4sUUFBUSxFQUNSLE1BQU0sRUFFTixTQUFTLEVBQ1QsUUFBUSxFQUNSLE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUU3QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRWxDLE9BQU8sRUFBWSxjQUFjLEVBQUUsWUFBWSxFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQ3JFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3JFLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDbEQsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0scUJB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QUFxQjs7MkZBTVosbUJBQW1CO2tCQTdCL0IsU0FBUzsrQkFDRSxZQUFZLGNBQ1YsSUFBSSxXQUNQO3dCQUNQLFlBQVk7d0JBQ1osV0FBVzt3QkFDWCxZQUFZO3dCQUNaLFlBQVk7d0JBQ1osY0FBYzt3QkFDZCxpQkFBaUI7d0JBQ2pCLFlBQVk7d0JBQ1osY0FBYzt3QkFDZCxpQkFBaUI7d0JBQ2pCLGlCQUFpQjt3QkFDakIsWUFBWTt3QkFDWixXQUFXO3dCQUNYLGFBQWE7d0JBQ2IscUJBQXFCO3dCQUNyQixnQkFBZ0I7d0JBQ2hCLHVCQUF1Qjt3QkFDdkIsb0JBQW9CO3dCQUNwQix5QkFBeUI7d0JBQ3pCLHdCQUF3Qjt3QkFDeEIscUJBQXFCO3FCQUN0QixtQkFHZ0IsdUJBQXVCLENBQUMsTUFBTTs7MEJBOGM1QyxNQUFNOzJCQUFDLGdCQUFnQjs7MEJBQ3ZCLE1BQU07MkJBQUMsVUFBVTs7MEJBU2pCLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsVUFBVTs7MEJBSTdCLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsYUFBYTs7MEJBR2hDLFFBQVE7OzBCQUFJLE1BQU07MkJBQUMsaUJBQWlCOzswQkFHcEMsUUFBUTs7MEJBQUksTUFBTTsyQkFBQyx1QkFBdUI7OzBCQUcxQyxRQUFROzswQkFFUixRQUFRO2tFQS9iWCxZQUFZO3NCQURYLE1BQU07Z0JBSVAsZ0JBQWdCO3NCQURmLE1BQU07Z0JBTUgsWUFBWTtzQkFEZixLQUFLO2dCQWNOLFFBQVE7c0JBRFAsS0FBSztnQkErQ1csV0FBVztzQkFBM0IsU0FBUzt1QkFBQyxJQUFJO2dCQXNMWCxpQkFBaUI7c0JBRHBCLFNBQVM7dUJBQUMsbUJBQW1CO2dCQThCd0IsS0FBSztzQkFBMUQsU0FBUzt1QkFBQyx1QkFBdUIsRUFBRSxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUU7Z0JBNDhCaEQsY0FBYztzQkFEakIsU0FBUzt1QkFBQyxnQkFBZ0IiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBBZnRlclZpZXdJbml0LFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gIENvbXBvbmVudCxcbiAgRGVzdHJveVJlZixcbiAgRWxlbWVudFJlZixcbiAgRXZlbnRFbWl0dGVyLFxuICBJbmplY3QsXG4gIEluamVjdG9yLFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkNoYW5nZXMsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPcHRpb25hbCxcbiAgT3V0cHV0LFxuICBTaW1wbGVDaGFuZ2VzLFxuICBWaWV3Q2hpbGQsXG4gIGNvbXB1dGVkLFxuICBzaWduYWwsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tICdAYW5ndWxhci9jb21tb24vaHR0cCc7XG5pbXBvcnQgeyBGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcblxuaW1wb3J0IHsgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBNZW51SXRlbSwgTWVzc2FnZVNlcnZpY2UsIFNoYXJlZE1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvYXBpJztcbmltcG9ydCB7IEJ1dHRvbk1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvYnV0dG9uJztcbmltcG9ydCB7IENoZWNrYm94TW9kdWxlIH0gZnJvbSAncHJpbWVuZy9jaGVja2JveCc7XG5pbXBvcnQgeyBDb250ZXh0TWVudSwgQ29udGV4dE1lbnVNb2R1bGUgfSBmcm9tICdwcmltZW5nL2NvbnRleHRtZW51JztcbmltcG9ydCB7IERpYWxvZ01vZHVsZSB9IGZyb20gJ3ByaW1lbmcvZGlhbG9nJztcbmltcG9ydCB7IERyb3Bkb3duTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9kcm9wZG93bic7XG5pbXBvcnQgeyBJbnB1dE51bWJlck1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvaW5wdXRudW1iZXInO1xuaW1wb3J0IHsgUHJvZ3Jlc3NCYXJNb2R1bGUgfSBmcm9tICdwcmltZW5nL3Byb2dyZXNzYmFyJztcbmltcG9ydCB7IFNsaWRlck1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvc2xpZGVyJztcbmltcG9ydCB7IFRvYXN0TW9kdWxlIH0gZnJvbSAncHJpbWVuZy90b2FzdCc7XG5pbXBvcnQgeyBUb29sdGlwTW9kdWxlIH0gZnJvbSAncHJpbWVuZy90b29sdGlwJztcbmltcG9ydCB7IElJbWFnZUluZm8gfSBmcm9tICcuL2NvbnRyYWN0cy9pbWFnZS5jb250cmFjdCc7XG5pbXBvcnQgeyBJbWFnZVN0YXRlUG9ydCwgSU1BR0VfU1RBVEVfUE9SVCB9IGZyb20gJy4vY29udHJhY3RzL3BvcnRzL2ltYWdlLXN0YXRlLnBvcnQnO1xuaW1wb3J0IHsgUG9seWdvbiB9IGZyb20gJy4vbW9kZWxzL3JlZ2lvbic7XG5pbXBvcnQgeyBSZWdpb25PcHNTZXJ2aWNlIH0gZnJvbSAnLi9yZWdpb24tb3BzLnNlcnZpY2UnO1xuaW1wb3J0IHsgVklaX1RPQVNUX0tFWSwgVklaX0FMRVJUX1RPQVNUX0tFWSB9IGZyb20gJy4vdG9hc3Qtb3V0bGV0cyc7XG5pbXBvcnQgeyBWaXN1YWxpemVyU3RvcmUgfSBmcm9tICcuL3N0b3JlL3Zpc3VhbGl6ZXItc3RvcmUuc2VydmljZSc7XG5pbXBvcnQgeyBTbGljZVNjcnViYmVyIH0gZnJvbSAnLi9yZW5kZXItb3JjaGVzdHJhdG9yJztcbmltcG9ydCB7IEltYWdlUmVuZGVyU2Vzc2lvbiwgZXJyb3JNZXNzYWdlIH0gZnJvbSAnLi9yZW5kZXItc2Vzc2lvbic7XG5pbXBvcnQge1xuICBQbG90VHlwZSxcbiAgUGxvdFR5cGVEZXNjcmlwdG9yLFxuICBQbG90VHlwZUlkLFxuICBnZXRQbG90VHlwZURlc2NyaXB0b3IsXG4gIGlzQnVpbHRpblBsb3RUeXBlLFxuICBpc05hcGFyaTNkLFxuICBpc1NwYXRpYWxPbWljcyxcbiAgaXNTcGF0aWFsT21pY3MzZCxcbiAgcmVuZGVyZXJPd25zV2hlZWwsXG4gIE5BUEFSSV9ERUZBVUxUX0RFQ0lNQVRFLFxuICBpc05hcGFyaVZvbHVtZSxcbiAgaXNOYXBhcmlJc29zdXJmYWNlLFxufSBmcm9tICcuL2NvbnRyYWN0cy9wbG90LXR5cGUnO1xuaW1wb3J0IHtcbiAgUExPVF9UWVBFX0NPTlRSSUJVVElPTlMsXG4gIFBsb3RUeXBlQ29udHJpYnV0aW9uLFxuICBQbG90VHlwZU9wdGlvbixcbn0gZnJvbSAnLi9jb250cmFjdHMvcGxvdC10eXBlLWNvbnRyaWJ1dGlvbi5jb250cmFjdCc7XG5pbXBvcnQgeyBQbG90TW9kZUNvbnRyb2xsZXIgfSBmcm9tICcuL3Bsb3QtbW9kZS9wbG90LW1vZGUtY29udHJvbGxlcic7XG5pbXBvcnQgeyBjb21wdXRlUGxvdFR5cGVNZW51LCByZWNvbmNpbGVQbG90VHlwZSB9IGZyb20gJy4vcGxvdC1tb2RlL3Bsb3QtdHlwZS1tZW51JztcbmltcG9ydCB7IFRvb2xQYXJhbXNNb2RlbCB9IGZyb20gJy4vcGxvdC1tb2RlL3Rvb2wtcGFyYW1zLW1vZGVsJztcbmltcG9ydCB7IENvbnRyaWJ1dGlvbkhvc3QsIFBsb3RNb2RlUGFuZWxWaWV3LCBUb29sRGlhbG9nVmlldyB9IGZyb20gJy4vcGxvdC1tb2RlL2NvbnRyaWJ1dGlvbi1ob3N0JztcbmltcG9ydCB7IElWaXN1YWxpemVyLCBWSVNVQUxJWkVSLCBWaXN1YWxpemVySGFuZGxlIH0gZnJvbSAnLi9jb250cmFjdHMvdmlzdWFsaXplci5jb250cmFjdCc7XG5pbXBvcnQgeyBTQU1fTU9ERUxTLCBnZXREZWZhdWx0U2FtTW9kZWxJZCwgaXNTYW1Nb2RlbFJlYWR5IH0gZnJvbSAnLi90b29sYmFyL3NlZ21lbnRhdGlvbi9zYW0tbW9kZWwtcmVnaXN0cnknO1xuaW1wb3J0IHsgU2FtVG9vbFNlcnZpY2UgfSBmcm9tICcuL3Rvb2xiYXIvc2VnbWVudGF0aW9uL3NhbS10b29sLnNlcnZpY2UnO1xuaW1wb3J0IHsgU2FtUG9pbnRUb29sU2VydmljZSB9IGZyb20gJy4vdG9vbGJhci9zZWdtZW50YXRpb24vc2FtLXBvaW50LXRvb2wuc2VydmljZSc7XG5pbXBvcnQgeyBDZWxsU2VnbWVudFRvb2xTZXJ2aWNlIH0gZnJvbSAnLi90b29sYmFyL3NlZ21lbnRhdGlvbi9jZWxsLXNlZ21lbnQtdG9vbC5zZXJ2aWNlJztcbmltcG9ydCB7IFNlZ21lbnRhdGlvblJ1bm5lciB9IGZyb20gJy4vdG9vbGJhci9zZWdtZW50YXRpb24vc2VnbWVudGF0aW9uLXJ1bm5lcic7XG5pbXBvcnQge1xuICBUT09MQkFSX1RPT0xTLFxuICBUb29sYmFyQ29udHJpYnV0aW9uLFxuICBUb29sYmFyRGlhbG9nVG9vbENvbnRyaWJ1dGlvbixcbiAgVG9vbGJhclRvb2xDb250cmlidXRpb24sXG4gIHZpc2libGVUb29sQ29udHJpYnV0aW9ucyxcbn0gZnJvbSAnLi9jb250cmFjdHMvdG9vbGJhci10b29sLmNvbnRyYWN0JztcbmltcG9ydCB7IFRvb2xiYXJUb29sVmlzaWJpbGl0eSwgQUxMX1RPT0xCQVJfVE9PTFMgfSBmcm9tICcuL2NvbnRyYWN0cy90b29sYmFyLWNvbmZpZyc7XG5pbXBvcnQgeyBWSVpfQ09ORklHLCBWaXpDb25maWcgfSBmcm9tICcuL2NvbnRyYWN0cy92aXotY29uZmlnJztcbmltcG9ydCB7IFNQQVRJQUxfREFUQV9QT1JULCBTcGF0aWFsRGF0YVBvcnQgfSBmcm9tICcuL2NvbnRyYWN0cy9wb3J0cy9zcGF0aWFsLWRhdGEucG9ydCc7XG5pbXBvcnQgeyBhcHBseUltYWdlUm9pcyB9IGZyb20gJy4vdmlzdWFsaXplci9yZWdpb24tbG9hZCc7XG5pbXBvcnQgeyBDb250ZXh0TWVudUFjdGlvbnMsIENvbnRleHRNZW51U3RhdGUsIGJ1aWxkQ29udGV4dE1lbnUgfSBmcm9tICcuL3Zpc3VhbGl6ZXIvdmlzdWFsaXplci1jb250ZXh0LW1lbnUnO1xuaW1wb3J0IHsgUmVnaW9uQWN0aW9ucyB9IGZyb20gJy4vdmlzdWFsaXplci9yZWdpb24tYWN0aW9ucyc7XG5pbXBvcnQgeyBUb29sTW9kZXMgfSBmcm9tICcuL3Zpc3VhbGl6ZXIvdG9vbC1tb2Rlcyc7XG5pbXBvcnQgeyBTaG9ydGN1dEhvc3QsIFZpZXdlclNob3J0Y3V0cyB9IGZyb20gJy4vdmlzdWFsaXplci92aWV3ZXItc2hvcnRjdXRzJztcbmltcG9ydCB7IEZsb2F0aW5nRHJhZ0RpcmVjdGl2ZSwgRmxvYXRpbmdQb3MgfSBmcm9tICcuL3Zpc3VhbGl6ZXIvZmxvYXRpbmctZHJhZy5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgSW50ZW5zaXR5SW5zZXRDb21wb25lbnQgfSBmcm9tICcuL2ludGVuc2l0eS1pbnNldC9pbnRlbnNpdHktaW5zZXQuY29tcG9uZW50JztcbmltcG9ydCB7IFNlY3Rpb25QYW5lQ29tcG9uZW50IH0gZnJvbSAnLi9zZWN0aW9uLXBhbmUvc2VjdGlvbi1wYW5lLmNvbXBvbmVudCc7XG5pbXBvcnQgdHlwZSB7IFNlY3Rpb25BeGlzLCBTZWN0aW9uVmlld3MgfSBmcm9tICcuL2NvbnRyYWN0cy9zZWN0aW9uLXZpZXcuY29udHJhY3QnO1xuaW1wb3J0IHsgU3BhdGlhbERhdGFzZXRCaW5kZXIgfSBmcm9tICcuL3Zpc3VhbGl6ZXIvc3BhdGlhbC1kYXRhc2V0LWJpbmRlcic7XG5pbXBvcnQgeyBTcGF0aWFsUmVnaW9uU2V0TGluayB9IGZyb20gJy4vdmlzdWFsaXplci9zcGF0aWFsLXJlZ2lvbi1zZXQnO1xuaW1wb3J0IHsgVG9vbGJhckNvbXBvbmVudCB9IGZyb20gJy4vdG9vbGJhci90b29sYmFyLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBSZWdpb25FZGl0b3JDb21wb25lbnQgfSBmcm9tICcuL3JlZ2lvbi1lZGl0b3IvcmVnaW9uLWVkaXRvci5jb21wb25lbnQnO1xuaW1wb3J0IHsgQ2hhbm5lbEhpc3RvZ3JhbUNvbXBvbmVudCB9IGZyb20gJy4vY2hhbm5lbC1oaXN0b2dyYW0vY2hhbm5lbC1oaXN0b2dyYW0uY29tcG9uZW50JztcbmltcG9ydCB7IFNwYXRpYWxDb250cm9sc0NvbXBvbmVudCB9IGZyb20gJy4vc3BhdGlhbC1jb250cm9scy9zcGF0aWFsLWNvbnRyb2xzLmNvbXBvbmVudCc7XG5cbi8qKiBQZXItaW5zdGFuY2UgcGxvdC1kaXYgaWQgc291cmNlLiBUaGUgbW91bnQgZWxlbWVudCdzIGlkIG11c3QgYmUgdW5pcXVlIHNvIHR3b1xuICogIGxpdmUgdmlld2VycyAoZS5nLiB0aGUgbWFpbiBkaWFncmFtICsgYSBtb2RhbCBwcmV2aWV3KSBkb24ndCBjb2xsaWRlIG9uIHRoZVxuICogIHNhbWUgRE9NIGlkIOKAlCBgZ2V0RWxlbWVudEJ5SWRgIHdvdWxkIG90aGVyd2lzZSByZXR1cm4gd2hpY2hldmVyIGNhbWUgZmlyc3QuXG4gKiAgU3R5bGluZyBoYW5ncyBvZmYgdGhlIGAudml6LXBsb3RgIGNsYXNzIGluc3RlYWQgb2YgdGhlIGlkLiAqL1xubGV0IHBsb3RJbnN0YW5jZVNlcSA9IDA7XG5cbi8qKlxuICogVGhlIHZpZXdlciAoYDx2aXN1YWxpemVyPmApOiB0aGUgcGxvdCBzdXJmYWNlLCBpdHMgdG9vbGJhciwgdGhlIGxvYWRpbmcgb3ZlcmxheSBhbmRcbiAqIHRoZSBkaWFsb2dzIGl0IG9wZW5zIChDaGFubmVscyAmIEhpc3RvZ3JhbSwgc3BhdGlhbC1vbWljcyBjb250cm9scywgUmVnaW9uIEVkaXRvcixcbiAqIGNvbnRyaWJ1dGVkIG1vZGVzIGFuZCB0b29scykuIEl0IG9yY2hlc3RyYXRlcyByZW5kZXJpbmcgdGhyb3VnaCB0aGUgYFZJU1VBTElaRVJgXG4gKiBjb250cmFjdCBhbmQgcmVhZHMgdGhlIGltYWdlIGZyb20gdGhlIGhvc3QncyBgSU1BR0VfU1RBVEVfUE9SVGAuXG4gKlxuICogT25QdXNoLiBUZW1wbGF0ZSBldmVudHMgcmUtcmVuZGVyIGl0OyBzdGF0ZSB0aGF0IGxhbmRzIGFzeW5jaHJvbm91c2x5IGdvZXMgdGhyb3VnaFxuICoge0BsaW5rIGNoYW5nZWR9IChvciBhIHNpZ25hbDogdGhlIGxvYWRpbmcgb3ZlcmxheSksIGFuZCB0aGUgY29sbGFib3JhdG9ycyB0aGF0IG11c3RcbiAqIHJlbmRlciBzeW5jaHJvbm91c2x5ICh0aGUgcmVuZGVyIHNlc3Npb24ncyBvdmVybGF5LCBhIGNvbnRyaWJ1dGVkIHBhbmVsJ3Mgc2xvdCwgdGhlXG4gKiBjb250ZXh0IG1lbnUgYmVmb3JlIGl0IG9wZW5zKSBzdGlsbCBjYWxsIGBkZXRlY3RDaGFuZ2VzKClgLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd2aXN1YWxpemVyJyxcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaW1wb3J0czogW1xuICAgIENvbW1vbk1vZHVsZSxcbiAgICBGb3Jtc01vZHVsZSxcbiAgICBTaGFyZWRNb2R1bGUsXG4gICAgQnV0dG9uTW9kdWxlLFxuICAgIENoZWNrYm94TW9kdWxlLFxuICAgIENvbnRleHRNZW51TW9kdWxlLFxuICAgIERpYWxvZ01vZHVsZSxcbiAgICBEcm9wZG93bk1vZHVsZSxcbiAgICBJbnB1dE51bWJlck1vZHVsZSxcbiAgICBQcm9ncmVzc0Jhck1vZHVsZSxcbiAgICBTbGlkZXJNb2R1bGUsXG4gICAgVG9hc3RNb2R1bGUsXG4gICAgVG9vbHRpcE1vZHVsZSxcbiAgICBGbG9hdGluZ0RyYWdEaXJlY3RpdmUsXG4gICAgVG9vbGJhckNvbXBvbmVudCxcbiAgICBJbnRlbnNpdHlJbnNldENvbXBvbmVudCxcbiAgICBTZWN0aW9uUGFuZUNvbXBvbmVudCxcbiAgICBDaGFubmVsSGlzdG9ncmFtQ29tcG9uZW50LFxuICAgIFNwYXRpYWxDb250cm9sc0NvbXBvbmVudCxcbiAgICBSZWdpb25FZGl0b3JDb21wb25lbnQsXG4gIF0sXG4gIHRlbXBsYXRlVXJsOiAnLi92aXN1YWxpemVyLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vdmlzdWFsaXplci5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgVmlzdWFsaXplckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25DaGFuZ2VzLCBBZnRlclZpZXdJbml0LCBPbkRlc3Ryb3ksIENvbnRleHRNZW51QWN0aW9ucyB7XG4gIC8qKiBQZXItaW5zdGFuY2UgdG9hc3Qga2V5LiBNZXNzYWdlU2VydmljZSBpcyBhIGdsb2JhbCBzaW5nbGV0b24sIHNvIHR3byBsaXZlXG4gICAqICBgPHZpc3VhbGl6ZXI+YCBpbnN0YW5jZXMgKG1haW4gdmlld2VyICsgcGlwZWxpbmUtZGlhbG9nIHByZXZpZXcpIHNoYXJpbmdcbiAgICogIG9uZSBrZXkgd291bGQgZWFjaCByZW5kZXIgdGhlIHNhbWUgbWVzc2FnZSDigJQgYSBkdXBsaWNhdGUgdG9hc3QuIEEgdW5pcXVlXG4gICAqICBrZXkgcGVyIGluc3RhbmNlIHNjb3BlcyB0aGUgdG9hc3QgdG8gdGhlIGNvbXBvbmVudCB0aGF0IHJhaXNlZCBpdC4gKi9cbiAgcHJpdmF0ZSBzdGF0aWMgbmV4dFRvYXN0SWQgPSAwO1xuXG4gIC8qKlxuICAgKiBUaGUgbGlicmFyeSBhbHNvIHJhaXNlcyBub3RpY2VzIGZyb20gcGxhY2VzIHRoYXQgaGF2ZSBubyBpbnN0YW5jZSBvZiB0aGVpclxuICAgKiBvd24gdG8ga2V5IGFnYWluc3Q6IHtAbGluayBQbG90bHlTZXJ2aWNlfSBpcyBgcHJvdmlkZWRJbjogJ3Jvb3QnYCwgYW5kIHRoZVxuICAgKiByZWdpb24gZWRpdG9yIGlzIGEgY2hpbGQgZGlhbG9nLiBUaG9zZSB1c2UgdGhlIGZpeGVkXG4gICAqIHtAbGluayBWSVpfVE9BU1RfS0VZfSAvIHtAbGluayBWSVpfQUxFUlRfVE9BU1RfS0VZfSBvdXRsZXRzLlxuICAgKlxuICAgKiBGb3IgdGhlIHNhbWUgcmVhc29uIHRoZSBwZXItaW5zdGFuY2Uga2V5IGFib3ZlIGV4aXN0cywgZXhhY3RseSBPTkUgbW91bnRlZFxuICAgKiB2aXN1YWxpemVyIG1heSByZW5kZXIgdGhvc2Ugc2hhcmVkIG91dGxldHMg4oCUIG90aGVyd2lzZSBhIG1lc3NhZ2UgZnJvbSB0aGVcbiAgICogcm9vdCBzZXJ2aWNlIHdvdWxkIGJlIHNob3duIG9uY2UgcGVyIGxpdmUgdmlld2VyIChqaXQtdWkgcnVucyBhIG1haW4gdmlld1xuICAgKiBhbmQgYSBwaXBlbGluZS1wcmV2aWV3IGF0IHRoZSBzYW1lIHRpbWUpLiBUaGUgZmlyc3QgdG8gaW5pdCBjbGFpbXMgdGhlbSBhbmRcbiAgICogcmVsZWFzZXMgb24gZGVzdHJveSwgc28gdGhlIHN1cnZpdmluZyB2aWV3ZXIgcGlja3MgdGhlbSB1cC5cbiAgICovXG4gIHByaXZhdGUgc3RhdGljIHJlYWRvbmx5IGxpdmVJbnN0YW5jZXMgPSBuZXcgU2V0PFZpc3VhbGl6ZXJDb21wb25lbnQ+KCk7XG4gIHByb3RlY3RlZCByZWFkb25seSB2aXpUb2FzdEtleSA9IFZJWl9UT0FTVF9LRVk7XG4gIHByb3RlY3RlZCByZWFkb25seSB2aXpBbGVydFRvYXN0S2V5ID0gVklaX0FMRVJUX1RPQVNUX0tFWTtcbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhpcyBpbnN0YW5jZSByZW5kZXJzIHRoZSBzaGFyZWQgb3V0bGV0cy4gVGhlIG93bmVyIGlzIHNpbXBseSB0aGVcbiAgICogb2xkZXN0IGxpdmUgdmlzdWFsaXplciDigJQgYSBgU2V0YCBpdGVyYXRlcyBpbiBpbnNlcnRpb24gb3JkZXIsIHNvIHdoZW4gdGhlXG4gICAqIG93bmVyIGlzIGRlc3Ryb3llZCB0aGUgbmV4dCBvbmUgdGFrZXMgb3ZlciBvbiBpdHMgZm9sbG93aW5nIGNoYW5nZS1kZXRlY3Rpb25cbiAgICogcGFzcy4gVHJhY2tpbmcgYSBzZXQgcmF0aGVyIHRoYW4gYSBzaW5nbGUgb3duZXIgbWF0dGVyczogd2l0aCBhIGxvbmVcbiAgICogYG93bmVyYCByZWZlcmVuY2UsIHRlYXJpbmcgZG93biB0aGUgb3duZXIgd2hpbGUgYSBzaWJsaW5nIHdhcyBhbHJlYWR5XG4gICAqIGluaXRpYWxpc2VkIHdvdWxkIGxlYXZlIG5vYm9keSByZW5kZXJpbmcgdGhlIG91dGxldHMsIGFuZCBldmVyeSBub3RpY2UgZnJvbVxuICAgKiB0aGUgcm9vdCBzZXJ2aWNlIHdvdWxkIHNpbGVudGx5IHZhbmlzaCBhZ2Fpbi5cbiAgICovXG4gIHByb3RlY3RlZCBnZXQgb3duc1NoYXJlZFRvYXN0cygpOiBib29sZWFuIHtcbiAgICBjb25zdCBvbGRlc3QgPSBWaXN1YWxpemVyQ29tcG9uZW50LmxpdmVJbnN0YW5jZXMudmFsdWVzKCkubmV4dCgpO1xuICAgIHJldHVybiAhb2xkZXN0LmRvbmUgJiYgb2xkZXN0LnZhbHVlID09PSB0aGlzO1xuICB9XG5cbiAgLyoqIEVhY2ggbmV3IGltYWdlOiB3aGV0aGVyIGl0IGlzIGEgei1zdGFjay4gKi9cbiAgQE91dHB1dCgpXG4gIGlzU3RhY2tFdmVudCA9IG5ldyBFdmVudEVtaXR0ZXIoZmFsc2UpO1xuICAvKiogRWFjaCBuZXcgaW1hZ2U6IHdoZXRoZXIgaXQgaXMgc2luZ2xlLWNoYW5uZWwgKGdyYXlzY2FsZSkuICovXG4gIEBPdXRwdXQoKVxuICBpc0dyYXlzY2FsZUV2ZW50ID0gbmV3IEV2ZW50RW1pdHRlcihmYWxzZSk7XG5cbiAgLyoqIFdoaWNoIHRvb2xiYXIgZ3JvdXBzIHRvIHNob3cuIEEgcGFydGlhbCBvdmVycmlkZSBtZXJnZXMgb3ZlciB0aGUgZnVsbCBzZXQsXG4gICAqICBzbyBgeyBzcGVjaWFsVG9vbHM6IGZhbHNlIH1gIGhpZGVzIG9ubHkgdGhhdCBncm91cC4gRGVmYXVsdHMgdG8gZXZlcnl0aGluZy4gKi9cbiAgQElucHV0KClcbiAgc2V0IHRvb2xiYXJUb29scyh2OiBUb29sYmFyVG9vbFZpc2liaWxpdHkgfCB1bmRlZmluZWQpIHtcbiAgICB0aGlzLl90b29sYmFyVG9vbHMgPSB7IC4uLkFMTF9UT09MQkFSX1RPT0xTLCAuLi4odiA/PyB7fSkgfTtcbiAgfVxuXG4gIGdldCB0b29sYmFyVG9vbHMoKTogUmVxdWlyZWQ8VG9vbGJhclRvb2xWaXNpYmlsaXR5PiB7XG4gICAgcmV0dXJuIHRoaXMuX3Rvb2xiYXJUb29scztcbiAgfVxuICBwcml2YXRlIF90b29sYmFyVG9vbHM6IFJlcXVpcmVkPFRvb2xiYXJUb29sVmlzaWJpbGl0eT4gPSBBTExfVE9PTEJBUl9UT09MUztcblxuICAvKiogRXhwb3NlIHRlc3Qtb25seSBwbG90IG1vZGVzIGluIHRoZSBzZWxlY3RvciAoZS5nLiB0aGUgbmFwYXJpIGBJbWFnZWBcbiAgICogIG1vZGUsIG90aGVyd2lzZSBoaWRkZW4pLiBUaGUgaG9zdCBhcHAgc2V0cyB0aGlzIGZyb20gYSBgP3Rlc3Q9MWAgVVJMXG4gICAqICB0b2dnbGUuIE9mZiBieSBkZWZhdWx0LCBzbyBwcm9kdWN0aW9uIHVzZXJzIG5ldmVyIHNlZSB0aGVtLiAqL1xuICBASW5wdXQoKVxuICB0ZXN0TW9kZSA9IGZhbHNlO1xuXG4gIC8qKiBJbWFnZS1zbW9vdGhpbmcgc3RhdGUgZm9yIHRoZSB0b29sYmFyJ3MgU21vb3RoZW4gdG9nZ2xlIChPU0Qgb25seSkuXG4gICAqICBEZWZhdWx0cyB0byBgZmFsc2VgIHNvIE9TRCBzaG93cyByYXcgcGl4ZWxzIChuZWFyZXN0LW5laWdoYm91cikuICovXG4gIHByb3RlY3RlZCBpbWFnZVNtb290aGluZ0VuYWJsZWQgPSBmYWxzZTtcbiAgZmlsZU5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBsb2FkZWRGaWxlTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICBwcm90ZWN0ZWQgaW1hZ2VJbmZvOiBJSW1hZ2VJbmZvIHwgdW5kZWZpbmVkO1xuXG4gIC8vIOKUgOKUgCBUaGUgbG9hZGluZyBvdmVybGF5LCBhcyBzaWduYWxzOiBpdCBpcyBmZWQgYnkgdGhlIGhvc3QncyBhbmQgdGhlIGJhY2tlbmRzJyBzdHJlYW1zXG4gIC8vIGFuZCBieSB0aGUgcmVuZGVyIHNlc3Npb24sIGFsbCBvZiB3aGljaCBsYW5kIG91dHNpZGUgdGhpcyB2aWV3J3MgdGVtcGxhdGUgZXZlbnRzLiDilIDilIBcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGxvYWRpbmdNZXNzYWdlID0gc2lnbmFsKCdMb2FkaW5nIGltYWdlLi4uJyk7XG4gIC8qKiBUaGUgaG9zdCBpcyBsb2FkaW5nIGF0IHpvb20gKHRoZSBvdmVybGF5IG1lc3NhZ2UgbW92ZXMgb3V0IG9mIHRoZSB3YXkpLiAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgem9vbSA9IHNpZ25hbChmYWxzZSk7XG4gIHByb3RlY3RlZCByZWFkb25seSBzdGFja0xvYWRpbmcgPSBzaWduYWwoZmFsc2UpO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgaW1nTG9hZGluZyA9IHNpZ25hbChmYWxzZSk7XG4gIHByb3RlY3RlZCByZWFkb25seSBsb2FkaW5nUGVyY2VudGFnZSA9IHNpZ25hbCgwKTtcbiAgLy8gTm9uLW51bGwgKDAuLjEwMCkgd2hpbGUgaml0LXNlcnZpY2UgaXMgY29weWluZyB0aGUgc291cmNlIGZpbGUgaW50byB0aGVcbiAgLy8gbG9jYWwgY2FjaGUgUFZDIG9uIGZpcnN0IGNsaWNrLiBXaGVuIHNldCwgdGhlIGxvYWRpbmcgb3ZlcmxheSBzd2FwcyB0aGVcbiAgLy8gc3Bpbm5lciBmb3IgYSBkZXRlcm1pbmF0ZSBwcm9ncmVzcyBiYXIgd2l0aCBhIFwiQ2FjaGluZyBpbWFnZVwiIG1lc3NhZ2UuXG4gIHByb3RlY3RlZCByZWFkb25seSBjYWNoZVByb2dyZXNzID0gc2lnbmFsPG51bWJlciB8IG51bGw+KG51bGwpO1xuICAvKiogQSBqaXQtc2VydmljZSBjYWNoZSBjb3B5IGlzIGFjdGl2ZWx5IGluIHByb2dyZXNzIChkZXRlcm1pbmF0ZSAwLi45OSkuIERyaXZlcyB0aGUgY2FjaGVcbiAgICogIHByb2dyZXNzIGJhciBpbmRlcGVuZGVudGx5IG9mIGBpbWdMb2FkaW5nYCBzbyB0aGUgYmFyIGNhbid0IGJlIGRyb3BwZWQg4oCUIG9yIG1hc2tlZCBieSB0aGVcbiAgICogIFwiU2hhcnBlbmluZyBwcmV2aWV3Li4uXCIgb3ZlcmxheSDigJQgbWlkLWRvd25sb2FkIGlmIHRoZSBsb2FkaW5nIGZsYWcgZmxpcHMgZWFybHkuICovXG4gIHByb3RlY3RlZCByZWFkb25seSBpc0NhY2hpbmcgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgY29uc3QgcCA9IHRoaXMuY2FjaGVQcm9ncmVzcygpO1xuICAgIHJldHVybiBwICE9PSBudWxsICYmIHAgPCAxMDA7XG4gIH0pO1xuXG4gIC8qKiBFbWl0cyBvbmNlIHdoZW4gdGhpcyB2aWV3IGlzIGRlc3Ryb3llZDsgdGhlIGNvbGxhYm9yYXRvcnMgZW5kIHRoZWlyIHN1YnNjcmlwdGlvbnMgb24gaXQuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgZGVzdHJveWVkJCA9IG5ldyBPYnNlcnZhYmxlPHZvaWQ+KChzdWJzY3JpYmVyKSA9PlxuICAgIHRoaXMuZGVzdHJveVJlZi5vbkRlc3Ryb3koKCkgPT4ge1xuICAgICAgc3Vic2NyaWJlci5uZXh0KCk7XG4gICAgICBzdWJzY3JpYmVyLmNvbXBsZXRlKCk7XG4gICAgfSksXG4gICk7XG4gIC8qKiBIb3N0IGltYWdlLWluZm8gb2JqZWN0cyB3aG9zZSBvbmUtc2hvdCBgaW5pdGlhbFpJbmRleGAgd2FzIGFscmVhZHkgYXBwbGllZC4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBjb25zdW1lZFNsaWNlSGludHMgPSBuZXcgV2Vha1NldDxJSW1hZ2VJbmZvPigpO1xuICBwcm90ZWN0ZWQgekluZGV4ID0gMDtcbiAgcHJvdGVjdGVkIG1heEluZGV4ID0gMDtcbiAgLyoqXG4gICAqIFBsYW5lcyBvZiB0aGUgc3BhdGlhbCBkYXRhc2V0J3MgcmVnaW9uIHNldCBzbGljaW5nIHRoZSBpbWFnZSwgYW4gaW1hZ2Ugb2Ygb25lIHBsYW5lIChzZWVcbiAgICogYElWaXN1YWxpemVyLmdldERhdGFzZXRQbGFuZXMkYCk6IHRoZSBzbGlkZXIgdGhlbiBydW5zIG92ZXIgdGhlbS4gMCB3aXRob3V0LlxuICAgKi9cbiAgcHJvdGVjdGVkIGRhdGFzZXRQbGFuZXMgPSAwO1xuXG4gIEBWaWV3Q2hpbGQoJ2NtJykgY29udGV4dE1lbnUhOiBDb250ZXh0TWVudTtcbiAgcHJvdGVjdGVkIGNvbnRleHRNZW51SXRlbXM6IE1lbnVJdGVtW10gPSBbXTtcblxuICAvKiogVGhlIGFybWVkIHRvb2wgbW9kZSBhbmQgdGhlIHRvb2xiYXIncyB0b29sIHNldHRpbmdzLiAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgdG9vbHMgPSBuZXcgVG9vbE1vZGVzKFxuICAgIHRoaXMucGxvdFNlcnZpY2UsXG4gICAgdGhpcy5zZXNzaW9uLFxuICAgIHRoaXMubmdab25lLFxuICAgIChtb2RlKSA9PiB7XG4gICAgICBpZiAobW9kZSAhPT0gJ3NhbVBvaW50JykgdGhpcy5zZWdtZW50YXRpb24uaGlkZSgpO1xuICAgIH0sIC8vIGxlYXZpbmcgcG9pbnQgbW9kZSBkcm9wcyBpdHMgdG9hc3RcbiAgICAoKSA9PiB0aGlzLmNoYW5nZWQoKSxcbiAgKTtcbiAgcHJvdGVjdGVkIGdldCBhY3RpdmVEcmFnTW9kZSgpOiBzdHJpbmcgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy50b29scy5hY3RpdmU7XG4gIH1cbiAgcHJvdGVjdGVkIHNldCBhY3RpdmVEcmFnTW9kZShtb2RlOiBzdHJpbmcgfCBudWxsKSB7XG4gICAgdGhpcy50b29scy5hY3RpdmUgPSBtb2RlO1xuICB9XG4gIHByb3RlY3RlZCBnZXQgd2FuZFNlbnNpdGl2aXR5KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMudG9vbHMud2FuZFNlbnNpdGl2aXR5O1xuICB9XG4gIHByb3RlY3RlZCBzZXQgd2FuZFNlbnNpdGl2aXR5KHY6IG51bWJlcikge1xuICAgIHRoaXMudG9vbHMud2FuZFNlbnNpdGl2aXR5ID0gdjtcbiAgfVxuICBwcm90ZWN0ZWQgZ2V0IGJydXNoU2l6ZSgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnRvb2xzLmJydXNoU2l6ZTtcbiAgfVxuICBwcm90ZWN0ZWQgZ2V0IHZlcnRleEVyYXNlclJhZGl1cygpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLnRvb2xzLnZlcnRleEVyYXNlclJhZGl1cztcbiAgfVxuICBwcm90ZWN0ZWQgc2V0IHZlcnRleEVyYXNlclJhZGl1cyh2OiBudW1iZXIpIHtcbiAgICB0aGlzLnRvb2xzLnZlcnRleEVyYXNlclJhZGl1cyA9IHY7XG4gIH1cblxuICAvKiogUmVnaW9uIHNldC1vcGVyYXRpb25zIG9uIHRoZSBzZWxlY3Rpb24sIGFuZCB0aGUgc3RvcmUgbWlycm9ycyB0aGV5IHJlYWQgKGppdC11aSM4NSkuICovXG4gIHByb3RlY3RlZCByZWFkb25seSByZWdpb25BY3Rpb25zID0gbmV3IFJlZ2lvbkFjdGlvbnMoXG4gICAgdGhpcy5wbG90U2VydmljZSxcbiAgICB0aGlzLnJlZ2lvbk9wcyxcbiAgICAoKSA9PiB0aGlzLmltYWdlSW5mbz8udHJ1ZUltYWdlU2l6ZSxcbiAgICAobSkgPT4gdGhpcy5tZXNzYWdlU2VydmljZS5hZGQoeyBrZXk6IHRoaXMucmVzdWx0VG9hc3RLZXksIC4uLm0gfSksXG4gICk7XG4gIC8qKiBDdXN0b20tdGhyZXNob2xkIFNpbXBsaWZ5IGRpYWxvZyB2aXNpYmlsaXR5IChzZWUge0BsaW5rIFJlZ2lvbkFjdGlvbnN9KS4gKi9cbiAgcHJvdGVjdGVkIGdldCBkaXNwbGF5U2ltcGxpZnlEaWFsb2coKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMucmVnaW9uQWN0aW9ucy5kaXNwbGF5U2ltcGxpZnlEaWFsb2c7XG4gIH1cbiAgcHJvdGVjdGVkIHNldCBkaXNwbGF5U2ltcGxpZnlEaWFsb2codjogYm9vbGVhbikge1xuICAgIHRoaXMucmVnaW9uQWN0aW9ucy5kaXNwbGF5U2ltcGxpZnlEaWFsb2cgPSB2O1xuICB9XG5cbiAgLyoqIFNBTSBtb2RlbCBwaWNrZXIgb3B0aW9ucyArIGN1cnJlbnQgc2VsZWN0aW9uIChqaXQtdWkjOTAgUDEpLiBPbmx5IG1vZGVsc1xuICAgKiAgd2l0aCBhIGhvc3RlZCBPTk5YIHBhaXIgKGNvbmZpZ3VyZWQgdmlhIHNldFNhbU1vZGVsVXJscyBhdCBhcHAgaW5pdCkgYXJlXG4gICAqICBvZmZlcmVkLCBzbyB0aGUgcGlja2VyIGNhbid0IHNlbGVjdCBhIG1vZGVsIHRoYXQgY2FuJ3QgcnVuLiAqL1xuICBwcm90ZWN0ZWQgc2FtTW9kZWxzID0gU0FNX01PREVMUy5maWx0ZXIoaXNTYW1Nb2RlbFJlYWR5KS5tYXAoKG0pID0+ICh7IGlkOiBtLmlkLCBsYWJlbDogbS5sYWJlbCB9KSk7XG4gIHByb3RlY3RlZCBzYW1Nb2RlbElkID0gZ2V0RGVmYXVsdFNhbU1vZGVsSWQoKTtcblxuICAvKipcbiAgICogTm8tcHJvbXB0IHRvb2xzIHJlZ2lzdGVyZWQgdGhyb3VnaCB7QGxpbmsgVE9PTEJBUl9UT09MU30sIGZpbHRlcmVkIHRvIHRob3NlXG4gICAqIHdpdGggY29uZmlndXJlZCBtb2RlbHMgYW5kIHNvcnRlZC4gVGhpcyBsaWJyYXJ5IHJlZ2lzdGVycyBub25lIOKAlCBhIGhvc3RcbiAgICogc3VwcGxpZXMgdGhlbSDigJQgc28gYW4gb3BlbiBidWlsZCBoYXMgYW4gZW1wdHkgYXJyYXkgaGVyZSBhbmQgdGhlIHRvb2xiYXJcbiAgICogYW5kIGhlbHAgZGlhbG9nIHNpbXBseSBvbWl0IHRoYXQgZ3JvdXAuXG4gICAqL1xuICBwcm90ZWN0ZWQgY29udHJpYnV0ZWRUb29sczogVG9vbGJhclRvb2xDb250cmlidXRpb25bXSA9IFtdO1xuICAvKiogQ2hlY2twb2ludHMgYW5kIHBhcmFtZXRlciB2YWx1ZXMgb2Yge0BsaW5rIGNvbnRyaWJ1dGVkVG9vbHN9LCBhbmQgdGhlaXIgZGlhbG9nLiAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgdG9vbFBhcmFtczogVG9vbFBhcmFtc01vZGVsO1xuICAvKiogQ29udHJpYnV0ZWQgcGxvdCBtb2RlcyBhbmQgZGlhbG9nIHRvb2xzLCBhbmQgdGhlaXIgbGl2ZSBzZXNzaW9ucy4gKi9cbiAgcmVhZG9ubHkgY29udHJpYnV0aW9uczogQ29udHJpYnV0aW9uSG9zdDtcbiAgLyoqIERpYWxvZyB0b29scyByZWdpc3RlcmVkIHRocm91Z2gge0BsaW5rIFRPT0xCQVJfVE9PTFN9IChga2luZDogJ2RpYWxvZydgKS4gKi9cbiAgcHJvdGVjdGVkIGdldCBkaWFsb2dUb29scygpOiBUb29sYmFyRGlhbG9nVG9vbENvbnRyaWJ1dGlvbltdIHtcbiAgICByZXR1cm4gdGhpcy5jb250cmlidXRpb25zLmRpYWxvZ1Rvb2xzO1xuICB9XG4gIC8qKiBUaGUgZGlhbG9nIHRvb2wgdGhlIHVzZXIgaGFzIG9wZW4gKGl0cyBzZXNzaW9uIG1heSBiZSBiZXR3ZWVuIHJlbmRlcnMpLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IG9wZW5EaWFsb2dUb29sSWQoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuY29udHJpYnV0aW9ucy5vcGVuRGlhbG9nVG9vbElkO1xuICB9XG4gIC8qKiBUaGUgb3BlbiBkaWFsb2cgdG9vbCdzIGxpdmUgZGlhbG9nLCBhcyB0aGUgdGVtcGxhdGUgcmVuZGVycyBpdC4gKi9cbiAgcHJvdGVjdGVkIGdldCB0b29sRGlhbG9nKCk6IFRvb2xEaWFsb2dWaWV3IHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMuY29udHJpYnV0aW9ucy50b29sRGlhbG9nO1xuICB9XG4gIHByb3RlY3RlZCByZWFkb25seSBzYW1Ub2FzdEtleSA9IGBzYW0tJHtWaXN1YWxpemVyQ29tcG9uZW50Lm5leHRUb2FzdElkKyt9YDtcbiAgLyoqXG4gICAqIE91dGxldCBmb3IgdGhlIGxpYnJhcnkncyBvd24gcmVzdWx0L2Vycm9yIG5vdGljZXMsIGtleWVkIHRvIHRoaXMgaW5zdGFuY2Ugc28gdGhleVxuICAgKiBkbyBub3QgZGVwZW5kIG9uIHRoZSBob3N0IG1vdW50aW5nIGEga2V5bGVzcyBgPHAtdG9hc3Q+YCAobW9zdCBob3N0cyBkb24ndCwgYW5kIGFcbiAgICogZmFpbGVkIHNlZ21lbnRhdGlvbiB0aGVuIGxvb2tlZCBsaWtlIGEgZGVhZCBidXR0b24pLiBEZWxpYmVyYXRlbHkgTk9UIHRoZSBzdGlja3lcbiAgICogdG9hc3QncyBrZXk6IHRoYXQgaXMgY2xlYXJlZCB3aGVuIGEgcnVuIHNldHRsZXMsIHdoaWNoIHdvdWxkIHdpcGUgdGhlIHJlc3VsdC5cbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSByZXN1bHRUb2FzdEtleSA9IGAke3RoaXMuc2FtVG9hc3RLZXl9LXJlc3VsdGA7XG4gIC8qKiBTZWdtZW50YXRpb24gcnVucyBhbmQgdGhlaXIgc3RpY2t5IHByb2dyZXNzIHRvYXN0LiAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgc2VnbWVudGF0aW9uID0gbmV3IFNlZ21lbnRhdGlvblJ1bm5lcihcbiAgICB0aGlzLm1lc3NhZ2VTZXJ2aWNlLFxuICAgIHRoaXMuc2FtVG9hc3RLZXksXG4gICAgdGhpcy5yZXN1bHRUb2FzdEtleSxcbiAgICAoKSA9PiB0aGlzLmNoYW5nZWQoKSxcbiAgKTtcblxuICAvKiogQ2hhbm5lbHMgJiBIaXN0b2dyYW0gZGlhbG9nIHZpc2liaWxpdHkgKG9wZW5lZCBmcm9tIHRoZSB0b29sYmFyKS4gKi9cbiAgcHJvdGVjdGVkIHNob3dDaGFubmVsSGlzdG9ncmFtID0gZmFsc2U7XG4gIC8qKiBTcGF0aWFsLW9taWNzIGNvbnRyb2xzIGRpYWxvZyB2aXNpYmlsaXR5ICh0b29sYmFyIGJ1dHRvbikuICovXG4gIHByb3RlY3RlZCBzaG93U3BhdGlhbENvbnRyb2xzID0gZmFsc2U7XG4gIC8qKiBSZWdpb24gRWRpdG9yIGRpYWxvZyB2aXNpYmlsaXR5IChvcGVuZWQgZnJvbSB0aGUgdG9vbGJhcikuICovXG4gIHByb3RlY3RlZCBzaG93UmVnaW9uRWRpdG9yID0gZmFsc2U7XG4gIC8qKiBSZWdpb24gRWRpdG9yIGRpYWxvZyB3aWR0aC4gT24gb3BlbiBpdCBpcyBzZXQgdG8gdGhlIGNvbmZpZ3VyZWQgaG9zdFxuICAgKiAgZWxlbWVudCdzIGN1cnJlbnQgd2lkdGgsIG9yIOKAlCB3aGVuIG5vIHNlbGVjdG9yIGlzIGNvbmZpZ3VyZWQgLyB0aGUgZWxlbWVudFxuICAgKiAgaXNuJ3QgZm91bmQg4oCUIHRvIGEgcXVhcnRlciBvZiB0aGUgcGFnZSAoc2VlIG9wZW5SZWdpb25FZGl0b3IpLiAqL1xuICBwcm90ZWN0ZWQgcmVnaW9uRWRpdG9yV2lkdGggPSAnMjV2dyc7XG4gIHByb3RlY3RlZCByZWFkb25seSBwbG90RGl2TmFtZSA9IGB2aXotcGxvdC0ke3Bsb3RJbnN0YW5jZVNlcSsrfWA7XG4gIC8qKiBUaGUgcmVuZGVyIHBpcGVsaW5lOiB0aGUgbmV3ZXN0IGltYWdlIChvciBpbWFnZS1sZXNzIGRhdGFzZXQpIGFsd2F5cyB3aW5zLiAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgcmVuZGVyOiBJbWFnZVJlbmRlclNlc3Npb24gPSBuZXcgSW1hZ2VSZW5kZXJTZXNzaW9uKHtcbiAgICBwbG90RGl2TmFtZTogdGhpcy5wbG90RGl2TmFtZSxcbiAgICB2aXN1YWxpemVyOiB0aGlzLnBsb3RTZXJ2aWNlLFxuICAgIHpJbmRleDogKCkgPT4gdGhpcy56SW5kZXgsXG4gICAgcGxvdFR5cGU6ICgpID0+IHRoaXMucGxvdFR5cGUsXG4gICAgaXNIZWF0bWFwOiAoKSA9PiB0aGlzLmlzSGVhdG1hcCxcbiAgICBpc0NhY2hpbmc6ICgpID0+IHRoaXMuaXNDYWNoaW5nKCksXG4gICAgYmVmb3JlUmVzZXQ6ICgpID0+IHRoaXMuY29udHJpYnV0aW9ucy5lbmRTZXNzaW9ucygpLFxuICAgIHByZXBhcmU6IChpbmZvKSA9PiB0aGlzLmxheU91dFNsaWNlcyhpbmZvKSxcbiAgICByZWxlYXNlT3ZlcmxheTogKGluZm8pID0+IHtcbiAgICAgIGlmIChpbmZvLmlzU3RhY2sgJiYgaW5mby5zaG93U3RhY2spIHRoaXMuc3RhY2tMb2FkaW5nLnNldChmYWxzZSk7XG4gICAgICB0aGlzLnN0YXRlLnNldEltYWdlTG9hZGluZyhmYWxzZSk7XG4gICAgfSxcbiAgICBsYW5kZWQ6IChpbmZvKSA9PiB7XG4gICAgICAvLyBUaGUgaG9zdCdzIEh0dHBDbGllbnQgY2FycmllcyBhIHNlcnZlci1zaWRlIHJlZ2lvbiBzb3VyY2UncyByZXF1ZXN0czogaXRzIGludGVyY2VwdG9ycyAoYXV0aCkgYXBwbHkuXG4gICAgICBjb25zdCBodHRwID0gdGhpcy5pbmplY3Rvcj8uZ2V0KEh0dHBDbGllbnQsIG51bGwpID8/IHVuZGVmaW5lZDtcbiAgICAgIGFwcGx5SW1hZ2VSb2lzKGluZm8sIHRoaXMucGxvdFNlcnZpY2UsIHRoaXMuekluZGV4LCB0aGlzLnZpekNvbmZpZz8ucmVnaW9uU291cmNlTWluQ2hhcnMsIGh0dHApO1xuICAgICAgLy8gQWZ0ZXIgdGhlIGltYWdlJ3Mgb3duIHJlZ2lvbnM6IGEgc3BhdGlhbCBkYXRhc2V0J3MgcmVnaW9uIHNldCBqb2lucyB0aGVtIChpdHMgY2VsbHMgaW4gM0QpLlxuICAgICAgdGhpcy5yZWdpb25TZXRMaW5rLmltYWdlTGFuZGVkKGluZm8pO1xuICAgICAgdGhpcy5jb250cmlidXRpb25zLmFjdGl2YXRlKCk7XG4gICAgfSxcbiAgICBzZXRJbWFnZUxvYWRpbmc6IChsb2FkaW5nKSA9PiB0aGlzLnN0YXRlLnNldEltYWdlTG9hZGluZyhsb2FkaW5nKSxcbiAgICBhbGVydDogKHNldmVyaXR5LCBzdW1tYXJ5LCBkZXRhaWwpID0+XG4gICAgICB0aGlzLm1lc3NhZ2VTZXJ2aWNlLmFkZCh7IGtleTogdGhpcy52aXpBbGVydFRvYXN0S2V5LCBzZXZlcml0eSwgc3VtbWFyeSwgZGV0YWlsIH0pLFxuICAgIGRldGVjdENoYW5nZXM6ICgpID0+IHRoaXMuY2RyLmRldGVjdENoYW5nZXMoKSxcbiAgfSk7XG4gIHBsb3RUeXBlID0gUGxvdFR5cGUuSU1BR0U7XG4gIHByb3RlY3RlZCBpc0hlYXRtYXAgPSB0cnVlO1xuICBwcm90ZWN0ZWQgYWN0aXZlU3VyZmFjZTNkTW9kZSA9ICd0dXJudGFibGUnO1xuICAvKiogV2hldGhlciB0aGUgbmFwYXJpIDNEIGNvb3JkaW5hdGUtYXhlcyAvIHNjYWxlIGdpem1vIGlzIHNob3duICh2b2x1bWUvaXNvc3VyZmFjZSkuICovXG4gIHByb3RlY3RlZCBheGVzVmlzaWJsZSA9IHRydWU7XG4gIHByb3RlY3RlZCB3aXJlZnJhbWVBY3RpdmUgPSBmYWxzZTtcbiAgLyoqIG5hcGFyaSAzRCBkZWNpbWF0ZSBmYWN0b3IgKDEgPSBGdWxsIOKApiA4ID0g4oWbOyBkZWZhdWx0IMK9KTsgY2hhbmdpbmcgaXQgcmUtcGxvdHMuICovXG4gIHByb3RlY3RlZCByZXNvbHV0aW9uU2NhbGUgPSBOQVBBUklfREVGQVVMVF9ERUNJTUFURTtcblxuICAvKiogVGhlIHNlbGVjdG9yJ3MgZW50cmllczogdGhlIGJ1aWx0LWluIHBsb3QgdHlwZXMgdGhlIGFjdGl2ZSBiYWNrZW5kXG4gICAqICBhZHZlcnRpc2VzICgzRCBnYXRlZCBieSBjYXBhYmlsaXR5KSwgdGhlbiBhbnkgY29udHJpYnV0ZWQgbW9kZXNcbiAgICogICh7QGxpbmsgUExPVF9UWVBFX0NPTlRSSUJVVElPTlN9KS4gKi9cbiAgcHJvdGVjdGVkIHBsb3RUeXBlTWVudTogUGxvdFR5cGVPcHRpb25bXSA9IFtdO1xuICAvKipcbiAgICogVGhlIGJ1aWx0LWluIHBsb3QgdHlwZXMgb24gb2ZmZXIg4oCUIHtAbGluayBwbG90VHlwZU1lbnV9IHdpdGhvdXQgY29udHJpYnV0ZWRcbiAgICogbW9kZXMuIEtlcHQgd2l0aCBpdHMgb3JpZ2luYWwgdHlwZSBzbyBleGlzdGluZyByZWFkZXJzIGFyZSB1bmFmZmVjdGVkLlxuICAgKi9cbiAgcHJvdGVjdGVkIHBsb3RUeXBlT3B0aW9uczogUGxvdFR5cGVEZXNjcmlwdG9yW10gPSBbXTtcbiAgLyoqXG4gICAqIFdoYXQgdGhlIHNlbGVjdG9yIHNob3dzOiBhIGJ1aWx0LWluIHR5cGUgb3IgYSBjb250cmlidXRlZCBtb2RlJ3MgaWQuIEV2ZXJ5XG4gICAqIHJlbmRlcmluZyBhbmQgdG9vbCBkZWNpc2lvbiBnb2VzIHRocm91Z2gge0BsaW5rIGJhc2VQbG90VHlwZX0gaW5zdGVhZCwgc28gYVxuICAgKiBjb250cmlidXRlZCBtb2RlIGJlaGF2ZXMgZXhhY3RseSBsaWtlIHRoZSBidWlsdC1pbiB0eXBlIGl0IHJpZGVzIG9uLlxuICAgKi9cbiAgcHJvdGVjdGVkIHNlbGVjdGVkUGxvdFR5cGVJZDogUGxvdFR5cGVJZCA9IFBsb3RUeXBlLklNQUdFO1xuXG4gIC8qKlxuICAgKiBUaGUgYnVpbHQtaW4gcGxvdCB0eXBlIGJlaW5nIHJlbmRlcmVkLiBXaXRoIG5vIGNvbnRyaWJ1dGVkIG1vZGUgYWN0aXZlIHRoaXNcbiAgICogaXMgdGhlIHNlbGVjdGlvbiBpdHNlbGY7IGR1cmluZyBvbmUgaXQgaXMgdGhlIG1vZGUncyBgYmFzZVR5cGVgLiBLZXB0IHdpdGggaXRzXG4gICAqIG9yaWdpbmFsIGBQbG90VHlwZWAgdHlwZSBmb3IgZXhpc3RpbmcgcmVhZGVycyDigJQgdXNlIHtAbGluayBzZWxlY3RlZFBsb3RUeXBlSWR9XG4gICAqIGZvciB0aGUgc2VsZWN0b3IncyBpZC4gQXNzaWduaW5nIHNlbGVjdHMgdGhhdCBidWlsdC1pbiB0eXBlLlxuICAgKi9cbiAgcHJvdGVjdGVkIGdldCBzZWxlY3RlZFBsb3RUeXBlKCk6IFBsb3RUeXBlIHtcbiAgICByZXR1cm4gdGhpcy5iYXNlUGxvdFR5cGU7XG4gIH1cbiAgcHJvdGVjdGVkIHNldCBzZWxlY3RlZFBsb3RUeXBlKHR5cGU6IFBsb3RUeXBlKSB7XG4gICAgdGhpcy5zZWxlY3RlZFBsb3RUeXBlSWQgPSB0eXBlO1xuICB9XG5cbiAgLyoqIENvbnRyaWJ1dGVkIHBsb3QgbW9kZXMgYW5kIHRoZWlyIHNpbmdsZSBsaXZlIHNlc3Npb24uICovXG4gIGdldCBwbG90TW9kZXMoKTogUGxvdE1vZGVDb250cm9sbGVyIHtcbiAgICByZXR1cm4gdGhpcy5jb250cmlidXRpb25zLnBsb3RNb2RlcztcbiAgfVxuICAvKiogVGhlIGxpdmUgY29udHJpYnV0ZWQgbW9kZSdzIHNpZGUgcGFuZWw7IG51bGwgd2hpbGUgbm8gY29udHJpYnV0ZWQgc2Vzc2lvbiBpcyBsaXZlLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IHBsb3RNb2RlUGFuZWwoKTogUGxvdE1vZGVQYW5lbFZpZXcgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5jb250cmlidXRpb25zLnBsb3RNb2RlUGFuZWw7XG4gIH1cblxuICAvKiogV2hlcmUgYSBgbW91bnRgIHBhbmVsJ3MgaG9zdCBlbGVtZW50IGlzIGF0dGFjaGVkIG9uY2UgdGhlIGRpYWxvZyByZW5kZXJzLiAqL1xuICBAVmlld0NoaWxkKCdwbG90TW9kZVBhbmVsU2xvdCcpXG4gIHNldCBwbG90TW9kZVBhbmVsU2xvdChyZWY6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+IHwgdW5kZWZpbmVkKSB7XG4gICAgdGhpcy5jb250cmlidXRpb25zLmF0dGFjaFBhbmVsU2xvdChyZWY/Lm5hdGl2ZUVsZW1lbnQpO1xuICB9XG5cbiAgLyoqIFRoZSBidWlsdC1pbiB0eXBlIGFjdHVhbGx5IHJlbmRlcmVkIGZvciB7QGxpbmsgc2VsZWN0ZWRQbG90VHlwZUlkfTogaXRzZWxmXG4gICAqICBmb3IgYSBidWlsdC1pbiB0eXBlLCBgYmFzZVR5cGVgIGZvciBhIGNvbnRyaWJ1dGVkIG1vZGUuICovXG4gIHByb3RlY3RlZCBnZXQgYmFzZVBsb3RUeXBlKCk6IFBsb3RUeXBlIHtcbiAgICByZXR1cm4gdGhpcy5wbG90TW9kZXMuYmFzZVR5cGVPZih0aGlzLnNlbGVjdGVkUGxvdFR5cGVJZCk7XG4gIH1cblxuICAvKiogRGl2IHRoZSBmbG9hdGluZyBpbnRlbnNpdHktcHJvZmlsZSBpbnNldCBpcyBjaGFydGVkIGludG8uIFBlciBpbnN0YW5jZSwgbGlrZVxuICAgKiAge0BsaW5rIHBsb3REaXZOYW1lfTogdGhlIGJhY2tlbmQgcmVzb2x2ZXMgaXQgYnkgaWQsIHNvIGEgZml4ZWQgaWQgbWFkZSB0d28gbGl2ZVxuICAgKiAgdmlld2VycyBkcmF3IGJvdGggaW5zZXRzIGludG8gd2hpY2hldmVyIGRpdiBjYW1lIGZpcnN0IGluIHRoZSBkb2N1bWVudC4gKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGludGVuc2l0eUluc2V0RGl2ID0gYCR7dGhpcy5wbG90RGl2TmFtZX0taW5zZXRgO1xuXG4gIC8qKiBUb29sYmFyIGRvY2tpbmc6IGRvY2tlZCBhY3Jvc3MgdGhlIHRvcCBieSBkZWZhdWx0OyBkcmFnZ2luZyBpdHMgaGFuZGxlXG4gICAqICBkZXRhY2hlcyBpdCBpbnRvIGEgZmxvYXRpbmcsIG1vdmFibGUgd2luZG93IChmcmVlcyB0aGUgdG9wIHJvdyBmb3IgdGhlXG4gICAqICB2aXN1YWxpemF0aW9uKS4gKi9cbiAgcHJvdGVjdGVkIHRvb2xiYXJGbG9hdGluZyA9IGZhbHNlO1xuICBwcm90ZWN0ZWQgdG9vbGJhclBvcyA9IHsgeDogOCwgeTogOCB9O1xuICAvKiogV2hlcmUgYSB0b29sYmFyLWhhbmRsZSBkcmFnIHN0YXJ0cyBmcm9tOiBncmFiYmluZyB0aGUgZG9ja2VkIHRvb2xiYXIgZmxvYXRzIGl0LiAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgdG9vbGJhckRyYWdPcmlnaW4gPSAoKTogRmxvYXRpbmdQb3MgPT4ge1xuICAgIGlmICghdGhpcy50b29sYmFyRmxvYXRpbmcpIHtcbiAgICAgIHRoaXMudG9vbGJhckZsb2F0aW5nID0gdHJ1ZTtcbiAgICAgIHRoaXMudG9vbGJhclBvcyA9IHsgeDogOCwgeTogOCB9O1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy50b29sYmFyUG9zO1xuICB9O1xuICAvKiogVGhlIGZsb2F0aW5nIGludGVuc2l0eS1wcm9maWxlIGluc2V0IChhbHdheXMgbW91bnRlZDsgc2hvd3MgaXRzZWxmIHdoaWxlIGxpbmVzIGV4aXN0KS4gKi9cbiAgQFZpZXdDaGlsZChJbnRlbnNpdHlJbnNldENvbXBvbmVudCwgeyBzdGF0aWM6IHRydWUgfSkgaW5zZXQ/OiBJbnRlbnNpdHlJbnNldENvbXBvbmVudDtcblxuICAvKiogVHJ1ZSB3aGlsZSB0aGUgM0Qgc3BhdGlhbCBjbG91ZCBpcyB0aGUgYWN0aXZlIG1vZGUuIFRoZSBjb250cm9scyBkcm9wIHRoZSBST0lcbiAgICogIHNlbGVjdGlvbiB0aGVyZTogcmVnaW9uIHRvb2xzIGFyZSBzY3JlZW4tc3BhY2UsIGFuZCBhZ2FpbnN0IGFuIG9yYml0aW5nXG4gICAqICBjYW1lcmEgYSBkcmF3biByZWN0YW5nbGUgaGFzIG5vIGZpeGVkIG1lYW5pbmcgaW4gdGhlIGRhdGEuICovXG4gIHByb3RlY3RlZCBnZXQgaXNTcGF0aWFsM2RNb2RlKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBpc1NwYXRpYWxPbWljczNkKHRoaXMuYmFzZVBsb3RUeXBlKTtcbiAgfVxuXG4gIC8qKiBUcnVlIGluIGEgbmFwYXJpIHZvbHVtZSBvciBpc29zdXJmYWNlIHZpZXcsIHdoZXJlIHRoZSBSZWdpb24gRWRpdG9yIHNob3dzIHJlZ2lvbnMgaW4gM0QuICovXG4gIHByb3RlY3RlZCBnZXQgaXNWb2x1bWVWaWV3KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBpc05hcGFyaVZvbHVtZSh0aGlzLmJhc2VQbG90VHlwZSkgfHwgaXNOYXBhcmlJc29zdXJmYWNlKHRoaXMuYmFzZVBsb3RUeXBlKTtcbiAgfVxuXG4gIC8qKiBXaGV0aGVyIHRoZSB1c2VyIHNwbGl0IHRoZSB2b2x1bWUgdmlldyB3aXRoIHRoZSBzbGljZSBlZGl0b3IgKG9mZiBieSBkZWZhdWx0OyBrZXB0IHdoaWxlXG4gICAqICB0aGUgdmlldyBzaG93cyBvdGhlciBwbG90IHR5cGVzLCBzbyBhIHZvbHVtZSB2aWV3IG9wZW5zIHNwbGl0IGFnYWluKS4gKi9cbiAgcHJvdGVjdGVkIHNsaWNlRWRpdG9yID0gZmFsc2U7XG4gIC8qKiBUaGUgc2xpY2UgZWRpdG9yJ3MgcGFuZTogdGhlIGRpc3BsYXllZCBzbGljZSwgd2l0aCBldmVyeSByZWdpb24gdG9vbCwgdG9wIHJpZ2h0LiAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgc2xpY2VEaXZOYW1lID0gYCR7dGhpcy5wbG90RGl2TmFtZX0tc2xpY2VgO1xuICAvKiogVGhlIGxlZnQgY29sdW1uJ3MgYW5kIHRoZSB0b3Agcm93J3Mgc2hhcmVzIG9mIHRoZSBzbGljZSBlZGl0b3IgKCUpLiAqL1xuICBwcm90ZWN0ZWQgc3BsaXRYID0gNTA7XG4gIHByb3RlY3RlZCBzcGxpdFkgPSA1MDtcbiAgLyoqIFRoZSBzZWN0aW9ucyB0aHJvdWdoIHggYW5kIHkgc2hvd24gYmVsb3cgKG51bGxzIHVudGlsIHRoZSB2b2x1bWUgaXMgY3V0KS4gKi9cbiAgcHJvdGVjdGVkIHNlY3Rpb25zOiBTZWN0aW9uVmlld3MgPSB7IHg6IG51bGwsIHk6IG51bGwgfTtcbiAgcHJvdGVjdGVkIGdldCBzbGljZUVkaXRvclNob3duKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnNsaWNlRWRpdG9yICYmIHRoaXMuaXNWb2x1bWVWaWV3O1xuICB9XG5cbiAgLyoqXG4gICAqIFNwbGl0IHRoZSB2b2x1bWUgdmlldyB3aXRoIHRoZSBzbGljZSBlZGl0b3IsIG9yIGNsb3NlIGl0LiBUaGUgZWRpdG9yIG9wZW5zIG9uIHRoZSBkaXNwbGF5ZWRcbiAgICogc2xpY2UgYW5kIHRha2VzIHRoZSBkcmF3aW5nIHRvb2xzOyBjbG9zaW5nIGl0IGxlYXZlcyB0aGUgc2VsZWN0aW9uIHRvb2wgYXJtZWQgKGl0IHBpY2tzIHRoZVxuICAgKiBzdXJmYWNlcyBpbiAzRCkgYW5kIGRpc2FybXMgYW55IG90aGVyLlxuICAgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIHRvZ2dsZVNsaWNlRWRpdG9yKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHRoaXMuc2xpY2VFZGl0b3IgPSAhdGhpcy5zbGljZUVkaXRvcjtcbiAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7IC8vIHRoZSBwYW5lJ3MgZGl2LCBiZWZvcmUgdGhlIGJhY2tlbmQgbG9va3MgaXQgdXBcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnJlbGF5b3V0KCk7IC8vIHRoZSAzRCB2aWV3IGlzIGEgcXVhcnRlciBvZiB0aGUgYXJlYSBub3csIG9yIGFsbCBvZiBpdCBhZ2FpblxuICAgIGlmICghdGhpcy5zbGljZUVkaXRvcikge1xuICAgICAgYXdhaXQgdGhpcy5wbG90U2VydmljZS5zZXRTbGljZUVkaXRvcj8uKG51bGwpO1xuICAgICAgaWYgKHRoaXMudG9vbHMuYWN0aXZlICE9PSBudWxsICYmIHRoaXMudG9vbHMuYWN0aXZlICE9PSAnc2VsZWN0JykgdGhpcy50b29scy5hcHBseShudWxsKTtcbiAgICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBUaGUgcmVnaW9ucyBlZGl0ZWQgYXJlIHRoZSBkaXNwbGF5ZWQgc2xpY2Uncy5cbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldERpc3BsYXlTbGljZSh0aGlzLnpJbmRleCk7XG4gICAgY29uc3Qgc2hvd24gPSBhd2FpdCB0aGlzLnBsb3RTZXJ2aWNlLnNldFNsaWNlRWRpdG9yPy4odGhpcy5zbGljZURpdk5hbWUpO1xuICAgIC8vIFRoZSBhcm1lZCB0b29sIG5vdyBhY3RzIGluIHRoZSBwYW5lLlxuICAgIGlmIChzaG93biAmJiB0aGlzLnRvb2xzLmFjdGl2ZSAhPT0gbnVsbCkgdGhpcy50b29scy5hcHBseSh0aGlzLnRvb2xzLmFjdGl2ZSk7XG4gICAgdGhpcy5jaGFuZ2VkKCk7XG4gIH1cblxuICAvKiogQSBwb2ludCBwaWNrZWQgaW4gYSBzZWN0aW9uOiB0aGUgc2xpY2UgYW5kIHRoZSBvdGhlciBzZWN0aW9uJ3MgcGxhbmUgbW92ZSB0aGVyZS4gKi9cbiAgcHJvdGVjdGVkIG9uU2VjdGlvblBpY2soYXhpczogU2VjdGlvbkF4aXMsIGF0OiB7IHU6IG51bWJlcjsgdjogbnVtYmVyIH0pOiB2b2lkIHtcbiAgICAvLyBUaHJvdWdoIHgsIGFjcm9zcyBpcyB0aGUgc2xpY2UgYW5kIGRvd24gaXMgeTsgdGhyb3VnaCB5LCBhY3Jvc3MgaXMgeCBhbmQgZG93biB0aGUgc2xpY2UuXG4gICAgY29uc3Qgc2xpY2UgPSBNYXRoLmZsb29yKGF4aXMgPT09ICd4JyA/IGF0LnUgOiBhdC52KTtcbiAgICBpZiAoYXhpcyA9PT0gJ3gnKSB0aGlzLnBsb3RTZXJ2aWNlLnNldFNlY3Rpb25QbGFuZT8uKCd5JywgYXQudik7XG4gICAgZWxzZSB0aGlzLnBsb3RTZXJ2aWNlLnNldFNlY3Rpb25QbGFuZT8uKCd4JywgYXQudSk7XG4gICAgdGhpcy5vblpTbGlkZShNYXRoLm1pbih0aGlzLm1heEluZGV4LCBNYXRoLm1heCgwLCBzbGljZSkpKTtcbiAgfVxuXG4gIC8qKiBEcmFnIGEgZGl2aWRlciBvZiB0aGUgc2xpY2UgZWRpdG9yOiB0aGUgdmVydGljYWwgb25lIHNldHMgdGhlIGNvbHVtbnMsIHRoZSBob3Jpem9udGFsIG9uZSB0aGUgcm93cy4gKi9cbiAgcHJvdGVjdGVkIHN0YXJ0UGFuZVJlc2l6ZShldmVudDogUG9pbnRlckV2ZW50LCBheGlzOiAneCcgfCAneScpOiB2b2lkIHtcbiAgICBjb25zdCBkaXZpZGVyID0gZXZlbnQuY3VycmVudFRhcmdldCBhcyBIVE1MRWxlbWVudDtcbiAgICBjb25zdCBwYW5lcyA9IGRpdmlkZXIucGFyZW50RWxlbWVudDtcbiAgICBpZiAoIXBhbmVzKSByZXR1cm47XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBkaXZpZGVyLnNldFBvaW50ZXJDYXB0dXJlKGV2ZW50LnBvaW50ZXJJZCk7XG4gICAgY29uc3QgbW92ZSA9IChlOiBQb2ludGVyRXZlbnQpID0+IHtcbiAgICAgIGNvbnN0IGJveCA9IHBhbmVzLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgaWYgKGF4aXMgPT09ICd4JyAmJiBib3gud2lkdGggPiAwKSB0aGlzLnNldFNwbGl0KCd4JywgKChlLmNsaWVudFggLSBib3gubGVmdCkgLyBib3gud2lkdGgpICogMTAwKTtcbiAgICAgIGlmIChheGlzID09PSAneScgJiYgYm94LmhlaWdodCA+IDApIHRoaXMuc2V0U3BsaXQoJ3knLCAoKGUuY2xpZW50WSAtIGJveC50b3ApIC8gYm94LmhlaWdodCkgKiAxMDApO1xuICAgIH07XG4gICAgY29uc3QgZW5kID0gKCkgPT4ge1xuICAgICAgZGl2aWRlci5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVybW92ZScsIG1vdmUpO1xuICAgICAgZGl2aWRlci5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVydXAnLCBlbmQpO1xuICAgICAgZGl2aWRlci5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVyY2FuY2VsJywgZW5kKTtcbiAgICB9O1xuICAgIGRpdmlkZXIuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcm1vdmUnLCBtb3ZlKTtcbiAgICBkaXZpZGVyLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJ1cCcsIGVuZCk7XG4gICAgZGl2aWRlci5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVyY2FuY2VsJywgZW5kKTtcbiAgfVxuXG4gIC8qKiBBIGRpdmlkZXIncyBrZXlib2FyZDog4oaQIOKGkiBtb3ZlIHRoZSB2ZXJ0aWNhbCBvbmUsIOKGkSDihpMgdGhlIGhvcml6b250YWwgb25lLCBieSA1JS4gKi9cbiAgcHJvdGVjdGVkIG51ZGdlUGFuZVNpemUoZXZlbnQ6IEtleWJvYXJkRXZlbnQsIGF4aXM6ICd4JyB8ICd5Jyk6IHZvaWQge1xuICAgIGNvbnN0IGtleXMgPSBheGlzID09PSAneCcgPyBbJ0Fycm93TGVmdCcsICdBcnJvd1JpZ2h0J10gOiBbJ0Fycm93VXAnLCAnQXJyb3dEb3duJ107XG4gICAgY29uc3Qgc3RlcCA9IGV2ZW50LmtleSA9PT0ga2V5c1swXSA/IC01IDogZXZlbnQua2V5ID09PSBrZXlzWzFdID8gNSA6IDA7XG4gICAgaWYgKCFzdGVwKSByZXR1cm47XG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICBldmVudC5zdG9wUHJvcGFnYXRpb24oKTsgLy8gbm90IGEgc2xpY2Ugc3RlcFxuICAgIHRoaXMuc2V0U3BsaXQoYXhpcywgKGF4aXMgPT09ICd4JyA/IHRoaXMuc3BsaXRYIDogdGhpcy5zcGxpdFkpICsgc3RlcCk7XG4gIH1cblxuICBwcml2YXRlIHNldFNwbGl0KGF4aXM6ICd4JyB8ICd5JywgcGVyY2VudDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgdmFsdWUgPSBNYXRoLnJvdW5kKE1hdGgubWluKDgwLCBNYXRoLm1heCgyMCwgcGVyY2VudCkpKTtcbiAgICBpZiAoYXhpcyA9PT0gJ3gnKSB0aGlzLnNwbGl0WCA9IHZhbHVlO1xuICAgIGVsc2UgdGhpcy5zcGxpdFkgPSB2YWx1ZTtcbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICAvLyBUaGUgM0QgdmlldyBmb2xsb3dzIGl0cyBjZWxsIG9uY2UgdGhlIGdyaWQgaGFzIGl0cyBuZXcgdHJhY2tzLlxuICAgIGlmICh0aGlzLnJlbGF5b3V0RnJhbWUgPT09IG51bGwgJiYgdHlwZW9mIHJlcXVlc3RBbmltYXRpb25GcmFtZSAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRoaXMucmVsYXlvdXRGcmFtZSA9IHJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgIHRoaXMucmVsYXlvdXRGcmFtZSA9IG51bGw7XG4gICAgICAgIHRoaXMucGxvdFNlcnZpY2UucmVsYXlvdXQoKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuICBwcml2YXRlIHJlbGF5b3V0RnJhbWU6IG51bWJlciB8IG51bGwgPSBudWxsO1xuXG4gIC8qKiBUcnVlIGZvciB0aGUgSW1hZ2UgcGxvdCB0eXBlLCB3aGljaCByZW5kZXJzIGFzIGEgbmF0aXZlbHkgcGFuL3pvb20tYWJsZVxuICAgKiAgcmFzdGVyIOKAlCBzbyB0aGUgYmFja2VuZC1hZ25vc3RpYyB6b29tL3BhbiB0b29sYmFyIHRvb2xzIGFyZSBoaWRkZW4uIFRoZVxuICAgKiAgY29tcG9uZW50IGRyaXZlcyB0aGlzIG9mZiB0aGUgcGxvdCB0eXBlLCBub3QgdGhlIGFjdGl2ZSBiYWNrZW5kLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGlzSW1hZ2VWaWV3KCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmJhc2VQbG90VHlwZSA9PT0gUGxvdFR5cGUuSU1BR0U7XG4gIH1cblxuICAvKiogSXNvc3VyZmFjZSBiYW5kIGFzIGEgMOKAkzI1NSBzbGlkZXIgcG9zaXRpb24sIG1hcHBlZCBvbnRvIHRoZSB2b2x1bWUncyByZWFsXG4gICAqICBpbnRlbnNpdHkgcmFuZ2UgYnkgdGhlIHJlbmRlcmVyLiBEZWZhdWx0cyB0byB0aGUgZnVsbCByYW5nZS4gKi9cbiAgcHJvdGVjdGVkIGlzb1JhbmdlOiBudW1iZXJbXSA9IFswLCAyNTVdO1xuXG4gIC8qKiBUaGUgc3BhdGlhbC1vbWljcyBkYXRhc2V0IG9uIG9mZmVyIGFuZCB0aGUgZ2F0ZXMgaXQgcHV0cyBvbiB0aGUgc2VsZWN0b3IuICovXG4gIHByb3RlY3RlZCByZWFkb25seSBzcGF0aWFsOiBTcGF0aWFsRGF0YXNldEJpbmRlcjtcbiAgLyoqIEF0dGFjaGVzIGEgc3BhdGlhbCBkYXRhc2V0J3MgcmVnaW9uIHNldCAoYSAzRCBzZWdtZW50YXRpb24ncyBjZWxscykgdG8gaXRzIGltYWdlJ3MgcmVnaW9ucy4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSByZWdpb25TZXRMaW5rOiBTcGF0aWFsUmVnaW9uU2V0TGluaztcbiAgLyoqIFdoZXRoZXIgYSBzcGF0aWFsLW9taWNzIGRhdGFzZXQgaXMgcHVibGlzaGVkIG9uIGBTUEFUSUFMX0RBVEFfUE9SVGAg4oCUIGdhdGVzIHRoZVxuICAgKiAgc3BhdGlhbCBwbG90IHR5cGVzOyB0aGUgdG9vbGJhciBvZmZlcnMgdGhlIHBsb3QgbW9kZXMgZm9yIGFuIGltYWdlLWxlc3Mgb25lIHRvby4gKi9cbiAgcHJvdGVjdGVkIGdldCBoYXNTcGF0aWFsRGF0YXNldCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zcGF0aWFsLmhhc0RhdGFzZXQ7XG4gIH1cblxuICAvKiogS2V5Ym9hcmQsIHdoZWVsIGFuZCBjb250ZXh0LW1lbnUgaGFuZGxpbmc7IGNyZWF0ZWQgb25jZSB0aGUgdmlldyBleGlzdHMuICovXG4gIHByaXZhdGUgc2hvcnRjdXRzPzogVmlld2VyU2hvcnRjdXRzO1xuICAvKiogV2FpdHMgZm9yIGEgdmlld2VyIGNyZWF0ZWQgb3V0c2lkZSB0aGUgZG9jdW1lbnQgdG8gYmUgYXR0YWNoZWQgKHNlZSB7QGxpbmsgd2hlbkluRG9jdW1lbnR9KS4gKi9cbiAgcHJpdmF0ZSBhdHRhY2hPYnNlcnZlcjogUmVzaXplT2JzZXJ2ZXIgfCBudWxsID0gbnVsbDtcblxuICAvKiogRGVib3VuY2VkIHotc2xpY2Ugc2NydWJiaW5nIChzZWUgU2xpY2VTY3J1YmJlciDigJQgcmVmYWN0b3JpbmcgcGxhbiBTdGVwIDcpLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHNjcnViYmVyID0gbmV3IFNsaWNlU2NydWJiZXIoKHopID0+IHtcbiAgICB0aGlzLnBsb3RTZXJ2aWNlLnNldFpJbmRleCh6KTtcbiAgICAvLyBJbiBhIHBlci1zbGljZSB6LXN0YWNrIHNlc3Npb24gdGhlIHN0b3JlIHN3YXBzIHRoZSBsaXZlIHJlZ2lvbiBzZXQgdG8gdGhpc1xuICAgIC8vIHNsaWNlIChwcmVzZXJ2aW5nIGVkaXRzIG1hZGUgb24gdGhlIHByZXZpb3VzIG9uZSk7IG91dHNpZGUgc3RhY2sgbW9kZSB0aGlzXG4gICAgLy8ganVzdCByZWNvcmRzIHRoZSBzbGljZSwgbGVhdmluZyBzaW5nbGUtcGxhbmUgcmVnaW9ucyB1bnRvdWNoZWQgKGppdC11aSM5MykuXG4gICAgdGhpcy5wbG90U2VydmljZS5zZXREaXNwbGF5U2xpY2Uoeik7XG4gIH0pO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIC8vIFRoZSBjb25zdHJ1Y3RvciBwYXJhbWV0ZXJzIGJlbG93IGFyZSB0aGUgaW5qZWN0aW9uIHBvaW50czsgbm9uZSBpcyBwdWJsaWMgQVBJLlxuICAgIEBJbmplY3QoSU1BR0VfU1RBVEVfUE9SVCkgcHJpdmF0ZSBzdGF0ZTogSW1hZ2VTdGF0ZVBvcnQsXG4gICAgQEluamVjdChWSVNVQUxJWkVSKSBwdWJsaWMgcGxvdFNlcnZpY2U6IElWaXN1YWxpemVyLFxuICAgIHB1YmxpYyBtZXNzYWdlU2VydmljZTogTWVzc2FnZVNlcnZpY2UsXG4gICAgcHJpdmF0ZSBuZ1pvbmU6IE5nWm9uZSxcbiAgICBwcml2YXRlIGNkcjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHJpdmF0ZSBzZXNzaW9uOiBWaXN1YWxpemVyU3RvcmUsXG4gICAgcHJpdmF0ZSBzYW1Ub29sOiBTYW1Ub29sU2VydmljZSxcbiAgICBwcml2YXRlIGNlbGxTZWdtZW50VG9vbDogQ2VsbFNlZ21lbnRUb29sU2VydmljZSxcbiAgICBwcml2YXRlIHNhbVBvaW50VG9vbDogU2FtUG9pbnRUb29sU2VydmljZSxcbiAgICBwcml2YXRlIHJlZ2lvbk9wczogUmVnaW9uT3BzU2VydmljZSxcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFZJWl9DT05GSUcpIHByaXZhdGUgdml6Q29uZmlnPzogVml6Q29uZmlnLFxuICAgIC8vIEEgY29uc3RydWN0b3IgcGFyYW1ldGVyIHJhdGhlciB0aGFuIGEgZmllbGQgYGluamVjdCgpYDogdGhpcyBjb21wb25lbnQgaXNcbiAgICAvLyBhbHNvIGNvbnN0cnVjdGVkIGRpcmVjdGx5IHdpdGggYG5ld2AgaW4gaXRzIG93biBzcGVjcywgd2hpY2ggaXMgb3V0c2lkZVxuICAgIC8vIGFuIGluamVjdGlvbiBjb250ZXh0IGFuZCB3b3VsZCB0aHJvdyBORzAyMDMgb24gYSBmaWVsZCBpbml0aWFsaXplci5cbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFRPT0xCQVJfVE9PTFMpIHRvb2xDb250cmlidXRpb25zPzogcmVhZG9ubHkgVG9vbGJhckNvbnRyaWJ1dGlvbltdLFxuICAgIC8vIE9wdGlvbmFsIGxpa2UgdGhlIHJlc3Q6IGEgaG9zdCB0aGF0IHNob3dzIG9ubHkgaW1hZ2VzIG5ldmVyIHByb3ZpZGVzIGl0LFxuICAgIC8vIGFuZCB0aGUgc3BhdGlhbCBwbG90IHR5cGVzIHNpbXBseSBzdGF5IGhpZGRlbi5cbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFNQQVRJQUxfREFUQV9QT1JUKSBwcml2YXRlIHNwYXRpYWxEYXRhPzogU3BhdGlhbERhdGFQb3J0LFxuICAgIC8vIENvbnRyaWJ1dGVkIHBsb3QgbW9kZXMuIExpa2UgVE9PTEJBUl9UT09MUyB0aGUgdG9rZW4gaGFzIG5vIGZhY3RvcnksIHNvIGFcbiAgICAvLyBob3N0IHRoYXQgcHJvdmlkZXMgbm9uZSBnZXRzIG51bGwgaGVyZSBhbmQgdGhlIHNlbGVjdG9yIGlzIHVuY2hhbmdlZC5cbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KFBMT1RfVFlQRV9DT05UUklCVVRJT05TKSBwbG90VHlwZUNvbnRyaWJ1dGlvbnM/OiByZWFkb25seSBQbG90VHlwZUNvbnRyaWJ1dGlvbltdLFxuICAgIC8vIFBhcmVudCBvZiBhIGNvbnRyaWJ1dGVkIHBhbmVsIGNvbXBvbmVudCdzIGluamVjdG9yLiBPcHRpb25hbCBvbmx5IHNvIHRoZVxuICAgIC8vIHNwZWNzIGNhbiBjb25zdHJ1Y3QgdGhpcyBjb21wb25lbnQgd2l0aCBgbmV3YC5cbiAgICBAT3B0aW9uYWwoKSBwcml2YXRlIGluamVjdG9yPzogSW5qZWN0b3IsXG4gICAgLy8gVGhlIGA8dmlzdWFsaXplcj5gIGVsZW1lbnQ6IGtleWJvYXJkIHNob3J0Y3V0cyBhcmUgc2NvcGVkIHRvIGl0IChDT1JFLTIpLlxuICAgIEBPcHRpb25hbCgpIHByaXZhdGUgaG9zdFJlZj86IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+LFxuICAgIC8vIEVuZHMgdGhlIHN1YnNjcmlwdGlvbnMgKGB0YWtlVW50aWxEZXN0cm95ZWRgKS4gQSBwYXJhbWV0ZXIsIGxpa2UgdGhlIHJlc3QsIHNvIHRoZVxuICAgIC8vIHNwZWNzJyBgbmV3YCBjYW4gcGFzcyBvbmU7IEFuZ3VsYXIgYWx3YXlzIHByb3ZpZGVzIGl0LlxuICAgIHByaXZhdGUgcmVhZG9ubHkgZGVzdHJveVJlZjogRGVzdHJveVJlZiA9IHVuZGVmaW5lZCBhcyB1bmtub3duIGFzIERlc3Ryb3lSZWYsXG4gICkge1xuICAgIHRoaXMuY29udHJpYnV0ZWRUb29scyA9IHZpc2libGVUb29sQ29udHJpYnV0aW9ucyh0b29sQ29udHJpYnV0aW9ucyk7XG4gICAgdGhpcy50b29sUGFyYW1zID0gbmV3IFRvb2xQYXJhbXNNb2RlbCh0aGlzLmNvbnRyaWJ1dGVkVG9vbHMpO1xuICAgIHRoaXMuY29udHJpYnV0aW9ucyA9IG5ldyBDb250cmlidXRpb25Ib3N0KHBsb3RUeXBlQ29udHJpYnV0aW9ucywgdG9vbENvbnRyaWJ1dGlvbnMsIHtcbiAgICAgIHZpc3VhbGl6ZXI6IHRoaXMucGxvdFNlcnZpY2UsXG4gICAgICB6b25lOiB0aGlzLm5nWm9uZSxcbiAgICAgIHRvb2xzOiB0aGlzLnRvb2xzLnBsb3RNb2RlVG9vbHMsXG4gICAgICBpbmplY3RvcjogdGhpcy5pbmplY3RvcixcbiAgICAgIGltYWdlSW5mbyQ6ICgpID0+IHRoaXMuc3RhdGUuZ2V0SW1hZ2VJbmZvJCgpLFxuICAgICAgc2VsZWN0ZWRJZDogKCkgPT4gdGhpcy5zZWxlY3RlZFBsb3RUeXBlSWQsXG4gICAgICByZW5kZXJlZFR5cGU6ICgpID0+IHRoaXMucGxvdFR5cGUsXG4gICAgICBzZWxlY3RCYXNlOiAoYmFzZSkgPT4ge1xuICAgICAgICB0aGlzLnNlbGVjdGVkUGxvdFR5cGVJZCA9IGJhc2U7XG4gICAgICAgIHRoaXMucGxvdFR5cGUgPSBiYXNlO1xuICAgICAgfSxcbiAgICAgIG5vdGlmeTogKG0pID0+IHRoaXMubWVzc2FnZVNlcnZpY2UuYWRkKHsga2V5OiB0aGlzLnJlc3VsdFRvYXN0S2V5LCAuLi5tIH0pLFxuICAgICAgZGV0ZWN0Q2hhbmdlczogKCkgPT4gdGhpcy5jZHIuZGV0ZWN0Q2hhbmdlcygpLFxuICAgIH0pO1xuICAgIHRoaXMucmVnaW9uU2V0TGluayA9IG5ldyBTcGF0aWFsUmVnaW9uU2V0TGluayh0aGlzLnNwYXRpYWxEYXRhLCB0aGlzLnBsb3RTZXJ2aWNlKTtcbiAgICB0aGlzLnNwYXRpYWwgPSBuZXcgU3BhdGlhbERhdGFzZXRCaW5kZXIodGhpcy5zcGF0aWFsRGF0YSwge1xuICAgICAgZ2F0ZXNDaGFuZ2VkOiAoKSA9PiB0aGlzLmNvbXB1dGVQbG90VHlwZU9wdGlvbnMoKSxcbiAgICAgIHNlbGVjdGVkSWQ6ICgpID0+IHRoaXMuc2VsZWN0ZWRQbG90VHlwZUlkLFxuICAgICAgYmFzZVBsb3RUeXBlOiAoKSA9PiB0aGlzLmJhc2VQbG90VHlwZSxcbiAgICAgIGhhc0ltYWdlOiAoKSA9PiAhIXRoaXMuaW1hZ2VJbmZvLFxuICAgICAgc2VsZWN0UGxvdFR5cGU6ICh0eXBlKSA9PiB0aGlzLm9uU2VsZWN0UGxvdFR5cGUodHlwZSksXG4gICAgICByZXBsb3Q6ICgpID0+IHRoaXMucmVsb2FkQW5kUGxvdCgpLFxuICAgICAgcHVibGlzaEltYWdlOiAoaW5mbykgPT4gdGhpcy5zdGF0ZS5zZXRJbWFnZUluZm8oaW5mbyksXG4gICAgICBzZXRJbWFnZUxvYWRpbmc6IChsb2FkaW5nKSA9PiB0aGlzLnN0YXRlLnNldEltYWdlTG9hZGluZyhsb2FkaW5nKSxcbiAgICAgIHNldHRsZWQ6ICgpID0+IHtcbiAgICAgICAgdGhpcy5yZWNvbmNpbGVTZWxlY3RlZFBsb3RUeXBlKCk7XG4gICAgICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgICAgfSxcbiAgICAgIGRldGVjdENoYW5nZXM6ICgpID0+IHRoaXMuY2hhbmdlZCgpLFxuICAgIH0pO1xuICAgIHRoaXMuY29tcHV0ZVBsb3RUeXBlT3B0aW9ucygpO1xuICB9XG5cbiAgLyoqIEZvbGxvdyB0aGUgc3BhdGlhbC1vbWljcyBkYXRhc2V0OiBhIGRhdGFzZXQgYXBwZWFyaW5nLCBzd2l0Y2hpbmcgb3IgYmVpbmcgY2xlYXJlZFxuICAgKiAgcmUtZ2F0ZXMgdGhlIHNlbGVjdG9yIGV4YWN0bHkgYXMgdGhlIGltYWdlIHN0cmVhbSBhbmQgdGhlIHRlc3QtbW9kZSB0b2dnbGUgZG8uICovXG4gIHByaXZhdGUgd2F0Y2hTcGF0aWFsRGF0YXNldCgpOiB2b2lkIHtcbiAgICB0aGlzLnNwYXRpYWwuYmluZCh0aGlzLmRlc3Ryb3llZCQpO1xuICAgIHRoaXMucmVnaW9uU2V0TGluay5iaW5kKHRoaXMuZGVzdHJveWVkJCk7XG4gICAgY29uc3QgcGxhbmVzJCA9IHRoaXMucGxvdFNlcnZpY2UuZ2V0RGF0YXNldFBsYW5lcyQ/LigpO1xuICAgIGlmIChwbGFuZXMkKSB7XG4gICAgICB0aGlzLm1pcnJvcihwbGFuZXMkLCAocGxhbmVzKSA9PiB7XG4gICAgICAgIHRoaXMuZGF0YXNldFBsYW5lcyA9IHBsYW5lcz8ubGVuZ3RoID8/IDA7XG4gICAgICAgIHRoaXMubGF5T3V0UGxhbmVzKCk7XG4gICAgICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBzbGlkZXIgb3ZlciB0aGUgZGF0YXNldCdzIHBsYW5lcywgb24gYW4gaW1hZ2Ugb2Ygb25lIHBsYW5lOiBpdHMgYm91bmRzIGFyZSB0aGUgcGxhbmVzJ1xuICAgKiAobm9uZSBsZWZ0OiBiYWNrIHRvIHRoZSBpbWFnZSdzIG9uZSksIHRoZSBzbGljZSBrZXB0IHdpdGhpbiB0aGVtLlxuICAgKi9cbiAgcHJpdmF0ZSBsYXlPdXRQbGFuZXMoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuaW1hZ2VJbmZvPy5pc1N0YWNrKSByZXR1cm47XG4gICAgY29uc3QgbWF4ID0gdGhpcy5wbGFuZU1heEluZGV4KCk7XG4gICAgaWYgKG1heCA9PT0gdGhpcy5tYXhJbmRleCkgcmV0dXJuO1xuICAgIHRoaXMubWF4SW5kZXggPSBtYXg7XG4gICAgaWYgKHRoaXMuekluZGV4ID4gbWF4KSB0aGlzLm9uWlNsaWRlKG1heCk7XG4gIH1cblxuICAvKiogVGhlIGxhc3Qgc2xpY2UgaW5kZXggdGhlIGRhdGFzZXQncyBwbGFuZXMgZ2l2ZSBhbiBpbWFnZSBvZiBvbmUgcGxhbmUgKDAgd2l0aG91dCkuICovXG4gIHByaXZhdGUgcGxhbmVNYXhJbmRleCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmRhdGFzZXRQbGFuZXMgPiAxID8gdGhpcy5kYXRhc2V0UGxhbmVzIC0gMSA6IDA7XG4gIH1cblxuICAvKiogUmVjb21wdXRlIHRoZSBzZWxlY3RvcidzIGVudHJpZXMgZm9yIHRoZSBjdXJyZW50IGltYWdlLCBkYXRhc2V0IGFuZCB0ZXN0IG1vZGVcbiAgICogIChzZWUge0BsaW5rIGNvbXB1dGVQbG90VHlwZU1lbnV9KS4gKi9cbiAgcHJpdmF0ZSBjb21wdXRlUGxvdFR5cGVPcHRpb25zKCkge1xuICAgIGNvbnN0IHsgYnVpbHRJbiwgbWVudSB9ID0gY29tcHV0ZVBsb3RUeXBlTWVudSh7XG4gICAgICBkZXNjcmlwdG9yczogdGhpcy5wbG90U2VydmljZS5nZXRQbG90VHlwZURlc2NyaXB0b3JzKCksXG4gICAgICBjb250cmlidXRpb25zOiB0aGlzLnBsb3RNb2Rlcy5kZXNjcmlwdG9ycygpLFxuICAgICAgY2FwczogdGhpcy5wbG90U2VydmljZS5jYXBhYmlsaXRpZXMsXG4gICAgICBpbWFnZUluZm86IHRoaXMuaW1hZ2VJbmZvLFxuICAgICAgc3BhdGlhbDogdGhpcy5zcGF0aWFsLFxuICAgICAgdGVzdE1vZGU6IHRoaXMudGVzdE1vZGUsXG4gICAgfSk7XG4gICAgdGhpcy5wbG90VHlwZU9wdGlvbnMgPSBidWlsdEluO1xuICAgIHRoaXMucGxvdFR5cGVNZW51ID0gbWVudTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICAvLyBUaGUgY29uc3RydWN0b3IgY29tcHV0ZXMgdGhlIG9wdGlvbnMgd2l0aCB0ZXN0TW9kZSBzdGlsbCBhdCBpdHMgZGVmYXVsdDtcbiAgICAvLyByZWNvbXB1dGUgb25jZSB0aGUgaG9zdCBiaW5kcyBpdCAoYW5kIG9uIGFueSBsYXRlciBjaGFuZ2UpIHNvIHRoZSBzZWxlY3RvclxuICAgIC8vIHJlZmxlY3RzIHRlc3QgbW9kZSBpbW1lZGlhdGVseSwgd2l0aG91dCB3YWl0aW5nIGZvciBhbiBpbWFnZSB0byAocmUpbG9hZC5cbiAgICBpZiAoY2hhbmdlc1sndGVzdE1vZGUnXSkge1xuICAgICAgdGhpcy5jb21wdXRlUGxvdFR5cGVPcHRpb25zKCk7XG4gICAgICAvLyBJZiB0ZXN0IG1vZGUgaXMgdHVybmVkIG9mZiB3aGlsZSBhIHRlc3Qtb25seSB0eXBlIChlLmcuIE5BUEFSSV9JTUFHRSkgaXNcbiAgICAgIC8vIGFjdGl2ZSwgdGhhdCB0eXBlIGlzIG5vIGxvbmdlciBvZmZlcmVkIOKAlCBmYWxsIGJhY2sgdG8gSW1hZ2UuXG4gICAgICB0aGlzLnJlY29uY2lsZVNlbGVjdGVkUGxvdFR5cGUoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVGhlIGhvc3QgcHVibGlzaGVkIE5PIGltYWdlIOKAlCBhIHNwYXRpYWwgZGF0YXNldCB0aGF0IGJyaW5ncyBub25lIGRvZXMgdGhpcy5cbiAgICpcbiAgICogV2l0aG91dCBoYW5kbGluZyB0aGUgZW1wdHkgZW1pc3Npb24sIGBpbWFnZUluZm9gIGtlZXBzIHRoZSBMQVNUIGltYWdlJ3MgbWV0YWRhdGE6IHRoZVxuICAgKiBzZWxlY3RvciBnb2VzIG9uIG9mZmVyaW5nIHBpeGVsIG1vZGVzIGZvciBwaXhlbHMgdGhhdCBhcmUgZ29uZSwgYW5kIGV2ZXJ5XG4gICAqIGBpc1N0YWNrYC9gaXNHcmF5c2NhbGVgIGRlY2lzaW9uIGlzIG1hZGUgYWdhaW5zdCBhIGZpbGUgdGhhdCBpcyBubyBsb25nZXIgbG9hZGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBvbkltYWdlQ2xlYXJlZCgpOiB2b2lkIHtcbiAgICAvLyBUaGUgaW1hZ2UgYSBjb250cmlidXRlZCBtb2RlIHdhcyBkcmF3aW5nIG92ZXIgaXMgZ29uZS4gQW4gb3BlbiBkaWFsb2dcbiAgICAvLyB0b29sIHN0YXlzIG9wZW4gYW5kIHJlc3RhcnRzIG9uY2UgdGhlIG5leHQgaW1hZ2UgaGFzIHBsb3R0ZWQuXG4gICAgdGhpcy5jb250cmlidXRpb25zLmVuZFNlc3Npb25zKCk7XG4gICAgdGhpcy5pbWFnZUluZm8gPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5sb2FkZWRGaWxlTmFtZSA9IHVuZGVmaW5lZDtcbiAgICB0aGlzLmNvbXB1dGVQbG90VHlwZU9wdGlvbnMoKTtcbiAgICAvLyBEZWxpYmVyYXRlbHkgTk9UIHJlY29uY2lsaW5nIHRoZSBzZWxlY3RlZCB0eXBlIGhlcmUuIFJlY29uY2lsaW5nIGNhbGxzXG4gICAgLy8gYHNldFBsb3RUeXBlYCwgd2hpY2ggZHJpdmVzIGEgcmUtcGxvdCDigJQgYW5kIHRoZXJlIGlzIG5vdGhpbmcgdG8gcGxvdCwgc28gdGhlXG4gICAgLy8gUGxvdGx5IGJhY2tlbmQgcmVhZCBpdHMgb3duIG5vdy11bnNldCBgaW1hZ2VJbmZvYCBhbmQgdGhyZXdcbiAgICAvLyAoXCJjYW4ndCBhY2Nlc3MgcHJvcGVydHkgaXNHcmF5c2NhbGVcIiksIGFib3J0aW5nIHRoZSBsb2FkIHdpdGggbm8gb2JzZXJ2YXRpb25zXG4gICAgLy8gZHJhd24uIElnbm9yaW5nIHRoZSBlbXB0eSBlbWlzc2lvbiBlbnRpcmVseSBpcyB3aGF0IHVzZWQgdG8gYXZvaWQgdGhhdC5cbiAgICAvL1xuICAgIC8vIE5vdGhpbmcgaXMgbGVmdCBzdHJhbmRlZDogYW4gaW1hZ2UgaXMgY2xlYXJlZCBiZWNhdXNlIGEgc3BhdGlhbCBkYXRhc2V0IHRoYXRcbiAgICAvLyBicmluZ3Mgbm9uZSBpcyBiZWluZyBvcGVuZWQsIGFuZCB0aGF0IGRhdGFzZXQncyBvd24gc3Vic2NyaXB0aW9uIHNlbGVjdHMgdGhlXG4gICAgLy8gbW9kZSBpdHMgY29vcmRpbmF0ZXMgc3VwcG9ydCBhIG1vbWVudCBsYXRlci5cbiAgICB0aGlzLmNoYW5nZWQoKTtcbiAgfVxuXG4gIC8qKiBJZiB0aGUgYWN0aXZlIHBsb3QgdHlwZSBpcyBubyBsb25nZXIgaW4gdGhlIG9mZmVyZWQgb3B0aW9ucyAoZS5nLiB0ZXN0IG1vZGVcbiAgICogIHR1cm5lZCBvZmYgd2hpbGUgYSB0ZXN0LW9ubHkgdHlwZSB3YXMgYWN0aXZlLCBvciBhIHNjYWxhciB0eXBlIGNhcnJpZWQgb250b1xuICAgKiAgYW4gUkdCIGltYWdlKSwgZmFsbCBiYWNrIHRvIHRoZSBkZWZhdWx0IDJEIEltYWdlIHZpZXcuICovXG4gIHByaXZhdGUgcmVjb25jaWxlU2VsZWN0ZWRQbG90VHlwZSgpOiB2b2lkIHtcbiAgICBjb25zdCBmYWxsYmFjayA9IHJlY29uY2lsZVBsb3RUeXBlKHRoaXMucGxvdFR5cGVNZW51LCB0aGlzLnNlbGVjdGVkUGxvdFR5cGVJZCk7XG4gICAgaWYgKCFmYWxsYmFjaykgcmV0dXJuO1xuICAgIC8vIExlYXZpbmcgYSBjb250cmlidXRlZCBtb2RlIChpdHMgZ2F0ZXMgc3RvcHBlZCBwYXNzaW5nLCBvciBpdHMgcHJvdmlkZXIgaXNcbiAgICAvLyBnb25lKTogaXRzIHNlc3Npb24gZW5kcyBiZWZvcmUgYW55dGhpbmcgZWxzZSBkcmF3cy5cbiAgICB0aGlzLnBsb3RNb2Rlcy5kZWFjdGl2YXRlKCk7XG4gICAgY29uc3QgYmFzZSA9IHRoaXMucGxvdE1vZGVzLmJhc2VUeXBlT2YoZmFsbGJhY2spO1xuICAgIGlmIChiYXNlICE9PSBQbG90VHlwZS5JTUFHRSkgdGhpcy5jbG9zZURpYWxvZ1Rvb2woKTtcbiAgICB0aGlzLnNlbGVjdGVkUGxvdFR5cGVJZCA9IGZhbGxiYWNrO1xuICAgIHRoaXMucGxvdFR5cGUgPSBiYXNlO1xuICAgIHRoaXMuaXNIZWF0bWFwID0gYmFzZSA9PT0gUGxvdFR5cGUuSU1BR0U7XG4gICAgdGhpcy5wbG90U2VydmljZS5zZXRQbG90VHlwZShiYXNlKTtcbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIC8vIEpvaW4gdGhlIGxpdmUgc2V0OyB0aGUgb2xkZXN0IG1lbWJlciByZW5kZXJzIHRoZSBzaGFyZWQgbm90aWNlIG91dGxldHMuXG4gICAgVmlzdWFsaXplckNvbXBvbmVudC5saXZlSW5zdGFuY2VzLmFkZCh0aGlzKTtcbiAgICB0aGlzLnN0YXRlLnNldERpYWdyYW0odGhpcy5ob3N0SGFuZGxlKTtcbiAgICB0aGlzLndhdGNoU3BhdGlhbERhdGFzZXQoKTtcbiAgICAvLyBPU0QgYW5kIG5hcGFyaS1qcyBlbWl0IHRoaXMgZnJvbSB0aGVpciBvd24gXCJmaXQgdG8gdmlld1wiOiBkaXNhcm0gdGhlIHRvb2wgb25cbiAgICAvLyB0aGUgYmFja2VuZCB0b28sIG5vdCBvbmx5IHRoZSB0b29sYmFyJ3MgaGlnaGxpZ2h0LlxuICAgIHRoaXMucGxvdFNlcnZpY2VcbiAgICAgIC5nZXRBdXRvc2NhbGVFdmVudCgpXG4gICAgICAucGlwZSh0YWtlVW50aWxEZXN0cm95ZWQodGhpcy5kZXN0cm95UmVmKSlcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy50b29scy5hcHBseShudWxsKSk7XG4gICAgLy8gTG9hZGluZy9vdmVybGF5IFVJIG1pcnJvcnMgKHNpZ25hbHM6IHRoZXkgcmUtcmVuZGVyIHRoZSB2aWV3IHRoZW1zZWx2ZXMpLlxuICAgIHRoaXMubWlycm9yKHRoaXMuc3RhdGUuaXNJbWFnZUxvYWRpbmckKCksICh2KSA9PiB0aGlzLmltZ0xvYWRpbmcuc2V0KHYpKTtcbiAgICB0aGlzLm1pcnJvcih0aGlzLnBsb3RTZXJ2aWNlLmdldFN0YWNrTG9hZGluZ1Byb2dyZXNzKCksICh2KSA9PiB0aGlzLmxvYWRpbmdQZXJjZW50YWdlLnNldCh2KSk7XG4gICAgdGhpcy5taXJyb3IodGhpcy5wbG90U2VydmljZS5pc1N0YWNrTG9hZGluZygpLCAodikgPT4gdGhpcy5zdGFja0xvYWRpbmcuc2V0KHYpKTtcbiAgICAvLyBUaGUgc2xpY2UgZWRpdG9yOiBpdHMgc2VjdGlvbnMsIGFuZCB0aGUgc2xpY2UgcGlja2VkIGJ5IGRyYWdnaW5nIHRoZSB6IHBsYW5lIGluIHRoZSB2b2x1bWUuXG4gICAgY29uc3Qgc2VjdGlvbnMkID0gdGhpcy5wbG90U2VydmljZS5nZXRTZWN0aW9uVmlld3MkPy4oKTtcbiAgICBpZiAoc2VjdGlvbnMkKSB7XG4gICAgICB0aGlzLm1pcnJvcihzZWN0aW9ucyQsICh2KSA9PiB7XG4gICAgICAgIHRoaXMuc2VjdGlvbnMgPSB2O1xuICAgICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICBjb25zdCBzbGljZURyYWckID0gdGhpcy5wbG90U2VydmljZS5nZXRTbGljZURyYWckPy4oKTtcbiAgICBpZiAoc2xpY2VEcmFnJCkge1xuICAgICAgdGhpcy5taXJyb3Ioc2xpY2VEcmFnJCwgKHopID0+IHtcbiAgICAgICAgdGhpcy5vblpTY3J1YihNYXRoLm1pbih0aGlzLm1heEluZGV4LCBNYXRoLm1heCgwLCB6KSkpO1xuICAgICAgICAvLyBGcm9tIGEgRE9NIGxpc3RlbmVyLCBub3QgYSB0ZW1wbGF0ZSBldmVudDogdGhlIHNsaWRlciBhbmQgYmFkZ2UgbXVzdCBiZSBtYXJrZWQgdG8gZm9sbG93LlxuICAgICAgICB0aGlzLmNoYW5nZWQoKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgICB0aGlzLm1pcnJvcih0aGlzLnN0YXRlLmdldEltYWdlTG9hZGluZ01lc3NhZ2UkKCksICh2KSA9PiB0aGlzLmxvYWRpbmdNZXNzYWdlLnNldCh2KSk7XG4gICAgdGhpcy5taXJyb3IodGhpcy5zdGF0ZS5nZXRDYWNoZVByb2dyZXNzJCgpLCAodikgPT4gdGhpcy5jYWNoZVByb2dyZXNzLnNldCh2KSk7XG4gICAgdGhpcy5taXJyb3IodGhpcy5zdGF0ZS5pc1pvb20kKCksICh2KSA9PiB0aGlzLnpvb20uc2V0KHYpKTtcbiAgICB0aGlzLm1pcnJvcih0aGlzLnN0YXRlLmdldEZpbGVuYW1lJCgpLCAodikgPT4ge1xuICAgICAgaWYgKHYpIHRoaXMuZmlsZU5hbWUgPSB2O1xuICAgIH0pO1xuICAgIHRoaXMucmVnaW9uQWN0aW9ucy5iaW5kKHRoaXMuZGVzdHJveWVkJCwgKCkgPT4gdGhpcy5jaGFuZ2VkKCkpO1xuICAgIHRoaXMuc2VnbWVudGF0aW9uLmJpbmRQb2ludFRvb2wodGhpcy5zYW1Qb2ludFRvb2wsIHRoaXMuZGVzdHJveWVkJCk7XG4gICAgdGhpcy5taXJyb3IodGhpcy5zdGF0ZS5nZXRQYW5lbFdpZHRoJCgpLCAoKSA9PiB7XG4gICAgICB0aGlzLnBsb3RTZXJ2aWNlLnJlbGF5b3V0KCk7XG4gICAgICAvLyBUaGUgaW50ZW5zaXR5IGluc2V0IGlzIGEgc2VwYXJhdGUgY2hhcnQgaW4gYSBmbG9hdGluZyBwYW5lbDsgcmVmbG93IGl0IHRvby5cbiAgICAgIHRoaXMuaW5zZXQ/LnJlZmxvdygpO1xuICAgIH0pO1xuICAgIHRoaXMuc3RhdGVcbiAgICAgIC5nZXRJbWFnZUluZm8kKClcbiAgICAgIC5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLmRlc3Ryb3lSZWYpKVxuICAgICAgLnN1YnNjcmliZSh7XG4gICAgICAgIG5leHQ6IChpbWdJbmZvKSA9PiB7XG4gICAgICAgICAgaWYgKCFpbWdJbmZvKSB7XG4gICAgICAgICAgICB0aGlzLm9uSW1hZ2VDbGVhcmVkKCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICAgIC8vIFRoZSBzZWxlY3RvciwgdGhlIHN0YWNrIGNvbnRyb2xzIGFuZCB0aGUgaW5zZXQgYWxsIGZvbGxvdyB0aGUgaW1hZ2UuXG4gICAgICAgICAgdGhpcy5jaGFuZ2VkKCk7XG4gICAgICAgICAgaWYgKGltZ0luZm8pIHtcbiAgICAgICAgICAgIHRoaXMuaW1hZ2VJbmZvID0gaW1nSW5mbztcbiAgICAgICAgICAgIC8vIFN0YWNrLW9ubHkgcGxvdCB0eXBlcyAoaXNvc3VyZmFjZSwgc2NhdHRlcjNkKSBkZXBlbmQgb24gd2hldGhlciB0aGlzXG4gICAgICAgICAgICAvLyBmaWxlIGlzIGEgc3RhY2sg4oCUIHJlY29tcHV0ZSB0aGUgc2VsZWN0b3Igb3B0aW9ucy5cbiAgICAgICAgICAgIHRoaXMuY29tcHV0ZVBsb3RUeXBlT3B0aW9ucygpO1xuICAgICAgICAgICAgLy8gSWYgdGhlIGFjdGl2ZSBwbG90IHR5cGUgaXNuJ3QgdmFsaWQgZm9yIHRoaXMgaW1hZ2UgKGUuZy4gYSBzY2FsYXJcbiAgICAgICAgICAgIC8vIHR5cGUgbGlrZSBDb250b3VyIGNhcnJpZWQgb3ZlciB0byBhbiBSR0IgaW1hZ2UpLCBmYWxsIGJhY2sgdG8gSW1hZ2UuXG4gICAgICAgICAgICB0aGlzLnJlY29uY2lsZVNlbGVjdGVkUGxvdFR5cGUoKTtcbiAgICAgICAgICAgIC8vIFJlYWQgZnJvbSBgaW1nSW5mb2AsIHRoZSB2YWx1ZSB0aGlzIGVtaXNzaW9uIGNhcnJpZWQsIHJhdGhlciB0aGFuIGZyb20gdGhlXG4gICAgICAgICAgICAvLyBmaWVsZC4gSGFuZGxpbmcgdGhlIGVtcHR5IGVtaXNzaW9uIG1lYW5zIHRoZSBmaWVsZCBDQU4gYmUgbnVsbGVkIHBhcnQtd2F5XG4gICAgICAgICAgICAvLyB0aHJvdWdoIHRoaXMgYnJhbmNoOiBgcmVjb25jaWxlU2VsZWN0ZWRQbG90VHlwZWAgbWF5IGNhbGwgYHNldFBsb3RUeXBlYCxcbiAgICAgICAgICAgIC8vIHdoaWNoIGNhbiBtYWtlIHRoZSBob3N0IHB1Ymxpc2ggYSBuZXcgaW1hZ2Ugc3RhdGUsIHJlLWVudGVyaW5nIHRoaXMgdmVyeVxuICAgICAgICAgICAgLy8gc3Vic2NyaXB0aW9uLiBSZWFkaW5nIHRoZSBmaWVsZCB0aGVuIHRocmV3IG9uIGBpc0dyYXlzY2FsZWAgYW5kIGFib3J0ZWQgdGhlXG4gICAgICAgICAgICAvLyBoYW5kbGVyLCBzbyB0aGUgb2JzZXJ2YXRpb25zIHdlcmUgbmV2ZXIgZHJhd24uXG4gICAgICAgICAgICB0aGlzLmlzR3JheXNjYWxlRXZlbnQuZW1pdChpbWdJbmZvLmlzR3JheXNjYWxlKTtcbiAgICAgICAgICAgIHRoaXMuaXNTdGFja0V2ZW50LmVtaXQoaW1nSW5mby5pc1N0YWNrKTtcbiAgICAgICAgICAgIC8vIFJlc2V0IHRvIHRoZSBkZWZhdWx0IDJEIEltYWdlIHZpZXcgd2hlbiBhIGRpZmZlcmVudCBpbWFnZSBpc1xuICAgICAgICAgICAgLy8gc2VsZWN0ZWQgd2hpbGUgYSAzRCB0eXBlIGlzIGFjdGl2ZS5cbiAgICAgICAgICAgIGlmICghdGhpcy5pc0hlYXRtYXAgJiYgaW1nSW5mby5maWxlTmFtZSAhPT0gdGhpcy5sb2FkZWRGaWxlTmFtZSkge1xuICAgICAgICAgICAgICB0aGlzLmlzSGVhdG1hcCA9IHRydWU7XG4gICAgICAgICAgICAgIHRoaXMucGxvdFR5cGUgPSBQbG90VHlwZS5JTUFHRTtcbiAgICAgICAgICAgICAgdGhpcy5zZWxlY3RlZFBsb3RUeXBlSWQgPSBQbG90VHlwZS5JTUFHRTtcbiAgICAgICAgICAgICAgdGhpcy5wbG90U2VydmljZS5zZXRQbG90VHlwZSh0aGlzLnBsb3RUeXBlKTtcbiAgICAgICAgICAgICAgdGhpcy5hY3RpdmVTdXJmYWNlM2RNb2RlID0gJ3R1cm50YWJsZSc7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmxvYWRlZEZpbGVOYW1lID0gaW1nSW5mby5maWxlTmFtZTtcbiAgICAgICAgICAgIHRoaXMucGxvdFNlcnZpY2Uuc2V0SW1hZ2VNZXRhKGltZ0luZm8uaW1hZ2VNZXRhLCBpbWdJbmZvLmZpbGVOYW1lKTtcbiAgICAgICAgICAgIC8vIEEgbmV3ZXIgaW1hZ2UgYWx3YXlzIHByZWVtcHRzIGFuIGluLWZsaWdodCByZW5kZXIgKHNlZSBJbWFnZVJlbmRlclNlc3Npb24pLlxuICAgICAgICAgICAgaWYgKGltZ0luZm8udXJscykgdGhpcy5yZW5kZXIucmVuZGVyKGltZ0luZm8pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgICAgZXJyb3I6IChlcnI6IHVua25vd24pID0+IHtcbiAgICAgICAgICBjb25zdCBtc2cgPSBlcnJvck1lc3NhZ2UoZXJyKTtcbiAgICAgICAgICBjb25zb2xlLmVycm9yKCdFcnJvciBvY2N1cmVkIHdoZW4gZ2V0dGluZyBpbWFnZSBpbmZvJywgZXJyKTtcbiAgICAgICAgICB0aGlzLm1lc3NhZ2VTZXJ2aWNlLmFkZCh7XG4gICAgICAgICAgICBrZXk6IHRoaXMudml6QWxlcnRUb2FzdEtleSxcbiAgICAgICAgICAgIHN0aWNreTogdHJ1ZSxcbiAgICAgICAgICAgIHNldmVyaXR5OiAnZXJyb3InLFxuICAgICAgICAgICAgc3VtbWFyeTogJ0FuIGVycm9yIG9jY3VyZWQnLFxuICAgICAgICAgICAgZGV0YWlsOiBgVGhlIGZvbGxvd2luZyBlcnJvciBvY2N1cmVkIHdoaWxlIGdldHRpbmcgaW1hZ2UgaW5mbzogJHttc2d9LlxuICAgICAgICAgICAgICAgICAgIFBsZWFzZSB0cnkgdG8gb3BlbiB0aGUgaW1hZ2UgYWdhaW4gdGhyb3VnaCB0aGUgZmlsZSBuYXZpZ2F0b3IuYCxcbiAgICAgICAgICB9KTtcbiAgICAgICAgICB0aGlzLnN0YWNrTG9hZGluZy5zZXQoZmFsc2UpO1xuICAgICAgICAgIHRoaXMuc3RhdGUuc2V0SW1hZ2VMb2FkaW5nKGZhbHNlKTtcbiAgICAgICAgICB0aGlzLnJlbmRlci5ydW5uaW5nID0gZmFsc2U7XG4gICAgICAgICAgdGhpcy5wbG90U2VydmljZS5yZXNldCgpO1xuICAgICAgICB9LFxuICAgICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogRm9sbG93IGBzb3VyY2VgIHVudGlsIGRlc3Ryb3kuIEhvc3Qgc3RyZWFtcyBjYW4gZW1pdCBvdXRzaWRlIHRoZSBBbmd1bGFyIHpvbmUgKGFcbiAgICogc2VydmVybGVzcyBob3N0IGNsZWFycyBpdHMgbG9hZGluZyBmbGFnIGZyb20gYW4gaW1hZ2UgZGVjb2RlIG9yIGFuIE9wZW5TZWFkcmFnb25cbiAgICogY2FsbGJhY2spOyBzZXR0aW5nIGEgc2lnbmFsIHRoZXJlIG1hcmtzIHRoaXMgT25QdXNoIHZpZXcgYnV0IHNjaGVkdWxlcyBubyBjaGFuZ2VcbiAgICogZGV0ZWN0aW9uLCBzbyB0aGUgdXBkYXRlIGlzIGFwcGxpZWQgaW5zaWRlIHRoZSB6b25lLCBhcyB7QGxpbmsgY2hhbmdlZH0gZG9lcy5cbiAgICovXG4gIHByaXZhdGUgbWlycm9yPFQ+KHNvdXJjZTogT2JzZXJ2YWJsZTxUPiwgYXBwbHk6ICh2YWx1ZTogVCkgPT4gdm9pZCk6IHZvaWQge1xuICAgIHNvdXJjZS5waXBlKHRha2VVbnRpbERlc3Ryb3llZCh0aGlzLmRlc3Ryb3lSZWYpKS5zdWJzY3JpYmUoKHZhbHVlKSA9PiB7XG4gICAgICBpZiAoTmdab25lLmlzSW5Bbmd1bGFyWm9uZSgpKSBhcHBseSh2YWx1ZSk7XG4gICAgICBlbHNlIHRoaXMubmdab25lLnJ1bigoKSA9PiBhcHBseSh2YWx1ZSkpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXRlIHRoaXMgdmlldyBzaG93cyBjaGFuZ2VkIG91dHNpZGUgb25lIG9mIGl0cyB0ZW1wbGF0ZSBldmVudHMgKGEgc3RyZWFtLCBhXG4gICAqIHJlc29sdmVkIHByb21pc2UsIGEgaG9zdCBjYWxsKTogbWFyayB0aGUgT25QdXNoIHZpZXcgZm9yIGNoZWNrLCByZS1lbnRlcmluZyB0aGVcbiAgICogem9uZSB3aGVuIGl0IGNoYW5nZWQgb3V0c2lkZSBpdCBzbyBhIGNoYW5nZS1kZXRlY3Rpb24gcGFzcyBmb2xsb3dzLlxuICAgKi9cbiAgcHJpdmF0ZSBjaGFuZ2VkKCk6IHZvaWQge1xuICAgIGlmIChOZ1pvbmUuaXNJbkFuZ3VsYXJab25lKCkpIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgIGVsc2UgdGhpcy5uZ1pvbmUucnVuKCgpID0+IHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMYXkgYSBuZXcgaW1hZ2Ugb3V0IG9uY2UgdGhlIG9sZCB2aWV3IGlzIGdvbmU6IHRoZSBzdGFjayBmbGFnLCB0aGUgc2xpY2UgYm91bmRzIChvbmVcbiAgICogdXJsIHBlciBzbGljZSwgc28gdGhlIGxhc3QgaW5kZXggaXMgbGVuZ3RoLTEpLCBhbmQgdGhlIG9uZS1zaG90IGBpbml0aWFsWkluZGV4YCBoaW50XG4gICAqIChlLmcuIHRoZSBmaWxlIHRoZSB1c2VyIGNsaWNrZWQgd2l0aGluIGEgbnVtYmVyZWQgc2VyaWVzKS4gVGhlIGhpbnQgaXMgY29uc3VtZWQgc29cbiAgICogcmUtZGVsaXZlcmluZyB0aGUgc2FtZSBpbmZvIChhIHBsb3QtdHlwZSBzd2l0Y2gsIHJlbG9hZEFuZFBsb3QpIGRvZXMgbm90IHJlc2V0IHRoZVxuICAgKiB1c2VyJ3Mgc2NydWI7IHRoZSBob3N0J3Mgb2JqZWN0IGlzIG5ldmVyIHdyaXR0ZW4gdG8gKGEgaG9zdCBzdG9yZSBtYXkgZnJlZXplIGl0KSDigJRcbiAgICogdGhlIGNvbXBvbmVudCBrZWVwcyBhIGNvcHkgd2l0aG91dCB0aGUgaGludCwgYW5kIHJlbWVtYmVycyB0aGUgaG9zdCBvYmplY3QuXG4gICAqL1xuICBwcml2YXRlIGxheU91dFNsaWNlcyhpbmZvOiBJSW1hZ2VJbmZvKTogdm9pZCB7XG4gICAgdGhpcy5zdGFja0xvYWRpbmcuc2V0KGluZm8uaXNTdGFjayAmJiBpbmZvLnNob3dTdGFjayk7XG4gICAgdGhpcy5tYXhJbmRleCA9IGluZm8udXJscy5sZW5ndGggPiAxID8gaW5mby51cmxzLmxlbmd0aCAtIDEgOiBpbmZvLmlzU3RhY2sgPyAwIDogdGhpcy5wbGFuZU1heEluZGV4KCk7XG4gICAgaWYgKGluZm8uaW5pdGlhbFpJbmRleCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAoIXRoaXMuY29uc3VtZWRTbGljZUhpbnRzLmhhcyhpbmZvKSkge1xuICAgICAgICB0aGlzLmNvbnN1bWVkU2xpY2VIaW50cy5hZGQoaW5mbyk7XG4gICAgICAgIHRoaXMuekluZGV4ID0gaW5mby5pbml0aWFsWkluZGV4O1xuICAgICAgfVxuICAgICAgdGhpcy5pbWFnZUluZm8gPSB7IC4uLmluZm8sIGluaXRpYWxaSW5kZXg6IHVuZGVmaW5lZCB9O1xuICAgIH1cbiAgICB0aGlzLnVwZGF0ZVpJbmRleCgpO1xuICB9XG5cbiAgbmdBZnRlclZpZXdJbml0KCkge1xuICAgIC8vIFdpbmRvdyBsaXN0ZW5lcnMgYXJlIHJlZ2lzdGVyZWQgT1VUU0lERSB0aGUgQW5ndWxhciB6b25lOiB6b25lLXBhdGNoZWQsIGV2ZXJ5XG4gICAgLy8gbW91c2Vtb3ZlIGFueXdoZXJlIGluIHRoZSBob3N0IGFwcCByYW4gYXBwLXdpZGUgY2hhbmdlIGRldGVjdGlvbi4gRWFjaCBoYW5kbGVyXG4gICAgLy8gcmUtZW50ZXJzIHRoZSB6b25lIChuZ1pvbmUucnVuKSBvbmx5IHdoZW4gaXQgYWN0dWFsbHkgY2hhbmdlcyB2aWV3IHN0YXRlLlxuICAgIHRoaXMuc2hvcnRjdXRzID0gbmV3IFZpZXdlclNob3J0Y3V0cyh0aGlzLnNob3J0Y3V0SG9zdCgpLCB0aGlzLm5nWm9uZSk7XG4gICAgdGhpcy5zaG9ydGN1dHMuYXR0YWNoKCk7XG4gICAgdGhpcy53aGVuSW5Eb2N1bWVudCgoKSA9PiB0aGlzLm9uVmlld1JlYWR5KCkpO1xuICB9XG5cbiAgLyoqIFRoZSBwbG90IGRpdiBleGlzdHMgbm93OiBydW4gYW4gaW1hZ2UtbGVzcyBkcmF3IHRoYXQgYXJyaXZlZCBiZWZvcmUgaXQgZGlkLiAqL1xuICBwcml2YXRlIG9uVmlld1JlYWR5KCk6IHZvaWQge1xuICAgIHRoaXMucmVuZGVyLnZpZXdJc1JlYWR5KHRoaXMuc3BhdGlhbC5kYXRhc2V0LCAhIXRoaXMuaW1hZ2VJbmZvKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW4gYHJlYWR5YCBvbmNlIHRoaXMgdmlld2VyIGlzIGluIHRoZSBkb2N1bWVudC4gQSBob3N0IG1heSBjcmVhdGUgaXQgZGV0YWNoZWQg4oCUIGEgY2xvc2VkXG4gICAqIGRpYWxvZydzIHByb2plY3RlZCBjb250ZW50LCBzdWNoIGFzIGppdC11aSdzIHBpcGVsaW5lIHByZXZpZXcg4oCUIGFuZCB0aGUgYmFja2VuZHMgZmluZCB0aGVcbiAgICogcGxvdCBkaXYgYnkgaWQsIHNvIGEgZHJhdyB0aGVuIGZvdW5kIG5vIHRhcmdldCBhbmQgYWxlcnRlZCBcInRoZSByZW5kZXJlciBjb3VsZCBub3Qgc3RhcnRcIlxuICAgKiBvdmVyIGFub3RoZXIgdmlld2VyLiBVbnRpbCB0aGVuIGl0cyB2aWV3IGlzIG5vdCByZWFkeSwgYW5kIGFuIGltYWdlLWxlc3MgZHJhdyB3YWl0cy5cbiAgICovXG4gIHByaXZhdGUgd2hlbkluRG9jdW1lbnQocmVhZHk6ICgpID0+IHZvaWQpOiB2b2lkIHtcbiAgICBjb25zdCBlbCA9IHRoaXMuaG9zdFJlZj8ubmF0aXZlRWxlbWVudDtcbiAgICBpZiAoIWVsIHx8IGVsLmlzQ29ubmVjdGVkIHx8IHR5cGVvZiBSZXNpemVPYnNlcnZlciA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJlYWR5KCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIEF0dGFjaGVkIGFuZCBsYWlkIG91dCwgaXRzIHNpemUgY2hhbmdlcyBmcm9tIG5vdGhpbmc6IHRoYXQgaXMgd2hlbiBpdCBjYW4gYmUgZHJhd24gaW50by5cbiAgICBjb25zdCBvYnNlcnZlciA9IG5ldyBSZXNpemVPYnNlcnZlcigoKSA9PiB7XG4gICAgICBpZiAoIWVsLmlzQ29ubmVjdGVkKSByZXR1cm47XG4gICAgICBvYnNlcnZlci5kaXNjb25uZWN0KCk7XG4gICAgICB0aGlzLmF0dGFjaE9ic2VydmVyID0gbnVsbDtcbiAgICAgIHRoaXMubmdab25lLnJ1bihyZWFkeSk7XG4gICAgfSk7XG4gICAgdGhpcy5hdHRhY2hPYnNlcnZlciA9IG9ic2VydmVyO1xuICAgIG9ic2VydmVyLm9ic2VydmUoZWwpO1xuICB9XG5cbiAgLyoqIFdoYXQgdGhlIGtleWJvYXJkLCB3aGVlbCBhbmQgY29udGV4dC1tZW51IHNob3J0Y3V0cyBhY3Qgb24uIFRoZWlyIGxpc3RlbmVycyBsaXZlXG4gICAqICBvdXRzaWRlIHRoaXMgdmlldywgc28gZXZlcnkgYWN0aW9uIHRoYXQgY2hhbmdlcyB3aGF0IGl0IHNob3dzIG1hcmtzIGl0IGZvciBjaGVjay4gKi9cbiAgcHJpdmF0ZSBzaG9ydGN1dEhvc3QoKTogU2hvcnRjdXRIb3N0IHtcbiAgICBjb25zdCBtYXJrZWQgPVxuICAgICAgPEEgZXh0ZW5kcyB1bmtub3duW10+KGFjdDogKC4uLmFyZ3M6IEEpID0+IHZvaWQpID0+XG4gICAgICAoLi4uYXJnczogQSk6IHZvaWQgPT4ge1xuICAgICAgICBhY3QoLi4uYXJncyk7XG4gICAgICAgIHRoaXMuY2hhbmdlZCgpO1xuICAgICAgfTtcbiAgICByZXR1cm4ge1xuICAgICAgcGxvdERpdk5hbWU6IHRoaXMucGxvdERpdk5hbWUsXG4gICAgICBob3N0RWxlbWVudDogdGhpcy5ob3N0UmVmPy5uYXRpdmVFbGVtZW50ID8/IG51bGwsXG4gICAgICBhY3RpdmVEcmFnTW9kZTogKCkgPT4gdGhpcy5hY3RpdmVEcmFnTW9kZSxcbiAgICAgIGNhblN0ZXBTbGljZTogKCkgPT4gISF0aGlzLmltYWdlSW5mbz8uaXNTdGFjayAmJiAodGhpcy5pc0ltYWdlVmlldyB8fCB0aGlzLnNsaWNlRWRpdG9yU2hvd24pLFxuICAgICAgd2hlZWxab29tczogKCkgPT4gIXJlbmRlcmVyT3duc1doZWVsKHRoaXMuYmFzZVBsb3RUeXBlKSAmJiB0aGlzLmlzSGVhdG1hcCxcbiAgICAgIHN0ZXBTbGljZTogbWFya2VkKChkZWx0YTogbnVtYmVyKSA9PiB0aGlzLnN0ZXBTbGljZShkZWx0YSkpLFxuICAgICAgcmVzb2x2ZVNhbVByb21wdDogbWFya2VkKChjb21taXQ6IGJvb2xlYW4pID0+IHtcbiAgICAgICAgaWYgKGNvbW1pdCkgdGhpcy5wbG90U2VydmljZS5jb21taXRTYW1Qb2ludHMoKTtcbiAgICAgICAgZWxzZSB0aGlzLnBsb3RTZXJ2aWNlLmNsZWFyU2FtUG9pbnRzKCk7XG4gICAgICAgIHRoaXMuc2VnbWVudGF0aW9uLmhpZGUoKTsgLy8gcHJvbXB0IHJlc29sdmVkIOKGkiBkaXNtaXNzIHRoZSBzdGF0dXMgdG9hc3RcbiAgICAgIH0pLFxuICAgICAgdW5kbzogbWFya2VkKCgpID0+IHRoaXMudW5kb1JlZ2lvbigpKSxcbiAgICAgIHJlZG86IG1hcmtlZCgoKSA9PiB0aGlzLnJlZG9SZWdpb24oKSksXG4gICAgICBkZWxldGVSZWdpb246IG1hcmtlZCgoKSA9PiB0aGlzLmRlbGV0ZVJlZ2lvbigpKSxcbiAgICAgIHpvb21JbjogbWFya2VkKCgpID0+IHRoaXMuem9vbUluKCkpLFxuICAgICAgem9vbU91dDogbWFya2VkKCgpID0+IHRoaXMuem9vbU91dCgpKSxcbiAgICAgIHRvZ2dsZURyYWdNb2RlOiBtYXJrZWQoKG1vZGU6IHN0cmluZykgPT4gdGhpcy50b2dnbGVEcmFnTW9kZShtb2RlKSksXG4gICAgICBvcGVuQ29udGV4dE1lbnU6IChldmVudCkgPT4ge1xuICAgICAgICB0aGlzLmNvbnRleHRNZW51SXRlbXMgPSB0aGlzLmJ1aWxkQ29udGV4dE1lbnVJdGVtcygpO1xuICAgICAgICB0aGlzLmNkci5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgICAgIHRoaXMuY29udGV4dE1lbnUuc2hvdyhldmVudCk7XG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICAvKiogU25hcCB0aGUgZmxvYXRpbmcgdG9vbGJhciBiYWNrIHRvIGl0cyBkb2NrZWQgcG9zaXRpb24gYWNyb3NzIHRoZSB0b3AuICovXG4gIHByb3RlY3RlZCBkb2NrVG9vbGJhcigpIHtcbiAgICB0aGlzLnRvb2xiYXJGbG9hdGluZyA9IGZhbHNlO1xuICB9XG5cbiAgLyoqIFRvb2xiYXIgXCJJbnRlbnNpdHlcIiBncm91cDogYWRkIGFub3RoZXIgbGluZSBST0kgKG5leHQgYnJpZ2h0IGNvbG91cikuICovXG4gIHByb3RlY3RlZCBhc3luYyBhZGRQcm9maWxlTGluZSgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCByZWdpb24gPSBhd2FpdCB0aGlzLmluc2V0Py5hZGRQcm9maWxlTGluZSgpO1xuICAgIC8vIE9TRCBvbmx5IGRyYXdzIGEgc2VsZWN0ZWQgcmVnaW9uJ3MgaGFuZGxlcyBpbiBhbiBlZGl0IG1vZGUsIHNvIGEgbGluZSBpblxuICAgIC8vICdub25lJyBtb2RlIGxvb2tzIHVuc2VsZWN0ZWQuIFN3aXRjaCB0byAnc2VsZWN0JyBzbyB0aGUgbmV3IGxpbmUgc2hvd3MgaXRzXG4gICAgLy8gZW5kcG9pbnQgaGFuZGxlcyBhbmQgY2FuIGJlIGRyYWdnZWQvZGVsZXRlZCByaWdodCBhd2F5LlxuICAgIGlmIChyZWdpb24gJiYgdGhpcy5pc0ltYWdlVmlldyAmJiB0aGlzLmFjdGl2ZURyYWdNb2RlICE9PSAnc2VsZWN0JykgdGhpcy50b2dnbGVEcmFnTW9kZSgnc2VsZWN0Jyk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLmF0dGFjaE9ic2VydmVyPy5kaXNjb25uZWN0KCk7XG4gICAgLy8gQSBjb250cmlidXRlZCBtb2RlJ3Mgc2Vzc2lvbiBlbmRzIGZpcnN0LCB3aGlsZSB0aGUgdmlld2VyIGl0IGRyZXcgb3ZlclxuICAgIC8vIHN0aWxsIGV4aXN0cy4gVGhlIHBhbmVsIGdvZXMgd2l0aCB0aGlzIHZpZXcsIHNvIG5vIGNoYW5nZSBkZXRlY3Rpb24uXG4gICAgdGhpcy5jb250cmlidXRpb25zLmRlc3Ryb3koKTtcbiAgICAvLyBMZWF2ZSB0aGUgbGl2ZSBzZXQgc28gdGhlIG5leHQtb2xkZXN0IHZpc3VhbGl6ZXIgcGlja3MgdXAgdGhlIG91dGxldHMg4oCUIG9uIGl0c1xuICAgIC8vIG5leHQgY2hlY2ssIHdoaWNoIGFuIE9uUHVzaCBzaWJsaW5nIG5lZWRzIGFza2luZyBmb3IuXG4gICAgVmlzdWFsaXplckNvbXBvbmVudC5saXZlSW5zdGFuY2VzLmRlbGV0ZSh0aGlzKTtcbiAgICBmb3IgKGNvbnN0IG90aGVyIG9mIFZpc3VhbGl6ZXJDb21wb25lbnQubGl2ZUluc3RhbmNlcykgb3RoZXIuY2hhbmdlZCgpO1xuICAgIHRoaXMuc3RhdGUuc2V0RGlhZ3JhbShudWxsKTtcbiAgICB0aGlzLnJlbmRlci5jYW5jZWwoKTtcbiAgICB0aGlzLnNwYXRpYWwuZGlzcG9zZSgpO1xuICAgIHRoaXMuc2NydWJiZXIuY2FuY2VsKCk7XG4gICAgdGhpcy5zaG9ydGN1dHM/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+XG4gIDwvZGl2PlxuICA8cGxvdHRpbmctdG9vbGJhclxuICAgIFtpbWFnZUluZm9dPVwiaW1hZ2VJbmZvXCJcbiAgICBbaGFzU3BhdGlhbERhdGFzZXRdPVwiaGFzU3BhdGlhbERhdGFzZXRcIlxuICAgIFtwbG90VHlwZU9wdGlvbnNdPVwicGxvdFR5cGVNZW51XCJcbiAgICBbc2VsZWN0ZWRQbG90VHlwZV09XCJzZWxlY3RlZFBsb3RUeXBlSWRcIlxuICAgIFtiYXNlUGxvdFR5cGVdPVwiYmFzZVBsb3RUeXBlXCJcbiAgICBbaXNvUmFuZ2VdPVwiaXNvUmFuZ2VcIlxuICAgIFttYXhJbmRleF09XCJtYXhJbmRleFwiXG4gICAgW3pJbmRleF09XCJ6SW5kZXhcIlxuICAgIFtwbGFuZVNsaWNlc109XCJkYXRhc2V0UGxhbmVzID4gMSAmJiAhaW1hZ2VJbmZvPy5pc1N0YWNrXCJcbiAgICBbaXNIZWF0bWFwXT1cImlzSGVhdG1hcFwiXG4gICAgW2lzM2RSZWdpb25zXT1cImlzU3BhdGlhbDNkTW9kZVwiXG4gICAgW2lzVm9sdW1lVmlld109XCJpc1ZvbHVtZVZpZXdcIlxuICAgIFtzbGljZUVkaXRvcl09XCJzbGljZUVkaXRvclwiXG4gICAgW2FjdGl2ZURyYWdNb2RlXT1cImFjdGl2ZURyYWdNb2RlXCJcbiAgICBbYWN0aXZlU3VyZmFjZTNkTW9kZV09XCJhY3RpdmVTdXJmYWNlM2RNb2RlXCJcbiAgICBbYXhlc1Zpc2libGVdPVwiYXhlc1Zpc2libGVcIlxuICAgIFt3aXJlZnJhbWVBY3RpdmVdPVwid2lyZWZyYW1lQWN0aXZlXCJcbiAgICBbcmVzb2x1dGlvblNjYWxlXT1cInJlc29sdXRpb25TY2FsZVwiXG4gICAgW3dhbmRTZW5zaXRpdml0eV09XCJ3YW5kU2Vuc2l0aXZpdHlcIlxuICAgIFticnVzaFNpemVdPVwiYnJ1c2hTaXplXCJcbiAgICBbc2FtTW9kZWxzXT1cInNhbU1vZGVsc1wiXG4gICAgW3NhbU1vZGVsSWRdPVwic2FtTW9kZWxJZFwiXG4gICAgW2NvbnRyaWJ1dGVkVG9vbHNdPVwiY29udHJpYnV0ZWRUb29sc1wiXG4gICAgW2RpYWxvZ1Rvb2xzXT1cImRpYWxvZ1Rvb2xzXCJcbiAgICBbb3BlbkRpYWxvZ1Rvb2xJZF09XCJvcGVuRGlhbG9nVG9vbElkXCJcbiAgICAodG9nZ2xlRGlhbG9nVG9vbCk9XCJ0b2dnbGVEaWFsb2dUb29sKCRldmVudClcIlxuICAgIFt0b29sTW9kZWxJZHNdPVwidG9vbFBhcmFtcy50b29sTW9kZWxJZHNcIlxuICAgIFt2ZXJ0ZXhFcmFzZXJSYWRpdXNdPVwidmVydGV4RXJhc2VyUmFkaXVzXCJcbiAgICBbY2FuVW5kb109XCJyZWdpb25BY3Rpb25zLmNhblVuZG9cIlxuICAgIFtjYW5SZWRvXT1cInJlZ2lvbkFjdGlvbnMuY2FuUmVkb1wiXG4gICAgW3Rvb2xzXT1cInRvb2xiYXJUb29sc1wiXG4gICAgW2ltYWdlU21vb3RoaW5nRW5hYmxlZF09XCJpbWFnZVNtb290aGluZ0VuYWJsZWRcIlxuICAgIChzZWxlY3RQbG90VHlwZSk9XCJvblNlbGVjdFBsb3RUeXBlKCRldmVudClcIlxuICAgICh0b2dnbGVJbWFnZVNtb290aGluZyk9XCJvblRvZ2dsZUltYWdlU21vb3RoaW5nKClcIlxuICAgIChhZGRQcm9maWxlTGluZSk9XCJhZGRQcm9maWxlTGluZSgpXCJcbiAgICAoaXNvUmFuZ2VDaGFuZ2UpPVwib25Jc29SYW5nZUNoYW5nZSgkZXZlbnQpXCJcbiAgICAob3BlbkNoYW5uZWxIaXN0b2dyYW0pPVwib3BlbkNoYW5uZWxIaXN0b2dyYW0oKVwiXG4gICAgKG9wZW5TcGF0aWFsQ29udHJvbHMpPVwib3BlblNwYXRpYWxDb250cm9scygpXCJcbiAgICAob3BlblJlZ2lvbkVkaXRvcik9XCJvcGVuUmVnaW9uRWRpdG9yKClcIlxuICAgICh0b2dnbGVTbGljZUVkaXRvcik9XCJ0b2dnbGVTbGljZUVkaXRvcigpXCJcbiAgICAoc2VsZWN0U3RhY2tPcHRpb24pPVwic2VsZWN0U3RhY2tPcHRpb24oJGV2ZW50KVwiXG4gICAgKHpTY3J1Yik9XCJvblpTY3J1YigkZXZlbnQpXCJcbiAgICAoelNsaWRlKT1cIm9uWlNsaWRlKCRldmVudClcIlxuICAgICh6SW5kZXhJbnB1dCk9XCJ6SW5kZXggPSAkZXZlbnQ7IHVwZGF0ZVpJbmRleCgpXCJcbiAgICAocmVsb2FkQW5kUGxvdCk9XCJyZWxvYWRBbmRQbG90KClcIlxuICAgIChkb3dubG9hZEltYWdlKT1cImRvd25sb2FkSW1hZ2UoKVwiXG4gICAgKGF1dG9zY2FsZUltYWdlKT1cImF1dG9zY2FsZUltYWdlKClcIlxuICAgICh0b2dnbGVEcmFnTW9kZSk9XCJ0b2dnbGVEcmFnTW9kZSgkZXZlbnQpXCJcbiAgICAoem9vbUluKT1cInpvb21JbigpXCJcbiAgICAoem9vbU91dCk9XCJ6b29tT3V0KClcIlxuICAgICh0b2dnbGVTdXJmYWNlM2RNb2RlKT1cInRvZ2dsZVN1cmZhY2UzZE1vZGUoJGV2ZW50KVwiXG4gICAgKHJlc2V0U3VyZmFjZUNhbWVyYSk9XCJyZXNldFN1cmZhY2VDYW1lcmEoKVwiXG4gICAgKHRvZ2dsZUF4ZXMpPVwidG9nZ2xlQXhlcygpXCJcbiAgICAodG9nZ2xlV2lyZWZyYW1lKT1cInRvZ2dsZVdpcmVmcmFtZSgpXCJcbiAgICAoc2VsZWN0UmVzb2x1dGlvbik9XCJzZWxlY3RSZXNvbHV0aW9uKCRldmVudClcIlxuICAgIChkZWxldGVSZWdpb24pPVwiZGVsZXRlUmVnaW9uKClcIlxuICAgICh1bmRvUmVnaW9uKT1cInVuZG9SZWdpb24oKVwiXG4gICAgKHJlZG9SZWdpb24pPVwicmVkb1JlZ2lvbigpXCJcbiAgICAoc2VnbWVudFJlZ2lvbnMpPVwic2VnbWVudFJlZ2lvbnMoKVwiXG4gICAgKHNlZ21lbnRDZWxscG9zZSk9XCJzZWdtZW50Q2VsbHBvc2UoKVwiXG4gICAgKHNhbU1vZGVsQ2hhbmdlKT1cIm9uU2FtTW9kZWxDaGFuZ2UoJGV2ZW50KVwiXG4gICAgKHJ1blRvb2wpPVwicnVuVG9vbCgkZXZlbnQpXCJcbiAgICAodG9vbE1vZGVsQ2hhbmdlKT1cIm9uVG9vbE1vZGVsQ2hhbmdlKCRldmVudClcIlxuICAgIChvcGVuVG9vbFBhcmFtcyk9XCJvcGVuVG9vbFBhcmFtcygkZXZlbnQpXCJcbiAgICAod2FuZFNlbnNpdGl2aXR5Q2hhbmdlKT1cIm9uV2FuZFNlbnNpdGl2aXR5Q2hhbmdlKCRldmVudClcIlxuICAgIChicnVzaFNpemVDaGFuZ2UpPVwib25CcnVzaFNpemVDaGFuZ2UoJGV2ZW50KVwiXG4gICAgKHZlcnRleEVyYXNlclJhZGl1c0NoYW5nZSk9XCJvblZlcnRleEVyYXNlclJhZGl1c0NoYW5nZSgkZXZlbnQpXCJcbiAgPlxuICAgIDwhLS0gSG9zdC1wcm9qZWN0ZWQgY3VzdG9tIHRvb2xiYXIgYnV0dG9ucywgZm9yd2FyZGVkIGludG8gdGhlIHRvb2xiYXIuIC0tPlxuICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbiAgPC9wbG90dGluZy10b29sYmFyPlxuICA8cC1idXR0b25cbiAgICAqbmdJZj1cInRvb2xiYXJGbG9hdGluZ1wiXG4gICAgY2xhc3M9XCJ0b29sYmFyLWRvY2stYnRuXCJcbiAgICBpY29uPVwicGkgcGktdGh1bWJ0YWNrXCJcbiAgICBzaXplPVwic21hbGxcIlxuICAgIFt0ZXh0XT1cInRydWVcIlxuICAgIHBUb29sdGlwPVwiRG9jayB0byB0b3BcIlxuICAgIHRvb2x0aXBQb3NpdGlvbj1cImJvdHRvbVwiXG4gICAgKG9uQ2xpY2spPVwiZG9ja1Rvb2xiYXIoKVwiXG4gID5cbiAgPC9wLWJ1dHRvbj5cbjwvZGl2PlxuXG48cC1jb250ZXh0TWVudSAjY20gW21vZGVsXT1cImNvbnRleHRNZW51SXRlbXNcIiBhcHBlbmRUbz1cImJvZHlcIj48L3AtY29udGV4dE1lbnU+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=
|