@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,6 +1,9 @@
|
|
|
1
1
|
import { Subscription } from 'rxjs';
|
|
2
2
|
import { Region, Rectangle, Polygon } from '../../models/region';
|
|
3
|
-
import {
|
|
3
|
+
import { hitHandle, nearestEdge, nearestVertex, regionContains, regionsInRect, } from '../../region-overlay/region-geometry';
|
|
4
|
+
import { NapariRegionSvgRenderer } from './region-overlay/region-svg-renderer';
|
|
5
|
+
import { OverlayProjection } from './region-overlay/overlay-projection';
|
|
6
|
+
import { applyRegionEdit } from './region-overlay/region-edit';
|
|
4
7
|
const SVG_NS = 'http://www.w3.org/2000/svg';
|
|
5
8
|
/**
|
|
6
9
|
* Min drag before a freehand path records another point, in SCREEN pixels.
|
|
@@ -23,24 +26,36 @@ const FREEHAND_STEP_PX = 2;
|
|
|
23
26
|
* impossible to create there.
|
|
24
27
|
*/
|
|
25
28
|
const MIN_RECT_DRAG_PX = 2;
|
|
29
|
+
/**
|
|
30
|
+
* A rubber band smaller than this on both sides, in SCREEN pixels, is a click on empty space
|
|
31
|
+
* (it clears the selection). Screen for the same reason as {@link MIN_RECT_DRAG_PX}: 3 world
|
|
32
|
+
* units is over half of seqFISH's sample.
|
|
33
|
+
*/
|
|
34
|
+
const MIN_MARQUEE_PX = 3;
|
|
26
35
|
/** Click-distance (screen px) within which a polygon click snaps closed onto the first vertex. */
|
|
27
36
|
const CLOSE_SNAP_PX = 10;
|
|
28
37
|
/** Screen-px hit radius for grabbing a vertex / rectangle corner handle. */
|
|
29
38
|
const HANDLE_HIT_PX = 9;
|
|
30
|
-
/**
|
|
31
|
-
const
|
|
39
|
+
/** Screen-px distance from an open polyline within which a click selects it (as OSD). */
|
|
40
|
+
const OPEN_PATH_HIT_PX = 6;
|
|
32
41
|
/**
|
|
33
42
|
* SVG region overlay for the napari-js WebGPU image view (jit-ui#102), mirroring the OSD backend's
|
|
34
|
-
* {@link OsdRegionOverlay} but driven by napari's `canvasToWorld`/`
|
|
43
|
+
* {@link OsdRegionOverlay} but driven by napari's `canvasToWorld`/`canvasTransform` transforms
|
|
44
|
+
* (see {@link OverlayViewer} for their coordinate spaces).
|
|
35
45
|
* Vector shapes are drawn in an absolutely-positioned `<svg>` over the canvas (no need to push
|
|
36
|
-
* them through WebGPU)
|
|
37
|
-
*
|
|
38
|
-
*
|
|
46
|
+
* them through WebGPU) by {@link NapariRegionSvgRenderer} over the shared `SvgRegionRenderer`:
|
|
47
|
+
* in world coordinates inside one transformed group, rebuilt on a region or selection change,
|
|
48
|
+
* while a camera move only rewrites the transform (napari-js's `canvasTransform`, the camera
|
|
49
|
+
* centre/zoom) and the few screen-space handles and labels. This class is
|
|
50
|
+
* the gesture controller: pointer handlers, the tool mode, and the edit/draft/marquee state.
|
|
51
|
+
* It writes completed shapes to the shared {@link RegionStore} (so save / undo / export work
|
|
52
|
+
* identically to OSD).
|
|
39
53
|
*
|
|
40
54
|
* Supports (jit-ui#102): rectangle / polygon / freehand path drawing, click-select and rubber-band
|
|
41
55
|
* marquee select, pan/zoom gating via `setControlsEnabled`, body move, vertex move/add/delete,
|
|
42
|
-
* bezier handle editing, and donut holes (including hole vertex + hole-bezier-handle editing)
|
|
43
|
-
*
|
|
56
|
+
* bezier handle editing, and donut holes (including hole vertex + hole-bezier-handle editing).
|
|
57
|
+
* Hit-testing shares `region-overlay/region-geometry` with the OSD overlay, so both follow
|
|
58
|
+
* the same rules (multi-part regions, holes, open polylines, handle-less bezier curves).
|
|
44
59
|
*/
|
|
45
60
|
export class NapariRegionOverlay {
|
|
46
61
|
constructor(host, viewer, store) {
|
|
@@ -54,55 +69,21 @@ export class NapariRegionOverlay {
|
|
|
54
69
|
this.draftRect = null;
|
|
55
70
|
/** In-progress rubber-band selection marquee (select mode), image-space. */
|
|
56
71
|
this.marquee = null;
|
|
57
|
-
/** Dedicated marquee rect element, updated directly during the drag (no full region redraw). */
|
|
58
|
-
this.marqueeEl = null;
|
|
59
72
|
this.draftPath = null; // freehand or click polygon
|
|
60
73
|
this.drawing = false; // pointer is down for rect / freehand
|
|
61
74
|
this.regionsVisible = true;
|
|
62
75
|
/** In-progress manipulation (select/move modes): dragging a body, a polygon vertex, or a
|
|
63
76
|
* rectangle corner. `anchor` is the fixed opposite corner for a rectangle resize. */
|
|
64
77
|
this.edit = null;
|
|
65
|
-
/**
|
|
66
|
-
* How finely a drawn vertex may be placed, in world units.
|
|
67
|
-
*
|
|
68
|
-
* One by default, because for an image the world IS pixels and a region should align to
|
|
69
|
-
* them. A dataset whose coordinates are not pixels sets it finer — seqFISH's whole
|
|
70
|
-
* sample spans about 5 x 7 units, where whole-unit vertices leave roughly six by eight
|
|
71
|
-
* placeable positions and no ROI can be drawn at all.
|
|
72
|
-
*/
|
|
73
|
-
this.worldQuantum = PIXEL_WORLD_QUANTUM;
|
|
74
78
|
// ── pointer handlers ──────────────────────────────────────────────────────
|
|
75
79
|
this.onPointerDown = (e) => {
|
|
76
80
|
if (this.mode === 'none')
|
|
77
81
|
return;
|
|
78
82
|
e.preventDefault();
|
|
79
|
-
|
|
80
|
-
if (this.mode === 'drawrect') {
|
|
81
|
-
this.draftRect = { x0: ix, y0: iy, x1: ix, y1: iy };
|
|
82
|
-
this.drawing = true;
|
|
83
|
-
this.svg.setPointerCapture(e.pointerId);
|
|
84
|
-
}
|
|
85
|
-
else if (this.mode === 'drawclosedpath' || this.mode === 'drawopenpath') {
|
|
86
|
-
this.draftPath = [[ix, iy]];
|
|
87
|
-
this.drawing = true;
|
|
88
|
-
this.svg.setPointerCapture(e.pointerId);
|
|
89
|
-
}
|
|
90
|
-
else if (this.mode === 'drawpolygon') {
|
|
91
|
-
this.handlePolygonClick(ix, iy, e.clientX, e.clientY);
|
|
92
|
-
}
|
|
93
|
-
else if (this.mode === 'select' || this.mode === 'move') {
|
|
94
|
-
this.beginManipulation(ix, iy, e);
|
|
95
|
-
}
|
|
96
|
-
else if (this.mode === 'addpoint') {
|
|
97
|
-
this.handleAddPoint(ix, iy);
|
|
98
|
-
}
|
|
99
|
-
else if (this.mode === 'deletepoint') {
|
|
100
|
-
this.handleDeletePoint(ix, iy);
|
|
101
|
-
}
|
|
102
|
-
this.redraw();
|
|
83
|
+
this.projection.withOrigin(() => this.pointerDown(e));
|
|
103
84
|
};
|
|
104
85
|
this.onPointerMove = (e) => {
|
|
105
|
-
const [ix, iy] = this.toImage(e.clientX, e.clientY);
|
|
86
|
+
const [ix, iy] = this.projection.toImage(e.clientX, e.clientY);
|
|
106
87
|
if (this.marquee) {
|
|
107
88
|
this.marquee.x1 = ix;
|
|
108
89
|
this.marquee.y1 = iy;
|
|
@@ -110,7 +91,7 @@ export class NapariRegionOverlay {
|
|
|
110
91
|
return;
|
|
111
92
|
}
|
|
112
93
|
if (this.edit) {
|
|
113
|
-
this.
|
|
94
|
+
applyRegionEdit(this.store, this.edit, ix, iy);
|
|
114
95
|
this.redraw();
|
|
115
96
|
return;
|
|
116
97
|
}
|
|
@@ -121,19 +102,19 @@ export class NapariRegionOverlay {
|
|
|
121
102
|
this.draftRect.y1 = iy;
|
|
122
103
|
}
|
|
123
104
|
else if (this.draftPath) {
|
|
124
|
-
const step = FREEHAND_STEP_PX * this.worldPerCanvasPixel();
|
|
105
|
+
const step = FREEHAND_STEP_PX * this.projection.worldPerCanvasPixel();
|
|
125
106
|
const last = this.draftPath[this.draftPath.length - 1];
|
|
126
107
|
if (Math.abs(ix - last[0]) >= step || Math.abs(iy - last[1]) >= step) {
|
|
127
108
|
this.draftPath.push([ix, iy]);
|
|
128
109
|
}
|
|
129
110
|
}
|
|
130
|
-
this.
|
|
111
|
+
this.renderOverlay();
|
|
131
112
|
};
|
|
132
113
|
this.onPointerUp = (e) => {
|
|
133
114
|
if (this.marquee) {
|
|
134
115
|
const m = this.marquee;
|
|
135
116
|
this.marquee = null;
|
|
136
|
-
this.
|
|
117
|
+
this.renderer.clearMarquee();
|
|
137
118
|
try {
|
|
138
119
|
this.svg.releasePointerCapture(e.pointerId);
|
|
139
120
|
}
|
|
@@ -171,7 +152,7 @@ export class NapariRegionOverlay {
|
|
|
171
152
|
const w = Math.abs(x1 - x0);
|
|
172
153
|
const h = Math.abs(y1 - y0);
|
|
173
154
|
this.draftRect = null;
|
|
174
|
-
const min = MIN_RECT_DRAG_PX * this.worldPerCanvasPixel();
|
|
155
|
+
const min = MIN_RECT_DRAG_PX * this.projection.worldPerCanvasPixel();
|
|
175
156
|
if (w >= min && h >= min)
|
|
176
157
|
this.commitRectangle(x, y, w, h);
|
|
177
158
|
}
|
|
@@ -184,6 +165,17 @@ export class NapariRegionOverlay {
|
|
|
184
165
|
}
|
|
185
166
|
this.redraw();
|
|
186
167
|
};
|
|
168
|
+
/**
|
|
169
|
+
* The pointer gesture ended without a pointerup (the browser cancelled it, or capture was
|
|
170
|
+
* lost): end it without committing. Also fires after every normal release, when nothing
|
|
171
|
+
* is live any more.
|
|
172
|
+
*/
|
|
173
|
+
this.onPointerCancel = () => {
|
|
174
|
+
if (!this.edit && !this.drawing && !this.marquee)
|
|
175
|
+
return;
|
|
176
|
+
this.endGesture();
|
|
177
|
+
this.redraw();
|
|
178
|
+
};
|
|
187
179
|
this.onDblClick = (e) => {
|
|
188
180
|
if (this.mode !== 'drawpolygon' || !this.draftPath)
|
|
189
181
|
return;
|
|
@@ -207,16 +199,22 @@ export class NapariRegionOverlay {
|
|
|
207
199
|
touchAction: 'none',
|
|
208
200
|
});
|
|
209
201
|
this.host.appendChild(this.svg);
|
|
202
|
+
this.renderer = new NapariRegionSvgRenderer(this.svg, this.store);
|
|
203
|
+
this.projection = new OverlayProjection(this.svg, this.viewer);
|
|
210
204
|
this.svg.addEventListener('pointerdown', this.onPointerDown);
|
|
211
205
|
this.svg.addEventListener('pointermove', this.onPointerMove);
|
|
212
206
|
this.svg.addEventListener('pointerup', this.onPointerUp);
|
|
207
|
+
this.svg.addEventListener('pointercancel', this.onPointerCancel);
|
|
208
|
+
this.svg.addEventListener('lostpointercapture', this.onPointerCancel);
|
|
213
209
|
this.svg.addEventListener('dblclick', this.onDblClick);
|
|
214
210
|
this.subs.add(this.store.getRegionUpdateEvent().subscribe(() => this.redraw()));
|
|
215
211
|
this.subs.add(this.store.getSelectedShapeIndices$().subscribe((idx) => {
|
|
216
212
|
this.selected = idx ?? [];
|
|
217
213
|
this.redraw();
|
|
218
214
|
}));
|
|
219
|
-
|
|
215
|
+
// A camera move rewrites the renderer's transform and its few screen-space elements;
|
|
216
|
+
// the regions are drawn in world coordinates and are not rebuilt (NAPARI-BOUNDARY-10).
|
|
217
|
+
this.disconnectCamera = this.viewer.camera.changed.connect(() => this.updateCamera());
|
|
220
218
|
this.redraw();
|
|
221
219
|
}
|
|
222
220
|
// ── IRegionOverlay ────────────────────────────────────────────────────────
|
|
@@ -232,68 +230,87 @@ export class NapariRegionOverlay {
|
|
|
232
230
|
return this.mode !== 'none';
|
|
233
231
|
}
|
|
234
232
|
setMode(mode) {
|
|
233
|
+
this.endGesture();
|
|
235
234
|
this.mode = mode;
|
|
236
235
|
this.draftRect = null;
|
|
237
236
|
this.draftPath = null;
|
|
238
|
-
this.marquee = null;
|
|
239
|
-
this.clearMarqueeEl();
|
|
240
|
-
this.drawing = false;
|
|
241
237
|
// The overlay owns pointer/navigation gating: while a tool is active it captures the pointer
|
|
242
238
|
// and the napari camera controls are disabled; 'none' hands the pointer back for pan/zoom.
|
|
243
239
|
const active = mode !== 'none';
|
|
244
240
|
this.viewer.setControlsEnabled(!active);
|
|
245
241
|
this.svg.style.pointerEvents = active ? 'auto' : 'none';
|
|
246
242
|
this.svg.style.cursor = active ? 'crosshair' : 'default';
|
|
247
|
-
this.
|
|
243
|
+
this.renderOverlay();
|
|
248
244
|
}
|
|
249
245
|
setSelectedBezier(bezier) {
|
|
250
246
|
const sel = this.selectedRegion();
|
|
251
247
|
if (sel?.id != null)
|
|
252
248
|
this.store.setBezier(sel.id, bezier);
|
|
253
249
|
}
|
|
250
|
+
/**
|
|
251
|
+
* How finely a drawn vertex may be placed, in world units: one (an image's pixels) by
|
|
252
|
+
* default, finer for a dataset whose coordinates are not pixels (see OverlayProjection).
|
|
253
|
+
*/
|
|
254
254
|
setWorldQuantum(quantum) {
|
|
255
|
-
this.
|
|
256
|
-
? quantum
|
|
257
|
-
: PIXEL_WORLD_QUANTUM;
|
|
255
|
+
this.projection.setWorldQuantum(quantum);
|
|
258
256
|
}
|
|
259
257
|
destroy() {
|
|
260
258
|
this.svg.removeEventListener('pointerdown', this.onPointerDown);
|
|
261
259
|
this.svg.removeEventListener('pointermove', this.onPointerMove);
|
|
262
260
|
this.svg.removeEventListener('pointerup', this.onPointerUp);
|
|
261
|
+
this.svg.removeEventListener('pointercancel', this.onPointerCancel);
|
|
262
|
+
this.svg.removeEventListener('lostpointercapture', this.onPointerCancel);
|
|
263
263
|
this.svg.removeEventListener('dblclick', this.onDblClick);
|
|
264
264
|
this.disconnectCamera();
|
|
265
265
|
this.subs.unsubscribe();
|
|
266
|
+
// A drag torn down mid-gesture (a backend switch) must still close its store batch.
|
|
267
|
+
this.endGesture();
|
|
266
268
|
if (this.svg.parentNode)
|
|
267
269
|
this.svg.parentNode.removeChild(this.svg);
|
|
268
270
|
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
271
|
+
pointerDown(e) {
|
|
272
|
+
const [ix, iy] = this.projection.toImage(e.clientX, e.clientY);
|
|
273
|
+
if (this.mode === 'drawrect') {
|
|
274
|
+
this.draftRect = { x0: ix, y0: iy, x1: ix, y1: iy };
|
|
275
|
+
this.drawing = true;
|
|
276
|
+
this.svg.setPointerCapture(e.pointerId);
|
|
277
|
+
}
|
|
278
|
+
else if (this.mode === 'drawclosedpath' || this.mode === 'drawopenpath') {
|
|
279
|
+
this.draftPath = [[ix, iy]];
|
|
280
|
+
this.drawing = true;
|
|
281
|
+
this.svg.setPointerCapture(e.pointerId);
|
|
282
|
+
}
|
|
283
|
+
else if (this.mode === 'drawpolygon') {
|
|
284
|
+
this.handlePolygonClick(ix, iy, e.clientX, e.clientY);
|
|
285
|
+
}
|
|
286
|
+
else if (this.mode === 'select' || this.mode === 'move') {
|
|
287
|
+
this.beginManipulation(ix, iy, e);
|
|
288
|
+
}
|
|
289
|
+
else if (this.mode === 'addpoint') {
|
|
290
|
+
this.handleAddPoint(ix, iy, e.clientX, e.clientY);
|
|
291
|
+
}
|
|
292
|
+
else if (this.mode === 'deletepoint') {
|
|
293
|
+
this.handleDeletePoint(ix, iy);
|
|
294
|
+
}
|
|
295
|
+
this.redraw();
|
|
277
296
|
}
|
|
278
297
|
/**
|
|
279
|
-
*
|
|
280
|
-
*
|
|
281
|
-
*
|
|
282
|
-
*
|
|
283
|
-
* if the transform gives nothing usable, which keeps the established pixel behaviour
|
|
284
|
-
* rather than collapsing the threshold to zero and recording a point per event.
|
|
298
|
+
* End whatever pointer gesture is live without committing it: close the store batch a drag
|
|
299
|
+
* opened (so later edits are emitted again) and forget the drag (so a bare hover no longer
|
|
300
|
+
* moves the region), and drop the marquee and a rectangle/freehand draft. A click-placed
|
|
301
|
+
* polygon is not a pointer gesture and survives.
|
|
285
302
|
*/
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
303
|
+
endGesture() {
|
|
304
|
+
if (this.edit)
|
|
305
|
+
this.store.endBatch();
|
|
306
|
+
this.edit = null;
|
|
307
|
+
if (this.drawing) {
|
|
308
|
+
this.draftRect = null;
|
|
309
|
+
this.draftPath = null;
|
|
310
|
+
}
|
|
311
|
+
this.drawing = false;
|
|
312
|
+
this.marquee = null;
|
|
313
|
+
this.renderer.clearMarquee();
|
|
297
314
|
}
|
|
298
315
|
/** Click-to-place polygon: add a vertex, or close when clicking near the first one. */
|
|
299
316
|
handlePolygonClick(ix, iy, clientX, clientY) {
|
|
@@ -301,9 +318,7 @@ export class NapariRegionOverlay {
|
|
|
301
318
|
this.draftPath = [[ix, iy]];
|
|
302
319
|
return;
|
|
303
320
|
}
|
|
304
|
-
const
|
|
305
|
-
const r = this.svg.getBoundingClientRect();
|
|
306
|
-
const near = Math.hypot(clientX - r.left - fx, clientY - r.top - fy) <= CLOSE_SNAP_PX &&
|
|
321
|
+
const near = this.projection.screenDist(clientX, clientY, this.draftPath[0][0], this.draftPath[0][1]) <= CLOSE_SNAP_PX &&
|
|
307
322
|
this.draftPath.length >= 3;
|
|
308
323
|
if (near) {
|
|
309
324
|
const pts = this.draftPath;
|
|
@@ -320,12 +335,6 @@ export class NapariRegionOverlay {
|
|
|
320
335
|
const i = this.selected[0];
|
|
321
336
|
return i != null && i >= 0 && i < regions.length ? regions[i] : null;
|
|
322
337
|
}
|
|
323
|
-
/** Screen distance (px) between a client point and an image coord. */
|
|
324
|
-
screenDist(clientX, clientY, imgX, imgY) {
|
|
325
|
-
const [lx, ly] = this.toLocal(imgX, imgY);
|
|
326
|
-
const r = this.svg.getBoundingClientRect();
|
|
327
|
-
return Math.hypot(clientX - r.left - lx, clientY - r.top - ly);
|
|
328
|
-
}
|
|
329
338
|
/**
|
|
330
339
|
* Start a select/move interaction: grab a handle (rectangle corner) or vertex of the already-
|
|
331
340
|
* selected region first; otherwise select the topmost region under the cursor and drag its body.
|
|
@@ -333,7 +342,8 @@ export class NapariRegionOverlay {
|
|
|
333
342
|
beginManipulation(ix, iy, e) {
|
|
334
343
|
const sel = this.selectedRegion();
|
|
335
344
|
if (sel?.bounds) {
|
|
336
|
-
const
|
|
345
|
+
const [lx, ly] = this.projection.clientToLocal(e.clientX, e.clientY);
|
|
346
|
+
const grab = hitHandle(sel, lx, ly, this.projection.toScreen, HANDLE_HIT_PX);
|
|
337
347
|
if (grab) {
|
|
338
348
|
this.store.beginBatch();
|
|
339
349
|
this.edit = { ...grab, id: sel.id, last: [ix, iy] };
|
|
@@ -341,10 +351,12 @@ export class NapariRegionOverlay {
|
|
|
341
351
|
return;
|
|
342
352
|
}
|
|
343
353
|
}
|
|
344
|
-
// Hit-test bodies, topmost first (last drawn renders on top)
|
|
354
|
+
// Hit-test bodies, topmost first (last drawn renders on top), at the exact pointer
|
|
355
|
+
// position — snapping is for placing vertices, not for picking.
|
|
345
356
|
const regions = this.store.getRegions();
|
|
357
|
+
const [wx, wy] = this.projection.toWorld(e.clientX, e.clientY);
|
|
346
358
|
for (let i = regions.length - 1; i >= 0; i--) {
|
|
347
|
-
if (
|
|
359
|
+
if (regionContains(regions[i], wx, wy, { toScreen: this.projection.toScreen, tolPx: OPEN_PATH_HIT_PX })) {
|
|
348
360
|
this.store.selectRegion(regions[i]);
|
|
349
361
|
this.store.beginBatch();
|
|
350
362
|
this.edit = { kind: 'body', id: regions[i].id, last: [ix, iy] };
|
|
@@ -363,237 +375,58 @@ export class NapariRegionOverlay {
|
|
|
363
375
|
this.store.setSelectedShapeIndices([]);
|
|
364
376
|
}
|
|
365
377
|
}
|
|
366
|
-
/**
|
|
378
|
+
/** Show the marquee where it is now (only the marquee element: no full region redraw). */
|
|
367
379
|
updateMarqueeEl() {
|
|
368
380
|
if (!this.marquee)
|
|
369
381
|
return;
|
|
370
|
-
if (!this.marqueeEl || !this.marqueeEl.parentNode) {
|
|
371
|
-
this.marqueeEl = document.createElementNS(SVG_NS, 'rect');
|
|
372
|
-
this.marqueeEl.setAttribute('stroke', '#4da3ff');
|
|
373
|
-
this.marqueeEl.setAttribute('stroke-width', '1');
|
|
374
|
-
this.marqueeEl.setAttribute('stroke-dasharray', '4 3');
|
|
375
|
-
this.marqueeEl.setAttribute('fill', '#4da3ff');
|
|
376
|
-
this.marqueeEl.setAttribute('fill-opacity', '0.12');
|
|
377
|
-
this.marqueeEl.setAttribute('vector-effect', 'non-scaling-stroke');
|
|
378
|
-
this.svg.appendChild(this.marqueeEl);
|
|
379
|
-
}
|
|
380
382
|
const { x0, y0, x1, y1 } = this.marquee;
|
|
381
|
-
const [lx, ly] = this.toLocal(Math.min(x0, x1), Math.min(y0, y1));
|
|
382
|
-
const [rx, ry] = this.toLocal(Math.max(x0, x1), Math.max(y0, y1));
|
|
383
|
-
this.
|
|
384
|
-
this.marqueeEl.setAttribute('y', `${ly}`);
|
|
385
|
-
this.marqueeEl.setAttribute('width', `${Math.abs(rx - lx)}`);
|
|
386
|
-
this.marqueeEl.setAttribute('height', `${Math.abs(ry - ly)}`);
|
|
387
|
-
}
|
|
388
|
-
/** Remove the marquee element from the SVG. */
|
|
389
|
-
clearMarqueeEl() {
|
|
390
|
-
if (this.marqueeEl?.parentNode)
|
|
391
|
-
this.marqueeEl.parentNode.removeChild(this.marqueeEl);
|
|
392
|
-
this.marqueeEl = null;
|
|
393
|
-
}
|
|
394
|
-
/** Test whether a client point grabs a rectangle corner or a polygon vertex of `region`. */
|
|
395
|
-
hitHandle(region, clientX, clientY) {
|
|
396
|
-
const b = region.bounds;
|
|
397
|
-
if (!b)
|
|
398
|
-
return null;
|
|
399
|
-
if ('width' in b && 'x' in b) {
|
|
400
|
-
const r = b;
|
|
401
|
-
const corners = [
|
|
402
|
-
[r.x, r.y, [r.x + r.width, r.y + r.height]],
|
|
403
|
-
[r.x + r.width, r.y, [r.x, r.y + r.height]],
|
|
404
|
-
[r.x, r.y + r.height, [r.x + r.width, r.y]],
|
|
405
|
-
[r.x + r.width, r.y + r.height, [r.x, r.y]],
|
|
406
|
-
];
|
|
407
|
-
for (const [cx, cy, anchor] of corners) {
|
|
408
|
-
if (this.screenDist(clientX, clientY, cx, cy) <= HANDLE_HIT_PX)
|
|
409
|
-
return { kind: 'corner', anchor };
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
else if ('npoints' in b) {
|
|
413
|
-
const p = b;
|
|
414
|
-
// Bezier control points first (they sit off the anchors), so they're grabbable.
|
|
415
|
-
if (p.bezier && p.handlesIn?.length === p.npoints && p.handlesOut?.length === p.npoints) {
|
|
416
|
-
for (let i = 0; i < p.npoints; i++) {
|
|
417
|
-
const out = p.handlesOut[i];
|
|
418
|
-
const inn = p.handlesIn[i];
|
|
419
|
-
if (this.screenDist(clientX, clientY, p.xpoints[i] + out[0], p.ypoints[i] + out[1]) <= HANDLE_HIT_PX) {
|
|
420
|
-
return { kind: 'bezier', vertexIndex: i, side: 'out' };
|
|
421
|
-
}
|
|
422
|
-
if (this.screenDist(clientX, clientY, p.xpoints[i] + inn[0], p.ypoints[i] + inn[1]) <= HANDLE_HIT_PX) {
|
|
423
|
-
return { kind: 'bezier', vertexIndex: i, side: 'in' };
|
|
424
|
-
}
|
|
425
|
-
}
|
|
426
|
-
}
|
|
427
|
-
for (let i = 0; i < p.npoints; i++) {
|
|
428
|
-
if (this.screenDist(clientX, clientY, p.xpoints[i], p.ypoints[i]) <= HANDLE_HIT_PX) {
|
|
429
|
-
return { kind: 'vertex', vertexIndex: i };
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
// Hole (donut) ring: bezier control points first, then the vertices.
|
|
433
|
-
const holes = p.holes ?? [];
|
|
434
|
-
const holeBezier = !!(p.bezier && p.holeHandlesIn && p.holeHandlesOut);
|
|
435
|
-
for (let hi = 0; hi < holes.length; hi++) {
|
|
436
|
-
const ring = holes[hi];
|
|
437
|
-
if (holeBezier && p.holeHandlesIn[hi] && p.holeHandlesOut[hi]) {
|
|
438
|
-
for (let vi = 0; vi < ring.length; vi++) {
|
|
439
|
-
const out = p.holeHandlesOut[hi][vi] ?? [0, 0];
|
|
440
|
-
const inn = p.holeHandlesIn[hi][vi] ?? [0, 0];
|
|
441
|
-
if (this.screenDist(clientX, clientY, ring[vi][0] + out[0], ring[vi][1] + out[1]) <= HANDLE_HIT_PX) {
|
|
442
|
-
return { kind: 'holebezier', holeIndex: hi, vertexIndex: vi, side: 'out' };
|
|
443
|
-
}
|
|
444
|
-
if (this.screenDist(clientX, clientY, ring[vi][0] + inn[0], ring[vi][1] + inn[1]) <= HANDLE_HIT_PX) {
|
|
445
|
-
return { kind: 'holebezier', holeIndex: hi, vertexIndex: vi, side: 'in' };
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
for (let vi = 0; vi < ring.length; vi++) {
|
|
450
|
-
if (this.screenDist(clientX, clientY, ring[vi][0], ring[vi][1]) <= HANDLE_HIT_PX) {
|
|
451
|
-
return { kind: 'holevertex', holeIndex: hi, vertexIndex: vi };
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
return null;
|
|
457
|
-
}
|
|
458
|
-
/** Apply the live drag for the active manipulation (image coords `ix,iy`). */
|
|
459
|
-
applyManipulation(ix, iy) {
|
|
460
|
-
if (!this.edit)
|
|
461
|
-
return;
|
|
462
|
-
if (this.edit.kind === 'body') {
|
|
463
|
-
const [lx, ly] = this.edit.last;
|
|
464
|
-
this.store.moveRegion(this.edit.id, ix - lx, iy - ly);
|
|
465
|
-
this.edit.last = [ix, iy];
|
|
466
|
-
}
|
|
467
|
-
else if (this.edit.kind === 'vertex' && this.edit.vertexIndex != null) {
|
|
468
|
-
this.store.moveVertex(this.edit.id, this.edit.vertexIndex, ix, iy);
|
|
469
|
-
}
|
|
470
|
-
else if (this.edit.kind === 'corner' && this.edit.anchor) {
|
|
471
|
-
const [ax, ay] = this.edit.anchor;
|
|
472
|
-
const rect = new Rectangle();
|
|
473
|
-
rect.x = Math.min(ax, ix);
|
|
474
|
-
rect.y = Math.min(ay, iy);
|
|
475
|
-
rect.width = Math.abs(ix - ax);
|
|
476
|
-
rect.height = Math.abs(iy - ay);
|
|
477
|
-
this.store.updateBounds(this.edit.id, rect);
|
|
478
|
-
}
|
|
479
|
-
else if (this.edit.kind === 'bezier' && this.edit.vertexIndex != null && this.edit.side) {
|
|
480
|
-
this.store.moveBezierHandle(this.edit.id, this.edit.vertexIndex, this.edit.side, ix, iy);
|
|
481
|
-
}
|
|
482
|
-
else if (this.edit.kind === 'holevertex' &&
|
|
483
|
-
this.edit.holeIndex != null &&
|
|
484
|
-
this.edit.vertexIndex != null) {
|
|
485
|
-
this.store.moveHoleVertex(this.edit.id, this.edit.holeIndex, this.edit.vertexIndex, ix, iy);
|
|
486
|
-
}
|
|
487
|
-
else if (this.edit.kind === 'holebezier' &&
|
|
488
|
-
this.edit.holeIndex != null &&
|
|
489
|
-
this.edit.vertexIndex != null &&
|
|
490
|
-
this.edit.side) {
|
|
491
|
-
this.store.moveHoleBezierHandle(this.edit.id, this.edit.holeIndex, this.edit.vertexIndex, this.edit.side, ix, iy);
|
|
492
|
-
}
|
|
383
|
+
const [lx, ly] = this.projection.toLocal(Math.min(x0, x1), Math.min(y0, y1));
|
|
384
|
+
const [rx, ry] = this.projection.toLocal(Math.max(x0, x1), Math.max(y0, y1));
|
|
385
|
+
this.renderer.showMarquee(lx, ly, rx, ry);
|
|
493
386
|
}
|
|
494
|
-
/** addpoint mode: insert a vertex on the selected polygon's nearest edge
|
|
495
|
-
|
|
387
|
+
/** addpoint mode: insert a vertex at the click on the selected polygon's nearest edge
|
|
388
|
+
* (exterior or a hole ring). */
|
|
389
|
+
handleAddPoint(ix, iy, clientX, clientY) {
|
|
496
390
|
const sel = this.selectedRegion();
|
|
497
|
-
|
|
498
|
-
if (!sel || !b || !('npoints' in b))
|
|
391
|
+
if (!sel)
|
|
499
392
|
return;
|
|
500
|
-
const
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
bestD = d;
|
|
509
|
-
bestSeg = s;
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
this.store.addVertex(sel.id, bestSeg, ix, iy);
|
|
393
|
+
const [lx, ly] = this.projection.clientToLocal(clientX, clientY);
|
|
394
|
+
const edge = nearestEdge(sel, lx, ly, this.projection.toScreen);
|
|
395
|
+
if (!edge)
|
|
396
|
+
return;
|
|
397
|
+
if (edge.ring < 0)
|
|
398
|
+
this.store.addVertex(sel.id, edge.segIndex, ix, iy);
|
|
399
|
+
else
|
|
400
|
+
this.store.addHoleVertex(sel.id, edge.ring, edge.segIndex, ix, iy);
|
|
513
401
|
}
|
|
514
|
-
/** deletepoint mode: remove the selected polygon's vertex nearest the click
|
|
402
|
+
/** deletepoint mode: remove the selected polygon's vertex nearest the click (exterior or a
|
|
403
|
+
* hole ring). */
|
|
515
404
|
handleDeletePoint(ix, iy) {
|
|
516
405
|
const sel = this.selectedRegion();
|
|
517
|
-
|
|
518
|
-
if (!sel || !b || !('npoints' in b))
|
|
406
|
+
if (!sel)
|
|
519
407
|
return;
|
|
520
|
-
const
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
best = i;
|
|
528
|
-
}
|
|
529
|
-
}
|
|
530
|
-
if (best >= 0)
|
|
531
|
-
this.store.deleteVertex(sel.id, best);
|
|
532
|
-
}
|
|
533
|
-
/** Distance from point (px,py) to segment (ax,ay)-(bx,by), in image units. */
|
|
534
|
-
pointSegDist(px, py, ax, ay, bx, by) {
|
|
535
|
-
const dx = bx - ax;
|
|
536
|
-
const dy = by - ay;
|
|
537
|
-
const len2 = dx * dx + dy * dy || 1;
|
|
538
|
-
let t = ((px - ax) * dx + (py - ay) * dy) / len2;
|
|
539
|
-
t = Math.max(0, Math.min(1, t));
|
|
540
|
-
return Math.hypot(px - (ax + t * dx), py - (ay + t * dy));
|
|
408
|
+
const v = nearestVertex(sel, ix, iy);
|
|
409
|
+
if (!v)
|
|
410
|
+
return;
|
|
411
|
+
if (v.ring < 0)
|
|
412
|
+
this.store.deleteVertex(sel.id, v.index);
|
|
413
|
+
else
|
|
414
|
+
this.store.deleteHoleVertex(sel.id, v.ring, v.index);
|
|
541
415
|
}
|
|
542
|
-
/** Finalize a rubber-band marquee: select every region whose bounding box it overlaps (a
|
|
543
|
-
* marquee
|
|
416
|
+
/** Finalize a rubber-band marquee: select every region whose bounding box it overlaps (a
|
|
417
|
+
* marquee under {@link MIN_MARQUEE_PX} is a click on empty space → clear the selection). */
|
|
544
418
|
finishMarquee(m) {
|
|
545
419
|
const x0 = Math.min(m.x0, m.x1);
|
|
546
420
|
const x1 = Math.max(m.x0, m.x1);
|
|
547
421
|
const y0 = Math.min(m.y0, m.y1);
|
|
548
422
|
const y1 = Math.max(m.y0, m.y1);
|
|
549
|
-
|
|
423
|
+
const min = MIN_MARQUEE_PX * this.projection.worldPerCanvasPixel();
|
|
424
|
+
if (x1 - x0 < min && y1 - y0 < min) {
|
|
550
425
|
this.store.setSelectedShapeIndices([]);
|
|
551
426
|
return;
|
|
552
427
|
}
|
|
553
|
-
const
|
|
554
|
-
this.store.
|
|
555
|
-
if (r.isProfile?.())
|
|
556
|
-
return;
|
|
557
|
-
const bb = this.regionBBox(r);
|
|
558
|
-
if (bb && bb.x0 <= x1 && bb.x1 >= x0 && bb.y0 <= y1 && bb.y1 >= y0)
|
|
559
|
-
indices.push(i);
|
|
560
|
-
});
|
|
561
|
-
this.store.setSelectedShapeIndices(indices);
|
|
562
|
-
}
|
|
563
|
-
/** A region's bounding box in image coords (rectangle, polygon, or multipolygon), or null. */
|
|
564
|
-
regionBBox(region) {
|
|
565
|
-
const b = region.bounds;
|
|
566
|
-
if (!b)
|
|
567
|
-
return null;
|
|
568
|
-
if ('width' in b && 'x' in b) {
|
|
569
|
-
const r = b;
|
|
570
|
-
return { x0: r.x, y0: r.y, x1: r.x + r.width, y1: r.y + r.height };
|
|
571
|
-
}
|
|
572
|
-
const acc = { x0: Infinity, y0: Infinity, x1: -Infinity, y1: -Infinity };
|
|
573
|
-
const addRing = (xs, ys) => {
|
|
574
|
-
for (let i = 0; i < xs.length; i++) {
|
|
575
|
-
if (xs[i] < acc.x0)
|
|
576
|
-
acc.x0 = xs[i];
|
|
577
|
-
if (xs[i] > acc.x1)
|
|
578
|
-
acc.x1 = xs[i];
|
|
579
|
-
if (ys[i] < acc.y0)
|
|
580
|
-
acc.y0 = ys[i];
|
|
581
|
-
if (ys[i] > acc.y1)
|
|
582
|
-
acc.y1 = ys[i];
|
|
583
|
-
}
|
|
584
|
-
};
|
|
585
|
-
if ('npoints' in b) {
|
|
586
|
-
const p = b;
|
|
587
|
-
addRing(p.xpoints, p.ypoints);
|
|
588
|
-
}
|
|
589
|
-
else if ('polygons' in b) {
|
|
590
|
-
for (const p of b.polygons)
|
|
591
|
-
addRing(p.xpoints, p.ypoints);
|
|
592
|
-
}
|
|
593
|
-
else {
|
|
594
|
-
return null;
|
|
595
|
-
}
|
|
596
|
-
return isFinite(acc.x0) ? acc : null;
|
|
428
|
+
const regions = this.store.getRegions();
|
|
429
|
+
this.store.setSelectedShapeIndices(regionsInRect(regions, x0, y0, x1, y1, { skipProfiles: true }));
|
|
597
430
|
}
|
|
598
431
|
// ── shape commit ──────────────────────────────────────────────────────────
|
|
599
432
|
commitRectangle(x, y, width, height) {
|
|
@@ -621,29 +454,6 @@ export class NapariRegionOverlay {
|
|
|
621
454
|
this.store.addRegion(region);
|
|
622
455
|
}
|
|
623
456
|
// ── rendering ─────────────────────────────────────────────────────────────
|
|
624
|
-
hitTest(region, x, y) {
|
|
625
|
-
const b = region.bounds;
|
|
626
|
-
if (!b)
|
|
627
|
-
return false;
|
|
628
|
-
if ('width' in b && 'x' in b) {
|
|
629
|
-
const r = b;
|
|
630
|
-
return x >= r.x && x <= r.x + r.width && y >= r.y && y <= r.y + r.height;
|
|
631
|
-
}
|
|
632
|
-
if ('npoints' in b) {
|
|
633
|
-
const p = b;
|
|
634
|
-
let inside = false;
|
|
635
|
-
for (let i = 0, j = p.npoints - 1; i < p.npoints; j = i++) {
|
|
636
|
-
const xi = p.xpoints[i];
|
|
637
|
-
const yi = p.ypoints[i];
|
|
638
|
-
const xj = p.xpoints[j];
|
|
639
|
-
const yj = p.ypoints[j];
|
|
640
|
-
if (yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi)
|
|
641
|
-
inside = !inside;
|
|
642
|
-
}
|
|
643
|
-
return inside;
|
|
644
|
-
}
|
|
645
|
-
return false;
|
|
646
|
-
}
|
|
647
457
|
/** Show or hide the drawn regions. A region being drawn stays visible either way. */
|
|
648
458
|
setRegionsVisible(visible) {
|
|
649
459
|
if (visible === this.regionsVisible)
|
|
@@ -651,269 +461,25 @@ export class NapariRegionOverlay {
|
|
|
651
461
|
this.regionsVisible = visible;
|
|
652
462
|
this.redraw();
|
|
653
463
|
}
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
const regions = this.regionsVisible ? this.store.getRegions() : [];
|
|
658
|
-
regions.forEach((region, i) => {
|
|
659
|
-
if (region.isProfile?.())
|
|
660
|
-
return;
|
|
661
|
-
const isSel = this.selected.includes(i);
|
|
662
|
-
const el = this.buildRegionEl(region, isSel);
|
|
663
|
-
if (el)
|
|
664
|
-
this.svg.appendChild(el);
|
|
665
|
-
this.drawLabel(region);
|
|
666
|
-
if (isSel)
|
|
667
|
-
this.drawHandles(region);
|
|
668
|
-
});
|
|
669
|
-
this.drawDraft();
|
|
670
|
-
}
|
|
671
|
-
/** Draw a region's classification label at its top-left, when labels are enabled (matches OSD). */
|
|
672
|
-
drawLabel(region) {
|
|
673
|
-
if (!this.store.getShowShapeLabel() || region.isProfile?.())
|
|
674
|
-
return;
|
|
675
|
-
const label = region.label;
|
|
676
|
-
const b = region.bounds;
|
|
677
|
-
if (!label || !b)
|
|
678
|
-
return;
|
|
679
|
-
let ix;
|
|
680
|
-
let iy;
|
|
681
|
-
if ('width' in b && 'x' in b) {
|
|
682
|
-
ix = b.x;
|
|
683
|
-
iy = b.y;
|
|
684
|
-
}
|
|
685
|
-
else if ('npoints' in b) {
|
|
686
|
-
const p = b;
|
|
687
|
-
ix = p.xpoints.reduce((m, x) => Math.min(m, x), Infinity);
|
|
688
|
-
iy = p.ypoints.reduce((m, y) => Math.min(m, y), Infinity);
|
|
689
|
-
}
|
|
690
|
-
else {
|
|
691
|
-
return;
|
|
692
|
-
}
|
|
693
|
-
const [lx, ly] = this.toLocal(ix, iy);
|
|
694
|
-
const text = document.createElementNS(SVG_NS, 'text');
|
|
695
|
-
text.setAttribute('x', `${lx}`);
|
|
696
|
-
text.setAttribute('y', `${ly - 4}`);
|
|
697
|
-
text.setAttribute('fill', '#fff');
|
|
698
|
-
text.setAttribute('stroke', '#000');
|
|
699
|
-
text.setAttribute('stroke-width', '3');
|
|
700
|
-
text.setAttribute('paint-order', 'stroke');
|
|
701
|
-
text.setAttribute('font', '12px sans-serif');
|
|
702
|
-
text.setAttribute('pointer-events', 'none');
|
|
703
|
-
text.textContent = label;
|
|
704
|
-
this.svg.appendChild(text);
|
|
705
|
-
}
|
|
706
|
-
/** Draw grab handles for the selected region: rectangle corners or polygon vertices. */
|
|
707
|
-
drawHandles(region) {
|
|
708
|
-
const b = region.bounds;
|
|
709
|
-
if (!b)
|
|
710
|
-
return;
|
|
711
|
-
const stroke = region.color || this.store.getShapeColor() || '#00ffff';
|
|
712
|
-
const handle = (imgX, imgY) => {
|
|
713
|
-
const [lx, ly] = this.toLocal(imgX, imgY);
|
|
714
|
-
const el = document.createElementNS(SVG_NS, 'rect');
|
|
715
|
-
el.setAttribute('x', `${lx - HANDLE_SIZE / 2}`);
|
|
716
|
-
el.setAttribute('y', `${ly - HANDLE_SIZE / 2}`);
|
|
717
|
-
el.setAttribute('width', `${HANDLE_SIZE}`);
|
|
718
|
-
el.setAttribute('height', `${HANDLE_SIZE}`);
|
|
719
|
-
el.setAttribute('fill', '#fff');
|
|
720
|
-
el.setAttribute('stroke', stroke);
|
|
721
|
-
el.setAttribute('stroke-width', '1.5');
|
|
722
|
-
this.svg.appendChild(el);
|
|
723
|
-
};
|
|
724
|
-
if ('width' in b && 'x' in b) {
|
|
725
|
-
const r = b;
|
|
726
|
-
handle(r.x, r.y);
|
|
727
|
-
handle(r.x + r.width, r.y);
|
|
728
|
-
handle(r.x, r.y + r.height);
|
|
729
|
-
handle(r.x + r.width, r.y + r.height);
|
|
730
|
-
}
|
|
731
|
-
else if ('npoints' in b) {
|
|
732
|
-
const p = b;
|
|
733
|
-
const isBezier = p.bezier && p.handlesIn?.length === p.npoints && p.handlesOut?.length === p.npoints;
|
|
734
|
-
for (let i = 0; i < p.npoints; i++)
|
|
735
|
-
handle(p.xpoints[i], p.ypoints[i]);
|
|
736
|
-
for (const ring of p.holes ?? [])
|
|
737
|
-
for (const [hx, hy] of ring)
|
|
738
|
-
handle(hx, hy);
|
|
739
|
-
// Bezier regions also expose their tangent control points (circles) joined to the anchor
|
|
740
|
-
// by a thin line, matching the OSD overlay's editable bezier handles.
|
|
741
|
-
if (isBezier) {
|
|
742
|
-
const hIn = p.handlesIn;
|
|
743
|
-
const hOut = p.handlesOut;
|
|
744
|
-
for (let i = 0; i < p.npoints; i++) {
|
|
745
|
-
this.drawBezierHandle(p.xpoints[i], p.ypoints[i], hOut[i], stroke);
|
|
746
|
-
this.drawBezierHandle(p.xpoints[i], p.ypoints[i], hIn[i], stroke);
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
// Donut hole bezier control handles.
|
|
750
|
-
if (p.bezier && p.holeHandlesIn && p.holeHandlesOut) {
|
|
751
|
-
(p.holes ?? []).forEach((ring, hi) => {
|
|
752
|
-
const hIn = p.holeHandlesIn[hi];
|
|
753
|
-
const hOut = p.holeHandlesOut[hi];
|
|
754
|
-
if (!hIn || !hOut)
|
|
755
|
-
return;
|
|
756
|
-
ring.forEach(([hx, hy], vi) => {
|
|
757
|
-
this.drawBezierHandle(hx, hy, hOut[vi], stroke);
|
|
758
|
-
this.drawBezierHandle(hx, hy, hIn[vi], stroke);
|
|
759
|
-
});
|
|
760
|
-
});
|
|
761
|
-
}
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
/** Draw one bezier control point (anchor + handle offset) as a small circle connected to its
|
|
765
|
-
* anchor by a tangent line. `handle` is the [dx,dy] offset from the anchor in image space. */
|
|
766
|
-
drawBezierHandle(ax, ay, handle, stroke) {
|
|
767
|
-
if (!handle || (handle[0] === 0 && handle[1] === 0))
|
|
768
|
-
return;
|
|
769
|
-
const [alx, aly] = this.toLocal(ax, ay);
|
|
770
|
-
const [hlx, hly] = this.toLocal(ax + handle[0], ay + handle[1]);
|
|
771
|
-
const line = document.createElementNS(SVG_NS, 'line');
|
|
772
|
-
line.setAttribute('x1', `${alx}`);
|
|
773
|
-
line.setAttribute('y1', `${aly}`);
|
|
774
|
-
line.setAttribute('x2', `${hlx}`);
|
|
775
|
-
line.setAttribute('y2', `${hly}`);
|
|
776
|
-
line.setAttribute('stroke', stroke);
|
|
777
|
-
line.setAttribute('stroke-width', '1');
|
|
778
|
-
line.setAttribute('stroke-opacity', '0.7');
|
|
779
|
-
this.svg.appendChild(line);
|
|
780
|
-
const dot = document.createElementNS(SVG_NS, 'circle');
|
|
781
|
-
dot.setAttribute('cx', `${hlx}`);
|
|
782
|
-
dot.setAttribute('cy', `${hly}`);
|
|
783
|
-
dot.setAttribute('r', `${HANDLE_SIZE / 2}`);
|
|
784
|
-
dot.setAttribute('fill', stroke);
|
|
785
|
-
dot.setAttribute('stroke', '#fff');
|
|
786
|
-
dot.setAttribute('stroke-width', '1');
|
|
787
|
-
this.svg.appendChild(dot);
|
|
788
|
-
}
|
|
789
|
-
buildRegionEl(region, isSelected) {
|
|
790
|
-
const b = region.bounds;
|
|
791
|
-
if (!b)
|
|
792
|
-
return null;
|
|
793
|
-
const stroke = region.color || this.store.getShapeColor() || '#00ffff';
|
|
794
|
-
if ('width' in b && 'x' in b) {
|
|
795
|
-
const r = b;
|
|
796
|
-
const [lx, ly] = this.toLocal(r.x, r.y);
|
|
797
|
-
const [rx, ry] = this.toLocal(r.x + r.width, r.y + r.height);
|
|
798
|
-
const el = document.createElementNS(SVG_NS, 'rect');
|
|
799
|
-
el.setAttribute('x', `${Math.min(lx, rx)}`);
|
|
800
|
-
el.setAttribute('y', `${Math.min(ly, ry)}`);
|
|
801
|
-
el.setAttribute('width', `${Math.abs(rx - lx)}`);
|
|
802
|
-
el.setAttribute('height', `${Math.abs(ry - ly)}`);
|
|
803
|
-
this.style(el, stroke, isSelected);
|
|
804
|
-
return el;
|
|
805
|
-
}
|
|
806
|
-
if ('npoints' in b) {
|
|
807
|
-
const p = b;
|
|
808
|
-
const isBezier = !!p.bezier && p.handlesIn?.length === p.npoints && p.handlesOut?.length === p.npoints;
|
|
809
|
-
const hasHoles = !!(p.holes && p.holes.length);
|
|
810
|
-
// Bezier or donut (holes) → a single <path>; holes use even-odd fill so they punch through.
|
|
811
|
-
if (isBezier || hasHoles) {
|
|
812
|
-
const el = document.createElementNS(SVG_NS, 'path');
|
|
813
|
-
el.setAttribute('d', this.polygonPathData(p, isBezier));
|
|
814
|
-
if (hasHoles)
|
|
815
|
-
el.setAttribute('fill-rule', 'evenodd');
|
|
816
|
-
this.style(el, stroke, isSelected);
|
|
817
|
-
return el;
|
|
818
|
-
}
|
|
819
|
-
const pts = p.xpoints
|
|
820
|
-
.map((_, i) => this.toLocal(p.xpoints[i], p.ypoints[i]).join(','))
|
|
821
|
-
.join(' ');
|
|
822
|
-
const el = document.createElementNS(SVG_NS, p.closed === false ? 'polyline' : 'polygon');
|
|
823
|
-
el.setAttribute('points', pts);
|
|
824
|
-
this.style(el, stroke, isSelected);
|
|
825
|
-
return el;
|
|
826
|
-
}
|
|
827
|
-
return null;
|
|
464
|
+
/** Follow a camera move: one transform attribute plus the screen-space elements. */
|
|
465
|
+
updateCamera() {
|
|
466
|
+
this.renderer.setCamera(this.projection.affine());
|
|
828
467
|
}
|
|
829
|
-
/**
|
|
830
|
-
*
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
}
|
|
844
|
-
else {
|
|
845
|
-
d += ' ' + this.straightPath(xs, ys, true);
|
|
846
|
-
}
|
|
468
|
+
/**
|
|
469
|
+
* Rebuild every element from the store: the regions in world coordinates (one transformed
|
|
470
|
+
* group), their labels, and the overlay. Reads no layout: the camera affine is the viewer's.
|
|
471
|
+
*/
|
|
472
|
+
redraw() {
|
|
473
|
+
this.renderer.setCamera(this.projection.affine());
|
|
474
|
+
this.renderer.render(this.regionsVisible ? this.store.getRegions() : [], this.selected);
|
|
475
|
+
this.renderOverlay();
|
|
476
|
+
}
|
|
477
|
+
/** Rebuild the screen-space overlay only: the selected regions' handles and the draft. */
|
|
478
|
+
renderOverlay() {
|
|
479
|
+
this.renderer.renderOverlay(this.regionsVisible ? this.store.getRegions() : [], this.selected, {
|
|
480
|
+
rect: this.draftRect,
|
|
481
|
+
path: this.draftPath,
|
|
847
482
|
});
|
|
848
|
-
return d;
|
|
849
|
-
}
|
|
850
|
-
/** SVG path data for a straight ring/polyline in image coords (closed appends `Z`). */
|
|
851
|
-
straightPath(xs, ys, closed) {
|
|
852
|
-
let d = '';
|
|
853
|
-
for (let i = 0; i < xs.length; i++) {
|
|
854
|
-
const [lx, ly] = this.toLocal(xs[i], ys[i]);
|
|
855
|
-
d += (i === 0 ? 'M' : ' L') + ` ${lx},${ly}`;
|
|
856
|
-
}
|
|
857
|
-
return closed ? d + ' Z' : d;
|
|
858
|
-
}
|
|
859
|
-
/** SVG cubic-bezier path data for any ring (exterior or hole): anchors joined by cubic segments
|
|
860
|
-
* whose control points are `anchor + handleOut` (leaving) and `nextAnchor + handleIn` (arriving),
|
|
861
|
-
* in image space. Used for both the exterior and (donut) hole rings. */
|
|
862
|
-
ringBezierPath(xs, ys, hIn, hOut, closed) {
|
|
863
|
-
const n = xs.length;
|
|
864
|
-
const anchor = (i) => this.toLocal(xs[i], ys[i]);
|
|
865
|
-
const ctrlOut = (i) => this.toLocal(xs[i] + (hOut[i]?.[0] ?? 0), ys[i] + (hOut[i]?.[1] ?? 0));
|
|
866
|
-
const ctrlIn = (i) => this.toLocal(xs[i] + (hIn[i]?.[0] ?? 0), ys[i] + (hIn[i]?.[1] ?? 0));
|
|
867
|
-
const [sx, sy] = anchor(0);
|
|
868
|
-
let d = `M ${sx},${sy}`;
|
|
869
|
-
const segments = closed ? n : n - 1;
|
|
870
|
-
for (let s = 0; s < segments; s++) {
|
|
871
|
-
const i = s;
|
|
872
|
-
const j = (s + 1) % n;
|
|
873
|
-
const [c1x, c1y] = ctrlOut(i);
|
|
874
|
-
const [c2x, c2y] = ctrlIn(j);
|
|
875
|
-
const [ex, ey] = anchor(j);
|
|
876
|
-
d += ` C ${c1x},${c1y} ${c2x},${c2y} ${ex},${ey}`;
|
|
877
|
-
}
|
|
878
|
-
if (closed)
|
|
879
|
-
d += ' Z';
|
|
880
|
-
return d;
|
|
881
|
-
}
|
|
882
|
-
style(el, stroke, isSelected) {
|
|
883
|
-
el.setAttribute('stroke', stroke);
|
|
884
|
-
el.setAttribute('stroke-width', isSelected ? '4' : '2');
|
|
885
|
-
el.setAttribute('fill', isSelected ? stroke : 'none');
|
|
886
|
-
el.setAttribute('fill-opacity', isSelected ? '0.35' : '0');
|
|
887
|
-
el.setAttribute('vector-effect', 'non-scaling-stroke');
|
|
888
|
-
}
|
|
889
|
-
/** Draw the in-progress rectangle / path preview. */
|
|
890
|
-
drawDraft() {
|
|
891
|
-
if (this.draftRect) {
|
|
892
|
-
const { x0, y0, x1, y1 } = this.draftRect;
|
|
893
|
-
const [lx, ly] = this.toLocal(Math.min(x0, x1), Math.min(y0, y1));
|
|
894
|
-
const [rx, ry] = this.toLocal(Math.max(x0, x1), Math.max(y0, y1));
|
|
895
|
-
const el = document.createElementNS(SVG_NS, 'rect');
|
|
896
|
-
el.setAttribute('x', `${lx}`);
|
|
897
|
-
el.setAttribute('y', `${ly}`);
|
|
898
|
-
el.setAttribute('width', `${Math.abs(rx - lx)}`);
|
|
899
|
-
el.setAttribute('height', `${Math.abs(ry - ly)}`);
|
|
900
|
-
this.styleDraft(el);
|
|
901
|
-
this.svg.appendChild(el);
|
|
902
|
-
}
|
|
903
|
-
if (this.draftPath && this.draftPath.length) {
|
|
904
|
-
const pts = this.draftPath.map(([x, y]) => this.toLocal(x, y).join(',')).join(' ');
|
|
905
|
-
const el = document.createElementNS(SVG_NS, 'polyline');
|
|
906
|
-
el.setAttribute('points', pts);
|
|
907
|
-
this.styleDraft(el);
|
|
908
|
-
this.svg.appendChild(el);
|
|
909
|
-
}
|
|
910
|
-
}
|
|
911
|
-
styleDraft(el) {
|
|
912
|
-
el.setAttribute('stroke', this.store.getShapeColor() || '#00ffff');
|
|
913
|
-
el.setAttribute('stroke-width', '2');
|
|
914
|
-
el.setAttribute('stroke-dasharray', '4 3');
|
|
915
|
-
el.setAttribute('fill', 'none');
|
|
916
|
-
el.setAttribute('vector-effect', 'non-scaling-stroke');
|
|
917
483
|
}
|
|
918
484
|
}
|
|
919
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFwYXJpLXJlZ2lvbi1vdmVybGF5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9pbXBsZW1lbnRhdGlvbnMvbmFwYXJpLWpzL25hcGFyaS1yZWdpb24tb3ZlcmxheS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBR3BDLE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRWpFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxlQUFlLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUVoRixNQUFNLE1BQU0sR0FBRyw0QkFBNEIsQ0FBQztBQUM1Qzs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLGdCQUFnQixHQUFHLENBQUMsQ0FBQztBQUMzQjs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO0FBQzNCLGtHQUFrRztBQUNsRyxNQUFNLGFBQWEsR0FBRyxFQUFFLENBQUM7QUFDekIsNEVBQTRFO0FBQzVFLE1BQU0sYUFBYSxHQUFHLENBQUMsQ0FBQztBQUN4Qix3Q0FBd0M7QUFDeEMsTUFBTSxXQUFXLEdBQUcsQ0FBQyxDQUFDO0FBaUJ0Qjs7Ozs7Ozs7Ozs7O0dBWUc7QUFDSCxNQUFNLE9BQU8sbUJBQW1CO0lBOEI5QixZQUNtQixJQUFpQixFQUNqQixNQUFxQixFQUNyQixLQUFrQjtRQUZsQixTQUFJLEdBQUosSUFBSSxDQUFhO1FBQ2pCLFdBQU0sR0FBTixNQUFNLENBQWU7UUFDckIsVUFBSyxHQUFMLEtBQUssQ0FBYTtRQS9CcEIsU0FBSSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFHbkMsU0FBSSxHQUFtQixNQUFNLENBQUM7UUFDOUIsYUFBUSxHQUFhLEVBQUUsQ0FBQztRQUVoQywrQ0FBK0M7UUFDdkMsY0FBUyxHQUE4RCxJQUFJLENBQUM7UUFDcEYs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LElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDM0QsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQztZQUNsQyxNQUFNLElBQUksR0FBRyxJQUFJLFNBQVMsRUFBRSxDQUFDO1lBQzdCLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDMUIsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUMxQixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQy9CLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7WUFDaEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDOUMsQ0FBQzthQUFNLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssUUFBUSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQzFGLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzNGLENBQUM7YUFBTSxJQUNMLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxLQUFLLFlBQVk7WUFDL0IsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSTtZ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QztRQUMxQixDQUFDO2FBQU0sSUFBSSxTQUFTLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDMUIsTUFBTSxDQUFDLEdBQUcsQ0FBWSxDQUFDO1lBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQzFELEVBQUUsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzVELENBQUM7YUFBTSxDQUFDO1lBQ04sT0FBTztRQUNULENBQUM7UUFDRCxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ3RDLE1BQU0sSUFBSSxHQUFHLFFBQVEsQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ3RELElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNoQyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ2xDLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxZQUFZLENBQUMsY0FBYyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxZQUFZLENBQUMsYUFBYSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzNDLElBQUks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RUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekUsTUFBTSxNQUFNLEdBQUcsQ0FBQyxDQUFTLEVBQW9CLEVBQUUsQ0FDN0MsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZFLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNCLElBQUksQ0FBQyxHQUFHLEtBQUssRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDO1FBQ3hCLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3BDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxRQUFRLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNsQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDWixNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDdEIsTUFBTSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDOUIsTUFBTSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDN0IsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDM0IsQ0FBQyxJQUFJLE1BQU0sR0FBRyxJQUFJLEdBQUcsSUFB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QUFFLFVBQVUsQ0FBQyxDQUFDO1lBQ3hELEVBQUUsQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQy9CLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDcEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDM0IsQ0FBQztJQUNILENBQUM7SUFFTyxVQUFVLENBQUMsRUFBYztRQUMvQixFQUFFLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsRUFBRSxJQUFJLFNBQVMsQ0FBQyxDQUFDO1FBQ25FLEVBQUUsQ0FBQyxZQUFZLENBQUMsY0FBYyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3JDLEVBQUUsQ0FBQyxZQUFZLENBQUMsa0JBQWtCLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDM0MsRUFBRSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDaEMsRUFBRSxDQUFDLFlBQVksQ0FBQyxlQUFlLEVBQUUsb0JBQW9CLENBQUMsQ0FBQztJQUN6RCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgSVJlZ2lvbk92ZXJsYXksIFJlZ2lvblRvb2xNb2RlIH0gZnJvbSAnLi4vLi4vY29udHJhY3RzL3JlZ2lvbi1vdmVybGF5LmNvbnRyYWN0JztcbmltcG9ydCB7IFJlZ2lvbiwgUmVjdGFuZ2xlLCBQb2x5Z29uIH0gZnJvbSAnLi4vLi4vbW9kZWxzL3JlZ2lvbic7XG5pbXBvcnQgeyBSZWdpb25TdG9yZSB9IGZyb20gJy4uLy4uL3N0b3JlL3JlZ2lvbi1zdG9yZS5zZXJ2aWNlJztcbmltcG9ydCB7IFBJWEVMX1dPUkxEX1FVQU5UVU0sIHNuYXBUb1dvcmxkR3JpZCB9IGZyb20gJy4uLy4uL3NwYXRpYWwvd29ybGQtZ3JpZCc7XG5cbmNvbnN0IFNWR19OUyA9ICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zyc7XG4vKipcbiAqIE1pbiBkcmFnIGJlZm9yZSBhIGZyZWVoYW5kIHBhdGggcmVjb3JkcyBhbm90aGVyIHBvaW50LCBpbiBTQ1JFRU4gcGl4ZWxzLlxuICpcbiAqIFNjcmVlbiByYXRoZXIgdGhhbiB3b3JsZCwgd2hpY2ggaXMgd2hhdCBcIjIgaW1hZ2UgcHhcIiBhbHdheXMgbWVhbnQgaW4gcHJhY3RpY2U6IGF0IDEwMCVcbiAqIHpvb20gb3ZlciBhbiBpbWFnZSB0aGUgdHdvIGFyZSB0aGUgc2FtZSB0aGluZy4gVGFrZW4gYXMgd29ybGQgdW5pdHMgaXQgYnJlYWtzIG9uIGFueVxuICogZGF0YXNldCB3aG9zZSB3b3JsZCBpcyBzbWFsbCDigJQgc2VxRklTSCdzIHNhbXBsZSBzcGFucyBhYm91dCA1IHVuaXRzLCBzbyBhIDItdW5pdFxuICogdGhyZXNob2xkIHJlY29yZHMgYSBwb2ludCBldmVyeSA0MCUgb2YgdGhlIHdheSBhY3Jvc3MgYW5kIGEgZnJlZWhhbmQgUk9JIGNvbWVzIG91dCBhcyBhXG4gKiB0cmlhbmdsZS4gQWdhaW5zdCB0aGUgc2NyZWVuIGl0IGFsc28gZG9lcyB0aGUgcmlnaHQgdGhpbmcgdW5kZXIgem9vbTogZHJhd2luZyB6b29tZWQgaW5cbiAqIHJlY29yZHMgYSBmaW5lciBwYXRoLCBiZWNhdXNlIHRoYXQgaXMgZXhhY3RseSB3aGVuIHRoZSBleHRyYSBkZXRhaWwgaXMgdmlzaWJsZS5cbiAqL1xuY29uc3QgRlJFRUhBTkRfU1RFUF9QWCA9IDI7XG4vKipcbiAqIFNtYWxsZXN0IGNvbW1pdHRlZCByZWN0YW5nbGUsIGluIFNDUkVFTiBwaXhlbHMgb24gZWFjaCBzaWRlLlxuICpcbiAqIEl0cyBqb2IgaXMgdG8gdGhyb3cgYXdheSBhIGNsaWNrIHRoYXQgd2FzIG5vdCBhIGRyYWcuIEhlbGQgaW4gd29ybGQgdW5pdHMg4oCUIHdoaWNoIGl0IHdhc1xuICog4oCUIGl0IGluc3RlYWQgdGhyb3dzIGF3YXkgcmVhbCBkcmFncyBvbiBhbnkgZGF0YXNldCB3aG9zZSB3b3JsZCBpcyBzbWFsbDogaW4gc2VxRklTSCdzXG4gKiB+NSB4IDcgdW5pdCBzYW1wbGUgYSByZWN0YW5nbGUgaGFkIHRvIGNvdmVyIDQwJSBvZiB0aGUgd2lkdGggdG8gY29tbWl0IGF0IGFsbCwgYW5kXG4gKiBhbnl0aGluZyBzbWFsbGVyIHZhbmlzaGVkIHdpdGggbm8gZmVlZGJhY2suIFRoYXQgd2FzIHRoZSBkaXJlY3QgY2F1c2Ugb2YgUk9JcyBiZWluZ1xuICogaW1wb3NzaWJsZSB0byBjcmVhdGUgdGhlcmUuXG4gKi9cbmNvbnN0IE1JTl9SRUNUX0RSQUdfUFggPSAyO1xuLyoqIENsaWNrLWRpc3RhbmNlIChzY3JlZW4gcHgpIHdpdGhpbiB3aGljaCBhIHBvbHlnb24gY2xpY2sgc25hcHMgY2xvc2VkIG9udG8gdGhlIGZpcnN0IHZlcnRleC4gKi9cbmNvbnN0IENMT1NFX1NOQVBfUFggPSAxMDtcbi8qKiBTY3JlZW4tcHggaGl0IHJhZGl1cyBmb3IgZ3JhYmJpbmcgYSB2ZXJ0ZXggLyByZWN0YW5nbGUgY29ybmVyIGhhbmRsZS4gKi9cbmNvbnN0IEhBTkRMRV9ISVRfUFggPSA5O1xuLyoqIFJlbmRlcmVkIGhhbmRsZSBzaXplIChzY3JlZW4gcHgpLiAqL1xuY29uc3QgSEFORExFX1NJWkUgPSA3O1xuXG4vKipcbiAqIFRoZSBzbGljZSBvZiB0aGUgbmFwYXJpIFZpZXdlciB0aGUgb3ZlcmxheSBuZWVkcyAoY29vcmQgdHJhbnNmb3JtcyArIGNvbnRyb2wgZ2F0aW5nKS5cbiAqXG4gKiBFeHBvcnRlZCBiZWNhdXNlIHRoZSAzRCBzcGF0aWFsIG1vZGUgc3VwcGxpZXMgYSBTQ1JFRU4tU1BBQ0UgaW1wbGVtZW50YXRpb24gb2YgaXQ6IHRoZXJlIHRoZVxuICogZHJhd24gc2hhcGUgaXMgYSBsYXNzbyBpbiBjYW52YXMgcGl4ZWxzLCBub3QgYSByZWN0YW5nbGUgaW4gaW1hZ2Ugc3BhY2UsIHNvIFwid29ybGRcIiBpcyB0aGVcbiAqIGNhbnZhcyBpdHNlbGYgYW5kIGJvdGggdHJhbnNmb3JtcyBjb2xsYXBzZSB0byBpZGVudGl0eS4gVGhhdCBsZXRzIHRoZSAzRCB2aWV3IHJldXNlIHRoaXMgd2hvbGVcbiAqIG92ZXJsYXkg4oCUIGV2ZXJ5IHRvb2wsIHRoZSBoYW5kbGVzLCB0aGUgc3RvcmUgcm91bmQtdHJpcCDigJQgd2l0aCBubyAzRC1zcGVjaWZpYyBkcmF3aW5nIGNvZGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT3ZlcmxheVZpZXdlciB7XG4gIGNhbnZhc1RvV29ybGQoY2xpZW50WDogbnVtYmVyLCBjbGllbnRZOiBudW1iZXIpOiBbbnVtYmVyLCBudW1iZXJdO1xuICB3b3JsZFRvQ2FudmFzKHdvcmxkWDogbnVtYmVyLCB3b3JsZFk6IG51bWJlcik6IFtudW1iZXIsIG51bWJlcl07XG4gIHNldENvbnRyb2xzRW5hYmxlZChlbmFibGVkOiBib29sZWFuKTogdm9pZDtcbiAgcmVhZG9ubHkgY2FtZXJhOiB7IHJlYWRvbmx5IGNoYW5nZWQ6IHsgY29ubmVjdChsaXN0ZW5lcjogKCkgPT4gdm9pZCk6ICgpID0+IHZvaWQgfSB9O1xufVxuXG4vKipcbiAqIFNWRyByZWdpb24gb3ZlcmxheSBmb3IgdGhlIG5hcGFyaS1qcyBXZWJHUFUgaW1hZ2UgdmlldyAoaml0LXVpIzEwMiksIG1pcnJvcmluZyB0aGUgT1NEIGJhY2tlbmQnc1xuICoge0BsaW5rIE9zZFJlZ2lvbk92ZXJsYXl9IGJ1dCBkcml2ZW4gYnkgbmFwYXJpJ3MgYGNhbnZhc1RvV29ybGRgL2B3b3JsZFRvQ2FudmFzYCB0cmFuc2Zvcm1zLlxuICogVmVjdG9yIHNoYXBlcyBhcmUgZHJhd24gaW4gYW4gYWJzb2x1dGVseS1wb3NpdGlvbmVkIGA8c3ZnPmAgb3ZlciB0aGUgY2FudmFzIChubyBuZWVkIHRvIHB1c2hcbiAqIHRoZW0gdGhyb3VnaCBXZWJHUFUpLiBJdCB3cml0ZXMgY29tcGxldGVkIHNoYXBlcyB0byB0aGUgc2hhcmVkIHtAbGluayBSZWdpb25TdG9yZX0gKHNvIHNhdmUgL1xuICogdW5kbyAvIGV4cG9ydCB3b3JrIGlkZW50aWNhbGx5IHRvIE9TRCkgYW5kIHJlLXJlbmRlcnMgZnJvbSB0aGUgc3RvcmUgb24gZXZlcnkgY2FtZXJhIG1vdmUsXG4gKiByZWdpb24gY2hhbmdlLCBhbmQgc2VsZWN0aW9uIGNoYW5nZS5cbiAqXG4gKiBTdXBwb3J0cyAoaml0LXVpIzEwMik6IHJlY3RhbmdsZSAvIHBvbHlnb24gLyBmcmVlaGFuZCBwYXRoIGRyYXdpbmcsIGNsaWNrLXNlbGVjdCBhbmQgcnViYmVyLWJhbmRcbiAqIG1hcnF1ZWUgc2VsZWN0LCBwYW4vem9vbSBnYXRpbmcgdmlhIGBzZXRDb250cm9sc0VuYWJsZWRgLCBib2R5IG1vdmUsIHZlcnRleCBtb3ZlL2FkZC9kZWxldGUsXG4gKiBiZXppZXIgaGFuZGxlIGVkaXRpbmcsIGFuZCBkb251dCBob2xlcyAoaW5jbHVkaW5nIGhvbGUgdmVydGV4ICsgaG9sZS1iZXppZXItaGFuZGxlIGVkaXRpbmcpIOKAlFxuICogZnVsbCBwYXJpdHkgd2l0aCB7QGxpbmsgT3NkUmVnaW9uT3ZlcmxheX0uXG4gKi9cbmV4cG9ydCBjbGFzcyBOYXBhcmlSZWdpb25PdmVybGF5IGltcGxlbWVudHMgSVJlZ2lvbk92ZXJsYXkge1xuICBwcml2YXRlIHJlYWRvbmx5IHN2ZzogU1ZHU1ZHRWxlbWVudDtcbiAgcHJpdmF0ZSByZWFkb25seSBzdWJzID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuICBwcml2YXRlIHJlYWRvbmx5IGRpc2Nvbm5lY3RDYW1lcmE6ICgpID0+IHZvaWQ7XG5cbiAgcHJpdmF0ZSBtb2RlOiBSZWdpb25Ub29sTW9kZSA9ICdub25lJztcbiAgcHJpdmF0ZSBzZWxlY3RlZDogbnVtYmVyW10gPSBbXTtcblxuICAvKiogSW4tcHJvZ3Jlc3MgZHJhd2luZyBzdGF0ZSAoaW1hZ2Utc3BhY2UpLiAqL1xuICBwcml2YXRlIGRyYWZ0UmVjdDogeyB4MDogbnVtYmVyOyB5MDogbnVtYmVyOyB4MTogbnVtYmVyOyB5MTogbnVtYmVyIH0gfCBudWxsID0gbnVsbDtcbiAgLyoqIEluLXByb2dyZXNzIHJ1YmJlci1iYW5kIHNlbGVjdGlvbiBtYXJxdWVlIChzZWxlY3QgbW9kZSksIGltYWdlLXNwYWNlLiAqL1xuICBwcml2YXRlIG1hcnF1ZWU6IHsgeDA6IG51bWJlcjsgeTA6IG51bWJlcjsgeDE6IG51bWJlcjsgeTE6IG51bWJlciB9IHwgbnVsbCA9IG51bGw7XG4gIC8qKiBEZWRpY2F0ZWQgbWFycXVlZSByZWN0IGVsZW1lbnQsIHVwZGF0ZWQgZGlyZWN0bHkgZHVyaW5nIHRoZSBkcmFnIChubyBmdWxsIHJlZ2lvbiByZWRyYXcpLiAqL1xuICBwcml2YXRlIG1hcnF1ZWVFbDogU1ZHUmVjdEVsZW1lbnQgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBkcmFmdFBhdGg6IEFycmF5PFtudW1iZXIsIG51bWJlcl0+IHwgbnVsbCA9IG51bGw7IC8vIGZyZWVoYW5kIG9yIGNsaWNrIHBvbHlnb25cbiAgcHJpdmF0ZSBkcmF3aW5nID0gZmFsc2U7IC8vIHBvaW50ZXIgaXMgZG93biBmb3IgcmVjdCAvIGZyZWVoYW5kXG4gIHByaXZhdGUgcmVnaW9uc1Zpc2libGUgPSB0cnVlO1xuXG4gIC8qKiBJbi1wcm9ncmVzcyBtYW5pcHVsYXRpb24gKHNlbGVjdC9tb3ZlIG1vZGVzKTogZHJhZ2dpbmcgYSBib2R5LCBhIHBvbHlnb24gdmVydGV4LCBvciBhXG4gICAqICByZWN0YW5nbGUgY29ybmVyLiBgYW5jaG9yYCBpcyB0aGUgZml4ZWQgb3Bwb3NpdGUgY29ybmVyIGZvciBhIHJlY3RhbmdsZSByZXNpemUuICovXG4gIHByaXZhdGUgZWRpdDoge1xuICAgIGtpbmQ6ICdib2R5JyB8ICd2ZXJ0ZXgnIHwgJ2Nvcm5lcicgfCAnYmV6aWVyJyB8ICdob2xldmVydGV4JyB8ICdob2xlYmV6aWVyJztcbiAgICBpZDogbnVtYmVyO1xuICAgIHZlcnRleEluZGV4PzogbnVtYmVyO1xuICAgIGhvbGVJbmRleD86IG51bWJlcjtcbiAgICBzaWRlPzogJ2luJyB8ICdvdXQnO1xuICAgIGFuY2hvcj86IFtudW1iZXIsIG51bWJlcl07XG4gICAgbGFzdDogW251bWJlciwgbnVtYmVyXTtcbiAgfSB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgaG9zdDogSFRNTEVsZW1lbnQsXG4gICAgcHJpdmF0ZSByZWFkb25seSB2aWV3ZXI6IE92ZXJsYXlWaWV3ZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSBzdG9yZTogUmVnaW9uU3RvcmUsXG4gICkge1xuICAgIGlmIChnZXRDb21wdXRlZFN0eWxlKGhvc3QpLnBvc2l0aW9uID09PSAnc3RhdGljJykgaG9zdC5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XG4gICAgdGhpcy5zdmcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoU1ZHX05TLCAnc3ZnJyk7XG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLnN2Zy5zdHlsZSwge1xuICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICBpbnNldDogJzAnLFxuICAgICAgd2lkdGg6ICcxMDAlJyxcbiAgICAgIGhlaWdodDogJzEwMCUnLFxuICAgICAgekluZGV4OiAnMjAnLFxuICAgICAgcG9pbnRlckV2ZW50czogJ25vbmUnLCAvLyB1bnRpbCBhIHRvb2wgYWN0aXZhdGVzXG4gICAgICB0b3VjaEFjdGlvbjogJ25vbmUnLFxuICAgIH0gYXMgUGFydGlhbDxDU1NTdHlsZURlY2xhcmF0aW9uPik7XG4gICAgdGhpcy5ob3N0LmFwcGVuZENoaWxkKHRoaXMuc3ZnKTtcblxuICAgIHRoaXMuc3ZnLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJkb3duJywgdGhpcy5vblBvaW50ZXJEb3duKTtcbiAgICB0aGlzLnN2Zy5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVybW92ZScsIHRoaXMub25Qb2ludGVyTW92ZSk7XG4gICAgdGhpcy5zdmcuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcnVwJywgdGhpcy5vblBvaW50ZXJVcCk7XG4gICAgdGhpcy5zdmcuYWRkRXZlbnRMaXN0ZW5lcignZGJsY2xpY2snLCB0aGlzLm9uRGJsQ2xpY2spO1xuXG4gICAgdGhpcy5zdWJzLmFkZCh0aGlzLnN0b3JlLmdldFJlZ2lvblVwZGF0ZUV2ZW50KCkuc3Vic2NyaWJlKCgpID0+IHRoaXMucmVkcmF3KCkpKTtcbiAgICB0aGlzLnN1YnMuYWRkKFxuICAgICAgdGhpcy5zdG9yZS5nZXRTZWxlY3RlZFNoYXBlSW5kaWNlcyQoKS5zdWJzY3JpYmUoKGlkeCkgPT4ge1xuICAgICAgICB0aGlzLnNlbGVjdGVkID0gaWR4ID8/IFtdO1xuICAgICAgICB0aGlzLnJlZHJhdygpO1xuICAgICAgfSksXG4gICAgKTtcbiAgICB0aGlzLmRpc2Nvbm5lY3RDYW1lcmEgPSB0aGlzLnZpZXdlci5jYW1lcmEuY2hhbmdlZC5jb25uZWN0KCgpID0+IHRoaXMucmVkcmF3KCkpO1xuICAgIHRoaXMucmVkcmF3KCk7XG4gIH1cblxuICAvLyDilIDilIAgSVJlZ2lvbk92ZXJsYXkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gIC8qKlxuICAgKiBXaGV0aGVyIGEgcmVnaW9uIHRvb2wgY3VycmVudGx5IG93bnMgdGhlIHBvaW50ZXIuXG4gICAqXG4gICAqIEV4cG9zZWQgc28gdGhlIHNwYXRpYWwgdmlld3MgY2FuIHRlbGwgYSBiYXJlIGNsaWNrIG9uIHRoZSBjbG91ZCAoc2VsZWN0IHRoZVxuICAgKiBjbGFzcyB1bmRlciB0aGUgY3Vyc29yKSBmcm9tIGEgY2xpY2sgdGhhdCBiZWxvbmdzIHRvIGEgZHJhd2luZyBnZXN0dXJlIOKAlFxuICAgKiBwbGFjaW5nIGEgcG9seWdvbiB2ZXJ0ZXggaXMgYWxzbyBhIGNsaWNrIHRoYXQgZG9lcyBub3QgbW92ZSwgYW5kIGl0IG11c3Qgbm90XG4gICAqIGNoYW5nZSB0aGUgc2VsZWN0aW9uIGJlaGluZCB0aGUgc2hhcGUgYmVpbmcgZHJhd24uXG4gICAqL1xuICBnZXQgdG9vbEFjdGl2ZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5tb2RlICE9PSAnbm9uZSc7XG4gIH1cblxuICBzZXRNb2RlKG1vZGU6IFJlZ2lvblRvb2xNb2RlKTogdm9pZCB7XG4gICAgdGhpcy5tb2RlID0gbW9kZTtcbiAgICB0aGlzLmRyYWZ0UmVjdCA9IG51bGw7XG4gICAgdGhpcy5kcmFmdFBhdGggPSBudWxsO1xuICAgIHRoaXMubWFycXVlZSA9IG51bGw7XG4gICAgdGhpcy5jbGVhck1hcnF1ZWVFbCgpO1xuICAgIHRoaXMuZHJhd2luZyA9IGZhbHNlO1xuICAgIC8vIFRoZSBvdmVybGF5IG93bnMgcG9pbnRlci9uYXZpZ2F0aW9uIGdhdGluZzogd2hpbGUgYSB0b29sIGlzIGFjdGl2ZSBpdCBjYXB0dXJlcyB0aGUgcG9pbnRlclxuICAgIC8vIGFuZCB0aGUgbmFwYXJpIGNhbWVyYSBjb250cm9scyBhcmUgZGlzYWJsZWQ7ICdub25lJyBoYW5kcyB0aGUgcG9pbnRlciBiYWNrIGZvciBwYW4vem9vbS5cbiAgICBjb25zdCBhY3RpdmUgPSBtb2RlICE9PSAnbm9uZSc7XG4gICAgdGhpcy52aWV3ZXIuc2V0Q29udHJvbHNFbmFibGVkKCFhY3RpdmUpO1xuICAgIHRoaXMuc3ZnLnN0eWxlLnBvaW50ZXJFdmVudHMgPSBhY3RpdmUgPyAnYXV0bycgOiAnbm9uZSc7XG4gICAgdGhpcy5zdmcuc3R5bGUuY3Vyc29yID0gYWN0aXZlID8gJ2Nyb3NzaGFpcicgOiAnZGVmYXVsdCc7XG4gICAgdGhpcy5yZWRyYXcoKTtcbiAgfVxuXG4gIHNldFNlbGVjdGVkQmV6aWVyKGJlemllcjogYm9vbGVhbik6IHZvaWQge1xuICAgIGNvbnN0IHNlbCA9IHRoaXMuc2VsZWN0ZWRSZWdpb24oKTtcbiAgICBpZiAoc2VsPy5pZCAhPSBudWxsKSB0aGlzLnN0b3JlLnNldEJlemllcihzZWwuaWQsIGJlemllcik7XG4gIH1cblxuICAvKipcbiAgICogSG93IGZpbmVseSBhIGRyYXduIHZlcnRleCBtYXkgYmUgcGxhY2VkLCBpbiB3b3JsZCB1bml0cy5cbiAgICpcbiAgICogT25lIGJ5IGRlZmF1bHQsIGJlY2F1c2UgZm9yIGFuIGltYWdlIHRoZSB3b3JsZCBJUyBwaXhlbHMgYW5kIGEgcmVnaW9uIHNob3VsZCBhbGlnbiB0b1xuICAgKiB0aGVtLiBBIGRhdGFzZXQgd2hvc2UgY29vcmRpbmF0ZXMgYXJlIG5vdCBwaXhlbHMgc2V0cyBpdCBmaW5lciDigJQgc2VxRklTSCdzIHdob2xlXG4gICAqIHNhbXBsZSBzcGFucyBhYm91dCA1IHggNyB1bml0cywgd2hlcmUgd2hvbGUtdW5pdCB2ZXJ0aWNlcyBsZWF2ZSByb3VnaGx5IHNpeCBieSBlaWdodFxuICAgKiBwbGFjZWFibGUgcG9zaXRpb25zIGFuZCBubyBST0kgY2FuIGJlIGRyYXduIGF0IGFsbC5cbiAgICovXG4gIHByaXZhdGUgd29ybGRRdWFudHVtID0gUElYRUxfV09STERfUVVBTlRVTTtcblxuICBzZXRXb3JsZFF1YW50dW0ocXVhbnR1bTogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy53b3JsZFF1YW50dW0gPSBOdW1iZXIuaXNGaW5pdGUocXVhbnR1bSkgJiYgcXVhbnR1bSA+IDBcbiAgICAgID8gcXVhbnR1bVxuICAgICAgOiBQSVhFTF9XT1JMRF9RVUFOVFVNO1xuICB9XG5cbiAgZGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLnN2Zy5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVyZG93bicsIHRoaXMub25Qb2ludGVyRG93bik7XG4gICAgdGhpcy5zdmcucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcm1vdmUnLCB0aGlzLm9uUG9pbnRlck1vdmUpO1xuICAgIHRoaXMuc3ZnLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJ1cCcsIHRoaXMub25Qb2ludGVyVXApO1xuICAgIHRoaXMuc3ZnLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2RibGNsaWNrJywgdGhpcy5vbkRibENsaWNrKTtcbiAgICB0aGlzLmRpc2Nvbm5lY3RDYW1lcmEoKTtcbiAgICB0aGlzLnN1YnMudW5zdWJzY3JpYmUoKTtcbiAgICBpZiAodGhpcy5zdmcucGFyZW50Tm9kZSkgdGhpcy5zdmcucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLnN2Zyk7XG4gIH1cblxuICAvLyDilIDilIAgY29vcmRpbmF0ZSB0cmFuc2Zvcm1zIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAvKiogUG9pbnRlciBjbGllbnQgY29vcmRzIOKGkiB3b3JsZCBjb29yZHMsIHNuYXBwZWQgdG8ge0BsaW5rIHdvcmxkUXVhbnR1bX0uICovXG4gIHByaXZhdGUgdG9JbWFnZShjbGllbnRYOiBudW1iZXIsIGNsaWVudFk6IG51bWJlcik6IFtudW1iZXIsIG51bWJlcl0ge1xuICAgIGNvbnN0IFt3eCwgd3ldID0gdGhpcy52aWV3ZXIuY2FudmFzVG9Xb3JsZChjbGllbnRYLCBjbGllbnRZKTtcbiAgICByZXR1cm4gW1xuICAgICAgc25hcFRvV29ybGRHcmlkKHd4LCB0aGlzLndvcmxkUXVhbnR1bSksXG4gICAgICBzbmFwVG9Xb3JsZEdyaWQod3ksIHRoaXMud29ybGRRdWFudHVtKSxcbiAgICBdO1xuICB9XG5cbiAgLyoqXG4gICAqIFdvcmxkIHVuaXRzIHNwYW5uZWQgYnkgb25lIHNjcmVlbiBwaXhlbCwgbWVhc3VyZWQgdGhyb3VnaCB0aGUgdmlld2VyJ3Mgb3duIHRyYW5zZm9ybS5cbiAgICpcbiAgICogUmVhZCBmcm9tIHRoZSB0cmFuc2Zvcm0gcmF0aGVyIHRoYW4gZnJvbSB0aGUgY2FtZXJhLCBzbyBpdCBob2xkcyBmb3IgYm90aCB0aGUgMkQgYW5kXG4gICAqIHRoZSAzRCBzY3JlZW4tc3BhY2UgYWRhcHRlcnMgd2l0aG91dCBlaXRoZXIgaGF2aW5nIHRvIGV4cG9zZSBhIHpvb20uIEZhbGxzIGJhY2sgdG8gMVxuICAgKiBpZiB0aGUgdHJhbnNmb3JtIGdpdmVzIG5vdGhpbmcgdXNhYmxlLCB3aGljaCBrZWVwcyB0aGUgZXN0YWJsaXNoZWQgcGl4ZWwgYmVoYXZpb3VyXG4gICAqIHJhdGhlciB0aGFuIGNvbGxhcHNpbmcgdGhlIHRocmVzaG9sZCB0byB6ZXJvIGFuZCByZWNvcmRpbmcgYSBwb2ludCBwZXIgZXZlbnQuXG4gICAqL1xuICBwcml2YXRlIHdvcmxkUGVyQ2FudmFzUGl4ZWwoKTogbnVtYmVyIHtcbiAgICBjb25zdCBbeDBdID0gdGhpcy52aWV3ZXIuY2FudmFzVG9Xb3JsZCgwLCAwKTtcbiAgICBjb25zdCBbeDFdID0gdGhpcy52aWV3ZXIuY2FudmFzVG9Xb3JsZCgxLCAwKTtcbiAgICBjb25zdCBwZXIgPSBNYXRoLmFicyh4MSAtIHgwKTtcbiAgICByZXR1cm4gTnVtYmVyLmlzRmluaXRlKHBlcikgJiYgcGVyID4gMCA/IHBlciA6IDE7XG4gIH1cblxuICAvKiogSW1hZ2UgY29vcmRzIOKGkiBTVkctbG9jYWwgcHggKHRoZSBzdmcgb3ZlcmxheXMgdGhlIGNhbnZhcyBhdCB0aGUgc2FtZSBjbGllbnQgcmVjdCkuICovXG4gIHByaXZhdGUgdG9Mb2NhbChpbWdYOiBudW1iZXIsIGltZ1k6IG51bWJlcik6IFtudW1iZXIsIG51bWJlcl0ge1xuICAgIGNvbnN0IFtjeCwgY3ldID0gdGhpcy52aWV3ZXIud29ybGRUb0NhbnZhcyhpbWdYLCBpbWdZKTtcbiAgICBjb25zdCByID0gdGhpcy5zdmcuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgcmV0dXJuIFtjeCAtIHIubGVmdCwgY3kgLSByLnRvcF07XG4gIH1cblxuICAvLyDilIDilIAgcG9pbnRlciBoYW5kbGVycyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgcHJpdmF0ZSByZWFkb25seSBvblBvaW50ZXJEb3duID0gKGU6IFBvaW50ZXJFdmVudCk6IHZvaWQgPT4ge1xuICAgIGlmICh0aGlzLm1vZGUgPT09ICdub25lJykgcmV0dXJuO1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBjb25zdCBbaXgsIGl5XSA9IHRoaXMudG9JbWFnZShlLmNsaWVudFgsIGUuY2xpZW50WSk7XG4gICAgaWYgKHRoaXMubW9kZSA9PT0gJ2RyYXdyZWN0Jykge1xuICAgICAgdGhpcy5kcmFmdFJlY3QgPSB7IHgwOiBpeCwgeTA6IGl5LCB4MTogaXgsIHkxOiBpeSB9O1xuICAgICAgdGhpcy5kcmF3aW5nID0gdHJ1ZTtcbiAgICAgIHRoaXMuc3ZnLnNldFBvaW50ZXJDYXB0dXJlKGUucG9pbnRlcklkKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMubW9kZSA9PT0gJ2RyYXdjbG9zZWRwYXRoJyB8fCB0aGlzLm1vZGUgPT09ICdkcmF3b3BlbnBhdGgnKSB7XG4gICAgICB0aGlzLmRyYWZ0UGF0aCA9IFtbaXgsIGl5XV07XG4gICAgICB0aGlzLmRyYXdpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5zdmcuc2V0UG9pbnRlckNhcHR1cmUoZS5wb2ludGVySWQpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5tb2RlID09PSAnZHJhd3BvbHlnb24nKSB7XG4gICAgICB0aGlzLmhhbmRsZVBvbHlnb25DbGljayhpeCwgaXksIGUuY2xpZW50WCwgZS5jbGllbnRZKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMubW9kZSA9PT0gJ3NlbGVjdCcgfHwgdGhpcy5tb2RlID09PSAnbW92ZScpIHtcbiAgICAgIHRoaXMuYmVnaW5NYW5pcHVsYXRpb24oaXgsIGl5LCBlKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMubW9kZSA9PT0gJ2FkZHBvaW50Jykge1xuICAgICAgdGhpcy5oYW5kbGVBZGRQb2ludChpeCwgaXkpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5tb2RlID09PSAnZGVsZXRlcG9pbnQnKSB7XG4gICAgICB0aGlzLmhhbmRsZURlbGV0ZVBvaW50KGl4LCBpeSk7XG4gICAgfVxuICAgIHRoaXMucmVkcmF3KCk7XG4gIH07XG5cbiAgcHJpdmF0ZSByZWFkb25seSBvblBvaW50ZXJNb3ZlID0gKGU6IFBvaW50ZXJFdmVudCk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IFtpeCwgaXldID0gdGhpcy50b0ltYWdlKGUuY2xpZW50WCwgZS5jbGllbnRZKTtcbiAgICBpZiAodGhpcy5tYXJxdWVlKSB7XG4gICAgICB0aGlzLm1hcnF1ZWUueDEgPSBpeDtcbiAgICAgIHRoaXMubWFycXVlZS55MSA9IGl5O1xuICAgICAgdGhpcy51cGRhdGVNYXJxdWVlRWwoKTsgLy8gdXBkYXRlIGp1c3QgdGhlIG1hcnF1ZWUgcmVjdCDigJQgTk9UIGEgZnVsbCByZWdpb24gcmVkcmF3XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLmVkaXQpIHtcbiAgICAgIHRoaXMuYXBwbHlNYW5pcHVsYXRpb24oaXgsIGl5KTtcbiAgICAgIHRoaXMucmVkcmF3KCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghdGhpcy5kcmF3aW5nKSByZXR1cm47XG4gICAgaWYgKHRoaXMuZHJhZnRSZWN0KSB7XG4gICAgICB0aGlzLmRyYWZ0UmVjdC54MSA9IGl4O1xuICAgICAgdGhpcy5kcmFmdFJlY3QueTEgPSBpeTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuZHJhZnRQYXRoKSB7XG4gICAgICBjb25zdCBzdGVwID0gRlJFRUhBTkRfU1RFUF9QWCAqIHRoaXMud29ybGRQZXJDYW52YXNQaXhlbCgpO1xuICAgICAgY29uc3QgbGFzdCA9IHRoaXMuZHJhZnRQYXRoW3RoaXMuZHJhZnRQYXRoLmxlbmd0aCAtIDFdO1xuICAgICAgaWYgKE1hdGguYWJzKGl4IC0gbGFzdFswXSkgPj0gc3RlcCB8fCBNYXRoLmFicyhpeSAtIGxhc3RbMV0pID49IHN0ZXApIHtcbiAgICAgICAgdGhpcy5kcmFmdFBhdGgucHVzaChbaXgsIGl5XSk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMucmVkcmF3KCk7XG4gIH07XG5cbiAgcHJpdmF0ZSByZWFkb25seSBvblBvaW50ZXJVcCA9IChlOiBQb2ludGVyRXZlbnQpOiB2b2lkID0+IHtcbiAgICBpZiAodGhpcy5tYXJxdWVlKSB7XG4gICAgICBjb25zdCBtID0gdGhpcy5tYXJxdWVlO1xuICAgICAgdGhpcy5tYXJxdWVlID0gbnVsbDtcbiAgICAgIHRoaXMuY2xlYXJNYXJxdWVlRWwoKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRoaXMuc3ZnLnJlbGVhc2VQb2ludGVyQ2FwdHVyZShlLnBvaW50ZXJJZCk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLyogYWxyZWFkeSByZWxlYXNlZCAqL1xuICAgICAgfVxuICAgICAgdGhpcy5maW5pc2hNYXJxdWVlKG0pOyAvLyBzZXRTZWxlY3RlZFNoYXBlSW5kaWNlcyDihpIgb25lIHJlZHJhdyB2aWEgdGhlIHNlbGVjdGlvbiBzdWJzY3JpcHRpb25cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMuZWRpdCkge1xuICAgICAgdGhpcy5zdG9yZS5lbmRCYXRjaCgpO1xuICAgICAgdGhpcy5lZGl0ID0gbnVsbDtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRoaXMuc3ZnLnJlbGVhc2VQb2ludGVyQ2FwdHVyZShlLnBvaW50ZXJJZCk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLyogYWxyZWFkeSByZWxlYXNlZCAqL1xuICAgICAgfVxuICAgICAgdGhpcy5yZWRyYXcoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCF0aGlzLmRyYXdpbmcpIHJldHVybjtcbiAgICB0aGlzLmRyYXdpbmcgPSBmYWxzZTtcbiAgICB0cnkge1xuICAgICAgdGhpcy5zdmcucmVsZWFzZVBvaW50ZXJDYXB0dXJlKGUucG9pbnRlcklkKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8qIGNhcHR1cmUgbWF5IGFscmVhZHkgYmUgcmVsZWFzZWQgKi9cbiAgICB9XG4gICAgaWYgKHRoaXMuZHJhZnRSZWN0KSB7XG4gICAgICBjb25zdCB7IHgwLCB5MCwgeDEsIHkxIH0gPSB0aGlzLmRyYWZ0UmVjdDtcbiAgICAgIGNvbnN0IHggPSBNYXRoLm1pbih4MCwgeDEpO1xuICAgICAgY29uc3QgeSA9IE1hdGgubWluKHkwLCB5MSk7XG4gICAgICBjb25zdCB3ID0gTWF0aC5hYnMoeDEgLSB4MCk7XG4gICAgICBjb25zdCBoID0gTWF0aC5hYnMoeTEgLSB5MCk7XG4gICAgICB0aGlzLmRyYWZ0UmVjdCA9IG51bGw7XG4gICAgICBjb25zdCBtaW4gPSBNSU5fUkVDVF9EUkFHX1BYICogdGhpcy53b3JsZFBlckNhbnZhc1BpeGVsKCk7XG4gICAgICBpZiAodyA+PSBtaW4gJiYgaCA+PSBtaW4pIHRoaXMuY29tbWl0UmVjdGFuZ2xlKHgsIHksIHcsIGgpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5kcmFmdFBhdGgpIHtcbiAgICAgIGNvbnN0IHB0cyA9IHRoaXMuZHJhZnRQYXRoO1xuICAgICAgdGhpcy5kcmFmdFBhdGggPSBudWxsO1xuICAgICAgY29uc3QgY2xvc2VkID0gdGhpcy5tb2RlID09PSAnZHJhd2Nsb3NlZHBhdGgnO1xuICAgICAgaWYgKHB0cy5sZW5ndGggPj0gKGNsb3NlZCA/IDMgOiAyKSkgdGhpcy5jb21taXRQb2x5Z29uKHB0cywgY2xvc2VkKTtcbiAgICB9XG4gICAgdGhpcy5yZWRyYXcoKTtcbiAgfTtcblxuICAvKiogQ2xpY2stdG8tcGxhY2UgcG9seWdvbjogYWRkIGEgdmVydGV4LCBvciBjbG9zZSB3aGVuIGNsaWNraW5nIG5lYXIgdGhlIGZpcnN0IG9uZS4gKi9cbiAgcHJpdmF0ZSBoYW5kbGVQb2x5Z29uQ2xpY2soaXg6IG51bWJlciwgaXk6IG51bWJlciwgY2xpZW50WDogbnVtYmVyLCBjbGllbnRZOiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZHJhZnRQYXRoKSB7XG4gICAgICB0aGlzLmRyYWZ0UGF0aCA9IFtbaXgsIGl5XV07XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IFtmeCwgZnldID0gdGhpcy50b0xvY2FsKHRoaXMuZHJhZnRQYXRoWzBdWzBdLCB0aGlzLmRyYWZ0UGF0aFswXVsxXSk7XG4gICAgY29uc3QgciA9IHRoaXMuc3ZnLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IG5lYXIgPVxuICAgICAgTWF0aC5oeXBvdChjbGllbnRYIC0gci5sZWZ0IC0gZngsIGNsaWVudFkgLSByLnRvcCAtIGZ5KSA8PSBDTE9TRV9TTkFQX1BYICYmXG4gICAgICB0aGlzLmRyYWZ0UGF0aC5sZW5ndGggPj0gMztcbiAgICBpZiAobmVhcikge1xuICAgICAgY29uc3QgcHRzID0gdGhpcy5kcmFmdFBhdGg7XG4gICAgICB0aGlzLmRyYWZ0UGF0aCA9IG51bGw7XG4gICAgICB0aGlzLmNvbW1pdFBvbHlnb24ocHRzLCB0cnVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5kcmFmdFBhdGgucHVzaChbaXgsIGl5XSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWFkb25seSBvbkRibENsaWNrID0gKGU6IE1vdXNlRXZlbnQpOiB2b2lkID0+IHtcbiAgICBpZiAodGhpcy5tb2RlICE9PSAnZHJhd3BvbHlnb24nIHx8ICF0aGlzLmRyYWZ0UGF0aCkgcmV0dXJuO1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBjb25zdCBwdHMgPSB0aGlzLmRyYWZ0UGF0aDtcbiAgICB0aGlzLmRyYWZ0UGF0aCA9IG51bGw7XG4gICAgaWYgKHB0cy5sZW5ndGggPj0gMykgdGhpcy5jb21taXRQb2x5Z29uKHB0cywgdHJ1ZSk7XG4gICAgdGhpcy5yZWRyYXcoKTtcbiAgfTtcblxuICAvKiogVGhlIGN1cnJlbnRseS1zZWxlY3RlZCByZWdpb24gKHNpbmdsZSBzZWxlY3Rpb24pLCBvciBudWxsLiAqL1xuICBwcml2YXRlIHNlbGVjdGVkUmVnaW9uKCk6IFJlZ2lvbiB8IG51bGwge1xuICAgIGNvbnN0IHJlZ2lvbnMgPSB0aGlzLnN0b3JlLmdldFJlZ2lvbnMoKTtcbiAgICBjb25zdCBpID0gdGhpcy5zZWxlY3RlZFswXTtcbiAgICByZXR1cm4gaSAhPSBudWxsICYmIGkgPj0gMCAmJiBpIDwgcmVnaW9ucy5sZW5ndGggPyByZWdpb25zW2ldIDogbnVsbDtcbiAgfVxuXG4gIC8qKiBTY3JlZW4gZGlzdGFuY2UgKHB4KSBiZXR3ZWVuIGEgY2xpZW50IHBvaW50IGFuZCBhbiBpbWFnZSBjb29yZC4gKi9cbiAgcHJpdmF0ZSBzY3JlZW5EaXN0KGNsaWVudFg6IG51bWJlciwgY2xpZW50WTogbnVtYmVyLCBpbWdYOiBudW1iZXIsIGltZ1k6IG51bWJlcik6IG51bWJlciB7XG4gICAgY29uc3QgW2x4LCBseV0gPSB0aGlzLnRvTG9jYWwoaW1nWCwgaW1nWSk7XG4gICAgY29uc3QgciA9IHRoaXMuc3ZnLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIHJldHVybiBNYXRoLmh5cG90KGNsaWVudFggLSByLmxlZnQgLSBseCwgY2xpZW50WSAtIHIudG9wIC0gbHkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0IGEgc2VsZWN0L21vdmUgaW50ZXJhY3Rpb246IGdyYWIgYSBoYW5kbGUgKHJlY3RhbmdsZSBjb3JuZXIpIG9yIHZlcnRleCBvZiB0aGUgYWxyZWFkeS1cbiAgICogc2VsZWN0ZWQgcmVnaW9uIGZpcnN0OyBvdGhlcndpc2Ugc2VsZWN0IHRoZSB0b3Btb3N0IHJlZ2lvbiB1bmRlciB0aGUgY3Vyc29yIGFuZCBkcmFnIGl0cyBib2R5LlxuICAgKi9cbiAgcHJpdmF0ZSBiZWdpbk1hbmlwdWxhdGlvbihpeDogbnVtYmVyLCBpeTogbnVtYmVyLCBlOiBQb2ludGVyRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBzZWwgPSB0aGlzLnNlbGVjdGVkUmVnaW9uKCk7XG4gICAgaWYgKHNlbD8uYm91bmRzKSB7XG4gICAgICBjb25zdCBncmFiID0gdGhpcy5oaXRIYW5kbGUoc2VsLCBlLmNsaWVudFgsIGUuY2xpZW50WSk7XG4gICAgICBpZiAoZ3JhYikge1xuICAgICAgICB0aGlzLnN0b3JlLmJlZ2luQmF0Y2goKTtcbiAgICAgICAgdGhpcy5lZGl0ID0geyAuLi5ncmFiLCBpZDogc2VsLmlkLCBsYXN0OiBbaXgsIGl5XSB9O1xuICAgICAgICB0aGlzLnN2Zy5zZXRQb2ludGVyQ2FwdHVyZShlLnBvaW50ZXJJZCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gSGl0LXRlc3QgYm9kaWVzLCB0b3Btb3N0IGZpcnN0IChsYXN0IGRyYXduIHJlbmRlcnMgb24gdG9wKS5cbiAgICBjb25zdCByZWdpb25zID0gdGhpcy5zdG9yZS5nZXRSZWdpb25zKCk7XG4gICAgZm9yIChsZXQgaSA9IHJlZ2lvbnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGlmICh0aGlzLmhpdFRlc3QocmVnaW9uc1tpXSwgaXgsIGl5KSkge1xuICAgICAgICB0aGlzLnN0b3JlLnNlbGVjdFJlZ2lvbihyZWdpb25zW2ldKTtcbiAgICAgICAgdGhpcy5zdG9yZS5iZWdpbkJhdGNoKCk7XG4gICAgICAgIHRoaXMuZWRpdCA9IHsga2luZDogJ2JvZHknLCBpZDogcmVnaW9uc1tpXS5pZCwgbGFzdDogW2l4LCBpeV0gfTtcbiAgICAgICAgdGhpcy5zdmcuc2V0UG9pbnRlckNhcHR1cmUoZS5wb2ludGVySWQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICAgIC8vIEVtcHR5IHNwYWNlOiBpbiBzZWxlY3QgbW9kZSBzdGFydCBhIHJ1YmJlci1iYW5kIG1hcnF1ZWUgKHNlbGVjdHMgdGhlIHJlZ2lvbnMgaXQgY292ZXJzIG9uXG4gICAgLy8gcmVsZWFzZSk7IGluIG1vdmUgbW9kZSBqdXN0IGNsZWFyIHRoZSBzZWxlY3Rpb24uXG4gICAgaWYgKHRoaXMubW9kZSA9PT0gJ3NlbGVjdCcpIHtcbiAgICAgIHRoaXMubWFycXVlZSA9IHsgeDA6IGl4LCB5MDogaXksIHgxOiBpeCwgeTE6IGl5IH07XG4gICAgICB0aGlzLnVwZGF0ZU1hcnF1ZWVFbCgpO1xuICAgICAgdGhpcy5zdmcuc2V0UG9pbnRlckNhcHR1cmUoZS5wb2ludGVySWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnN0b3JlLnNldFNlbGVjdGVkU2hhcGVJbmRpY2VzKFtdKTtcbiAgICB9XG4gIH1cblxuICAvKiogQ3JlYXRlL3VwZGF0ZSB0aGUgbWFycXVlZSByZWN0IGVsZW1lbnQgZGlyZWN0bHkgKGF2b2lkcyBhIGZ1bGwgcmVnaW9uIHJlZHJhdyBwZXIgbW92ZSkuICovXG4gIHByaXZhdGUgdXBkYXRlTWFycXVlZUVsKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5tYXJxdWVlKSByZXR1cm47XG4gICAgaWYgKCF0aGlzLm1hcnF1ZWVFbCB8fCAhdGhpcy5tYXJxdWVlRWwucGFyZW50Tm9kZSkge1xuICAgICAgdGhpcy5tYXJxdWVlRWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoU1ZHX05TLCAncmVjdCcpO1xuICAgICAgdGhpcy5tYXJxdWVlRWwuc2V0QXR0cmlidXRlKCdzdHJva2UnLCAnIzRkYTNmZicpO1xuICAgICAgdGhpcy5tYXJxdWVlRWwuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCAnMScpO1xuICAgICAgdGhpcy5tYXJxdWVlRWwuc2V0QXR0cmlidXRlKCdzdHJva2UtZGFzaGFycmF5JywgJzQgMycpO1xuICAgICAgdGhpcy5tYXJxdWVlRWwuc2V0QXR0cmlidXRlKCdmaWxsJywgJyM0ZGEzZmYnKTtcbiAgICAgIHRoaXMubWFycXVlZUVsLnNldEF0dHJpYnV0ZSgnZmlsbC1vcGFjaXR5JywgJzAuMTInKTtcbiAgICAgIHRoaXMubWFycXVlZUVsLnNldEF0dHJpYnV0ZSgndmVjdG9yLWVmZmVjdCcsICdub24tc2NhbGluZy1zdHJva2UnKTtcbiAgICAgIHRoaXMuc3ZnLmFwcGVuZENoaWxkKHRoaXMubWFycXVlZUVsKTtcbiAgICB9XG4gICAgY29uc3QgeyB4MCwgeTAsIHgxLCB5MSB9ID0gdGhpcy5tYXJxdWVlO1xuICAgIGNvbnN0IFtseCwgbHldID0gdGhpcy50b0xvY2FsKE1hdGgubWluKHgwLCB4MSksIE1hdGgubWluKHkwLCB5MSkpO1xuICAgIGNvbnN0IFtyeCwgcnldID0gdGhpcy50b0xvY2FsKE1hdGgubWF4KHgwLCB4MSksIE1hdGgubWF4KHkwLCB5MSkpO1xuICAgIHRoaXMubWFycXVlZUVsLnNldEF0dHJpYnV0ZSgneCcsIGAke2x4fWApO1xuICAgIHRoaXMubWFycXVlZUVsLnNldEF0dHJpYnV0ZSgneScsIGAke2x5fWApO1xuICAgIHRoaXMubWFycXVlZUVsLnNldEF0dHJpYnV0ZSgnd2lkdGgnLCBgJHtNYXRoLmFicyhyeCAtIGx4KX1gKTtcbiAgICB0aGlzLm1hcnF1ZWVFbC5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsIGAke01hdGguYWJzKHJ5IC0gbHkpfWApO1xuICB9XG5cbiAgLyoqIFJlbW92ZSB0aGUgbWFycXVlZSBlbGVtZW50IGZyb20gdGhlIFNWRy4gKi9cbiAgcHJpdmF0ZSBjbGVhck1hcnF1ZWVFbCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5tYXJxdWVlRWw/LnBhcmVudE5vZGUpIHRoaXMubWFycXVlZUVsLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5tYXJxdWVlRWwpO1xuICAgIHRoaXMubWFycXVlZUVsID0gbnVsbDtcbiAgfVxuXG4gIC8qKiBUZXN0IHdoZXRoZXIgYSBjbGllbnQgcG9pbnQgZ3JhYnMgYSByZWN0YW5nbGUgY29ybmVyIG9yIGEgcG9seWdvbiB2ZXJ0ZXggb2YgYHJlZ2lvbmAuICovXG4gIHByaXZhdGUgaGl0SGFuZGxlKFxuICAgIHJlZ2lvbjogUmVnaW9uLFxuICAgIGNsaWVudFg6IG51bWJlcixcbiAgICBjbGllbnRZOiBudW1iZXIsXG4gICk6XG4gICAgfCB7IGtpbmQ6ICdjb3JuZXInOyBhbmNob3I6IFtudW1iZXIsIG51bWJlcl0gfVxuICAgIHwgeyBraW5kOiAndmVydGV4JzsgdmVydGV4SW5kZXg6IG51bWJlciB9XG4gICAgfCB7IGtpbmQ6ICdiZXppZXInOyB2ZXJ0ZXhJbmRleDogbnVtYmVyOyBzaWRlOiAnaW4nIHwgJ291dCcgfVxuICAgIHwgeyBraW5kOiAnaG9sZXZlcnRleCc7IGhvbGVJbmRleDogbnVtYmVyOyB2ZXJ0ZXhJbmRleDogbnVtYmVyIH1cbiAgICB8IHsga2luZDogJ2hvbGViZXppZXInOyBob2xlSW5kZXg6IG51bWJlcjsgdmVydGV4SW5kZXg6IG51bWJlcjsgc2lkZTogJ2luJyB8ICdvdXQnIH1cbiAgICB8IG51bGwge1xuICAgIGNvbnN0IGIgPSByZWdpb24uYm91bmRzO1xuICAgIGlmICghYikgcmV0dXJuIG51bGw7XG4gICAgaWYgKCd3aWR0aCcgaW4gYiAmJiAneCcgaW4gYikge1xuICAgICAgY29uc3QgciA9IGIgYXMgUmVjdGFuZ2xlO1xuICAgICAgY29uc3QgY29ybmVyczogQXJyYXk8W251bWJlciwgbnVtYmVyLCBbbnVtYmVyLCBudW1iZXJdXT4gPSBbXG4gICAgICAgIFtyLngsIHIueSwgW3IueCArIHIud2lkdGgsIHIueSArIHIuaGVpZ2h0XV0sXG4gICAgICAgIFtyLnggKyByLndpZHRoLCByLnksIFtyLngsIHIueSArIHIuaGVpZ2h0XV0sXG4gICAgICAgIFtyLngsIHIueSArIHIuaGVpZ2h0LCBbci54ICsgci53aWR0aCwgci55XV0sXG4gICAgICAgIFtyLnggKyByLndpZHRoLCByLnkgKyByLmhlaWdodCwgW3IueCwgci55XV0sXG4gICAgICBdO1xuICAgICAgZm9yIChjb25zdCBbY3gsIGN5LCBhbmNob3JdIG9mIGNvcm5lcnMpIHtcbiAgICAgICAgaWYgKHRoaXMuc2NyZWVuRGlzdChjbGllbnRYLCBjbGllbnRZLCBjeCwgY3kpIDw9IEhBTkRMRV9ISVRfUFgpIHJldHVybiB7IGtpbmQ6ICdjb3JuZXInLCBhbmNob3IgfTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKCducG9pbnRzJyBpbiBiKSB7XG4gICAgICBjb25zdCBwID0gYiBhcyBQb2x5Z29uO1xuICAgICAgLy8gQmV6aWVyIGNvbnRyb2wgcG9pbnRzIGZpcnN0ICh0aGV5IHNpdCBvZmYgdGhlIGFuY2hvcnMpLCBzbyB0aGV5J3JlIGdyYWJiYWJsZS5cbiAgICAgIGlmIChwLmJlemllciAmJiBwLmhhbmRsZXNJbj8ubGVuZ3RoID09PSBwLm5wb2ludHMgJiYgcC5oYW5kbGVzT3V0Py5sZW5ndGggPT09IHAubnBvaW50cykge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHAubnBvaW50czsgaSsrKSB7XG4gICAgICAgICAgY29uc3Qgb3V0ID0gcC5oYW5kbGVzT3V0W2ldO1xuICAgICAgICAgIGNvbnN0IGlubiA9IHAuaGFuZGxlc0luW2ldO1xuICAgICAgICAgIGlmICh0aGlzLnNjcmVlbkRpc3QoY2xpZW50WCwgY2xpZW50WSwgcC54cG9pbnRzW2ldICsgb3V0WzBdLCBwLnlwb2ludHNbaV0gKyBvdXRbMV0pIDw9IEhBTkRMRV9ISVRfUFgpIHtcbiAgICAgICAgICAgIHJldHVybiB7IGtpbmQ6ICdiZXppZXInLCB2ZXJ0ZXhJbmRleDogaSwgc2lkZTogJ291dCcgfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHRoaXMuc2NyZWVuRGlzdChjbGllbnRYLCBjbGllbnRZLCBwLnhwb2ludHNbaV0gKyBpbm5bMF0sIHAueXBvaW50c1tpXSArIGlublsxXSkgPD0gSEFORExFX0hJVF9QWCkge1xuICAgICAgICAgICAgcmV0dXJuIHsga2luZDogJ2JlemllcicsIHZlcnRleEluZGV4OiBpLCBzaWRlOiAnaW4nIH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHAubnBvaW50czsgaSsrKSB7XG4gICAgICAgIGlmICh0aGlzLnNjcmVlbkRpc3QoY2xpZW50WCwgY2xpZW50WSwgcC54cG9pbnRzW2ldLCBwLnlwb2ludHNbaV0pIDw9IEhBTkRMRV9ISVRfUFgpIHtcbiAgICAgICAgICByZXR1cm4geyBraW5kOiAndmVydGV4JywgdmVydGV4SW5kZXg6IGkgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gSG9sZSAoZG9udXQpIHJpbmc6IGJlemllciBjb250cm9sIHBvaW50cyBmaXJzdCwgdGhlbiB0aGUgdmVydGljZXMuXG4gICAgICBjb25zdCBob2xlcyA9IHAuaG9sZXMgPz8gW107XG4gICAgICBjb25zdCBob2xlQmV6aWVyID0gISEocC5iZXppZXIgJiYgcC5ob2xlSGFuZGxlc0luICYmIHAuaG9sZUhhbmRsZXNPdXQpO1xuICAgICAgZm9yIChsZXQgaGkgPSAwOyBoaSA8IGhvbGVzLmxlbmd0aDsgaGkrKykge1xuICAgICAgICBjb25zdCByaW5nID0gaG9sZXNbaGldO1xuICAgICAgICBpZiAoaG9sZUJlemllciAmJiBwLmhvbGVIYW5kbGVzSW4hW2hpXSAmJiBwLmhvbGVIYW5kbGVzT3V0IVtoaV0pIHtcbiAgICAgICAgICBmb3IgKGxldCB2aSA9IDA7IHZpIDwgcmluZy5sZW5ndGg7IHZpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IG91dCA9IHAuaG9sZUhhbmRsZXNPdXQhW2hpXVt2aV0gPz8gWzAsIDBdO1xuICAgICAgICAgICAgY29uc3QgaW5uID0gcC5ob2xlSGFuZGxlc0luIVtoaV1bdmldID8/IFswLCAwXTtcbiAgICAgICAgICAgIGlmICh0aGlzLnNjcmVlbkRpc3QoY2xpZW50WCwgY2xpZW50WSwgcmluZ1t2aV1bMF0gKyBvdXRbMF0sIHJpbmdbdmldWzFdICsgb3V0WzFdKSA8PSBIQU5ETEVfSElUX1BYKSB7XG4gICAgICAgICAgICAgIHJldHVybiB7IGtpbmQ6ICdob2xlYmV6aWVyJywgaG9sZUluZGV4OiBoaSwgdmVydGV4SW5kZXg6IHZpLCBzaWRlOiAnb3V0JyB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuc2NyZWVuRGlzdChjbGllbnRYLCBjbGllbnRZLCByaW5nW3ZpXVswXSArIGlublswXSwgcmluZ1t2aV1bMV0gKyBpbm5bMV0pIDw9IEhBTkRMRV9ISVRfUFgpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHsga2luZDogJ2hvbGViZXppZXInLCBob2xlSW5kZXg6IGhpLCB2ZXJ0ZXhJbmRleDogdmksIHNpZGU6ICdpbicgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgdmkgPSAwOyB2aSA8IHJpbmcubGVuZ3RoOyB2aSsrKSB7XG4gICAgICAgICAgaWYgKHRoaXMuc2NyZWVuRGlzdChjbGllbnRYLCBjbGllbnRZLCByaW5nW3ZpXVswXSwgcmluZ1t2aV1bMV0pIDw9IEhBTkRMRV9ISVRfUFgpIHtcbiAgICAgICAgICAgIHJldHVybiB7IGtpbmQ6ICdob2xldmVydGV4JywgaG9sZUluZGV4OiBoaSwgdmVydGV4SW5kZXg6IHZpIH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqIEFwcGx5IHRoZSBsaXZlIGRyYWcgZm9yIHRoZSBhY3RpdmUgbWFuaXB1bGF0aW9uIChpbWFnZSBjb29yZHMgYGl4LGl5YCkuICovXG4gIHByaXZhdGUgYXBwbHlNYW5pcHVsYXRpb24oaXg6IG51bWJlciwgaXk6IG51bWJlcik6IHZvaWQge1xuICAgIGlmICghdGhpcy5lZGl0KSByZXR1cm47XG4gICAgaWYgKHRoaXMuZWRpdC5raW5kID09PSAnYm9keScpIHtcbiAgICAgIGNvbnN0IFtseCwgbHldID0gdGhpcy5lZGl0Lmxhc3Q7XG4gICAgICB0aGlzLnN0b3JlLm1vdmVSZWdpb24odGhpcy5lZGl0LmlkLCBpeCAtIGx4LCBpeSAtIGx5KTtcbiAgICAgIHRoaXMuZWRpdC5sYXN0ID0gW2l4LCBpeV07XG4gICAgfSBlbHNlIGlmICh0aGlzLmVkaXQua2luZCA9PT0gJ3ZlcnRleCcgJiYgdGhpcy5lZGl0LnZlcnRleEluZGV4ICE9IG51bGwpIHtcbiAgICAgIHRoaXMuc3RvcmUubW92ZVZlcnRleCh0aGlzLmVkaXQuaWQsIHRoaXMuZWRpdC52ZXJ0ZXhJbmRleCwgaXgsIGl5KTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuZWRpdC5raW5kID09PSAnY29ybmVyJyAmJiB0aGlzLmVkaXQuYW5jaG9yKSB7XG4gICAgICBjb25zdCBbYXgsIGF5XSA9IHRoaXMuZWRpdC5hbmNob3I7XG4gICAgICBjb25zdCByZWN0ID0gbmV3IFJlY3RhbmdsZSgpO1xuICAgICAgcmVjdC54ID0gTWF0aC5taW4oYXgsIGl4KTtcbiAgICAgIHJlY3QueSA9IE1hdGgubWluKGF5LCBpeSk7XG4gICAgICByZWN0LndpZHRoID0gTWF0aC5hYnMoaXggLSBheCk7XG4gICAgICByZWN0LmhlaWdodCA9IE1hdGguYWJzKGl5IC0gYXkpO1xuICAgICAgdGhpcy5zdG9yZS51cGRhdGVCb3VuZHModGhpcy5lZGl0LmlkLCByZWN0KTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuZWRpdC5raW5kID09PSAnYmV6aWVyJyAmJiB0aGlzLmVkaXQudmVydGV4SW5kZXggIT0gbnVsbCAmJiB0aGlzLmVkaXQuc2lkZSkge1xuICAgICAgdGhpcy5zdG9yZS5tb3ZlQmV6aWVySGFuZGxlKHRoaXMuZWRpdC5pZCwgdGhpcy5lZGl0LnZlcnRleEluZGV4LCB0aGlzLmVkaXQuc2lkZSwgaXgsIGl5KTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgdGhpcy5lZGl0LmtpbmQgPT09ICdob2xldmVydGV4JyAmJlxuICAgICAgdGhpcy5lZGl0LmhvbGVJbmRleCAhPSBudWxsICYmXG4gICAgICB0aGlzLmVkaXQudmVydGV4SW5kZXggIT0gbnVsbFxuICAgICkge1xuICAgICAgdGhpcy5zdG9yZS5tb3ZlSG9sZVZlcnRleCh0aGlzLmVkaXQuaWQsIHRoaXMuZWRpdC5ob2xlSW5kZXgsIHRoaXMuZWRpdC52ZXJ0ZXhJbmRleCwgaXgsIGl5KTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgdGhpcy5lZGl0LmtpbmQgPT09ICdob2xlYmV6aWVyJyAmJlxuICAgICAgdGhpcy5lZGl0LmhvbGVJbmRleCAhPSBudWxsICYmXG4gICAgICB0aGlzLmVkaXQudmVydGV4SW5kZXggIT0gbnVsbCAmJlxuICAgICAgdGhpcy5lZGl0LnNpZGVcbiAgICApIHtcbiAgICAgIHRoaXMuc3RvcmUubW92ZUhvbGVCZXppZXJIYW5kbGUoXG4gICAgICAgIHRoaXMuZWRpdC5pZCxcbiAgICAgICAgdGhpcy5lZGl0LmhvbGVJbmRleCxcbiAgICAgICAgdGhpcy5lZGl0LnZlcnRleEluZGV4LFxuICAgICAgICB0aGlzLmVkaXQuc2lkZSxcbiAgICAgICAgaXgsXG4gICAgICAgIGl5LFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKiogYWRkcG9pbnQgbW9kZTogaW5zZXJ0IGEgdmVydGV4IG9uIHRoZSBzZWxlY3RlZCBwb2x5Z29uJ3MgbmVhcmVzdCBlZGdlIGF0IHRoZSBjbGljay4gKi9cbiAgcHJpdmF0ZSBoYW5kbGVBZGRQb2ludChpeDogbnVtYmVyLCBpeTogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3Qgc2VsID0gdGhpcy5zZWxlY3RlZFJlZ2lvbigpO1xuICAgIGNvbnN0IGIgPSBzZWw/LmJvdW5kcztcbiAgICBpZiAoIXNlbCB8fCAhYiB8fCAhKCducG9pbnRzJyBpbiBiKSkgcmV0dXJuO1xuICAgIGNvbnN0IHAgPSBiIGFzIFBvbHlnb247XG4gICAgbGV0IGJlc3RTZWcgPSAwO1xuICAgIGxldCBiZXN0RCA9IEluZmluaXR5O1xuICAgIGNvbnN0IHNlZ3MgPSBwLmNsb3NlZCA9PT0gZmFsc2UgPyBwLm5wb2ludHMgLSAxIDogcC5ucG9pbnRzO1xuICAgIGZvciAobGV0IHMgPSAwOyBzIDwgc2VnczsgcysrKSB7XG4gICAgICBjb25zdCBqID0gKHMgKyAxKSAlIHAubnBvaW50cztcbiAgICAgIGNvbnN0IGQgPSB0aGlzLnBvaW50U2VnRGlzdChpeCwgaXksIHAueHBvaW50c1tzXSwgcC55cG9pbnRzW3NdLCBwLnhwb2ludHNbal0sIHAueXBvaW50c1tqXSk7XG4gICAgICBpZiAoZCA8IGJlc3REKSB7XG4gICAgICAgIGJlc3REID0gZDtcbiAgICAgICAgYmVzdFNlZyA9IHM7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuc3RvcmUuYWRkVmVydGV4KHNlbC5pZCwgYmVzdFNlZywgaXgsIGl5KTtcbiAgfVxuXG4gIC8qKiBkZWxldGVwb2ludCBtb2RlOiByZW1vdmUgdGhlIHNlbGVjdGVkIHBvbHlnb24ncyB2ZXJ0ZXggbmVhcmVzdCB0aGUgY2xpY2suICovXG4gIHByaXZhdGUgaGFuZGxlRGVsZXRlUG9pbnQoaXg6IG51bWJlciwgaXk6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHNlbCA9IHRoaXMuc2VsZWN0ZWRSZWdpb24oKTtcbiAgICBjb25zdCBiID0gc2VsPy5ib3VuZHM7XG4gICAgaWYgKCFzZWwgfHwgIWIgfHwgISgnbnBvaW50cycgaW4gYikpIHJldHVybjtcbiAgICBjb25zdCBwID0gYiBhcyBQb2x5Z29uO1xuICAgIGxldCBiZXN0ID0gLTE7XG4gICAgbGV0IGJlc3REID0gSW5maW5pdHk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwLm5wb2ludHM7IGkrKykge1xuICAgICAgY29uc3QgZCA9IE1hdGguaHlwb3QocC54cG9pbnRzW2ldIC0gaXgsIHAueXBvaW50c1tpXSAtIGl5KTtcbiAgICAgIGlmIChkIDwgYmVzdEQpIHtcbiAgICAgICAgYmVzdEQgPSBkO1xuICAgICAgICBiZXN0ID0gaTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGJlc3QgPj0gMCkgdGhpcy5zdG9yZS5kZWxldGVWZXJ0ZXgoc2VsLmlkLCBiZXN0KTtcbiAgfVxuXG4gIC8qKiBEaXN0YW5jZSBmcm9tIHBvaW50IChweCxweSkgdG8gc2VnbWVudCAoYXgsYXkpLShieCxieSksIGluIGltYWdlIHVuaXRzLiAqL1xuICBwcml2YXRlIHBvaW50U2VnRGlzdChcbiAgICBweDogbnVtYmVyLFxuICAgIHB5OiBudW1iZXIsXG4gICAgYXg6IG51bWJlcixcbiAgICBheTogbnVtYmVyLFxuICAgIGJ4OiBudW1iZXIsXG4gICAgYnk6IG51bWJlcixcbiAgKTogbnVtYmVyIHtcbiAgICBjb25zdCBkeCA9IGJ4IC0gYXg7XG4gICAgY29uc3QgZHkgPSBieSAtIGF5O1xuICAgIGNvbnN0IGxlbjIgPSBkeCAqIGR4ICsgZHkgKiBkeSB8fCAxO1xuICAgIGxldCB0ID0gKChweCAtIGF4KSAqIGR4ICsgKHB5IC0gYXkpICogZHkpIC8gbGVuMjtcbiAgICB0ID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oMSwgdCkpO1xuICAgIHJldHVybiBNYXRoLmh5cG90KHB4IC0gKGF4ICsgdCAqIGR4KSwgcHkgLSAoYXkgKyB0ICogZHkpKTtcbiAgfVxuXG4gIC8qKiBGaW5hbGl6ZSBhIHJ1YmJlci1iYW5kIG1hcnF1ZWU6IHNlbGVjdCBldmVyeSByZWdpb24gd2hvc2UgYm91bmRpbmcgYm94IGl0IG92ZXJsYXBzIChhIHRpbnlcbiAgICogIG1hcnF1ZWUgaXMgdHJlYXRlZCBhcyBhIGNsaWNrIG9uIGVtcHR5IHNwYWNlIOKGkiBjbGVhciB0aGUgc2VsZWN0aW9uKS4gKi9cbiAgcHJpdmF0ZSBmaW5pc2hNYXJxdWVlKG06IHsgeDA6IG51bWJlcjsgeTA6IG51bWJlcjsgeDE6IG51bWJlcjsgeTE6IG51bWJlciB9KTogdm9pZCB7XG4gICAgY29uc3QgeDAgPSBNYXRoLm1pbihtLngwLCBtLngxKTtcbiAgICBjb25zdCB4MSA9IE1hdGgubWF4KG0ueDAsIG0ueDEpO1xuICAgIGNvbnN0IHkwID0gTWF0aC5taW4obS55MCwgbS55MSk7XG4gICAgY29uc3QgeTEgPSBNYXRoLm1heChtLnkwLCBtLnkxKTtcbiAgICBpZiAoeDEgLSB4MCA8IDMgJiYgeTEgLSB5MCA8IDMpIHtcbiAgICAgIHRoaXMuc3RvcmUuc2V0U2VsZWN0ZWRTaGFwZUluZGljZXMoW10pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBpbmRpY2VzOiBudW1iZXJbXSA9IFtdO1xuICAgIHRoaXMuc3RvcmUuZ2V0UmVnaW9ucygpLmZvckVhY2goKHIsIGkpID0+IHtcbiAgICAgIGlmIChyLmlzUHJvZmlsZT8uKCkpIHJldHVybjtcbiAgICAgIGNvbnN0IGJiID0gdGhpcy5yZWdpb25CQm94KHIpO1xuICAgICAgaWYgKGJiICYmIGJiLngwIDw9IHgxICYmIGJiLngxID49IHgwICYmIGJiLnkwIDw9IHkxICYmIGJiLnkxID49IHkwKSBpbmRpY2VzLnB1c2goaSk7XG4gICAgfSk7XG4gICAgdGhpcy5zdG9yZS5zZXRTZWxlY3RlZFNoYXBlSW5kaWNlcyhpbmRpY2VzKTtcbiAgfVxuXG4gIC8qKiBBIHJlZ2lvbidzIGJvdW5kaW5nIGJveCBpbiBpbWFnZSBjb29yZHMgKHJlY3RhbmdsZSwgcG9seWdvbiwgb3IgbXVsdGlwb2x5Z29uKSwgb3IgbnVsbC4gKi9cbiAgcHJpdmF0ZSByZWdpb25CQm94KFxuICAgIHJlZ2lvbjogUmVnaW9uLFxuICApOiB7IHgwOiBudW1iZXI7IHkwOiBudW1iZXI7IHgxOiBudW1iZXI7IHkxOiBudW1iZXIgfSB8IG51bGwge1xuICAgIGNvbnN0IGIgPSByZWdpb24uYm91bmRzO1xuICAgIGlmICghYikgcmV0dXJuIG51bGw7XG4gICAgaWYgKCd3aWR0aCcgaW4gYiAmJiAneCcgaW4gYikge1xuICAgICAgY29uc3QgciA9IGIgYXMgUmVjdGFuZ2xlO1xuICAgICAgcmV0dXJuIHsgeDA6IHIueCwgeTA6IHIueSwgeDE6IHIueCArIHIud2lkdGgsIHkxOiByLnkgKyByLmhlaWdodCB9O1xuICAgIH1cbiAgICBjb25zdCBhY2MgPSB7IHgwOiBJbmZpbml0eSwgeTA6IEluZmluaXR5LCB4MTogLUluZmluaXR5LCB5MTogLUluZmluaXR5IH07XG4gICAgY29uc3QgYWRkUmluZyA9ICh4czogbnVtYmVyW10sIHlzOiBudW1iZXJbXSk6IHZvaWQgPT4ge1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB4cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoeHNbaV0gPCBhY2MueDApIGFjYy54MCA9IHhzW2ldO1xuICAgICAgICBpZiAoeHNbaV0gPiBhY2MueDEpIGFjYy54MSA9IHhzW2ldO1xuICAgICAgICBpZiAoeXNbaV0gPCBhY2MueTApIGFjYy55MCA9IHlzW2ldO1xuICAgICAgICBpZiAoeXNbaV0gPiBhY2MueTEpIGFjYy55MSA9IHlzW2ldO1xuICAgICAgfVxuICAgIH07XG4gICAgaWYgKCducG9pbnRzJyBpbiBiKSB7XG4gICAgICBjb25zdCBwID0gYiBhcyBQb2x5Z29uO1xuICAgICAgYWRkUmluZyhwLnhwb2ludHMsIHAueXBvaW50cyk7XG4gICAgfSBlbHNlIGlmICgncG9seWdvbnMnIGluIGIpIHtcbiAgICAgIGZvciAoY29uc3QgcCBvZiAoYiBhcyB7IHBvbHlnb25zOiBQb2x5Z29uW10gfSkucG9seWdvbnMpIGFkZFJpbmcocC54cG9pbnRzLCBwLnlwb2ludHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIGlzRmluaXRlKGFjYy54MCkgPyBhY2MgOiBudWxsO1xuICB9XG5cbiAgLy8g4pSA4pSAIHNoYXBlIGNvbW1pdCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgcHJpdmF0ZSBjb21taXRSZWN0YW5nbGUoeDogbnVtYmVyLCB5OiBudW1iZXIsIHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgcmVjdCA9IG5ldyBSZWN0YW5nbGUoKTtcbiAgICByZWN0LnggPSB4O1xuICAgIHJlY3QueSA9IHk7XG4gICAgcmVjdC53aWR0aCA9IHdpZHRoO1xuICAgIHJlY3QuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgIGNvbnN0IHJlZ2lvbiA9IG5ldyBSZWdpb24oKTtcbiAgICByZWdpb24uYm91bmRzID0gcmVjdDtcbiAgICByZWdpb24uY29sb3IgPSB0aGlzLnN0b3JlLmdldFNoYXBlQ29sb3IoKTtcbiAgICB0aGlzLnN0b3JlLmFkZFJlZ2lvbihyZWdpb24pO1xuICB9XG5cbiAgcHJpdmF0ZSBjb21taXRQb2x5Z29uKHBvaW50czogQXJyYXk8W251bWJlciwgbnVtYmVyXT4sIGNsb3NlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIGNvbnN0IHBvbHkgPSBuZXcgUG9seWdvbigpO1xuICAgIHBvbHkubnBvaW50cyA9IHBvaW50cy5sZW5ndGg7XG4gICAgcG9seS54cG9pbnRzID0gcG9pbnRzLm1hcCgocCkgPT4gcFswXSk7XG4gICAgcG9seS55cG9pbnRzID0gcG9pbnRzLm1hcCgocCkgPT4gcFsxXSk7XG4gICAgcG9seS5jb29yZGluYXRlcyA9IHBvaW50cy5tYXAoKHApID0+IFtwWzBdLCBwWzFdXSk7XG4gICAgcG9seS5jbG9zZWQgPSBjbG9zZWQ7XG4gICAgY29uc3QgcmVnaW9uID0gbmV3IFJlZ2lvbigpO1xuICAgIHJlZ2lvbi5ib3VuZHMgPSBwb2x5O1xuICAgIHJlZ2lvbi5jb2xvciA9IHRoaXMuc3RvcmUuZ2V0U2hhcGVDb2xvcigpO1xuICAgIHJlZ2lvbi5sYWJlbCA9ICdSZWdpb24nO1xuICAgIHRoaXMuc3RvcmUuYWRkUmVnaW9uKHJlZ2lvbik7XG4gIH1cblxuICAvLyDilIDilIAgcmVuZGVyaW5nIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICBwcml2YXRlIGhpdFRlc3QocmVnaW9uOiBSZWdpb24sIHg6IG51bWJlciwgeTogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgY29uc3QgYiA9IHJlZ2lvbi5ib3VuZHM7XG4gICAgaWYgKCFiKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKCd3aWR0aCcgaW4gYiAmJiAneCcgaW4gYikge1xuICAgICAgY29uc3QgciA9IGIgYXMgUmVjdGFuZ2xlO1xuICAgICAgcmV0dXJuIHggPj0gci54ICYmIHggPD0gci54ICsgci53aWR0aCAmJiB5ID49IHIueSAmJiB5IDw9IHIueSArIHIuaGVpZ2h0O1xuICAgIH1cbiAgICBpZiAoJ25wb2ludHMnIGluIGIpIHtcbiAgICAgIGNvbnN0IHAgPSBiIGFzIFBvbHlnb247XG4gICAgICBsZXQgaW5zaWRlID0gZmFsc2U7XG4gICAgICBmb3IgKGxldCBpID0gMCwgaiA9IHAubnBvaW50cyAtIDE7IGkgPCBwLm5wb2ludHM7IGogPSBpKyspIHtcbiAgICAgICAgY29uc3QgeGkgPSBwLnhwb2ludHNbaV07XG4gICAgICAgIGNvbnN0IHlpID0gcC55cG9pbnRzW2ldO1xuICAgICAgICBjb25zdCB4aiA9IHAueHBvaW50c1tqXTtcbiAgICAgICAgY29uc3QgeWogPSBwLnlwb2ludHNbal07XG4gICAgICAgIGlmICh5aSA+IHkgIT09IHlqID4geSAmJiB4IDwgKCh4aiAtIHhpKSAqICh5IC0geWkpKSAvICh5aiAtIHlpKSArIHhpKSBpbnNpZGUgPSAhaW5zaWRlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGluc2lkZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqIFNob3cgb3IgaGlkZSB0aGUgZHJhd24gcmVnaW9ucy4gQSByZWdpb24gYmVpbmcgZHJhd24gc3RheXMgdmlzaWJsZSBlaXRoZXIgd2F5LiAqL1xuICBzZXRSZWdpb25zVmlzaWJsZSh2aXNpYmxlOiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKHZpc2libGUgPT09IHRoaXMucmVnaW9uc1Zpc2libGUpIHJldHVybjtcbiAgICB0aGlzLnJlZ2lvbnNWaXNpYmxlID0gdmlzaWJsZTtcbiAgICB0aGlzLnJlZHJhdygpO1xuICB9XG5cbiAgcmVkcmF3KCk6IHZvaWQge1xuICAgIHdoaWxlICh0aGlzLnN2Zy5maXJzdENoaWxkKSB0aGlzLnN2Zy5yZW1vdmVDaGlsZCh0aGlzLnN2Zy5maXJzdENoaWxkKTtcbiAgICBjb25zdCByZWdpb25zID0gdGhpcy5yZWdpb25zVmlzaWJsZSA/IHRoaXMuc3RvcmUuZ2V0UmVnaW9ucygpIDogW107XG4gICAgcmVnaW9ucy5mb3JFYWNoKChyZWdpb24sIGkpID0+IHtcbiAgICAgIGlmIChyZWdpb24uaXNQcm9maWxlPy4oKSkgcmV0dXJuO1xuICAgICAgY29uc3QgaXNTZWwgPSB0aGlzLnNlbGVjdGVkLmluY2x1ZGVzKGkpO1xuICAgICAgY29uc3QgZWwgPSB0aGlzLmJ1aWxkUmVnaW9uRWwocmVnaW9uLCBpc1NlbCk7XG4gICAgICBpZiAoZWwpIHRoaXMuc3ZnLmFwcGVuZENoaWxkKGVsKTtcbiAgICAgIHRoaXMuZHJhd0xhYmVsKHJlZ2lvbik7XG4gICAgICBpZiAoaXNTZWwpIHRoaXMuZHJhd0hhbmRsZXMocmVnaW9uKTtcbiAgICB9KTtcbiAgICB0aGlzLmRyYXdEcmFmdCgpO1xuICB9XG5cbiAgLyoqIERyYXcgYSByZWdpb24ncyBjbGFzc2lmaWNhdGlvbiBsYWJlbCBhdCBpdHMgdG9wLWxlZnQsIHdoZW4gbGFiZWxzIGFyZSBlbmFibGVkIChtYXRjaGVzIE9TRCkuICovXG4gIHByaXZhdGUgZHJhd0xhYmVsKHJlZ2lvbjogUmVnaW9uKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnN0b3JlLmdldFNob3dTaGFwZUxhYmVsKCkgfHwgcmVnaW9uLmlzUHJvZmlsZT8uKCkpIHJldHVybjtcbiAgICBjb25zdCBsYWJlbCA9IHJlZ2lvbi5sYWJlbDtcbiAgICBjb25zdCBiID0gcmVnaW9uLmJvdW5kcztcbiAgICBpZiAoIWxhYmVsIHx8ICFiKSByZXR1cm47XG4gICAgbGV0IGl4OiBudW1iZXI7XG4gICAgbGV0IGl5OiBudW1iZXI7XG4gICAgaWYgKCd3aWR0aCcgaW4gYiAmJiAneCcgaW4gYikge1xuICAgICAgaXggPSAoYiBhcyBSZWN0YW5nbGUpLng7XG4gICAgICBpeSA9IChiIGFzIFJlY3RhbmdsZSkueTtcbiAgICB9IGVsc2UgaWYgKCducG9pbnRzJyBpbiBiKSB7XG4gICAgICBjb25zdCBwID0gYiBhcyBQb2x5Z29uO1xuICAgICAgaXggPSBwLnhwb2ludHMucmVkdWNlKChtLCB4KSA9PiBNYXRoLm1pbihtLCB4KSwgSW5maW5pdHkpO1xuICAgICAgaXkgPSBwLnlwb2ludHMucmVkdWNlKChtLCB5KSA9PiBNYXRoLm1pbihtLCB5KSwgSW5maW5pdHkpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IFtseCwgbHldID0gdGhpcy50b0xvY2FsKGl4LCBpeSk7XG4gICAgY29uc3QgdGV4dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhTVkdfTlMsICd0ZXh0Jyk7XG4gICAgdGV4dC5zZXRBdHRyaWJ1dGUoJ3gnLCBgJHtseH1gKTtcbiAgICB0ZXh0LnNldEF0dHJpYnV0ZSgneScsIGAke2x5IC0gNH1gKTtcbiAgICB0ZXh0LnNldEF0dHJpYnV0ZSgnZmlsbCcsICcjZmZmJyk7XG4gICAgdGV4dC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsICcjMDAwJyk7XG4gICAgdGV4dC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZS13aWR0aCcsICczJyk7XG4gICAgdGV4dC5zZXRBdHRyaWJ1dGUoJ3BhaW50LW9yZGVyJywgJ3N0cm9rZScpO1xuICAgIHRleHQuc2V0QXR0cmlidXRlKCdmb250JywgJzEycHggc2Fucy1zZXJpZicpO1xuICAgIHRleHQuc2V0QXR0cmlidXRlKCdwb2ludGVyLWV2ZW50cycsICdub25lJyk7XG4gICAgdGV4dC50ZXh0Q29udGVudCA9IGxhYmVsO1xuICAgIHRoaXMuc3ZnLmFwcGVuZENoaWxkKHRleHQpO1xuICB9XG5cbiAgLyoqIERyYXcgZ3JhYiBoYW5kbGVzIGZvciB0aGUgc2VsZWN0ZWQgcmVnaW9uOiByZWN0YW5nbGUgY29ybmVycyBvciBwb2x5Z29uIHZlcnRpY2VzLiAqL1xuICBwcml2YXRlIGRyYXdIYW5kbGVzKHJlZ2lvbjogUmVnaW9uKTogdm9pZCB7XG4gICAgY29uc3QgYiA9IHJlZ2lvbi5ib3VuZHM7XG4gICAgaWYgKCFiKSByZXR1cm47XG4gICAgY29uc3Qgc3Ryb2tlID0gcmVnaW9uLmNvbG9yIHx8IHRoaXMuc3RvcmUuZ2V0U2hhcGVDb2xvcigpIHx8ICcjMDBmZmZmJztcbiAgICBjb25zdCBoYW5kbGUgPSAoaW1nWDogbnVtYmVyLCBpbWdZOiBudW1iZXIpOiB2b2lkID0+IHtcbiAgICAgIGNvbnN0IFtseCwgbHldID0gdGhpcy50b0xvY2FsKGltZ1gsIGltZ1kpO1xuICAgICAgY29uc3QgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoU1ZHX05TLCAncmVjdCcpO1xuICAgICAgZWwuc2V0QXR0cmlidXRlKCd4JywgYCR7bHggLSBIQU5ETEVfU0laRSAvIDJ9YCk7XG4gICAgICBlbC5zZXRBdHRyaWJ1dGUoJ3knLCBgJHtseSAtIEhBTkRMRV9TSVpFIC8gMn1gKTtcbiAgICAgIGVsLnNldEF0dHJpYnV0ZSgnd2lkdGgnLCBgJHtIQU5ETEVfU0laRX1gKTtcbiAgICAgIGVsLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgYCR7SEFORExFX1NJWkV9YCk7XG4gICAgICBlbC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCAnI2ZmZicpO1xuICAgICAgZWwuc2V0QXR0cmlidXRlKCdzdHJva2UnLCBzdHJva2UpO1xuICAgICAgZWwuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCAnMS41Jyk7XG4gICAgICB0aGlzLnN2Zy5hcHBlbmRDaGlsZChlbCk7XG4gICAgfTtcbiAgICBpZiAoJ3dpZHRoJyBpbiBiICYmICd4JyBpbiBiKSB7XG4gICAgICBjb25zdCByID0gYiBhcyBSZWN0YW5nbGU7XG4gICAgICBoYW5kbGUoci54LCByLnkpO1xuICAgICAgaGFuZGxlKHIueCArIHIud2lkdGgsIHIueSk7XG4gICAgICBoYW5kbGUoci54LCByLnkgKyByLmhlaWdodCk7XG4gICAgICBoYW5kbGUoci54ICsgci53aWR0aCwgci55ICsgci5oZWlnaHQpO1xuICAgIH0gZWxzZSBpZiAoJ25wb2ludHMnIGluIGIpIHtcbiAgICAgIGNvbnN0IHAgPSBiIGFzIFBvbHlnb247XG4gICAgICBjb25zdCBpc0JlemllciA9IHAuYmV6aWVyICYmIHAuaGFuZGxlc0luPy5sZW5ndGggPT09IHAubnBvaW50cyAmJiBwLmhhbmRsZXNPdXQ/Lmxlbmd0aCA9PT0gcC5ucG9pbnRzO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwLm5wb2ludHM7IGkrKykgaGFuZGxlKHAueHBvaW50c1tpXSwgcC55cG9pbnRzW2ldKTtcbiAgICAgIGZvciAoY29uc3QgcmluZyBvZiBwLmhvbGVzID8/IFtdKSBmb3IgKGNvbnN0IFtoeCwgaHldIG9mIHJpbmcpIGhhbmRsZShoeCwgaHkpO1xuICAgICAgLy8gQmV6aWVyIHJlZ2lvbnMgYWxzbyBleHBvc2UgdGhlaXIgdGFuZ2VudCBjb250cm9sIHBvaW50cyAoY2lyY2xlcykgam9pbmVkIHRvIHRoZSBhbmNob3JcbiAgICAgIC8vIGJ5IGEgdGhpbiBsaW5lLCBtYXRjaGluZyB0aGUgT1NEIG92ZXJsYXkncyBlZGl0YWJsZSBiZXppZXIgaGFuZGxlcy5cbiAgICAgIGlmIChpc0Jlemllcikge1xuICAgICAgICBjb25zdCBoSW4gPSBwLmhhbmRsZXNJbiBhcyBudW1iZXJbXVtdO1xuICAgICAgICBjb25zdCBoT3V0ID0gcC5oYW5kbGVzT3V0IGFzIG51bWJlcltdW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcC5ucG9pbnRzOyBpKyspIHtcbiAgICAgICAgICB0aGlzLmRyYXdCZXppZXJIYW5kbGUocC54cG9pbnRzW2ldLCBwLnlwb2ludHNbaV0sIGhPdXRbaV0sIHN0cm9rZSk7XG4gICAgICAgICAgdGhpcy5kcmF3QmV6aWVySGFuZGxlKHAueHBvaW50c1tpXSwgcC55cG9pbnRzW2ldLCBoSW5baV0sIHN0cm9rZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIERvbnV0IGhvbGUgYmV6aWVyIGNvbnRyb2wgaGFuZGxlcy5cbiAgICAgIGlmIChwLmJlemllciAmJiBwLmhvbGVIYW5kbGVzSW4gJiYgcC5ob2xlSGFuZGxlc091dCkge1xuICAgICAgICAocC5ob2xlcyA/PyBbXSkuZm9yRWFjaCgocmluZywgaGkpID0+IHtcbiAgICAgICAgICBjb25zdCBoSW4gPSBwLmhvbGVIYW5kbGVzSW4hW2hpXTtcbiAgICAgICAgICBjb25zdCBoT3V0ID0gcC5ob2xlSGFuZGxlc091dCFbaGldO1xuICAgICAgICAgIGlmICghaEluIHx8ICFoT3V0KSByZXR1cm47XG4gICAgICAgICAgcmluZy5mb3JFYWNoKChbaHgsIGh5XSwgdmkpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZHJhd0JlemllckhhbmRsZShoeCwgaHksIGhPdXRbdmldLCBzdHJva2UpO1xuICAgICAgICAgICAgdGhpcy5kcmF3QmV6aWVySGFuZGxlKGh4LCBoeSwgaEluW3ZpXSwgc3Ryb2tlKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqIERyYXcgb25lIGJlemllciBjb250cm9sIHBvaW50IChhbmNob3IgKyBoYW5kbGUgb2Zmc2V0KSBhcyBhIHNtYWxsIGNpcmNsZSBjb25uZWN0ZWQgdG8gaXRzXG4gICAqICBhbmNob3IgYnkgYSB0YW5nZW50IGxpbmUuIGBoYW5kbGVgIGlzIHRoZSBbZHgsZHldIG9mZnNldCBmcm9tIHRoZSBhbmNob3IgaW4gaW1hZ2Ugc3BhY2UuICovXG4gIHByaXZhdGUgZHJhd0JlemllckhhbmRsZShheDogbnVtYmVyLCBheTogbnVtYmVyLCBoYW5kbGU6IG51bWJlcltdLCBzdHJva2U6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghaGFuZGxlIHx8IChoYW5kbGVbMF0gPT09IDAgJiYgaGFuZGxlWzFdID09PSAwKSkgcmV0dXJuO1xuICAgIGNvbnN0IFthbHgsIGFseV0gPSB0aGlzLnRvTG9jYWwoYXgsIGF5KTtcbiAgICBjb25zdCBbaGx4LCBobHldID0gdGhpcy50b0xvY2FsKGF4ICsgaGFuZGxlWzBdLCBheSArIGhhbmRsZVsxXSk7XG4gICAgY29uc3QgbGluZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhTVkdfTlMsICdsaW5lJyk7XG4gICAgbGluZS5zZXRBdHRyaWJ1dGUoJ3gxJywgYCR7YWx4fWApO1xuICAgIGxpbmUuc2V0QXR0cmlidXRlKCd5MScsIGAke2FseX1gKTtcbiAgICBsaW5lLnNldEF0dHJpYnV0ZSgneDInLCBgJHtobHh9YCk7XG4gICAgbGluZS5zZXRBdHRyaWJ1dGUoJ3kyJywgYCR7aGx5fWApO1xuICAgIGxpbmUuc2V0QXR0cmlidXRlKCdzdHJva2UnLCBzdHJva2UpO1xuICAgIGxpbmUuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCAnMScpO1xuICAgIGxpbmUuc2V0QXR0cmlidXRlKCdzdHJva2Utb3BhY2l0eScsICcwLjcnKTtcbiAgICB0aGlzLnN2Zy5hcHBlbmRDaGlsZChsaW5lKTtcbiAgICBjb25zdCBkb3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoU1ZHX05TLCAnY2lyY2xlJyk7XG4gICAgZG90LnNldEF0dHJpYnV0ZSgnY3gnLCBgJHtobHh9YCk7XG4gICAgZG90LnNldEF0dHJpYnV0ZSgnY3knLCBgJHtobHl9YCk7XG4gICAgZG90LnNldEF0dHJpYnV0ZSgncicsIGAke0hBTkRMRV9TSVpFIC8gMn1gKTtcbiAgICBkb3Quc2V0QXR0cmlidXRlKCdmaWxsJywgc3Ryb2tlKTtcbiAgICBkb3Quc2V0QXR0cmlidXRlKCdzdHJva2UnLCAnI2ZmZicpO1xuICAgIGRvdC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZS13aWR0aCcsICcxJyk7XG4gICAgdGhpcy5zdmcuYXBwZW5kQ2hpbGQoZG90KTtcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRSZWdpb25FbChyZWdpb246IFJlZ2lvbiwgaXNTZWxlY3RlZDogYm9vbGVhbik6IFNWR0VsZW1lbnQgfCBudWxsIHtcbiAgICBjb25zdCBiID0gcmVnaW9uLmJvdW5kcztcbiAgICBpZiAoIWIpIHJldHVybiBudWxsO1xuICAgIGNvbnN0IHN0cm9rZSA9IHJlZ2lvbi5jb2xvciB8fCB0aGlzLnN0b3JlLmdldFNoYXBlQ29sb3IoKSB8fCAnIzAwZmZmZic7XG4gICAgaWYgKCd3aWR0aCcgaW4gYiAmJiAneCcgaW4gYikge1xuICAgICAgY29uc3QgciA9IGIgYXMgUmVjdGFuZ2xlO1xuICAgICAgY29uc3QgW2x4LCBseV0gPSB0aGlzLnRvTG9jYWwoci54LCByLnkpO1xuICAgICAgY29uc3QgW3J4LCByeV0gPSB0aGlzLnRvTG9jYWwoci54ICsgci53aWR0aCwgci55ICsgci5oZWlnaHQpO1xuICAgICAgY29uc3QgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoU1ZHX05TLCAncmVjdCcpO1xuICAgICAgZWwuc2V0QXR0cmlidXRlKCd4JywgYCR7TWF0aC5taW4obHgsIHJ4KX1gKTtcbiAgICAgIGVsLnNldEF0dHJpYnV0ZSgneScsIGAke01hdGgubWluKGx5LCByeSl9YCk7XG4gICAgICBlbC5zZXRBdHRyaWJ1dGUoJ3dpZHRoJywgYCR7TWF0aC5hYnMocnggLSBseCl9YCk7XG4gICAgICBlbC5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsIGAke01hdGguYWJzKHJ5IC0gbHkpfWApO1xuICAgICAgdGhpcy5zdHlsZShlbCwgc3Ryb2tlLCBpc1NlbGVjdGVkKTtcbiAgICAgIHJldHVybiBlbDtcbiAgICB9XG4gICAgaWYgKCducG9pbnRzJyBpbiBiKSB7XG4gICAgICBjb25zdCBwID0gYiBhcyBQb2x5Z29uO1xuICAgICAgY29uc3QgaXNCZXppZXIgPVxuICAgICAgICAhIXAuYmV6aWVyICYmIHAuaGFuZGxlc0luPy5sZW5ndGggPT09IHAubnBvaW50cyAmJiBwLmhhbmRsZXNPdXQ/Lmxlbmd0aCA9PT0gcC5ucG9pbnRzO1xuICAgICAgY29uc3QgaGFzSG9sZXMgPSAhIShwLmhvbGVzICYmIHAuaG9sZXMubGVuZ3RoKTtcbiAgICAgIC8vIEJlemllciBvciBkb251dCAoaG9sZXMpIOKGkiBhIHNpbmdsZSA8cGF0aD47IGhvbGVzIHVzZSBldmVuLW9kZCBmaWxsIHNvIHRoZXkgcHVuY2ggdGhyb3VnaC5cbiAgICAgIGlmIChpc0JlemllciB8fCBoYXNIb2xlcykge1xuICAgICAgICBjb25zdCBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhTVkdfTlMsICdwYXRoJyk7XG4gICAgICAgIGVsLnNldEF0dHJpYnV0ZSgnZCcsIHRoaXMucG9seWdvblBhdGhEYXRhKHAsIGlzQmV6aWVyKSk7XG4gICAgICAgIGlmIChoYXNIb2xlcykgZWwuc2V0QXR0cmlidXRlKCdmaWxsLXJ1bGUnLCAnZXZlbm9kZCcpO1xuICAgICAgICB0aGlzLnN0eWxlKGVsLCBzdHJva2UsIGlzU2VsZWN0ZWQpO1xuICAgICAgICByZXR1cm4gZWw7XG4gICAgICB9XG4gICAgICBjb25zdCBwdHMgPSBwLnhwb2ludHNcbiAgICAgICAgLm1hcCgoXywgaSkgPT4gdGhpcy50b0xvY2FsKHAueHBvaW50c1tpXSwgcC55cG9pbnRzW2ldKS5qb2luKCcsJykpXG4gICAgICAgIC5qb2luKCcgJyk7XG4gICAgICBjb25zdCBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhTVkdfTlMsIHAuY2xvc2VkID09PSBmYWxzZSA/ICdwb2x5bGluZScgOiAncG9seWdvbicpO1xuICAgICAgZWwuc2V0QXR0cmlidXRlKCdwb2ludHMnLCBwdHMpO1xuICAgICAgdGhpcy5zdHlsZShlbCwgc3Ryb2tlLCBpc1NlbGVjdGVkKTtcbiAgICAgIHJldHVybiBlbDtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKiogUGF0aCBkYXRhIGZvciBhIHBvbHlnb246IHRoZSBleHRlcmlvciByaW5nIChiZXppZXIgb3Igc3RyYWlnaHQpIHBsdXMgYW55IGhvbGVzIChiZXppZXIgd2hlblxuICAgKiAgdGhlIGRvbnV0IGNhcnJpZXMgaG9sZSBoYW5kbGVzLCBlbHNlIHN0cmFpZ2h0KSBhcyBzdWItcGF0aHMg4oCUIGV2ZW4tb2RkIGZpbGwgY3V0cyB0aGVtIG91dC4gKi9cbiAgcHJpdmF0ZSBwb2x5Z29uUGF0aERhdGEocDogUG9seWdvbiwgaXNCZXppZXI6IGJvb2xlYW4pOiBzdHJpbmcge1xuICAgIGxldCBkID0gaXNCZXppZXJcbiAgICAgID8gdGhpcy5yaW5nQmV6aWVyUGF0aChwLnhwb2ludHMsIHAueXBvaW50cywgcC5oYW5kbGVzSW4hLCBwLmhhbmRsZXNPdXQhLCBwLmNsb3NlZCAhPT0gZmFsc2UpXG4gICAgICA6IHRoaXMuc3RyYWlnaHRQYXRoKHAueHBvaW50cywgcC55cG9pbnRzLCBwLmNsb3NlZCAhPT0gZmFsc2UpO1xuICAgIGNvbnN0IGhvbGVCZXppZXIgPSAhIShwLmJlemllciAmJiBwLmhvbGVIYW5kbGVzSW4gJiYgcC5ob2xlSGFuZGxlc091dCk7XG4gICAgKHAuaG9sZXMgPz8gW10pLmZvckVhY2goKHJpbmcsIGhpKSA9PiB7XG4gICAgICBpZiAocmluZy5sZW5ndGggPCAzKSByZXR1cm47XG4gICAgICBjb25zdCB4cyA9IHJpbmcubWFwKChwdCkgPT4gcHRbMF0pO1xuICAgICAgY29uc3QgeXMgPSByaW5nLm1hcCgocHQpID0+IHB0WzFdKTtcbiAgICAgIGlmIChob2xlQmV6aWVyICYmIHAuaG9sZUhhbmRsZXNJbiFbaGldICYmIHAuaG9sZUhhbmRsZXNPdXQhW2hpXSkge1xuICAgICAgICBkICs9ICcgJyArIHRoaXMucmluZ0JlemllclBhdGgoeHMsIHlzLCBwLmhvbGVIYW5kbGVzSW4hW2hpXSwgcC5ob2xlSGFuZGxlc091dCFbaGldLCB0cnVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGQgKz0gJyAnICsgdGhpcy5zdHJhaWdodFBhdGgoeHMsIHlzLCB0cnVlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gZDtcbiAgfVxuXG4gIC8qKiBTVkcgcGF0aCBkYXRhIGZvciBhIHN0cmFpZ2h0IHJpbmcvcG9seWxpbmUgaW4gaW1hZ2UgY29vcmRzIChjbG9zZWQgYXBwZW5kcyBgWmApLiAqL1xuICBwcml2YXRlIHN0cmFpZ2h0UGF0aCh4czogbnVtYmVyW10sIHlzOiBudW1iZXJbXSwgY2xvc2VkOiBib29sZWFuKTogc3RyaW5nIHtcbiAgICBsZXQgZCA9ICcnO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IFtseCwgbHldID0gdGhpcy50b0xvY2FsKHhzW2ldLCB5c1tpXSk7XG4gICAgICBkICs9IChpID09PSAwID8gJ00nIDogJyBMJykgKyBgICR7bHh9LCR7bHl9YDtcbiAgICB9XG4gICAgcmV0dXJuIGNsb3NlZCA/IGQgKyAnIFonIDogZDtcbiAgfVxuXG4gIC8qKiBTVkcgY3ViaWMtYmV6aWVyIHBhdGggZGF0YSBmb3IgYW55IHJpbmcgKGV4dGVyaW9yIG9yIGhvbGUpOiBhbmNob3JzIGpvaW5lZCBieSBjdWJpYyBzZWdtZW50c1xuICAgKiAgd2hvc2UgY29udHJvbCBwb2ludHMgYXJlIGBhbmNob3IgKyBoYW5kbGVPdXRgIChsZWF2aW5nKSBhbmQgYG5leHRBbmNob3IgKyBoYW5kbGVJbmAgKGFycml2aW5nKSxcbiAgICogIGluIGltYWdlIHNwYWNlLiBVc2VkIGZvciBib3RoIHRoZSBleHRlcmlvciBhbmQgKGRvbnV0KSBob2xlIHJpbmdzLiAqL1xuICBwcml2YXRlIHJpbmdCZXppZXJQYXRoKFxuICAgIHhzOiBudW1iZXJbXSxcbiAgICB5czogbnVtYmVyW10sXG4gICAgaEluOiBudW1iZXJbXVtdLFxuICAgIGhPdXQ6IG51bWJlcltdW10sXG4gICAgY2xvc2VkOiBib29sZWFuLFxuICApOiBzdHJpbmcge1xuICAgIGNvbnN0IG4gPSB4cy5sZW5ndGg7XG4gICAgY29uc3QgYW5jaG9yID0gKGk6IG51bWJlcik6IFtudW1iZXIsIG51bWJlcl0gPT4gdGhpcy50b0xvY2FsKHhzW2ldLCB5c1tpXSk7XG4gICAgY29uc3QgY3RybE91dCA9IChpOiBudW1iZXIpOiBbbnVtYmVyLCBudW1iZXJdID0+XG4gICAgICB0aGlzLnRvTG9jYWwoeHNbaV0gKyAoaE91dFtpXT8uWzBdID8/IDApLCB5c1tpXSArIChoT3V0W2ldPy5bMV0gPz8gMCkpO1xuICAgIGNvbnN0IGN0cmxJbiA9IChpOiBudW1iZXIpOiBbbnVtYmVyLCBudW1iZXJdID0+XG4gICAgICB0aGlzLnRvTG9jYWwoeHNbaV0gKyAoaEluW2ldPy5bMF0gPz8gMCksIHlzW2ldICsgKGhJbltpXT8uWzFdID8/IDApKTtcbiAgICBjb25zdCBbc3gsIHN5XSA9IGFuY2hvcigwKTtcbiAgICBsZXQgZCA9IGBNICR7c3h9LCR7c3l9YDtcbiAgICBjb25zdCBzZWdtZW50cyA9IGNsb3NlZCA/IG4gOiBuIC0gMTtcbiAgICBmb3IgKGxldCBzID0gMDsgcyA8IHNlZ21lbnRzOyBzKyspIHtcbiAgICAgIGNvbnN0IGkgPSBzO1xuICAgICAgY29uc3QgaiA9IChzICsgMSkgJSBuO1xuICAgICAgY29uc3QgW2MxeCwgYzF5XSA9IGN0cmxPdXQoaSk7XG4gICAgICBjb25zdCBbYzJ4LCBjMnldID0gY3RybEluKGopO1xuICAgICAgY29uc3QgW2V4LCBleV0gPSBhbmNob3Ioaik7XG4gICAgICBkICs9IGAgQyAke2MxeH0sJHtjMXl9ICR7YzJ4fSwke2MyeX0gJHtleH0sJHtleX1gO1xuICAgIH1cbiAgICBpZiAoY2xvc2VkKSBkICs9ICcgWic7XG4gICAgcmV0dXJuIGQ7XG4gIH1cblxuICBwcml2YXRlIHN0eWxlKGVsOiBTVkdFbGVtZW50LCBzdHJva2U6IHN0cmluZywgaXNTZWxlY3RlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIGVsLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJywgc3Ryb2tlKTtcbiAgICBlbC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZS13aWR0aCcsIGlzU2VsZWN0ZWQgPyAnNCcgOiAnMicpO1xuICAgIGVsLnNldEF0dHJpYnV0ZSgnZmlsbCcsIGlzU2VsZWN0ZWQgPyBzdHJva2UgOiAnbm9uZScpO1xuICAgIGVsLnNldEF0dHJpYnV0ZSgnZmlsbC1vcGFjaXR5JywgaXNTZWxlY3RlZCA/ICcwLjM1JyA6ICcwJyk7XG4gICAgZWwuc2V0QXR0cmlidXRlKCd2ZWN0b3ItZWZmZWN0JywgJ25vbi1zY2FsaW5nLXN0cm9rZScpO1xuICB9XG5cbiAgLyoqIERyYXcgdGhlIGluLXByb2dyZXNzIHJlY3RhbmdsZSAvIHBhdGggcHJldmlldy4gKi9cbiAgcHJpdmF0ZSBkcmF3RHJhZnQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZHJhZnRSZWN0KSB7XG4gICAgICBjb25zdCB7IHgwLCB5MCwgeDEsIHkxIH0gPSB0aGlzLmRyYWZ0UmVjdDtcbiAgICAgIGNvbnN0IFtseCwgbHldID0gdGhpcy50b0xvY2FsKE1hdGgubWluKHgwLCB4MSksIE1hdGgubWluKHkwLCB5MSkpO1xuICAgICAgY29uc3QgW3J4LCByeV0gPSB0aGlzLnRvTG9jYWwoTWF0aC5tYXgoeDAsIHgxKSwgTWF0aC5tYXgoeTAsIHkxKSk7XG4gICAgICBjb25zdCBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhTVkdfTlMsICdyZWN0Jyk7XG4gICAgICBlbC5zZXRBdHRyaWJ1dGUoJ3gnLCBgJHtseH1gKTtcbiAgICAgIGVsLnNldEF0dHJpYnV0ZSgneScsIGAke2x5fWApO1xuICAgICAgZWwuc2V0QXR0cmlidXRlKCd3aWR0aCcsIGAke01hdGguYWJzKHJ4IC0gbHgpfWApO1xuICAgICAgZWwuc2V0QXR0cmlidXRlKCdoZWlnaHQnLCBgJHtNYXRoLmFicyhyeSAtIGx5KX1gKTtcbiAgICAgIHRoaXMuc3R5bGVEcmFmdChlbCk7XG4gICAgICB0aGlzLnN2Zy5hcHBlbmRDaGlsZChlbCk7XG4gICAgfVxuICAgIGlmICh0aGlzLmRyYWZ0UGF0aCAmJiB0aGlzLmRyYWZ0UGF0aC5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IHB0cyA9IHRoaXMuZHJhZnRQYXRoLm1hcCgoW3gsIHldKSA9PiB0aGlzLnRvTG9jYWwoeCwgeSkuam9pbignLCcpKS5qb2luKCcgJyk7XG4gICAgICBjb25zdCBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhTVkdfTlMsICdwb2x5bGluZScpO1xuICAgICAgZWwuc2V0QXR0cmlidXRlKCdwb2ludHMnLCBwdHMpO1xuICAgICAgdGhpcy5zdHlsZURyYWZ0KGVsKTtcbiAgICAgIHRoaXMuc3ZnLmFwcGVuZENoaWxkKGVsKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHN0eWxlRHJhZnQoZWw6IFNWR0VsZW1lbnQpOiB2b2lkIHtcbiAgICBlbC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIHRoaXMuc3RvcmUuZ2V0U2hhcGVDb2xvcigpIHx8ICcjMDBmZmZmJyk7XG4gICAgZWwuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCAnMicpO1xuICAgIGVsLnNldEF0dHJpYnV0ZSgnc3Ryb2tlLWRhc2hhcnJheScsICc0IDMnKTtcbiAgICBlbC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCAnbm9uZScpO1xuICAgIGVsLnNldEF0dHJpYnV0ZSgndmVjdG9yLWVmZmVjdCcsICdub24tc2NhbGluZy1zdHJva2UnKTtcbiAgfVxufVxuIl19
|
|
485
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFwYXJpLXJlZ2lvbi1vdmVybGF5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9pbXBsZW1lbnRhdGlvbnMvbmFwYXJpLWpzL25hcGFyaS1yZWdpb24tb3ZlcmxheS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBR3BDLE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBSWpFLE9BQU8sRUFDTCxTQUFTLEVBQ1QsV0FBVyxFQUNYLGFBQWEsRUFDYixjQUFjLEVBQ2QsYUFBYSxHQUNkLE1BQU0sc0NBQXNDLENBQUM7QUFFOUMsT0FBTyxFQUFXLHVCQUF1QixFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDeEYsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDeEUsT0FBTyxFQUFjLGVBQWUsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBRTNFLE1BQU0sTUFBTSxHQUFHLDRCQUE0QixDQUFDO0FBQzVDOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO0FBQzNCOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLENBQUM7QUFDM0I7Ozs7R0FJRztBQUNILE1BQU0sY0FBYyxHQUFHLENBQUMsQ0FBQztBQUN6QixrR0FBa0c7QUFDbEcsTUFBTSxhQUFhLEdBQUcsRUFBRSxDQUFDO0FBQ3pCLDRFQUE0RTtBQUM1RSxNQUFNLGFBQWEsR0FBRyxDQUFDLENBQUM7QUFDeEIseUZBQXlGO0FBQ3pGLE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO0FBNkIzQjs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHO0FBQ0gsTUFBTSxPQUFPLG1CQUFtQjtJQXVCOUIsWUFDbUIsSUFBaUIsRUFDakIsTUFBcUIsRUFDckIsS0FBa0I7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QzdGLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUztZQUNwQixJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVM7U0FDckIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IElSZWdpb25PdmVybGF5LCBSZWdpb25Ub29sTW9kZSB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cy9yZWdpb24tb3ZlcmxheS5jb250cmFjdCc7XG5pbXBvcnQgeyBSZWdpb24sIFJlY3RhbmdsZSwgUG9seWdvbiB9IGZyb20gJy4uLy4uL21vZGVscy9yZWdpb24nO1xuaW1wb3J0IHsgUmVnaW9uU3RvcmUgfSBmcm9tICcuLi8uLi9zdG9yZS9yZWdpb24tc3RvcmUuc2VydmljZSc7XG5pbXBvcnQgdHlwZSB7IEFmZmluZSB9IGZyb20gJy4uLy4uL3JlZ2lvbi1vdmVybGF5L3N2Zy1yZWdpb24tcmVuZGVyZXInO1xuXG5pbXBvcnQge1xuICBoaXRIYW5kbGUsXG4gIG5lYXJlc3RFZGdlLFxuICBuZWFyZXN0VmVydGV4LFxuICByZWdpb25Db250YWlucyxcbiAgcmVnaW9uc0luUmVjdCxcbn0gZnJvbSAnLi4vLi4vcmVnaW9uLW92ZXJsYXkvcmVnaW9uLWdlb21ldHJ5JztcblxuaW1wb3J0IHsgRHJhZ0JveCwgTmFwYXJpUmVnaW9uU3ZnUmVuZGVyZXIgfSBmcm9tICcuL3JlZ2lvbi1vdmVybGF5L3JlZ2lvbi1zdmctcmVuZGVyZXInO1xuaW1wb3J0IHsgT3ZlcmxheVByb2plY3Rpb24gfSBmcm9tICcuL3JlZ2lvbi1vdmVybGF5L292ZXJsYXktcHJvamVjdGlvbic7XG5pbXBvcnQgeyBSZWdpb25FZGl0LCBhcHBseVJlZ2lvbkVkaXQgfSBmcm9tICcuL3JlZ2lvbi1vdmVybGF5L3JlZ2lvbi1lZGl0JztcblxuY29uc3QgU1ZHX05TID0gJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJztcbi8qKlxuICogTWluIGRyYWcgYmVmb3JlIGEgZnJlZWhhbmQgcGF0aCByZWNvcmRzIGFub3RoZXIgcG9pbnQsIGluIFNDUkVFTiBwaXhlbHMuXG4gKlxuICogU2NyZWVuIHJhdGhlciB0aGFuIHdvcmxkLCB3aGljaCBpcyB3aGF0IFwiMiBpbWFnZSBweFwiIGFsd2F5cyBtZWFudCBpbiBwcmFjdGljZTogYXQgMTAwJVxuICogem9vbSBvdmVyIGFuIGltYWdlIHRoZSB0d28gYXJlIHRoZSBzYW1lIHRoaW5nLiBUYWtlbiBhcyB3b3JsZCB1bml0cyBpdCBicmVha3Mgb24gYW55XG4gKiBkYXRhc2V0IHdob3NlIHdvcmxkIGlzIHNtYWxsIOKAlCBzZXFGSVNIJ3Mgc2FtcGxlIHNwYW5zIGFib3V0IDUgdW5pdHMsIHNvIGEgMi11bml0XG4gKiB0aHJlc2hvbGQgcmVjb3JkcyBhIHBvaW50IGV2ZXJ5IDQwJSBvZiB0aGUgd2F5IGFjcm9zcyBhbmQgYSBmcmVlaGFuZCBST0kgY29tZXMgb3V0IGFzIGFcbiAqIHRyaWFuZ2xlLiBBZ2FpbnN0IHRoZSBzY3JlZW4gaXQgYWxzbyBkb2VzIHRoZSByaWdodCB0aGluZyB1bmRlciB6b29tOiBkcmF3aW5nIHpvb21lZCBpblxuICogcmVjb3JkcyBhIGZpbmVyIHBhdGgsIGJlY2F1c2UgdGhhdCBpcyBleGFjdGx5IHdoZW4gdGhlIGV4dHJhIGRldGFpbCBpcyB2aXNpYmxlLlxuICovXG5jb25zdCBGUkVFSEFORF9TVEVQX1BYID0gMjtcbi8qKlxuICogU21hbGxlc3QgY29tbWl0dGVkIHJlY3RhbmdsZSwgaW4gU0NSRUVOIHBpeGVscyBvbiBlYWNoIHNpZGUuXG4gKlxuICogSXRzIGpvYiBpcyB0byB0aHJvdyBhd2F5IGEgY2xpY2sgdGhhdCB3YXMgbm90IGEgZHJhZy4gSGVsZCBpbiB3b3JsZCB1bml0cyDigJQgd2hpY2ggaXQgd2FzXG4gKiDigJQgaXQgaW5zdGVhZCB0aHJvd3MgYXdheSByZWFsIGRyYWdzIG9uIGFueSBkYXRhc2V0IHdob3NlIHdvcmxkIGlzIHNtYWxsOiBpbiBzZXFGSVNIJ3NcbiAqIH41IHggNyB1bml0IHNhbXBsZSBhIHJlY3RhbmdsZSBoYWQgdG8gY292ZXIgNDAlIG9mIHRoZSB3aWR0aCB0byBjb21taXQgYXQgYWxsLCBhbmRcbiAqIGFueXRoaW5nIHNtYWxsZXIgdmFuaXNoZWQgd2l0aCBubyBmZWVkYmFjay4gVGhhdCB3YXMgdGhlIGRpcmVjdCBjYXVzZSBvZiBST0lzIGJlaW5nXG4gKiBpbXBvc3NpYmxlIHRvIGNyZWF0ZSB0aGVyZS5cbiAqL1xuY29uc3QgTUlOX1JFQ1RfRFJBR19QWCA9IDI7XG4vKipcbiAqIEEgcnViYmVyIGJhbmQgc21hbGxlciB0aGFuIHRoaXMgb24gYm90aCBzaWRlcywgaW4gU0NSRUVOIHBpeGVscywgaXMgYSBjbGljayBvbiBlbXB0eSBzcGFjZVxuICogKGl0IGNsZWFycyB0aGUgc2VsZWN0aW9uKS4gU2NyZWVuIGZvciB0aGUgc2FtZSByZWFzb24gYXMge0BsaW5rIE1JTl9SRUNUX0RSQUdfUFh9OiAzIHdvcmxkXG4gKiB1bml0cyBpcyBvdmVyIGhhbGYgb2Ygc2VxRklTSCdzIHNhbXBsZS5cbiAqL1xuY29uc3QgTUlOX01BUlFVRUVfUFggPSAzO1xuLyoqIENsaWNrLWRpc3RhbmNlIChzY3JlZW4gcHgpIHdpdGhpbiB3aGljaCBhIHBvbHlnb24gY2xpY2sgc25hcHMgY2xvc2VkIG9udG8gdGhlIGZpcnN0IHZlcnRleC4gKi9cbmNvbnN0IENMT1NFX1NOQVBfUFggPSAxMDtcbi8qKiBTY3JlZW4tcHggaGl0IHJhZGl1cyBmb3IgZ3JhYmJpbmcgYSB2ZXJ0ZXggLyByZWN0YW5nbGUgY29ybmVyIGhhbmRsZS4gKi9cbmNvbnN0IEhBTkRMRV9ISVRfUFggPSA5O1xuLyoqIFNjcmVlbi1weCBkaXN0YW5jZSBmcm9tIGFuIG9wZW4gcG9seWxpbmUgd2l0aGluIHdoaWNoIGEgY2xpY2sgc2VsZWN0cyBpdCAoYXMgT1NEKS4gKi9cbmNvbnN0IE9QRU5fUEFUSF9ISVRfUFggPSA2O1xuXG4vKipcbiAqIFRoZSBzbGljZSBvZiB0aGUgbmFwYXJpIFZpZXdlciB0aGUgb3ZlcmxheSBuZWVkcyAoY29vcmQgdHJhbnNmb3JtcyArIGNvbnRyb2wgZ2F0aW5nKS5cbiAqXG4gKiBDT09SRElOQVRFIFNQQUNFUzogYGNhbnZhc1RvV29ybGRgIHRha2VzIENMSUVOVCBwaXhlbHMgKHZpZXdwb3J0IGNvb3JkaW5hdGVzLCBhcyBhIHBvaW50ZXJcbiAqIGV2ZW50J3MgYGNsaWVudFgvWWApLCBleGFjdGx5IGFzIG5hcGFyaS1qcyBgVmlld2VyLmNhbnZhc1RvV29ybGRgIGRvZXMuIGBjYW52YXNUcmFuc2Zvcm1gIGlzXG4gKiB0aGUgY2FtZXJhJ3Mgd29ybGQg4oaSIENBTlZBUy1MT0NBTCBDU1MtcGl4ZWwgYWZmaW5lLCBuYXBhcmktanMgYFZpZXdlci5jYW52YXNUcmFuc2Zvcm1gLCB3aGljaFxuICogcmVhZHMgbm8gbGF5b3V0OiBkcmF3aW5nIGFuZCBmb2xsb3dpbmcgdGhlIGNhbWVyYSB1c2UgaXQsIHNvIGEgY2FtZXJhIGZyYW1lIGNvc3RzIG9uZVxuICogYG1hdHJpeCguLi4pYCBhbmQgbm8gYGdldEJvdW5kaW5nQ2xpZW50UmVjdCgpYCAocmV2aWV3IE5BUEFSSS1CT1VOREFSWS0xMCkuIFRoZSBzdmcgY292ZXJzIHRoZVxuICogcGxvdCBob3N0IGFuZCB0aGUgY2FudmFzIGlzIHRoZSBob3N0J3MgaW4tZmxvdyBjaGlsZCBhdCBpdHMgdG9wLWxlZnQsIHNvIGNhbnZhcy1sb2NhbCBhbmRcbiAqIHN2Zy1sb2NhbCBwaXhlbHMgYXJlIHRoZSBzYW1lOyBhIHBvaW50ZXIncyBjbGllbnQgcGl4ZWxzIGFyZSBtYXBwZWQgaW50byB0aGUgc3ZnIGJ5IHRoZVxuICogb3ZlcmxheSBpdHNlbGYuXG4gKlxuICogRXhwb3J0ZWQgYmVjYXVzZSB0aGUgM0Qgc3BhdGlhbCBtb2RlIHN1cHBsaWVzIGEgU0NSRUVOLVNQQUNFIGltcGxlbWVudGF0aW9uIG9mIGl0OiB0aGVyZSB0aGVcbiAqIGRyYXduIHNoYXBlIGlzIGEgbGFzc28gaW4gY2FudmFzIHBpeGVscywgbm90IGEgcmVjdGFuZ2xlIGluIGltYWdlIHNwYWNlLCBzbyBcIndvcmxkXCIgaXMgdGhlXG4gKiBjYW52YXMgaXRzZWxmIOKAlCBgY2FudmFzVG9Xb3JsZGAgaXMgdGhlIGNsaWVudCDihpIgY2FudmFzIG9mZnNldCBhbmQgYGNhbnZhc1RyYW5zZm9ybWAgdGhlXG4gKiBpZGVudGl0eS4gVGhhdCBsZXRzIHRoZSAzRCB2aWV3IHJldXNlIHRoaXMgd2hvbGUgb3ZlcmxheSDigJQgZXZlcnkgdG9vbCwgdGhlIGhhbmRsZXMsIHRoZSBzdG9yZVxuICogcm91bmQtdHJpcCDigJQgd2l0aCBubyAzRC1zcGVjaWZpYyBkcmF3aW5nIGNvZGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT3ZlcmxheVZpZXdlciB7XG4gIC8qKiBDbGllbnQgcHgg4oaSIHdvcmxkLiAqL1xuICBjYW52YXNUb1dvcmxkKGNsaWVudFg6IG51bWJlciwgY2xpZW50WTogbnVtYmVyKTogW251bWJlciwgbnVtYmVyXTtcbiAgLyoqIFdvcmxkIOKGkiBjYW52YXMtbG9jYWwgKD0gc3ZnLWxvY2FsKSBDU1MgcHgsIGFzIGFuIFNWRyBhZmZpbmUgYFthLCBiLCBjLCBkLCBlLCBmXWAuICovXG4gIGNhbnZhc1RyYW5zZm9ybSgpOiBBZmZpbmU7XG4gIHNldENvbnRyb2xzRW5hYmxlZChlbmFibGVkOiBib29sZWFuKTogdm9pZDtcbiAgcmVhZG9ubHkgY2FtZXJhOiB7IHJlYWRvbmx5IGNoYW5nZWQ6IHsgY29ubmVjdChsaXN0ZW5lcjogKCkgPT4gdm9pZCk6ICgpID0+IHZvaWQgfSB9O1xufVxuXG4vKipcbiAqIFNWRyByZWdpb24gb3ZlcmxheSBmb3IgdGhlIG5hcGFyaS1qcyBXZWJHUFUgaW1hZ2UgdmlldyAoaml0LXVpIzEwMiksIG1pcnJvcmluZyB0aGUgT1NEIGJhY2tlbmQnc1xuICoge0BsaW5rIE9zZFJlZ2lvbk92ZXJsYXl9IGJ1dCBkcml2ZW4gYnkgbmFwYXJpJ3MgYGNhbnZhc1RvV29ybGRgL2BjYW52YXNUcmFuc2Zvcm1gIHRyYW5zZm9ybXNcbiAqIChzZWUge0BsaW5rIE92ZXJsYXlWaWV3ZXJ9IGZvciB0aGVpciBjb29yZGluYXRlIHNwYWNlcykuXG4gKiBWZWN0b3Igc2hhcGVzIGFyZSBkcmF3biBpbiBhbiBhYnNvbHV0ZWx5LXBvc2l0aW9uZWQgYDxzdmc+YCBvdmVyIHRoZSBjYW52YXMgKG5vIG5lZWQgdG8gcHVzaFxuICogdGhlbSB0aHJvdWdoIFdlYkdQVSkgYnkge0BsaW5rIE5hcGFyaVJlZ2lvblN2Z1JlbmRlcmVyfSBvdmVyIHRoZSBzaGFyZWQgYFN2Z1JlZ2lvblJlbmRlcmVyYDpcbiAqIGluIHdvcmxkIGNvb3JkaW5hdGVzIGluc2lkZSBvbmUgdHJhbnNmb3JtZWQgZ3JvdXAsIHJlYnVpbHQgb24gYSByZWdpb24gb3Igc2VsZWN0aW9uIGNoYW5nZSxcbiAqIHdoaWxlIGEgY2FtZXJhIG1vdmUgb25seSByZXdyaXRlcyB0aGUgdHJhbnNmb3JtIChuYXBhcmktanMncyBgY2FudmFzVHJhbnNmb3JtYCwgdGhlIGNhbWVyYVxuICogY2VudHJlL3pvb20pIGFuZCB0aGUgZmV3IHNjcmVlbi1zcGFjZSBoYW5kbGVzIGFuZCBsYWJlbHMuIFRoaXMgY2xhc3MgaXNcbiAqIHRoZSBnZXN0dXJlIGNvbnRyb2xsZXI6IHBvaW50ZXIgaGFuZGxlcnMsIHRoZSB0b29sIG1vZGUsIGFuZCB0aGUgZWRpdC9kcmFmdC9tYXJxdWVlIHN0YXRlLlxuICogSXQgd3JpdGVzIGNvbXBsZXRlZCBzaGFwZXMgdG8gdGhlIHNoYXJlZCB7QGxpbmsgUmVnaW9uU3RvcmV9IChzbyBzYXZlIC8gdW5kbyAvIGV4cG9ydCB3b3JrXG4gKiBpZGVudGljYWxseSB0byBPU0QpLlxuICpcbiAqIFN1cHBvcnRzIChqaXQtdWkjMTAyKTogcmVjdGFuZ2xlIC8gcG9seWdvbiAvIGZyZWVoYW5kIHBhdGggZHJhd2luZywgY2xpY2stc2VsZWN0IGFuZCBydWJiZXItYmFuZFxuICogbWFycXVlZSBzZWxlY3QsIHBhbi96b29tIGdhdGluZyB2aWEgYHNldENvbnRyb2xzRW5hYmxlZGAsIGJvZHkgbW92ZSwgdmVydGV4IG1vdmUvYWRkL2RlbGV0ZSxcbiAqIGJlemllciBoYW5kbGUgZWRpdGluZywgYW5kIGRvbnV0IGhvbGVzIChpbmNsdWRpbmcgaG9sZSB2ZXJ0ZXggKyBob2xlLWJlemllci1oYW5kbGUgZWRpdGluZykuXG4gKiBIaXQtdGVzdGluZyBzaGFyZXMgYHJlZ2lvbi1vdmVybGF5L3JlZ2lvbi1nZW9tZXRyeWAgd2l0aCB0aGUgT1NEIG92ZXJsYXksIHNvIGJvdGggZm9sbG93XG4gKiB0aGUgc2FtZSBydWxlcyAobXVsdGktcGFydCByZWdpb25zLCBob2xlcywgb3BlbiBwb2x5bGluZXMsIGhhbmRsZS1sZXNzIGJlemllciBjdXJ2ZXMpLlxuICovXG5leHBvcnQgY2xhc3MgTmFwYXJpUmVnaW9uT3ZlcmxheSBpbXBsZW1lbnRzIElSZWdpb25PdmVybGF5IHtcbiAgcHJpdmF0ZSByZWFkb25seSBzdmc6IFNWR1NWR0VsZW1lbnQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVuZGVyZXI6IE5hcGFyaVJlZ2lvblN2Z1JlbmRlcmVyO1xuICAvKiogQ2xpZW50IOKGlCBzdmctbG9jYWwg4oaUIHdvcmxkIGNvbnZlcnNpb25zLCB3aXRoIHRoZSBzdmcgb3JpZ2luIHJlYWQgb25jZSBwZXIgZ2VzdHVyZS9yZWRyYXcuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgcHJvamVjdGlvbjogT3ZlcmxheVByb2plY3Rpb247XG4gIHByaXZhdGUgcmVhZG9ubHkgc3VicyA9IG5ldyBTdWJzY3JpcHRpb24oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBkaXNjb25uZWN0Q2FtZXJhOiAoKSA9PiB2b2lkO1xuXG4gIHByaXZhdGUgbW9kZTogUmVnaW9uVG9vbE1vZGUgPSAnbm9uZSc7XG4gIHByaXZhdGUgc2VsZWN0ZWQ6IG51bWJlcltdID0gW107XG5cbiAgLyoqIEluLXByb2dyZXNzIGRyYXdpbmcgc3RhdGUgKGltYWdlLXNwYWNlKS4gKi9cbiAgcHJpdmF0ZSBkcmFmdFJlY3Q6IERyYWdCb3ggfCBudWxsID0gbnVsbDtcbiAgLyoqIEluLXByb2dyZXNzIHJ1YmJlci1iYW5kIHNlbGVjdGlvbiBtYXJxdWVlIChzZWxlY3QgbW9kZSksIGltYWdlLXNwYWNlLiAqL1xuICBwcml2YXRlIG1hcnF1ZWU6IERyYWdCb3ggfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBkcmFmdFBhdGg6IEFycmF5PFtudW1iZXIsIG51bWJlcl0+IHwgbnVsbCA9IG51bGw7IC8vIGZyZWVoYW5kIG9yIGNsaWNrIHBvbHlnb25cbiAgcHJpdmF0ZSBkcmF3aW5nID0gZmFsc2U7IC8vIHBvaW50ZXIgaXMgZG93biBmb3IgcmVjdCAvIGZyZWVoYW5kXG4gIHByaXZhdGUgcmVnaW9uc1Zpc2libGUgPSB0cnVlO1xuXG4gIC8qKiBJbi1wcm9ncmVzcyBtYW5pcHVsYXRpb24gKHNlbGVjdC9tb3ZlIG1vZGVzKTogZHJhZ2dpbmcgYSBib2R5LCBhIHBvbHlnb24gdmVydGV4LCBvciBhXG4gICAqICByZWN0YW5nbGUgY29ybmVyLiBgYW5jaG9yYCBpcyB0aGUgZml4ZWQgb3Bwb3NpdGUgY29ybmVyIGZvciBhIHJlY3RhbmdsZSByZXNpemUuICovXG4gIHByaXZhdGUgZWRpdDogUmVnaW9uRWRpdCB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgaG9zdDogSFRNTEVsZW1lbnQsXG4gICAgcHJpdmF0ZSByZWFkb25seSB2aWV3ZXI6IE92ZXJsYXlWaWV3ZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSBzdG9yZTogUmVnaW9uU3RvcmUsXG4gICkge1xuICAgIGlmIChnZXRDb21wdXRlZFN0eWxlKGhvc3QpLnBvc2l0aW9uID09PSAnc3RhdGljJykgaG9zdC5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XG4gICAgdGhpcy5zdmcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoU1ZHX05TLCAnc3ZnJyk7XG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLnN2Zy5zdHlsZSwge1xuICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICBpbnNldDogJzAnLFxuICAgICAgd2lkdGg6ICcxMDAlJyxcbiAgICAgIGhlaWdodDogJzEwMCUnLFxuICAgICAgekluZGV4OiAnMjAnLFxuICAgICAgcG9pbnRlckV2ZW50czogJ25vbmUnLCAvLyB1bnRpbCBhIHRvb2wgYWN0aXZhdGVzXG4gICAgICB0b3VjaEFjdGlvbjogJ25vbmUnLFxuICAgIH0gYXMgUGFydGlhbDxDU1NTdHlsZURlY2xhcmF0aW9uPik7XG4gICAgdGhpcy5ob3N0LmFwcGVuZENoaWxkKHRoaXMuc3ZnKTtcbiAgICB0aGlzLnJlbmRlcmVyID0gbmV3IE5hcGFyaVJlZ2lvblN2Z1JlbmRlcmVyKHRoaXMuc3ZnLCB0aGlzLnN0b3JlKTtcbiAgICB0aGlzLnByb2plY3Rpb24gPSBuZXcgT3ZlcmxheVByb2plY3Rpb24odGhpcy5zdmcsIHRoaXMudmlld2VyKTtcblxuICAgIHRoaXMuc3ZnLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJkb3duJywgdGhpcy5vblBvaW50ZXJEb3duKTtcbiAgICB0aGlzLnN2Zy5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVybW92ZScsIHRoaXMub25Qb2ludGVyTW92ZSk7XG4gICAgdGhpcy5zdmcuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcnVwJywgdGhpcy5vblBvaW50ZXJVcCk7XG4gICAgdGhpcy5zdmcuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcmNhbmNlbCcsIHRoaXMub25Qb2ludGVyQ2FuY2VsKTtcbiAgICB0aGlzLnN2Zy5hZGRFdmVudExpc3RlbmVyKCdsb3N0cG9pbnRlcmNhcHR1cmUnLCB0aGlzLm9uUG9pbnRlckNhbmNlbCk7XG4gICAgdGhpcy5zdmcuYWRkRXZlbnRMaXN0ZW5lcignZGJsY2xpY2snLCB0aGlzLm9uRGJsQ2xpY2spO1xuXG4gICAgdGhpcy5zdWJzLmFkZCh0aGlzLnN0b3JlLmdldFJlZ2lvblVwZGF0ZUV2ZW50KCkuc3Vic2NyaWJlKCgpID0+IHRoaXMucmVkcmF3KCkpKTtcbiAgICB0aGlzLnN1YnMuYWRkKFxuICAgICAgdGhpcy5zdG9yZS5nZXRTZWxlY3RlZFNoYXBlSW5kaWNlcyQoKS5zdWJzY3JpYmUoKGlkeCkgPT4ge1xuICAgICAgICB0aGlzLnNlbGVjdGVkID0gaWR4ID8/IFtdO1xuICAgICAgICB0aGlzLnJlZHJhdygpO1xuICAgICAgfSksXG4gICAgKTtcbiAgICAvLyBBIGNhbWVyYSBtb3ZlIHJld3JpdGVzIHRoZSByZW5kZXJlcidzIHRyYW5zZm9ybSBhbmQgaXRzIGZldyBzY3JlZW4tc3BhY2UgZWxlbWVudHM7XG4gICAgLy8gdGhlIHJlZ2lvbnMgYXJlIGRyYXduIGluIHdvcmxkIGNvb3JkaW5hdGVzIGFuZCBhcmUgbm90IHJlYnVpbHQgKE5BUEFSSS1CT1VOREFSWS0xMCkuXG4gICAgdGhpcy5kaXNjb25uZWN0Q2FtZXJhID0gdGhpcy52aWV3ZXIuY2FtZXJhLmNoYW5nZWQuY29ubmVjdCgoKSA9PiB0aGlzLnVwZGF0ZUNhbWVyYSgpKTtcbiAgICB0aGlzLnJlZHJhdygpO1xuICB9XG5cbiAgLy8g4pSA4pSAIElSZWdpb25PdmVybGF5IOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAvKipcbiAgICogV2hldGhlciBhIHJlZ2lvbiB0b29sIGN1cnJlbnRseSBvd25zIHRoZSBwb2ludGVyLlxuICAgKlxuICAgKiBFeHBvc2VkIHNvIHRoZSBzcGF0aWFsIHZpZXdzIGNhbiB0ZWxsIGEgYmFyZSBjbGljayBvbiB0aGUgY2xvdWQgKHNlbGVjdCB0aGVcbiAgICogY2xhc3MgdW5kZXIgdGhlIGN1cnNvcikgZnJvbSBhIGNsaWNrIHRoYXQgYmVsb25ncyB0byBhIGRyYXdpbmcgZ2VzdHVyZSDigJRcbiAgICogcGxhY2luZyBhIHBvbHlnb24gdmVydGV4IGlzIGFsc28gYSBjbGljayB0aGF0IGRvZXMgbm90IG1vdmUsIGFuZCBpdCBtdXN0IG5vdFxuICAgKiBjaGFuZ2UgdGhlIHNlbGVjdGlvbiBiZWhpbmQgdGhlIHNoYXBlIGJlaW5nIGRyYXduLlxuICAgKi9cbiAgZ2V0IHRvb2xBY3RpdmUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubW9kZSAhPT0gJ25vbmUnO1xuICB9XG5cbiAgc2V0TW9kZShtb2RlOiBSZWdpb25Ub29sTW9kZSk6IHZvaWQge1xuICAgIHRoaXMuZW5kR2VzdHVyZSgpO1xuICAgIHRoaXMubW9kZSA9IG1vZGU7XG4gICAgdGhpcy5kcmFmdFJlY3QgPSBudWxsO1xuICAgIHRoaXMuZHJhZnRQYXRoID0gbnVsbDtcbiAgICAvLyBUaGUgb3ZlcmxheSBvd25zIHBvaW50ZXIvbmF2aWdhdGlvbiBnYXRpbmc6IHdoaWxlIGEgdG9vbCBpcyBhY3RpdmUgaXQgY2FwdHVyZXMgdGhlIHBvaW50ZXJcbiAgICAvLyBhbmQgdGhlIG5hcGFyaSBjYW1lcmEgY29udHJvbHMgYXJlIGRpc2FibGVkOyAnbm9uZScgaGFuZHMgdGhlIHBvaW50ZXIgYmFjayBmb3IgcGFuL3pvb20uXG4gICAgY29uc3QgYWN0aXZlID0gbW9kZSAhPT0gJ25vbmUnO1xuICAgIHRoaXMudmlld2VyLnNldENvbnRyb2xzRW5hYmxlZCghYWN0aXZlKTtcbiAgICB0aGlzLnN2Zy5zdHlsZS5wb2ludGVyRXZlbnRzID0gYWN0aXZlID8gJ2F1dG8nIDogJ25vbmUnO1xuICAgIHRoaXMuc3ZnLnN0eWxlLmN1cnNvciA9IGFjdGl2ZSA/ICdjcm9zc2hhaXInIDogJ2RlZmF1bHQnO1xuICAgIHRoaXMucmVuZGVyT3ZlcmxheSgpO1xuICB9XG5cbiAgc2V0U2VsZWN0ZWRCZXppZXIoYmV6aWVyOiBib29sZWFuKTogdm9pZCB7XG4gICAgY29uc3Qgc2VsID0gdGhpcy5zZWxlY3RlZFJlZ2lvbigpO1xuICAgIGlmIChzZWw/LmlkICE9IG51bGwpIHRoaXMuc3RvcmUuc2V0QmV6aWVyKHNlbC5pZCwgYmV6aWVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIb3cgZmluZWx5IGEgZHJhd24gdmVydGV4IG1heSBiZSBwbGFjZWQsIGluIHdvcmxkIHVuaXRzOiBvbmUgKGFuIGltYWdlJ3MgcGl4ZWxzKSBieVxuICAgKiBkZWZhdWx0LCBmaW5lciBmb3IgYSBkYXRhc2V0IHdob3NlIGNvb3JkaW5hdGVzIGFyZSBub3QgcGl4ZWxzIChzZWUgT3ZlcmxheVByb2plY3Rpb24pLlxuICAgKi9cbiAgc2V0V29ybGRRdWFudHVtKHF1YW50dW06IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMucHJvamVjdGlvbi5zZXRXb3JsZFF1YW50dW0ocXVhbnR1bSk7XG4gIH1cblxuICBkZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuc3ZnLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJkb3duJywgdGhpcy5vblBvaW50ZXJEb3duKTtcbiAgICB0aGlzLnN2Zy5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVybW92ZScsIHRoaXMub25Qb2ludGVyTW92ZSk7XG4gICAgdGhpcy5zdmcucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcnVwJywgdGhpcy5vblBvaW50ZXJVcCk7XG4gICAgdGhpcy5zdmcucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcmNhbmNlbCcsIHRoaXMub25Qb2ludGVyQ2FuY2VsKTtcbiAgICB0aGlzLnN2Zy5yZW1vdmVFdmVudExpc3RlbmVyKCdsb3N0cG9pbnRlcmNhcHR1cmUnLCB0aGlzLm9uUG9pbnRlckNhbmNlbCk7XG4gICAgdGhpcy5zdmcucmVtb3ZlRXZlbnRMaXN0ZW5lcignZGJsY2xpY2snLCB0aGlzLm9uRGJsQ2xpY2spO1xuICAgIHRoaXMuZGlzY29ubmVjdENhbWVyYSgpO1xuICAgIHRoaXMuc3Vicy51bnN1YnNjcmliZSgpO1xuICAgIC8vIEEgZHJhZyB0b3JuIGRvd24gbWlkLWdlc3R1cmUgKGEgYmFja2VuZCBzd2l0Y2gpIG11c3Qgc3RpbGwgY2xvc2UgaXRzIHN0b3JlIGJhdGNoLlxuICAgIHRoaXMuZW5kR2VzdHVyZSgpO1xuICAgIGlmICh0aGlzLnN2Zy5wYXJlbnROb2RlKSB0aGlzLnN2Zy5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRoaXMuc3ZnKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBwb2ludGVyIGhhbmRsZXJzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICBwcml2YXRlIHJlYWRvbmx5IG9uUG9pbnRlckRvd24gPSAoZTogUG9pbnRlckV2ZW50KTogdm9pZCA9PiB7XG4gICAgaWYgKHRoaXMubW9kZSA9PT0gJ25vbmUnKSByZXR1cm47XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMucHJvamVjdGlvbi53aXRoT3JpZ2luKCgpID0+IHRoaXMucG9pbnRlckRvd24oZSkpO1xuICB9O1xuXG4gIHByaXZhdGUgcG9pbnRlckRvd24oZTogUG9pbnRlckV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgW2l4LCBpeV0gPSB0aGlzLnByb2plY3Rpb24udG9JbWFnZShlLmNsaWVudFgsIGUuY2xpZW50WSk7XG4gICAgaWYgKHRoaXMubW9kZSA9PT0gJ2RyYXdyZWN0Jykge1xuICAgICAgdGhpcy5kcmFmdFJlY3QgPSB7IHgwOiBpeCwgeTA6IGl5LCB4MTogaXgsIHkxOiBpeSB9O1xuICAgICAgdGhpcy5kcmF3aW5nID0gdHJ1ZTtcbiAgICAgIHRoaXMuc3ZnLnNldFBvaW50ZXJDYXB0dXJlKGUucG9pbnRlcklkKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMubW9kZSA9PT0gJ2RyYXdjbG9zZWRwYXRoJyB8fCB0aGlzLm1vZGUgPT09ICdkcmF3b3BlbnBhdGgnKSB7XG4gICAgICB0aGlzLmRyYWZ0UGF0aCA9IFtbaXgsIGl5XV07XG4gICAgICB0aGlzLmRyYXdpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5zdmcuc2V0UG9pbnRlckNhcHR1cmUoZS5wb2ludGVySWQpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5tb2RlID09PSAnZHJhd3BvbHlnb24nKSB7XG4gICAgICB0aGlzLmhhbmRsZVBvbHlnb25DbGljayhpeCwgaXksIGUuY2xpZW50WCwgZS5jbGllbnRZKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMubW9kZSA9PT0gJ3NlbGVjdCcgfHwgdGhpcy5tb2RlID09PSAnbW92ZScpIHtcbiAgICAgIHRoaXMuYmVnaW5NYW5pcHVsYXRpb24oaXgsIGl5LCBlKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMubW9kZSA9PT0gJ2FkZHBvaW50Jykge1xuICAgICAgdGhpcy5oYW5kbGVBZGRQb2ludChpeCwgaXksIGUuY2xpZW50WCwgZS5jbGllbnRZKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMubW9kZSA9PT0gJ2RlbGV0ZXBvaW50Jykge1xuICAgICAgdGhpcy5oYW5kbGVEZWxldGVQb2ludChpeCwgaXkpO1xuICAgIH1cbiAgICB0aGlzLnJlZHJhdygpO1xuICB9XG5cbiAgcHJpdmF0ZSByZWFkb25seSBvblBvaW50ZXJNb3ZlID0gKGU6IFBvaW50ZXJFdmVudCk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IFtpeCwgaXldID0gdGhpcy5wcm9qZWN0aW9uLnRvSW1hZ2UoZS5jbGllbnRYLCBlLmNsaWVudFkpO1xuICAgIGlmICh0aGlzLm1hcnF1ZWUpIHtcbiAgICAgIHRoaXMubWFycXVlZS54MSA9IGl4O1xuICAgICAgdGhpcy5tYXJxdWVlLnkxID0gaXk7XG4gICAgICB0aGlzLnVwZGF0ZU1hcnF1ZWVFbCgpOyAvLyB1cGRhdGUganVzdCB0aGUgbWFycXVlZSByZWN0IOKAlCBOT1QgYSBmdWxsIHJlZ2lvbiByZWRyYXdcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMuZWRpdCkge1xuICAgICAgYXBwbHlSZWdpb25FZGl0KHRoaXMuc3RvcmUsIHRoaXMuZWRpdCwgaXgsIGl5KTtcbiAgICAgIHRoaXMucmVkcmF3KCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghdGhpcy5kcmF3aW5nKSByZXR1cm47XG4gICAgaWYgKHRoaXMuZHJhZnRSZWN0KSB7XG4gICAgICB0aGlzLmRyYWZ0UmVjdC54MSA9IGl4O1xuICAgICAgdGhpcy5kcmFmdFJlY3QueTEgPSBpeTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuZHJhZnRQYXRoKSB7XG4gICAgICBjb25zdCBzdGVwID0gRlJFRUhBTkRfU1RFUF9QWCAqIHRoaXMucHJvamVjdGlvbi53b3JsZFBlckNhbnZhc1BpeGVsKCk7XG4gICAgICBjb25zdCBsYXN0ID0gdGhpcy5kcmFmdFBhdGhbdGhpcy5kcmFmdFBhdGgubGVuZ3RoIC0gMV07XG4gICAgICBpZiAoTWF0aC5hYnMoaXggLSBsYXN0WzBdKSA+PSBzdGVwIHx8IE1hdGguYWJzKGl5IC0gbGFzdFsxXSkgPj0gc3RlcCkge1xuICAgICAgICB0aGlzLmRyYWZ0UGF0aC5wdXNoKFtpeCwgaXldKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5yZW5kZXJPdmVybGF5KCk7XG4gIH07XG5cbiAgcHJpdmF0ZSByZWFkb25seSBvblBvaW50ZXJVcCA9IChlOiBQb2ludGVyRXZlbnQpOiB2b2lkID0+IHtcbiAgICBpZiAodGhpcy5tYXJxdWVlKSB7XG4gICAgICBjb25zdCBtID0gdGhpcy5tYXJxdWVlO1xuICAgICAgdGhpcy5tYXJxdWVlID0gbnVsbDtcbiAgICAgIHRoaXMucmVuZGVyZXIuY2xlYXJNYXJxdWVlKCk7XG4gICAgICB0cnkge1xuICAgICAgICB0aGlzLnN2Zy5yZWxlYXNlUG9pbnRlckNhcHR1cmUoZS5wb2ludGVySWQpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8qIGFscmVhZHkgcmVsZWFzZWQgKi9cbiAgICAgIH1cbiAgICAgIHRoaXMuZmluaXNoTWFycXVlZShtKTsgLy8gc2V0U2VsZWN0ZWRTaGFwZUluZGljZXMg4oaSIG9uZSByZWRyYXcgdmlhIHRoZSBzZWxlY3Rpb24gc3Vic2NyaXB0aW9uXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLmVkaXQpIHtcbiAgICAgIHRoaXMuc3RvcmUuZW5kQmF0Y2goKTtcbiAgICAgIHRoaXMuZWRpdCA9IG51bGw7XG4gICAgICB0cnkge1xuICAgICAgICB0aGlzLnN2Zy5yZWxlYXNlUG9pbnRlckNhcHR1cmUoZS5wb2ludGVySWQpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8qIGFscmVhZHkgcmVsZWFzZWQgKi9cbiAgICAgIH1cbiAgICAgIHRoaXMucmVkcmF3KCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghdGhpcy5kcmF3aW5nKSByZXR1cm47XG4gICAgdGhpcy5kcmF3aW5nID0gZmFsc2U7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMuc3ZnLnJlbGVhc2VQb2ludGVyQ2FwdHVyZShlLnBvaW50ZXJJZCk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvKiBjYXB0dXJlIG1heSBhbHJlYWR5IGJlIHJlbGVhc2VkICovXG4gICAgfVxuICAgIGlmICh0aGlzLmRyYWZ0UmVjdCkge1xuICAgICAgY29uc3QgeyB4MCwgeTAsIHgxLCB5MSB9ID0gdGhpcy5kcmFmdFJlY3Q7XG4gICAgICBjb25zdCB4ID0gTWF0aC5taW4oeDAsIHgxKTtcbiAgICAgIGNvbnN0IHkgPSBNYXRoLm1pbih5MCwgeTEpO1xuICAgICAgY29uc3QgdyA9IE1hdGguYWJzKHgxIC0geDApO1xuICAgICAgY29uc3QgaCA9IE1hdGguYWJzKHkxIC0geTApO1xuICAgICAgdGhpcy5kcmFmdFJlY3QgPSBudWxsO1xuICAgICAgY29uc3QgbWluID0gTUlOX1JFQ1RfRFJBR19QWCAqIHRoaXMucHJvamVjdGlvbi53b3JsZFBlckNhbnZhc1BpeGVsKCk7XG4gICAgICBpZiAodyA+PSBtaW4gJiYgaCA+PSBtaW4pIHRoaXMuY29tbWl0UmVjdGFuZ2xlKHgsIHksIHcsIGgpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5kcmFmdFBhdGgpIHtcbiAgICAgIGNvbnN0IHB0cyA9IHRoaXMuZHJhZnRQYXRoO1xuICAgICAgdGhpcy5kcmFmdFBhdGggPSBudWxsO1xuICAgICAgY29uc3QgY2xvc2VkID0gdGhpcy5tb2RlID09PSAnZHJhd2Nsb3NlZHBhdGgnO1xuICAgICAgaWYgKHB0cy5sZW5ndGggPj0gKGNsb3NlZCA/IDMgOiAyKSkgdGhpcy5jb21taXRQb2x5Z29uKHB0cywgY2xvc2VkKTtcbiAgICB9XG4gICAgdGhpcy5yZWRyYXcoKTtcbiAgfTtcblxuICAvKipcbiAgICogVGhlIHBvaW50ZXIgZ2VzdHVyZSBlbmRlZCB3aXRob3V0IGEgcG9pbnRlcnVwICh0aGUgYnJvd3NlciBjYW5jZWxsZWQgaXQsIG9yIGNhcHR1cmUgd2FzXG4gICAqIGxvc3QpOiBlbmQgaXQgd2l0aG91dCBjb21taXR0aW5nLiBBbHNvIGZpcmVzIGFmdGVyIGV2ZXJ5IG5vcm1hbCByZWxlYXNlLCB3aGVuIG5vdGhpbmdcbiAgICogaXMgbGl2ZSBhbnkgbW9yZS5cbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgb25Qb2ludGVyQ2FuY2VsID0gKCk6IHZvaWQgPT4ge1xuICAgIGlmICghdGhpcy5lZGl0ICYmICF0aGlzLmRyYXdpbmcgJiYgIXRoaXMubWFycXVlZSkgcmV0dXJuO1xuICAgIHRoaXMuZW5kR2VzdHVyZSgpO1xuICAgIHRoaXMucmVkcmF3KCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIEVuZCB3aGF0ZXZlciBwb2ludGVyIGdlc3R1cmUgaXMgbGl2ZSB3aXRob3V0IGNvbW1pdHRpbmcgaXQ6IGNsb3NlIHRoZSBzdG9yZSBiYXRjaCBhIGRyYWdcbiAgICogb3BlbmVkIChzbyBsYXRlciBlZGl0cyBhcmUgZW1pdHRlZCBhZ2FpbikgYW5kIGZvcmdldCB0aGUgZHJhZyAoc28gYSBiYXJlIGhvdmVyIG5vIGxvbmdlclxuICAgKiBtb3ZlcyB0aGUgcmVnaW9uKSwgYW5kIGRyb3AgdGhlIG1hcnF1ZWUgYW5kIGEgcmVjdGFuZ2xlL2ZyZWVoYW5kIGRyYWZ0LiBBIGNsaWNrLXBsYWNlZFxuICAgKiBwb2x5Z29uIGlzIG5vdCBhIHBvaW50ZXIgZ2VzdHVyZSBhbmQgc3Vydml2ZXMuXG4gICAqL1xuICBwcml2YXRlIGVuZEdlc3R1cmUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZWRpdCkgdGhpcy5zdG9yZS5lbmRCYXRjaCgpO1xuICAgIHRoaXMuZWRpdCA9IG51bGw7XG4gICAgaWYgKHRoaXMuZHJhd2luZykge1xuICAgICAgdGhpcy5kcmFmdFJlY3QgPSBudWxsO1xuICAgICAgdGhpcy5kcmFmdFBhdGggPSBudWxsO1xuICAgIH1cbiAgICB0aGlzLmRyYXdpbmcgPSBmYWxzZTtcbiAgICB0aGlzLm1hcnF1ZWUgPSBudWxsO1xuICAgIHRoaXMucmVuZGVyZXIuY2xlYXJNYXJxdWVlKCk7XG4gIH1cblxuICAvKiogQ2xpY2stdG8tcGxhY2UgcG9seWdvbjogYWRkIGEgdmVydGV4LCBvciBjbG9zZSB3aGVuIGNsaWNraW5nIG5lYXIgdGhlIGZpcnN0IG9uZS4gKi9cbiAgcHJpdmF0ZSBoYW5kbGVQb2x5Z29uQ2xpY2soaXg6IG51bWJlciwgaXk6IG51bWJlciwgY2xpZW50WDogbnVtYmVyLCBjbGllbnRZOiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZHJhZnRQYXRoKSB7XG4gICAgICB0aGlzLmRyYWZ0UGF0aCA9IFtbaXgsIGl5XV07XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IG5lYXIgPVxuICAgICAgdGhpcy5wcm9qZWN0aW9uLnNjcmVlbkRpc3QoY2xpZW50WCwgY2xpZW50WSwgdGhpcy5kcmFmdFBhdGhbMF1bMF0sIHRoaXMuZHJhZnRQYXRoWzBdWzFdKSA8PSBDTE9TRV9TTkFQX1BYICYmXG4gICAgICB0aGlzLmRyYWZ0UGF0aC5sZW5ndGggPj0gMztcbiAgICBpZiAobmVhcikge1xuICAgICAgY29uc3QgcHRzID0gdGhpcy5kcmFmdFBhdGg7XG4gICAgICB0aGlzLmRyYWZ0UGF0aCA9IG51bGw7XG4gICAgICB0aGlzLmNvbW1pdFBvbHlnb24ocHRzLCB0cnVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5kcmFmdFBhdGgucHVzaChbaXgsIGl5XSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWFkb25seSBvbkRibENsaWNrID0gKGU6IE1vdXNlRXZlbnQpOiB2b2lkID0+IHtcbiAgICBpZiAodGhpcy5tb2RlICE9PSAnZHJhd3BvbHlnb24nIHx8ICF0aGlzLmRyYWZ0UGF0aCkgcmV0dXJuO1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBjb25zdCBwdHMgPSB0aGlzLmRyYWZ0UGF0aDtcbiAgICB0aGlzLmRyYWZ0UGF0aCA9IG51bGw7XG4gICAgaWYgKHB0cy5sZW5ndGggPj0gMykgdGhpcy5jb21taXRQb2x5Z29uKHB0cywgdHJ1ZSk7XG4gICAgdGhpcy5yZWRyYXcoKTtcbiAgfTtcblxuICAvKiogVGhlIGN1cnJlbnRseS1zZWxlY3RlZCByZWdpb24gKHNpbmdsZSBzZWxlY3Rpb24pLCBvciBudWxsLiAqL1xuICBwcml2YXRlIHNlbGVjdGVkUmVnaW9uKCk6IFJlZ2lvbiB8IG51bGwge1xuICAgIGNvbnN0IHJlZ2lvbnMgPSB0aGlzLnN0b3JlLmdldFJlZ2lvbnMoKTtcbiAgICBjb25zdCBpID0gdGhpcy5zZWxlY3RlZFswXTtcbiAgICByZXR1cm4gaSAhPSBudWxsICYmIGkgPj0gMCAmJiBpIDwgcmVnaW9ucy5sZW5ndGggPyByZWdpb25zW2ldIDogbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGFydCBhIHNlbGVjdC9tb3ZlIGludGVyYWN0aW9uOiBncmFiIGEgaGFuZGxlIChyZWN0YW5nbGUgY29ybmVyKSBvciB2ZXJ0ZXggb2YgdGhlIGFscmVhZHktXG4gICAqIHNlbGVjdGVkIHJlZ2lvbiBmaXJzdDsgb3RoZXJ3aXNlIHNlbGVjdCB0aGUgdG9wbW9zdCByZWdpb24gdW5kZXIgdGhlIGN1cnNvciBhbmQgZHJhZyBpdHMgYm9keS5cbiAgICovXG4gIHByaXZhdGUgYmVnaW5NYW5pcHVsYXRpb24oaXg6IG51bWJlciwgaXk6IG51bWJlciwgZTogUG9pbnRlckV2ZW50KTogdm9pZCB7XG4gICAgY29uc3Qgc2VsID0gdGhpcy5zZWxlY3RlZFJlZ2lvbigpO1xuICAgIGlmIChzZWw/LmJvdW5kcykge1xuICAgICAgY29uc3QgW2x4LCBseV0gPSB0aGlzLnByb2plY3Rpb24uY2xpZW50VG9Mb2NhbChlLmNsaWVudFgsIGUuY2xpZW50WSk7XG4gICAgICBjb25zdCBncmFiID0gaGl0SGFuZGxlKHNlbCwgbHgsIGx5LCB0aGlzLnByb2plY3Rpb24udG9TY3JlZW4sIEhBTkRMRV9ISVRfUFgpO1xuICAgICAgaWYgKGdyYWIpIHtcbiAgICAgICAgdGhpcy5zdG9yZS5iZWdpbkJhdGNoKCk7XG4gICAgICAgIHRoaXMuZWRpdCA9IHsgLi4uZ3JhYiwgaWQ6IHNlbC5pZCwgbGFzdDogW2l4LCBpeV0gfTtcbiAgICAgICAgdGhpcy5zdmcuc2V0UG9pbnRlckNhcHR1cmUoZS5wb2ludGVySWQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICAgIC8vIEhpdC10ZXN0IGJvZGllcywgdG9wbW9zdCBmaXJzdCAobGFzdCBkcmF3biByZW5kZXJzIG9uIHRvcCksIGF0IHRoZSBleGFjdCBwb2ludGVyXG4gICAgLy8gcG9zaXRpb24g4oCUIHNuYXBwaW5nIGlzIGZvciBwbGFjaW5nIHZlcnRpY2VzLCBub3QgZm9yIHBpY2tpbmcuXG4gICAgY29uc3QgcmVnaW9ucyA9IHRoaXMuc3RvcmUuZ2V0UmVnaW9ucygpO1xuICAgIGNvbnN0IFt3eCwgd3ldID0gdGhpcy5wcm9qZWN0aW9uLnRvV29ybGQoZS5jbGllbnRYLCBlLmNsaWVudFkpO1xuICAgIGZvciAobGV0IGkgPSByZWdpb25zLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBpZiAocmVnaW9uQ29udGFpbnMocmVnaW9uc1tpXSwgd3gsIHd5LCB7IHRvU2NyZWVuOiB0aGlzLnByb2plY3Rpb24udG9TY3JlZW4sIHRvbFB4OiBPUEVOX1BBVEhfSElUX1BYIH0pKSB7XG4gICAgICAgIHRoaXMuc3RvcmUuc2VsZWN0UmVnaW9uKHJlZ2lvbnNbaV0pO1xuICAgICAgICB0aGlzLnN0b3JlLmJlZ2luQmF0Y2goKTtcbiAgICAgICAgdGhpcy5lZGl0ID0geyBraW5kOiAnYm9keScsIGlkOiByZWdpb25zW2ldLmlkLCBsYXN0OiBbaXgsIGl5XSB9O1xuICAgICAgICB0aGlzLnN2Zy5zZXRQb2ludGVyQ2FwdHVyZShlLnBvaW50ZXJJZCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gRW1wdHkgc3BhY2U6IGluIHNlbGVjdCBtb2RlIHN0YXJ0IGEgcnViYmVyLWJhbmQgbWFycXVlZSAoc2VsZWN0cyB0aGUgcmVnaW9ucyBpdCBjb3ZlcnMgb25cbiAgICAvLyByZWxlYXNlKTsgaW4gbW92ZSBtb2RlIGp1c3QgY2xlYXIgdGhlIHNlbGVjdGlvbi5cbiAgICBpZiAodGhpcy5tb2RlID09PSAnc2VsZWN0Jykge1xuICAgICAgdGhpcy5tYXJxdWVlID0geyB4MDogaXgsIHkwOiBpeSwgeDE6IGl4LCB5MTogaXkgfTtcbiAgICAgIHRoaXMudXBkYXRlTWFycXVlZUVsKCk7XG4gICAgICB0aGlzLnN2Zy5zZXRQb2ludGVyQ2FwdHVyZShlLnBvaW50ZXJJZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc3RvcmUuc2V0U2VsZWN0ZWRTaGFwZUluZGljZXMoW10pO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBTaG93IHRoZSBtYXJxdWVlIHdoZXJlIGl0IGlzIG5vdyAob25seSB0aGUgbWFycXVlZSBlbGVtZW50OiBubyBmdWxsIHJlZ2lvbiByZWRyYXcpLiAqL1xuICBwcml2YXRlIHVwZGF0ZU1hcnF1ZWVFbCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMubWFycXVlZSkgcmV0dXJuO1xuICAgIGNvbnN0IHsgeDAsIHkwLCB4MSwgeTEgfSA9IHRoaXMubWFycXVlZTtcbiAgICBjb25zdCBbbHgsIGx5XSA9IHRoaXMucHJvamVjdGlvbi50b0xvY2FsKE1hdGgubWluKHgwLCB4MSksIE1hdGgubWluKHkwLCB5MSkpO1xuICAgIGNvbnN0IFtyeCwgcnldID0gdGhpcy5wcm9qZWN0aW9uLnRvTG9jYWwoTWF0aC5tYXgoeDAsIHgxKSwgTWF0aC5tYXgoeTAsIHkxKSk7XG4gICAgdGhpcy5yZW5kZXJlci5zaG93TWFycXVlZShseCwgbHksIHJ4LCByeSk7XG4gIH1cblxuICAvKiogYWRkcG9pbnQgbW9kZTogaW5zZXJ0IGEgdmVydGV4IGF0IHRoZSBjbGljayBvbiB0aGUgc2VsZWN0ZWQgcG9seWdvbidzIG5lYXJlc3QgZWRnZVxuICAgKiAgKGV4dGVyaW9yIG9yIGEgaG9sZSByaW5nKS4gKi9cbiAgcHJpdmF0ZSBoYW5kbGVBZGRQb2ludChpeDogbnVtYmVyLCBpeTogbnVtYmVyLCBjbGllbnRYOiBudW1iZXIsIGNsaWVudFk6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHNlbCA9IHRoaXMuc2VsZWN0ZWRSZWdpb24oKTtcbiAgICBpZiAoIXNlbCkgcmV0dXJuO1xuICAgIGNvbnN0IFtseCwgbHldID0gdGhpcy5wcm9qZWN0aW9uLmNsaWVudFRvTG9jYWwoY2xpZW50WCwgY2xpZW50WSk7XG4gICAgY29uc3QgZWRnZSA9IG5lYXJlc3RFZGdlKHNlbCwgbHgsIGx5LCB0aGlzLnByb2plY3Rpb24udG9TY3JlZW4pO1xuICAgIGlmICghZWRnZSkgcmV0dXJuO1xuICAgIGlmIChlZGdlLnJpbmcgPCAwKSB0aGlzLnN0b3JlLmFkZFZlcnRleChzZWwuaWQsIGVkZ2Uuc2VnSW5kZXgsIGl4LCBpeSk7XG4gICAgZWxzZSB0aGlzLnN0b3JlLmFkZEhvbGVWZXJ0ZXgoc2VsLmlkLCBlZGdlLnJpbmcsIGVkZ2Uuc2VnSW5kZXgsIGl4LCBpeSk7XG4gIH1cblxuICAvKiogZGVsZXRlcG9pbnQgbW9kZTogcmVtb3ZlIHRoZSBzZWxlY3RlZCBwb2x5Z29uJ3MgdmVydGV4IG5lYXJlc3QgdGhlIGNsaWNrIChleHRlcmlvciBvciBhXG4gICAqICBob2xlIHJpbmcpLiAqL1xuICBwcml2YXRlIGhhbmRsZURlbGV0ZVBvaW50KGl4OiBudW1iZXIsIGl5OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBzZWwgPSB0aGlzLnNlbGVjdGVkUmVnaW9uKCk7XG4gICAgaWYgKCFzZWwpIHJldHVybjtcbiAgICBjb25zdCB2ID0gbmVhcmVzdFZlcnRleChzZWwsIGl4LCBpeSk7XG4gICAgaWYgKCF2KSByZXR1cm47XG4gICAgaWYgKHYucmluZyA8IDApIHRoaXMuc3RvcmUuZGVsZXRlVmVydGV4KHNlbC5pZCwgdi5pbmRleCk7XG4gICAgZWxzZSB0aGlzLnN0b3JlLmRlbGV0ZUhvbGVWZXJ0ZXgoc2VsLmlkLCB2LnJpbmcsIHYuaW5kZXgpO1xuICB9XG5cbiAgLyoqIEZpbmFsaXplIGEgcnViYmVyLWJhbmQgbWFycXVlZTogc2VsZWN0IGV2ZXJ5IHJlZ2lvbiB3aG9zZSBib3VuZGluZyBib3ggaXQgb3ZlcmxhcHMgKGFcbiAgICogIG1hcnF1ZWUgdW5kZXIge0BsaW5rIE1JTl9NQVJRVUVFX1BYfSBpcyBhIGNsaWNrIG9uIGVtcHR5IHNwYWNlIOKGkiBjbGVhciB0aGUgc2VsZWN0aW9uKS4gKi9cbiAgcHJpdmF0ZSBmaW5pc2hNYXJxdWVlKG06IERyYWdCb3gpOiB2b2lkIHtcbiAgICBjb25zdCB4MCA9IE1hdGgubWluKG0ueDAsIG0ueDEpO1xuICAgIGNvbnN0IHgxID0gTWF0aC5tYXgobS54MCwgbS54MSk7XG4gICAgY29uc3QgeTAgPSBNYXRoLm1pbihtLnkwLCBtLnkxKTtcbiAgICBjb25zdCB5MSA9IE1hdGgubWF4KG0ueTAsIG0ueTEpO1xuICAgIGNvbnN0IG1pbiA9IE1JTl9NQVJRVUVFX1BYICogdGhpcy5wcm9qZWN0aW9uLndvcmxkUGVyQ2FudmFzUGl4ZWwoKTtcbiAgICBpZiAoeDEgLSB4MCA8IG1pbiAmJiB5MSAtIHkwIDwgbWluKSB7XG4gICAgICB0aGlzLnN0b3JlLnNldFNlbGVjdGVkU2hhcGVJbmRpY2VzKFtdKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcmVnaW9ucyA9IHRoaXMuc3RvcmUuZ2V0UmVnaW9ucygpO1xuICAgIHRoaXMuc3RvcmUuc2V0U2VsZWN0ZWRTaGFwZUluZGljZXMocmVnaW9uc0luUmVjdChyZWdpb25zLCB4MCwgeTAsIHgxLCB5MSwgeyBza2lwUHJvZmlsZXM6IHRydWUgfSkpO1xuICB9XG5cbiAgLy8g4pSA4pSAIHNoYXBlIGNvbW1pdCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgcHJpdmF0ZSBjb21taXRSZWN0YW5nbGUoeDogbnVtYmVyLCB5OiBudW1iZXIsIHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgcmVjdCA9IG5ldyBSZWN0YW5nbGUoKTtcbiAgICByZWN0LnggPSB4O1xuICAgIHJlY3QueSA9IHk7XG4gICAgcmVjdC53aWR0aCA9IHdpZHRoO1xuICAgIHJlY3QuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgIGNvbnN0IHJlZ2lvbiA9IG5ldyBSZWdpb24oKTtcbiAgICByZWdpb24uYm91bmRzID0gcmVjdDtcbiAgICByZWdpb24uY29sb3IgPSB0aGlzLnN0b3JlLmdldFNoYXBlQ29sb3IoKTtcbiAgICB0aGlzLnN0b3JlLmFkZFJlZ2lvbihyZWdpb24pO1xuICB9XG5cbiAgcHJpdmF0ZSBjb21taXRQb2x5Z29uKHBvaW50czogQXJyYXk8W251bWJlciwgbnVtYmVyXT4sIGNsb3NlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIGNvbnN0IHBvbHkgPSBuZXcgUG9seWdvbigpO1xuICAgIHBvbHkubnBvaW50cyA9IHBvaW50cy5sZW5ndGg7XG4gICAgcG9seS54cG9pbnRzID0gcG9pbnRzLm1hcCgocCkgPT4gcFswXSk7XG4gICAgcG9seS55cG9pbnRzID0gcG9pbnRzLm1hcCgocCkgPT4gcFsxXSk7XG4gICAgcG9seS5jb29yZGluYXRlcyA9IHBvaW50cy5tYXAoKHApID0+IFtwWzBdLCBwWzFdXSk7XG4gICAgcG9seS5jbG9zZWQgPSBjbG9zZWQ7XG4gICAgY29uc3QgcmVnaW9uID0gbmV3IFJlZ2lvbigpO1xuICAgIHJlZ2lvbi5ib3VuZHMgPSBwb2x5O1xuICAgIHJlZ2lvbi5jb2xvciA9IHRoaXMuc3RvcmUuZ2V0U2hhcGVDb2xvcigpO1xuICAgIHJlZ2lvbi5sYWJlbCA9ICdSZWdpb24nO1xuICAgIHRoaXMuc3RvcmUuYWRkUmVnaW9uKHJlZ2lvbik7XG4gIH1cblxuICAvLyDilIDilIAgcmVuZGVyaW5nIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAvKiogU2hvdyBvciBoaWRlIHRoZSBkcmF3biByZWdpb25zLiBBIHJlZ2lvbiBiZWluZyBkcmF3biBzdGF5cyB2aXNpYmxlIGVpdGhlciB3YXkuICovXG4gIHNldFJlZ2lvbnNWaXNpYmxlKHZpc2libGU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBpZiAodmlzaWJsZSA9PT0gdGhpcy5yZWdpb25zVmlzaWJsZSkgcmV0dXJuO1xuICAgIHRoaXMucmVnaW9uc1Zpc2libGUgPSB2aXNpYmxlO1xuICAgIHRoaXMucmVkcmF3KCk7XG4gIH1cblxuICAvKiogRm9sbG93IGEgY2FtZXJhIG1vdmU6IG9uZSB0cmFuc2Zvcm0gYXR0cmlidXRlIHBsdXMgdGhlIHNjcmVlbi1zcGFjZSBlbGVtZW50cy4gKi9cbiAgcHJpdmF0ZSB1cGRhdGVDYW1lcmEoKTogdm9pZCB7XG4gICAgdGhpcy5yZW5kZXJlci5zZXRDYW1lcmEodGhpcy5wcm9qZWN0aW9uLmFmZmluZSgpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWJ1aWxkIGV2ZXJ5IGVsZW1lbnQgZnJvbSB0aGUgc3RvcmU6IHRoZSByZWdpb25zIGluIHdvcmxkIGNvb3JkaW5hdGVzIChvbmUgdHJhbnNmb3JtZWRcbiAgICogZ3JvdXApLCB0aGVpciBsYWJlbHMsIGFuZCB0aGUgb3ZlcmxheS4gUmVhZHMgbm8gbGF5b3V0OiB0aGUgY2FtZXJhIGFmZmluZSBpcyB0aGUgdmlld2VyJ3MuXG4gICAqL1xuICByZWRyYXcoKTogdm9pZCB7XG4gICAgdGhpcy5yZW5kZXJlci5zZXRDYW1lcmEodGhpcy5wcm9qZWN0aW9uLmFmZmluZSgpKTtcbiAgICB0aGlzLnJlbmRlcmVyLnJlbmRlcih0aGlzLnJlZ2lvbnNWaXNpYmxlID8gdGhpcy5zdG9yZS5nZXRSZWdpb25zKCkgOiBbXSwgdGhpcy5zZWxlY3RlZCk7XG4gICAgdGhpcy5yZW5kZXJPdmVybGF5KCk7XG4gIH1cblxuICAvKiogUmVidWlsZCB0aGUgc2NyZWVuLXNwYWNlIG92ZXJsYXkgb25seTogdGhlIHNlbGVjdGVkIHJlZ2lvbnMnIGhhbmRsZXMgYW5kIHRoZSBkcmFmdC4gKi9cbiAgcHJpdmF0ZSByZW5kZXJPdmVybGF5KCk6IHZvaWQge1xuICAgIHRoaXMucmVuZGVyZXIucmVuZGVyT3ZlcmxheSh0aGlzLnJlZ2lvbnNWaXNpYmxlID8gdGhpcy5zdG9yZS5nZXRSZWdpb25zKCkgOiBbXSwgdGhpcy5zZWxlY3RlZCwge1xuICAgICAgcmVjdDogdGhpcy5kcmFmdFJlY3QsXG4gICAgICBwYXRoOiB0aGlzLmRyYWZ0UGF0aCxcbiAgICB9KTtcbiAgfVxufVxuIl19
|