@jax-data-science/sci-image-visualizer 0.8.3 → 0.10.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 +34 -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/image.contract.mjs +1 -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/region-store.contract.mjs +1 -1
- package/esm2022/lib/contracts/sam.contract.mjs +1 -1
- package/esm2022/lib/contracts/section-view.contract.mjs +2 -0
- 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/loft.mjs +128 -0
- package/esm2022/lib/geometry/polylabel.mjs +156 -0
- package/esm2022/lib/geometry/raster.mjs +98 -0
- package/esm2022/lib/geometry/reconstruct.mjs +315 -0
- package/esm2022/lib/geometry/reslice-image.mjs +57 -0
- package/esm2022/lib/geometry/ring.mjs +201 -0
- package/esm2022/lib/geometry/section.mjs +215 -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 +12 -9
- package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +83 -0
- package/esm2022/lib/implementations/napari-js/napari-region-mesh-pointer.mjs +100 -0
- package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +180 -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 +270 -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 +347 -0
- package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +427 -4207
- package/esm2022/lib/implementations/napari-js/napari-volume-region-meshes.mjs +129 -0
- package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +550 -0
- package/esm2022/lib/implementations/napari-js/napari-volume-slice-planes.mjs +103 -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 +194 -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 +164 -0
- package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +213 -716
- 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 +134 -0
- package/esm2022/lib/models/region-clone.mjs +68 -0
- package/esm2022/lib/models/region-geojson.mjs +411 -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/class-tree/class-tree.component.mjs +156 -0
- package/esm2022/lib/region-editor/class-tree/class-tree.mjs +108 -0
- package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +163 -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 +896 -660
- package/esm2022/lib/region-editor/region-metrics.mjs +86 -0
- package/esm2022/lib/region-editor/region-persistence.service.mjs +160 -0
- package/esm2022/lib/region-editor/region-table/region-table.component.mjs +169 -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/region-source-layer.mjs +378 -0
- package/esm2022/lib/region-overlay/region-style.mjs +97 -0
- package/esm2022/lib/region-overlay/svg-region-renderer.mjs +228 -0
- package/esm2022/lib/region-source/http-region-source.mjs +104 -0
- package/esm2022/lib/region-source/region-source-ops.mjs +53 -0
- package/esm2022/lib/region-source/region-source-worker.mjs +10 -0
- package/esm2022/lib/region-source/region-source.mjs +67 -0
- package/esm2022/lib/region-source/region-tiles.mjs +708 -0
- package/esm2022/lib/region-source/worker-region-source.mjs +229 -0
- package/esm2022/lib/render-orchestrator.mjs +14 -11
- package/esm2022/lib/render-session.mjs +207 -0
- package/esm2022/lib/routing-visualizer.service.mjs +858 -414
- package/esm2022/lib/section-pane/section-pane.component.mjs +299 -0
- 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 +53 -5
- package/esm2022/lib/store/class-signatures.mjs +63 -0
- package/esm2022/lib/store/region-history.mjs +146 -0
- package/esm2022/lib/store/region-scope-cache.mjs +144 -0
- package/esm2022/lib/store/region-selection.mjs +82 -0
- package/esm2022/lib/store/region-source-scope.mjs +171 -0
- package/esm2022/lib/store/region-store.service.mjs +986 -670
- package/esm2022/lib/store/spatial-selection.service.mjs +2 -2
- package/esm2022/lib/store/visualizer-store.service.mjs +81 -76
- 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 +120 -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 +121 -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 +84 -119
- 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 +123 -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/volume-sections.mjs +175 -0
- package/esm2022/lib/visualizer.component.mjs +602 -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-BKQhpbHv.mjs +47169 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-BKQhpbHv.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-z1IN-F7w.mjs +238 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-z1IN-F7w.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.mjs +12 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-region-source-worker-CAqBjM5L.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/region-source.worker.js +1067 -0
- package/fesm2022/spatial-math.worker.js +471 -0
- package/fesm2022/tsne.worker.js +32 -15
- package/index.d.ts +19 -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/image.contract.d.ts +4 -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 +85 -1
- package/lib/contracts/region-overlay.contract.d.ts +5 -0
- package/lib/contracts/region-store.contract.d.ts +22 -0
- package/lib/contracts/sam.contract.d.ts +7 -0
- package/lib/contracts/section-view.contract.d.ts +44 -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 +231 -54
- package/lib/contracts/viz-config.d.ts +9 -0
- package/lib/geometry/contour.d.ts +24 -0
- package/lib/geometry/loft.d.ts +22 -0
- package/lib/geometry/polylabel.d.ts +23 -0
- package/lib/geometry/raster.d.ts +42 -0
- package/lib/geometry/reconstruct.d.ts +54 -0
- package/lib/geometry/reslice-image.d.ts +33 -0
- package/lib/geometry/ring.d.ts +67 -0
- package/lib/geometry/section.d.ts +52 -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 +4 -3
- package/lib/implementations/napari-js/napari-loading-state.d.ts +37 -0
- package/lib/implementations/napari-js/napari-region-mesh-pointer.d.ts +32 -0
- package/lib/implementations/napari-js/napari-region-overlay.d.ts +68 -71
- package/lib/implementations/napari-js/napari-scene.d.ts +126 -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 +91 -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 +169 -883
- package/lib/implementations/napari-js/napari-volume-region-meshes.d.ts +66 -0
- package/lib/implementations/napari-js/napari-volume-scene.d.ts +148 -0
- package/lib/implementations/napari-js/napari-volume-slice-planes.d.ts +43 -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 +38 -0
- package/lib/implementations/osd/osd-region-overlay.d.ts +46 -51
- 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 +83 -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 +25 -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 +45 -0
- package/lib/models/region-clone.d.ts +20 -0
- package/lib/models/region-geojson.d.ts +57 -0
- package/lib/models/region.d.ts +59 -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/class-tree/class-tree.component.d.ts +78 -0
- package/lib/region-editor/class-tree/class-tree.d.ts +31 -0
- package/lib/region-editor/classes-panel/classes-panel.component.d.ts +86 -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 +283 -200
- package/lib/region-editor/region-metrics.d.ts +34 -0
- package/lib/region-editor/region-persistence.service.d.ts +77 -0
- package/lib/region-editor/region-table/region-table.component.d.ts +89 -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 +158 -0
- package/lib/region-overlay/region-hit-test.d.ts +38 -0
- package/lib/region-overlay/region-source-layer.d.ts +96 -0
- package/lib/region-overlay/region-style.d.ts +52 -0
- package/lib/region-overlay/svg-region-renderer.d.ts +110 -0
- package/lib/region-source/http-region-source.d.ts +45 -0
- package/lib/region-source/region-source-ops.d.ts +89 -0
- package/lib/region-source/region-source-worker.d.ts +7 -0
- package/lib/region-source/region-source.d.ts +82 -0
- package/lib/region-source/region-tiles.d.ts +289 -0
- package/lib/region-source/worker-region-source.d.ts +65 -0
- package/lib/render-orchestrator.d.ts +6 -2
- package/lib/render-session.d.ts +75 -0
- package/lib/routing-visualizer.service.d.ts +248 -59
- package/lib/section-pane/section-pane.component.d.ts +47 -0
- 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 +39 -2
- package/lib/store/class-signatures.d.ts +11 -0
- package/lib/store/region-history.d.ts +66 -0
- package/lib/store/region-scope-cache.d.ts +65 -0
- package/lib/store/region-selection.d.ts +36 -0
- package/lib/store/region-source-scope.d.ts +68 -0
- package/lib/store/region-store.service.d.ts +312 -116
- package/lib/store/visualizer-store.service.d.ts +32 -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 +62 -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 +51 -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 +55 -84
- 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 +46 -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/volume-sections.d.ts +64 -0
- package/lib/visualizer.component.d.ts +232 -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/assets/slice.svg +23 -0
- 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,10 @@
|
|
|
1
1
|
import { Subscription } from 'rxjs';
|
|
2
2
|
import { Region, Rectangle, Polygon } from '../../models/region';
|
|
3
|
-
import {
|
|
3
|
+
import { RegionSourceLayer, SOURCE_MARQUEE_LIMIT } from '../../region-overlay/region-source-layer';
|
|
4
|
+
import { hitHandle, nearestEdge, nearestVertex, regionContains, regionsInRect, } from '../../region-overlay/region-geometry';
|
|
5
|
+
import { NapariRegionSvgRenderer } from './region-overlay/region-svg-renderer';
|
|
6
|
+
import { OverlayProjection } from './region-overlay/overlay-projection';
|
|
7
|
+
import { applyRegionEdit } from './region-overlay/region-edit';
|
|
4
8
|
const SVG_NS = 'http://www.w3.org/2000/svg';
|
|
5
9
|
/**
|
|
6
10
|
* Min drag before a freehand path records another point, in SCREEN pixels.
|
|
@@ -23,27 +27,39 @@ const FREEHAND_STEP_PX = 2;
|
|
|
23
27
|
* impossible to create there.
|
|
24
28
|
*/
|
|
25
29
|
const MIN_RECT_DRAG_PX = 2;
|
|
30
|
+
/**
|
|
31
|
+
* A rubber band smaller than this on both sides, in SCREEN pixels, is a click on empty space
|
|
32
|
+
* (it clears the selection). Screen for the same reason as {@link MIN_RECT_DRAG_PX}: 3 world
|
|
33
|
+
* units is over half of seqFISH's sample.
|
|
34
|
+
*/
|
|
35
|
+
const MIN_MARQUEE_PX = 3;
|
|
26
36
|
/** Click-distance (screen px) within which a polygon click snaps closed onto the first vertex. */
|
|
27
37
|
const CLOSE_SNAP_PX = 10;
|
|
28
38
|
/** Screen-px hit radius for grabbing a vertex / rectangle corner handle. */
|
|
29
39
|
const HANDLE_HIT_PX = 9;
|
|
30
|
-
/**
|
|
31
|
-
const
|
|
40
|
+
/** Screen-px distance from an open polyline within which a click selects it (as OSD). */
|
|
41
|
+
const OPEN_PATH_HIT_PX = 6;
|
|
32
42
|
/**
|
|
33
43
|
* 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`/`
|
|
44
|
+
* {@link OsdRegionOverlay} but driven by napari's `canvasToWorld`/`canvasTransform` transforms
|
|
45
|
+
* (see {@link OverlayViewer} for their coordinate spaces).
|
|
35
46
|
* Vector shapes are drawn in an absolutely-positioned `<svg>` over the canvas (no need to push
|
|
36
|
-
* them through WebGPU)
|
|
37
|
-
*
|
|
38
|
-
*
|
|
47
|
+
* them through WebGPU) by {@link NapariRegionSvgRenderer} over the shared `SvgRegionRenderer`:
|
|
48
|
+
* in world coordinates inside one transformed group, rebuilt on a region or selection change,
|
|
49
|
+
* while a camera move only rewrites the transform (napari-js's `canvasTransform`, the camera
|
|
50
|
+
* centre/zoom) and the few screen-space handles and labels. This class is
|
|
51
|
+
* the gesture controller: pointer handlers, the tool mode, and the edit/draft/marquee state.
|
|
52
|
+
* It writes completed shapes to the shared {@link RegionStore} (so save / undo / export work
|
|
53
|
+
* identically to OSD).
|
|
39
54
|
*
|
|
40
55
|
* Supports (jit-ui#102): rectangle / polygon / freehand path drawing, click-select and rubber-band
|
|
41
56
|
* 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
|
-
*
|
|
57
|
+
* bezier handle editing, and donut holes (including hole vertex + hole-bezier-handle editing).
|
|
58
|
+
* Hit-testing shares `region-overlay/region-geometry` with the OSD overlay, so both follow
|
|
59
|
+
* the same rules (multi-part regions, holes, open polylines, handle-less bezier curves).
|
|
44
60
|
*/
|
|
45
61
|
export class NapariRegionOverlay {
|
|
46
|
-
constructor(host, viewer, store) {
|
|
62
|
+
constructor(host, viewer, store, opts = {}) {
|
|
47
63
|
this.host = host;
|
|
48
64
|
this.viewer = viewer;
|
|
49
65
|
this.store = store;
|
|
@@ -54,55 +70,21 @@ export class NapariRegionOverlay {
|
|
|
54
70
|
this.draftRect = null;
|
|
55
71
|
/** In-progress rubber-band selection marquee (select mode), image-space. */
|
|
56
72
|
this.marquee = null;
|
|
57
|
-
/** Dedicated marquee rect element, updated directly during the drag (no full region redraw). */
|
|
58
|
-
this.marqueeEl = null;
|
|
59
73
|
this.draftPath = null; // freehand or click polygon
|
|
60
74
|
this.drawing = false; // pointer is down for rect / freehand
|
|
61
75
|
this.regionsVisible = true;
|
|
62
76
|
/** In-progress manipulation (select/move modes): dragging a body, a polygon vertex, or a
|
|
63
77
|
* rectangle corner. `anchor` is the fixed opposite corner for a rectangle resize. */
|
|
64
78
|
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
79
|
// ── pointer handlers ──────────────────────────────────────────────────────
|
|
75
80
|
this.onPointerDown = (e) => {
|
|
76
81
|
if (this.mode === 'none')
|
|
77
82
|
return;
|
|
78
83
|
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();
|
|
84
|
+
this.projection.withOrigin(() => this.pointerDown(e));
|
|
103
85
|
};
|
|
104
86
|
this.onPointerMove = (e) => {
|
|
105
|
-
const [ix, iy] = this.toImage(e.clientX, e.clientY);
|
|
87
|
+
const [ix, iy] = this.projection.toImage(e.clientX, e.clientY);
|
|
106
88
|
if (this.marquee) {
|
|
107
89
|
this.marquee.x1 = ix;
|
|
108
90
|
this.marquee.y1 = iy;
|
|
@@ -110,7 +92,7 @@ export class NapariRegionOverlay {
|
|
|
110
92
|
return;
|
|
111
93
|
}
|
|
112
94
|
if (this.edit) {
|
|
113
|
-
this.
|
|
95
|
+
applyRegionEdit(this.store, this.edit, ix, iy);
|
|
114
96
|
this.redraw();
|
|
115
97
|
return;
|
|
116
98
|
}
|
|
@@ -121,19 +103,19 @@ export class NapariRegionOverlay {
|
|
|
121
103
|
this.draftRect.y1 = iy;
|
|
122
104
|
}
|
|
123
105
|
else if (this.draftPath) {
|
|
124
|
-
const step = FREEHAND_STEP_PX * this.worldPerCanvasPixel();
|
|
106
|
+
const step = FREEHAND_STEP_PX * this.projection.worldPerCanvasPixel();
|
|
125
107
|
const last = this.draftPath[this.draftPath.length - 1];
|
|
126
108
|
if (Math.abs(ix - last[0]) >= step || Math.abs(iy - last[1]) >= step) {
|
|
127
109
|
this.draftPath.push([ix, iy]);
|
|
128
110
|
}
|
|
129
111
|
}
|
|
130
|
-
this.
|
|
112
|
+
this.renderOverlay();
|
|
131
113
|
};
|
|
132
114
|
this.onPointerUp = (e) => {
|
|
133
115
|
if (this.marquee) {
|
|
134
116
|
const m = this.marquee;
|
|
135
117
|
this.marquee = null;
|
|
136
|
-
this.
|
|
118
|
+
this.renderer.clearMarquee();
|
|
137
119
|
try {
|
|
138
120
|
this.svg.releasePointerCapture(e.pointerId);
|
|
139
121
|
}
|
|
@@ -171,7 +153,7 @@ export class NapariRegionOverlay {
|
|
|
171
153
|
const w = Math.abs(x1 - x0);
|
|
172
154
|
const h = Math.abs(y1 - y0);
|
|
173
155
|
this.draftRect = null;
|
|
174
|
-
const min = MIN_RECT_DRAG_PX * this.worldPerCanvasPixel();
|
|
156
|
+
const min = MIN_RECT_DRAG_PX * this.projection.worldPerCanvasPixel();
|
|
175
157
|
if (w >= min && h >= min)
|
|
176
158
|
this.commitRectangle(x, y, w, h);
|
|
177
159
|
}
|
|
@@ -184,6 +166,17 @@ export class NapariRegionOverlay {
|
|
|
184
166
|
}
|
|
185
167
|
this.redraw();
|
|
186
168
|
};
|
|
169
|
+
/**
|
|
170
|
+
* The pointer gesture ended without a pointerup (the browser cancelled it, or capture was
|
|
171
|
+
* lost): end it without committing. Also fires after every normal release, when nothing
|
|
172
|
+
* is live any more.
|
|
173
|
+
*/
|
|
174
|
+
this.onPointerCancel = () => {
|
|
175
|
+
if (!this.edit && !this.drawing && !this.marquee)
|
|
176
|
+
return;
|
|
177
|
+
this.endGesture();
|
|
178
|
+
this.redraw();
|
|
179
|
+
};
|
|
187
180
|
this.onDblClick = (e) => {
|
|
188
181
|
if (this.mode !== 'drawpolygon' || !this.draftPath)
|
|
189
182
|
return;
|
|
@@ -207,16 +200,24 @@ export class NapariRegionOverlay {
|
|
|
207
200
|
touchAction: 'none',
|
|
208
201
|
});
|
|
209
202
|
this.host.appendChild(this.svg);
|
|
203
|
+
this.renderer = new NapariRegionSvgRenderer(this.svg, this.store);
|
|
204
|
+
this.projection = new OverlayProjection(this.svg, this.viewer);
|
|
205
|
+
this.sourceLayer =
|
|
206
|
+
opts.regionSource === false ? null : new RegionSourceLayer(this.svg, this.store.getRegionSourceView$());
|
|
210
207
|
this.svg.addEventListener('pointerdown', this.onPointerDown);
|
|
211
208
|
this.svg.addEventListener('pointermove', this.onPointerMove);
|
|
212
209
|
this.svg.addEventListener('pointerup', this.onPointerUp);
|
|
210
|
+
this.svg.addEventListener('pointercancel', this.onPointerCancel);
|
|
211
|
+
this.svg.addEventListener('lostpointercapture', this.onPointerCancel);
|
|
213
212
|
this.svg.addEventListener('dblclick', this.onDblClick);
|
|
214
213
|
this.subs.add(this.store.getRegionUpdateEvent().subscribe(() => this.redraw()));
|
|
215
214
|
this.subs.add(this.store.getSelectedShapeIndices$().subscribe((idx) => {
|
|
216
215
|
this.selected = idx ?? [];
|
|
217
216
|
this.redraw();
|
|
218
217
|
}));
|
|
219
|
-
|
|
218
|
+
// A camera move rewrites the renderer's transform and its few screen-space elements;
|
|
219
|
+
// the regions are drawn in world coordinates and are not rebuilt (NAPARI-BOUNDARY-10).
|
|
220
|
+
this.disconnectCamera = this.viewer.camera.changed.connect(() => this.updateCamera());
|
|
220
221
|
this.redraw();
|
|
221
222
|
}
|
|
222
223
|
// ── IRegionOverlay ────────────────────────────────────────────────────────
|
|
@@ -232,68 +233,88 @@ export class NapariRegionOverlay {
|
|
|
232
233
|
return this.mode !== 'none';
|
|
233
234
|
}
|
|
234
235
|
setMode(mode) {
|
|
236
|
+
this.endGesture();
|
|
235
237
|
this.mode = mode;
|
|
236
238
|
this.draftRect = null;
|
|
237
239
|
this.draftPath = null;
|
|
238
|
-
this.marquee = null;
|
|
239
|
-
this.clearMarqueeEl();
|
|
240
|
-
this.drawing = false;
|
|
241
240
|
// The overlay owns pointer/navigation gating: while a tool is active it captures the pointer
|
|
242
241
|
// and the napari camera controls are disabled; 'none' hands the pointer back for pan/zoom.
|
|
243
242
|
const active = mode !== 'none';
|
|
244
243
|
this.viewer.setControlsEnabled(!active);
|
|
245
244
|
this.svg.style.pointerEvents = active ? 'auto' : 'none';
|
|
246
245
|
this.svg.style.cursor = active ? 'crosshair' : 'default';
|
|
247
|
-
this.
|
|
246
|
+
this.renderOverlay();
|
|
248
247
|
}
|
|
249
248
|
setSelectedBezier(bezier) {
|
|
250
249
|
const sel = this.selectedRegion();
|
|
251
250
|
if (sel?.id != null)
|
|
252
251
|
this.store.setBezier(sel.id, bezier);
|
|
253
252
|
}
|
|
253
|
+
/**
|
|
254
|
+
* How finely a drawn vertex may be placed, in world units: one (an image's pixels) by
|
|
255
|
+
* default, finer for a dataset whose coordinates are not pixels (see OverlayProjection).
|
|
256
|
+
*/
|
|
254
257
|
setWorldQuantum(quantum) {
|
|
255
|
-
this.
|
|
256
|
-
? quantum
|
|
257
|
-
: PIXEL_WORLD_QUANTUM;
|
|
258
|
+
this.projection.setWorldQuantum(quantum);
|
|
258
259
|
}
|
|
259
260
|
destroy() {
|
|
260
261
|
this.svg.removeEventListener('pointerdown', this.onPointerDown);
|
|
261
262
|
this.svg.removeEventListener('pointermove', this.onPointerMove);
|
|
262
263
|
this.svg.removeEventListener('pointerup', this.onPointerUp);
|
|
264
|
+
this.svg.removeEventListener('pointercancel', this.onPointerCancel);
|
|
265
|
+
this.svg.removeEventListener('lostpointercapture', this.onPointerCancel);
|
|
263
266
|
this.svg.removeEventListener('dblclick', this.onDblClick);
|
|
264
267
|
this.disconnectCamera();
|
|
265
268
|
this.subs.unsubscribe();
|
|
269
|
+
// A drag torn down mid-gesture (a backend switch) must still close its store batch.
|
|
270
|
+
this.endGesture();
|
|
271
|
+
this.sourceLayer?.destroy();
|
|
266
272
|
if (this.svg.parentNode)
|
|
267
273
|
this.svg.parentNode.removeChild(this.svg);
|
|
268
274
|
}
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
275
|
+
pointerDown(e) {
|
|
276
|
+
const [ix, iy] = this.projection.toImage(e.clientX, e.clientY);
|
|
277
|
+
if (this.mode === 'drawrect') {
|
|
278
|
+
this.draftRect = { x0: ix, y0: iy, x1: ix, y1: iy };
|
|
279
|
+
this.drawing = true;
|
|
280
|
+
this.svg.setPointerCapture(e.pointerId);
|
|
281
|
+
}
|
|
282
|
+
else if (this.mode === 'drawclosedpath' || this.mode === 'drawopenpath') {
|
|
283
|
+
this.draftPath = [[ix, iy]];
|
|
284
|
+
this.drawing = true;
|
|
285
|
+
this.svg.setPointerCapture(e.pointerId);
|
|
286
|
+
}
|
|
287
|
+
else if (this.mode === 'drawpolygon') {
|
|
288
|
+
this.handlePolygonClick(ix, iy, e.clientX, e.clientY);
|
|
289
|
+
}
|
|
290
|
+
else if (this.mode === 'select' || this.mode === 'move') {
|
|
291
|
+
this.beginManipulation(ix, iy, e);
|
|
292
|
+
}
|
|
293
|
+
else if (this.mode === 'addpoint') {
|
|
294
|
+
this.handleAddPoint(ix, iy, e.clientX, e.clientY);
|
|
295
|
+
}
|
|
296
|
+
else if (this.mode === 'deletepoint') {
|
|
297
|
+
this.handleDeletePoint(ix, iy);
|
|
298
|
+
}
|
|
299
|
+
this.redraw();
|
|
277
300
|
}
|
|
278
301
|
/**
|
|
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.
|
|
302
|
+
* End whatever pointer gesture is live without committing it: close the store batch a drag
|
|
303
|
+
* opened (so later edits are emitted again) and forget the drag (so a bare hover no longer
|
|
304
|
+
* moves the region), and drop the marquee and a rectangle/freehand draft. A click-placed
|
|
305
|
+
* polygon is not a pointer gesture and survives.
|
|
285
306
|
*/
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
307
|
+
endGesture() {
|
|
308
|
+
if (this.edit)
|
|
309
|
+
this.store.endBatch();
|
|
310
|
+
this.edit = null;
|
|
311
|
+
if (this.drawing) {
|
|
312
|
+
this.draftRect = null;
|
|
313
|
+
this.draftPath = null;
|
|
314
|
+
}
|
|
315
|
+
this.drawing = false;
|
|
316
|
+
this.marquee = null;
|
|
317
|
+
this.renderer.clearMarquee();
|
|
297
318
|
}
|
|
298
319
|
/** Click-to-place polygon: add a vertex, or close when clicking near the first one. */
|
|
299
320
|
handlePolygonClick(ix, iy, clientX, clientY) {
|
|
@@ -301,9 +322,7 @@ export class NapariRegionOverlay {
|
|
|
301
322
|
this.draftPath = [[ix, iy]];
|
|
302
323
|
return;
|
|
303
324
|
}
|
|
304
|
-
const
|
|
305
|
-
const r = this.svg.getBoundingClientRect();
|
|
306
|
-
const near = Math.hypot(clientX - r.left - fx, clientY - r.top - fy) <= CLOSE_SNAP_PX &&
|
|
325
|
+
const near = this.projection.screenDist(clientX, clientY, this.draftPath[0][0], this.draftPath[0][1]) <= CLOSE_SNAP_PX &&
|
|
307
326
|
this.draftPath.length >= 3;
|
|
308
327
|
if (near) {
|
|
309
328
|
const pts = this.draftPath;
|
|
@@ -320,12 +339,6 @@ export class NapariRegionOverlay {
|
|
|
320
339
|
const i = this.selected[0];
|
|
321
340
|
return i != null && i >= 0 && i < regions.length ? regions[i] : null;
|
|
322
341
|
}
|
|
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
342
|
/**
|
|
330
343
|
* Start a select/move interaction: grab a handle (rectangle corner) or vertex of the already-
|
|
331
344
|
* selected region first; otherwise select the topmost region under the cursor and drag its body.
|
|
@@ -333,7 +346,8 @@ export class NapariRegionOverlay {
|
|
|
333
346
|
beginManipulation(ix, iy, e) {
|
|
334
347
|
const sel = this.selectedRegion();
|
|
335
348
|
if (sel?.bounds) {
|
|
336
|
-
const
|
|
349
|
+
const [lx, ly] = this.projection.clientToLocal(e.clientX, e.clientY);
|
|
350
|
+
const grab = hitHandle(sel, lx, ly, this.projection.toScreen, HANDLE_HIT_PX);
|
|
337
351
|
if (grab) {
|
|
338
352
|
this.store.beginBatch();
|
|
339
353
|
this.edit = { ...grab, id: sel.id, last: [ix, iy] };
|
|
@@ -341,10 +355,14 @@ export class NapariRegionOverlay {
|
|
|
341
355
|
return;
|
|
342
356
|
}
|
|
343
357
|
}
|
|
344
|
-
// Hit-test bodies, topmost first (last drawn renders on top)
|
|
358
|
+
// Hit-test bodies, topmost first (last drawn renders on top), at the exact pointer
|
|
359
|
+
// position — snapping is for placing vertices, not for picking.
|
|
345
360
|
const regions = this.store.getRegions();
|
|
361
|
+
const [wx, wy] = this.projection.toWorld(e.clientX, e.clientY);
|
|
346
362
|
for (let i = regions.length - 1; i >= 0; i--) {
|
|
347
|
-
if (this.
|
|
363
|
+
if (this.store.isClassHidden(regions[i].label))
|
|
364
|
+
continue;
|
|
365
|
+
if (regionContains(regions[i], wx, wy, { toScreen: this.projection.toScreen, tolPx: OPEN_PATH_HIT_PX })) {
|
|
348
366
|
this.store.selectRegion(regions[i]);
|
|
349
367
|
this.store.beginBatch();
|
|
350
368
|
this.edit = { kind: 'body', id: regions[i].id, last: [ix, iy] };
|
|
@@ -352,6 +370,13 @@ export class NapariRegionOverlay {
|
|
|
352
370
|
return;
|
|
353
371
|
}
|
|
354
372
|
}
|
|
373
|
+
// A feature of the region source: take it into the regions and select it (a drag on it
|
|
374
|
+
// moves it once it is selected).
|
|
375
|
+
const feature = this.sourceLayer?.featureAt(wx, wy, OPEN_PATH_HIT_PX);
|
|
376
|
+
if (feature) {
|
|
377
|
+
void this.store.selectSourceFeatures([feature.id], e.shiftKey || e.metaKey || e.ctrlKey);
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
355
380
|
// Empty space: in select mode start a rubber-band marquee (selects the regions it covers on
|
|
356
381
|
// release); in move mode just clear the selection.
|
|
357
382
|
if (this.mode === 'select') {
|
|
@@ -363,237 +388,65 @@ export class NapariRegionOverlay {
|
|
|
363
388
|
this.store.setSelectedShapeIndices([]);
|
|
364
389
|
}
|
|
365
390
|
}
|
|
366
|
-
/**
|
|
391
|
+
/** Show the marquee where it is now (only the marquee element: no full region redraw). */
|
|
367
392
|
updateMarqueeEl() {
|
|
368
393
|
if (!this.marquee)
|
|
369
394
|
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
395
|
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;
|
|
396
|
+
const [lx, ly] = this.projection.toLocal(Math.min(x0, x1), Math.min(y0, y1));
|
|
397
|
+
const [rx, ry] = this.projection.toLocal(Math.max(x0, x1), Math.max(y0, y1));
|
|
398
|
+
this.renderer.showMarquee(lx, ly, rx, ry);
|
|
457
399
|
}
|
|
458
|
-
/**
|
|
459
|
-
|
|
460
|
-
|
|
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
|
-
}
|
|
493
|
-
}
|
|
494
|
-
/** addpoint mode: insert a vertex on the selected polygon's nearest edge at the click. */
|
|
495
|
-
handleAddPoint(ix, iy) {
|
|
400
|
+
/** addpoint mode: insert a vertex at the click on the selected polygon's nearest edge
|
|
401
|
+
* (exterior or a hole ring). */
|
|
402
|
+
handleAddPoint(ix, iy, clientX, clientY) {
|
|
496
403
|
const sel = this.selectedRegion();
|
|
497
|
-
|
|
498
|
-
if (!sel || !b || !('npoints' in b))
|
|
404
|
+
if (!sel)
|
|
499
405
|
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);
|
|
406
|
+
const [lx, ly] = this.projection.clientToLocal(clientX, clientY);
|
|
407
|
+
const edge = nearestEdge(sel, lx, ly, this.projection.toScreen);
|
|
408
|
+
if (!edge)
|
|
409
|
+
return;
|
|
410
|
+
if (edge.ring < 0)
|
|
411
|
+
this.store.addVertex(sel.id, edge.segIndex, ix, iy);
|
|
412
|
+
else
|
|
413
|
+
this.store.addHoleVertex(sel.id, edge.ring, edge.segIndex, ix, iy);
|
|
513
414
|
}
|
|
514
|
-
/** deletepoint mode: remove the selected polygon's vertex nearest the click
|
|
415
|
+
/** deletepoint mode: remove the selected polygon's vertex nearest the click (exterior or a
|
|
416
|
+
* hole ring). */
|
|
515
417
|
handleDeletePoint(ix, iy) {
|
|
516
418
|
const sel = this.selectedRegion();
|
|
517
|
-
|
|
518
|
-
if (!sel || !b || !('npoints' in b))
|
|
419
|
+
if (!sel)
|
|
519
420
|
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));
|
|
421
|
+
const v = nearestVertex(sel, ix, iy);
|
|
422
|
+
if (!v)
|
|
423
|
+
return;
|
|
424
|
+
if (v.ring < 0)
|
|
425
|
+
this.store.deleteVertex(sel.id, v.index);
|
|
426
|
+
else
|
|
427
|
+
this.store.deleteHoleVertex(sel.id, v.ring, v.index);
|
|
541
428
|
}
|
|
542
|
-
/** Finalize a rubber-band marquee: select every region whose bounding box it overlaps (a
|
|
543
|
-
* marquee
|
|
429
|
+
/** Finalize a rubber-band marquee: select every region whose bounding box it overlaps (a
|
|
430
|
+
* marquee under {@link MIN_MARQUEE_PX} is a click on empty space → clear the selection). */
|
|
544
431
|
finishMarquee(m) {
|
|
545
432
|
const x0 = Math.min(m.x0, m.x1);
|
|
546
433
|
const x1 = Math.max(m.x0, m.x1);
|
|
547
434
|
const y0 = Math.min(m.y0, m.y1);
|
|
548
435
|
const y1 = Math.max(m.y0, m.y1);
|
|
549
|
-
|
|
436
|
+
const min = MIN_MARQUEE_PX * this.projection.worldPerCanvasPixel();
|
|
437
|
+
if (x1 - x0 < min && y1 - y0 < min) {
|
|
550
438
|
this.store.setSelectedShapeIndices([]);
|
|
551
439
|
return;
|
|
552
440
|
}
|
|
553
|
-
const
|
|
554
|
-
this.store.
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
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;
|
|
441
|
+
const regions = this.store.getRegions();
|
|
442
|
+
this.store.setSelectedShapeIndices(regionsInRect(regions, x0, y0, x1, y1, {
|
|
443
|
+
skipProfiles: true,
|
|
444
|
+
skip: (r) => this.store.isClassHidden(r.label),
|
|
445
|
+
}));
|
|
446
|
+
const features = this.sourceLayer?.featuresInRect(x0, y0, x1, y1) ?? [];
|
|
447
|
+
if (features.length) {
|
|
448
|
+
void this.store.selectSourceFeatures(features.slice(0, SOURCE_MARQUEE_LIMIT).map((f) => f.id), true);
|
|
595
449
|
}
|
|
596
|
-
return isFinite(acc.x0) ? acc : null;
|
|
597
450
|
}
|
|
598
451
|
// ── shape commit ──────────────────────────────────────────────────────────
|
|
599
452
|
commitRectangle(x, y, width, height) {
|
|
@@ -621,299 +474,35 @@ export class NapariRegionOverlay {
|
|
|
621
474
|
this.store.addRegion(region);
|
|
622
475
|
}
|
|
623
476
|
// ── 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
477
|
/** Show or hide the drawn regions. A region being drawn stays visible either way. */
|
|
648
478
|
setRegionsVisible(visible) {
|
|
649
479
|
if (visible === this.regionsVisible)
|
|
650
480
|
return;
|
|
651
481
|
this.regionsVisible = visible;
|
|
482
|
+
this.sourceLayer?.setVisible(visible);
|
|
652
483
|
this.redraw();
|
|
653
484
|
}
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
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();
|
|
485
|
+
/** Follow a camera move: one transform attribute plus the screen-space elements. */
|
|
486
|
+
updateCamera() {
|
|
487
|
+
const affine = this.projection.affine();
|
|
488
|
+
this.renderer.setCamera(affine);
|
|
489
|
+
this.sourceLayer?.setCamera(affine);
|
|
670
490
|
}
|
|
671
|
-
/**
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
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;
|
|
828
|
-
}
|
|
829
|
-
/** Path data for a polygon: the exterior ring (bezier or straight) plus any holes (bezier when
|
|
830
|
-
* the donut carries hole handles, else straight) as sub-paths — even-odd fill cuts them out. */
|
|
831
|
-
polygonPathData(p, isBezier) {
|
|
832
|
-
let d = isBezier
|
|
833
|
-
? this.ringBezierPath(p.xpoints, p.ypoints, p.handlesIn, p.handlesOut, p.closed !== false)
|
|
834
|
-
: this.straightPath(p.xpoints, p.ypoints, p.closed !== false);
|
|
835
|
-
const holeBezier = !!(p.bezier && p.holeHandlesIn && p.holeHandlesOut);
|
|
836
|
-
(p.holes ?? []).forEach((ring, hi) => {
|
|
837
|
-
if (ring.length < 3)
|
|
838
|
-
return;
|
|
839
|
-
const xs = ring.map((pt) => pt[0]);
|
|
840
|
-
const ys = ring.map((pt) => pt[1]);
|
|
841
|
-
if (holeBezier && p.holeHandlesIn[hi] && p.holeHandlesOut[hi]) {
|
|
842
|
-
d += ' ' + this.ringBezierPath(xs, ys, p.holeHandlesIn[hi], p.holeHandlesOut[hi], true);
|
|
843
|
-
}
|
|
844
|
-
else {
|
|
845
|
-
d += ' ' + this.straightPath(xs, ys, true);
|
|
846
|
-
}
|
|
491
|
+
/**
|
|
492
|
+
* Rebuild every element from the store: the regions in world coordinates (one transformed
|
|
493
|
+
* group), their labels, and the overlay. Reads no layout: the camera affine is the viewer's.
|
|
494
|
+
*/
|
|
495
|
+
redraw() {
|
|
496
|
+
this.updateCamera();
|
|
497
|
+
this.renderer.render(this.regionsVisible ? this.store.getRegions() : [], this.selected);
|
|
498
|
+
this.renderOverlay();
|
|
499
|
+
}
|
|
500
|
+
/** Rebuild the screen-space overlay only: the selected regions' handles and the draft. */
|
|
501
|
+
renderOverlay() {
|
|
502
|
+
this.renderer.renderOverlay(this.regionsVisible ? this.store.getRegions() : [], this.selected, {
|
|
503
|
+
rect: this.draftRect,
|
|
504
|
+
path: this.draftPath,
|
|
847
505
|
});
|
|
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
506
|
}
|
|
918
507
|
}
|
|
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
|
|
508
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFwYXJpLXJlZ2lvbi1vdmVybGF5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9pbXBsZW1lbnRhdGlvbnMvbmFwYXJpLWpzL25hcGFyaS1yZWdpb24tb3ZlcmxheS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBR3BDLE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBR2pFLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDBDQUEwQyxDQUFDO0FBRW5HLE9BQU8sRUFDTCxTQUFTLEVBQ1QsV0FBVyxFQUNYLGFBQWEsRUFDYixjQUFjLEVBQ2QsYUFBYSxHQUNkLE1BQU0sc0NBQXNDLENBQUM7QUFFOUMsT0FBTyxFQUFXLHVCQUF1QixFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDeEYsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDeEUsT0FBTyxFQUFjLGVBQWUsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBRTNFLE1BQU0sTUFBTSxHQUFHLDRCQUE0QixDQUFDO0FBQzVDOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO0FBQzNCOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLENBQUM7QUFDM0I7Ozs7R0FJRztBQUNILE1BQU0sY0FBYyxHQUFHLENBQUMsQ0FBQztBQUN6QixrR0FBa0c7QUFDbEcsTUFBTSxhQUFhLEdBQUcsRUFBRSxDQUFDO0FBQ3pCLDRFQUE0RTtBQUM1RSxNQUFNLGFBQWEsR0FBRyxDQUFDLENBQUM7QUFDeEIseUZBQXlGO0FBQ3pGLE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO0FBNkIzQjs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHO0FBQ0gsTUFB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RUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQ3hGLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUN2QixDQUFDO0lBRUQsMEZBQTBGO0lBQ2xGLGFBQWE7UUFDbkIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUU7WUFDN0YsSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTO1lBQ3BCLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUztTQUNyQixDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgSVJlZ2lvbk92ZXJsYXksIFJlZ2lvblRvb2xNb2RlIH0gZnJvbSAnLi4vLi4vY29udHJhY3RzL3JlZ2lvbi1vdmVybGF5LmNvbnRyYWN0JztcbmltcG9ydCB7IFJlZ2lvbiwgUmVjdGFuZ2xlLCBQb2x5Z29uIH0gZnJvbSAnLi4vLi4vbW9kZWxzL3JlZ2lvbic7XG5pbXBvcnQgeyBSZWdpb25TdG9yZSB9IGZyb20gJy4uLy4uL3N0b3JlL3JlZ2lvbi1zdG9yZS5zZXJ2aWNlJztcbmltcG9ydCB0eXBlIHsgQWZmaW5lIH0gZnJvbSAnLi4vLi4vcmVnaW9uLW92ZXJsYXkvc3ZnLXJlZ2lvbi1yZW5kZXJlcic7XG5pbXBvcnQgeyBSZWdpb25Tb3VyY2VMYXllciwgU09VUkNFX01BUlFVRUVfTElNSVQgfSBmcm9tICcuLi8uLi9yZWdpb24tb3ZlcmxheS9yZWdpb24tc291cmNlLWxheWVyJztcblxuaW1wb3J0IHtcbiAgaGl0SGFuZGxlLFxuICBuZWFyZXN0RWRnZSxcbiAgbmVhcmVzdFZlcnRleCxcbiAgcmVnaW9uQ29udGFpbnMsXG4gIHJlZ2lvbnNJblJlY3QsXG59IGZyb20gJy4uLy4uL3JlZ2lvbi1vdmVybGF5L3JlZ2lvbi1nZW9tZXRyeSc7XG5cbmltcG9ydCB7IERyYWdCb3gsIE5hcGFyaVJlZ2lvblN2Z1JlbmRlcmVyIH0gZnJvbSAnLi9yZWdpb24tb3ZlcmxheS9yZWdpb24tc3ZnLXJlbmRlcmVyJztcbmltcG9ydCB7IE92ZXJsYXlQcm9qZWN0aW9uIH0gZnJvbSAnLi9yZWdpb24tb3ZlcmxheS9vdmVybGF5LXByb2plY3Rpb24nO1xuaW1wb3J0IHsgUmVnaW9uRWRpdCwgYXBwbHlSZWdpb25FZGl0IH0gZnJvbSAnLi9yZWdpb24tb3ZlcmxheS9yZWdpb24tZWRpdCc7XG5cbmNvbnN0IFNWR19OUyA9ICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zyc7XG4vKipcbiAqIE1pbiBkcmFnIGJlZm9yZSBhIGZyZWVoYW5kIHBhdGggcmVjb3JkcyBhbm90aGVyIHBvaW50LCBpbiBTQ1JFRU4gcGl4ZWxzLlxuICpcbiAqIFNjcmVlbiByYXRoZXIgdGhhbiB3b3JsZCwgd2hpY2ggaXMgd2hhdCBcIjIgaW1hZ2UgcHhcIiBhbHdheXMgbWVhbnQgaW4gcHJhY3RpY2U6IGF0IDEwMCVcbiAqIHpvb20gb3ZlciBhbiBpbWFnZSB0aGUgdHdvIGFyZSB0aGUgc2FtZSB0aGluZy4gVGFrZW4gYXMgd29ybGQgdW5pdHMgaXQgYnJlYWtzIG9uIGFueVxuICogZGF0YXNldCB3aG9zZSB3b3JsZCBpcyBzbWFsbCDigJQgc2VxRklTSCdzIHNhbXBsZSBzcGFucyBhYm91dCA1IHVuaXRzLCBzbyBhIDItdW5pdFxuICogdGhyZXNob2xkIHJlY29yZHMgYSBwb2ludCBldmVyeSA0MCUgb2YgdGhlIHdheSBhY3Jvc3MgYW5kIGEgZnJlZWhhbmQgUk9JIGNvbWVzIG91dCBhcyBhXG4gKiB0cmlhbmdsZS4gQWdhaW5zdCB0aGUgc2NyZWVuIGl0IGFsc28gZG9lcyB0aGUgcmlnaHQgdGhpbmcgdW5kZXIgem9vbTogZHJhd2luZyB6b29tZWQgaW5cbiAqIHJlY29yZHMgYSBmaW5lciBwYXRoLCBiZWNhdXNlIHRoYXQgaXMgZXhhY3RseSB3aGVuIHRoZSBleHRyYSBkZXRhaWwgaXMgdmlzaWJsZS5cbiAqL1xuY29uc3QgRlJFRUhBTkRfU1RFUF9QWCA9IDI7XG4vKipcbiAqIFNtYWxsZXN0IGNvbW1pdHRlZCByZWN0YW5nbGUsIGluIFNDUkVFTiBwaXhlbHMgb24gZWFjaCBzaWRlLlxuICpcbiAqIEl0cyBqb2IgaXMgdG8gdGhyb3cgYXdheSBhIGNsaWNrIHRoYXQgd2FzIG5vdCBhIGRyYWcuIEhlbGQgaW4gd29ybGQgdW5pdHMg4oCUIHdoaWNoIGl0IHdhc1xuICog4oCUIGl0IGluc3RlYWQgdGhyb3dzIGF3YXkgcmVhbCBkcmFncyBvbiBhbnkgZGF0YXNldCB3aG9zZSB3b3JsZCBpcyBzbWFsbDogaW4gc2VxRklTSCdzXG4gKiB+NSB4IDcgdW5pdCBzYW1wbGUgYSByZWN0YW5nbGUgaGFkIHRvIGNvdmVyIDQwJSBvZiB0aGUgd2lkdGggdG8gY29tbWl0IGF0IGFsbCwgYW5kXG4gKiBhbnl0aGluZyBzbWFsbGVyIHZhbmlzaGVkIHdpdGggbm8gZmVlZGJhY2suIFRoYXQgd2FzIHRoZSBkaXJlY3QgY2F1c2Ugb2YgUk9JcyBiZWluZ1xuICogaW1wb3NzaWJsZSB0byBjcmVhdGUgdGhlcmUuXG4gKi9cbmNvbnN0IE1JTl9SRUNUX0RSQUdfUFggPSAyO1xuLyoqXG4gKiBBIHJ1YmJlciBiYW5kIHNtYWxsZXIgdGhhbiB0aGlzIG9uIGJvdGggc2lkZXMsIGluIFNDUkVFTiBwaXhlbHMsIGlzIGEgY2xpY2sgb24gZW1wdHkgc3BhY2VcbiAqIChpdCBjbGVhcnMgdGhlIHNlbGVjdGlvbikuIFNjcmVlbiBmb3IgdGhlIHNhbWUgcmVhc29uIGFzIHtAbGluayBNSU5fUkVDVF9EUkFHX1BYfTogMyB3b3JsZFxuICogdW5pdHMgaXMgb3ZlciBoYWxmIG9mIHNlcUZJU0gncyBzYW1wbGUuXG4gKi9cbmNvbnN0IE1JTl9NQVJRVUVFX1BYID0gMztcbi8qKiBDbGljay1kaXN0YW5jZSAoc2NyZWVuIHB4KSB3aXRoaW4gd2hpY2ggYSBwb2x5Z29uIGNsaWNrIHNuYXBzIGNsb3NlZCBvbnRvIHRoZSBmaXJzdCB2ZXJ0ZXguICovXG5jb25zdCBDTE9TRV9TTkFQX1BYID0gMTA7XG4vKiogU2NyZWVuLXB4IGhpdCByYWRpdXMgZm9yIGdyYWJiaW5nIGEgdmVydGV4IC8gcmVjdGFuZ2xlIGNvcm5lciBoYW5kbGUuICovXG5jb25zdCBIQU5ETEVfSElUX1BYID0gOTtcbi8qKiBTY3JlZW4tcHggZGlzdGFuY2UgZnJvbSBhbiBvcGVuIHBvbHlsaW5lIHdpdGhpbiB3aGljaCBhIGNsaWNrIHNlbGVjdHMgaXQgKGFzIE9TRCkuICovXG5jb25zdCBPUEVOX1BBVEhfSElUX1BYID0gNjtcblxuLyoqXG4gKiBUaGUgc2xpY2Ugb2YgdGhlIG5hcGFyaSBWaWV3ZXIgdGhlIG92ZXJsYXkgbmVlZHMgKGNvb3JkIHRyYW5zZm9ybXMgKyBjb250cm9sIGdhdGluZykuXG4gKlxuICogQ09PUkRJTkFURSBTUEFDRVM6IGBjYW52YXNUb1dvcmxkYCB0YWtlcyBDTElFTlQgcGl4ZWxzICh2aWV3cG9ydCBjb29yZGluYXRlcywgYXMgYSBwb2ludGVyXG4gKiBldmVudCdzIGBjbGllbnRYL1lgKSwgZXhhY3RseSBhcyBuYXBhcmktanMgYFZpZXdlci5jYW52YXNUb1dvcmxkYCBkb2VzLiBgY2FudmFzVHJhbnNmb3JtYCBpc1xuICogdGhlIGNhbWVyYSdzIHdvcmxkIOKGkiBDQU5WQVMtTE9DQUwgQ1NTLXBpeGVsIGFmZmluZSwgbmFwYXJpLWpzIGBWaWV3ZXIuY2FudmFzVHJhbnNmb3JtYCwgd2hpY2hcbiAqIHJlYWRzIG5vIGxheW91dDogZHJhd2luZyBhbmQgZm9sbG93aW5nIHRoZSBjYW1lcmEgdXNlIGl0LCBzbyBhIGNhbWVyYSBmcmFtZSBjb3N0cyBvbmVcbiAqIGBtYXRyaXgoLi4uKWAgYW5kIG5vIGBnZXRCb3VuZGluZ0NsaWVudFJlY3QoKWAgKHJldmlldyBOQVBBUkktQk9VTkRBUlktMTApLiBUaGUgc3ZnIGNvdmVycyB0aGVcbiAqIHBsb3QgaG9zdCBhbmQgdGhlIGNhbnZhcyBpcyB0aGUgaG9zdCdzIGluLWZsb3cgY2hpbGQgYXQgaXRzIHRvcC1sZWZ0LCBzbyBjYW52YXMtbG9jYWwgYW5kXG4gKiBzdmctbG9jYWwgcGl4ZWxzIGFyZSB0aGUgc2FtZTsgYSBwb2ludGVyJ3MgY2xpZW50IHBpeGVscyBhcmUgbWFwcGVkIGludG8gdGhlIHN2ZyBieSB0aGVcbiAqIG92ZXJsYXkgaXRzZWxmLlxuICpcbiAqIEV4cG9ydGVkIGJlY2F1c2UgdGhlIDNEIHNwYXRpYWwgbW9kZSBzdXBwbGllcyBhIFNDUkVFTi1TUEFDRSBpbXBsZW1lbnRhdGlvbiBvZiBpdDogdGhlcmUgdGhlXG4gKiBkcmF3biBzaGFwZSBpcyBhIGxhc3NvIGluIGNhbnZhcyBwaXhlbHMsIG5vdCBhIHJlY3RhbmdsZSBpbiBpbWFnZSBzcGFjZSwgc28gXCJ3b3JsZFwiIGlzIHRoZVxuICogY2FudmFzIGl0c2VsZiDigJQgYGNhbnZhc1RvV29ybGRgIGlzIHRoZSBjbGllbnQg4oaSIGNhbnZhcyBvZmZzZXQgYW5kIGBjYW52YXNUcmFuc2Zvcm1gIHRoZVxuICogaWRlbnRpdHkuIFRoYXQgbGV0cyB0aGUgM0QgdmlldyByZXVzZSB0aGlzIHdob2xlIG92ZXJsYXkg4oCUIGV2ZXJ5IHRvb2wsIHRoZSBoYW5kbGVzLCB0aGUgc3RvcmVcbiAqIHJvdW5kLXRyaXAg4oCUIHdpdGggbm8gM0Qtc3BlY2lmaWMgZHJhd2luZyBjb2RlLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIE92ZXJsYXlWaWV3ZXIge1xuICAvKiogQ2xpZW50IHB4IOKGkiB3b3JsZC4gKi9cbiAgY2FudmFzVG9Xb3JsZChjbGllbnRYOiBudW1iZXIsIGNsaWVudFk6IG51bWJlcik6IFtudW1iZXIsIG51bWJlcl07XG4gIC8qKiBXb3JsZCDihpIgY2FudmFzLWxvY2FsICg9IHN2Zy1sb2NhbCkgQ1NTIHB4LCBhcyBhbiBTVkcgYWZmaW5lIGBbYSwgYiwgYywgZCwgZSwgZl1gLiAqL1xuICBjYW52YXNUcmFuc2Zvcm0oKTogQWZmaW5lO1xuICBzZXRDb250cm9sc0VuYWJsZWQoZW5hYmxlZDogYm9vbGVhbik6IHZvaWQ7XG4gIHJlYWRvbmx5IGNhbWVyYTogeyByZWFkb25seSBjaGFuZ2VkOiB7IGNvbm5lY3QobGlzdGVuZXI6ICgpID0+IHZvaWQpOiAoKSA9PiB2b2lkIH0gfTtcbn1cblxuLyoqXG4gKiBTVkcgcmVnaW9uIG92ZXJsYXkgZm9yIHRoZSBuYXBhcmktanMgV2ViR1BVIGltYWdlIHZpZXcgKGppdC11aSMxMDIpLCBtaXJyb3JpbmcgdGhlIE9TRCBiYWNrZW5kJ3NcbiAqIHtAbGluayBPc2RSZWdpb25PdmVybGF5fSBidXQgZHJpdmVuIGJ5IG5hcGFyaSdzIGBjYW52YXNUb1dvcmxkYC9gY2FudmFzVHJhbnNmb3JtYCB0cmFuc2Zvcm1zXG4gKiAoc2VlIHtAbGluayBPdmVybGF5Vmlld2VyfSBmb3IgdGhlaXIgY29vcmRpbmF0ZSBzcGFjZXMpLlxuICogVmVjdG9yIHNoYXBlcyBhcmUgZHJhd24gaW4gYW4gYWJzb2x1dGVseS1wb3NpdGlvbmVkIGA8c3ZnPmAgb3ZlciB0aGUgY2FudmFzIChubyBuZWVkIHRvIHB1c2hcbiAqIHRoZW0gdGhyb3VnaCBXZWJHUFUpIGJ5IHtAbGluayBOYXBhcmlSZWdpb25TdmdSZW5kZXJlcn0gb3ZlciB0aGUgc2hhcmVkIGBTdmdSZWdpb25SZW5kZXJlcmA6XG4gKiBpbiB3b3JsZCBjb29yZGluYXRlcyBpbnNpZGUgb25lIHRyYW5zZm9ybWVkIGdyb3VwLCByZWJ1aWx0IG9uIGEgcmVnaW9uIG9yIHNlbGVjdGlvbiBjaGFuZ2UsXG4gKiB3aGlsZSBhIGNhbWVyYSBtb3ZlIG9ubHkgcmV3cml0ZXMgdGhlIHRyYW5zZm9ybSAobmFwYXJpLWpzJ3MgYGNhbnZhc1RyYW5zZm9ybWAsIHRoZSBjYW1lcmFcbiAqIGNlbnRyZS96b29tKSBhbmQgdGhlIGZldyBzY3JlZW4tc3BhY2UgaGFuZGxlcyBhbmQgbGFiZWxzLiBUaGlzIGNsYXNzIGlzXG4gKiB0aGUgZ2VzdHVyZSBjb250cm9sbGVyOiBwb2ludGVyIGhhbmRsZXJzLCB0aGUgdG9vbCBtb2RlLCBhbmQgdGhlIGVkaXQvZHJhZnQvbWFycXVlZSBzdGF0ZS5cbiAqIEl0IHdyaXRlcyBjb21wbGV0ZWQgc2hhcGVzIHRvIHRoZSBzaGFyZWQge0BsaW5rIFJlZ2lvblN0b3JlfSAoc28gc2F2ZSAvIHVuZG8gLyBleHBvcnQgd29ya1xuICogaWRlbnRpY2FsbHkgdG8gT1NEKS5cbiAqXG4gKiBTdXBwb3J0cyAoaml0LXVpIzEwMik6IHJlY3RhbmdsZSAvIHBvbHlnb24gLyBmcmVlaGFuZCBwYXRoIGRyYXdpbmcsIGNsaWNrLXNlbGVjdCBhbmQgcnViYmVyLWJhbmRcbiAqIG1hcnF1ZWUgc2VsZWN0LCBwYW4vem9vbSBnYXRpbmcgdmlhIGBzZXRDb250cm9sc0VuYWJsZWRgLCBib2R5IG1vdmUsIHZlcnRleCBtb3ZlL2FkZC9kZWxldGUsXG4gKiBiZXppZXIgaGFuZGxlIGVkaXRpbmcsIGFuZCBkb251dCBob2xlcyAoaW5jbHVkaW5nIGhvbGUgdmVydGV4ICsgaG9sZS1iZXppZXItaGFuZGxlIGVkaXRpbmcpLlxuICogSGl0LXRlc3Rpbmcgc2hhcmVzIGByZWdpb24tb3ZlcmxheS9yZWdpb24tZ2VvbWV0cnlgIHdpdGggdGhlIE9TRCBvdmVybGF5LCBzbyBib3RoIGZvbGxvd1xuICogdGhlIHNhbWUgcnVsZXMgKG11bHRpLXBhcnQgcmVnaW9ucywgaG9sZXMsIG9wZW4gcG9seWxpbmVzLCBoYW5kbGUtbGVzcyBiZXppZXIgY3VydmVzKS5cbiAqL1xuZXhwb3J0IGNsYXNzIE5hcGFyaVJlZ2lvbk92ZXJsYXkgaW1wbGVtZW50cyBJUmVnaW9uT3ZlcmxheSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgc3ZnOiBTVkdTVkdFbGVtZW50O1xuICBwcml2YXRlIHJlYWRvbmx5IHJlbmRlcmVyOiBOYXBhcmlSZWdpb25TdmdSZW5kZXJlcjtcbiAgLyoqIFRoZSBpbWFnZSdzIHJlZ2lvbiBzb3VyY2UsIGRyYXduIHVuZGVyIHRoZSByZWdpb25zIGF0IHRoZSB6b29tJ3MgbGV2ZWwgb2YgZGV0YWlsOyBudWxsXG4gICAqICB3aGVyZSB3b3JsZCBpcyBub3QgdGhlIGltYWdlICh0aGUgM0QgdmlldydzIHNjcmVlbi1zcGFjZSBsYXNzb3MpLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHNvdXJjZUxheWVyOiBSZWdpb25Tb3VyY2VMYXllciB8IG51bGw7XG4gIC8qKiBDbGllbnQg4oaUIHN2Zy1sb2NhbCDihpQgd29ybGQgY29udmVyc2lvbnMsIHdpdGggdGhlIHN2ZyBvcmlnaW4gcmVhZCBvbmNlIHBlciBnZXN0dXJlL3JlZHJhdy4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBwcm9qZWN0aW9uOiBPdmVybGF5UHJvamVjdGlvbjtcbiAgcHJpdmF0ZSByZWFkb25seSBzdWJzID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuICBwcml2YXRlIHJlYWRvbmx5IGRpc2Nvbm5lY3RDYW1lcmE6ICgpID0+IHZvaWQ7XG5cbiAgcHJpdmF0ZSBtb2RlOiBSZWdpb25Ub29sTW9kZSA9ICdub25lJztcbiAgcHJpdmF0ZSBzZWxlY3RlZDogbnVtYmVyW10gPSBbXTtcblxuICAvKiogSW4tcHJvZ3Jlc3MgZHJhd2luZyBzdGF0ZSAoaW1hZ2Utc3BhY2UpLiAqL1xuICBwcml2YXRlIGRyYWZ0UmVjdDogRHJhZ0JveCB8IG51bGwgPSBudWxsO1xuICAvKiogSW4tcHJvZ3Jlc3MgcnViYmVyLWJhbmQgc2VsZWN0aW9uIG1hcnF1ZWUgKHNlbGVjdCBtb2RlKSwgaW1hZ2Utc3BhY2UuICovXG4gIHByaXZhdGUgbWFycXVlZTogRHJhZ0JveCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGRyYWZ0UGF0aDogQXJyYXk8W251bWJlciwgbnVtYmVyXT4gfCBudWxsID0gbnVsbDsgLy8gZnJlZWhhbmQgb3IgY2xpY2sgcG9seWdvblxuICBwcml2YXRlIGRyYXdpbmcgPSBmYWxzZTsgLy8gcG9pbnRlciBpcyBkb3duIGZvciByZWN0IC8gZnJlZWhhbmRcbiAgcHJpdmF0ZSByZWdpb25zVmlzaWJsZSA9IHRydWU7XG5cbiAgLyoqIEluLXByb2dyZXNzIG1hbmlwdWxhdGlvbiAoc2VsZWN0L21vdmUgbW9kZXMpOiBkcmFnZ2luZyBhIGJvZHksIGEgcG9seWdvbiB2ZXJ0ZXgsIG9yIGFcbiAgICogIHJlY3RhbmdsZSBjb3JuZXIuIGBhbmNob3JgIGlzIHRoZSBmaXhlZCBvcHBvc2l0ZSBjb3JuZXIgZm9yIGEgcmVjdGFuZ2xlIHJlc2l6ZS4gKi9cbiAgcHJpdmF0ZSBlZGl0OiBSZWdpb25FZGl0IHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBob3N0OiBIVE1MRWxlbWVudCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHZpZXdlcjogT3ZlcmxheVZpZXdlcixcbiAgICBwcml2YXRlIHJlYWRvbmx5IHN0b3JlOiBSZWdpb25TdG9yZSxcbiAgICBvcHRzOiB7IHJlZ2lvblNvdXJjZT86IGJvb2xlYW4gfSA9IHt9LFxuICApIHtcbiAgICBpZiAoZ2V0Q29tcHV0ZWRTdHlsZShob3N0KS5wb3NpdGlvbiA9PT0gJ3N0YXRpYycpIGhvc3Quc3R5bGUucG9zaXRpb24gPSAncmVsYXRpdmUnO1xuICAgIHRoaXMuc3ZnID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFNWR19OUywgJ3N2ZycpO1xuICAgIE9iamVjdC5hc3NpZ24odGhpcy5zdmcuc3R5bGUsIHtcbiAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgaW5zZXQ6ICcwJyxcbiAgICAgIHdpZHRoOiAnMTAwJScsXG4gICAgICBoZWlnaHQ6ICcxMDAlJyxcbiAgICAgIHpJbmRleDogJzIwJyxcbiAgICAgIHBvaW50ZXJFdmVudHM6ICdub25lJywgLy8gdW50aWwgYSB0b29sIGFjdGl2YXRlc1xuICAgICAgdG91Y2hBY3Rpb246ICdub25lJyxcbiAgICB9IGFzIFBhcnRpYWw8Q1NTU3R5bGVEZWNsYXJhdGlvbj4pO1xuICAgIHRoaXMuaG9zdC5hcHBlbmRDaGlsZCh0aGlzLnN2Zyk7XG4gICAgdGhpcy5yZW5kZXJlciA9IG5ldyBOYXBhcmlSZWdpb25TdmdSZW5kZXJlcih0aGlzLnN2ZywgdGhpcy5zdG9yZSk7XG4gICAgdGhpcy5wcm9qZWN0aW9uID0gbmV3IE92ZXJsYXlQcm9qZWN0aW9uKHRoaXMuc3ZnLCB0aGlzLnZpZXdlcik7XG4gICAgdGhpcy5zb3VyY2VMYXllciA9XG4gICAgICBvcHRzLnJlZ2lvblNvdXJjZSA9PT0gZmFsc2UgPyBudWxsIDogbmV3IFJlZ2lvblNvdXJjZUxheWVyKHRoaXMuc3ZnLCB0aGlzLnN0b3JlLmdldFJlZ2lvblNvdXJjZVZpZXckKCkpO1xuXG4gICAgdGhpcy5zdmcuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcmRvd24nLCB0aGlzLm9uUG9pbnRlckRvd24pO1xuICAgIHRoaXMuc3ZnLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJtb3ZlJywgdGhpcy5vblBvaW50ZXJNb3ZlKTtcbiAgICB0aGlzLnN2Zy5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVydXAnLCB0aGlzLm9uUG9pbnRlclVwKTtcbiAgICB0aGlzLnN2Zy5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVyY2FuY2VsJywgdGhpcy5vblBvaW50ZXJDYW5jZWwpO1xuICAgIHRoaXMuc3ZnLmFkZEV2ZW50TGlzdGVuZXIoJ2xvc3Rwb2ludGVyY2FwdHVyZScsIHRoaXMub25Qb2ludGVyQ2FuY2VsKTtcbiAgICB0aGlzLnN2Zy5hZGRFdmVudExpc3RlbmVyKCdkYmxjbGljaycsIHRoaXMub25EYmxDbGljayk7XG5cbiAgICB0aGlzLnN1YnMuYWRkKHRoaXMuc3RvcmUuZ2V0UmVnaW9uVXBkYXRlRXZlbnQoKS5zdWJzY3JpYmUoKCkgPT4gdGhpcy5yZWRyYXcoKSkpO1xuICAgIHRoaXMuc3Vicy5hZGQoXG4gICAgICB0aGlzLnN0b3JlLmdldFNlbGVjdGVkU2hhcGVJbmRpY2VzJCgpLnN1YnNjcmliZSgoaWR4KSA9PiB7XG4gICAgICAgIHRoaXMuc2VsZWN0ZWQgPSBpZHggPz8gW107XG4gICAgICAgIHRoaXMucmVkcmF3KCk7XG4gICAgICB9KSxcbiAgICApO1xuICAgIC8vIEEgY2FtZXJhIG1vdmUgcmV3cml0ZXMgdGhlIHJlbmRlcmVyJ3MgdHJhbnNmb3JtIGFuZCBpdHMgZmV3IHNjcmVlbi1zcGFjZSBlbGVtZW50cztcbiAgICAvLyB0aGUgcmVnaW9ucyBhcmUgZHJhd24gaW4gd29ybGQgY29vcmRpbmF0ZXMgYW5kIGFyZSBub3QgcmVidWlsdCAoTkFQQVJJLUJPVU5EQVJZLTEwKS5cbiAgICB0aGlzLmRpc2Nvbm5lY3RDYW1lcmEgPSB0aGlzLnZpZXdlci5jYW1lcmEuY2hhbmdlZC5jb25uZWN0KCgpID0+IHRoaXMudXBkYXRlQ2FtZXJhKCkpO1xuICAgIHRoaXMucmVkcmF3KCk7XG4gIH1cblxuICAvLyDilIDilIAgSVJlZ2lvbk92ZXJsYXkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gIC8qKlxuICAgKiBXaGV0aGVyIGEgcmVnaW9uIHRvb2wgY3VycmVudGx5IG93bnMgdGhlIHBvaW50ZXIuXG4gICAqXG4gICAqIEV4cG9zZWQgc28gdGhlIHNwYXRpYWwgdmlld3MgY2FuIHRlbGwgYSBiYXJlIGNsaWNrIG9uIHRoZSBjbG91ZCAoc2VsZWN0IHRoZVxuICAgKiBjbGFzcyB1bmRlciB0aGUgY3Vyc29yKSBmcm9tIGEgY2xpY2sgdGhhdCBiZWxvbmdzIHRvIGEgZHJhd2luZyBnZXN0dXJlIOKAlFxuICAgKiBwbGFjaW5nIGEgcG9seWdvbiB2ZXJ0ZXggaXMgYWxzbyBhIGNsaWNrIHRoYXQgZG9lcyBub3QgbW92ZSwgYW5kIGl0IG11c3Qgbm90XG4gICAqIGNoYW5nZSB0aGUgc2VsZWN0aW9uIGJlaGluZCB0aGUgc2hhcGUgYmVpbmcgZHJhd24uXG4gICAqL1xuICBnZXQgdG9vbEFjdGl2ZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5tb2RlICE9PSAnbm9uZSc7XG4gIH1cblxuICBzZXRNb2RlKG1vZGU6IFJlZ2lvblRvb2xNb2RlKTogdm9pZCB7XG4gICAgdGhpcy5lbmRHZXN0dXJlKCk7XG4gICAgdGhpcy5tb2RlID0gbW9kZTtcbiAgICB0aGlzLmRyYWZ0UmVjdCA9IG51bGw7XG4gICAgdGhpcy5kcmFmdFBhdGggPSBudWxsO1xuICAgIC8vIFRoZSBvdmVybGF5IG93bnMgcG9pbnRlci9uYXZpZ2F0aW9uIGdhdGluZzogd2hpbGUgYSB0b29sIGlzIGFjdGl2ZSBpdCBjYXB0dXJlcyB0aGUgcG9pbnRlclxuICAgIC8vIGFuZCB0aGUgbmFwYXJpIGNhbWVyYSBjb250cm9scyBhcmUgZGlzYWJsZWQ7ICdub25lJyBoYW5kcyB0aGUgcG9pbnRlciBiYWNrIGZvciBwYW4vem9vbS5cbiAgICBjb25zdCBhY3RpdmUgPSBtb2RlICE9PSAnbm9uZSc7XG4gICAgdGhpcy52aWV3ZXIuc2V0Q29udHJvbHNFbmFibGVkKCFhY3RpdmUpO1xuICAgIHRoaXMuc3ZnLnN0eWxlLnBvaW50ZXJFdmVudHMgPSBhY3RpdmUgPyAnYXV0bycgOiAnbm9uZSc7XG4gICAgdGhpcy5zdmcuc3R5bGUuY3Vyc29yID0gYWN0aXZlID8gJ2Nyb3NzaGFpcicgOiAnZGVmYXVsdCc7XG4gICAgdGhpcy5yZW5kZXJPdmVybGF5KCk7XG4gIH1cblxuICBzZXRTZWxlY3RlZEJlemllcihiZXppZXI6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBjb25zdCBzZWwgPSB0aGlzLnNlbGVjdGVkUmVnaW9uKCk7XG4gICAgaWYgKHNlbD8uaWQgIT0gbnVsbCkgdGhpcy5zdG9yZS5zZXRCZXppZXIoc2VsLmlkLCBiZXppZXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEhvdyBmaW5lbHkgYSBkcmF3biB2ZXJ0ZXggbWF5IGJlIHBsYWNlZCwgaW4gd29ybGQgdW5pdHM6IG9uZSAoYW4gaW1hZ2UncyBwaXhlbHMpIGJ5XG4gICAqIGRlZmF1bHQsIGZpbmVyIGZvciBhIGRhdGFzZXQgd2hvc2UgY29vcmRpbmF0ZXMgYXJlIG5vdCBwaXhlbHMgKHNlZSBPdmVybGF5UHJvamVjdGlvbikuXG4gICAqL1xuICBzZXRXb3JsZFF1YW50dW0ocXVhbnR1bTogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5wcm9qZWN0aW9uLnNldFdvcmxkUXVhbnR1bShxdWFudHVtKTtcbiAgfVxuXG4gIGRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5zdmcucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcmRvd24nLCB0aGlzLm9uUG9pbnRlckRvd24pO1xuICAgIHRoaXMuc3ZnLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJtb3ZlJywgdGhpcy5vblBvaW50ZXJNb3ZlKTtcbiAgICB0aGlzLnN2Zy5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVydXAnLCB0aGlzLm9uUG9pbnRlclVwKTtcbiAgICB0aGlzLnN2Zy5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVyY2FuY2VsJywgdGhpcy5vblBvaW50ZXJDYW5jZWwpO1xuICAgIHRoaXMuc3ZnLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2xvc3Rwb2ludGVyY2FwdHVyZScsIHRoaXMub25Qb2ludGVyQ2FuY2VsKTtcbiAgICB0aGlzLnN2Zy5yZW1vdmVFdmVudExpc3RlbmVyKCdkYmxjbGljaycsIHRoaXMub25EYmxDbGljayk7XG4gICAgdGhpcy5kaXNjb25uZWN0Q2FtZXJhKCk7XG4gICAgdGhpcy5zdWJzLnVuc3Vic2NyaWJlKCk7XG4gICAgLy8gQSBkcmFnIHRvcm4gZG93biBtaWQtZ2VzdHVyZSAoYSBiYWNrZW5kIHN3aXRjaCkgbXVzdCBzdGlsbCBjbG9zZSBpdHMgc3RvcmUgYmF0Y2guXG4gICAgdGhpcy5lbmRHZXN0dXJlKCk7XG4gICAgdGhpcy5zb3VyY2VMYXllcj8uZGVzdHJveSgpO1xuICAgIGlmICh0aGlzLnN2Zy5wYXJlbnROb2RlKSB0aGlzLnN2Zy5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRoaXMuc3ZnKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBwb2ludGVyIGhhbmRsZXJzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICBwcml2YXRlIHJlYWRvbmx5IG9uUG9pbnRlckRvd24gPSAoZTogUG9pbnRlckV2ZW50KTogdm9pZCA9PiB7XG4gICAgaWYgKHRoaXMubW9kZSA9PT0gJ25vbmUnKSByZXR1cm47XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMucHJvamVjdGlvbi53aXRoT3JpZ2luKCgpID0+IHRoaXMucG9pbnRlckRvd24oZSkpO1xuICB9O1xuXG4gIHByaXZhdGUgcG9pbnRlckRvd24oZTogUG9pbnRlckV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgW2l4LCBpeV0gPSB0aGlzLnByb2plY3Rpb24udG9JbWFnZShlLmNsaWVudFgsIGUuY2xpZW50WSk7XG4gICAgaWYgKHRoaXMubW9kZSA9PT0gJ2RyYXdyZWN0Jykge1xuICAgICAgdGhpcy5kcmFmdFJlY3QgPSB7IHgwOiBpeCwgeTA6IGl5LCB4MTogaXgsIHkxOiBpeSB9O1xuICAgICAgdGhpcy5kcmF3aW5nID0gdHJ1ZTtcbiAgICAgIHRoaXMuc3ZnLnNldFBvaW50ZXJDYXB0dXJlKGUucG9pbnRlcklkKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMubW9kZSA9PT0gJ2RyYXdjbG9zZWRwYXRoJyB8fCB0aGlzLm1vZGUgPT09ICdkcmF3b3BlbnBhdGgnKSB7XG4gICAgICB0aGlzLmRyYWZ0UGF0aCA9IFtbaXgsIGl5XV07XG4gICAgICB0aGlzLmRyYXdpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5zdmcuc2V0UG9pbnRlckNhcHR1cmUoZS5wb2ludGVySWQpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5tb2RlID09PSAnZHJhd3BvbHlnb24nKSB7XG4gICAgICB0aGlzLmhhbmRsZVBvbHlnb25DbGljayhpeCwgaXksIGUuY2xpZW50WCwgZS5jbGllbnRZKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMubW9kZSA9PT0gJ3NlbGVjdCcgfHwgdGhpcy5tb2RlID09PSAnbW92ZScpIHtcbiAgICAgIHRoaXMuYmVnaW5NYW5pcHVsYXRpb24oaXgsIGl5LCBlKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMubW9kZSA9PT0gJ2FkZHBvaW50Jykge1xuICAgICAgdGhpcy5oYW5kbGVBZGRQb2ludChpeCwgaXksIGUuY2xpZW50WCwgZS5jbGllbnRZKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMubW9kZSA9PT0gJ2RlbGV0ZXBvaW50Jykge1xuICAgICAgdGhpcy5oYW5kbGVEZWxldGVQb2ludChpeCwgaXkpO1xuICAgIH1cbiAgICB0aGlzLnJlZHJhdygpO1xuICB9XG5cbiAgcHJpdmF0ZSByZWFkb25seSBvblBvaW50ZXJNb3ZlID0gKGU6IFBvaW50ZXJFdmVudCk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IFtpeCwgaXldID0gdGhpcy5wcm9qZWN0aW9uLnRvSW1hZ2UoZS5jbGllbnRYLCBlLmNsaWVudFkpO1xuICAgIGlmICh0aGlzLm1hcnF1ZWUpIHtcbiAgICAgIHRoaXMubWFycXVlZS54MSA9IGl4O1xuICAgICAgdGhpcy5tYXJxdWVlLnkxID0gaXk7XG4gICAgICB0aGlzLnVwZGF0ZU1hcnF1ZWVFbCgpOyAvLyB1cGRhdGUganVzdCB0aGUgbWFycXVlZSByZWN0IOKAlCBOT1QgYSBmdWxsIHJlZ2lvbiByZWRyYXdcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMuZWRpdCkge1xuICAgICAgYXBwbHlSZWdpb25FZGl0KHRoaXMuc3RvcmUsIHRoaXMuZWRpdCwgaXgsIGl5KTtcbiAgICAgIHRoaXMucmVkcmF3KCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghdGhpcy5kcmF3aW5nKSByZXR1cm47XG4gICAgaWYgKHRoaXMuZHJhZnRSZWN0KSB7XG4gICAgICB0aGlzLmRyYWZ0UmVjdC54MSA9IGl4O1xuICAgICAgdGhpcy5kcmFmdFJlY3QueTEgPSBpeTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuZHJhZnRQYXRoKSB7XG4gICAgICBjb25zdCBzdGVwID0gRlJFRUhBTkRfU1RFUF9QWCAqIHRoaXMucHJvamVjdGlvbi53b3JsZFBlckNhbnZhc1BpeGVsKCk7XG4gICAgICBjb25zdCBsYXN0ID0gdGhpcy5kcmFmdFBhdGhbdGhpcy5kcmFmdFBhdGgubGVuZ3RoIC0gMV07XG4gICAgICBpZiAoTWF0aC5hYnMoaXggLSBsYXN0WzBdKSA+PSBzdGVwIHx8IE1hdGguYWJzKGl5IC0gbGFzdFsxXSkgPj0gc3RlcCkge1xuICAgICAgICB0aGlzLmRyYWZ0UGF0aC5wdXNoKFtpeCwgaXldKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5yZW5kZXJPdmVybGF5KCk7XG4gIH07XG5cbiAgcHJpdmF0ZSByZWFkb25seSBvblBvaW50ZXJVcCA9IChlOiBQb2ludGVyRXZlbnQpOiB2b2lkID0+IHtcbiAgICBpZiAodGhpcy5tYXJxdWVlKSB7XG4gICAgICBjb25zdCBtID0gdGhpcy5tYXJxdWVlO1xuICAgICAgdGhpcy5tYXJxdWVlID0gbnVsbDtcbiAgICAgIHRoaXMucmVuZGVyZXIuY2xlYXJNYXJxdWVlKCk7XG4gICAgICB0cnkge1xuICAgICAgICB0aGlzLnN2Zy5yZWxlYXNlUG9pbnRlckNhcHR1cmUoZS5wb2ludGVySWQpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8qIGFscmVhZHkgcmVsZWFzZWQgKi9cbiAgICAgIH1cbiAgICAgIHRoaXMuZmluaXNoTWFycXVlZShtKTsgLy8gc2V0U2VsZWN0ZWRTaGFwZUluZGljZXMg4oaSIG9uZSByZWRyYXcgdmlhIHRoZSBzZWxlY3Rpb24gc3Vic2NyaXB0aW9uXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLmVkaXQpIHtcbiAgICAgIHRoaXMuc3RvcmUuZW5kQmF0Y2goKTtcbiAgICAgIHRoaXMuZWRpdCA9IG51bGw7XG4gICAgICB0cnkge1xuICAgICAgICB0aGlzLnN2Zy5yZWxlYXNlUG9pbnRlckNhcHR1cmUoZS5wb2ludGVySWQpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8qIGFscmVhZHkgcmVsZWFzZWQgKi9cbiAgICAgIH1cbiAgICAgIHRoaXMucmVkcmF3KCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghdGhpcy5kcmF3aW5nKSByZXR1cm47XG4gICAgdGhpcy5kcmF3aW5nID0gZmFsc2U7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMuc3ZnLnJlbGVhc2VQb2ludGVyQ2FwdHVyZShlLnBvaW50ZXJJZCk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvKiBjYXB0dXJlIG1heSBhbHJlYWR5IGJlIHJlbGVhc2VkICovXG4gICAgfVxuICAgIGlmICh0aGlzLmRyYWZ0UmVjdCkge1xuICAgICAgY29uc3QgeyB4MCwgeTAsIHgxLCB5MSB9ID0gdGhpcy5kcmFmdFJlY3Q7XG4gICAgICBjb25zdCB4ID0gTWF0aC5taW4oeDAsIHgxKTtcbiAgICAgIGNvbnN0IHkgPSBNYXRoLm1pbih5MCwgeTEpO1xuICAgICAgY29uc3QgdyA9IE1hdGguYWJzKHgxIC0geDApO1xuICAgICAgY29uc3QgaCA9IE1hdGguYWJzKHkxIC0geTApO1xuICAgICAgdGhpcy5kcmFmdFJlY3QgPSBudWxsO1xuICAgICAgY29uc3QgbWluID0gTUlOX1JFQ1RfRFJBR19QWCAqIHRoaXMucHJvamVjdGlvbi53b3JsZFBlckNhbnZhc1BpeGVsKCk7XG4gICAgICBpZiAodyA+PSBtaW4gJiYgaCA+PSBtaW4pIHRoaXMuY29tbWl0UmVjdGFuZ2xlKHgsIHksIHcsIGgpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5kcmFmdFBhdGgpIHtcbiAgICAgIGNvbnN0IHB0cyA9IHRoaXMuZHJhZnRQYXRoO1xuICAgICAgdGhpcy5kcmFmdFBhdGggPSBudWxsO1xuICAgICAgY29uc3QgY2xvc2VkID0gdGhpcy5tb2RlID09PSAnZHJhd2Nsb3NlZHBhdGgnO1xuICAgICAgaWYgKHB0cy5sZW5ndGggPj0gKGNsb3NlZCA/IDMgOiAyKSkgdGhpcy5jb21taXRQb2x5Z29uKHB0cywgY2xvc2VkKTtcbiAgICB9XG4gICAgdGhpcy5yZWRyYXcoKTtcbiAgfTtcblxuICAvKipcbiAgICogVGhlIHBvaW50ZXIgZ2VzdHVyZSBlbmRlZCB3aXRob3V0IGEgcG9pbnRlcnVwICh0aGUgYnJvd3NlciBjYW5jZWxsZWQgaXQsIG9yIGNhcHR1cmUgd2FzXG4gICAqIGxvc3QpOiBlbmQgaXQgd2l0aG91dCBjb21taXR0aW5nLiBBbHNvIGZpcmVzIGFmdGVyIGV2ZXJ5IG5vcm1hbCByZWxlYXNlLCB3aGVuIG5vdGhpbmdcbiAgICogaXMgbGl2ZSBhbnkgbW9yZS5cbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgb25Qb2ludGVyQ2FuY2VsID0gKCk6IHZvaWQgPT4ge1xuICAgIGlmICghdGhpcy5lZGl0ICYmICF0aGlzLmRyYXdpbmcgJiYgIXRoaXMubWFycXVlZSkgcmV0dXJuO1xuICAgIHRoaXMuZW5kR2VzdHVyZSgpO1xuICAgIHRoaXMucmVkcmF3KCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIEVuZCB3aGF0ZXZlciBwb2ludGVyIGdlc3R1cmUgaXMgbGl2ZSB3aXRob3V0IGNvbW1pdHRpbmcgaXQ6IGNsb3NlIHRoZSBzdG9yZSBiYXRjaCBhIGRyYWdcbiAgICogb3BlbmVkIChzbyBsYXRlciBlZGl0cyBhcmUgZW1pdHRlZCBhZ2FpbikgYW5kIGZvcmdldCB0aGUgZHJhZyAoc28gYSBiYXJlIGhvdmVyIG5vIGxvbmdlclxuICAgKiBtb3ZlcyB0aGUgcmVnaW9uKSwgYW5kIGRyb3AgdGhlIG1hcnF1ZWUgYW5kIGEgcmVjdGFuZ2xlL2ZyZWVoYW5kIGRyYWZ0LiBBIGNsaWNrLXBsYWNlZFxuICAgKiBwb2x5Z29uIGlzIG5vdCBhIHBvaW50ZXIgZ2VzdHVyZSBhbmQgc3Vydml2ZXMuXG4gICAqL1xuICBwcml2YXRlIGVuZEdlc3R1cmUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZWRpdCkgdGhpcy5zdG9yZS5lbmRCYXRjaCgpO1xuICAgIHRoaXMuZWRpdCA9IG51bGw7XG4gICAgaWYgKHRoaXMuZHJhd2luZykge1xuICAgICAgdGhpcy5kcmFmdFJlY3QgPSBudWxsO1xuICAgICAgdGhpcy5kcmFmdFBhdGggPSBudWxsO1xuICAgIH1cbiAgICB0aGlzLmRyYXdpbmcgPSBmYWxzZTtcbiAgICB0aGlzLm1hcnF1ZWUgPSBudWxsO1xuICAgIHRoaXMucmVuZGVyZXIuY2xlYXJNYXJxdWVlKCk7XG4gIH1cblxuICAvKiogQ2xpY2stdG8tcGxhY2UgcG9seWdvbjogYWRkIGEgdmVydGV4LCBvciBjbG9zZSB3aGVuIGNsaWNraW5nIG5lYXIgdGhlIGZpcnN0IG9uZS4gKi9cbiAgcHJpdmF0ZSBoYW5kbGVQb2x5Z29uQ2xpY2soaXg6IG51bWJlciwgaXk6IG51bWJlciwgY2xpZW50WDogbnVtYmVyLCBjbGllbnRZOiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZHJhZnRQYXRoKSB7XG4gICAgICB0aGlzLmRyYWZ0UGF0aCA9IFtbaXgsIGl5XV07XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IG5lYXIgPVxuICAgICAgdGhpcy5wcm9qZWN0aW9uLnNjcmVlbkRpc3QoY2xpZW50WCwgY2xpZW50WSwgdGhpcy5kcmFmdFBhdGhbMF1bMF0sIHRoaXMuZHJhZnRQYXRoWzBdWzFdKSA8PSBDTE9TRV9TTkFQX1BYICYmXG4gICAgICB0aGlzLmRyYWZ0UGF0aC5sZW5ndGggPj0gMztcbiAgICBpZiAobmVhcikge1xuICAgICAgY29uc3QgcHRzID0gdGhpcy5kcmFmdFBhdGg7XG4gICAgICB0aGlzLmRyYWZ0UGF0aCA9IG51bGw7XG4gICAgICB0aGlzLmNvbW1pdFBvbHlnb24ocHRzLCB0cnVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5kcmFmdFBhdGgucHVzaChbaXgsIGl5XSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWFkb25seSBvbkRibENsaWNrID0gKGU6IE1vdXNlRXZlbnQpOiB2b2lkID0+IHtcbiAgICBpZiAodGhpcy5tb2RlICE9PSAnZHJhd3BvbHlnb24nIHx8ICF0aGlzLmRyYWZ0UGF0aCkgcmV0dXJuO1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBjb25zdCBwdHMgPSB0aGlzLmRyYWZ0UGF0aDtcbiAgICB0aGlzLmRyYWZ0UGF0aCA9IG51bGw7XG4gICAgaWYgKHB0cy5sZW5ndGggPj0gMykgdGhpcy5jb21taXRQb2x5Z29uKHB0cywgdHJ1ZSk7XG4gICAgdGhpcy5yZWRyYXcoKTtcbiAgfTtcblxuICAvKiogVGhlIGN1cnJlbnRseS1zZWxlY3RlZCByZWdpb24gKHNpbmdsZSBzZWxlY3Rpb24pLCBvciBudWxsLiAqL1xuICBwcml2YXRlIHNlbGVjdGVkUmVnaW9uKCk6IFJlZ2lvbiB8IG51bGwge1xuICAgIGNvbnN0IHJlZ2lvbnMgPSB0aGlzLnN0b3JlLmdldFJlZ2lvbnMoKTtcbiAgICBjb25zdCBpID0gdGhpcy5zZWxlY3RlZFswXTtcbiAgICByZXR1cm4gaSAhPSBudWxsICYmIGkgPj0gMCAmJiBpIDwgcmVnaW9ucy5sZW5ndGggPyByZWdpb25zW2ldIDogbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGFydCBhIHNlbGVjdC9tb3ZlIGludGVyYWN0aW9uOiBncmFiIGEgaGFuZGxlIChyZWN0YW5nbGUgY29ybmVyKSBvciB2ZXJ0ZXggb2YgdGhlIGFscmVhZHktXG4gICAqIHNlbGVjdGVkIHJlZ2lvbiBmaXJzdDsgb3RoZXJ3aXNlIHNlbGVjdCB0aGUgdG9wbW9zdCByZWdpb24gdW5kZXIgdGhlIGN1cnNvciBhbmQgZHJhZyBpdHMgYm9keS5cbiAgICovXG4gIHByaXZhdGUgYmVnaW5NYW5pcHVsYXRpb24oaXg6IG51bWJlciwgaXk6IG51bWJlciwgZTogUG9pbnRlckV2ZW50KTogdm9pZCB7XG4gICAgY29uc3Qgc2VsID0gdGhpcy5zZWxlY3RlZFJlZ2lvbigpO1xuICAgIGlmIChzZWw/LmJvdW5kcykge1xuICAgICAgY29uc3QgW2x4LCBseV0gPSB0aGlzLnByb2plY3Rpb24uY2xpZW50VG9Mb2NhbChlLmNsaWVudFgsIGUuY2xpZW50WSk7XG4gICAgICBjb25zdCBncmFiID0gaGl0SGFuZGxlKHNlbCwgbHgsIGx5LCB0aGlzLnByb2plY3Rpb24udG9TY3JlZW4sIEhBTkRMRV9ISVRfUFgpO1xuICAgICAgaWYgKGdyYWIpIHtcbiAgICAgICAgdGhpcy5zdG9yZS5iZWdpbkJhdGNoKCk7XG4gICAgICAgIHRoaXMuZWRpdCA9IHsgLi4uZ3JhYiwgaWQ6IHNlbC5pZCwgbGFzdDogW2l4LCBpeV0gfTtcbiAgICAgICAgdGhpcy5zdmcuc2V0UG9pbnRlckNhcHR1cmUoZS5wb2ludGVySWQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICAgIC8vIEhpdC10ZXN0IGJvZGllcywgdG9wbW9zdCBmaXJzdCAobGFzdCBkcmF3biByZW5kZXJzIG9uIHRvcCksIGF0IHRoZSBleGFjdCBwb2ludGVyXG4gICAgLy8gcG9zaXRpb24g4oCUIHNuYXBwaW5nIGlzIGZvciBwbGFjaW5nIHZlcnRpY2VzLCBub3QgZm9yIHBpY2tpbmcuXG4gICAgY29uc3QgcmVnaW9ucyA9IHRoaXMuc3RvcmUuZ2V0UmVnaW9ucygpO1xuICAgIGNvbnN0IFt3eCwgd3ldID0gdGhpcy5wcm9qZWN0aW9uLnRvV29ybGQoZS5jbGllbnRYLCBlLmNsaWVudFkpO1xuICAgIGZvciAobGV0IGkgPSByZWdpb25zLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBpZiAodGhpcy5zdG9yZS5pc0NsYXNzSGlkZGVuKHJlZ2lvbnNbaV0ubGFiZWwpKSBjb250aW51ZTtcbiAgICAgIGlmIChyZWdpb25Db250YWlucyhyZWdpb25zW2ldLCB3eCwgd3ksIHsgdG9TY3JlZW46IHRoaXMucHJvamVjdGlvbi50b1NjcmVlbiwgdG9sUHg6IE9QRU5fUEFUSF9ISVRfUFggfSkpIHtcbiAgICAgICAgdGhpcy5zdG9yZS5zZWxlY3RSZWdpb24ocmVnaW9uc1tpXSk7XG4gICAgICAgIHRoaXMuc3RvcmUuYmVnaW5CYXRjaCgpO1xuICAgICAgICB0aGlzLmVkaXQgPSB7IGtpbmQ6ICdib2R5JywgaWQ6IHJlZ2lvbnNbaV0uaWQsIGxhc3Q6IFtpeCwgaXldIH07XG4gICAgICAgIHRoaXMuc3ZnLnNldFBvaW50ZXJDYXB0dXJlKGUucG9pbnRlcklkKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBBIGZlYXR1cmUgb2YgdGhlIHJlZ2lvbiBzb3VyY2U6IHRha2UgaXQgaW50byB0aGUgcmVnaW9ucyBhbmQgc2VsZWN0IGl0IChhIGRyYWcgb24gaXRcbiAgICAvLyBtb3ZlcyBpdCBvbmNlIGl0IGlzIHNlbGVjdGVkKS5cbiAgICBjb25zdCBmZWF0dXJlID0gdGhpcy5zb3VyY2VMYXllcj8uZmVhdHVyZUF0KHd4LCB3eSwgT1BFTl9QQVRIX0hJVF9QWCk7XG4gICAgaWYgKGZlYXR1cmUpIHtcbiAgICAgIHZvaWQgdGhpcy5zdG9yZS5zZWxlY3RTb3VyY2VGZWF0dXJlcyhbZmVhdHVyZS5pZF0sIGUuc2hpZnRLZXkgfHwgZS5tZXRhS2V5IHx8IGUuY3RybEtleSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIEVtcHR5IHNwYWNlOiBpbiBzZWxlY3QgbW9kZSBzdGFydCBhIHJ1YmJlci1iYW5kIG1hcnF1ZWUgKHNlbGVjdHMgdGhlIHJlZ2lvbnMgaXQgY292ZXJzIG9uXG4gICAgLy8gcmVsZWFzZSk7IGluIG1vdmUgbW9kZSBqdXN0IGNsZWFyIHRoZSBzZWxlY3Rpb24uXG4gICAgaWYgKHRoaXMubW9kZSA9PT0gJ3NlbGVjdCcpIHtcbiAgICAgIHRoaXMubWFycXVlZSA9IHsgeDA6IGl4LCB5MDogaXksIHgxOiBpeCwgeTE6IGl5IH07XG4gICAgICB0aGlzLnVwZGF0ZU1hcnF1ZWVFbCgpO1xuICAgICAgdGhpcy5zdmcuc2V0UG9pbnRlckNhcHR1cmUoZS5wb2ludGVySWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnN0b3JlLnNldFNlbGVjdGVkU2hhcGVJbmRpY2VzKFtdKTtcbiAgICB9XG4gIH1cblxuICAvKiogU2hvdyB0aGUgbWFycXVlZSB3aGVyZSBpdCBpcyBub3cgKG9ubHkgdGhlIG1hcnF1ZWUgZWxlbWVudDogbm8gZnVsbCByZWdpb24gcmVkcmF3KS4gKi9cbiAgcHJpdmF0ZSB1cGRhdGVNYXJxdWVlRWwoKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLm1hcnF1ZWUpIHJldHVybjtcbiAgICBjb25zdCB7IHgwLCB5MCwgeDEsIHkxIH0gPSB0aGlzLm1hcnF1ZWU7XG4gICAgY29uc3QgW2x4LCBseV0gPSB0aGlzLnByb2plY3Rpb24udG9Mb2NhbChNYXRoLm1pbih4MCwgeDEpLCBNYXRoLm1pbih5MCwgeTEpKTtcbiAgICBjb25zdCBbcngsIHJ5XSA9IHRoaXMucHJvamVjdGlvbi50b0xvY2FsKE1hdGgubWF4KHgwLCB4MSksIE1hdGgubWF4KHkwLCB5MSkpO1xuICAgIHRoaXMucmVuZGVyZXIuc2hvd01hcnF1ZWUobHgsIGx5LCByeCwgcnkpO1xuICB9XG5cbiAgLyoqIGFkZHBvaW50IG1vZGU6IGluc2VydCBhIHZlcnRleCBhdCB0aGUgY2xpY2sgb24gdGhlIHNlbGVjdGVkIHBvbHlnb24ncyBuZWFyZXN0IGVkZ2VcbiAgICogIChleHRlcmlvciBvciBhIGhvbGUgcmluZykuICovXG4gIHByaXZhdGUgaGFuZGxlQWRkUG9pbnQoaXg6IG51bWJlciwgaXk6IG51bWJlciwgY2xpZW50WDogbnVtYmVyLCBjbGllbnRZOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBzZWwgPSB0aGlzLnNlbGVjdGVkUmVnaW9uKCk7XG4gICAgaWYgKCFzZWwpIHJldHVybjtcbiAgICBjb25zdCBbbHgsIGx5XSA9IHRoaXMucHJvamVjdGlvbi5jbGllbnRUb0xvY2FsKGNsaWVudFgsIGNsaWVudFkpO1xuICAgIGNvbnN0IGVkZ2UgPSBuZWFyZXN0RWRnZShzZWwsIGx4LCBseSwgdGhpcy5wcm9qZWN0aW9uLnRvU2NyZWVuKTtcbiAgICBpZiAoIWVkZ2UpIHJldHVybjtcbiAgICBpZiAoZWRnZS5yaW5nIDwgMCkgdGhpcy5zdG9yZS5hZGRWZXJ0ZXgoc2VsLmlkLCBlZGdlLnNlZ0luZGV4LCBpeCwgaXkpO1xuICAgIGVsc2UgdGhpcy5zdG9yZS5hZGRIb2xlVmVydGV4KHNlbC5pZCwgZWRnZS5yaW5nLCBlZGdlLnNlZ0luZGV4LCBpeCwgaXkpO1xuICB9XG5cbiAgLyoqIGRlbGV0ZXBvaW50IG1vZGU6IHJlbW92ZSB0aGUgc2VsZWN0ZWQgcG9seWdvbidzIHZlcnRleCBuZWFyZXN0IHRoZSBjbGljayAoZXh0ZXJpb3Igb3IgYVxuICAgKiAgaG9sZSByaW5nKS4gKi9cbiAgcHJpdmF0ZSBoYW5kbGVEZWxldGVQb2ludChpeDogbnVtYmVyLCBpeTogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3Qgc2VsID0gdGhpcy5zZWxlY3RlZFJlZ2lvbigpO1xuICAgIGlmICghc2VsKSByZXR1cm47XG4gICAgY29uc3QgdiA9IG5lYXJlc3RWZXJ0ZXgoc2VsLCBpeCwgaXkpO1xuICAgIGlmICghdikgcmV0dXJuO1xuICAgIGlmICh2LnJpbmcgPCAwKSB0aGlzLnN0b3JlLmRlbGV0ZVZlcnRleChzZWwuaWQsIHYuaW5kZXgpO1xuICAgIGVsc2UgdGhpcy5zdG9yZS5kZWxldGVIb2xlVmVydGV4KHNlbC5pZCwgdi5yaW5nLCB2LmluZGV4KTtcbiAgfVxuXG4gIC8qKiBGaW5hbGl6ZSBhIHJ1YmJlci1iYW5kIG1hcnF1ZWU6IHNlbGVjdCBldmVyeSByZWdpb24gd2hvc2UgYm91bmRpbmcgYm94IGl0IG92ZXJsYXBzIChhXG4gICAqICBtYXJxdWVlIHVuZGVyIHtAbGluayBNSU5fTUFSUVVFRV9QWH0gaXMgYSBjbGljayBvbiBlbXB0eSBzcGFjZSDihpIgY2xlYXIgdGhlIHNlbGVjdGlvbikuICovXG4gIHByaXZhdGUgZmluaXNoTWFycXVlZShtOiBEcmFnQm94KTogdm9pZCB7XG4gICAgY29uc3QgeDAgPSBNYXRoLm1pbihtLngwLCBtLngxKTtcbiAgICBjb25zdCB4MSA9IE1hdGgubWF4KG0ueDAsIG0ueDEpO1xuICAgIGNvbnN0IHkwID0gTWF0aC5taW4obS55MCwgbS55MSk7XG4gICAgY29uc3QgeTEgPSBNYXRoLm1heChtLnkwLCBtLnkxKTtcbiAgICBjb25zdCBtaW4gPSBNSU5fTUFSUVVFRV9QWCAqIHRoaXMucHJvamVjdGlvbi53b3JsZFBlckNhbnZhc1BpeGVsKCk7XG4gICAgaWYgKHgxIC0geDAgPCBtaW4gJiYgeTEgLSB5MCA8IG1pbikge1xuICAgICAgdGhpcy5zdG9yZS5zZXRTZWxlY3RlZFNoYXBlSW5kaWNlcyhbXSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHJlZ2lvbnMgPSB0aGlzLnN0b3JlLmdldFJlZ2lvbnMoKTtcbiAgICB0aGlzLnN0b3JlLnNldFNlbGVjdGVkU2hhcGVJbmRpY2VzKFxuICAgICAgcmVnaW9uc0luUmVjdChyZWdpb25zLCB4MCwgeTAsIHgxLCB5MSwge1xuICAgICAgICBza2lwUHJvZmlsZXM6IHRydWUsXG4gICAgICAgIHNraXA6IChyKSA9PiB0aGlzLnN0b3JlLmlzQ2xhc3NIaWRkZW4oci5sYWJlbCksXG4gICAgICB9KSxcbiAgICApO1xuICAgIGNvbnN0IGZlYXR1cmVzID0gdGhpcy5zb3VyY2VMYXllcj8uZmVhdHVyZXNJblJlY3QoeDAsIHkwLCB4MSwgeTEpID8/IFtdO1xuICAgIGlmIChmZWF0dXJlcy5sZW5ndGgpIHtcbiAgICAgIHZvaWQgdGhpcy5zdG9yZS5zZWxlY3RTb3VyY2VGZWF0dXJlcyhcbiAgICAgICAgZmVhdHVyZXMuc2xpY2UoMCwgU09VUkNFX01BUlFVRUVfTElNSVQpLm1hcCgoZikgPT4gZi5pZCksXG4gICAgICAgIHRydWUsXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8vIOKUgOKUgCBzaGFwZSBjb21taXQg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gIHByaXZhdGUgY29tbWl0UmVjdGFuZ2xlKHg6IG51bWJlciwgeTogbnVtYmVyLCB3aWR0aDogbnVtYmVyLCBoZWlnaHQ6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHJlY3QgPSBuZXcgUmVjdGFuZ2xlKCk7XG4gICAgcmVjdC54ID0geDtcbiAgICByZWN0LnkgPSB5O1xuICAgIHJlY3Qud2lkdGggPSB3aWR0aDtcbiAgICByZWN0LmhlaWdodCA9IGhlaWdodDtcbiAgICBjb25zdCByZWdpb24gPSBuZXcgUmVnaW9uKCk7XG4gICAgcmVnaW9uLmJvdW5kcyA9IHJlY3Q7XG4gICAgcmVnaW9uLmNvbG9yID0gdGhpcy5zdG9yZS5nZXRTaGFwZUNvbG9yKCk7XG4gICAgdGhpcy5zdG9yZS5hZGRSZWdpb24ocmVnaW9uKTtcbiAgfVxuXG4gIHByaXZhdGUgY29tbWl0UG9seWdvbihwb2ludHM6IEFycmF5PFtudW1iZXIsIG51bWJlcl0+LCBjbG9zZWQ6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBjb25zdCBwb2x5ID0gbmV3IFBvbHlnb24oKTtcbiAgICBwb2x5Lm5wb2ludHMgPSBwb2ludHMubGVuZ3RoO1xuICAgIHBvbHkueHBvaW50cyA9IHBvaW50cy5tYXAoKHApID0+IHBbMF0pO1xuICAgIHBvbHkueXBvaW50cyA9IHBvaW50cy5tYXAoKHApID0+IHBbMV0pO1xuICAgIHBvbHkuY29vcmRpbmF0ZXMgPSBwb2ludHMubWFwKChwKSA9PiBbcFswXSwgcFsxXV0pO1xuICAgIHBvbHkuY2xvc2VkID0gY2xvc2VkO1xuICAgIGNvbnN0IHJlZ2lvbiA9IG5ldyBSZWdpb24oKTtcbiAgICByZWdpb24uYm91bmRzID0gcG9seTtcbiAgICByZWdpb24uY29sb3IgPSB0aGlzLnN0b3JlLmdldFNoYXBlQ29sb3IoKTtcbiAgICByZWdpb24ubGFiZWwgPSAnUmVnaW9uJztcbiAgICB0aGlzLnN0b3JlLmFkZFJlZ2lvbihyZWdpb24pO1xuICB9XG5cbiAgLy8g4pSA4pSAIHJlbmRlcmluZyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgLyoqIFNob3cgb3IgaGlkZSB0aGUgZHJhd24gcmVnaW9ucy4gQSByZWdpb24gYmVpbmcgZHJhd24gc3RheXMgdmlzaWJsZSBlaXRoZXIgd2F5LiAqL1xuICBzZXRSZWdpb25zVmlzaWJsZSh2aXNpYmxlOiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKHZpc2libGUgPT09IHRoaXMucmVnaW9uc1Zpc2libGUpIHJldHVybjtcbiAgICB0aGlzLnJlZ2lvbnNWaXNpYmxlID0gdmlzaWJsZTtcbiAgICB0aGlzLnNvdXJjZUxheWVyPy5zZXRWaXNpYmxlKHZpc2libGUpO1xuICAgIHRoaXMucmVkcmF3KCk7XG4gIH1cblxuICAvKiogRm9sbG93IGEgY2FtZXJhIG1vdmU6IG9uZSB0cmFuc2Zvcm0gYXR0cmlidXRlIHBsdXMgdGhlIHNjcmVlbi1zcGFjZSBlbGVtZW50cy4gKi9cbiAgcHJpdmF0ZSB1cGRhdGVDYW1lcmEoKTogdm9pZCB7XG4gICAgY29uc3QgYWZmaW5lID0gdGhpcy5wcm9qZWN0aW9uLmFmZmluZSgpO1xuICAgIHRoaXMucmVuZGVyZXIuc2V0Q2FtZXJhKGFmZmluZSk7XG4gICAgdGhpcy5zb3VyY2VMYXllcj8uc2V0Q2FtZXJhKGFmZmluZSk7XG4gIH1cblxuICAvKipcbiAgICogUmVidWlsZCBldmVyeSBlbGVtZW50IGZyb20gdGhlIHN0b3JlOiB0aGUgcmVnaW9ucyBpbiB3b3JsZCBjb29yZGluYXRlcyAob25lIHRyYW5zZm9ybWVkXG4gICAqIGdyb3VwKSwgdGhlaXIgbGFiZWxzLCBhbmQgdGhlIG92ZXJsYXkuIFJlYWRzIG5vIGxheW91dDogdGhlIGNhbWVyYSBhZmZpbmUgaXMgdGhlIHZpZXdlcidzLlxuICAgKi9cbiAgcmVkcmF3KCk6IHZvaWQge1xuICAgIHRoaXMudXBkYXRlQ2FtZXJhKCk7XG4gICAgdGhpcy5yZW5kZXJlci5yZW5kZXIodGhpcy5yZWdpb25zVmlzaWJsZSA/IHRoaXMuc3RvcmUuZ2V0UmVnaW9ucygpIDogW10sIHRoaXMuc2VsZWN0ZWQpO1xuICAgIHRoaXMucmVuZGVyT3ZlcmxheSgpO1xuICB9XG5cbiAgLyoqIFJlYnVpbGQgdGhlIHNjcmVlbi1zcGFjZSBvdmVybGF5IG9ubHk6IHRoZSBzZWxlY3RlZCByZWdpb25zJyBoYW5kbGVzIGFuZCB0aGUgZHJhZnQuICovXG4gIHByaXZhdGUgcmVuZGVyT3ZlcmxheSgpOiB2b2lkIHtcbiAgICB0aGlzLnJlbmRlcmVyLnJlbmRlck92ZXJsYXkodGhpcy5yZWdpb25zVmlzaWJsZSA/IHRoaXMuc3RvcmUuZ2V0UmVnaW9ucygpIDogW10sIHRoaXMuc2VsZWN0ZWQsIHtcbiAgICAgIHJlY3Q6IHRoaXMuZHJhZnRSZWN0LFxuICAgICAgcGF0aDogdGhpcy5kcmFmdFBhdGgsXG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==
|