@jax-data-science/sci-image-visualizer 0.13.0 → 0.15.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 (67) hide show
  1. package/esm2022/lib/channel-histogram/channel-histogram.component.mjs +39 -3
  2. package/esm2022/lib/channel-histogram/channel-tree.mjs +65 -0
  3. package/esm2022/lib/contracts/channel-histogram-api.contract.mjs +19 -1
  4. package/esm2022/lib/contracts/display-types.mjs +7 -1
  5. package/esm2022/lib/contracts/image.contract.mjs +1 -1
  6. package/esm2022/lib/contracts/spatial-dataset.contract.mjs +1 -1
  7. package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
  8. package/esm2022/lib/implementations/napari-js/napari-image-2d-scene.mjs +17 -2
  9. package/esm2022/lib/implementations/napari-js/napari-spatial-2d-scene.mjs +88 -10
  10. package/esm2022/lib/implementations/napari-js/napari-spatial-3d-scene.mjs +62 -13
  11. package/esm2022/lib/implementations/napari-js/napari-spatial-encoding.mjs +21 -1
  12. package/esm2022/lib/implementations/napari-js/napari-spatial-scene.mjs +5 -1
  13. package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +4 -1
  14. package/esm2022/lib/implementations/napari-js/spatial-tiles/categorical-lookup.mjs +26 -3
  15. package/esm2022/lib/implementations/napari-js/spatial-tiles/cell-layers.mjs +7 -9
  16. package/esm2022/lib/implementations/napari-js/spatial-tiles/density-layer.mjs +20 -4
  17. package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-hover.mjs +4 -2
  18. package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-jobs.mjs +4 -2
  19. package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-layers.mjs +42 -15
  20. package/esm2022/lib/implementations/osd/openseadragon-visualizer.service.mjs +3 -1
  21. package/esm2022/lib/spatial/lod.mjs +24 -3
  22. package/esm2022/lib/spatial/spatial-controls.facade.mjs +8 -3
  23. package/esm2022/lib/spatial/spatial-gene-filter.mjs +138 -0
  24. package/esm2022/lib/spatial/spatial-tile-merge.mjs +42 -1
  25. package/esm2022/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.mjs +47 -10
  26. package/esm2022/lib/spatial-controls/spatial-controls.component.mjs +4 -3
  27. package/esm2022/lib/spatial-controls/spatial-gene-style/spatial-gene-style.component.mjs +66 -0
  28. package/esm2022/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.mjs +106 -26
  29. package/esm2022/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.mjs +3 -3
  30. package/esm2022/lib/spatial-controls/spatial-key/spatial-key.component.mjs +3 -3
  31. package/esm2022/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.mjs +3 -3
  32. package/esm2022/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.mjs +110 -8
  33. package/esm2022/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.mjs +41 -9
  34. package/esm2022/lib/store/visualizer-store.service.mjs +67 -1
  35. package/fesm2022/{jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-DURPqs5a.mjs → jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-qUeMuBb0.mjs} +1250 -335
  36. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-qUeMuBb0.mjs.map +1 -0
  37. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-D0IQ6PjZ.mjs → jax-data-science-sci-image-visualizer-onnx-sam-session-U1ODcfYD.mjs} +3 -2
  38. package/fesm2022/{jax-data-science-sci-image-visualizer-onnx-sam-session-D0IQ6PjZ.mjs.map → jax-data-science-sci-image-visualizer-onnx-sam-session-U1ODcfYD.mjs.map} +1 -1
  39. package/fesm2022/jax-data-science-sci-image-visualizer.mjs +2 -1
  40. package/fesm2022/jax-data-science-sci-image-visualizer.mjs.map +1 -1
  41. package/lib/channel-histogram/channel-histogram.component.d.ts +14 -0
  42. package/lib/channel-histogram/channel-tree.d.ts +30 -0
  43. package/lib/contracts/channel-histogram-api.contract.d.ts +16 -0
  44. package/lib/contracts/display-types.d.ts +27 -0
  45. package/lib/contracts/image.contract.d.ts +8 -0
  46. package/lib/contracts/spatial-dataset.contract.d.ts +7 -0
  47. package/lib/contracts/visualizer.contract.d.ts +3 -0
  48. package/lib/implementations/napari-js/napari-image-2d-scene.d.ts +7 -0
  49. package/lib/implementations/napari-js/napari-spatial-2d-scene.d.ts +13 -2
  50. package/lib/implementations/napari-js/napari-spatial-encoding.d.ts +5 -0
  51. package/lib/implementations/napari-js/napari-spatial-scene.d.ts +4 -0
  52. package/lib/implementations/napari-js/napari-visualizer.service.d.ts +2 -0
  53. package/lib/implementations/napari-js/spatial-tiles/categorical-lookup.d.ts +6 -1
  54. package/lib/implementations/napari-js/spatial-tiles/transcript-hover.d.ts +4 -0
  55. package/lib/implementations/napari-js/spatial-tiles/transcript-layers.d.ts +3 -1
  56. package/lib/spatial/lod.d.ts +14 -2
  57. package/lib/spatial/spatial-controls.facade.d.ts +3 -0
  58. package/lib/spatial/spatial-gene-filter.d.ts +44 -0
  59. package/lib/spatial/spatial-tile-merge.d.ts +17 -0
  60. package/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.d.ts +18 -1
  61. package/lib/spatial-controls/spatial-gene-style/spatial-gene-style.component.d.ts +30 -0
  62. package/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.d.ts +39 -7
  63. package/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.d.ts +33 -1
  64. package/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.d.ts +13 -1
  65. package/lib/store/visualizer-store.service.d.ts +19 -0
  66. package/package.json +1 -1
  67. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-DURPqs5a.mjs.map +0 -1
@@ -100,6 +100,7 @@ export class SpatialControlsComponent {
100
100
  */
101
101
  this.genes = new GenePickerModel(() => this.controls, () => [
102
102
  ...(this.view?.transcriptGenes ?? []),
103
+ ...(this.view?.observationGenes ?? []),
103
104
  ...(this.view?.colorBy?.kind === 'feature' ? [this.view.colorBy.name] : []),
104
105
  ], (fn) => this.runAndMark(fn));
105
106
  /** The key — legend or colour bar — for the active colouring. Kept here, not in
@@ -365,7 +366,7 @@ export class SpatialControlsComponent {
365
366
  return this.key.refresh(this.controls, this.dataset, this.view, this.colormap, this.reverse);
366
367
  }
367
368
  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 }); }
368
- 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}: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 }); }
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 }); }
369
370
  }
370
371
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: SpatialControlsComponent, decorators: [{
371
372
  type: Component,
@@ -380,7 +381,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
380
381
  SpatialTranscriptsPanelComponent,
381
382
  SpatialObservationsPanelComponent,
382
383
  SpatialChartsComponent,
383
- ], 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}: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"] }]
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"] }]
384
385
  }], ctorParameters: () => [{ type: undefined, decorators: [{
385
386
  type: Inject,
386
387
  args: [VISUALIZER]
@@ -394,4 +395,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImpor
394
395
  }], visibleChange: [{
395
396
  type: Output
396
397
  }] } });
397
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BhdGlhbC1jb250cm9scy5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL3NwYXRpYWwtY29udHJvbHMvc3BhdGlhbC1jb250cm9scy5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9zcmMvbGliL3NwYXRpYWwtY29udHJvbHMvc3BhdGlhbC1jb250cm9scy5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsVUFBVSxFQUNWLFlBQVksRUFDWixNQUFNLEVBQ04sS0FBSyxFQUNMLE1BQU0sRUFFTixNQUFNLEVBQ04sU0FBUyxFQUNULE1BQU0sR0FDUCxNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDL0MsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzdDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDbEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzlDLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUNoRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRXJDLE9BQU8sRUFBRSxVQUFVLEVBQW1ELE1BQU0sa0NBQWtDLENBQUM7QUFDL0csT0FBTyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sMkNBQTJDLENBQUM7QUFFbkYsT0FBTyxFQUFrQyxvQkFBb0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ2xHLE9BQU8sRUFBZSxlQUFlLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUM5RSxPQUFPLEVBQXdCLGNBQWMsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQ3BGLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsZUFBZSxFQUFzQixNQUFNLGlDQUFpQyxDQUFDO0FBQ3RGLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUNuRSxPQUFPLEVBQUUsMEJBQTBCLEVBQUUsTUFBTSxxREFBcUQsQ0FBQztBQUNqRyxPQUFPLEVBQUUsZ0NBQWdDLEVBQUUsTUFBTSxpRUFBaUUsQ0FBQztBQUNuSCxPQUFPLEVBQUUsaUNBQWlDLEVBQUUsTUFBTSxtRUFBbUUsQ0FBQzs7Ozs7Ozs7QUFLdEgsdUZBQXVGO0FBQ3ZGLE9BQU8sRUFBRSxlQUFlLEVBQUUsQ0FBQztBQUUzQixrRkFBa0Y7QUFDbEYsSUFBSSxtQkFBbUIsR0FBRyxDQUFDLENBQUM7QUFFNUI7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnQkc7QUFvQkgsTUFBTSxPQUFPLHdCQUF3QjtJQUluQzs7Ozs7Ozs7T0FRRztJQUNPLFdBQVc7UUFDbkIsSUFBSSxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsQ0FBQztJQUN4QixDQUFDO0lBNkJELG1DQUFtQztJQUNuQyxJQUFJLFdBQVc7UUFDYixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDO0lBQzVCLENBQUM7SUFDRCwwRkFBMEY7SUFDMUYsSUFBSSxjQUFjO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUM7SUFDM0IsQ0FBQztJQUNELElBQUksZ0JBQWdCO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUM7SUFDM0IsQ0FBQztJQU1ELHdFQUF3RTtJQUN4RSxJQUFjLE1BQU07UUFDbEIsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQztJQUN6QixDQUFDO0lBQ0QseUVBQXlFO0lBQ3pFLElBQWMsV0FBVztRQUN2QixPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDO0lBQzlCLENBQUM7SUFtQ0QsWUFDdUMsR0FBZ0IsRUFDcEMsSUFBWTtRQURRLFFBQUcsR0FBSCxHQUFHLENBQWE7UUFDcEMsU0FBSSxHQUFKLElBQUksQ0FBUTtRQXZGL0Isd0VBQXdFO1FBQy9ELFlBQU8sR0FBRyxLQUFLLENBQUM7UUFDekI7O2lGQUV5RTtRQUNoRSxTQUFJLEdBQUcsS0FBSyxDQUFDO1FBQ3RCLHFFQUFxRTtRQUMzRCxrQkFBYSxHQUFHLElBQUksWUFBWSxFQUFXLENBQUM7UUFFdEQsdURBQXVEO1FBQzdDLGFBQVEsR0FBNEIsSUFBSSxDQUFDO1FBQ3pDLFlBQU8sR0FBMEIsSUFBSSxDQUFDO1FBQ3RDLFNBQUksR0FBcUIsRUFBRSxHQUFHLG9CQUFvQixFQUFFLENBQUM7UUFFL0Q7Ozs7V0FJRztRQUNnQixVQUFLLEdBQUcsSUFBSSxlQUFlLENBQzVDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQ25CLEdBQUcsRUFBRSxDQUFDO1lBQ0osR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsZUFBZSxJQUFJLEVBQUUsQ0FBQztZQUNyQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsSUFBSSxLQUFLLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1NBQzVFLEVBQ0QsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLENBQzVCLENBQUM7UUFhRjs7cUVBRTZEO1FBQ3BELFFBQUcsR0FBRyxJQUFJLGVBQWUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO1FBVWhFLDZFQUE2RTtRQUNuRSxjQUFTLEdBQXlCLGNBQWMsRUFBRSxDQUFDO1FBQzdELDZFQUE2RTtRQUNuRSxxQkFBZ0IsR0FBa0IsSUFBSSxDQUFDO1FBQ2pEO21EQUMyQztRQUNqQyxvQkFBZSxHQUFHLEtBQUssQ0FBQztRQUNsQyw0RkFBNEY7UUFDbEYsZUFBVSxHQUFxQixTQUFTLENBQUM7UUFDbkQscUdBQXFHO1FBQzNGLGtCQUFhLEdBQXNCLEVBQUUsQ0FBQztRQUNoRCxtRUFBbUU7UUFDekQseUJBQW9CLEdBQUcsS0FBSyxDQUFDO1FBRXZDOzs7O1dBSUc7UUFDTyxlQUFVLEdBQUcsS0FBSyxDQUFDO1FBQzdCOzBGQUNrRjtRQUMvRCxpQkFBWSxHQUFHLGtCQUFrQixFQUFFLG1CQUFtQixFQUFFLENBQUM7UUFFNUU7c0NBQzhCO1FBQ3BCLG9CQUFlLEdBQW1CLEVBQUUsQ0FBQztRQUV2QyxhQUFRLEdBQXdCLElBQUksQ0FBQztRQUNyQyxZQUFPLEdBQUcsS0FBSyxDQUFDO1FBQ1AsZUFBVSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNoQyxRQUFHLEdBQUcsTUFBTSxDQUFDLGlCQUFpQixDQUFDLENBQUM7UUEwTmpELCtFQUErRTtRQUNyRSxTQUFJLEdBQXlGO1lBQ3JHLE1BQU0sRUFBRSxLQUFLO1lBQ2IsS0FBSyxFQUFFLElBQUk7WUFDWCxXQUFXLEVBQUUsS0FBSztZQUNsQixXQUFXLEVBQUUsS0FBSztZQUNsQixZQUFZLEVBQUUsS0FBSztTQUNwQixDQUFDO1FBV0YseUVBQXlFO1FBRXpFLGlGQUFpRjtRQUN2RSxhQUFRLEdBQTJDLElBQUksQ0FBQztRQUNsRSxnRkFBZ0Y7UUFDdEUsaUJBQVksR0FBbUQsSUFBSSxDQUFDO1FBQzlFLGdGQUFnRjtRQUN0RSxlQUFVLEdBQWtDLElBQUksQ0FBQztJQTlPeEQsQ0FBQztJQUVKLFFBQVE7UUFDTixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsa0JBQWtCLEVBQUUsRUFBRSxJQUFJLElBQUksQ0FBQztRQUN4RCxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsa0JBQWtCLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQztRQUM3RCxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVE7WUFBRSxPQUFPO1FBRTNCLE1BQU0sY0FBYyxHQUFHLEdBQU0sRUFBRSxDQUFDLGtCQUFrQixDQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUN2RSxJQUFJLENBQUMsUUFBUTthQUNWLFdBQVcsRUFBRTthQUNiLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQzthQUN0QixTQUFTLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRTtZQUNyQixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQztZQUN2QixJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUMvQixrRUFBa0U7WUFDbEUsSUFBSSxDQUFDLElBQUksR0FBRztnQkFDVixHQUFHLElBQUksQ0FBQyxJQUFJO2dCQUNaLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsWUFBWSxJQUFJLE9BQU8sRUFBRSxRQUFRLENBQUM7Z0JBQ3JELFlBQVksRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLFlBQVksSUFBSSxPQUFPLEVBQUUsUUFBUSxDQUFDO2FBQzVELENBQUM7WUFDRixLQUFLLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQzFCLENBQUMsQ0FBQyxDQUFDO1FBRUwsSUFBSSxDQUFDLFFBQVE7YUFDVixhQUFhLEVBQUU7YUFDZixJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7YUFDdEIsU0FBUyxDQUFDLENBQUMsSUFBSSxFQUFFLEVBQUU7WUFDbEIsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7WUFDakIsS0FBSyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDdkIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUMxQixDQUFDLENBQUMsQ0FBQztRQUVMLG1GQUFtRjtRQUNuRix5QkFBeUI7UUFDekIsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxzQkFBc0IsRUFBRSxFQUFFLENBQUM7UUFDM0QsU0FBUyxFQUFFLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQ2hELElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ25CLElBQUksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDO1FBQ3BCLENBQUMsQ0FBQyxDQUNILENBQUM7UUFDRixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLG9CQUFvQixFQUFFLEVBQUUsQ0FBQztRQUN2RCxPQUFPLEVBQUUsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FDOUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDbkIsSUFBSSxDQUFDLFVBQVUsR0FBRyxDQUFDLENBQUM7UUFDdEIsQ0FBQyxDQUFDLENBQ0gsQ0FBQztRQUNGLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLEVBQUUsRUFBRSxDQUFDO1FBQ3BELFFBQVEsRUFBRSxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUMvQyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUNuQixJQUFJLENBQUMsWUFBWSxHQUFHLENBQUMsQ0FBQztRQUN4QixDQUFDLENBQUMsQ0FDSCxDQUFDO1FBRUYsSUFBSSxDQUFDLFFBQVE7YUFDVixhQUFhLEVBQUU7YUFDZixJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7YUFDdEIsU0FBUyxDQUFDLENBQUMsU0FBUyxFQUFFLEVBQUU7UUFDdkIsK0VBQStFO1FBQy9FLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ25CLElBQUksQ0FBQyxTQUFTLEdBQUcsU0FBUyxDQUFDO1lBQzNCLElBQUksU0FBUyxDQUFDLEtBQUssS0FBSyxDQUFDO2dCQUFFLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7UUFDMUQsQ0FBQyxDQUFDLENBQ0gsQ0FBQztRQUVKLElBQUksQ0FBQyxRQUFRO2FBQ1YsdUJBQXVCLEVBQUUsRUFBRTtZQUM1QixFQUFFLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQzthQUN2QixTQUFTLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUNyQixJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUNuQixJQUFJLENBQUMsYUFBYSxHQUFHLE9BQU8sQ0FBQztRQUMvQixDQUFDLENBQUMsQ0FDSCxDQUFDO1FBRUosOERBQThEO1FBQzlELGFBQWEsQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxFQUFFLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxlQUFlLEVBQUUsQ0FBQyxDQUFDO2FBQ2hFLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQzthQUN0QixTQUFTLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsRUFBRSxFQUFFO1lBQ2pDLElBQUksQ0FBQyxRQUFRLEdBQUksUUFBeUIsSUFBSSxJQUFJLENBQUM7WUFDbkQsSUFBSSxDQUFDLE9BQU8sR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDO1lBQ3pCLEtBQUssSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ3pCLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVELDhFQUE4RTtJQUN0RSxVQUFVLENBQUMsRUFBYztRQUMvQixJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUU7WUFDakIsRUFBRSxFQUFFLENBQUM7WUFDTCxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxDQUFDO1FBQzFCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVTLGVBQWUsQ0FBQyxLQUFjO1FBQ3RDLElBQUksQ0FBQyxPQUFPLEdBQUcsS0FBSyxDQUFDO1FBQ3JCLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFFRCwyRUFBMkU7SUFFM0UsMEZBQTBGO0lBQzFGLFlBQVksQ0FBQyxLQUFhO1FBQ3hCLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDcEMsQ0FBQztJQUVELHVFQUF1RTtJQUN2RSxjQUFjO1FBQ1osT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ2pDLENBQUM7SUFFRCwyRUFBMkU7SUFFM0U7bUNBQytCO0lBQ3JCLEtBQUssQ0FBQyxpQkFBaUI7UUFDL0IsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLG9CQUFvQjtZQUFFLE9BQU87UUFDeEQsSUFBSSxDQUFDLG9CQUFvQixHQUFHLElBQUksQ0FBQztRQUNqQyx5RkFBeUY7UUFDekYsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDO1FBQ25DLElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDeEIsSUFBSSxLQUFLLEdBQWtCLENBQUMsQ0FBQztRQUM3QixJQUFJLENBQUM7WUFDSCxLQUFLLEdBQUcsTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDbEQsQ0FBQztRQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7WUFDYixPQUFPLENBQUMsSUFBSSxDQUFDLDZDQUE2QyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ25FLENBQUM7UUFDRCxtRkFBbUY7UUFDbkYsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDbkIsSUFBSSxDQUFDLG9CQUFvQixHQUFHLEtBQUssQ0FBQztZQUNsQywyRUFBMkU7WUFDM0UsSUFBSSxLQUFLLEtBQUssSUFBSTtnQkFBRSxPQUFPO1lBQzNCLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7WUFDN0IsSUFBSSxDQUFDLGVBQWUsR0FBRyxLQUFLLEtBQUssQ0FBQyxDQUFDO1lBQ25DLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO1FBQ3pCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELGtGQUFrRjtJQUNsRixJQUFjLG1CQUFtQjtRQUMvQixPQUFPLElBQUksQ0FBQyxnQkFBZ0IsS0FBSyxlQUFlLENBQUM7SUFDbkQsQ0FBQztJQUVELGlHQUFpRztJQUNqRyxJQUFZLGdCQUFnQjtRQUMxQixPQUFPLElBQUksQ0FBQyxRQUFRLEVBQUUsZ0JBQWdCLEVBQUUsRUFBRSxJQUFJLFNBQVMsQ0FBQztJQUMxRCxDQUFDO0lBRUQ7dURBQ21EO0lBQ3pDLEtBQUssQ0FBQyxjQUFjLENBQUMsS0FBYTtRQUMxQyxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztRQUM3QixJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsSUFBSSxFQUFFLEVBQUUsSUFBSSxLQUFLLFFBQVE7WUFBRSxPQUFPO1FBQ3BELElBQUksSUFBSSxDQUFDLGdCQUFnQixLQUFLLEtBQUssRUFBRSxDQUFDO1lBQ3BDLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztZQUN0QixPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksQ0FBQztZQUNILE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQyxjQUFjLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNuRCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsS0FBSyxDQUFDO1lBQzlCLElBQUksQ0FBQyxlQUFlLEdBQUcsS0FBSyxDQUFDO1FBQy9CLENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO1FBQy9CLENBQUM7UUFDRCxJQUFJLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxDQUFDO0lBQzFCLENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNPLFlBQVk7UUFDcEIsSUFBSSxDQUFDLFVBQVUsR0FBRyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUM7UUFDbkMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVO1lBQUUsT0FBTztRQUM3QixVQUFVLENBQUMsR0FBRyxFQUFFO1lBQ2QsUUFBUSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsY0FBYyxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxRQUFRLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztRQUNuRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDUixDQUFDO0lBRVMsY0FBYztRQUN0QixJQUFJLENBQUMsUUFBUSxFQUFFLGNBQWMsRUFBRSxDQUFDO1FBQ2hDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7UUFDN0IsSUFBSSxDQUFDLGVBQWUsR0FBRyxLQUFLLENBQUM7SUFDL0IsQ0FBQztJQUVELHdFQUF3RTtJQUN4RSxJQUFjLFlBQVk7UUFDeEIsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUM7SUFDbEMsQ0FBQztJQUVELDJFQUEyRTtJQUUzRSwyRUFBMkU7SUFDM0UsSUFBYyxRQUFRO1FBQ3BCLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxZQUFZLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxRQUFRLENBQUMsQ0FBQztJQUNsRSxDQUFDO0lBRUQsNkRBQTZEO0lBQzdELElBQWMsY0FBYztRQUMxQixPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLGVBQWUsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUM7SUFDcEUsQ0FBQztJQUVTLFdBQVcsQ0FBQyxFQUFXO1FBQy9CLElBQUksQ0FBQyxRQUFRLEVBQUUsWUFBWSxDQUFDLEVBQUUsU0FBUyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDakQsQ0FBQztJQUVTLGlCQUFpQixDQUFDLEVBQVc7UUFDckMsSUFBSSxDQUFDLFFBQVEsRUFBRSxZQUFZLENBQUMsRUFBRSxlQUFlLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUN2RCxDQUFDO0lBV1MsYUFBYSxDQUFDLElBQTRDO1FBQ2xFLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQ3ZDLENBQUM7SUFFRCxxRUFBcUU7SUFDM0QsT0FBTyxDQUFDLElBQTRDLEVBQUUsRUFBVztRQUN6RSxJQUFJLENBQUMsSUFBSSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUM7SUFDM0MsQ0FBQztJQVdTLEtBQUs7UUFDYixJQUFJLENBQUMsUUFBUSxFQUFFLFlBQVksQ0FBQyxFQUFFLEdBQUcsb0JBQW9CLEVBQUUsQ0FBQyxDQUFDO1FBQ3pELElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztJQUN4QixDQUFDO0lBRUQscUVBQXFFO0lBQ3JFLElBQWMsWUFBWTtRQUN4QixPQUFPLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDakMsQ0FBQztJQUVELCtFQUErRTtJQUMvRSxJQUFJLGFBQWE7UUFDZixPQUFPLElBQUksQ0FBQyxNQUFNLEtBQUssSUFBSSxDQUFDO0lBQzlCLENBQUM7SUFFRCwrREFBK0Q7SUFDL0QsSUFBSSxZQUFZO1FBQ2QsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxJQUFJLENBQUM7SUFDckQsQ0FBQztJQUVELDJFQUEyRTtJQUUzRSxrRUFBa0U7SUFDMUQsVUFBVTtRQUNoQixPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQy9GLENBQUM7OEdBbFhVLHdCQUF3QixrQkF1R3pCLFVBQVU7a0dBdkdULHdCQUF3QiwrTUFFeEIsc0JBQXNCLGdEQ25GbkMsdWxQQXlMQSx5akxEdkhJLFlBQVksMExBQ1osV0FBVyw4VkFDWCxZQUFZLDZYQUNaLGNBQWMsZ1pBQ2QsWUFBWSx1dUJBQ1osYUFBYSxzWEFDYiwwQkFBMEIsa0tBQzFCLGdDQUFnQyxzTkFDaEMsaUNBQWlDLGtRQUNqQyxzQkFBc0I7OzJGQU1iLHdCQUF3QjtrQkFuQnBDLFNBQVM7K0JBQ0Usa0JBQWtCLGNBQ2hCLElBQUksV0FDUDt3QkFDUCxZQUFZO3dCQUNaLFdBQVc7d0JBQ1gsWUFBWTt3QkFDWixjQUFjO3dCQUNkLFlBQVk7d0JBQ1osYUFBYTt3QkFDYiwwQkFBMEI7d0JBQzFCLGdDQUFnQzt3QkFDaEMsaUNBQWlDO3dCQUNqQyxzQkFBc0I7cUJBQ3ZCLG1CQUdnQix1QkFBdUIsQ0FBQyxNQUFNOzswQkF5RzVDLE1BQU07MkJBQUMsVUFBVTs4REFyR3VCLE1BQU07c0JBQWhELFNBQVM7dUJBQUMsc0JBQXNCO2dCQWdCeEIsT0FBTztzQkFBZixLQUFLO2dCQUlHLElBQUk7c0JBQVosS0FBSztnQkFFSSxhQUFhO3NCQUF0QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBDb21wb25lbnQsXG4gIERlc3Ryb3lSZWYsXG4gIEV2ZW50RW1pdHRlcixcbiAgSW5qZWN0LFxuICBJbnB1dCxcbiAgTmdab25lLFxuICBPbkluaXQsXG4gIE91dHB1dCxcbiAgVmlld0NoaWxkLFxuICBpbmplY3QsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGFrZVVudGlsRGVzdHJveWVkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZS9yeGpzLWludGVyb3AnO1xuaW1wb3J0IHsgQ29tbW9uTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEZvcm1zTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xuaW1wb3J0IHsgQnV0dG9uTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9idXR0b24nO1xuaW1wb3J0IHsgQ2hlY2tib3hNb2R1bGUgfSBmcm9tICdwcmltZW5nL2NoZWNrYm94JztcbmltcG9ydCB7IERpYWxvZ01vZHVsZSB9IGZyb20gJ3ByaW1lbmcvZGlhbG9nJztcbmltcG9ydCB7IFRvb2x0aXBNb2R1bGUgfSBmcm9tICdwcmltZW5nL3Rvb2x0aXAnO1xuaW1wb3J0IHsgY29tYmluZUxhdGVzdCB9IGZyb20gJ3J4anMnO1xuXG5pbXBvcnQgeyBWSVNVQUxJWkVSLCBJVmlzdWFsaXplciwgSVNwYXRpYWxDb250cm9scywgUm9pU2VsZWN0aW9uTW9kZSB9IGZyb20gJy4uL2NvbnRyYWN0cy92aXN1YWxpemVyLmNvbnRyYWN0JztcbmltcG9ydCB7IFNwYXRpYWxDaGFydHNDb21wb25lbnQgfSBmcm9tICcuL3NwYXRpYWwtY2hhcnRzL3NwYXRpYWwtY2hhcnRzLmNvbXBvbmVudCc7XG5pbXBvcnQgeyBTcGF0aWFsRGF0YXNldCB9IGZyb20gJy4uL2NvbnRyYWN0cy9zcGF0aWFsLWRhdGFzZXQuY29udHJhY3QnO1xuaW1wb3J0IHsgQ29sb3JtYXBOb2RlLCBTcGF0aWFsVmlld1N0YXRlLCBERUZBVUxUX1NQQVRJQUxfVklFVyB9IGZyb20gJy4uL2NvbnRyYWN0cy9kaXNwbGF5LXR5cGVzJztcbmltcG9ydCB7IFBhbmVsT3B0aW9uLCBwYXJzZUdlbmVHcm91cHMgfSBmcm9tICcuLi9zcGF0aWFsL3NwYXRpYWwtcGFuZWwtbW9kZWwnO1xuaW1wb3J0IHsgU3BhdGlhbFNlbGVjdGlvbk1hc2ssIGVtcHR5U2VsZWN0aW9uIH0gZnJvbSAnLi4vc3BhdGlhbC9zcGF0aWFsLXNlbGVjdGlvbic7XG5pbXBvcnQgeyBHZW5lUGlja2VyTW9kZWwgfSBmcm9tICcuL3NwYXRpYWwtZ2VuZS1waWNrZXInO1xuaW1wb3J0IHsgU3BhdGlhbEtleU1vZGVsLCBTcGF0aWFsTGVnZW5kRW50cnkgfSBmcm9tICcuL3NwYXRpYWwta2V5L3NwYXRpYWwta2V5Lm1vZGVsJztcbmltcG9ydCB7IGNvbG9yQnlMYWJlbCB9IGZyb20gJy4vc3BhdGlhbC1rZXkvc3BhdGlhbC1rZXkuY29tcG9uZW50JztcbmltcG9ydCB7IFNwYXRpYWxDZWxsc1BhbmVsQ29tcG9uZW50IH0gZnJvbSAnLi9zcGF0aWFsLWNlbGxzLXBhbmVsL3NwYXRpYWwtY2VsbHMtcGFuZWwuY29tcG9uZW50JztcbmltcG9ydCB7IFNwYXRpYWxUcmFuc2NyaXB0c1BhbmVsQ29tcG9uZW50IH0gZnJvbSAnLi9zcGF0aWFsLXRyYW5zY3JpcHRzLXBhbmVsL3NwYXRpYWwtdHJhbnNjcmlwdHMtcGFuZWwuY29tcG9uZW50JztcbmltcG9ydCB7IFNwYXRpYWxPYnNlcnZhdGlvbnNQYW5lbENvbXBvbmVudCB9IGZyb20gJy4vc3BhdGlhbC1vYnNlcnZhdGlvbnMtcGFuZWwvc3BhdGlhbC1vYnNlcnZhdGlvbnMtcGFuZWwuY29tcG9uZW50JztcblxuLyoqIEBkZXByZWNhdGVkIE1vdmVkIHRvIGBzcGF0aWFsLWtleS9zcGF0aWFsLWtleS5tb2RlbGA7IHJlLWV4cG9ydGVkIGZvciBvbmUgcmVsZWFzZS4gKi9cbmV4cG9ydCB0eXBlIHsgU3BhdGlhbExlZ2VuZEVudHJ5IH07XG5cbi8qKiBAZGVwcmVjYXRlZCBNb3ZlZCB0byBgc3BhdGlhbC9zcGF0aWFsLXBhbmVsLW1vZGVsYDsgcmUtZXhwb3J0ZWQgZm9yIG9uZSByZWxlYXNlLiAqL1xuZXhwb3J0IHsgcGFyc2VHZW5lR3JvdXBzIH07XG5cbi8qKiBQZXItaW5zdGFuY2UgaWQgc291cmNlIOKAlCBzZWUge0BsaW5rIFNwYXRpYWxDb250cm9sc0NvbXBvbmVudC5jaGFydHNCb2R5SWR9LiAqL1xubGV0IGNvbnRyb2xzSW5zdGFuY2VTZXEgPSAwO1xuXG4vKipcbiAqIFNwYXRpYWwtb21pY3MgY29udHJvbHM6IGEgbm9uLW1vZGFsLCByZXNpemFibGUsIGRyYWdnYWJsZSBkaWFsb2cgZm9yIGNob29zaW5nXG4gKiB3aGF0IHRoZSBvYnNlcnZhdGlvbiBtYXJrZXJzIGFyZSBjb2xvdXJlZCBieSwgYW5kIGhvdyB0aGV5IGFyZSBkcmF3bi5cbiAqXG4gKiBEZXBlbmRzIG9ubHkgb24ge0BsaW5rIElTcGF0aWFsQ29udHJvbHN9LCByZWFjaGVkIHRocm91Z2ggdGhlIGBWSVNVQUxJWkVSYFxuICogY29udHJhY3QgdG9rZW4g4oCUIG5ldmVyIGEgY29uY3JldGUgYmFja2VuZCDigJQgbWlycm9yaW5nIGhvd1xuICogYENoYW5uZWxIaXN0b2dyYW1Db21wb25lbnRgIGRlcGVuZHMgb25seSBvbiBgQ0hBTk5FTF9ISVNUT0dSQU1fQVBJYC4gV2hlbiBub1xuICogaG9zdCBoYXMgYm91bmQgYFNQQVRJQUxfREFUQV9QT1JUYCwgYGdldFNwYXRpYWxDb250cm9scygpYCByZXR1cm5zIG51bGwgYW5kXG4gKiB0aGUgZGlhbG9nIHJlbmRlcnMgYW4gZXhwbGFuYXRvcnkgZW1wdHkgc3RhdGUgcmF0aGVyIHRoYW4gZGVhZCBjb250cm9scy5cbiAqXG4gKiBUaGUgbGVnZW5kIHN3YXRjaGVzIGFuZCB0aGUgY29udGludW91cyBjb2xvdXIgYmFyIGFyZSBidWlsdCB3aXRoIHRoZSBTQU1FXG4gKiBmdW5jdGlvbnMgdGhlIHJlbmRlcmVyIHVzZXMgKGBjYXRlZ29yeUNvbG9yc2Ag4oaSIGByZXNvbHZlQ2F0ZWdvcnlDb2xvcnNgLFxuICogYHNwYXRpYWxDb250aW51b3VzTHV0YCksIHNvIHRoZSBrZXkgY2Fubm90IGRyaWZ0IGZyb20gd2hhdCBpcyBvbiBzY3JlZW4uXG4gKlxuICogT25QdXNoOiB0aGUgY29udHJvbHMnIHN0cmVhbXMsIHRoZSBrZXkgYW5kIGdlbmUtbGlzdCBtb2RlbHMgKHdoaWNoIHJlLWVudGVyIHRoZSB6b25lXG4gKiB3aGVuIHRoZWlyIGFzeW5jIHdvcmsgbGFuZHMpIGFuZCBhbiBhd2FpdGVkIGNhdGVnb3J5IHNlbGVjdGlvbiBtYXJrIGl0IGZvciBjaGVjay5cbiAqL1xuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnc3BhdGlhbC1jb250cm9scycsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtcbiAgICBDb21tb25Nb2R1bGUsXG4gICAgRm9ybXNNb2R1bGUsXG4gICAgQnV0dG9uTW9kdWxlLFxuICAgIENoZWNrYm94TW9kdWxlLFxuICAgIERpYWxvZ01vZHVsZSxcbiAgICBUb29sdGlwTW9kdWxlLFxuICAgIFNwYXRpYWxDZWxsc1BhbmVsQ29tcG9uZW50LFxuICAgIFNwYXRpYWxUcmFuc2NyaXB0c1BhbmVsQ29tcG9uZW50LFxuICAgIFNwYXRpYWxPYnNlcnZhdGlvbnNQYW5lbENvbXBvbmVudCxcbiAgICBTcGF0aWFsQ2hhcnRzQ29tcG9uZW50LFxuICBdLFxuICB0ZW1wbGF0ZVVybDogJy4vc3BhdGlhbC1jb250cm9scy5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3NwYXRpYWwtY29udHJvbHMuY29tcG9uZW50LnNjc3MnXSxcbiAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG59KVxuZXhwb3J0IGNsYXNzIFNwYXRpYWxDb250cm9sc0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIC8qKiBUaGUgZW1iZWRkZWQgY2hhcnQsIHNvIGEgZGlhbG9nIHJlc2l6ZSBjYW4gcmUtZml0IGl0LiAqL1xuICBAVmlld0NoaWxkKFNwYXRpYWxDaGFydHNDb21wb25lbnQpIHByaXZhdGUgY2hhcnRzPzogU3BhdGlhbENoYXJ0c0NvbXBvbmVudDtcblxuICAvKipcbiAgICogUmUtZml0IHRoZSBjaGFydCBhZnRlciB0aGUgZGlhbG9nIGlzIHJlc2l6ZWQuXG4gICAqXG4gICAqIFBsb3RseSBkb2VzIG5vdCBmb2xsb3cgYSBjb250YWluZXIgcmVzaXplIG9uIGl0cyBvd24g4oCUIGl0cyBgcmVzcG9uc2l2ZWBcbiAgICogb3B0aW9uIGxpc3RlbnMgZm9yIFdJTkRPVyByZXNpemVzIG9ubHksIHNvIGRyYWdnaW5nIHRoZSBkaWFsb2cncyBoYW5kbGVcbiAgICogcmVhY2hlcyBpdCB0aHJvdWdoIG5vdGhpbmcuIFByaW1lTkcgdGVsbHMgdXMgd2hlbiB0aGUgZHJhZyBlbmRzLCB3aGljaCBpcyBhXG4gICAqIGZhciBtb3JlIGRpcmVjdCBzaWduYWwgdGhhbiB3YXRjaGluZyBib3hlcywgYW5kIGZpcmluZyBvbmNlIG9uIHJlbGVhc2UgbWVhbnNcbiAgICogbm8gcmVsYXlvdXQgY2h1cm4gZHVyaW5nIHRoZSBkcmFnLlxuICAgKi9cbiAgcHJvdGVjdGVkIG9uUmVzaXplRW5kKCk6IHZvaWQge1xuICAgIHRoaXMuY2hhcnRzPy5yZXNpemUoKTtcbiAgfVxuXG4gIC8qKiBEaWFsb2cgdmlzaWJpbGl0eSwgdHdvLXdheSBib3VuZCBzbyBhIHRvb2xiYXIgYnV0dG9uIGNhbiBvcGVuIGl0LiAqL1xuICBASW5wdXQoKSB2aXNpYmxlID0gZmFsc2U7XG4gIC8qKiBTZXQgd2hpbGUgdGhlIDNEIGNsb3VkIGlzIHRoZSBhY3RpdmUgbW9kZS4gQ2hhbmdlcyB3aGF0IHRoZSBST0kgc2VsZWN0aW9uXG4gICAqICBNRUFOUyDigJQgYSBzY3JlZW4tc3BhY2UgbGFzc28gY3V0dGluZyB0aHJvdWdoIHRoZSBjbG91ZCdzIGZ1bGwgZGVwdGggcmF0aGVyXG4gICAqICB0aGFuIGEgc2hhcGUgaW4gdGlzc3VlIGNvb3JkaW5hdGVzIOKAlCBzbyB0aGUgaGludCBiZWxvdyBpdCBzYXlzIHNvLiAqL1xuICBASW5wdXQoKSBpczNkID0gZmFsc2U7XG4gIC8qKiBUaGUgZGlhbG9nIHdhcyBvcGVuZWQgb3IgY2xvc2VkOyB0d28td2F5IHdpdGgge0BsaW5rIHZpc2libGV9LiAqL1xuICBAT3V0cHV0KCkgdmlzaWJsZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcblxuICAvKiogTnVsbCB3aGVuIHRoZSBob3N0IGJvdW5kIG5vIGBTUEFUSUFMX0RBVEFfUE9SVGAuICovXG4gIHByb3RlY3RlZCBjb250cm9sczogSVNwYXRpYWxDb250cm9scyB8IG51bGwgPSBudWxsO1xuICBwcm90ZWN0ZWQgZGF0YXNldDogU3BhdGlhbERhdGFzZXQgfCBudWxsID0gbnVsbDtcbiAgcHJvdGVjdGVkIHZpZXc6IFNwYXRpYWxWaWV3U3RhdGUgPSB7IC4uLkRFRkFVTFRfU1BBVElBTF9WSUVXIH07XG5cbiAgLyoqXG4gICAqIEdlbmUgcGlja2VyOiBhIGZpbHRlcmFibGUgZHJvcGRvd24gcmF0aGVyIHRoYW4gYSBmcmVlLXRleHQgdHlwZWFoZWFkLCBzbyB0aGVcbiAgICogb3B0aW9ucyBhcmUgdmlzaWJsZSBiZWZvcmUgYW55dGhpbmcgaXMgdHlwZWQgYW5kIGVhY2gga2V5c3Ryb2tlIG5hcnJvd3MgYSBsaXN0XG4gICAqIHRoZSB1c2VyIGNhbiBzZWUuIE9uZSBtb2RlbCBmZWVkcyBldmVyeSBnZW5lIGRyb3Bkb3duIG9mIHRoZSBwYW5lbC5cbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSBnZW5lcyA9IG5ldyBHZW5lUGlja2VyTW9kZWwoXG4gICAgKCkgPT4gdGhpcy5jb250cm9scyxcbiAgICAoKSA9PiBbXG4gICAgICAuLi4odGhpcy52aWV3Py50cmFuc2NyaXB0R2VuZXMgPz8gW10pLFxuICAgICAgLi4uKHRoaXMudmlldz8uY29sb3JCeT8ua2luZCA9PT0gJ2ZlYXR1cmUnID8gW3RoaXMudmlldy5jb2xvckJ5Lm5hbWVdIDogW10pLFxuICAgIF0sXG4gICAgKGZuKSA9PiB0aGlzLnJ1bkFuZE1hcmsoZm4pLFxuICApO1xuICAvKiogVGhlIGdlbmUgZHJvcGRvd25zJyBvcHRpb25zLiAqL1xuICBnZXQgZ2VuZU9wdGlvbnMoKTogUGFuZWxPcHRpb248c3RyaW5nPltdIHtcbiAgICByZXR1cm4gdGhpcy5nZW5lcy5vcHRpb25zO1xuICB9XG4gIC8qKiBUcnVlIHdoZW4gdGhlIG9wdGlvbnMgY29tZSBmcm9tIHRoZSBwb3J0IHBlciBrZXlzdHJva2UgcmF0aGVyIHRoYW4gYSByZXNpZGVudCBsaXN0LiAqL1xuICBnZXQgZ2VuZXNBcmVSZW1vdGUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuZ2VuZXMucmVtb3RlO1xuICB9XG4gIGdldCBnZW5lU2VhcmNoRmFpbGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmdlbmVzLmZhaWxlZDtcbiAgfVxuXG4gIC8qKiBUaGUga2V5IOKAlCBsZWdlbmQgb3IgY29sb3VyIGJhciDigJQgZm9yIHRoZSBhY3RpdmUgY29sb3VyaW5nLiBLZXB0IGhlcmUsIG5vdCBpblxuICAgKiAgYDxzcGF0aWFsLWtleT5gOiB3aGV0aGVyIHRoZSBjb2xvdXJpbmcgaXMgY2F0ZWdvcmljYWwgZGVjaWRlcyB3aGljaCBrbm9icyB0aGUgcmVzdCBvZlxuICAgKiAgdGhlIHBhbmVsIG9mZmVycywgd2hldGhlciBvciBub3QgdGhlIGtleSBpcyBvbiBzY3JlZW4uICovXG4gIHJlYWRvbmx5IGtleSA9IG5ldyBTcGF0aWFsS2V5TW9kZWwoKGZuKSA9PiB0aGlzLnJ1bkFuZE1hcmsoZm4pKTtcbiAgLyoqIENhdGVnb3JpY2FsIGtleSwgb3IgbnVsbCB3aGVuIHRoZSBhY3RpdmUgY29sb3VyaW5nIGlzIGNvbnRpbnVvdXMuICovXG4gIHByb3RlY3RlZCBnZXQgbGVnZW5kKCk6IFNwYXRpYWxMZWdlbmRFbnRyeVtdIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMua2V5LmxlZ2VuZDtcbiAgfVxuICAvKiogQ1NTIGdyYWRpZW50IGZvciBhIGNvbnRpbnVvdXMgY29sb3VyaW5nLCBvciBudWxsIHdoZW4gY2F0ZWdvcmljYWwuICovXG4gIHByb3RlY3RlZCBnZXQgY29sb3JCYXJDc3MoKTogc3RyaW5nIHwgbnVsbCB7XG4gICAgcmV0dXJuIHRoaXMua2V5LmNvbG9yQmFyQ3NzO1xuICB9XG5cbiAgLyoqIEN1cnJlbnQgc2VsZWN0aW9uIOKAlCBkcml2ZXMgdGhlIGNvdW50LCB0aGUgQ2xlYXIgYnV0dG9uIGFuZCB0aGUgbXV0aW5nLiAqL1xuICBwcm90ZWN0ZWQgc2VsZWN0aW9uOiBTcGF0aWFsU2VsZWN0aW9uTWFzayA9IGVtcHR5U2VsZWN0aW9uKCk7XG4gIC8qKiBUaGUgbGVnZW5kIHJvdyB3aG9zZSBjYXRlZ29yeSBpcyBjdXJyZW50bHkgc2VsZWN0ZWQsIGZvciBoaWdobGlnaHRpbmcuICovXG4gIHByb3RlY3RlZCBzZWxlY3RlZENhdGVnb3J5OiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgLyoqIEFuIFJPSSBzZWxlY3Rpb24gdGhhdCBtYXRjaGVkIG5vdGhpbmcsIHNvIHRoZSBVSSBjYW4gc2F5IHNvIHJhdGhlciB0aGFuXG4gICAqICBsb29raW5nIGxpa2UgdGhlIGJ1dHRvbiBkaWQgbm90aGluZy4gKi9cbiAgcHJvdGVjdGVkIHNlbGVjdGlvbk1pc3NlZCA9IGZhbHNlO1xuICAvKiogVGhlIG1vZGUgb2YgdGhlIHNlbGVjdGlvbiB0aGF0IHtAbGluayBzZWxlY3Rpb25NaXNzZWR9OiB3aGF0IGl0IGZvdW5kIG5vdGhpbmcgaW5zaWRlLiAqL1xuICBwcm90ZWN0ZWQgbWlzc2VkTW9kZTogUm9pU2VsZWN0aW9uTW9kZSA9ICdyZWdpb25zJztcbiAgLyoqIFRoZSByZWdpb24gY2xhc3NlcyBwaWNrZWQgaW4gdGhlIFJlZ2lvbiBFZGl0b3I6IGluIDNELCBcIlNlbGVjdCBmcm9tIFJPSXNcIiBzZWxlY3RzIGluc2lkZSB0aGVtLiAqL1xuICBwcm90ZWN0ZWQgcGlja2VkQ2xhc3NlczogcmVhZG9ubHkgc3RyaW5nW10gPSBbXTtcbiAgLyoqIFdoaWxlIFwiU2VsZWN0IGZyb20gUk9Jc1wiIHJlYWRzIHRoZSBwaWNrZWQgY2xhc3Nlcycgb3V0bGluZXMuICovXG4gIHByb3RlY3RlZCBzZWxlY3RpbmdGcm9tUmVnaW9ucyA9IGZhbHNlO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBEaXN0cmlidXRpb24gc2VjdGlvbiBpcyBleHBhbmRlZC4gQ29sbGFwc2VkIGJ5IGRlZmF1bHQ6IHRoZVxuICAgKiBwYW5lbCdzIHByaW1hcnkgam9iIGlzIHRoZSBjb2xvdXIgY29udHJvbHMsIGFuZCB0aGUgY2hhcnQgcm91Z2hseSBkb3VibGVzXG4gICAqIGl0cyBoZWlnaHQuXG4gICAqL1xuICBwcm90ZWN0ZWQgY2hhcnRzT3BlbiA9IGZhbHNlO1xuICAvKiogUGVyLWluc3RhbmNlIGlkIGZvciB0aGUgY29sbGFwc2libGUgYm9keSwgc28gYGFyaWEtY29udHJvbHNgIHBvaW50cyBhdCBvbmVcbiAgICogIGVsZW1lbnQgYW5kIGV4cGFuZGluZyB0aGUgc2Vjb25kIHBhbmVsIGNhbm5vdCBzY3JvbGwgdGhlIGZpcnN0IG9uZSdzIGNoYXJ0LiAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgY2hhcnRzQm9keUlkID0gYHNjLWNoYXJ0cy1ib2R5LSR7Kytjb250cm9sc0luc3RhbmNlU2VxfWA7XG5cbiAgLyoqIENvbG9ybWFwIHRyZWUgZm9yIHRoZSBjb250aW51b3VzIGNvbG91ciBzY2FsZSBhbmQgdGhlIGRlbnNpdHkgbWFwOiB0aGUgbGlicmFyeSdzXG4gICAqICBvd24gYENPTE9STUFQX09QVElPTlNgLiAqL1xuICBwcm90ZWN0ZWQgY29sb3JtYXBPcHRpb25zOiBDb2xvcm1hcE5vZGVbXSA9IFtdO1xuXG4gIHByaXZhdGUgY29sb3JtYXA6IENvbG9ybWFwTm9kZSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHJldmVyc2UgPSBmYWxzZTtcbiAgcHJpdmF0ZSByZWFkb25seSBkZXN0cm95UmVmID0gaW5qZWN0KERlc3Ryb3lSZWYpO1xuICBwcml2YXRlIHJlYWRvbmx5IGNkciA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgQEluamVjdChWSVNVQUxJWkVSKSBwcml2YXRlIHJlYWRvbmx5IHZpejogSVZpc3VhbGl6ZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSB6b25lOiBOZ1pvbmUsXG4gICkge31cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmNvbnRyb2xzID0gdGhpcy52aXouZ2V0U3BhdGlhbENvbnRyb2xzPy4oKSA/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
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
@@ -0,0 +1,66 @@
1
+ import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from '@angular/core';
2
+ import { CommonModule } from '@angular/common';
3
+ import { ButtonModule } from 'primeng/button';
4
+ import { InputTextModule } from 'primeng/inputtext';
5
+ import { parseCssColor, rgbToHex } from '../../contracts/color';
6
+ import { DEFAULT_CATEGORICAL_PALETTE } from '../../spatial/spatial-encoding';
7
+ import { GLYPH_OPTIONS } from '../../spatial/spatial-panel-model';
8
+ import * as i0 from "@angular/core";
9
+ import * as i1 from "@angular/common";
10
+ import * as i2 from "primeng/button";
11
+ import * as i3 from "primeng/inputtext";
12
+ /**
13
+ * One gene's icon and colour: the icon grid, a colour picker with its hex value, presets, and
14
+ * a reset — the content of a popover its host opens on the gene's swatch. Writes nothing itself:
15
+ * it reports the choice, and the host stores it where it belongs.
16
+ */
17
+ export class SpatialGeneStyleComponent {
18
+ constructor() {
19
+ /** The gene, for the controls' labels. */
20
+ this.gene = '';
21
+ /** What the icons and colour are of ("Observation", "Transcript"), for the titles. */
22
+ this.what = '';
23
+ /** The gene's colour, `#rrggbb`. */
24
+ this.color = '#ffffff';
25
+ /** The gene's icon. */
26
+ this.glyph = 'circle';
27
+ /** A note under the icons, e.g. where they show; none when null. */
28
+ this.iconHint = null;
29
+ this.colorChange = new EventEmitter();
30
+ this.glyphChange = new EventEmitter();
31
+ /** Back to the gene's default icon and colour. */
32
+ this.resetStyle = new EventEmitter();
33
+ this.glyphOptions = GLYPH_OPTIONS;
34
+ this.colorPresets = DEFAULT_CATEGORICAL_PALETTE.slice(0, 10).map((c) => c.toLowerCase());
35
+ }
36
+ /** A typed hex colour, accepted as `#rrggbb` or `rrggbb`; anything else is ignored. */
37
+ onHex(text) {
38
+ const t = text.trim();
39
+ const rgb = /^#?[0-9a-f]{6}$/i.test(t) ? parseCssColor(t) : null;
40
+ if (rgb)
41
+ this.colorChange.emit(rgbToHex(rgb));
42
+ }
43
+ 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 }); }
45
+ }
46
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: SpatialGeneStyleComponent, decorators: [{
47
+ 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"] }]
49
+ }], propDecorators: { gene: [{
50
+ type: Input
51
+ }], what: [{
52
+ type: Input
53
+ }], color: [{
54
+ type: Input
55
+ }], glyph: [{
56
+ type: Input
57
+ }], iconHint: [{
58
+ type: Input
59
+ }], colorChange: [{
60
+ type: Output
61
+ }], glyphChange: [{
62
+ type: Output
63
+ }], resetStyle: [{
64
+ type: Output
65
+ }] } });
66
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3BhdGlhbC1nZW5lLXN0eWxlLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvc3BhdGlhbC1jb250cm9scy9zcGF0aWFsLWdlbmUtc3R5bGUvc3BhdGlhbC1nZW5lLXN0eWxlLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvc3BhdGlhbC1jb250cm9scy9zcGF0aWFsLWdlbmUtc3R5bGUvc3BhdGlhbC1nZW5lLXN0eWxlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDaEcsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQy9DLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5QyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFHcEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxRQUFRLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsMkJBQTJCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUM3RSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sbUNBQW1DLENBQUM7Ozs7O0FBRWxFOzs7O0dBSUc7QUFTSCxNQUFNLE9BQU8seUJBQXlCO0lBUnRDO1FBU0UsMENBQTBDO1FBQ2pDLFNBQUksR0FBRyxFQUFFLENBQUM7UUFDbkIsc0ZBQXNGO1FBQzdFLFNBQUksR0FBRyxFQUFFLENBQUM7UUFDbkIsb0NBQW9DO1FBQzNCLFVBQUssR0FBRyxTQUFTLENBQUM7UUFDM0IsdUJBQXVCO1FBQ2QsVUFBSyxHQUF3QixRQUFRLENBQUM7UUFDL0Msb0VBQW9FO1FBQzNELGFBQVEsR0FBa0IsSUFBSSxDQUFDO1FBQ3JCLGdCQUFXLEdBQUcsSUFBSSxZQUFZLEVBQVUsQ0FBQztRQUN6QyxnQkFBVyxHQUFHLElBQUksWUFBWSxFQUF1QixDQUFDO1FBQ3pFLGtEQUFrRDtRQUMvQixlQUFVLEdBQUcsSUFBSSxZQUFZLEVBQVEsQ0FBQztRQUV0QyxpQkFBWSxHQUFHLGFBQWEsQ0FBQztRQUM3QixpQkFBWSxHQUFHLDJCQUEyQixDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQztLQVF4RztJQU5DLHVGQUF1RjtJQUM3RSxLQUFLLENBQUMsSUFBWTtRQUMxQixNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDdEIsTUFBTSxHQUFHLEdBQUcsa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUNqRSxJQUFJLEdBQUc7WUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNoRCxDQUFDOzhHQXhCVSx5QkFBeUI7a0dBQXpCLHlCQUF5QiwyUUN2QnRDLDg1REF3REEscTBDRHRDWSxZQUFZLCtQQUFFLFlBQVksNlhBQUUsZUFBZTs7MkZBSzFDLHlCQUF5QjtrQkFSckMsU0FBUzsrQkFDRSxvQkFBb0IsY0FDbEIsSUFBSSxXQUNQLENBQUMsWUFBWSxFQUFFLFlBQVksRUFBRSxlQUFlLENBQUMsbUJBR3JDLHVCQUF1QixDQUFDLE1BQU07OEJBSXRDLElBQUk7c0JBQVosS0FBSztnQkFFRyxJQUFJO3NCQUFaLEtBQUs7Z0JBRUcsS0FBSztzQkFBYixLQUFLO2dCQUVHLEtBQUs7c0JBQWIsS0FBSztnQkFFRyxRQUFRO3NCQUFoQixLQUFLO2dCQUNhLFdBQVc7c0JBQTdCLE1BQU07Z0JBQ1ksV0FBVztzQkFBN0IsTUFBTTtnQkFFWSxVQUFVO3NCQUE1QixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgRXZlbnRFbWl0dGVyLCBJbnB1dCwgT3V0cHV0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgQnV0dG9uTW9kdWxlIH0gZnJvbSAncHJpbWVuZy9idXR0b24nO1xuaW1wb3J0IHsgSW5wdXRUZXh0TW9kdWxlIH0gZnJvbSAncHJpbWVuZy9pbnB1dHRleHQnO1xuXG5pbXBvcnQgeyBUcmFuc2NyaXB0R2x5cGhOYW1lIH0gZnJvbSAnLi4vLi4vY29udHJhY3RzL2Rpc3BsYXktdHlwZXMnO1xuaW1wb3J0IHsgcGFyc2VDc3NDb2xvciwgcmdiVG9IZXggfSBmcm9tICcuLi8uLi9jb250cmFjdHMvY29sb3InO1xuaW1wb3J0IHsgREVGQVVMVF9DQVRFR09SSUNBTF9QQUxFVFRFIH0gZnJvbSAnLi4vLi4vc3BhdGlhbC9zcGF0aWFsLWVuY29kaW5nJztcbmltcG9ydCB7IEdMWVBIX09QVElPTlMgfSBmcm9tICcuLi8uLi9zcGF0aWFsL3NwYXRpYWwtcGFuZWwtbW9kZWwnO1xuXG4vKipcbiAqIE9uZSBnZW5lJ3MgaWNvbiBhbmQgY29sb3VyOiB0aGUgaWNvbiBncmlkLCBhIGNvbG91ciBwaWNrZXIgd2l0aCBpdHMgaGV4IHZhbHVlLCBwcmVzZXRzLCBhbmRcbiAqIGEgcmVzZXQg4oCUIHRoZSBjb250ZW50IG9mIGEgcG9wb3ZlciBpdHMgaG9zdCBvcGVucyBvbiB0aGUgZ2VuZSdzIHN3YXRjaC4gV3JpdGVzIG5vdGhpbmcgaXRzZWxmOlxuICogaXQgcmVwb3J0cyB0aGUgY2hvaWNlLCBhbmQgdGhlIGhvc3Qgc3RvcmVzIGl0IHdoZXJlIGl0IGJlbG9uZ3MuXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ3NwYXRpYWwtZ2VuZS1zdHlsZScsXG4gIHN0YW5kYWxvbmU6IHRydWUsXG4gIGltcG9ydHM6IFtDb21tb25Nb2R1bGUsIEJ1dHRvbk1vZHVsZSwgSW5wdXRUZXh0TW9kdWxlXSxcbiAgdGVtcGxhdGVVcmw6ICcuL3NwYXRpYWwtZ2VuZS1zdHlsZS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3NwYXRpYWwtZ2VuZS1zdHlsZS5jb21wb25lbnQuc2NzcyddLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgU3BhdGlhbEdlbmVTdHlsZUNvbXBvbmVudCB7XG4gIC8qKiBUaGUgZ2VuZSwgZm9yIHRoZSBjb250cm9scycgbGFiZWxzLiAqL1xuICBASW5wdXQoKSBnZW5lID0gJyc7XG4gIC8qKiBXaGF0IHRoZSBpY29ucyBhbmQgY29sb3VyIGFyZSBvZiAoXCJPYnNlcnZhdGlvblwiLCBcIlRyYW5zY3JpcHRcIiksIGZvciB0aGUgdGl0bGVzLiAqL1xuICBASW5wdXQoKSB3aGF0ID0gJyc7XG4gIC8qKiBUaGUgZ2VuZSdzIGNvbG91ciwgYCNycmdnYmJgLiAqL1xuICBASW5wdXQoKSBjb2xvciA9ICcjZmZmZmZmJztcbiAgLyoqIFRoZSBnZW5lJ3MgaWNvbi4gKi9cbiAgQElucHV0KCkgZ2x5cGg6IFRyYW5zY3JpcHRHbHlwaE5hbWUgPSAnY2lyY2xlJztcbiAgLyoqIEEgbm90ZSB1bmRlciB0aGUgaWNvbnMsIGUuZy4gd2hlcmUgdGhleSBzaG93OyBub25lIHdoZW4gbnVsbC4gKi9cbiAgQElucHV0KCkgaWNvbkhpbnQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBAT3V0cHV0KCkgcmVhZG9ubHkgY29sb3JDaGFuZ2UgPSBuZXcgRXZlbnRFbWl0dGVyPHN0cmluZz4oKTtcbiAgQE91dHB1dCgpIHJlYWRvbmx5IGdseXBoQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxUcmFuc2NyaXB0R2x5cGhOYW1lPigpO1xuICAvKiogQmFjayB0byB0aGUgZ2VuZSdzIGRlZmF1bHQgaWNvbiBhbmQgY29sb3VyLiAqL1xuICBAT3V0cHV0KCkgcmVhZG9ubHkgcmVzZXRTdHlsZSA9IG5ldyBFdmVudEVtaXR0ZXI8dm9pZD4oKTtcblxuICBwcm90ZWN0ZWQgcmVhZG9ubHkgZ2x5cGhPcHRpb25zID0gR0xZUEhfT1BUSU9OUztcbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGNvbG9yUHJlc2V0cyA9IERFRkFVTFRfQ0FURUdPUklDQUxfUEFMRVRURS5zbGljZSgwLCAxMCkubWFwKChjKSA9PiBjLnRvTG93ZXJDYXNlKCkpO1xuXG4gIC8qKiBBIHR5cGVkIGhleCBjb2xvdXIsIGFjY2VwdGVkIGFzIGAjcnJnZ2JiYCBvciBgcnJnZ2JiYDsgYW55dGhpbmcgZWxzZSBpcyBpZ25vcmVkLiAqL1xuICBwcm90ZWN0ZWQgb25IZXgodGV4dDogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgdCA9IHRleHQudHJpbSgpO1xuICAgIGNvbnN0IHJnYiA9IC9eIz9bMC05YS1mXXs2fSQvaS50ZXN0KHQpID8gcGFyc2VDc3NDb2xvcih0KSA6IG51bGw7XG4gICAgaWYgKHJnYikgdGhpcy5jb2xvckNoYW5nZS5lbWl0KHJnYlRvSGV4KHJnYikpO1xuICB9XG59XG4iLCI8ZGl2IGNsYXNzPVwic2Mtc3R5bGUtcG9wXCI+XG4gIDxkaXYgY2xhc3M9XCJzYy1zdHlsZS10aXRsZVwiPnt7IHdoYXQgfX0gSWNvbjwvZGl2PlxuICA8ZGl2IGNsYXNzPVwic2Mtc3R5bGUtaWNvbnNcIiByb2xlPVwicmFkaW9ncm91cFwiIFthdHRyLmFyaWEtbGFiZWxdPVwiJ0ljb24gZm9yICcgKyBnZW5lXCI+XG4gICAgPGJ1dHRvblxuICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAqbmdGb3I9XCJsZXQgb3B0IG9mIGdseXBoT3B0aW9uc1wiXG4gICAgICBjbGFzcz1cInNjLXN0eWxlLWljb25cIlxuICAgICAgcm9sZT1cInJhZGlvXCJcbiAgICAgIFthdHRyLmFyaWEtY2hlY2tlZF09XCJvcHQudmFsdWUgPT09IGdseXBoXCJcbiAgICAgIFtjbGFzcy5hY3RpdmVdPVwib3B0LnZhbHVlID09PSBnbHlwaFwiXG4gICAgICBbdGl0bGVdPVwib3B0LmxhYmVsXCJcbiAgICAgIChjbGljayk9XCJnbHlwaENoYW5nZS5lbWl0KG9wdC52YWx1ZSlcIlxuICAgID5cbiAgICAgIDxzdmcgdmlld0JveD1cIi0xLjIgLTEuMiAyLjQgMi40XCIgY2xhc3M9XCJzYy1nbHlwaC1zdmdcIj5cbiAgICAgICAgPHBvbHlnb24gW2F0dHIucG9pbnRzXT1cIm9wdC5wb2ludHNcIj48L3BvbHlnb24+XG4gICAgICA8L3N2Zz5cbiAgICA8L2J1dHRvbj5cbiAgPC9kaXY+XG4gIDxzbWFsbCBjbGFzcz1cInNjLWhpbnRcIiAqbmdJZj1cImljb25IaW50XCI+e3sgaWNvbkhpbnQgfX08L3NtYWxsPlxuICA8ZGl2IGNsYXNzPVwic2Mtc3R5bGUtdGl0bGVcIj57eyB3aGF0IH19IENvbG9yPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJzYy1zdHlsZS1jb2xvclwiPlxuICAgIDxsYWJlbCBjbGFzcz1cInNjLXN0eWxlLXN3YXRjaFwiIFtzdHlsZS5iYWNrZ3JvdW5kXT1cImNvbG9yXCIgdGl0bGU9XCJQaWNrIGEgY29sb3VyXCI+XG4gICAgICA8aW5wdXQgdHlwZT1cImNvbG9yXCIgW3ZhbHVlXT1cImNvbG9yXCIgKGNoYW5nZSk9XCJjb2xvckNoYW5nZS5lbWl0KCRhbnkoJGV2ZW50LnRhcmdldCkudmFsdWUpXCIgLz5cbiAgICA8L2xhYmVsPlxuICAgIDxpbnB1dFxuICAgICAgcElucHV0VGV4dFxuICAgICAgY2xhc3M9XCJzYy1zdHlsZS1oZXhcIlxuICAgICAgW3ZhbHVlXT1cImNvbG9yXCJcbiAgICAgIG1heGxlbmd0aD1cIjdcIlxuICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCInSGV4IGNvbG91ciBmb3IgJyArIGdlbmVcIlxuICAgICAgKGNoYW5nZSk9XCJvbkhleCgkYW55KCRldmVudC50YXJnZXQpLnZhbHVlKVwiXG4gICAgICAoa2V5ZG93bi5lbnRlcik9XCJvbkhleCgkYW55KCRldmVudC50YXJnZXQpLnZhbHVlKVwiXG4gICAgLz5cbiAgPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJzYy1zdHlsZS10aXRsZSBzYy1zdHlsZS1zdWJcIj5QcmVzZXRzPC9kaXY+XG4gIDxkaXYgY2xhc3M9XCJzYy1zdHlsZS1wcmVzZXRzXCI+XG4gICAgPGJ1dHRvblxuICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAqbmdGb3I9XCJsZXQgYyBvZiBjb2xvclByZXNldHNcIlxuICAgICAgY2xhc3M9XCJzYy1zdHlsZS1wcmVzZXRcIlxuICAgICAgW3N0eWxlLmJhY2tncm91bmRdPVwiY1wiXG4gICAgICBbY2xhc3MuYWN0aXZlXT1cImMgPT09IGNvbG9yLnRvTG93ZXJDYXNlKClcIlxuICAgICAgW3RpdGxlXT1cImNcIlxuICAgICAgW2F0dHIuYXJpYS1sYWJlbF09XCInQ29sb3VyICcgKyBjXCJcbiAgICAgIChjbGljayk9XCJjb2xvckNoYW5nZS5lbWl0KGMpXCJcbiAgICA+PC9idXR0b24+XG4gIDwvZGl2PlxuICA8cC1idXR0b25cbiAgICBsYWJlbD1cIlJlc2V0IHRvIGRlZmF1bHRcIlxuICAgIGljb249XCJwaSBwaS1yZWZyZXNoXCJcbiAgICBzaXplPVwic21hbGxcIlxuICAgIFt0ZXh0XT1cInRydWVcIlxuICAgIHN0eWxlQ2xhc3M9XCJzYy1zdHlsZS1yZXNldFwiXG4gICAgKG9uQ2xpY2spPVwicmVzZXRTdHlsZS5lbWl0KClcIlxuICA+PC9wLWJ1dHRvbj5cbjwvZGl2PlxuIl19