@jax-data-science/sci-image-visualizer 0.15.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/esm2022/lib/contracts/display-types.mjs +2 -1
  2. package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +1 -1
  3. package/esm2022/lib/implementations/napari-js/napari-scene.mjs +1 -1
  4. package/esm2022/lib/implementations/napari-js/napari-spatial-2d-scene.mjs +10 -8
  5. package/esm2022/lib/implementations/napari-js/napari-spatial-3d-scene.mjs +226 -39
  6. package/esm2022/lib/implementations/napari-js/napari-spatial-3d-transcripts.mjs +269 -0
  7. package/esm2022/lib/implementations/napari-js/napari-spatial-encoding.mjs +11 -4
  8. package/esm2022/lib/implementations/napari-js/napari-spatial-tiles.mjs +6 -7
  9. package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +2 -1
  10. package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +33 -8
  11. package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +6 -2
  12. package/esm2022/lib/implementations/napari-js/spatial-tiles/cell-layers.mjs +10 -6
  13. package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-layers.mjs +9 -5
  14. package/esm2022/lib/spatial/spatial-controls.facade.mjs +7 -4
  15. package/esm2022/lib/spatial/spatial-encoding.mjs +18 -1
  16. package/esm2022/lib/spatial-controls/spatial-charts/spatial-charts.component.mjs +6 -2
  17. package/esm2022/lib/spatial-controls/spatial-controls.component.mjs +7 -3
  18. package/esm2022/lib/spatial-controls/spatial-gene-style/spatial-gene-style.component.mjs +7 -3
  19. package/esm2022/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.mjs +67 -19
  20. package/esm2022/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.mjs +61 -8
  21. package/esm2022/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.mjs +3 -3
  22. package/esm2022/lib/toolbar/toolbar.component.mjs +13 -4
  23. package/esm2022/lib/toolbar/view-controls/view-controls.component.mjs +7 -7
  24. package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-qUeMuBb0.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-DHrHO2ay.mjs} +795 -165
  25. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-DHrHO2ay.mjs.map +1 -0
  26. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-U1ODcfYD.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-CKEUwNta.mjs} +2 -2
  27. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-U1ODcfYD.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-CKEUwNta.mjs.map} +1 -1
  28. package/fesm2022/jax-data-science-sci-image-visualizer.mjs +1 -1
  29. package/lib/contracts/display-types.d.ts +9 -2
  30. package/lib/implementations/napari-js/napari-loading-state.d.ts +1 -1
  31. package/lib/implementations/napari-js/napari-scene.d.ts +2 -0
  32. package/lib/implementations/napari-js/napari-spatial-2d-scene.d.ts +3 -3
  33. package/lib/implementations/napari-js/napari-spatial-3d-scene.d.ts +82 -9
  34. package/lib/implementations/napari-js/napari-spatial-3d-transcripts.d.ts +62 -0
  35. package/lib/implementations/napari-js/napari-spatial-encoding.d.ts +9 -2
  36. package/lib/implementations/napari-js/napari-spatial-tiles.d.ts +5 -6
  37. package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +16 -3
  38. package/lib/implementations/napari-js/spatial-tiles/cell-layers.d.ts +1 -1
  39. package/lib/spatial/spatial-encoding.d.ts +10 -0
  40. package/lib/spatial-controls/spatial-controls.component.d.ts +2 -0
  41. package/lib/spatial-controls/spatial-gene-style/spatial-gene-style.component.d.ts +3 -1
  42. package/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.d.ts +25 -0
  43. package/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.d.ts +14 -3
  44. package/lib/toolbar/toolbar.component.d.ts +6 -0
  45. package/lib/toolbar/view-controls/view-controls.component.d.ts +3 -3
  46. package/package.json +2 -2
  47. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-qUeMuBb0.mjs.map +0 -1
@@ -331,6 +331,10 @@ export class SpatialControlsComponent {
331
331
  get hasTranscripts() {
332
332
  return !!this.dataset?.transcriptTiles || !!this.dataset?.density;
333
333
  }
334
+ /** Whether the 3D cloud can draw the transcripts too: they carry z (a MERFISH volume's do). */
335
+ get hasTranscripts3d() {
336
+ return !!this.dataset?.transcriptTiles?.hasZ;
337
+ }
334
338
  onShowImage(on) {
335
339
  this.controls?.setViewState({ showImage: on });
336
340
  }
@@ -366,7 +370,7 @@ export class SpatialControlsComponent {
366
370
  return this.key.refresh(this.controls, this.dataset, this.view, this.colormap, this.reverse);
367
371
  }
368
372
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: SpatialControlsComponent, deps: [{ token: VISUALIZER }, { token: i0.NgZone }], target: i0.ɵɵFactoryTarget.Component }); }
369
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: SpatialControlsComponent, isStandalone: true, selector: "spatial-controls", inputs: { visible: "visible", is3d: "is3d" }, outputs: { visibleChange: "visibleChange" }, viewQueries: [{ propertyName: "charts", first: true, predicate: SpatialChartsComponent, descendants: true }], ngImport: i0, template: "<p-dialog\n header=\"Spatial omics\"\n [visible]=\"visible\"\n (visibleChange)=\"onVisibleChange($event)\"\n [modal]=\"false\"\n [resizable]=\"true\"\n [draggable]=\"true\"\n position=\"left\"\n (onResizeEnd)=\"onResizeEnd()\"\n [style]=\"{ width: '30rem' }\"\n [breakpoints]=\"{ '960px': '90vw' }\"\n styleClass=\"spatial-controls-dialog\"\n>\n <!-- No port bound: say why rather than showing controls that do nothing. -->\n <div class=\"sc-empty\" *ngIf=\"!controls\">\n No spatial-omics data source is configured. A host provides one by binding\n <code>SPATIAL_DATA_PORT</code>.\n </div>\n\n <div class=\"sc-empty\" *ngIf=\"controls && !dataset\">No dataset is loaded.</div>\n\n <div class=\"sc-body\" *ngIf=\"controls && dataset as ds\">\n <div class=\"sc-dataset\">\n <span class=\"sc-dataset-name\">{{ ds.name }}</span>\n <span class=\"sc-dataset-count\">{{ ds.observations.count | number }} observations</span>\n </div>\n\n <!-- Organised as Xenium Explorer's side panel: one collapsible section per layer,\n each with its own on/off switch in the header. -->\n\n <!-- Images -->\n <div class=\"sc-panel\" *ngIf=\"ds.imageRef && !is3d\" [class.open]=\"open.images\">\n <div class=\"sc-panel-head\" (click)=\"toggleSection('images')\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"view.showImage\"\n (click)=\"$event.stopPropagation()\"\n (onChange)=\"onShowImage($event.checked)\"\n ></p-checkbox>\n <span class=\"sc-panel-title\">Images</span>\n <i class=\"pi\" [class.pi-chevron-down]=\"open.images\" [class.pi-chevron-right]=\"!open.images\"></i>\n </div>\n <div class=\"sc-panel-body\" *ngIf=\"open.images\">\n <small class=\"sc-hint\"> Channels, colours and contrast are in the Channels &amp; Histogram dialog. </small>\n </div>\n </div>\n\n <!-- Cells -->\n <spatial-cells-panel\n *ngIf=\"hasCells && !is3d\"\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [colorBarCss]=\"colorBarCss\"\n [open]=\"open.cells\"\n (openChange)=\"setOpen('cells', $event)\"\n ></spatial-cells-panel>\n\n <!-- Transcripts -->\n <spatial-transcripts-panel\n *ngIf=\"hasTranscripts && !is3d\"\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [estimate]=\"estimate\"\n [densityStats]=\"densityStats\"\n [geneCounts]=\"geneCounts\"\n [colormapOptions]=\"colormapOptions\"\n [open]=\"open.transcripts\"\n (openChange)=\"setOpen('transcripts', $event)\"\n >\n </spatial-transcripts-panel>\n\n <!-- Annotations: the drawn regions, and selecting what they enclose. -->\n <div class=\"sc-panel\" [class.open]=\"open.annotations\">\n <div class=\"sc-panel-head\" (click)=\"toggleSection('annotations')\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"view.showAnnotations !== false\"\n (click)=\"$event.stopPropagation()\"\n (onChange)=\"onShowAnnotations($event.checked)\"\n pTooltip=\"Show the drawn regions\"\n tooltipPosition=\"top\"\n ></p-checkbox>\n <span class=\"sc-panel-title\">Annotations</span>\n <i class=\"pi\" [class.pi-chevron-down]=\"open.annotations\" [class.pi-chevron-right]=\"!open.annotations\"></i>\n </div>\n <div class=\"sc-panel-body\" *ngIf=\"open.annotations\">\n <div class=\"sc-row\">\n <p-button\n label=\"Select from ROIs\"\n icon=\"pi pi-object-group\"\n size=\"small\"\n [outlined]=\"true\"\n [loading]=\"selectingFromRegions\"\n (onClick)=\"selectFromRegions()\"\n [pTooltip]=\"\n selectsClassVolumes\n ? 'Select every observation inside the volumes of the classes picked in the Region Editor'\n : 'Select every observation inside the drawn regions'\n \"\n tooltipPosition=\"top\"\n ></p-button>\n <p-button\n *ngIf=\"hasSelection\"\n label=\"Clear\"\n size=\"small\"\n [text]=\"true\"\n (onClick)=\"clearSelection()\"\n ></p-button>\n </div>\n <small class=\"sc-hint\" *ngIf=\"hasSelection\">\n {{ selection.count | number }} of {{ ds.observations.count | number }} selected \u2014 the rest are muted.\n </small>\n <small class=\"sc-hint\" *ngIf=\"selectionMissed\">\n No observations fell inside the\n {{ missedMode === 'class-volumes' ? 'picked classes' : 'drawn regions' }}.\n </small>\n <small class=\"sc-hint\" *ngIf=\"selectsClassVolumes\">\n Selects inside the volume of {{ pickedClasses[0]\n }}{{ pickedClasses.length > 1 ? ' and ' + (pickedClasses.length - 1 | number) + ' more classes' : '' }},\n picked in the Region Editor. Draw a region to select by it instead.\n </small>\n <small class=\"sc-hint\" *ngIf=\"is3d && !selectsClassVolumes && pickedClasses.length\">\n The classes picked in the Region Editor are not on the reference volume shown here, so this selects by\n the regions drawn over the cloud instead.\n </small>\n <small class=\"sc-hint\" *ngIf=\"is3d && !selectsClassVolumes\">\n In 3D a region cuts through the cloud's full depth. Orbit and draw again to cut from another angle.\n <ng-container *ngIf=\"!pickedClasses.length\">\n Pick classes in the Region Editor's class tree to select inside their volumes.\n </ng-container>\n </small>\n </div>\n </div>\n\n <!-- Observations, then what else draws them: the gene map, the 3D scene, and the\n continuous-only knobs. -->\n <spatial-observations-panel\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [legend]=\"legend\"\n [colorBarCss]=\"colorBarCss\"\n [selection]=\"selection\"\n [selectedCategory]=\"selectedCategory\"\n [colormapOptions]=\"colormapOptions\"\n [is3d]=\"is3d\"\n [open]=\"open.observations\"\n (openChange)=\"setOpen('observations', $event)\"\n (categoryClicked)=\"selectCategory($event)\"\n ></spatial-observations-panel>\n\n <!-- Distributions of whatever the map is coloured by. In the SAME dialog as\n the colour controls on purpose: changing the gene and watching the\n distribution move is one action, and two floating windows made that\n harder to see rather than easier. -->\n <div class=\"sc-section sc-charts\">\n <button\n type=\"button\"\n class=\"sc-disclosure\"\n (click)=\"toggleCharts()\"\n [attr.aria-expanded]=\"chartsOpen\"\n [attr.aria-controls]=\"chartsBodyId\"\n >\n <i class=\"pi\" [class.pi-chevron-right]=\"!chartsOpen\" [class.pi-chevron-down]=\"chartsOpen\"></i>\n <span>Distribution</span>\n <small *ngIf=\"!chartsOpen && view.colorBy\">of {{ colorByLabel }}</small>\n </button>\n <!-- Kept MOUNTED when collapsed, only hidden: destroying it would throw\n away the chart kind and grouping the user picked. `active` is what\n stops it drawing while it has no size. -->\n <div [id]=\"chartsBodyId\" [hidden]=\"!chartsOpen\">\n <spatial-charts [active]=\"visible && chartsOpen\"></spatial-charts>\n </div>\n </div>\n\n <div class=\"sc-btns\">\n <p-button label=\"Reset\" size=\"small\" [text]=\"true\" (onClick)=\"reset()\"></p-button>\n </div>\n </div>\n</p-dialog>\n", styles: [".sc-hint{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-error{color:var(--red-600, #c62828)}.sc-section{display:flex;flex-direction:column;gap:.35rem}.sc-lbl{font-size:.78rem;color:var(--text-color-secondary, #6c757d);white-space:nowrap}.sc-row{display:flex;align-items:center;gap:.6rem}.sc-row p-slider,.sc-row p-dropdown,.sc-row p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row p-slider .p-slider{width:100%}:host ::ng-deep .sc-row p-dropdown .p-dropdown,:host ::ng-deep .sc-row p-treeSelect .p-treeselect{width:100%}.sc-row .sc-lbl{flex:0 0 calc(50% - .6rem);min-width:0;overflow:hidden;text-overflow:ellipsis}.sc-cmap-option{display:inline-flex;align-items:center;gap:.4rem}.sc-cmap-swatch{width:3.5rem;height:.7rem;border-radius:2px;display:block}.sc-val{flex:0 0 4rem;text-align:right;font-size:.78rem;font-variant-numeric:tabular-nums;white-space:nowrap}:host ::ng-deep .sc-full,:host ::ng-deep .sc-full .p-dropdown,:host ::ng-deep .sc-full .p-autocomplete,:host ::ng-deep .sc-full input{width:100%}.sc-colorbar{height:.75rem;border-radius:2px;border:1px solid rgba(0,0,0,.2)}.sc-colorbar-ends{display:flex;justify-content:space-between;font-size:.7rem;color:var(--text-color-secondary, #6c757d);margin-top:.2rem}.sc-panel{border:1px solid var(--surface-border, #dee2e6);border-radius:6px;margin-bottom:.5rem;overflow:hidden}.sc-panel-head{display:flex;align-items:center;gap:.6rem;padding:.5rem .7rem;cursor:pointer;-webkit-user-select:none;user-select:none;background:var(--surface-100, #f5f6f7)}.sc-panel-head .sc-panel-title{flex:1;font-weight:600}.sc-panel.open>.sc-panel-head{background:var(--primary-color, #2196f3);color:var(--primary-color-text, #fff)}.sc-panel-body{display:flex;flex-direction:column;gap:.45rem;padding:.6rem .75rem .75rem}.sc-subhead{display:flex;align-items:center;gap:.5rem;margin-top:.4rem;font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-color-secondary, #6c757d)}.sc-subhead:after{content:\"\";flex:1;border-top:1px solid var(--surface-border, #dee2e6)}:host ::ng-deep .sc-buttons .p-button{padding:.35rem .75rem;font-size:.85rem}.sc-row-picker p-dropdown,.sc-row-picker p-multiSelect,.sc-row-picker p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row-picker .sc-variant{width:6.5rem}:host ::ng-deep .sc-row-picker p-multiselect .p-multiselect{width:100%}:host ::ng-deep .sc-row-picker p-dropdown:has(.sc-variant){flex:0 0 6.5rem}:host ::ng-deep .sc-row-picker p-treeselect:has(.sc-palette){flex:0 0 3rem}:host ::ng-deep .sc-palette .p-treeselect-label{width:0;padding:0}.sc-icon-btn{flex:0 0 auto;border:0;background:transparent;cursor:pointer;padding:.25rem .35rem;font:inherit;font-size:1.05rem;color:var(--text-color, #333);border-radius:4px}.sc-icon-btn:hover{background:var(--surface-200, #e9ecef)}.sc-icon-btn.active{color:var(--primary-color, #2196f3);font-weight:700}.sc-icon-btn:disabled{opacity:.5;cursor:default}.sc-small-btn{margin-left:auto;border:1px solid var(--surface-border, #ced4da);background:var(--surface-0, #fff);border-radius:4px;padding:.2rem .6rem;font:inherit;font-size:.8rem;cursor:pointer}:host ::ng-deep .sc-group-heading{font-size:.7rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;opacity:.7}.sc-group-list,.sc-gene-tree{max-height:16rem;overflow-y:auto;border:1px solid var(--surface-border, #dee2e6);border-radius:4px;padding:.25rem .4rem}.sc-group-row,.sc-gene-row{display:flex;align-items:center;gap:.45rem;padding:.15rem 0;font-size:.88rem}.sc-group-row .sc-group-label,.sc-gene-row .sc-group-label{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-group-all,.sc-gene-root,.sc-gene-group{font-weight:600}.sc-group-all .sc-icon-btn,.sc-gene-root .sc-icon-btn,.sc-gene-group .sc-icon-btn{margin-left:auto;font-size:.85rem}.sc-count{flex:0 0 auto;font-size:.78rem;color:var(--text-color-secondary, #6c757d)}.sc-glyph-option{display:inline-flex;align-items:center;gap:.4rem}.sc-glyph-svg{width:1rem;height:1rem;fill:currentColor}:host ::ng-deep .sc-glyph-pick .p-dropdown-label{padding:.2rem .4rem}.sc-color-input{width:2.5rem;height:1.8rem;border:1px solid var(--surface-border, #ced4da);border-radius:4px;padding:0;background:none}.sc-row-number p-slider,.sc-row-range p-slider{flex:1 1 0;min-width:0}:host ::ng-deep .sc-num{width:4.5rem;padding:.3rem .4rem;text-align:center}:host ::ng-deep .sc-row-number p-inputnumber,:host ::ng-deep .sc-row-range p-inputnumber{flex:0 0 auto}.sc-gene-icon{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:1.4rem;height:1.4rem;padding:0;border:1px solid transparent;border-radius:4px;background:transparent;cursor:pointer}.sc-gene-icon:hover,.sc-gene-icon:focus-visible{border-color:var(--surface-border, rgba(0, 0, 0, .2))}:host ::ng-deep .spatial-controls-dialog .p-dialog-content{padding:.75rem 1rem 1rem}.sc-empty{padding:.5rem 0;font-size:.85rem;color:var(--text-color-secondary, #6c757d);line-height:1.4}.sc-empty code{font-size:.8rem}.sc-body{display:flex;flex-direction:column;gap:.85rem}.sc-dataset{display:flex;flex-direction:column;gap:.1rem;padding-bottom:.5rem;border-bottom:1px solid var(--surface-border, #dee2e6)}.sc-dataset-name{font-weight:600;font-size:.9rem}.sc-dataset-count{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-btns{display:flex;justify-content:flex-end}.sc-charts{padding-top:.5rem;border-top:1px solid var(--surface-border, #dee2e6);gap:0}.sc-disclosure{display:flex;align-items:center;gap:.4rem;width:100%;padding:.2rem 0;font:inherit;font-size:.82rem;font-weight:600;text-align:left;background:none;border:0;cursor:pointer;color:inherit}.sc-disclosure i{font-size:.7rem;color:var(--text-color-secondary, #6c757d)}.sc-disclosure small{font-weight:400;color:var(--text-color-secondary, #6c757d);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-disclosure:hover{color:var(--primary-color, #3b82f6)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i3.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: i4.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: DialogModule }, { kind: "component", type: i5.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: TooltipModule }, { kind: "directive", type: i6.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "component", type: SpatialCellsPanelComponent, selector: "spatial-cells-panel", inputs: ["controls", "dataset", "view", "genes", "colorBarCss", "open"], outputs: ["openChange"] }, { kind: "component", type: SpatialTranscriptsPanelComponent, selector: "spatial-transcripts-panel", inputs: ["controls", "dataset", "view", "genes", "estimate", "densityStats", "geneCounts", "colormapOptions", "open"], outputs: ["openChange"] }, { kind: "component", type: SpatialObservationsPanelComponent, selector: "spatial-observations-panel", inputs: ["controls", "dataset", "view", "genes", "legend", "colorBarCss", "selection", "selectedCategory", "colormapOptions", "is3d", "open"], outputs: ["openChange", "categoryClicked"] }, { kind: "component", type: SpatialChartsComponent, selector: "spatial-charts", inputs: ["active"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
373
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: SpatialControlsComponent, isStandalone: true, selector: "spatial-controls", inputs: { visible: "visible", is3d: "is3d" }, outputs: { visibleChange: "visibleChange" }, viewQueries: [{ propertyName: "charts", first: true, predicate: SpatialChartsComponent, descendants: true }], ngImport: i0, template: "<p-dialog\n header=\"Spatial omics\"\n [visible]=\"visible\"\n (visibleChange)=\"onVisibleChange($event)\"\n [modal]=\"false\"\n [resizable]=\"true\"\n [draggable]=\"true\"\n position=\"left\"\n (onResizeEnd)=\"onResizeEnd()\"\n [style]=\"{ width: '30rem' }\"\n [breakpoints]=\"{ '960px': '90vw' }\"\n styleClass=\"spatial-controls-dialog\"\n>\n <!-- No port bound: say why rather than showing controls that do nothing. -->\n <div class=\"sc-empty\" *ngIf=\"!controls\">\n No spatial-omics data source is configured. A host provides one by binding\n <code>SPATIAL_DATA_PORT</code>.\n </div>\n\n <div class=\"sc-empty\" *ngIf=\"controls && !dataset\">No dataset is loaded.</div>\n\n <div class=\"sc-body\" *ngIf=\"controls && dataset as ds\">\n <div class=\"sc-dataset\">\n <span class=\"sc-dataset-name\">{{ ds.name }}</span>\n <span class=\"sc-dataset-count\">{{ ds.observations.count | number }} observations</span>\n </div>\n\n <!-- Organised as Xenium Explorer's side panel: one collapsible section per layer,\n each with its own on/off switch in the header. -->\n\n <!-- Images -->\n <div class=\"sc-panel\" *ngIf=\"ds.imageRef && !is3d\" [class.open]=\"open.images\">\n <div class=\"sc-panel-head\" (click)=\"toggleSection('images')\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"view.showImage\"\n (click)=\"$event.stopPropagation()\"\n (onChange)=\"onShowImage($event.checked)\"\n ></p-checkbox>\n <span class=\"sc-panel-title\">Images</span>\n <i class=\"pi\" [class.pi-chevron-down]=\"open.images\" [class.pi-chevron-right]=\"!open.images\"></i>\n </div>\n <div class=\"sc-panel-body\" *ngIf=\"open.images\">\n <small class=\"sc-hint\"> Channels, colours and contrast are in the Channels &amp; Histogram dialog. </small>\n </div>\n </div>\n\n <!-- Cells -->\n <spatial-cells-panel\n *ngIf=\"hasCells && !is3d\"\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [colorBarCss]=\"colorBarCss\"\n [open]=\"open.cells\"\n (openChange)=\"setOpen('cells', $event)\"\n ></spatial-cells-panel>\n\n <!-- Transcripts -->\n <spatial-transcripts-panel\n *ngIf=\"hasTranscripts && (!is3d || hasTranscripts3d)\"\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [estimate]=\"estimate\"\n [densityStats]=\"densityStats\"\n [geneCounts]=\"geneCounts\"\n [colormapOptions]=\"colormapOptions\"\n [open]=\"open.transcripts\"\n (openChange)=\"setOpen('transcripts', $event)\"\n >\n </spatial-transcripts-panel>\n\n <!-- Annotations: the drawn regions, and selecting what they enclose. -->\n <div class=\"sc-panel\" [class.open]=\"open.annotations\">\n <div class=\"sc-panel-head\" (click)=\"toggleSection('annotations')\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"view.showAnnotations !== false\"\n (click)=\"$event.stopPropagation()\"\n (onChange)=\"onShowAnnotations($event.checked)\"\n pTooltip=\"Show the drawn regions\"\n tooltipPosition=\"top\"\n ></p-checkbox>\n <span class=\"sc-panel-title\">Annotations</span>\n <i class=\"pi\" [class.pi-chevron-down]=\"open.annotations\" [class.pi-chevron-right]=\"!open.annotations\"></i>\n </div>\n <div class=\"sc-panel-body\" *ngIf=\"open.annotations\">\n <div class=\"sc-row\">\n <p-button\n label=\"Select from ROIs\"\n icon=\"pi pi-object-group\"\n size=\"small\"\n [outlined]=\"true\"\n [loading]=\"selectingFromRegions\"\n (onClick)=\"selectFromRegions()\"\n [pTooltip]=\"\n selectsClassVolumes\n ? 'Select every observation inside the volumes of the classes picked in the Region Editor'\n : 'Select every observation inside the drawn regions'\n \"\n tooltipPosition=\"top\"\n ></p-button>\n <p-button\n *ngIf=\"hasSelection\"\n label=\"Clear\"\n size=\"small\"\n [text]=\"true\"\n (onClick)=\"clearSelection()\"\n ></p-button>\n </div>\n <small class=\"sc-hint\" *ngIf=\"hasSelection\">\n {{ selection.count | number }} of {{ ds.observations.count | number }} selected \u2014 the rest are muted.\n </small>\n <small class=\"sc-hint\" *ngIf=\"selectionMissed\">\n No observations fell inside the\n {{ missedMode === 'class-volumes' ? 'picked classes' : 'drawn regions' }}.\n </small>\n <small class=\"sc-hint\" *ngIf=\"selectsClassVolumes\">\n Selects inside the volume of {{ pickedClasses[0]\n }}{{ pickedClasses.length > 1 ? ' and ' + (pickedClasses.length - 1 | number) + ' more classes' : '' }},\n picked in the Region Editor. Draw a region to select by it instead.\n </small>\n <small class=\"sc-hint\" *ngIf=\"is3d && !selectsClassVolumes && pickedClasses.length\">\n The classes picked in the Region Editor are not on the reference volume shown here, so this selects by\n the regions drawn over the cloud instead.\n </small>\n <small class=\"sc-hint\" *ngIf=\"is3d && !selectsClassVolumes\">\n In 3D a region cuts through the cloud's full depth. Orbit and draw again to cut from another angle.\n <ng-container *ngIf=\"!pickedClasses.length\">\n Pick classes in the Region Editor's class tree to select inside their volumes.\n </ng-container>\n </small>\n </div>\n </div>\n\n <!-- Observations, then what else draws them: the gene map, the 3D scene, and the\n continuous-only knobs. -->\n <spatial-observations-panel\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [legend]=\"legend\"\n [colorBarCss]=\"colorBarCss\"\n [selection]=\"selection\"\n [selectedCategory]=\"selectedCategory\"\n [colormapOptions]=\"colormapOptions\"\n [is3d]=\"is3d\"\n [open]=\"open.observations\"\n (openChange)=\"setOpen('observations', $event)\"\n (categoryClicked)=\"selectCategory($event)\"\n ></spatial-observations-panel>\n\n <!-- Distributions of whatever the map is coloured by. In the SAME dialog as\n the colour controls on purpose: changing the gene and watching the\n distribution move is one action, and two floating windows made that\n harder to see rather than easier. -->\n <div class=\"sc-section sc-charts\">\n <button\n type=\"button\"\n class=\"sc-disclosure\"\n (click)=\"toggleCharts()\"\n [attr.aria-expanded]=\"chartsOpen\"\n [attr.aria-controls]=\"chartsBodyId\"\n >\n <i class=\"pi\" [class.pi-chevron-right]=\"!chartsOpen\" [class.pi-chevron-down]=\"chartsOpen\"></i>\n <span>Distribution</span>\n <small *ngIf=\"!chartsOpen && view.colorBy\">of {{ colorByLabel }}</small>\n </button>\n <!-- Kept MOUNTED when collapsed, only hidden: destroying it would throw\n away the chart kind and grouping the user picked. `active` is what\n stops it drawing while it has no size. -->\n <div [id]=\"chartsBodyId\" [hidden]=\"!chartsOpen\">\n <spatial-charts [active]=\"visible && chartsOpen\"></spatial-charts>\n </div>\n </div>\n\n <div class=\"sc-btns\">\n <p-button label=\"Reset\" size=\"small\" [text]=\"true\" (onClick)=\"reset()\"></p-button>\n </div>\n </div>\n</p-dialog>\n", styles: [".sc-hint{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-error{color:var(--red-600, #c62828)}.sc-section{display:flex;flex-direction:column;gap:.35rem}.sc-lbl{font-size:.78rem;color:var(--text-color-secondary, #6c757d);white-space:nowrap}.sc-row{display:flex;align-items:center;gap:.6rem}.sc-row p-slider,.sc-row p-dropdown,.sc-row p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row p-slider .p-slider{width:100%}:host ::ng-deep .sc-row p-dropdown .p-dropdown,:host ::ng-deep .sc-row p-treeSelect .p-treeselect{width:100%}.sc-row .sc-lbl{flex:0 0 calc(50% - .6rem);min-width:0;overflow:hidden;text-overflow:ellipsis}.sc-cmap-option{display:inline-flex;align-items:center;gap:.4rem}.sc-cmap-swatch{width:3.5rem;height:.7rem;border-radius:2px;display:block}.sc-val{flex:0 0 4rem;text-align:right;font-size:.78rem;font-variant-numeric:tabular-nums;white-space:nowrap}:host ::ng-deep .sc-full,:host ::ng-deep .sc-full .p-dropdown,:host ::ng-deep .sc-full .p-autocomplete,:host ::ng-deep .sc-full input{width:100%}.sc-colorbar{height:.75rem;border-radius:2px;border:1px solid rgba(0,0,0,.2)}.sc-colorbar-ends{display:flex;justify-content:space-between;font-size:.7rem;color:var(--text-color-secondary, #6c757d);margin-top:.2rem}.sc-panel{border:1px solid var(--surface-border, #dee2e6);border-radius:6px;margin-bottom:.5rem;overflow:hidden}.sc-panel-head{display:flex;align-items:center;gap:.6rem;padding:.5rem .7rem;cursor:pointer;-webkit-user-select:none;user-select:none;background:var(--surface-100, #f5f6f7)}.sc-panel-head .sc-panel-title{flex:1;font-weight:600}.sc-panel.open>.sc-panel-head{background:var(--primary-color, #2196f3);color:var(--primary-color-text, #fff)}.sc-panel-body{display:flex;flex-direction:column;gap:.45rem;padding:.6rem .75rem .75rem}.sc-subhead{display:flex;align-items:center;gap:.5rem;margin-top:.4rem;font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-color-secondary, #6c757d)}.sc-subhead:after{content:\"\";flex:1;border-top:1px solid var(--surface-border, #dee2e6)}:host ::ng-deep .sc-buttons .p-button{padding:.35rem .75rem;font-size:.85rem}.sc-row-picker p-dropdown,.sc-row-picker p-multiSelect,.sc-row-picker p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row-picker .sc-variant{width:6.5rem}:host ::ng-deep .sc-row-picker p-multiselect .p-multiselect{width:100%}:host ::ng-deep .sc-row-picker p-dropdown:has(.sc-variant){flex:0 0 6.5rem}:host ::ng-deep .sc-row-picker p-treeselect:has(.sc-palette){flex:0 0 3rem}:host ::ng-deep .sc-palette .p-treeselect-label{width:0;padding:0}.sc-icon-btn{flex:0 0 auto;border:0;background:transparent;cursor:pointer;padding:.25rem .35rem;font:inherit;font-size:1.05rem;color:var(--text-color, #333);border-radius:4px}.sc-icon-btn:hover{background:var(--surface-200, #e9ecef)}.sc-icon-btn.active{color:var(--primary-color, #2196f3);font-weight:700}.sc-icon-btn:disabled{opacity:.5;cursor:default}.sc-small-btn{margin-left:auto;border:1px solid var(--surface-border, #ced4da);background:var(--surface-0, #fff);border-radius:4px;padding:.2rem .6rem;font:inherit;font-size:.8rem;cursor:pointer}:host ::ng-deep .sc-group-heading{font-size:.7rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;opacity:.7}.sc-group-list,.sc-gene-tree{max-height:16rem;overflow-y:auto;border:1px solid var(--surface-border, #dee2e6);border-radius:4px;padding:.25rem .4rem}.sc-group-row,.sc-gene-row{display:flex;align-items:center;gap:.45rem;padding:.15rem 0;font-size:.88rem}.sc-group-row .sc-group-label,.sc-gene-row .sc-group-label{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-group-all,.sc-gene-root,.sc-gene-group{font-weight:600}.sc-group-all .sc-icon-btn,.sc-gene-root .sc-icon-btn,.sc-gene-group .sc-icon-btn{margin-left:auto;font-size:.85rem}.sc-count{flex:0 0 auto;font-size:.78rem;color:var(--text-color-secondary, #6c757d)}.sc-glyph-option{display:inline-flex;align-items:center;gap:.4rem}.sc-glyph-svg{width:1rem;height:1rem;fill:currentColor}:host ::ng-deep .sc-glyph-pick .p-dropdown-label{padding:.2rem .4rem}.sc-color-input{width:2.5rem;height:1.8rem;border:1px solid var(--surface-border, #ced4da);border-radius:4px;padding:0;background:none}.sc-row-number p-slider,.sc-row-range p-slider{flex:1 1 0;min-width:0}:host ::ng-deep .sc-num{width:4.5rem;padding:.3rem .4rem;text-align:center}:host ::ng-deep .sc-row-number p-inputnumber,:host ::ng-deep .sc-row-range p-inputnumber{flex:0 0 auto}.sc-gene-icon{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:1.4rem;height:1.4rem;padding:0;border:1px solid transparent;border-radius:4px;background:transparent;cursor:pointer}.sc-gene-icon:hover,.sc-gene-icon:focus-visible{border-color:var(--surface-border, rgba(0, 0, 0, .2))}:host ::ng-deep .spatial-controls-dialog .p-dialog-content{padding:.75rem 1rem 1rem}.sc-empty{padding:.5rem 0;font-size:.85rem;color:var(--text-color-secondary, #6c757d);line-height:1.4}.sc-empty code{font-size:.8rem}.sc-body{display:flex;flex-direction:column;gap:.85rem}.sc-dataset{display:flex;flex-direction:column;gap:.1rem;padding-bottom:.5rem;border-bottom:1px solid var(--surface-border, #dee2e6)}.sc-dataset-name{font-weight:600;font-size:.9rem}.sc-dataset-count{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-btns{display:flex;justify-content:flex-end}.sc-charts{padding-top:.5rem;border-top:1px solid var(--surface-border, #dee2e6);gap:0}.sc-disclosure{display:flex;align-items:center;gap:.4rem;width:100%;padding:.2rem 0;font:inherit;font-size:.82rem;font-weight:600;text-align:left;background:none;border:0;cursor:pointer;color:inherit}.sc-disclosure i{font-size:.7rem;color:var(--text-color-secondary, #6c757d)}.sc-disclosure small{font-weight:400;color:var(--text-color-secondary, #6c757d);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-disclosure:hover{color:var(--primary-color, #3b82f6)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "pipe", type: i1.DecimalPipe, name: "number" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i3.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: i4.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: DialogModule }, { kind: "component", type: i5.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: TooltipModule }, { kind: "directive", type: i6.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "autoHide", "fitContent", "hideOnEscape", "pTooltip", "tooltipDisabled", "tooltipOptions"] }, { kind: "component", type: SpatialCellsPanelComponent, selector: "spatial-cells-panel", inputs: ["controls", "dataset", "view", "genes", "colorBarCss", "open"], outputs: ["openChange"] }, { kind: "component", type: SpatialTranscriptsPanelComponent, selector: "spatial-transcripts-panel", inputs: ["controls", "dataset", "view", "genes", "estimate", "densityStats", "geneCounts", "colormapOptions", "open"], outputs: ["openChange"] }, { kind: "component", type: SpatialObservationsPanelComponent, selector: "spatial-observations-panel", inputs: ["controls", "dataset", "view", "genes", "legend", "colorBarCss", "selection", "selectedCategory", "colormapOptions", "is3d", "open"], outputs: ["openChange", "categoryClicked"] }, { kind: "component", type: SpatialChartsComponent, selector: "spatial-charts", inputs: ["active"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
370
374
  }
371
375
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: SpatialControlsComponent, decorators: [{
372
376
  type: Component,
@@ -381,7 +385,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
381
385
  SpatialTranscriptsPanelComponent,
382
386
  SpatialObservationsPanelComponent,
383
387
  SpatialChartsComponent,
384
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<p-dialog\n header=\"Spatial omics\"\n [visible]=\"visible\"\n (visibleChange)=\"onVisibleChange($event)\"\n [modal]=\"false\"\n [resizable]=\"true\"\n [draggable]=\"true\"\n position=\"left\"\n (onResizeEnd)=\"onResizeEnd()\"\n [style]=\"{ width: '30rem' }\"\n [breakpoints]=\"{ '960px': '90vw' }\"\n styleClass=\"spatial-controls-dialog\"\n>\n <!-- No port bound: say why rather than showing controls that do nothing. -->\n <div class=\"sc-empty\" *ngIf=\"!controls\">\n No spatial-omics data source is configured. A host provides one by binding\n <code>SPATIAL_DATA_PORT</code>.\n </div>\n\n <div class=\"sc-empty\" *ngIf=\"controls && !dataset\">No dataset is loaded.</div>\n\n <div class=\"sc-body\" *ngIf=\"controls && dataset as ds\">\n <div class=\"sc-dataset\">\n <span class=\"sc-dataset-name\">{{ ds.name }}</span>\n <span class=\"sc-dataset-count\">{{ ds.observations.count | number }} observations</span>\n </div>\n\n <!-- Organised as Xenium Explorer's side panel: one collapsible section per layer,\n each with its own on/off switch in the header. -->\n\n <!-- Images -->\n <div class=\"sc-panel\" *ngIf=\"ds.imageRef && !is3d\" [class.open]=\"open.images\">\n <div class=\"sc-panel-head\" (click)=\"toggleSection('images')\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"view.showImage\"\n (click)=\"$event.stopPropagation()\"\n (onChange)=\"onShowImage($event.checked)\"\n ></p-checkbox>\n <span class=\"sc-panel-title\">Images</span>\n <i class=\"pi\" [class.pi-chevron-down]=\"open.images\" [class.pi-chevron-right]=\"!open.images\"></i>\n </div>\n <div class=\"sc-panel-body\" *ngIf=\"open.images\">\n <small class=\"sc-hint\"> Channels, colours and contrast are in the Channels &amp; Histogram dialog. </small>\n </div>\n </div>\n\n <!-- Cells -->\n <spatial-cells-panel\n *ngIf=\"hasCells && !is3d\"\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [colorBarCss]=\"colorBarCss\"\n [open]=\"open.cells\"\n (openChange)=\"setOpen('cells', $event)\"\n ></spatial-cells-panel>\n\n <!-- Transcripts -->\n <spatial-transcripts-panel\n *ngIf=\"hasTranscripts && !is3d\"\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [estimate]=\"estimate\"\n [densityStats]=\"densityStats\"\n [geneCounts]=\"geneCounts\"\n [colormapOptions]=\"colormapOptions\"\n [open]=\"open.transcripts\"\n (openChange)=\"setOpen('transcripts', $event)\"\n >\n </spatial-transcripts-panel>\n\n <!-- Annotations: the drawn regions, and selecting what they enclose. -->\n <div class=\"sc-panel\" [class.open]=\"open.annotations\">\n <div class=\"sc-panel-head\" (click)=\"toggleSection('annotations')\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"view.showAnnotations !== false\"\n (click)=\"$event.stopPropagation()\"\n (onChange)=\"onShowAnnotations($event.checked)\"\n pTooltip=\"Show the drawn regions\"\n tooltipPosition=\"top\"\n ></p-checkbox>\n <span class=\"sc-panel-title\">Annotations</span>\n <i class=\"pi\" [class.pi-chevron-down]=\"open.annotations\" [class.pi-chevron-right]=\"!open.annotations\"></i>\n </div>\n <div class=\"sc-panel-body\" *ngIf=\"open.annotations\">\n <div class=\"sc-row\">\n <p-button\n label=\"Select from ROIs\"\n icon=\"pi pi-object-group\"\n size=\"small\"\n [outlined]=\"true\"\n [loading]=\"selectingFromRegions\"\n (onClick)=\"selectFromRegions()\"\n [pTooltip]=\"\n selectsClassVolumes\n ? 'Select every observation inside the volumes of the classes picked in the Region Editor'\n : 'Select every observation inside the drawn regions'\n \"\n tooltipPosition=\"top\"\n ></p-button>\n <p-button\n *ngIf=\"hasSelection\"\n label=\"Clear\"\n size=\"small\"\n [text]=\"true\"\n (onClick)=\"clearSelection()\"\n ></p-button>\n </div>\n <small class=\"sc-hint\" *ngIf=\"hasSelection\">\n {{ selection.count | number }} of {{ ds.observations.count | number }} selected \u2014 the rest are muted.\n </small>\n <small class=\"sc-hint\" *ngIf=\"selectionMissed\">\n No observations fell inside the\n {{ missedMode === 'class-volumes' ? 'picked classes' : 'drawn regions' }}.\n </small>\n <small class=\"sc-hint\" *ngIf=\"selectsClassVolumes\">\n Selects inside the volume of {{ pickedClasses[0]\n }}{{ pickedClasses.length > 1 ? ' and ' + (pickedClasses.length - 1 | number) + ' more classes' : '' }},\n picked in the Region Editor. Draw a region to select by it instead.\n </small>\n <small class=\"sc-hint\" *ngIf=\"is3d && !selectsClassVolumes && pickedClasses.length\">\n The classes picked in the Region Editor are not on the reference volume shown here, so this selects by\n the regions drawn over the cloud instead.\n </small>\n <small class=\"sc-hint\" *ngIf=\"is3d && !selectsClassVolumes\">\n In 3D a region cuts through the cloud's full depth. Orbit and draw again to cut from another angle.\n <ng-container *ngIf=\"!pickedClasses.length\">\n Pick classes in the Region Editor's class tree to select inside their volumes.\n </ng-container>\n </small>\n </div>\n </div>\n\n <!-- Observations, then what else draws them: the gene map, the 3D scene, and the\n continuous-only knobs. -->\n <spatial-observations-panel\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [legend]=\"legend\"\n [colorBarCss]=\"colorBarCss\"\n [selection]=\"selection\"\n [selectedCategory]=\"selectedCategory\"\n [colormapOptions]=\"colormapOptions\"\n [is3d]=\"is3d\"\n [open]=\"open.observations\"\n (openChange)=\"setOpen('observations', $event)\"\n (categoryClicked)=\"selectCategory($event)\"\n ></spatial-observations-panel>\n\n <!-- Distributions of whatever the map is coloured by. In the SAME dialog as\n the colour controls on purpose: changing the gene and watching the\n distribution move is one action, and two floating windows made that\n harder to see rather than easier. -->\n <div class=\"sc-section sc-charts\">\n <button\n type=\"button\"\n class=\"sc-disclosure\"\n (click)=\"toggleCharts()\"\n [attr.aria-expanded]=\"chartsOpen\"\n [attr.aria-controls]=\"chartsBodyId\"\n >\n <i class=\"pi\" [class.pi-chevron-right]=\"!chartsOpen\" [class.pi-chevron-down]=\"chartsOpen\"></i>\n <span>Distribution</span>\n <small *ngIf=\"!chartsOpen && view.colorBy\">of {{ colorByLabel }}</small>\n </button>\n <!-- Kept MOUNTED when collapsed, only hidden: destroying it would throw\n away the chart kind and grouping the user picked. `active` is what\n stops it drawing while it has no size. -->\n <div [id]=\"chartsBodyId\" [hidden]=\"!chartsOpen\">\n <spatial-charts [active]=\"visible && chartsOpen\"></spatial-charts>\n </div>\n </div>\n\n <div class=\"sc-btns\">\n <p-button label=\"Reset\" size=\"small\" [text]=\"true\" (onClick)=\"reset()\"></p-button>\n </div>\n </div>\n</p-dialog>\n", styles: [".sc-hint{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-error{color:var(--red-600, #c62828)}.sc-section{display:flex;flex-direction:column;gap:.35rem}.sc-lbl{font-size:.78rem;color:var(--text-color-secondary, #6c757d);white-space:nowrap}.sc-row{display:flex;align-items:center;gap:.6rem}.sc-row p-slider,.sc-row p-dropdown,.sc-row p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row p-slider .p-slider{width:100%}:host ::ng-deep .sc-row p-dropdown .p-dropdown,:host ::ng-deep .sc-row p-treeSelect .p-treeselect{width:100%}.sc-row .sc-lbl{flex:0 0 calc(50% - .6rem);min-width:0;overflow:hidden;text-overflow:ellipsis}.sc-cmap-option{display:inline-flex;align-items:center;gap:.4rem}.sc-cmap-swatch{width:3.5rem;height:.7rem;border-radius:2px;display:block}.sc-val{flex:0 0 4rem;text-align:right;font-size:.78rem;font-variant-numeric:tabular-nums;white-space:nowrap}:host ::ng-deep .sc-full,:host ::ng-deep .sc-full .p-dropdown,:host ::ng-deep .sc-full .p-autocomplete,:host ::ng-deep .sc-full input{width:100%}.sc-colorbar{height:.75rem;border-radius:2px;border:1px solid rgba(0,0,0,.2)}.sc-colorbar-ends{display:flex;justify-content:space-between;font-size:.7rem;color:var(--text-color-secondary, #6c757d);margin-top:.2rem}.sc-panel{border:1px solid var(--surface-border, #dee2e6);border-radius:6px;margin-bottom:.5rem;overflow:hidden}.sc-panel-head{display:flex;align-items:center;gap:.6rem;padding:.5rem .7rem;cursor:pointer;-webkit-user-select:none;user-select:none;background:var(--surface-100, #f5f6f7)}.sc-panel-head .sc-panel-title{flex:1;font-weight:600}.sc-panel.open>.sc-panel-head{background:var(--primary-color, #2196f3);color:var(--primary-color-text, #fff)}.sc-panel-body{display:flex;flex-direction:column;gap:.45rem;padding:.6rem .75rem .75rem}.sc-subhead{display:flex;align-items:center;gap:.5rem;margin-top:.4rem;font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-color-secondary, #6c757d)}.sc-subhead:after{content:\"\";flex:1;border-top:1px solid var(--surface-border, #dee2e6)}:host ::ng-deep .sc-buttons .p-button{padding:.35rem .75rem;font-size:.85rem}.sc-row-picker p-dropdown,.sc-row-picker p-multiSelect,.sc-row-picker p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row-picker .sc-variant{width:6.5rem}:host ::ng-deep .sc-row-picker p-multiselect .p-multiselect{width:100%}:host ::ng-deep .sc-row-picker p-dropdown:has(.sc-variant){flex:0 0 6.5rem}:host ::ng-deep .sc-row-picker p-treeselect:has(.sc-palette){flex:0 0 3rem}:host ::ng-deep .sc-palette .p-treeselect-label{width:0;padding:0}.sc-icon-btn{flex:0 0 auto;border:0;background:transparent;cursor:pointer;padding:.25rem .35rem;font:inherit;font-size:1.05rem;color:var(--text-color, #333);border-radius:4px}.sc-icon-btn:hover{background:var(--surface-200, #e9ecef)}.sc-icon-btn.active{color:var(--primary-color, #2196f3);font-weight:700}.sc-icon-btn:disabled{opacity:.5;cursor:default}.sc-small-btn{margin-left:auto;border:1px solid var(--surface-border, #ced4da);background:var(--surface-0, #fff);border-radius:4px;padding:.2rem .6rem;font:inherit;font-size:.8rem;cursor:pointer}:host ::ng-deep .sc-group-heading{font-size:.7rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;opacity:.7}.sc-group-list,.sc-gene-tree{max-height:16rem;overflow-y:auto;border:1px solid var(--surface-border, #dee2e6);border-radius:4px;padding:.25rem .4rem}.sc-group-row,.sc-gene-row{display:flex;align-items:center;gap:.45rem;padding:.15rem 0;font-size:.88rem}.sc-group-row .sc-group-label,.sc-gene-row .sc-group-label{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-group-all,.sc-gene-root,.sc-gene-group{font-weight:600}.sc-group-all .sc-icon-btn,.sc-gene-root .sc-icon-btn,.sc-gene-group .sc-icon-btn{margin-left:auto;font-size:.85rem}.sc-count{flex:0 0 auto;font-size:.78rem;color:var(--text-color-secondary, #6c757d)}.sc-glyph-option{display:inline-flex;align-items:center;gap:.4rem}.sc-glyph-svg{width:1rem;height:1rem;fill:currentColor}:host ::ng-deep .sc-glyph-pick .p-dropdown-label{padding:.2rem .4rem}.sc-color-input{width:2.5rem;height:1.8rem;border:1px solid var(--surface-border, #ced4da);border-radius:4px;padding:0;background:none}.sc-row-number p-slider,.sc-row-range p-slider{flex:1 1 0;min-width:0}:host ::ng-deep .sc-num{width:4.5rem;padding:.3rem .4rem;text-align:center}:host ::ng-deep .sc-row-number p-inputnumber,:host ::ng-deep .sc-row-range p-inputnumber{flex:0 0 auto}.sc-gene-icon{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:1.4rem;height:1.4rem;padding:0;border:1px solid transparent;border-radius:4px;background:transparent;cursor:pointer}.sc-gene-icon:hover,.sc-gene-icon:focus-visible{border-color:var(--surface-border, rgba(0, 0, 0, .2))}:host ::ng-deep .spatial-controls-dialog .p-dialog-content{padding:.75rem 1rem 1rem}.sc-empty{padding:.5rem 0;font-size:.85rem;color:var(--text-color-secondary, #6c757d);line-height:1.4}.sc-empty code{font-size:.8rem}.sc-body{display:flex;flex-direction:column;gap:.85rem}.sc-dataset{display:flex;flex-direction:column;gap:.1rem;padding-bottom:.5rem;border-bottom:1px solid var(--surface-border, #dee2e6)}.sc-dataset-name{font-weight:600;font-size:.9rem}.sc-dataset-count{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-btns{display:flex;justify-content:flex-end}.sc-charts{padding-top:.5rem;border-top:1px solid var(--surface-border, #dee2e6);gap:0}.sc-disclosure{display:flex;align-items:center;gap:.4rem;width:100%;padding:.2rem 0;font:inherit;font-size:.82rem;font-weight:600;text-align:left;background:none;border:0;cursor:pointer;color:inherit}.sc-disclosure i{font-size:.7rem;color:var(--text-color-secondary, #6c757d)}.sc-disclosure small{font-weight:400;color:var(--text-color-secondary, #6c757d);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-disclosure:hover{color:var(--primary-color, #3b82f6)}\n"] }]
388
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<p-dialog\n header=\"Spatial omics\"\n [visible]=\"visible\"\n (visibleChange)=\"onVisibleChange($event)\"\n [modal]=\"false\"\n [resizable]=\"true\"\n [draggable]=\"true\"\n position=\"left\"\n (onResizeEnd)=\"onResizeEnd()\"\n [style]=\"{ width: '30rem' }\"\n [breakpoints]=\"{ '960px': '90vw' }\"\n styleClass=\"spatial-controls-dialog\"\n>\n <!-- No port bound: say why rather than showing controls that do nothing. -->\n <div class=\"sc-empty\" *ngIf=\"!controls\">\n No spatial-omics data source is configured. A host provides one by binding\n <code>SPATIAL_DATA_PORT</code>.\n </div>\n\n <div class=\"sc-empty\" *ngIf=\"controls && !dataset\">No dataset is loaded.</div>\n\n <div class=\"sc-body\" *ngIf=\"controls && dataset as ds\">\n <div class=\"sc-dataset\">\n <span class=\"sc-dataset-name\">{{ ds.name }}</span>\n <span class=\"sc-dataset-count\">{{ ds.observations.count | number }} observations</span>\n </div>\n\n <!-- Organised as Xenium Explorer's side panel: one collapsible section per layer,\n each with its own on/off switch in the header. -->\n\n <!-- Images -->\n <div class=\"sc-panel\" *ngIf=\"ds.imageRef && !is3d\" [class.open]=\"open.images\">\n <div class=\"sc-panel-head\" (click)=\"toggleSection('images')\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"view.showImage\"\n (click)=\"$event.stopPropagation()\"\n (onChange)=\"onShowImage($event.checked)\"\n ></p-checkbox>\n <span class=\"sc-panel-title\">Images</span>\n <i class=\"pi\" [class.pi-chevron-down]=\"open.images\" [class.pi-chevron-right]=\"!open.images\"></i>\n </div>\n <div class=\"sc-panel-body\" *ngIf=\"open.images\">\n <small class=\"sc-hint\"> Channels, colours and contrast are in the Channels &amp; Histogram dialog. </small>\n </div>\n </div>\n\n <!-- Cells -->\n <spatial-cells-panel\n *ngIf=\"hasCells && !is3d\"\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [colorBarCss]=\"colorBarCss\"\n [open]=\"open.cells\"\n (openChange)=\"setOpen('cells', $event)\"\n ></spatial-cells-panel>\n\n <!-- Transcripts -->\n <spatial-transcripts-panel\n *ngIf=\"hasTranscripts && (!is3d || hasTranscripts3d)\"\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [estimate]=\"estimate\"\n [densityStats]=\"densityStats\"\n [geneCounts]=\"geneCounts\"\n [colormapOptions]=\"colormapOptions\"\n [open]=\"open.transcripts\"\n (openChange)=\"setOpen('transcripts', $event)\"\n >\n </spatial-transcripts-panel>\n\n <!-- Annotations: the drawn regions, and selecting what they enclose. -->\n <div class=\"sc-panel\" [class.open]=\"open.annotations\">\n <div class=\"sc-panel-head\" (click)=\"toggleSection('annotations')\">\n <p-checkbox\n [binary]=\"true\"\n [ngModel]=\"view.showAnnotations !== false\"\n (click)=\"$event.stopPropagation()\"\n (onChange)=\"onShowAnnotations($event.checked)\"\n pTooltip=\"Show the drawn regions\"\n tooltipPosition=\"top\"\n ></p-checkbox>\n <span class=\"sc-panel-title\">Annotations</span>\n <i class=\"pi\" [class.pi-chevron-down]=\"open.annotations\" [class.pi-chevron-right]=\"!open.annotations\"></i>\n </div>\n <div class=\"sc-panel-body\" *ngIf=\"open.annotations\">\n <div class=\"sc-row\">\n <p-button\n label=\"Select from ROIs\"\n icon=\"pi pi-object-group\"\n size=\"small\"\n [outlined]=\"true\"\n [loading]=\"selectingFromRegions\"\n (onClick)=\"selectFromRegions()\"\n [pTooltip]=\"\n selectsClassVolumes\n ? 'Select every observation inside the volumes of the classes picked in the Region Editor'\n : 'Select every observation inside the drawn regions'\n \"\n tooltipPosition=\"top\"\n ></p-button>\n <p-button\n *ngIf=\"hasSelection\"\n label=\"Clear\"\n size=\"small\"\n [text]=\"true\"\n (onClick)=\"clearSelection()\"\n ></p-button>\n </div>\n <small class=\"sc-hint\" *ngIf=\"hasSelection\">\n {{ selection.count | number }} of {{ ds.observations.count | number }} selected \u2014 the rest are muted.\n </small>\n <small class=\"sc-hint\" *ngIf=\"selectionMissed\">\n No observations fell inside the\n {{ missedMode === 'class-volumes' ? 'picked classes' : 'drawn regions' }}.\n </small>\n <small class=\"sc-hint\" *ngIf=\"selectsClassVolumes\">\n Selects inside the volume of {{ pickedClasses[0]\n }}{{ pickedClasses.length > 1 ? ' and ' + (pickedClasses.length - 1 | number) + ' more classes' : '' }},\n picked in the Region Editor. Draw a region to select by it instead.\n </small>\n <small class=\"sc-hint\" *ngIf=\"is3d && !selectsClassVolumes && pickedClasses.length\">\n The classes picked in the Region Editor are not on the reference volume shown here, so this selects by\n the regions drawn over the cloud instead.\n </small>\n <small class=\"sc-hint\" *ngIf=\"is3d && !selectsClassVolumes\">\n In 3D a region cuts through the cloud's full depth. Orbit and draw again to cut from another angle.\n <ng-container *ngIf=\"!pickedClasses.length\">\n Pick classes in the Region Editor's class tree to select inside their volumes.\n </ng-container>\n </small>\n </div>\n </div>\n\n <!-- Observations, then what else draws them: the gene map, the 3D scene, and the\n continuous-only knobs. -->\n <spatial-observations-panel\n [controls]=\"controls\"\n [dataset]=\"ds\"\n [view]=\"view\"\n [genes]=\"genes\"\n [legend]=\"legend\"\n [colorBarCss]=\"colorBarCss\"\n [selection]=\"selection\"\n [selectedCategory]=\"selectedCategory\"\n [colormapOptions]=\"colormapOptions\"\n [is3d]=\"is3d\"\n [open]=\"open.observations\"\n (openChange)=\"setOpen('observations', $event)\"\n (categoryClicked)=\"selectCategory($event)\"\n ></spatial-observations-panel>\n\n <!-- Distributions of whatever the map is coloured by. In the SAME dialog as\n the colour controls on purpose: changing the gene and watching the\n distribution move is one action, and two floating windows made that\n harder to see rather than easier. -->\n <div class=\"sc-section sc-charts\">\n <button\n type=\"button\"\n class=\"sc-disclosure\"\n (click)=\"toggleCharts()\"\n [attr.aria-expanded]=\"chartsOpen\"\n [attr.aria-controls]=\"chartsBodyId\"\n >\n <i class=\"pi\" [class.pi-chevron-right]=\"!chartsOpen\" [class.pi-chevron-down]=\"chartsOpen\"></i>\n <span>Distribution</span>\n <small *ngIf=\"!chartsOpen && view.colorBy\">of {{ colorByLabel }}</small>\n </button>\n <!-- Kept MOUNTED when collapsed, only hidden: destroying it would throw\n away the chart kind and grouping the user picked. `active` is what\n stops it drawing while it has no size. -->\n <div [id]=\"chartsBodyId\" [hidden]=\"!chartsOpen\">\n <spatial-charts [active]=\"visible && chartsOpen\"></spatial-charts>\n </div>\n </div>\n\n <div class=\"sc-btns\">\n <p-button label=\"Reset\" size=\"small\" [text]=\"true\" (onClick)=\"reset()\"></p-button>\n </div>\n </div>\n</p-dialog>\n", styles: [".sc-hint{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-error{color:var(--red-600, #c62828)}.sc-section{display:flex;flex-direction:column;gap:.35rem}.sc-lbl{font-size:.78rem;color:var(--text-color-secondary, #6c757d);white-space:nowrap}.sc-row{display:flex;align-items:center;gap:.6rem}.sc-row p-slider,.sc-row p-dropdown,.sc-row p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row p-slider .p-slider{width:100%}:host ::ng-deep .sc-row p-dropdown .p-dropdown,:host ::ng-deep .sc-row p-treeSelect .p-treeselect{width:100%}.sc-row .sc-lbl{flex:0 0 calc(50% - .6rem);min-width:0;overflow:hidden;text-overflow:ellipsis}.sc-cmap-option{display:inline-flex;align-items:center;gap:.4rem}.sc-cmap-swatch{width:3.5rem;height:.7rem;border-radius:2px;display:block}.sc-val{flex:0 0 4rem;text-align:right;font-size:.78rem;font-variant-numeric:tabular-nums;white-space:nowrap}:host ::ng-deep .sc-full,:host ::ng-deep .sc-full .p-dropdown,:host ::ng-deep .sc-full .p-autocomplete,:host ::ng-deep .sc-full input{width:100%}.sc-colorbar{height:.75rem;border-radius:2px;border:1px solid rgba(0,0,0,.2)}.sc-colorbar-ends{display:flex;justify-content:space-between;font-size:.7rem;color:var(--text-color-secondary, #6c757d);margin-top:.2rem}.sc-panel{border:1px solid var(--surface-border, #dee2e6);border-radius:6px;margin-bottom:.5rem;overflow:hidden}.sc-panel-head{display:flex;align-items:center;gap:.6rem;padding:.5rem .7rem;cursor:pointer;-webkit-user-select:none;user-select:none;background:var(--surface-100, #f5f6f7)}.sc-panel-head .sc-panel-title{flex:1;font-weight:600}.sc-panel.open>.sc-panel-head{background:var(--primary-color, #2196f3);color:var(--primary-color-text, #fff)}.sc-panel-body{display:flex;flex-direction:column;gap:.45rem;padding:.6rem .75rem .75rem}.sc-subhead{display:flex;align-items:center;gap:.5rem;margin-top:.4rem;font-size:.72rem;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--text-color-secondary, #6c757d)}.sc-subhead:after{content:\"\";flex:1;border-top:1px solid var(--surface-border, #dee2e6)}:host ::ng-deep .sc-buttons .p-button{padding:.35rem .75rem;font-size:.85rem}.sc-row-picker p-dropdown,.sc-row-picker p-multiSelect,.sc-row-picker p-treeSelect{flex:1 1 0;min-width:0}:host ::ng-deep .sc-row-picker .sc-variant{width:6.5rem}:host ::ng-deep .sc-row-picker p-multiselect .p-multiselect{width:100%}:host ::ng-deep .sc-row-picker p-dropdown:has(.sc-variant){flex:0 0 6.5rem}:host ::ng-deep .sc-row-picker p-treeselect:has(.sc-palette){flex:0 0 3rem}:host ::ng-deep .sc-palette .p-treeselect-label{width:0;padding:0}.sc-icon-btn{flex:0 0 auto;border:0;background:transparent;cursor:pointer;padding:.25rem .35rem;font:inherit;font-size:1.05rem;color:var(--text-color, #333);border-radius:4px}.sc-icon-btn:hover{background:var(--surface-200, #e9ecef)}.sc-icon-btn.active{color:var(--primary-color, #2196f3);font-weight:700}.sc-icon-btn:disabled{opacity:.5;cursor:default}.sc-small-btn{margin-left:auto;border:1px solid var(--surface-border, #ced4da);background:var(--surface-0, #fff);border-radius:4px;padding:.2rem .6rem;font:inherit;font-size:.8rem;cursor:pointer}:host ::ng-deep .sc-group-heading{font-size:.7rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;opacity:.7}.sc-group-list,.sc-gene-tree{max-height:16rem;overflow-y:auto;border:1px solid var(--surface-border, #dee2e6);border-radius:4px;padding:.25rem .4rem}.sc-group-row,.sc-gene-row{display:flex;align-items:center;gap:.45rem;padding:.15rem 0;font-size:.88rem}.sc-group-row .sc-group-label,.sc-gene-row .sc-group-label{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-group-all,.sc-gene-root,.sc-gene-group{font-weight:600}.sc-group-all .sc-icon-btn,.sc-gene-root .sc-icon-btn,.sc-gene-group .sc-icon-btn{margin-left:auto;font-size:.85rem}.sc-count{flex:0 0 auto;font-size:.78rem;color:var(--text-color-secondary, #6c757d)}.sc-glyph-option{display:inline-flex;align-items:center;gap:.4rem}.sc-glyph-svg{width:1rem;height:1rem;fill:currentColor}:host ::ng-deep .sc-glyph-pick .p-dropdown-label{padding:.2rem .4rem}.sc-color-input{width:2.5rem;height:1.8rem;border:1px solid var(--surface-border, #ced4da);border-radius:4px;padding:0;background:none}.sc-row-number p-slider,.sc-row-range p-slider{flex:1 1 0;min-width:0}:host ::ng-deep .sc-num{width:4.5rem;padding:.3rem .4rem;text-align:center}:host ::ng-deep .sc-row-number p-inputnumber,:host ::ng-deep .sc-row-range p-inputnumber{flex:0 0 auto}.sc-gene-icon{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:1.4rem;height:1.4rem;padding:0;border:1px solid transparent;border-radius:4px;background:transparent;cursor:pointer}.sc-gene-icon:hover,.sc-gene-icon:focus-visible{border-color:var(--surface-border, rgba(0, 0, 0, .2))}:host ::ng-deep .spatial-controls-dialog .p-dialog-content{padding:.75rem 1rem 1rem}.sc-empty{padding:.5rem 0;font-size:.85rem;color:var(--text-color-secondary, #6c757d);line-height:1.4}.sc-empty code{font-size:.8rem}.sc-body{display:flex;flex-direction:column;gap:.85rem}.sc-dataset{display:flex;flex-direction:column;gap:.1rem;padding-bottom:.5rem;border-bottom:1px solid var(--surface-border, #dee2e6)}.sc-dataset-name{font-weight:600;font-size:.9rem}.sc-dataset-count{font-size:.75rem;color:var(--text-color-secondary, #6c757d)}.sc-btns{display:flex;justify-content:flex-end}.sc-charts{padding-top:.5rem;border-top:1px solid var(--surface-border, #dee2e6);gap:0}.sc-disclosure{display:flex;align-items:center;gap:.4rem;width:100%;padding:.2rem 0;font:inherit;font-size:.82rem;font-weight:600;text-align:left;background:none;border:0;cursor:pointer;color:inherit}.sc-disclosure i{font-size:.7rem;color:var(--text-color-secondary, #6c757d)}.sc-disclosure small{font-weight:400;color:var(--text-color-secondary, #6c757d);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sc-disclosure:hover{color:var(--primary-color, #3b82f6)}\n"] }]
385
389
  }], ctorParameters: () => [{ type: undefined, decorators: [{
386
390
  type: Inject,
387
391
  args: [VISUALIZER]
@@ -395,4 +399,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
395
399
  }], visibleChange: [{
396
400
  type: Output
397
401
  }] } });
398
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BhdGlhbC1jb250cm9scy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3NwYXRpYWwtY29udHJvbHMvc3BhdGlhbC1jb250cm9scy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9zcmMvbGliL3NwYXRpYWwtY29udHJvbHMvc3BhdGlhbC1jb250cm9scy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixNQUFNLEVBQ04sS0FBSyxFQUNMLE1BQU0sRUFFTixNQUFNLEVBQ04sU0FBUyxFQUNULE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXJDLE9BQU8sRUFBRSxVQUFVLEVBQW1ELE1BQU0sa0NBQWtDLENBQUM7QUFDL0csT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sMkNBQTJDLENBQUM7QUFFbkYsT0FBTyxFQUFrQyxvQkFBb0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ2xHLE9BQU8sRUFBZSxlQUFlLEVBQUUsTUFBTSxn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QUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUMvRixDQUFDOzhHQW5YVSx3QkFBd0Isa0JBd0d6QixVQUFVO2tHQXhHVCx3QkFBd0IsK01BRXhCLHNCQUFzQixnRENuRm5DLHVsUEF5TEEsbTNMRHZISSxZQUFZLDBMQUNaLFdBQVcsOFZBQ1gsWUFBWSw2WEFDWixjQUFjLGdaQUNkLFlBQVksdXVCQUNaLGFBQWEsc1hBQ2IsMEJBQTBCLGtLQUMxQixnQ0FBZ0Msc05BQ2hDLGlDQUFpQyxrUUFDakMsc0JBQXNCOzsyRkFNYix3QkFBd0I7a0JBbkJwQyxTQUFTOytCQUNFLGtCQUFrQixjQUNoQixJQUFJLFdBQ1A7d0JBQ1AsWUFBWTt3QkFDWixXQUFXO3dCQUNYLFlBQVk7d0JBQ1osY0FBYzt3QkFDZCxZQUFZO3dCQUNaLGFBQWE7d0JBQ2IsMEJBQTBCO3dCQUMxQixnQ0FBZ0M7d0JBQ2hDLGlDQUFpQzt3QkFDakMsc0JBQXNCO3FCQUN2QixtQkFHZ0IsdUJBQXVCLENBQUMsTUFBTTs7MEJBMEc1QyxNQUFNOzJCQUFDLFVBQVU7OERBdEd1QixNQUFNO3NCQUFoRCxTQUFTO3VCQUFDLHNCQUFzQjtnQkFnQnhCLE9BQU87c0JBQWYsS0FBSztnQkFJRyxJQUFJO3NCQUFaLEtBQUs7Z0JBRUksYUFBYTtzQkFBdEIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBEZXN0cm95UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEluamVjdCxcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFZpZXdDaGlsZCxcbiAgaW5qZWN0LFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IEJ1dHRvbk1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvYnV0dG9uJztcbmltcG9ydCB7IENoZWNrYm94TW9kdWxlIH0gZnJvbSAncHJpbWVuZy9jaGVja2JveCc7XG5pbXBvcnQgeyBEaWFsb2dNb2R1bGUgfSBmcm9tICdwcmltZW5nL2RpYWxvZyc7XG5pbXBvcnQgeyBUb29sdGlwTW9kdWxlIH0gZnJvbSAncHJpbWVuZy90b29sdGlwJztcbmltcG9ydCB7IGNvbWJpbmVMYXRlc3QgfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgVklTVUFMSVpFUiwgSVZpc3VhbGl6ZXIsIElTcGF0aWFsQ29udHJvbHMsIFJvaVNlbGVjdGlvbk1vZGUgfSBmcm9tICcuLi9jb250cmFjdHMvdmlzdWFsaXplci5jb250cmFjdCc7XG5pbXBvcnQgeyBTcGF0aWFsQ2hhcnRzQ29tcG9uZW50IH0gZnJvbSAnLi9zcGF0aWFsLWNoYXJ0cy9zcGF0aWFsLWNoYXJ0cy5jb21wb25lbnQnO1xuaW1wb3J0IHsgU3BhdGlhbERhdGFzZXQgfSBmcm9tICcuLi9jb250cmFjdHMvc3BhdGlhbC1kYXRhc2V0LmNvbnRyYWN0JztcbmltcG9ydCB7IENvbG9ybWFwTm9kZSwgU3BhdGlhbFZpZXdTdGF0ZSwgREVGQVVMVF9TUEFUSUFMX1ZJRVcgfSBmcm9tICcuLi9jb250cmFjdHMvZGlzcGxheS10eXBlcyc7XG5pbXBvcnQgeyBQYW5lbE9wdGlvbiwgcGFyc2VHZW5lR3JvdXBzIH0gZnJvbSAnLi4vc3BhdGlhbC9zcGF0aWFsLXBhbmVsLW1vZGVsJztcbmltcG9ydCB7IFNwYXRpYWxTZWxlY3Rpb25NYXNrLCBlbXB0eVNlbGVjdGlvbiB9IGZyb20gJy4uL3NwYXRpYWwvc3BhdGlhbC1zZWxlY3Rpb24nO1xuaW1wb3J0IHsgR2VuZVBpY2tlck1vZGVsIH0gZnJvbSAnLi9zcGF0aWFsLWdlbmUtcGlja2VyJztcbmltcG9ydCB7IFNwYXRpYWxLZXlNb2RlbCwgU3BhdGlhbExlZ2VuZEVudHJ5IH0gZnJvbSAnLi9zcGF0aWFsLWtleS9zcGF0aWFsLWtleS5tb2RlbCc7XG5pbXBvcnQgeyBjb2xvckJ5TGFiZWwgfSBmcm9tICcuL3NwYXRpYWwta2V5L3NwYXRpYWwta2V5LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTcGF0aWFsQ2VsbHNQYW5lbENvbXBvbmVudCB9IGZyb20gJy4vc3BhdGlhbC1jZWxscy1wYW5lbC9zcGF0aWFsLWNlbGxzLXBhbmVsLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTcGF0aWFsVHJhbnNjcmlwdHNQYW5lbENvbXBvbmVudCB9IGZyb20gJy4vc3BhdGlhbC10cmFuc2NyaXB0cy1wYW5lbC9zcGF0aWFsLXRyYW5zY3JpcHRzLXBhbmVsLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTcGF0aWFsT2JzZXJ2YXRpb25zUGFuZWxDb21wb25lbnQgfSBmcm9tICcuL3NwYXRpYWwtb2JzZXJ2YXRpb25zLXBhbmVsL3NwYXRpYWwtb2JzZXJ2YXRpb25zLXBhbmVsLmNvbXBvbmVudCc7XG5cbi8qKiBAZGVwcmVjYXRlZCBNb3ZlZCB0byBgc3BhdGlhbC1rZXkvc3BhdGlhbC1rZXkubW9kZWxgOyByZS1leHBvcnRlZCBmb3Igb25lIHJlbGVhc2UuICovXG5leHBvcnQgdHlwZSB7IFNwYXRpYWxMZWdlbmRFbnRyeSB9O1xuXG4vKiogQGRlcHJlY2F0ZWQgTW92ZWQgdG8gYHNwYXRpYWwvc3BhdGlhbC1wYW5lbC1tb2RlbGA7IHJlLWV4cG9ydGVkIGZvciBvbmUgcmVsZWFzZS4gKi9cbmV4cG9ydCB7IHBhcnNlR2VuZUdyb3VwcyB9O1xuXG4vKiogUGVyLWluc3RhbmNlIGlkIHNvdXJjZSDigJQgc2VlIHtAbGluayBTcGF0aWFsQ29udHJvbHNDb21wb25lbnQuY2hhcnRzQm9keUlkfS4gKi9cbmxldCBjb250cm9sc0luc3RhbmNlU2VxID0gMDtcblxuLyoqXG4gKiBTcGF0aWFsLW9taWNzIGNvbnRyb2xzOiBhIG5vbi1tb2RhbCwgcmVzaXphYmxlLCBkcmFnZ2FibGUgZGlhbG9nIGZvciBjaG9vc2luZ1xuICogd2hhdCB0aGUgb2JzZXJ2YXRpb24gbWFya2VycyBhcmUgY29sb3VyZWQgYnksIGFuZCBob3cgdGhleSBhcmUgZHJhd24uXG4gKlxuICogRGVwZW5kcyBvbmx5IG9uIHtAbGluayBJU3BhdGlhbENvbnRyb2xzfSwgcmVhY2hlZCB0aHJvdWdoIHRoZSBgVklTVUFMSVpFUmBcbiAqIGNvbnRyYWN0IHRva2VuIOKAlCBuZXZlciBhIGNvbmNyZXRlIGJhY2tlbmQg4oCUIG1pcnJvcmluZyBob3dcbiAqIGBDaGFubmVsSGlzdG9ncmFtQ29tcG9uZW50YCBkZXBlbmRzIG9ubHkgb24gYENIQU5ORUxfSElTVE9HUkFNX0FQSWAuIFdoZW4gbm9cbiAqIGhvc3QgaGFzIGJvdW5kIGBTUEFUSUFMX0RBVEFfUE9SVGAsIGBnZXRTcGF0aWFsQ29udHJvbHMoKWAgcmV0dXJucyBudWxsIGFuZFxuICogdGhlIGRpYWxvZyByZW5kZXJzIGFuIGV4cGxhbmF0b3J5IGVtcHR5IHN0YXRlIHJhdGhlciB0aGFuIGRlYWQgY29udHJvbHMuXG4gKlxuICogVGhlIGxlZ2VuZCBzd2F0Y2hlcyBhbmQgdGhlIGNvbnRpbnVvdXMgY29sb3VyIGJhciBhcmUgYnVpbHQgd2l0aCB0aGUgU0FNRVxuICogZnVuY3Rpb25zIHRoZSByZW5kZXJlciB1c2VzIChgY2F0ZWdvcnlDb2xvcnNgIOKGkiBgcmVzb2x2ZUNhdGVnb3J5Q29sb3JzYCxcbiAqIGBzcGF0aWFsQ29udGludW91c0x1dGApLCBzbyB0aGUga2V5IGNhbm5vdCBkcmlmdCBmcm9tIHdoYXQgaXMgb24gc2NyZWVuLlxuICpcbiAqIE9uUHVzaDogdGhlIGNvbnRyb2xzJyBzdHJlYW1zLCB0aGUga2V5IGFuZCBnZW5lLWxpc3QgbW9kZWxzICh3aGljaCByZS1lbnRlciB0aGUgem9uZVxuICogd2hlbiB0aGVpciBhc3luYyB3b3JrIGxhbmRzKSBhbmQgYW4gYXdhaXRlZCBjYXRlZ29yeSBzZWxlY3Rpb24gbWFyayBpdCBmb3IgY2hlY2suXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3NwYXRpYWwtY29udHJvbHMnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlLFxuICAgIEZvcm1zTW9kdWxlLFxuICAgIEJ1dHRvbk1vZHVsZSxcbiAgICBDaGVja2JveE1vZHVsZSxcbiAgICBEaWFsb2dNb2R1bGUsXG4gICAgVG9vbHRpcE1vZHVsZSxcbiAgICBTcGF0aWFsQ2VsbHNQYW5lbENvbXBvbmVudCxcbiAgICBTcGF0aWFsVHJhbnNjcmlwdHNQYW5lbENvbXBvbmVudCxcbiAgICBTcGF0aWFsT2JzZXJ2YXRpb25zUGFuZWxDb21wb25lbnQsXG4gICAgU3BhdGlhbENoYXJ0c0NvbXBvbmVudCxcbiAgXSxcbiAgdGVtcGxhdGVVcmw6ICcuL3NwYXRpYWwtY29udHJvbHMuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9zcGF0aWFsLWNvbnRyb2xzLmNvbXBvbmVudC5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBTcGF0aWFsQ29udHJvbHNDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICAvKiogVGhlIGVtYmVkZGVkIGNoYXJ0LCBzbyBhIGRpYWxvZyByZXNpemUgY2FuIHJlLWZpdCBpdC4gKi9cbiAgQFZpZXdDaGlsZChTcGF0aWFsQ2hhcnRzQ29tcG9uZW50KSBwcml2YXRlIGNoYXJ0cz86IFNwYXRpYWxDaGFydHNDb21wb25lbnQ7XG5cbiAgLyoqXG4gICAqIFJlLWZpdCB0aGUgY2hhcnQgYWZ0ZXIgdGhlIGRpYWxvZyBpcyByZXNpemVkLlxuICAgKlxuICAgKiBQbG90bHkgZG9lcyBub3QgZm9sbG93IGEgY29udGFpbmVyIHJlc2l6ZSBvbiBpdHMgb3duIOKAlCBpdHMgYHJlc3BvbnNpdmVgXG4gICAqIG9wdGlvbiBsaXN0ZW5zIGZvciBXSU5ET1cgcmVzaXplcyBvbmx5LCBzbyBkcmFnZ2luZyB0aGUgZGlhbG9nJ3MgaGFuZGxlXG4gICAqIHJlYWNoZXMgaXQgdGhyb3VnaCBub3RoaW5nLiBQcmltZU5HIHRlbGxzIHVzIHdoZW4gdGhlIGRyYWcgZW5kcywgd2hpY2ggaXMgYVxuICAgKiBmYXIgbW9yZSBkaXJlY3Qgc2lnbmFsIHRoYW4gd2F0Y2hpbmcgYm94ZXMsIGFuZCBmaXJpbmcgb25jZSBvbiByZWxlYXNlIG1lYW5zXG4gICAqIG5vIHJlbGF5b3V0IGNodXJuIGR1cmluZyB0aGUgZHJhZy5cbiAgICovXG4gIHByb3RlY3RlZCBvblJlc2l6ZUVuZCgpOiB2b2lkIHtcbiAgICB0aGlzLmNoYXJ0cz8ucmVzaXplKCk7XG4gIH1cblxuICAvKiogRGlhbG9nIHZpc2liaWxpdHksIHR3by13YXkgYm91bmQgc28gYSB0b29sYmFyIGJ1dHRvbiBjYW4gb3BlbiBpdC4gKi9cbiAgQElucHV0KCkgdmlzaWJsZSA9IGZhbHNlO1xuICAvKiogU2V0IHdoaWxlIHRoZSAzRCBjbG91ZCBpcyB0aGUgYWN0aXZlIG1vZGUuIENoYW5nZXMgd2hhdCB0aGUgUk9JIHNlbGVjdGlvblxuICAgKiAgTUVBTlMg4oCUIGEgc2NyZWVuLXNwYWNlIGxhc3NvIGN1dHRpbmcgdGhyb3VnaCB0aGUgY2xvdWQncyBmdWxsIGRlcHRoIHJhdGhlclxuICAgKiAgdGhhbiBhIHNoYXBlIGluIHRpc3N1ZSBjb29yZGluYXRlcyDigJQgc28gdGhlIGhpbnQgYmVsb3cgaXQgc2F5cyBzby4gKi9cbiAgQElucHV0KCkgaXMzZCA9IGZhbHNlO1xuICAvKiogVGhlIGRpYWxvZyB3YXMgb3BlbmVkIG9yIGNsb3NlZDsgdHdvLXdheSB3aXRoIHtAbGluayB2aXNpYmxlfS4gKi9cbiAgQE91dHB1dCgpIHZpc2libGVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XG5cbiAgLyoqIE51bGwgd2hlbiB0aGUgaG9zdCBib3VuZCBubyBgU1BBVElBTF9EQVRBX1BPUlRgLiAqL1xuICBwcm90ZWN0ZWQgY29udHJvbHM6IElTcGF0aWFsQ29udHJvbHMgfCBudWxsID0gbnVsbDtcbiAgcHJvdGVjdGVkIGRhdGFzZXQ6IFNwYXRpYWxEYXRhc2V0IHwgbnVsbCA9IG51bGw7XG4gIHByb3RlY3RlZCB2aWV3OiBTcGF0aWFsVmlld1N0YXRlID0geyAuLi5ERUZBVUxUX1NQQVRJQUxfVklFVyB9O1xuXG4gIC8qKlxuICAgKiBHZW5lIHBpY2tlcjogYSBmaWx0ZXJhYmxlIGRyb3Bkb3duIHJhdGhlciB0aGFuIGEgZnJlZS10ZXh0IHR5cGVhaGVhZCwgc28gdGhlXG4gICAqIG9wdGlvbnMgYXJlIHZpc2libGUgYmVmb3JlIGFueXRoaW5nIGlzIHR5cGVkIGFuZCBlYWNoIGtleXN0cm9rZSBuYXJyb3dzIGEgbGlzdFxuICAgKiB0aGUgdXNlciBjYW4gc2VlLiBPbmUgbW9kZWwgZmVlZHMgZXZlcnkgZ2VuZSBkcm9wZG93biBvZiB0aGUgcGFuZWwuXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZ2VuZXMgPSBuZXcgR2VuZVBpY2tlck1vZGVsKFxuICAgICgpID0+IHRoaXMuY29udHJvbHMsXG4gICAgKCkgPT4gW1xuICAgICAgLi4uKHRoaXMudmlldz8udHJhbnNjcmlwdEdlbmVzID8/IFtdKSxcbiAgICAgIC4uLih0aGlzLnZpZXc/Lm9ic2VydmF0aW9uR2VuZXMgPz8gW10pLFxuICAgICAgLi4uKHRoaXMudmlldz8uY29sb3JCeT8ua2luZCA9PT0gJ2ZlYXR1cmUnID8gW3RoaXMudmlldy5jb2xvckJ5Lm5hbWVdIDogW10pLFxuICAgIF0sXG4gICAgKGZuKSA9PiB0aGlzLnJ1bkFuZE1hcmsoZm4pLFxuICApO1xuICAvKiogVGhlIGdlbmUgZHJvcGRvd25zJyBvcHRpb25zLiAqL1xuICBnZXQgZ2VuZU9wdGlvbnMoKTogUGFuZWxPcHRpb248c3RyaW5nPltdIHtcbiAgICByZXR1cm4gdGhpcy5nZW5lcy5vcHRpb25zO1xuICB9XG4gIC8qKiBUcnVlIHdoZW4gdGhlIG9wdGlvbnMgY29tZSBmcm9tIHRoZSBwb3J0IHBlciBrZXlzdHJva2UgcmF0aGVyIHRoYW4gYSByZXNpZGVudCBsaXN0LiAqL1xuICBnZXQgZ2VuZXNBcmVSZW1vdGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZ2VuZXMucmVtb3RlO1xuICB9XG4gIGdldCBnZW5lU2VhcmNoRmFpbGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmdlbmVzLmZhaWxlZDtcbiAgfVxuXG4gIC8qKiBUaGUga2V5IOKAlCBsZWdlbmQgb3IgY29sb3VyIGJhciDigJQgZm9yIHRoZSBhY3RpdmUgY29sb3VyaW5nLiBLZXB0IGhlcmUsIG5vdCBpblxuICAgKiAgYDxzcGF0aWFsLWtleT5gOiB3aGV0aGVyIHRoZSBjb2xvdXJpbmcgaXMgY2F0ZWdvcmljYWwgZGVjaWRlcyB3aGljaCBrbm9icyB0aGUgcmVzdCBvZlxuICAgKiAgdGhlIHBhbmVsIG9mZmVycywgd2hldGhlciBvciBub3QgdGhlIGtleSBpcyBvbiBzY3JlZW4uICovXG4gIHJlYWRvbmx5IGtleSA9IG5ldyBTcGF0aWFsS2V5TW9kZWwoKGZuKSA9PiB0aGlzLnJ1bkFuZE1hcmsoZm4pKTtcbiAgLyoqIENhdGVnb3JpY2FsIGtleSwgb3IgbnVsbCB3aGVuIHRoZSBhY3RpdmUgY29sb3VyaW5nIGlzIGNvbnRpbnVvdXMuICovXG4gIHByb3RlY3RlZCBnZXQgbGVnZW5kKCk6IFNwYXRpYWxMZWdlbmRFbnRyeVtdIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMua2V5LmxlZ2VuZDtcbiAgfVxuICAvKiogQ1NTIGdyYWRpZW50IGZvciBhIGNvbnRpbnVvdXMgY29sb3VyaW5nLCBvciBudWxsIHdoZW4gY2F0ZWdvcmljYWwuICovXG4gIHByb3RlY3RlZCBnZXQgY29sb3JCYXJDc3MoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMua2V5LmNvbG9yQmFyQ3NzO1xuICB9XG5cbiAgLyoqIEN1cnJlbnQgc2VsZWN0aW9uIOKAlCBkcml2ZXMgdGhlIGNvdW50LCB0aGUgQ2xlYXIgYnV0dG9uIGFuZCB0aGUgbXV0aW5nLiAqL1xuICBwcm90ZWN0ZWQgc2VsZWN0aW9uOiBTcGF0aWFsU2VsZWN0aW9uTWFzayA9IGVtcHR5U2VsZWN0aW9uKCk7XG4gIC8qKiBUaGUgbGVnZW5kIHJvdyB3aG9zZSBjYXRlZ29yeSBpcyBjdXJyZW50bHkgc2VsZWN0ZWQsIGZvciBoaWdobGlnaHRpbmcuICovXG4gIHByb3RlY3RlZCBzZWxlY3RlZENhdGVnb3J5OiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgLyoqIEFuIFJPSSBzZWxlY3Rpb24gdGhhdCBtYXRjaGVkIG5vdGhpbmcsIHNvIHRoZSBVSSBjYW4gc2F5IHNvIHJhdGhlciB0aGFuXG4gICAqICBsb29raW5nIGxpa2UgdGhlIGJ1dHRvbiBkaWQgbm90aGluZy4gKi9cbiAgcHJvdGVjdGVkIHNlbGVjdGlvbk1pc3NlZCA9IGZhbHNlO1xuICAvKiogVGhlIG1vZGUgb2YgdGhlIHNlbGVjdGlvbiB0aGF0IHtAbGluayBzZWxlY3Rpb25NaXNzZWR9OiB3aGF0IGl0IGZvdW5kIG5vdGhpbmcgaW5zaWRlLiAqL1xuICBwcm90ZWN0ZWQgbWlzc2VkTW9kZTogUm9pU2VsZWN0aW9uTW9kZSA9ICdyZWdpb25zJztcbiAgLyoqIFRoZSByZWdpb24gY2xhc3NlcyBwaWNrZWQgaW4gdGhlIFJlZ2lvbiBFZGl0b3I6IGluIDNELCBcIlNlbGVjdCBmcm9tIFJPSXNcIiBzZWxlY3RzIGluc2lkZSB0aGVtLiAqL1xuICBwcm90ZWN0ZWQgcGlja2VkQ2xhc3NlczogcmVhZG9ubHkgc3RyaW5nW10gPSBbXTtcbiAgLyoqIFdoaWxlIFwiU2VsZWN0IGZyb20gUk9Jc1wiIHJlYWRzIHRoZSBwaWNrZWQgY2xhc3Nlcycgb3V0bGluZXMuICovXG4gIHByb3RlY3RlZCBzZWxlY3RpbmdGcm9tUmVnaW9ucyA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBEaXN0cmlidXRpb24gc2VjdGlvbiBpcyBleHBhbmRlZC4gQ29sbGFwc2VkIGJ5IGRlZmF1bHQ6IHRoZVxuICAgKiBwYW5lbCdzIHByaW1hcnkgam9iIGlzIHRoZSBjb2xvdXIgY29udHJvbHMsIGFuZCB0aGUgY2hhcnQgcm91Z2hseSBkb3VibGVzXG4gICAqIGl0cyBoZWlnaHQuXG4gICAqL1xuICBwcm90ZWN0ZWQgY2hhcnRzT3BlbiA9IGZhbHNlO1xuICAvKiogUGVyLWluc3RhbmNlIGlkIGZvciB0aGUgY29sbGFwc2libGUgYm9keSwgc28gYGFyaWEtY29udHJvbHNgIHBvaW50cyBhdCBvbmVcbiAgICogIGVsZW1lbnQgYW5kIGV4cGFuZGluZyB0aGUgc2Vjb25kIHBhbmVsIGNhbm5vdCBzY3JvbGwgdGhlIGZpcnN0IG9uZSdzIGNoYXJ0LiAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgY2hhcnRzQm9keUlkID0gYHNjLWNoYXJ0cy1ib2R5LSR7Kytjb250cm9sc0luc3RhbmNlU2VxfWA7XG5cbiAgLyoqIENvbG9ybWFwIHRyZWUgZm9yIHRoZSBjb250aW51b3VzIGNvbG91ciBzY2FsZSBhbmQgdGhlIGRlbnNpdHkgbWFwOiB0aGUgbGlicmFyeSdzXG4gICAqICBvd24gYENPTE9STUFQX09QVElPTlNgLiAqL1xuICBwcm90ZWN0ZWQgY29sb3JtYXBPcHRpb25zOiBDb2xvcm1hcE5vZGVbXSA9IFtdO1xuXG4gIHByaXZhdGUgY29sb3JtYXA6IENvbG9ybWFwTm9kZSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHJldmVyc2UgPSBmYWxzZTtcbiAgcHJpdmF0ZSByZWFkb25seSBkZXN0cm95UmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuICBwcml2YXRlIHJlYWRvbmx5IGNkciA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgQEluamVjdChWSVNVQUxJWkVSKSBwcml2YXRlIHJlYWRvbmx5IHZpejogSVZpc3VhbGl6ZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSB6b25lOiBOZ1pvbmUsXG4gICkge31cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmNvbnRyb2xzID0gdGhpcy52aXouZ2V0U3BhdGlhbENvbnRyb2xzPy4oKSA/PyBudWxsO1xuICAgIHRoaXMuY29sb3JtYXBPcHRpb25zID0gdGhpcy52aXouZ2V0Q29sb3JtYXBPcHRpb25zPy4oKSA/PyBbXTtcbiAgICBpZiAoIXRoaXMuY29udHJvbHMpIHJldHVybjtcblxuICAgIGNvbnN0IHVudGlsRGVzdHJveWVkID0gPFQ+KCkgPT4gdGFrZVVudGlsRGVzdHJveWVkPFQ+KHRoaXMuZGVzdHJveVJlZik7XG4gICAgdGhpcy5jb250cm9sc1xuICAgICAgLmdldERhdGFzZXQkKClcbiAgICAgIC5waXBlKHVudGlsRGVzdHJveWVkKCkpXG4gICAgICAuc3Vic2NyaWJlKChkYXRhc2V0KSA9PiB7XG4gICAgICAgIHRoaXMuZGF0YXNldCA9IGRhdGFzZXQ7XG4gICAgICAgIHRoaXMuZ2VuZXMuc2V0RGF0YXNldChkYXRhc2V0KTtcbiAgICAgICAgLy8gQSBkYXRhc2V0IHdpdGggbm8gY2VsbHMgdG8gb3V0bGluZSBsZWFkcyB3aXRoIGl0cyBvYnNlcnZhdGlvbnMuXG4gICAgICAgIHRoaXMub3BlbiA9IHtcbiAgICAgICAgICAuLi50aGlzLm9wZW4sXG4gICAgICAgICAgY2VsbHM6ICEhKGRhdGFzZXQ/LnBvbHlnb25UaWxlcyB8fCBkYXRhc2V0Py5wb2x5Z29ucyksXG4gICAgICAgICAgb2JzZXJ2YXRpb25zOiAhKGRhdGFzZXQ/LnBvbHlnb25UaWxlcyB8fCBkYXRhc2V0Py5wb2x5Z29ucyksXG4gICAgICAgIH07XG4gICAgICAgIHZvaWQgdGhpcy5yZWZyZXNoS2V5KCk7XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSk7XG5cbiAgICB0aGlzLmNvbnRyb2xzXG4gICAgICAuZ2V0Vmlld1N0YXRlJCgpXG4gICAgICAucGlwZSh1bnRpbERlc3Ryb3llZCgpKVxuICAgICAgLnN1YnNjcmliZSgodmlldykgPT4ge1xuICAgICAgICB0aGlzLnZpZXcgPSB2aWV3O1xuICAgICAgICB2b2lkIHRoaXMucmVmcmVzaEtleSgpO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pO1xuXG4gICAgLy8gVGhlIHJlbmRlcmVyJ3Mgb3duIHN0cmVhbXMgbWF5IGVtaXQgb3V0c2lkZSB0aGUgem9uZTogcmUtZW50ZXJlZCBoZXJlLCBvbmNlLCBmb3JcbiAgICAvLyBldmVyeSBwYW5lbCB0aGV5IGZlZWQuXG4gICAgY29uc3QgZXN0aW1hdGUkID0gdGhpcy5jb250cm9scy5nZXRUcmFuc2NyaXB0RXN0aW1hdGUkPy4oKTtcbiAgICBlc3RpbWF0ZSQ/LnBpcGUodW50aWxEZXN0cm95ZWQoKSkuc3Vic2NyaWJlKChlKSA9PlxuICAgICAgdGhpcy5ydW5BbmRNYXJrKCgpID0+IHtcbiAgICAgICAgdGhpcy5lc3RpbWF0ZSA9IGU7XG4gICAgICB9KSxcbiAgICApO1xuICAgIGNvbnN0IGNvdW50cyQgPSB0aGlzLmNvbnRyb2xzLmdldEdlbmVDb3VudHNJblZpZXckPy4oKTtcbiAgICBjb3VudHMkPy5waXBlKHVudGlsRGVzdHJveWVkKCkpLnN1YnNjcmliZSgoYykgPT5cbiAgICAgIHRoaXMucnVuQW5kTWFyaygoKSA9PiB7XG4gICAgICAgIHRoaXMuZ2VuZUNvdW50cyA9IGM7XG4gICAgICB9KSxcbiAgICApO1xuICAgIGNvbnN0IGRlbnNpdHkkID0gdGhpcy5jb250cm9scy5nZXREZW5zaXR5U3RhdHMkPy4oKTtcbiAgICBkZW5zaXR5JD8ucGlwZSh1bnRpbERlc3Ryb3llZCgpKS5zdWJzY3JpYmUoKGQpID0+XG4gICAgICB0aGlzLnJ1bkFuZE1hcmsoKCkgPT4ge1xuICAgICAgICB0aGlzLmRlbnNpdHlTdGF0cyA9IGQ7XG4gICAgICB9KSxcbiAgICApO1xuXG4gICAgdGhpcy5jb250cm9sc1xuICAgICAgLmdldFNlbGVjdGlvbiQoKVxuICAgICAgLnBpcGUodW50aWxEZXN0cm95ZWQoKSlcbiAgICAgIC5zdWJzY3JpYmUoKHNlbGVjdGlvbikgPT5cbiAgICAgICAgLy8gU2V0IGZyb20gb3V0c2lkZSB0aGUgem9uZSB0b286IGEgc2VsZWN0aW9uIGZyb20gdGhlIHJlZ2lvbiBjbGFzc2VzJyB2b2x1bWVzLlxuICAgICAgICB0aGlzLnJ1bkFuZE1hcmsoKCkgPT4ge1xuICAgICAgICAgIHRoaXMuc2VsZWN0aW9uID0gc2VsZWN0aW9uO1xuICAgICAgICAgIGlmIChzZWxlY3Rpb24uY291bnQgPT09IDApIHRoaXMuc2VsZWN0ZWRDYXRlZ29yeSA9IG51bGw7XG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgIHRoaXMuY29udHJvbHNcbiAgICAgIC5nZXRQaWNrZWRSZWdpb25DbGFzc2VzJD8uKClcbiAgICAgID8ucGlwZSh1bnRpbERlc3Ryb3llZCgpKVxuICAgICAgLnN1YnNjcmliZSgoY2xhc3NlcykgPT5cbiAgICAgICAgdGhpcy5ydW5BbmRNYXJrKCgpID0+IHtcbiAgICAgICAgICB0aGlzLnBpY2tlZENsYXNzZXMgPSBjbGFzc2VzO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAvLyBUaGUgY29sb3VyIGJhciBtdXN0IHVzZSB0aGUgY29sb3JtYXAgdGhlIHJlbmRlcmVyIGlzIHVzaW5nLlxuICAgIGNvbWJpbmVMYXRlc3QoW3RoaXMudml6LmdldENvbG9ybWFwKCksIHRoaXMudml6LmdldFJldmVyc2VTY2FsZSgpXSlcbiAgICAgIC5waXBlKHVudGlsRGVzdHJveWVkKCkpXG4gICAgICAuc3Vic2NyaWJlKChbY29sb3JtYXAsIHJldmVyc2VdKSA9PiB7XG4gICAgICAgIHRoaXMuY29sb3JtYXAgPSAoY29sb3JtYXAgYXMgQ29sb3JtYXBOb2RlKSA/PyBudWxsO1xuICAgICAgICB0aGlzLnJldmVyc2UgPSAhIXJldmVyc2U7XG4gICAgICAgIHZvaWQgdGhpcy5yZWZyZXNoS2V5KCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKiBBcHBseSBhbiBhc3luYyByZXN1bHQgaW5zaWRlIHRoZSB6b25lIGFuZCByZS1yZW5kZXIgdGhpcyBPblB1c2ggZGlhbG9nLiAqL1xuICBwcml2YXRlIHJ1bkFuZE1hcmsoZm46ICgpID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLnpvbmUucnVuKCgpID0+IHtcbiAgICAgIGZuKCk7XG4gICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvblZpc2libGVDaGFuZ2UodmFsdWU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLnZpc2libGUgPSB2YWx1ZTtcbiAgICB0aGlzLnZpc2libGVDaGFuZ2UuZW1pdCh2YWx1ZSk7XG4gIH1cblxuICAvLyDilIDilIAgdGhlIHNoYXJlZCBnZW5lIGxpc3Qg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqIEEga2V5c3Ryb2tlIGluIGEgZ2VuZSBkcm9wZG93bidzIGZpbHRlciBib3gg4oCUIHNlZSB7QGxpbmsgR2VuZVBpY2tlck1vZGVsLm9uRmlsdGVyfS4gKi9cbiAgb25HZW5lRmlsdGVyKHF1ZXJ5OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5nZW5lcy5vbkZpbHRlcihxdWVyeSk7XG4gIH1cblxuICAvKiogQSBnZW5lIGRyb3Bkb3duIG9wZW5lZCDigJQgc2VlIHtAbGluayBHZW5lUGlja2VyTW9kZWwuZW5zdXJlTGlzdH0uICovXG4gIGVuc3VyZUdlbmVMaXN0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLmdlbmVzLmVuc3VyZUxpc3QoKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBzZWxlY3Rpb24g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqIFNlbGVjdCBldmVyeSBvYnNlcnZhdGlvbiBpbnNpZGUgdGhlIGRyYXduIHJlZ2lvbnMgKHRoZWlyIHVuaW9uKSDigJQgaW4gM0QsIGluc2lkZSB0aGVcbiAgICogIHBpY2tlZCBjbGFzc2VzJyB2b2x1bWVzLiAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgc2VsZWN0RnJvbVJlZ2lvbnMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCF0aGlzLmNvbnRyb2xzIHx8IHRoaXMuc2VsZWN0aW5nRnJvbVJlZ2lvbnMpIHJldHVybjtcbiAgICB0aGlzLnNlbGVjdGluZ0Zyb21SZWdpb25zID0gdHJ1ZTtcbiAgICAvLyBUaGUgbW9kZSB0aGUgc2VsZWN0aW9uIHJ1bnMgaW4gKGRlY2lkZWQgYXMgaXQgc3RhcnRzKSwgZm9yIHdoYXQgYSBtaXNzIHNheXMgaXQgbWlzc2VkLlxuICAgIGNvbnN0IG1vZGUgPSB0aGlzLnJvaVNlbGVjdGlvbk1vZGU7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgbGV0IGNvdW50OiBudW1iZXIgfCBudWxsID0gMDtcbiAgICB0cnkge1xuICAgICAgY291bnQgPSBhd2FpdCB0aGlzLmNvbnRyb2xzLnNlbGVjdEZyb21SZWdpb25zKCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ1tzcGF0aWFsXSBjb3VsZCBub3Qgc2VsZWN0IGZyb20gdGhlIHJlZ2lvbnMnLCBlcnIpO1xuICAgIH1cbiAgICAvLyBUaGUgY2xhc3Nlcycgb3V0bGluZXMgYXJlIHJlYWQgaW4gYSB3b3JrZXIsIHdob3NlIGFuc3dlciBsYW5kcyBvdXRzaWRlIHRoZSB6b25lLlxuICAgIHRoaXMucnVuQW5kTWFyaygoKSA9PiB7XG4gICAgICB0aGlzLnNlbGVjdGluZ0Zyb21SZWdpb25zID0gZmFsc2U7XG4gICAgICAvLyBTdXBlcnNlZGVkIChudWxsKTogYSBuZXdlciBzZWxlY3Rpb24gc3RhbmRzLCBhbmQgc2F5cyB3aGF0IGl0IGlzIGl0c2VsZi5cbiAgICAgIGlmIChjb3VudCA9PT0gbnVsbCkgcmV0dXJuO1xuICAgICAgdGhpcy5zZWxlY3RlZENhdGVnb3J5ID0gbnVsbDtcbiAgICAgIHRoaXMuc2VsZWN0aW9uTWlzc2VkID0gY291bnQgPT09IDA7XG4gICAgICB0aGlzLm1pc3NlZE1vZGUgPSBtb2RlO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqIEluIDNEIHdpdGggY2xhc3NlcyBwaWNrZWQsIFwiU2VsZWN0IGZyb20gUk9Jc1wiIHNlbGVjdHMgaW5zaWRlIHRoZWlyIHZvbHVtZXMuICovXG4gIHByb3RlY3RlZCBnZXQgc2VsZWN0c0NsYXNzVm9sdW1lcygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5yb2lTZWxlY3Rpb25Nb2RlID09PSAnY2xhc3Mtdm9sdW1lcyc7XG4gIH1cblxuICAvKiogSG93IFwiU2VsZWN0IGZyb20gUk9Jc1wiIHNlbGVjdHMgbm93OiB0aGUgY29udHJvbHMnIG93biBydWxlLCB0aGUgb25lIHRoZSBzZWxlY3Rpb24gcnVucyBieS4gKi9cbiAgcHJpdmF0ZSBnZXQgcm9pU2VsZWN0aW9uTW9kZSgpOiBSb2lTZWxlY3Rpb25Nb2RlIHtcbiAgICByZXR1cm4gdGhpcy5jb250cm9scz8ucm9pU2VsZWN0aW9uTW9kZT8uKCkgPz8gJ3JlZ2lvbnMnO1xuICB9XG5cbiAgLyoqIExlZ2VuZCBjbGljazogc2VsZWN0IG9uZSBjYXRlZ29yeS4gQ2xpY2tpbmcgdGhlIGFjdGl2ZSByb3cgY2xlYXJzIGl0LCBzbyBhXG4gICAqICBzZWNvbmQgY2xpY2sgaXMgYW4gdW5kbyByYXRoZXIgdGhhbiBhIG5vLW9wLiAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgc2VsZWN0Q2F0ZWdvcnkoaW5kZXg6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGJ5ID0gdGhpcy52aWV3LmNvbG9yQnk7XG4gICAgaWYgKCF0aGlzLmNvbnRyb2xzIHx8IGJ5Py5raW5kICE9PSAnY29sdW1uJykgcmV0dXJuO1xuICAgIGlmICh0aGlzLnNlbGVjdGVkQ2F0ZWdvcnkgPT09IGluZGV4KSB7XG4gICAgICB0aGlzLmNsZWFyU2VsZWN0aW9uKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmNvbnRyb2xzLnNlbGVjdENhdGVnb3J5KGJ5Lm5hbWUsIGluZGV4KTtcbiAgICAgIHRoaXMuc2VsZWN0ZWRDYXRlZ29yeSA9IGluZGV4O1xuICAgICAgdGhpcy5zZWxlY3Rpb25NaXNzZWQgPSBmYWxzZTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRDYXRlZ29yeSA9IG51bGw7XG4gICAgfVxuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4cGFuZCBvciBjb2xsYXBzZSB0aGUgZGlzdHJpYnV0aW9uIHNlY3Rpb24uXG4gICAqXG4gICAqIEV4cGFuZGluZyBTQ1JPTExTIGl0IGludG8gdmlldywgYmVjYXVzZSB0aGUgcGFuZWwgaXMgdGFsbGVyIHRoYW4gdGhlIHZpZXdwb3J0XG4gICAqIG9uY2UgdGhpcyBzZWN0aW9uIGlzIG9wZW4gYW5kIHRoZSBjaGFydCBpcyBpdHMgbGFzdCByb3c6IGV4cGFuZGluZyBpdCBkcmV3IGFcbiAgICogY2hhcnQgfjMwMCBweCBiZWxvdyB0aGUgZm9sZCwgd2hpY2ggcmVhZHMgYXMgdGhlIHNlY3Rpb24gYmVpbmcgZW1wdHkuIFRoZVxuICAgKiBzY3JvbGwgaXMgZGVmZXJyZWQgYSB0YXNrIHNvIHRoZSBjaGFydCdzIG93biBkZWZlcnJlZCBmaXJzdCBkcmF3IGhhcyBnaXZlbiB0aGVcbiAgICogYm9keSBpdHMgaGVpZ2h0LlxuICAgKi9cbiAgcHJvdGVjdGVkIHRvZ2dsZUNoYXJ0cygpOiB2b2lkIHtcbiAgICB0aGlzLmNoYXJ0c09wZW4gPSAhdGhpcy5jaGFydHNPcGVuO1xuICAgIGlmICghdGhpcy5jaGFydHNPcGVuKSByZXR1cm47XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLmNoYXJ0c0JvZHlJZCk/LnNjcm9sbEludG9WaWV3KHsgYmxvY2s6ICdlbmQnLCBiZWhhdmlvcjogJ3Ntb290aCcgfSk7XG4gICAgfSwgMCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY2xlYXJTZWxlY3Rpb24oKTogdm9pZCB7XG4gICAgdGhpcy5jb250cm9scz8uY2xlYXJTZWxlY3Rpb24oKTtcbiAgICB0aGlzLnNlbGVjdGVkQ2F0ZWdvcnkgPSBudWxsO1xuICAgIHRoaXMuc2VsZWN0aW9uTWlzc2VkID0gZmFsc2U7XG4gIH1cblxuICAvKiogVHJ1ZSB3aGlsZSBhIHNlbGVjdGlvbiBpcyBhY3RpdmUg4oCUIGV2ZXJ5dGhpbmcgZWxzZSByZW5kZXJzIG11dGVkLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGhhc1NlbGVjdGlvbigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3Rpb24uY291bnQgPiAwO1xuICB9XG5cbiAgLy8g4pSA4pSAIHNlY3Rpb25zIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIC8qKiBCb3VuZGFyaWVzIG9uIG9mZmVyOiB0aWxlZCAobGV2ZWwtb2YtZGV0YWlsKSBvciB3aG9sZS1kYXRhc2V0IHJpbmdzLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGhhc0NlbGxzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhISh0aGlzLmRhdGFzZXQ/LnBvbHlnb25UaWxlcyB8fCB0aGlzLmRhdGFzZXQ/LnBvbHlnb25zKTtcbiAgfVxuXG4gIC8qKiBUcmFuc2NyaXB0cyBvbiBvZmZlcjogdGlsZXMgdG8gZHJhdywgb3IgYSBkZW5zaXR5IG1hcC4gKi9cbiAgcHJvdGVjdGVkIGdldCBoYXNUcmFuc2NyaXB0cygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmRhdGFzZXQ/LnRyYW5zY3JpcHRUaWxlcyB8fCAhIXRoaXMuZGF0YXNldD8uZGVuc2l0eTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvblNob3dJbWFnZShvbjogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuY29udHJvbHM/LnNldFZpZXdTdGF0ZSh7IHNob3dJbWFnZTogb24gfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb25TaG93QW5ub3RhdGlvbnMob246IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmNvbnRyb2xzPy5zZXRWaWV3U3RhdGUoeyBzaG93QW5ub3RhdGlvbnM6IG9uIH0pO1xuICB9XG5cbiAgLyoqIFdoaWNoIGNvbGxhcHNpYmxlIHNlY3Rpb25zIGFyZSBvcGVuLiBQZXIgZGlhbG9nIGluc3RhbmNlLCBub3QgcGVyc2lzdGVkLiAqL1xuICBwcm90ZWN0ZWQgb3BlbjogUmVjb3JkPCdpbWFnZXMnIHwgJ2NlbGxzJyB8ICd0cmFuc2NyaXB0cycgfCAnYW5ub3RhdGlvbnMnIHwgJ29ic2VydmF0aW9ucycsIGJvb2xlYW4+ID0ge1xuICAgIGltYWdlczogZmFsc2UsXG4gICAgY2VsbHM6IHRydWUsXG4gICAgdHJhbnNjcmlwdHM6IGZhbHNlLFxuICAgIGFubm90YXRpb25zOiBmYWxzZSxcbiAgICBvYnNlcnZhdGlvbnM6IGZhbHNlLFxuICB9O1xuXG4gIHByb3RlY3RlZCB0b2dnbGVTZWN0aW9uKG5hbWU6IGtleW9mIFNwYXRpYWxDb250cm9sc0NvbXBvbmVudFsnb3BlbiddKTogdm9pZCB7XG4gICAgdGhpcy5zZXRPcGVuKG5hbWUsICF0aGlzLm9wZW5bbmFtZV0pO1xuICB9XG5cbiAgLyoqIEV4cGFuZCBvciBjb2xsYXBzZSBhIHNlY3Rpb24g4oCUIHdoYXQgYSBwYW5lbCdzIGhlYWRlciBhc2tzIGZvci4gKi9cbiAgcHJvdGVjdGVkIHNldE9wZW4obmFtZToga2V5b2YgU3BhdGlhbENvbnRyb2xzQ29tcG9uZW50WydvcGVuJ10sIG9uOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5vcGVuID0geyAuLi50aGlzLm9wZW4sIFtuYW1lXTogb24gfTtcbiAgfVxuXG4gIC8vIOKUgOKUgCByZW5kZXJlciByZWFkb3V0cywgZm9yIHRoZSBUcmFuc2NyaXB0cyBzZWN0aW9uIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIC8qKiBFc3RpbWF0ZWQgdHJhbnNjcmlwdHMgaW4gdmlldywgYWdhaW5zdCB0aGUgYnVkZ2V0IOKAlCBFeHBsb3JlcidzIHBvaW50cyBiYXIuICovXG4gIHByb3RlY3RlZCBlc3RpbWF0ZTogeyBwb2ludHM6IG51bWJlcjsgbWF4OiBudW1iZXIgfSB8IG51bGwgPSBudWxsO1xuICAvKiogVGhlIGRlbnNpdHkgd2luZG93IGluIHVzZSBhbmQgaXRzIGRlbnNlc3QgYmluLCBmb3IgdGhlIHRocmVzaG9sZCBjb250cm9sLiAqL1xuICBwcm90ZWN0ZWQgZGVuc2l0eVN0YXRzOiB7IGxvOiBudW1iZXI7IGhpOiBudW1iZXI7IG1heDogbnVtYmVyIH0gfCBudWxsID0gbnVsbDtcbiAgLyoqIFRyYW5zY3JpcHRzIG9mIGVhY2ggc2VsZWN0ZWQgZ2VuZSBpbiB0aGUgY3VycmVudCB2aWV3LCBmcm9tIHRoZSByZW5kZXJlci4gKi9cbiAgcHJvdGVjdGVkIGdlbmVDb3VudHM6IFJlY29yZDxzdHJpbmcsIG51bWJlcj4gfCBudWxsID0gbnVsbDtcblxuICBwcm90ZWN0ZWQgcmVzZXQoKTogdm9pZCB7XG4gICAgdGhpcy5jb250cm9scz8uc2V0Vmlld1N0YXRlKHsgLi4uREVGQVVMVF9TUEFUSUFMX1ZJRVcgfSk7XG4gICAgdGhpcy5jbGVhclNlbGVjdGlvbigpO1xuICB9XG5cbiAgLyoqIExhYmVsIGZvciB0aGUgY3VycmVudCBjb2xvdXJpbmcsIGZvciB0aGUgRGlzdHJpYnV0aW9uIGhlYWRpbmcuICovXG4gIHByb3RlY3RlZCBnZXQgY29sb3JCeUxhYmVsKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGNvbG9yQnlMYWJlbCh0aGlzLnZpZXcpO1xuICB9XG5cbiAgLyoqIFRydWUgd2hlbiB0aGUgYWN0aXZlIGNvbG91cmluZyBpcyBhIGNhdGVnb3JpY2FsIGNvbHVtbiAoZHJpdmVzIHRoZSBrZXkpLiAqL1xuICBnZXQgaXNDYXRlZ29yaWNhbCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5sZWdlbmQgIT09IG51bGw7XG4gIH1cblxuICAvKiogV2hldGhlciBsb2cvY2xpcCBhcHBseSDigJQgdGhleSBhcmUgY29udGludW91cy1vbmx5IGtub2JzLiAqL1xuICBnZXQgaXNDb250aW51b3VzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIXRoaXMudmlldy5jb2xvckJ5ICYmIHRoaXMubGVnZW5kID09PSBudWxsO1xuICB9XG5cbiAgLy8g4pSA4pSAIGludGVybmFscyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAvKiogUmVidWlsZCB0aGUgbGVnZW5kIG9yIGNvbG91ciBiYXIgZm9yIHRoZSBjdXJyZW50IGNvbG91cmluZy4gKi9cbiAgcHJpdmF0ZSByZWZyZXNoS2V5KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLmtleS5yZWZyZXNoKHRoaXMuY29udHJvbHMsIHRoaXMuZGF0YXNldCwgdGhpcy52aWV3LCB0aGlzLmNvbG9ybWFwLCB0aGlzLnJldmVyc2UpO1xuICB9XG59XG4iLCI8cC1kaWFsb2dcbiAgaGVhZGVyPVwiU3BhdGlhbCBvbWljc1wiXG4gIFt2aXNpYmxlXT1cInZpc2libGVcIlxuICAodmlzaWJsZUNoYW5nZSk9XCJvblZpc2libGVDaGFuZ2UoJGV2ZW50KVwiXG4gIFttb2RhbF09XCJmYWxzZVwiXG4gIFtyZXNpemFibGVdPVwidHJ1ZVwiXG4gIFtkcmFnZ2FibGVdPVwidHJ1ZVwiXG4gIHBvc2l0aW9uPVwibGVmdFwiXG4gIChvblJlc2l6ZUVuZCk9XCJvblJlc2l6ZUVuZCgpXCJcbiAgW3N0eWxlXT1cInsgd2lkdGg6ICczMHJlbScgfVwiXG4gIFticmVha3BvaW50c109XCJ7ICc5NjBweCc6ICc5MHZ3JyB9XCJcbiAgc3R5bGVDbGFzcz1cInNwYXRpYWwtY29udHJvbHMtZGlhbG9nXCJcbj5cbiAgPCEtLSBObyBwb3J0IGJvdW5kOiBzYXkgd2h5IHJhdGhlciB0aGFuIHNob3dpbmcgY29udHJvbHMgdGhhdCBkbyBub3RoaW5nLiAtLT5cbiAgPGRpdiBjbGFzcz1cInNjLWVtcHR5XCIgKm5nSWY9XCIhY29udHJvbHNcIj5cbiAgICBObyBzcGF0aWFsLW9taWNzIGRhdGEgc291cmNlIGlzIGNvbmZpZ3VyZWQuIEEgaG9zdCBwcm92aWRlcyBvbmUgYnkgYmluZGluZ1xuICAgIDxjb2RlPlNQQVRJQUxfREFUQV9QT1JUPC9jb2RlPi5cbiAgPC9kaXY+XG5cbiAgPGRpdiBjbGFzcz1cInNjLWVtcHR5XCIgKm5nSWY9XCJjb250cm9scyAmJiAhZGF0YXNldFwiPk5vIGRhdGFzZXQgaXMgbG9hZGVkLjwvZGl2PlxuXG4gIDxkaXYgY2xhc3M9XCJzYy1ib2R5XCIgKm5nSWY9XCJjb250cm9scyAmJiBkYXRhc2V0IGFzIGRzXCI+XG4gICAgPGRpdiBjbGFzcz1cInNjLWRhdGFzZXRcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwic2MtZGF0YXNldC1uYW1lXCI+e3sgZHMubmFtZSB9fTwvc3Bhbj5cbiAgICAgIDxzcGFuIGNsYXNzPVwic2MtZGF0YXNldC1jb3VudFwiPnt7IGRzLm9ic2VydmF0aW9ucy5jb3VudCB8IG51bWJlciB9fSBvYnNlcnZhdGlvbnM8L3NwYW4+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIE9yZ2FuaXNlZCBhcyBYZW5pdW0gRXhwbG9yZXIncyBzaWRlIHBhbmVsOiBvbmUgY29sbGFwc2libGUgc2VjdGlvbiBwZXIgbGF5ZXIsXG4gICAgICAgICBlYWNoIHdpdGggaXRzIG93biBvbi9vZmYgc3dpdGNoIGluIHRoZSBoZWFkZXIuIC0tPlxuXG4gICAgPCEtLSBJbWFnZXMgLS0+XG4gICAgPGRpdiBjbGFzcz1cInNjLXBhbmVsXCIgKm5nSWY9XCJkcy5pbWFnZVJlZiAmJiAhaXMzZFwiIFtjbGFzcy5vcGVuXT1cIm9wZW4uaW1hZ2VzXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwic2MtcGFuZWwtaGVhZFwiIChjbGljayk9XCJ0b2dnbGVTZWN0aW9uKCdpbWFnZXMnKVwiPlxuICAgICAgICA8cC1jaGVja2JveFxuICAgICAgICAgIFtiaW5hcnldPVwidHJ1ZVwiXG4gICAgICAgICAgW25nTW9kZWxdPVwidmlldy5zaG93SW1hZ2VcIlxuICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgICAgIChvbkNoYW5nZSk9XCJvblNob3dJbWFnZSgkZXZlbnQuY2hlY2tlZClcIlxuICAgICAgICA+PC9wLWNoZWNrYm94PlxuICAgICAgICA8c3BhbiBjbGFzcz1cInNjLXBhbmVsLXRpdGxlXCI+SW1hZ2VzPC9zcGFuPlxuICAgICAgICA8aSBjbGFzcz1cInBpXCIgW2NsYXNzLnBpLWNoZXZyb24tZG93bl09XCJvcGVuLmltYWdlc1wiIFtjbGFzcy5waS1jaGV2cm9uLXJpZ2h0XT1cIiFvcGVuLmltYWdlc1wiPjwvaT5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cInNjLXBhbmVsLWJvZHlcIiAqbmdJZj1cIm9wZW4uaW1hZ2VzXCI+XG4gICAgICAgIDxzbWFsbCBjbGFzcz1cInNjLWhpbnRcIj4gQ2hhbm5lbHMsIGNvbG91cnMgYW5kIGNvbnRyYXN0IGFyZSBpbiB0aGUgQ2hhbm5lbHMgJmFtcDsgSGlzdG9ncmFtIGRpYWxvZy4gPC9zbWFsbD5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBDZWxscyAtLT5cbiAgICA8c3BhdGlhbC1jZWxscy1wYW5lbFxuICAgICAgKm5nSWY9XCJoYXNDZWxscyAmJiAhaXMzZFwiXG4gICAgICBbY29udHJvbHNdPVwiY29udHJvbHNcIlxuICAgICAgW2RhdGFzZXRdPVwiZHNcIlxuICAgICAgW3ZpZXddPVwidmlld1wiXG4gICAgICBbZ2VuZXNdPVwiZ2VuZXNcIlxuICAgICAgW2NvbG9yQmFyQ3NzXT1cImNvbG9yQmFyQ3NzXCJcbiAgICAgIFtvcGVuXT1cIm9wZW4uY2VsbHNcIlxuICAgICAgKG9wZW5DaGFuZ2UpPVwic2V0T3BlbignY2VsbHMnLCAkZXZlbnQpXCJcbiAgICA+PC9zcGF0aWFsLWNlbGxzLXBhbmVsPlxuXG4gICAgPCEtLSBUcmFuc2NyaXB0cyAtLT5cbiAgICA8c3BhdGlhbC10cmFuc2NyaXB0cy1wYW5lbFxuICAgICAgKm5nSWY9XCJoYXNUcmFuc2NyaXB0cyAmJiAhaXMzZFwiXG4gICAgICBbY29udHJvbHNdPVwiY29udHJvbHNcIlxuICAgICAgW2RhdGFzZXRdPVwiZHNcIlxuICAgICAgW3ZpZXddPVwidmlld1wiXG4gICAgICBbZ2VuZXNdPVwiZ2VuZXNcIlxuICAgICAgW2VzdGltYXRlXT1cImVzdGltYXRlXCJcbiAgICAgIFtkZW5zaXR5U3RhdHNdPVwiZGVuc2l0eVN0YXRzXCJcbiAgICAgIFtnZW5lQ291bnRzXT1cImdlbmVDb3VudHNcIlxuICAgICAgW2NvbG9ybWFwT3B0aW9uc109XCJjb2xvcm1hcE9wdGlvbnNcIlxuICAgICAgW29wZW5dPVwib3Blbi50cmFuc2NyaXB0c1wiXG4gICAgICAob3BlbkNoYW5nZSk9XCJzZXRPcGVuKCd0cmFuc2NyaXB0cycsICRldmVudClcIlxuICAgID5cbiAgICA8L3NwYXRpYWwtdHJhbnNjcmlwdHMtcGFuZWw+XG5cbiAgICA8IS0tIEFubm90YXRpb25zOiB0aGUgZHJhd24gcmVnaW9ucywgYW5kIHNlbGVjdGluZyB3aGF0IHRoZXkgZW5jbG9zZS4gLS0+XG4gICAgPGRpdiBjbGFzcz1cInNjLXBhbmVsXCIgW2NsYXNzLm9wZW5dPVwib3Blbi5hbm5vdGF0aW9uc1wiPlxuICAgICAgPGRpdiBjbGFzcz1cInNjLXBhbmVsLWhlYWRcIiAoY2xpY2spPVwidG9nZ2xlU2VjdGlvbignYW5ub3RhdGlvbnMnKVwiPlxuICAgICAgICA8cC1jaGVja2JveFxuICAgICAgICAgIFtiaW5hcnldPVwidHJ1ZVwiXG4gICAgICAgICAgW25nTW9kZWxdPVwidmlldy5zaG93QW5ub3RhdGlvbnMgIT09IGZhbHNlXCJcbiAgICAgICAgICAoY2xpY2spPVwiJGV2ZW50LnN0b3BQcm9wYWdhdGlvbigpXCJcbiAgICAgICAgICAob25DaGFuZ2UpPVwib25TaG93QW5ub3RhdGlvbnMoJGV2ZW50LmNoZWNrZWQpXCJcbiAgICAgICAgICBwVG9vbHRpcD1cIlNob3cgdGhlIGRyYXduIHJlZ2lvbnNcIlxuICAgICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cInRvcFwiXG4gICAgICAgID48L3AtY2hlY2tib3g+XG4gICAgICAgIDxzcGFuIGNsYXNzPVwic2MtcGFuZWwtdGl0bGVcIj5Bbm5vdGF0aW9uczwvc3Bhbj5cbiAgICAgICAgPGkgY2xhc3M9XCJwaVwiIFtjbGFzcy5waS1jaGV2cm9uLWRvd25dPVwib3Blbi5hbm5vdGF0aW9uc1wiIFtjbGFzcy5waS1jaGV2cm9uLXJpZ2h0XT1cIiFvcGVuLmFubm90YXRpb25zXCI+PC9pPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2IGNsYXNzPVwic2MtcGFuZWwtYm9keVwiICpuZ0lmPVwib3Blbi5hbm5vdGF0aW9uc1wiPlxuICAgICAgICA8ZGl2IGNsYXNzPVwic2Mtcm93XCI+XG4gICAgICAgICAgPHAtYnV0dG9uXG4gICAgICAgICAgICBsYWJlbD1cIlNlbGVjdCBmcm9tIFJPSXNcIlxuICAgICAgICAgICAgaWNvbj1cInBpIHBpLW9iamVjdC1ncm91cFwiXG4gICAgICAgICAgICBzaXplPVwic21hbGxcIlxuICAgICAgICAgICAgW291dGxpbmVkXT1cInRydWVcIlxuICAgICAgICAgICAgW2xvYWRpbmddPVwic2VsZWN0aW5nRnJvbVJlZ2lvbnNcIlxuICAgICAgICAgICAgKG9uQ2xpY2spPVwic2VsZWN0RnJvbVJlZ2lvbnMoKVwiXG4gICAgICAgICAgICBbcFRvb2x0aXBdPVwiXG4gICAgICAgICAgICAgIHNlbGVjdHNDbGFzc1ZvbHVtZXNcbiAgICAgICAgICAgICAgICA/ICdTZWxlY3QgZXZlcnkgb2JzZXJ2YXRpb24gaW5zaWRlIHRoZSB2b2x1bWVzIG9mIHRoZSBjbGFzc2VzIHBpY2tlZCBpbiB0aGUgUmVnaW9uIEVkaXRvcidcbiAgICAgICAgICAgICAgICA6ICdTZWxlY3QgZXZlcnkgb2JzZXJ2YXRpb24gaW5zaWRlIHRoZSBkcmF3biByZWdpb25zJ1xuICAgICAgICAgICAgXCJcbiAgICAgICAgICAgIHRvb2x0aXBQb3NpdGlvbj1cInRvcFwiXG4gICAgICAgICAgPjwvcC1idXR0b24+XG4gICAgICAgICAgPHAtYnV0dG9uXG4gICAgICAgICAgICAqbmdJZj1cImhhc1NlbGVjdGlvblwiXG4gICAgICAgICAgICBsYWJlbD1cIkNsZWFyXCJcbiAgICAgICAgICAgIHNpemU9XCJzbWFsbFwiXG4gICAgICAgICAgICBbdGV4dF09XCJ0cnVlXCJcbiAgICAgICAgICAgIChvbkNsaWNrKT1cImNsZWFyU2VsZWN0aW9uKClcIlxuICAgICAgICAgID48L3AtYnV0dG9uPlxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPHNtYWxsIGNsYXNzPVwic2MtaGludFwiICpuZ0lmPVwiaGFzU2VsZWN0aW9uXCI+XG4gICAgICAgICAge3sgc2VsZWN0aW9uLmNvdW50IHwgbnVtYmVyIH19IG9mIHt7IGRzLm9ic2VydmF0aW9ucy5jb3VudCB8IG51bWJlciB9fSBzZWxlY3RlZCDigJQgdGhlIHJlc3QgYXJlIG11dGVkLlxuICAgICAgICA8L3NtYWxsPlxuICAgICAgICA8c21hbGwgY2xhc3M9XCJzYy1oaW50XCIgKm5nSWY9XCJzZWxlY3Rpb25NaXNzZWRcIj5cbiAgICAgICAgICBObyBvYnNlcnZhdGlvbnMgZmVsbCBpbnNpZGUgdGhlXG4gICAgICAgICAge3sgbWlzc2VkTW9kZSA9PT0gJ2NsYXNzLXZvbHVtZXMnID8gJ3BpY2tlZCBjbGFzc2VzJyA6ICdkcmF3biByZWdpb25zJyB9fS5cbiAgICAgICAgPC9zbWFsbD5cbiAgICAgICAgPHNtYWxsIGNsYXNzPVwic2MtaGludFwiICpuZ0lmPVwic2VsZWN0c0NsYXNzVm9sdW1lc1wiPlxuICAgICAgICAgIFNlbGVjdHMgaW5zaWRlIHRoZSB2b2x1bWUgb2Yge3sgcGlja2VkQ2xhc3Nlc1swXVxuICAgICAgICAgIH19e3sgcGlja2VkQ2xhc3Nlcy5sZW5ndGggPiAxID8gJyBhbmQgJyArIChwaWNrZWRDbGFzc2VzLmxlbmd0aCAtIDEgfCBudW1iZXIpICsgJyBtb3JlIGNsYXNzZXMnIDogJycgfX0sXG4gICAgICAgICAgcGlja2VkIGluIHRoZSBSZWdpb24gRWRpdG9yLiBEcmF3IGEgcmVnaW9uIHRvIHNlbGVjdCBieSBpdCBpbnN0ZWFkLlxuICAgICAgICA8L3NtYWxsPlxuICAgICAgICA8c21hbGwgY2xhc3M9XCJzYy1oaW50XCIgKm5nSWY9XCJpczNkICYmICFzZWxlY3RzQ2xhc3NWb2x1bWVzICYmIHBpY2tlZENsYXNzZXMubGVuZ3RoXCI+XG4gICAgICAgICAgVGhlIGNsYXNzZXMgcGlja2VkIGluIHRoZSBSZWdpb24gRWRpdG9yIGFyZSBub3Qgb24gdGhlIHJlZmVyZW5jZSB2b2x1bWUgc2hvd24gaGVyZSwgc28gdGhpcyBzZWxlY3RzIGJ5XG4gICAgICAgICAgdGhlIHJlZ2lvbnMgZHJhd24gb3ZlciB0aGUgY2xvdWQgaW5zdGVhZC5cbiAgICAgICAgPC9zbWFsbD5cbiAgICAgICAgPHNtYWxsIGNsYXNzPVwic2MtaGludFwiICpuZ0lmPVwiaXMzZCAmJiAhc2VsZWN0c0NsYXNzVm9sdW1lc1wiPlxuICAgICAgICAgIEluIDNEIGEgcmVnaW9uIGN1dHMgdGhyb3VnaCB0aGUgY2xvdWQncyBmdWxsIGRlcHRoLiBPcmJpdCBhbmQgZHJhdyBhZ2FpbiB0byBjdXQgZnJvbSBhbm90aGVyIGFuZ2xlLlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhcGlja2VkQ2xhc3Nlcy5sZW5ndGhcIj5cbiAgICAgICAgICAgIFBpY2sgY2xhc3NlcyBpbiB0aGUgUmVnaW9uIEVkaXRvcidzIGNsYXNzIHRyZWUgdG8gc2VsZWN0IGluc2lkZSB0aGVpciB2b2x1bWVzLlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L3NtYWxsPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIE9ic2VydmF0aW9ucywgdGhlbiB3aGF0IGVsc2UgZHJhd3MgdGhlbTogdGhlIGdlbmUgbWFwLCB0aGUgM0Qgc2NlbmUsIGFuZCB0aGVcbiAgICAgICAgIGNvbnRpbnVvdXMtb25seSBrbm9icy4gLS0+XG4gICAgPHNwYXRpYWwtb2JzZXJ2YXRpb25zLXBhbmVsXG4gICAgICBbY29udHJvbHNdPVwiY29udHJvbHNcIlxuICAgICAgW2RhdGFzZXRdPVwiZHNcIlxuICAgICAgW3ZpZXddPVwidmlld1wiXG4gICAgICBbZ2VuZXNdPVwiZ2VuZXNcIlxuICAgICAgW2xlZ2VuZF09XCJsZWdlbmRcIlxuICAgICAgW2NvbG9yQmFyQ3NzXT1cImNvbG9yQmFyQ3NzXCJcbiAgICAgIFtzZWxlY3Rpb25dPVwic2VsZWN0aW9uXCJcbiAgICAgIFtzZWxlY3RlZENhdGVnb3J5XT1cInNlbGVjdGVkQ2F0ZWdvcnlcIlxuICAgICAgW2NvbG9ybWFwT3B0aW9uc109XCJjb2xvcm1hcE9wdGlvbnNcIlxuICAgICAgW2lzM2RdPVwiaXMzZFwiXG4gICAgICBbb3Blbl09XCJvcGVuLm9ic2VydmF0aW9uc1wiXG4gICAgICAob3BlbkNoYW5nZSk9XCJzZXRPcGVuKCdvYnNlcnZhdGlvbnMnLCAkZXZlbnQpXCJcbiAgICAgIChjYXRlZ29yeUNsaWNrZWQpPVwic2VsZWN0Q2F0ZWdvcnkoJGV2ZW50KVwiXG4gICAgPjwvc3BhdGlhbC1vYnNlcnZhdGlvbnMtcGFuZWw+XG5cbiAgICA8IS0tIERpc3RyaWJ1dGlvbnMgb2Ygd2hhdGV2ZXIgdGhlIG1hcCBpcyBjb2xvdXJlZCBieS4gSW4gdGhlIFNBTUUgZGlhbG9nIGFzXG4gICAgICAgICB0aGUgY29sb3VyIGNvbnRyb2xzIG9uIHB1cnBvc2U6IGNoYW5naW5nIHRoZSBnZW5lIGFuZCB3YXRjaGluZyB0aGVcbiAgICAgICAgIGRpc3RyaWJ1dGlvbiBtb3ZlIGlzIG9uZSBhY3Rpb24sIGFuZCB0d28gZmxvYXRpbmcgd2luZG93cyBtYWRlIHRoYXRcbiAgICAgICAgIGhhcmRlciB0byBzZWUgcmF0aGVyIHRoYW4gZWFzaWVyLiAtLT5cbiAgICA8ZGl2IGNsYXNzPVwic2Mtc2VjdGlvbiBzYy1jaGFydHNcIj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIGNsYXNzPVwic2MtZGlzY2xvc3VyZVwiXG4gICAgICAgIChjbGljayk9XCJ0b2dnbGVDaGFydHMoKVwiXG4gICAgICAgIFthdHRyLmFyaWEtZXhwYW5kZWRdPVwiY2hhcnRzT3BlblwiXG4gICAgICAgIFthdHRyLmFyaWEtY29udHJvbHNdPVwiY2hhcnRzQm9keUlkXCJcbiAgICAgID5cbiAgICAgICAgPGkgY2xhc3M9XCJwaVwiIFtjbGFzcy5waS1jaGV2cm9uLXJpZ2h0XT1cIiFjaGFydHNPcGVuXCIgW2NsYXNzLnBpLWNoZXZyb24tZG93bl09XCJjaGFydHNPcGVuXCI+PC9pPlxuICAgICAgICA8c3Bhbj5EaXN0cmlidXRpb248L3NwYW4+XG4gICAgICAgIDxzbWFsbCAqbmdJZj1cIiFjaGFydHNPcGVuICYmIHZpZXcuY29sb3JCeVwiPm9mIHt7IGNvbG9yQnlMYWJlbCB9fTwvc21hbGw+XG4gICAgICA8L2J1dHRvbj5cbiAgICAgIDwhLS0gS2VwdCBNT1VOVEVEIHdoZW4gY29sbGFwc2VkLCBvbmx5IGhpZGRlbjogZGVzdHJveWluZyBpdCB3b3VsZCB0aHJvd1xuICAgICAgICAgICBhd2F5IHRoZSBjaGFydCBraW5kIGFuZCBncm91cGluZyB0aGUgdXNlciBwaWNrZWQuIGBhY3RpdmVgIGlzIHdoYXRcbiAgICAgICAgICAgc3RvcHMgaXQgZHJhd2luZyB3aGlsZSBpdCBoYXMgbm8gc2l6ZS4gLS0+XG4gICAgICA8ZGl2IFtpZF09XCJjaGFydHNCb2R5SWRcIiBbaGlkZGVuXT1cIiFjaGFydHNPcGVuXCI+XG4gICAgICAgIDxzcGF0aWFsLWNoYXJ0cyBbYWN0aXZlXT1cInZpc2libGUgJiYgY2hhcnRzT3BlblwiPjwvc3BhdGlhbC1jaGFydHM+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cblxuICAgIDxkaXYgY2xhc3M9XCJzYy1idG5zXCI+XG4gICAgICA8cC1idXR0b24gbGFiZWw9XCJSZXNldFwiIHNpemU9XCJzbWFsbFwiIFt0ZXh0XT1cInRydWVcIiAob25DbGljayk9XCJyZXNldCgpXCI+PC9wLWJ1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L3AtZGlhbG9nPlxuIl19
402
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BhdGlhbC1jb250cm9scy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3NwYXRpYWwtY29udHJvbHMvc3BhdGlhbC1jb250cm9scy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9zcmMvbGliL3NwYXRpYWwtY29udHJvbHMvc3BhdGlhbC1jb250cm9scy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixNQUFNLEVBQ04sS0FBSyxFQUNMLE1BQU0sRUFFTixNQUFNLEVBQ04sU0FBUyxFQUNULE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXJDLE9BQU8sRUFBRSxVQUFVLEVBQW1ELE1BQU0sa0NBQWtDLENBQUM7QUFDL0csT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sMkNBQTJDLENBQUM7QUFFbkYsT0FBTyxFQUFrQyxvQkFBb0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ2xHLE9BQU8sRUFBZSxlQUFlLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUM5RSxPQUFPLEVBQXdCLGNBQWMsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ3BGLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsZUFBZSxFQUFzQixNQUFNLGlDQUFpQyxDQUFDO0FBQ3RGLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUNuRSxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxxREFBcUQsQ0FBQztBQUNqRyxPQUFPLEVBQUUsZ0NBQWdDLEVBQUUsTUFBTSxpRUFBaUUsQ0FBQztBQUNuSCxPQUFPLEVBQUUsaUNBQWlDLEVBQUUsTUFBTSxtRUFBbUUsQ0FBQzs7Ozs7Ozs7QUFLdEgsdUZBQXVGO0FBQ3ZGLE9BQU8sRUFBRSxlQUFlLEVBQUUsQ0FBQztBQUUzQixrRkFBa0Y7QUFDbEYsSUFBSSxtQkFBbUIsR0FBRyxDQUFDLENBQUM7QUFFNUI7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnQkc7QUFvQkgsTUFBTSxPQUFPLHdCQUF3QjtJQUluQzs7Ozs7Ozs7T0FRRztJQUNPLFdBQVc7UUFDbkIsSUFBSSxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsQ0FBQztJQUN4QixDQUFDO0lBOEJELG1DQUFtQztJQUNuQyxJQUFJLFdBQVc7UUFDYixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDO0lBQzVCLENBQUM7SUFDRCwwRkFBMEY7SUFDMUYsSUFBSSxjQUFjO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUM7SUFDM0IsQ0FBQztJQUNELElBQUksZ0JBQWdCO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUM7SUFDM0IsQ0FBQztJQU1ELHdFQUF3RTtJQUN4RSxJQUFjLE1BQU07UUFDbEIsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQztJQUN6QixDQUFDO0lBQ0QseUVBQXlFO0lBQ3pFLElBQWMsV0FBVztRQUN2QixPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDO0lBQzlCLENBQUM7SUFtQ0QsWUFDdUMsR0FBZ0IsRUFDcEMsSUFBWTtRQURRLFFBQUcsR0FBSCxHQUFHLENBQWE7UUFDcEMsU0FBSSxHQUFKLElBQUksQ0FBUTtRQXhGL0Isd0VBQXdFO1FBQy9ELFlBQU8sR0FBRyxLQUFLLENBQUM7UUFDekI7O2lGQUV5RTtRQUNoRSxTQUFJLEdBQUcsS0FBSyxDQUFDO1FBQ3RCLHFFQUFxRTtRQUMzRCxrQkFBYSxHQUFHLElBQUksWUFBWSxFQUFXLENBQUM7UUFFdEQsdURBQXVEO1FBQzdDLGFBQVEsR0FBNEIsSUFBSSxDQUFDO1FBQ3pDLFlBQU8sR0FBMEIsSUFBSSxDQUFDO1FBQ3RDLFNBQUksR0FBcUIsRUFBRSxHQUFHLG9CQUFvQixFQUFFLENBQUM7UUFFL0Q7Ozs7V0FJRztRQUNnQixVQUFLLEdBQUcsSUFBSSxlQUFlLENBQzVDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQ25CLEdBQUcsRUFBRSxDQUFDO1lBQ0osR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsZUFBZSxJQUFJLEVBQUUsQ0FBQztZQUNyQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxnQkFBZ0IsSUFBSSxFQUFFLENBQUM7WUFDdEMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLElBQUksS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztTQUM1RSxFQUNELENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUM1QixDQUFDO1FBYUY7O3FFQUU2RDtRQUNwRCxRQUFHLEdBQUcsSUFBSSxlQUFlLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztRQVVoRSw2RUFBNkU7UUFDbkUsY0FBUyxHQUF5QixjQUFjLEVBQUUsQ0FBQztRQUM3RCw2RUFBNkU7UUFDbkUscUJBQWdCLEdBQWtCLElBQUksQ0FBQztRQUNqRDttREFDMkM7UUFDakMsb0JBQWUsR0FBRyxLQUFLLENBQUM7UUFDbEMsNEZBQTRGO1FBQ2xGLGVBQVUsR0FBcUIsU0FBUyxDQUFDO1FBQ25ELHFHQUFxRztRQUMzRixrQkFBYSxHQUFzQixFQUFFLENBQUM7UUFDaEQsbUVBQW1FO1FBQ3pELHlCQUFvQixHQUFHLEtBQUssQ0FBQztRQUV2Qzs7OztXQUlHO1FBQ08sZUFBVSxHQUFHLEtBQUssQ0FBQztRQUM3QjswRkFDa0Y7UUFDL0QsaUJBQVksR0FBRyxrQkFBa0IsRUFBRSxtQkFBbUIsRUFBRSxDQUFDO1FBRTVFO3NDQUM4QjtRQUNwQixvQkFBZSxHQUFtQixFQUFFLENBQUM7UUFFdkMsYUFBUSxHQUF3QixJQUFJLENBQUM7UUFDckMsWUFBTyxHQUFHLEtBQUssQ0FBQztRQUNQLGVBQVUsR0FBRyxNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDaEMsUUFBRyxHQUFHLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1FBK05qRCwrRUFBK0U7UUFDckUsU0FBSSxHQUF5RjtZQUNyRyxNQUFNLEVBQUUsS0FBSztZQUNiLEtBQUssRUFBRSxJQUFJO1lBQ1gsV0FBVyxFQUFFLEtBQUs7WUFDbEIsV0FBVyxFQUFFLEtBQUs7WUFDbEIsWUFBWSxFQUFFLEtBQUs7U0FDcEIsQ0FBQztRQVdGLHlFQUF5RTtRQUV6RSxpRkFBaUY7UUFDdkUsYUFBUSxHQUEyQyxJQUFJLENBQUM7UUFDbEUsZ0ZBQWdGO1FBQ3RFLGlCQUFZLEdBQW1ELElBQUksQ0FBQztRQUM5RSxnRkFBZ0Y7UUFDdEUsZUFBVSxHQUFrQyxJQUFJLENBQUM7SUFuUHhELENBQUM7SUFFSixRQUFRO1FBQ04sSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLGtCQUFrQixFQUFFLEVBQUUsSUFBSSxJQUFJLENBQUM7UUFDeEQsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLGtCQUFrQixFQUFFLEVBQUUsSUFBSSxFQUFFLENBQUM7UUFDN0QsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRO1lBQUUsT0FBTztRQUUzQixNQUFNLGNBQWMsR0FBRyxHQUFNLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBSSxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDdkUsSUFBSSxDQUFDLFFBQVE7YUFDVixXQUFXLEVBQUU7YUFDYixJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7YUFDdEIsU0FBUyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUU7WUFDckIsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7WUFDdkIsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDL0Isa0VBQWtFO1lBQ2xFLElBQUksQ0FBQyxJQUFJLEdBQUc7Z0JBQ1YsR0FBRyxJQUFJLENBQUMsSUFBSTtnQkFDWixLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLFlBQVksSUFBSSxPQUFPLEVBQUUsUUFBUSxDQUFDO2dCQUNyRCxZQUFZLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxZQUFZLElBQUksT0FBTyxFQUFFLFFBQVEsQ0FBQzthQUM1RCxDQUFDO1lBQ0YsS0FBSyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDdkIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUMxQixDQUFDLENBQUMsQ0FBQztRQUVMLElBQUksQ0FBQyxRQUFRO2FBQ1YsYUFBYSxFQUFFO2FBQ2YsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO2FBQ3RCLFNBQVMsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1lBQ2xCLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO1lBQ2pCLEtBQUssSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDMUIsQ0FBQyxDQUFDLENBQUM7UUFFTCxtRkFBbUY7UUFDbkYseUJBQXlCO1FBQ3pCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsc0JBQXNCLEVBQUUsRUFBRSxDQUFDO1FBQzNELFNBQVMsRUFBRSxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUNoRCxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUNuQixJQUFJLENBQUMsUUFBUSxHQUFHLENBQUMsQ0FBQztRQUNwQixDQUFDLENBQUMsQ0FDSCxDQUFDO1FBQ0YsTUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxvQkFBb0IsRUFBRSxFQUFFLENBQUM7UUFDdkQsT0FBTyxFQUFFLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQzlDLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ25CLElBQUksQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDO1FBQ3RCLENBQUMsQ0FBQyxDQUNILENBQUM7UUFDRixNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGdCQUFnQixFQUFFLEVBQUUsQ0FBQztRQUNwRCxRQUFRLEVBQUUsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FDL0MsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDbkIsSUFBSSxDQUFDLFlBQVksR0FBRyxDQUFDLENBQUM7UUFDeEIsQ0FBQyxDQUFDLENBQ0gsQ0FBQztRQUVGLElBQUksQ0FBQyxRQUFRO2FBQ1YsYUFBYSxFQUFFO2FBQ2YsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO2FBQ3RCLFNBQVMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxFQUFFO1FBQ3ZCLCtFQUErRTtRQUMvRSxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUNuQixJQUFJLENBQUMsU0FBUyxHQUFHLFNBQVMsQ0FBQztZQUMzQixJQUFJLFNBQVMsQ0FBQyxLQUFLLEtBQUssQ0FBQztnQkFBRSxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO1FBQzFELENBQUMsQ0FBQyxDQUNILENBQUM7UUFFSixJQUFJLENBQUMsUUFBUTthQUNWLHVCQUF1QixFQUFFLEVBQUU7WUFDNUIsRUFBRSxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7YUFDdkIsU0FBUyxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FDckIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDbkIsSUFBSSxDQUFDLGFBQWEsR0FBRyxPQUFPLENBQUM7UUFDL0IsQ0FBQyxDQUFDLENBQ0gsQ0FBQztRQUVKLDhEQUE4RDtRQUM5RCxhQUFhLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsRUFBRSxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsZUFBZSxFQUFFLENBQUMsQ0FBQzthQUNoRSxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7YUFDdEIsU0FBUyxDQUFDLENBQUMsQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLEVBQUUsRUFBRTtZQUNqQyxJQUFJLENBQUMsUUFBUSxHQUFJLFFBQXlCLElBQUksSUFBSSxDQUFDO1lBQ25ELElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQztZQUN6QixLQUFLLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUN6QixDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRCw4RUFBOEU7SUFDdEUsVUFBVSxDQUFDLEVBQWM7UUFDL0IsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFO1lBQ2pCLEVBQUUsRUFBRSxDQUFDO1lBQ0wsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUMxQixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFUyxlQUFlLENBQUMsS0FBYztRQUN0QyxJQUFJLENBQUMsT0FBTyxHQUFHLEtBQUssQ0FBQztRQUNyQixJQUFJLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNqQyxDQUFDO0lBRUQsMkVBQTJFO0lBRTNFLDBGQUEwRjtJQUMxRixZQUFZLENBQUMsS0FBYTtRQUN4QixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFRCx1RUFBdUU7SUFDdkUsY0FBYztRQUNaLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUNqQyxDQUFDO0lBRUQsMkVBQTJFO0lBRTNFO21DQUMrQjtJQUNyQixLQUFLLENBQUMsaUJBQWlCO1FBQy9CLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxvQkFBb0I7WUFBRSxPQUFPO1FBQ3hELElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLENBQUM7UUFDakMseUZBQXlGO1FBQ3pGLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQztRQUNuQyxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3hCLElBQUksS0FBSyxHQUFrQixDQUFDLENBQUM7UUFDN0IsSUFBSSxDQUFDO1lBQ0gsS0FBSyxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQ2xELENBQUM7UUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1lBQ2IsT0FBTyxDQUFDLElBQUksQ0FBQyw2Q0FBNkMsRUFBRSxHQUFHLENBQUMsQ0FBQztRQUNuRSxDQUFDO1FBQ0QsbUZBQW1GO1FBQ25GLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ25CLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxLQUFLLENBQUM7WUFDbEMsMkVBQTJFO1lBQzNFLElBQUksS0FBSyxLQUFLLElBQUk7Z0JBQUUsT0FBTztZQUMzQixJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO1lBQzdCLElBQUksQ0FBQyxlQUFlLEdBQUcsS0FBSyxLQUFLLENBQUMsQ0FBQztZQUNuQyxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQztRQUN6QixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxrRkFBa0Y7SUFDbEYsSUFBYyxtQkFBbUI7UUFDL0IsT0FBTyxJQUFJLENBQUMsZ0JBQWdCLEtBQUssZUFBZSxDQUFDO0lBQ25ELENBQUM7SUFFRCxpR0FBaUc7SUFDakcsSUFBWSxnQkFBZ0I7UUFDMUIsT0FBTyxJQUFJLENBQUMsUUFBUSxFQUFFLGdCQUFnQixFQUFFLEVBQUUsSUFBSSxTQUFTLENBQUM7SUFDMUQsQ0FBQztJQUVEO3VEQUNtRDtJQUN6QyxLQUFLLENBQUMsY0FBYyxDQUFDLEtBQWE7UUFDMUMsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7UUFDN0IsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLElBQUksRUFBRSxFQUFFLElBQUksS0FBSyxRQUFRO1lBQUUsT0FBTztRQUNwRCxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsS0FBSyxLQUFLLEVBQUUsQ0FBQztZQUNwQyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDdEIsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLENBQUM7WUFDSCxNQUFNLElBQUksQ0FBQyxRQUFRLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQyxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDbkQsSUFBSSxDQUFDLGdCQUFnQixHQUFHLEtBQUssQ0FBQztZQUM5QixJQUFJLENBQUMsZUFBZSxHQUFHLEtBQUssQ0FBQztRQUMvQixDQUFDO1FBQUMsTUFBTSxDQUFDO1lBQ1AsSUFBSSxDQUFDLGdCQUFnQixHQUFHLElBQUksQ0FBQztRQUMvQixDQUFDO1FBQ0QsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUMxQixDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDTyxZQUFZO1FBQ3BCLElBQUksQ0FBQyxVQUFVLEdBQUcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDO1FBQ25DLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVTtZQUFFLE9BQU87UUFDN0IsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUNkLFFBQVEsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxFQUFFLGNBQWMsQ0FBQyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxDQUFDLENBQUM7UUFDbkcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ1IsQ0FBQztJQUVTLGNBQWM7UUFDdEIsSUFBSSxDQUFDLFFBQVEsRUFBRSxjQUFjLEVBQUUsQ0FBQztRQUNoQyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO1FBQzdCLElBQUksQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDO0lBQy9CLENBQUM7SUFFRCx3RUFBd0U7SUFDeEUsSUFBYyxZQUFZO1FBQ3hCLE9BQU8sSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDO0lBQ2xDLENBQUM7SUFFRCwyRUFBMkU7SUFFM0UsMkVBQTJFO0lBQzNFLElBQWMsUUFBUTtRQUNwQixPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsWUFBWSxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDbEUsQ0FBQztJQUVELDZEQUE2RDtJQUM3RCxJQUFjLGNBQWM7UUFDMUIsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxlQUFlLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDO0lBQ3BFLENBQUM7SUFFRCwrRkFBK0Y7SUFDL0YsSUFBYyxnQkFBZ0I7UUFDNUIsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxlQUFlLEVBQUUsSUFBSSxDQUFDO0lBQy9DLENBQUM7SUFFUyxXQUFXLENBQUMsRUFBVztRQUMvQixJQUFJLENBQUMsUUFBUSxFQUFFLFlBQVksQ0FBQyxFQUFFLFNBQVMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ2pELENBQUM7SUFFUyxpQkFBaUIsQ0FBQyxFQUFXO1FBQ3JDLElBQUksQ0FBQyxRQUFRLEVBQUUsWUFBWSxDQUFDLEVBQUUsZUFBZSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDdkQsQ0FBQztJQVdTLGFBQWEsQ0FBQyxJQUE0QztRQUNsRSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRUQscUVBQXFFO0lBQzNELE9BQU8sQ0FBQyxJQUE0QyxFQUFFLEVBQVc7UUFDekUsSUFBSSxDQUFDLElBQUksR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDO0lBQzNDLENBQUM7SUFXUyxLQUFLO1FBQ2IsSUFBSSxDQUFDLFFBQVEsRUFBRSxZQUFZLENBQUMsRUFBRSxHQUFHLG9CQUFvQixFQUFFLENBQUMsQ0FBQztRQUN6RCxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7SUFDeEIsQ0FBQztJQUVELHFFQUFxRTtJQUNyRSxJQUFjLFlBQVk7UUFDeEIsT0FBTyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFFRCwrRUFBK0U7SUFDL0UsSUFBSSxhQUFhO1FBQ2YsT0FBTyxJQUFJLENBQUMsTUFBTSxLQUFLLElBQUksQ0FBQztJQUM5QixDQUFDO0lBRUQsK0RBQStEO0lBQy9ELElBQUksWUFBWTtRQUNkLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDO0lBQ3JELENBQUM7SUFFRCwyRUFBMkU7SUFFM0Usa0VBQWtFO0lBQzFELFVBQVU7UUFDaEIsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUMvRixDQUFDOzhHQXhYVSx3QkFBd0Isa0JBd0d6QixVQUFVO2tHQXhHVCx3QkFBd0IsK01BRXhCLHNCQUFzQixnRENuRm5DLDZtUEF5TEEsbTNMRHZISSxZQUFZLDBMQUNaLFdBQVcsOFZBQ1gsWUFBWSw2WEFDWixjQUFjLGdaQUNkLFlBQVksdXVCQUNaLGFBQWEsc1hBQ2IsMEJBQTBCLGtLQUMxQixnQ0FBZ0Msc05BQ2hDLGlDQUFpQyxrUUFDakMsc0JBQXNCOzsyRkFNYix3QkFBd0I7a0JBbkJwQyxTQUFTOytCQUNFLGtCQUFrQixjQUNoQixJQUFJLFdBQ1A7d0JBQ1AsWUFBWTt3QkFDWixXQUFXO3dCQUNYLFlBQVk7d0JBQ1osY0FBYzt3QkFDZCxZQUFZO3dCQUNaLGFBQWE7d0JBQ2IsMEJBQTBCO3dCQUMxQixnQ0FBZ0M7d0JBQ2hDLGlDQUFpQzt3QkFDakMsc0JBQXNCO3FCQUN2QixtQkFHZ0IsdUJBQXVCLENBQUMsTUFBTTs7MEJBMEc1QyxNQUFNOzJCQUFDLFVBQVU7OERBdEd1QixNQUFNO3NCQUFoRCxTQUFTO3VCQUFDLHNCQUFzQjtnQkFnQnhCLE9BQU87c0JBQWYsS0FBSztnQkFJRyxJQUFJO3NCQUFaLEtBQUs7Z0JBRUksYUFBYTtzQkFBdEIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBEZXN0cm95UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEluamVjdCxcbiAgSW5wdXQsXG4gIE5nWm9uZSxcbiAgT25Jbml0LFxuICBPdXRwdXQsXG4gIFZpZXdDaGlsZCxcbiAgaW5qZWN0LFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IHRha2VVbnRpbERlc3Ryb3llZCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBGb3Jtc01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IEJ1dHRvbk1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvYnV0dG9uJztcbmltcG9ydCB7IENoZWNrYm94TW9kdWxlIH0gZnJvbSAncHJpbWVuZy9jaGVja2JveCc7XG5pbXBvcnQgeyBEaWFsb2dNb2R1bGUgfSBmcm9tICdwcmltZW5nL2RpYWxvZyc7XG5pbXBvcnQgeyBUb29sdGlwTW9kdWxlIH0gZnJvbSAncHJpbWVuZy90b29sdGlwJztcbmltcG9ydCB7IGNvbWJpbmVMYXRlc3QgfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgVklTVUFMSVpFUiwgSVZpc3VhbGl6ZXIsIElTcGF0aWFsQ29udHJvbHMsIFJvaVNlbGVjdGlvbk1vZGUgfSBmcm9tICcuLi9jb250cmFjdHMvdmlzdWFsaXplci5jb250cmFjdCc7XG5pbXBvcnQgeyBTcGF0aWFsQ2hhcnRzQ29tcG9uZW50IH0gZnJvbSAnLi9zcGF0aWFsLWNoYXJ0cy9zcGF0aWFsLWNoYXJ0cy5jb21wb25lbnQnO1xuaW1wb3J0IHsgU3BhdGlhbERhdGFzZXQgfSBmcm9tICcuLi9jb250cmFjdHMvc3BhdGlhbC1kYXRhc2V0LmNvbnRyYWN0JztcbmltcG9ydCB7IENvbG9ybWFwTm9kZSwgU3BhdGlhbFZpZXdTdGF0ZSwgREVGQVVMVF9TUEFUSUFMX1ZJRVcgfSBmcm9tICcuLi9jb250cmFjdHMvZGlzcGxheS10eXBlcyc7XG5pbXBvcnQgeyBQYW5lbE9wdGlvbiwgcGFyc2VHZW5lR3JvdXBzIH0gZnJvbSAnLi4vc3BhdGlhbC9zcGF0aWFsLXBhbmVsLW1vZGVsJztcbmltcG9ydCB7IFNwYXRpYWxTZWxlY3Rpb25NYXNrLCBlbXB0eVNlbGVjdGlvbiB9IGZyb20gJy4uL3NwYXRpYWwvc3BhdGlhbC1zZWxlY3Rpb24nO1xuaW1wb3J0IHsgR2VuZVBpY2tlck1vZGVsIH0gZnJvbSAnLi9zcGF0aWFsLWdlbmUtcGlja2VyJztcbmltcG9ydCB7IFNwYXRpYWxLZXlNb2RlbCwgU3BhdGlhbExlZ2VuZEVudHJ5IH0gZnJvbSAnLi9zcGF0aWFsLWtleS9zcGF0aWFsLWtleS5tb2RlbCc7XG5pbXBvcnQgeyBjb2xvckJ5TGFiZWwgfSBmcm9tICcuL3NwYXRpYWwta2V5L3NwYXRpYWwta2V5LmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTcGF0aWFsQ2VsbHNQYW5lbENvbXBvbmVudCB9IGZyb20gJy4vc3BhdGlhbC1jZWxscy1wYW5lbC9zcGF0aWFsLWNlbGxzLXBhbmVsLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTcGF0aWFsVHJhbnNjcmlwdHNQYW5lbENvbXBvbmVudCB9IGZyb20gJy4vc3BhdGlhbC10cmFuc2NyaXB0cy1wYW5lbC9zcGF0aWFsLXRyYW5zY3JpcHRzLXBhbmVsLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTcGF0aWFsT2JzZXJ2YXRpb25zUGFuZWxDb21wb25lbnQgfSBmcm9tICcuL3NwYXRpYWwtb2JzZXJ2YXRpb25zLXBhbmVsL3NwYXRpYWwtb2JzZXJ2YXRpb25zLXBhbmVsLmNvbXBvbmVudCc7XG5cbi8qKiBAZGVwcmVjYXRlZCBNb3ZlZCB0byBgc3BhdGlhbC1rZXkvc3BhdGlhbC1rZXkubW9kZWxgOyByZS1leHBvcnRlZCBmb3Igb25lIHJlbGVhc2UuICovXG5leHBvcnQgdHlwZSB7IFNwYXRpYWxMZWdlbmRFbnRyeSB9O1xuXG4vKiogQGRlcHJlY2F0ZWQgTW92ZWQgdG8gYHNwYXRpYWwvc3BhdGlhbC1wYW5lbC1tb2RlbGA7IHJlLWV4cG9ydGVkIGZvciBvbmUgcmVsZWFzZS4gKi9cbmV4cG9ydCB7IHBhcnNlR2VuZUdyb3VwcyB9O1xuXG4vKiogUGVyLWluc3RhbmNlIGlkIHNvdXJjZSDigJQgc2VlIHtAbGluayBTcGF0aWFsQ29udHJvbHNDb21wb25lbnQuY2hhcnRzQm9keUlkfS4gKi9cbmxldCBjb250cm9sc0luc3RhbmNlU2VxID0gMDtcblxuLyoqXG4gKiBTcGF0aWFsLW9taWNzIGNvbnRyb2xzOiBhIG5vbi1tb2RhbCwgcmVzaXphYmxlLCBkcmFnZ2FibGUgZGlhbG9nIGZvciBjaG9vc2luZ1xuICogd2hhdCB0aGUgb2JzZXJ2YXRpb24gbWFya2VycyBhcmUgY29sb3VyZWQgYnksIGFuZCBob3cgdGhleSBhcmUgZHJhd24uXG4gKlxuICogRGVwZW5kcyBvbmx5IG9uIHtAbGluayBJU3BhdGlhbENvbnRyb2xzfSwgcmVhY2hlZCB0aHJvdWdoIHRoZSBgVklTVUFMSVpFUmBcbiAqIGNvbnRyYWN0IHRva2VuIOKAlCBuZXZlciBhIGNvbmNyZXRlIGJhY2tlbmQg4oCUIG1pcnJvcmluZyBob3dcbiAqIGBDaGFubmVsSGlzdG9ncmFtQ29tcG9uZW50YCBkZXBlbmRzIG9ubHkgb24gYENIQU5ORUxfSElTVE9HUkFNX0FQSWAuIFdoZW4gbm9cbiAqIGhvc3QgaGFzIGJvdW5kIGBTUEFUSUFMX0RBVEFfUE9SVGAsIGBnZXRTcGF0aWFsQ29udHJvbHMoKWAgcmV0dXJucyBudWxsIGFuZFxuICogdGhlIGRpYWxvZyByZW5kZXJzIGFuIGV4cGxhbmF0b3J5IGVtcHR5IHN0YXRlIHJhdGhlciB0aGFuIGRlYWQgY29udHJvbHMuXG4gKlxuICogVGhlIGxlZ2VuZCBzd2F0Y2hlcyBhbmQgdGhlIGNvbnRpbnVvdXMgY29sb3VyIGJhciBhcmUgYnVpbHQgd2l0aCB0aGUgU0FNRVxuICogZnVuY3Rpb25zIHRoZSByZW5kZXJlciB1c2VzIChgY2F0ZWdvcnlDb2xvcnNgIOKGkiBgcmVzb2x2ZUNhdGVnb3J5Q29sb3JzYCxcbiAqIGBzcGF0aWFsQ29udGludW91c0x1dGApLCBzbyB0aGUga2V5IGNhbm5vdCBkcmlmdCBmcm9tIHdoYXQgaXMgb24gc2NyZWVuLlxuICpcbiAqIE9uUHVzaDogdGhlIGNvbnRyb2xzJyBzdHJlYW1zLCB0aGUga2V5IGFuZCBnZW5lLWxpc3QgbW9kZWxzICh3aGljaCByZS1lbnRlciB0aGUgem9uZVxuICogd2hlbiB0aGVpciBhc3luYyB3b3JrIGxhbmRzKSBhbmQgYW4gYXdhaXRlZCBjYXRlZ29yeSBzZWxlY3Rpb24gbWFyayBpdCBmb3IgY2hlY2suXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3NwYXRpYWwtY29udHJvbHMnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbXG4gICAgQ29tbW9uTW9kdWxlLFxuICAgIEZvcm1zTW9kdWxlLFxuICAgIEJ1dHRvbk1vZHVsZSxcbiAgICBDaGVja2JveE1vZHVsZSxcbiAgICBEaWFsb2dNb2R1bGUsXG4gICAgVG9vbHRpcE1vZHVsZSxcbiAgICBTcGF0aWFsQ2VsbHNQYW5lbENvbXBvbmVudCxcbiAgICBTcGF0aWFsVHJhbnNjcmlwdHNQYW5lbENvbXBvbmVudCxcbiAgICBTcGF0aWFsT2JzZXJ2YXRpb25zUGFuZWxDb21wb25lbnQsXG4gICAgU3BhdGlhbENoYXJ0c0NvbXBvbmVudCxcbiAgXSxcbiAgdGVtcGxhdGVVcmw6ICcuL3NwYXRpYWwtY29udHJvbHMuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9zcGF0aWFsLWNvbnRyb2xzLmNvbXBvbmVudC5zY3NzJ10sXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBTcGF0aWFsQ29udHJvbHNDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICAvKiogVGhlIGVtYmVkZGVkIGNoYXJ0LCBzbyBhIGRpYWxvZyByZXNpemUgY2FuIHJlLWZpdCBpdC4gKi9cbiAgQFZpZXdDaGlsZChTcGF0aWFsQ2hhcnRzQ29tcG9uZW50KSBwcml2YXRlIGNoYXJ0cz86IFNwYXRpYWxDaGFydHNDb21wb25lbnQ7XG5cbiAgLyoqXG4gICAqIFJlLWZpdCB0aGUgY2hhcnQgYWZ0ZXIgdGhlIGRpYWxvZyBpcyByZXNpemVkLlxuICAgKlxuICAgKiBQbG90bHkgZG9lcyBub3QgZm9sbG93IGEgY29udGFpbmVyIHJlc2l6ZSBvbiBpdHMgb3duIOKAlCBpdHMgYHJlc3BvbnNpdmVgXG4gICAqIG9wdGlvbiBsaXN0ZW5zIGZvciBXSU5ET1cgcmVzaXplcyBvbmx5LCBzbyBkcmFnZ2luZyB0aGUgZGlhbG9nJ3MgaGFuZGxlXG4gICAqIHJlYWNoZXMgaXQgdGhyb3VnaCBub3RoaW5nLiBQcmltZU5HIHRlbGxzIHVzIHdoZW4gdGhlIGRyYWcgZW5kcywgd2hpY2ggaXMgYVxuICAgKiBmYXIgbW9yZSBkaXJlY3Qgc2lnbmFsIHRoYW4gd2F0Y2hpbmcgYm94ZXMsIGFuZCBmaXJpbmcgb25jZSBvbiByZWxlYXNlIG1lYW5zXG4gICAqIG5vIHJlbGF5b3V0IGNodXJuIGR1cmluZyB0aGUgZHJhZy5cbiAgICovXG4gIHByb3RlY3RlZCBvblJlc2l6ZUVuZCgpOiB2b2lkIHtcbiAgICB0aGlzLmNoYXJ0cz8ucmVzaXplKCk7XG4gIH1cblxuICAvKiogRGlhbG9nIHZpc2liaWxpdHksIHR3by13YXkgYm91bmQgc28gYSB0b29sYmFyIGJ1dHRvbiBjYW4gb3BlbiBpdC4gKi9cbiAgQElucHV0KCkgdmlzaWJsZSA9IGZhbHNlO1xuICAvKiogU2V0IHdoaWxlIHRoZSAzRCBjbG91ZCBpcyB0aGUgYWN0aXZlIG1vZGUuIENoYW5nZXMgd2hhdCB0aGUgUk9JIHNlbGVjdGlvblxuICAgKiAgTUVBTlMg4oCUIGEgc2NyZWVuLXNwYWNlIGxhc3NvIGN1dHRpbmcgdGhyb3VnaCB0aGUgY2xvdWQncyBmdWxsIGRlcHRoIHJhdGhlclxuICAgKiAgdGhhbiBhIHNoYXBlIGluIHRpc3N1ZSBjb29yZGluYXRlcyDigJQgc28gdGhlIGhpbnQgYmVsb3cgaXQgc2F5cyBzby4gKi9cbiAgQElucHV0KCkgaXMzZCA9IGZhbHNlO1xuICAvKiogVGhlIGRpYWxvZyB3YXMgb3BlbmVkIG9yIGNsb3NlZDsgdHdvLXdheSB3aXRoIHtAbGluayB2aXNpYmxlfS4gKi9cbiAgQE91dHB1dCgpIHZpc2libGVDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPGJvb2xlYW4+KCk7XG5cbiAgLyoqIE51bGwgd2hlbiB0aGUgaG9zdCBib3VuZCBubyBgU1BBVElBTF9EQVRBX1BPUlRgLiAqL1xuICBwcm90ZWN0ZWQgY29udHJvbHM6IElTcGF0aWFsQ29udHJvbHMgfCBudWxsID0gbnVsbDtcbiAgcHJvdGVjdGVkIGRhdGFzZXQ6IFNwYXRpYWxEYXRhc2V0IHwgbnVsbCA9IG51bGw7XG4gIHByb3RlY3RlZCB2aWV3OiBTcGF0aWFsVmlld1N0YXRlID0geyAuLi5ERUZBVUxUX1NQQVRJQUxfVklFVyB9O1xuXG4gIC8qKlxuICAgKiBHZW5lIHBpY2tlcjogYSBmaWx0ZXJhYmxlIGRyb3Bkb3duIHJhdGhlciB0aGFuIGEgZnJlZS10ZXh0IHR5cGVhaGVhZCwgc28gdGhlXG4gICAqIG9wdGlvbnMgYXJlIHZpc2libGUgYmVmb3JlIGFueXRoaW5nIGlzIHR5cGVkIGFuZCBlYWNoIGtleXN0cm9rZSBuYXJyb3dzIGEgbGlzdFxuICAgKiB0aGUgdXNlciBjYW4gc2VlLiBPbmUgbW9kZWwgZmVlZHMgZXZlcnkgZ2VuZSBkcm9wZG93biBvZiB0aGUgcGFuZWwuXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZ2VuZXMgPSBuZXcgR2VuZVBpY2tlck1vZGVsKFxuICAgICgpID0+IHRoaXMuY29udHJvbHMsXG4gICAgKCkgPT4gW1xuICAgICAgLi4uKHRoaXMudmlldz8udHJhbnNjcmlwdEdlbmVzID8/IFtdKSxcbiAgICAgIC4uLih0aGlzLnZpZXc/Lm9ic2VydmF0aW9uR2VuZXMgPz8gW10pLFxuICAgICAgLi4uKHRoaXMudmlldz8uY29sb3JCeT8ua2luZCA9PT0gJ2ZlYXR1cmUnID8gW3RoaXMudmlldy5jb2xvckJ5Lm5hbWVdIDogW10pLFxuICAgIF0sXG4gICAgKGZuKSA9PiB0aGlzLnJ1bkFuZE1hcmsoZm4pLFxuICApO1xuICAvKiogVGhlIGdlbmUgZHJvcGRvd25zJyBvcHRpb25zLiAqL1xuICBnZXQgZ2VuZU9wdGlvbnMoKTogUGFuZWxPcHRpb248c3RyaW5nPltdIHtcbiAgICByZXR1cm4gdGhpcy5nZW5lcy5vcHRpb25zO1xuICB9XG4gIC8qKiBUcnVlIHdoZW4gdGhlIG9wdGlvbnMgY29tZSBmcm9tIHRoZSBwb3J0IHBlciBrZXlzdHJva2UgcmF0aGVyIHRoYW4gYSByZXNpZGVudCBsaXN0LiAqL1xuICBnZXQgZ2VuZXNBcmVSZW1vdGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZ2VuZXMucmVtb3RlO1xuICB9XG4gIGdldCBnZW5lU2VhcmNoRmFpbGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmdlbmVzLmZhaWxlZDtcbiAgfVxuXG4gIC8qKiBUaGUga2V5IOKAlCBsZWdlbmQgb3IgY29sb3VyIGJhciDigJQgZm9yIHRoZSBhY3RpdmUgY29sb3VyaW5nLiBLZXB0IGhlcmUsIG5vdCBpblxuICAgKiAgYDxzcGF0aWFsLWtleT5gOiB3aGV0aGVyIHRoZSBjb2xvdXJpbmcgaXMgY2F0ZWdvcmljYWwgZGVjaWRlcyB3aGljaCBrbm9icyB0aGUgcmVzdCBvZlxuICAgKiAgdGhlIHBhbmVsIG9mZmVycywgd2hldGhlciBvciBub3QgdGhlIGtleSBpcyBvbiBzY3JlZW4uICovXG4gIHJlYWRvbmx5IGtleSA9IG5ldyBTcGF0aWFsS2V5TW9kZWwoKGZuKSA9PiB0aGlzLnJ1bkFuZE1hcmsoZm4pKTtcbiAgLyoqIENhdGVnb3JpY2FsIGtleSwgb3IgbnVsbCB3aGVuIHRoZSBhY3RpdmUgY29sb3VyaW5nIGlzIGNvbnRpbnVvdXMuICovXG4gIHByb3RlY3RlZCBnZXQgbGVnZW5kKCk6IFNwYXRpYWxMZWdlbmRFbnRyeVtdIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMua2V5LmxlZ2VuZDtcbiAgfVxuICAvKiogQ1NTIGdyYWRpZW50IGZvciBhIGNvbnRpbnVvdXMgY29sb3VyaW5nLCBvciBudWxsIHdoZW4gY2F0ZWdvcmljYWwuICovXG4gIHByb3RlY3RlZCBnZXQgY29sb3JCYXJDc3MoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMua2V5LmNvbG9yQmFyQ3NzO1xuICB9XG5cbiAgLyoqIEN1cnJlbnQgc2VsZWN0aW9uIOKAlCBkcml2ZXMgdGhlIGNvdW50LCB0aGUgQ2xlYXIgYnV0dG9uIGFuZCB0aGUgbXV0aW5nLiAqL1xuICBwcm90ZWN0ZWQgc2VsZWN0aW9uOiBTcGF0aWFsU2VsZWN0aW9uTWFzayA9IGVtcHR5U2VsZWN0aW9uKCk7XG4gIC8qKiBUaGUgbGVnZW5kIHJvdyB3aG9zZSBjYXRlZ29yeSBpcyBjdXJyZW50bHkgc2VsZWN0ZWQsIGZvciBoaWdobGlnaHRpbmcuICovXG4gIHByb3RlY3RlZCBzZWxlY3RlZENhdGVnb3J5OiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgLyoqIEFuIFJPSSBzZWxlY3Rpb24gdGhhdCBtYXRjaGVkIG5vdGhpbmcsIHNvIHRoZSBVSSBjYW4gc2F5IHNvIHJhdGhlciB0aGFuXG4gICAqICBsb29raW5nIGxpa2UgdGhlIGJ1dHRvbiBkaWQgbm90aGluZy4gKi9cbiAgcHJvdGVjdGVkIHNlbGVjdGlvbk1pc3NlZCA9IGZhbHNlO1xuICAvKiogVGhlIG1vZGUgb2YgdGhlIHNlbGVjdGlvbiB0aGF0IHtAbGluayBzZWxlY3Rpb25NaXNzZWR9OiB3aGF0IGl0IGZvdW5kIG5vdGhpbmcgaW5zaWRlLiAqL1xuICBwcm90ZWN0ZWQgbWlzc2VkTW9kZTogUm9pU2VsZWN0aW9uTW9kZSA9ICdyZWdpb25zJztcbiAgLyoqIFRoZSByZWdpb24gY2xhc3NlcyBwaWNrZWQgaW4gdGhlIFJlZ2lvbiBFZGl0b3I6IGluIDNELCBcIlNlbGVjdCBmcm9tIFJPSXNcIiBzZWxlY3RzIGluc2lkZSB0aGVtLiAqL1xuICBwcm90ZWN0ZWQgcGlja2VkQ2xhc3NlczogcmVhZG9ubHkgc3RyaW5nW10gPSBbXTtcbiAgLyoqIFdoaWxlIFwiU2VsZWN0IGZyb20gUk9Jc1wiIHJlYWRzIHRoZSBwaWNrZWQgY2xhc3Nlcycgb3V0bGluZXMuICovXG4gIHByb3RlY3RlZCBzZWxlY3RpbmdGcm9tUmVnaW9ucyA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBEaXN0cmlidXRpb24gc2VjdGlvbiBpcyBleHBhbmRlZC4gQ29sbGFwc2VkIGJ5IGRlZmF1bHQ6IHRoZVxuICAgKiBwYW5lbCdzIHByaW1hcnkgam9iIGlzIHRoZSBjb2xvdXIgY29udHJvbHMsIGFuZCB0aGUgY2hhcnQgcm91Z2hseSBkb3VibGVzXG4gICAqIGl0cyBoZWlnaHQuXG4gICAqL1xuICBwcm90ZWN0ZWQgY2hhcnRzT3BlbiA9IGZhbHNlO1xuICAvKiogUGVyLWluc3RhbmNlIGlkIGZvciB0aGUgY29sbGFwc2libGUgYm9keSwgc28gYGFyaWEtY29udHJvbHNgIHBvaW50cyBhdCBvbmVcbiAgICogIGVsZW1lbnQgYW5kIGV4cGFuZGluZyB0aGUgc2Vjb25kIHBhbmVsIGNhbm5vdCBzY3JvbGwgdGhlIGZpcnN0IG9uZSdzIGNoYXJ0LiAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgY2hhcnRzQm9keUlkID0gYHNjLWNoYXJ0cy1ib2R5LSR7Kytjb250cm9sc0luc3RhbmNlU2VxfWA7XG5cbiAgLyoqIENvbG9ybWFwIHRyZWUgZm9yIHRoZSBjb250aW51b3VzIGNvbG91ciBzY2FsZSBhbmQgdGhlIGRlbnNpdHkgbWFwOiB0aGUgbGlicmFyeSdzXG4gICAqICBvd24gYENPTE9STUFQX09QVElPTlNgLiAqL1xuICBwcm90ZWN0ZWQgY29sb3JtYXBPcHRpb25zOiBDb2xvcm1hcE5vZGVbXSA9IFtdO1xuXG4gIHByaXZhdGUgY29sb3JtYXA6IENvbG9ybWFwTm9kZSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHJldmVyc2UgPSBmYWxzZTtcbiAgcHJpdmF0ZSByZWFkb25seSBkZXN0cm95UmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuICBwcml2YXRlIHJlYWRvbmx5IGNkciA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgQEluamVjdChWSVNVQUxJWkVSKSBwcml2YXRlIHJlYWRvbmx5IHZpejogSVZpc3VhbGl6ZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSB6b25lOiBOZ1pvbmUsXG4gICkge31cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmNvbnRyb2xzID0gdGhpcy52aXouZ2V0U3BhdGlhbENvbnRyb2xzPy4oKSA/PyBudWxsO1xuICAgIHRoaXMuY29sb3JtYXBPcHRpb25zID0gdGhpcy52aXouZ2V0Q29sb3JtYXBPcHRpb25zPy4oKSA/PyBbXTtcbiAgICBpZiAoIXRoaXMuY29udHJvbHMpIHJldHVybjtcblxuICAgIGNvbnN0IHVudGlsRGVzdHJveWVkID0gPFQ+KCkgPT4gdGFrZVVudGlsRGVzdHJveWVkPFQ+KHRoaXMuZGVzdHJveVJlZik7XG4gICAgdGhpcy5jb250cm9sc1xuICAgICAgLmdldERhdGFzZXQkKClcbiAgICAgIC5waXBlKHVudGlsRGVzdHJveWVkKCkpXG4gICAgICAuc3Vic2NyaWJlKChkYXRhc2V0KSA9PiB7XG4gICAgICAgIHRoaXMuZGF0YXNldCA9IGRhdGFzZXQ7XG4gICAgICAgIHRoaXMuZ2VuZXMuc2V0RGF0YXNldChkYXRhc2V0KTtcbiAgICAgICAgLy8gQSBkYXRhc2V0IHdpdGggbm8gY2VsbHMgdG8gb3V0bGluZSBsZWFkcyB3aXRoIGl0cyBvYnNlcnZhdGlvbnMuXG4gICAgICAgIHRoaXMub3BlbiA9IHtcbiAgICAgICAgICAuLi50aGlzLm9wZW4sXG4gICAgICAgICAgY2VsbHM6ICEhKGRhdGFzZXQ/LnBvbHlnb25UaWxlcyB8fCBkYXRhc2V0Py5wb2x5Z29ucyksXG4gICAgICAgICAgb2JzZXJ2YXRpb25zOiAhKGRhdGFzZXQ/LnBvbHlnb25UaWxlcyB8fCBkYXRhc2V0Py5wb2x5Z29ucyksXG4gICAgICAgIH07XG4gICAgICAgIHZvaWQgdGhpcy5yZWZyZXNoS2V5KCk7XG4gICAgICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSk7XG5cbiAgICB0aGlzLmNvbnRyb2xzXG4gICAgICAuZ2V0Vmlld1N0YXRlJCgpXG4gICAgICAucGlwZSh1bnRpbERlc3Ryb3llZCgpKVxuICAgICAgLnN1YnNjcmliZSgodmlldykgPT4ge1xuICAgICAgICB0aGlzLnZpZXcgPSB2aWV3O1xuICAgICAgICB2b2lkIHRoaXMucmVmcmVzaEtleSgpO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pO1xuXG4gICAgLy8gVGhlIHJlbmRlcmVyJ3Mgb3duIHN0cmVhbXMgbWF5IGVtaXQgb3V0c2lkZSB0aGUgem9uZTogcmUtZW50ZXJlZCBoZXJlLCBvbmNlLCBmb3JcbiAgICAvLyBldmVyeSBwYW5lbCB0aGV5IGZlZWQuXG4gICAgY29uc3QgZXN0aW1hdGUkID0gdGhpcy5jb250cm9scy5nZXRUcmFuc2NyaXB0RXN0aW1hdGUkPy4oKTtcbiAgICBlc3RpbWF0ZSQ/LnBpcGUodW50aWxEZXN0cm95ZWQoKSkuc3Vic2NyaWJlKChlKSA9PlxuICAgICAgdGhpcy5ydW5BbmRNYXJrKCgpID0+IHtcbiAgICAgICAgdGhpcy5lc3RpbWF0ZSA9IGU7XG4gICAgICB9KSxcbiAgICApO1xuICAgIGNvbnN0IGNvdW50cyQgPSB0aGlzLmNvbnRyb2xzLmdldEdlbmVDb3VudHNJblZpZXckPy4oKTtcbiAgICBjb3VudHMkPy5waXBlKHVudGlsRGVzdHJveWVkKCkpLnN1YnNjcmliZSgoYykgPT5cbiAgICAgIHRoaXMucnVuQW5kTWFyaygoKSA9PiB7XG4gICAgICAgIHRoaXMuZ2VuZUNvdW50cyA9IGM7XG4gICAgICB9KSxcbiAgICApO1xuICAgIGNvbnN0IGRlbnNpdHkkID0gdGhpcy5jb250cm9scy5nZXREZW5zaXR5U3RhdHMkPy4oKTtcbiAgICBkZW5zaXR5JD8ucGlwZSh1bnRpbERlc3Ryb3llZCgpKS5zdWJzY3JpYmUoKGQpID0+XG4gICAgICB0aGlzLnJ1bkFuZE1hcmsoKCkgPT4ge1xuICAgICAgICB0aGlzLmRlbnNpdHlTdGF0cyA9IGQ7XG4gICAgICB9KSxcbiAgICApO1xuXG4gICAgdGhpcy5jb250cm9sc1xuICAgICAgLmdldFNlbGVjdGlvbiQoKVxuICAgICAgLnBpcGUodW50aWxEZXN0cm95ZWQoKSlcbiAgICAgIC5zdWJzY3JpYmUoKHNlbGVjdGlvbikgPT5cbiAgICAgICAgLy8gU2V0IGZyb20gb3V0c2lkZSB0aGUgem9uZSB0b286IGEgc2VsZWN0aW9uIGZyb20gdGhlIHJlZ2lvbiBjbGFzc2VzJyB2b2x1bWVzLlxuICAgICAgICB0aGlzLnJ1bkFuZE1hcmsoKCkgPT4ge1xuICAgICAgICAgIHRoaXMuc2VsZWN0aW9uID0gc2VsZWN0aW9uO1xuICAgICAgICAgIGlmIChzZWxlY3Rpb24uY291bnQgPT09IDApIHRoaXMuc2VsZWN0ZWRDYXRlZ29yeSA9IG51bGw7XG4gICAgICAgIH0pLFxuICAgICAgKTtcblxuICAgIHRoaXMuY29udHJvbHNcbiAgICAgIC5nZXRQaWNrZWRSZWdpb25DbGFzc2VzJD8uKClcbiAgICAgID8ucGlwZSh1bnRpbERlc3Ryb3llZCgpKVxuICAgICAgLnN1YnNjcmliZSgoY2xhc3NlcykgPT5cbiAgICAgICAgdGhpcy5ydW5BbmRNYXJrKCgpID0+IHtcbiAgICAgICAgICB0aGlzLnBpY2tlZENsYXNzZXMgPSBjbGFzc2VzO1xuICAgICAgICB9KSxcbiAgICAgICk7XG5cbiAgICAvLyBUaGUgY29sb3VyIGJhciBtdXN0IHVzZSB0aGUgY29sb3JtYXAgdGhlIHJlbmRlcmVyIGlzIHVzaW5nLlxuICAgIGNvbWJpbmVMYXRlc3QoW3RoaXMudml6LmdldENvbG9ybWFwKCksIHRoaXMudml6LmdldFJldmVyc2VTY2FsZSgpXSlcbiAgICAgIC5waXBlKHVudGlsRGVzdHJveWVkKCkpXG4gICAgICAuc3Vic2NyaWJlKChbY29sb3JtYXAsIHJldmVyc2VdKSA9PiB7XG4gICAgICAgIHRoaXMuY29sb3JtYXAgPSAoY29sb3JtYXAgYXMgQ29sb3JtYXBOb2RlKSA/PyBudWxsO1xuICAgICAgICB0aGlzLnJldmVyc2UgPSAhIXJldmVyc2U7XG4gICAgICAgIHZvaWQgdGhpcy5yZWZyZXNoS2V5KCk7XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKiBBcHBseSBhbiBhc3luYyByZXN1bHQgaW5zaWRlIHRoZSB6b25lIGFuZCByZS1yZW5kZXIgdGhpcyBPblB1c2ggZGlhbG9nLiAqL1xuICBwcml2YXRlIHJ1bkFuZE1hcmsoZm46ICgpID0+IHZvaWQpOiB2b2lkIHtcbiAgICB0aGlzLnpvbmUucnVuKCgpID0+IHtcbiAgICAgIGZuKCk7XG4gICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvblZpc2libGVDaGFuZ2UodmFsdWU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLnZpc2libGUgPSB2YWx1ZTtcbiAgICB0aGlzLnZpc2libGVDaGFuZ2UuZW1pdCh2YWx1ZSk7XG4gIH1cblxuICAvLyDilIDilIAgdGhlIHNoYXJlZCBnZW5lIGxpc3Qg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqIEEga2V5c3Ryb2tlIGluIGEgZ2VuZSBkcm9wZG93bidzIGZpbHRlciBib3gg4oCUIHNlZSB7QGxpbmsgR2VuZVBpY2tlck1vZGVsLm9uRmlsdGVyfS4gKi9cbiAgb25HZW5lRmlsdGVyKHF1ZXJ5OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICByZXR1cm4gdGhpcy5nZW5lcy5vbkZpbHRlcihxdWVyeSk7XG4gIH1cblxuICAvKiogQSBnZW5lIGRyb3Bkb3duIG9wZW5lZCDigJQgc2VlIHtAbGluayBHZW5lUGlja2VyTW9kZWwuZW5zdXJlTGlzdH0uICovXG4gIGVuc3VyZUdlbmVMaXN0KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLmdlbmVzLmVuc3VyZUxpc3QoKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBzZWxlY3Rpb24g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqIFNlbGVjdCBldmVyeSBvYnNlcnZhdGlvbiBpbnNpZGUgdGhlIGRyYXduIHJlZ2lvbnMgKHRoZWlyIHVuaW9uKSDigJQgaW4gM0QsIGluc2lkZSB0aGVcbiAgICogIHBpY2tlZCBjbGFzc2VzJyB2b2x1bWVzLiAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgc2VsZWN0RnJvbVJlZ2lvbnMoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCF0aGlzLmNvbnRyb2xzIHx8IHRoaXMuc2VsZWN0aW5nRnJvbVJlZ2lvbnMpIHJldHVybjtcbiAgICB0aGlzLnNlbGVjdGluZ0Zyb21SZWdpb25zID0gdHJ1ZTtcbiAgICAvLyBUaGUgbW9kZSB0aGUgc2VsZWN0aW9uIHJ1bnMgaW4gKGRlY2lkZWQgYXMgaXQgc3RhcnRzKSwgZm9yIHdoYXQgYSBtaXNzIHNheXMgaXQgbWlzc2VkLlxuICAgIGNvbnN0IG1vZGUgPSB0aGlzLnJvaVNlbGVjdGlvbk1vZGU7XG4gICAgdGhpcy5jZHIubWFya0ZvckNoZWNrKCk7XG4gICAgbGV0IGNvdW50OiBudW1iZXIgfCBudWxsID0gMDtcbiAgICB0cnkge1xuICAgICAgY291bnQgPSBhd2FpdCB0aGlzLmNvbnRyb2xzLnNlbGVjdEZyb21SZWdpb25zKCk7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBjb25zb2xlLndhcm4oJ1tzcGF0aWFsXSBjb3VsZCBub3Qgc2VsZWN0IGZyb20gdGhlIHJlZ2lvbnMnLCBlcnIpO1xuICAgIH1cbiAgICAvLyBUaGUgY2xhc3Nlcycgb3V0bGluZXMgYXJlIHJlYWQgaW4gYSB3b3JrZXIsIHdob3NlIGFuc3dlciBsYW5kcyBvdXRzaWRlIHRoZSB6b25lLlxuICAgIHRoaXMucnVuQW5kTWFyaygoKSA9PiB7XG4gICAgICB0aGlzLnNlbGVjdGluZ0Zyb21SZWdpb25zID0gZmFsc2U7XG4gICAgICAvLyBTdXBlcnNlZGVkIChudWxsKTogYSBuZXdlciBzZWxlY3Rpb24gc3RhbmRzLCBhbmQgc2F5cyB3aGF0IGl0IGlzIGl0c2VsZi5cbiAgICAgIGlmIChjb3VudCA9PT0gbnVsbCkgcmV0dXJuO1xuICAgICAgdGhpcy5zZWxlY3RlZENhdGVnb3J5ID0gbnVsbDtcbiAgICAgIHRoaXMuc2VsZWN0aW9uTWlzc2VkID0gY291bnQgPT09IDA7XG4gICAgICB0aGlzLm1pc3NlZE1vZGUgPSBtb2RlO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqIEluIDNEIHdpdGggY2xhc3NlcyBwaWNrZWQsIFwiU2VsZWN0IGZyb20gUk9Jc1wiIHNlbGVjdHMgaW5zaWRlIHRoZWlyIHZvbHVtZXMuICovXG4gIHByb3RlY3RlZCBnZXQgc2VsZWN0c0NsYXNzVm9sdW1lcygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5yb2lTZWxlY3Rpb25Nb2RlID09PSAnY2xhc3Mtdm9sdW1lcyc7XG4gIH1cblxuICAvKiogSG93IFwiU2VsZWN0IGZyb20gUk9Jc1wiIHNlbGVjdHMgbm93OiB0aGUgY29udHJvbHMnIG93biBydWxlLCB0aGUgb25lIHRoZSBzZWxlY3Rpb24gcnVucyBieS4gKi9cbiAgcHJpdmF0ZSBnZXQgcm9pU2VsZWN0aW9uTW9kZSgpOiBSb2lTZWxlY3Rpb25Nb2RlIHtcbiAgICByZXR1cm4gdGhpcy5jb250cm9scz8ucm9pU2VsZWN0aW9uTW9kZT8uKCkgPz8gJ3JlZ2lvbnMnO1xuICB9XG5cbiAgLyoqIExlZ2VuZCBjbGljazogc2VsZWN0IG9uZSBjYXRlZ29yeS4gQ2xpY2tpbmcgdGhlIGFjdGl2ZSByb3cgY2xlYXJzIGl0LCBzbyBhXG4gICAqICBzZWNvbmQgY2xpY2sgaXMgYW4gdW5kbyByYXRoZXIgdGhhbiBhIG5vLW9wLiAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgc2VsZWN0Q2F0ZWdvcnkoaW5kZXg6IG51bWJlcik6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGJ5ID0gdGhpcy52aWV3LmNvbG9yQnk7XG4gICAgaWYgKCF0aGlzLmNvbnRyb2xzIHx8IGJ5Py5raW5kICE9PSAnY29sdW1uJykgcmV0dXJuO1xuICAgIGlmICh0aGlzLnNlbGVjdGVkQ2F0ZWdvcnkgPT09IGluZGV4KSB7XG4gICAgICB0aGlzLmNsZWFyU2VsZWN0aW9uKCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBhd2FpdCB0aGlzLmNvbnRyb2xzLnNlbGVjdENhdGVnb3J5KGJ5Lm5hbWUsIGluZGV4KTtcbiAgICAgIHRoaXMuc2VsZWN0ZWRDYXRlZ29yeSA9IGluZGV4O1xuICAgICAgdGhpcy5zZWxlY3Rpb25NaXNzZWQgPSBmYWxzZTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIHRoaXMuc2VsZWN0ZWRDYXRlZ29yeSA9IG51bGw7XG4gICAgfVxuICAgIHRoaXMuY2RyLm1hcmtGb3JDaGVjaygpO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4cGFuZCBvciBjb2xsYXBzZSB0aGUgZGlzdHJpYnV0aW9uIHNlY3Rpb24uXG4gICAqXG4gICAqIEV4cGFuZGluZyBTQ1JPTExTIGl0IGludG8gdmlldywgYmVjYXVzZSB0aGUgcGFuZWwgaXMgdGFsbGVyIHRoYW4gdGhlIHZpZXdwb3J0XG4gICAqIG9uY2UgdGhpcyBzZWN0aW9uIGlzIG9wZW4gYW5kIHRoZSBjaGFydCBpcyBpdHMgbGFzdCByb3c6IGV4cGFuZGluZyBpdCBkcmV3IGFcbiAgICogY2hhcnQgfjMwMCBweCBiZWxvdyB0aGUgZm9sZCwgd2hpY2ggcmVhZHMgYXMgdGhlIHNlY3Rpb24gYmVpbmcgZW1wdHkuIFRoZVxuICAgKiBzY3JvbGwgaXMgZGVmZXJyZWQgYSB0YXNrIHNvIHRoZSBjaGFydCdzIG93biBkZWZlcnJlZCBmaXJzdCBkcmF3IGhhcyBnaXZlbiB0aGVcbiAgICogYm9keSBpdHMgaGVpZ2h0LlxuICAgKi9cbiAgcHJvdGVjdGVkIHRvZ2dsZUNoYXJ0cygpOiB2b2lkIHtcbiAgICB0aGlzLmNoYXJ0c09wZW4gPSAhdGhpcy5jaGFydHNPcGVuO1xuICAgIGlmICghdGhpcy5jaGFydHNPcGVuKSByZXR1cm47XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh0aGlzLmNoYXJ0c0JvZHlJZCk/LnNjcm9sbEludG9WaWV3KHsgYmxvY2s6ICdlbmQnLCBiZWhhdmlvcjogJ3Ntb290aCcgfSk7XG4gICAgfSwgMCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgY2xlYXJTZWxlY3Rpb24oKTogdm9pZCB7XG4gICAgdGhpcy5jb250cm9scz8uY2xlYXJTZWxlY3Rpb24oKTtcbiAgICB0aGlzLnNlbGVjdGVkQ2F0ZWdvcnkgPSBudWxsO1xuICAgIHRoaXMuc2VsZWN0aW9uTWlzc2VkID0gZmFsc2U7XG4gIH1cblxuICAvKiogVHJ1ZSB3aGlsZSBhIHNlbGVjdGlvbiBpcyBhY3RpdmUg4oCUIGV2ZXJ5dGhpbmcgZWxzZSByZW5kZXJzIG11dGVkLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGhhc1NlbGVjdGlvbigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5zZWxlY3Rpb24uY291bnQgPiAwO1xuICB9XG5cbiAgLy8g4pSA4pSAIHNlY3Rpb25zIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIC8qKiBCb3VuZGFyaWVzIG9uIG9mZmVyOiB0aWxlZCAobGV2ZWwtb2YtZGV0YWlsKSBvciB3aG9sZS1kYXRhc2V0IHJpbmdzLiAqL1xuICBwcm90ZWN0ZWQgZ2V0IGhhc0NlbGxzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhISh0aGlzLmRhdGFzZXQ/LnBvbHlnb25UaWxlcyB8fCB0aGlzLmRhdGFzZXQ/LnBvbHlnb25zKTtcbiAgfVxuXG4gIC8qKiBUcmFuc2NyaXB0cyBvbiBvZmZlcjogdGlsZXMgdG8gZHJhdywgb3IgYSBkZW5zaXR5IG1hcC4gKi9cbiAgcHJvdGVjdGVkIGdldCBoYXNUcmFuc2NyaXB0cygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmRhdGFzZXQ/LnRyYW5zY3JpcHRUaWxlcyB8fCAhIXRoaXMuZGF0YXNldD8uZGVuc2l0eTtcbiAgfVxuXG4gIC8qKiBXaGV0aGVyIHRoZSAzRCBjbG91ZCBjYW4gZHJhdyB0aGUgdHJhbnNjcmlwdHMgdG9vOiB0aGV5IGNhcnJ5IHogKGEgTUVSRklTSCB2b2x1bWUncyBkbykuICovXG4gIHByb3RlY3RlZCBnZXQgaGFzVHJhbnNjcmlwdHMzZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gISF0aGlzLmRhdGFzZXQ/LnRyYW5zY3JpcHRUaWxlcz8uaGFzWjtcbiAgfVxuXG4gIHByb3RlY3RlZCBvblNob3dJbWFnZShvbjogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMuY29udHJvbHM/LnNldFZpZXdTdGF0ZSh7IHNob3dJbWFnZTogb24gfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgb25TaG93QW5ub3RhdGlvbnMob246IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLmNvbnRyb2xzPy5zZXRWaWV3U3RhdGUoeyBzaG93QW5ub3RhdGlvbnM6IG9uIH0pO1xuICB9XG5cbiAgLyoqIFdoaWNoIGNvbGxhcHNpYmxlIHNlY3Rpb25zIGFyZSBvcGVuLiBQZXIgZGlhbG9nIGluc3RhbmNlLCBub3QgcGVyc2lzdGVkLiAqL1xuICBwcm90ZWN0ZWQgb3BlbjogUmVjb3JkPCdpbWFnZXMnIHwgJ2NlbGxzJyB8ICd0cmFuc2NyaXB0cycgfCAnYW5ub3RhdGlvbnMnIHwgJ29ic2VydmF0aW9ucycsIGJvb2xlYW4+ID0ge1xuICAgIGltYWdlczogZmFsc2UsXG4gICAgY2VsbHM6IHRydWUsXG4gICAgdHJhbnNjcmlwdHM6IGZhbHNlLFxuICAgIGFubm90YXRpb25zOiBmYWxzZSxcbiAgICBvYnNlcnZhdGlvbnM6IGZhbHNlLFxuICB9O1xuXG4gIHByb3RlY3RlZCB0b2dnbGVTZWN0aW9uKG5hbWU6IGtleW9mIFNwYXRpYWxDb250cm9sc0NvbXBvbmVudFsnb3BlbiddKTogdm9pZCB7XG4gICAgdGhpcy5zZXRPcGVuKG5hbWUsICF0aGlzLm9wZW5bbmFtZV0pO1xuICB9XG5cbiAgLyoqIEV4cGFuZCBvciBjb2xsYXBzZSBhIHNlY3Rpb24g4oCUIHdoYXQgYSBwYW5lbCdzIGhlYWRlciBhc2tzIGZvci4gKi9cbiAgcHJvdGVjdGVkIHNldE9wZW4obmFtZToga2V5b2YgU3BhdGlhbENvbnRyb2xzQ29tcG9uZW50WydvcGVuJ10sIG9uOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5vcGVuID0geyAuLi50aGlzLm9wZW4sIFtuYW1lXTogb24gfTtcbiAgfVxuXG4gIC8vIOKUgOKUgCByZW5kZXJlciByZWFkb3V0cywgZm9yIHRoZSBUcmFuc2NyaXB0cyBzZWN0aW9uIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIC8qKiBFc3RpbWF0ZWQgdHJhbnNjcmlwdHMgaW4gdmlldywgYWdhaW5zdCB0aGUgYnVkZ2V0IOKAlCBFeHBsb3JlcidzIHBvaW50cyBiYXIuICovXG4gIHByb3RlY3RlZCBlc3RpbWF0ZTogeyBwb2ludHM6IG51bWJlcjsgbWF4OiBudW1iZXIgfSB8IG51bGwgPSBudWxsO1xuICAvKiogVGhlIGRlbnNpdHkgd2luZG93IGluIHVzZSBhbmQgaXRzIGRlbnNlc3QgYmluLCBmb3IgdGhlIHRocmVzaG9sZCBjb250cm9sLiAqL1xuICBwcm90ZWN0ZWQgZGVuc2l0eVN0YXRzOiB7IGxvOiBudW1iZXI7IGhpOiBudW1iZXI7IG1heDogbnVtYmVyIH0gfCBudWxsID0gbnVsbDtcbiAgLyoqIFRyYW5zY3JpcHRzIG9mIGVhY2ggc2VsZWN0ZWQgZ2VuZSBpbiB0aGUgY3VycmVudCB2aWV3LCBmcm9tIHRoZSByZW5kZXJlci4gKi9cbiAgcHJvdGVjdGVkIGdlbmVDb3VudHM6IFJlY29yZDxzdHJpbmcsIG51bWJlcj4gfCBudWxsID0gbnVsbDtcblxuICBwcm90ZWN0ZWQgcmVzZXQoKTogdm9pZCB7XG4gICAgdGhpcy5jb250cm9scz8uc2V0Vmlld1N0YXRlKHsgLi4uREVGQVVMVF9TUEFUSUFMX1ZJRVcgfSk7XG4gICAgdGhpcy5jbGVhclNlbGVjdGlvbigpO1xuICB9XG5cbiAgLyoqIExhYmVsIGZvciB0aGUgY3VycmVudCBjb2xvdXJpbmcsIGZvciB0aGUgRGlzdHJpYnV0aW9uIGhlYWRpbmcuICovXG4gIHByb3RlY3RlZCBnZXQgY29sb3JCeUxhYmVsKCk6IHN0cmluZyB7XG4gICAgcmV0dXJuIGNvbG9yQnlMYWJlbCh0aGlzLnZpZXcpO1xuICB9XG5cbiAgLyoqIFRydWUgd2hlbiB0aGUgYWN0aXZlIGNvbG91cmluZyBpcyBhIGNhdGVnb3JpY2FsIGNvbHVtbiAoZHJpdmVzIHRoZSBrZXkpLiAqL1xuICBnZXQgaXNDYXRlZ29yaWNhbCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5sZWdlbmQgIT09IG51bGw7XG4gIH1cblxuICAvKiogV2hldGhlciBsb2cvY2xpcCBhcHBseSDigJQgdGhleSBhcmUgY29udGludW91cy1vbmx5IGtub2JzLiAqL1xuICBnZXQgaXNDb250aW51b3VzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAhIXRoaXMudmlldy5jb2xvckJ5ICYmIHRoaXMubGVnZW5kID09PSBudWxsO1xuICB9XG5cbiAgLy8g4pSA4pSAIGludGVybmFscyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAvKiogUmVidWlsZCB0aGUgbGVnZW5kIG9yIGNvbG91ciBiYXIgZm9yIHRoZSBjdXJyZW50IGNvbG91cmluZy4gKi9cbiAgcHJpdmF0ZSByZWZyZXNoS2V5KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIHJldHVybiB0aGlzLmtleS5yZWZyZXNoKHRoaXMuY29udHJvbHMsIHRoaXMuZGF0YXNldCwgdGhpcy52aWV3LCB0aGlzLmNvbG9ybWFwLCB0aGlzLnJldmVyc2UpO1xuICB9XG59XG4iLCI8cC1kaWFsb2dcbiAgaGVhZGVyPVwiU3BhdGlhbCBvbWljc1wiXG4gIFt2aXNpYmxlXT1cInZpc2libGVcIlxuICAodmlzaWJsZUNoYW5nZSk9XCJvblZpc2libGVDaGFuZ2UoJGV2ZW50KVwiXG4gIFttb2RhbF09XCJmYWxzZVwiXG4gIFtyZXNpemFibGVdPVwidHJ1ZVwiXG4gIFtkcmFnZ2FibGVdPVwidHJ1ZVwiXG4gIHBvc2l0aW9uPVwibGVmdFwiXG4gIChvblJlc2l6ZUVuZCk9XCJvblJlc2l6ZUVuZCgpXCJcbiAgW3N0eWxlXT1cInsgd2lkdGg6ICczMHJlbScgfVwiXG4gIFticmVha3BvaW50c109XCJ7ICc5NjBweCc6ICc5MHZ3JyB9XCJcbiAgc3R5bGVDbGFzcz1cInNwYXRpYWwtY29udHJvbHMtZGlhbG9nXCJcbj5cbiAgPCEtLSBObyBwb3J0IGJvdW5kOiBzYXkgd2h5IHJhdGhlciB0aGFuIHNob3dpbmcgY29udHJvbHMgdGhhdCBkbyBub3RoaW5nLiAtLT5cbiAgPGRpdiBjbGFzcz1cInNjLWVtcHR5XCIgKm5nSWY9XCIhY29udHJvbHNcIj5cbiAgICBObyBzcGF0aWFsLW9taWNzIGRhdGEgc291cmNlIGlzIGNvbmZpZ3VyZWQuIEEgaG9zdCBwcm92aWRlcyBvbmUgYnkgYmluZGluZ1xuICAgIDxjb2RlPlNQQVRJQUxfREFUQV9QT1JUPC9jb2RlPi5cbiAgPC9kaXY+XG5cbiAgPGRpdiBjbGFzcz1cInNjLWVtcHR5XCIgKm5nSWY9XCJjb250cm9scyAmJiAhZGF0YXNldFwiPk5vIGRhdGFzZXQgaXMgbG9hZGVkLjwvZGl2PlxuXG4gIDxkaXYgY2xhc3M9XCJzYy1ib2R5XCIgKm5nSWY9XCJjb250cm9scyAmJiBkYXRhc2V0IGFzIGRzXCI+XG4gICAgPGRpdiBjbGFzcz1cInNjLWRhdGFzZXRcIj5cbiAgICAgIDxzcGFuIGNsYXNzPVwic2MtZGF0YXNldC1uYW1lXCI+e3sgZHMubmFtZSB9fTwvc3Bhbj5cbiAgICAgIDxzcGFuIGNsYXNzPVwic2MtZGF0YXNldC1jb3VudFwiPnt7IGRzLm9ic2VydmF0aW9ucy5jb3VudCB8IG51bWJlciB9fSBvYnNlcnZhdGlvbnM8L3NwYW4+XG4gICAgPC9kaXY+XG5cbiAgICA8IS0tIE9yZ2FuaXNlZCBhcyBYZW5pdW0gRXhwbG9yZXIncyBzaWRlIHBhbmVsOiBvbmUgY29sbGFwc2libGUgc2VjdGlvbiBwZXIgbGF5ZXIsXG4gICAgICAgICBlYWNoIHdpdGggaXRzIG93biBvbi9vZmYgc3dpdGNoIGluIHRoZSBoZWFkZXIuIC0tPlxuXG4gICAgPCEtLSBJbWFnZXMgLS0+XG4gICAgPGRpdiBjbGFzcz1cInNjLXBhbmVsXCIgKm5nSWY9XCJkcy5pbWFnZVJlZiAmJiAhaXMzZFwiIFtjbGFzcy5vcGVuXT1cIm9wZW4uaW1hZ2VzXCI+XG4gICAgICA8ZGl2IGNsYXNzPVwic2MtcGFuZWwtaGVhZFwiIChjbGljayk9XCJ0b2dnbGVTZWN0aW9uKCdpbWFnZXMnKVwiPlxuICAgICAgICA8cC1jaGVja2JveFxuICAgICAgICAgIFtiaW5hcnldPVwidHJ1ZVwiXG4gICAgICAgICAgW25nTW9kZWxdPVwidmlldy5zaG93SW1hZ2VcIlxuICAgICAgICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgICAgICAgIChvbkNoYW5nZSk9XCJvblNob3dJbWFnZSgkZXZlbnQuY2hlY2tlZClcIlxuICAgICAgICA+PC9wLWNoZWNrYm94PlxuICAgICAgICA8c3BhbiBjbGFzcz1cInNjLXBhbmVsLXRpdGxlXCI+SW1hZ2VzPC9zcGFuPlxuICAgICAgICA8aSBjbGFzcz1cInBpXCIgW2NsYXNzLnBpLWNoZXZyb24tZG93bl09XCJvcGVuLmltYWdlc1wiIFtjbGFzcy5waS1jaGV2cm9uLXJpZ2h0XT1cIiFvcGVuLmltYWdlc1wiPjwvaT5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cInNjLXBhbmVsLWJvZHlcIiAqbmdJZj1cIm9wZW4uaW1hZ2VzXCI+XG4gICAgICAgIDxzbWFsbCBjbGFzcz1cInNjLWhpbnRcIj4gQ2hhbm5lbHMsIGNvbG91cnMgYW5kIGNvbnRyYXN0IGFyZSBpbiB0aGUgQ2hhbm5lbHMgJmFtcDsgSGlzdG9ncmFtIGRpYWxvZy4gPC9zbWFsbD5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBDZWxscyAtLT5cbiAgICA8c3BhdGlhbC1jZWxscy1wYW5lbFxuICAgICAgKm5nSWY9XCJoYXNDZWxscyAmJiAhaXMzZFwiXG4gICAgICBbY29udHJvbHNdPVwiY29udHJvbHNcIlxuICAgICAgW2RhdGFzZXRdPVwiZHNcIlxuICAgICAgW3ZpZXddPVwidmlld1wiXG4gICAgICBbZ2VuZXNdPVwiZ2VuZXNcIlxuICAgICAgW2NvbG9yQmFyQ3NzXT1cImNvbG9yQmFyQ3NzXCJcbiAgICAgIFtvcGVuXT1cIm9wZW4uY2VsbHNcIlxuICAgICAgKG9wZW5DaGFuZ2UpPVwic2V0T3BlbignY2VsbHMnLCAkZXZlbnQpXCJcbiAgICA+PC9zcGF0aWFsLWNlbGxzLXBhbmVsPlxuXG4gICAgPCEtLSBUcmFuc2NyaXB0cyAtLT5cbiAgICA8c3BhdGlhbC10cmFuc2NyaXB0cy1wYW5lbFxuICAgICAgKm5nSWY9XCJoYXNUcmFuc2NyaXB0cyAmJiAoIWlzM2QgfHwgaGFzVHJhbnNjcmlwdHMzZClcIlxuICAgICAgW2NvbnRyb2xzXT1cImNvbnRyb2xzXCJcbiAgICAgIFtkYXRhc2V0XT1cImRzXCJcbiAgICAgIFt2aWV3XT1cInZpZXdcIlxuICAgICAgW2dlbmVzXT1cImdlbmVzXCJcbiAgICAgIFtlc3RpbWF0ZV09XCJlc3RpbWF0ZVwiXG4gICAgICBbZGVuc2l0eVN0YXRzXT1cImRlbnNpdHlTdGF0c1wiXG4gICAgICBbZ2VuZUNvdW50c109XCJnZW5lQ291bnRzXCJcbiAgICAgIFtjb2xvcm1hcE9wdGlvbnNdPVwiY29sb3JtYXBPcHRpb25zXCJcbiAgICAgIFtvcGVuXT1cIm9wZW4udHJhbnNjcmlwdHNcIlxuICAgICAgKG9wZW5DaGFuZ2UpPVwic2V0T3BlbigndHJhbnNjcmlwdHMnLCAkZXZlbnQpXCJcbiAgICA+XG4gICAgPC9zcGF0aWFsLXRyYW5zY3JpcHRzLXBhbmVsPlxuXG4gICAgPCEtLSBBbm5vdGF0aW9uczogdGhlIGRyYXduIHJlZ2lvbnMsIGFuZCBzZWxlY3Rpbmcgd2hhdCB0aGV5IGVuY2xvc2UuIC0tPlxuICAgIDxkaXYgY2xhc3M9XCJzYy1wYW5lbFwiIFtjbGFzcy5vcGVuXT1cIm9wZW4uYW5ub3RhdGlvbnNcIj5cbiAgICAgIDxkaXYgY2xhc3M9XCJzYy1wYW5lbC1oZWFkXCIgKGNsaWNrKT1cInRvZ2dsZVNlY3Rpb24oJ2Fubm90YXRpb25zJylcIj5cbiAgICAgICAgPHAtY2hlY2tib3hcbiAgICAgICAgICBbYmluYXJ5XT1cInRydWVcIlxuICAgICAgICAgIFtuZ01vZGVsXT1cInZpZXcuc2hvd0Fubm90YXRpb25zICE9PSBmYWxzZVwiXG4gICAgICAgICAgKGNsaWNrKT1cIiRldmVudC5zdG9wUHJvcGFnYXRpb24oKVwiXG4gICAgICAgICAgKG9uQ2hhbmdlKT1cIm9uU2hvd0Fubm90YXRpb25zKCRldmVudC5jaGVja2VkKVwiXG4gICAgICAgICAgcFRvb2x0aXA9XCJTaG93IHRoZSBkcmF3biByZWdpb25zXCJcbiAgICAgICAgICB0b29sdGlwUG9zaXRpb249XCJ0b3BcIlxuICAgICAgICA+PC9wLWNoZWNrYm94PlxuICAgICAgICA8c3BhbiBjbGFzcz1cInNjLXBhbmVsLXRpdGxlXCI+QW5ub3RhdGlvbnM8L3NwYW4+XG4gICAgICAgIDxpIGNsYXNzPVwicGlcIiBbY2xhc3MucGktY2hldnJvbi1kb3duXT1cIm9wZW4uYW5ub3RhdGlvbnNcIiBbY2xhc3MucGktY2hldnJvbi1yaWdodF09XCIhb3Blbi5hbm5vdGF0aW9uc1wiPjwvaT5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cInNjLXBhbmVsLWJvZHlcIiAqbmdJZj1cIm9wZW4uYW5ub3RhdGlvbnNcIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInNjLXJvd1wiPlxuICAgICAgICAgIDxwLWJ1dHRvblxuICAgICAgICAgICAgbGFiZWw9XCJTZWxlY3QgZnJvbSBST0lzXCJcbiAgICAgICAgICAgIGljb249XCJwaSBwaS1vYmplY3QtZ3JvdXBcIlxuICAgICAgICAgICAgc2l6ZT1cInNtYWxsXCJcbiAgICAgICAgICAgIFtvdXRsaW5lZF09XCJ0cnVlXCJcbiAgICAgICAgICAgIFtsb2FkaW5nXT1cInNlbGVjdGluZ0Zyb21SZWdpb25zXCJcbiAgICAgICAgICAgIChvbkNsaWNrKT1cInNlbGVjdEZyb21SZWdpb25zKClcIlxuICAgICAgICAgICAgW3BUb29sdGlwXT1cIlxuICAgICAgICAgICAgICBzZWxlY3RzQ2xhc3NWb2x1bWVzXG4gICAgICAgICAgICAgICAgPyAnU2VsZWN0IGV2ZXJ5IG9ic2VydmF0aW9uIGluc2lkZSB0aGUgdm9sdW1lcyBvZiB0aGUgY2xhc3NlcyBwaWNrZWQgaW4gdGhlIFJlZ2lvbiBFZGl0b3InXG4gICAgICAgICAgICAgICAgOiAnU2VsZWN0IGV2ZXJ5IG9ic2VydmF0aW9uIGluc2lkZSB0aGUgZHJhd24gcmVnaW9ucydcbiAgICAgICAgICAgIFwiXG4gICAgICAgICAgICB0b29sdGlwUG9zaXRpb249XCJ0b3BcIlxuICAgICAgICAgID48L3AtYnV0dG9uPlxuICAgICAgICAgIDxwLWJ1dHRvblxuICAgICAgICAgICAgKm5nSWY9XCJoYXNTZWxlY3Rpb25cIlxuICAgICAgICAgICAgbGFiZWw9XCJDbGVhclwiXG4gICAgICAgICAgICBzaXplPVwic21hbGxcIlxuICAgICAgICAgICAgW3RleHRdPVwidHJ1ZVwiXG4gICAgICAgICAgICAob25DbGljayk9XCJjbGVhclNlbGVjdGlvbigpXCJcbiAgICAgICAgICA+PC9wLWJ1dHRvbj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxzbWFsbCBjbGFzcz1cInNjLWhpbnRcIiAqbmdJZj1cImhhc1NlbGVjdGlvblwiPlxuICAgICAgICAgIHt7IHNlbGVjdGlvbi5jb3VudCB8IG51bWJlciB9fSBvZiB7eyBkcy5vYnNlcnZhdGlvbnMuY291bnQgfCBudW1iZXIgfX0gc2VsZWN0ZWQg4oCUIHRoZSByZXN0IGFyZSBtdXRlZC5cbiAgICAgICAgPC9zbWFsbD5cbiAgICAgICAgPHNtYWxsIGNsYXNzPVwic2MtaGludFwiICpuZ0lmPVwic2VsZWN0aW9uTWlzc2VkXCI+XG4gICAgICAgICAgTm8gb2JzZXJ2YXRpb25zIGZlbGwgaW5zaWRlIHRoZVxuICAgICAgICAgIHt7IG1pc3NlZE1vZGUgPT09ICdjbGFzcy12b2x1bWVzJyA/ICdwaWNrZWQgY2xhc3NlcycgOiAnZHJhd24gcmVnaW9ucycgfX0uXG4gICAgICAgIDwvc21hbGw+XG4gICAgICAgIDxzbWFsbCBjbGFzcz1cInNjLWhpbnRcIiAqbmdJZj1cInNlbGVjdHNDbGFzc1ZvbHVtZXNcIj5cbiAgICAgICAgICBTZWxlY3RzIGluc2lkZSB0aGUgdm9sdW1lIG9mIHt7IHBpY2tlZENsYXNzZXNbMF1cbiAgICAgICAgICB9fXt7IHBpY2tlZENsYXNzZXMubGVuZ3RoID4gMSA/ICcgYW5kICcgKyAocGlja2VkQ2xhc3Nlcy5sZW5ndGggLSAxIHwgbnVtYmVyKSArICcgbW9yZSBjbGFzc2VzJyA6ICcnIH19LFxuICAgICAgICAgIHBpY2tlZCBpbiB0aGUgUmVnaW9uIEVkaXRvci4gRHJhdyBhIHJlZ2lvbiB0byBzZWxlY3QgYnkgaXQgaW5zdGVhZC5cbiAgICAgICAgPC9zbWFsbD5cbiAgICAgICAgPHNtYWxsIGNsYXNzPVwic2MtaGludFwiICpuZ0lmPVwiaXMzZCAmJiAhc2VsZWN0c0NsYXNzVm9sdW1lcyAmJiBwaWNrZWRDbGFzc2VzLmxlbmd0aFwiPlxuICAgICAgICAgIFRoZSBjbGFzc2VzIHBpY2tlZCBpbiB0aGUgUmVnaW9uIEVkaXRvciBhcmUgbm90IG9uIHRoZSByZWZlcmVuY2Ugdm9sdW1lIHNob3duIGhlcmUsIHNvIHRoaXMgc2VsZWN0cyBieVxuICAgICAgICAgIHRoZSByZWdpb25zIGRyYXduIG92ZXIgdGhlIGNsb3VkIGluc3RlYWQuXG4gICAgICAgIDwvc21hbGw+XG4gICAgICAgIDxzbWFsbCBjbGFzcz1cInNjLWhpbnRcIiAqbmdJZj1cImlzM2QgJiYgIXNlbGVjdHNDbGFzc1ZvbHVtZXNcIj5cbiAgICAgICAgICBJbiAzRCBhIHJlZ2lvbiBjdXRzIHRocm91Z2ggdGhlIGNsb3VkJ3MgZnVsbCBkZXB0aC4gT3JiaXQgYW5kIGRyYXcgYWdhaW4gdG8gY3V0IGZyb20gYW5vdGhlciBhbmdsZS5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIXBpY2tlZENsYXNzZXMubGVuZ3RoXCI+XG4gICAgICAgICAgICBQaWNrIGNsYXNzZXMgaW4gdGhlIFJlZ2lvbiBFZGl0b3IncyBjbGFzcyB0cmVlIHRvIHNlbGVjdCBpbnNpZGUgdGhlaXIgdm9sdW1lcy5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9zbWFsbD5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuXG4gICAgPCEtLSBPYnNlcnZhdGlvbnMsIHRoZW4gd2hhdCBlbHNlIGRyYXdzIHRoZW06IHRoZSBnZW5lIG1hcCwgdGhlIDNEIHNjZW5lLCBhbmQgdGhlXG4gICAgICAgICBjb250aW51b3VzLW9ubHkga25vYnMuIC0tPlxuICAgIDxzcGF0aWFsLW9ic2VydmF0aW9ucy1wYW5lbFxuICAgICAgW2NvbnRyb2xzXT1cImNvbnRyb2xzXCJcbiAgICAgIFtkYXRhc2V0XT1cImRzXCJcbiAgICAgIFt2aWV3XT1cInZpZXdcIlxuICAgICAgW2dlbmVzXT1cImdlbmVzXCJcbiAgICAgIFtsZWdlbmRdPVwibGVnZW5kXCJcbiAgICAgIFtjb2xvckJhckNzc109XCJjb2xvckJhckNzc1wiXG4gICAgICBbc2VsZWN0aW9uXT1cInNlbGVjdGlvblwiXG4gICAgICBbc2VsZWN0ZWRDYXRlZ29yeV09XCJzZWxlY3RlZENhdGVnb3J5XCJcbiAgICAgIFtjb2xvcm1hcE9wdGlvbnNdPVwiY29sb3JtYXBPcHRpb25zXCJcbiAgICAgIFtpczNkXT1cImlzM2RcIlxuICAgICAgW29wZW5dPVwib3Blbi5vYnNlcnZhdGlvbnNcIlxuICAgICAgKG9wZW5DaGFuZ2UpPVwic2V0T3Blbignb2JzZXJ2YXRpb25zJywgJGV2ZW50KVwiXG4gICAgICAoY2F0ZWdvcnlDbGlja2VkKT1cInNlbGVjdENhdGVnb3J5KCRldmVudClcIlxuICAgID48L3NwYXRpYWwtb2JzZXJ2YXRpb25zLXBhbmVsPlxuXG4gICAgPCEtLSBEaXN0cmlidXRpb25zIG9mIHdoYXRldmVyIHRoZSBtYXAgaXMgY29sb3VyZWQgYnkuIEluIHRoZSBTQU1FIGRpYWxvZyBhc1xuICAgICAgICAgdGhlIGNvbG91ciBjb250cm9scyBvbiBwdXJwb3NlOiBjaGFuZ2luZyB0aGUgZ2VuZSBhbmQgd2F0Y2hpbmcgdGhlXG4gICAgICAgICBkaXN0cmlidXRpb24gbW92ZSBpcyBvbmUgYWN0aW9uLCBhbmQgdHdvIGZsb2F0aW5nIHdpbmRvd3MgbWFkZSB0aGF0XG4gICAgICAgICBoYXJkZXIgdG8gc2VlIHJhdGhlciB0aGFuIGVhc2llci4gLS0+XG4gICAgPGRpdiBjbGFzcz1cInNjLXNlY3Rpb24gc2MtY2hhcnRzXCI+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIHR5cGU9XCJidXR0b25cIlxuICAgICAgICBjbGFzcz1cInNjLWRpc2Nsb3N1cmVcIlxuICAgICAgICAoY2xpY2spPVwidG9nZ2xlQ2hhcnRzKClcIlxuICAgICAgICBbYXR0ci5hcmlhLWV4cGFuZGVkXT1cImNoYXJ0c09wZW5cIlxuICAgICAgICBbYXR0ci5hcmlhLWNvbnRyb2xzXT1cImNoYXJ0c0JvZHlJZFwiXG4gICAgICA+XG4gICAgICAgIDxpIGNsYXNzPVwicGlcIiBbY2xhc3MucGktY2hldnJvbi1yaWdodF09XCIhY2hhcnRzT3BlblwiIFtjbGFzcy5waS1jaGV2cm9uLWRvd25dPVwiY2hhcnRzT3BlblwiPjwvaT5cbiAgICAgICAgPHNwYW4+RGlzdHJpYnV0aW9uPC9zcGFuPlxuICAgICAgICA8c21hbGwgKm5nSWY9XCIhY2hhcnRzT3BlbiAmJiB2aWV3LmNvbG9yQnlcIj5vZiB7eyBjb2xvckJ5TGFiZWwgfX08L3NtYWxsPlxuICAgICAgPC9idXR0b24+XG4gICAgICA8IS0tIEtlcHQgTU9VTlRFRCB3aGVuIGNvbGxhcHNlZCwgb25seSBoaWRkZW46IGRlc3Ryb3lpbmcgaXQgd291bGQgdGhyb3dcbiAgICAgICAgICAgYXdheSB0aGUgY2hhcnQga2luZCBhbmQgZ3JvdXBpbmcgdGhlIHVzZXIgcGlja2VkLiBgYWN0aXZlYCBpcyB3aGF0XG4gICAgICAgICAgIHN0b3BzIGl0IGRyYXdpbmcgd2hpbGUgaXQgaGFzIG5vIHNpemUuIC0tPlxuICAgICAgPGRpdiBbaWRdPVwiY2hhcnRzQm9keUlkXCIgW2hpZGRlbl09XCIhY2hhcnRzT3BlblwiPlxuICAgICAgICA8c3BhdGlhbC1jaGFydHMgW2FjdGl2ZV09XCJ2aXNpYmxlICYmIGNoYXJ0c09wZW5cIj48L3NwYXRpYWwtY2hhcnRzPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwic2MtYnRuc1wiPlxuICAgICAgPHAtYnV0dG9uIGxhYmVsPVwiUmVzZXRcIiBzaXplPVwic21hbGxcIiBbdGV4dF09XCJ0cnVlXCIgKG9uQ2xpY2spPVwicmVzZXQoKVwiPjwvcC1idXR0b24+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9wLWRpYWxvZz5cbiJdfQ==
@@ -26,6 +26,8 @@ export class SpatialGeneStyleComponent {
26
26
  this.glyph = 'circle';
27
27
  /** A note under the icons, e.g. where they show; none when null. */
28
28
  this.iconHint = null;
29
+ /** False for a colour alone (a cell group, or every gene drawn with one icon): no icon grid. */
30
+ this.showIcons = true;
29
31
  this.colorChange = new EventEmitter();
30
32
  this.glyphChange = new EventEmitter();
31
33
  /** Back to the gene's default icon and colour. */
@@ -41,11 +43,11 @@ export class SpatialGeneStyleComponent {
41
43
  this.colorChange.emit(rgbToHex(rgb));
42
44
  }
43
45
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: SpatialGeneStyleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
44
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: SpatialGeneStyleComponent, isStandalone: true, selector: "spatial-gene-style", inputs: { gene: "gene", what: "what", color: "color", glyph: "glyph", iconHint: "iconHint" }, outputs: { colorChange: "colorChange", glyphChange: "glyphChange", resetStyle: "resetStyle" }, ngImport: i0, template: "<div class=\"sc-style-pop\">\n <div class=\"sc-style-title\">{{ what }} Icon</div>\n <div class=\"sc-style-icons\" role=\"radiogroup\" [attr.aria-label]=\"'Icon for ' + gene\">\n <button\n type=\"button\"\n *ngFor=\"let opt of glyphOptions\"\n class=\"sc-style-icon\"\n role=\"radio\"\n [attr.aria-checked]=\"opt.value === glyph\"\n [class.active]=\"opt.value === glyph\"\n [title]=\"opt.label\"\n (click)=\"glyphChange.emit(opt.value)\"\n >\n <svg viewBox=\"-1.2 -1.2 2.4 2.4\" class=\"sc-glyph-svg\">\n <polygon [attr.points]=\"opt.points\"></polygon>\n </svg>\n </button>\n </div>\n <small class=\"sc-hint\" *ngIf=\"iconHint\">{{ iconHint }}</small>\n <div class=\"sc-style-title\">{{ what }} Color</div>\n <div class=\"sc-style-color\">\n <label class=\"sc-style-swatch\" [style.background]=\"color\" title=\"Pick a colour\">\n <input type=\"color\" [value]=\"color\" (change)=\"colorChange.emit($any($event.target).value)\" />\n </label>\n <input\n pInputText\n class=\"sc-style-hex\"\n [value]=\"color\"\n maxlength=\"7\"\n [attr.aria-label]=\"'Hex colour for ' + gene\"\n (change)=\"onHex($any($event.target).value)\"\n (keydown.enter)=\"onHex($any($event.target).value)\"\n />\n </div>\n <div class=\"sc-style-title sc-style-sub\">Presets</div>\n <div class=\"sc-style-presets\">\n <button\n type=\"button\"\n *ngFor=\"let c of colorPresets\"\n class=\"sc-style-preset\"\n [style.background]=\"c\"\n [class.active]=\"c === color.toLowerCase()\"\n [title]=\"c\"\n [attr.aria-label]=\"'Colour ' + c\"\n (click)=\"colorChange.emit(c)\"\n ></button>\n </div>\n <p-button\n label=\"Reset to default\"\n icon=\"pi pi-refresh\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"sc-style-reset\"\n (onClick)=\"resetStyle.emit()\"\n ></p-button>\n</div>\n", styles: ["::ng-deep .sc-gene-style .p-overlaypanel-content{padding:.75rem}.sc-style-pop{display:flex;flex-direction:column;gap:.5rem;width:15rem}.sc-style-title{font-weight:600;font-size:.9rem}.sc-style-sub{font-size:.75rem;text-transform:uppercase;opacity:.7}.sc-style-icons,.sc-style-presets{display:grid;grid-template-columns:repeat(5,1fr);gap:.35rem}.sc-style-icon{display:inline-flex;align-items:center;justify-content:center;height:1.9rem;border:1px solid var(--surface-border, rgba(0, 0, 0, .15));border-radius:4px;background:transparent;color:var(--text-color, inherit);cursor:pointer}.sc-style-icon .sc-glyph-svg{width:1.1rem;height:1.1rem}.sc-style-icon.active{border-color:var(--primary-color, #3b82f6);background:var(--highlight-bg, rgba(59, 130, 246, .12))}.sc-style-color{display:flex;gap:.5rem;align-items:center}.sc-style-swatch{position:relative;flex:0 0 3rem;height:2rem;border-radius:4px;border:1px solid rgba(0,0,0,.2);cursor:pointer}.sc-style-swatch input{position:absolute;inset:0;opacity:0;width:100%;height:100%;cursor:pointer}.sc-style-hex{flex:1 1 auto;min-width:0;font-family:monospace}.sc-style-preset{width:1.4rem;height:1.4rem;justify-self:center;border-radius:50%;border:2px solid transparent;cursor:pointer}.sc-style-preset.active{border-color:var(--text-color, #000)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.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: InputTextModule }, { kind: "directive", type: i3.InputText, selector: "[pInputText]", inputs: ["variant"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
46
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.9", type: SpatialGeneStyleComponent, isStandalone: true, selector: "spatial-gene-style", inputs: { gene: "gene", what: "what", color: "color", glyph: "glyph", iconHint: "iconHint", showIcons: "showIcons" }, outputs: { colorChange: "colorChange", glyphChange: "glyphChange", resetStyle: "resetStyle" }, ngImport: i0, template: "<div class=\"sc-style-pop\">\n <ng-container *ngIf=\"showIcons\">\n <div class=\"sc-style-title\">{{ what }} Icon</div>\n <div class=\"sc-style-icons\" role=\"radiogroup\" [attr.aria-label]=\"'Icon for ' + gene\">\n <button\n type=\"button\"\n *ngFor=\"let opt of glyphOptions\"\n class=\"sc-style-icon\"\n role=\"radio\"\n [attr.aria-checked]=\"opt.value === glyph\"\n [class.active]=\"opt.value === glyph\"\n [title]=\"opt.label\"\n (click)=\"glyphChange.emit(opt.value)\"\n >\n <svg viewBox=\"-1.2 -1.2 2.4 2.4\" class=\"sc-glyph-svg\">\n <polygon [attr.points]=\"opt.points\"></polygon>\n </svg>\n </button>\n </div>\n <small class=\"sc-hint\" *ngIf=\"iconHint\">{{ iconHint }}</small>\n </ng-container>\n <div class=\"sc-style-title\">{{ what }} Color</div>\n <div class=\"sc-style-color\">\n <label class=\"sc-style-swatch\" [style.background]=\"color\" title=\"Pick a colour\">\n <input type=\"color\" [value]=\"color\" (change)=\"colorChange.emit($any($event.target).value)\" />\n </label>\n <input\n pInputText\n class=\"sc-style-hex\"\n [value]=\"color\"\n maxlength=\"7\"\n [attr.aria-label]=\"'Hex colour for ' + gene\"\n (change)=\"onHex($any($event.target).value)\"\n (keydown.enter)=\"onHex($any($event.target).value)\"\n />\n </div>\n <div class=\"sc-style-title sc-style-sub\">Presets</div>\n <div class=\"sc-style-presets\">\n <button\n type=\"button\"\n *ngFor=\"let c of colorPresets\"\n class=\"sc-style-preset\"\n [style.background]=\"c\"\n [class.active]=\"c === color.toLowerCase()\"\n [title]=\"c\"\n [attr.aria-label]=\"'Colour ' + c\"\n (click)=\"colorChange.emit(c)\"\n ></button>\n </div>\n <p-button\n label=\"Reset to default\"\n icon=\"pi pi-refresh\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"sc-style-reset\"\n (onClick)=\"resetStyle.emit()\"\n ></p-button>\n</div>\n", styles: ["::ng-deep .sc-gene-style .p-overlaypanel-content{padding:.75rem}.sc-style-pop{display:flex;flex-direction:column;gap:.5rem;width:15rem}.sc-style-title{font-weight:600;font-size:.9rem}.sc-style-sub{font-size:.75rem;text-transform:uppercase;opacity:.7}.sc-style-icons,.sc-style-presets{display:grid;grid-template-columns:repeat(5,1fr);gap:.35rem}.sc-style-icon{display:inline-flex;align-items:center;justify-content:center;height:1.9rem;border:1px solid var(--surface-border, rgba(0, 0, 0, .15));border-radius:4px;background:transparent;color:var(--text-color, inherit);cursor:pointer}.sc-style-icon .sc-glyph-svg{width:1.1rem;height:1.1rem}.sc-style-icon.active{border-color:var(--primary-color, #3b82f6);background:var(--highlight-bg, rgba(59, 130, 246, .12))}.sc-style-color{display:flex;gap:.5rem;align-items:center}.sc-style-swatch{position:relative;flex:0 0 3rem;height:2rem;border-radius:4px;border:1px solid rgba(0,0,0,.2);cursor:pointer}.sc-style-swatch input{position:absolute;inset:0;opacity:0;width:100%;height:100%;cursor:pointer}.sc-style-hex{flex:1 1 auto;min-width:0;font-family:monospace}.sc-style-preset{width:1.4rem;height:1.4rem;justify-self:center;border-radius:50%;border:2px solid transparent;cursor:pointer}.sc-style-preset.active{border-color:var(--text-color, #000)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "component", type: i2.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: InputTextModule }, { kind: "directive", type: i3.InputText, selector: "[pInputText]", inputs: ["variant"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
45
47
  }
46
48
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: SpatialGeneStyleComponent, decorators: [{
47
49
  type: Component,
48
- args: [{ selector: 'spatial-gene-style', standalone: true, imports: [CommonModule, ButtonModule, InputTextModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"sc-style-pop\">\n <div class=\"sc-style-title\">{{ what }} Icon</div>\n <div class=\"sc-style-icons\" role=\"radiogroup\" [attr.aria-label]=\"'Icon for ' + gene\">\n <button\n type=\"button\"\n *ngFor=\"let opt of glyphOptions\"\n class=\"sc-style-icon\"\n role=\"radio\"\n [attr.aria-checked]=\"opt.value === glyph\"\n [class.active]=\"opt.value === glyph\"\n [title]=\"opt.label\"\n (click)=\"glyphChange.emit(opt.value)\"\n >\n <svg viewBox=\"-1.2 -1.2 2.4 2.4\" class=\"sc-glyph-svg\">\n <polygon [attr.points]=\"opt.points\"></polygon>\n </svg>\n </button>\n </div>\n <small class=\"sc-hint\" *ngIf=\"iconHint\">{{ iconHint }}</small>\n <div class=\"sc-style-title\">{{ what }} Color</div>\n <div class=\"sc-style-color\">\n <label class=\"sc-style-swatch\" [style.background]=\"color\" title=\"Pick a colour\">\n <input type=\"color\" [value]=\"color\" (change)=\"colorChange.emit($any($event.target).value)\" />\n </label>\n <input\n pInputText\n class=\"sc-style-hex\"\n [value]=\"color\"\n maxlength=\"7\"\n [attr.aria-label]=\"'Hex colour for ' + gene\"\n (change)=\"onHex($any($event.target).value)\"\n (keydown.enter)=\"onHex($any($event.target).value)\"\n />\n </div>\n <div class=\"sc-style-title sc-style-sub\">Presets</div>\n <div class=\"sc-style-presets\">\n <button\n type=\"button\"\n *ngFor=\"let c of colorPresets\"\n class=\"sc-style-preset\"\n [style.background]=\"c\"\n [class.active]=\"c === color.toLowerCase()\"\n [title]=\"c\"\n [attr.aria-label]=\"'Colour ' + c\"\n (click)=\"colorChange.emit(c)\"\n ></button>\n </div>\n <p-button\n label=\"Reset to default\"\n icon=\"pi pi-refresh\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"sc-style-reset\"\n (onClick)=\"resetStyle.emit()\"\n ></p-button>\n</div>\n", styles: ["::ng-deep .sc-gene-style .p-overlaypanel-content{padding:.75rem}.sc-style-pop{display:flex;flex-direction:column;gap:.5rem;width:15rem}.sc-style-title{font-weight:600;font-size:.9rem}.sc-style-sub{font-size:.75rem;text-transform:uppercase;opacity:.7}.sc-style-icons,.sc-style-presets{display:grid;grid-template-columns:repeat(5,1fr);gap:.35rem}.sc-style-icon{display:inline-flex;align-items:center;justify-content:center;height:1.9rem;border:1px solid var(--surface-border, rgba(0, 0, 0, .15));border-radius:4px;background:transparent;color:var(--text-color, inherit);cursor:pointer}.sc-style-icon .sc-glyph-svg{width:1.1rem;height:1.1rem}.sc-style-icon.active{border-color:var(--primary-color, #3b82f6);background:var(--highlight-bg, rgba(59, 130, 246, .12))}.sc-style-color{display:flex;gap:.5rem;align-items:center}.sc-style-swatch{position:relative;flex:0 0 3rem;height:2rem;border-radius:4px;border:1px solid rgba(0,0,0,.2);cursor:pointer}.sc-style-swatch input{position:absolute;inset:0;opacity:0;width:100%;height:100%;cursor:pointer}.sc-style-hex{flex:1 1 auto;min-width:0;font-family:monospace}.sc-style-preset{width:1.4rem;height:1.4rem;justify-self:center;border-radius:50%;border:2px solid transparent;cursor:pointer}.sc-style-preset.active{border-color:var(--text-color, #000)}\n"] }]
50
+ args: [{ selector: 'spatial-gene-style', standalone: true, imports: [CommonModule, ButtonModule, InputTextModule], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"sc-style-pop\">\n <ng-container *ngIf=\"showIcons\">\n <div class=\"sc-style-title\">{{ what }} Icon</div>\n <div class=\"sc-style-icons\" role=\"radiogroup\" [attr.aria-label]=\"'Icon for ' + gene\">\n <button\n type=\"button\"\n *ngFor=\"let opt of glyphOptions\"\n class=\"sc-style-icon\"\n role=\"radio\"\n [attr.aria-checked]=\"opt.value === glyph\"\n [class.active]=\"opt.value === glyph\"\n [title]=\"opt.label\"\n (click)=\"glyphChange.emit(opt.value)\"\n >\n <svg viewBox=\"-1.2 -1.2 2.4 2.4\" class=\"sc-glyph-svg\">\n <polygon [attr.points]=\"opt.points\"></polygon>\n </svg>\n </button>\n </div>\n <small class=\"sc-hint\" *ngIf=\"iconHint\">{{ iconHint }}</small>\n </ng-container>\n <div class=\"sc-style-title\">{{ what }} Color</div>\n <div class=\"sc-style-color\">\n <label class=\"sc-style-swatch\" [style.background]=\"color\" title=\"Pick a colour\">\n <input type=\"color\" [value]=\"color\" (change)=\"colorChange.emit($any($event.target).value)\" />\n </label>\n <input\n pInputText\n class=\"sc-style-hex\"\n [value]=\"color\"\n maxlength=\"7\"\n [attr.aria-label]=\"'Hex colour for ' + gene\"\n (change)=\"onHex($any($event.target).value)\"\n (keydown.enter)=\"onHex($any($event.target).value)\"\n />\n </div>\n <div class=\"sc-style-title sc-style-sub\">Presets</div>\n <div class=\"sc-style-presets\">\n <button\n type=\"button\"\n *ngFor=\"let c of colorPresets\"\n class=\"sc-style-preset\"\n [style.background]=\"c\"\n [class.active]=\"c === color.toLowerCase()\"\n [title]=\"c\"\n [attr.aria-label]=\"'Colour ' + c\"\n (click)=\"colorChange.emit(c)\"\n ></button>\n </div>\n <p-button\n label=\"Reset to default\"\n icon=\"pi pi-refresh\"\n size=\"small\"\n [text]=\"true\"\n styleClass=\"sc-style-reset\"\n (onClick)=\"resetStyle.emit()\"\n ></p-button>\n</div>\n", styles: ["::ng-deep .sc-gene-style .p-overlaypanel-content{padding:.75rem}.sc-style-pop{display:flex;flex-direction:column;gap:.5rem;width:15rem}.sc-style-title{font-weight:600;font-size:.9rem}.sc-style-sub{font-size:.75rem;text-transform:uppercase;opacity:.7}.sc-style-icons,.sc-style-presets{display:grid;grid-template-columns:repeat(5,1fr);gap:.35rem}.sc-style-icon{display:inline-flex;align-items:center;justify-content:center;height:1.9rem;border:1px solid var(--surface-border, rgba(0, 0, 0, .15));border-radius:4px;background:transparent;color:var(--text-color, inherit);cursor:pointer}.sc-style-icon .sc-glyph-svg{width:1.1rem;height:1.1rem}.sc-style-icon.active{border-color:var(--primary-color, #3b82f6);background:var(--highlight-bg, rgba(59, 130, 246, .12))}.sc-style-color{display:flex;gap:.5rem;align-items:center}.sc-style-swatch{position:relative;flex:0 0 3rem;height:2rem;border-radius:4px;border:1px solid rgba(0,0,0,.2);cursor:pointer}.sc-style-swatch input{position:absolute;inset:0;opacity:0;width:100%;height:100%;cursor:pointer}.sc-style-hex{flex:1 1 auto;min-width:0;font-family:monospace}.sc-style-preset{width:1.4rem;height:1.4rem;justify-self:center;border-radius:50%;border:2px solid transparent;cursor:pointer}.sc-style-preset.active{border-color:var(--text-color, #000)}\n"] }]
49
51
  }], propDecorators: { gene: [{
50
52
  type: Input
51
53
  }], what: [{
@@ -56,6 +58,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
56
58
  type: Input
57
59
  }], iconHint: [{
58
60
  type: Input
61
+ }], showIcons: [{
62
+ type: Input
59
63
  }], colorChange: [{
60
64
  type: Output
61
65
  }], glyphChange: [{
@@ -63,4 +67,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
63
67
  }], resetStyle: [{
64
68
  type: Output
65
69
  }] } });
66
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BhdGlhbC1nZW5lLXN0eWxlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvc3BhdGlhbC1jb250cm9scy9zcGF0aWFsLWdlbmUtc3R5bGUvc3BhdGlhbC1nZW5lLXN0eWxlLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvc3BhdGlhbC1jb250cm9scy9zcGF0aWFsLWdlbmUtc3R5bGUvc3BhdGlhbC1nZW5lLXN0eWxlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDaEcsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFHcEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxRQUFRLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUM3RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sbUNBQW1DLENBQUM7Ozs7O0FBRWxFOzs7O0dBSUc7QUFTSCxNQUFNLE9BQU8seUJBQXlCO0lBUnRDO1FBU0UsMENBQTBDO1FBQ2pDLFNBQUksR0FBRyxFQUFFLENBQUM7UUFDbkIsc0ZBQXNGO1FBQzdFLFNBQUksR0FBRyxFQUFFLENBQUM7UUFDbkIsb0NBQW9DO1FBQzNCLFVBQUssR0FBRyxTQUFTLENBQUM7UUFDM0IsdUJBQXVCO1FBQ2QsVUFBSyxHQUF3QixRQUFRLENBQUM7UUFDL0Msb0VBQW9FO1FBQzNELGFBQVEsR0FBa0IsSUFBSSxDQUFDO1FBQ3JCLGdCQUFXLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQUN6QyxnQkFBVyxHQUFHLElBQUksWUFBWSxFQUF1QixDQUFDO1FBQ3pFLGtEQUFrRDtRQUMvQixlQUFVLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUV0QyxpQkFBWSxHQUFHLGFBQWEsQ0FBQztRQUM3QixpQkFBWSxHQUFHLDJCQUEyQixDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztLQVF4RztJQU5DLHVGQUF1RjtJQUM3RSxLQUFLLENBQUMsSUFBWTtRQUMxQixNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDdEIsTUFBTSxHQUFHLEdBQUcsa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUNqRSxJQUFJLEdBQUc7WUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNoRCxDQUFDOzhHQXhCVSx5QkFBeUI7a0dBQXpCLHlCQUF5QiwyUUN2QnRDLDg1REF3REEscTBDRHRDWSxZQUFZLCtQQUFFLFlBQVksNlhBQUUsZUFBZTs7MkZBSzFDLHlCQUF5QjtrQkFSckMsU0FBUzsrQkFDRSxvQkFBb0IsY0FDbEIsSUFBSSxXQUNQLENBQUMsWUFBWSxFQUFFLFlBQVksRUFBRSxlQUFlLENBQUMsbUJBR3JDLHVCQUF1QixDQUFDLE1BQU07OEJBSXRDLElBQUk7c0JBQVosS0FBSztnQkFFRyxJQUFJO3NCQUFaLEtBQUs7Z0JBRUcsS0FBSztzQkFBYixLQUFLO2dCQUVHLEtBQUs7c0JBQWIsS0FBSztnQkFFRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNhLFdBQVc7c0JBQTdCLE1BQU07Z0JBQ1ksV0FBVztzQkFBN0IsTUFBTTtnQkFFWSxVQUFVO3NCQUE1QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT3V0cHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQnV0dG9uTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9idXR0b24nO1xuaW1wb3J0IHsgSW5wdXRUZXh0TW9kdWxlIH0gZnJvbSAncHJpbWVuZy9pbnB1dHRleHQnO1xuXG5pbXBvcnQgeyBUcmFuc2NyaXB0R2x5cGhOYW1lIH0gZnJvbSAnLi4vLi4vY29udHJhY3RzL2Rpc3BsYXktdHlwZXMnO1xuaW1wb3J0IHsgcGFyc2VDc3NDb2xvciwgcmdiVG9IZXggfSBmcm9tICcuLi8uLi9jb250cmFjdHMvY29sb3InO1xuaW1wb3J0IHsgREVGQVVMVF9DQVRFR09SSUNBTF9QQUxFVFRFIH0gZnJvbSAnLi4vLi4vc3BhdGlhbC9zcGF0aWFsLWVuY29kaW5nJztcbmltcG9ydCB7IEdMWVBIX09QVElPTlMgfSBmcm9tICcuLi8uLi9zcGF0aWFsL3NwYXRpYWwtcGFuZWwtbW9kZWwnO1xuXG4vKipcbiAqIE9uZSBnZW5lJ3MgaWNvbiBhbmQgY29sb3VyOiB0aGUgaWNvbiBncmlkLCBhIGNvbG91ciBwaWNrZXIgd2l0aCBpdHMgaGV4IHZhbHVlLCBwcmVzZXRzLCBhbmRcbiAqIGEgcmVzZXQg4oCUIHRoZSBjb250ZW50IG9mIGEgcG9wb3ZlciBpdHMgaG9zdCBvcGVucyBvbiB0aGUgZ2VuZSdzIHN3YXRjaC4gV3JpdGVzIG5vdGhpbmcgaXRzZWxmOlxuICogaXQgcmVwb3J0cyB0aGUgY2hvaWNlLCBhbmQgdGhlIGhvc3Qgc3RvcmVzIGl0IHdoZXJlIGl0IGJlbG9uZ3MuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3NwYXRpYWwtZ2VuZS1zdHlsZScsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIEJ1dHRvbk1vZHVsZSwgSW5wdXRUZXh0TW9kdWxlXSxcbiAgdGVtcGxhdGVVcmw6ICcuL3NwYXRpYWwtZ2VuZS1zdHlsZS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3NwYXRpYWwtZ2VuZS1zdHlsZS5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgU3BhdGlhbEdlbmVTdHlsZUNvbXBvbmVudCB7XG4gIC8qKiBUaGUgZ2VuZSwgZm9yIHRoZSBjb250cm9scycgbGFiZWxzLiAqL1xuICBASW5wdXQoKSBnZW5lID0gJyc7XG4gIC8qKiBXaGF0IHRoZSBpY29ucyBhbmQgY29sb3VyIGFyZSBvZiAoXCJPYnNlcnZhdGlvblwiLCBcIlRyYW5zY3JpcHRcIiksIGZvciB0aGUgdGl0bGVzLiAqL1xuICBASW5wdXQoKSB3aGF0ID0gJyc7XG4gIC8qKiBUaGUgZ2VuZSdzIGNvbG91ciwgYCNycmdnYmJgLiAqL1xuICBASW5wdXQoKSBjb2xvciA9ICcjZmZmZmZmJztcbiAgLyoqIFRoZSBnZW5lJ3MgaWNvbi4gKi9cbiAgQElucHV0KCkgZ2x5cGg6IFRyYW5zY3JpcHRHbHlwaE5hbWUgPSAnY2lyY2xlJztcbiAgLyoqIEEgbm90ZSB1bmRlciB0aGUgaWNvbnMsIGUuZy4gd2hlcmUgdGhleSBzaG93OyBub25lIHdoZW4gbnVsbC4gKi9cbiAgQElucHV0KCkgaWNvbkhpbnQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBAT3V0cHV0KCkgcmVhZG9ubHkgY29sb3JDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcbiAgQE91dHB1dCgpIHJlYWRvbmx5IGdseXBoQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxUcmFuc2NyaXB0R2x5cGhOYW1lPigpO1xuICAvKiogQmFjayB0byB0aGUgZ2VuZSdzIGRlZmF1bHQgaWNvbiBhbmQgY29sb3VyLiAqL1xuICBAT3V0cHV0KCkgcmVhZG9ubHkgcmVzZXRTdHlsZSA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZ2x5cGhPcHRpb25zID0gR0xZUEhfT1BUSU9OUztcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGNvbG9yUHJlc2V0cyA9IERFRkFVTFRfQ0FURUdPUklDQUxfUEFMRVRURS5zbGljZSgwLCAxMCkubWFwKChjKSA9PiBjLnRvTG93ZXJDYXNlKCkpO1xuXG4gIC8qKiBBIHR5cGVkIGhleCBjb2xvdXIsIGFjY2VwdGVkIGFzIGAjcnJnZ2JiYCBvciBgcnJnZ2JiYDsgYW55dGhpbmcgZWxzZSBpcyBpZ25vcmVkLiAqL1xuICBwcm90ZWN0ZWQgb25IZXgodGV4dDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgdCA9IHRleHQudHJpbSgpO1xuICAgIGNvbnN0IHJnYiA9IC9eIz9bMC05YS1mXXs2fSQvaS50ZXN0KHQpID8gcGFyc2VDc3NDb2xvcih0KSA6IG51bGw7XG4gICAgaWYgKHJnYikgdGhpcy5jb2xvckNoYW5nZS5lbWl0KHJnYlRvSGV4KHJnYikpO1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwic2Mtc3R5bGUtcG9wXCI+XG4gIDxkaXYgY2xhc3M9XCJzYy1zdHlsZS10aXRsZVwiPnt7IHdoYXQgfX0gSWNvbjwvZGl2PlxuICA8ZGl2IGNsYXNzPVwic2Mtc3R5bGUtaWNvbnNcIiByb2xlPVwicmFkaW9ncm91cFwiIFthdHRyLmFyaWEtbGFiZWxdPVwiJ0ljb24gZm9yICcgKyBnZW5lXCI+XG4gICAgPGJ1dHRvblxuICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAqbmdGb3I9XCJsZXQgb3B0IG9mIGdseXBoT3B0aW9uc1wiXG4gICAgICBjbGFzcz1cInNjLXN0eWxlLWljb25cIlxuICAgICAgcm9sZT1cInJhZGlvXCJcbiAgICAgIFthdHRyLmFyaWEtY2hlY2tlZF09XCJvcHQudmFsdWUgPT09IGdseXBoXCJcbiAgICAgIFtjbGFzcy5hY3RpdmVdPVwib3B0LnZhbHVlID09PSBnbHlwaFwiXG4gICAgICBbdGl0bGVdPVwib3B0LmxhYmVsXCJcbiAgICAgIChjbGljayk9XCJnbHlwaENoYW5nZS5lbWl0KG9wdC52YWx1ZSlcIlxuICAgID5cbiAgICAgIDxzdmcgdmlld0JveD1cIi0xLjIgLTEuMiAyLjQgMi40XCIgY2xhc3M9XCJzYy1nbHlwaC1zdmdcIj5cbiAgICAgICAgPHBvbHlnb24gW2F0dHIucG9pbnRzXT1cIm9wdC5wb2ludHNcIj48L3BvbHlnb24+XG4gICAgICA8L3N2Zz5cbiAgICA8L2J1dHRvbj5cbiAgPC9kaXY+XG4gIDxzbWFsbCBjbGFzcz1cInNjLWhpbnRcIiAqbmdJZj1cImljb25IaW50XCI+e3sgaWNvbkhpbnQgfX08L3NtYWxsPlxuICA8ZGl2IGNsYXNzPVwic2Mtc3R5bGUtdGl0bGVcIj57eyB3aGF0IH19IENvbG9yPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJzYy1zdHlsZS1jb2xvclwiPlxuICAgIDxsYWJlbCBjbGFzcz1cInNjLXN0eWxlLXN3YXRjaFwiIFtzdHlsZS5iYWNrZ3JvdW5kXT1cImNvbG9yXCIgdGl0bGU9XCJQaWNrIGEgY29sb3VyXCI+XG4gICAgICA8aW5wdXQgdHlwZT1cImNvbG9yXCIgW3ZhbHVlXT1cImNvbG9yXCIgKGNoYW5nZSk9XCJjb2xvckNoYW5nZS5lbWl0KCRhbnkoJGV2ZW50LnRhcmdldCkudmFsdWUpXCIgLz5cbiAgICA8L2xhYmVsPlxuICAgIDxpbnB1dFxuICAgICAgcElucHV0VGV4dFxuICAgICAgY2xhc3M9XCJzYy1zdHlsZS1oZXhcIlxuICAgICAgW3ZhbHVlXT1cImNvbG9yXCJcbiAgICAgIG1heGxlbmd0aD1cIjdcIlxuICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCInSGV4IGNvbG91ciBmb3IgJyArIGdlbmVcIlxuICAgICAgKGNoYW5nZSk9XCJvbkhleCgkYW55KCRldmVudC50YXJnZXQpLnZhbHVlKVwiXG4gICAgICAoa2V5ZG93bi5lbnRlcik9XCJvbkhleCgkYW55KCRldmVudC50YXJnZXQpLnZhbHVlKVwiXG4gICAgLz5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJzYy1zdHlsZS10aXRsZSBzYy1zdHlsZS1zdWJcIj5QcmVzZXRzPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJzYy1zdHlsZS1wcmVzZXRzXCI+XG4gICAgPGJ1dHRvblxuICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAqbmdGb3I9XCJsZXQgYyBvZiBjb2xvclByZXNldHNcIlxuICAgICAgY2xhc3M9XCJzYy1zdHlsZS1wcmVzZXRcIlxuICAgICAgW3N0eWxlLmJhY2tncm91bmRdPVwiY1wiXG4gICAgICBbY2xhc3MuYWN0aXZlXT1cImMgPT09IGNvbG9yLnRvTG93ZXJDYXNlKClcIlxuICAgICAgW3RpdGxlXT1cImNcIlxuICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCInQ29sb3VyICcgKyBjXCJcbiAgICAgIChjbGljayk9XCJjb2xvckNoYW5nZS5lbWl0KGMpXCJcbiAgICA+PC9idXR0b24+XG4gIDwvZGl2PlxuICA8cC1idXR0b25cbiAgICBsYWJlbD1cIlJlc2V0IHRvIGRlZmF1bHRcIlxuICAgIGljb249XCJwaSBwaS1yZWZyZXNoXCJcbiAgICBzaXplPVwic21hbGxcIlxuICAgIFt0ZXh0XT1cInRydWVcIlxuICAgIHN0eWxlQ2xhc3M9XCJzYy1zdHlsZS1yZXNldFwiXG4gICAgKG9uQ2xpY2spPVwicmVzZXRTdHlsZS5lbWl0KClcIlxuICA+PC9wLWJ1dHRvbj5cbjwvZGl2PlxuIl19
70
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BhdGlhbC1nZW5lLXN0eWxlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvc3BhdGlhbC1jb250cm9scy9zcGF0aWFsLWdlbmUtc3R5bGUvc3BhdGlhbC1nZW5lLXN0eWxlLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvc3BhdGlhbC1jb250cm9scy9zcGF0aWFsLWdlbmUtc3R5bGUvc3BhdGlhbC1nZW5lLXN0eWxlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDaEcsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFHcEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxRQUFRLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUM3RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sbUNBQW1DLENBQUM7Ozs7O0FBRWxFOzs7O0dBSUc7QUFTSCxNQUFNLE9BQU8seUJBQXlCO0lBUnRDO1FBU0UsMENBQTBDO1FBQ2pDLFNBQUksR0FBRyxFQUFFLENBQUM7UUFDbkIsc0ZBQXNGO1FBQzdFLFNBQUksR0FBRyxFQUFFLENBQUM7UUFDbkIsb0NBQW9DO1FBQzNCLFVBQUssR0FBRyxTQUFTLENBQUM7UUFDM0IsdUJBQXVCO1FBQ2QsVUFBSyxHQUF3QixRQUFRLENBQUM7UUFDL0Msb0VBQW9FO1FBQzNELGFBQVEsR0FBa0IsSUFBSSxDQUFDO1FBQ3hDLGdHQUFnRztRQUN2RixjQUFTLEdBQUcsSUFBSSxDQUFDO1FBQ1AsZ0JBQVcsR0FBRyxJQUFJLFlBQVksRUFBVSxDQUFDO1FBQ3pDLGdCQUFXLEdBQUcsSUFBSSxZQUFZLEVBQXVCLENBQUM7UUFDekUsa0RBQWtEO1FBQy9CLGVBQVUsR0FBRyxJQUFJLFlBQVksRUFBUSxDQUFDO1FBRXRDLGlCQUFZLEdBQUcsYUFBYSxDQUFDO1FBQzdCLGlCQUFZLEdBQUcsMkJBQTJCLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO0tBUXhHO0lBTkMsdUZBQXVGO0lBQzdFLEtBQUssQ0FBQyxJQUFZO1FBQzFCLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUN0QixNQUFNLEdBQUcsR0FBRyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQ2pFLElBQUksR0FBRztZQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ2hELENBQUM7OEdBMUJVLHlCQUF5QjtrR0FBekIseUJBQXlCLG1TQ3ZCdEMsMi9EQTBEQSxxMENEeENZLFlBQVksK1BBQUUsWUFBWSw2WEFBRSxlQUFlOzsyRkFLMUMseUJBQXlCO2tCQVJyQyxTQUFTOytCQUNFLG9CQUFvQixjQUNsQixJQUFJLFdBQ1AsQ0FBQyxZQUFZLEVBQUUsWUFBWSxFQUFFLGVBQWUsQ0FBQyxtQkFHckMsdUJBQXVCLENBQUMsTUFBTTs4QkFJdEMsSUFBSTtzQkFBWixLQUFLO2dCQUVHLElBQUk7c0JBQVosS0FBSztnQkFFRyxLQUFLO3NCQUFiLEtBQUs7Z0JBRUcsS0FBSztzQkFBYixLQUFLO2dCQUVHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBRUcsU0FBUztzQkFBakIsS0FBSztnQkFDYSxXQUFXO3NCQUE3QixNQUFNO2dCQUNZLFdBQVc7c0JBQTdCLE1BQU07Z0JBRVksVUFBVTtzQkFBNUIsTUFBTSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LCBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE91dHB1dCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEJ1dHRvbk1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvYnV0dG9uJztcbmltcG9ydCB7IElucHV0VGV4dE1vZHVsZSB9IGZyb20gJ3ByaW1lbmcvaW5wdXR0ZXh0JztcblxuaW1wb3J0IHsgVHJhbnNjcmlwdEdseXBoTmFtZSB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cy9kaXNwbGF5LXR5cGVzJztcbmltcG9ydCB7IHBhcnNlQ3NzQ29sb3IsIHJnYlRvSGV4IH0gZnJvbSAnLi4vLi4vY29udHJhY3RzL2NvbG9yJztcbmltcG9ydCB7IERFRkFVTFRfQ0FURUdPUklDQUxfUEFMRVRURSB9IGZyb20gJy4uLy4uL3NwYXRpYWwvc3BhdGlhbC1lbmNvZGluZyc7XG5pbXBvcnQgeyBHTFlQSF9PUFRJT05TIH0gZnJvbSAnLi4vLi4vc3BhdGlhbC9zcGF0aWFsLXBhbmVsLW1vZGVsJztcblxuLyoqXG4gKiBPbmUgZ2VuZSdzIGljb24gYW5kIGNvbG91cjogdGhlIGljb24gZ3JpZCwgYSBjb2xvdXIgcGlja2VyIHdpdGggaXRzIGhleCB2YWx1ZSwgcHJlc2V0cywgYW5kXG4gKiBhIHJlc2V0IOKAlCB0aGUgY29udGVudCBvZiBhIHBvcG92ZXIgaXRzIGhvc3Qgb3BlbnMgb24gdGhlIGdlbmUncyBzd2F0Y2guIFdyaXRlcyBub3RoaW5nIGl0c2VsZjpcbiAqIGl0IHJlcG9ydHMgdGhlIGNob2ljZSwgYW5kIHRoZSBob3N0IHN0b3JlcyBpdCB3aGVyZSBpdCBiZWxvbmdzLlxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdzcGF0aWFsLWdlbmUtc3R5bGUnLFxuICBzdGFuZGFsb25lOiB0cnVlLFxuICBpbXBvcnRzOiBbQ29tbW9uTW9kdWxlLCBCdXR0b25Nb2R1bGUsIElucHV0VGV4dE1vZHVsZV0sXG4gIHRlbXBsYXRlVXJsOiAnLi9zcGF0aWFsLWdlbmUtc3R5bGUuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9zcGF0aWFsLWdlbmUtc3R5bGUuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIFNwYXRpYWxHZW5lU3R5bGVDb21wb25lbnQge1xuICAvKiogVGhlIGdlbmUsIGZvciB0aGUgY29udHJvbHMnIGxhYmVscy4gKi9cbiAgQElucHV0KCkgZ2VuZSA9ICcnO1xuICAvKiogV2hhdCB0aGUgaWNvbnMgYW5kIGNvbG91ciBhcmUgb2YgKFwiT2JzZXJ2YXRpb25cIiwgXCJUcmFuc2NyaXB0XCIpLCBmb3IgdGhlIHRpdGxlcy4gKi9cbiAgQElucHV0KCkgd2hhdCA9ICcnO1xuICAvKiogVGhlIGdlbmUncyBjb2xvdXIsIGAjcnJnZ2JiYC4gKi9cbiAgQElucHV0KCkgY29sb3IgPSAnI2ZmZmZmZic7XG4gIC8qKiBUaGUgZ2VuZSdzIGljb24uICovXG4gIEBJbnB1dCgpIGdseXBoOiBUcmFuc2NyaXB0R2x5cGhOYW1lID0gJ2NpcmNsZSc7XG4gIC8qKiBBIG5vdGUgdW5kZXIgdGhlIGljb25zLCBlLmcuIHdoZXJlIHRoZXkgc2hvdzsgbm9uZSB3aGVuIG51bGwuICovXG4gIEBJbnB1dCgpIGljb25IaW50OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgLyoqIEZhbHNlIGZvciBhIGNvbG91ciBhbG9uZSAoYSBjZWxsIGdyb3VwLCBvciBldmVyeSBnZW5lIGRyYXduIHdpdGggb25lIGljb24pOiBubyBpY29uIGdyaWQuICovXG4gIEBJbnB1dCgpIHNob3dJY29ucyA9IHRydWU7XG4gIEBPdXRwdXQoKSByZWFkb25seSBjb2xvckNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8c3RyaW5nPigpO1xuICBAT3V0cHV0KCkgcmVhZG9ubHkgZ2x5cGhDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPFRyYW5zY3JpcHRHbHlwaE5hbWU+KCk7XG4gIC8qKiBCYWNrIHRvIHRoZSBnZW5lJ3MgZGVmYXVsdCBpY29uIGFuZCBjb2xvdXIuICovXG4gIEBPdXRwdXQoKSByZWFkb25seSByZXNldFN0eWxlID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xuXG4gIHByb3RlY3RlZCByZWFkb25seSBnbHlwaE9wdGlvbnMgPSBHTFlQSF9PUFRJT05TO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgY29sb3JQcmVzZXRzID0gREVGQVVMVF9DQVRFR09SSUNBTF9QQUxFVFRFLnNsaWNlKDAsIDEwKS5tYXAoKGMpID0+IGMudG9Mb3dlckNhc2UoKSk7XG5cbiAgLyoqIEEgdHlwZWQgaGV4IGNvbG91ciwgYWNjZXB0ZWQgYXMgYCNycmdnYmJgIG9yIGBycmdnYmJgOyBhbnl0aGluZyBlbHNlIGlzIGlnbm9yZWQuICovXG4gIHByb3RlY3RlZCBvbkhleCh0ZXh0OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCB0ID0gdGV4dC50cmltKCk7XG4gICAgY29uc3QgcmdiID0gL14jP1swLTlhLWZdezZ9JC9pLnRlc3QodCkgPyBwYXJzZUNzc0NvbG9yKHQpIDogbnVsbDtcbiAgICBpZiAocmdiKSB0aGlzLmNvbG9yQ2hhbmdlLmVtaXQocmdiVG9IZXgocmdiKSk7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJzYy1zdHlsZS1wb3BcIj5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInNob3dJY29uc1wiPlxuICAgIDxkaXYgY2xhc3M9XCJzYy1zdHlsZS10aXRsZVwiPnt7IHdoYXQgfX0gSWNvbjwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJzYy1zdHlsZS1pY29uc1wiIHJvbGU9XCJyYWRpb2dyb3VwXCIgW2F0dHIuYXJpYS1sYWJlbF09XCInSWNvbiBmb3IgJyArIGdlbmVcIj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgICpuZ0Zvcj1cImxldCBvcHQgb2YgZ2x5cGhPcHRpb25zXCJcbiAgICAgICAgY2xhc3M9XCJzYy1zdHlsZS1pY29uXCJcbiAgICAgICAgcm9sZT1cInJhZGlvXCJcbiAgICAgICAgW2F0dHIuYXJpYS1jaGVja2VkXT1cIm9wdC52YWx1ZSA9PT0gZ2x5cGhcIlxuICAgICAgICBbY2xhc3MuYWN0aXZlXT1cIm9wdC52YWx1ZSA9PT0gZ2x5cGhcIlxuICAgICAgICBbdGl0bGVdPVwib3B0LmxhYmVsXCJcbiAgICAgICAgKGNsaWNrKT1cImdseXBoQ2hhbmdlLmVtaXQob3B0LnZhbHVlKVwiXG4gICAgICA+XG4gICAgICAgIDxzdmcgdmlld0JveD1cIi0xLjIgLTEuMiAyLjQgMi40XCIgY2xhc3M9XCJzYy1nbHlwaC1zdmdcIj5cbiAgICAgICAgICA8cG9seWdvbiBbYXR0ci5wb2ludHNdPVwib3B0LnBvaW50c1wiPjwvcG9seWdvbj5cbiAgICAgICAgPC9zdmc+XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgICA8c21hbGwgY2xhc3M9XCJzYy1oaW50XCIgKm5nSWY9XCJpY29uSGludFwiPnt7IGljb25IaW50IH19PC9zbWFsbD5cbiAgPC9uZy1jb250YWluZXI+XG4gIDxkaXYgY2xhc3M9XCJzYy1zdHlsZS10aXRsZVwiPnt7IHdoYXQgfX0gQ29sb3I8L2Rpdj5cbiAgPGRpdiBjbGFzcz1cInNjLXN0eWxlLWNvbG9yXCI+XG4gICAgPGxhYmVsIGNsYXNzPVwic2Mtc3R5bGUtc3dhdGNoXCIgW3N0eWxlLmJhY2tncm91bmRdPVwiY29sb3JcIiB0aXRsZT1cIlBpY2sgYSBjb2xvdXJcIj5cbiAgICAgIDxpbnB1dCB0eXBlPVwiY29sb3JcIiBbdmFsdWVdPVwiY29sb3JcIiAoY2hhbmdlKT1cImNvbG9yQ2hhbmdlLmVtaXQoJGFueSgkZXZlbnQudGFyZ2V0KS52YWx1ZSlcIiAvPlxuICAgIDwvbGFiZWw+XG4gICAgPGlucHV0XG4gICAgICBwSW5wdXRUZXh0XG4gICAgICBjbGFzcz1cInNjLXN0eWxlLWhleFwiXG4gICAgICBbdmFsdWVdPVwiY29sb3JcIlxuICAgICAgbWF4bGVuZ3RoPVwiN1wiXG4gICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIidIZXggY29sb3VyIGZvciAnICsgZ2VuZVwiXG4gICAgICAoY2hhbmdlKT1cIm9uSGV4KCRhbnkoJGV2ZW50LnRhcmdldCkudmFsdWUpXCJcbiAgICAgIChrZXlkb3duLmVudGVyKT1cIm9uSGV4KCRhbnkoJGV2ZW50LnRhcmdldCkudmFsdWUpXCJcbiAgICAvPlxuICA8L2Rpdj5cbiAgPGRpdiBjbGFzcz1cInNjLXN0eWxlLXRpdGxlIHNjLXN0eWxlLXN1YlwiPlByZXNldHM8L2Rpdj5cbiAgPGRpdiBjbGFzcz1cInNjLXN0eWxlLXByZXNldHNcIj5cbiAgICA8YnV0dG9uXG4gICAgICB0eXBlPVwiYnV0dG9uXCJcbiAgICAgICpuZ0Zvcj1cImxldCBjIG9mIGNvbG9yUHJlc2V0c1wiXG4gICAgICBjbGFzcz1cInNjLXN0eWxlLXByZXNldFwiXG4gICAgICBbc3R5bGUuYmFja2dyb3VuZF09XCJjXCJcbiAgICAgIFtjbGFzcy5hY3RpdmVdPVwiYyA9PT0gY29sb3IudG9Mb3dlckNhc2UoKVwiXG4gICAgICBbdGl0bGVdPVwiY1wiXG4gICAgICBbYXR0ci5hcmlhLWxhYmVsXT1cIidDb2xvdXIgJyArIGNcIlxuICAgICAgKGNsaWNrKT1cImNvbG9yQ2hhbmdlLmVtaXQoYylcIlxuICAgID48L2J1dHRvbj5cbiAgPC9kaXY+XG4gIDxwLWJ1dHRvblxuICAgIGxhYmVsPVwiUmVzZXQgdG8gZGVmYXVsdFwiXG4gICAgaWNvbj1cInBpIHBpLXJlZnJlc2hcIlxuICAgIHNpemU9XCJzbWFsbFwiXG4gICAgW3RleHRdPVwidHJ1ZVwiXG4gICAgc3R5bGVDbGFzcz1cInNjLXN0eWxlLXJlc2V0XCJcbiAgICAob25DbGljayk9XCJyZXNldFN0eWxlLmVtaXQoKVwiXG4gID48L3AtYnV0dG9uPlxuPC9kaXY+XG4iXX0=