@jax-data-science/sci-image-visualizer 0.8.3 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +201 -460
- package/esm2022/index.mjs +28 -15
- package/esm2022/lib/channel-histogram/channel-histogram.component.mjs +163 -91
- package/esm2022/lib/contracts/capabilities.contract.mjs +4 -3
- package/esm2022/lib/contracts/cell-segmenter.contract.mjs +1 -1
- package/esm2022/lib/contracts/channel-histogram-api.contract.mjs +5 -1
- package/esm2022/lib/contracts/color.mjs +60 -0
- package/esm2022/lib/contracts/colormap-lut.mjs +213 -57
- package/esm2022/lib/contracts/coordinate-transform.contract.mjs +1 -1
- package/esm2022/lib/contracts/display-types.mjs +11 -1
- package/esm2022/lib/contracts/instance-segmenter.contract.mjs +1 -1
- package/esm2022/lib/contracts/intensity.mjs +48 -5
- package/esm2022/lib/contracts/plot-type-contribution.contract.mjs +1 -1
- package/esm2022/lib/contracts/plot-type.mjs +134 -17
- package/esm2022/lib/contracts/ports/image-state.port.mjs +4 -1
- package/esm2022/lib/contracts/ports/preferences.port.mjs +5 -1
- package/esm2022/lib/contracts/ports/region-io.port.mjs +2 -1
- package/esm2022/lib/contracts/ports/spatial-data.port.mjs +5 -1
- package/esm2022/lib/contracts/ports/tile-access.port.mjs +2 -1
- package/esm2022/lib/contracts/region-editor-api.contract.mjs +1 -1
- package/esm2022/lib/contracts/region-overlay.contract.mjs +1 -1
- package/esm2022/lib/contracts/sam.contract.mjs +1 -1
- package/esm2022/lib/contracts/semantic-segmenter.contract.mjs +1 -1
- package/esm2022/lib/contracts/spatial-dataset.contract.mjs +3 -1
- package/esm2022/lib/contracts/toolbar-tool.contract.mjs +6 -4
- package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
- package/esm2022/lib/contracts/viz-config.mjs +2 -1
- package/esm2022/lib/geometry/contour.mjs +63 -0
- package/esm2022/lib/geometry/raster.mjs +98 -0
- package/esm2022/lib/geometry/ring.mjs +201 -0
- package/esm2022/lib/hex-color-picker/hex-color-picker.component.mjs +202 -102
- package/esm2022/lib/implementations/base-store-visualizer.mjs +201 -48
- package/esm2022/lib/implementations/napari-js/napari-axes-gizmo.mjs +65 -0
- package/esm2022/lib/implementations/napari-js/napari-display-state.mjs +136 -0
- package/esm2022/lib/implementations/napari-js/napari-helpers.mjs +199 -0
- package/esm2022/lib/implementations/napari-js/napari-image-2d-scene.mjs +602 -0
- package/esm2022/lib/implementations/napari-js/napari-loading-badge.mjs +3 -4
- package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +66 -0
- package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +157 -591
- package/esm2022/lib/implementations/napari-js/napari-scene.mjs +2 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-2d-scene.mjs +614 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-3d-scene.mjs +769 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-encoding.mjs +199 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +263 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-scene.mjs +159 -0
- package/esm2022/lib/implementations/napari-js/napari-spatial-tiles.mjs +106 -1408
- package/esm2022/lib/implementations/napari-js/napari-spatial-tooltip.mjs +2 -2
- package/esm2022/lib/implementations/napari-js/napari-surface-scene.mjs +271 -0
- package/esm2022/lib/implementations/napari-js/napari-tile-client.mjs +562 -0
- package/esm2022/lib/implementations/napari-js/napari-tool-bridge.mjs +344 -0
- package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +358 -4218
- package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +439 -0
- package/esm2022/lib/implementations/napari-js/napari-volume-z-handle.mjs +6 -6
- package/esm2022/lib/implementations/napari-js/region-overlay/overlay-projection.mjs +96 -0
- package/esm2022/lib/implementations/napari-js/region-overlay/region-edit.mjs +35 -0
- package/esm2022/lib/implementations/napari-js/region-overlay/region-svg-renderer.mjs +182 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/categorical-lookup.mjs +30 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/cell-layers.mjs +274 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/density-layer.mjs +144 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/layer-groups.mjs +165 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/plan-context.mjs +78 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-hover.mjs +182 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-jobs.mjs +369 -0
- package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-layers.mjs +306 -0
- package/esm2022/lib/implementations/osd/display-pipeline.mjs +102 -40
- package/esm2022/lib/implementations/osd/histogram-sampler.mjs +56 -31
- package/esm2022/lib/implementations/osd/openseadragon-viewer-options.mjs +128 -0
- package/esm2022/lib/implementations/osd/openseadragon-visualizer.service.mjs +333 -1685
- package/esm2022/lib/implementations/osd/osd-coordinate-transform.mjs +1 -1
- package/esm2022/lib/implementations/osd/osd-coords.mjs +5 -6
- package/esm2022/lib/implementations/osd/osd-export.mjs +122 -0
- package/esm2022/lib/implementations/osd/osd-lib.mjs +15 -1
- package/esm2022/lib/implementations/osd/osd-navigator-chrome.mjs +205 -0
- package/esm2022/lib/implementations/osd/osd-pixel-readback.mjs +68 -0
- package/esm2022/lib/implementations/osd/osd-region-overlay-draw.mjs +153 -0
- package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +185 -718
- package/esm2022/lib/implementations/osd/osd-scale-bar.mjs +52 -60
- package/esm2022/lib/implementations/osd/osd-tile-source.mjs +105 -0
- package/esm2022/lib/implementations/osd/osd-viewer-like.mjs +2 -0
- package/esm2022/lib/implementations/osd/osd-viewer-mount.mjs +44 -0
- package/esm2022/lib/implementations/osd/osd-viewport.mjs +184 -0
- package/esm2022/lib/implementations/osd/osd-zoom.mjs +7 -1
- package/esm2022/lib/implementations/osd/simple-source.mjs +395 -0
- package/esm2022/lib/implementations/osd/slice-cache.mjs +53 -48
- package/esm2022/lib/implementations/osd/tile-client.mjs +32 -11
- package/esm2022/lib/implementations/osd/tile-recolor.mjs +330 -0
- package/esm2022/lib/implementations/plotly/omics-trace-builders.mjs +161 -73
- package/esm2022/lib/implementations/plotly/plotly-coordinate-transform.mjs +1 -1
- package/esm2022/lib/implementations/plotly/plotly-image-loader.mjs +112 -0
- package/esm2022/lib/implementations/plotly/plotly-image-recolor.mjs +178 -0
- package/esm2022/lib/implementations/plotly/plotly-intensity-inset.mjs +33 -0
- package/esm2022/lib/implementations/plotly/plotly-isosurface-controls.mjs +83 -0
- package/esm2022/lib/implementations/plotly/plotly-layouts.mjs +121 -0
- package/esm2022/lib/implementations/plotly/plotly-readback.mjs +117 -0
- package/esm2022/lib/implementations/plotly/plotly-region-overlay.mjs +19 -10
- package/esm2022/lib/implementations/plotly/plotly-shape-projection.mjs +223 -0
- package/esm2022/lib/implementations/plotly/plotly-trace-builders.mjs +79 -19
- package/esm2022/lib/implementations/plotly/plotly-zoom-controller.mjs +223 -0
- package/esm2022/lib/implementations/plotly/plotly.service.mjs +439 -1655
- package/esm2022/lib/implementations/region-centroids.mjs +47 -0
- package/esm2022/lib/implementations/simple-slice-access.service.mjs +22 -12
- package/esm2022/lib/implementations/spatial-data-http/spatial-data-http.service.mjs +172 -92
- package/esm2022/lib/implementations/spatial-data-http/spatial-wire.mjs +103 -22
- package/esm2022/lib/implementations/tile-server/index.mjs +6 -0
- package/esm2022/lib/implementations/tile-server/native-histogram.mjs +30 -0
- package/esm2022/lib/implementations/tile-server/poll-descriptor.mjs +65 -0
- package/esm2022/lib/implementations/tile-server/tile-protocol.mjs +42 -0
- package/esm2022/lib/implementations/tile-server/transport.mjs +135 -0
- package/esm2022/lib/intensity/intensity-profile.mjs +107 -0
- package/esm2022/lib/intensity/intensity-profile.service.mjs +223 -0
- package/esm2022/lib/intensity-inset/intensity-inset.component.mjs +133 -0
- package/esm2022/lib/models/bezier.mjs +1 -11
- package/esm2022/lib/models/class-preset.mjs +41 -3
- package/esm2022/lib/models/geometry.mjs +27 -164
- package/esm2022/lib/models/polygon-edit.mjs +254 -0
- package/esm2022/lib/models/polygon-factory.mjs +118 -0
- package/esm2022/lib/models/region-clone.mjs +68 -0
- package/esm2022/lib/models/region-geojson.mjs +373 -0
- package/esm2022/lib/models/region.mjs +34 -33
- package/esm2022/lib/models/shape.mjs +18 -16
- package/esm2022/lib/plot-mode/contribution-host.mjs +297 -0
- package/esm2022/lib/plot-mode/plot-mode-controller.mjs +9 -6
- package/esm2022/lib/plot-mode/plot-type-menu.mjs +85 -0
- package/esm2022/lib/plot-mode/tool-params-model.mjs +87 -0
- package/esm2022/lib/plot.utilities.mjs +296 -473
- package/esm2022/lib/processing/image-crop.mjs +1 -1
- package/esm2022/lib/processing/processing-image.mjs +28 -15
- package/esm2022/lib/provide-visualization.mjs +40 -14
- package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +99 -0
- package/esm2022/lib/region-editor/file-stem.mjs +13 -0
- package/esm2022/lib/region-editor/manage-classes-dialog/manage-classes-dialog.component.mjs +118 -0
- package/esm2022/lib/region-editor/mask-export.service.mjs +98 -0
- package/esm2022/lib/region-editor/mask-raster.mjs +11 -5
- package/esm2022/lib/region-editor/region-color-dialog/region-color-dialog.component.mjs +56 -0
- package/esm2022/lib/region-editor/region-editor-help/region-editor-help.component.mjs +28 -0
- package/esm2022/lib/region-editor/region-editor.component.mjs +402 -651
- package/esm2022/lib/region-editor/region-metrics.mjs +68 -0
- package/esm2022/lib/region-editor/region-persistence.service.mjs +134 -0
- package/esm2022/lib/region-editor/region-table/region-table.component.mjs +153 -0
- package/esm2022/lib/region-editor/save-mask-dialog/save-mask-dialog.component.mjs +91 -0
- package/esm2022/lib/region-editor/save-regions-dialog/save-regions-dialog.component.mjs +92 -0
- package/esm2022/lib/region-ops.service.mjs +28 -70
- package/esm2022/lib/region-overlay/region-geometry.mjs +360 -0
- package/esm2022/lib/region-overlay/region-hit-test.mjs +103 -0
- package/esm2022/lib/region-overlay/svg-region-renderer.mjs +228 -0
- package/esm2022/lib/render-orchestrator.mjs +14 -11
- package/esm2022/lib/render-session.mjs +207 -0
- package/esm2022/lib/routing-visualizer.service.mjs +459 -411
- package/esm2022/lib/spatial/density-raster.mjs +14 -0
- package/esm2022/lib/spatial/embedding-compute-coordinator.mjs +239 -0
- package/esm2022/lib/spatial/embedding-compute.mjs +43 -10
- package/esm2022/lib/spatial/gene-search.mjs +1 -1
- package/esm2022/lib/spatial/glyphs.mjs +97 -0
- package/esm2022/lib/spatial/lod.mjs +187 -0
- package/esm2022/lib/spatial/spatial-controls.facade.mjs +200 -0
- package/esm2022/lib/spatial/spatial-density.mjs +25 -16
- package/esm2022/lib/spatial/spatial-encoding.mjs +26 -82
- package/esm2022/lib/spatial/spatial-expression.mjs +43 -42
- package/esm2022/lib/spatial/spatial-framing.mjs +1 -1
- package/esm2022/lib/spatial/spatial-heatmap.mjs +6 -3
- package/esm2022/lib/spatial/spatial-hover.mjs +5 -33
- package/esm2022/lib/spatial/spatial-panel-model.mjs +282 -0
- package/esm2022/lib/spatial/spatial-sections.mjs +1 -1
- package/esm2022/lib/spatial/spatial-selection.mjs +33 -46
- package/esm2022/lib/spatial/spatial-tile-merge.mjs +219 -0
- package/esm2022/lib/spatial/spatial-tiles.mjs +12 -648
- package/esm2022/lib/spatial/spatial-volume-image.mjs +2 -4
- package/esm2022/lib/spatial/stats.mjs +71 -0
- package/esm2022/lib/spatial/transcript-grouping.mjs +307 -0
- package/esm2022/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.mjs +150 -0
- package/esm2022/lib/spatial-controls/spatial-charts/chart-data-model.mjs +309 -0
- package/esm2022/lib/spatial-controls/spatial-charts/chart-help.mjs +145 -0
- package/esm2022/lib/spatial-controls/spatial-charts/plotly-chart-host.mjs +158 -0
- package/esm2022/lib/spatial-controls/spatial-charts/spatial-chart-window/spatial-chart-window.component.mjs +47 -0
- package/esm2022/lib/spatial-controls/spatial-charts/spatial-charts.component.mjs +297 -802
- package/esm2022/lib/spatial-controls/spatial-charts/spatial-embedding-controls/spatial-embedding-controls.component.mjs +89 -0
- package/esm2022/lib/spatial-controls/spatial-charts/spatial-heatmap-controls/spatial-heatmap-controls.component.mjs +52 -0
- package/esm2022/lib/spatial-controls/spatial-controls.component.mjs +143 -1238
- package/esm2022/lib/spatial-controls/spatial-gene-picker.mjs +153 -0
- package/esm2022/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.mjs +241 -0
- package/esm2022/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.mjs +193 -0
- package/esm2022/lib/spatial-controls/spatial-key/spatial-key.component.mjs +132 -0
- package/esm2022/lib/spatial-controls/spatial-key/spatial-key.model.mjs +67 -0
- package/esm2022/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.mjs +147 -0
- package/esm2022/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.mjs +300 -0
- package/esm2022/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.mjs +370 -0
- package/esm2022/lib/store/class-color.util.mjs +46 -3
- package/esm2022/lib/store/region-history.mjs +146 -0
- package/esm2022/lib/store/region-scope-cache.mjs +140 -0
- package/esm2022/lib/store/region-selection.mjs +82 -0
- package/esm2022/lib/store/region-store.service.mjs +279 -675
- package/esm2022/lib/store/spatial-selection.service.mjs +2 -2
- package/esm2022/lib/store/visualizer-store.service.mjs +49 -71
- package/esm2022/lib/toast-outlets.mjs +5 -4
- package/esm2022/lib/toolbar/brush/brush-tool.service.mjs +92 -434
- package/esm2022/lib/toolbar/canvas-tools.mjs +20 -0
- package/esm2022/lib/toolbar/crop/slide-crop.mjs +26 -42
- package/esm2022/lib/toolbar/plot-type-selector/plot-type-selector.component.mjs +85 -0
- package/esm2022/lib/toolbar/region-tools/region-tool-buttons.mjs +74 -0
- package/esm2022/lib/toolbar/region-tools/region-tools.component.mjs +114 -0
- package/esm2022/lib/toolbar/segmentation/cell-segment-tool.service.mjs +74 -78
- package/esm2022/lib/toolbar/segmentation/cellpose-segmenter.service.mjs +50 -8
- package/esm2022/lib/toolbar/segmentation/onnx-sam-session.mjs +61 -42
- package/esm2022/lib/toolbar/segmentation/pending-calls.mjs +47 -0
- package/esm2022/lib/toolbar/segmentation/sam-model-registry.mjs +12 -4
- package/esm2022/lib/toolbar/segmentation/sam-onnx-core.mjs +70 -14
- package/esm2022/lib/toolbar/segmentation/sam-point-tool.service.mjs +135 -172
- package/esm2022/lib/toolbar/segmentation/sam-prompt.mjs +9 -90
- package/esm2022/lib/toolbar/segmentation/sam-session.service.mjs +183 -0
- package/esm2022/lib/toolbar/segmentation/sam-tool.service.mjs +95 -150
- package/esm2022/lib/toolbar/segmentation/segmentation-commit.mjs +12 -0
- package/esm2022/lib/toolbar/segmentation/segmentation-runner.mjs +108 -0
- package/esm2022/lib/toolbar/segmentation-tools/segmentation-tools.component.mjs +155 -0
- package/esm2022/lib/toolbar/stack-controls/stack-controls.component.mjs +81 -0
- package/esm2022/lib/toolbar/tool-kit/async-tool-status.mjs +37 -0
- package/esm2022/lib/toolbar/tool-kit/canvas-tool-manager.mjs +63 -0
- package/esm2022/lib/toolbar/tool-kit/canvas-tool.mjs +2 -0
- package/esm2022/lib/toolbar/tool-kit/frame-pixels.mjs +108 -0
- package/esm2022/lib/toolbar/tool-kit/mask-stroke-editor.mjs +306 -0
- package/esm2022/lib/toolbar/tool-kit/matrix-frame.mjs +61 -0
- package/esm2022/lib/toolbar/tool-kit/tool-overlay.mjs +140 -0
- package/esm2022/lib/toolbar/tool-kit/undo-gesture.mjs +24 -0
- package/esm2022/lib/toolbar/tool-slider/tool-slider.component.mjs +63 -0
- package/esm2022/lib/toolbar/toolbar-help-dialog/toolbar-help-dialog.component.mjs +50 -0
- package/esm2022/lib/toolbar/toolbar.component.mjs +68 -117
- package/esm2022/lib/toolbar/vertex-eraser/vertex-eraser-tool.service.mjs +93 -115
- package/esm2022/lib/toolbar/view-controls/view-controls.component.mjs +107 -0
- package/esm2022/lib/toolbar/wand/wand-region-grow.mjs +321 -0
- package/esm2022/lib/toolbar/wand/wand-tool.service.mjs +121 -416
- package/esm2022/lib/toolbar/wand/wand.service.mjs +30 -894
- package/esm2022/lib/toolbar/zoom-to-box/zoom-to-box-tool.service.mjs +48 -90
- package/esm2022/lib/util/mark-for-check.mjs +17 -0
- package/esm2022/lib/util/supersede.mjs +56 -0
- package/esm2022/lib/visualization.module.mjs +39 -141
- package/esm2022/lib/visualizer/floating-drag.directive.mjs +58 -0
- package/esm2022/lib/visualizer/region-actions.mjs +149 -0
- package/esm2022/lib/visualizer/region-load.mjs +60 -0
- package/esm2022/lib/visualizer/spatial-dataset-binder.mjs +163 -0
- package/esm2022/lib/visualizer/tool-modes.mjs +113 -0
- package/esm2022/lib/visualizer/viewer-shortcuts.mjs +167 -0
- package/esm2022/lib/visualizer/visualizer-context-menu.mjs +119 -0
- package/esm2022/lib/visualizer.component.mjs +480 -1902
- package/esm2022/lib/workers/spatial-math-ops.mjs +43 -0
- package/esm2022/lib/workers/spatial-math-worker.mjs +10 -0
- package/esm2022/lib/workers/spatial-math.mjs +190 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs +41083 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs +238 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-spatial-math-worker-BzVFFqGS.mjs +12 -0
- package/fesm2022/jax-data-science-sci-image-visualizer-spatial-math-worker-BzVFFqGS.mjs.map +1 -0
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs +41 -34467
- package/fesm2022/jax-data-science-sci-image-visualizer.mjs.map +1 -1
- package/fesm2022/mask.worker.js +36 -917
- package/fesm2022/onnx-sam.worker.js +52 -16
- package/fesm2022/spatial-math.worker.js +471 -0
- package/fesm2022/tsne.worker.js +32 -15
- package/index.d.ts +13 -10
- package/lib/channel-histogram/channel-histogram.component.d.ts +53 -43
- package/lib/contracts/capabilities.contract.d.ts +4 -2
- package/lib/contracts/cell-segmenter.contract.d.ts +1 -0
- package/lib/contracts/channel-histogram-api.contract.d.ts +4 -0
- package/lib/contracts/color.d.ts +27 -0
- package/lib/contracts/colormap-lut.d.ts +19 -4
- package/lib/contracts/coordinate-transform.contract.d.ts +3 -3
- package/lib/contracts/display-types.d.ts +21 -0
- package/lib/contracts/instance-segmenter.contract.d.ts +5 -0
- package/lib/contracts/intensity.d.ts +13 -2
- package/lib/contracts/plot-type.d.ts +3 -1
- package/lib/contracts/ports/image-state.port.d.ts +6 -2
- package/lib/contracts/ports/preferences.port.d.ts +4 -0
- package/lib/contracts/ports/region-io.port.d.ts +1 -0
- package/lib/contracts/ports/spatial-data.port.d.ts +4 -10
- package/lib/contracts/ports/tile-access.port.d.ts +1 -0
- package/lib/contracts/region-editor-api.contract.d.ts +1 -1
- package/lib/contracts/region-overlay.contract.d.ts +5 -0
- package/lib/contracts/sam.contract.d.ts +7 -0
- package/lib/contracts/semantic-segmenter.contract.d.ts +6 -0
- package/lib/contracts/spatial-dataset.contract.d.ts +19 -6
- package/lib/contracts/toolbar-tool.contract.d.ts +1 -0
- package/lib/contracts/visualizer.contract.d.ts +221 -54
- package/lib/contracts/viz-config.d.ts +1 -0
- package/lib/geometry/contour.d.ts +24 -0
- package/lib/geometry/raster.d.ts +42 -0
- package/lib/geometry/ring.d.ts +67 -0
- package/lib/hex-color-picker/hex-color-picker.component.d.ts +61 -27
- package/lib/implementations/base-store-visualizer.d.ts +61 -15
- package/lib/implementations/napari-js/napari-axes-gizmo.d.ts +36 -0
- package/lib/implementations/napari-js/napari-display-state.d.ts +76 -0
- package/lib/implementations/napari-js/napari-helpers.d.ts +129 -0
- package/lib/implementations/napari-js/napari-image-2d-scene.d.ts +162 -0
- package/lib/implementations/napari-js/napari-loading-badge.d.ts +0 -1
- package/lib/implementations/napari-js/napari-loading-state.d.ts +30 -0
- package/lib/implementations/napari-js/napari-region-overlay.d.ts +62 -70
- package/lib/implementations/napari-js/napari-scene.d.ts +93 -0
- package/lib/implementations/napari-js/napari-spatial-2d-scene.d.ts +163 -0
- package/lib/implementations/napari-js/napari-spatial-3d-scene.d.ts +212 -0
- package/lib/implementations/napari-js/napari-spatial-encoding.d.ts +114 -0
- package/lib/implementations/napari-js/napari-spatial-hover.d.ts +89 -0
- package/lib/implementations/napari-js/napari-spatial-scene.d.ts +118 -0
- package/lib/implementations/napari-js/napari-spatial-tiles.d.ts +56 -263
- package/lib/implementations/napari-js/napari-spatial-tooltip.d.ts +1 -1
- package/lib/implementations/napari-js/napari-surface-scene.d.ts +76 -0
- package/lib/implementations/napari-js/napari-tile-client.d.ts +214 -0
- package/lib/implementations/napari-js/napari-tool-bridge.d.ts +179 -0
- package/lib/implementations/napari-js/napari-visualizer.service.d.ts +121 -883
- package/lib/implementations/napari-js/napari-volume-scene.d.ts +104 -0
- package/lib/implementations/napari-js/napari-volume-z-handle.d.ts +8 -12
- package/lib/implementations/napari-js/region-overlay/overlay-projection.d.ts +59 -0
- package/lib/implementations/napari-js/region-overlay/region-edit.d.ts +15 -0
- package/lib/implementations/napari-js/region-overlay/region-svg-renderer.d.ts +54 -0
- package/lib/implementations/napari-js/spatial-tiles/categorical-lookup.d.ts +26 -0
- package/lib/implementations/napari-js/spatial-tiles/cell-layers.d.ts +70 -0
- package/lib/implementations/napari-js/spatial-tiles/density-layer.d.ts +61 -0
- package/lib/implementations/napari-js/spatial-tiles/layer-groups.d.ts +67 -0
- package/lib/implementations/napari-js/spatial-tiles/plan-context.d.ts +38 -0
- package/lib/implementations/napari-js/spatial-tiles/transcript-hover.d.ts +71 -0
- package/lib/implementations/napari-js/spatial-tiles/transcript-jobs.d.ts +105 -0
- package/lib/implementations/napari-js/spatial-tiles/transcript-layers.d.ts +56 -0
- package/lib/implementations/osd/display-pipeline.d.ts +38 -9
- package/lib/implementations/osd/histogram-sampler.d.ts +22 -12
- package/lib/implementations/osd/openseadragon-viewer-options.d.ts +35 -0
- package/lib/implementations/osd/openseadragon-visualizer.service.d.ts +78 -354
- package/lib/implementations/osd/osd-coordinate-transform.d.ts +2 -1
- package/lib/implementations/osd/osd-coords.d.ts +6 -4
- package/lib/implementations/osd/osd-export.d.ts +36 -0
- package/lib/implementations/osd/osd-lib.d.ts +7 -0
- package/lib/implementations/osd/osd-navigator-chrome.d.ts +69 -0
- package/lib/implementations/osd/osd-pixel-readback.d.ts +22 -0
- package/lib/implementations/osd/osd-region-overlay-draw.d.ts +37 -0
- package/lib/implementations/osd/osd-region-overlay.d.ts +36 -48
- package/lib/implementations/osd/osd-scale-bar.d.ts +8 -6
- package/lib/implementations/osd/osd-tile-source.d.ts +49 -0
- package/lib/implementations/osd/osd-viewer-like.d.ts +100 -0
- package/lib/implementations/osd/osd-viewer-mount.d.ts +14 -0
- package/lib/implementations/osd/osd-viewport.d.ts +77 -0
- package/lib/implementations/osd/osd-zoom.d.ts +6 -0
- package/lib/implementations/osd/simple-source.d.ts +161 -0
- package/lib/implementations/osd/slice-cache.d.ts +12 -3
- package/lib/implementations/osd/tile-client.d.ts +11 -14
- package/lib/implementations/osd/tile-recolor.d.ts +141 -0
- package/lib/implementations/plotly/omics-trace-builders.d.ts +32 -20
- package/lib/implementations/plotly/plotly-image-loader.d.ts +49 -0
- package/lib/implementations/plotly/plotly-image-recolor.d.ts +75 -0
- package/lib/implementations/plotly/plotly-intensity-inset.d.ts +8 -0
- package/lib/implementations/plotly/plotly-isosurface-controls.d.ts +38 -0
- package/lib/implementations/plotly/plotly-layouts.d.ts +188 -0
- package/lib/implementations/plotly/plotly-readback.d.ts +41 -0
- package/lib/implementations/plotly/plotly-region-overlay.d.ts +2 -2
- package/lib/implementations/plotly/plotly-shape-projection.d.ts +92 -0
- package/lib/implementations/plotly/plotly-trace-builders.d.ts +23 -12
- package/lib/implementations/plotly/plotly-zoom-controller.d.ts +86 -0
- package/lib/implementations/plotly/plotly.service.d.ts +136 -401
- package/lib/implementations/region-centroids.d.ts +14 -0
- package/lib/implementations/simple-slice-access.service.d.ts +7 -4
- package/lib/implementations/spatial-data-http/spatial-data-http.service.d.ts +42 -18
- package/lib/implementations/spatial-data-http/spatial-wire.d.ts +34 -9
- package/lib/implementations/tile-server/index.d.ts +5 -0
- package/lib/implementations/tile-server/native-histogram.d.ts +25 -0
- package/lib/implementations/tile-server/poll-descriptor.d.ts +39 -0
- package/lib/implementations/tile-server/tile-protocol.d.ts +80 -0
- package/lib/implementations/tile-server/transport.d.ts +62 -0
- package/lib/intensity/intensity-profile.d.ts +66 -0
- package/lib/intensity/intensity-profile.service.d.ts +108 -0
- package/lib/intensity-inset/intensity-inset.component.d.ts +58 -0
- package/lib/models/bezier.d.ts +0 -5
- package/lib/models/class-preset.d.ts +18 -0
- package/lib/models/geometry.d.ts +14 -48
- package/lib/models/polygon-edit.d.ts +72 -0
- package/lib/models/polygon-factory.d.ts +40 -0
- package/lib/models/region-clone.d.ts +20 -0
- package/lib/models/region-geojson.d.ts +17 -0
- package/lib/models/region.d.ts +40 -4
- package/lib/models/shape.d.ts +8 -0
- package/lib/plot-mode/contribution-host.d.ts +125 -0
- package/lib/plot-mode/plot-type-menu.d.ts +60 -0
- package/lib/plot-mode/tool-params-model.d.ts +49 -0
- package/lib/plot.utilities.d.ts +19 -30
- package/lib/processing/processing-image.d.ts +5 -2
- package/lib/provide-visualization.d.ts +19 -2
- package/lib/region-editor/classes-panel/classes-panel.component.d.ts +56 -0
- package/lib/region-editor/file-stem.d.ts +7 -0
- package/lib/region-editor/manage-classes-dialog/manage-classes-dialog.component.d.ts +45 -0
- package/lib/region-editor/mask-export.service.d.ts +54 -0
- package/lib/region-editor/mask-raster.d.ts +2 -8
- package/lib/region-editor/region-color-dialog/region-color-dialog.component.d.ts +29 -0
- package/lib/region-editor/region-editor-help/region-editor-help.component.d.ts +11 -0
- package/lib/region-editor/region-editor.component.d.ts +166 -199
- package/lib/region-editor/region-metrics.d.ts +26 -0
- package/lib/region-editor/region-persistence.service.d.ts +69 -0
- package/lib/region-editor/region-table/region-table.component.d.ts +83 -0
- package/lib/region-editor/save-mask-dialog/save-mask-dialog.component.d.ts +36 -0
- package/lib/region-editor/save-regions-dialog/save-regions-dialog.component.d.ts +37 -0
- package/lib/region-ops.service.d.ts +1 -7
- package/lib/region-overlay/region-geometry.d.ts +157 -0
- package/lib/region-overlay/region-hit-test.d.ts +38 -0
- package/lib/region-overlay/svg-region-renderer.d.ts +110 -0
- package/lib/render-orchestrator.d.ts +6 -2
- package/lib/render-session.d.ts +75 -0
- package/lib/routing-visualizer.service.d.ts +110 -58
- package/lib/spatial/density-raster.d.ts +6 -0
- package/lib/spatial/embedding-compute-coordinator.d.ts +123 -0
- package/lib/spatial/embedding-compute.d.ts +21 -2
- package/lib/spatial/glyphs.d.ts +16 -0
- package/lib/spatial/lod.d.ts +94 -0
- package/lib/spatial/spatial-controls.facade.d.ts +64 -0
- package/lib/spatial/spatial-density.d.ts +15 -5
- package/lib/spatial/spatial-encoding.d.ts +11 -44
- package/lib/spatial/spatial-expression.d.ts +40 -22
- package/lib/spatial/spatial-framing.d.ts +1 -0
- package/lib/spatial/spatial-heatmap.d.ts +2 -0
- package/lib/spatial/spatial-hover.d.ts +4 -16
- package/lib/spatial/spatial-panel-model.d.ts +135 -0
- package/lib/spatial/spatial-selection.d.ts +21 -26
- package/lib/spatial/spatial-tile-merge.d.ts +41 -0
- package/lib/spatial/spatial-tiles.d.ts +9 -256
- package/lib/spatial/stats.d.ts +38 -0
- package/lib/spatial/transcript-grouping.d.ts +119 -0
- package/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.d.ts +64 -0
- package/lib/spatial-controls/spatial-charts/chart-data-model.d.ts +153 -0
- package/lib/spatial-controls/spatial-charts/chart-help.d.ts +69 -0
- package/lib/spatial-controls/spatial-charts/plotly-chart-host.d.ts +98 -0
- package/lib/spatial-controls/spatial-charts/spatial-chart-window/spatial-chart-window.component.d.ts +26 -0
- package/lib/spatial-controls/spatial-charts/spatial-charts.component.d.ts +101 -260
- package/lib/spatial-controls/spatial-charts/spatial-embedding-controls/spatial-embedding-controls.component.d.ts +43 -0
- package/lib/spatial-controls/spatial-charts/spatial-heatmap-controls/spatial-heatmap-controls.component.d.ts +27 -0
- package/lib/spatial-controls/spatial-controls.component.d.ts +68 -448
- package/lib/spatial-controls/spatial-gene-picker.d.ts +86 -0
- package/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.d.ts +102 -0
- package/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.d.ts +72 -0
- package/lib/spatial-controls/spatial-key/spatial-key.component.d.ts +66 -0
- package/lib/spatial-controls/spatial-key/spatial-key.model.d.ts +33 -0
- package/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.d.ts +64 -0
- package/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.d.ts +117 -0
- package/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.d.ts +142 -0
- package/lib/store/class-color.util.d.ts +35 -1
- package/lib/store/region-history.d.ts +66 -0
- package/lib/store/region-scope-cache.d.ts +63 -0
- package/lib/store/region-selection.d.ts +36 -0
- package/lib/store/region-store.service.d.ts +104 -112
- package/lib/store/visualizer-store.service.d.ts +22 -33
- package/lib/toast-outlets.d.ts +4 -3
- package/lib/toolbar/brush/brush-tool.service.d.ts +31 -98
- package/lib/toolbar/canvas-tools.d.ts +20 -0
- package/lib/toolbar/crop/slide-crop.d.ts +10 -4
- package/lib/toolbar/plot-type-selector/plot-type-selector.component.d.ts +38 -0
- package/lib/toolbar/region-tools/region-tool-buttons.d.ts +21 -0
- package/lib/toolbar/region-tools/region-tools.component.d.ts +60 -0
- package/lib/toolbar/segmentation/cell-segment-tool.service.d.ts +10 -14
- package/lib/toolbar/segmentation/cellpose-segmenter.service.d.ts +12 -2
- package/lib/toolbar/segmentation/onnx-sam-session.d.ts +22 -3
- package/lib/toolbar/segmentation/pending-calls.d.ts +31 -0
- package/lib/toolbar/segmentation/sam-model-registry.d.ts +9 -3
- package/lib/toolbar/segmentation/sam-onnx-core.d.ts +18 -5
- package/lib/toolbar/segmentation/sam-point-tool.service.d.ts +46 -32
- package/lib/toolbar/segmentation/sam-prompt.d.ts +7 -31
- package/lib/toolbar/segmentation/sam-session.service.d.ts +74 -0
- package/lib/toolbar/segmentation/sam-tool.service.d.ts +23 -30
- package/lib/toolbar/segmentation/segmentation-commit.d.ts +8 -0
- package/lib/toolbar/segmentation/segmentation-runner.d.ts +52 -0
- package/lib/toolbar/segmentation-tools/segmentation-tools.component.d.ts +87 -0
- package/lib/toolbar/stack-controls/stack-controls.component.d.ts +40 -0
- package/lib/toolbar/tool-kit/async-tool-status.d.ts +21 -0
- package/lib/toolbar/tool-kit/canvas-tool-manager.d.ts +36 -0
- package/lib/toolbar/tool-kit/canvas-tool.d.ts +86 -0
- package/lib/toolbar/tool-kit/frame-pixels.d.ts +45 -0
- package/lib/toolbar/tool-kit/mask-stroke-editor.d.ts +125 -0
- package/lib/toolbar/tool-kit/matrix-frame.d.ts +40 -0
- package/lib/toolbar/tool-kit/tool-overlay.d.ts +60 -0
- package/lib/toolbar/tool-kit/undo-gesture.d.ts +17 -0
- package/lib/toolbar/tool-slider/tool-slider.component.d.ts +33 -0
- package/lib/toolbar/toolbar-help-dialog/toolbar-help-dialog.component.d.ts +24 -0
- package/lib/toolbar/toolbar.component.d.ts +47 -83
- package/lib/toolbar/vertex-eraser/vertex-eraser-tool.service.d.ts +33 -40
- package/lib/toolbar/view-controls/view-controls.component.d.ts +54 -0
- package/lib/toolbar/wand/wand-region-grow.d.ts +49 -0
- package/lib/toolbar/wand/wand-tool.service.d.ts +39 -124
- package/lib/toolbar/wand/wand.service.d.ts +22 -116
- package/lib/toolbar/zoom-to-box/zoom-to-box-tool.service.d.ts +17 -37
- package/lib/util/mark-for-check.d.ts +11 -0
- package/lib/util/supersede.d.ts +53 -0
- package/lib/visualization.module.d.ts +18 -39
- package/lib/visualizer/floating-drag.directive.d.ts +30 -0
- package/lib/visualizer/region-actions.d.ts +54 -0
- package/lib/visualizer/region-load.d.ts +27 -0
- package/lib/visualizer/spatial-dataset-binder.d.ts +74 -0
- package/lib/visualizer/tool-modes.d.ts +49 -0
- package/lib/visualizer/viewer-shortcuts.d.ts +71 -0
- package/lib/visualizer/visualizer-context-menu.d.ts +55 -0
- package/lib/visualizer.component.d.ts +201 -447
- package/lib/workers/spatial-math-ops.d.ts +65 -0
- package/lib/workers/spatial-math-worker.d.ts +7 -0
- package/lib/workers/spatial-math.d.ts +74 -0
- package/package.json +12 -3
- package/src/lib/styles/_viz-icons-rules.scss +73 -0
- package/src/lib/styles/viz-icons.scss +14 -0
- package/esm2022/lib/implementations/napari-js/napari-axes-labels.mjs +0 -97
- package/esm2022/lib/implementations/napari-js/napari-navigator.mjs +0 -195
- package/esm2022/lib/implementations/napari-js/napari-scale-bar.mjs +0 -92
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-BwP-A11m.mjs +0 -329
- package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-BwP-A11m.mjs.map +0 -1
- package/lib/implementations/napari-js/napari-axes-labels.d.ts +0 -49
- package/lib/implementations/napari-js/napari-navigator.d.ts +0 -72
- package/lib/implementations/napari-js/napari-scale-bar.d.ts +0 -35
- package/src/lib/assets/cell-detection.svg +0 -37
- package/src/lib/assets/click.svg +0 -1
- package/src/lib/assets/colormap-luts.json +0 -1
- package/src/lib/assets/edit-selection-white.svg +0 -47
- package/src/lib/assets/icons/colormap-earth.png +0 -0
- package/src/lib/assets/icons/colormap-placeholder.png +0 -0
- package/src/lib/assets/icons/colormap-pubu.png +0 -0
- package/src/lib/assets/interactive-segmentation-cursor.svg +0 -1
- package/src/lib/assets/picture-segmentation.svg +0 -43
- package/src/lib/assets/test/download-379.svg +0 -1
- package/src/lib/assets/test/download-98.svg +0 -1
- package/src/lib/assets/test/json-1.svg +0 -1
- package/src/lib/assets/test/load-53.svg +0 -1
- package/src/lib/assets/test/mask-44.svg +0 -1
- package/src/lib/assets/test/mask-download-44.svg +0 -15
- package/src/lib/assets/test/mask-save-44.svg +0 -11
- package/src/lib/assets/test/overlay-1.svg +0 -1
- package/src/lib/assets/test/overlay-4.svg +0 -1
- package/src/lib/assets/test/region-26.svg +0 -1
- package/src/lib/assets/test/save-56.svg +0 -1
- package/src/lib/assets/test/upload-43.svg +0 -1
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
import { floodFill } from 'napari-js/geometry';
|
|
2
|
+
import { maskToPolygons } from '../../geometry/contour';
|
|
3
|
+
import { bt601Luminance } from '../../contracts/intensity';
|
|
4
|
+
import { framePixels, isPackedFrame } from '../tool-kit/frame-pixels';
|
|
5
|
+
const DEFAULT_PATCH_SIZE = 149;
|
|
6
|
+
const DEFAULT_SIGMA = 4.0;
|
|
7
|
+
const DEFAULT_SENSITIVITY = 2.0;
|
|
8
|
+
/**
|
|
9
|
+
* Grow a region from a click and trace it.
|
|
10
|
+
*
|
|
11
|
+
* @param image full-image pixel matrix (already in memory).
|
|
12
|
+
* @param cx click x in image-pixel coordinates.
|
|
13
|
+
* @param cy click y in image-pixel coordinates.
|
|
14
|
+
* @param options wand parameters; missing fields fall back to defaults.
|
|
15
|
+
* @returns a Polygon in image-pixel coordinates, or null if no region grew.
|
|
16
|
+
*/
|
|
17
|
+
export function computeWandRegion(image, cx, cy, options = {}) {
|
|
18
|
+
const patch = computeWandPatchMask(image, cx, cy, options);
|
|
19
|
+
if (!patch)
|
|
20
|
+
return null;
|
|
21
|
+
// The largest traced piece (with holes of 4+ px, as the tools trace); single pixels still count.
|
|
22
|
+
return (maskToPolygons(patch.mask, patch.size, patch.size, Math.floor(cx) - (patch.size - 1) / 2, Math.floor(cy) - (patch.size - 1) / 2, 1, 4)[0] ?? null);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* The wand's per-click flood-fill mask in patch-local coordinates: the same
|
|
26
|
+
* pipeline as {@link computeWandRegion}, stopping before contour tracing (the
|
|
27
|
+
* tools accumulate per-tick masks across a brush-style stroke).
|
|
28
|
+
*
|
|
29
|
+
* @throws when `options.patchSize` is even.
|
|
30
|
+
*/
|
|
31
|
+
export function computeWandPatchMask(image, cx, cy, options = {}) {
|
|
32
|
+
const W = options.patchSize ?? DEFAULT_PATCH_SIZE;
|
|
33
|
+
if (W % 2 === 0) {
|
|
34
|
+
throw new Error(`patchSize must be odd, got ${W}`);
|
|
35
|
+
}
|
|
36
|
+
const sigma = options.sigma ?? DEFAULT_SIGMA;
|
|
37
|
+
const sensitivity = options.sensitivity ?? DEFAULT_SENSITIVITY;
|
|
38
|
+
const isGrayscale = image.isGrayscale;
|
|
39
|
+
const type = options.type ?? (isGrayscale ? 'GRAY' : 'RGB');
|
|
40
|
+
const simple = !!options.simpleMode;
|
|
41
|
+
// extractPatch always interleaves 1 channel for GRAY, 3 for RGB/LAB_DISTANCE.
|
|
42
|
+
const inputChannels = type === 'GRAY' ? 1 : 3;
|
|
43
|
+
let buf = extractPatch(image, cx, cy, W, type);
|
|
44
|
+
// Flood fill operates on whatever buffer we end up with: the raw patch in
|
|
45
|
+
// simple mode (so multi-channel exact-match), the blurred patch for
|
|
46
|
+
// GRAY/RGB, or the single-channel CIELAB distance map for LAB_DISTANCE.
|
|
47
|
+
let floodChannels;
|
|
48
|
+
let threshold;
|
|
49
|
+
if (simple) {
|
|
50
|
+
// Skip blur + threshold computation. Flood-fill the raw patch at
|
|
51
|
+
// exact-match per channel — same as QuPath's doSimpleSelection.
|
|
52
|
+
floodChannels = inputChannels;
|
|
53
|
+
threshold = new Array(floodChannels).fill(0);
|
|
54
|
+
}
|
|
55
|
+
else {
|
|
56
|
+
const blurSigma = Math.max(0.5, sigma);
|
|
57
|
+
buf = gaussianBlur(buf, W, inputChannels, blurSigma);
|
|
58
|
+
if (type === 'LAB_DISTANCE') {
|
|
59
|
+
// Convert blurred 3-channel patch to a single-channel distance map,
|
|
60
|
+
// then flood-fill on that single channel.
|
|
61
|
+
const distance = labDistanceMap(buf, W);
|
|
62
|
+
const max = distance.max > 0 ? distance.max : 1;
|
|
63
|
+
const scaled = new Float32Array(W * W);
|
|
64
|
+
for (let i = 0; i < scaled.length; i++)
|
|
65
|
+
scaled[i] = (distance.values[i] * 255.0) / max;
|
|
66
|
+
buf = scaled;
|
|
67
|
+
floodChannels = 1;
|
|
68
|
+
threshold = [(distance.mean * sensitivity * 255.0) / max];
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
floodChannels = inputChannels;
|
|
72
|
+
threshold = perChannelThreshold(buf, W, inputChannels, sensitivity);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// Fixed-range flood fill from the patch centre (napari-js's fill bucket): a pixel is taken
|
|
76
|
+
// when every channel is within its threshold of the SEED's, 4-connected.
|
|
77
|
+
const centre = (W - 1) / 2;
|
|
78
|
+
const mask = floodFill({ data: buf, width: W, height: W }, centre, centre, {
|
|
79
|
+
channels: floodChannels,
|
|
80
|
+
tolerance: threshold,
|
|
81
|
+
});
|
|
82
|
+
const closed = simple ? mask : morphClose(mask, W, 5);
|
|
83
|
+
return { mask: closed, size: W };
|
|
84
|
+
}
|
|
85
|
+
// ── Patch extraction ────────────────────────────────────────────────
|
|
86
|
+
function extractPatch(image, cx, cy, W, type) {
|
|
87
|
+
const channels = type === 'GRAY' ? 1 : 3;
|
|
88
|
+
const half = (W - 1) / 2;
|
|
89
|
+
// The patch centres on the pixel under the click: pixel x covers [x, x + 1) on every backend.
|
|
90
|
+
const x0 = Math.floor(cx) - half;
|
|
91
|
+
const y0 = Math.floor(cy) - half;
|
|
92
|
+
const buf = new Float32Array(W * W * channels);
|
|
93
|
+
const pixels = framePixels(image.data, image.isGrayscale);
|
|
94
|
+
// A grayscale nested frame reads as (v, v, v): its value is rgb[0].
|
|
95
|
+
const gray = image.isGrayscale && !isPackedFrame(image.data);
|
|
96
|
+
const rgb = [0, 0, 0];
|
|
97
|
+
for (let py = 0; py < W; py++) {
|
|
98
|
+
const iy = y0 + py;
|
|
99
|
+
if (iy < 0 || iy >= image.height)
|
|
100
|
+
continue;
|
|
101
|
+
for (let px = 0; px < W; px++) {
|
|
102
|
+
const ix = x0 + px;
|
|
103
|
+
if (ix < 0 || ix >= image.width)
|
|
104
|
+
continue;
|
|
105
|
+
if (!pixels.rgb(ix, iy, rgb))
|
|
106
|
+
continue;
|
|
107
|
+
const dst = (py * W + px) * channels;
|
|
108
|
+
if (gray) {
|
|
109
|
+
const v = rgb[0];
|
|
110
|
+
if (channels === 1) {
|
|
111
|
+
buf[dst] = v;
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
buf[dst] = v;
|
|
115
|
+
buf[dst + 1] = v;
|
|
116
|
+
buf[dst + 2] = v;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
else if (channels === 1) {
|
|
120
|
+
// GRAY type forced on RGB image: convert with luminance.
|
|
121
|
+
buf[dst] = bt601Luminance(rgb[0], rgb[1], rgb[2]);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
buf[dst] = rgb[0];
|
|
125
|
+
buf[dst + 1] = rgb[1];
|
|
126
|
+
buf[dst + 2] = rgb[2];
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
return buf;
|
|
131
|
+
}
|
|
132
|
+
// ── Gaussian blur (separable) ───────────────────────────────────────
|
|
133
|
+
function gaussianBlur(buf, W, channels, sigma) {
|
|
134
|
+
const radius = Math.max(1, Math.ceil(sigma * 2));
|
|
135
|
+
const size = radius * 2 + 1;
|
|
136
|
+
const kernel = new Float32Array(size);
|
|
137
|
+
let sum = 0;
|
|
138
|
+
const inv2s2 = 1 / (2 * sigma * sigma);
|
|
139
|
+
for (let i = 0; i < size; i++) {
|
|
140
|
+
const x = i - radius;
|
|
141
|
+
kernel[i] = Math.exp(-x * x * inv2s2);
|
|
142
|
+
sum += kernel[i];
|
|
143
|
+
}
|
|
144
|
+
for (let i = 0; i < size; i++)
|
|
145
|
+
kernel[i] /= sum;
|
|
146
|
+
const horiz = new Float32Array(buf.length);
|
|
147
|
+
// Horizontal pass.
|
|
148
|
+
for (let y = 0; y < W; y++) {
|
|
149
|
+
for (let x = 0; x < W; x++) {
|
|
150
|
+
for (let c = 0; c < channels; c++) {
|
|
151
|
+
let acc = 0;
|
|
152
|
+
for (let k = 0; k < size; k++) {
|
|
153
|
+
let xx = x + k - radius;
|
|
154
|
+
if (xx < 0)
|
|
155
|
+
xx = 0;
|
|
156
|
+
else if (xx >= W)
|
|
157
|
+
xx = W - 1;
|
|
158
|
+
acc += kernel[k] * buf[(y * W + xx) * channels + c];
|
|
159
|
+
}
|
|
160
|
+
horiz[(y * W + x) * channels + c] = acc;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
const out = new Float32Array(buf.length);
|
|
165
|
+
// Vertical pass.
|
|
166
|
+
for (let y = 0; y < W; y++) {
|
|
167
|
+
for (let x = 0; x < W; x++) {
|
|
168
|
+
for (let c = 0; c < channels; c++) {
|
|
169
|
+
let acc = 0;
|
|
170
|
+
for (let k = 0; k < size; k++) {
|
|
171
|
+
let yy = y + k - radius;
|
|
172
|
+
if (yy < 0)
|
|
173
|
+
yy = 0;
|
|
174
|
+
else if (yy >= W)
|
|
175
|
+
yy = W - 1;
|
|
176
|
+
acc += kernel[k] * horiz[(yy * W + x) * channels + c];
|
|
177
|
+
}
|
|
178
|
+
out[(y * W + x) * channels + c] = acc;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return out;
|
|
183
|
+
}
|
|
184
|
+
// ── Threshold computation ───────────────────────────────────────────
|
|
185
|
+
function perChannelThreshold(buf, W, channels, sensitivity) {
|
|
186
|
+
const n = W * W;
|
|
187
|
+
const sums = new Array(channels).fill(0);
|
|
188
|
+
const sqs = new Array(channels).fill(0);
|
|
189
|
+
for (let i = 0; i < n; i++) {
|
|
190
|
+
for (let c = 0; c < channels; c++) {
|
|
191
|
+
const v = buf[i * channels + c];
|
|
192
|
+
sums[c] += v;
|
|
193
|
+
sqs[c] += v * v;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
const scale = sensitivity > 0 ? 1 / sensitivity : 100;
|
|
197
|
+
const threshold = new Array(channels);
|
|
198
|
+
for (let c = 0; c < channels; c++) {
|
|
199
|
+
const mean = sums[c] / n;
|
|
200
|
+
const variance = Math.max(0, sqs[c] / n - mean * mean);
|
|
201
|
+
const stddev = Math.sqrt(variance);
|
|
202
|
+
threshold[c] = stddev * scale;
|
|
203
|
+
}
|
|
204
|
+
return threshold;
|
|
205
|
+
}
|
|
206
|
+
function labDistanceMap(buf, W) {
|
|
207
|
+
const n = W * W;
|
|
208
|
+
const lab = new Float32Array(n * 3);
|
|
209
|
+
for (let i = 0; i < n; i++) {
|
|
210
|
+
const r = buf[i * 3] / 255;
|
|
211
|
+
const g = buf[i * 3 + 1] / 255;
|
|
212
|
+
const b = buf[i * 3 + 2] / 255;
|
|
213
|
+
const [L, A, B] = srgbToLab(r, g, b);
|
|
214
|
+
lab[i * 3] = L;
|
|
215
|
+
lab[i * 3 + 1] = A;
|
|
216
|
+
lab[i * 3 + 2] = B;
|
|
217
|
+
}
|
|
218
|
+
const mid = Math.floor(n / 2);
|
|
219
|
+
const cL = lab[mid * 3];
|
|
220
|
+
const cA = lab[mid * 3 + 1];
|
|
221
|
+
const cB = lab[mid * 3 + 2];
|
|
222
|
+
const values = new Float32Array(n);
|
|
223
|
+
let max = 0;
|
|
224
|
+
let sum = 0;
|
|
225
|
+
for (let i = 0; i < n; i++) {
|
|
226
|
+
const dL = lab[i * 3] - cL;
|
|
227
|
+
const dA = lab[i * 3 + 1] - cA;
|
|
228
|
+
const dB = lab[i * 3 + 2] - cB;
|
|
229
|
+
const d = Math.sqrt(dL * dL + dA * dA + dB * dB);
|
|
230
|
+
values[i] = d;
|
|
231
|
+
if (d > max)
|
|
232
|
+
max = d;
|
|
233
|
+
sum += d;
|
|
234
|
+
}
|
|
235
|
+
return { values, mean: sum / n, max };
|
|
236
|
+
}
|
|
237
|
+
// ── Morphological close (dilate then erode) ─────────────────────────
|
|
238
|
+
function morphClose(mask, W, kernelSize) {
|
|
239
|
+
const r = (kernelSize - 1) / 2;
|
|
240
|
+
const dil = dilate(mask, W, r);
|
|
241
|
+
return erode(dil, W, r);
|
|
242
|
+
}
|
|
243
|
+
function dilate(mask, W, r) {
|
|
244
|
+
const out = new Uint8Array(W * W);
|
|
245
|
+
for (let y = 0; y < W; y++) {
|
|
246
|
+
for (let x = 0; x < W; x++) {
|
|
247
|
+
let hit = 0;
|
|
248
|
+
for (let dy = -r; dy <= r && !hit; dy++) {
|
|
249
|
+
const yy = y + dy;
|
|
250
|
+
if (yy < 0 || yy >= W)
|
|
251
|
+
continue;
|
|
252
|
+
for (let dx = -r; dx <= r; dx++) {
|
|
253
|
+
const xx = x + dx;
|
|
254
|
+
if (xx < 0 || xx >= W)
|
|
255
|
+
continue;
|
|
256
|
+
if (mask[yy * W + xx]) {
|
|
257
|
+
hit = 1;
|
|
258
|
+
break;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
out[y * W + x] = hit;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
return out;
|
|
266
|
+
}
|
|
267
|
+
function erode(mask, W, r) {
|
|
268
|
+
const out = new Uint8Array(W * W);
|
|
269
|
+
for (let y = 0; y < W; y++) {
|
|
270
|
+
for (let x = 0; x < W; x++) {
|
|
271
|
+
let all = 1;
|
|
272
|
+
for (let dy = -r; dy <= r && all; dy++) {
|
|
273
|
+
const yy = y + dy;
|
|
274
|
+
if (yy < 0 || yy >= W) {
|
|
275
|
+
all = 0;
|
|
276
|
+
break;
|
|
277
|
+
}
|
|
278
|
+
for (let dx = -r; dx <= r; dx++) {
|
|
279
|
+
const xx = x + dx;
|
|
280
|
+
if (xx < 0 || xx >= W) {
|
|
281
|
+
all = 0;
|
|
282
|
+
break;
|
|
283
|
+
}
|
|
284
|
+
if (!mask[yy * W + xx]) {
|
|
285
|
+
all = 0;
|
|
286
|
+
break;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
out[y * W + x] = all;
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return out;
|
|
294
|
+
}
|
|
295
|
+
// ── sRGB → CIELAB (D65) ───────────────────────────────────────────────
|
|
296
|
+
function srgbToLinear(c) {
|
|
297
|
+
return c <= 0.04045 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4);
|
|
298
|
+
}
|
|
299
|
+
function srgbToLab(r, g, b) {
|
|
300
|
+
const R = srgbToLinear(r);
|
|
301
|
+
const G = srgbToLinear(g);
|
|
302
|
+
const B = srgbToLinear(b);
|
|
303
|
+
// sRGB → XYZ (D65)
|
|
304
|
+
const X = R * 0.4124564 + G * 0.3575761 + B * 0.1804375;
|
|
305
|
+
const Y = R * 0.2126729 + G * 0.7151522 + B * 0.072175;
|
|
306
|
+
const Z = R * 0.0193339 + G * 0.119192 + B * 0.9503041;
|
|
307
|
+
// Reference white (D65)
|
|
308
|
+
const Xn = 0.95047, Yn = 1.0, Zn = 1.08883;
|
|
309
|
+
const fx = labF(X / Xn);
|
|
310
|
+
const fy = labF(Y / Yn);
|
|
311
|
+
const fz = labF(Z / Zn);
|
|
312
|
+
const L = 116 * fy - 16;
|
|
313
|
+
const A = 500 * (fx - fy);
|
|
314
|
+
const Bv = 200 * (fy - fz);
|
|
315
|
+
return [L, A, Bv];
|
|
316
|
+
}
|
|
317
|
+
function labF(t) {
|
|
318
|
+
const d = 6 / 29;
|
|
319
|
+
return t > d * d * d ? Math.cbrt(t) : t / (3 * d * d) + 4 / 29;
|
|
320
|
+
}
|
|
321
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2FuZC1yZWdpb24tZ3Jvdy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvdG9vbGJhci93YW5kL3dhbmQtcmVnaW9uLWdyb3cudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBRy9DLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUV4RCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDM0QsT0FBTyxFQUFlLFdBQVcsRUFBRSxhQUFhLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQWtDbkYsTUFBTSxrQkFBa0IsR0FBRyxHQUFHLENBQUM7QUFDL0IsTUFBTSxhQUFhLEdBQUcsR0FBRyxDQUFDO0FBQzFCLE1BQU0sbUJBQW1CLEdBQUcsR0FBRyxDQUFDO0FBRWhDOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxVQUFVLGlCQUFpQixDQUMvQixLQUFnQixFQUNoQixFQUFVLEVBQ1YsRUFBVSxFQUNWLFVBQXVCLEVBQUU7SUFFekIsTUFBTSxLQUFLLEdBQUcsb0JBQW9CLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDM0QsSUFBSSxDQUFDLEtBQUs7UUFBRSxPQUFPLElBQUksQ0FBQztJQUN4QixpR0FBaUc7SUFDakcsT0FBTyxDQUNMLGNBQWMsQ0FDWixLQUFLLENBQUMsSUFBSSxFQUNWLEtBQUssQ0FBQyxJQUFJLEVBQ1YsS0FBSyxDQUFDLElBQUksRUFDVixJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLElBQUksR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQ3JDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxHQUFHLENB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RUFBRSxDQUFDLENBQUM7SUFDeEIsTUFBTSxDQUFDLEdBQUcsR0FBRyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7SUFDeEIsTUFBTSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO0lBQzFCLE1BQU0sRUFBRSxHQUFHLEdBQUcsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztJQUMzQixPQUFPLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztBQUNwQixDQUFDO0FBRUQsU0FBUyxJQUFJLENBQUMsQ0FBUztJQUNyQixNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQ2pCLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUM7QUFDakUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGZsb29kRmlsbCB9IGZyb20gJ25hcGFyaS1qcy9nZW9tZXRyeSc7XG5cbmltcG9ydCB7IFBvbHlnb24gfSBmcm9tICcuLi8uLi9tb2RlbHMvcmVnaW9uJztcbmltcG9ydCB7IG1hc2tUb1BvbHlnb25zIH0gZnJvbSAnLi4vLi4vZ2VvbWV0cnkvY29udG91cic7XG5pbXBvcnQgeyBJV2FuZE9wdGlvbnMsIFdhbmRUeXBlIH0gZnJvbSAnLi4vLi4vY29udHJhY3RzL2Rpc3BsYXktdHlwZXMnO1xuaW1wb3J0IHsgYnQ2MDFMdW1pbmFuY2UgfSBmcm9tICcuLi8uLi9jb250cmFjdHMvaW50ZW5zaXR5JztcbmltcG9ydCB7IENhY2hlZEZyYW1lLCBmcmFtZVBpeGVscywgaXNQYWNrZWRGcmFtZSB9IGZyb20gJy4uL3Rvb2wta2l0L2ZyYW1lLXBpeGVscyc7XG5cbi8qKlxuICogV2FuZCByZWdpb24tZ3JvdyBwaXBlbGluZSAocHVyZSwgRE9NLSBhbmQgREktZnJlZSksIG1vZGVsbGVkIGFmdGVyIFF1UGF0aCdzXG4gKiBXYW5kVG9vbEV2ZW50SGFuZGxlcjogZXh0cmFjdCBhIHNxdWFyZSBwYXRjaCBhcm91bmQgdGhlIGNsaWNrLCBvcHRpb25hbGx5XG4gKiBibHVyIGl0LCBjb21wdXRlIGEgbG9jYWwgdGhyZXNob2xkIChwZXIgY2hhbm5lbCwgb3IgYSBDSUVMQUIgZGlzdGFuY2UgbWFwKSxcbiAqIHJ1biBhIGZpeGVkLXJhbmdlIGZsb29kIGZpbGwgZnJvbSB0aGUgY2VudHJlLCBjbG9zZSB0aGUgbWFzaywgYW5kIChmb3JcbiAqIHtAbGluayBjb21wdXRlV2FuZFJlZ2lvbn0pIHRyYWNlIGl0IHRvIGEgcG9seWdvbiBpbiBpbWFnZSBjb29yZGluYXRlcy5cbiAqXG4gKiBgV2FuZFNlcnZpY2VgIGRlbGVnYXRlcyBoZXJlOyB3b3JrZXJzIGFuZCBuZXcgY29kZSBzaG91bGQgaW1wb3J0IHRoZXNlXG4gKiBmdW5jdGlvbnMgZGlyZWN0bHkuXG4gKi9cblxuZXhwb3J0IHR5cGUgeyBXYW5kVHlwZSB9O1xuZXhwb3J0IHR5cGUgV2FuZE9wdGlvbnMgPSBJV2FuZE9wdGlvbnM7XG5cbmV4cG9ydCBpbnRlcmZhY2UgV2FuZEltYWdlIHtcbiAgLyoqXG4gICAqIEdyYXlzY2FsZTogbnVtYmVyW11bXSB3aGVyZSBkYXRhW3ldW3hdIGlzIGludGVuc2l0eS5cbiAgICogUkdCOiBbcixnLGJdW11bXSB3aGVyZSBkYXRhW3ldW3hdIGlzIGEgMy10dXBsZS5cbiAgICogT3IgYSBwYWNrZWQgUkdCQSByZWFkYmFjaywgcmVhZCBhcyBSR0IgKHNlZSBgdG9vbC1raXQvZnJhbWUtcGl4ZWxzYCkuXG4gICAqL1xuICBkYXRhOiBDYWNoZWRGcmFtZTtcbiAgd2lkdGg6IG51bWJlcjtcbiAgaGVpZ2h0OiBudW1iZXI7XG4gIGlzR3JheXNjYWxlOiBib29sZWFuO1xufVxuXG4vKiogQSB3YW5kIHBhdGNoIG1hc2s6IGBzaXplYMOXYHNpemVgIDAvMSBjZWxscyBpbiBwYXRjaC1sb2NhbCBjb29yZGluYXRlcy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgV2FuZFBhdGNoTWFzayB7XG4gIG1hc2s6IFVpbnQ4QXJyYXk7XG4gIHNpemU6IG51bWJlcjtcbn1cblxuY29uc3QgREVGQVVMVF9QQVRDSF9TSVpFID0gMTQ5O1xuY29uc3QgREVGQVVMVF9TSUdNQSA9IDQuMDtcbmNvbnN0IERFRkFVTFRfU0VOU0lUSVZJVFkgPSAyLjA7XG5cbi8qKlxuICogR3JvdyBhIHJlZ2lvbiBmcm9tIGEgY2xpY2sgYW5kIHRyYWNlIGl0LlxuICpcbiAqIEBwYXJhbSBpbWFnZSBmdWxsLWltYWdlIHBpeGVsIG1hdHJpeCAoYWxyZWFkeSBpbiBtZW1vcnkpLlxuICogQHBhcmFtIGN4IGNsaWNrIHggaW4gaW1hZ2UtcGl4ZWwgY29vcmRpbmF0ZXMuXG4gKiBAcGFyYW0gY3kgY2xpY2sgeSBpbiBpbWFnZS1waXhlbCBjb29yZGluYXRlcy5cbiAqIEBwYXJhbSBvcHRpb25zIHdhbmQgcGFyYW1ldGVyczsgbWlzc2luZyBmaWVsZHMgZmFsbCBiYWNrIHRvIGRlZmF1bHRzLlxuICogQHJldHVybnMgYSBQb2x5Z29uIGluIGltYWdlLXBpeGVsIGNvb3JkaW5hdGVzLCBvciBudWxsIGlmIG5vIHJlZ2lvbiBncmV3LlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29tcHV0ZVdhbmRSZWdpb24oXG4gIGltYWdlOiBXYW5kSW1hZ2UsXG4gIGN4OiBudW1iZXIsXG4gIGN5OiBudW1iZXIsXG4gIG9wdGlvbnM6IFdhbmRPcHRpb25zID0ge30sXG4pOiBQb2x5Z29uIHwgbnVsbCB7XG4gIGNvbnN0IHBhdGNoID0gY29tcHV0ZVdhbmRQYXRjaE1hc2soaW1hZ2UsIGN4LCBjeSwgb3B0aW9ucyk7XG4gIGlmICghcGF0Y2gpIHJldHVybiBudWxsO1xuICAvLyBUaGUgbGFyZ2VzdCB0cmFjZWQgcGllY2UgKHdpdGggaG9sZXMgb2YgNCsgcHgsIGFzIHRoZSB0b29scyB0cmFjZSk7IHNpbmdsZSBwaXhlbHMgc3RpbGwgY291bnQuXG4gIHJldHVybiAoXG4gICAgbWFza1RvUG9seWdvbnMoXG4gICAgICBwYXRjaC5tYXNrLFxuICAgICAgcGF0Y2guc2l6ZSxcbiAgICAgIHBhdGNoLnNpemUsXG4gICAgICBNYXRoLmZsb29yKGN4KSAtIChwYXRjaC5zaXplIC0gMSkgLyAyLFxuICAgICAgTWF0aC5mbG9vcihjeSkgLSAocGF0Y2guc2l6ZSAtIDEpIC8gMixcbiAgICAgIDEsXG4gICAgICA0LFxuICAgIClbMF0gPz8gbnVsbFxuICApO1xufVxuXG4vKipcbiAqIFRoZSB3YW5kJ3MgcGVyLWNsaWNrIGZsb29kLWZpbGwgbWFzayBpbiBwYXRjaC1sb2NhbCBjb29yZGluYXRlczogdGhlIHNhbWVcbiAqIHBpcGVsaW5lIGFzIHtAbGluayBjb21wdXRlV2FuZFJlZ2lvbn0sIHN0b3BwaW5nIGJlZm9yZSBjb250b3VyIHRyYWNpbmcgKHRoZVxuICogdG9vbHMgYWNjdW11bGF0ZSBwZXItdGljayBtYXNrcyBhY3Jvc3MgYSBicnVzaC1zdHlsZSBzdHJva2UpLlxuICpcbiAqIEB0aHJvd3Mgd2hlbiBgb3B0aW9ucy5wYXRjaFNpemVgIGlzIGV2ZW4uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21wdXRlV2FuZFBhdGNoTWFzayhcbiAgaW1hZ2U6IFdhbmRJbWFnZSxcbiAgY3g6IG51bWJlcixcbiAgY3k6IG51bWJlcixcbiAgb3B0aW9uczogV2FuZE9wdGlvbnMgPSB7fSxcbik6IFdhbmRQYXRjaE1hc2sgfCBudWxsIHtcbiAgY29uc3QgVyA9IG9wdGlvbnMucGF0Y2hTaXplID8/IERFRkFVTFRfUEFUQ0hfU0laRTtcbiAgaWYgKFcgJSAyID09PSAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBwYXRjaFNpemUgbXVzdCBiZSBvZGQsIGdvdCAke1d9YCk7XG4gIH1cbiAgY29uc3Qgc2lnbWEgPSBvcHRpb25zLnNpZ21hID8/IERFRkFVTFRfU0lHTUE7XG4gIGNvbnN0IHNlbnNpdGl2aXR5ID0gb3B0aW9ucy5zZW5zaXRpdml0eSA/PyBERUZBVUxUX1NFTlNJVElWSVRZO1xuICBjb25zdCBpc0dyYXlzY2FsZSA9IGltYWdlLmlzR3JheXNjYWxlO1xuICBjb25zdCB0eXBlOiBXYW5kVHlwZSA9IG9wdGlvbnMudHlwZSA/PyAoaXNHcmF5c2NhbGUgPyAnR1JBWScgOiAnUkdCJyk7XG4gIGNvbnN0IHNpbXBsZSA9ICEhb3B0aW9ucy5zaW1wbGVNb2RlO1xuICAvLyBleHRyYWN0UGF0Y2ggYWx3YXlzIGludGVybGVhdmVzIDEgY2hhbm5lbCBmb3IgR1JBWSwgMyBmb3IgUkdCL0xBQl9ESVNUQU5DRS5cbiAgY29uc3QgaW5wdXRDaGFubmVscyA9IHR5cGUgPT09ICdHUkFZJyA/IDEgOiAzO1xuXG4gIGxldCBidWYgPSBleHRyYWN0UGF0Y2goaW1hZ2UsIGN4LCBjeSwgVywgdHlwZSk7XG5cbiAgLy8gRmxvb2QgZmlsbCBvcGVyYXRlcyBvbiB3aGF0ZXZlciBidWZmZXIgd2UgZW5kIHVwIHdpdGg6IHRoZSByYXcgcGF0Y2ggaW5cbiAgLy8gc2ltcGxlIG1vZGUgKHNvIG11bHRpLWNoYW5uZWwgZXhhY3QtbWF0Y2gpLCB0aGUgYmx1cnJlZCBwYXRjaCBmb3JcbiAgLy8gR1JBWS9SR0IsIG9yIHRoZSBzaW5nbGUtY2hhbm5lbCBDSUVMQUIgZGlzdGFuY2UgbWFwIGZvciBMQUJfRElTVEFOQ0UuXG4gIGxldCBmbG9vZENoYW5uZWxzOiBudW1iZXI7XG4gIGxldCB0aHJlc2hvbGQ6IG51bWJlcltdO1xuXG4gIGlmIChzaW1wbGUpIHtcbiAgICAvLyBTa2lwIGJsdXIgKyB0aHJlc2hvbGQgY29tcHV0YXRpb24uIEZsb29kLWZpbGwgdGhlIHJhdyBwYXRjaCBhdFxuICAgIC8vIGV4YWN0LW1hdGNoIHBlciBjaGFubmVsIOKAlCBzYW1lIGFzIFF1UGF0aCdzIGRvU2ltcGxlU2VsZWN0aW9uLlxuICAgIGZsb29kQ2hhbm5lbHMgPSBpbnB1dENoYW5uZWxzO1xuICAgIHRocmVzaG9sZCA9IG5ldyBBcnJheShmbG9vZENoYW5uZWxzKS5maWxsKDApO1xuICB9IGVsc2Uge1xuICAgIGNvbnN0IGJsdXJTaWdtYSA9IE1hdGgubWF4KDAuNSwgc2lnbWEpO1xuICAgIGJ1ZiA9IGdhdXNzaWFuQmx1cihidWYsIFcsIGlucHV0Q2hhbm5lbHMsIGJsdXJTaWdtYSk7XG5cbiAgICBpZiAodHlwZSA9PT0gJ0xBQl9ESVNUQU5DRScpIHtcbiAgICAgIC8vIENvbnZlcnQgYmx1cnJlZCAzLWNoYW5uZWwgcGF0Y2ggdG8gYSBzaW5nbGUtY2hhbm5lbCBkaXN0YW5jZSBtYXAsXG4gICAgICAvLyB0aGVuIGZsb29kLWZpbGwgb24gdGhhdCBzaW5nbGUgY2hhbm5lbC5cbiAgICAgIGNvbnN0IGRpc3RhbmNlID0gbGFiRGlzdGFuY2VNYXAoYnVmLCBXKTtcbiAgICAgIGNvbnN0IG1heCA9IGRpc3RhbmNlLm1heCA+IDAgPyBkaXN0YW5jZS5tYXggOiAxO1xuICAgICAgY29uc3Qgc2NhbGVkID0gbmV3IEZsb2F0MzJBcnJheShXICogVyk7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNjYWxlZC5sZW5ndGg7IGkrKykgc2NhbGVkW2ldID0gKGRpc3RhbmNlLnZhbHVlc1tpXSAqIDI1NS4wKSAvIG1heDtcbiAgICAgIGJ1ZiA9IHNjYWxlZDtcbiAgICAgIGZsb29kQ2hhbm5lbHMgPSAxO1xuICAgICAgdGhyZXNob2xkID0gWyhkaXN0YW5jZS5tZWFuICogc2Vuc2l0aXZpdHkgKiAyNTUuMCkgLyBtYXhdO1xuICAgIH0gZWxzZSB7XG4gICAgICBmbG9vZENoYW5uZWxzID0gaW5wdXRDaGFubmVscztcbiAgICAgIHRocmVzaG9sZCA9IHBlckNoYW5uZWxUaHJlc2hvbGQoYnVmLCBXLCBpbnB1dENoYW5uZWxzLCBzZW5zaXRpdml0eSk7XG4gICAgfVxuICB9XG5cbiAgLy8gRml4ZWQtcmFuZ2UgZmxvb2QgZmlsbCBmcm9tIHRoZSBwYXRjaCBjZW50cmUgKG5hcGFyaS1qcydzIGZpbGwgYnVja2V0KTogYSBwaXhlbCBpcyB0YWtlblxuICAvLyB3aGVuIGV2ZXJ5IGNoYW5uZWwgaXMgd2l0aGluIGl0cyB0aHJlc2hvbGQgb2YgdGhlIFNFRUQncywgNC1jb25uZWN0ZWQuXG4gIGNvbnN0IGNlbnRyZSA9IChXIC0gMSkgLyAyO1xuICBjb25zdCBtYXNrID0gZmxvb2RGaWxsKHsgZGF0YTogYnVmLCB3aWR0aDogVywgaGVpZ2h0OiBXIH0sIGNlbnRyZSwgY2VudHJlLCB7XG4gICAgY2hhbm5lbHM6IGZsb29kQ2hhbm5lbHMsXG4gICAgdG9sZXJhbmNlOiB0aHJlc2hvbGQsXG4gIH0pO1xuICBjb25zdCBjbG9zZWQgPSBzaW1wbGUgPyBtYXNrIDogbW9ycGhDbG9zZShtYXNrLCBXLCA1KTtcbiAgcmV0dXJuIHsgbWFzazogY2xvc2VkLCBzaXplOiBXIH07XG59XG5cbi8vIOKUgOKUgCBQYXRjaCBleHRyYWN0aW9uIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5mdW5jdGlvbiBleHRyYWN0UGF0Y2goaW1hZ2U6IFdhbmRJbWFnZSwgY3g6IG51bWJlciwgY3k6IG51bWJlciwgVzogbnVtYmVyLCB0eXBlOiBXYW5kVHlwZSk6IEZsb2F0MzJBcnJheSB7XG4gIGNvbnN0IGNoYW5uZWxzID0gdHlwZSA9PT0gJ0dSQVknID8gMSA6IDM7XG4gIGNvbnN0IGhhbGYgPSAoVyAtIDEpIC8gMjtcbiAgLy8gVGhlIHBhdGNoIGNlbnRyZXMgb24gdGhlIHBpeGVsIHVuZGVyIHRoZSBjbGljazogcGl4ZWwgeCBjb3ZlcnMgW3gsIHggKyAxKSBvbiBldmVyeSBiYWNrZW5kLlxuICBjb25zdCB4MCA9IE1hdGguZmxvb3IoY3gpIC0gaGFsZjtcbiAgY29uc3QgeTAgPSBNYXRoLmZsb29yKGN5KSAtIGhhbGY7XG4gIGNvbnN0IGJ1ZiA9IG5ldyBGbG9hdDMyQXJyYXkoVyAqIFcgKiBjaGFubmVscyk7XG4gIGNvbnN0IHBpeGVscyA9IGZyYW1lUGl4ZWxzKGltYWdlLmRhdGEsIGltYWdlLmlzR3JheXNjYWxlKTtcbiAgLy8gQSBncmF5c2NhbGUgbmVzdGVkIGZyYW1lIHJlYWRzIGFzICh2LCB2LCB2KTogaXRzIHZhbHVlIGlzIHJnYlswXS5cbiAgY29uc3QgZ3JheSA9IGltYWdlLmlzR3JheXNjYWxlICYmICFpc1BhY2tlZEZyYW1lKGltYWdlLmRhdGEpO1xuICBjb25zdCByZ2IgPSBbMCwgMCwgMF07XG5cbiAgZm9yIChsZXQgcHkgPSAwOyBweSA8IFc7IHB5KyspIHtcbiAgICBjb25zdCBpeSA9IHkwICsgcHk7XG4gICAgaWYgKGl5IDwgMCB8fCBpeSA+PSBpbWFnZS5oZWlnaHQpIGNvbnRpbnVlO1xuICAgIGZvciAobGV0IHB4ID0gMDsgcHggPCBXOyBweCsrKSB7XG4gICAgICBjb25zdCBpeCA9IHgwICsgcHg7XG4gICAgICBpZiAoaXggPCAwIHx8IGl4ID49IGltYWdlLndpZHRoKSBjb250aW51ZTtcbiAgICAgIGlmICghcGl4ZWxzLnJnYihpeCwgaXksIHJnYikpIGNvbnRpbnVlO1xuICAgICAgY29uc3QgZHN0ID0gKHB5ICogVyArIHB4KSAqIGNoYW5uZWxzO1xuICAgICAgaWYgKGdyYXkpIHtcbiAgICAgICAgY29uc3QgdiA9IHJnYlswXTtcbiAgICAgICAgaWYgKGNoYW5uZWxzID09PSAxKSB7XG4gICAgICAgICAgYnVmW2RzdF0gPSB2O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGJ1Zltkc3RdID0gdjtcbiAgICAgICAgICBidWZbZHN0ICsgMV0gPSB2O1xuICAgICAgICAgIGJ1Zltkc3QgKyAyXSA9IHY7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoY2hhbm5lbHMgPT09IDEpIHtcbiAgICAgICAgLy8gR1JBWSB0eXBlIGZvcmNlZCBvbiBSR0IgaW1hZ2U6IGNvbnZlcnQgd2l0aCBsdW1pbmFuY2UuXG4gICAgICAgIGJ1Zltkc3RdID0gYnQ2MDFMdW1pbmFuY2UocmdiWzBdLCByZ2JbMV0sIHJnYlsyXSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBidWZbZHN0XSA9IHJnYlswXTtcbiAgICAgICAgYnVmW2RzdCArIDFdID0gcmdiWzFdO1xuICAgICAgICBidWZbZHN0ICsgMl0gPSByZ2JbMl07XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBidWY7XG59XG5cbi8vIOKUgOKUgCBHYXVzc2lhbiBibHVyIChzZXBhcmFibGUpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5mdW5jdGlvbiBnYXVzc2lhbkJsdXIoYnVmOiBGbG9hdDMyQXJyYXksIFc6IG51bWJlciwgY2hhbm5lbHM6IG51bWJlciwgc2lnbWE6IG51bWJlcik6IEZsb2F0MzJBcnJheSB7XG4gIGNvbnN0IHJhZGl1cyA9IE1hdGgubWF4KDEsIE1hdGguY2VpbChzaWdtYSAqIDIpKTtcbiAgY29uc3Qgc2l6ZSA9IHJhZGl1cyAqIDIgKyAxO1xuICBjb25zdCBrZXJuZWwgPSBuZXcgRmxvYXQzMkFycmF5KHNpemUpO1xuICBsZXQgc3VtID0gMDtcbiAgY29uc3QgaW52MnMyID0gMSAvICgyICogc2lnbWEgKiBzaWdtYSk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSB7XG4gICAgY29uc3QgeCA9IGkgLSByYWRpdXM7XG4gICAga2VybmVsW2ldID0gTWF0aC5leHAoLXggKiB4ICogaW52MnMyKTtcbiAgICBzdW0gKz0ga2VybmVsW2ldO1xuICB9XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgc2l6ZTsgaSsrKSBrZXJuZWxbaV0gLz0gc3VtO1xuXG4gIGNvbnN0IGhvcml6ID0gbmV3IEZsb2F0MzJBcnJheShidWYubGVuZ3RoKTtcbiAgLy8gSG9yaXpvbnRhbCBwYXNzLlxuICBmb3IgKGxldCB5ID0gMDsgeSA8IFc7IHkrKykge1xuICAgIGZvciAobGV0IHggPSAwOyB4IDwgVzsgeCsrKSB7XG4gICAgICBmb3IgKGxldCBjID0gMDsgYyA8IGNoYW5uZWxzOyBjKyspIHtcbiAgICAgICAgbGV0IGFjYyA9IDA7XG4gICAgICAgIGZvciAobGV0IGsgPSAwOyBrIDwgc2l6ZTsgaysrKSB7XG4gICAgICAgICAgbGV0IHh4ID0geCArIGsgLSByYWRpdXM7XG4gICAgICAgICAgaWYgKHh4IDwgMCkgeHggPSAwO1xuICAgICAgICAgIGVsc2UgaWYgKHh4ID49IFcpIHh4ID0gVyAtIDE7XG4gICAgICAgICAgYWNjICs9IGtlcm5lbFtrXSAqIGJ1ZlsoeSAqIFcgKyB4eCkgKiBjaGFubmVscyArIGNdO1xuICAgICAgICB9XG4gICAgICAgIGhvcml6Wyh5ICogVyArIHgpICogY2hhbm5lbHMgKyBjXSA9IGFjYztcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgY29uc3Qgb3V0ID0gbmV3IEZsb2F0MzJBcnJheShidWYubGVuZ3RoKTtcbiAgLy8gVmVydGljYWwgcGFzcy5cbiAgZm9yIChsZXQgeSA9IDA7IHkgPCBXOyB5KyspIHtcbiAgICBmb3IgKGxldCB4ID0gMDsgeCA8IFc7IHgrKykge1xuICAgICAgZm9yIChsZXQgYyA9IDA7IGMgPCBjaGFubmVsczsgYysrKSB7XG4gICAgICAgIGxldCBhY2MgPSAwO1xuICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IHNpemU7IGsrKykge1xuICAgICAgICAgIGxldCB5eSA9IHkgKyBrIC0gcmFkaXVzO1xuICAgICAgICAgIGlmICh5eSA8IDApIHl5ID0gMDtcbiAgICAgICAgICBlbHNlIGlmICh5eSA+PSBXKSB5eSA9IFcgLSAxO1xuICAgICAgICAgIGFjYyArPSBrZXJuZWxba10gKiBob3JpelsoeXkgKiBXICsgeCkgKiBjaGFubmVscyArIGNdO1xuICAgICAgICB9XG4gICAgICAgIG91dFsoeSAqIFcgKyB4KSAqIGNoYW5uZWxzICsgY10gPSBhY2M7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBvdXQ7XG59XG5cbi8vIOKUgOKUgCBUaHJlc2hvbGQgY29tcHV0YXRpb24g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmZ1bmN0aW9uIHBlckNoYW5uZWxUaHJlc2hvbGQoYnVmOiBGbG9hdDMyQXJyYXksIFc6IG51bWJlciwgY2hhbm5lbHM6IG51bWJlciwgc2Vuc2l0aXZpdHk6IG51bWJlcik6IG51bWJlcltdIHtcbiAgY29uc3QgbiA9IFcgKiBXO1xuICBjb25zdCBzdW1zID0gbmV3IEFycmF5KGNoYW5uZWxzKS5maWxsKDApO1xuICBjb25zdCBzcXMgPSBuZXcgQXJyYXkoY2hhbm5lbHMpLmZpbGwoMCk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7XG4gICAgZm9yIChsZXQgYyA9IDA7IGMgPCBjaGFubmVsczsgYysrKSB7XG4gICAgICBjb25zdCB2ID0gYnVmW2kgKiBjaGFubmVscyArIGNdO1xuICAgICAgc3Vtc1tjXSArPSB2O1xuICAgICAgc3FzW2NdICs9IHYgKiB2O1xuICAgIH1cbiAgfVxuICBjb25zdCBzY2FsZSA9IHNlbnNpdGl2aXR5ID4gMCA/IDEgLyBzZW5zaXRpdml0eSA6IDEwMDtcbiAgY29uc3QgdGhyZXNob2xkID0gbmV3IEFycmF5KGNoYW5uZWxzKTtcbiAgZm9yIChsZXQgYyA9IDA7IGMgPCBjaGFubmVsczsgYysrKSB7XG4gICAgY29uc3QgbWVhbiA9IHN1bXNbY10gLyBuO1xuICAgIGNvbnN0IHZhcmlhbmNlID0gTWF0aC5tYXgoMCwgc3FzW2NdIC8gbiAtIG1lYW4gKiBtZWFuKTtcbiAgICBjb25zdCBzdGRkZXYgPSBNYXRoLnNxcnQodmFyaWFuY2UpO1xuICAgIHRocmVzaG9sZFtjXSA9IHN0ZGRldiAqIHNjYWxlO1xuICB9XG4gIHJldHVybiB0aHJlc2hvbGQ7XG59XG5cbmZ1bmN0aW9uIGxhYkRpc3RhbmNlTWFwKGJ1ZjogRmxvYXQzMkFycmF5LCBXOiBudW1iZXIpOiB7IHZhbHVlczogRmxvYXQzMkFycmF5OyBtZWFuOiBudW1iZXI7IG1heDogbnVtYmVyIH0ge1xuICBjb25zdCBuID0gVyAqIFc7XG4gIGNvbnN0IGxhYiA9IG5ldyBGbG9hdDMyQXJyYXkobiAqIDMpO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IG47IGkrKykge1xuICAgIGNvbnN0IHIgPSBidWZbaSAqIDNdIC8gMjU1O1xuICAgIGNvbnN0IGcgPSBidWZbaSAqIDMgKyAxXSAvIDI1NTtcbiAgICBjb25zdCBiID0gYnVmW2kgKiAzICsgMl0gLyAyNTU7XG4gICAgY29uc3QgW0wsIEEsIEJdID0gc3JnYlRvTGFiKHIsIGcsIGIpO1xuICAgIGxhYltpICogM10gPSBMO1xuICAgIGxhYltpICogMyArIDFdID0gQTtcbiAgICBsYWJbaSAqIDMgKyAyXSA9IEI7XG4gIH1cbiAgY29uc3QgbWlkID0gTWF0aC5mbG9vcihuIC8gMik7XG4gIGNvbnN0IGNMID0gbGFiW21pZCAqIDNdO1xuICBjb25zdCBjQSA9IGxhYlttaWQgKiAzICsgMV07XG4gIGNvbnN0IGNCID0gbGFiW21pZCAqIDMgKyAyXTtcblxuICBjb25zdCB2YWx1ZXMgPSBuZXcgRmxvYXQzMkFycmF5KG4pO1xuICBsZXQgbWF4ID0gMDtcbiAgbGV0IHN1bSA9IDA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbjsgaSsrKSB7XG4gICAgY29uc3QgZEwgPSBsYWJbaSAqIDNdIC0gY0w7XG4gICAgY29uc3QgZEEgPSBsYWJbaSAqIDMgKyAxXSAtIGNBO1xuICAgIGNvbnN0IGRCID0gbGFiW2kgKiAzICsgMl0gLSBjQjtcbiAgICBjb25zdCBkID0gTWF0aC5zcXJ0KGRMICogZEwgKyBkQSAqIGRBICsgZEIgKiBkQik7XG4gICAgdmFsdWVzW2ldID0gZDtcbiAgICBpZiAoZCA+IG1heCkgbWF4ID0gZDtcbiAgICBzdW0gKz0gZDtcbiAgfVxuICByZXR1cm4geyB2YWx1ZXMsIG1lYW46IHN1bSAvIG4sIG1heCB9O1xufVxuXG4vLyDilIDilIAgTW9ycGhvbG9naWNhbCBjbG9zZSAoZGlsYXRlIHRoZW4gZXJvZGUpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5mdW5jdGlvbiBtb3JwaENsb3NlKG1hc2s6IFVpbnQ4QXJyYXksIFc6IG51bWJlciwga2VybmVsU2l6ZTogbnVtYmVyKTogVWludDhBcnJheSB7XG4gIGNvbnN0IHIgPSAoa2VybmVsU2l6ZSAtIDEpIC8gMjtcbiAgY29uc3QgZGlsID0gZGlsYXRlKG1hc2ssIFcsIHIpO1xuICByZXR1cm4gZXJvZGUoZGlsLCBXLCByKTtcbn1cblxuZnVuY3Rpb24gZGlsYXRlKG1hc2s6IFVpbnQ4QXJyYXksIFc6IG51bWJlciwgcjogbnVtYmVyKTogVWludDhBcnJheSB7XG4gIGNvbnN0IG91dCA9IG5ldyBVaW50OEFycmF5KFcgKiBXKTtcbiAgZm9yIChsZXQgeSA9IDA7IHkgPCBXOyB5KyspIHtcbiAgICBmb3IgKGxldCB4ID0gMDsgeCA8IFc7IHgrKykge1xuICAgICAgbGV0IGhpdCA9IDA7XG4gICAgICBmb3IgKGxldCBkeSA9IC1yOyBkeSA8PSByICYmICFoaXQ7IGR5KyspIHtcbiAgICAgICAgY29uc3QgeXkgPSB5ICsgZHk7XG4gICAgICAgIGlmICh5eSA8IDAgfHwgeXkgPj0gVykgY29udGludWU7XG4gICAgICAgIGZvciAobGV0IGR4ID0gLXI7IGR4IDw9IHI7IGR4KyspIHtcbiAgICAgICAgICBjb25zdCB4eCA9IHggKyBkeDtcbiAgICAgICAgICBpZiAoeHggPCAwIHx8IHh4ID49IFcpIGNvbnRpbnVlO1xuICAgICAgICAgIGlmIChtYXNrW3l5ICogVyArIHh4XSkge1xuICAgICAgICAgICAgaGl0ID0gMTtcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgb3V0W3kgKiBXICsgeF0gPSBoaXQ7XG4gICAgfVxuICB9XG4gIHJldHVybiBvdXQ7XG59XG5cbmZ1bmN0aW9uIGVyb2RlKG1hc2s6IFVpbnQ4QXJyYXksIFc6IG51bWJlciwgcjogbnVtYmVyKTogVWludDhBcnJheSB7XG4gIGNvbnN0IG91dCA9IG5ldyBVaW50OEFycmF5KFcgKiBXKTtcbiAgZm9yIChsZXQgeSA9IDA7IHkgPCBXOyB5KyspIHtcbiAgICBmb3IgKGxldCB4ID0gMDsgeCA8IFc7IHgrKykge1xuICAgICAgbGV0IGFsbCA9IDE7XG4gICAgICBmb3IgKGxldCBkeSA9IC1yOyBkeSA8PSByICYmIGFsbDsgZHkrKykge1xuICAgICAgICBjb25zdCB5eSA9IHkgKyBkeTtcbiAgICAgICAgaWYgKHl5IDwgMCB8fCB5eSA+PSBXKSB7XG4gICAgICAgICAgYWxsID0gMDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGxldCBkeCA9IC1yOyBkeCA8PSByOyBkeCsrKSB7XG4gICAgICAgICAgY29uc3QgeHggPSB4ICsgZHg7XG4gICAgICAgICAgaWYgKHh4IDwgMCB8fCB4eCA+PSBXKSB7XG4gICAgICAgICAgICBhbGwgPSAwO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmICghbWFza1t5eSAqIFcgKyB4eF0pIHtcbiAgICAgICAgICAgIGFsbCA9IDA7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIG91dFt5ICogVyArIHhdID0gYWxsO1xuICAgIH1cbiAgfVxuICByZXR1cm4gb3V0O1xufVxuXG4vLyDilIDilIAgc1JHQiDihpIgQ0lFTEFCIChENjUpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5mdW5jdGlvbiBzcmdiVG9MaW5lYXIoYzogbnVtYmVyKTogbnVtYmVyIHtcbiAgcmV0dXJuIGMgPD0gMC4wNDA0NSA/IGMgLyAxMi45MiA6IE1hdGgucG93KChjICsgMC4wNTUpIC8gMS4wNTUsIDIuNCk7XG59XG5cbmZ1bmN0aW9uIHNyZ2JUb0xhYihyOiBudW1iZXIsIGc6IG51bWJlciwgYjogbnVtYmVyKTogW251bWJlciwgbnVtYmVyLCBudW1iZXJdIHtcbiAgY29uc3QgUiA9IHNyZ2JUb0xpbmVhcihyKTtcbiAgY29uc3QgRyA9IHNyZ2JUb0xpbmVhcihnKTtcbiAgY29uc3QgQiA9IHNyZ2JUb0xpbmVhcihiKTtcbiAgLy8gc1JHQiDihpIgWFlaIChENjUpXG4gIGNvbnN0IFggPSBSICogMC40MTI0NTY0ICsgRyAqIDAuMzU3NTc2MSArIEIgKiAwLjE4MDQzNzU7XG4gIGNvbnN0IFkgPSBSICogMC4yMTI2NzI5ICsgRyAqIDAuNzE1MTUyMiArIEIgKiAwLjA3MjE3NTtcbiAgY29uc3QgWiA9IFIgKiAwLjAxOTMzMzkgKyBHICogMC4xMTkxOTIgKyBCICogMC45NTAzMDQxO1xuICAvLyBSZWZlcmVuY2Ugd2hpdGUgKEQ2NSlcbiAgY29uc3QgWG4gPSAwLjk1MDQ3LFxuICAgIFluID0gMS4wLFxuICAgIFpuID0gMS4wODg4MztcbiAgY29uc3QgZnggPSBsYWJGKFggLyBYbik7XG4gIGNvbnN0IGZ5ID0gbGFiRihZIC8gWW4pO1xuICBjb25zdCBmeiA9IGxhYkYoWiAvIFpuKTtcbiAgY29uc3QgTCA9IDExNiAqIGZ5IC0gMTY7XG4gIGNvbnN0IEEgPSA1MDAgKiAoZnggLSBmeSk7XG4gIGNvbnN0IEJ2ID0gMjAwICogKGZ5IC0gZnopO1xuICByZXR1cm4gW0wsIEEsIEJ2XTtcbn1cblxuZnVuY3Rpb24gbGFiRih0OiBudW1iZXIpOiBudW1iZXIge1xuICBjb25zdCBkID0gNiAvIDI5O1xuICByZXR1cm4gdCA+IGQgKiBkICogZCA/IE1hdGguY2JydCh0KSA6IHQgLyAoMyAqIGQgKiBkKSArIDQgLyAyOTtcbn1cbiJdfQ==
|