@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
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copy-on-write polygon edits (review RT-13, RegionStore split "polygon-edit").
|
|
3
|
+
*
|
|
4
|
+
* Every function takes a polygon and returns a NEW {@link Polygon} with the
|
|
5
|
+
* edit applied — or null when the edit does not apply (an index out of range,
|
|
6
|
+
* a vertex delete that would degenerate the ring, …), so a caller can skip its
|
|
7
|
+
* undo step. The input is never mutated: arrays the edit does not touch are
|
|
8
|
+
* shared with it (structural sharing), arrays it does touch are copied. That
|
|
9
|
+
* is what lets `RegionStore` keep shallow undo snapshots instead of deep
|
|
10
|
+
* clones: an instance in a snapshot is never changed after the fact.
|
|
11
|
+
*
|
|
12
|
+
* Pure: no DOM, no store. Coordinates are image pixels; bézier handle offsets
|
|
13
|
+
* are relative to their anchor, as on {@link Polygon}.
|
|
14
|
+
*/
|
|
15
|
+
import { MultiPolygon, Polygon, Rectangle } from './region';
|
|
16
|
+
import { defaultHandleOffsets } from './bezier';
|
|
17
|
+
/** A shallow copy of `p` with `patch` applied (untouched arrays are shared). */
|
|
18
|
+
function withPolygon(p, patch) {
|
|
19
|
+
return Object.assign(new Polygon(), p, patch);
|
|
20
|
+
}
|
|
21
|
+
/** `xs` with `value` inserted at `at`. */
|
|
22
|
+
function inserted(xs, at, value) {
|
|
23
|
+
return [...xs.slice(0, at), value, ...xs.slice(at)];
|
|
24
|
+
}
|
|
25
|
+
/** `xs` without the element at `at`. */
|
|
26
|
+
function removed(xs, at) {
|
|
27
|
+
return [...xs.slice(0, at), ...xs.slice(at + 1)];
|
|
28
|
+
}
|
|
29
|
+
/** `xs` with the element at `at` replaced. */
|
|
30
|
+
function replaced(xs, at, value) {
|
|
31
|
+
const out = xs.slice();
|
|
32
|
+
out[at] = value;
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
35
|
+
function coordinatesOf(xs, ys) {
|
|
36
|
+
return xs.map((x, i) => [x, ys[i]]);
|
|
37
|
+
}
|
|
38
|
+
// ── exterior vertices ───────────────────────────────────────────────────
|
|
39
|
+
/** Move exterior vertex `index` to (x, y). Null when `index` is out of range. */
|
|
40
|
+
export function moveVertex(p, index, x, y) {
|
|
41
|
+
if (index < 0 || index >= p.xpoints.length)
|
|
42
|
+
return null;
|
|
43
|
+
return withPolygon(p, {
|
|
44
|
+
xpoints: replaced(p.xpoints, index, x),
|
|
45
|
+
ypoints: replaced(p.ypoints, index, y),
|
|
46
|
+
coordinates: replaced(p.coordinates, index, [x, y]),
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Insert a vertex at (x, y) after `segIndex` (the start vertex of the edge),
|
|
51
|
+
* clamped to the ring. A bézier polygon with stored handles gives the new
|
|
52
|
+
* vertex smooth handles from its neighbours and keeps the others' (possibly
|
|
53
|
+
* hand-edited) handles.
|
|
54
|
+
*/
|
|
55
|
+
export function addVertex(p, segIndex, x, y) {
|
|
56
|
+
const at = Math.max(0, Math.min(segIndex + 1, p.xpoints.length));
|
|
57
|
+
const xpoints = inserted(p.xpoints, at, x);
|
|
58
|
+
const ypoints = inserted(p.ypoints, at, y);
|
|
59
|
+
const patch = {
|
|
60
|
+
xpoints,
|
|
61
|
+
ypoints,
|
|
62
|
+
coordinates: coordinatesOf(xpoints, ypoints),
|
|
63
|
+
npoints: xpoints.length,
|
|
64
|
+
};
|
|
65
|
+
if (p.bezier && p.handlesIn && p.handlesOut) {
|
|
66
|
+
const n = xpoints.length;
|
|
67
|
+
const closed = p.closed !== false;
|
|
68
|
+
const prev = closed ? (at - 1 + n) % n : Math.max(0, at - 1);
|
|
69
|
+
const next = closed ? (at + 1) % n : Math.min(n - 1, at + 1);
|
|
70
|
+
const tx = (xpoints[next] - xpoints[prev]) / 6;
|
|
71
|
+
const ty = (ypoints[next] - ypoints[prev]) / 6;
|
|
72
|
+
patch.handlesIn = inserted(p.handlesIn, at, [-tx, -ty]);
|
|
73
|
+
patch.handlesOut = inserted(p.handlesOut, at, [tx, ty]);
|
|
74
|
+
}
|
|
75
|
+
return withPolygon(p, patch);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Delete exterior vertex `index`. Null when out of range, or when it would
|
|
79
|
+
* leave fewer than 3 vertices (2 for an open polyline).
|
|
80
|
+
*/
|
|
81
|
+
export function deleteVertex(p, index) {
|
|
82
|
+
if (index < 0 || index >= p.xpoints.length)
|
|
83
|
+
return null;
|
|
84
|
+
const min = p.closed === false ? 2 : 3;
|
|
85
|
+
if (p.xpoints.length <= min)
|
|
86
|
+
return null;
|
|
87
|
+
const xpoints = removed(p.xpoints, index);
|
|
88
|
+
const ypoints = removed(p.ypoints, index);
|
|
89
|
+
const patch = {
|
|
90
|
+
xpoints,
|
|
91
|
+
ypoints,
|
|
92
|
+
coordinates: coordinatesOf(xpoints, ypoints),
|
|
93
|
+
npoints: xpoints.length,
|
|
94
|
+
};
|
|
95
|
+
if (p.bezier && p.handlesIn && p.handlesOut) {
|
|
96
|
+
patch.handlesIn = removed(p.handlesIn, index);
|
|
97
|
+
patch.handlesOut = removed(p.handlesOut, index);
|
|
98
|
+
}
|
|
99
|
+
return withPolygon(p, patch);
|
|
100
|
+
}
|
|
101
|
+
// ── hole (interior ring) vertices — jit-ui#85 ───────────────────────────
|
|
102
|
+
function hasHole(p, holeIndex) {
|
|
103
|
+
return !!p.holes && holeIndex >= 0 && holeIndex < p.holes.length;
|
|
104
|
+
}
|
|
105
|
+
/** Move vertex `index` of hole `holeIndex` to (x, y). Null when either is out of range. */
|
|
106
|
+
export function moveHoleVertex(p, holeIndex, index, x, y) {
|
|
107
|
+
if (!hasHole(p, holeIndex))
|
|
108
|
+
return null;
|
|
109
|
+
const ring = p.holes[holeIndex];
|
|
110
|
+
if (index < 0 || index >= ring.length)
|
|
111
|
+
return null;
|
|
112
|
+
return withPolygon(p, { holes: replaced(p.holes, holeIndex, replaced(ring, index, [x, y])) });
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Insert a vertex at (x, y) on hole `holeIndex`, after `segIndex`. A bézier
|
|
116
|
+
* polygon re-seeds its hole handles so they stay parallel to the rings. Null
|
|
117
|
+
* for an out-of-range hole.
|
|
118
|
+
*/
|
|
119
|
+
export function addHoleVertex(p, holeIndex, segIndex, x, y) {
|
|
120
|
+
if (!hasHole(p, holeIndex))
|
|
121
|
+
return null;
|
|
122
|
+
const ring = p.holes[holeIndex];
|
|
123
|
+
const at = Math.max(0, Math.min(segIndex + 1, ring.length));
|
|
124
|
+
const holes = replaced(p.holes, holeIndex, inserted(ring, at, [x, y]));
|
|
125
|
+
return withPolygon(p, { holes, ...(p.bezier ? seededHoleHandles(holes) : {}) });
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Delete vertex `index` of hole `holeIndex`. Taking a ring below 3 vertices
|
|
129
|
+
* drops the whole hole (it would bound no area). Null when out of range.
|
|
130
|
+
*/
|
|
131
|
+
export function deleteHoleVertex(p, holeIndex, index) {
|
|
132
|
+
if (!hasHole(p, holeIndex))
|
|
133
|
+
return null;
|
|
134
|
+
const ring = p.holes[holeIndex];
|
|
135
|
+
if (index < 0 || index >= ring.length)
|
|
136
|
+
return null;
|
|
137
|
+
let holes = ring.length <= 3 ? removed(p.holes, holeIndex) : replaced(p.holes, holeIndex, removed(ring, index));
|
|
138
|
+
if (holes.length === 0)
|
|
139
|
+
holes = undefined;
|
|
140
|
+
return withPolygon(p, { holes, ...(p.bezier ? seededHoleHandles(holes) : {}) });
|
|
141
|
+
}
|
|
142
|
+
// ── bézier ──────────────────────────────────────────────────────────────
|
|
143
|
+
/**
|
|
144
|
+
* Per-hole bézier handles seeded from the Catmull-Rom default, parallel to
|
|
145
|
+
* `holes` (both undefined without holes).
|
|
146
|
+
*/
|
|
147
|
+
export function seededHoleHandles(holes) {
|
|
148
|
+
if (!holes || !holes.length)
|
|
149
|
+
return { holeHandlesIn: undefined, holeHandlesOut: undefined };
|
|
150
|
+
const ins = [];
|
|
151
|
+
const outs = [];
|
|
152
|
+
for (const ring of holes) {
|
|
153
|
+
const off = defaultHandleOffsets(ring.map((q) => q[0]), ring.map((q) => q[1]), true);
|
|
154
|
+
ins.push(off.in);
|
|
155
|
+
outs.push(off.out);
|
|
156
|
+
}
|
|
157
|
+
return { holeHandlesIn: ins, holeHandlesOut: outs };
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Turn bézier on — seeding editable handles (holes included) from the smooth
|
|
161
|
+
* default — or off, dropping every handle. The anchors never move. Null when
|
|
162
|
+
* the polygon is already in that state.
|
|
163
|
+
*/
|
|
164
|
+
export function setBezier(p, bezier) {
|
|
165
|
+
if (p.bezier === bezier)
|
|
166
|
+
return null;
|
|
167
|
+
if (!bezier) {
|
|
168
|
+
return withPolygon(p, {
|
|
169
|
+
bezier: false,
|
|
170
|
+
handlesIn: undefined,
|
|
171
|
+
handlesOut: undefined,
|
|
172
|
+
holeHandlesIn: undefined,
|
|
173
|
+
holeHandlesOut: undefined,
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
const off = defaultHandleOffsets(p.xpoints, p.ypoints, p.closed !== false);
|
|
177
|
+
return withPolygon(p, { bezier: true, handlesIn: off.in, handlesOut: off.out, ...seededHoleHandles(p.holes) });
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Move the `side` control point of exterior vertex `index` to the absolute
|
|
181
|
+
* point (x, y). Handles missing from a bézier polygon are seeded from the
|
|
182
|
+
* default first. Null for a non-bézier polygon or an out-of-range index.
|
|
183
|
+
*/
|
|
184
|
+
export function moveBezierHandle(p, index, side, x, y) {
|
|
185
|
+
if (!p.bezier || index < 0 || index >= p.xpoints.length)
|
|
186
|
+
return null;
|
|
187
|
+
let handlesIn = p.handlesIn, handlesOut = p.handlesOut;
|
|
188
|
+
if (!handlesIn || !handlesOut) {
|
|
189
|
+
const off = defaultHandleOffsets(p.xpoints, p.ypoints, p.closed !== false);
|
|
190
|
+
handlesIn = off.in;
|
|
191
|
+
handlesOut = off.out;
|
|
192
|
+
}
|
|
193
|
+
const offset = [x - p.xpoints[index], y - p.ypoints[index]];
|
|
194
|
+
return side === 'in'
|
|
195
|
+
? withPolygon(p, { handlesIn: replaced(handlesIn, index, offset), handlesOut })
|
|
196
|
+
: withPolygon(p, { handlesIn, handlesOut: replaced(handlesOut, index, offset) });
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Move the `side` control point of vertex `index` on hole `holeIndex` to the
|
|
200
|
+
* absolute point (x, y), seeding the hole handles first when missing. Null for
|
|
201
|
+
* a non-bézier polygon or an out-of-range hole/index.
|
|
202
|
+
*/
|
|
203
|
+
export function moveHoleBezierHandle(p, holeIndex, index, side, x, y) {
|
|
204
|
+
if (!p.bezier || !hasHole(p, holeIndex))
|
|
205
|
+
return null;
|
|
206
|
+
const ring = p.holes[holeIndex];
|
|
207
|
+
if (index < 0 || index >= ring.length)
|
|
208
|
+
return null;
|
|
209
|
+
let ins = p.holeHandlesIn, outs = p.holeHandlesOut;
|
|
210
|
+
if (!ins || !outs) {
|
|
211
|
+
const seeded = seededHoleHandles(p.holes);
|
|
212
|
+
ins = seeded.holeHandlesIn;
|
|
213
|
+
outs = seeded.holeHandlesOut;
|
|
214
|
+
}
|
|
215
|
+
const offset = [x - ring[index][0], y - ring[index][1]];
|
|
216
|
+
return side === 'in'
|
|
217
|
+
? withPolygon(p, {
|
|
218
|
+
holeHandlesIn: replaced(ins, holeIndex, replaced(ins[holeIndex], index, offset)),
|
|
219
|
+
holeHandlesOut: outs,
|
|
220
|
+
})
|
|
221
|
+
: withPolygon(p, {
|
|
222
|
+
holeHandlesIn: ins,
|
|
223
|
+
holeHandlesOut: replaced(outs, holeIndex, replaced(outs[holeIndex], index, offset)),
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
// ── translation ─────────────────────────────────────────────────────────
|
|
227
|
+
/**
|
|
228
|
+
* A polygon moved by (dx, dy): its vertices and holes (bézier offsets are
|
|
229
|
+
* relative, so they carry over). `round` snaps the moved coordinates.
|
|
230
|
+
*/
|
|
231
|
+
export function translatePolygon(p, dx, dy, round) {
|
|
232
|
+
const f = round ?? ((v) => v);
|
|
233
|
+
const xpoints = p.xpoints.map((x) => f(x + dx));
|
|
234
|
+
const ypoints = p.ypoints.map((y) => f(y + dy));
|
|
235
|
+
return withPolygon(p, {
|
|
236
|
+
xpoints,
|
|
237
|
+
ypoints,
|
|
238
|
+
coordinates: coordinatesOf(xpoints, ypoints),
|
|
239
|
+
holes: p.holes?.map((ring) => ring.map(([x, y]) => [f(x + dx), f(y + dy)])),
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
/** Any region geometry moved by (dx, dy) (see {@link translatePolygon}). */
|
|
243
|
+
export function translateBounds(b, dx, dy, round) {
|
|
244
|
+
const f = round ?? ((v) => v);
|
|
245
|
+
if (b instanceof Rectangle) {
|
|
246
|
+
return Object.assign(new Rectangle(), b, { x: f(b.x + dx), y: f(b.y + dy) });
|
|
247
|
+
}
|
|
248
|
+
if (b instanceof MultiPolygon) {
|
|
249
|
+
const polygons = b.polygons.map((p) => translatePolygon(p, dx, dy, round));
|
|
250
|
+
return Object.assign(new MultiPolygon(), { polygons });
|
|
251
|
+
}
|
|
252
|
+
return translatePolygon(b, dx, dy, round);
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9seWdvbi1lZGl0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9tb2RlbHMvcG9seWdvbi1lZGl0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7O0dBYUc7QUFDSCxPQUFPLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDNUQsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sVUFBVSxDQUFDO0FBRWhELGdGQUFnRjtBQUNoRixTQUFTLFdBQVcsQ0FBQyxDQUFVLEVBQUUsS0FBdUI7SUFDdEQsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksT0FBTyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQ2hELENBQUM7QUFFRCwwQ0FBMEM7QUFDMUMsU0FBUyxRQUFRLENBQUksRUFBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBUTtJQUN6RCxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUUsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7QUFDdEQsQ0FBQztBQUVELHdDQUF3QztBQUN4QyxTQUFTLE9BQU8sQ0FBSSxFQUFnQixFQUFFLEVBQVU7SUFDOUMsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ25ELENBQUM7QUFFRCw4Q0FBOEM7QUFDOUMsU0FBUyxRQUFRLENBQUksRUFBZ0IsRUFBRSxFQUFVLEVBQUUsS0FBUTtJQUN6RCxNQUFNLEdBQUcsR0FBRyxFQUFFLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDdkIsR0FBRyxDQUFDLEVBQUUsQ0FBQyxH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UUFDM0IsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksU0FBUyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDL0UsQ0FBQztJQUNELElBQUksQ0FBQyxZQUFZLFlBQVksRUFBRSxDQUFDO1FBQzlCLE1BQU0sUUFBUSxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQzNFLE9BQU8sTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLFlBQVksRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztJQUN6RCxDQUFDO0lBQ0QsT0FBTyxnQkFBZ0IsQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxLQUFLLENBQUMsQ0FBQztBQUM1QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBDb3B5LW9uLXdyaXRlIHBvbHlnb24gZWRpdHMgKHJldmlldyBSVC0xMywgUmVnaW9uU3RvcmUgc3BsaXQgXCJwb2x5Z29uLWVkaXRcIikuXG4gKlxuICogRXZlcnkgZnVuY3Rpb24gdGFrZXMgYSBwb2x5Z29uIGFuZCByZXR1cm5zIGEgTkVXIHtAbGluayBQb2x5Z29ufSB3aXRoIHRoZVxuICogZWRpdCBhcHBsaWVkIOKAlCBvciBudWxsIHdoZW4gdGhlIGVkaXQgZG9lcyBub3QgYXBwbHkgKGFuIGluZGV4IG91dCBvZiByYW5nZSxcbiAqIGEgdmVydGV4IGRlbGV0ZSB0aGF0IHdvdWxkIGRlZ2VuZXJhdGUgdGhlIHJpbmcsIOKApiksIHNvIGEgY2FsbGVyIGNhbiBza2lwIGl0c1xuICogdW5kbyBzdGVwLiBUaGUgaW5wdXQgaXMgbmV2ZXIgbXV0YXRlZDogYXJyYXlzIHRoZSBlZGl0IGRvZXMgbm90IHRvdWNoIGFyZVxuICogc2hhcmVkIHdpdGggaXQgKHN0cnVjdHVyYWwgc2hhcmluZyksIGFycmF5cyBpdCBkb2VzIHRvdWNoIGFyZSBjb3BpZWQuIFRoYXRcbiAqIGlzIHdoYXQgbGV0cyBgUmVnaW9uU3RvcmVgIGtlZXAgc2hhbGxvdyB1bmRvIHNuYXBzaG90cyBpbnN0ZWFkIG9mIGRlZXBcbiAqIGNsb25lczogYW4gaW5zdGFuY2UgaW4gYSBzbmFwc2hvdCBpcyBuZXZlciBjaGFuZ2VkIGFmdGVyIHRoZSBmYWN0LlxuICpcbiAqIFB1cmU6IG5vIERPTSwgbm8gc3RvcmUuIENvb3JkaW5hdGVzIGFyZSBpbWFnZSBwaXhlbHM7IGLDqXppZXIgaGFuZGxlIG9mZnNldHNcbiAqIGFyZSByZWxhdGl2ZSB0byB0aGVpciBhbmNob3IsIGFzIG9uIHtAbGluayBQb2x5Z29ufS5cbiAqL1xuaW1wb3J0IHsgTXVsdGlQb2x5Z29uLCBQb2x5Z29uLCBSZWN0YW5nbGUgfSBmcm9tICcuL3JlZ2lvbic7XG5pbXBvcnQgeyBkZWZhdWx0SGFuZGxlT2Zmc2V0cyB9IGZyb20gJy4vYmV6aWVyJztcblxuLyoqIEEgc2hhbGxvdyBjb3B5IG9mIGBwYCB3aXRoIGBwYXRjaGAgYXBwbGllZCAodW50b3VjaGVkIGFycmF5cyBhcmUgc2hhcmVkKS4gKi9cbmZ1bmN0aW9uIHdpdGhQb2x5Z29uKHA6IFBvbHlnb24sIHBhdGNoOiBQYXJ0aWFsPFBvbHlnb24+KTogUG9seWdvbiB7XG4gIHJldHVybiBPYmplY3QuYXNzaWduKG5ldyBQb2x5Z29uKCksIHAsIHBhdGNoKTtcbn1cblxuLyoqIGB4c2Agd2l0aCBgdmFsdWVgIGluc2VydGVkIGF0IGBhdGAuICovXG5mdW5jdGlvbiBpbnNlcnRlZDxUPih4czogcmVhZG9ubHkgVFtdLCBhdDogbnVtYmVyLCB2YWx1ZTogVCk6IFRbXSB7XG4gIHJldHVybiBbLi4ueHMuc2xpY2UoMCwgYXQpLCB2YWx1ZSwgLi4ueHMuc2xpY2UoYXQpXTtcbn1cblxuLyoqIGB4c2Agd2l0aG91dCB0aGUgZWxlbWVudCBhdCBgYXRgLiAqL1xuZnVuY3Rpb24gcmVtb3ZlZDxUPih4czogcmVhZG9ubHkgVFtdLCBhdDogbnVtYmVyKTogVFtdIHtcbiAgcmV0dXJuIFsuLi54cy5zbGljZSgwLCBhdCksIC4uLnhzLnNsaWNlKGF0ICsgMSldO1xufVxuXG4vKiogYHhzYCB3aXRoIHRoZSBlbGVtZW50IGF0IGBhdGAgcmVwbGFjZWQuICovXG5mdW5jdGlvbiByZXBsYWNlZDxUPih4czogcmVhZG9ubHkgVFtdLCBhdDogbnVtYmVyLCB2YWx1ZTogVCk6IFRbXSB7XG4gIGNvbnN0IG91dCA9IHhzLnNsaWNlKCk7XG4gIG91dFthdF0gPSB2YWx1ZTtcbiAgcmV0dXJuIG91dDtcbn1cblxuZnVuY3Rpb24gY29vcmRpbmF0ZXNPZih4czogbnVtYmVyW10sIHlzOiBudW1iZXJbXSk6IG51bWJlcltdW10ge1xuICByZXR1cm4geHMubWFwKCh4LCBpKSA9PiBbeCwgeXNbaV1dKTtcbn1cblxuLy8g4pSA4pSAIGV4dGVyaW9yIHZlcnRpY2VzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4vKiogTW92ZSBleHRlcmlvciB2ZXJ0ZXggYGluZGV4YCB0byAoeCwgeSkuIE51bGwgd2hlbiBgaW5kZXhgIGlzIG91dCBvZiByYW5nZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtb3ZlVmVydGV4KHA6IFBvbHlnb24sIGluZGV4OiBudW1iZXIsIHg6IG51bWJlciwgeTogbnVtYmVyKTogUG9seWdvbiB8IG51bGwge1xuICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID49IHAueHBvaW50cy5sZW5ndGgpIHJldHVybiBudWxsO1xuICByZXR1cm4gd2l0aFBvbHlnb24ocCwge1xuICAgIHhwb2ludHM6IHJlcGxhY2VkKHAueHBvaW50cywgaW5kZXgsIHgpLFxuICAgIHlwb2ludHM6IHJlcGxhY2VkKHAueXBvaW50cywgaW5kZXgsIHkpLFxuICAgIGNvb3JkaW5hdGVzOiByZXBsYWNlZChwLmNvb3JkaW5hdGVzLCBpbmRleCwgW3gsIHldKSxcbiAgfSk7XG59XG5cbi8qKlxuICogSW5zZXJ0IGEgdmVydGV4IGF0ICh4LCB5KSBhZnRlciBgc2VnSW5kZXhgICh0aGUgc3RhcnQgdmVydGV4IG9mIHRoZSBlZGdlKSxcbiAqIGNsYW1wZWQgdG8gdGhlIHJpbmcuIEEgYsOpemllciBwb2x5Z29uIHdpdGggc3RvcmVkIGhhbmRsZXMgZ2l2ZXMgdGhlIG5ld1xuICogdmVydGV4IHNtb290aCBoYW5kbGVzIGZyb20gaXRzIG5laWdoYm91cnMgYW5kIGtlZXBzIHRoZSBvdGhlcnMnIChwb3NzaWJseVxuICogaGFuZC1lZGl0ZWQpIGhhbmRsZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGRWZXJ0ZXgocDogUG9seWdvbiwgc2VnSW5kZXg6IG51bWJlciwgeDogbnVtYmVyLCB5OiBudW1iZXIpOiBQb2x5Z29uIHtcbiAgY29uc3QgYXQgPSBNYXRoLm1heCgwLCBNYXRoLm1pbihzZWdJbmRleCArIDEsIHAueHBvaW50cy5sZW5ndGgpKTtcbiAgY29uc3QgeHBvaW50cyA9IGluc2VydGVkKHAueHBvaW50cywgYXQsIHgpO1xuICBjb25zdCB5cG9pbnRzID0gaW5zZXJ0ZWQocC55cG9pbnRzLCBhdCwgeSk7XG4gIGNvbnN0IHBhdGNoOiBQYXJ0aWFsPFBvbHlnb24+ID0ge1xuICAgIHhwb2ludHMsXG4gICAgeXBvaW50cyxcbiAgICBjb29yZGluYXRlczogY29vcmRpbmF0ZXNPZih4cG9pbnRzLCB5cG9pbnRzKSxcbiAgICBucG9pbnRzOiB4cG9pbnRzLmxlbmd0aCxcbiAgfTtcbiAgaWYgKHAuYmV6aWVyICYmIHAuaGFuZGxlc0luICYmIHAuaGFuZGxlc091dCkge1xuICAgIGNvbnN0IG4gPSB4cG9pbnRzLmxlbmd0aDtcbiAgICBjb25zdCBjbG9zZWQgPSBwLmNsb3NlZCAhPT0gZmFsc2U7XG4gICAgY29uc3QgcHJldiA9IGNsb3NlZCA/IChhdCAtIDEgKyBuKSAlIG4gOiBNYXRoLm1heCgwLCBhdCAtIDEpO1xuICAgIGNvbnN0IG5leHQgPSBjbG9zZWQgPyAoYXQgKyAxKSAlIG4gOiBNYXRoLm1pbihuIC0gMSwgYXQgKyAxKTtcbiAgICBjb25zdCB0eCA9ICh4cG9pbnRzW25leHRdIC0geHBvaW50c1twcmV2XSkgLyA2O1xuICAgIGNvbnN0IHR5ID0gKHlwb2ludHNbbmV4dF0gLSB5cG9pbnRzW3ByZXZdKSAvIDY7XG4gICAgcGF0Y2guaGFuZGxlc0luID0gaW5zZXJ0ZWQocC5oYW5kbGVzSW4sIGF0LCBbLXR4LCAtdHldKTtcbiAgICBwYXRjaC5oYW5kbGVzT3V0ID0gaW5zZXJ0ZWQocC5oYW5kbGVzT3V0LCBhdCwgW3R4LCB0eV0pO1xuICB9XG4gIHJldHVybiB3aXRoUG9seWdvbihwLCBwYXRjaCk7XG59XG5cbi8qKlxuICogRGVsZXRlIGV4dGVyaW9yIHZlcnRleCBgaW5kZXhgLiBOdWxsIHdoZW4gb3V0IG9mIHJhbmdlLCBvciB3aGVuIGl0IHdvdWxkXG4gKiBsZWF2ZSBmZXdlciB0aGFuIDMgdmVydGljZXMgKDIgZm9yIGFuIG9wZW4gcG9seWxpbmUpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVsZXRlVmVydGV4KHA6IFBvbHlnb24sIGluZGV4OiBudW1iZXIpOiBQb2x5Z29uIHwgbnVsbCB7XG4gIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gcC54cG9pbnRzLmxlbmd0aCkgcmV0dXJuIG51bGw7XG4gIGNvbnN0IG1pbiA9IHAuY2xvc2VkID09PSBmYWxzZSA/IDIgOiAzO1xuICBpZiAocC54cG9pbnRzLmxlbmd0aCA8PSBtaW4pIHJldHVybiBudWxsO1xuICBjb25zdCB4cG9pbnRzID0gcmVtb3ZlZChwLnhwb2ludHMsIGluZGV4KTtcbiAgY29uc3QgeXBvaW50cyA9IHJlbW92ZWQocC55cG9pbnRzLCBpbmRleCk7XG4gIGNvbnN0IHBhdGNoOiBQYXJ0aWFsPFBvbHlnb24+ID0ge1xuICAgIHhwb2ludHMsXG4gICAgeXBvaW50cyxcbiAgICBjb29yZGluYXRlczogY29vcmRpbmF0ZXNPZih4cG9pbnRzLCB5cG9pbnRzKSxcbiAgICBucG9pbnRzOiB4cG9pbnRzLmxlbmd0aCxcbiAgfTtcbiAgaWYgKHAuYmV6aWVyICYmIHAuaGFuZGxlc0luICYmIHAuaGFuZGxlc091dCkge1xuICAgIHBhdGNoLmhhbmRsZXNJbiA9IHJlbW92ZWQocC5oYW5kbGVzSW4sIGluZGV4KTtcbiAgICBwYXRjaC5oYW5kbGVzT3V0ID0gcmVtb3ZlZChwLmhhbmRsZXNPdXQsIGluZGV4KTtcbiAgfVxuICByZXR1cm4gd2l0aFBvbHlnb24ocCwgcGF0Y2gpO1xufVxuXG4vLyDilIDilIAgaG9sZSAoaW50ZXJpb3IgcmluZykgdmVydGljZXMg4oCUIGppdC11aSM4NSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuZnVuY3Rpb24gaGFzSG9sZShwOiBQb2x5Z29uLCBob2xlSW5kZXg6IG51bWJlcik6IGJvb2xlYW4ge1xuICByZXR1cm4gISFwLmhvbGVzICYmIGhvbGVJbmRleCA+PSAwICYmIGhvbGVJbmRleCA8IHAuaG9sZXMubGVuZ3RoO1xufVxuXG4vKiogTW92ZSB2ZXJ0ZXggYGluZGV4YCBvZiBob2xlIGBob2xlSW5kZXhgIHRvICh4LCB5KS4gTnVsbCB3aGVuIGVpdGhlciBpcyBvdXQgb2YgcmFuZ2UuICovXG5leHBvcnQgZnVuY3Rpb24gbW92ZUhvbGVWZXJ0ZXgoXG4gIHA6IFBvbHlnb24sXG4gIGhvbGVJbmRleDogbnVtYmVyLFxuICBpbmRleDogbnVtYmVyLFxuICB4OiBudW1iZXIsXG4gIHk6IG51bWJlcixcbik6IFBvbHlnb24gfCBudWxsIHtcbiAgaWYgKCFoYXNIb2xlKHAsIGhvbGVJbmRleCkpIHJldHVybiBudWxsO1xuICBjb25zdCByaW5nID0gcC5ob2xlcyFbaG9sZUluZGV4XTtcbiAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSByaW5nLmxlbmd0aCkgcmV0dXJuIG51bGw7XG4gIHJldHVybiB3aXRoUG9seWdvbihwLCB7IGhvbGVzOiByZXBsYWNlZChwLmhvbGVzISwgaG9sZUluZGV4LCByZXBsYWNlZChyaW5nLCBpbmRleCwgW3gsIHldKSkgfSk7XG59XG5cbi8qKlxuICogSW5zZXJ0IGEgdmVydGV4IGF0ICh4LCB5KSBvbiBob2xlIGBob2xlSW5kZXhgLCBhZnRlciBgc2VnSW5kZXhgLiBBIGLDqXppZXJcbiAqIHBvbHlnb24gcmUtc2VlZHMgaXRzIGhvbGUgaGFuZGxlcyBzbyB0aGV5IHN0YXkgcGFyYWxsZWwgdG8gdGhlIHJpbmdzLiBOdWxsXG4gKiBmb3IgYW4gb3V0LW9mLXJhbmdlIGhvbGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGRIb2xlVmVydGV4KFxuICBwOiBQb2x5Z29uLFxuICBob2xlSW5kZXg6IG51bWJlcixcbiAgc2VnSW5kZXg6IG51bWJlcixcbiAgeDogbnVtYmVyLFxuICB5OiBudW1iZXIsXG4pOiBQb2x5Z29uIHwgbnVsbCB7XG4gIGlmICghaGFzSG9sZShwLCBob2xlSW5kZXgpKSByZXR1cm4gbnVsbDtcbiAgY29uc3QgcmluZyA9IHAuaG9sZXMhW2hvbGVJbmRleF07XG4gIGNvbnN0IGF0ID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oc2VnSW5kZXggKyAxLCByaW5nLmxlbmd0aCkpO1xuICBjb25zdCBob2xlcyA9IHJlcGxhY2VkKHAuaG9sZXMhLCBob2xlSW5kZXgsIGluc2VydGVkKHJpbmcsIGF0LCBbeCwgeV0pKTtcbiAgcmV0dXJuIHdpdGhQb2x5Z29uKHAsIHsgaG9sZXMsIC4uLihwLmJlemllciA/IHNlZWRlZEhvbGVIYW5kbGVzKGhvbGVzKSA6IHt9KSB9KTtcbn1cblxuLyoqXG4gKiBEZWxldGUgdmVydGV4IGBpbmRleGAgb2YgaG9sZSBgaG9sZUluZGV4YC4gVGFraW5nIGEgcmluZyBiZWxvdyAzIHZlcnRpY2VzXG4gKiBkcm9wcyB0aGUgd2hvbGUgaG9sZSAoaXQgd291bGQgYm91bmQgbm8gYXJlYSkuIE51bGwgd2hlbiBvdXQgb2YgcmFuZ2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWxldGVIb2xlVmVydGV4KHA6IFBvbHlnb24sIGhvbGVJbmRleDogbnVtYmVyLCBpbmRleDogbnVtYmVyKTogUG9seWdvbiB8IG51bGwge1xuICBpZiAoIWhhc0hvbGUocCwgaG9sZUluZGV4KSkgcmV0dXJuIG51bGw7XG4gIGNvbnN0IHJpbmcgPSBwLmhvbGVzIVtob2xlSW5kZXhdO1xuICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID49IHJpbmcubGVuZ3RoKSByZXR1cm4gbnVsbDtcbiAgbGV0IGhvbGVzOiBudW1iZXJbXVtdW10gfCB1bmRlZmluZWQgPVxuICAgIHJpbmcubGVuZ3RoIDw9IDMgPyByZW1vdmVkKHAuaG9sZXMhLCBob2xlSW5kZXgpIDogcmVwbGFjZWQocC5ob2xlcyEsIGhvbGVJbmRleCwgcmVtb3ZlZChyaW5nLCBpbmRleCkpO1xuICBpZiAoaG9sZXMubGVuZ3RoID09PSAwKSBob2xlcyA9IHVuZGVmaW5lZDtcbiAgcmV0dXJuIHdpdGhQb2x5Z29uKHAsIHsgaG9sZXMsIC4uLihwLmJlemllciA/IHNlZWRlZEhvbGVIYW5kbGVzKGhvbGVzKSA6IHt9KSB9KTtcbn1cblxuLy8g4pSA4pSAIGLDqXppZXIg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbi8qKlxuICogUGVyLWhvbGUgYsOpemllciBoYW5kbGVzIHNlZWRlZCBmcm9tIHRoZSBDYXRtdWxsLVJvbSBkZWZhdWx0LCBwYXJhbGxlbCB0b1xuICogYGhvbGVzYCAoYm90aCB1bmRlZmluZWQgd2l0aG91dCBob2xlcykuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZWVkZWRIb2xlSGFuZGxlcyhcbiAgaG9sZXM6IG51bWJlcltdW11bXSB8IHVuZGVmaW5lZCxcbik6IFBpY2s8UG9seWdvbiwgJ2hvbGVIYW5kbGVzSW4nIHwgJ2hvbGVIYW5kbGVzT3V0Jz4ge1xuICBpZiAoIWhvbGVzIHx8ICFob2xlcy5sZW5ndGgpIHJldHVybiB7IGhvbGVIYW5kbGVzSW46IHVuZGVmaW5lZCwgaG9sZUhhbmRsZXNPdXQ6IHVuZGVmaW5lZCB9O1xuICBjb25zdCBpbnM6IG51bWJlcltdW11bXSA9IFtdO1xuICBjb25zdCBvdXRzOiBudW1iZXJbXVtdW10gPSBbXTtcbiAgZm9yIChjb25zdCByaW5nIG9mIGhvbGVzKSB7XG4gICAgY29uc3Qgb2ZmID0gZGVmYXVsdEhhbmRsZU9mZnNldHMoXG4gICAgICByaW5nLm1hcCgocSkgPT4gcVswXSksXG4gICAgICByaW5nLm1hcCgocSkgPT4gcVsxXSksXG4gICAgICB0cnVlLFxuICAgICk7XG4gICAgaW5zLnB1c2gob2ZmLmluKTtcbiAgICBvdXRzLnB1c2gob2ZmLm91dCk7XG4gIH1cbiAgcmV0dXJuIHsgaG9sZUhhbmRsZXNJbjogaW5zLCBob2xlSGFuZGxlc091dDogb3V0cyB9O1xufVxuXG4vKipcbiAqIFR1cm4gYsOpemllciBvbiDigJQgc2VlZGluZyBlZGl0YWJsZSBoYW5kbGVzIChob2xlcyBpbmNsdWRlZCkgZnJvbSB0aGUgc21vb3RoXG4gKiBkZWZhdWx0IOKAlCBvciBvZmYsIGRyb3BwaW5nIGV2ZXJ5IGhhbmRsZS4gVGhlIGFuY2hvcnMgbmV2ZXIgbW92ZS4gTnVsbCB3aGVuXG4gKiB0aGUgcG9seWdvbiBpcyBhbHJlYWR5IGluIHRoYXQgc3RhdGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRCZXppZXIocDogUG9seWdvbiwgYmV6aWVyOiBib29sZWFuKTogUG9seWdvbiB8IG51bGwge1xuICBpZiAocC5iZXppZXIgPT09IGJlemllcikgcmV0dXJuIG51bGw7XG4gIGlmICghYmV6aWVyKSB7XG4gICAgcmV0dXJuIHdpdGhQb2x5Z29uKHAsIHtcbiAgICAgIGJlemllcjogZmFsc2UsXG4gICAgICBoYW5kbGVzSW46IHVuZGVmaW5lZCxcbiAgICAgIGhhbmRsZXNPdXQ6IHVuZGVmaW5lZCxcbiAgICAgIGhvbGVIYW5kbGVzSW46IHVuZGVmaW5lZCxcbiAgICAgIGhvbGVIYW5kbGVzT3V0OiB1bmRlZmluZWQsXG4gICAgfSk7XG4gIH1cbiAgY29uc3Qgb2ZmID0gZGVmYXVsdEhhbmRsZU9mZnNldHMocC54cG9pbnRzLCBwLnlwb2ludHMsIHAuY2xvc2VkICE9PSBmYWxzZSk7XG4gIHJldHVybiB3aXRoUG9seWdvbihwLCB7IGJlemllcjogdHJ1ZSwgaGFuZGxlc0luOiBvZmYuaW4sIGhhbmRsZXNPdXQ6IG9mZi5vdXQsIC4uLnNlZWRlZEhvbGVIYW5kbGVzKHAuaG9sZXMpIH0pO1xufVxuXG4vKipcbiAqIE1vdmUgdGhlIGBzaWRlYCBjb250cm9sIHBvaW50IG9mIGV4dGVyaW9yIHZlcnRleCBgaW5kZXhgIHRvIHRoZSBhYnNvbHV0ZVxuICogcG9pbnQgKHgsIHkpLiBIYW5kbGVzIG1pc3NpbmcgZnJvbSBhIGLDqXppZXIgcG9seWdvbiBhcmUgc2VlZGVkIGZyb20gdGhlXG4gKiBkZWZhdWx0IGZpcnN0LiBOdWxsIGZvciBhIG5vbi1iw6l6aWVyIHBvbHlnb24gb3IgYW4gb3V0LW9mLXJhbmdlIGluZGV4LlxuICovXG5leHBvcnQgZnVuY3Rpb24gbW92ZUJlemllckhhbmRsZShcbiAgcDogUG9seWdvbixcbiAgaW5kZXg6IG51bWJlcixcbiAgc2lkZTogJ2luJyB8ICdvdXQnLFxuICB4OiBudW1iZXIsXG4gIHk6IG51bWJlcixcbik6IFBvbHlnb24gfCBudWxsIHtcbiAgaWYgKCFwLmJlemllciB8fCBpbmRleCA8IDAgfHwgaW5kZXggPj0gcC54cG9pbnRzLmxlbmd0aCkgcmV0dXJuIG51bGw7XG4gIGxldCBoYW5kbGVzSW4gPSBwLmhhbmRsZXNJbixcbiAgICBoYW5kbGVzT3V0ID0gcC5oYW5kbGVzT3V0O1xuICBpZiAoIWhhbmRsZXNJbiB8fCAhaGFuZGxlc091dCkge1xuICAgIGNvbnN0IG9mZiA9IGRlZmF1bHRIYW5kbGVPZmZzZXRzKHAueHBvaW50cywgcC55cG9pbnRzLCBwLmNsb3NlZCAhPT0gZmFsc2UpO1xuICAgIGhhbmRsZXNJbiA9IG9mZi5pbjtcbiAgICBoYW5kbGVzT3V0ID0gb2ZmLm91dDtcbiAgfVxuICBjb25zdCBvZmZzZXQgPSBbeCAtIHAueHBvaW50c1tpbmRleF0sIHkgLSBwLnlwb2ludHNbaW5kZXhdXTtcbiAgcmV0dXJuIHNpZGUgPT09ICdpbidcbiAgICA/IHdpdGhQb2x5Z29uKHAsIHsgaGFuZGxlc0luOiByZXBsYWNlZChoYW5kbGVzSW4sIGluZGV4LCBvZmZzZXQpLCBoYW5kbGVzT3V0IH0pXG4gICAgOiB3aXRoUG9seWdvbihwLCB7IGhhbmRsZXNJbiwgaGFuZGxlc091dDogcmVwbGFjZWQoaGFuZGxlc091dCwgaW5kZXgsIG9mZnNldCkgfSk7XG59XG5cbi8qKlxuICogTW92ZSB0aGUgYHNpZGVgIGNvbnRyb2wgcG9pbnQgb2YgdmVydGV4IGBpbmRleGAgb24gaG9sZSBgaG9sZUluZGV4YCB0byB0aGVcbiAqIGFic29sdXRlIHBvaW50ICh4LCB5KSwgc2VlZGluZyB0aGUgaG9sZSBoYW5kbGVzIGZpcnN0IHdoZW4gbWlzc2luZy4gTnVsbCBmb3JcbiAqIGEgbm9uLWLDqXppZXIgcG9seWdvbiBvciBhbiBvdXQtb2YtcmFuZ2UgaG9sZS9pbmRleC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1vdmVIb2xlQmV6aWVySGFuZGxlKFxuICBwOiBQb2x5Z29uLFxuICBob2xlSW5kZXg6IG51bWJlcixcbiAgaW5kZXg6IG51bWJlcixcbiAgc2lkZTogJ2luJyB8ICdvdXQnLFxuICB4OiBudW1iZXIsXG4gIHk6IG51bWJlcixcbik6IFBvbHlnb24gfCBudWxsIHtcbiAgaWYgKCFwLmJlemllciB8fCAhaGFzSG9sZShwLCBob2xlSW5kZXgpKSByZXR1cm4gbnVsbDtcbiAgY29uc3QgcmluZyA9IHAuaG9sZXMhW2hvbGVJbmRleF07XG4gIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gcmluZy5sZW5ndGgpIHJldHVybiBudWxsO1xuICBsZXQgaW5zID0gcC5ob2xlSGFuZGxlc0luLFxuICAgIG91dHMgPSBwLmhvbGVIYW5kbGVzT3V0O1xuICBpZiAoIWlucyB8fCAhb3V0cykge1xuICAgIGNvbnN0IHNlZWRlZCA9IHNlZWRlZEhvbGVIYW5kbGVzKHAuaG9sZXMpO1xuICAgIGlucyA9IHNlZWRlZC5ob2xlSGFuZGxlc0luITtcbiAgICBvdXRzID0gc2VlZGVkLmhvbGVIYW5kbGVzT3V0ITtcbiAgfVxuICBjb25zdCBvZmZzZXQgPSBbeCAtIHJpbmdbaW5kZXhdWzBdLCB5IC0gcmluZ1tpbmRleF1bMV1dO1xuICByZXR1cm4gc2lkZSA9PT0gJ2luJ1xuICAgID8gd2l0aFBvbHlnb24ocCwge1xuICAgICAgICBob2xlSGFuZGxlc0luOiByZXBsYWNlZChpbnMsIGhvbGVJbmRleCwgcmVwbGFjZWQoaW5zW2hvbGVJbmRleF0sIGluZGV4LCBvZmZzZXQpKSxcbiAgICAgICAgaG9sZUhhbmRsZXNPdXQ6IG91dHMsXG4gICAgICB9KVxuICAgIDogd2l0aFBvbHlnb24ocCwge1xuICAgICAgICBob2xlSGFuZGxlc0luOiBpbnMsXG4gICAgICAgIGhvbGVIYW5kbGVzT3V0OiByZXBsYWNlZChvdXRzLCBob2xlSW5kZXgsIHJlcGxhY2VkKG91dHNbaG9sZUluZGV4XSwgaW5kZXgsIG9mZnNldCkpLFxuICAgICAgfSk7XG59XG5cbi8vIOKUgOKUgCB0cmFuc2xhdGlvbiDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuLyoqXG4gKiBBIHBvbHlnb24gbW92ZWQgYnkgKGR4LCBkeSk6IGl0cyB2ZXJ0aWNlcyBhbmQgaG9sZXMgKGLDqXppZXIgb2Zmc2V0cyBhcmVcbiAqIHJlbGF0aXZlLCBzbyB0aGV5IGNhcnJ5IG92ZXIpLiBgcm91bmRgIHNuYXBzIHRoZSBtb3ZlZCBjb29yZGluYXRlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zbGF0ZVBvbHlnb24ocDogUG9seWdvbiwgZHg6IG51bWJlciwgZHk6IG51bWJlciwgcm91bmQ/OiAodjogbnVtYmVyKSA9PiBudW1iZXIpOiBQb2x5Z29uIHtcbiAgY29uc3QgZiA9IHJvdW5kID8/ICgodjogbnVtYmVyKSA9PiB2KTtcbiAgY29uc3QgeHBvaW50cyA9IHAueHBvaW50cy5tYXAoKHgpID0+IGYoeCArIGR4KSk7XG4gIGNvbnN0IHlwb2ludHMgPSBwLnlwb2ludHMubWFwKCh5KSA9PiBmKHkgKyBkeSkpO1xuICByZXR1cm4gd2l0aFBvbHlnb24ocCwge1xuICAgIHhwb2ludHMsXG4gICAgeXBvaW50cyxcbiAgICBjb29yZGluYXRlczogY29vcmRpbmF0ZXNPZih4cG9pbnRzLCB5cG9pbnRzKSxcbiAgICBob2xlczogcC5ob2xlcz8ubWFwKChyaW5nKSA9PiByaW5nLm1hcCgoW3gsIHldKSA9PiBbZih4ICsgZHgpLCBmKHkgKyBkeSldKSksXG4gIH0pO1xufVxuXG4vKiogQW55IHJlZ2lvbiBnZW9tZXRyeSBtb3ZlZCBieSAoZHgsIGR5KSAoc2VlIHtAbGluayB0cmFuc2xhdGVQb2x5Z29ufSkuICovXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNsYXRlQm91bmRzKFxuICBiOiBSZWN0YW5nbGUgfCBQb2x5Z29uIHwgTXVsdGlQb2x5Z29uLFxuICBkeDogbnVtYmVyLFxuICBkeTogbnVtYmVyLFxuICByb3VuZD86ICh2OiBudW1iZXIpID0+IG51bWJlcixcbik6IFJlY3RhbmdsZSB8IFBvbHlnb24gfCBNdWx0aVBvbHlnb24ge1xuICBjb25zdCBmID0gcm91bmQgPz8gKCh2OiBudW1iZXIpID0+IHYpO1xuICBpZiAoYiBpbnN0YW5jZW9mIFJlY3RhbmdsZSkge1xuICAgIHJldHVybiBPYmplY3QuYXNzaWduKG5ldyBSZWN0YW5nbGUoKSwgYiwgeyB4OiBmKGIueCArIGR4KSwgeTogZihiLnkgKyBkeSkgfSk7XG4gIH1cbiAgaWYgKGIgaW5zdGFuY2VvZiBNdWx0aVBvbHlnb24pIHtcbiAgICBjb25zdCBwb2x5Z29ucyA9IGIucG9seWdvbnMubWFwKChwKSA9PiB0cmFuc2xhdGVQb2x5Z29uKHAsIGR4LCBkeSwgcm91bmQpKTtcbiAgICByZXR1cm4gT2JqZWN0LmFzc2lnbihuZXcgTXVsdGlQb2x5Z29uKCksIHsgcG9seWdvbnMgfSk7XG4gIH1cbiAgcmV0dXJuIHRyYW5zbGF0ZVBvbHlnb24oYiwgZHgsIGR5LCByb3VuZCk7XG59XG4iXX0=
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { MultiPolygon, Polygon, Rectangle, Region } from './region';
|
|
2
|
+
import { bezierCurveFromHandles, resolveHandles } from './bezier';
|
|
3
|
+
/** A Polygon over the given vertex arrays (taken by reference). */
|
|
4
|
+
export function makePolygon(xs, ys, opts = {}) {
|
|
5
|
+
const poly = new Polygon();
|
|
6
|
+
poly.npoints = xs.length;
|
|
7
|
+
poly.xpoints = xs;
|
|
8
|
+
poly.ypoints = ys;
|
|
9
|
+
poly.coordinates = xs.map((x, i) => [x, ys[i]]);
|
|
10
|
+
poly.closed = opts.closed ?? true;
|
|
11
|
+
if (opts.bezier)
|
|
12
|
+
poly.bezier = true;
|
|
13
|
+
if (opts.holes && opts.holes.length)
|
|
14
|
+
poly.holes = opts.holes;
|
|
15
|
+
return poly;
|
|
16
|
+
}
|
|
17
|
+
/** The four corners of a rectangle as a closed ring (clockwise from top-left). */
|
|
18
|
+
export function rectToRing(r) {
|
|
19
|
+
return {
|
|
20
|
+
xs: [r.x, r.x + r.width, r.x + r.width, r.x],
|
|
21
|
+
ys: [r.y, r.y, r.y + r.height, r.y + r.height],
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/** A deep copy of a polygon: vertices, holes and every bézier handle. */
|
|
25
|
+
export function clonePolygon(p) {
|
|
26
|
+
const poly = new Polygon();
|
|
27
|
+
poly.npoints = p.npoints;
|
|
28
|
+
poly.xpoints = p.xpoints.slice();
|
|
29
|
+
poly.ypoints = p.ypoints.slice();
|
|
30
|
+
poly.coordinates = p.coordinates.map((c) => c.slice());
|
|
31
|
+
poly.closed = p.closed;
|
|
32
|
+
poly.bezier = p.bezier;
|
|
33
|
+
if (p.handlesIn)
|
|
34
|
+
poly.handlesIn = p.handlesIn.map((o) => o.slice());
|
|
35
|
+
if (p.handlesOut)
|
|
36
|
+
poly.handlesOut = p.handlesOut.map((o) => o.slice());
|
|
37
|
+
if (p.holes)
|
|
38
|
+
poly.holes = p.holes.map((ring) => ring.map((pt) => pt.slice()));
|
|
39
|
+
if (p.holeHandlesIn)
|
|
40
|
+
poly.holeHandlesIn = p.holeHandlesIn.map((r) => r.map((o) => o.slice()));
|
|
41
|
+
if (p.holeHandlesOut)
|
|
42
|
+
poly.holeHandlesOut = p.holeHandlesOut.map((r) => r.map((o) => o.slice()));
|
|
43
|
+
return poly;
|
|
44
|
+
}
|
|
45
|
+
/** A deep copy of any region geometry. */
|
|
46
|
+
export function cloneBounds(bounds) {
|
|
47
|
+
if (bounds instanceof Rectangle) {
|
|
48
|
+
const rect = new Rectangle();
|
|
49
|
+
rect.x = bounds.x;
|
|
50
|
+
rect.y = bounds.y;
|
|
51
|
+
rect.width = bounds.width;
|
|
52
|
+
rect.height = bounds.height;
|
|
53
|
+
return rect;
|
|
54
|
+
}
|
|
55
|
+
if (bounds instanceof MultiPolygon) {
|
|
56
|
+
const mp = new MultiPolygon();
|
|
57
|
+
mp.polygons = bounds.polygons.map((p) => clonePolygon(p));
|
|
58
|
+
return mp;
|
|
59
|
+
}
|
|
60
|
+
return clonePolygon(bounds);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* A copy of `existing` (id, name, label, colour, colour override, source,
|
|
64
|
+
* file name, kind, z, …) with new geometry and optional extra fields. Use it
|
|
65
|
+
* whenever a tool edits a region's shape, so the edit never drops metadata and
|
|
66
|
+
* never mutates the store's instance.
|
|
67
|
+
*/
|
|
68
|
+
export function replaceBounds(existing, bounds, patch = {}) {
|
|
69
|
+
return Object.assign(new Region(), existing, patch, { bounds });
|
|
70
|
+
}
|
|
71
|
+
/** A closed ring rounded to whole pixels, as image-processing consumers expect. */
|
|
72
|
+
function roundedPolygon(xs, ys, holes) {
|
|
73
|
+
return makePolygon(xs.map(Math.round), ys.map(Math.round), {
|
|
74
|
+
holes: holes?.map((ring) => ring.map(([x, y]) => [Math.round(x), Math.round(y)])),
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
/** A polygon's exterior and holes, with a bézier region flattened to its curve. */
|
|
78
|
+
function flattenPolygon(p) {
|
|
79
|
+
if (!p.bezier)
|
|
80
|
+
return roundedPolygon(p.xpoints, p.ypoints, p.holes);
|
|
81
|
+
const closed = p.closed !== false;
|
|
82
|
+
const curve = bezierCurveFromHandles(p.xpoints, p.ypoints, resolveHandles(p.xpoints, p.ypoints, closed, p.handlesIn, p.handlesOut), closed);
|
|
83
|
+
const holes = p.holes?.map((ring, h) => {
|
|
84
|
+
const hx = ring.map((pt) => pt[0]);
|
|
85
|
+
const hy = ring.map((pt) => pt[1]);
|
|
86
|
+
const c = bezierCurveFromHandles(hx, hy, resolveHandles(hx, hy, true, p.holeHandlesIn?.[h], p.holeHandlesOut?.[h]), true);
|
|
87
|
+
return dropClosingPoint(c.xs, c.ys).xs.map((x, i) => [x, c.ys[i]]);
|
|
88
|
+
});
|
|
89
|
+
const ring = dropClosingPoint(curve.xs, curve.ys);
|
|
90
|
+
return roundedPolygon(ring.xs, ring.ys, holes);
|
|
91
|
+
}
|
|
92
|
+
/** A sampled closed curve repeats its first point at the end; rings don't. */
|
|
93
|
+
function dropClosingPoint(xs, ys) {
|
|
94
|
+
const n = xs.length;
|
|
95
|
+
if (n > 1 && xs[0] === xs[n - 1] && ys[0] === ys[n - 1])
|
|
96
|
+
return { xs: xs.slice(0, -1), ys: ys.slice(0, -1) };
|
|
97
|
+
return { xs, ys };
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* The closed polygons a region covers, for image-processing consumers (crop,
|
|
101
|
+
* segmentation requests): a rectangle's four corners, a closed polygon with its
|
|
102
|
+
* holes (a bézier region as its flattened curve), one polygon per part of a
|
|
103
|
+
* multi-polygon. Open polylines cover no area and yield nothing. Coordinates
|
|
104
|
+
* are rounded to whole pixels.
|
|
105
|
+
*/
|
|
106
|
+
export function regionPolygons(region) {
|
|
107
|
+
const b = region.bounds;
|
|
108
|
+
if (b instanceof Rectangle) {
|
|
109
|
+
// Bottom-left first, as the previous Plotly-shape projection produced.
|
|
110
|
+
return [roundedPolygon([b.x, b.x + b.width, b.x + b.width, b.x], [b.y + b.height, b.y + b.height, b.y, b.y])];
|
|
111
|
+
}
|
|
112
|
+
if (b instanceof Polygon)
|
|
113
|
+
return b.closed === false ? [] : [flattenPolygon(b)];
|
|
114
|
+
if (b instanceof MultiPolygon)
|
|
115
|
+
return b.polygons.filter((p) => p.closed !== false).map(flattenPolygon);
|
|
116
|
+
return [];
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* The open polylines a region traces (a polyline, or a multi-polygon's open parts), as interleaved
|
|
120
|
+
* `x, y` image px; a bézier polyline as its flattened curve. Closed shapes yield nothing.
|
|
121
|
+
*/
|
|
122
|
+
export function regionPolylines(region) {
|
|
123
|
+
const b = region.bounds;
|
|
124
|
+
const parts = b instanceof Polygon ? [b] : b instanceof MultiPolygon ? b.polygons : [];
|
|
125
|
+
return parts
|
|
126
|
+
.filter((p) => p.closed === false && p.xpoints.length >= 2)
|
|
127
|
+
.map((p) => {
|
|
128
|
+
const { xs, ys } = p.bezier
|
|
129
|
+
? bezierCurveFromHandles(p.xpoints, p.ypoints, resolveHandles(p.xpoints, p.ypoints, false, p.handlesIn, p.handlesOut), false)
|
|
130
|
+
: { xs: p.xpoints, ys: p.ypoints };
|
|
131
|
+
return Float64Array.from(xs.flatMap((x, i) => [x, ys[i]]));
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9seWdvbi1mYWN0b3J5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9tb2RlbHMvcG9seWdvbi1mYWN0b3J5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFDcEUsT0FBTyxFQUFFLHNCQUFzQixFQUFFLGNBQWMsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQWlCbEUsbUVBQW1FO0FBQ25FLE1BQU0sVUFBVSxXQUFXLENBQUMsRUFBWSxFQUFFLEVBQVksRUFBRSxPQUEyQixFQUFFO0lBQ25GLE1BQU0sSUFBSSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7SUFDM0IsSUFBSSxDQUFDLE9BQU8sR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDO0lBQ3pCLElBQUksQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO0lBQ2xCLElBQUksQ0FBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO0lBQ2xCLElBQUksQ0FBQyxXQUFXLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDaEQsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQztJQUNsQyxJQUFJLElBQUksQ0FBQyxNQUFNO1FBQUUsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUM7SUFDcEMsSUFBSSxJQUFJLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTTtRQUFFLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQztJQUM3RCxPQUFPLElBQUksQ0FBQztBQUNkLENBQUM7QUFFRCxrRkFBa0Y7QUFDbEYsTUFBTSxVQUFV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QUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztJQUN2RixPQUFPLEtBQUs7U0FDVCxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLEtBQUssS0FBSyxJQUFJLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQztTQUMxRCxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtRQUNULE1BQU0sRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDLE1BQU07WUFDekIsQ0FBQyxDQUFDLHNCQUFzQixDQUNwQixDQUFDLENBQUMsT0FBTyxFQUNULENBQUMsQ0FBQyxPQUFPLEVBQ1QsY0FBYyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUMsVUFBVSxDQUFDLEVBQ3RFLEtBQUssQ0FDTjtZQUNILENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDckMsT0FBTyxZQUFZLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDN0QsQ0FBQyxDQUFDLENBQUM7QUFDUCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTXVsdGlQb2x5Z29uLCBQb2x5Z29uLCBSZWN0YW5nbGUsIFJlZ2lvbiB9IGZyb20gJy4vcmVnaW9uJztcbmltcG9ydCB7IGJlemllckN1cnZlRnJvbUhhbmRsZXMsIHJlc29sdmVIYW5kbGVzIH0gZnJvbSAnLi9iZXppZXInO1xuXG4vKipcbiAqIFBvbHlnb24gLyBSZWdpb24gY29uc3RydWN0aW9uIGFuZCBjbG9uaW5nIGluIG9uZSBwbGFjZSwgc28gY2FsbGVycyBzdG9wXG4gKiBoYW5kLWZpbGxpbmcgYG5wb2ludHNgLCBgeHBvaW50c2AsIGB5cG9pbnRzYCwgYGNvb3JkaW5hdGVzYCBhbmQgYGNsb3NlZGBcbiAqICh0aHJlZSByZWR1bmRhbnQgdmlld3Mgb2Ygb25lIHJpbmcgdGhhdCBldmVyeSBtdXRhdG9yIG11c3Qga2VlcCBpbiBzeW5jKS5cbiAqL1xuXG4vKiogT3B0aW9ucyBmb3Ige0BsaW5rIG1ha2VQb2x5Z29ufS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWFrZVBvbHlnb25PcHRpb25zIHtcbiAgLyoqIGZhbHNlIGZvciBhbiBvcGVuIHBvbHlsaW5lOyBkZWZhdWx0IHRydWUuICovXG4gIGNsb3NlZD86IGJvb2xlYW47XG4gIC8qKiBJbnRlcmlvciByaW5nczsgb21pdHRlZCB3aGVuIGFic2VudCBvciBlbXB0eS4gKi9cbiAgaG9sZXM/OiBudW1iZXJbXVtdW107XG4gIGJlemllcj86IGJvb2xlYW47XG59XG5cbi8qKiBBIFBvbHlnb24gb3ZlciB0aGUgZ2l2ZW4gdmVydGV4IGFycmF5cyAodGFrZW4gYnkgcmVmZXJlbmNlKS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYWtlUG9seWdvbih4czogbnVtYmVyW10sIHlzOiBudW1iZXJbXSwgb3B0czogTWFrZVBvbHlnb25PcHRpb25zID0ge30pOiBQb2x5Z29uIHtcbiAgY29uc3QgcG9seSA9IG5ldyBQb2x5Z29uKCk7XG4gIHBvbHkubnBvaW50cyA9IHhzLmxlbmd0aDtcbiAgcG9seS54cG9pbnRzID0geHM7XG4gIHBvbHkueXBvaW50cyA9IHlzO1xuICBwb2x5LmNvb3JkaW5hdGVzID0geHMubWFwKCh4LCBpKSA9PiBbeCwgeXNbaV1dKTtcbiAgcG9seS5jbG9zZWQgPSBvcHRzLmNsb3NlZCA/PyB0cnVlO1xuICBpZiAob3B0cy5iZXppZXIpIHBvbHkuYmV6aWVyID0gdHJ1ZTtcbiAgaWYgKG9wdHMuaG9sZXMgJiYgb3B0cy5ob2xlcy5sZW5ndGgpIHBvbHkuaG9sZXMgPSBvcHRzLmhvbGVzO1xuICByZXR1cm4gcG9seTtcbn1cblxuLyoqIFRoZSBmb3VyIGNvcm5lcnMgb2YgYSByZWN0YW5nbGUgYXMgYSBjbG9zZWQgcmluZyAoY2xvY2t3aXNlIGZyb20gdG9wLWxlZnQpLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlY3RUb1JpbmcocjogUGljazxSZWN0YW5nbGUsICd4JyB8ICd5JyB8ICd3aWR0aCcgfCAnaGVpZ2h0Jz4pOiB7IHhzOiBudW1iZXJbXTsgeXM6IG51bWJlcltdIH0ge1xuICByZXR1cm4ge1xuICAgIHhzOiBbci54LCByLnggKyByLndpZHRoLCByLnggKyByLndpZHRoLCByLnhdLFxuICAgIHlzOiBbci55LCByLnksIHIueSArIHIuaGVpZ2h0LCByLnkgKyByLmhlaWdodF0sXG4gIH07XG59XG5cbi8qKiBBIGRlZXAgY29weSBvZiBhIHBvbHlnb246IHZlcnRpY2VzLCBob2xlcyBhbmQgZXZlcnkgYsOpemllciBoYW5kbGUuICovXG5leHBvcnQgZnVuY3Rpb24gY2xvbmVQb2x5Z29uKHA6IFBvbHlnb24pOiBQb2x5Z29uIHtcbiAgY29uc3QgcG9seSA9IG5ldyBQb2x5Z29uKCk7XG4gIHBvbHkubnBvaW50cyA9IHAubnBvaW50cztcbiAgcG9seS54cG9pbnRzID0gcC54cG9pbnRzLnNsaWNlKCk7XG4gIHBvbHkueXBvaW50cyA9IHAueXBvaW50cy5zbGljZSgpO1xuICBwb2x5LmNvb3JkaW5hdGVzID0gcC5jb29yZGluYXRlcy5tYXAoKGMpID0+IGMuc2xpY2UoKSk7XG4gIHBvbHkuY2xvc2VkID0gcC5jbG9zZWQ7XG4gIHBvbHkuYmV6aWVyID0gcC5iZXppZXI7XG4gIGlmIChwLmhhbmRsZXNJbikgcG9seS5oYW5kbGVzSW4gPSBwLmhhbmRsZXNJbi5tYXAoKG8pID0+IG8uc2xpY2UoKSk7XG4gIGlmIChwLmhhbmRsZXNPdXQpIHBvbHkuaGFuZGxlc091dCA9IHAuaGFuZGxlc091dC5tYXAoKG8pID0+IG8uc2xpY2UoKSk7XG4gIGlmIChwLmhvbGVzKSBwb2x5LmhvbGVzID0gcC5ob2xlcy5tYXAoKHJpbmcpID0+IHJpbmcubWFwKChwdCkgPT4gcHQuc2xpY2UoKSkpO1xuICBpZiAocC5ob2xlSGFuZGxlc0luKSBwb2x5LmhvbGVIYW5kbGVzSW4gPSBwLmhvbGVIYW5kbGVzSW4ubWFwKChyKSA9PiByLm1hcCgobykgPT4gby5zbGljZSgpKSk7XG4gIGlmIChwLmhvbGVIYW5kbGVzT3V0KSBwb2x5LmhvbGVIYW5kbGVzT3V0ID0gcC5ob2xlSGFuZGxlc091dC5tYXAoKHIpID0+IHIubWFwKChvKSA9PiBvLnNsaWNlKCkpKTtcbiAgcmV0dXJuIHBvbHk7XG59XG5cbi8qKiBBIGRlZXAgY29weSBvZiBhbnkgcmVnaW9uIGdlb21ldHJ5LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNsb25lQm91bmRzKGJvdW5kczogUmVjdGFuZ2xlIHwgUG9seWdvbiB8IE11bHRpUG9seWdvbik6IFJlY3RhbmdsZSB8IFBvbHlnb24gfCBNdWx0aVBvbHlnb24ge1xuICBpZiAoYm91bmRzIGluc3RhbmNlb2YgUmVjdGFuZ2xlKSB7XG4gICAgY29uc3QgcmVjdCA9IG5ldyBSZWN0YW5nbGUoKTtcbiAgICByZWN0LnggPSBib3VuZHMueDtcbiAgICByZWN0LnkgPSBib3VuZHMueTtcbiAgICByZWN0LndpZHRoID0gYm91bmRzLndpZHRoO1xuICAgIHJlY3QuaGVpZ2h0ID0gYm91bmRzLmhlaWdodDtcbiAgICByZXR1cm4gcmVjdDtcbiAgfVxuICBpZiAoYm91bmRzIGluc3RhbmNlb2YgTXVsdGlQb2x5Z29uKSB7XG4gICAgY29uc3QgbXAgPSBuZXcgTXVsdGlQb2x5Z29uKCk7XG4gICAgbXAucG9seWdvbnMgPSBib3VuZHMucG9seWdvbnMubWFwKChwKSA9PiBjbG9uZVBvbHlnb24ocCkpO1xuICAgIHJldHVybiBtcDtcbiAgfVxuICByZXR1cm4gY2xvbmVQb2x5Z29uKGJvdW5kcyk7XG59XG5cbi8qKlxuICogQSBjb3B5IG9mIGBleGlzdGluZ2AgKGlkLCBuYW1lLCBsYWJlbCwgY29sb3VyLCBjb2xvdXIgb3ZlcnJpZGUsIHNvdXJjZSxcbiAqIGZpbGUgbmFtZSwga2luZCwgeiwg4oCmKSB3aXRoIG5ldyBnZW9tZXRyeSBhbmQgb3B0aW9uYWwgZXh0cmEgZmllbGRzLiBVc2UgaXRcbiAqIHdoZW5ldmVyIGEgdG9vbCBlZGl0cyBhIHJlZ2lvbidzIHNoYXBlLCBzbyB0aGUgZWRpdCBuZXZlciBkcm9wcyBtZXRhZGF0YSBhbmRcbiAqIG5ldmVyIG11dGF0ZXMgdGhlIHN0b3JlJ3MgaW5zdGFuY2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXBsYWNlQm91bmRzKGV4aXN0aW5nOiBSZWdpb24sIGJvdW5kczogUmVnaW9uWydib3VuZHMnXSwgcGF0Y2g6IFBhcnRpYWw8UmVnaW9uPiA9IHt9KTogUmVnaW9uIHtcbiAgcmV0dXJuIE9iamVjdC5hc3NpZ24obmV3IFJlZ2lvbigpLCBleGlzdGluZywgcGF0Y2gsIHsgYm91bmRzIH0pO1xufVxuXG4vKiogQSBjbG9zZWQgcmluZyByb3VuZGVkIHRvIHdob2xlIHBpeGVscywgYXMgaW1hZ2UtcHJvY2Vzc2luZyBjb25zdW1lcnMgZXhwZWN0LiAqL1xuZnVuY3Rpb24gcm91bmRlZFBvbHlnb24oeHM6IG51bWJlcltdLCB5czogbnVtYmVyW10sIGhvbGVzPzogbnVtYmVyW11bXVtdKTogUG9seWdvbiB7XG4gIHJldHVybiBtYWtlUG9seWdvbih4cy5tYXAoTWF0aC5yb3VuZCksIHlzLm1hcChNYXRoLnJvdW5kKSwge1xuICAgIGhvbGVzOiBob2xlcz8ubWFwKChyaW5nKSA9PiByaW5nLm1hcCgoW3gsIHldKSA9PiBbTWF0aC5yb3VuZCh4KSwgTWF0aC5yb3VuZCh5KV0pKSxcbiAgfSk7XG59XG5cbi8qKiBBIHBvbHlnb24ncyBleHRlcmlvciBhbmQgaG9sZXMsIHdpdGggYSBiw6l6aWVyIHJlZ2lvbiBmbGF0dGVuZWQgdG8gaXRzIGN1cnZlLiAqL1xuZnVuY3Rpb24gZmxhdHRlblBvbHlnb24ocDogUG9seWdvbik6IFBvbHlnb24ge1xuICBpZiAoIXAuYmV6aWVyKSByZXR1cm4gcm91bmRlZFBvbHlnb24ocC54cG9pbnRzLCBwLnlwb2ludHMsIHAuaG9sZXMpO1xuICBjb25zdCBjbG9zZWQgPSBwLmNsb3NlZCAhPT0gZmFsc2U7XG4gIGNvbnN0IGN1cnZlID0gYmV6aWVyQ3VydmVGcm9tSGFuZGxlcyhcbiAgICBwLnhwb2ludHMsXG4gICAgcC55cG9pbnRzLFxuICAgIHJlc29sdmVIYW5kbGVzKHAueHBvaW50cywgcC55cG9pbnRzLCBjbG9zZWQsIHAuaGFuZGxlc0luLCBwLmhhbmRsZXNPdXQpLFxuICAgIGNsb3NlZCxcbiAgKTtcbiAgY29uc3QgaG9sZXMgPSBwLmhvbGVzPy5tYXAoKHJpbmcsIGgpID0+IHtcbiAgICBjb25zdCBoeCA9IHJpbmcubWFwKChwdCkgPT4gcHRbMF0pO1xuICAgIGNvbnN0IGh5ID0gcmluZy5tYXAoKHB0KSA9PiBwdFsxXSk7XG4gICAgY29uc3QgYyA9IGJlemllckN1cnZlRnJvbUhhbmRsZXMoXG4gICAgICBoeCxcbiAgICAgIGh5LFxuICAgICAgcmVzb2x2ZUhhbmRsZXMoaHgsIGh5LCB0cnVlLCBwLmhvbGVIYW5kbGVzSW4/LltoXSwgcC5ob2xlSGFuZGxlc091dD8uW2hdKSxcbiAgICAgIHRydWUsXG4gICAgKTtcbiAgICByZXR1cm4gZHJvcENsb3NpbmdQb2ludChjLnhzLCBjLnlzKS54cy5tYXAoKHgsIGkpID0+IFt4LCBjLnlzW2ldXSk7XG4gIH0pO1xuICBjb25zdCByaW5nID0gZHJvcENsb3NpbmdQb2ludChjdXJ2ZS54cywgY3VydmUueXMpO1xuICByZXR1cm4gcm91bmRlZFBvbHlnb24ocmluZy54cywgcmluZy55cywgaG9sZXMpO1xufVxuXG4vKiogQSBzYW1wbGVkIGNsb3NlZCBjdXJ2ZSByZXBlYXRzIGl0cyBmaXJzdCBwb2ludCBhdCB0aGUgZW5kOyByaW5ncyBkb24ndC4gKi9cbmZ1bmN0aW9uIGRyb3BDbG9zaW5nUG9pbnQoeHM6IG51bWJlcltdLCB5czogbnVtYmVyW10pOiB7IHhzOiBudW1iZXJbXTsgeXM6IG51bWJlcltdIH0ge1xuICBjb25zdCBuID0geHMubGVuZ3RoO1xuICBpZiAobiA+IDEgJiYgeHNbMF0gPT09IHhzW24gLSAxXSAmJiB5c1swXSA9PT0geXNbbiAtIDFdKSByZXR1cm4geyB4czogeHMuc2xpY2UoMCwgLTEpLCB5czogeXMuc2xpY2UoMCwgLTEpIH07XG4gIHJldHVybiB7IHhzLCB5cyB9O1xufVxuXG4vKipcbiAqIFRoZSBjbG9zZWQgcG9seWdvbnMgYSByZWdpb24gY292ZXJzLCBmb3IgaW1hZ2UtcHJvY2Vzc2luZyBjb25zdW1lcnMgKGNyb3AsXG4gKiBzZWdtZW50YXRpb24gcmVxdWVzdHMpOiBhIHJlY3RhbmdsZSdzIGZvdXIgY29ybmVycywgYSBjbG9zZWQgcG9seWdvbiB3aXRoIGl0c1xuICogaG9sZXMgKGEgYsOpemllciByZWdpb24gYXMgaXRzIGZsYXR0ZW5lZCBjdXJ2ZSksIG9uZSBwb2x5Z29uIHBlciBwYXJ0IG9mIGFcbiAqIG11bHRpLXBvbHlnb24uIE9wZW4gcG9seWxpbmVzIGNvdmVyIG5vIGFyZWEgYW5kIHlpZWxkIG5vdGhpbmcuIENvb3JkaW5hdGVzXG4gKiBhcmUgcm91bmRlZCB0byB3aG9sZSBwaXhlbHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdpb25Qb2x5Z29ucyhyZWdpb246IFJlZ2lvbik6IFBvbHlnb25bXSB7XG4gIGNvbnN0IGIgPSByZWdpb24uYm91bmRzO1xuICBpZiAoYiBpbnN0YW5jZW9mIFJlY3RhbmdsZSkge1xuICAgIC8vIEJvdHRvbS1sZWZ0IGZpcnN0LCBhcyB0aGUgcHJldmlvdXMgUGxvdGx5LXNoYXBlIHByb2plY3Rpb24gcHJvZHVjZWQuXG4gICAgcmV0dXJuIFtyb3VuZGVkUG9seWdvbihbYi54LCBiLnggKyBiLndpZHRoLCBiLnggKyBiLndpZHRoLCBiLnhdLCBbYi55ICsgYi5oZWlnaHQsIGIueSArIGIuaGVpZ2h0LCBiLnksIGIueV0pXTtcbiAgfVxuICBpZiAoYiBpbnN0YW5jZW9mIFBvbHlnb24pIHJldHVybiBiLmNsb3NlZCA9PT0gZmFsc2UgPyBbXSA6IFtmbGF0dGVuUG9seWdvbihiKV07XG4gIGlmIChiIGluc3RhbmNlb2YgTXVsdGlQb2x5Z29uKSByZXR1cm4gYi5wb2x5Z29ucy5maWx0ZXIoKHApID0+IHAuY2xvc2VkICE9PSBmYWxzZSkubWFwKGZsYXR0ZW5Qb2x5Z29uKTtcbiAgcmV0dXJuIFtdO1xufVxuXG4vKipcbiAqIFRoZSBvcGVuIHBvbHlsaW5lcyBhIHJlZ2lvbiB0cmFjZXMgKGEgcG9seWxpbmUsIG9yIGEgbXVsdGktcG9seWdvbidzIG9wZW4gcGFydHMpLCBhcyBpbnRlcmxlYXZlZFxuICogYHgsIHlgIGltYWdlIHB4OyBhIGLDqXppZXIgcG9seWxpbmUgYXMgaXRzIGZsYXR0ZW5lZCBjdXJ2ZS4gQ2xvc2VkIHNoYXBlcyB5aWVsZCBub3RoaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVnaW9uUG9seWxpbmVzKHJlZ2lvbjogUmVnaW9uKTogRmxvYXQ2NEFycmF5W10ge1xuICBjb25zdCBiID0gcmVnaW9uLmJvdW5kcztcbiAgY29uc3QgcGFydHMgPSBiIGluc3RhbmNlb2YgUG9seWdvbiA/IFtiXSA6IGIgaW5zdGFuY2VvZiBNdWx0aVBvbHlnb24gPyBiLnBvbHlnb25zIDogW107XG4gIHJldHVybiBwYXJ0c1xuICAgIC5maWx0ZXIoKHApID0+IHAuY2xvc2VkID09PSBmYWxzZSAmJiBwLnhwb2ludHMubGVuZ3RoID49IDIpXG4gICAgLm1hcCgocCkgPT4ge1xuICAgICAgY29uc3QgeyB4cywgeXMgfSA9IHAuYmV6aWVyXG4gICAgICAgID8gYmV6aWVyQ3VydmVGcm9tSGFuZGxlcyhcbiAgICAgICAgICAgIHAueHBvaW50cyxcbiAgICAgICAgICAgIHAueXBvaW50cyxcbiAgICAgICAgICAgIHJlc29sdmVIYW5kbGVzKHAueHBvaW50cywgcC55cG9pbnRzLCBmYWxzZSwgcC5oYW5kbGVzSW4sIHAuaGFuZGxlc091dCksXG4gICAgICAgICAgICBmYWxzZSxcbiAgICAgICAgICApXG4gICAgICAgIDogeyB4czogcC54cG9pbnRzLCB5czogcC55cG9pbnRzIH07XG4gICAgICByZXR1cm4gRmxvYXQ2NEFycmF5LmZyb20oeHMuZmxhdE1hcCgoeCwgaSkgPT4gW3gsIHlzW2ldXSkpO1xuICAgIH0pO1xufVxuIl19
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { MultiPolygon, Polygon, Rectangle, Region } from './region';
|
|
2
|
+
/**
|
|
3
|
+
* Copy-on-write region copies and geometry equality (RT-13). Stored regions
|
|
4
|
+
* are shared with the undo history, so a change is always a copy; these
|
|
5
|
+
* helpers return the input unchanged when the patch would not change it.
|
|
6
|
+
* (Deep geometry copies are `cloneBounds` / `clonePolygon` in `polygon-factory`.)
|
|
7
|
+
*/
|
|
8
|
+
/** A shallow copy of `r` with `patch` applied; `r` itself is never changed. */
|
|
9
|
+
export function withRegionPatch(r, patch) {
|
|
10
|
+
return Object.assign(new Region(), r, patch);
|
|
11
|
+
}
|
|
12
|
+
/** `r` tagged with slice `z`: itself when it already is, else a copy. */
|
|
13
|
+
export function withRegionZ(r, z) {
|
|
14
|
+
return r.z === z ? r : withRegionPatch(r, { z });
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* True when two regions have the same geometry: equal rectangles, or polygons
|
|
18
|
+
* (each part of a multi-polygon, in order) with the same vertices, open/closed
|
|
19
|
+
* state and holes. Bézier handles, labels and colours are not compared. Mixed
|
|
20
|
+
* kinds are never equal.
|
|
21
|
+
*/
|
|
22
|
+
export function regionsEqual(a, b) {
|
|
23
|
+
const ba = a.bounds, bb = b.bounds;
|
|
24
|
+
if (ba instanceof Rectangle && bb instanceof Rectangle) {
|
|
25
|
+
return ba.x === bb.x && ba.y === bb.y && ba.width === bb.width && ba.height === bb.height;
|
|
26
|
+
}
|
|
27
|
+
if (ba instanceof MultiPolygon && bb instanceof MultiPolygon) {
|
|
28
|
+
if (ba.polygons.length !== bb.polygons.length)
|
|
29
|
+
return false;
|
|
30
|
+
for (let i = 0; i < ba.polygons.length; i++) {
|
|
31
|
+
if (!polygonsEqual(ba.polygons[i], bb.polygons[i]))
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
return true;
|
|
35
|
+
}
|
|
36
|
+
if (ba instanceof Polygon && bb instanceof Polygon) {
|
|
37
|
+
return polygonsEqual(ba, bb);
|
|
38
|
+
}
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
/** Same vertices, open/closed state and holes (see {@link regionsEqual}). */
|
|
42
|
+
export function polygonsEqual(pa, pb) {
|
|
43
|
+
if ((pa.closed !== false) !== (pb.closed !== false))
|
|
44
|
+
return false;
|
|
45
|
+
if (pa.xpoints.length !== pb.xpoints.length)
|
|
46
|
+
return false;
|
|
47
|
+
for (let i = 0; i < pa.xpoints.length; i++) {
|
|
48
|
+
if (pa.xpoints[i] !== pb.xpoints[i] || pa.ypoints[i] !== pb.ypoints[i])
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
return holesEqual(pa.holes, pb.holes);
|
|
52
|
+
}
|
|
53
|
+
function holesEqual(a, b) {
|
|
54
|
+
const na = a?.length ?? 0, nb = b?.length ?? 0;
|
|
55
|
+
if (na !== nb)
|
|
56
|
+
return false;
|
|
57
|
+
for (let h = 0; h < na; h++) {
|
|
58
|
+
const ra = a[h], rb = b[h];
|
|
59
|
+
if (ra.length !== rb.length)
|
|
60
|
+
return false;
|
|
61
|
+
for (let i = 0; i < ra.length; i++) {
|
|
62
|
+
if (ra[i][0] !== rb[i][0] || ra[i][1] !== rb[i][1])
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVnaW9uLWNsb25lLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2xpYi9tb2RlbHMvcmVnaW9uLWNsb25lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFFcEU7Ozs7O0dBS0c7QUFFSCwrRUFBK0U7QUFDL0UsTUFBTSxVQUFVLGVBQWUsQ0FBQyxDQUFTLEVBQUUsS0FBc0I7SUFDL0QsT0FBTyxNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksTUFBTSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQy9DLENBQUM7QUFFRCx5RUFBeUU7QUFDekUsTUFBTSxVQUFVLFdBQVcsQ0FBQyxDQUFTLEVBQUUsQ0FBUztJQUM5QyxPQUFPLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0FBQ25ELENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxZQUFZLENBQUMsQ0FBUyxFQUFFLENBQVM7SUFDL0MsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFDakIsRUFBRSxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUM7SUFDaEIsSUFBSSxFQUFFLFlBQVksU0FBUyxJQUFJLEVBQUUsWUFBWSxTQUFTLEVBQUUsQ0FBQztRQUN2RCxPQUFPLEVBQUUsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLEtBQUssS0FBSyxFQUFFLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQyxNQUFNLEtBQUssRUFBRSxDQUFDLE1BQU0sQ0FBQztJQUM1RixD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QUFLLENBQUM7UUFDbkUsQ0FBQztJQUNILENBQUM7SUFDRCxPQUFPLElBQUksQ0FBQztBQUNkLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBNdWx0aVBvbHlnb24sIFBvbHlnb24sIFJlY3RhbmdsZSwgUmVnaW9uIH0gZnJvbSAnLi9yZWdpb24nO1xuXG4vKipcbiAqIENvcHktb24td3JpdGUgcmVnaW9uIGNvcGllcyBhbmQgZ2VvbWV0cnkgZXF1YWxpdHkgKFJULTEzKS4gU3RvcmVkIHJlZ2lvbnNcbiAqIGFyZSBzaGFyZWQgd2l0aCB0aGUgdW5kbyBoaXN0b3J5LCBzbyBhIGNoYW5nZSBpcyBhbHdheXMgYSBjb3B5OyB0aGVzZVxuICogaGVscGVycyByZXR1cm4gdGhlIGlucHV0IHVuY2hhbmdlZCB3aGVuIHRoZSBwYXRjaCB3b3VsZCBub3QgY2hhbmdlIGl0LlxuICogKERlZXAgZ2VvbWV0cnkgY29waWVzIGFyZSBgY2xvbmVCb3VuZHNgIC8gYGNsb25lUG9seWdvbmAgaW4gYHBvbHlnb24tZmFjdG9yeWAuKVxuICovXG5cbi8qKiBBIHNoYWxsb3cgY29weSBvZiBgcmAgd2l0aCBgcGF0Y2hgIGFwcGxpZWQ7IGByYCBpdHNlbGYgaXMgbmV2ZXIgY2hhbmdlZC4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3aXRoUmVnaW9uUGF0Y2gocjogUmVnaW9uLCBwYXRjaDogUGFydGlhbDxSZWdpb24+KTogUmVnaW9uIHtcbiAgcmV0dXJuIE9iamVjdC5hc3NpZ24obmV3IFJlZ2lvbigpLCByLCBwYXRjaCk7XG59XG5cbi8qKiBgcmAgdGFnZ2VkIHdpdGggc2xpY2UgYHpgOiBpdHNlbGYgd2hlbiBpdCBhbHJlYWR5IGlzLCBlbHNlIGEgY29weS4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3aXRoUmVnaW9uWihyOiBSZWdpb24sIHo6IG51bWJlcik6IFJlZ2lvbiB7XG4gIHJldHVybiByLnogPT09IHogPyByIDogd2l0aFJlZ2lvblBhdGNoKHIsIHsgeiB9KTtcbn1cblxuLyoqXG4gKiBUcnVlIHdoZW4gdHdvIHJlZ2lvbnMgaGF2ZSB0aGUgc2FtZSBnZW9tZXRyeTogZXF1YWwgcmVjdGFuZ2xlcywgb3IgcG9seWdvbnNcbiAqIChlYWNoIHBhcnQgb2YgYSBtdWx0aS1wb2x5Z29uLCBpbiBvcmRlcikgd2l0aCB0aGUgc2FtZSB2ZXJ0aWNlcywgb3Blbi9jbG9zZWRcbiAqIHN0YXRlIGFuZCBob2xlcy4gQsOpemllciBoYW5kbGVzLCBsYWJlbHMgYW5kIGNvbG91cnMgYXJlIG5vdCBjb21wYXJlZC4gTWl4ZWRcbiAqIGtpbmRzIGFyZSBuZXZlciBlcXVhbC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlZ2lvbnNFcXVhbChhOiBSZWdpb24sIGI6IFJlZ2lvbik6IGJvb2xlYW4ge1xuICBjb25zdCBiYSA9IGEuYm91bmRzLFxuICAgIGJiID0gYi5ib3VuZHM7XG4gIGlmIChiYSBpbnN0YW5jZW9mIFJlY3RhbmdsZSAmJiBiYiBpbnN0YW5jZW9mIFJlY3RhbmdsZSkge1xuICAgIHJldHVybiBiYS54ID09PSBiYi54ICYmIGJhLnkgPT09IGJiLnkgJiYgYmEud2lkdGggPT09IGJiLndpZHRoICYmIGJhLmhlaWdodCA9PT0gYmIuaGVpZ2h0O1xuICB9XG4gIGlmIChiYSBpbnN0YW5jZW9mIE11bHRpUG9seWdvbiAmJiBiYiBpbnN0YW5jZW9mIE11bHRpUG9seWdvbikge1xuICAgIGlmIChiYS5wb2x5Z29ucy5sZW5ndGggIT09IGJiLnBvbHlnb25zLmxlbmd0aCkgcmV0dXJuIGZhbHNlO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYmEucG9seWdvbnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmICghcG9seWdvbnNFcXVhbChiYS5wb2x5Z29uc1tpXSwgYmIucG9seWdvbnNbaV0pKSByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIGlmIChiYSBpbnN0YW5jZW9mIFBvbHlnb24gJiYgYmIgaW5zdGFuY2VvZiBQb2x5Z29uKSB7XG4gICAgcmV0dXJuIHBvbHlnb25zRXF1YWwoYmEsIGJiKTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKiBTYW1lIHZlcnRpY2VzLCBvcGVuL2Nsb3NlZCBzdGF0ZSBhbmQgaG9sZXMgKHNlZSB7QGxpbmsgcmVnaW9uc0VxdWFsfSkuICovXG5leHBvcnQgZnVuY3Rpb24gcG9seWdvbnNFcXVhbChwYTogUG9seWdvbiwgcGI6IFBvbHlnb24pOiBib29sZWFuIHtcbiAgaWYgKChwYS5jbG9zZWQgIT09IGZhbHNlKSAhPT0gKHBiLmNsb3NlZCAhPT0gZmFsc2UpKSByZXR1cm4gZmFsc2U7XG4gIGlmIChwYS54cG9pbnRzLmxlbmd0aCAhPT0gcGIueHBvaW50cy5sZW5ndGgpIHJldHVybiBmYWxzZTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBwYS54cG9pbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKHBhLnhwb2ludHNbaV0gIT09IHBiLnhwb2ludHNbaV0gfHwgcGEueXBvaW50c1tpXSAhPT0gcGIueXBvaW50c1tpXSkgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiBob2xlc0VxdWFsKHBhLmhvbGVzLCBwYi5ob2xlcyk7XG59XG5cbmZ1bmN0aW9uIGhvbGVzRXF1YWwoYTogbnVtYmVyW11bXVtdIHwgdW5kZWZpbmVkLCBiOiBudW1iZXJbXVtdW10gfCB1bmRlZmluZWQpOiBib29sZWFuIHtcbiAgY29uc3QgbmEgPSBhPy5sZW5ndGggPz8gMCxcbiAgICBuYiA9IGI/Lmxlbmd0aCA/PyAwO1xuICBpZiAobmEgIT09IG5iKSByZXR1cm4gZmFsc2U7XG4gIGZvciAobGV0IGggPSAwOyBoIDwgbmE7IGgrKykge1xuICAgIGNvbnN0IHJhID0gKGEgYXMgbnVtYmVyW11bXVtdKVtoXSxcbiAgICAgIHJiID0gKGIgYXMgbnVtYmVyW11bXVtdKVtoXTtcbiAgICBpZiAocmEubGVuZ3RoICE9PSByYi5sZW5ndGgpIHJldHVybiBmYWxzZTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJhLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAocmFbaV1bMF0gIT09IHJiW2ldWzBdIHx8IHJhW2ldWzFdICE9PSByYltpXVsxXSkgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cbiJdfQ==
|