@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.
Files changed (525) hide show
  1. package/README.md +201 -460
  2. package/esm2022/index.mjs +28 -15
  3. package/esm2022/lib/channel-histogram/channel-histogram.component.mjs +163 -91
  4. package/esm2022/lib/contracts/capabilities.contract.mjs +4 -3
  5. package/esm2022/lib/contracts/cell-segmenter.contract.mjs +1 -1
  6. package/esm2022/lib/contracts/channel-histogram-api.contract.mjs +5 -1
  7. package/esm2022/lib/contracts/color.mjs +60 -0
  8. package/esm2022/lib/contracts/colormap-lut.mjs +213 -57
  9. package/esm2022/lib/contracts/coordinate-transform.contract.mjs +1 -1
  10. package/esm2022/lib/contracts/display-types.mjs +11 -1
  11. package/esm2022/lib/contracts/instance-segmenter.contract.mjs +1 -1
  12. package/esm2022/lib/contracts/intensity.mjs +48 -5
  13. package/esm2022/lib/contracts/plot-type-contribution.contract.mjs +1 -1
  14. package/esm2022/lib/contracts/plot-type.mjs +134 -17
  15. package/esm2022/lib/contracts/ports/image-state.port.mjs +4 -1
  16. package/esm2022/lib/contracts/ports/preferences.port.mjs +5 -1
  17. package/esm2022/lib/contracts/ports/region-io.port.mjs +2 -1
  18. package/esm2022/lib/contracts/ports/spatial-data.port.mjs +5 -1
  19. package/esm2022/lib/contracts/ports/tile-access.port.mjs +2 -1
  20. package/esm2022/lib/contracts/region-editor-api.contract.mjs +1 -1
  21. package/esm2022/lib/contracts/region-overlay.contract.mjs +1 -1
  22. package/esm2022/lib/contracts/sam.contract.mjs +1 -1
  23. package/esm2022/lib/contracts/semantic-segmenter.contract.mjs +1 -1
  24. package/esm2022/lib/contracts/spatial-dataset.contract.mjs +3 -1
  25. package/esm2022/lib/contracts/toolbar-tool.contract.mjs +6 -4
  26. package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
  27. package/esm2022/lib/contracts/viz-config.mjs +2 -1
  28. package/esm2022/lib/geometry/contour.mjs +63 -0
  29. package/esm2022/lib/geometry/raster.mjs +98 -0
  30. package/esm2022/lib/geometry/ring.mjs +201 -0
  31. package/esm2022/lib/hex-color-picker/hex-color-picker.component.mjs +202 -102
  32. package/esm2022/lib/implementations/base-store-visualizer.mjs +201 -48
  33. package/esm2022/lib/implementations/napari-js/napari-axes-gizmo.mjs +65 -0
  34. package/esm2022/lib/implementations/napari-js/napari-display-state.mjs +136 -0
  35. package/esm2022/lib/implementations/napari-js/napari-helpers.mjs +199 -0
  36. package/esm2022/lib/implementations/napari-js/napari-image-2d-scene.mjs +602 -0
  37. package/esm2022/lib/implementations/napari-js/napari-loading-badge.mjs +3 -4
  38. package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +66 -0
  39. package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +157 -591
  40. package/esm2022/lib/implementations/napari-js/napari-scene.mjs +2 -0
  41. package/esm2022/lib/implementations/napari-js/napari-spatial-2d-scene.mjs +614 -0
  42. package/esm2022/lib/implementations/napari-js/napari-spatial-3d-scene.mjs +769 -0
  43. package/esm2022/lib/implementations/napari-js/napari-spatial-encoding.mjs +199 -0
  44. package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +263 -0
  45. package/esm2022/lib/implementations/napari-js/napari-spatial-scene.mjs +159 -0
  46. package/esm2022/lib/implementations/napari-js/napari-spatial-tiles.mjs +106 -1408
  47. package/esm2022/lib/implementations/napari-js/napari-spatial-tooltip.mjs +2 -2
  48. package/esm2022/lib/implementations/napari-js/napari-surface-scene.mjs +271 -0
  49. package/esm2022/lib/implementations/napari-js/napari-tile-client.mjs +562 -0
  50. package/esm2022/lib/implementations/napari-js/napari-tool-bridge.mjs +344 -0
  51. package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +358 -4218
  52. package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +439 -0
  53. package/esm2022/lib/implementations/napari-js/napari-volume-z-handle.mjs +6 -6
  54. package/esm2022/lib/implementations/napari-js/region-overlay/overlay-projection.mjs +96 -0
  55. package/esm2022/lib/implementations/napari-js/region-overlay/region-edit.mjs +35 -0
  56. package/esm2022/lib/implementations/napari-js/region-overlay/region-svg-renderer.mjs +182 -0
  57. package/esm2022/lib/implementations/napari-js/spatial-tiles/categorical-lookup.mjs +30 -0
  58. package/esm2022/lib/implementations/napari-js/spatial-tiles/cell-layers.mjs +274 -0
  59. package/esm2022/lib/implementations/napari-js/spatial-tiles/density-layer.mjs +144 -0
  60. package/esm2022/lib/implementations/napari-js/spatial-tiles/layer-groups.mjs +165 -0
  61. package/esm2022/lib/implementations/napari-js/spatial-tiles/plan-context.mjs +78 -0
  62. package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-hover.mjs +182 -0
  63. package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-jobs.mjs +369 -0
  64. package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-layers.mjs +306 -0
  65. package/esm2022/lib/implementations/osd/display-pipeline.mjs +102 -40
  66. package/esm2022/lib/implementations/osd/histogram-sampler.mjs +56 -31
  67. package/esm2022/lib/implementations/osd/openseadragon-viewer-options.mjs +128 -0
  68. package/esm2022/lib/implementations/osd/openseadragon-visualizer.service.mjs +333 -1685
  69. package/esm2022/lib/implementations/osd/osd-coordinate-transform.mjs +1 -1
  70. package/esm2022/lib/implementations/osd/osd-coords.mjs +5 -6
  71. package/esm2022/lib/implementations/osd/osd-export.mjs +122 -0
  72. package/esm2022/lib/implementations/osd/osd-lib.mjs +15 -1
  73. package/esm2022/lib/implementations/osd/osd-navigator-chrome.mjs +205 -0
  74. package/esm2022/lib/implementations/osd/osd-pixel-readback.mjs +68 -0
  75. package/esm2022/lib/implementations/osd/osd-region-overlay-draw.mjs +153 -0
  76. package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +185 -718
  77. package/esm2022/lib/implementations/osd/osd-scale-bar.mjs +52 -60
  78. package/esm2022/lib/implementations/osd/osd-tile-source.mjs +105 -0
  79. package/esm2022/lib/implementations/osd/osd-viewer-like.mjs +2 -0
  80. package/esm2022/lib/implementations/osd/osd-viewer-mount.mjs +44 -0
  81. package/esm2022/lib/implementations/osd/osd-viewport.mjs +184 -0
  82. package/esm2022/lib/implementations/osd/osd-zoom.mjs +7 -1
  83. package/esm2022/lib/implementations/osd/simple-source.mjs +395 -0
  84. package/esm2022/lib/implementations/osd/slice-cache.mjs +53 -48
  85. package/esm2022/lib/implementations/osd/tile-client.mjs +32 -11
  86. package/esm2022/lib/implementations/osd/tile-recolor.mjs +330 -0
  87. package/esm2022/lib/implementations/plotly/omics-trace-builders.mjs +161 -73
  88. package/esm2022/lib/implementations/plotly/plotly-coordinate-transform.mjs +1 -1
  89. package/esm2022/lib/implementations/plotly/plotly-image-loader.mjs +112 -0
  90. package/esm2022/lib/implementations/plotly/plotly-image-recolor.mjs +178 -0
  91. package/esm2022/lib/implementations/plotly/plotly-intensity-inset.mjs +33 -0
  92. package/esm2022/lib/implementations/plotly/plotly-isosurface-controls.mjs +83 -0
  93. package/esm2022/lib/implementations/plotly/plotly-layouts.mjs +121 -0
  94. package/esm2022/lib/implementations/plotly/plotly-readback.mjs +117 -0
  95. package/esm2022/lib/implementations/plotly/plotly-region-overlay.mjs +19 -10
  96. package/esm2022/lib/implementations/plotly/plotly-shape-projection.mjs +223 -0
  97. package/esm2022/lib/implementations/plotly/plotly-trace-builders.mjs +79 -19
  98. package/esm2022/lib/implementations/plotly/plotly-zoom-controller.mjs +223 -0
  99. package/esm2022/lib/implementations/plotly/plotly.service.mjs +439 -1655
  100. package/esm2022/lib/implementations/region-centroids.mjs +47 -0
  101. package/esm2022/lib/implementations/simple-slice-access.service.mjs +22 -12
  102. package/esm2022/lib/implementations/spatial-data-http/spatial-data-http.service.mjs +172 -92
  103. package/esm2022/lib/implementations/spatial-data-http/spatial-wire.mjs +103 -22
  104. package/esm2022/lib/implementations/tile-server/index.mjs +6 -0
  105. package/esm2022/lib/implementations/tile-server/native-histogram.mjs +30 -0
  106. package/esm2022/lib/implementations/tile-server/poll-descriptor.mjs +65 -0
  107. package/esm2022/lib/implementations/tile-server/tile-protocol.mjs +42 -0
  108. package/esm2022/lib/implementations/tile-server/transport.mjs +135 -0
  109. package/esm2022/lib/intensity/intensity-profile.mjs +107 -0
  110. package/esm2022/lib/intensity/intensity-profile.service.mjs +223 -0
  111. package/esm2022/lib/intensity-inset/intensity-inset.component.mjs +133 -0
  112. package/esm2022/lib/models/bezier.mjs +1 -11
  113. package/esm2022/lib/models/class-preset.mjs +41 -3
  114. package/esm2022/lib/models/geometry.mjs +27 -164
  115. package/esm2022/lib/models/polygon-edit.mjs +254 -0
  116. package/esm2022/lib/models/polygon-factory.mjs +118 -0
  117. package/esm2022/lib/models/region-clone.mjs +68 -0
  118. package/esm2022/lib/models/region-geojson.mjs +373 -0
  119. package/esm2022/lib/models/region.mjs +34 -33
  120. package/esm2022/lib/models/shape.mjs +18 -16
  121. package/esm2022/lib/plot-mode/contribution-host.mjs +297 -0
  122. package/esm2022/lib/plot-mode/plot-mode-controller.mjs +9 -6
  123. package/esm2022/lib/plot-mode/plot-type-menu.mjs +85 -0
  124. package/esm2022/lib/plot-mode/tool-params-model.mjs +87 -0
  125. package/esm2022/lib/plot.utilities.mjs +296 -473
  126. package/esm2022/lib/processing/image-crop.mjs +1 -1
  127. package/esm2022/lib/processing/processing-image.mjs +28 -15
  128. package/esm2022/lib/provide-visualization.mjs +40 -14
  129. package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +99 -0
  130. package/esm2022/lib/region-editor/file-stem.mjs +13 -0
  131. package/esm2022/lib/region-editor/manage-classes-dialog/manage-classes-dialog.component.mjs +118 -0
  132. package/esm2022/lib/region-editor/mask-export.service.mjs +98 -0
  133. package/esm2022/lib/region-editor/mask-raster.mjs +11 -5
  134. package/esm2022/lib/region-editor/region-color-dialog/region-color-dialog.component.mjs +56 -0
  135. package/esm2022/lib/region-editor/region-editor-help/region-editor-help.component.mjs +28 -0
  136. package/esm2022/lib/region-editor/region-editor.component.mjs +402 -651
  137. package/esm2022/lib/region-editor/region-metrics.mjs +68 -0
  138. package/esm2022/lib/region-editor/region-persistence.service.mjs +134 -0
  139. package/esm2022/lib/region-editor/region-table/region-table.component.mjs +153 -0
  140. package/esm2022/lib/region-editor/save-mask-dialog/save-mask-dialog.component.mjs +91 -0
  141. package/esm2022/lib/region-editor/save-regions-dialog/save-regions-dialog.component.mjs +92 -0
  142. package/esm2022/lib/region-ops.service.mjs +28 -70
  143. package/esm2022/lib/region-overlay/region-geometry.mjs +360 -0
  144. package/esm2022/lib/region-overlay/region-hit-test.mjs +103 -0
  145. package/esm2022/lib/region-overlay/svg-region-renderer.mjs +228 -0
  146. package/esm2022/lib/render-orchestrator.mjs +14 -11
  147. package/esm2022/lib/render-session.mjs +207 -0
  148. package/esm2022/lib/routing-visualizer.service.mjs +459 -411
  149. package/esm2022/lib/spatial/density-raster.mjs +14 -0
  150. package/esm2022/lib/spatial/embedding-compute-coordinator.mjs +239 -0
  151. package/esm2022/lib/spatial/embedding-compute.mjs +43 -10
  152. package/esm2022/lib/spatial/gene-search.mjs +1 -1
  153. package/esm2022/lib/spatial/glyphs.mjs +97 -0
  154. package/esm2022/lib/spatial/lod.mjs +187 -0
  155. package/esm2022/lib/spatial/spatial-controls.facade.mjs +200 -0
  156. package/esm2022/lib/spatial/spatial-density.mjs +25 -16
  157. package/esm2022/lib/spatial/spatial-encoding.mjs +26 -82
  158. package/esm2022/lib/spatial/spatial-expression.mjs +43 -42
  159. package/esm2022/lib/spatial/spatial-framing.mjs +1 -1
  160. package/esm2022/lib/spatial/spatial-heatmap.mjs +6 -3
  161. package/esm2022/lib/spatial/spatial-hover.mjs +5 -33
  162. package/esm2022/lib/spatial/spatial-panel-model.mjs +282 -0
  163. package/esm2022/lib/spatial/spatial-sections.mjs +1 -1
  164. package/esm2022/lib/spatial/spatial-selection.mjs +33 -46
  165. package/esm2022/lib/spatial/spatial-tile-merge.mjs +219 -0
  166. package/esm2022/lib/spatial/spatial-tiles.mjs +12 -648
  167. package/esm2022/lib/spatial/spatial-volume-image.mjs +2 -4
  168. package/esm2022/lib/spatial/stats.mjs +71 -0
  169. package/esm2022/lib/spatial/transcript-grouping.mjs +307 -0
  170. package/esm2022/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.mjs +150 -0
  171. package/esm2022/lib/spatial-controls/spatial-charts/chart-data-model.mjs +309 -0
  172. package/esm2022/lib/spatial-controls/spatial-charts/chart-help.mjs +145 -0
  173. package/esm2022/lib/spatial-controls/spatial-charts/plotly-chart-host.mjs +158 -0
  174. package/esm2022/lib/spatial-controls/spatial-charts/spatial-chart-window/spatial-chart-window.component.mjs +47 -0
  175. package/esm2022/lib/spatial-controls/spatial-charts/spatial-charts.component.mjs +297 -802
  176. package/esm2022/lib/spatial-controls/spatial-charts/spatial-embedding-controls/spatial-embedding-controls.component.mjs +89 -0
  177. package/esm2022/lib/spatial-controls/spatial-charts/spatial-heatmap-controls/spatial-heatmap-controls.component.mjs +52 -0
  178. package/esm2022/lib/spatial-controls/spatial-controls.component.mjs +143 -1238
  179. package/esm2022/lib/spatial-controls/spatial-gene-picker.mjs +153 -0
  180. package/esm2022/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.mjs +241 -0
  181. package/esm2022/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.mjs +193 -0
  182. package/esm2022/lib/spatial-controls/spatial-key/spatial-key.component.mjs +132 -0
  183. package/esm2022/lib/spatial-controls/spatial-key/spatial-key.model.mjs +67 -0
  184. package/esm2022/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.mjs +147 -0
  185. package/esm2022/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.mjs +300 -0
  186. package/esm2022/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.mjs +370 -0
  187. package/esm2022/lib/store/class-color.util.mjs +46 -3
  188. package/esm2022/lib/store/region-history.mjs +146 -0
  189. package/esm2022/lib/store/region-scope-cache.mjs +140 -0
  190. package/esm2022/lib/store/region-selection.mjs +82 -0
  191. package/esm2022/lib/store/region-store.service.mjs +279 -675
  192. package/esm2022/lib/store/spatial-selection.service.mjs +2 -2
  193. package/esm2022/lib/store/visualizer-store.service.mjs +49 -71
  194. package/esm2022/lib/toast-outlets.mjs +5 -4
  195. package/esm2022/lib/toolbar/brush/brush-tool.service.mjs +92 -434
  196. package/esm2022/lib/toolbar/canvas-tools.mjs +20 -0
  197. package/esm2022/lib/toolbar/crop/slide-crop.mjs +26 -42
  198. package/esm2022/lib/toolbar/plot-type-selector/plot-type-selector.component.mjs +85 -0
  199. package/esm2022/lib/toolbar/region-tools/region-tool-buttons.mjs +74 -0
  200. package/esm2022/lib/toolbar/region-tools/region-tools.component.mjs +114 -0
  201. package/esm2022/lib/toolbar/segmentation/cell-segment-tool.service.mjs +74 -78
  202. package/esm2022/lib/toolbar/segmentation/cellpose-segmenter.service.mjs +50 -8
  203. package/esm2022/lib/toolbar/segmentation/onnx-sam-session.mjs +61 -42
  204. package/esm2022/lib/toolbar/segmentation/pending-calls.mjs +47 -0
  205. package/esm2022/lib/toolbar/segmentation/sam-model-registry.mjs +12 -4
  206. package/esm2022/lib/toolbar/segmentation/sam-onnx-core.mjs +70 -14
  207. package/esm2022/lib/toolbar/segmentation/sam-point-tool.service.mjs +135 -172
  208. package/esm2022/lib/toolbar/segmentation/sam-prompt.mjs +9 -90
  209. package/esm2022/lib/toolbar/segmentation/sam-session.service.mjs +183 -0
  210. package/esm2022/lib/toolbar/segmentation/sam-tool.service.mjs +95 -150
  211. package/esm2022/lib/toolbar/segmentation/segmentation-commit.mjs +12 -0
  212. package/esm2022/lib/toolbar/segmentation/segmentation-runner.mjs +108 -0
  213. package/esm2022/lib/toolbar/segmentation-tools/segmentation-tools.component.mjs +155 -0
  214. package/esm2022/lib/toolbar/stack-controls/stack-controls.component.mjs +81 -0
  215. package/esm2022/lib/toolbar/tool-kit/async-tool-status.mjs +37 -0
  216. package/esm2022/lib/toolbar/tool-kit/canvas-tool-manager.mjs +63 -0
  217. package/esm2022/lib/toolbar/tool-kit/canvas-tool.mjs +2 -0
  218. package/esm2022/lib/toolbar/tool-kit/frame-pixels.mjs +108 -0
  219. package/esm2022/lib/toolbar/tool-kit/mask-stroke-editor.mjs +306 -0
  220. package/esm2022/lib/toolbar/tool-kit/matrix-frame.mjs +61 -0
  221. package/esm2022/lib/toolbar/tool-kit/tool-overlay.mjs +140 -0
  222. package/esm2022/lib/toolbar/tool-kit/undo-gesture.mjs +24 -0
  223. package/esm2022/lib/toolbar/tool-slider/tool-slider.component.mjs +63 -0
  224. package/esm2022/lib/toolbar/toolbar-help-dialog/toolbar-help-dialog.component.mjs +50 -0
  225. package/esm2022/lib/toolbar/toolbar.component.mjs +68 -117
  226. package/esm2022/lib/toolbar/vertex-eraser/vertex-eraser-tool.service.mjs +93 -115
  227. package/esm2022/lib/toolbar/view-controls/view-controls.component.mjs +107 -0
  228. package/esm2022/lib/toolbar/wand/wand-region-grow.mjs +321 -0
  229. package/esm2022/lib/toolbar/wand/wand-tool.service.mjs +121 -416
  230. package/esm2022/lib/toolbar/wand/wand.service.mjs +30 -894
  231. package/esm2022/lib/toolbar/zoom-to-box/zoom-to-box-tool.service.mjs +48 -90
  232. package/esm2022/lib/util/mark-for-check.mjs +17 -0
  233. package/esm2022/lib/util/supersede.mjs +56 -0
  234. package/esm2022/lib/visualization.module.mjs +39 -141
  235. package/esm2022/lib/visualizer/floating-drag.directive.mjs +58 -0
  236. package/esm2022/lib/visualizer/region-actions.mjs +149 -0
  237. package/esm2022/lib/visualizer/region-load.mjs +60 -0
  238. package/esm2022/lib/visualizer/spatial-dataset-binder.mjs +163 -0
  239. package/esm2022/lib/visualizer/tool-modes.mjs +113 -0
  240. package/esm2022/lib/visualizer/viewer-shortcuts.mjs +167 -0
  241. package/esm2022/lib/visualizer/visualizer-context-menu.mjs +119 -0
  242. package/esm2022/lib/visualizer.component.mjs +480 -1902
  243. package/esm2022/lib/workers/spatial-math-ops.mjs +43 -0
  244. package/esm2022/lib/workers/spatial-math-worker.mjs +10 -0
  245. package/esm2022/lib/workers/spatial-math.mjs +190 -0
  246. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs +41083 -0
  247. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs.map +1 -0
  248. package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs +238 -0
  249. package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs.map +1 -0
  250. package/fesm2022/jax-data-science-sci-image-visualizer-spatial-math-worker-BzVFFqGS.mjs +12 -0
  251. package/fesm2022/jax-data-science-sci-image-visualizer-spatial-math-worker-BzVFFqGS.mjs.map +1 -0
  252. package/fesm2022/jax-data-science-sci-image-visualizer.mjs +41 -34467
  253. package/fesm2022/jax-data-science-sci-image-visualizer.mjs.map +1 -1
  254. package/fesm2022/mask.worker.js +36 -917
  255. package/fesm2022/onnx-sam.worker.js +52 -16
  256. package/fesm2022/spatial-math.worker.js +471 -0
  257. package/fesm2022/tsne.worker.js +32 -15
  258. package/index.d.ts +13 -10
  259. package/lib/channel-histogram/channel-histogram.component.d.ts +53 -43
  260. package/lib/contracts/capabilities.contract.d.ts +4 -2
  261. package/lib/contracts/cell-segmenter.contract.d.ts +1 -0
  262. package/lib/contracts/channel-histogram-api.contract.d.ts +4 -0
  263. package/lib/contracts/color.d.ts +27 -0
  264. package/lib/contracts/colormap-lut.d.ts +19 -4
  265. package/lib/contracts/coordinate-transform.contract.d.ts +3 -3
  266. package/lib/contracts/display-types.d.ts +21 -0
  267. package/lib/contracts/instance-segmenter.contract.d.ts +5 -0
  268. package/lib/contracts/intensity.d.ts +13 -2
  269. package/lib/contracts/plot-type.d.ts +3 -1
  270. package/lib/contracts/ports/image-state.port.d.ts +6 -2
  271. package/lib/contracts/ports/preferences.port.d.ts +4 -0
  272. package/lib/contracts/ports/region-io.port.d.ts +1 -0
  273. package/lib/contracts/ports/spatial-data.port.d.ts +4 -10
  274. package/lib/contracts/ports/tile-access.port.d.ts +1 -0
  275. package/lib/contracts/region-editor-api.contract.d.ts +1 -1
  276. package/lib/contracts/region-overlay.contract.d.ts +5 -0
  277. package/lib/contracts/sam.contract.d.ts +7 -0
  278. package/lib/contracts/semantic-segmenter.contract.d.ts +6 -0
  279. package/lib/contracts/spatial-dataset.contract.d.ts +19 -6
  280. package/lib/contracts/toolbar-tool.contract.d.ts +1 -0
  281. package/lib/contracts/visualizer.contract.d.ts +221 -54
  282. package/lib/contracts/viz-config.d.ts +1 -0
  283. package/lib/geometry/contour.d.ts +24 -0
  284. package/lib/geometry/raster.d.ts +42 -0
  285. package/lib/geometry/ring.d.ts +67 -0
  286. package/lib/hex-color-picker/hex-color-picker.component.d.ts +61 -27
  287. package/lib/implementations/base-store-visualizer.d.ts +61 -15
  288. package/lib/implementations/napari-js/napari-axes-gizmo.d.ts +36 -0
  289. package/lib/implementations/napari-js/napari-display-state.d.ts +76 -0
  290. package/lib/implementations/napari-js/napari-helpers.d.ts +129 -0
  291. package/lib/implementations/napari-js/napari-image-2d-scene.d.ts +162 -0
  292. package/lib/implementations/napari-js/napari-loading-badge.d.ts +0 -1
  293. package/lib/implementations/napari-js/napari-loading-state.d.ts +30 -0
  294. package/lib/implementations/napari-js/napari-region-overlay.d.ts +62 -70
  295. package/lib/implementations/napari-js/napari-scene.d.ts +93 -0
  296. package/lib/implementations/napari-js/napari-spatial-2d-scene.d.ts +163 -0
  297. package/lib/implementations/napari-js/napari-spatial-3d-scene.d.ts +212 -0
  298. package/lib/implementations/napari-js/napari-spatial-encoding.d.ts +114 -0
  299. package/lib/implementations/napari-js/napari-spatial-hover.d.ts +89 -0
  300. package/lib/implementations/napari-js/napari-spatial-scene.d.ts +118 -0
  301. package/lib/implementations/napari-js/napari-spatial-tiles.d.ts +56 -263
  302. package/lib/implementations/napari-js/napari-spatial-tooltip.d.ts +1 -1
  303. package/lib/implementations/napari-js/napari-surface-scene.d.ts +76 -0
  304. package/lib/implementations/napari-js/napari-tile-client.d.ts +214 -0
  305. package/lib/implementations/napari-js/napari-tool-bridge.d.ts +179 -0
  306. package/lib/implementations/napari-js/napari-visualizer.service.d.ts +121 -883
  307. package/lib/implementations/napari-js/napari-volume-scene.d.ts +104 -0
  308. package/lib/implementations/napari-js/napari-volume-z-handle.d.ts +8 -12
  309. package/lib/implementations/napari-js/region-overlay/overlay-projection.d.ts +59 -0
  310. package/lib/implementations/napari-js/region-overlay/region-edit.d.ts +15 -0
  311. package/lib/implementations/napari-js/region-overlay/region-svg-renderer.d.ts +54 -0
  312. package/lib/implementations/napari-js/spatial-tiles/categorical-lookup.d.ts +26 -0
  313. package/lib/implementations/napari-js/spatial-tiles/cell-layers.d.ts +70 -0
  314. package/lib/implementations/napari-js/spatial-tiles/density-layer.d.ts +61 -0
  315. package/lib/implementations/napari-js/spatial-tiles/layer-groups.d.ts +67 -0
  316. package/lib/implementations/napari-js/spatial-tiles/plan-context.d.ts +38 -0
  317. package/lib/implementations/napari-js/spatial-tiles/transcript-hover.d.ts +71 -0
  318. package/lib/implementations/napari-js/spatial-tiles/transcript-jobs.d.ts +105 -0
  319. package/lib/implementations/napari-js/spatial-tiles/transcript-layers.d.ts +56 -0
  320. package/lib/implementations/osd/display-pipeline.d.ts +38 -9
  321. package/lib/implementations/osd/histogram-sampler.d.ts +22 -12
  322. package/lib/implementations/osd/openseadragon-viewer-options.d.ts +35 -0
  323. package/lib/implementations/osd/openseadragon-visualizer.service.d.ts +78 -354
  324. package/lib/implementations/osd/osd-coordinate-transform.d.ts +2 -1
  325. package/lib/implementations/osd/osd-coords.d.ts +6 -4
  326. package/lib/implementations/osd/osd-export.d.ts +36 -0
  327. package/lib/implementations/osd/osd-lib.d.ts +7 -0
  328. package/lib/implementations/osd/osd-navigator-chrome.d.ts +69 -0
  329. package/lib/implementations/osd/osd-pixel-readback.d.ts +22 -0
  330. package/lib/implementations/osd/osd-region-overlay-draw.d.ts +37 -0
  331. package/lib/implementations/osd/osd-region-overlay.d.ts +36 -48
  332. package/lib/implementations/osd/osd-scale-bar.d.ts +8 -6
  333. package/lib/implementations/osd/osd-tile-source.d.ts +49 -0
  334. package/lib/implementations/osd/osd-viewer-like.d.ts +100 -0
  335. package/lib/implementations/osd/osd-viewer-mount.d.ts +14 -0
  336. package/lib/implementations/osd/osd-viewport.d.ts +77 -0
  337. package/lib/implementations/osd/osd-zoom.d.ts +6 -0
  338. package/lib/implementations/osd/simple-source.d.ts +161 -0
  339. package/lib/implementations/osd/slice-cache.d.ts +12 -3
  340. package/lib/implementations/osd/tile-client.d.ts +11 -14
  341. package/lib/implementations/osd/tile-recolor.d.ts +141 -0
  342. package/lib/implementations/plotly/omics-trace-builders.d.ts +32 -20
  343. package/lib/implementations/plotly/plotly-image-loader.d.ts +49 -0
  344. package/lib/implementations/plotly/plotly-image-recolor.d.ts +75 -0
  345. package/lib/implementations/plotly/plotly-intensity-inset.d.ts +8 -0
  346. package/lib/implementations/plotly/plotly-isosurface-controls.d.ts +38 -0
  347. package/lib/implementations/plotly/plotly-layouts.d.ts +188 -0
  348. package/lib/implementations/plotly/plotly-readback.d.ts +41 -0
  349. package/lib/implementations/plotly/plotly-region-overlay.d.ts +2 -2
  350. package/lib/implementations/plotly/plotly-shape-projection.d.ts +92 -0
  351. package/lib/implementations/plotly/plotly-trace-builders.d.ts +23 -12
  352. package/lib/implementations/plotly/plotly-zoom-controller.d.ts +86 -0
  353. package/lib/implementations/plotly/plotly.service.d.ts +136 -401
  354. package/lib/implementations/region-centroids.d.ts +14 -0
  355. package/lib/implementations/simple-slice-access.service.d.ts +7 -4
  356. package/lib/implementations/spatial-data-http/spatial-data-http.service.d.ts +42 -18
  357. package/lib/implementations/spatial-data-http/spatial-wire.d.ts +34 -9
  358. package/lib/implementations/tile-server/index.d.ts +5 -0
  359. package/lib/implementations/tile-server/native-histogram.d.ts +25 -0
  360. package/lib/implementations/tile-server/poll-descriptor.d.ts +39 -0
  361. package/lib/implementations/tile-server/tile-protocol.d.ts +80 -0
  362. package/lib/implementations/tile-server/transport.d.ts +62 -0
  363. package/lib/intensity/intensity-profile.d.ts +66 -0
  364. package/lib/intensity/intensity-profile.service.d.ts +108 -0
  365. package/lib/intensity-inset/intensity-inset.component.d.ts +58 -0
  366. package/lib/models/bezier.d.ts +0 -5
  367. package/lib/models/class-preset.d.ts +18 -0
  368. package/lib/models/geometry.d.ts +14 -48
  369. package/lib/models/polygon-edit.d.ts +72 -0
  370. package/lib/models/polygon-factory.d.ts +40 -0
  371. package/lib/models/region-clone.d.ts +20 -0
  372. package/lib/models/region-geojson.d.ts +17 -0
  373. package/lib/models/region.d.ts +40 -4
  374. package/lib/models/shape.d.ts +8 -0
  375. package/lib/plot-mode/contribution-host.d.ts +125 -0
  376. package/lib/plot-mode/plot-type-menu.d.ts +60 -0
  377. package/lib/plot-mode/tool-params-model.d.ts +49 -0
  378. package/lib/plot.utilities.d.ts +19 -30
  379. package/lib/processing/processing-image.d.ts +5 -2
  380. package/lib/provide-visualization.d.ts +19 -2
  381. package/lib/region-editor/classes-panel/classes-panel.component.d.ts +56 -0
  382. package/lib/region-editor/file-stem.d.ts +7 -0
  383. package/lib/region-editor/manage-classes-dialog/manage-classes-dialog.component.d.ts +45 -0
  384. package/lib/region-editor/mask-export.service.d.ts +54 -0
  385. package/lib/region-editor/mask-raster.d.ts +2 -8
  386. package/lib/region-editor/region-color-dialog/region-color-dialog.component.d.ts +29 -0
  387. package/lib/region-editor/region-editor-help/region-editor-help.component.d.ts +11 -0
  388. package/lib/region-editor/region-editor.component.d.ts +166 -199
  389. package/lib/region-editor/region-metrics.d.ts +26 -0
  390. package/lib/region-editor/region-persistence.service.d.ts +69 -0
  391. package/lib/region-editor/region-table/region-table.component.d.ts +83 -0
  392. package/lib/region-editor/save-mask-dialog/save-mask-dialog.component.d.ts +36 -0
  393. package/lib/region-editor/save-regions-dialog/save-regions-dialog.component.d.ts +37 -0
  394. package/lib/region-ops.service.d.ts +1 -7
  395. package/lib/region-overlay/region-geometry.d.ts +157 -0
  396. package/lib/region-overlay/region-hit-test.d.ts +38 -0
  397. package/lib/region-overlay/svg-region-renderer.d.ts +110 -0
  398. package/lib/render-orchestrator.d.ts +6 -2
  399. package/lib/render-session.d.ts +75 -0
  400. package/lib/routing-visualizer.service.d.ts +110 -58
  401. package/lib/spatial/density-raster.d.ts +6 -0
  402. package/lib/spatial/embedding-compute-coordinator.d.ts +123 -0
  403. package/lib/spatial/embedding-compute.d.ts +21 -2
  404. package/lib/spatial/glyphs.d.ts +16 -0
  405. package/lib/spatial/lod.d.ts +94 -0
  406. package/lib/spatial/spatial-controls.facade.d.ts +64 -0
  407. package/lib/spatial/spatial-density.d.ts +15 -5
  408. package/lib/spatial/spatial-encoding.d.ts +11 -44
  409. package/lib/spatial/spatial-expression.d.ts +40 -22
  410. package/lib/spatial/spatial-framing.d.ts +1 -0
  411. package/lib/spatial/spatial-heatmap.d.ts +2 -0
  412. package/lib/spatial/spatial-hover.d.ts +4 -16
  413. package/lib/spatial/spatial-panel-model.d.ts +135 -0
  414. package/lib/spatial/spatial-selection.d.ts +21 -26
  415. package/lib/spatial/spatial-tile-merge.d.ts +41 -0
  416. package/lib/spatial/spatial-tiles.d.ts +9 -256
  417. package/lib/spatial/stats.d.ts +38 -0
  418. package/lib/spatial/transcript-grouping.d.ts +119 -0
  419. package/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.d.ts +64 -0
  420. package/lib/spatial-controls/spatial-charts/chart-data-model.d.ts +153 -0
  421. package/lib/spatial-controls/spatial-charts/chart-help.d.ts +69 -0
  422. package/lib/spatial-controls/spatial-charts/plotly-chart-host.d.ts +98 -0
  423. package/lib/spatial-controls/spatial-charts/spatial-chart-window/spatial-chart-window.component.d.ts +26 -0
  424. package/lib/spatial-controls/spatial-charts/spatial-charts.component.d.ts +101 -260
  425. package/lib/spatial-controls/spatial-charts/spatial-embedding-controls/spatial-embedding-controls.component.d.ts +43 -0
  426. package/lib/spatial-controls/spatial-charts/spatial-heatmap-controls/spatial-heatmap-controls.component.d.ts +27 -0
  427. package/lib/spatial-controls/spatial-controls.component.d.ts +68 -448
  428. package/lib/spatial-controls/spatial-gene-picker.d.ts +86 -0
  429. package/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.d.ts +102 -0
  430. package/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.d.ts +72 -0
  431. package/lib/spatial-controls/spatial-key/spatial-key.component.d.ts +66 -0
  432. package/lib/spatial-controls/spatial-key/spatial-key.model.d.ts +33 -0
  433. package/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.d.ts +64 -0
  434. package/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.d.ts +117 -0
  435. package/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.d.ts +142 -0
  436. package/lib/store/class-color.util.d.ts +35 -1
  437. package/lib/store/region-history.d.ts +66 -0
  438. package/lib/store/region-scope-cache.d.ts +63 -0
  439. package/lib/store/region-selection.d.ts +36 -0
  440. package/lib/store/region-store.service.d.ts +104 -112
  441. package/lib/store/visualizer-store.service.d.ts +22 -33
  442. package/lib/toast-outlets.d.ts +4 -3
  443. package/lib/toolbar/brush/brush-tool.service.d.ts +31 -98
  444. package/lib/toolbar/canvas-tools.d.ts +20 -0
  445. package/lib/toolbar/crop/slide-crop.d.ts +10 -4
  446. package/lib/toolbar/plot-type-selector/plot-type-selector.component.d.ts +38 -0
  447. package/lib/toolbar/region-tools/region-tool-buttons.d.ts +21 -0
  448. package/lib/toolbar/region-tools/region-tools.component.d.ts +60 -0
  449. package/lib/toolbar/segmentation/cell-segment-tool.service.d.ts +10 -14
  450. package/lib/toolbar/segmentation/cellpose-segmenter.service.d.ts +12 -2
  451. package/lib/toolbar/segmentation/onnx-sam-session.d.ts +22 -3
  452. package/lib/toolbar/segmentation/pending-calls.d.ts +31 -0
  453. package/lib/toolbar/segmentation/sam-model-registry.d.ts +9 -3
  454. package/lib/toolbar/segmentation/sam-onnx-core.d.ts +18 -5
  455. package/lib/toolbar/segmentation/sam-point-tool.service.d.ts +46 -32
  456. package/lib/toolbar/segmentation/sam-prompt.d.ts +7 -31
  457. package/lib/toolbar/segmentation/sam-session.service.d.ts +74 -0
  458. package/lib/toolbar/segmentation/sam-tool.service.d.ts +23 -30
  459. package/lib/toolbar/segmentation/segmentation-commit.d.ts +8 -0
  460. package/lib/toolbar/segmentation/segmentation-runner.d.ts +52 -0
  461. package/lib/toolbar/segmentation-tools/segmentation-tools.component.d.ts +87 -0
  462. package/lib/toolbar/stack-controls/stack-controls.component.d.ts +40 -0
  463. package/lib/toolbar/tool-kit/async-tool-status.d.ts +21 -0
  464. package/lib/toolbar/tool-kit/canvas-tool-manager.d.ts +36 -0
  465. package/lib/toolbar/tool-kit/canvas-tool.d.ts +86 -0
  466. package/lib/toolbar/tool-kit/frame-pixels.d.ts +45 -0
  467. package/lib/toolbar/tool-kit/mask-stroke-editor.d.ts +125 -0
  468. package/lib/toolbar/tool-kit/matrix-frame.d.ts +40 -0
  469. package/lib/toolbar/tool-kit/tool-overlay.d.ts +60 -0
  470. package/lib/toolbar/tool-kit/undo-gesture.d.ts +17 -0
  471. package/lib/toolbar/tool-slider/tool-slider.component.d.ts +33 -0
  472. package/lib/toolbar/toolbar-help-dialog/toolbar-help-dialog.component.d.ts +24 -0
  473. package/lib/toolbar/toolbar.component.d.ts +47 -83
  474. package/lib/toolbar/vertex-eraser/vertex-eraser-tool.service.d.ts +33 -40
  475. package/lib/toolbar/view-controls/view-controls.component.d.ts +54 -0
  476. package/lib/toolbar/wand/wand-region-grow.d.ts +49 -0
  477. package/lib/toolbar/wand/wand-tool.service.d.ts +39 -124
  478. package/lib/toolbar/wand/wand.service.d.ts +22 -116
  479. package/lib/toolbar/zoom-to-box/zoom-to-box-tool.service.d.ts +17 -37
  480. package/lib/util/mark-for-check.d.ts +11 -0
  481. package/lib/util/supersede.d.ts +53 -0
  482. package/lib/visualization.module.d.ts +18 -39
  483. package/lib/visualizer/floating-drag.directive.d.ts +30 -0
  484. package/lib/visualizer/region-actions.d.ts +54 -0
  485. package/lib/visualizer/region-load.d.ts +27 -0
  486. package/lib/visualizer/spatial-dataset-binder.d.ts +74 -0
  487. package/lib/visualizer/tool-modes.d.ts +49 -0
  488. package/lib/visualizer/viewer-shortcuts.d.ts +71 -0
  489. package/lib/visualizer/visualizer-context-menu.d.ts +55 -0
  490. package/lib/visualizer.component.d.ts +201 -447
  491. package/lib/workers/spatial-math-ops.d.ts +65 -0
  492. package/lib/workers/spatial-math-worker.d.ts +7 -0
  493. package/lib/workers/spatial-math.d.ts +74 -0
  494. package/package.json +12 -3
  495. package/src/lib/styles/_viz-icons-rules.scss +73 -0
  496. package/src/lib/styles/viz-icons.scss +14 -0
  497. package/esm2022/lib/implementations/napari-js/napari-axes-labels.mjs +0 -97
  498. package/esm2022/lib/implementations/napari-js/napari-navigator.mjs +0 -195
  499. package/esm2022/lib/implementations/napari-js/napari-scale-bar.mjs +0 -92
  500. package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-BwP-A11m.mjs +0 -329
  501. package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-BwP-A11m.mjs.map +0 -1
  502. package/lib/implementations/napari-js/napari-axes-labels.d.ts +0 -49
  503. package/lib/implementations/napari-js/napari-navigator.d.ts +0 -72
  504. package/lib/implementations/napari-js/napari-scale-bar.d.ts +0 -35
  505. package/src/lib/assets/cell-detection.svg +0 -37
  506. package/src/lib/assets/click.svg +0 -1
  507. package/src/lib/assets/colormap-luts.json +0 -1
  508. package/src/lib/assets/edit-selection-white.svg +0 -47
  509. package/src/lib/assets/icons/colormap-earth.png +0 -0
  510. package/src/lib/assets/icons/colormap-placeholder.png +0 -0
  511. package/src/lib/assets/icons/colormap-pubu.png +0 -0
  512. package/src/lib/assets/interactive-segmentation-cursor.svg +0 -1
  513. package/src/lib/assets/picture-segmentation.svg +0 -43
  514. package/src/lib/assets/test/download-379.svg +0 -1
  515. package/src/lib/assets/test/download-98.svg +0 -1
  516. package/src/lib/assets/test/json-1.svg +0 -1
  517. package/src/lib/assets/test/load-53.svg +0 -1
  518. package/src/lib/assets/test/mask-44.svg +0 -1
  519. package/src/lib/assets/test/mask-download-44.svg +0 -15
  520. package/src/lib/assets/test/mask-save-44.svg +0 -11
  521. package/src/lib/assets/test/overlay-1.svg +0 -1
  522. package/src/lib/assets/test/overlay-4.svg +0 -1
  523. package/src/lib/assets/test/region-26.svg +0 -1
  524. package/src/lib/assets/test/save-56.svg +0 -1
  525. package/src/lib/assets/test/upload-43.svg +0 -1
@@ -0,0 +1,65 @@
1
+ import type { SpatialObservations } from '../contracts/spatial-dataset.contract';
2
+ import { DensityGrid, DensityOptions } from '../spatial/spatial-density';
3
+ import { ExpressionField, ExpressionFieldOptions, ExpressionVolumeField, ExpressionVolumeOptions } from '../spatial/spatial-expression';
4
+ import { HeatmapGene, HeatmapGroups, HeatmapMatrix, HeatmapMatrixOptions } from '../spatial/spatial-heatmap';
5
+ /**
6
+ * The pure spatial field and density math, as messages: what crosses into
7
+ * `spatial-math.worker` and what comes back, and the one dispatcher both the worker and
8
+ * the main-thread fallback run. DOM-free and Angular-free, because the worker bundles it.
9
+ */
10
+ /**
11
+ * Just the coordinates of {@link SpatialObservations}: all the math reads. Cloning the
12
+ * full observations would also copy `ids` — millions of strings on a large dataset.
13
+ */
14
+ export type SpatialMathObservations = Pick<SpatialObservations, 'count' | 'x' | 'y' | 'z'>;
15
+ /** One computation, by name, with the arguments of the synchronous function it runs. */
16
+ export type SpatialMathRequest = {
17
+ op: 'expressionField';
18
+ obs: SpatialMathObservations;
19
+ opts: ExpressionFieldOptions;
20
+ } | {
21
+ op: 'expressionVolume';
22
+ obs: SpatialMathObservations;
23
+ grid: DensityGrid;
24
+ opts: ExpressionVolumeOptions;
25
+ } | {
26
+ op: 'rasterizeDensity';
27
+ obs: SpatialMathObservations;
28
+ grid: DensityGrid;
29
+ opts: DensityOptions;
30
+ } | {
31
+ op: 'heatmapMatrix';
32
+ genes: readonly HeatmapGene[];
33
+ groups: HeatmapGroups;
34
+ opts: HeatmapMatrixOptions;
35
+ };
36
+ /** What each {@link SpatialMathRequest} op resolves to. */
37
+ export interface SpatialMathResults {
38
+ expressionField: ExpressionField | null;
39
+ expressionVolume: ExpressionVolumeField | null;
40
+ rasterizeDensity: Uint8Array | null;
41
+ heatmapMatrix: HeatmapMatrix | null;
42
+ }
43
+ /** A request on the wire: the computation plus the id its answer is matched by. */
44
+ export type SpatialMathMessage = SpatialMathRequest & {
45
+ id: number;
46
+ };
47
+ /** The worker's answer to one {@link SpatialMathMessage}. */
48
+ export type SpatialMathReply = {
49
+ id: number;
50
+ ok: true;
51
+ result: SpatialMathResults[keyof SpatialMathResults];
52
+ } | {
53
+ id: number;
54
+ ok: false;
55
+ error: string;
56
+ };
57
+ /** The coordinates of `obs`, without the per-observation strings the math never reads. */
58
+ export declare function slimObservations(obs: SpatialMathObservations): SpatialMathObservations;
59
+ /** Run one request synchronously — in the worker, or on the main thread as the fallback. */
60
+ export declare function runSpatialMath<R extends SpatialMathRequest>(request: R): SpatialMathResults[R['op']];
61
+ /**
62
+ * The buffers of a result, to transfer rather than copy back: the worker made them and
63
+ * never reads them again. Deduplicated, since a transfer list may not name one twice.
64
+ */
65
+ export declare function resultTransferables(result: unknown): ArrayBuffer[];
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Factory for the spatial-math Web Worker, isolated in its own module so the
3
+ * `import.meta.url` reference — which the bundler needs in order to locate the worker —
4
+ * is never pulled into the ts-jest CommonJS compile of anything that uses it. Same
5
+ * arrangement as `spatial/tsne-worker.ts` and `region-editor/mask-worker.ts`.
6
+ */
7
+ export declare function createSpatialMathWorker(): Worker;
@@ -0,0 +1,74 @@
1
+ import type { SpatialObservations } from '../contracts/spatial-dataset.contract';
2
+ import type { DensityGrid, DensityOptions } from '../spatial/spatial-density';
3
+ import type { ExpressionField, ExpressionFieldOptions, ExpressionVolumeField, ExpressionVolumeOptions } from '../spatial/spatial-expression';
4
+ import type { HeatmapGene, HeatmapGroups, HeatmapMatrix, HeatmapMatrixOptions } from '../spatial/spatial-heatmap';
5
+ import { SpatialMathRequest, SpatialMathResults } from './spatial-math-ops';
6
+ /**
7
+ * Async, off-main-thread versions of the pure spatial field and density math
8
+ * (`expressionField`, `expressionVolume`, `rasterizeDensity`, `heatmapMatrix`).
9
+ *
10
+ * Each call runs in `spatial-math.worker` when it is big enough to be worth posting, and
11
+ * on the main thread otherwise — below {@link SPATIAL_MATH_WORKER_MIN_OBSERVATIONS}, where
12
+ * Web Workers do not exist (jsdom, SSR), or when the worker fails to start. Same
13
+ * function, same answer either way; only where it runs changes.
14
+ *
15
+ * Inputs are copied to the worker, never transferred: they are the dataset's own arrays,
16
+ * which the caller keeps using. Results are transferred back.
17
+ *
18
+ * An `AbortSignal` (a `Supersede` task's, typically) rejects the call with an
19
+ * `AbortError` as soon as it fires. When that leaves the worker with nothing else to do,
20
+ * the worker is terminated so the abandoned computation stops using the CPU; the next
21
+ * call starts a fresh one.
22
+ */
23
+ /**
24
+ * Below this many observations (genes × observations for a heatmap) a call runs on the
25
+ * main thread: copying the inputs to a worker would cost about what it saves.
26
+ */
27
+ export declare const SPATIAL_MATH_WORKER_MIN_OBSERVATIONS = 50000;
28
+ /** Per-call options of the async spatial math. */
29
+ export interface SpatialMathCallOptions {
30
+ /** Abandon the call: it rejects with an `AbortError` and its result is dropped. */
31
+ signal?: AbortSignal;
32
+ /** Override {@link SPATIAL_MATH_WORKER_MIN_OBSERVATIONS} for this call (0 forces the worker). */
33
+ minObservations?: number;
34
+ }
35
+ /** Makes the worker; may be async, as the default one is (it imports the factory on demand). */
36
+ export type SpatialMathWorkerFactory = () => Worker | Promise<Worker>;
37
+ /**
38
+ * Owns one spatial-math worker and the calls in flight on it. The module-level functions
39
+ * share one instance; a test, or a caller that wants its own worker, makes another.
40
+ */
41
+ export declare class SpatialMathClient {
42
+ private readonly factory?;
43
+ private worker;
44
+ private starting;
45
+ /** Set once the worker failed to start or crashed: every later call runs here. */
46
+ private unavailable;
47
+ private nextId;
48
+ private readonly pending;
49
+ /**
50
+ * `factory` is optional: without one the real worker module is imported on demand —
51
+ * dynamically, because it holds an `import.meta.url` that ts-jest's CommonJS compile
52
+ * rejects, so a static import would break every spec that reaches this file.
53
+ */
54
+ constructor(factory?: SpatialMathWorkerFactory | undefined);
55
+ /** Run `request`, in the worker when `size` reaches the threshold and a worker can run. */
56
+ run<R extends SpatialMathRequest>(request: R, size: number, options?: SpatialMathCallOptions): Promise<SpatialMathResults[R['op']]>;
57
+ /** Terminate the worker; calls still in flight reject with an `AbortError`. */
58
+ dispose(): void;
59
+ private post;
60
+ private ensureWorker;
61
+ private startWorker;
62
+ private onReply;
63
+ /** The worker died (failed to load, or threw outside a request): answer every call here. */
64
+ private onCrash;
65
+ private stopWorker;
66
+ }
67
+ /** {@link expressionField}, off the main thread when it is big enough to matter. */
68
+ export declare function computeExpressionFieldAsync(obs: SpatialObservations, opts: ExpressionFieldOptions, options?: SpatialMathCallOptions): Promise<ExpressionField | null>;
69
+ /** {@link expressionVolume}, off the main thread when it is big enough to matter. */
70
+ export declare function computeExpressionVolumeAsync(obs: SpatialObservations, grid: DensityGrid, opts: ExpressionVolumeOptions, options?: SpatialMathCallOptions): Promise<ExpressionVolumeField | null>;
71
+ /** {@link rasterizeDensity}, off the main thread when it is big enough to matter. */
72
+ export declare function rasterizeDensityAsync(obs: SpatialObservations, grid: DensityGrid, opts: DensityOptions, options?: SpatialMathCallOptions): Promise<Uint8Array | null>;
73
+ /** {@link heatmapMatrix}, off the main thread when it is big enough to matter. */
74
+ export declare function computeHeatmapMatrixAsync(genes: readonly HeatmapGene[], groups: HeatmapGroups, opts?: HeatmapMatrixOptions, options?: SpatialMathCallOptions): Promise<HeatmapMatrix | null>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jax-data-science/sci-image-visualizer",
3
- "version": "0.8.3",
3
+ "version": "0.9.0",
4
4
  "engines": {
5
5
  "node": ">=20.9.0"
6
6
  },
@@ -37,10 +37,9 @@
37
37
  "access": "public"
38
38
  },
39
39
  "dependencies": {
40
- "@jax-js/jax": "^0.1.24",
41
40
  "cellpose-js": "^0.6.0",
42
41
  "fast-png": "^6.4.0",
43
- "napari-js": "^0.14.0",
42
+ "napari-js": "^0.15.0",
44
43
  "openseadragon": "^6.0.2",
45
44
  "plotly.js-dist-min": "^3.0.1",
46
45
  "tslib": "^2.3.0"
@@ -55,9 +54,19 @@
55
54
  "file-saver": "^2.0.5",
56
55
  "image-js": "^0.35.6",
57
56
  "onnxruntime-web": "~1.26.0",
57
+ "primeflex": "^3.3.0 || ^4.0.0",
58
+ "primeicons": "^7.0.0",
58
59
  "primeng": "^17.18.0",
59
60
  "rxjs": "^7.8.0"
60
61
  },
62
+ "peerDependenciesMeta": {
63
+ "primeflex": {
64
+ "optional": true
65
+ },
66
+ "primeicons": {
67
+ "optional": true
68
+ }
69
+ },
61
70
  "overrides": {
62
71
  "@ngtools/webpack": "17.3.17"
63
72
  },
@@ -0,0 +1,73 @@
1
+ @use 'sass:list';
2
+
3
+ // The visualizer's toolbar / context-menu icon classes, as a mixin so the same rules can
4
+ // be emitted from two places with the right asset path for each:
5
+ // - `viz-icons.scss`, the stylesheet the package ships for hosts (global styles);
6
+ // - the visualizer component, inside `::ng-deep`, so nothing changes for a host that
7
+ // does not include the shipped stylesheet.
8
+ // They must be global either way: the context menu and the toolbar overlays are appended
9
+ // to <body>, outside the component's view.
10
+
11
+ $icons: (
12
+ 'zoom-box-off-icon': 'zoom-box',
13
+ 'wand-icon': 'wand',
14
+ 'brush-icon': 'paintbrush',
15
+ 'polyline-icon': 'polyline',
16
+ 'polygon-vertices-icon': 'polygon-vertices',
17
+ 'vertex-add-icon': 'vertex-add',
18
+ 'vertex-delete-icon': 'vertex-delete',
19
+ 'region-move-icon': 'region-move',
20
+ 'to-bezier-icon': 'to-bezier',
21
+ 'to-polygon-icon': 'to-polygon',
22
+ );
23
+
24
+ // Icons inverted to white on the highlighted (active) context-menu entry.
25
+ $context-menu-icons: (
26
+ 'zoom-box-off-icon',
27
+ 'wand-icon',
28
+ 'polyline-icon',
29
+ 'polygon-vertices-icon',
30
+ 'vertex-add-icon',
31
+ 'vertex-delete-icon',
32
+ 'region-move-icon',
33
+ 'to-bezier-icon',
34
+ 'to-polygon-icon'
35
+ );
36
+
37
+ /// Emit the icon and active-context-menu rules. `$assets` is the path, relative to the
38
+ /// stylesheet being compiled, of the package's `src/lib/assets` folder.
39
+ @mixin rules($assets) {
40
+ .context-menu-active > .p-menuitem-content {
41
+ background-color: var(--primary-color) !important;
42
+ }
43
+
44
+ .context-menu-active > .p-menuitem-content .p-menuitem-icon,
45
+ .context-menu-active > .p-menuitem-content .p-menuitem-text {
46
+ color: #ffffff !important;
47
+ }
48
+
49
+ $active: ();
50
+ @each $class in $context-menu-icons {
51
+ $active: list.append($active, '.context-menu-active > .p-menuitem-content .#{$class}', $separator: comma);
52
+ }
53
+ #{$active} {
54
+ filter: brightness(0) invert(1);
55
+ }
56
+
57
+ @each $class, $file in $icons {
58
+ .#{$class} {
59
+ background: url('#{$assets}/#{$file}.svg') no-repeat center center;
60
+ background-size: contain;
61
+ width: 1.25rem;
62
+ height: 1.25rem;
63
+ display: inline-block;
64
+ filter: brightness(0)
65
+ invert(47%)
66
+ sepia(98%)
67
+ saturate(567%)
68
+ hue-rotate(181deg)
69
+ brightness(103%)
70
+ contrast(98%);
71
+ }
72
+ }
73
+ }
@@ -0,0 +1,14 @@
1
+ // Global icon rules of the visualizer's toolbar and context menu, shipped for hosts.
2
+ //
3
+ // The visualizer component also emits these when it loads, so including this file is
4
+ // optional. Include it to have the classes defined before any visualizer has loaded (a
5
+ // host toolbar or menu that reuses them), and independent of stylesheet load order. In
6
+ // angular.json:
7
+ //
8
+ // "styles": ["node_modules/@jax-data-science/sci-image-visualizer/src/lib/styles/viz-icons.scss"]
9
+ //
10
+ // The icon URLs are relative to this file (`../assets/*.svg`, the package's assets folder),
11
+ // which the Angular CLI resolves and bundles.
12
+ @use 'viz-icons-rules';
13
+
14
+ @include viz-icons-rules.rules('../assets');
@@ -1,97 +0,0 @@
1
- /**
2
- * DOM text labels for the napari-js 3D axes gizmo (jit-ui#102). The {@link AxesLayer} draws the
3
- * axis lines/ticks/box in WebGPU; this overlay adds the crisp X/Y/Z + scale text on top, projected
4
- * with the 3D camera's view-projection so each label tracks its anchor as the volume orbits.
5
- * Mirrors the {@link NapariScaleBar} overlay pattern (absolute-positioned over the host, updated on
6
- * every `camera3d.changed`). Falls back to pixel/slice counts when no physical µm/pixel is known.
7
- */
8
- /**
9
- * Re-exported from napari-js, which owns the projection now.
10
- *
11
- * This used to be a local copy: the same column-major multiply, perspective divide and y-flip
12
- * that {@link NapariVisualizerService.getSpatialScreenProjection} ALSO carried, written twice
13
- * with two different behind-the-eye conventions. The renderer owns the camera and the clip
14
- * convention, so it owns the projection; kept as a named export here only so the overlays that
15
- * import it from this module do not all have to change.
16
- */
17
- import { projectPoint } from 'napari-js';
18
- export { projectPoint };
19
- export class NapariAxesLabels {
20
- constructor(host, camera3d, labels) {
21
- this.host = host;
22
- this.camera3d = camera3d;
23
- this.labels = labels;
24
- this.els = [];
25
- this.visible = true;
26
- if (getComputedStyle(host).position === 'static')
27
- host.style.position = 'relative';
28
- for (const spec of labels) {
29
- const el = document.createElement('span');
30
- Object.assign(el.style, {
31
- position: 'absolute',
32
- zIndex: '30',
33
- pointerEvents: 'none',
34
- font: '11px sans-serif',
35
- fontWeight: '600',
36
- color: spec.color,
37
- textShadow: '0 0 3px #000, 0 0 3px #000',
38
- whiteSpace: 'nowrap',
39
- transform: 'translate(-50%, -50%)',
40
- userSelect: 'none',
41
- });
42
- el.textContent = spec.text;
43
- this.host.appendChild(el);
44
- this.els.push(el);
45
- }
46
- this.disconnectCamera = this.camera3d.changed.connect(() => this.update());
47
- if (typeof ResizeObserver !== 'undefined') {
48
- this.resizeObserver = new ResizeObserver(() => this.update());
49
- this.resizeObserver.observe(this.host);
50
- }
51
- this.update();
52
- }
53
- setVisible(visible) {
54
- this.visible = visible;
55
- this.update();
56
- }
57
- /** Replace the label anchors/text in place (same count) and reproject — lets a host move the
58
- * labels when the box geometry changes live (e.g. a Z-height gizmo restretching the volume)
59
- * without tearing down and recreating the DOM elements (which would flicker). */
60
- updateAnchors(labels) {
61
- for (let i = 0; i < this.labels.length && i < labels.length; i++) {
62
- this.labels[i] = labels[i];
63
- if (labels[i].text !== this.els[i].textContent)
64
- this.els[i].textContent = labels[i].text;
65
- }
66
- this.update();
67
- }
68
- update() {
69
- const vw = this.host.clientWidth;
70
- const vh = this.host.clientHeight;
71
- if (!this.visible || vw <= 0 || vh <= 0) {
72
- for (const el of this.els)
73
- el.style.display = 'none';
74
- return;
75
- }
76
- const mvp = this.camera3d.viewProjection(vw, vh);
77
- this.labels.forEach((spec, i) => {
78
- const el = this.els[i];
79
- const s = projectPoint(mvp, spec.anchor, vw, vh);
80
- if (!s.visible) {
81
- el.style.display = 'none';
82
- return;
83
- }
84
- el.style.display = '';
85
- el.style.left = `${s.x}px`;
86
- el.style.top = `${s.y}px`;
87
- });
88
- }
89
- destroy() {
90
- this.disconnectCamera();
91
- this.resizeObserver?.disconnect();
92
- for (const el of this.els)
93
- el.parentNode?.removeChild(el);
94
- this.els.length = 0;
95
- }
96
- }
97
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFwYXJpLWF4ZXMtbGFiZWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9pbXBsZW1lbnRhdGlvbnMvbmFwYXJpLWpzL25hcGFyaS1heGVzLWxhYmVscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFnQkg7Ozs7Ozs7O0dBUUc7QUFDSCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBRXpDLE9BQU8sRUFBRSxZQUFZLEVBQUUsQ0FBQztBQUV4QixNQUFNLE9BQU8sZ0JBQWdCO0lBTTNCLFlBQ21CLElBQWlCLEVBQ2pCLFFBQTJCLEVBQzNCLE1BQXVCO1FBRnZCLFNBQUksR0FBSixJQUFJLENBQWE7UUFDakIsYUFBUSxHQUFSLFFBQVEsQ0FBbUI7UUFDM0IsV0FBTSxHQUFOLE1BQU0sQ0FBaUI7UUFSekIsUUFBRyxHQUFzQixFQUFFLENBQUM7UUFHckMsWUFBTyxHQUFHLElBQUksQ0FBQztRQU9yQixJQUFJLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDLFFBQVEsS0FBSyxRQUFRO1lBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLEdBQUcsVUFBVSxDQUFDO1FBQ25GLEtBQUssTUFBTSxJQUFJLElBQUksTUFBTSxFQUFFLENBQUM7WUFDMUIsTUFBTSxFQUFFLEdBQUcsUUFBUSxDQUFDLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUMxQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUU7Z0JBQ3RCLFFBQVEsRUFBRSxVQUFVO2dCQUNwQixNQUFNLEVBQUUsSUFBSTtnQkFDWixhQUFhLEVBQUUsTUFBTTtnQkFDckIsSUFBSSxFQUFFLGlCQUFpQjtnQkFDdkIsVUFBVSxFQUFFLEtBQUs7Z0JBQ2pCLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztnQkFDakIsVUFBVSxFQUFFLDRCQUE0QjtnQkFDeEMsVUFBVSxFQUFFLFFBQVE7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QUFPO1lBQ1QsQ0FBQztZQUNELEVBQUUsQ0FBQyxLQUFLLENBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztZQUN0QixFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztZQUMzQixFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUM1QixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFRCxPQUFPO1FBQ0wsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDeEIsSUFBSSxDQUFDLGNBQWMsRUFBRSxVQUFVLEVBQUUsQ0FBQztRQUNsQyxLQUFLLE1BQU0sRUFBRSxJQUFJLElBQUksQ0FBQyxHQUFHO1lBQUUsRUFBRSxDQUFDLFVBQVUsRUFBRSxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDMUQsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0lBQ3RCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRE9NIHRleHQgbGFiZWxzIGZvciB0aGUgbmFwYXJpLWpzIDNEIGF4ZXMgZ2l6bW8gKGppdC11aSMxMDIpLiBUaGUge0BsaW5rIEF4ZXNMYXllcn0gZHJhd3MgdGhlXG4gKiBheGlzIGxpbmVzL3RpY2tzL2JveCBpbiBXZWJHUFU7IHRoaXMgb3ZlcmxheSBhZGRzIHRoZSBjcmlzcCBYL1kvWiArIHNjYWxlIHRleHQgb24gdG9wLCBwcm9qZWN0ZWRcbiAqIHdpdGggdGhlIDNEIGNhbWVyYSdzIHZpZXctcHJvamVjdGlvbiBzbyBlYWNoIGxhYmVsIHRyYWNrcyBpdHMgYW5jaG9yIGFzIHRoZSB2b2x1bWUgb3JiaXRzLlxuICogTWlycm9ycyB0aGUge0BsaW5rIE5hcGFyaVNjYWxlQmFyfSBvdmVybGF5IHBhdHRlcm4gKGFic29sdXRlLXBvc2l0aW9uZWQgb3ZlciB0aGUgaG9zdCwgdXBkYXRlZCBvblxuICogZXZlcnkgYGNhbWVyYTNkLmNoYW5nZWRgKS4gRmFsbHMgYmFjayB0byBwaXhlbC9zbGljZSBjb3VudHMgd2hlbiBubyBwaHlzaWNhbCDCtW0vcGl4ZWwgaXMga25vd24uXG4gKi9cblxuLyoqIE9uZSBheGlzIGxhYmVsOiBhIHdvcmxkLXNwYWNlIGFuY2hvciAodGhlIGF4aXMgZW5kLCBpbiB0aGUgdm9sdW1lJ3MgY2VudHJlZCBib3gpLCB0aGUgdGV4dCB0b1xuICogIHNob3csIGFuZCBpdHMgY29sb3VyIChtYXRjaGluZyB0aGUgV2ViR1BVIGF4aXMgY29sb3VyKS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXhpc0xhYmVsU3BlYyB7XG4gIGFuY2hvcjogW251bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuICB0ZXh0OiBzdHJpbmc7XG4gIGNvbG9yOiBzdHJpbmc7XG59XG5cbi8qKiBUaGUgc2xpY2Ugb2YgbmFwYXJpJ3MgQ2FtZXJhM0QgdGhpcyBvdmVybGF5IHJlYWRzLiBgdmlld1Byb2plY3Rpb25gIGlzIGNvbHVtbi1tYWpvciAoZ2wtbWF0cml4KS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXhlc0xhYmVsQ2FtZXJhM0Qge1xuICB2aWV3UHJvamVjdGlvbih2dzogbnVtYmVyLCB2aDogbnVtYmVyKTogQXJyYXlMaWtlPG51bWJlcj47XG4gIHJlYWRvbmx5IGNoYW5nZWQ6IHsgY29ubmVjdChsaXN0ZW5lcjogKCkgPT4gdm9pZCk6ICgpID0+IHZvaWQgfTtcbn1cblxuLyoqXG4gKiBSZS1leHBvcnRlZCBmcm9tIG5hcGFyaS1qcywgd2hpY2ggb3ducyB0aGUgcHJvamVjdGlvbiBub3cuXG4gKlxuICogVGhpcyB1c2VkIHRvIGJlIGEgbG9jYWwgY29weTogdGhlIHNhbWUgY29sdW1uLW1ham9yIG11bHRpcGx5LCBwZXJzcGVjdGl2ZSBkaXZpZGUgYW5kIHktZmxpcFxuICogdGhhdCB7QGxpbmsgTmFwYXJpVmlzdWFsaXplclNlcnZpY2UuZ2V0U3BhdGlhbFNjcmVlblByb2plY3Rpb259IEFMU08gY2FycmllZCwgd3JpdHRlbiB0d2ljZVxuICogd2l0aCB0d28gZGlmZmVyZW50IGJlaGluZC10aGUtZXllIGNvbnZlbnRpb25zLiBUaGUgcmVuZGVyZXIgb3ducyB0aGUgY2FtZXJhIGFuZCB0aGUgY2xpcFxuICogY29udmVudGlvbiwgc28gaXQgb3ducyB0aGUgcHJvamVjdGlvbjsga2VwdCBhcyBhIG5hbWVkIGV4cG9ydCBoZXJlIG9ubHkgc28gdGhlIG92ZXJsYXlzIHRoYXRcbiAqIGltcG9ydCBpdCBmcm9tIHRoaXMgbW9kdWxlIGRvIG5vdCBhbGwgaGF2ZSB0byBjaGFuZ2UuXG4gKi9cbmltcG9ydCB7IHByb2plY3RQb2ludCB9IGZyb20gJ25hcGFyaS1qcyc7XG5cbmV4cG9ydCB7IHByb2plY3RQb2ludCB9O1xuXG5leHBvcnQgY2xhc3MgTmFwYXJpQXhlc0xhYmVscyB7XG4gIHByaXZhdGUgcmVhZG9ubHkgZWxzOiBIVE1MU3BhbkVsZW1lbnRbXSA9IFtdO1xuICBwcml2YXRlIHJlYWRvbmx5IGRpc2Nvbm5lY3RDYW1lcmE6ICgpID0+IHZvaWQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVzaXplT2JzZXJ2ZXI/OiBSZXNpemVPYnNlcnZlcjtcbiAgcHJpdmF0ZSB2aXNpYmxlID0gdHJ1ZTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IGhvc3Q6IEhUTUxFbGVtZW50LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY2FtZXJhM2Q6IEF4ZXNMYWJlbENhbWVyYTNELFxuICAgIHByaXZhdGUgcmVhZG9ubHkgbGFiZWxzOiBBeGlzTGFiZWxTcGVjW10sXG4gICkge1xuICAgIGlmIChnZXRDb21wdXRlZFN0eWxlKGhvc3QpLnBvc2l0aW9uID09PSAnc3RhdGljJykgaG9zdC5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XG4gICAgZm9yIChjb25zdCBzcGVjIG9mIGxhYmVscykge1xuICAgICAgY29uc3QgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzcGFuJyk7XG4gICAgICBPYmplY3QuYXNzaWduKGVsLnN0eWxlLCB7XG4gICAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgICB6SW5kZXg6ICczMCcsXG4gICAgICAgIHBvaW50ZXJFdmVudHM6ICdub25lJyxcbiAgICAgICAgZm9udDogJzExcHggc2Fucy1zZXJpZicsXG4gICAgICAgIGZvbnRXZWlnaHQ6ICc2MDAnLFxuICAgICAgICBjb2xvcjogc3BlYy5jb2xvcixcbiAgICAgICAgdGV4dFNoYWRvdzogJzAgMCAzcHggIzAwMCwgMCAwIDNweCAjMDAwJyxcbiAgICAgICAgd2hpdGVTcGFjZTogJ25vd3JhcCcsXG4gICAgICAgIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZSgtNTAlLCAtNTAlKScsXG4gICAgICAgIHVzZXJTZWxlY3Q6ICdub25lJyxcbiAgICAgIH0gYXMgUGFydGlhbDxDU1NTdHlsZURlY2xhcmF0aW9uPik7XG4gICAgICBlbC50ZXh0Q29udGVudCA9IHNwZWMudGV4dDtcbiAgICAgIHRoaXMuaG9zdC5hcHBlbmRDaGlsZChlbCk7XG4gICAgICB0aGlzLmVscy5wdXNoKGVsKTtcbiAgICB9XG4gICAgdGhpcy5kaXNjb25uZWN0Q2FtZXJhID0gdGhpcy5jYW1lcmEzZC5jaGFuZ2VkLmNvbm5lY3QoKCkgPT4gdGhpcy51cGRhdGUoKSk7XG4gICAgaWYgKHR5cGVvZiBSZXNpemVPYnNlcnZlciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIoKCkgPT4gdGhpcy51cGRhdGUoKSk7XG4gICAgICB0aGlzLnJlc2l6ZU9ic2VydmVyLm9ic2VydmUodGhpcy5ob3N0KTtcbiAgICB9XG4gICAgdGhpcy51cGRhdGUoKTtcbiAgfVxuXG4gIHNldFZpc2libGUodmlzaWJsZTogYm9vbGVhbik6IHZvaWQge1xuICAgIHRoaXMudmlzaWJsZSA9IHZpc2libGU7XG4gICAgdGhpcy51cGRhdGUoKTtcbiAgfVxuXG4gIC8qKiBSZXBsYWNlIHRoZSBsYWJlbCBhbmNob3JzL3RleHQgaW4gcGxhY2UgKHNhbWUgY291bnQpIGFuZCByZXByb2plY3Qg4oCUIGxldHMgYSBob3N0IG1vdmUgdGhlXG4gICAqICBsYWJlbHMgd2hlbiB0aGUgYm94IGdlb21ldHJ5IGNoYW5nZXMgbGl2ZSAoZS5nLiBhIFotaGVpZ2h0IGdpem1vIHJlc3RyZXRjaGluZyB0aGUgdm9sdW1lKVxuICAgKiAgd2l0aG91dCB0ZWFyaW5nIGRvd24gYW5kIHJlY3JlYXRpbmcgdGhlIERPTSBlbGVtZW50cyAod2hpY2ggd291bGQgZmxpY2tlcikuICovXG4gIHVwZGF0ZUFuY2hvcnMobGFiZWxzOiBBeGlzTGFiZWxTcGVjW10pOiB2b2lkIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMubGFiZWxzLmxlbmd0aCAmJiBpIDwgbGFiZWxzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB0aGlzLmxhYmVsc1tpXSA9IGxhYmVsc1tpXTtcbiAgICAgIGlmIChsYWJlbHNbaV0udGV4dCAhPT0gdGhpcy5lbHNbaV0udGV4dENvbnRlbnQpIHRoaXMuZWxzW2ldLnRleHRDb250ZW50ID0gbGFiZWxzW2ldLnRleHQ7XG4gICAgfVxuICAgIHRoaXMudXBkYXRlKCk7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZSgpOiB2b2lkIHtcbiAgICBjb25zdCB2dyA9IHRoaXMuaG9zdC5jbGllbnRXaWR0aDtcbiAgICBjb25zdCB2aCA9IHRoaXMuaG9zdC5jbGllbnRIZWlnaHQ7XG4gICAgaWYgKCF0aGlzLnZpc2libGUgfHwgdncgPD0gMCB8fCB2aCA8PSAwKSB7XG4gICAgICBmb3IgKGNvbnN0IGVsIG9mIHRoaXMuZWxzKSBlbC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBtdnAgPSB0aGlzLmNhbWVyYTNkLnZpZXdQcm9qZWN0aW9uKHZ3LCB2aCk7XG4gICAgdGhpcy5sYWJlbHMuZm9yRWFjaCgoc3BlYywgaSkgPT4ge1xuICAgICAgY29uc3QgZWwgPSB0aGlzLmVsc1tpXTtcbiAgICAgIGNvbnN0IHMgPSBwcm9qZWN0UG9pbnQobXZwLCBzcGVjLmFuY2hvciwgdncsIHZoKTtcbiAgICAgIGlmICghcy52aXNpYmxlKSB7XG4gICAgICAgIGVsLnN0eWxlLmRpc3BsYXkgPSAnbm9uZSc7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGVsLnN0eWxlLmRpc3BsYXkgPSAnJztcbiAgICAgIGVsLnN0eWxlLmxlZnQgPSBgJHtzLnh9cHhgO1xuICAgICAgZWwuc3R5bGUudG9wID0gYCR7cy55fXB4YDtcbiAgICB9KTtcbiAgfVxuXG4gIGRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5kaXNjb25uZWN0Q2FtZXJhKCk7XG4gICAgdGhpcy5yZXNpemVPYnNlcnZlcj8uZGlzY29ubmVjdCgpO1xuICAgIGZvciAoY29uc3QgZWwgb2YgdGhpcy5lbHMpIGVsLnBhcmVudE5vZGU/LnJlbW92ZUNoaWxkKGVsKTtcbiAgICB0aGlzLmVscy5sZW5ndGggPSAwO1xuICB9XG59XG4iXX0=
@@ -1,195 +0,0 @@
1
- /**
2
- * Overview navigator (minimap) for the napari-js 2D views, mirroring the OSD backend's
3
- * built-in navigator: a thumbnail of the whole image in the bottom-right corner with the
4
- * current viewport drawn on it. Clicking re-centres the main view on that point at the
5
- * same zoom; dragging pans continuously — exactly OSD's behaviour.
6
- *
7
- * napari keeps layers at full-resolution pixel scale, so the camera's world units ARE
8
- * image pixels and the thumbnail maps onto `[0, width) × [0, height)` directly.
9
- */
10
- /** Fraction of the host's width the navigator takes — OSD's `navigatorSizeRatio`. */
11
- export const NAVIGATOR_SIZE_RATIO = 0.16;
12
- const NAVIGATOR_MIN_PX = 110;
13
- const NAVIGATOR_MAX_PX = 300;
14
- /** Box size and scale for a `worldW × worldH` image in a host `hostW` wide. */
15
- export function navigatorLayout(hostW, worldW, worldH, ratio = NAVIGATOR_SIZE_RATIO) {
16
- if (!(worldW > 0) || !(worldH > 0) || !(hostW > 0))
17
- return null;
18
- const longest = Math.min(NAVIGATOR_MAX_PX, Math.max(NAVIGATOR_MIN_PX, hostW * ratio));
19
- const scale = longest / Math.max(worldW, worldH);
20
- return { width: worldW * scale, height: worldH * scale, scale };
21
- }
22
- /** The part of the world the camera shows, as `[x0, y0, x1, y1]`. */
23
- export function viewportWorldRect(center, zoom, hostW, hostH) {
24
- const hw = hostW / zoom / 2;
25
- const hh = hostH / zoom / 2;
26
- return [center[0] - hw, center[1] - hh, center[0] + hw, center[1] + hh];
27
- }
28
- /** A point in the navigator box → world coordinates, clamped to the image. */
29
- export function navigatorToWorld(px, py, layout, worldW, worldH) {
30
- const x = Math.min(worldW, Math.max(0, px / layout.scale));
31
- const y = Math.min(worldH, Math.max(0, py / layout.scale));
32
- return [x, y];
33
- }
34
- export class NapariNavigator {
35
- constructor(host, camera, worldW, worldH,
36
- /** Called when the pointer enters the navigator — e.g. to hide a hover tooltip that
37
- * was describing the canvas underneath. */
38
- onEnter) {
39
- this.host = host;
40
- this.camera = camera;
41
- this.worldW = worldW;
42
- this.worldH = worldH;
43
- this.onEnter = onEnter;
44
- /** Aborted by destroy() to remove every DOM listener the box holds. */
45
- this.listeners = new AbortController();
46
- this.layout = null;
47
- this.image = null;
48
- this.dragging = false;
49
- this.visible = true;
50
- this.onDown = (e) => {
51
- stop(e);
52
- if (e.button !== 0)
53
- return;
54
- this.dragging = true;
55
- this.box.setPointerCapture?.(e.pointerId);
56
- this.panTo(e);
57
- };
58
- this.onMove = (e) => {
59
- // Always consumed: a hover over the navigator is not a hover over the canvas.
60
- stop(e);
61
- if (this.dragging)
62
- this.panTo(e);
63
- };
64
- this.onUp = (e) => {
65
- if (!this.dragging)
66
- return;
67
- stop(e);
68
- this.dragging = false;
69
- this.box.releasePointerCapture?.(e.pointerId);
70
- };
71
- if (getComputedStyle(host).position === 'static')
72
- host.style.position = 'relative';
73
- this.box = document.createElement('div');
74
- this.box.className = 'napari-navigator';
75
- Object.assign(this.box.style, {
76
- position: 'absolute',
77
- right: '12px',
78
- bottom: '12px',
79
- background: 'rgba(0,0,0,0.5)',
80
- border: '1px solid rgba(255,255,255,0.35)',
81
- overflow: 'hidden',
82
- cursor: 'pointer',
83
- zIndex: '5',
84
- touchAction: 'none',
85
- });
86
- this.canvas = document.createElement('canvas');
87
- Object.assign(this.canvas.style, { display: 'block', width: '100%', height: '100%' });
88
- // OSD's default display-region style.
89
- this.region = document.createElement('div');
90
- Object.assign(this.region.style, {
91
- position: 'absolute',
92
- border: '2px solid #900',
93
- boxSizing: 'border-box',
94
- pointerEvents: 'none',
95
- });
96
- this.box.append(this.canvas, this.region);
97
- host.appendChild(this.box);
98
- // The navigator's own gestures must not also reach the canvas underneath (pan/zoom,
99
- // region drawing), so every pointer/wheel event is consumed here.
100
- // One signal for all of them, so destroy() releases every listener at once.
101
- const signal = this.listeners.signal;
102
- this.box.addEventListener('pointerdown', this.onDown, { signal });
103
- this.box.addEventListener('pointermove', this.onMove, { signal });
104
- this.box.addEventListener('pointerup', this.onUp, { signal });
105
- this.box.addEventListener('pointercancel', this.onUp, { signal });
106
- this.box.addEventListener('pointerenter', () => this.onEnter?.(), { signal });
107
- for (const type of ['wheel', 'click', 'dblclick', 'contextmenu', 'mousedown']) {
108
- this.box.addEventListener(type, stop, { passive: false, signal });
109
- }
110
- this.disconnectCamera = camera.changed.connect(() => this.updateRegion());
111
- if (typeof ResizeObserver !== 'undefined') {
112
- this.resizeObserver = new ResizeObserver(() => this.relayout());
113
- this.resizeObserver.observe(host);
114
- }
115
- this.relayout();
116
- }
117
- /** The thumbnail to draw: any image of the whole world (a coarse pyramid level). */
118
- setImage(image) {
119
- this.image = image;
120
- this.drawImage();
121
- }
122
- /** The image's world size changed (another image was loaded). */
123
- setWorld(width, height) {
124
- this.worldW = width;
125
- this.worldH = height;
126
- this.relayout();
127
- }
128
- setVisible(visible) {
129
- this.visible = visible;
130
- this.box.style.display = visible && this.layout ? 'block' : 'none';
131
- }
132
- destroy() {
133
- this.listeners.abort();
134
- this.disconnectCamera();
135
- this.resizeObserver?.disconnect();
136
- this.box.remove();
137
- }
138
- relayout() {
139
- this.layout = navigatorLayout(this.host.clientWidth, this.worldW, this.worldH);
140
- if (!this.layout) {
141
- this.box.style.display = 'none';
142
- return;
143
- }
144
- this.box.style.display = this.visible ? 'block' : 'none';
145
- this.box.style.width = `${this.layout.width}px`;
146
- this.box.style.height = `${this.layout.height}px`;
147
- const dpr = typeof devicePixelRatio === 'number' ? devicePixelRatio : 1;
148
- this.canvas.width = Math.max(1, Math.round(this.layout.width * dpr));
149
- this.canvas.height = Math.max(1, Math.round(this.layout.height * dpr));
150
- this.drawImage();
151
- this.updateRegion();
152
- }
153
- drawImage() {
154
- const ctx = this.canvas.getContext('2d');
155
- if (!ctx)
156
- return;
157
- ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
158
- if (this.image) {
159
- ctx.imageSmoothingEnabled = true;
160
- ctx.drawImage(this.image, 0, 0, this.canvas.width, this.canvas.height);
161
- }
162
- }
163
- /** Draw the viewport rectangle, clipped to the box (as OSD does when zoomed out). */
164
- updateRegion() {
165
- const l = this.layout;
166
- if (!l)
167
- return;
168
- const [x0, y0, x1, y1] = viewportWorldRect(this.camera.center, this.camera.zoom, this.host.clientWidth, this.host.clientHeight);
169
- const left = Math.max(0, x0 * l.scale);
170
- const top = Math.max(0, y0 * l.scale);
171
- const right = Math.min(l.width, x1 * l.scale);
172
- const bottom = Math.min(l.height, y1 * l.scale);
173
- Object.assign(this.region.style, {
174
- left: `${left}px`,
175
- top: `${top}px`,
176
- width: `${Math.max(2, right - left)}px`,
177
- height: `${Math.max(2, bottom - top)}px`,
178
- display: right > left && bottom > top ? 'block' : 'none',
179
- });
180
- }
181
- /** Re-centre the main view on the navigator point under the pointer, keeping the zoom. */
182
- panTo(e) {
183
- const l = this.layout;
184
- if (!l)
185
- return;
186
- const rect = this.box.getBoundingClientRect();
187
- this.camera.center = navigatorToWorld(e.clientX - rect.left, e.clientY - rect.top, l, this.worldW, this.worldH);
188
- }
189
- }
190
- function stop(e) {
191
- e.stopPropagation();
192
- if (e.cancelable)
193
- e.preventDefault();
194
- }
195
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFwYXJpLW5hdmlnYXRvci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvaW1wbGVtZW50YXRpb25zL25hcGFyaS1qcy9uYXBhcmktbmF2aWdhdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7OztHQVFHO0FBa0JILHFGQUFxRjtBQUNyRixNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLENBQUM7QUFDekMsTUFBTSxnQkFBZ0IsR0FBRyxHQUFHLENBQUM7QUFDN0IsTUFBTSxnQkFBZ0IsR0FBRyxHQUFHLENBQUM7QUFFN0IsK0VBQStFO0FBQy9FLE1BQU0sVUFBVSxlQUFlLENBQzdCLEtBQWEsRUFBRSxNQUFjLEVBQUUsTUFBYyxFQUFFLEtBQUssR0FBRyxvQkFBb0I7SUFFM0UsSUFBSSxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUM7UUFBRSxPQUFPLElBQUksQ0FBQztJQUNoRSxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLGdCQUFnQixFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsZ0JBQWdCLEVBQUUsS0FBSyxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUM7SUFDdEYsTUFBTSxLQUFLLEdBQUcsT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ2pELE9BQU8sRUFBRSxLQUFLLEVBQUUsTUFBTSxHQUFHLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxHQUFHLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQztBQUNsRSxDQUFDO0FBRUQscUVBQXFFO0FBQ3JFLE1BQU0sVUFBVSxpQkFBaUIsQ0FDL0IsTUFBaUMsRUFBRSxJQUFZLEVBQUUsS0FBYSxFQUFFLEtBQWE7SUFFN0UsTUFB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Q0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FDekUsQ0FBQztJQUNKLENBQUM7Q0FzQkY7QUFFRCxTQUFTLElBQUksQ0FBQyxDQUFRO0lBQ3BCLENBQUMsQ0FBQyxlQUFlLEVBQUUsQ0FBQztJQUNwQixJQUFJLENBQUMsQ0FBQyxVQUFVO1FBQUUsQ0FBQyxDQUFDLGNBQWMsRUFBRSxDQUFDO0FBQ3ZDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE92ZXJ2aWV3IG5hdmlnYXRvciAobWluaW1hcCkgZm9yIHRoZSBuYXBhcmktanMgMkQgdmlld3MsIG1pcnJvcmluZyB0aGUgT1NEIGJhY2tlbmQnc1xuICogYnVpbHQtaW4gbmF2aWdhdG9yOiBhIHRodW1ibmFpbCBvZiB0aGUgd2hvbGUgaW1hZ2UgaW4gdGhlIGJvdHRvbS1yaWdodCBjb3JuZXIgd2l0aCB0aGVcbiAqIGN1cnJlbnQgdmlld3BvcnQgZHJhd24gb24gaXQuIENsaWNraW5nIHJlLWNlbnRyZXMgdGhlIG1haW4gdmlldyBvbiB0aGF0IHBvaW50IGF0IHRoZVxuICogc2FtZSB6b29tOyBkcmFnZ2luZyBwYW5zIGNvbnRpbnVvdXNseSDigJQgZXhhY3RseSBPU0QncyBiZWhhdmlvdXIuXG4gKlxuICogbmFwYXJpIGtlZXBzIGxheWVycyBhdCBmdWxsLXJlc29sdXRpb24gcGl4ZWwgc2NhbGUsIHNvIHRoZSBjYW1lcmEncyB3b3JsZCB1bml0cyBBUkVcbiAqIGltYWdlIHBpeGVscyBhbmQgdGhlIHRodW1ibmFpbCBtYXBzIG9udG8gYFswLCB3aWR0aCkgw5cgWzAsIGhlaWdodClgIGRpcmVjdGx5LlxuICovXG5cbi8qKiBUaGUgc2xpY2Ugb2YgdGhlIG5hcGFyaSAyRCBjYW1lcmEgdGhlIG5hdmlnYXRvciByZWFkcyBhbmQgZHJpdmVzLiAqL1xuZXhwb3J0IGludGVyZmFjZSBOYXZpZ2F0b3JDYW1lcmEge1xuICBjZW50ZXI6IHJlYWRvbmx5IFtudW1iZXIsIG51bWJlcl07XG4gIHJlYWRvbmx5IHpvb206IG51bWJlcjtcbiAgcmVhZG9ubHkgY2hhbmdlZDogeyBjb25uZWN0KGxpc3RlbmVyOiAoKSA9PiB2b2lkKTogKCkgPT4gdm9pZCB9O1xufVxuXG4vKiogV2hlcmUgdGhlIHRodW1ibmFpbCBzaXRzIGluc2lkZSB0aGUgbmF2aWdhdG9yIGJveCwgaW4gQ1NTIHB4LiAqL1xuZXhwb3J0IGludGVyZmFjZSBOYXZpZ2F0b3JMYXlvdXQge1xuICAvKiogQm94IHNpemUuICovXG4gIHdpZHRoOiBudW1iZXI7XG4gIGhlaWdodDogbnVtYmVyO1xuICAvKiogQ1NTIHB4IHBlciB3b3JsZCB1bml0IChpbWFnZSBwaXhlbCkuICovXG4gIHNjYWxlOiBudW1iZXI7XG59XG5cbi8qKiBGcmFjdGlvbiBvZiB0aGUgaG9zdCdzIHdpZHRoIHRoZSBuYXZpZ2F0b3IgdGFrZXMg4oCUIE9TRCdzIGBuYXZpZ2F0b3JTaXplUmF0aW9gLiAqL1xuZXhwb3J0IGNvbnN0IE5BVklHQVRPUl9TSVpFX1JBVElPID0gMC4xNjtcbmNvbnN0IE5BVklHQVRPUl9NSU5fUFggPSAxMTA7XG5jb25zdCBOQVZJR0FUT1JfTUFYX1BYID0gMzAwO1xuXG4vKiogQm94IHNpemUgYW5kIHNjYWxlIGZvciBhIGB3b3JsZFcgw5cgd29ybGRIYCBpbWFnZSBpbiBhIGhvc3QgYGhvc3RXYCB3aWRlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5hdmlnYXRvckxheW91dChcbiAgaG9zdFc6IG51bWJlciwgd29ybGRXOiBudW1iZXIsIHdvcmxkSDogbnVtYmVyLCByYXRpbyA9IE5BVklHQVRPUl9TSVpFX1JBVElPLFxuKTogTmF2aWdhdG9yTGF5b3V0IHwgbnVsbCB7XG4gIGlmICghKHdvcmxkVyA+IDApIHx8ICEod29ybGRIID4gMCkgfHwgIShob3N0VyA+IDApKSByZXR1cm4gbnVsbDtcbiAgY29uc3QgbG9uZ2VzdCA9IE1hdGgubWluKE5BVklHQVRPUl9NQVhfUFgsIE1hdGgubWF4KE5BVklHQVRPUl9NSU5fUFgsIGhvc3RXICogcmF0aW8pKTtcbiAgY29uc3Qgc2NhbGUgPSBsb25nZXN0IC8gTWF0aC5tYXgod29ybGRXLCB3b3JsZEgpO1xuICByZXR1cm4geyB3aWR0aDogd29ybGRXICogc2NhbGUsIGhlaWdodDogd29ybGRIICogc2NhbGUsIHNjYWxlIH07XG59XG5cbi8qKiBUaGUgcGFydCBvZiB0aGUgd29ybGQgdGhlIGNhbWVyYSBzaG93cywgYXMgYFt4MCwgeTAsIHgxLCB5MV1gLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZpZXdwb3J0V29ybGRSZWN0KFxuICBjZW50ZXI6IHJlYWRvbmx5IFtudW1iZXIsIG51bWJlcl0sIHpvb206IG51bWJlciwgaG9zdFc6IG51bWJlciwgaG9zdEg6IG51bWJlcixcbik6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyLCBudW1iZXJdIHtcbiAgY29uc3QgaHcgPSBob3N0VyAvIHpvb20gLyAyO1xuICBjb25zdCBoaCA9IGhvc3RIIC8gem9vbSAvIDI7XG4gIHJldHVybiBbY2VudGVyWzBdIC0gaHcsIGNlbnRlclsxXSAtIGhoLCBjZW50ZXJbMF0gKyBodywgY2VudGVyWzFdICsgaGhdO1xufVxuXG4vKiogQSBwb2ludCBpbiB0aGUgbmF2aWdhdG9yIGJveCDihpIgd29ybGQgY29vcmRpbmF0ZXMsIGNsYW1wZWQgdG8gdGhlIGltYWdlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG5hdmlnYXRvclRvV29ybGQoXG4gIHB4OiBudW1iZXIsIHB5OiBudW1iZXIsIGxheW91dDogTmF2aWdhdG9yTGF5b3V0LCB3b3JsZFc6IG51bWJlciwgd29ybGRIOiBudW1iZXIsXG4pOiBbbnVtYmVyLCBudW1iZXJdIHtcbiAgY29uc3QgeCA9IE1hdGgubWluKHdvcmxkVywgTWF0aC5tYXgoMCwgcHggLyBsYXlvdXQuc2NhbGUpKTtcbiAgY29uc3QgeSA9IE1hdGgubWluKHdvcmxkSCwgTWF0aC5tYXgoMCwgcHkgLyBsYXlvdXQuc2NhbGUpKTtcbiAgcmV0dXJuIFt4LCB5XTtcbn1cblxuZXhwb3J0IGNsYXNzIE5hcGFyaU5hdmlnYXRvciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgYm94OiBIVE1MRGl2RWxlbWVudDtcbiAgcHJpdmF0ZSByZWFkb25seSBjYW52YXM6IEhUTUxDYW52YXNFbGVtZW50O1xuICBwcml2YXRlIHJlYWRvbmx5IHJlZ2lvbjogSFRNTERpdkVsZW1lbnQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgZGlzY29ubmVjdENhbWVyYTogKCkgPT4gdm9pZDtcbiAgcHJpdmF0ZSByZWFkb25seSByZXNpemVPYnNlcnZlcj86IFJlc2l6ZU9ic2VydmVyO1xuICAvKiogQWJvcnRlZCBieSBkZXN0cm95KCkgdG8gcmVtb3ZlIGV2ZXJ5IERPTSBsaXN0ZW5lciB0aGUgYm94IGhvbGRzLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGxpc3RlbmVycyA9IG5ldyBBYm9ydENvbnRyb2xsZXIoKTtcbiAgcHJpdmF0ZSBsYXlvdXQ6IE5hdmlnYXRvckxheW91dCB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGltYWdlOiBDYW52YXNJbWFnZVNvdXJjZSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGRyYWdnaW5nID0gZmFsc2U7XG4gIHByaXZhdGUgdmlzaWJsZSA9IHRydWU7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBob3N0OiBIVE1MRWxlbWVudCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNhbWVyYTogTmF2aWdhdG9yQ2FtZXJhLFxuICAgIHByaXZhdGUgd29ybGRXOiBudW1iZXIsXG4gICAgcHJpdmF0ZSB3b3JsZEg6IG51bWJlcixcbiAgICAvKiogQ2FsbGVkIHdoZW4gdGhlIHBvaW50ZXIgZW50ZXJzIHRoZSBuYXZpZ2F0b3Ig4oCUIGUuZy4gdG8gaGlkZSBhIGhvdmVyIHRvb2x0aXAgdGhhdFxuICAgICAqICB3YXMgZGVzY3JpYmluZyB0aGUgY2FudmFzIHVuZGVybmVhdGguICovXG4gICAgcHJpdmF0ZSByZWFkb25seSBvbkVudGVyPzogKCkgPT4gdm9pZCxcbiAgKSB7XG4gICAgaWYgKGdldENvbXB1dGVkU3R5bGUoaG9zdCkucG9zaXRpb24gPT09ICdzdGF0aWMnKSBob3N0LnN0eWxlLnBvc2l0aW9uID0gJ3JlbGF0aXZlJztcblxuICAgIHRoaXMuYm94ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgdGhpcy5ib3guY2xhc3NOYW1lID0gJ25hcGFyaS1uYXZpZ2F0b3InO1xuICAgIE9iamVjdC5hc3NpZ24odGhpcy5ib3guc3R5bGUsIHtcbiAgICAgIHBvc2l0aW9uOiAnYWJzb2x1dGUnLFxuICAgICAgcmlnaHQ6ICcxMnB4JyxcbiAgICAgIGJvdHRvbTogJzEycHgnLFxuICAgICAgYmFja2dyb3VuZDogJ3JnYmEoMCwwLDAsMC41KScsXG4gICAgICBib3JkZXI6ICcxcHggc29saWQgcmdiYSgyNTUsMjU1LDI1NSwwLjM1KScsXG4gICAgICBvdmVyZmxvdzogJ2hpZGRlbicsXG4gICAgICBjdXJzb3I6ICdwb2ludGVyJyxcbiAgICAgIHpJbmRleDogJzUnLFxuICAgICAgdG91Y2hBY3Rpb246ICdub25lJyxcbiAgICB9IHNhdGlzZmllcyBQYXJ0aWFsPENTU1N0eWxlRGVjbGFyYXRpb24+KTtcblxuICAgIHRoaXMuY2FudmFzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnY2FudmFzJyk7XG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLmNhbnZhcy5zdHlsZSwgeyBkaXNwbGF5OiAnYmxvY2snLCB3aWR0aDogJzEwMCUnLCBoZWlnaHQ6ICcxMDAlJyB9KTtcblxuICAgIC8vIE9TRCdzIGRlZmF1bHQgZGlzcGxheS1yZWdpb24gc3R5bGUuXG4gICAgdGhpcy5yZWdpb24gPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdkaXYnKTtcbiAgICBPYmplY3QuYXNzaWduKHRoaXMucmVnaW9uLnN0eWxlLCB7XG4gICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgIGJvcmRlcjogJzJweCBzb2xpZCAjOTAwJyxcbiAgICAgIGJveFNpemluZzogJ2JvcmRlci1ib3gnLFxuICAgICAgcG9pbnRlckV2ZW50czogJ25vbmUnLFxuICAgIH0gc2F0aXNmaWVzIFBhcnRpYWw8Q1NTU3R5bGVEZWNsYXJhdGlvbj4pO1xuXG4gICAgdGhpcy5ib3guYXBwZW5kKHRoaXMuY2FudmFzLCB0aGlzLnJlZ2lvbik7XG4gICAgaG9zdC5hcHBlbmRDaGlsZCh0aGlzLmJveCk7XG5cbiAgICAvLyBUaGUgbmF2aWdhdG9yJ3Mgb3duIGdlc3R1cmVzIG11c3Qgbm90IGFsc28gcmVhY2ggdGhlIGNhbnZhcyB1bmRlcm5lYXRoIChwYW4vem9vbSxcbiAgICAvLyByZWdpb24gZHJhd2luZyksIHNvIGV2ZXJ5IHBvaW50ZXIvd2hlZWwgZXZlbnQgaXMgY29uc3VtZWQgaGVyZS5cbiAgICAvLyBPbmUgc2lnbmFsIGZvciBhbGwgb2YgdGhlbSwgc28gZGVzdHJveSgpIHJlbGVhc2VzIGV2ZXJ5IGxpc3RlbmVyIGF0IG9uY2UuXG4gICAgY29uc3Qgc2lnbmFsID0gdGhpcy5saXN0ZW5lcnMuc2lnbmFsO1xuICAgIHRoaXMuYm94LmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJkb3duJywgdGhpcy5vbkRvd24sIHsgc2lnbmFsIH0pO1xuICAgIHRoaXMuYm94LmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJtb3ZlJywgdGhpcy5vbk1vdmUsIHsgc2lnbmFsIH0pO1xuICAgIHRoaXMuYm94LmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJ1cCcsIHRoaXMub25VcCwgeyBzaWduYWwgfSk7XG4gICAgdGhpcy5ib3guYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcmNhbmNlbCcsIHRoaXMub25VcCwgeyBzaWduYWwgfSk7XG4gICAgdGhpcy5ib3guYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcmVudGVyJywgKCkgPT4gdGhpcy5vbkVudGVyPy4oKSwgeyBzaWduYWwgfSk7XG4gICAgZm9yIChjb25zdCB0eXBlIG9mIFsnd2hlZWwnLCAnY2xpY2snLCAnZGJsY2xpY2snLCAnY29udGV4dG1lbnUnLCAnbW91c2Vkb3duJ10gYXMgY29uc3QpIHtcbiAgICAgIHRoaXMuYm94LmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgc3RvcCwgeyBwYXNzaXZlOiBmYWxzZSwgc2lnbmFsIH0pO1xuICAgIH1cblxuICAgIHRoaXMuZGlzY29ubmVjdENhbWVyYSA9IGNhbWVyYS5jaGFuZ2VkLmNvbm5lY3QoKCkgPT4gdGhpcy51cGRhdGVSZWdpb24oKSk7XG4gICAgaWYgKHR5cGVvZiBSZXNpemVPYnNlcnZlciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIoKCkgPT4gdGhpcy5yZWxheW91dCgpKTtcbiAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXIub2JzZXJ2ZShob3N0KTtcbiAgICB9XG4gICAgdGhpcy5yZWxheW91dCgpO1xuICB9XG5cbiAgLyoqIFRoZSB0aHVtYm5haWwgdG8gZHJhdzogYW55IGltYWdlIG9mIHRoZSB3aG9sZSB3b3JsZCAoYSBjb2Fyc2UgcHlyYW1pZCBsZXZlbCkuICovXG4gIHNldEltYWdlKGltYWdlOiBDYW52YXNJbWFnZVNvdXJjZSB8IG51bGwpOiB2b2lkIHtcbiAgICB0aGlzLmltYWdlID0gaW1hZ2U7XG4gICAgdGhpcy5kcmF3SW1hZ2UoKTtcbiAgfVxuXG4gIC8qKiBUaGUgaW1hZ2UncyB3b3JsZCBzaXplIGNoYW5nZWQgKGFub3RoZXIgaW1hZ2Ugd2FzIGxvYWRlZCkuICovXG4gIHNldFdvcmxkKHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy53b3JsZFcgPSB3aWR0aDtcbiAgICB0aGlzLndvcmxkSCA9IGhlaWdodDtcbiAgICB0aGlzLnJlbGF5b3V0KCk7XG4gIH1cblxuICBzZXRWaXNpYmxlKHZpc2libGU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICB0aGlzLnZpc2libGUgPSB2aXNpYmxlO1xuICAgIHRoaXMuYm94LnN0eWxlLmRpc3BsYXkgPSB2aXNpYmxlICYmIHRoaXMubGF5b3V0ID8gJ2Jsb2NrJyA6ICdub25lJztcbiAgfVxuXG4gIGRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5saXN0ZW5lcnMuYWJvcnQoKTtcbiAgICB0aGlzLmRpc2Nvbm5lY3RDYW1lcmEoKTtcbiAgICB0aGlzLnJlc2l6ZU9ic2VydmVyPy5kaXNjb25uZWN0KCk7XG4gICAgdGhpcy5ib3gucmVtb3ZlKCk7XG4gIH1cblxuICBwcml2YXRlIHJlbGF5b3V0KCk6IHZvaWQge1xuICAgIHRoaXMubGF5b3V0ID0gbmF2aWdhdG9yTGF5b3V0KHRoaXMuaG9zdC5jbGllbnRXaWR0aCwgdGhpcy53b3JsZFcsIHRoaXMud29ybGRIKTtcbiAgICBpZiAoIXRoaXMubGF5b3V0KSB7XG4gICAgICB0aGlzLmJveC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmJveC5zdHlsZS5kaXNwbGF5ID0gdGhpcy52aXNpYmxlID8gJ2Jsb2NrJyA6ICdub25lJztcbiAgICB0aGlzLmJveC5zdHlsZS53aWR0aCA9IGAke3RoaXMubGF5b3V0LndpZHRofXB4YDtcbiAgICB0aGlzLmJveC5zdHlsZS5oZWlnaHQgPSBgJHt0aGlzLmxheW91dC5oZWlnaHR9cHhgO1xuICAgIGNvbnN0IGRwciA9IHR5cGVvZiBkZXZpY2VQaXhlbFJhdGlvID09PSAnbnVtYmVyJyA/IGRldmljZVBpeGVsUmF0aW8gOiAxO1xuICAgIHRoaXMuY2FudmFzLndpZHRoID0gTWF0aC5tYXgoMSwgTWF0aC5yb3VuZCh0aGlzLmxheW91dC53aWR0aCAqIGRwcikpO1xuICAgIHRoaXMuY2FudmFzLmhlaWdodCA9IE1hdGgubWF4KDEsIE1hdGgucm91bmQodGhpcy5sYXlvdXQuaGVpZ2h0ICogZHByKSk7XG4gICAgdGhpcy5kcmF3SW1hZ2UoKTtcbiAgICB0aGlzLnVwZGF0ZVJlZ2lvbigpO1xuICB9XG5cbiAgcHJpdmF0ZSBkcmF3SW1hZ2UoKTogdm9pZCB7XG4gICAgY29uc3QgY3R4ID0gdGhpcy5jYW52YXMuZ2V0Q29udGV4dCgnMmQnKTtcbiAgICBpZiAoIWN0eCkgcmV0dXJuO1xuICAgIGN0eC5jbGVhclJlY3QoMCwgMCwgdGhpcy5jYW52YXMud2lkdGgsIHRoaXMuY2FudmFzLmhlaWdodCk7XG4gICAgaWYgKHRoaXMuaW1hZ2UpIHtcbiAgICAgIGN0eC5pbWFnZVNtb290aGluZ0VuYWJsZWQgPSB0cnVlO1xuICAgICAgY3R4LmRyYXdJbWFnZSh0aGlzLmltYWdlLCAwLCAwLCB0aGlzLmNhbnZhcy53aWR0aCwgdGhpcy5jYW52YXMuaGVpZ2h0KTtcbiAgICB9XG4gIH1cblxuICAvKiogRHJhdyB0aGUgdmlld3BvcnQgcmVjdGFuZ2xlLCBjbGlwcGVkIHRvIHRoZSBib3ggKGFzIE9TRCBkb2VzIHdoZW4gem9vbWVkIG91dCkuICovXG4gIHByaXZhdGUgdXBkYXRlUmVnaW9uKCk6IHZvaWQge1xuICAgIGNvbnN0IGwgPSB0aGlzLmxheW91dDtcbiAgICBpZiAoIWwpIHJldHVybjtcbiAgICBjb25zdCBbeDAsIHkwLCB4MSwgeTFdID0gdmlld3BvcnRXb3JsZFJlY3QoXG4gICAgICB0aGlzLmNhbWVyYS5jZW50ZXIsIHRoaXMuY2FtZXJhLnpvb20sIHRoaXMuaG9zdC5jbGllbnRXaWR0aCwgdGhpcy5ob3N0LmNsaWVudEhlaWdodCxcbiAgICApO1xuICAgIGNvbnN0IGxlZnQgPSBNYXRoLm1heCgwLCB4MCAqIGwuc2NhbGUpO1xuICAgIGNvbnN0IHRvcCA9IE1hdGgubWF4KDAsIHkwICogbC5zY2FsZSk7XG4gICAgY29uc3QgcmlnaHQgPSBNYXRoLm1pbihsLndpZHRoLCB4MSAqIGwuc2NhbGUpO1xuICAgIGNvbnN0IGJvdHRvbSA9IE1hdGgubWluKGwuaGVpZ2h0LCB5MSAqIGwuc2NhbGUpO1xuICAgIE9iamVjdC5hc3NpZ24odGhpcy5yZWdpb24uc3R5bGUsIHtcbiAgICAgIGxlZnQ6IGAke2xlZnR9cHhgLFxuICAgICAgdG9wOiBgJHt0b3B9cHhgLFxuICAgICAgd2lkdGg6IGAke01hdGgubWF4KDIsIHJpZ2h0IC0gbGVmdCl9cHhgLFxuICAgICAgaGVpZ2h0OiBgJHtNYXRoLm1heCgyLCBib3R0b20gLSB0b3ApfXB4YCxcbiAgICAgIGRpc3BsYXk6IHJpZ2h0ID4gbGVmdCAmJiBib3R0b20gPiB0b3AgPyAnYmxvY2snIDogJ25vbmUnLFxuICAgIH0pO1xuICB9XG5cbiAgLyoqIFJlLWNlbnRyZSB0aGUgbWFpbiB2aWV3IG9uIHRoZSBuYXZpZ2F0b3IgcG9pbnQgdW5kZXIgdGhlIHBvaW50ZXIsIGtlZXBpbmcgdGhlIHpvb20uICovXG4gIHByaXZhdGUgcGFuVG8oZTogUG9pbnRlckV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgbCA9IHRoaXMubGF5b3V0O1xuICAgIGlmICghbCkgcmV0dXJuO1xuICAgIGNvbnN0IHJlY3QgPSB0aGlzLmJveC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICB0aGlzLmNhbWVyYS5jZW50ZXIgPSBuYXZpZ2F0b3JUb1dvcmxkKFxuICAgICAgZS5jbGllbnRYIC0gcmVjdC5sZWZ0LCBlLmNsaWVudFkgLSByZWN0LnRvcCwgbCwgdGhpcy53b3JsZFcsIHRoaXMud29ybGRILFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHJlYWRvbmx5IG9uRG93biA9IChlOiBQb2ludGVyRXZlbnQpOiB2b2lkID0+IHtcbiAgICBzdG9wKGUpO1xuICAgIGlmIChlLmJ1dHRvbiAhPT0gMCkgcmV0dXJuO1xuICAgIHRoaXMuZHJhZ2dpbmcgPSB0cnVlO1xuICAgIHRoaXMuYm94LnNldFBvaW50ZXJDYXB0dXJlPy4oZS5wb2ludGVySWQpO1xuICAgIHRoaXMucGFuVG8oZSk7XG4gIH07XG5cbiAgcHJpdmF0ZSByZWFkb25seSBvbk1vdmUgPSAoZTogUG9pbnRlckV2ZW50KTogdm9pZCA9PiB7XG4gICAgLy8gQWx3YXlzIGNvbnN1bWVkOiBhIGhvdmVyIG92ZXIgdGhlIG5hdmlnYXRvciBpcyBub3QgYSBob3ZlciBvdmVyIHRoZSBjYW52YXMuXG4gICAgc3RvcChlKTtcbiAgICBpZiAodGhpcy5kcmFnZ2luZykgdGhpcy5wYW5UbyhlKTtcbiAgfTtcblxuICBwcml2YXRlIHJlYWRvbmx5IG9uVXAgPSAoZTogUG9pbnRlckV2ZW50KTogdm9pZCA9PiB7XG4gICAgaWYgKCF0aGlzLmRyYWdnaW5nKSByZXR1cm47XG4gICAgc3RvcChlKTtcbiAgICB0aGlzLmRyYWdnaW5nID0gZmFsc2U7XG4gICAgdGhpcy5ib3gucmVsZWFzZVBvaW50ZXJDYXB0dXJlPy4oZS5wb2ludGVySWQpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBzdG9wKGU6IEV2ZW50KTogdm9pZCB7XG4gIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gIGlmIChlLmNhbmNlbGFibGUpIGUucHJldmVudERlZmF1bHQoKTtcbn1cbiJdfQ==