@jax-data-science/sci-image-visualizer 0.8.3 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +201 -460
- package/esm2022/index.mjs +28 -15
- package/esm2022/lib/channel-histogram/channel-histogram.component.mjs +163 -91
- package/esm2022/lib/contracts/capabilities.contract.mjs +4 -3
- package/esm2022/lib/contracts/cell-segmenter.contract.mjs +1 -1
- package/esm2022/lib/contracts/channel-histogram-api.contract.mjs +5 -1
- package/esm2022/lib/contracts/color.mjs +60 -0
- package/esm2022/lib/contracts/colormap-lut.mjs +213 -57
- package/esm2022/lib/contracts/coordinate-transform.contract.mjs +1 -1
- package/esm2022/lib/contracts/display-types.mjs +11 -1
- package/esm2022/lib/contracts/instance-segmenter.contract.mjs +1 -1
- package/esm2022/lib/contracts/intensity.mjs +48 -5
- package/esm2022/lib/contracts/plot-type-contribution.contract.mjs +1 -1
- package/esm2022/lib/contracts/plot-type.mjs +134 -17
- package/esm2022/lib/contracts/ports/image-state.port.mjs +4 -1
- package/esm2022/lib/contracts/ports/preferences.port.mjs +5 -1
- package/esm2022/lib/contracts/ports/region-io.port.mjs +2 -1
- package/esm2022/lib/contracts/ports/spatial-data.port.mjs +5 -1
- package/esm2022/lib/contracts/ports/tile-access.port.mjs +2 -1
- package/esm2022/lib/contracts/region-editor-api.contract.mjs +1 -1
- package/esm2022/lib/contracts/region-overlay.contract.mjs +1 -1
- package/esm2022/lib/contracts/sam.contract.mjs +1 -1
- package/esm2022/lib/contracts/semantic-segmenter.contract.mjs +1 -1
- package/esm2022/lib/contracts/spatial-dataset.contract.mjs +3 -1
- package/esm2022/lib/contracts/toolbar-tool.contract.mjs +6 -4
- package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
- package/esm2022/lib/contracts/viz-config.mjs +2 -1
- package/esm2022/lib/geometry/contour.mjs +63 -0
- package/esm2022/lib/geometry/raster.mjs +98 -0
- package/esm2022/lib/geometry/ring.mjs +201 -0
- package/esm2022/lib/hex-color-picker/hex-color-picker.component.mjs +202 -102
- package/esm2022/lib/implementations/base-store-visualizer.mjs +201 -48
- package/esm2022/lib/implementations/napari-js/napari-axes-gizmo.mjs +65 -0
- package/esm2022/lib/implementations/napari-js/napari-display-state.mjs +136 -0
- package/esm2022/lib/implementations/napari-js/napari-helpers.mjs +199 -0
- package/esm2022/lib/implementations/napari-js/napari-image-2d-scene.mjs +602 -0
- package/esm2022/lib/implementations/napari-js/napari-loading-badge.mjs +3 -4
- package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +66 -0
- package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +157 -591
- package/esm2022/lib/implementations/napari-js/napari-scene.mjs +2 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-2d-scene.mjs +614 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-3d-scene.mjs +769 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-encoding.mjs +199 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +263 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-scene.mjs +159 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-tiles.mjs +106 -1408
- package/esm2022/lib/implementations/napari-js/napari-spatial-tooltip.mjs +2 -2
- package/esm2022/lib/implementations/napari-js/napari-surface-scene.mjs +271 -0
- package/esm2022/lib/implementations/napari-js/napari-tile-client.mjs +562 -0
- package/esm2022/lib/implementations/napari-js/napari-tool-bridge.mjs +344 -0
- package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +358 -4218
- package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +439 -0
- package/esm2022/lib/implementations/napari-js/napari-volume-z-handle.mjs +6 -6
- package/esm2022/lib/implementations/napari-js/region-overlay/overlay-projection.mjs +96 -0
- package/esm2022/lib/implementations/napari-js/region-overlay/region-edit.mjs +35 -0
- package/esm2022/lib/implementations/napari-js/region-overlay/region-svg-renderer.mjs +182 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/categorical-lookup.mjs +30 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/cell-layers.mjs +274 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/density-layer.mjs +144 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/layer-groups.mjs +165 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/plan-context.mjs +78 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-hover.mjs +182 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-jobs.mjs +369 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-layers.mjs +306 -0
- package/esm2022/lib/implementations/osd/display-pipeline.mjs +102 -40
- package/esm2022/lib/implementations/osd/histogram-sampler.mjs +56 -31
- package/esm2022/lib/implementations/osd/openseadragon-viewer-options.mjs +128 -0
- package/esm2022/lib/implementations/osd/openseadragon-visualizer.service.mjs +333 -1685
- package/esm2022/lib/implementations/osd/osd-coordinate-transform.mjs +1 -1
- package/esm2022/lib/implementations/osd/osd-coords.mjs +5 -6
- package/esm2022/lib/implementations/osd/osd-export.mjs +122 -0
- package/esm2022/lib/implementations/osd/osd-lib.mjs +15 -1
- package/esm2022/lib/implementations/osd/osd-navigator-chrome.mjs +205 -0
- package/esm2022/lib/implementations/osd/osd-pixel-readback.mjs +68 -0
- package/esm2022/lib/implementations/osd/osd-region-overlay-draw.mjs +153 -0
- package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +185 -718
- package/esm2022/lib/implementations/osd/osd-scale-bar.mjs +52 -60
- package/esm2022/lib/implementations/osd/osd-tile-source.mjs +105 -0
- package/esm2022/lib/implementations/osd/osd-viewer-like.mjs +2 -0
- package/esm2022/lib/implementations/osd/osd-viewer-mount.mjs +44 -0
- package/esm2022/lib/implementations/osd/osd-viewport.mjs +184 -0
- package/esm2022/lib/implementations/osd/osd-zoom.mjs +7 -1
- package/esm2022/lib/implementations/osd/simple-source.mjs +395 -0
- package/esm2022/lib/implementations/osd/slice-cache.mjs +53 -48
- package/esm2022/lib/implementations/osd/tile-client.mjs +32 -11
- package/esm2022/lib/implementations/osd/tile-recolor.mjs +330 -0
- package/esm2022/lib/implementations/plotly/omics-trace-builders.mjs +161 -73
- package/esm2022/lib/implementations/plotly/plotly-coordinate-transform.mjs +1 -1
- package/esm2022/lib/implementations/plotly/plotly-image-loader.mjs +112 -0
- package/esm2022/lib/implementations/plotly/plotly-image-recolor.mjs +178 -0
- package/esm2022/lib/implementations/plotly/plotly-intensity-inset.mjs +33 -0
- package/esm2022/lib/implementations/plotly/plotly-isosurface-controls.mjs +83 -0
- package/esm2022/lib/implementations/plotly/plotly-layouts.mjs +121 -0
- package/esm2022/lib/implementations/plotly/plotly-readback.mjs +117 -0
- package/esm2022/lib/implementations/plotly/plotly-region-overlay.mjs +19 -10
- package/esm2022/lib/implementations/plotly/plotly-shape-projection.mjs +223 -0
- package/esm2022/lib/implementations/plotly/plotly-trace-builders.mjs +79 -19
- package/esm2022/lib/implementations/plotly/plotly-zoom-controller.mjs +223 -0
- package/esm2022/lib/implementations/plotly/plotly.service.mjs +439 -1655
- package/esm2022/lib/implementations/region-centroids.mjs +47 -0
- package/esm2022/lib/implementations/simple-slice-access.service.mjs +22 -12
- package/esm2022/lib/implementations/spatial-data-http/spatial-data-http.service.mjs +172 -92
- package/esm2022/lib/implementations/spatial-data-http/spatial-wire.mjs +103 -22
- package/esm2022/lib/implementations/tile-server/index.mjs +6 -0
- package/esm2022/lib/implementations/tile-server/native-histogram.mjs +30 -0
- package/esm2022/lib/implementations/tile-server/poll-descriptor.mjs +65 -0
- package/esm2022/lib/implementations/tile-server/tile-protocol.mjs +42 -0
- package/esm2022/lib/implementations/tile-server/transport.mjs +135 -0
- package/esm2022/lib/intensity/intensity-profile.mjs +107 -0
- package/esm2022/lib/intensity/intensity-profile.service.mjs +223 -0
- package/esm2022/lib/intensity-inset/intensity-inset.component.mjs +133 -0
- package/esm2022/lib/models/bezier.mjs +1 -11
- package/esm2022/lib/models/class-preset.mjs +41 -3
- package/esm2022/lib/models/geometry.mjs +27 -164
- package/esm2022/lib/models/polygon-edit.mjs +254 -0
- package/esm2022/lib/models/polygon-factory.mjs +118 -0
- package/esm2022/lib/models/region-clone.mjs +68 -0
- package/esm2022/lib/models/region-geojson.mjs +373 -0
- package/esm2022/lib/models/region.mjs +34 -33
- package/esm2022/lib/models/shape.mjs +18 -16
- package/esm2022/lib/plot-mode/contribution-host.mjs +297 -0
- package/esm2022/lib/plot-mode/plot-mode-controller.mjs +9 -6
- package/esm2022/lib/plot-mode/plot-type-menu.mjs +85 -0
- package/esm2022/lib/plot-mode/tool-params-model.mjs +87 -0
- package/esm2022/lib/plot.utilities.mjs +296 -473
- package/esm2022/lib/processing/image-crop.mjs +1 -1
- package/esm2022/lib/processing/processing-image.mjs +28 -15
- package/esm2022/lib/provide-visualization.mjs +40 -14
- package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +99 -0
- package/esm2022/lib/region-editor/file-stem.mjs +13 -0
- package/esm2022/lib/region-editor/manage-classes-dialog/manage-classes-dialog.component.mjs +118 -0
- package/esm2022/lib/region-editor/mask-export.service.mjs +98 -0
- package/esm2022/lib/region-editor/mask-raster.mjs +11 -5
- package/esm2022/lib/region-editor/region-color-dialog/region-color-dialog.component.mjs +56 -0
- package/esm2022/lib/region-editor/region-editor-help/region-editor-help.component.mjs +28 -0
- package/esm2022/lib/region-editor/region-editor.component.mjs +402 -651
- package/esm2022/lib/region-editor/region-metrics.mjs +68 -0
- package/esm2022/lib/region-editor/region-persistence.service.mjs +134 -0
- package/esm2022/lib/region-editor/region-table/region-table.component.mjs +153 -0
- package/esm2022/lib/region-editor/save-mask-dialog/save-mask-dialog.component.mjs +91 -0
- package/esm2022/lib/region-editor/save-regions-dialog/save-regions-dialog.component.mjs +92 -0
- package/esm2022/lib/region-ops.service.mjs +28 -70
- package/esm2022/lib/region-overlay/region-geometry.mjs +360 -0
- package/esm2022/lib/region-overlay/region-hit-test.mjs +103 -0
- package/esm2022/lib/region-overlay/svg-region-renderer.mjs +228 -0
- package/esm2022/lib/render-orchestrator.mjs +14 -11
- package/esm2022/lib/render-session.mjs +207 -0
- package/esm2022/lib/routing-visualizer.service.mjs +459 -411
- package/esm2022/lib/spatial/density-raster.mjs +14 -0
- package/esm2022/lib/spatial/embedding-compute-coordinator.mjs +239 -0
- package/esm2022/lib/spatial/embedding-compute.mjs +43 -10
- package/esm2022/lib/spatial/gene-search.mjs +1 -1
- package/esm2022/lib/spatial/glyphs.mjs +97 -0
- package/esm2022/lib/spatial/lod.mjs +187 -0
- package/esm2022/lib/spatial/spatial-controls.facade.mjs +200 -0
- package/esm2022/lib/spatial/spatial-density.mjs +25 -16
- package/esm2022/lib/spatial/spatial-encoding.mjs +26 -82
- package/esm2022/lib/spatial/spatial-expression.mjs +43 -42
- package/esm2022/lib/spatial/spatial-framing.mjs +1 -1
- package/esm2022/lib/spatial/spatial-heatmap.mjs +6 -3
- package/esm2022/lib/spatial/spatial-hover.mjs +5 -33
- package/esm2022/lib/spatial/spatial-panel-model.mjs +282 -0
- package/esm2022/lib/spatial/spatial-sections.mjs +1 -1
- package/esm2022/lib/spatial/spatial-selection.mjs +33 -46
- package/esm2022/lib/spatial/spatial-tile-merge.mjs +219 -0
- package/esm2022/lib/spatial/spatial-tiles.mjs +12 -648
- package/esm2022/lib/spatial/spatial-volume-image.mjs +2 -4
- package/esm2022/lib/spatial/stats.mjs +71 -0
- package/esm2022/lib/spatial/transcript-grouping.mjs +307 -0
- package/esm2022/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.mjs +150 -0
- package/esm2022/lib/spatial-controls/spatial-charts/chart-data-model.mjs +309 -0
- package/esm2022/lib/spatial-controls/spatial-charts/chart-help.mjs +145 -0
- package/esm2022/lib/spatial-controls/spatial-charts/plotly-chart-host.mjs +158 -0
- package/esm2022/lib/spatial-controls/spatial-charts/spatial-chart-window/spatial-chart-window.component.mjs +47 -0
- package/esm2022/lib/spatial-controls/spatial-charts/spatial-charts.component.mjs +297 -802
- package/esm2022/lib/spatial-controls/spatial-charts/spatial-embedding-controls/spatial-embedding-controls.component.mjs +89 -0
- package/esm2022/lib/spatial-controls/spatial-charts/spatial-heatmap-controls/spatial-heatmap-controls.component.mjs +52 -0
- package/esm2022/lib/spatial-controls/spatial-controls.component.mjs +143 -1238
- package/esm2022/lib/spatial-controls/spatial-gene-picker.mjs +153 -0
- package/esm2022/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.mjs +241 -0
- package/esm2022/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.mjs +193 -0
- package/esm2022/lib/spatial-controls/spatial-key/spatial-key.component.mjs +132 -0
- package/esm2022/lib/spatial-controls/spatial-key/spatial-key.model.mjs +67 -0
- package/esm2022/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.mjs +147 -0
- package/esm2022/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.mjs +300 -0
- package/esm2022/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.mjs +370 -0
- package/esm2022/lib/store/class-color.util.mjs +46 -3
- package/esm2022/lib/store/region-history.mjs +146 -0
- package/esm2022/lib/store/region-scope-cache.mjs +140 -0
- package/esm2022/lib/store/region-selection.mjs +82 -0
- package/esm2022/lib/store/region-store.service.mjs +279 -675
- package/esm2022/lib/store/spatial-selection.service.mjs +2 -2
- package/esm2022/lib/store/visualizer-store.service.mjs +49 -71
- package/esm2022/lib/toast-outlets.mjs +5 -4
- package/esm2022/lib/toolbar/brush/brush-tool.service.mjs +92 -434
- package/esm2022/lib/toolbar/canvas-tools.mjs +20 -0
- package/esm2022/lib/toolbar/crop/slide-crop.mjs +26 -42
- package/esm2022/lib/toolbar/plot-type-selector/plot-type-selector.component.mjs +85 -0
- package/esm2022/lib/toolbar/region-tools/region-tool-buttons.mjs +74 -0
- package/esm2022/lib/toolbar/region-tools/region-tools.component.mjs +114 -0
- package/esm2022/lib/toolbar/segmentation/cell-segment-tool.service.mjs +74 -78
- package/esm2022/lib/toolbar/segmentation/cellpose-segmenter.service.mjs +50 -8
- package/esm2022/lib/toolbar/segmentation/onnx-sam-session.mjs +61 -42
- package/esm2022/lib/toolbar/segmentation/pending-calls.mjs +47 -0
- package/esm2022/lib/toolbar/segmentation/sam-model-registry.mjs +12 -4
- package/esm2022/lib/toolbar/segmentation/sam-onnx-core.mjs +70 -14
- package/esm2022/lib/toolbar/segmentation/sam-point-tool.service.mjs +135 -172
- package/esm2022/lib/toolbar/segmentation/sam-prompt.mjs +9 -90
- package/esm2022/lib/toolbar/segmentation/sam-session.service.mjs +183 -0
- package/esm2022/lib/toolbar/segmentation/sam-tool.service.mjs +95 -150
- package/esm2022/lib/toolbar/segmentation/segmentation-commit.mjs +12 -0
- package/esm2022/lib/toolbar/segmentation/segmentation-runner.mjs +108 -0
- package/esm2022/lib/toolbar/segmentation-tools/segmentation-tools.component.mjs +155 -0
- package/esm2022/lib/toolbar/stack-controls/stack-controls.component.mjs +81 -0
- package/esm2022/lib/toolbar/tool-kit/async-tool-status.mjs +37 -0
- package/esm2022/lib/toolbar/tool-kit/canvas-tool-manager.mjs +63 -0
- package/esm2022/lib/toolbar/tool-kit/canvas-tool.mjs +2 -0
- package/esm2022/lib/toolbar/tool-kit/frame-pixels.mjs +108 -0
- package/esm2022/lib/toolbar/tool-kit/mask-stroke-editor.mjs +306 -0
- package/esm2022/lib/toolbar/tool-kit/matrix-frame.mjs +61 -0
- package/esm2022/lib/toolbar/tool-kit/tool-overlay.mjs +140 -0
- package/esm2022/lib/toolbar/tool-kit/undo-gesture.mjs +24 -0
- package/esm2022/lib/toolbar/tool-slider/tool-slider.component.mjs +63 -0
- package/esm2022/lib/toolbar/toolbar-help-dialog/toolbar-help-dialog.component.mjs +50 -0
- package/esm2022/lib/toolbar/toolbar.component.mjs +68 -117
- package/esm2022/lib/toolbar/vertex-eraser/vertex-eraser-tool.service.mjs +93 -115
- package/esm2022/lib/toolbar/view-controls/view-controls.component.mjs +107 -0
- package/esm2022/lib/toolbar/wand/wand-region-grow.mjs +321 -0
- package/esm2022/lib/toolbar/wand/wand-tool.service.mjs +121 -416
- package/esm2022/lib/toolbar/wand/wand.service.mjs +30 -894
- package/esm2022/lib/toolbar/zoom-to-box/zoom-to-box-tool.service.mjs +48 -90
- package/esm2022/lib/util/mark-for-check.mjs +17 -0
- package/esm2022/lib/util/supersede.mjs +56 -0
- package/esm2022/lib/visualization.module.mjs +39 -141
- package/esm2022/lib/visualizer/floating-drag.directive.mjs +58 -0
- package/esm2022/lib/visualizer/region-actions.mjs +149 -0
- package/esm2022/lib/visualizer/region-load.mjs +60 -0
- package/esm2022/lib/visualizer/spatial-dataset-binder.mjs +163 -0
- package/esm2022/lib/visualizer/tool-modes.mjs +113 -0
- package/esm2022/lib/visualizer/viewer-shortcuts.mjs +167 -0
- package/esm2022/lib/visualizer/visualizer-context-menu.mjs +119 -0
- package/esm2022/lib/visualizer.component.mjs +480 -1902
- package/esm2022/lib/workers/spatial-math-ops.mjs +43 -0
- package/esm2022/lib/workers/spatial-math-worker.mjs +10 -0
- package/esm2022/lib/workers/spatial-math.mjs +190 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs +41083 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs +238 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-spatial-math-worker-BzVFFqGS.mjs +12 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-spatial-math-worker-BzVFFqGS.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs +41 -34467
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs.map +1 -1
- package/fesm2022/mask.worker.js +36 -917
- package/fesm2022/onnx-sam.worker.js +52 -16
- package/fesm2022/spatial-math.worker.js +471 -0
- package/fesm2022/tsne.worker.js +32 -15
- package/index.d.ts +13 -10
- package/lib/channel-histogram/channel-histogram.component.d.ts +53 -43
- package/lib/contracts/capabilities.contract.d.ts +4 -2
- package/lib/contracts/cell-segmenter.contract.d.ts +1 -0
- package/lib/contracts/channel-histogram-api.contract.d.ts +4 -0
- package/lib/contracts/color.d.ts +27 -0
- package/lib/contracts/colormap-lut.d.ts +19 -4
- package/lib/contracts/coordinate-transform.contract.d.ts +3 -3
- package/lib/contracts/display-types.d.ts +21 -0
- package/lib/contracts/instance-segmenter.contract.d.ts +5 -0
- package/lib/contracts/intensity.d.ts +13 -2
- package/lib/contracts/plot-type.d.ts +3 -1
- package/lib/contracts/ports/image-state.port.d.ts +6 -2
- package/lib/contracts/ports/preferences.port.d.ts +4 -0
- package/lib/contracts/ports/region-io.port.d.ts +1 -0
- package/lib/contracts/ports/spatial-data.port.d.ts +4 -10
- package/lib/contracts/ports/tile-access.port.d.ts +1 -0
- package/lib/contracts/region-editor-api.contract.d.ts +1 -1
- package/lib/contracts/region-overlay.contract.d.ts +5 -0
- package/lib/contracts/sam.contract.d.ts +7 -0
- package/lib/contracts/semantic-segmenter.contract.d.ts +6 -0
- package/lib/contracts/spatial-dataset.contract.d.ts +19 -6
- package/lib/contracts/toolbar-tool.contract.d.ts +1 -0
- package/lib/contracts/visualizer.contract.d.ts +221 -54
- package/lib/contracts/viz-config.d.ts +1 -0
- package/lib/geometry/contour.d.ts +24 -0
- package/lib/geometry/raster.d.ts +42 -0
- package/lib/geometry/ring.d.ts +67 -0
- package/lib/hex-color-picker/hex-color-picker.component.d.ts +61 -27
- package/lib/implementations/base-store-visualizer.d.ts +61 -15
- package/lib/implementations/napari-js/napari-axes-gizmo.d.ts +36 -0
- package/lib/implementations/napari-js/napari-display-state.d.ts +76 -0
- package/lib/implementations/napari-js/napari-helpers.d.ts +129 -0
- package/lib/implementations/napari-js/napari-image-2d-scene.d.ts +162 -0
- package/lib/implementations/napari-js/napari-loading-badge.d.ts +0 -1
- package/lib/implementations/napari-js/napari-loading-state.d.ts +30 -0
- package/lib/implementations/napari-js/napari-region-overlay.d.ts +62 -70
- package/lib/implementations/napari-js/napari-scene.d.ts +93 -0
- package/lib/implementations/napari-js/napari-spatial-2d-scene.d.ts +163 -0
- package/lib/implementations/napari-js/napari-spatial-3d-scene.d.ts +212 -0
- package/lib/implementations/napari-js/napari-spatial-encoding.d.ts +114 -0
- package/lib/implementations/napari-js/napari-spatial-hover.d.ts +89 -0
- package/lib/implementations/napari-js/napari-spatial-scene.d.ts +118 -0
- package/lib/implementations/napari-js/napari-spatial-tiles.d.ts +56 -263
- package/lib/implementations/napari-js/napari-spatial-tooltip.d.ts +1 -1
- package/lib/implementations/napari-js/napari-surface-scene.d.ts +76 -0
- package/lib/implementations/napari-js/napari-tile-client.d.ts +214 -0
- package/lib/implementations/napari-js/napari-tool-bridge.d.ts +179 -0
- package/lib/implementations/napari-js/napari-visualizer.service.d.ts +121 -883
- package/lib/implementations/napari-js/napari-volume-scene.d.ts +104 -0
- package/lib/implementations/napari-js/napari-volume-z-handle.d.ts +8 -12
- package/lib/implementations/napari-js/region-overlay/overlay-projection.d.ts +59 -0
- package/lib/implementations/napari-js/region-overlay/region-edit.d.ts +15 -0
- package/lib/implementations/napari-js/region-overlay/region-svg-renderer.d.ts +54 -0
- package/lib/implementations/napari-js/spatial-tiles/categorical-lookup.d.ts +26 -0
- package/lib/implementations/napari-js/spatial-tiles/cell-layers.d.ts +70 -0
- package/lib/implementations/napari-js/spatial-tiles/density-layer.d.ts +61 -0
- package/lib/implementations/napari-js/spatial-tiles/layer-groups.d.ts +67 -0
- package/lib/implementations/napari-js/spatial-tiles/plan-context.d.ts +38 -0
- package/lib/implementations/napari-js/spatial-tiles/transcript-hover.d.ts +71 -0
- package/lib/implementations/napari-js/spatial-tiles/transcript-jobs.d.ts +105 -0
- package/lib/implementations/napari-js/spatial-tiles/transcript-layers.d.ts +56 -0
- package/lib/implementations/osd/display-pipeline.d.ts +38 -9
- package/lib/implementations/osd/histogram-sampler.d.ts +22 -12
- package/lib/implementations/osd/openseadragon-viewer-options.d.ts +35 -0
- package/lib/implementations/osd/openseadragon-visualizer.service.d.ts +78 -354
- package/lib/implementations/osd/osd-coordinate-transform.d.ts +2 -1
- package/lib/implementations/osd/osd-coords.d.ts +6 -4
- package/lib/implementations/osd/osd-export.d.ts +36 -0
- package/lib/implementations/osd/osd-lib.d.ts +7 -0
- package/lib/implementations/osd/osd-navigator-chrome.d.ts +69 -0
- package/lib/implementations/osd/osd-pixel-readback.d.ts +22 -0
- package/lib/implementations/osd/osd-region-overlay-draw.d.ts +37 -0
- package/lib/implementations/osd/osd-region-overlay.d.ts +36 -48
- package/lib/implementations/osd/osd-scale-bar.d.ts +8 -6
- package/lib/implementations/osd/osd-tile-source.d.ts +49 -0
- package/lib/implementations/osd/osd-viewer-like.d.ts +100 -0
- package/lib/implementations/osd/osd-viewer-mount.d.ts +14 -0
- package/lib/implementations/osd/osd-viewport.d.ts +77 -0
- package/lib/implementations/osd/osd-zoom.d.ts +6 -0
- package/lib/implementations/osd/simple-source.d.ts +161 -0
- package/lib/implementations/osd/slice-cache.d.ts +12 -3
- package/lib/implementations/osd/tile-client.d.ts +11 -14
- package/lib/implementations/osd/tile-recolor.d.ts +141 -0
- package/lib/implementations/plotly/omics-trace-builders.d.ts +32 -20
- package/lib/implementations/plotly/plotly-image-loader.d.ts +49 -0
- package/lib/implementations/plotly/plotly-image-recolor.d.ts +75 -0
- package/lib/implementations/plotly/plotly-intensity-inset.d.ts +8 -0
- package/lib/implementations/plotly/plotly-isosurface-controls.d.ts +38 -0
- package/lib/implementations/plotly/plotly-layouts.d.ts +188 -0
- package/lib/implementations/plotly/plotly-readback.d.ts +41 -0
- package/lib/implementations/plotly/plotly-region-overlay.d.ts +2 -2
- package/lib/implementations/plotly/plotly-shape-projection.d.ts +92 -0
- package/lib/implementations/plotly/plotly-trace-builders.d.ts +23 -12
- package/lib/implementations/plotly/plotly-zoom-controller.d.ts +86 -0
- package/lib/implementations/plotly/plotly.service.d.ts +136 -401
- package/lib/implementations/region-centroids.d.ts +14 -0
- package/lib/implementations/simple-slice-access.service.d.ts +7 -4
- package/lib/implementations/spatial-data-http/spatial-data-http.service.d.ts +42 -18
- package/lib/implementations/spatial-data-http/spatial-wire.d.ts +34 -9
- package/lib/implementations/tile-server/index.d.ts +5 -0
- package/lib/implementations/tile-server/native-histogram.d.ts +25 -0
- package/lib/implementations/tile-server/poll-descriptor.d.ts +39 -0
- package/lib/implementations/tile-server/tile-protocol.d.ts +80 -0
- package/lib/implementations/tile-server/transport.d.ts +62 -0
- package/lib/intensity/intensity-profile.d.ts +66 -0
- package/lib/intensity/intensity-profile.service.d.ts +108 -0
- package/lib/intensity-inset/intensity-inset.component.d.ts +58 -0
- package/lib/models/bezier.d.ts +0 -5
- package/lib/models/class-preset.d.ts +18 -0
- package/lib/models/geometry.d.ts +14 -48
- package/lib/models/polygon-edit.d.ts +72 -0
- package/lib/models/polygon-factory.d.ts +40 -0
- package/lib/models/region-clone.d.ts +20 -0
- package/lib/models/region-geojson.d.ts +17 -0
- package/lib/models/region.d.ts +40 -4
- package/lib/models/shape.d.ts +8 -0
- package/lib/plot-mode/contribution-host.d.ts +125 -0
- package/lib/plot-mode/plot-type-menu.d.ts +60 -0
- package/lib/plot-mode/tool-params-model.d.ts +49 -0
- package/lib/plot.utilities.d.ts +19 -30
- package/lib/processing/processing-image.d.ts +5 -2
- package/lib/provide-visualization.d.ts +19 -2
- package/lib/region-editor/classes-panel/classes-panel.component.d.ts +56 -0
- package/lib/region-editor/file-stem.d.ts +7 -0
- package/lib/region-editor/manage-classes-dialog/manage-classes-dialog.component.d.ts +45 -0
- package/lib/region-editor/mask-export.service.d.ts +54 -0
- package/lib/region-editor/mask-raster.d.ts +2 -8
- package/lib/region-editor/region-color-dialog/region-color-dialog.component.d.ts +29 -0
- package/lib/region-editor/region-editor-help/region-editor-help.component.d.ts +11 -0
- package/lib/region-editor/region-editor.component.d.ts +166 -199
- package/lib/region-editor/region-metrics.d.ts +26 -0
- package/lib/region-editor/region-persistence.service.d.ts +69 -0
- package/lib/region-editor/region-table/region-table.component.d.ts +83 -0
- package/lib/region-editor/save-mask-dialog/save-mask-dialog.component.d.ts +36 -0
- package/lib/region-editor/save-regions-dialog/save-regions-dialog.component.d.ts +37 -0
- package/lib/region-ops.service.d.ts +1 -7
- package/lib/region-overlay/region-geometry.d.ts +157 -0
- package/lib/region-overlay/region-hit-test.d.ts +38 -0
- package/lib/region-overlay/svg-region-renderer.d.ts +110 -0
- package/lib/render-orchestrator.d.ts +6 -2
- package/lib/render-session.d.ts +75 -0
- package/lib/routing-visualizer.service.d.ts +110 -58
- package/lib/spatial/density-raster.d.ts +6 -0
- package/lib/spatial/embedding-compute-coordinator.d.ts +123 -0
- package/lib/spatial/embedding-compute.d.ts +21 -2
- package/lib/spatial/glyphs.d.ts +16 -0
- package/lib/spatial/lod.d.ts +94 -0
- package/lib/spatial/spatial-controls.facade.d.ts +64 -0
- package/lib/spatial/spatial-density.d.ts +15 -5
- package/lib/spatial/spatial-encoding.d.ts +11 -44
- package/lib/spatial/spatial-expression.d.ts +40 -22
- package/lib/spatial/spatial-framing.d.ts +1 -0
- package/lib/spatial/spatial-heatmap.d.ts +2 -0
- package/lib/spatial/spatial-hover.d.ts +4 -16
- package/lib/spatial/spatial-panel-model.d.ts +135 -0
- package/lib/spatial/spatial-selection.d.ts +21 -26
- package/lib/spatial/spatial-tile-merge.d.ts +41 -0
- package/lib/spatial/spatial-tiles.d.ts +9 -256
- package/lib/spatial/stats.d.ts +38 -0
- package/lib/spatial/transcript-grouping.d.ts +119 -0
- package/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.d.ts +64 -0
- package/lib/spatial-controls/spatial-charts/chart-data-model.d.ts +153 -0
- package/lib/spatial-controls/spatial-charts/chart-help.d.ts +69 -0
- package/lib/spatial-controls/spatial-charts/plotly-chart-host.d.ts +98 -0
- package/lib/spatial-controls/spatial-charts/spatial-chart-window/spatial-chart-window.component.d.ts +26 -0
- package/lib/spatial-controls/spatial-charts/spatial-charts.component.d.ts +101 -260
- package/lib/spatial-controls/spatial-charts/spatial-embedding-controls/spatial-embedding-controls.component.d.ts +43 -0
- package/lib/spatial-controls/spatial-charts/spatial-heatmap-controls/spatial-heatmap-controls.component.d.ts +27 -0
- package/lib/spatial-controls/spatial-controls.component.d.ts +68 -448
- package/lib/spatial-controls/spatial-gene-picker.d.ts +86 -0
- package/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.d.ts +102 -0
- package/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.d.ts +72 -0
- package/lib/spatial-controls/spatial-key/spatial-key.component.d.ts +66 -0
- package/lib/spatial-controls/spatial-key/spatial-key.model.d.ts +33 -0
- package/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.d.ts +64 -0
- package/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.d.ts +117 -0
- package/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.d.ts +142 -0
- package/lib/store/class-color.util.d.ts +35 -1
- package/lib/store/region-history.d.ts +66 -0
- package/lib/store/region-scope-cache.d.ts +63 -0
- package/lib/store/region-selection.d.ts +36 -0
- package/lib/store/region-store.service.d.ts +104 -112
- package/lib/store/visualizer-store.service.d.ts +22 -33
- package/lib/toast-outlets.d.ts +4 -3
- package/lib/toolbar/brush/brush-tool.service.d.ts +31 -98
- package/lib/toolbar/canvas-tools.d.ts +20 -0
- package/lib/toolbar/crop/slide-crop.d.ts +10 -4
- package/lib/toolbar/plot-type-selector/plot-type-selector.component.d.ts +38 -0
- package/lib/toolbar/region-tools/region-tool-buttons.d.ts +21 -0
- package/lib/toolbar/region-tools/region-tools.component.d.ts +60 -0
- package/lib/toolbar/segmentation/cell-segment-tool.service.d.ts +10 -14
- package/lib/toolbar/segmentation/cellpose-segmenter.service.d.ts +12 -2
- package/lib/toolbar/segmentation/onnx-sam-session.d.ts +22 -3
- package/lib/toolbar/segmentation/pending-calls.d.ts +31 -0
- package/lib/toolbar/segmentation/sam-model-registry.d.ts +9 -3
- package/lib/toolbar/segmentation/sam-onnx-core.d.ts +18 -5
- package/lib/toolbar/segmentation/sam-point-tool.service.d.ts +46 -32
- package/lib/toolbar/segmentation/sam-prompt.d.ts +7 -31
- package/lib/toolbar/segmentation/sam-session.service.d.ts +74 -0
- package/lib/toolbar/segmentation/sam-tool.service.d.ts +23 -30
- package/lib/toolbar/segmentation/segmentation-commit.d.ts +8 -0
- package/lib/toolbar/segmentation/segmentation-runner.d.ts +52 -0
- package/lib/toolbar/segmentation-tools/segmentation-tools.component.d.ts +87 -0
- package/lib/toolbar/stack-controls/stack-controls.component.d.ts +40 -0
- package/lib/toolbar/tool-kit/async-tool-status.d.ts +21 -0
- package/lib/toolbar/tool-kit/canvas-tool-manager.d.ts +36 -0
- package/lib/toolbar/tool-kit/canvas-tool.d.ts +86 -0
- package/lib/toolbar/tool-kit/frame-pixels.d.ts +45 -0
- package/lib/toolbar/tool-kit/mask-stroke-editor.d.ts +125 -0
- package/lib/toolbar/tool-kit/matrix-frame.d.ts +40 -0
- package/lib/toolbar/tool-kit/tool-overlay.d.ts +60 -0
- package/lib/toolbar/tool-kit/undo-gesture.d.ts +17 -0
- package/lib/toolbar/tool-slider/tool-slider.component.d.ts +33 -0
- package/lib/toolbar/toolbar-help-dialog/toolbar-help-dialog.component.d.ts +24 -0
- package/lib/toolbar/toolbar.component.d.ts +47 -83
- package/lib/toolbar/vertex-eraser/vertex-eraser-tool.service.d.ts +33 -40
- package/lib/toolbar/view-controls/view-controls.component.d.ts +54 -0
- package/lib/toolbar/wand/wand-region-grow.d.ts +49 -0
- package/lib/toolbar/wand/wand-tool.service.d.ts +39 -124
- package/lib/toolbar/wand/wand.service.d.ts +22 -116
- package/lib/toolbar/zoom-to-box/zoom-to-box-tool.service.d.ts +17 -37
- package/lib/util/mark-for-check.d.ts +11 -0
- package/lib/util/supersede.d.ts +53 -0
- package/lib/visualization.module.d.ts +18 -39
- package/lib/visualizer/floating-drag.directive.d.ts +30 -0
- package/lib/visualizer/region-actions.d.ts +54 -0
- package/lib/visualizer/region-load.d.ts +27 -0
- package/lib/visualizer/spatial-dataset-binder.d.ts +74 -0
- package/lib/visualizer/tool-modes.d.ts +49 -0
- package/lib/visualizer/viewer-shortcuts.d.ts +71 -0
- package/lib/visualizer/visualizer-context-menu.d.ts +55 -0
- package/lib/visualizer.component.d.ts +201 -447
- package/lib/workers/spatial-math-ops.d.ts +65 -0
- package/lib/workers/spatial-math-worker.d.ts +7 -0
- package/lib/workers/spatial-math.d.ts +74 -0
- package/package.json +12 -3
- package/src/lib/styles/_viz-icons-rules.scss +73 -0
- package/src/lib/styles/viz-icons.scss +14 -0
- package/esm2022/lib/implementations/napari-js/napari-axes-labels.mjs +0 -97
- package/esm2022/lib/implementations/napari-js/napari-navigator.mjs +0 -195
- package/esm2022/lib/implementations/napari-js/napari-scale-bar.mjs +0 -92
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-BwP-A11m.mjs +0 -329
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-BwP-A11m.mjs.map +0 -1
- package/lib/implementations/napari-js/napari-axes-labels.d.ts +0 -49
- package/lib/implementations/napari-js/napari-navigator.d.ts +0 -72
- package/lib/implementations/napari-js/napari-scale-bar.d.ts +0 -35
- package/src/lib/assets/cell-detection.svg +0 -37
- package/src/lib/assets/click.svg +0 -1
- package/src/lib/assets/colormap-luts.json +0 -1
- package/src/lib/assets/edit-selection-white.svg +0 -47
- package/src/lib/assets/icons/colormap-earth.png +0 -0
- package/src/lib/assets/icons/colormap-placeholder.png +0 -0
- package/src/lib/assets/icons/colormap-pubu.png +0 -0
- package/src/lib/assets/interactive-segmentation-cursor.svg +0 -1
- package/src/lib/assets/picture-segmentation.svg +0 -43
- package/src/lib/assets/test/download-379.svg +0 -1
- package/src/lib/assets/test/download-98.svg +0 -1
- package/src/lib/assets/test/json-1.svg +0 -1
- package/src/lib/assets/test/load-53.svg +0 -1
- package/src/lib/assets/test/mask-44.svg +0 -1
- package/src/lib/assets/test/mask-download-44.svg +0 -15
- package/src/lib/assets/test/mask-save-44.svg +0 -11
- package/src/lib/assets/test/overlay-1.svg +0 -1
- package/src/lib/assets/test/overlay-4.svg +0 -1
- package/src/lib/assets/test/region-26.svg +0 -1
- package/src/lib/assets/test/save-56.svg +0 -1
- package/src/lib/assets/test/upload-43.svg +0 -1
|
@@ -1,124 +1,90 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { Region
|
|
5
|
-
import * as i0 from "@angular/core";
|
|
6
|
-
import * as i1 from "./wand.service";
|
|
1
|
+
import { MaskStrokeEditor } from '../tool-kit/mask-stroke-editor';
|
|
2
|
+
import { UndoGesture } from '../tool-kit/undo-gesture';
|
|
3
|
+
import { ToolOverlayCanvas } from '../tool-kit/tool-overlay';
|
|
4
|
+
import { Region } from '../../models/region';
|
|
7
5
|
/**
|
|
8
|
-
* The wand drawing tool. Owns its
|
|
9
|
-
*
|
|
10
|
-
*
|
|
6
|
+
* The wand drawing tool. Owns its pointer overlay and stroke accumulator
|
|
7
|
+
* (shared with the brush, see {@link MaskStrokeEditor}). Reads/writes regions
|
|
8
|
+
* via its {@link CanvasToolHost} so it stays decoupled from the backends.
|
|
11
9
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* activate/deactivate the tool.
|
|
10
|
+
* A plain class: each backend's `CanvasToolManager` owns one instance and arms
|
|
11
|
+
* it with `activate(host, options)` / `deactivate()`.
|
|
15
12
|
*/
|
|
16
|
-
export class
|
|
17
|
-
|
|
13
|
+
export class WandTool {
|
|
14
|
+
/** @param gestureTarget the region store, so each drag is one undo step. */
|
|
15
|
+
constructor(wandService, gestureTarget) {
|
|
18
16
|
this.wandService = wandService;
|
|
19
|
-
this.
|
|
20
|
-
this.
|
|
17
|
+
this.id = 'wand';
|
|
18
|
+
this.overlay = new ToolOverlayCanvas();
|
|
21
19
|
/**
|
|
22
|
-
* Accumulated wand region. Every per-tick patch mask is OR'd into
|
|
23
|
-
* over a bbox that grows with the stroke, so the region keeps expanding
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
20
|
+
* Accumulated wand region. Every per-tick patch mask is OR'd into the stroke
|
|
21
|
+
* over a bbox that grows with the stroke, so the region keeps expanding as
|
|
22
|
+
* the user drags. The accumulator persists across mouseup/mousedown so that
|
|
23
|
+
* subsequent strokes extend the *same* region — matching QuPath's brush
|
|
24
|
+
* behaviour where the active annotation stays editable until the user
|
|
25
|
+
* switches tool.
|
|
28
26
|
*/
|
|
29
|
-
this.
|
|
30
|
-
/** Id of the region this wand stroke is editing (null = a fresh region). */
|
|
31
|
-
this.strokeRegionId = null;
|
|
32
|
-
/** Readback ratio/origin signature the active stroke's matrix coords are tied to; a change
|
|
33
|
-
* (zoom/pan) invalidates the stroke so it isn't re-committed at a different scale (jit-ui#102). */
|
|
34
|
-
this.strokeRatioSig = null;
|
|
27
|
+
this.editor = new MaskStrokeEditor();
|
|
35
28
|
this.dragging = false;
|
|
36
29
|
this.options = {};
|
|
37
|
-
this.
|
|
38
|
-
this.boundMouseMove = (e) => this.onMouseMove(e);
|
|
39
|
-
this.boundMouseUp = (e) => this.onMouseUp(e);
|
|
30
|
+
this.gesture = new UndoGesture(gestureTarget);
|
|
40
31
|
}
|
|
41
|
-
|
|
42
|
-
|
|
32
|
+
// ── ICanvasTool ─────────────────────────────────────────────────────
|
|
33
|
+
/** Arm the wand on `host` with `options` (replacing the previous options). */
|
|
34
|
+
activate(host, options = {}) {
|
|
43
35
|
this.host = host;
|
|
44
|
-
}
|
|
45
|
-
// ── Public API ──────────────────────────────────────────────────────
|
|
46
|
-
/** Toggle the wand on/off. */
|
|
47
|
-
setMode(active, options = {}) {
|
|
48
|
-
this.active = active;
|
|
49
36
|
this.options = options;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
37
|
+
this.createOverlay();
|
|
38
|
+
}
|
|
39
|
+
/** Disarm: remove the overlay and drop the active region. */
|
|
40
|
+
deactivate() {
|
|
41
|
+
this.overlay.detach();
|
|
42
|
+
this.resetStroke();
|
|
56
43
|
}
|
|
57
44
|
/** Merge new options (e.g. live sensitivity slider updates). */
|
|
58
45
|
setOptions(options) {
|
|
59
46
|
this.options = { ...this.options, ...options };
|
|
60
47
|
}
|
|
61
48
|
/** Drop the active wand region so the next click starts a new one. */
|
|
62
|
-
|
|
49
|
+
reset() {
|
|
63
50
|
this.resetStroke();
|
|
64
51
|
}
|
|
65
52
|
// ── Overlay lifecycle ───────────────────────────────────────────────
|
|
66
53
|
createOverlay() {
|
|
67
|
-
const
|
|
68
|
-
if (!
|
|
54
|
+
const container = this.host.getOverlayContainer();
|
|
55
|
+
if (!container)
|
|
69
56
|
return;
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
canvas.style.height = '100%';
|
|
76
|
-
canvas.style.cursor = 'crosshair';
|
|
77
|
-
canvas.style.zIndex = '100';
|
|
78
|
-
canvas.width = plotEl.offsetWidth;
|
|
79
|
-
canvas.height = plotEl.offsetHeight;
|
|
80
|
-
plotEl.appendChild(canvas);
|
|
81
|
-
this.overlay = canvas;
|
|
82
|
-
canvas.addEventListener('mousedown', this.boundMouseDown);
|
|
83
|
-
canvas.addEventListener('mousemove', this.boundMouseMove);
|
|
84
|
-
canvas.addEventListener('mouseup', this.boundMouseUp);
|
|
85
|
-
canvas.addEventListener('mouseleave', this.boundMouseUp);
|
|
57
|
+
this.overlay.attach(container, {
|
|
58
|
+
down: (e) => this.onPointerDown(e),
|
|
59
|
+
move: (e) => this.onPointerMove(e),
|
|
60
|
+
up: () => this.onPointerUp(),
|
|
61
|
+
});
|
|
86
62
|
}
|
|
87
|
-
|
|
88
|
-
if (!this.overlay)
|
|
89
|
-
return;
|
|
90
|
-
this.overlay.removeEventListener('mousedown', this.boundMouseDown);
|
|
91
|
-
this.overlay.removeEventListener('mousemove', this.boundMouseMove);
|
|
92
|
-
this.overlay.removeEventListener('mouseup', this.boundMouseUp);
|
|
93
|
-
this.overlay.removeEventListener('mouseleave', this.boundMouseUp);
|
|
94
|
-
this.overlay.remove();
|
|
95
|
-
this.overlay = null;
|
|
96
|
-
this.resetStroke();
|
|
97
|
-
}
|
|
98
|
-
onMouseDown(e) {
|
|
99
|
-
if (e.button !== 0)
|
|
100
|
-
return;
|
|
63
|
+
onPointerDown(e) {
|
|
101
64
|
this.dragging = true;
|
|
65
|
+
this.gesture.begin();
|
|
102
66
|
this.applyAtClient(e, true);
|
|
103
67
|
}
|
|
104
|
-
|
|
68
|
+
onPointerMove(e) {
|
|
105
69
|
if (!this.dragging)
|
|
106
70
|
return;
|
|
107
71
|
if ((e.buttons & 1) === 0) {
|
|
108
72
|
this.dragging = false;
|
|
73
|
+
this.gesture.end();
|
|
109
74
|
return;
|
|
110
75
|
}
|
|
111
76
|
this.applyAtClient(e, false);
|
|
112
77
|
}
|
|
113
|
-
|
|
78
|
+
onPointerUp() {
|
|
114
79
|
// Stop accumulating from this drag, but keep the region alive so the
|
|
115
80
|
// next mousedown extends it instead of starting fresh.
|
|
116
81
|
this.dragging = false;
|
|
82
|
+
this.gesture.end();
|
|
117
83
|
}
|
|
118
84
|
resetStroke() {
|
|
119
|
-
this.
|
|
120
|
-
this.strokeRegionId = null;
|
|
85
|
+
this.editor.reset();
|
|
121
86
|
this.dragging = false;
|
|
87
|
+
this.gesture.end();
|
|
122
88
|
}
|
|
123
89
|
// ── Per-tick stroke logic ───────────────────────────────────────────
|
|
124
90
|
/**
|
|
@@ -129,53 +95,15 @@ export class WandToolService {
|
|
|
129
95
|
* exact-match flood fill.
|
|
130
96
|
*/
|
|
131
97
|
applyAtClient(e, isStart = false) {
|
|
132
|
-
if (!this.overlay)
|
|
133
|
-
return;
|
|
134
|
-
const cached = this.host.getCachedImageData();
|
|
135
|
-
if (!cached || cached.frames.length === 0)
|
|
98
|
+
if (!this.overlay.attached)
|
|
136
99
|
return;
|
|
137
|
-
// The current regions (neutral model)
|
|
100
|
+
// The current regions (neutral model) are mutated locally across this tick and
|
|
138
101
|
// committed once via host.setRegions().
|
|
139
|
-
const
|
|
140
|
-
const
|
|
141
|
-
if (!
|
|
102
|
+
const editor = this.editor;
|
|
103
|
+
const tick = editor.beginTick(this.host, e);
|
|
104
|
+
if (!tick)
|
|
142
105
|
return;
|
|
143
|
-
const {
|
|
144
|
-
if (!Number.isFinite(dataX) || !Number.isFinite(dataY))
|
|
145
|
-
return;
|
|
146
|
-
// ratios = [xRatio, yRatio] from both backends. Use the X ratio for the
|
|
147
|
-
// column and the Y ratio for the row: they differ when the pixel aspect
|
|
148
|
-
// isn't 1:1 (e.g. a non-square OSD viewport), and reusing ratios[0] for
|
|
149
|
-
// both would distort the sampled region vertically. Fall back to the X
|
|
150
|
-
// ratio if only one was supplied.
|
|
151
|
-
const rx = cached.ratios[0] || 1;
|
|
152
|
-
const ry = cached.ratios[1] || cached.ratios[0] || 1;
|
|
153
|
-
const ox = cached.originX ?? 0;
|
|
154
|
-
const oy = cached.originY ?? 0;
|
|
155
|
-
// The stroke accumulator is in matrix (viewport-pixel) coordinates tied to the readback's
|
|
156
|
-
// ratio/origin. If the view changed (zoom/pan) since the stroke was built, those coords no
|
|
157
|
-
// longer mean the same thing — re-committing would rescale the region by the zoom factor
|
|
158
|
-
// (jit-ui#102). Drop the stale stroke so a fresh one is built at the current view.
|
|
159
|
-
const sig = `${rx},${ry},${ox},${oy}`;
|
|
160
|
-
if (this.stroke && this.strokeRatioSig !== sig) {
|
|
161
|
-
this.stroke = null;
|
|
162
|
-
this.strokeRegionId = null;
|
|
163
|
-
}
|
|
164
|
-
this.strokeRatioSig = sig;
|
|
165
|
-
const matrixX = (dataX - ox) / rx;
|
|
166
|
-
const matrixY = (dataY - oy) / ry;
|
|
167
|
-
if (matrixX < 0 || matrixX >= cached.width)
|
|
168
|
-
return;
|
|
169
|
-
if (matrixY < 0 || matrixY >= cached.height)
|
|
170
|
-
return;
|
|
171
|
-
const frameIdx = this.host.getActiveFrameIndex();
|
|
172
|
-
const frame = cached.frames[frameIdx] ?? cached.frames[0];
|
|
173
|
-
const wandImage = {
|
|
174
|
-
data: frame,
|
|
175
|
-
width: cached.width,
|
|
176
|
-
height: cached.height,
|
|
177
|
-
isGrayscale: cached.isGrayscale,
|
|
178
|
-
};
|
|
106
|
+
const { cached, regions, frame, mx: matrixX, my: matrixY } = tick;
|
|
179
107
|
// Shift = erase (subtract pixels from an existing region).
|
|
180
108
|
// Cmd/Ctrl alone = simple flood fill (no smoothing/threshold).
|
|
181
109
|
const erase = e.shiftKey;
|
|
@@ -183,76 +111,80 @@ export class WandToolService {
|
|
|
183
111
|
...this.options,
|
|
184
112
|
simpleMode: this.options.simpleMode || ((e.metaKey || e.ctrlKey) && !erase),
|
|
185
113
|
};
|
|
186
|
-
//
|
|
187
|
-
//
|
|
188
|
-
//
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
if (isStart && !erase && this.stroke && !this.pointInStroke(matrixX, matrixY)) {
|
|
192
|
-
// Will fall through to tryAdoptShapeAt below; if that also misses, a
|
|
193
|
-
// fresh stroke is created from the patch.
|
|
194
|
-
this.stroke = null;
|
|
195
|
-
this.strokeRegionId = null;
|
|
114
|
+
// A new drag that starts outside the current accumulator starts a new region
|
|
115
|
+
// (or adopts the one under the cursor) instead of growing the old stroke's
|
|
116
|
+
// bbox to span both areas.
|
|
117
|
+
if (isStart && !erase && editor.stroke && !editor.contains(matrixX, matrixY)) {
|
|
118
|
+
editor.reset();
|
|
196
119
|
}
|
|
197
|
-
const patch = this.wandService.computePatchMask(wandImage, matrixX, matrixY, opts);
|
|
120
|
+
const patch = this.wandService.computePatchMask(this.wandImage(cached), matrixX, matrixY, opts);
|
|
198
121
|
if (!patch)
|
|
199
122
|
return;
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
const px1 = px0 + W;
|
|
205
|
-
const py1 = py0 + W;
|
|
206
|
-
// If there's no active wand region, see if the click landed on an
|
|
207
|
-
// existing path-shape — adopt it so this stroke extends (or erases
|
|
208
|
-
// from) it instead of creating a new region.
|
|
209
|
-
if (!this.stroke) {
|
|
210
|
-
this.tryAdoptShapeAt(regions, matrixX, matrixY, rx, ry, cached);
|
|
211
|
-
}
|
|
123
|
+
// With no active region, a click on an existing region adopts it so this
|
|
124
|
+
// stroke extends (or erases from) it.
|
|
125
|
+
if (!editor.stroke)
|
|
126
|
+
editor.adoptAt(regions, matrixX, matrixY, frame, cached);
|
|
212
127
|
// Erasing requires an existing region. Shift-clicking empty space is a
|
|
213
128
|
// no-op — we don't create a region only to immediately delete from it.
|
|
214
|
-
if (erase && !
|
|
215
|
-
return;
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
129
|
+
if (erase && !editor.stroke)
|
|
130
|
+
return;
|
|
131
|
+
if (!this.stampPatch(patch, matrixX, matrixY, erase, cached))
|
|
132
|
+
return;
|
|
133
|
+
// Growing into other regions folds them in (QuPath's merge-on-touch).
|
|
134
|
+
if (!erase)
|
|
135
|
+
editor.mergeTouching(regions, frame, cached);
|
|
136
|
+
editor.commit(regions, frame, this.host, {
|
|
137
|
+
erase,
|
|
138
|
+
defaultLabel: 'Region',
|
|
139
|
+
newRegion: (bounds) => {
|
|
140
|
+
const region = new Region();
|
|
141
|
+
region.bounds = bounds;
|
|
142
|
+
region.color = this.host.getShapeColor();
|
|
143
|
+
// Default class/annotation name, matching the overlay-drawn regions and the
|
|
144
|
+
// Region Editor's "Add" actions so a wand region isn't left unlabeled.
|
|
145
|
+
region.label = 'Region';
|
|
146
|
+
return region;
|
|
147
|
+
},
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
/** The visible frame of the readback, as the region grow reads it. */
|
|
151
|
+
wandImage(cached) {
|
|
152
|
+
const frameIdx = this.host.getActiveFrameIndex();
|
|
153
|
+
return {
|
|
154
|
+
data: cached.frames[frameIdx] ?? cached.frames[0],
|
|
155
|
+
width: cached.width,
|
|
156
|
+
height: cached.height,
|
|
157
|
+
isGrayscale: cached.isGrayscale,
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* OR (add) or AND-NOT (erase) the patch mask, centred on matrix point
|
|
162
|
+
* (cx, cy), into the stroke, growing the stroke to cover it first when
|
|
163
|
+
* adding. False when a fresh stroke has nothing inside the readback.
|
|
164
|
+
*/
|
|
165
|
+
stampPatch(patch, cx, cy, erase, cached) {
|
|
166
|
+
const editor = this.editor;
|
|
167
|
+
const W = patch.size;
|
|
168
|
+
const half = (W - 1) / 2;
|
|
169
|
+
// The patch is centred on the clicked pixel (`computePatchMask` floors the same way).
|
|
170
|
+
const px0 = Math.floor(cx) - half;
|
|
171
|
+
const py0 = Math.floor(cy) - half;
|
|
172
|
+
if (!editor.stroke) {
|
|
173
|
+
// A fresh stroke starts at the patch, clipped to the readback.
|
|
174
|
+
const ok = editor.ensureCovers(Math.max(0, px0), Math.max(0, py0), Math.min(cached.width, px0 + W), Math.min(cached.height, py0 + W));
|
|
175
|
+
if (!ok)
|
|
176
|
+
return false;
|
|
228
177
|
}
|
|
229
178
|
else if (!erase) {
|
|
230
|
-
// Don't clamp
|
|
231
|
-
// clamping
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
const bx1 = Math.max(this.stroke.bx + this.stroke.bw, px1);
|
|
235
|
-
const by1 = Math.max(this.stroke.by + this.stroke.bh, py1);
|
|
236
|
-
const bw = bx1 - bx;
|
|
237
|
-
const bh = by1 - by;
|
|
238
|
-
if (bw !== this.stroke.bw || bh !== this.stroke.bh || bx !== this.stroke.bx || by !== this.stroke.by) {
|
|
239
|
-
// Reallocate the larger mask and copy the previous mask into it.
|
|
240
|
-
const next = new Uint8Array(bw * bh);
|
|
241
|
-
const dx = this.stroke.bx - bx;
|
|
242
|
-
const dy = this.stroke.by - by;
|
|
243
|
-
for (let row = 0; row < this.stroke.bh; row++) {
|
|
244
|
-
const srcOff = row * this.stroke.bw;
|
|
245
|
-
const dstOff = (row + dy) * bw + dx;
|
|
246
|
-
next.set(this.stroke.mask.subarray(srcOff, srcOff + this.stroke.bw), dstOff);
|
|
247
|
-
}
|
|
248
|
-
this.stroke = { bx, by, bw, bh, mask: next };
|
|
249
|
-
}
|
|
179
|
+
// Don't clamp a growing stroke to the viewport: an adopted region may extend
|
|
180
|
+
// off-screen, and clamping would discard that part (jit-ui#102). Erasing never
|
|
181
|
+
// grows the stroke.
|
|
182
|
+
editor.ensureCovers(px0, py0, px0 + W, py0 + W);
|
|
250
183
|
}
|
|
251
184
|
// Apply the patch: OR (add) or AND-NOT (erase).
|
|
252
|
-
const stroke =
|
|
185
|
+
const stroke = editor.stroke;
|
|
253
186
|
for (let py = 0; py < W; py++) {
|
|
254
|
-
const
|
|
255
|
-
const my = iy - stroke.by;
|
|
187
|
+
const my = py0 + py - stroke.by;
|
|
256
188
|
if (my < 0 || my >= stroke.bh)
|
|
257
189
|
continue;
|
|
258
190
|
const srcRow = py * W;
|
|
@@ -260,240 +192,13 @@ export class WandToolService {
|
|
|
260
192
|
for (let px = 0; px < W; px++) {
|
|
261
193
|
if (!patch.mask[srcRow + px])
|
|
262
194
|
continue;
|
|
263
|
-
const
|
|
264
|
-
const mx = ix - stroke.bx;
|
|
195
|
+
const mx = px0 + px - stroke.bx;
|
|
265
196
|
if (mx < 0 || mx >= stroke.bw)
|
|
266
197
|
continue;
|
|
267
|
-
|
|
268
|
-
stroke.mask[dstRow + mx] = 0;
|
|
269
|
-
else
|
|
270
|
-
stroke.mask[dstRow + mx] = 1;
|
|
198
|
+
stroke.mask[dstRow + mx] = erase ? 0 : 1;
|
|
271
199
|
}
|
|
272
200
|
}
|
|
273
|
-
|
|
274
|
-
// If the grown stroke now overlaps another path-shape, fold those
|
|
275
|
-
// shapes into this one and drop them — matching QuPath's
|
|
276
|
-
// merge-on-touch behaviour.
|
|
277
|
-
this.mergeOverlappingShapes(regions, rx, ry, cached);
|
|
278
|
-
}
|
|
279
|
-
// Trace the union boundary in image-pixel coords.
|
|
280
|
-
const stroke2 = this.stroke;
|
|
281
|
-
const poly = this.wandService.maskToPolygon(stroke2.mask, stroke2.bw, stroke2.bh, cached.width, cached.height, stroke2.bx, stroke2.by);
|
|
282
|
-
if (!poly) {
|
|
283
|
-
// Erased to nothing — remove the shape entirely.
|
|
284
|
-
if (erase)
|
|
285
|
-
this.dropActiveShape(regions);
|
|
286
|
-
return;
|
|
287
|
-
}
|
|
288
|
-
// Convert from matrix coords back to plot data coords.
|
|
289
|
-
const xPlot = poly.xpoints.map((x) => ox + x * rx);
|
|
290
|
-
const yPlot = poly.ypoints.map((y) => oy + y * ry);
|
|
291
|
-
this.commitStroke(regions, xPlot, yPlot);
|
|
292
|
-
}
|
|
293
|
-
/** True if (matrixX, matrixY) lies inside the current stroke accumulator. */
|
|
294
|
-
pointInStroke(matrixX, matrixY) {
|
|
295
|
-
const s = this.stroke;
|
|
296
|
-
if (!s)
|
|
297
|
-
return false;
|
|
298
|
-
const mx = Math.floor(matrixX) - s.bx;
|
|
299
|
-
const my = Math.floor(matrixY) - s.by;
|
|
300
|
-
if (mx < 0 || my < 0 || mx >= s.bw || my >= s.bh)
|
|
301
|
-
return false;
|
|
302
|
-
return s.mask[my * s.bw + mx] === 1;
|
|
303
|
-
}
|
|
304
|
-
/**
|
|
305
|
-
* Remove the region referenced by `strokeRegionId` from the region list and
|
|
306
|
-
* reset the active stroke — used when an erase stroke deletes every pixel.
|
|
307
|
-
*/
|
|
308
|
-
dropActiveShape(regions) {
|
|
309
|
-
if (this.strokeRegionId != null) {
|
|
310
|
-
const idx = regions.findIndex((r) => r.id === this.strokeRegionId);
|
|
311
|
-
if (idx >= 0) {
|
|
312
|
-
regions.splice(idx, 1);
|
|
313
|
-
this.host.setRegions(regions);
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
this.stroke = null;
|
|
317
|
-
this.strokeRegionId = null;
|
|
318
|
-
}
|
|
319
|
-
/**
|
|
320
|
-
* Whether a region can be faithfully rasterized into the wand stroke at the current view
|
|
321
|
-
* resolution (rx/ry = data units per matrix pixel). Editing rasterizes the region to the
|
|
322
|
-
* viewport grid and re-traces it, so a region whose matrix-space bbox exceeds the rasterizer's
|
|
323
|
-
* cap would be clipped/down-quantized and come back rescaled/corrupted (jit-ui#102) — e.g. a
|
|
324
|
-
* whole-slide annotation while zoomed out. Skip adopt/merge for those: leave them untouched and
|
|
325
|
-
* only edit them near native zoom.
|
|
326
|
-
*/
|
|
327
|
-
fitsForEdit(verts, rx, ry) {
|
|
328
|
-
const xs = verts.xpoints;
|
|
329
|
-
const ys = verts.ypoints;
|
|
330
|
-
let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
|
|
331
|
-
for (let i = 0; i < xs.length; i++) {
|
|
332
|
-
if (xs[i] < minX)
|
|
333
|
-
minX = xs[i];
|
|
334
|
-
if (xs[i] > maxX)
|
|
335
|
-
maxX = xs[i];
|
|
336
|
-
if (ys[i] < minY)
|
|
337
|
-
minY = ys[i];
|
|
338
|
-
if (ys[i] > maxY)
|
|
339
|
-
maxY = ys[i];
|
|
340
|
-
}
|
|
341
|
-
const w = (maxX - minX) / (rx || 1);
|
|
342
|
-
const h = (maxY - minY) / (ry || 1);
|
|
343
|
-
return w > 0 && h > 0 && w * h <= 4096 * 4096;
|
|
344
|
-
}
|
|
345
|
-
/** A region's closed-polygon vertices (image/data coords), or null when it
|
|
346
|
-
* isn't a fillable closed polygon (rectangles, open polylines). */
|
|
347
|
-
regionVerts(region) {
|
|
348
|
-
const b = region?.bounds;
|
|
349
|
-
if (b instanceof Polygon && b.closed !== false && b.xpoints.length >= 3) {
|
|
350
|
-
return { xpoints: b.xpoints, ypoints: b.ypoints, holes: b.holes };
|
|
351
|
-
}
|
|
352
|
-
return null;
|
|
353
|
-
}
|
|
354
|
-
/** Convert a region's hole rings from image/data coords into matrix coords so
|
|
355
|
-
* they line up with the stroke accumulator (jit-ui#85). */
|
|
356
|
-
holesToMatrix(holes, ox, oy, rx, ry) {
|
|
357
|
-
return holes?.map((ring) => ring.map(([x, y]) => [(x - ox) / rx, (y - oy) / ry]));
|
|
358
|
-
}
|
|
359
|
-
/**
|
|
360
|
-
* If (matrixX, matrixY) falls inside an existing region, rasterize it into
|
|
361
|
-
* the wand stroke accumulator so subsequent wand input extends it rather than
|
|
362
|
-
* starting a new region.
|
|
363
|
-
*/
|
|
364
|
-
tryAdoptShapeAt(regions, matrixX, matrixY, rx, ry, cached) {
|
|
365
|
-
if (!regions || regions.length === 0)
|
|
366
|
-
return false;
|
|
367
|
-
// Most-recently-added regions are on top — check them first.
|
|
368
|
-
for (let i = regions.length - 1; i >= 0; i--) {
|
|
369
|
-
const verts = this.regionVerts(regions[i]);
|
|
370
|
-
if (!verts)
|
|
371
|
-
continue;
|
|
372
|
-
// Too large to rasterize at this zoom → don't adopt it (editing would rescale/corrupt it).
|
|
373
|
-
if (!this.fitsForEdit(verts, rx, ry))
|
|
374
|
-
continue;
|
|
375
|
-
const ox = cached.originX ?? 0;
|
|
376
|
-
const oy = cached.originY ?? 0;
|
|
377
|
-
const xs = verts.xpoints.map((x) => (x - ox) / rx);
|
|
378
|
-
const ys = verts.ypoints.map((y) => (y - oy) / ry);
|
|
379
|
-
const holes = this.holesToMatrix(verts.holes, ox, oy, rx, ry);
|
|
380
|
-
// Clicking inside a hole must NOT adopt the donut (it's empty there).
|
|
381
|
-
if (!this.wandService.pointInPolygonWithHoles(matrixX, matrixY, xs, ys, holes))
|
|
382
|
-
continue;
|
|
383
|
-
const raster = this.wandService.rasterizePolygon(xs, ys, cached.width, cached.height, holes);
|
|
384
|
-
if (!raster)
|
|
385
|
-
continue;
|
|
386
|
-
this.stroke = raster;
|
|
387
|
-
this.strokeRegionId = regions[i].id ?? null;
|
|
388
|
-
return true;
|
|
389
|
-
}
|
|
390
|
-
return false;
|
|
391
|
-
}
|
|
392
|
-
/**
|
|
393
|
-
* Iterate every region; if its rasterized mask overlaps the wand stroke mask
|
|
394
|
-
* by at least one pixel, OR it into the stroke and remove it from the list.
|
|
395
|
-
* Called every tick so chained merges resolve. If the wand has no region id
|
|
396
|
-
* yet, the merged region's id is adopted so the merged region replaces it.
|
|
397
|
-
*/
|
|
398
|
-
mergeOverlappingShapes(regions, rx, ry, cached) {
|
|
399
|
-
if (!this.stroke)
|
|
400
|
-
return;
|
|
401
|
-
let didMerge = true;
|
|
402
|
-
while (didMerge) {
|
|
403
|
-
didMerge = false;
|
|
404
|
-
for (let i = regions.length - 1; i >= 0; i--) {
|
|
405
|
-
const region = regions[i];
|
|
406
|
-
if (region.id != null && region.id === this.strokeRegionId)
|
|
407
|
-
continue;
|
|
408
|
-
const verts = this.regionVerts(region);
|
|
409
|
-
if (!verts)
|
|
410
|
-
continue;
|
|
411
|
-
// Too large to rasterize at this zoom → don't merge it (would rescale/corrupt it).
|
|
412
|
-
if (!this.fitsForEdit(verts, rx, ry))
|
|
413
|
-
continue;
|
|
414
|
-
const ox = cached.originX ?? 0;
|
|
415
|
-
const oy = cached.originY ?? 0;
|
|
416
|
-
const xs = verts.xpoints.map((x) => (x - ox) / rx);
|
|
417
|
-
const ys = verts.ypoints.map((y) => (y - oy) / ry);
|
|
418
|
-
// Quick bbox reject before rasterizing.
|
|
419
|
-
let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
|
|
420
|
-
for (let k = 0; k < xs.length; k++) {
|
|
421
|
-
if (xs[k] < minX)
|
|
422
|
-
minX = xs[k];
|
|
423
|
-
if (xs[k] > maxX)
|
|
424
|
-
maxX = xs[k];
|
|
425
|
-
if (ys[k] < minY)
|
|
426
|
-
minY = ys[k];
|
|
427
|
-
if (ys[k] > maxY)
|
|
428
|
-
maxY = ys[k];
|
|
429
|
-
}
|
|
430
|
-
const wx0 = this.stroke.bx, wy0 = this.stroke.by;
|
|
431
|
-
const wx1 = wx0 + this.stroke.bw, wy1 = wy0 + this.stroke.bh;
|
|
432
|
-
if (maxX < wx0 || minX > wx1 || maxY < wy0 || minY > wy1)
|
|
433
|
-
continue;
|
|
434
|
-
const holes = this.holesToMatrix(verts.holes, ox, oy, rx, ry);
|
|
435
|
-
const raster = this.wandService.rasterizePolygon(xs, ys, cached.width, cached.height, holes);
|
|
436
|
-
if (!raster)
|
|
437
|
-
continue;
|
|
438
|
-
if (!masksOverlap(this.stroke, raster))
|
|
439
|
-
continue;
|
|
440
|
-
this.stroke = unionMasks(this.stroke, raster);
|
|
441
|
-
if (this.strokeRegionId == null) {
|
|
442
|
-
this.strokeRegionId = region.id ?? null;
|
|
443
|
-
}
|
|
444
|
-
regions.splice(i, 1);
|
|
445
|
-
didMerge = true;
|
|
446
|
-
break;
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
/**
|
|
451
|
-
* Commit the in-progress polygon as a region — a new region on the first tick
|
|
452
|
-
* of a stroke, or an in-place replacement of the active region on later ticks
|
|
453
|
-
* — then ask the host to render. The store mints an id on the first commit,
|
|
454
|
-
* which we adopt so subsequent ticks replace the same region.
|
|
455
|
-
*/
|
|
456
|
-
commitStroke(regions, xPlot, yPlot) {
|
|
457
|
-
if (xPlot.length < 3)
|
|
458
|
-
return;
|
|
459
|
-
const existing = this.strokeRegionId != null
|
|
460
|
-
? regions.find((r) => r.id === this.strokeRegionId) : null;
|
|
461
|
-
const poly = new Polygon();
|
|
462
|
-
poly.npoints = xPlot.length;
|
|
463
|
-
poly.xpoints = xPlot;
|
|
464
|
-
poly.ypoints = yPlot;
|
|
465
|
-
poly.coordinates = xPlot.map((x, i) => [x, yPlot[i]]);
|
|
466
|
-
poly.closed = true;
|
|
467
|
-
const region = new Region();
|
|
468
|
-
region.bounds = poly;
|
|
469
|
-
region.color = this.host.getShapeColor();
|
|
470
|
-
if (existing) {
|
|
471
|
-
// Preserve identity + class label across the stroke's drag ticks.
|
|
472
|
-
region.id = existing.id;
|
|
473
|
-
region.name = existing.name;
|
|
474
|
-
}
|
|
475
|
-
// Default class/annotation name, matching the overlay-drawn regions and the
|
|
476
|
-
// Region Editor's "Add" actions so a wand region isn't left unlabeled.
|
|
477
|
-
region.label = existing?.label ?? 'Region';
|
|
478
|
-
if (this.strokeRegionId == null) {
|
|
479
|
-
regions.push(region);
|
|
480
|
-
}
|
|
481
|
-
else {
|
|
482
|
-
const idx = regions.findIndex((r) => r.id === this.strokeRegionId);
|
|
483
|
-
if (idx >= 0)
|
|
484
|
-
regions[idx] = region;
|
|
485
|
-
else
|
|
486
|
-
regions.push(region);
|
|
487
|
-
}
|
|
488
|
-
this.host.setRegions(regions);
|
|
489
|
-
// The store assigns an id on the first commit — adopt it.
|
|
490
|
-
this.strokeRegionId = region.id ?? this.strokeRegionId;
|
|
201
|
+
return true;
|
|
491
202
|
}
|
|
492
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: WandToolService, deps: [{ token: i1.WandService }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
493
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: WandToolService, providedIn: 'root' }); }
|
|
494
203
|
}
|
|
495
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: WandToolService, decorators: [{
|
|
496
|
-
type: Injectable,
|
|
497
|
-
args: [{ providedIn: 'root' }]
|
|
498
|
-
}], ctorParameters: () => [{ type: i1.WandService }] });
|
|
499
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FuZC10b29sLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL3Rvb2xiYXIvd2FuZC93YW5kLXRvb2wuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBRTNDLE9BQU8sRUFBMEIsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDckUsT0FBTyxFQUFZLFlBQVksRUFBRSxVQUFVLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUUzRSxPQUFPLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxNQUFNLHFCQUFxQixDQUFDOzs7QUFrRHREOzs7Ozs7OztHQVFHO0FBRUgsTUFBTSxPQUFPLGVBQWU7SUEyQjFCLFlBQW9CLFdBQXdCO1FBQXhCLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBdkJwQyxZQUFPLEdBQTZCLElBQUksQ0FBQztRQUN6QyxXQUFNLEdBQUcsS0FBSyxDQUFDO1FBQ3ZCOzs7Ozs7O1dBT0c7UUFDSyxXQUFNLEdBQW9CLElBQUksQ0FBQztRQUN2Qyw0RUFBNEU7UUFDcEUsbUJBQWMsR0FBa0IsSUFBSSxDQUFDO1FBQzdDOzRHQUNvRztRQUM1RixtQkFBYyxHQUFrQixJQUFJLENBQUM7UUFDckMsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUNqQixZQUFPLEdBQWdCLEVBQUUsQ0FBQztRQU9oQyxJQUFJLENBQUMsY0FBYyxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2pELElBQUksQ0FBQyxjQUFjLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDakQsSUFBSSxDQUFDLFlBQVksR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLFNBQVMs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QUM5QiwwREFBMEQ7UUFDMUQsSUFBSSxDQUFDLGNBQWMsR0FBRyxNQUFNLENBQUMsRUFBRSxJQUFJLElBQUksQ0FBQyxjQUFjLENBQUM7SUFDekQsQ0FBQzs4R0FyZ0JVLGVBQWU7a0hBQWYsZUFBZSxjQURGLE1BQU07OzJGQUNuQixlQUFlO2tCQUQzQixVQUFVO21CQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgV2FuZEltYWdlLCBXYW5kT3B0aW9ucywgV2FuZFNlcnZpY2UgfSBmcm9tICcuL3dhbmQuc2VydmljZSc7XG5pbXBvcnQgeyBCQm94TWFzaywgbWFza3NPdmVybGFwLCB1bmlvbk1hc2tzIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2dlb21ldHJ5JztcbmltcG9ydCB7IElWaWV3cG9ydEhvc3QsIElSZWdpb25EYXRhSG9zdCB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cy9jb29yZGluYXRlLXRyYW5zZm9ybS5jb250cmFjdCc7XG5pbXBvcnQgeyBSZWdpb24sIFBvbHlnb24gfSBmcm9tICcuLi8uLi9tb2RlbHMvcmVnaW9uJztcblxuLyoqXG4gKiBUaGUgcGl4ZWwgZGF0YSBhbmQgZnJhbWUgc3RhdGUgUGxvdGx5U2VydmljZSBjYWNoZXMgZm9yIHNhbXBsaW5nLiBSZXR1cm5lZFxuICogYnkgYFdhbmRUb29sSG9zdC5nZXRDYWNoZWRJbWFnZURhdGEoKWAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ2FjaGVkSW1hZ2VEYXRhIHtcbiAgLyoqIDItRCBtYXRyaWNlcywgb25lIHBlciBzdGFjayBmcmFtZSAobGVuZ3RoIDEgZm9yIG5vbi1zdGFjayBpbWFnZXMpLiAqL1xuICBmcmFtZXM6IGFueVtdO1xuICAvKiogSW1hZ2UtcGl4ZWwgd2lkdGggb2YgZWFjaCBmcmFtZSBtYXRyaXguICovXG4gIHdpZHRoOiBudW1iZXI7XG4gIC8qKiBJbWFnZS1waXhlbCBoZWlnaHQgb2YgZWFjaCBmcmFtZSBtYXRyaXguICovXG4gIGhlaWdodDogbnVtYmVyO1xuICAvKipcbiAgICogUGxvdC1kYXRhLWNvb3Jkcy1wZXItaW1hZ2UtcGl4ZWwgYWxvbmcgeCAoYW5kIHkg4oCUIHRoZXkncmUgdGhlIHNhbWVcbiAgICogZm9yIGhlYXRtYXAgYW5kIGltYWdlIHRyYWNlcykuXG4gICAqL1xuICByYXRpb3M6IG51bWJlcltdO1xuICAvKiogV2hldGhlciBlYWNoIGZyYW1lIGlzIGEgMi1EIHNjYWxhciBtYXRyaXggKHRydWUpIG9yIDMtY2hhbm5lbCBSR0IgKGZhbHNlKS4gKi9cbiAgaXNHcmF5c2NhbGU6IGJvb2xlYW47XG4gIC8qKlxuICAgKiBEYXRhLWNvb3JkcyBvZiBtYXRyaXggcGl4ZWwgKDAsMCkuIExldHMgdGhlIG1hdHJpeCBiZSBhICpjcm9wKiBvZiB0aGUgZGF0YVxuICAgKiBzcGFjZSByYXRoZXIgdGhhbiBzdGFydGluZyBhdCB0aGUgb3JpZ2luIOKAlCBlLmcuIHRoZSBPU0QgYmFja2VuZCBzYW1wbGVzIHRoZVxuICAgKiBjdXJyZW50bHkgcmVuZGVyZWQgdmlld3BvcnQsIHNvIHdoZW4gem9vbWVkIGluIHRoZSBtYXRyaXggY292ZXJzIG9ubHkgdGhlXG4gICAqIHZpc2libGUgc3ViLXJlZ2lvbiBhdCBzY3JlZW4gcmVzb2x1dGlvbi4gRGVmYXVsdHMgdG8gMCAoZnVsbC1mcmFtZSBtYXRyaXgsXG4gICAqIGFzIFBsb3RseSBwcm92aWRlcykuIG1hdHJpeEluZGV4ID0gKGRhdGEgLSBvcmlnaW4pIC8gcmF0aW8uXG4gICAqL1xuICBvcmlnaW5YPzogbnVtYmVyO1xuICBvcmlnaW5ZPzogbnVtYmVyO1xufVxuXG4vKipcbiAqIFRoZSBjb2xsYWJvcmF0aW9uIGludGVyZmFjZSB0aGUgd2FuZCB0b29sIG5lZWRzIGZyb20gUGxvdGx5U2VydmljZS5cbiAqXG4gKiBLZWVwaW5nIGl0IGV4cGxpY2l0IG1ha2VzIHRoZSBkZXBlbmRlbmN5IG9uZS13YXk6IFdhbmRUb29sU2VydmljZSBuZXZlclxuICogaW1wb3J0cyBQbG90bHlTZXJ2aWNlIGRpcmVjdGx5LiBQbG90bHlTZXJ2aWNlIHNhdGlzZmllcyB0aGlzIGludGVyZmFjZVxuICogc3RydWN0dXJhbGx5IGFuZCBiaW5kcyBpdHNlbGYgdmlhIGBiaW5kSG9zdCh0aGlzKWAuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgV2FuZFRvb2xIb3N0IGV4dGVuZHMgSVZpZXdwb3J0SG9zdCwgSVJlZ2lvbkRhdGFIb3N0IHtcbiAgLyoqIFBpeGVsIGRhdGEgZm9yIHNhbXBsaW5nLiBudWxsIHdoZW4gbm8gaW1hZ2UgaXMgbG9hZGVkIHlldC4gKi9cbiAgZ2V0Q2FjaGVkSW1hZ2VEYXRhKCk6IENhY2hlZEltYWdlRGF0YSB8IG51bGw7XG4gIC8qKiBJbmRleCBvZiB0aGUgY3VycmVudGx5IHZpc2libGUgZnJhbWUgaW4gYSBzdGFjayAoMCBmb3Igbm9uLXN0YWNrKS4gKi9cbiAgZ2V0QWN0aXZlRnJhbWVJbmRleCgpOiBudW1iZXI7XG5cbiAgLyoqIEN1cnJlbnQgaW1hZ2UncyBmaWxlbmFtZSDigJQgc3RhbXBlZCBvbnRvIG5ldyBzaGFwZXMgZm9yIGZpbHRlcmluZy4gKi9cbiAgZ2V0RmlsZU5hbWUoKTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAvKiogRGVmYXVsdCBzdHJva2UgY29sb3VyIGZvciBuZXcgc2hhcGVzLiAqL1xuICBnZXRTaGFwZUNvbG9yKCk6IHN0cmluZztcbn1cblxuLyoqXG4gKiBUaGUgd2FuZCBkcmF3aW5nIHRvb2wuIE93bnMgaXRzIG93biBjYW52YXMgb3ZlcmxheSwgbW91c2UgaGFuZGxlcnMsIGFuZFxuICogc3Ryb2tlIGFjY3VtdWxhdG9yLiBSZWFkcy93cml0ZXMgdGhlIHNoYXBlIGxpc3QgdmlhIHRoZSBXYW5kVG9vbEhvc3RcbiAqIGludGVyZmFjZSBzbyBpdCBzdGF5cyBkZWNvdXBsZWQgZnJvbSBQbG90bHlTZXJ2aWNlIGludGVybmFscy5cbiAqXG4gKiBMaWZlY3ljbGU6IFBsb3RseVNlcnZpY2UgaW5qZWN0cyB0aGlzIHNlcnZpY2UsIGNhbGxzIGBiaW5kSG9zdCh0aGlzKWAgb25jZVxuICogZHVyaW5nIGl0cyBvd24gY29uc3RydWN0aW9uLCB0aGVuIGNhbGxzIGBzZXRNb2RlKHRydWUgfCBmYWxzZSwgb3B0aW9ucylgIHRvXG4gKiBhY3RpdmF0ZS9kZWFjdGl2YXRlIHRoZSB0b29sLlxuICovXG5ASW5qZWN0YWJsZSh7IHByb3ZpZGVkSW46ICdyb290JyB9KVxuZXhwb3J0IGNsYXNzIFdhbmRUb29sU2VydmljZSB7XG4gIC8vIOKUgOKUgCBUb29sIHN0YXRlIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHByaXZhdGUgaG9zdCE6IFdhbmRUb29sSG9zdDtcbiAgcHJpdmF0ZSBvdmVybGF5OiBIVE1MQ2FudmFzRWxlbWVudCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGFjdGl2ZSA9IGZhbHNlO1xuICAvKipcbiAgICogQWNjdW11bGF0ZWQgd2FuZCByZWdpb24uIEV2ZXJ5IHBlci10aWNrIHBhdGNoIG1hc2sgaXMgT1InZCBpbnRvIGBtYXNrYFxuICAgKiBvdmVyIGEgYmJveCB0aGF0IGdyb3dzIHdpdGggdGhlIHN0cm9rZSwgc28gdGhlIHJlZ2lvbiBrZWVwcyBleHBhbmRpbmdcbiAgICogYXMgdGhlIHVzZXIgZHJhZ3MuIFRoZSBhY2N1bXVsYXRvciBwZXJzaXN0cyBhY3Jvc3MgbW91c2V1cC9tb3VzZWRvd24gc29cbiAgICogdGhhdCBzdWJzZXF1ZW50IHN0cm9rZXMgZXh0ZW5kIHRoZSAqc2FtZSogcmVnaW9uIOKAlCBtYXRjaGluZyBRdVBhdGgnc1xuICAgKiBicnVzaCBiZWhhdmlvdXIgd2hlcmUgdGhlIGFjdGl2ZSBhbm5vdGF0aW9uIHN0YXlzIGVkaXRhYmxlIHVudGlsIHRoZVxuICAgKiB1c2VyIHN3aXRjaGVzIHRvb2wuXG4gICAqL1xuICBwcml2YXRlIHN0cm9rZTogQkJveE1hc2sgfCBudWxsID0gbnVsbDtcbiAgLyoqIElkIG9mIHRoZSByZWdpb24gdGhpcyB3YW5kIHN0cm9rZSBpcyBlZGl0aW5nIChudWxsID0gYSBmcmVzaCByZWdpb24pLiAqL1xuICBwcml2YXRlIHN0cm9rZVJlZ2lvbklkOiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgLyoqIFJlYWRiYWNrIHJhdGlvL29yaWdpbiBzaWduYXR1cmUgdGhlIGFjdGl2ZSBzdHJva2UncyBtYXRyaXggY29vcmRzIGFyZSB0aWVkIHRvOyBhIGNoYW5nZVxuICAgKiAgKHpvb20vcGFuKSBpbnZhbGlkYXRlcyB0aGUgc3Ryb2tlIHNvIGl0IGlzbid0IHJlLWNvbW1pdHRlZCBhdCBhIGRpZmZlcmVudCBzY2FsZSAoaml0LXVpIzEwMikuICovXG4gIHByaXZhdGUgc3Ryb2tlUmF0aW9TaWc6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGRyYWdnaW5nID0gZmFsc2U7XG4gIHByaXZhdGUgb3B0aW9uczogV2FuZE9wdGlvbnMgPSB7fTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGJvdW5kTW91c2VEb3duOiAoZTogTW91c2VFdmVudCkgPT4gdm9pZDtcbiAgcHJpdmF0ZSByZWFkb25seSBib3VuZE1vdXNlTW92ZTogKGU6IE1vdXNlRXZlbnQpID0+IHZvaWQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgYm91bmRNb3VzZVVwOiAoZTogTW91c2VFdmVudCkgPT4gdm9pZDtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHdhbmRTZXJ2aWNlOiBXYW5kU2VydmljZSkge1xuICAgIHRoaXMuYm91bmRNb3VzZURvd24gPSAoZSkgPT4gdGhpcy5vbk1vdXNlRG93bihlKTtcbiAgICB0aGlzLmJvdW5kTW91c2VNb3ZlID0gKGUpID0+IHRoaXMub25Nb3VzZU1vdmUoZSk7XG4gICAgdGhpcy5ib3VuZE1vdXNlVXAgPSAoZSkgPT4gdGhpcy5vbk1vdXNlVXAoZSk7XG4gIH1cblxuICAvKiogV2lyZSB0aGUgdG9vbCB0byBpdHMgaG9zdC4gTXVzdCBiZSBjYWxsZWQgb25jZSBiZWZvcmUgYHNldE1vZGUodHJ1ZSlgLiAqL1xuICBiaW5kSG9zdChob3N0OiBXYW5kVG9vbEhvc3QpIHtcbiAgICB0aGlzLmhvc3QgPSBob3N0O1xuICB9XG5cbiAgLy8g4pSA4pSAIFB1YmxpYyBBUEkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqIFRvZ2dsZSB0aGUgd2FuZCBvbi9vZmYuICovXG4gIHNldE1vZGUoYWN0aXZlOiBib29sZWFuLCBvcHRpb25zOiBXYW5kT3B0aW9ucyA9IHt9KSB7XG4gICAgdGhpcy5hY3RpdmUgPSBhY3RpdmU7XG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgICBpZiAoYWN0aXZlKSB7XG4gICAgICB0aGlzLmNyZWF0ZU92ZXJsYXkoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5kZXN0cm95T3ZlcmxheSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBNZXJnZSBuZXcgb3B0aW9ucyAoZS5nLiBsaXZlIHNlbnNpdGl2aXR5IHNsaWRlciB1cGRhdGVzKS4gKi9cbiAgc2V0T3B0aW9ucyhvcHRpb25zOiBXYW5kT3B0aW9ucykge1xuICAgIHRoaXMub3B0aW9ucyA9IHsgLi4udGhpcy5vcHRpb25zLCAuLi5vcHRpb25zIH07XG4gIH1cblxuICAvKiogRHJvcCB0aGUgYWN0aXZlIHdhbmQgcmVnaW9uIHNvIHRoZSBuZXh0IGNsaWNrIHN0YXJ0cyBhIG5ldyBvbmUuICovXG4gIGNsZWFyQWN0aXZlUmVnaW9uKCkge1xuICAgIHRoaXMucmVzZXRTdHJva2UoKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBPdmVybGF5IGxpZmVjeWNsZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICBwcml2YXRlIGNyZWF0ZU92ZXJsYXkoKSB7XG4gICAgY29uc3QgcGxvdEVsID0gdGhpcy5ob3N0LmdldE92ZXJsYXlDb250YWluZXIoKTtcbiAgICBpZiAoIXBsb3RFbCB8fCB0aGlzLm92ZXJsYXkpIHJldHVybjtcblxuICAgIGNvbnN0IGNhbnZhcyA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ2NhbnZhcycpO1xuICAgIGNhbnZhcy5zdHlsZS5wb3NpdGlvbiA9ICdhYnNvbHV0ZSc7XG4gICAgY2FudmFzLnN0eWxlLnRvcCA9ICcwJztcbiAgICBjYW52YXMuc3R5bGUubGVmdCA9ICcwJztcbiAgICBjYW52YXMuc3R5bGUud2lkdGggPSAnMTAwJSc7XG4gICAgY2FudmFzLnN0eWxlLmhlaWdodCA9ICcxMDAlJztcbiAgICBjYW52YXMuc3R5bGUuY3Vyc29yID0gJ2Nyb3NzaGFpcic7XG4gICAgY2FudmFzLnN0eWxlLnpJbmRleCA9ICcxMDAnO1xuICAgIGNhbnZhcy53aWR0aCA9IHBsb3RFbC5vZmZzZXRXaWR0aDtcbiAgICBjYW52YXMuaGVpZ2h0ID0gcGxvdEVsLm9mZnNldEhlaWdodDtcblxuICAgIHBsb3RFbC5hcHBlbmRDaGlsZChjYW52YXMpO1xuICAgIHRoaXMub3ZlcmxheSA9IGNhbnZhcztcblxuICAgIGNhbnZhcy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCB0aGlzLmJvdW5kTW91c2VEb3duKTtcbiAgICBjYW52YXMuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgdGhpcy5ib3VuZE1vdXNlTW92ZSk7XG4gICAgY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNldXAnLCB0aGlzLmJvdW5kTW91c2VVcCk7XG4gICAgY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlbGVhdmUnLCB0aGlzLmJvdW5kTW91c2VVcCk7XG4gIH1cblxuICBwcml2YXRlIGRlc3Ryb3lPdmVybGF5KCkge1xuICAgIGlmICghdGhpcy5vdmVybGF5KSByZXR1cm47XG4gICAgdGhpcy5vdmVybGF5LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlZG93bicsIHRoaXMuYm91bmRNb3VzZURvd24pO1xuICAgIHRoaXMub3ZlcmxheS5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW1vdmUnLCB0aGlzLmJvdW5kTW91c2VNb3ZlKTtcbiAgICB0aGlzLm92ZXJsYXkucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2V1cCcsIHRoaXMuYm91bmRNb3VzZVVwKTtcbiAgICB0aGlzLm92ZXJsYXkucmVtb3ZlRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsIHRoaXMuYm91bmRNb3VzZVVwKTtcbiAgICB0aGlzLm92ZXJsYXkucmVtb3ZlKCk7XG4gICAgdGhpcy5vdmVybGF5ID0gbnVsbDtcbiAgICB0aGlzLnJlc2V0U3Ryb2tlKCk7XG4gIH1cblxuICBwcml2YXRlIG9uTW91c2VEb3duKGU6IE1vdXNlRXZlbnQpIHtcbiAgICBpZiAoZS5idXR0b24gIT09IDApIHJldHVybjtcbiAgICB0aGlzLmRyYWdnaW5nID0gdHJ1ZTtcbiAgICB0aGlzLmFwcGx5QXRDbGllbnQoZSwgdHJ1ZSk7XG4gIH1cblxuICBwcml2YXRlIG9uTW91c2VNb3ZlKGU6IE1vdXNlRXZlbnQpIHtcbiAgICBpZiAoIXRoaXMuZHJhZ2dpbmcpIHJldHVybjtcbiAgICBpZiAoKGUuYnV0dG9ucyAmIDEpID09PSAwKSB7XG4gICAgICB0aGlzLmRyYWdnaW5nID0gZmFsc2U7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuYXBwbHlBdENsaWVudChlLCBmYWxzZSk7XG4gIH1cblxuICBwcml2YXRlIG9uTW91c2VVcChfOiBNb3VzZUV2ZW50KSB7XG4gICAgLy8gU3RvcCBhY2N1bXVsYXRpbmcgZnJvbSB0aGlzIGRyYWcsIGJ1dCBrZWVwIHRoZSByZWdpb24gYWxpdmUgc28gdGhlXG4gICAgLy8gbmV4dCBtb3VzZWRvd24gZXh0ZW5kcyBpdCBpbnN0ZWFkIG9mIHN0YXJ0aW5nIGZyZXNoLlxuICAgIHRoaXMuZHJhZ2dpbmcgPSBmYWxzZTtcbiAgfVxuXG4gIHByaXZhdGUgcmVzZXRTdHJva2UoKSB7XG4gICAgdGhpcy5zdHJva2UgPSBudWxsO1xuICAgIHRoaXMuc3Ryb2tlUmVnaW9uSWQgPSBudWxsO1xuICAgIHRoaXMuZHJhZ2dpbmcgPSBmYWxzZTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBQZXItdGljayBzdHJva2UgbG9naWMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqXG4gICAqIFNhbXBsZSB0aGUgY2FjaGVkIGltYWdlIGF0IHRoZSBjbGljayBsb2NhdGlvbiwgT1IgKG9yIEFORC1OT1QpIHRoZVxuICAgKiB3YW5kJ3MgcGVyLXRpY2sgcGF0Y2ggbWFzayBpbnRvIHRoZSBhY3RpdmUgcmVnaW9uJ3MgYmJveC1yZWxhdGl2ZSBtYXNrLFxuICAgKiByZS10cmFjZSB0aGUgYm91bmRhcnksIGFuZCB1cGRhdGUgdGhlIGluLXByb2dyZXNzIHNoYXBlIOKAlCBtYXRjaGluZ1xuICAgKiBRdVBhdGgncyBhZGRpdGl2ZSBicnVzaC93YW5kIGJlaGF2aW91ci4gU2hpZnQgPSBlcmFzZS4gQ21kL0N0cmwgPVxuICAgKiBleGFjdC1tYXRjaCBmbG9vZCBmaWxsLlxuICAgKi9cbiAgcHJpdmF0ZSBhcHBseUF0Q2xpZW50KGU6IE1vdXNlRXZlbnQsIGlzU3RhcnQgPSBmYWxzZSkge1xuICAgIGlmICghdGhpcy5vdmVybGF5KSByZXR1cm47XG4gICAgY29uc3QgY2FjaGVkID0gdGhpcy5ob3N0LmdldENhY2hlZEltYWdlRGF0YSgpO1xuICAgIGlmICghY2FjaGVkIHx8IGNhY2hlZC5mcmFtZXMubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgICAvLyBUaGUgY3VycmVudCByZWdpb25zIChuZXV0cmFsIG1vZGVsKS4gTXV0YXRlZCBsb2NhbGx5IGFjcm9zcyB0aGlzIHRpY2sgYW5kXG4gICAgLy8gY29tbWl0dGVkIG9uY2UgdmlhIGhvc3Quc2V0UmVnaW9ucygpLlxuICAgIGNvbnN0IHJlZ2lvbnMgPSB0aGlzLmhvc3QuZ2V0UmVnaW9ucygpO1xuXG4gICAgY29uc3QgdHJhbnNmb3JtID0gdGhpcy5ob3N0LmdldENvb3JkaW5hdGVUcmFuc2Zvcm0oKTtcbiAgICBpZiAoIXRyYW5zZm9ybS5pc1JlYWR5KCkpIHJldHVybjtcbiAgICBjb25zdCB7IHg6IGRhdGFYLCB5OiBkYXRhWSB9ID0gdHJhbnNmb3JtLmNsaWVudFRvRGF0YShlLmNsaWVudFgsIGUuY2xpZW50WSk7XG4gICAgaWYgKCFOdW1iZXIuaXNGaW5pdGUoZGF0YVgpIHx8ICFOdW1iZXIuaXNGaW5pdGUoZGF0YVkpKSByZXR1cm47XG5cbiAgICAvLyByYXRpb3MgPSBbeFJhdGlvLCB5UmF0aW9dIGZyb20gYm90aCBiYWNrZW5kcy4gVXNlIHRoZSBYIHJhdGlvIGZvciB0aGVcbiAgICAvLyBjb2x1bW4gYW5kIHRoZSBZIHJhdGlvIGZvciB0aGUgcm93OiB0aGV5IGRpZmZlciB3aGVuIHRoZSBwaXhlbCBhc3BlY3RcbiAgICAvLyBpc24ndCAxOjEgKGUuZy4gYSBub24tc3F1YXJlIE9TRCB2aWV3cG9ydCksIGFuZCByZXVzaW5nIHJhdGlvc1swXSBmb3JcbiAgICAvLyBib3RoIHdvdWxkIGRpc3RvcnQgdGhlIHNhbXBsZWQgcmVnaW9uIHZlcnRpY2FsbHkuIEZhbGwgYmFjayB0byB0aGUgWFxuICAgIC8vIHJhdGlvIGlmIG9ubHkgb25lIHdhcyBzdXBwbGllZC5cbiAgICBjb25zdCByeCA9IGNhY2hlZC5yYXRpb3NbMF0gfHwgMTtcbiAgICBjb25zdCByeSA9IGNhY2hlZC5yYXRpb3NbMV0gfHwgY2FjaGVkLnJhdGlvc1swXSB8fCAxO1xuICAgIGNvbnN0IG94ID0gY2FjaGVkLm9yaWdpblggPz8gMDtcbiAgICBjb25zdCBveSA9IGNhY2hlZC5vcmlnaW5ZID8/IDA7XG4gICAgLy8gVGhlIHN0cm9rZSBhY2N1bXVsYXRvciBpcyBpbiBtYXRyaXggKHZpZXdwb3J0LXBpeGVsKSBjb29yZGluYXRlcyB0aWVkIHRvIHRoZSByZWFkYmFjaydzXG4gICAgLy8gcmF0aW8vb3JpZ2luLiBJZiB0aGUgdmlldyBjaGFuZ2VkICh6b29tL3Bhbikgc2luY2UgdGhlIHN0cm9rZSB3YXMgYnVpbHQsIHRob3NlIGNvb3JkcyBub1xuICAgIC8vIGxvbmdlciBtZWFuIHRoZSBzYW1lIHRoaW5nIOKAlCByZS1jb21taXR0aW5nIHdvdWxkIHJlc2NhbGUgdGhlIHJlZ2lvbiBieSB0aGUgem9vbSBmYWN0b3JcbiAgICAvLyAoaml0LXVpIzEwMikuIERyb3AgdGhlIHN0YWxlIHN0cm9rZSBzbyBhIGZyZXNoIG9uZSBpcyBidWlsdCBhdCB0aGUgY3VycmVudCB2aWV3LlxuICAgIGNvbnN0IHNpZyA9IGAke3J4fSwke3J5fSwke294fSwke295fWA7XG4gICAgaWYgKHRoaXMuc3Ryb2tlICYmIHRoaXMuc3Ryb2tlUmF0aW9TaWcgIT09IHNpZykge1xuICAgICAgdGhpcy5zdHJva2UgPSBudWxsO1xuICAgICAgdGhpcy5zdHJva2VSZWdpb25JZCA9IG51bGw7XG4gICAgfVxuICAgIHRoaXMuc3Ryb2tlUmF0aW9TaWcgPSBzaWc7XG4gICAgY29uc3QgbWF0cml4WCA9IChkYXRhWCAtIG94KSAvIHJ4O1xuICAgIGNvbnN0IG1hdHJpeFkgPSAoZGF0YVkgLSBveSkgLyByeTtcbiAgICBpZiAobWF0cml4WCA8IDAgfHwgbWF0cml4WCA+PSBjYWNoZWQud2lkdGgpIHJldHVybjtcbiAgICBpZiAobWF0cml4WSA8IDAgfHwgbWF0cml4WSA+PSBjYWNoZWQuaGVpZ2h0KSByZXR1cm47XG5cbiAgICBjb25zdCBmcmFtZUlkeCA9IHRoaXMuaG9zdC5nZXRBY3RpdmVGcmFtZUluZGV4KCk7XG4gICAgY29uc3QgZnJhbWUgPSBjYWNoZWQuZnJhbWVzW2ZyYW1lSWR4XSA/PyBjYWNoZWQuZnJhbWVzWzBdO1xuXG4gICAgY29uc3Qgd2FuZEltYWdlOiBXYW5kSW1hZ2UgPSB7XG4gICAgICBkYXRhOiBmcmFtZSxcbiAgICAgIHdpZHRoOiBjYWNoZWQud2lkdGgsXG4gICAgICBoZWlnaHQ6IGNhY2hlZC5oZWlnaHQsXG4gICAgICBpc0dyYXlzY2FsZTogY2FjaGVkLmlzR3JheXNjYWxlLFxuICAgIH07XG4gICAgLy8gU2hpZnQgPSBlcmFzZSAoc3VidHJhY3QgcGl4ZWxzIGZyb20gYW4gZXhpc3RpbmcgcmVnaW9uKS5cbiAgICAvLyBDbWQvQ3RybCBhbG9uZSA9IHNpbXBsZSBmbG9vZCBmaWxsIChubyBzbW9vdGhpbmcvdGhyZXNob2xkKS5cbiAgICBjb25zdCBlcmFzZSA9IGUuc2hpZnRLZXk7XG4gICAgY29uc3Qgb3B0czogV2FuZE9wdGlvbnMgPSB7XG4gICAgICAuLi50aGlzLm9wdGlvbnMsXG4gICAgICBzaW1wbGVNb2RlOiB0aGlzLm9wdGlvbnMuc2ltcGxlTW9kZSB8fCAoKGUubWV0YUtleSB8fCBlLmN0cmxLZXkpICYmICFlcmFzZSksXG4gICAgfTtcblxuICAgIC8vIElmIHRoaXMgaXMgdGhlIGZpcnN0IHRpY2sgb2YgYSBuZXcgZHJhZyBhbmQgdGhlIGNsaWNrIGlzIE5PVCBpbnNpZGUgdGhlXG4gICAgLy8gY3VycmVudCBhY2N1bXVsYXRvciBhbmQgTk9UIGluc2lkZSBhbnkgZXhpc3RpbmcgcGF0aC1zaGFwZSwgZHJvcCB0aGUgb2xkXG4gICAgLy8gc3Ryb2tlIHNvIGEgYnJhbmQtbmV3IHJlZ2lvbiBzdGFydHMgaGVyZS4gV2l0aG91dCB0aGlzLCB0aGUgYWNjdW11bGF0b3JcbiAgICAvLyBiYm94IGdyb3dzIHRvIHNwYW4gYm90aCBhcmVhcyBhbmQgYG1hc2tUb1BvbHlnb25gIGtlZXBzIG9ubHkgdGhlIGxhcmdlc3RcbiAgICAvLyBjb25uZWN0ZWQgYmxvYiDigJQgbWFraW5nIHRoZSBuZXcgY2xpY2sgYXBwZWFyIHRvIGRvIG5vdGhpbmcuXG4gICAgaWYgKGlzU3RhcnQgJiYgIWVyYXNlICYmIHRoaXMuc3Ryb2tlICYmICF0aGlzLnBvaW50SW5TdHJva2UobWF0cml4WCwgbWF0cml4WSkpIHtcbiAgICAgIC8vIFdpbGwgZmFsbCB0aHJvdWdoIHRvIHRyeUFkb3B0U2hhcGVBdCBiZWxvdzsgaWYgdGhhdCBhbHNvIG1pc3NlcywgYVxuICAgICAgLy8gZnJlc2ggc3Ryb2tlIGlzIGNyZWF0ZWQgZnJvbSB0aGUgcGF0Y2guXG4gICAgICB0aGlzLnN0cm9rZSA9IG51bGw7XG4gICAgICB0aGlzLnN0cm9rZVJlZ2lvbklkID0gbnVsbDtcbiAgICB9XG5cbiAgICBjb25zdCBwYXRjaCA9IHRoaXMud2FuZFNlcnZpY2UuY29tcHV0ZVBhdGNoTWFzayh3YW5kSW1hZ2UsIG1hdHJpeFgsIG1hdHJpeFksIG9wdHMpO1xuICAgIGlmICghcGF0Y2gpIHJldHVybjtcblxuICAgIGNvbnN0IFcgPSBwYXRjaC5zaXplO1xuICAgIGNvbnN0IGhhbGYgPSAoVyAtIDEpIC8gMjtcbiAgICBjb25zdCBweDAgPSBNYXRoLnJvdW5kKG1hdHJpeFgpIC0gaGFsZjtcbiAgICBjb25zdCBweTAgPSBNYXRoLnJvdW5kKG1hdHJpeFkpIC0gaGFsZjtcbiAgICBjb25zdCBweDEgPSBweDAgKyBXO1xuICAgIGNvbnN0IHB5MSA9IHB5MCArIFc7XG5cbiAgICAvLyBJZiB0aGVyZSdzIG5vIGFjdGl2ZSB3YW5kIHJlZ2lvbiwgc2VlIGlmIHRoZSBjbGljayBsYW5kZWQgb24gYW5cbiAgICAvLyBleGlzdGluZyBwYXRoLXNoYXBlIOKAlCBhZG9wdCBpdCBzbyB0aGlzIHN0cm9rZSBleHRlbmRzIChvciBlcmFzZXNcbiAgICAvLyBmcm9tKSBpdCBpbnN0ZWFkIG9mIGNyZWF0aW5nIGEgbmV3IHJlZ2lvbi5cbiAgICBpZiAoIXRoaXMuc3Ryb2tlKSB7XG4gICAgICB0aGlzLnRyeUFkb3B0U2hhcGVBdChyZWdpb25zLCBtYXRyaXhYLCBtYXRyaXhZLCByeCwgcnksIGNhY2hlZCk7XG4gICAgfVxuXG4gICAgLy8gRXJhc2luZyByZXF1aXJlcyBhbiBleGlzdGluZyByZWdpb24uIFNoaWZ0LWNsaWNraW5nIGVtcHR5IHNwYWNlIGlzIGFcbiAgICAvLyBuby1vcCDigJQgd2UgZG9uJ3QgY3JlYXRlIGEgcmVnaW9uIG9ubHkgdG8gaW1tZWRpYXRlbHkgZGVsZXRlIGZyb20gaXQuXG4gICAgaWYgKGVyYXNlICYmICF0aGlzLnN0cm9rZSkgcmV0dXJuO1xuXG4gICAgLy8gR3JvdyB0aGUgcmVnaW9uJ3MgYWNjdW11bGF0ZWQgbWFzayBvbmx5IHdoZW4gYWRkaW5nLiBFcmFzaW5nIG5ldmVyXG4gICAgLy8gZXhwYW5kcyB0aGUgcmVnaW9uIGJleW9uZCBpdHMgY3VycmVudCBiYm94LlxuICAgIGlmICghdGhpcy5zdHJva2UpIHtcbiAgICAgIGNvbnN0IGJ4ID0gTWF0aC5tYXgoMCwgcHgwKTtcbiAgICAgIGNvbnN0IGJ5ID0gTWF0aC5tYXgoMCwgcHkwKTtcbiAgICAgIGNvbnN0IGJ4MSA9IE1hdGgubWluKGNhY2hlZC53aWR0aCwgcHgxKTtcbiAgICAgIGNvbnN0IGJ5MSA9IE1hdGgubWluKGNhY2hlZC5oZWlnaHQsIHB5MSk7XG4gICAgICBjb25zdCBidyA9IE1hdGgubWF4KDAsIGJ4MSAtIGJ4KTtcbiAgICAgIGNvbnN0IGJoID0gTWF0aC5tYXgoMCwgYnkxIC0gYnkpO1xuICAgICAgaWYgKGJ3ID09PSAwIHx8IGJoID09PSAwKSByZXR1cm47XG4gICAgICB0aGlzLnN0cm9rZSA9IHsgYngsIGJ5LCBidywgYmgsIG1hc2s6IG5ldyBVaW50OEFycmF5KGJ3ICogYmgpIH07XG4gICAgfSBlbHNlIGlmICghZXJhc2UpIHtcbiAgICAgIC8vIERvbid0IGNsYW1wIHRoZSBhY2N1bXVsYXRvciB0byB0aGUgdmlld3BvcnQ6IGFuIGFkb3B0ZWQgcmVnaW9uIG1heSBleHRlbmQgb2ZmLXNjcmVlbiwgYW5kXG4gICAgICAvLyBjbGFtcGluZyBoZXJlIHdvdWxkIGRpc2NhcmQgaXRzIG9mZi1zY3JlZW4gcGFydCB3aGVuIHRoZSBzdHJva2UgZ3Jvd3MgKGppdC11aSMxMDIpLlxuICAgICAgY29uc3QgYnggPSBNYXRoLm1pbih0aGlzLnN0cm9rZS5ieCwgcHgwKTtcbiAgICAgIGNvbnN0IGJ5ID0gTWF0aC5taW4odGhpcy5zdHJva2UuYnksIHB5MCk7XG4gICAgICBjb25zdCBieDEgPSBNYXRoLm1heCh0aGlzLnN0cm9rZS5ieCArIHRoaXMuc3Ryb2tlLmJ3LCBweDEpO1xuICAgICAgY29uc3QgYnkxID0gTWF0aC5tYXgodGhpcy5zdHJva2UuYnkgKyB0aGlzLnN0cm9rZS5iaCwgcHkxKTtcbiAgICAgIGNvbnN0IGJ3ID0gYngxIC0gYng7XG4gICAgICBjb25zdCBiaCA9IGJ5MSAtIGJ5O1xuICAgICAgaWYgKGJ3ICE9PSB0aGlzLnN0cm9rZS5idyB8fCBiaCAhPT0gdGhpcy5zdHJva2UuYmggfHwgYnggIT09IHRoaXMuc3Ryb2tlLmJ4IHx8IGJ5ICE9PSB0aGlzLnN0cm9rZS5ieSkge1xuICAgICAgICAvLyBSZWFsbG9jYXRlIHRoZSBsYXJnZXIgbWFzayBhbmQgY29weSB0aGUgcHJldmlvdXMgbWFzayBpbnRvIGl0LlxuICAgICAgICBjb25zdCBuZXh0ID0gbmV3IFVpbnQ4QXJyYXkoYncgKiBiaCk7XG4gICAgICAgIGNvbnN0IGR4ID0gdGhpcy5zdHJva2UuYnggLSBieDtcbiAgICAgICAgY29uc3QgZHkgPSB0aGlzLnN0cm9rZS5ieSAtIGJ5O1xuICAgICAgICBmb3IgKGxldCByb3cgPSAwOyByb3cgPCB0aGlzLnN0cm9rZS5iaDsgcm93KyspIHtcbiAgICAgICAgICBjb25zdCBzcmNPZmYgPSByb3cgKiB0aGlzLnN0cm9rZS5idztcbiAgICAgICAgICBjb25zdCBkc3RPZmYgPSAocm93ICsgZHkpICogYncgKyBkeDtcbiAgICAgICAgICBuZXh0LnNldCh0aGlzLnN0cm9rZS5tYXNrLnN1YmFycmF5KHNyY09mZiwgc3JjT2ZmICsgdGhpcy5zdHJva2UuYncpLCBkc3RPZmYpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuc3Ryb2tlID0geyBieCwgYnksIGJ3LCBiaCwgbWFzazogbmV4dCB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIEFwcGx5IHRoZSBwYXRjaDogT1IgKGFkZCkgb3IgQU5ELU5PVCAoZXJhc2UpLlxuICAgIGNvbnN0IHN0cm9rZSA9IHRoaXMuc3Ryb2tlO1xuICAgIGZvciAobGV0IHB5ID0gMDsgcHkgPCBXOyBweSsrKSB7XG4gICAgICBjb25zdCBpeSA9IHB5MCArIHB5O1xuICAgICAgY29uc3QgbXkgPSBpeSAtIHN0cm9rZS5ieTtcbiAgICAgIGlmIChteSA8IDAgfHwgbXkgPj0gc3Ryb2tlLmJoKSBjb250aW51ZTtcbiAgICAgIGNvbnN0IHNyY1JvdyA9IHB5ICogVztcbiAgICAgIGNvbnN0IGRzdFJvdyA9IG15ICogc3Ryb2tlLmJ3O1xuICAgICAgZm9yIChsZXQgcHggPSAwOyBweCA8IFc7IHB4KyspIHtcbiAgICAgICAgaWYgKCFwYXRjaC5tYXNrW3NyY1JvdyArIHB4XSkgY29udGludWU7XG4gICAgICAgIGNvbnN0IGl4ID0gcHgwICsgcHg7XG4gICAgICAgIGNvbnN0IG14ID0gaXggLSBzdHJva2UuYng7XG4gICAgICAgIGlmIChteCA8IDAgfHwgbXggPj0gc3Ryb2tlLmJ3KSBjb250aW51ZTtcbiAgICAgICAgaWYgKGVyYXNlKSBzdHJva2UubWFza1tkc3RSb3cgKyBteF0gPSAwO1xuICAgICAgICBlbHNlIHN0cm9rZS5tYXNrW2RzdFJvdyArIG14XSA9IDE7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKCFlcmFzZSkge1xuICAgICAgLy8gSWYgdGhlIGdyb3duIHN0cm9rZSBub3cgb3ZlcmxhcHMgYW5vdGhlciBwYXRoLXNoYXBlLCBmb2xkIHRob3NlXG4gICAgICAvLyBzaGFwZXMgaW50byB0aGlzIG9uZSBhbmQgZHJvcCB0aGVtIOKAlCBtYXRjaGluZyBRdVBhdGgnc1xuICAgICAgLy8gbWVyZ2Utb24tdG91Y2ggYmVoYXZpb3VyLlxuICAgICAgdGhpcy5tZXJnZU92ZXJsYXBwaW5nU2hhcGVzKHJlZ2lvbnMsIHJ4LCByeSwgY2FjaGVkKTtcbiAgICB9XG5cbiAgICAvLyBUcmFjZSB0aGUgdW5pb24gYm91bmRhcnkgaW4gaW1hZ2UtcGl4ZWwgY29vcmRzLlxuICAgIGNvbnN0IHN0cm9rZTIgPSB0aGlzLnN0cm9rZSE7XG4gICAgY29uc3QgcG9seSA9IHRoaXMud2FuZFNlcnZpY2UubWFza1RvUG9seWdvbihcbiAgICAgIHN0cm9rZTIubWFzayxcbiAgICAgIHN0cm9rZTIuYncsXG4gICAgICBzdHJva2UyLmJoLFxuICAgICAgY2FjaGVkLndpZHRoLFxuICAgICAgY2FjaGVkLmhlaWdodCxcbiAgICAgIHN0cm9rZTIuYngsXG4gICAgICBzdHJva2UyLmJ5LFxuICAgICk7XG5cbiAgICBpZiAoIXBvbHkpIHtcbiAgICAgIC8vIEVyYXNlZCB0byBub3RoaW5nIOKAlCByZW1vdmUgdGhlIHNoYXBlIGVudGlyZWx5LlxuICAgICAgaWYgKGVyYXNlKSB0aGlzLmRyb3BBY3RpdmVTaGFwZShyZWdpb25zKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBDb252ZXJ0IGZyb20gbWF0cml4IGNvb3JkcyBiYWNrIHRvIHBsb3QgZGF0YSBjb29yZHMuXG4gICAgY29uc3QgeFBsb3QgPSBwb2x5Lnhwb2ludHMubWFwKCh4KSA9PiBveCArIHggKiByeCk7XG4gICAgY29uc3QgeVBsb3QgPSBwb2x5Lnlwb2ludHMubWFwKCh5KSA9PiBveSArIHkgKiByeSk7XG5cbiAgICB0aGlzLmNvbW1pdFN0cm9rZShyZWdpb25zLCB4UGxvdCwgeVBsb3QpO1xuICB9XG5cbiAgLyoqIFRydWUgaWYgKG1hdHJpeFgsIG1hdHJpeFkpIGxpZXMgaW5zaWRlIHRoZSBjdXJyZW50IHN0cm9rZSBhY2N1bXVsYXRvci4gKi9cbiAgcHJpdmF0ZSBwb2ludEluU3Ryb2tlKG1hdHJpeFg6IG51bWJlciwgbWF0cml4WTogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgY29uc3QgcyA9IHRoaXMuc3Ryb2tlO1xuICAgIGlmICghcykgcmV0dXJuIGZhbHNlO1xuICAgIGNvbnN0IG14ID0gTWF0aC5mbG9vcihtYXRyaXhYKSAtIHMuYng7XG4gICAgY29uc3QgbXkgPSBNYXRoLmZsb29yKG1hdHJpeFkpIC0gcy5ieTtcbiAgICBpZiAobXggPCAwIHx8IG15IDwgMCB8fCBteCA+PSBzLmJ3IHx8IG15ID49IHMuYmgpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gcy5tYXNrW215ICogcy5idyArIG14XSA9PT0gMTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgdGhlIHJlZ2lvbiByZWZlcmVuY2VkIGJ5IGBzdHJva2VSZWdpb25JZGAgZnJvbSB0aGUgcmVnaW9uIGxpc3QgYW5kXG4gICAqIHJlc2V0IHRoZSBhY3RpdmUgc3Ryb2tlIOKAlCB1c2VkIHdoZW4gYW4gZXJhc2Ugc3Ryb2tlIGRlbGV0ZXMgZXZlcnkgcGl4ZWwuXG4gICAqL1xuICBwcml2YXRlIGRyb3BBY3RpdmVTaGFwZShyZWdpb25zOiBSZWdpb25bXSkge1xuICAgIGlmICh0aGlzLnN0cm9rZVJlZ2lvbklkICE9IG51bGwpIHtcbiAgICAgIGNvbnN0IGlkeCA9IHJlZ2lvbnMuZmluZEluZGV4KChyKSA9PiByLmlkID09PSB0aGlzLnN0cm9rZVJlZ2lvbklkKTtcbiAgICAgIGlmIChpZHggPj0gMCkge1xuICAgICAgICByZWdpb25zLnNwbGljZShpZHgsIDEpO1xuICAgICAgICB0aGlzLmhvc3Quc2V0UmVnaW9ucyhyZWdpb25zKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5zdHJva2UgPSBudWxsO1xuICAgIHRoaXMuc3Ryb2tlUmVnaW9uSWQgPSBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgYSByZWdpb24gY2FuIGJlIGZhaXRoZnVsbHkgcmFzdGVyaXplZCBpbnRvIHRoZSB3YW5kIHN0cm9rZSBhdCB0aGUgY3VycmVudCB2aWV3XG4gICAqIHJlc29sdXRpb24gKHJ4L3J5ID0gZGF0YSB1bml0cyBwZXIgbWF0cml4IHBpeGVsKS4gRWRpdGluZyByYXN0ZXJpemVzIHRoZSByZWdpb24gdG8gdGhlXG4gICAqIHZpZXdwb3J0IGdyaWQgYW5kIHJlLXRyYWNlcyBpdCwgc28gYSByZWdpb24gd2hvc2UgbWF0cml4LXNwYWNlIGJib3ggZXhjZWVkcyB0aGUgcmFzdGVyaXplcidzXG4gICAqIGNhcCB3b3VsZCBiZSBjbGlwcGVkL2Rvd24tcXVhbnRpemVkIGFuZCBjb21lIGJhY2sgcmVzY2FsZWQvY29ycnVwdGVkIChqaXQtdWkjMTAyKSDigJQgZS5nLiBhXG4gICAqIHdob2xlLXNsaWRlIGFubm90YXRpb24gd2hpbGUgem9vbWVkIG91dC4gU2tpcCBhZG9wdC9tZXJnZSBmb3IgdGhvc2U6IGxlYXZlIHRoZW0gdW50b3VjaGVkIGFuZFxuICAgKiBvbmx5IGVkaXQgdGhlbSBuZWFyIG5hdGl2ZSB6b29tLlxuICAgKi9cbiAgcHJpdmF0ZSBmaXRzRm9yRWRpdChcbiAgICB2ZXJ0czogeyB4cG9pbnRzOiBudW1iZXJbXTsgeXBvaW50czogbnVtYmVyW10gfSxcbiAgICByeDogbnVtYmVyLFxuICAgIHJ5OiBudW1iZXIsXG4gICk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHhzID0gdmVydHMueHBvaW50cztcbiAgICBjb25zdCB5cyA9IHZlcnRzLnlwb2ludHM7XG4gICAgbGV0IG1pblggPSBJbmZpbml0eSwgbWF4WCA9IC1JbmZpbml0eSwgbWluWSA9IEluZmluaXR5LCBtYXhZID0gLUluZmluaXR5O1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmICh4c1tpXSA8IG1pblgpIG1pblggPSB4c1tpXTtcbiAgICAgIGlmICh4c1tpXSA+IG1heFgpIG1heFggPSB4c1tpXTtcbiAgICAgIGlmICh5c1tpXSA8IG1pblkpIG1pblkgPSB5c1tpXTtcbiAgICAgIGlmICh5c1tpXSA+IG1heFkpIG1heFkgPSB5c1tpXTtcbiAgICB9XG4gICAgY29uc3QgdyA9IChtYXhYIC0gbWluWCkgLyAocnggfHwgMSk7XG4gICAgY29uc3QgaCA9IChtYXhZIC0gbWluWSkgLyAocnkgfHwgMSk7XG4gICAgcmV0dXJuIHcgPiAwICYmIGggPiAwICYmIHcgKiBoIDw9IDQwOTYgKiA0MDk2O1xuICB9XG5cbiAgLyoqIEEgcmVnaW9uJ3MgY2xvc2VkLXBvbHlnb24gdmVydGljZXMgKGltYWdlL2RhdGEgY29vcmRzKSwgb3IgbnVsbCB3aGVuIGl0XG4gICAqICBpc24ndCBhIGZpbGxhYmxlIGNsb3NlZCBwb2x5Z29uIChyZWN0YW5nbGVzLCBvcGVuIHBvbHlsaW5lcykuICovXG4gIHByaXZhdGUgcmVnaW9uVmVydHMoXG4gICAgcmVnaW9uOiBSZWdpb24sXG4gICk6IHsgeHBvaW50czogbnVtYmVyW107IHlwb2ludHM6IG51bWJlcltdOyBob2xlcz86IG51bWJlcltdW11bXSB9IHwgbnVsbCB7XG4gICAgY29uc3QgYiA9IHJlZ2lvbj8uYm91bmRzO1xuICAgIGlmIChiIGluc3RhbmNlb2YgUG9seWdvbiAmJiBiLmNsb3NlZCAhPT0gZmFsc2UgJiYgYi54cG9pbnRzLmxlbmd0aCA+PSAzKSB7XG4gICAgICByZXR1cm4geyB4cG9pbnRzOiBiLnhwb2ludHMsIHlwb2ludHM6IGIueXBvaW50cywgaG9sZXM6IGIuaG9sZXMgfTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKiogQ29udmVydCBhIHJlZ2lvbidzIGhvbGUgcmluZ3MgZnJvbSBpbWFnZS9kYXRhIGNvb3JkcyBpbnRvIG1hdHJpeCBjb29yZHMgc29cbiAgICogIHRoZXkgbGluZSB1cCB3aXRoIHRoZSBzdHJva2UgYWNjdW11bGF0b3IgKGppdC11aSM4NSkuICovXG4gIHByaXZhdGUgaG9sZXNUb01hdHJpeChcbiAgICBob2xlczogbnVtYmVyW11bXVtdIHwgdW5kZWZpbmVkLCBveDogbnVtYmVyLCBveTogbnVtYmVyLCByeDogbnVtYmVyLCByeTogbnVtYmVyLFxuICApOiBudW1iZXJbXVtdW10gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBob2xlcz8ubWFwKChyaW5nKSA9PiByaW5nLm1hcCgoW3gsIHldKSA9PiBbKHggLSBveCkgLyByeCwgKHkgLSBveSkgLyByeV0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJZiAobWF0cml4WCwgbWF0cml4WSkgZmFsbHMgaW5zaWRlIGFuIGV4aXN0aW5nIHJlZ2lvbiwgcmFzdGVyaXplIGl0IGludG9cbiAgICogdGhlIHdhbmQgc3Ryb2tlIGFjY3VtdWxhdG9yIHNvIHN1YnNlcXVlbnQgd2FuZCBpbnB1dCBleHRlbmRzIGl0IHJhdGhlciB0aGFuXG4gICAqIHN0YXJ0aW5nIGEgbmV3IHJlZ2lvbi5cbiAgICovXG4gIHByaXZhdGUgdHJ5QWRvcHRTaGFwZUF0KFxuICAgIHJlZ2lvbnM6IFJlZ2lvbltdLFxuICAgIG1hdHJpeFg6IG51bWJlcixcbiAgICBtYXRyaXhZOiBudW1iZXIsXG4gICAgcng6IG51bWJlcixcbiAgICByeTogbnVtYmVyLFxuICAgIGNhY2hlZDogQ2FjaGVkSW1hZ2VEYXRhLFxuICApOiBib29sZWFuIHtcbiAgICBpZiAoIXJlZ2lvbnMgfHwgcmVnaW9ucy5sZW5ndGggPT09IDApIHJldHVybiBmYWxzZTtcblxuICAgIC8vIE1vc3QtcmVjZW50bHktYWRkZWQgcmVnaW9ucyBhcmUgb24gdG9wIOKAlCBjaGVjayB0aGVtIGZpcnN0LlxuICAgIGZvciAobGV0IGkgPSByZWdpb25zLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBjb25zdCB2ZXJ0cyA9IHRoaXMucmVnaW9uVmVydHMocmVnaW9uc1tpXSk7XG4gICAgICBpZiAoIXZlcnRzKSBjb250aW51ZTtcbiAgICAgIC8vIFRvbyBsYXJnZSB0byByYXN0ZXJpemUgYXQgdGhpcyB6b29tIOKGkiBkb24ndCBhZG9wdCBpdCAoZWRpdGluZyB3b3VsZCByZXNjYWxlL2NvcnJ1cHQgaXQpLlxuICAgICAgaWYgKCF0aGlzLmZpdHNGb3JFZGl0KHZlcnRzLCByeCwgcnkpKSBjb250aW51ZTtcblxuICAgICAgY29uc3Qgb3ggPSBjYWNoZWQub3JpZ2luWCA/PyAwO1xuICAgICAgY29uc3Qgb3kgPSBjYWNoZWQub3JpZ2luWSA/PyAwO1xuICAgICAgY29uc3QgeHMgPSB2ZXJ0cy54cG9pbnRzLm1hcCgoeCkgPT4gKHggLSBveCkgLyByeCk7XG4gICAgICBjb25zdCB5cyA9IHZlcnRzLnlwb2ludHMubWFwKCh5KSA9PiAoeSAtIG95KSAvIHJ5KTtcbiAgICAgIGNvbnN0IGhvbGVzID0gdGhpcy5ob2xlc1RvTWF0cml4KHZlcnRzLmhvbGVzLCBveCwgb3ksIHJ4LCByeSk7XG5cbiAgICAgIC8vIENsaWNraW5nIGluc2lkZSBhIGhvbGUgbXVzdCBOT1QgYWRvcHQgdGhlIGRvbnV0IChpdCdzIGVtcHR5IHRoZXJlKS5cbiAgICAgIGlmICghdGhpcy53YW5kU2VydmljZS5wb2ludEluUG9seWdvbldpdGhIb2xlcyhtYXRyaXhYLCBtYXRyaXhZLCB4cywgeXMsIGhvbGVzKSkgY29udGludWU7XG5cbiAgICAgIGNvbnN0IHJhc3RlciA9IHRoaXMud2FuZFNlcnZpY2UucmFzdGVyaXplUG9seWdvbih4cywgeXMsIGNhY2hlZC53aWR0aCwgY2FjaGVkLmhlaWdodCwgaG9sZXMpO1xuICAgICAgaWYgKCFyYXN0ZXIpIGNvbnRpbnVlO1xuXG4gICAgICB0aGlzLnN0cm9rZSA9IHJhc3RlcjtcbiAgICAgIHRoaXMuc3Ryb2tlUmVnaW9uSWQgPSByZWdpb25zW2ldLmlkID8/IG51bGw7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqXG4gICAqIEl0ZXJhdGUgZXZlcnkgcmVnaW9uOyBpZiBpdHMgcmFzdGVyaXplZCBtYXNrIG92ZXJsYXBzIHRoZSB3YW5kIHN0cm9rZSBtYXNrXG4gICAqIGJ5IGF0IGxlYXN0IG9uZSBwaXhlbCwgT1IgaXQgaW50byB0aGUgc3Ryb2tlIGFuZCByZW1vdmUgaXQgZnJvbSB0aGUgbGlzdC5cbiAgICogQ2FsbGVkIGV2ZXJ5IHRpY2sgc28gY2hhaW5lZCBtZXJnZXMgcmVzb2x2ZS4gSWYgdGhlIHdhbmQgaGFzIG5vIHJlZ2lvbiBpZFxuICAgKiB5ZXQsIHRoZSBtZXJnZWQgcmVnaW9uJ3MgaWQgaXMgYWRvcHRlZCBzbyB0aGUgbWVyZ2VkIHJlZ2lvbiByZXBsYWNlcyBpdC5cbiAgICovXG4gIHByaXZhdGUgbWVyZ2VPdmVybGFwcGluZ1NoYXBlcyhyZWdpb25zOiBSZWdpb25bXSwgcng6IG51bWJlciwgcnk6IG51bWJlciwgY2FjaGVkOiBDYWNoZWRJbWFnZURhdGEpIHtcbiAgICBpZiAoIXRoaXMuc3Ryb2tlKSByZXR1cm47XG4gICAgbGV0IGRpZE1lcmdlID0gdHJ1ZTtcbiAgICB3aGlsZSAoZGlkTWVyZ2UpIHtcbiAgICAgIGRpZE1lcmdlID0gZmFsc2U7XG4gICAgICBmb3IgKGxldCBpID0gcmVnaW9ucy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgICBjb25zdCByZWdpb24gPSByZWdpb25zW2ldO1xuICAgICAgICBpZiAocmVnaW9uLmlkICE9IG51bGwgJiYgcmVnaW9uLmlkID09PSB0aGlzLnN0cm9rZVJlZ2lvbklkKSBjb250aW51ZTtcblxuICAgICAgICBjb25zdCB2ZXJ0cyA9IHRoaXMucmVnaW9uVmVydHMocmVnaW9uKTtcbiAgICAgICAgaWYgKCF2ZXJ0cykgY29udGludWU7XG4gICAgICAgIC8vIFRvbyBsYXJnZSB0byByYXN0ZXJpemUgYXQgdGhpcyB6b29tIOKGkiBkb24ndCBtZXJnZSBpdCAod291bGQgcmVzY2FsZS9jb3JydXB0IGl0KS5cbiAgICAgICAgaWYgKCF0aGlzLmZpdHNGb3JFZGl0KHZlcnRzLCByeCwgcnkpKSBjb250aW51ZTtcblxuICAgICAgICBjb25zdCBveCA9IGNhY2hlZC5vcmlnaW5YID8/IDA7XG4gICAgICAgIGNvbnN0IG95ID0gY2FjaGVkLm9yaWdpblkgPz8gMDtcbiAgICAgICAgY29uc3QgeHMgPSB2ZXJ0cy54cG9pbnRzLm1hcCgoeCkgPT4gKHggLSBveCkgLyByeCk7XG4gICAgICAgIGNvbnN0IHlzID0gdmVydHMueXBvaW50cy5tYXAoKHkpID0+ICh5IC0gb3kpIC8gcnkpO1xuXG4gICAgICAgIC8vIFF1aWNrIGJib3ggcmVqZWN0IGJlZm9yZSByYXN0ZXJpemluZy5cbiAgICAgICAgbGV0IG1pblggPSBJbmZpbml0eSwgbWF4WCA9IC1JbmZpbml0eSwgbWluWSA9IEluZmluaXR5LCBtYXhZID0gLUluZmluaXR5O1xuICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IHhzLmxlbmd0aDsgaysrKSB7XG4gICAgICAgICAgaWYgKHhzW2tdIDwgbWluWCkgbWluWCA9IHhzW2tdO1xuICAgICAgICAgIGlmICh4c1trXSA+IG1heFgpIG1heFggPSB4c1trXTtcbiAgICAgICAgICBpZiAoeXNba10gPCBtaW5ZKSBtaW5ZID0geXNba107XG4gICAgICAgICAgaWYgKHlzW2tdID4gbWF4WSkgbWF4WSA9IHlzW2tdO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHd4MCA9IHRoaXMuc3Ryb2tlLmJ4LCB3eTAgPSB0aGlzLnN0cm9rZS5ieTtcbiAgICAgICAgY29uc3Qgd3gxID0gd3gwICsgdGhpcy5zdHJva2UuYncsIHd5MSA9IHd5MCArIHRoaXMuc3Ryb2tlLmJoO1xuICAgICAgICBpZiAobWF4WCA8IHd4MCB8fCBtaW5YID4gd3gxIHx8IG1heFkgPCB3eTAgfHwgbWluWSA+IHd5MSkgY29udGludWU7XG5cbiAgICAgICAgY29uc3QgaG9sZXMgPSB0aGlzLmhvbGVzVG9NYXRyaXgodmVydHMuaG9sZXMsIG94LCBveSwgcngsIHJ5KTtcbiAgICAgICAgY29uc3QgcmFzdGVyID0gdGhpcy53YW5kU2VydmljZS5yYXN0ZXJpemVQb2x5Z29uKHhzLCB5cywgY2FjaGVkLndpZHRoLCBjYWNoZWQuaGVpZ2h0LCBob2xlcyk7XG4gICAgICAgIGlmICghcmFzdGVyKSBjb250aW51ZTtcblxuICAgICAgICBpZiAoIW1hc2tzT3ZlcmxhcCh0aGlzLnN0cm9rZSwgcmFzdGVyKSkgY29udGludWU7XG5cbiAgICAgICAgdGhpcy5zdHJva2UgPSB1bmlvbk1hc2tzKHRoaXMuc3Ryb2tlLCByYXN0ZXIpO1xuXG4gICAgICAgIGlmICh0aGlzLnN0cm9rZVJlZ2lvbklkID09IG51bGwpIHtcbiAgICAgICAgICB0aGlzLnN0cm9rZVJlZ2lvbklkID0gcmVnaW9uLmlkID8/IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgcmVnaW9ucy5zcGxpY2UoaSwgMSk7XG4gICAgICAgIGRpZE1lcmdlID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENvbW1pdCB0aGUgaW4tcHJvZ3Jlc3MgcG9seWdvbiBhcyBhIHJlZ2lvbiDigJQgYSBuZXcgcmVnaW9uIG9uIHRoZSBmaXJzdCB0aWNrXG4gICAqIG9mIGEgc3Ryb2tlLCBvciBhbiBpbi1wbGFjZSByZXBsYWNlbWVudCBvZiB0aGUgYWN0aXZlIHJlZ2lvbiBvbiBsYXRlciB0aWNrc1xuICAgKiDigJQgdGhlbiBhc2sgdGhlIGhvc3QgdG8gcmVuZGVyLiBUaGUgc3RvcmUgbWludHMgYW4gaWQgb24gdGhlIGZpcnN0IGNvbW1pdCxcbiAgICogd2hpY2ggd2UgYWRvcHQgc28gc3Vic2VxdWVudCB0aWNrcyByZXBsYWNlIHRoZSBzYW1lIHJlZ2lvbi5cbiAgICovXG4gIHByaXZhdGUgY29tbWl0U3Ryb2tlKHJlZ2lvbnM6IFJlZ2lvbltdLCB4UGxvdDogbnVtYmVyW10sIHlQbG90OiBudW1iZXJbXSkge1xuICAgIGlmICh4UGxvdC5sZW5ndGggPCAzKSByZXR1cm47XG5cbiAgICBjb25zdCBleGlzdGluZyA9IHRoaXMuc3Ryb2tlUmVnaW9uSWQgIT0gbnVsbFxuICAgICAgPyByZWdpb25zLmZpbmQoKHIpID0+IHIuaWQgPT09IHRoaXMuc3Ryb2tlUmVnaW9uSWQpIDogbnVsbDtcblxuICAgIGNvbnN0IHBvbHkgPSBuZXcgUG9seWdvbigpO1xuICAgIHBvbHkubnBvaW50cyA9IHhQbG90Lmxlbmd0aDtcbiAgICBwb2x5Lnhwb2ludHMgPSB4UGxvdDtcbiAgICBwb2x5Lnlwb2ludHMgPSB5UGxvdDtcbiAgICBwb2x5LmNvb3JkaW5hdGVzID0geFBsb3QubWFwKCh4LCBpKSA9PiBbeCwgeVBsb3RbaV1dKTtcbiAgICBwb2x5LmNsb3NlZCA9IHRydWU7XG5cbiAgICBjb25zdCByZWdpb24gPSBuZXcgUmVnaW9uKCk7XG4gICAgcmVnaW9uLmJvdW5kcyA9IHBvbHk7XG4gICAgcmVnaW9uLmNvbG9yID0gdGhpcy5ob3N0LmdldFNoYXBlQ29sb3IoKTtcbiAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgIC8vIFByZXNlcnZlIGlkZW50aXR5ICsgY2xhc3MgbGFiZWwgYWNyb3NzIHRoZSBzdHJva2UncyBkcmFnIHRpY2tzLlxuICAgICAgcmVnaW9uLmlkID0gZXhpc3RpbmcuaWQ7XG4gICAgICByZWdpb24ubmFtZSA9IGV4aXN0aW5nLm5hbWU7XG4gICAgfVxuICAgIC8vIERlZmF1bHQgY2xhc3MvYW5ub3RhdGlvbiBuYW1lLCBtYXRjaGluZyB0aGUgb3ZlcmxheS1kcmF3biByZWdpb25zIGFuZCB0aGVcbiAgICAvLyBSZWdpb24gRWRpdG9yJ3MgXCJBZGRcIiBhY3Rpb25zIHNvIGEgd2FuZCByZWdpb24gaXNuJ3QgbGVmdCB1bmxhYmVsZWQuXG4gICAgcmVnaW9uLmxhYmVsID0gZXhpc3Rpbmc/LmxhYmVsID8/ICdSZWdpb24nO1xuXG4gICAgaWYgKHRoaXMuc3Ryb2tlUmVnaW9uSWQgPT0gbnVsbCkge1xuICAgICAgcmVnaW9ucy5wdXNoKHJlZ2lvbik7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGlkeCA9IHJlZ2lvbnMuZmluZEluZGV4KChyKSA9PiByLmlkID09PSB0aGlzLnN0cm9rZVJlZ2lvbklkKTtcbiAgICAgIGlmIChpZHggPj0gMCkgcmVnaW9uc1tpZHhdID0gcmVnaW9uO1xuICAgICAgZWxzZSByZWdpb25zLnB1c2gocmVnaW9uKTtcbiAgICB9XG5cbiAgICB0aGlzLmhvc3Quc2V0UmVnaW9ucyhyZWdpb25zKTtcbiAgICAvLyBUaGUgc3RvcmUgYXNzaWducyBhbiBpZCBvbiB0aGUgZmlyc3QgY29tbWl0IOKAlCBhZG9wdCBpdC5cbiAgICB0aGlzLnN0cm9rZVJlZ2lvbklkID0gcmVnaW9uLmlkID8/IHRoaXMuc3Ryb2tlUmVnaW9uSWQ7XG4gIH1cbn1cbiJdfQ==
|
|
204
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FuZC10b29sLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL3Rvb2xiYXIvd2FuZC93YW5kLXRvb2wuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNsRSxPQUFPLEVBQUUsV0FBVyxFQUFxQixNQUFNLDBCQUEwQixDQUFDO0FBQzFFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBRTdELE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQVM3Qzs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxPQUFPLFFBQVE7SUFzQm5CLDRFQUE0RTtJQUM1RSxZQUNtQixXQUF3QixFQUN6QyxhQUF3QztRQUR2QixnQkFBVyxHQUFYLFdBQVcsQ0FBYTtRQXZCbEMsT0FBRSxHQUFHLE1BQU0sQ0FBQztRQUtKLFlBQU8sR0FBRyxJQUFJLGlCQUFpQixFQUFFLENBQUM7UUFDbkQ7Ozs7Ozs7V0FPRztRQUNjLFdBQU0sR0FBRyxJQUFJLGdCQUFnQixFQUFFLENBQUM7UUFDekMsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUNqQixZQUFPLEdBQWdCLEVBQUUsQ0FBQztRQVVoQyxJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksV0FBVyxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFFRCx1RUFBdUU7SUFFdkUsOEVBQThFO0lBQzlFLFFBQVEsQ0FBQyxJQUFvQixFQUFFLFVBQXVCLEVBQUU7UUFDdEQsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7UUFDdkIsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ3ZCLENBQUM7SUFFRCw2REFBNkQ7SUFDN0QsVUFBVTtRQUNSLElBQUksQ0FBQyxPQUFPLENBQUMs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QUUsQ0FBQztZQUNoQyxJQUFJLEVBQUUsR0FBRyxDQUFDLElBQUksRUFBRSxJQUFJLE1BQU0sQ0FBQyxFQUFFO2dCQUFFLFNBQVM7WUFDeEMsTUFBTSxNQUFNLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztZQUN0QixNQUFNLE1BQU0sR0FBRyxFQUFFLEdBQUcsTUFBTSxDQUFDLEVBQUUsQ0FBQztZQUM5QixLQUFLLElBQUksRUFBRSxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUM7Z0JBQzlCLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUM7b0JBQUUsU0FBUztnQkFDdkMsTUFBTSxFQUFFLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxNQUFNLENBQUMsRUFBRSxDQUFDO2dCQUNoQyxJQUFJLEVBQUUsR0FBRyxDQUFDLElBQUksRUFBRSxJQUFJLE1BQU0sQ0FBQyxFQUFFO29CQUFFLFNBQVM7Z0JBQ3hDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDM0MsQ0FBQztRQUNILENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFdhbmRJbWFnZSwgV2FuZE9wdGlvbnMsIFdhbmRQYXRjaE1hc2ssIFdhbmRTZXJ2aWNlIH0gZnJvbSAnLi93YW5kLnNlcnZpY2UnO1xuaW1wb3J0IHsgQkJveE1hc2sgfSBmcm9tICcuLi8uLi9nZW9tZXRyeS9yYXN0ZXInO1xuaW1wb3J0IHsgTWFza1N0cm9rZUVkaXRvciB9IGZyb20gJy4uL3Rvb2wta2l0L21hc2stc3Ryb2tlLWVkaXRvcic7XG5pbXBvcnQgeyBVbmRvR2VzdHVyZSwgVW5kb0dlc3R1cmVUYXJnZXQgfSBmcm9tICcuLi90b29sLWtpdC91bmRvLWdlc3R1cmUnO1xuaW1wb3J0IHsgVG9vbE92ZXJsYXlDYW52YXMgfSBmcm9tICcuLi90b29sLWtpdC90b29sLW92ZXJsYXknO1xuaW1wb3J0IHsgQ2FjaGVkSW1hZ2VEYXRhLCBDYW52YXNUb29sSG9zdCwgSUNhbnZhc1Rvb2wgfSBmcm9tICcuLi90b29sLWtpdC9jYW52YXMtdG9vbCc7XG5pbXBvcnQgeyBSZWdpb24gfSBmcm9tICcuLi8uLi9tb2RlbHMvcmVnaW9uJztcblxuLy8gVGhlIHJlYWRiYWNrIHR5cGUgbGl2ZXMgd2l0aCB0aGUgdG9vbCBjb250cmFjdCBub3c7IHJlLWV4cG9ydGVkIGZvciB0aGVcbi8vIG1vZHVsZXMgdGhhdCBpbXBvcnQgaXQgZnJvbSBoZXJlLlxuZXhwb3J0IHR5cGUgeyBDYWNoZWRJbWFnZURhdGEgfSBmcm9tICcuLi90b29sLWtpdC9jYW52YXMtdG9vbCc7XG5cbi8qKiBAZGVwcmVjYXRlZCBPbmUgaG9zdCBzZXJ2ZXMgZXZlcnkgY2FudmFzIHRvb2w6IHVzZSB7QGxpbmsgQ2FudmFzVG9vbEhvc3R9LiAqL1xuZXhwb3J0IHR5cGUgV2FuZFRvb2xIb3N0ID0gQ2FudmFzVG9vbEhvc3Q7XG5cbi8qKlxuICogVGhlIHdhbmQgZHJhd2luZyB0b29sLiBPd25zIGl0cyBwb2ludGVyIG92ZXJsYXkgYW5kIHN0cm9rZSBhY2N1bXVsYXRvclxuICogKHNoYXJlZCB3aXRoIHRoZSBicnVzaCwgc2VlIHtAbGluayBNYXNrU3Ryb2tlRWRpdG9yfSkuIFJlYWRzL3dyaXRlcyByZWdpb25zXG4gKiB2aWEgaXRzIHtAbGluayBDYW52YXNUb29sSG9zdH0gc28gaXQgc3RheXMgZGVjb3VwbGVkIGZyb20gdGhlIGJhY2tlbmRzLlxuICpcbiAqIEEgcGxhaW4gY2xhc3M6IGVhY2ggYmFja2VuZCdzIGBDYW52YXNUb29sTWFuYWdlcmAgb3ducyBvbmUgaW5zdGFuY2UgYW5kIGFybXNcbiAqIGl0IHdpdGggYGFjdGl2YXRlKGhvc3QsIG9wdGlvbnMpYCAvIGBkZWFjdGl2YXRlKClgLlxuICovXG5leHBvcnQgY2xhc3MgV2FuZFRvb2wgaW1wbGVtZW50cyBJQ2FudmFzVG9vbDxXYW5kT3B0aW9ucz4ge1xuICByZWFkb25seSBpZCA9ICd3YW5kJztcblxuICAvLyDilIDilIAgVG9vbCBzdGF0ZSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICBwcml2YXRlIGhvc3QhOiBDYW52YXNUb29sSG9zdDtcbiAgcHJpdmF0ZSByZWFkb25seSBvdmVybGF5ID0gbmV3IFRvb2xPdmVybGF5Q2FudmFzKCk7XG4gIC8qKlxuICAgKiBBY2N1bXVsYXRlZCB3YW5kIHJlZ2lvbi4gRXZlcnkgcGVyLXRpY2sgcGF0Y2ggbWFzayBpcyBPUidkIGludG8gdGhlIHN0cm9rZVxuICAgKiBvdmVyIGEgYmJveCB0aGF0IGdyb3dzIHdpdGggdGhlIHN0cm9rZSwgc28gdGhlIHJlZ2lvbiBrZWVwcyBleHBhbmRpbmcgYXNcbiAgICogdGhlIHVzZXIgZHJhZ3MuIFRoZSBhY2N1bXVsYXRvciBwZXJzaXN0cyBhY3Jvc3MgbW91c2V1cC9tb3VzZWRvd24gc28gdGhhdFxuICAgKiBzdWJzZXF1ZW50IHN0cm9rZXMgZXh0ZW5kIHRoZSAqc2FtZSogcmVnaW9uIOKAlCBtYXRjaGluZyBRdVBhdGgncyBicnVzaFxuICAgKiBiZWhhdmlvdXIgd2hlcmUgdGhlIGFjdGl2ZSBhbm5vdGF0aW9uIHN0YXlzIGVkaXRhYmxlIHVudGlsIHRoZSB1c2VyXG4gICAqIHN3aXRjaGVzIHRvb2wuXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGVkaXRvciA9IG5ldyBNYXNrU3Ryb2tlRWRpdG9yKCk7XG4gIHByaXZhdGUgZHJhZ2dpbmcgPSBmYWxzZTtcbiAgcHJpdmF0ZSBvcHRpb25zOiBXYW5kT3B0aW9ucyA9IHt9O1xuXG4gIC8qKiBNYWtlcyBlYWNoIGRyYWcgb25lIHVuZG8gc3RlcCwgaG93ZXZlciBsb25nIHRoZSB1c2VyIHBhdXNlcyAoUlQtMTIpLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGdlc3R1cmU6IFVuZG9HZXN0dXJlO1xuXG4gIC8qKiBAcGFyYW0gZ2VzdHVyZVRhcmdldCB0aGUgcmVnaW9uIHN0b3JlLCBzbyBlYWNoIGRyYWcgaXMgb25lIHVuZG8gc3RlcC4gKi9cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSB3YW5kU2VydmljZTogV2FuZFNlcnZpY2UsXG4gICAgZ2VzdHVyZVRhcmdldD86IFVuZG9HZXN0dXJlVGFyZ2V0IHwgbnVsbCxcbiAgKSB7XG4gICAgdGhpcy5nZXN0dXJlID0gbmV3IFVuZG9HZXN0dXJlKGdlc3R1cmVUYXJnZXQpO1xuICB9XG5cbiAgLy8g4pSA4pSAIElDYW52YXNUb29sIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIC8qKiBBcm0gdGhlIHdhbmQgb24gYGhvc3RgIHdpdGggYG9wdGlvbnNgIChyZXBsYWNpbmcgdGhlIHByZXZpb3VzIG9wdGlvbnMpLiAqL1xuICBhY3RpdmF0ZShob3N0OiBDYW52YXNUb29sSG9zdCwgb3B0aW9uczogV2FuZE9wdGlvbnMgPSB7fSkge1xuICAgIHRoaXMuaG9zdCA9IGhvc3Q7XG4gICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcbiAgICB0aGlzLmNyZWF0ZU92ZXJsYXkoKTtcbiAgfVxuXG4gIC8qKiBEaXNhcm06IHJlbW92ZSB0aGUgb3ZlcmxheSBhbmQgZHJvcCB0aGUgYWN0aXZlIHJlZ2lvbi4gKi9cbiAgZGVhY3RpdmF0ZSgpIHtcbiAgICB0aGlzLm92ZXJsYXkuZGV0YWNoKCk7XG4gICAgdGhpcy5yZXNldFN0cm9rZSgpO1xuICB9XG5cbiAgLyoqIE1lcmdlIG5ldyBvcHRpb25zIChlLmcuIGxpdmUgc2Vuc2l0aXZpdHkgc2xpZGVyIHVwZGF0ZXMpLiAqL1xuICBzZXRPcHRpb25zKG9wdGlvbnM6IFdhbmRPcHRpb25zKSB7XG4gICAgdGhpcy5vcHRpb25zID0geyAuLi50aGlzLm9wdGlvbnMsIC4uLm9wdGlvbnMgfTtcbiAgfVxuXG4gIC8qKiBEcm9wIHRoZSBhY3RpdmUgd2FuZCByZWdpb24gc28gdGhlIG5leHQgY2xpY2sgc3RhcnRzIGEgbmV3IG9uZS4gKi9cbiAgcmVzZXQoKSB7XG4gICAgdGhpcy5yZXNldFN0cm9rZSgpO1xuICB9XG5cbiAgLy8g4pSA4pSAIE92ZXJsYXkgbGlmZWN5Y2xlIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHByaXZhdGUgY3JlYXRlT3ZlcmxheSgpIHtcbiAgICBjb25zdCBjb250YWluZXIgPSB0aGlzLmhvc3QuZ2V0T3ZlcmxheUNvbnRhaW5lcigpO1xuICAgIGlmICghY29udGFpbmVyKSByZXR1cm47XG4gICAgdGhpcy5vdmVybGF5LmF0dGFjaChjb250YWluZXIsIHtcbiAgICAgIGRvd246IChlKSA9PiB0aGlzLm9uUG9pbnRlckRvd24oZSksXG4gICAgICBtb3ZlOiAoZSkgPT4gdGhpcy5vblBvaW50ZXJNb3ZlKGUpLFxuICAgICAgdXA6ICgpID0+IHRoaXMub25Qb2ludGVyVXAoKSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgb25Qb2ludGVyRG93bihlOiBQb2ludGVyRXZlbnQpIHtcbiAgICB0aGlzLmRyYWdnaW5nID0gdHJ1ZTtcbiAgICB0aGlzLmdlc3R1cmUuYmVnaW4oKTtcbiAgICB0aGlzLmFwcGx5QXRDbGllbnQoZSwgdHJ1ZSk7XG4gIH1cblxuICBwcml2YXRlIG9uUG9pbnRlck1vdmUoZTogUG9pbnRlckV2ZW50KSB7XG4gICAgaWYgKCF0aGlzLmRyYWdnaW5nKSByZXR1cm47XG4gICAgaWYgKChlLmJ1dHRvbnMgJiAxKSA9PT0gMCkge1xuICAgICAgdGhpcy5kcmFnZ2luZyA9IGZhbHNlO1xuICAgICAgdGhpcy5nZXN0dXJlLmVuZCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmFwcGx5QXRDbGllbnQoZSwgZmFsc2UpO1xuICB9XG5cbiAgcHJpdmF0ZSBvblBvaW50ZXJVcCgpIHtcbiAgICAvLyBTdG9wIGFjY3VtdWxhdGluZyBmcm9tIHRoaXMgZHJhZywgYnV0IGtlZXAgdGhlIHJlZ2lvbiBhbGl2ZSBzbyB0aGVcbiAgICAvLyBuZXh0IG1vdXNlZG93biBleHRlbmRzIGl0IGluc3RlYWQgb2Ygc3RhcnRpbmcgZnJlc2guXG4gICAgdGhpcy5kcmFnZ2luZyA9IGZhbHNlO1xuICAgIHRoaXMuZ2VzdHVyZS5lbmQoKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVzZXRTdHJva2UoKSB7XG4gICAgdGhpcy5lZGl0b3IucmVzZXQoKTtcbiAgICB0aGlzLmRyYWdnaW5nID0gZmFsc2U7XG4gICAgdGhpcy5nZXN0dXJlLmVuZCgpO1xuICB9XG5cbiAgLy8g4pSA4pSAIFBlci10aWNrIHN0cm9rZSBsb2dpYyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAvKipcbiAgICogU2FtcGxlIHRoZSBjYWNoZWQgaW1hZ2UgYXQgdGhlIGNsaWNrIGxvY2F0aW9uLCBPUiAob3IgQU5ELU5PVCkgdGhlXG4gICAqIHdhbmQncyBwZXItdGljayBwYXRjaCBtYXNrIGludG8gdGhlIGFjdGl2ZSByZWdpb24ncyBiYm94LXJlbGF0aXZlIG1hc2ssXG4gICAqIHJlLXRyYWNlIHRoZSBib3VuZGFyeSwgYW5kIHVwZGF0ZSB0aGUgaW4tcHJvZ3Jlc3Mgc2hhcGUg4oCUIG1hdGNoaW5nXG4gICAqIFF1UGF0aCdzIGFkZGl0aXZlIGJydXNoL3dhbmQgYmVoYXZpb3VyLiBTaGlmdCA9IGVyYXNlLiBDbWQvQ3RybCA9XG4gICAqIGV4YWN0LW1hdGNoIGZsb29kIGZpbGwuXG4gICAqL1xuICBwcml2YXRlIGFwcGx5QXRDbGllbnQoZTogUG9pbnRlckV2ZW50LCBpc1N0YXJ0ID0gZmFsc2UpIHtcbiAgICBpZiAoIXRoaXMub3ZlcmxheS5hdHRhY2hlZCkgcmV0dXJuO1xuICAgIC8vIFRoZSBjdXJyZW50IHJlZ2lvbnMgKG5ldXRyYWwgbW9kZWwpIGFyZSBtdXRhdGVkIGxvY2FsbHkgYWNyb3NzIHRoaXMgdGljayBhbmRcbiAgICAvLyBjb21taXR0ZWQgb25jZSB2aWEgaG9zdC5zZXRSZWdpb25zKCkuXG4gICAgY29uc3QgZWRpdG9yID0gdGhpcy5lZGl0b3I7XG4gICAgY29uc3QgdGljayA9IGVkaXRvci5iZWdpblRpY2sodGhpcy5ob3N0LCBlKTtcbiAgICBpZiAoIXRpY2spIHJldHVybjtcbiAgICBjb25zdCB7IGNhY2hlZCwgcmVnaW9ucywgZnJhbWUsIG14OiBtYXRyaXhYLCBteTogbWF0cml4WSB9ID0gdGljaztcblxuICAgIC8vIFNoaWZ0ID0gZXJhc2UgKHN1YnRyYWN0IHBpeGVscyBmcm9tIGFuIGV4aXN0aW5nIHJlZ2lvbikuXG4gICAgLy8gQ21kL0N0cmwgYWxvbmUgPSBzaW1wbGUgZmxvb2QgZmlsbCAobm8gc21vb3RoaW5nL3RocmVzaG9sZCkuXG4gICAgY29uc3QgZXJhc2UgPSBlLnNoaWZ0S2V5O1xuICAgIGNvbnN0IG9wdHM6IFdhbmRPcHRpb25zID0ge1xuICAgICAgLi4udGhpcy5vcHRpb25zLFxuICAgICAgc2ltcGxlTW9kZTogdGhpcy5vcHRpb25zLnNpbXBsZU1vZGUgfHwgKChlLm1ldGFLZXkgfHwgZS5jdHJsS2V5KSAmJiAhZXJhc2UpLFxuICAgIH07XG5cbiAgICAvLyBBIG5ldyBkcmFnIHRoYXQgc3RhcnRzIG91dHNpZGUgdGhlIGN1cnJlbnQgYWNjdW11bGF0b3Igc3RhcnRzIGEgbmV3IHJlZ2lvblxuICAgIC8vIChvciBhZG9wdHMgdGhlIG9uZSB1bmRlciB0aGUgY3Vyc29yKSBpbnN0ZWFkIG9mIGdyb3dpbmcgdGhlIG9sZCBzdHJva2Unc1xuICAgIC8vIGJib3ggdG8gc3BhbiBib3RoIGFyZWFzLlxuICAgIGlmIChpc1N0YXJ0ICYmICFlcmFzZSAmJiBlZGl0b3Iuc3Ryb2tlICYmICFlZGl0b3IuY29udGFpbnMobWF0cml4WCwgbWF0cml4WSkpIHtcbiAgICAgIGVkaXRvci5yZXNldCgpO1xuICAgIH1cblxuICAgIGNvbnN0IHBhdGNoID0gdGhpcy53YW5kU2VydmljZS5jb21wdXRlUGF0Y2hNYXNrKHRoaXMud2FuZEltYWdlKGNhY2hlZCksIG1hdHJpeFgsIG1hdHJpeFksIG9wdHMpO1xuICAgIGlmICghcGF0Y2gpIHJldHVybjtcblxuICAgIC8vIFdpdGggbm8gYWN0aXZlIHJlZ2lvbiwgYSBjbGljayBvbiBhbiBleGlzdGluZyByZWdpb24gYWRvcHRzIGl0IHNvIHRoaXNcbiAgICAvLyBzdHJva2UgZXh0ZW5kcyAob3IgZXJhc2VzIGZyb20pIGl0LlxuICAgIGlmICghZWRpdG9yLnN0cm9rZSkgZWRpdG9yLmFkb3B0QXQocmVnaW9ucywgbWF0cml4WCwgbWF0cml4WSwgZnJhbWUsIGNhY2hlZCk7XG5cbiAgICAvLyBFcmFzaW5nIHJlcXVpcmVzIGFuIGV4aXN0aW5nIHJlZ2lvbi4gU2hpZnQtY2xpY2tpbmcgZW1wdHkgc3BhY2UgaXMgYVxuICAgIC8vIG5vLW9wIOKAlCB3ZSBkb24ndCBjcmVhdGUgYSByZWdpb24gb25seSB0byBpbW1lZGlhdGVseSBkZWxldGUgZnJvbSBpdC5cbiAgICBpZiAoZXJhc2UgJiYgIWVkaXRvci5zdHJva2UpIHJldHVybjtcblxuICAgIGlmICghdGhpcy5zdGFtcFBhdGNoKHBhdGNoLCBtYXRyaXhYLCBtYXRyaXhZLCBlcmFzZSwgY2FjaGVkKSkgcmV0dXJuO1xuXG4gICAgLy8gR3Jvd2luZyBpbnRvIG90aGVyIHJlZ2lvbnMgZm9sZHMgdGhlbSBpbiAoUXVQYXRoJ3MgbWVyZ2Utb24tdG91Y2gpLlxuICAgIGlmICghZXJhc2UpIGVkaXRvci5tZXJnZVRvdWNoaW5nKHJlZ2lvbnMsIGZyYW1lLCBjYWNoZWQpO1xuXG4gICAgZWRpdG9yLmNvbW1pdChyZWdpb25zLCBmcmFtZSwgdGhpcy5ob3N0LCB7XG4gICAgICBlcmFzZSxcbiAgICAgIGRlZmF1bHRMYWJlbDogJ1JlZ2lvbicsXG4gICAgICBuZXdSZWdpb246IChib3VuZHMpID0+IHtcbiAgICAgICAgY29uc3QgcmVnaW9uID0gbmV3IFJlZ2lvbigpO1xuICAgICAgICByZWdpb24uYm91bmRzID0gYm91bmRzO1xuICAgICAgICByZWdpb24uY29sb3IgPSB0aGlzLmhvc3QuZ2V0U2hhcGVDb2xvcigpO1xuICAgICAgICAvLyBEZWZhdWx0IGNsYXNzL2Fubm90YXRpb24gbmFtZSwgbWF0Y2hpbmcgdGhlIG92ZXJsYXktZHJhd24gcmVnaW9ucyBhbmQgdGhlXG4gICAgICAgIC8vIFJlZ2lvbiBFZGl0b3IncyBcIkFkZFwiIGFjdGlvbnMgc28gYSB3YW5kIHJlZ2lvbiBpc24ndCBsZWZ0IHVubGFiZWxlZC5cbiAgICAgICAgcmVnaW9uLmxhYmVsID0gJ1JlZ2lvbic7XG4gICAgICAgIHJldHVybiByZWdpb247XG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgLyoqIFRoZSB2aXNpYmxlIGZyYW1lIG9mIHRoZSByZWFkYmFjaywgYXMgdGhlIHJlZ2lvbiBncm93IHJlYWRzIGl0LiAqL1xuICBwcml2YXRlIHdhbmRJbWFnZShjYWNoZWQ6IENhY2hlZEltYWdlRGF0YSk6IFdhbmRJbWFnZSB7XG4gICAgY29uc3QgZnJhbWVJZHggPSB0aGlzLmhvc3QuZ2V0QWN0aXZlRnJhbWVJbmRleCgpO1xuICAgIHJldHVybiB7XG4gICAgICBkYXRhOiBjYWNoZWQuZnJhbWVzW2ZyYW1lSWR4XSA/PyBjYWNoZWQuZnJhbWVzWzBdLFxuICAgICAgd2lkdGg6IGNhY2hlZC53aWR0aCxcbiAgICAgIGhlaWdodDogY2FjaGVkLmhlaWdodCxcbiAgICAgIGlzR3JheXNjYWxlOiBjYWNoZWQuaXNHcmF5c2NhbGUsXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBPUiAoYWRkKSBvciBBTkQtTk9UIChlcmFzZSkgdGhlIHBhdGNoIG1hc2ssIGNlbnRyZWQgb24gbWF0cml4IHBvaW50XG4gICAqIChjeCwgY3kpLCBpbnRvIHRoZSBzdHJva2UsIGdyb3dpbmcgdGhlIHN0cm9rZSB0byBjb3ZlciBpdCBmaXJzdCB3aGVuXG4gICAqIGFkZGluZy4gRmFsc2Ugd2hlbiBhIGZyZXNoIHN0cm9rZSBoYXMgbm90aGluZyBpbnNpZGUgdGhlIHJlYWRiYWNrLlxuICAgKi9cbiAgcHJpdmF0ZSBzdGFtcFBhdGNoKFxuICAgIHBhdGNoOiBXYW5kUGF0Y2hNYXNrLFxuICAgIGN4OiBudW1iZXIsXG4gICAgY3k6IG51bWJlcixcbiAgICBlcmFzZTogYm9vbGVhbixcbiAgICBjYWNoZWQ6IENhY2hlZEltYWdlRGF0YSxcbiAgKTogYm9vbGVhbiB7XG4gICAgY29uc3QgZWRpdG9yID0gdGhpcy5lZGl0b3I7XG4gICAgY29uc3QgVyA9IHBhdGNoLnNpemU7XG4gICAgY29uc3QgaGFsZiA9IChXIC0gMSkgLyAyO1xuICAgIC8vIFRoZSBwYXRjaCBpcyBjZW50cmVkIG9uIHRoZSBjbGlja2VkIHBpeGVsIChgY29tcHV0ZVBhdGNoTWFza2AgZmxvb3JzIHRoZSBzYW1lIHdheSkuXG4gICAgY29uc3QgcHgwID0gTWF0aC5mbG9vcihjeCkgLSBoYWxmO1xuICAgIGNvbnN0IHB5MCA9IE1hdGguZmxvb3IoY3kpIC0gaGFsZjtcblxuICAgIGlmICghZWRpdG9yLnN0cm9rZSkge1xuICAgICAgLy8gQSBmcmVzaCBzdHJva2Ugc3RhcnRzIGF0IHRoZSBwYXRjaCwgY2xpcHBlZCB0byB0aGUgcmVhZGJhY2suXG4gICAgICBjb25zdCBvayA9IGVkaXRvci5lbnN1cmVDb3ZlcnMoXG4gICAgICAgIE1hdGgubWF4KDAsIHB4MCksXG4gICAgICAgIE1hdGgubWF4KDAsIHB5MCksXG4gICAgICAgIE1hdGgubWluKGNhY2hlZC53aWR0aCwgcHgwICsgVyksXG4gICAgICAgIE1hdGgubWluKGNhY2hlZC5oZWlnaHQsIHB5MCArIFcpLFxuICAgICAgKTtcbiAgICAgIGlmICghb2spIHJldHVybiBmYWxzZTtcbiAgICB9IGVsc2UgaWYgKCFlcmFzZSkge1xuICAgICAgLy8gRG9uJ3QgY2xhbXAgYSBncm93aW5nIHN0cm9rZSB0byB0aGUgdmlld3BvcnQ6IGFuIGFkb3B0ZWQgcmVnaW9uIG1heSBleHRlbmRcbiAgICAgIC8vIG9mZi1zY3JlZW4sIGFuZCBjbGFtcGluZyB3b3VsZCBkaXNjYXJkIHRoYXQgcGFydCAoaml0LXVpIzEwMikuIEVyYXNpbmcgbmV2ZXJcbiAgICAgIC8vIGdyb3dzIHRoZSBzdHJva2UuXG4gICAgICBlZGl0b3IuZW5zdXJlQ292ZXJzKHB4MCwgcHkwLCBweDAgKyBXLCBweTAgKyBXKTtcbiAgICB9XG5cbiAgICAvLyBBcHBseSB0aGUgcGF0Y2g6IE9SIChhZGQpIG9yIEFORC1OT1QgKGVyYXNlKS5cbiAgICBjb25zdCBzdHJva2UgPSBlZGl0b3Iuc3Ryb2tlIGFzIEJCb3hNYXNrO1xuICAgIGZvciAobGV0IHB5ID0gMDsgcHkgPCBXOyBweSsrKSB7XG4gICAgICBjb25zdCBteSA9IHB5MCArIHB5IC0gc3Ryb2tlLmJ5O1xuICAgICAgaWYgKG15IDwgMCB8fCBteSA+PSBzdHJva2UuYmgpIGNvbnRpbnVlO1xuICAgICAgY29uc3Qgc3JjUm93ID0gcHkgKiBXO1xuICAgICAgY29uc3QgZHN0Um93ID0gbXkgKiBzdHJva2UuYnc7XG4gICAgICBmb3IgKGxldCBweCA9IDA7IHB4IDwgVzsgcHgrKykge1xuICAgICAgICBpZiAoIXBhdGNoLm1hc2tbc3JjUm93ICsgcHhdKSBjb250aW51ZTtcbiAgICAgICAgY29uc3QgbXggPSBweDAgKyBweCAtIHN0cm9rZS5ieDtcbiAgICAgICAgaWYgKG14IDwgMCB8fCBteCA+PSBzdHJva2UuYncpIGNvbnRpbnVlO1xuICAgICAgICBzdHJva2UubWFza1tkc3RSb3cgKyBteF0gPSBlcmFzZSA/IDAgOiAxO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxufVxuIl19
|