@jax-data-science/sci-image-visualizer 0.1.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 (311) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +404 -0
  3. package/esm2022/index.mjs +52 -0
  4. package/esm2022/jax-data-science-sci-image-visualizer.mjs +5 -0
  5. package/esm2022/lib/channel-histogram/channel-histogram.component.mjs +398 -0
  6. package/esm2022/lib/contracts/capabilities.contract.mjs +32 -0
  7. package/esm2022/lib/contracts/cell-segmenter.contract.mjs +12 -0
  8. package/esm2022/lib/contracts/channel-histogram-api.contract.mjs +14 -0
  9. package/esm2022/lib/contracts/colormap-lut.mjs +95 -0
  10. package/esm2022/lib/contracts/coordinate-transform.contract.mjs +2 -0
  11. package/esm2022/lib/contracts/display-types.mjs +8 -0
  12. package/esm2022/lib/contracts/image.contract.mjs +11 -0
  13. package/esm2022/lib/contracts/intensity.mjs +28 -0
  14. package/esm2022/lib/contracts/plot-type.mjs +112 -0
  15. package/esm2022/lib/contracts/ports/image-state.port.mjs +3 -0
  16. package/esm2022/lib/contracts/ports/preferences.port.mjs +3 -0
  17. package/esm2022/lib/contracts/ports/region-io.port.mjs +3 -0
  18. package/esm2022/lib/contracts/ports/tile-access.port.mjs +3 -0
  19. package/esm2022/lib/contracts/region-editor-api.contract.mjs +4 -0
  20. package/esm2022/lib/contracts/region-overlay.contract.mjs +2 -0
  21. package/esm2022/lib/contracts/region-store.contract.mjs +2 -0
  22. package/esm2022/lib/contracts/sam.contract.mjs +12 -0
  23. package/esm2022/lib/contracts/toolbar-config.mjs +8 -0
  24. package/esm2022/lib/contracts/visualizer.contract.mjs +10 -0
  25. package/esm2022/lib/contracts/viz-config.mjs +3 -0
  26. package/esm2022/lib/hex-color-picker/hex-color-picker.component.mjs +260 -0
  27. package/esm2022/lib/implementations/base-store-visualizer.mjs +76 -0
  28. package/esm2022/lib/implementations/napari-js/napari-axes-labels.mjs +106 -0
  29. package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +847 -0
  30. package/esm2022/lib/implementations/napari-js/napari-scale-bar.mjs +92 -0
  31. package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +2283 -0
  32. package/esm2022/lib/implementations/napari-js/napari-volume-z-handle.mjs +126 -0
  33. package/esm2022/lib/implementations/osd/display-pipeline.mjs +143 -0
  34. package/esm2022/lib/implementations/osd/histogram-sampler.mjs +217 -0
  35. package/esm2022/lib/implementations/osd/openseadragon-visualizer.service.mjs +1780 -0
  36. package/esm2022/lib/implementations/osd/osd-coordinate-transform.mjs +25 -0
  37. package/esm2022/lib/implementations/osd/osd-coords.mjs +53 -0
  38. package/esm2022/lib/implementations/osd/osd-lib.mjs +20 -0
  39. package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +1237 -0
  40. package/esm2022/lib/implementations/osd/osd-scale-bar.mjs +88 -0
  41. package/esm2022/lib/implementations/osd/slice-cache.mjs +488 -0
  42. package/esm2022/lib/implementations/osd/tile-client.mjs +29 -0
  43. package/esm2022/lib/implementations/plotly/plotly-coordinate-transform.mjs +37 -0
  44. package/esm2022/lib/implementations/plotly/plotly-region-overlay.mjs +31 -0
  45. package/esm2022/lib/implementations/plotly/plotly-trace-builders.mjs +183 -0
  46. package/esm2022/lib/implementations/plotly/plotly.service.mjs +2137 -0
  47. package/esm2022/lib/implementations/simple-slice-access.service.mjs +99 -0
  48. package/esm2022/lib/models/bezier.mjs +120 -0
  49. package/esm2022/lib/models/class-preset.mjs +46 -0
  50. package/esm2022/lib/models/geometry.mjs +198 -0
  51. package/esm2022/lib/models/region.mjs +166 -0
  52. package/esm2022/lib/models/shape.mjs +53 -0
  53. package/esm2022/lib/plot.utilities.mjs +693 -0
  54. package/esm2022/lib/processing/image-converter.service.mjs +90 -0
  55. package/esm2022/lib/processing/image-crop.mjs +62 -0
  56. package/esm2022/lib/processing/processing-image.mjs +50 -0
  57. package/esm2022/lib/provide-visualization.mjs +63 -0
  58. package/esm2022/lib/region-editor/mask-raster.mjs +95 -0
  59. package/esm2022/lib/region-editor/mask-worker.mjs +10 -0
  60. package/esm2022/lib/region-editor/region-editor.component.mjs +1190 -0
  61. package/esm2022/lib/region-ops.service.mjs +301 -0
  62. package/esm2022/lib/render-orchestrator.mjs +87 -0
  63. package/esm2022/lib/routing-visualizer.service.mjs +533 -0
  64. package/esm2022/lib/store/class-color.util.mjs +52 -0
  65. package/esm2022/lib/store/region-store.service.mjs +1029 -0
  66. package/esm2022/lib/store/visualizer-store.service.mjs +352 -0
  67. package/esm2022/lib/toolbar/brush/brush-tool.service.mjs +546 -0
  68. package/esm2022/lib/toolbar/crop/slide-crop.mjs +57 -0
  69. package/esm2022/lib/toolbar/segmentation/cell-segment-tool.service.mjs +115 -0
  70. package/esm2022/lib/toolbar/segmentation/cellpose-segmenter.service.mjs +84 -0
  71. package/esm2022/lib/toolbar/segmentation/onnx-sam-session.mjs +133 -0
  72. package/esm2022/lib/toolbar/segmentation/ort-runtime-config.mjs +31 -0
  73. package/esm2022/lib/toolbar/segmentation/sam-model-registry.mjs +108 -0
  74. package/esm2022/lib/toolbar/segmentation/sam-onnx-core.mjs +159 -0
  75. package/esm2022/lib/toolbar/segmentation/sam-point-tool.service.mjs +255 -0
  76. package/esm2022/lib/toolbar/segmentation/sam-prompt.mjs +94 -0
  77. package/esm2022/lib/toolbar/segmentation/sam-tool.service.mjs +188 -0
  78. package/esm2022/lib/toolbar/toolbar.component.mjs +311 -0
  79. package/esm2022/lib/toolbar/vertex-eraser/vertex-eraser-tool.service.mjs +234 -0
  80. package/esm2022/lib/toolbar/wand/wand-tool.service.mjs +499 -0
  81. package/esm2022/lib/toolbar/wand/wand.service.mjs +921 -0
  82. package/esm2022/lib/toolbar/zoom-to-box/zoom-to-box-tool.service.mjs +157 -0
  83. package/esm2022/lib/visualization.module.mjs +162 -0
  84. package/esm2022/lib/visualizer.component.mjs +1597 -0
  85. package/fesm2022/jax-data-science-sci-image-visualizer-mask-worker-uhepXUhM.mjs +12 -0
  86. package/fesm2022/jax-data-science-sci-image-visualizer-mask-worker-uhepXUhM.mjs.map +1 -0
  87. package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-ci1q0xnJ.mjs +327 -0
  88. package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-ci1q0xnJ.mjs.map +1 -0
  89. package/fesm2022/jax-data-science-sci-image-visualizer.mjs +21314 -0
  90. package/fesm2022/jax-data-science-sci-image-visualizer.mjs.map +1 -0
  91. package/fesm2022/mask.worker.js +989 -0
  92. package/fesm2022/onnx-sam.worker.js +202 -0
  93. package/index.d.ts +39 -0
  94. package/lib/channel-histogram/channel-histogram.component.d.ts +112 -0
  95. package/lib/contracts/capabilities.contract.d.ts +30 -0
  96. package/lib/contracts/cell-segmenter.contract.d.ts +40 -0
  97. package/lib/contracts/channel-histogram-api.contract.d.ts +98 -0
  98. package/lib/contracts/colormap-lut.d.ts +21 -0
  99. package/lib/contracts/coordinate-transform.contract.d.ts +43 -0
  100. package/lib/contracts/display-types.d.ts +41 -0
  101. package/lib/contracts/image.contract.d.ts +72 -0
  102. package/lib/contracts/intensity.d.ts +18 -0
  103. package/lib/contracts/plot-type.d.ts +108 -0
  104. package/lib/contracts/ports/image-state.port.d.ts +29 -0
  105. package/lib/contracts/ports/preferences.port.d.ts +19 -0
  106. package/lib/contracts/ports/region-io.port.d.ts +29 -0
  107. package/lib/contracts/ports/tile-access.port.d.ts +27 -0
  108. package/lib/contracts/region-editor-api.contract.d.ts +83 -0
  109. package/lib/contracts/region-overlay.contract.d.ts +47 -0
  110. package/lib/contracts/region-store.contract.d.ts +74 -0
  111. package/lib/contracts/sam.contract.d.ts +98 -0
  112. package/lib/contracts/toolbar-config.d.ts +24 -0
  113. package/lib/contracts/visualizer.contract.d.ts +346 -0
  114. package/lib/contracts/viz-config.d.ts +25 -0
  115. package/lib/hex-color-picker/hex-color-picker.component.d.ts +47 -0
  116. package/lib/implementations/base-store-visualizer.d.ts +71 -0
  117. package/lib/implementations/napari-js/napari-axes-labels.d.ts +47 -0
  118. package/lib/implementations/napari-js/napari-region-overlay.d.ts +115 -0
  119. package/lib/implementations/napari-js/napari-scale-bar.d.ts +31 -0
  120. package/lib/implementations/napari-js/napari-visualizer.service.d.ts +455 -0
  121. package/lib/implementations/napari-js/napari-volume-z-handle.d.ts +46 -0
  122. package/lib/implementations/osd/display-pipeline.d.ts +47 -0
  123. package/lib/implementations/osd/histogram-sampler.d.ts +85 -0
  124. package/lib/implementations/osd/openseadragon-visualizer.service.d.ts +476 -0
  125. package/lib/implementations/osd/osd-coordinate-transform.d.ts +17 -0
  126. package/lib/implementations/osd/osd-coords.d.ts +16 -0
  127. package/lib/implementations/osd/osd-lib.d.ts +19 -0
  128. package/lib/implementations/osd/osd-region-overlay.d.ts +191 -0
  129. package/lib/implementations/osd/osd-scale-bar.d.ts +17 -0
  130. package/lib/implementations/osd/slice-cache.d.ts +161 -0
  131. package/lib/implementations/osd/tile-client.d.ts +32 -0
  132. package/lib/implementations/plotly/plotly-coordinate-transform.d.ts +19 -0
  133. package/lib/implementations/plotly/plotly-region-overlay.d.ts +23 -0
  134. package/lib/implementations/plotly/plotly-trace-builders.d.ts +60 -0
  135. package/lib/implementations/plotly/plotly.service.d.ts +594 -0
  136. package/lib/implementations/simple-slice-access.service.d.ts +64 -0
  137. package/lib/models/bezier.d.ts +59 -0
  138. package/lib/models/class-preset.d.ts +39 -0
  139. package/lib/models/geometry.d.ts +66 -0
  140. package/lib/models/region.d.ts +132 -0
  141. package/lib/models/shape.d.ts +44 -0
  142. package/lib/plot.utilities.d.ts +107 -0
  143. package/lib/processing/image-converter.service.d.ts +28 -0
  144. package/lib/processing/image-crop.d.ts +18 -0
  145. package/lib/processing/processing-image.d.ts +17 -0
  146. package/lib/provide-visualization.d.ts +34 -0
  147. package/lib/region-editor/mask-raster.d.ts +61 -0
  148. package/lib/region-editor/mask-worker.d.ts +7 -0
  149. package/lib/region-editor/region-editor.component.d.ts +305 -0
  150. package/lib/region-ops.service.d.ts +92 -0
  151. package/lib/render-orchestrator.d.ts +59 -0
  152. package/lib/routing-visualizer.service.d.ts +227 -0
  153. package/lib/store/class-color.util.d.ts +26 -0
  154. package/lib/store/region-store.service.d.ts +315 -0
  155. package/lib/store/visualizer-store.service.d.ts +123 -0
  156. package/lib/toolbar/brush/brush-tool.service.d.ts +143 -0
  157. package/lib/toolbar/crop/slide-crop.d.ts +30 -0
  158. package/lib/toolbar/segmentation/cell-segment-tool.service.d.ts +32 -0
  159. package/lib/toolbar/segmentation/cellpose-segmenter.service.d.ts +39 -0
  160. package/lib/toolbar/segmentation/onnx-sam-session.d.ts +25 -0
  161. package/lib/toolbar/segmentation/ort-runtime-config.d.ts +4 -0
  162. package/lib/toolbar/segmentation/sam-model-registry.d.ts +36 -0
  163. package/lib/toolbar/segmentation/sam-onnx-core.d.ts +48 -0
  164. package/lib/toolbar/segmentation/sam-point-tool.service.d.ts +59 -0
  165. package/lib/toolbar/segmentation/sam-prompt.d.ts +34 -0
  166. package/lib/toolbar/segmentation/sam-tool.service.d.ts +50 -0
  167. package/lib/toolbar/toolbar.component.d.ts +167 -0
  168. package/lib/toolbar/vertex-eraser/vertex-eraser-tool.service.d.ts +64 -0
  169. package/lib/toolbar/wand/wand-tool.service.d.ts +149 -0
  170. package/lib/toolbar/wand/wand.service.d.ts +133 -0
  171. package/lib/toolbar/zoom-to-box/zoom-to-box-tool.service.d.ts +49 -0
  172. package/lib/visualization.module.d.ts +45 -0
  173. package/lib/visualizer.component.d.ts +378 -0
  174. package/package.json +73 -0
  175. package/src/lib/assets/3d-coordinates.svg +49 -0
  176. package/src/lib/assets/cells.svg +1 -0
  177. package/src/lib/assets/click.svg +1 -0
  178. package/src/lib/assets/colormap-luts.json +1 -0
  179. package/src/lib/assets/contour.svg +48 -0
  180. package/src/lib/assets/cube-3d.svg +1 -0
  181. package/src/lib/assets/edit-selection-white.svg +47 -0
  182. package/src/lib/assets/heatmap.svg +1 -0
  183. package/src/lib/assets/icons/colormap-Pastel1.png +0 -0
  184. package/src/lib/assets/icons/colormap-accent.png +0 -0
  185. package/src/lib/assets/icons/colormap-afmhot.png +0 -0
  186. package/src/lib/assets/icons/colormap-autumn.png +0 -0
  187. package/src/lib/assets/icons/colormap-berlin.png +0 -0
  188. package/src/lib/assets/icons/colormap-binary.png +0 -0
  189. package/src/lib/assets/icons/colormap-blackbody.png +0 -0
  190. package/src/lib/assets/icons/colormap-bluered.png +0 -0
  191. package/src/lib/assets/icons/colormap-blues.png +0 -0
  192. package/src/lib/assets/icons/colormap-bone.png +0 -0
  193. package/src/lib/assets/icons/colormap-brbg.png +0 -0
  194. package/src/lib/assets/icons/colormap-brg.png +0 -0
  195. package/src/lib/assets/icons/colormap-bugn.png +0 -0
  196. package/src/lib/assets/icons/colormap-bupu.png +0 -0
  197. package/src/lib/assets/icons/colormap-bwr.png +0 -0
  198. package/src/lib/assets/icons/colormap-cividis.png +0 -0
  199. package/src/lib/assets/icons/colormap-cmrmap.png +0 -0
  200. package/src/lib/assets/icons/colormap-cool.png +0 -0
  201. package/src/lib/assets/icons/colormap-coolwarm.png +0 -0
  202. package/src/lib/assets/icons/colormap-copper.png +0 -0
  203. package/src/lib/assets/icons/colormap-cubehelix.png +0 -0
  204. package/src/lib/assets/icons/colormap-dark2.png +0 -0
  205. package/src/lib/assets/icons/colormap-earth.png +0 -0
  206. package/src/lib/assets/icons/colormap-electric.png +0 -0
  207. package/src/lib/assets/icons/colormap-flag.png +0 -0
  208. package/src/lib/assets/icons/colormap-gist_earth.png +0 -0
  209. package/src/lib/assets/icons/colormap-gist_gray.png +0 -0
  210. package/src/lib/assets/icons/colormap-gist_heat.png +0 -0
  211. package/src/lib/assets/icons/colormap-gist_ncar.png +0 -0
  212. package/src/lib/assets/icons/colormap-gist_rainbow.png +0 -0
  213. package/src/lib/assets/icons/colormap-gist_stern.png +0 -0
  214. package/src/lib/assets/icons/colormap-gist_yarg.png +0 -0
  215. package/src/lib/assets/icons/colormap-gnbu.png +0 -0
  216. package/src/lib/assets/icons/colormap-gnuplot.png +0 -0
  217. package/src/lib/assets/icons/colormap-gnuplot2.png +0 -0
  218. package/src/lib/assets/icons/colormap-gray.png +0 -0
  219. package/src/lib/assets/icons/colormap-greens-inv.png +0 -0
  220. package/src/lib/assets/icons/colormap-greens.png +0 -0
  221. package/src/lib/assets/icons/colormap-greys-inv.png +0 -0
  222. package/src/lib/assets/icons/colormap-greys.png +0 -0
  223. package/src/lib/assets/icons/colormap-hot.png +0 -0
  224. package/src/lib/assets/icons/colormap-hsv.png +0 -0
  225. package/src/lib/assets/icons/colormap-inferno.png +0 -0
  226. package/src/lib/assets/icons/colormap-jet.png +0 -0
  227. package/src/lib/assets/icons/colormap-magma.png +0 -0
  228. package/src/lib/assets/icons/colormap-managua.png +0 -0
  229. package/src/lib/assets/icons/colormap-nipy_spectral.png +0 -0
  230. package/src/lib/assets/icons/colormap-ocean.png +0 -0
  231. package/src/lib/assets/icons/colormap-oranges.png +0 -0
  232. package/src/lib/assets/icons/colormap-orrd.png +0 -0
  233. package/src/lib/assets/icons/colormap-pastel2.png +0 -0
  234. package/src/lib/assets/icons/colormap-picnic.png +0 -0
  235. package/src/lib/assets/icons/colormap-pink.png +0 -0
  236. package/src/lib/assets/icons/colormap-piyg.png +0 -0
  237. package/src/lib/assets/icons/colormap-placeholder.png +0 -0
  238. package/src/lib/assets/icons/colormap-plasma.png +0 -0
  239. package/src/lib/assets/icons/colormap-portland.png +0 -0
  240. package/src/lib/assets/icons/colormap-prgn.png +0 -0
  241. package/src/lib/assets/icons/colormap-prism.png +0 -0
  242. package/src/lib/assets/icons/colormap-pubu.png +0 -0
  243. package/src/lib/assets/icons/colormap-pubugn.png +0 -0
  244. package/src/lib/assets/icons/colormap-puor.png +0 -0
  245. package/src/lib/assets/icons/colormap-purd.png +0 -0
  246. package/src/lib/assets/icons/colormap-purples.png +0 -0
  247. package/src/lib/assets/icons/colormap-rainbow.png +0 -0
  248. package/src/lib/assets/icons/colormap-rdbu.png +0 -0
  249. package/src/lib/assets/icons/colormap-rdgy.png +0 -0
  250. package/src/lib/assets/icons/colormap-rdpu.png +0 -0
  251. package/src/lib/assets/icons/colormap-rdylbu.png +0 -0
  252. package/src/lib/assets/icons/colormap-rdylgn.png +0 -0
  253. package/src/lib/assets/icons/colormap-reds.png +0 -0
  254. package/src/lib/assets/icons/colormap-seismic.png +0 -0
  255. package/src/lib/assets/icons/colormap-set1.png +0 -0
  256. package/src/lib/assets/icons/colormap-set2.png +0 -0
  257. package/src/lib/assets/icons/colormap-set3.png +0 -0
  258. package/src/lib/assets/icons/colormap-spectral.png +0 -0
  259. package/src/lib/assets/icons/colormap-spring.png +0 -0
  260. package/src/lib/assets/icons/colormap-summer.png +0 -0
  261. package/src/lib/assets/icons/colormap-tab10.png +0 -0
  262. package/src/lib/assets/icons/colormap-tab20.png +0 -0
  263. package/src/lib/assets/icons/colormap-tab20b.png +0 -0
  264. package/src/lib/assets/icons/colormap-tab20c.png +0 -0
  265. package/src/lib/assets/icons/colormap-terrain.png +0 -0
  266. package/src/lib/assets/icons/colormap-turbo.png +0 -0
  267. package/src/lib/assets/icons/colormap-twilight.png +0 -0
  268. package/src/lib/assets/icons/colormap-twilight_shifted.png +0 -0
  269. package/src/lib/assets/icons/colormap-vanimo.png +0 -0
  270. package/src/lib/assets/icons/colormap-viridis.png +0 -0
  271. package/src/lib/assets/icons/colormap-winter.png +0 -0
  272. package/src/lib/assets/icons/colormap-wistia.png +0 -0
  273. package/src/lib/assets/icons/colormap-ylgn.png +0 -0
  274. package/src/lib/assets/icons/colormap-ylgnbu-inv.png +0 -0
  275. package/src/lib/assets/icons/colormap-ylgnbu.png +0 -0
  276. package/src/lib/assets/icons/colormap-ylorbr.png +0 -0
  277. package/src/lib/assets/icons/colormap-ylorrd-inv.png +0 -0
  278. package/src/lib/assets/icons/colormap-ylorrd.png +0 -0
  279. package/src/lib/assets/interactive-segmentation-cursor.svg +1 -0
  280. package/src/lib/assets/invert.svg +1 -0
  281. package/src/lib/assets/isosurface.svg +7 -0
  282. package/src/lib/assets/mask.svg +1 -0
  283. package/src/lib/assets/paintbrush.svg +1 -0
  284. package/src/lib/assets/picture-segmentation.svg +43 -0
  285. package/src/lib/assets/polygon-vertices.svg +13 -0
  286. package/src/lib/assets/polyline.svg +3 -0
  287. package/src/lib/assets/redo.svg +39 -0
  288. package/src/lib/assets/region-editor.svg +37 -0
  289. package/src/lib/assets/region-move.svg +7 -0
  290. package/src/lib/assets/smooth.svg +56 -0
  291. package/src/lib/assets/spline-chart.svg +7 -0
  292. package/src/lib/assets/surface.svg +37 -0
  293. package/src/lib/assets/test/download-379.svg +1 -0
  294. package/src/lib/assets/test/download-98.svg +1 -0
  295. package/src/lib/assets/test/json-1.svg +1 -0
  296. package/src/lib/assets/test/load-53.svg +1 -0
  297. package/src/lib/assets/test/mask-44.svg +1 -0
  298. package/src/lib/assets/test/mask-download-44.svg +15 -0
  299. package/src/lib/assets/test/mask-save-44.svg +11 -0
  300. package/src/lib/assets/test/overlay-1.svg +1 -0
  301. package/src/lib/assets/test/overlay-4.svg +1 -0
  302. package/src/lib/assets/test/region-26.svg +1 -0
  303. package/src/lib/assets/test/save-56.svg +1 -0
  304. package/src/lib/assets/test/upload-43.svg +1 -0
  305. package/src/lib/assets/to-bezier.svg +15 -0
  306. package/src/lib/assets/to-polygon.svg +11 -0
  307. package/src/lib/assets/undo.svg +38 -0
  308. package/src/lib/assets/vertex-add.svg +12 -0
  309. package/src/lib/assets/vertex-delete.svg +12 -0
  310. package/src/lib/assets/wand.svg +54 -0
  311. package/src/lib/assets/zoom-box.svg +10 -0
@@ -0,0 +1,227 @@
1
+ import { Observable } from 'rxjs';
2
+ import { Image } from 'image-js';
3
+ import { IImageInfo, IImageMetadata } from './contracts/image.contract';
4
+ import { Region } from './models/region';
5
+ import { ClassPreset, PresetSet } from './models/class-preset';
6
+ import { PlotlyService } from './implementations/plotly/plotly.service';
7
+ import { OpenSeadragonVisualizerService } from './implementations/osd/openseadragon-visualizer.service';
8
+ import { PlotType, PlotTypeDescriptor } from './contracts/plot-type';
9
+ import { IVisualizer, PixelData, IntensityProfile, IIsosurfaceControls, IIntensityControls, ISurface3dControls } from './contracts/visualizer.contract';
10
+ import { ViewerCapabilities } from './contracts/capabilities.contract';
11
+ import { IRegionOverlay } from './contracts/region-overlay.contract';
12
+ import { IRegionEditorApi } from './contracts/region-editor-api.contract';
13
+ import { IChannelHistogramApi, IChannelState, IHistogram } from './contracts/channel-histogram-api.contract';
14
+ import { VisualizerStore } from './store/visualizer-store.service';
15
+ import { NapariVisualizerService } from './implementations/napari-js/napari-visualizer.service';
16
+ import { VizConfig } from './contracts/viz-config';
17
+ import * as i0 from "@angular/core";
18
+ export declare class RoutingVisualizerService implements IVisualizer, IRegionEditorApi, IChannelHistogramApi {
19
+ private plotly;
20
+ private osd;
21
+ private napari;
22
+ private store;
23
+ private config;
24
+ private currentPlotType;
25
+ private lastRendered;
26
+ /** OSD failed for the *current* render cycle (e.g. a fresh file still caching
27
+ * past the deadline) → fall back to Plotly for this image only. Reset by
28
+ * reset() at the start of every render cycle, so the next file — or a
29
+ * re-select once the file is cached — retries OSD. (Was a permanent flag,
30
+ * which left the whole session stuck on Plotly after one slow load.) */
31
+ private osdFellBack;
32
+ /** napari-js failed for the current render cycle → fall back to OSD (then Plotly).
33
+ * Reset by reset() at the start of every cycle, like {@link osdFellBack}. */
34
+ private napariFellBack;
35
+ constructor(plotly: PlotlyService, osd: OpenSeadragonVisualizerService, napari: NapariVisualizerService, store: VisualizerStore, config: VizConfig);
36
+ private isImageType;
37
+ /** The 2D napari types (image + region-centroid scatter) — a 2D fallback chain (OSD, then Plotly). */
38
+ private isNapariImageType;
39
+ /** The 3D napari types (volume/isosurface, either resolution) — no 2D fallback exists (OSD is
40
+ * image-only), so they fall straight to Plotly. */
41
+ private isNapari3dType;
42
+ /**
43
+ * Backend to attempt for the current plot type this render. The fallback chains below are
44
+ * mirrored exactly by {@link load} so the handle `plot()` receives always comes from the
45
+ * backend `plot()` selects (no load/plot backend mismatch):
46
+ * - 2D image (explicit `NAPARI_IMAGE`, or `IMAGE` with the WebGPU opt-in): napari-js → OSD → Plotly.
47
+ * - plain `IMAGE` (no opt-in): OSD → Plotly.
48
+ * - 3D napari (`NAPARI_VOLUME`/`NAPARI_ISOSURFACE`): napari-js → Plotly (OSD can't render 3D).
49
+ */
50
+ private imageBackend;
51
+ /** Backend currently on screen — what ongoing zoom/tool/region ops act on. */
52
+ private renderer;
53
+ get capabilities(): ViewerCapabilities;
54
+ load(imageInfo: IImageInfo, zIndex: number): Promise<any>;
55
+ /** Try OSD; on failure fall back to Plotly for this image (not permanent — see reset()). */
56
+ private loadViaOsdThenPlotly;
57
+ plot(plotDiv: string, imageLoaded: any, imageInfo: IImageInfo, screenHeight: number, plotType: PlotType, inPlace?: boolean): Promise<boolean>;
58
+ reloadAndPlot(): void;
59
+ reset(): void;
60
+ relayout(trueImageSize?: number[]): void;
61
+ resetAxes(): void;
62
+ autoscale(): void;
63
+ zoomIn(): void;
64
+ zoomOut(): void;
65
+ setDragMode(mode: string | false): void;
66
+ setNavigatorVisible(visible: boolean): void;
67
+ setImageSmoothingEnabled(enabled: boolean): void;
68
+ setShowStack(showstack: boolean): void;
69
+ setZIndex(zIndex: number): void;
70
+ getTrueImageSize(): {
71
+ width: number;
72
+ height: number;
73
+ } | null;
74
+ getCurrentImage(): Promise<Image | null>;
75
+ getDisplayedPixelData(): PixelData | null;
76
+ getDisplayedSourceRect(): {
77
+ x: number;
78
+ y: number;
79
+ width: number;
80
+ height: number;
81
+ } | null;
82
+ downloadImage(): void;
83
+ exportComposite(): void;
84
+ setPlotType(plotType: PlotType): void;
85
+ setSurfaceDragMode(mode: string): void;
86
+ resetSurfaceCamera(): void;
87
+ setResolutionScale(scale: number): void;
88
+ getResolutionScale(): number;
89
+ getPlotTypeDescriptors(): PlotTypeDescriptor[];
90
+ setStackLoading(b: boolean): void;
91
+ cancelLoading(): void;
92
+ isStackLoading(): Observable<boolean>;
93
+ getStackLoadingProgress(): Observable<number>;
94
+ getAutoscaleEvent(): Observable<any>;
95
+ getIntensityProfile$(): Observable<IntensityProfile[]>;
96
+ renderIntensityInset(divId: string, profiles: IntensityProfile[]): void;
97
+ setRegions(regions: Region[], showRegionLabel?: boolean, isRegionSaveOn?: boolean, fillColor?: string, append?: boolean): void;
98
+ getRegions(): Region[];
99
+ getRegionPolygons(): any[];
100
+ getRegionUpdateEvent(): Observable<any[]>;
101
+ setSelectedShapeIndices(indices: number[]): void;
102
+ selectRegion(region: Region): void;
103
+ getSelectedShapeIndices$(): Observable<number[]>;
104
+ deleteActiveShape(): void;
105
+ getShowShapeLabel(): boolean;
106
+ getShapeColor(): string;
107
+ getFillColor(): string;
108
+ getClassificationColors(): Map<string, string>;
109
+ setClassificationColor(label: string, color: string): void;
110
+ getPresetSet(): PresetSet;
111
+ getPresetSet$(): Observable<PresetSet>;
112
+ setPresetSet(set: PresetSet): void;
113
+ upsertClass(preset: ClassPreset): void;
114
+ removeClass(name: string): void;
115
+ resetPresets(): void;
116
+ plotPreviousShapes(): void;
117
+ setPreviousShapes(shapes: any[]): void;
118
+ getPreviousShapes(): any[];
119
+ undo(): void;
120
+ redo(): void;
121
+ canUndo(): boolean;
122
+ canRedo(): boolean;
123
+ getCanUndo$(): Observable<boolean>;
124
+ getCanRedo$(): Observable<boolean>;
125
+ resetUndoHistory(): void;
126
+ importRegions(geoJsonStr: string): Region[];
127
+ exportRegions(regions: Region[]): void;
128
+ getGeoJsonString(regions: Region[]): string;
129
+ enterStackMode(slices: Map<number, Region[]>, initialZ?: number, saveLayout?: 'combined' | 'per-slice-file'): void;
130
+ exitStackMode(): void;
131
+ isStackMode(): boolean;
132
+ getStackSaveLayout(): 'combined' | 'per-slice-file';
133
+ setDisplaySlice(z: number): void;
134
+ getSliceRegions(): Region[];
135
+ getStackSaveSlices(): Map<number, Region[]>;
136
+ /** All slices' ANNOTATION regions for a z-stack save (jit-ui#93), each tagged
137
+ * with its zero-based Region.z; profile lines excluded. Flat annotation set
138
+ * outside stack mode. */
139
+ getSliceAnnotationRegions(): Region[];
140
+ /** Per-slice annotation regions to write on a folder-stack save (jit-ui#93):
141
+ * slice index → that slice's annotation regions (profile lines excluded),
142
+ * including now-empty slices that were loaded non-empty (so they overwrite). */
143
+ getStackSaveAnnotationSlices(): Map<number, Region[]>;
144
+ /** Authoritative full-resolution image size for mask export. Prefers the
145
+ * active renderer's reported size, falling back to the image metadata (x/y
146
+ * are the full-res pixel dimensions used across the app). Rejects non-finite
147
+ * or non-positive sizes — the Plotly bounds can yield NaN before a plot is
148
+ * fully laid out, which would otherwise crash mask creation. */
149
+ getMaskImageSize(): {
150
+ width: number;
151
+ height: number;
152
+ } | null;
153
+ getAnnotationRegions(): Region[];
154
+ setAnnotationRegions(regions: Region[], showRegionLabel?: boolean, isRegionSaveOn?: boolean, fillColor?: string): void;
155
+ getSelectedRegions$(): Observable<Region[]>;
156
+ setSelectedRegions(regions: Region[]): void;
157
+ setWandMode(active: boolean, options?: any): void;
158
+ setWandOptions(options: any): void;
159
+ clearActiveWandRegion(): void;
160
+ setBrushMode(active: boolean, options?: any): void;
161
+ setBrushOptions(options: any): void;
162
+ setVertexEraserMode(active: boolean): void;
163
+ setVertexEraserRadius(radius: number): void;
164
+ setZoomToBoxMode(active: boolean): void;
165
+ segmentRectangles(): Promise<number>;
166
+ segmentRectanglesCellpose(): Promise<number>;
167
+ setSamModel(id: string): void;
168
+ setSamPointMode(active: boolean): void;
169
+ commitSamPoints(): void;
170
+ clearSamPoints(): void;
171
+ getColormap(): Observable<any>;
172
+ setColormap(colormap: any): void;
173
+ getColormapOptions(): any;
174
+ getReverseScale(): Observable<boolean>;
175
+ setReverseScale(reverscale: any): void;
176
+ setImageMeta(imageMeta: IImageMetadata[]): void;
177
+ getImageMeta(): Observable<IImageMetadata[]>;
178
+ getHistogram(channelIndex: number, bins: number): IHistogram | null;
179
+ getHistogram$(channelIndex: number, bins: number): Observable<IHistogram | null>;
180
+ /** Export the underlying data (16-bit multi-band TIFF) via the active backend. */
181
+ exportData(): void;
182
+ getChannels$(): Observable<IChannelState[]>;
183
+ setChannelState(index: number, partial: Partial<IChannelState>): void;
184
+ resetContrast(indices: number[]): void;
185
+ /** Auto-window each channel by saturating `saturation` (0..1) of pixels at each
186
+ * end of its histogram (skipping outlier first/last bins). */
187
+ autoContrast(indices: number[], saturation: number): void;
188
+ getGrayscale$(): Observable<boolean>;
189
+ setGrayscale(on: boolean): void;
190
+ getInvert$(): Observable<boolean>;
191
+ setInvert(on: boolean): void;
192
+ /**
193
+ * The active backend's region overlay. Falls back to Plotly's when the active backend
194
+ * (OSD or napari-js) is selected but a plot isn't mounted yet, so callers always get a
195
+ * usable overlay.
196
+ */
197
+ getRegionOverlay(): IRegionOverlay;
198
+ /**
199
+ * Isosurface controls when available — always Plotly's, since the isosurface
200
+ * plot type renders on Plotly (OSD only handles the image type).
201
+ */
202
+ getIsosurfaceControls(): IIsosurfaceControls | null;
203
+ /** 3D scene controls — always Plotly's, since the 3D plot types render on
204
+ * Plotly (OSD only handles the image type). */
205
+ getSurface3dControls(): ISurface3dControls | null;
206
+ /** Intensity (line-ROI) controls — always Plotly's, since the line profiles
207
+ * render their inset on Plotly regardless of which backend draws the image. */
208
+ getIntensityControls(): IIntensityControls | null;
209
+ /** Load pixel frames for intensity sampling when OpenSeadragon owns the image
210
+ * (it doesn't feed Plotly's frame cache). No-op needed when Plotly renders. */
211
+ ensureIntensitySampling(imageInfo: IImageInfo, zIndex: number): Promise<void>;
212
+ /** Visible-region changes from the OpenSeadragon viewer (image-pixel coords),
213
+ * so the intensity inset can re-sample at the current zoom level. Plotly's own
214
+ * high-def zoom updates the sampling cache inline, so only OSD feeds this. */
215
+ getViewportChange$(): Observable<{
216
+ x: number;
217
+ y: number;
218
+ width: number;
219
+ height: number;
220
+ }>;
221
+ /** Re-sample the intensity profiles from a fresh crop of the given image-pixel
222
+ * ROI at display resolution (sampling always lives in Plotly). */
223
+ refreshIntensitySamplingForRoi(x: number, y: number, width: number, height: number, zIndex: number): void;
224
+ unsubscribe(): void;
225
+ static ɵfac: i0.ɵɵFactoryDeclaration<RoutingVisualizerService, never>;
226
+ static ɵprov: i0.ɵɵInjectableDeclaration<RoutingVisualizerService>;
227
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Deterministic colour engine for preset annotation classes (jit-ui#70).
3
+ *
4
+ * Resolution order for a region `label`:
5
+ * 1. a matching preset (exact by default, or normalized if the set's matchMode says so)
6
+ * -> the preset's colour;
7
+ * 2. otherwise a deterministic fallback colour derived from a stable hash of the name,
8
+ * so the same unknown class always gets the same colour with no stored state.
9
+ *
10
+ * These functions are pure (no mutation); opt-in promotion of unknown classes into the
11
+ * set is handled by the store, which owns persistence.
12
+ */
13
+ import { ClassPreset, PresetSet } from '../models/class-preset';
14
+ export declare function normalizeLabel(s: string): string;
15
+ /** Stable, non-negative 32-bit string hash (identical across runs and machines). */
16
+ export declare function hashString(s: string): number;
17
+ /** Find the preset matching `label` under the set's match mode. */
18
+ export declare function findPreset(label: string, set: PresetSet): ClassPreset | undefined;
19
+ /**
20
+ * Deterministic fallback colour for an unknown class name: index into the palette by a
21
+ * stable hash of the (normalized) name; if the palette is empty, generate a golden-angle
22
+ * HSL hue. Same name -> same colour, every run.
23
+ */
24
+ export declare function fallbackColorFor(label: string, palette: string[]): string;
25
+ /** Resolve a colour for `label`: a matching preset's colour, else the deterministic fallback. */
26
+ export declare function colorForLabel(label: string, set: PresetSet): string;
@@ -0,0 +1,315 @@
1
+ import { Observable } from 'rxjs';
2
+ import { IImageInfo } from '../contracts/image.contract';
3
+ import { Region, Rectangle, Polygon, MultiPolygon } from '../models/region';
4
+ import { VisualizerStore } from './visualizer-store.service';
5
+ import { IRegionStore } from '../contracts/visualizer.contract';
6
+ import { IRegionEditApi } from '../contracts/region-store.contract';
7
+ import * as i0 from "@angular/core";
8
+ /**
9
+ * Backend-neutral region store — the single source of truth for region state.
10
+ *
11
+ * Holds the neutral {@link Region} model (never a backend's own shape
12
+ * representation), keyed per image so regions persist as the user switches
13
+ * files and survive a Plotly⇄OpenSeadragon backend switch (both backends read
14
+ * and write *this* store, so no migration is needed). Backends own *rendering*
15
+ * and react to {@link getRegionUpdateEvent}; this service owns *state* and the
16
+ * editing operations.
17
+ *
18
+ * Implements:
19
+ * - {@link IRegionStore} — the cross-backend CRUD/selection/colour contract
20
+ * every consumer (Region Editor, segmentation, etc.) already uses.
21
+ * - {@link IRegionEditApi} — Region-native geometry edits (move/resize, and
22
+ * add/delete/move vertex) the OSD overlay drives.
23
+ *
24
+ * Classification colours live in {@link VisualizerStore} (shared by both
25
+ * backends); GeoJSON import/export and the closed-polygon projection reuse the
26
+ * neutral {@link PlotUtilities} helpers. All coordinates are image pixels.
27
+ */
28
+ export declare class RegionStore implements IRegionStore, IRegionEditApi {
29
+ private store;
30
+ private static readonly UNDO_LIMIT;
31
+ private static readonly UNDO_COALESCE_MS;
32
+ /** Per-image region cache. `regions` is always a snapshot of the entry for
33
+ * `currentImageKey`. */
34
+ private regionsByImageKey;
35
+ private currentImageKey;
36
+ /** The current image's regions — the live, edited array. */
37
+ private regions;
38
+ /** Last saved snapshot, restorable via plotPreviousShapes(). */
39
+ private previousRegions;
40
+ /**
41
+ * Undo/redo history (jit-ui#85): up to {@link UNDO_LIMIT} snapshots of the
42
+ * region set, each a deep clone captured immediately *before* a
43
+ * region-editing action. {@link undo} pops the newest off `undoStack`, pushes
44
+ * the current state onto `redoStack`, and restores it — so it can be invoked
45
+ * up to {@link UNDO_LIMIT} times in a row. {@link redo} is the mirror. Any new
46
+ * region action clears `redoStack` (the redo future is no longer reachable).
47
+ *
48
+ * A continuous gesture (a wand/brush/vertex drag commits to the store many
49
+ * times) is coalesced into a single entry: the first commit of a burst
50
+ * captures the pre-burst state and every commit within
51
+ * {@link UNDO_COALESCE_MS} of the previous one is folded into it. History
52
+ * never crosses an image load/switch — {@link resetUndoHistory} clears it.
53
+ */
54
+ private undoStack;
55
+ private redoStack;
56
+ /** True while a coalescing burst is open (further commits fold into it). */
57
+ private undoBurstOpen;
58
+ private undoBurstTimer;
59
+ /** True while restoring a snapshot, so the restore records no new history. */
60
+ private restoringUndo;
61
+ private readonly canUndo$;
62
+ private readonly canRedo$;
63
+ /** Monotonic id source — ids never repeat within the service lifetime, so
64
+ * selection stays correct across delete/add cycles even when names collide. */
65
+ private nextId;
66
+ private showShapeLabel;
67
+ private shapeColor;
68
+ private fillColor;
69
+ private isRegionSavedOn;
70
+ /**
71
+ * Per-slice region support for z-stacks (jit-ui#93). While {@link stackMode}
72
+ * is on (a z-stack is loaded), the live `regions` array always holds ONE
73
+ * slice — the {@link currentSliceZ} slice — so the on-canvas overlays, the
74
+ * selection projection, and the Regions table keep working unchanged
75
+ * (they all read {@link getRegions}). The other slices live in
76
+ * {@link regionsBySlice}; {@link setDisplaySlice} swaps the live set on scrub
77
+ * and {@link getSliceRegions} flattens every slice (each tagged with its
78
+ * zero-based {@link Region.z}) for save/export. Off by default (stackMode
79
+ * false, z 0), so single-plane images are completely unaffected.
80
+ */
81
+ private regionsBySlice;
82
+ private stackMode;
83
+ private currentSliceZ;
84
+ /** How a stack's regions round-trip to disk (jit-ui#93): `combined` writes one
85
+ * z-indexed geojson (single-file z-stack, QuPath schema); `per-slice-file`
86
+ * writes one geojson per slice-file (a folder of numbered images). */
87
+ private stackSaveLayout;
88
+ /** Slices that were loaded with regions (jit-ui#93). A per-slice-file save
89
+ * re-writes these even when now empty, so clearing a slice's regions and
90
+ * saving removes its previously-saved geojson (writes an empty one). */
91
+ private stackInitialNonEmpty;
92
+ /** Selection is tracked by region *id* internally (stable across edits) and
93
+ * projected to array indices on the IRegionStore boundary. */
94
+ private selectedIds;
95
+ private readonly selectedIndices$;
96
+ private readonly regionUpdate$;
97
+ /** Non-coalesced sibling of regionUpdate$: fires on every change even during a
98
+ * batched drag, so live consumers (intensity inset) update per frame. */
99
+ private readonly regionLiveEdit$;
100
+ /** Emit coalescing for live drags (see IRegionEditApi.beginBatch). */
101
+ private batchDepth;
102
+ private pendingEmit;
103
+ private readonly plotUtilities;
104
+ constructor(store: VisualizerStore);
105
+ /**
106
+ * Replace (or, with `append`, add to) the current image's regions. Mints ids
107
+ * and default names, applies stored classification colours, and emits. When
108
+ * `isRegionSaveOn` is false the regions are shown transiently (emitted) but
109
+ * not stored — mirrors the previous Plotly behaviour.
110
+ */
111
+ setRegions(regions: Region[], showRegionLabel?: boolean, isRegionSaveOn?: boolean, fillColor?: string, append?: boolean): void;
112
+ /** The canonical accessor: current image's regions (live instances). */
113
+ getRegions(): Region[];
114
+ /** True while a z-stack is loaded and the store holds regions per slice. */
115
+ isStackMode(): boolean;
116
+ /** The current display slice (zero-based). */
117
+ getDisplaySlice(): number;
118
+ /** How the current stack persists to disk (jit-ui#93): `combined` = one
119
+ * z-indexed geojson (single-file z-stack); `per-slice-file` = one geojson per
120
+ * slice-file (folder stack). Meaningless outside stack mode. */
121
+ getStackSaveLayout(): 'combined' | 'per-slice-file';
122
+ /**
123
+ * Enter per-slice stack mode. `slices` maps each zero-based slice index to
124
+ * the regions imported for that slice; the store makes `initialZ`'s slice the
125
+ * live set, so the overlays / selection / Regions table are unchanged (they
126
+ * still read {@link getRegions}). Freshly-created regions are tagged with the
127
+ * current slice so they persist on it, and {@link getSliceRegions} returns
128
+ * every slice for save/export. Ids/names/classification colours are minted
129
+ * exactly as {@link setRegions} does.
130
+ */
131
+ enterStackMode(slices: Map<number, Region[]>, initialZ?: number, saveLayout?: 'combined' | 'per-slice-file'): void;
132
+ /** Leave stack mode (single-plane image, or the stack was closed). */
133
+ exitStackMode(): void;
134
+ /**
135
+ * Show a different slice: capture the current slice's (possibly edited)
136
+ * regions back into the per-slice store, then load the target slice's regions
137
+ * as the live set and emit. Undo never crosses a slice. Outside stack mode
138
+ * this only records the requested slice index (a no-op otherwise: single-plane
139
+ * regions stay on the default plane — addRegion tags Region.z only in stack
140
+ * mode, so the recorded index is unused until a stack is entered). (jit-ui#93)
141
+ */
142
+ setDisplaySlice(z: number): void;
143
+ /**
144
+ * Every slice's regions for save/export, each tagged with its zero-based
145
+ * slice index in {@link Region.z}. Captures the current slice's live edits
146
+ * first. Returns the flat single-plane set when not in stack mode. (jit-ui#93)
147
+ */
148
+ getSliceRegions(): Region[];
149
+ /**
150
+ * Slices to write on a per-slice-file save (folder stack, jit-ui#93): every
151
+ * slice that currently has regions, PLUS slices that were loaded non-empty but
152
+ * are now empty (so their file is re-written empty, clearing a slice whose
153
+ * regions the user deleted). Each returned region is tagged with its z, and
154
+ * the current live slice is captured first. Empty outside stack mode.
155
+ */
156
+ getStackSaveSlices(): Map<number, Region[]>;
157
+ /** Mint ids/names + apply classification colours + tag the slice index, as
158
+ * {@link setRegions} does, for regions entering the per-slice store. */
159
+ private normalizeSlice;
160
+ /**
161
+ * Closed polygons projected for image-processing consumers (segmentation,
162
+ * trace builders). Open polylines are annotation-only and excluded. Reuses
163
+ * the neutral PlotUtilities projection so output matches the previous path.
164
+ */
165
+ getRegionPolygons(): any[];
166
+ getRegionUpdateEvent(): Observable<any[]>;
167
+ /** Live (non-coalesced) region-change stream — fires per frame during a drag.
168
+ * Used by the intensity-profile inset so it tracks line ROIs live. */
169
+ getRegionLiveEdit$(): Observable<Region[]>;
170
+ /** Select regions by array index (or [] to clear). Stored internally by id
171
+ * so the selection survives subsequent edits/reorders. */
172
+ setSelectedShapeIndices(indices: number[]): void;
173
+ /** Select a single region by identity (id). Backends call this from their
174
+ * `selectRegion()`; the OSD overlay + region editor highlight off the
175
+ * resulting selection emit. No-op if the region isn't in the store. */
176
+ selectRegion(region: Region): void;
177
+ getSelectedShapeIndices$(): Observable<number[]>;
178
+ /** Synchronous current selection (array indices) — for callers that need to
179
+ * read the selection without subscribing. */
180
+ getSelectedShapeIndices(): number[];
181
+ /** Delete the currently selected regions and clear the selection. */
182
+ deleteActiveShape(): void;
183
+ getShowShapeLabel(): boolean;
184
+ getShapeColor(): string;
185
+ getFillColor(): string;
186
+ /** Convenience setters (not on the contract) for toolbar wiring. */
187
+ setShowShapeLabel(show: boolean): void;
188
+ setShapeColor(color: string): void;
189
+ setFillColor(color: string): void;
190
+ getClassificationColors(): Map<string, string>;
191
+ setClassificationColor(label: string, color: string): void;
192
+ /** Re-show the last saved snapshot (transient — does not alter stored state). */
193
+ plotPreviousShapes(): void;
194
+ setPreviousShapes(shapes: any[]): void;
195
+ getPreviousShapes(): any[];
196
+ /** Emits whether an undo step is currently available — drives the toolbar
197
+ * Undo button's enabled state (greyed out when false). */
198
+ getCanUndo$(): Observable<boolean>;
199
+ /** Emits whether a redo step is currently available — drives the toolbar
200
+ * Redo button's enabled state. */
201
+ getCanRedo$(): Observable<boolean>;
202
+ /** Synchronous read of {@link getCanUndo$} — true when at least one region
203
+ * action can be undone. */
204
+ canUndo(): boolean;
205
+ /** Synchronous read of {@link getCanRedo$} — true when an undone action can
206
+ * be re-applied. */
207
+ canRedo(): boolean;
208
+ /**
209
+ * Undo the most recent region action, restoring the region set to its state
210
+ * just before that action and pushing the current state onto the redo stack.
211
+ * Up to {@link UNDO_LIMIT} steps are retained, so this can be called up to
212
+ * {@link UNDO_LIMIT} times in a row before the history empties. No-op when
213
+ * nothing is left to undo.
214
+ */
215
+ undo(): void;
216
+ /**
217
+ * Redo the action most recently undone, restoring the region set to the state
218
+ * it had before that undo and pushing the current state back onto the undo
219
+ * stack. No-op when there's nothing to redo (the redo stack is cleared by any
220
+ * fresh region action).
221
+ */
222
+ redo(): void;
223
+ /** Discard the undo/redo history (e.g. on image load/switch — history never
224
+ * crosses images). */
225
+ resetUndoHistory(): void;
226
+ /** Make `snapshot` the live region set and notify both backends. Shared by
227
+ * {@link undo} and {@link redo}; the snapshot is already a detached deep
228
+ * clone, so it becomes the live array directly. */
229
+ private restoreSnapshot;
230
+ /**
231
+ * Capture the pre-action region set into the bounded undo history. Called at
232
+ * the top of every mutating operation, *before* it changes `regions`, so the
233
+ * snapshot is the state to return to. Rapid commits from one gesture coalesce
234
+ * into a single entry (see {@link undoStack}). A fresh action also abandons
235
+ * any redo future.
236
+ */
237
+ private recordUndoSnapshot;
238
+ /** Push the current can-undo / can-redo availability to subscribers. */
239
+ private emitUndoState;
240
+ /** (Re)arm the idle timer that closes the current coalescing burst. */
241
+ private armUndoBurst;
242
+ private closeUndoBurst;
243
+ private cloneRegions;
244
+ /** Deep clone a region so an in-place geometry edit can't mutate a stored
245
+ * history snapshot (bounds are cloned via {@link cloneBounds}). */
246
+ private cloneRegion;
247
+ importRegions(geoJsonStr: string): Region[];
248
+ exportRegions(regions: Region[]): void;
249
+ getGeoJsonString(regions: Region[]): string;
250
+ addRegion(region: Region): number;
251
+ removeRegion(id: number): void;
252
+ updateBounds(id: number, bounds: Rectangle | Polygon | MultiPolygon): void;
253
+ moveRegion(id: number, dx: number, dy: number): void;
254
+ /** Translate a polygon's vertices and any holes in place by (dx, dy). */
255
+ private translatePolygon;
256
+ moveVertex(id: number, index: number, x: number, y: number): void;
257
+ /** Move a vertex on a polygon's interior ring (hole) — jit-ui#85. */
258
+ moveHoleVertex(id: number, holeIndex: number, index: number, x: number, y: number): void;
259
+ /** Insert a vertex on a polygon's interior ring (hole), after `segIndex`
260
+ * (the edge's start vertex). No-op for an out-of-range hole — jit-ui#85. */
261
+ addHoleVertex(id: number, holeIndex: number, segIndex: number, x: number, y: number): void;
262
+ /** Delete the vertex at `index` on a polygon's interior ring (hole). Removing
263
+ * it below 3 vertices drops the whole hole (a ring with < 3 points bounds no
264
+ * area) — jit-ui#85. */
265
+ deleteHoleVertex(id: number, holeIndex: number, index: number): void;
266
+ addVertex(id: number, segIndex: number, x: number, y: number): void;
267
+ deleteVertex(id: number, index: number): void;
268
+ setBezier(id: number, bezier: boolean): void;
269
+ /** Turn bezier on (and seed editable handles from the smooth default) or off
270
+ * (and drop the handles). */
271
+ private applyBezier;
272
+ /** (Re)seed per-hole bezier handles from the Catmull-Rom default, parallel to `poly.holes`. */
273
+ private seedHoleHandles;
274
+ /** Drag a bezier control point on a hole ring vertex (donut bezier editing). */
275
+ moveHoleBezierHandle(id: number, holeIndex: number, index: number, side: 'in' | 'out', x: number, y: number): void;
276
+ moveBezierHandle(id: number, index: number, side: 'in' | 'out', x: number, y: number): void;
277
+ beginBatch(): void;
278
+ endBatch(): void;
279
+ /**
280
+ * Switch the active image: snapshot the outgoing regions, restore the
281
+ * incoming image's (or [] if none), clear selection, and notify. Idempotent
282
+ * for the same image (so repeated replots of one image keep its regions).
283
+ */
284
+ setActiveImage(imageInfo: IImageInfo): void;
285
+ /** Drop the entire per-image cache (logout / project switch). */
286
+ clearRegionsByImageKey(): void;
287
+ private deriveImageKey;
288
+ /**
289
+ * Resolve each region's colour from the annotation-class preset set (jit-ui#70).
290
+ * The presets are the source of truth for colour — this **overrides any colour
291
+ * embedded in the GeoJSON** (which the YOLO worker writes today). A matching
292
+ * preset gives the class colour; an unknown class gets a deterministic fallback
293
+ * colour (and, only when `autoPromote` is on, is added to the editable list).
294
+ * Regions the user explicitly recoloured (`colorOverridden`) are left untouched.
295
+ */
296
+ private applyClassificationColors;
297
+ private syncCache;
298
+ private emit;
299
+ /** Project selected ids to current array indices, pruning ids that no longer
300
+ * exist, and emit if the index set changed. */
301
+ private emitSelection;
302
+ private indicesEqual;
303
+ private findById;
304
+ private indexOfId;
305
+ /** The region's bounds as a Polygon, or undefined if it isn't a polygon. */
306
+ private polygonOf;
307
+ private clonePolygon;
308
+ private cloneBounds;
309
+ private regionsEqual;
310
+ private polygonsEqual;
311
+ /** Compare two polygons' interior-ring (hole) sets for the dedupe path. */
312
+ private holesEqual;
313
+ static ɵfac: i0.ɵɵFactoryDeclaration<RegionStore, never>;
314
+ static ɵprov: i0.ɵɵInjectableDeclaration<RegionStore>;
315
+ }