@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,57 @@
1
+ /**
2
+ * Browser "slide crop": extract the box region (data coords) from a cached image
3
+ * frame as an RGBA image, clamped to the image bounds. Grayscale frames are
4
+ * replicated across R/G/B; RGB tuples are copied through. Returns null when the
5
+ * box is empty/outside the image.
6
+ *
7
+ * The output feeds an automatic segmenter (e.g. cellpose-SAM): run it on the
8
+ * crop, then offset the resulting masks by (matrixX0, matrixY0) to place them
9
+ * back on the full frame.
10
+ */
11
+ export function cropImageRegion(cached, frameIndex, box) {
12
+ const rx = cached.ratios[0] || 1;
13
+ const ry = cached.ratios[0] || 1;
14
+ const ox = cached.originX ?? 0;
15
+ const oy = cached.originY ?? 0;
16
+ // data -> image (matrix) coords, normalized + clamped to the frame.
17
+ let mx0 = Math.round((Math.min(box.x0, box.x1) - ox) / rx);
18
+ let my0 = Math.round((Math.min(box.y0, box.y1) - oy) / ry);
19
+ let mx1 = Math.round((Math.max(box.x0, box.x1) - ox) / rx);
20
+ let my1 = Math.round((Math.max(box.y0, box.y1) - oy) / ry);
21
+ mx0 = Math.max(0, Math.min(cached.width, mx0));
22
+ my0 = Math.max(0, Math.min(cached.height, my0));
23
+ mx1 = Math.max(0, Math.min(cached.width, mx1));
24
+ my1 = Math.max(0, Math.min(cached.height, my1));
25
+ const cw = mx1 - mx0;
26
+ const ch = my1 - my0;
27
+ if (cw <= 0 || ch <= 0)
28
+ return null;
29
+ const frame = cached.frames[frameIndex] ?? cached.frames[0];
30
+ const data = new Uint8ClampedArray(cw * ch * 4);
31
+ for (let y = 0; y < ch; y++) {
32
+ const row = frame?.[my0 + y];
33
+ for (let x = 0; x < cw; x++) {
34
+ const o = (y * cw + x) * 4;
35
+ const px = row?.[mx0 + x];
36
+ if (px == null) {
37
+ data[o + 3] = 255;
38
+ continue;
39
+ }
40
+ if (cached.isGrayscale) {
41
+ const v = px;
42
+ data[o] = v;
43
+ data[o + 1] = v;
44
+ data[o + 2] = v;
45
+ }
46
+ else {
47
+ const t = px;
48
+ data[o] = t[0];
49
+ data[o + 1] = t[1];
50
+ data[o + 2] = t[2];
51
+ }
52
+ data[o + 3] = 255;
53
+ }
54
+ }
55
+ return { data, width: cw, height: ch, matrixX0: mx0, matrixY0: my0 };
56
+ }
57
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2xpZGUtY3JvcC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvdG9vbGJhci9jcm9wL3NsaWRlLWNyb3AudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBaUJBOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sVUFBVSxlQUFlLENBQzdCLE1BQXVCLEVBQUUsVUFBa0IsRUFBRSxHQUFZO0lBRXpELE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2pDLE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2pDLE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDO0lBQy9CLE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDO0lBQy9CLG9FQUFvRTtJQUNwRSxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQztJQUMzRCxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQztJQUMzRCxJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQztJQUMzRCxJQUFJLEdBQUcsR0FB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LENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQztRQUNwQixDQUFDO0lBQ0gsQ0FBQztJQUNELE9BQU8sRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsUUFBUSxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBQ3ZFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDYWNoZWRJbWFnZURhdGEgfSBmcm9tICcuLi93YW5kL3dhbmQtdG9vbC5zZXJ2aWNlJztcblxuLyoqIEEgY2xpZW50LXNpZGUgY3JvcCBvZiB0aGUgbG9hZGVkIGltYWdlIOKAlCB0aGUgYnJvd3NlciBlcXVpdmFsZW50IG9mIHRoZSBKSVRcbiAqICBzZXJ2ZXIgc2xpZGUtY3JvcCwgdGFrZW4gZnJvbSB0aGUgcGl4ZWxzIGFscmVhZHkgaW4gdGhlIHZpZXdlci4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQ3JvcHBlZEltYWdlIHtcbiAgLyoqIFJHQkEgcGl4ZWxzIG9mIHRoZSBjcm9wLCByb3ctbWFqb3IuICovXG4gIGRhdGE6IFVpbnQ4Q2xhbXBlZEFycmF5O1xuICB3aWR0aDogbnVtYmVyO1xuICBoZWlnaHQ6IG51bWJlcjtcbiAgLyoqIENyb3Agb3JpZ2luIGluIGltYWdlIChtYXRyaXgpIGNvb3JkcyDigJQgbGV0cyBtYXNrcyBtYXAgYmFjayB0byB0aGUgZnJhbWUuICovXG4gIG1hdHJpeFgwOiBudW1iZXI7XG4gIG1hdHJpeFkwOiBudW1iZXI7XG59XG5cbi8qKiBBIGJveCBpbiBpbWFnZSAqZGF0YSogY29vcmRpbmF0ZXMgKGFzIHN0b3JlZCBvbiBhIFJlY3RhbmdsZSByZWdpb24pLiAqL1xuZXhwb3J0IGludGVyZmFjZSBEYXRhQm94IHsgeDA6IG51bWJlcjsgeTA6IG51bWJlcjsgeDE6IG51bWJlcjsgeTE6IG51bWJlcjsgfVxuXG4vKipcbiAqIEJyb3dzZXIgXCJzbGlkZSBjcm9wXCI6IGV4dHJhY3QgdGhlIGJveCByZWdpb24gKGRhdGEgY29vcmRzKSBmcm9tIGEgY2FjaGVkIGltYWdlXG4gKiBmcmFtZSBhcyBhbiBSR0JBIGltYWdlLCBjbGFtcGVkIHRvIHRoZSBpbWFnZSBib3VuZHMuIEdyYXlzY2FsZSBmcmFtZXMgYXJlXG4gKiByZXBsaWNhdGVkIGFjcm9zcyBSL0cvQjsgUkdCIHR1cGxlcyBhcmUgY29waWVkIHRocm91Z2guIFJldHVybnMgbnVsbCB3aGVuIHRoZVxuICogYm94IGlzIGVtcHR5L291dHNpZGUgdGhlIGltYWdlLlxuICpcbiAqIFRoZSBvdXRwdXQgZmVlZHMgYW4gYXV0b21hdGljIHNlZ21lbnRlciAoZS5nLiBjZWxscG9zZS1TQU0pOiBydW4gaXQgb24gdGhlXG4gKiBjcm9wLCB0aGVuIG9mZnNldCB0aGUgcmVzdWx0aW5nIG1hc2tzIGJ5IChtYXRyaXhYMCwgbWF0cml4WTApIHRvIHBsYWNlIHRoZW1cbiAqIGJhY2sgb24gdGhlIGZ1bGwgZnJhbWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcm9wSW1hZ2VSZWdpb24oXG4gIGNhY2hlZDogQ2FjaGVkSW1hZ2VEYXRhLCBmcmFtZUluZGV4OiBudW1iZXIsIGJveDogRGF0YUJveCxcbik6IENyb3BwZWRJbWFnZSB8IG51bGwge1xuICBjb25zdCByeCA9IGNhY2hlZC5yYXRpb3NbMF0gfHwgMTtcbiAgY29uc3QgcnkgPSBjYWNoZWQucmF0aW9zWzBdIHx8IDE7XG4gIGNvbnN0IG94ID0gY2FjaGVkLm9yaWdpblggPz8gMDtcbiAgY29uc3Qgb3kgPSBjYWNoZWQub3JpZ2luWSA/PyAwO1xuICAvLyBkYXRhIC0+IGltYWdlIChtYXRyaXgpIGNvb3Jkcywgbm9ybWFsaXplZCArIGNsYW1wZWQgdG8gdGhlIGZyYW1lLlxuICBsZXQgbXgwID0gTWF0aC5yb3VuZCgoTWF0aC5taW4oYm94LngwLCBib3gueDEpIC0gb3gpIC8gcngpO1xuICBsZXQgbXkwID0gTWF0aC5yb3VuZCgoTWF0aC5taW4oYm94LnkwLCBib3gueTEpIC0gb3kpIC8gcnkpO1xuICBsZXQgbXgxID0gTWF0aC5yb3VuZCgoTWF0aC5tYXgoYm94LngwLCBib3gueDEpIC0gb3gpIC8gcngpO1xuICBsZXQgbXkxID0gTWF0aC5yb3VuZCgoTWF0aC5tYXgoYm94LnkwLCBib3gueTEpIC0gb3kpIC8gcnkpO1xuICBteDAgPSBNYXRoLm1heCgwLCBNYXRoLm1pbihjYWNoZWQud2lkdGgsIG14MCkpO1xuICBteTAgPSBNYXRoLm1heCgwLCBNYXRoLm1pbihjYWNoZWQuaGVpZ2h0LCBteTApKTtcbiAgbXgxID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oY2FjaGVkLndpZHRoLCBteDEpKTtcbiAgbXkxID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oY2FjaGVkLmhlaWdodCwgbXkxKSk7XG4gIGNvbnN0IGN3ID0gbXgxIC0gbXgwO1xuICBjb25zdCBjaCA9IG15MSAtIG15MDtcbiAgaWYgKGN3IDw9IDAgfHwgY2ggPD0gMCkgcmV0dXJuIG51bGw7XG5cbiAgY29uc3QgZnJhbWUgPSBjYWNoZWQuZnJhbWVzW2ZyYW1lSW5kZXhdID8/IGNhY2hlZC5mcmFtZXNbMF07XG4gIGNvbnN0IGRhdGEgPSBuZXcgVWludDhDbGFtcGVkQXJyYXkoY3cgKiBjaCAqIDQpO1xuICBmb3IgKGxldCB5ID0gMDsgeSA8IGNoOyB5KyspIHtcbiAgICBjb25zdCByb3cgPSBmcmFtZT8uW215MCArIHldO1xuICAgIGZvciAobGV0IHggPSAwOyB4IDwgY3c7IHgrKykge1xuICAgICAgY29uc3QgbyA9ICh5ICogY3cgKyB4KSAqIDQ7XG4gICAgICBjb25zdCBweCA9IHJvdz8uW214MCArIHhdO1xuICAgICAgaWYgKHB4ID09IG51bGwpIHsgZGF0YVtvICsgM10gPSAyNTU7IGNvbnRpbnVlOyB9XG4gICAgICBpZiAoY2FjaGVkLmlzR3JheXNjYWxlKSB7XG4gICAgICAgIGNvbnN0IHYgPSBweCBhcyBudW1iZXI7XG4gICAgICAgIGRhdGFbb10gPSB2OyBkYXRhW28gKyAxXSA9IHY7IGRhdGFbbyArIDJdID0gdjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnN0IHQgPSBweCBhcyBudW1iZXJbXTtcbiAgICAgICAgZGF0YVtvXSA9IHRbMF07IGRhdGFbbyArIDFdID0gdFsxXTsgZGF0YVtvICsgMl0gPSB0WzJdO1xuICAgICAgfVxuICAgICAgZGF0YVtvICsgM10gPSAyNTU7XG4gICAgfVxuICB9XG4gIHJldHVybiB7IGRhdGEsIHdpZHRoOiBjdywgaGVpZ2h0OiBjaCwgbWF0cml4WDA6IG14MCwgbWF0cml4WTA6IG15MCB9O1xufVxuIl19
@@ -0,0 +1,115 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { BehaviorSubject } from 'rxjs';
3
+ import { WandService } from '../wand/wand.service';
4
+ import { cropImageRegion } from '../crop/slide-crop';
5
+ import { Region, Polygon, Rectangle } from '../../models/region';
6
+ import * as i0 from "@angular/core";
7
+ import * as i1 from "../wand/wand.service";
8
+ /** Yield to the event loop (a macrotask) so the toast can repaint the latest
9
+ * status / animate the spinner before the next main-thread-blocking step. */
10
+ const tick = () => new Promise((r) => setTimeout(r, 0));
11
+ /**
12
+ * Automatic cell segmentation inside drawn boxes (jit-ui#90). For each rectangle
13
+ * it client slide-crops the box from the loaded image, runs an automatic
14
+ * segmenter (cellpose-SAM, supplied by the host via {@link ICellSegmenter}) on
15
+ * the crop, and turns every cell instance into a region — offset back onto the
16
+ * frame. The prompt rectangle is replaced by its cell regions.
17
+ *
18
+ * This is the complement to the promptable SAM tool: cellpose-SAM can't take a
19
+ * box prompt, so the box just bounds the crop it segments automatically.
20
+ */
21
+ export class CellSegmentToolService {
22
+ constructor(wandService) {
23
+ this.wandService = wandService;
24
+ this.status$ = new BehaviorSubject('');
25
+ this.busy$ = new BehaviorSubject(false);
26
+ this.progress$ = new BehaviorSubject(-1);
27
+ }
28
+ bindHost(host) { this.host = host; }
29
+ /**
30
+ * Crop + cellpose-segment every rectangle; append the cell regions and drop
31
+ * the prompt rectangles that produced cells. Returns the number of regions added.
32
+ */
33
+ async segmentBoxes(segmenter) {
34
+ if (!this.host)
35
+ return 0;
36
+ const cached = this.host.getCachedImageData();
37
+ if (!cached || cached.frames.length === 0) {
38
+ this.status$.next('No image loaded.');
39
+ return 0;
40
+ }
41
+ const regions = this.host.getRegions();
42
+ const rects = regions.filter((r) => r.bounds instanceof Rectangle);
43
+ if (rects.length === 0) {
44
+ this.status$.next('Draw one or more rectangles, then run Cellpose.');
45
+ return 0;
46
+ }
47
+ const rx = cached.ratios[0] || 1;
48
+ const ry = cached.ratios[0] || 1;
49
+ const ox = cached.originX ?? 0;
50
+ const oy = cached.originY ?? 0;
51
+ const frameIdx = this.host.getActiveFrameIndex();
52
+ this.busy$.next(true);
53
+ try {
54
+ const masks = [];
55
+ const consumed = new Set();
56
+ let added = 0;
57
+ for (let i = 0; i < rects.length; i++) {
58
+ const b = rects[i].bounds;
59
+ // Prefix each phase with the box index when there's more than one.
60
+ const prefix = rects.length > 1 ? `Box ${i + 1}/${rects.length}: ` : '';
61
+ this.status$.next(`${prefix}Cropping…`);
62
+ await tick(); // let the status paint before the (main-thread) crop
63
+ const crop = cropImageRegion(cached, frameIdx, { x0: b.x, y0: b.y, x1: b.x + b.width, y1: b.y + b.height });
64
+ if (!crop)
65
+ continue;
66
+ const seg = await segmenter.segmentCells({ data: crop.data, width: crop.width, height: crop.height }, { onProgress: (f) => this.progress$.next(f), onStatus: (s) => this.status$.next(prefix + s) });
67
+ this.status$.next(`${prefix}Tracing cells…`);
68
+ await tick(); // paint before the (main-thread) contour tracing
69
+ const polys = this.wandService.labelsToPolygons(seg.labels, seg.width, seg.height, seg.width, seg.height, 0, 0);
70
+ if (polys.length === 0)
71
+ continue;
72
+ for (const poly of polys) {
73
+ // crop-pixel → frame-matrix (offset by crop origin) → data coords.
74
+ const xData = poly.xpoints.map((x) => ox + (crop.matrixX0 + x) * rx);
75
+ const yData = poly.ypoints.map((y) => oy + (crop.matrixY0 + y) * ry);
76
+ masks.push(this.makeRegion(xData, yData, rects[i].color)); // inherit the box's color
77
+ added++;
78
+ }
79
+ consumed.add(rects[i]);
80
+ }
81
+ this.host.setRegions(regions.filter((r) => !consumed.has(r)).concat(masks));
82
+ this.status$.next(added > 0 ? `Added ${added} cell region(s).` : 'No cells found.');
83
+ return added;
84
+ }
85
+ catch (err) {
86
+ this.status$.next(err instanceof Error ? err.message : 'Cellpose segmentation failed.');
87
+ return 0;
88
+ }
89
+ finally {
90
+ this.busy$.next(false);
91
+ this.progress$.next(-1);
92
+ }
93
+ }
94
+ makeRegion(xData, yData, color) {
95
+ const poly = new Polygon();
96
+ poly.npoints = xData.length;
97
+ poly.xpoints = xData;
98
+ poly.ypoints = yData;
99
+ poly.coordinates = xData.map((x, i) => [x, yData[i]]);
100
+ poly.closed = true;
101
+ const region = new Region();
102
+ region.bounds = poly;
103
+ // Inherit the source box's color; fall back to the host default.
104
+ region.color = color || this.host.getShapeColor();
105
+ region.label = 'cell';
106
+ return region;
107
+ }
108
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: CellSegmentToolService, deps: [{ token: i1.WandService }], target: i0.ɵɵFactoryTarget.Injectable }); }
109
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: CellSegmentToolService, providedIn: 'root' }); }
110
+ }
111
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: CellSegmentToolService, decorators: [{
112
+ type: Injectable,
113
+ args: [{ providedIn: 'root' }]
114
+ }], ctorParameters: () => [{ type: i1.WandService }] });
115
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VsbC1zZWdtZW50LXRvb2wuc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvdG9vbGJhci9zZWdtZW50YXRpb24vY2VsbC1zZWdtZW50LXRvb2wuc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzNDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFdkMsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRW5ELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUVyRCxPQUFPLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQzs7O0FBRWpFOzhFQUM4RTtBQUM5RSxNQUFNLElBQUksR0FBRyxHQUFrQixFQUFFLENBQUMsSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLFVBQVUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztBQUV2RTs7Ozs7Ozs7O0dBU0c7QUFFSCxNQUFNLE9BQU8sc0JBQXNCO0lBT2pDLFlBQW9CLFdBQXdCO1FBQXhCLGdCQUFXLEdBQVgsV0FBVyxDQUFhO1FBSm5DLFlBQU8sR0FBRyxJQUFJLGVBQWUsQ0FBUyxFQUFFLENBQUMsQ0FBQztRQUMxQyxVQUFLLEdBQUcsSUFBSSxlQUFlLENBQVUsS0FBSyxDQUFDLENBQUM7UUFDNUMsY0FBUyxHQUFHLElBQUksZUFBZSxDQUFTLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFFTixDQUFDO0lBRWhELFFBQVEsQ0FBQyxJQUFrQixJQUFVLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQztJQUV4RDs7O09BR0c7SUFDSCxLQUFLLENBQUMsWUFBWSxDQUFDLFNBQXlCO1FBQzFDLElBQUks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QyxNQUFNLENBQUM7UUFDNUIsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7UUFDckIsSUFBSSxDQUFDLE9BQU8sR0FBRyxLQUFLLENBQUM7UUFDckIsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0RCxJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztRQUNuQixNQUFNLE1BQU0sR0FBRyxJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQzVCLE1BQU0sQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1FBQ3JCLGlFQUFpRTtRQUNqRSxNQUFNLENBQUMsS0FBSyxHQUFHLEtBQUssSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBQ2xELE1BQU0sQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFDO1FBQ3RCLE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7OEdBNUZVLHNCQUFzQjtrSEFBdEIsc0JBQXNCLGNBRFQsTUFBTTs7MkZBQ25CLHNCQUFzQjtrQkFEbEMsVUFBVTttQkFBQyxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QgfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgV2FuZFNlcnZpY2UgfSBmcm9tICcuLi93YW5kL3dhbmQuc2VydmljZSc7XG5pbXBvcnQgeyBXYW5kVG9vbEhvc3QgfSBmcm9tICcuLi93YW5kL3dhbmQtdG9vbC5zZXJ2aWNlJztcbmltcG9ydCB7IGNyb3BJbWFnZVJlZ2lvbiB9IGZyb20gJy4uL2Nyb3Avc2xpZGUtY3JvcCc7XG5pbXBvcnQgeyBJQ2VsbFNlZ21lbnRlciB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cy9jZWxsLXNlZ21lbnRlci5jb250cmFjdCc7XG5pbXBvcnQgeyBSZWdpb24sIFBvbHlnb24sIFJlY3RhbmdsZSB9IGZyb20gJy4uLy4uL21vZGVscy9yZWdpb24nO1xuXG4vKiogWWllbGQgdG8gdGhlIGV2ZW50IGxvb3AgKGEgbWFjcm90YXNrKSBzbyB0aGUgdG9hc3QgY2FuIHJlcGFpbnQgdGhlIGxhdGVzdFxuICogIHN0YXR1cyAvIGFuaW1hdGUgdGhlIHNwaW5uZXIgYmVmb3JlIHRoZSBuZXh0IG1haW4tdGhyZWFkLWJsb2NraW5nIHN0ZXAuICovXG5jb25zdCB0aWNrID0gKCk6IFByb21pc2U8dm9pZD4gPT4gbmV3IFByb21pc2UoKHIpID0+IHNldFRpbWVvdXQociwgMCkpO1xuXG4vKipcbiAqIEF1dG9tYXRpYyBjZWxsIHNlZ21lbnRhdGlvbiBpbnNpZGUgZHJhd24gYm94ZXMgKGppdC11aSM5MCkuIEZvciBlYWNoIHJlY3RhbmdsZVxuICogaXQgY2xpZW50IHNsaWRlLWNyb3BzIHRoZSBib3ggZnJvbSB0aGUgbG9hZGVkIGltYWdlLCBydW5zIGFuIGF1dG9tYXRpY1xuICogc2VnbWVudGVyIChjZWxscG9zZS1TQU0sIHN1cHBsaWVkIGJ5IHRoZSBob3N0IHZpYSB7QGxpbmsgSUNlbGxTZWdtZW50ZXJ9KSBvblxuICogdGhlIGNyb3AsIGFuZCB0dXJucyBldmVyeSBjZWxsIGluc3RhbmNlIGludG8gYSByZWdpb24g4oCUIG9mZnNldCBiYWNrIG9udG8gdGhlXG4gKiBmcmFtZS4gVGhlIHByb21wdCByZWN0YW5nbGUgaXMgcmVwbGFjZWQgYnkgaXRzIGNlbGwgcmVnaW9ucy5cbiAqXG4gKiBUaGlzIGlzIHRoZSBjb21wbGVtZW50IHRvIHRoZSBwcm9tcHRhYmxlIFNBTSB0b29sOiBjZWxscG9zZS1TQU0gY2FuJ3QgdGFrZSBhXG4gKiBib3ggcHJvbXB0LCBzbyB0aGUgYm94IGp1c3QgYm91bmRzIHRoZSBjcm9wIGl0IHNlZ21lbnRzIGF1dG9tYXRpY2FsbHkuXG4gKi9cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgQ2VsbFNlZ21lbnRUb29sU2VydmljZSB7XG4gIHByaXZhdGUgaG9zdCE6IFdhbmRUb29sSG9zdDtcblxuICByZWFkb25seSBzdGF0dXMkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxzdHJpbmc+KCcnKTtcbiAgcmVhZG9ubHkgYnVzeSQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PGJvb2xlYW4+KGZhbHNlKTtcbiAgcmVhZG9ubHkgcHJvZ3Jlc3MkID0gbmV3IEJlaGF2aW9yU3ViamVjdDxudW1iZXI+KC0xKTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHdhbmRTZXJ2aWNlOiBXYW5kU2VydmljZSkge31cblxuICBiaW5kSG9zdChob3N0OiBXYW5kVG9vbEhvc3QpOiB2b2lkIHsgdGhpcy5ob3N0ID0gaG9zdDsgfVxuXG4gIC8qKlxuICAgKiBDcm9wICsgY2VsbHBvc2Utc2VnbWVudCBldmVyeSByZWN0YW5nbGU7IGFwcGVuZCB0aGUgY2VsbCByZWdpb25zIGFuZCBkcm9wXG4gICAqIHRoZSBwcm9tcHQgcmVjdGFuZ2xlcyB0aGF0IHByb2R1Y2VkIGNlbGxzLiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgcmVnaW9ucyBhZGRlZC5cbiAgICovXG4gIGFzeW5jIHNlZ21lbnRCb3hlcyhzZWdtZW50ZXI6IElDZWxsU2VnbWVudGVyKTogUHJvbWlzZTxudW1iZXI+IHtcbiAgICBpZiAoIXRoaXMuaG9zdCkgcmV0dXJuIDA7XG4gICAgY29uc3QgY2FjaGVkID0gdGhpcy5ob3N0LmdldENhY2hlZEltYWdlRGF0YSgpO1xuICAgIGlmICghY2FjaGVkIHx8IGNhY2hlZC5mcmFtZXMubGVuZ3RoID09PSAwKSB7IHRoaXMuc3RhdHVzJC5uZXh0KCdObyBpbWFnZSBsb2FkZWQuJyk7IHJldHVybiAwOyB9XG5cbiAgICBjb25zdCByZWdpb25zID0gdGhpcy5ob3N0LmdldFJlZ2lvbnMoKTtcbiAgICBjb25zdCByZWN0cyA9IHJlZ2lvbnMuZmlsdGVyKChyKSA9PiByLmJvdW5kcyBpbnN0YW5jZW9mIFJlY3RhbmdsZSk7XG4gICAgaWYgKHJlY3RzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5zdGF0dXMkLm5leHQoJ0RyYXcgb25lIG9yIG1vcmUgcmVjdGFuZ2xlcywgdGhlbiBydW4gQ2VsbHBvc2UuJyk7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICBjb25zdCByeCA9IGNhY2hlZC5yYXRpb3NbMF0gfHwgMTtcbiAgICBjb25zdCByeSA9IGNhY2hlZC5yYXRpb3NbMF0gfHwgMTtcbiAgICBjb25zdCBveCA9IGNhY2hlZC5vcmlnaW5YID8/IDA7XG4gICAgY29uc3Qgb3kgPSBjYWNoZWQub3JpZ2luWSA/PyAwO1xuICAgIGNvbnN0IGZyYW1lSWR4ID0gdGhpcy5ob3N0LmdldEFjdGl2ZUZyYW1lSW5kZXgoKTtcblxuICAgIHRoaXMuYnVzeSQubmV4dCh0cnVlKTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgbWFza3M6IFJlZ2lvbltdID0gW107XG4gICAgICBjb25zdCBjb25zdW1lZCA9IG5ldyBTZXQ8UmVnaW9uPigpO1xuICAgICAgbGV0IGFkZGVkID0gMDtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcmVjdHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgY29uc3QgYiA9IHJlY3RzW2ldLmJvdW5kcyBhcyBSZWN0YW5nbGU7XG4gICAgICAgIC8vIFByZWZpeCBlYWNoIHBoYXNlIHdpdGggdGhlIGJveCBpbmRleCB3aGVuIHRoZXJlJ3MgbW9yZSB0aGFuIG9uZS5cbiAgICAgICAgY29uc3QgcHJlZml4ID0gcmVjdHMubGVuZ3RoID4gMSA/IGBCb3ggJHtpICsgMX0vJHtyZWN0cy5sZW5ndGh9OiBgIDogJyc7XG4gICAgICAgIHRoaXMuc3RhdHVzJC5uZXh0KGAke3ByZWZpeH1Dcm9wcGluZ+KApmApO1xuICAgICAgICBhd2FpdCB0aWNrKCk7IC8vIGxldCB0aGUgc3RhdHVzIHBhaW50IGJlZm9yZSB0aGUgKG1haW4tdGhyZWFkKSBjcm9wXG4gICAgICAgIGNvbnN0IGNyb3AgPSBjcm9wSW1hZ2VSZWdpb24oXG4gICAgICAgICAgY2FjaGVkLCBmcmFtZUlkeCwgeyB4MDogYi54LCB5MDogYi55LCB4MTogYi54ICsgYi53aWR0aCwgeTE6IGIueSArIGIuaGVpZ2h0IH0sXG4gICAgICAgICk7XG4gICAgICAgIGlmICghY3JvcCkgY29udGludWU7XG4gICAgICAgIGNvbnN0IHNlZyA9IGF3YWl0IHNlZ21lbnRlci5zZWdtZW50Q2VsbHMoXG4gICAgICAgICAgeyBkYXRhOiBjcm9wLmRhdGEsIHdpZHRoOiBjcm9wLndpZHRoLCBoZWlnaHQ6IGNyb3AuaGVpZ2h0IH0sXG4gICAgICAgICAgeyBvblByb2dyZXNzOiAoZikgPT4gdGhpcy5wcm9ncmVzcyQubmV4dChmKSwgb25TdGF0dXM6IChzKSA9PiB0aGlzLnN0YXR1cyQubmV4dChwcmVmaXggKyBzKSB9LFxuICAgICAgICApO1xuICAgICAgICB0aGlzLnN0YXR1cyQubmV4dChgJHtwcmVmaXh9VHJhY2luZyBjZWxsc+KApmApO1xuICAgICAgICBhd2FpdCB0aWNrKCk7IC8vIHBhaW50IGJlZm9yZSB0aGUgKG1haW4tdGhyZWFkKSBjb250b3VyIHRyYWNpbmdcbiAgICAgICAgY29uc3QgcG9seXMgPSB0aGlzLndhbmRTZXJ2aWNlLmxhYmVsc1RvUG9seWdvbnMoXG4gICAgICAgICAgc2VnLmxhYmVscywgc2VnLndpZHRoLCBzZWcuaGVpZ2h0LCBzZWcud2lkdGgsIHNlZy5oZWlnaHQsIDAsIDAsXG4gICAgICAgICk7XG4gICAgICAgIGlmIChwb2x5cy5sZW5ndGggPT09IDApIGNvbnRpbnVlO1xuICAgICAgICBmb3IgKGNvbnN0IHBvbHkgb2YgcG9seXMpIHtcbiAgICAgICAgICAvLyBjcm9wLXBpeGVsIOKGkiBmcmFtZS1tYXRyaXggKG9mZnNldCBieSBjcm9wIG9yaWdpbikg4oaSIGRhdGEgY29vcmRzLlxuICAgICAgICAgIGNvbnN0IHhEYXRhID0gcG9seS54cG9pbnRzLm1hcCgoeCkgPT4gb3ggKyAoY3JvcC5tYXRyaXhYMCArIHgpICogcngpO1xuICAgICAgICAgIGNvbnN0IHlEYXRhID0gcG9seS55cG9pbnRzLm1hcCgoeSkgPT4gb3kgKyAoY3JvcC5tYXRyaXhZMCArIHkpICogcnkpO1xuICAgICAgICAgIG1hc2tzLnB1c2godGhpcy5tYWtlUmVnaW9uKHhEYXRhLCB5RGF0YSwgcmVjdHNbaV0uY29sb3IpKTsgLy8gaW5oZXJpdCB0aGUgYm94J3MgY29sb3JcbiAgICAgICAgICBhZGRlZCsrO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN1bWVkLmFkZChyZWN0c1tpXSk7XG4gICAgICB9XG4gICAgICB0aGlzLmhvc3Quc2V0UmVnaW9ucyhyZWdpb25zLmZpbHRlcigocikgPT4gIWNvbnN1bWVkLmhhcyhyKSkuY29uY2F0KG1hc2tzKSk7XG4gICAgICB0aGlzLnN0YXR1cyQubmV4dChhZGRlZCA+IDAgPyBgQWRkZWQgJHthZGRlZH0gY2VsbCByZWdpb24ocykuYCA6ICdObyBjZWxscyBmb3VuZC4nKTtcbiAgICAgIHJldHVybiBhZGRlZDtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIHRoaXMuc3RhdHVzJC5uZXh0KGVyciBpbnN0YW5jZW9mIEVycm9yID8gZXJyLm1lc3NhZ2UgOiAnQ2VsbHBvc2Ugc2VnbWVudGF0aW9uIGZhaWxlZC4nKTtcbiAgICAgIHJldHVybiAwO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLmJ1c3kkLm5leHQoZmFsc2UpO1xuICAgICAgdGhpcy5wcm9ncmVzcyQubmV4dCgtMSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBtYWtlUmVnaW9uKHhEYXRhOiBudW1iZXJbXSwgeURhdGE6IG51bWJlcltdLCBjb2xvcj86IHN0cmluZyk6IFJlZ2lvbiB7XG4gICAgY29uc3QgcG9seSA9IG5ldyBQb2x5Z29uKCk7XG4gICAgcG9seS5ucG9pbnRzID0geERhdGEubGVuZ3RoO1xuICAgIHBvbHkueHBvaW50cyA9IHhEYXRhO1xuICAgIHBvbHkueXBvaW50cyA9IHlEYXRhO1xuICAgIHBvbHkuY29vcmRpbmF0ZXMgPSB4RGF0YS5tYXAoKHgsIGkpID0+IFt4LCB5RGF0YVtpXV0pO1xuICAgIHBvbHkuY2xvc2VkID0gdHJ1ZTtcbiAgICBjb25zdCByZWdpb24gPSBuZXcgUmVnaW9uKCk7XG4gICAgcmVnaW9uLmJvdW5kcyA9IHBvbHk7XG4gICAgLy8gSW5oZXJpdCB0aGUgc291cmNlIGJveCdzIGNvbG9yOyBmYWxsIGJhY2sgdG8gdGhlIGhvc3QgZGVmYXVsdC5cbiAgICByZWdpb24uY29sb3IgPSBjb2xvciB8fCB0aGlzLmhvc3QuZ2V0U2hhcGVDb2xvcigpO1xuICAgIHJlZ2lvbi5sYWJlbCA9ICdjZWxsJztcbiAgICByZXR1cm4gcmVnaW9uO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,84 @@
1
+ import { Injectable } from '@angular/core';
2
+ import { getOrtWasmBase } from './ort-runtime-config';
3
+ import * as i0 from "@angular/core";
4
+ /** Hosted cellpose-SAM ONNX (CPSAM, fp16). Override via {@link setModelUrl}. */
5
+ const DEFAULT_MODEL_URL = 'https://huggingface.co/ballon999/cellpose-sam-onnx/resolve/main/cpsam_fp16.onnx';
6
+ /**
7
+ * Default in-library {@link ICellSegmenter} backed by cellpose-js (WebGPU/WASM
8
+ * ONNX) — so the toolbar's automatic **Cellpose** tool works out of the box in
9
+ * any app, with no host wiring (jit-ui#90). `cellpose-js` is a peer dependency
10
+ * and is **lazy-imported** on first use, so apps that never run Cellpose pay
11
+ * nothing for it. A host can still override the {@link CELL_SEGMENTER} token to
12
+ * supply a different implementation.
13
+ *
14
+ * Owns a single shared {@link Cellpose} instance (one model load, one WebGPU
15
+ * session, one worker). {@link getModel} exposes that instance so a host's
16
+ * processing pipeline can reuse it instead of loading the ~588 MB model twice.
17
+ */
18
+ export class CellposeSegmenterService {
19
+ constructor() {
20
+ this.instance = null;
21
+ this.loading = null;
22
+ this.modelUrl = DEFAULT_MODEL_URL;
23
+ }
24
+ /** Point the segmenter at a different hosted CPSAM ONNX (before first use). */
25
+ setModelUrl(url) {
26
+ this.modelUrl = url;
27
+ }
28
+ async segmentCells(image, progress) {
29
+ let announcedDownload = false;
30
+ const cp = await this.getModel((loaded, total) => {
31
+ if (total)
32
+ progress?.onProgress?.(loaded / total);
33
+ if (loaded > 0 && !announcedDownload) {
34
+ announcedDownload = true;
35
+ progress?.onStatus?.('Downloading Cellpose-SAM model…');
36
+ }
37
+ }, (status) => progress?.onStatus?.(status));
38
+ progress?.onStatus?.('Preprocessing image…');
39
+ const out = await cp.segment({ data: image.data, width: image.width, height: image.height, channels: 4 }, {
40
+ // cellpose-js runs inference in its worker (these fire between tiles) and
41
+ // averaging/dynamics on the main thread; surface both so the toast shows
42
+ // real progress instead of looking stuck.
43
+ onTileProgress: (done, total) => progress?.onStatus?.(done < total ? `Running inference (tile ${done}/${total})…` : 'Computing flow dynamics…'),
44
+ });
45
+ return { labels: out.masks, width: out.width, height: out.height, count: out.count };
46
+ }
47
+ /**
48
+ * The shared Cellpose instance, lazily created on first use and reused
49
+ * thereafter (deduped across concurrent callers). Exposed so a host pipeline
50
+ * engine can run richer `segment()` options on the same instance. `onProgress`
51
+ * reports raw downloaded/total bytes (`total` is null when unknown); `onStatus`
52
+ * reports worker-init phase strings.
53
+ */
54
+ getModel(onProgress, onStatus) {
55
+ if (this.instance)
56
+ return Promise.resolve(this.instance);
57
+ if (!this.loading) {
58
+ this.loading = (async () => {
59
+ // Lazy: keep cellpose-js + its ORT runtime out of the initial bundle.
60
+ const { Cellpose, configureOrt } = await import('cellpose-js');
61
+ configureOrt({ wasmPaths: getOrtWasmBase() });
62
+ const cp = await Cellpose.fromPretrained(this.modelUrl, {
63
+ preload: true,
64
+ onProgress: ({ loaded, total }) => onProgress?.(loaded, total),
65
+ onStatus: (s) => onStatus?.(s),
66
+ });
67
+ this.instance = cp;
68
+ return cp;
69
+ })();
70
+ }
71
+ return this.loading;
72
+ }
73
+ /** Whether the shared model is already loaded (warm). */
74
+ isLoaded() {
75
+ return this.instance !== null;
76
+ }
77
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: CellposeSegmenterService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
78
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: CellposeSegmenterService, providedIn: 'root' }); }
79
+ }
80
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.9", ngImport: i0, type: CellposeSegmenterService, decorators: [{
81
+ type: Injectable,
82
+ args: [{ providedIn: 'root' }]
83
+ }] });
84
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2VsbHBvc2Utc2VnbWVudGVyLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvbGliL3Rvb2xiYXIvc2VnbWVudGF0aW9uL2NlbGxwb3NlLXNlZ21lbnRlci5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDM0MsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLHNCQUFzQixDQUFDOztBQUt0RCxnRkFBZ0Y7QUFDaEYsTUFBTSxpQkFBaUIsR0FDckIsaUZBQWlGLENBQUM7QUFFcEY7Ozs7Ozs7Ozs7O0dBV0c7QUFFSCxNQUFNLE9BQU8sd0JBQXdCO0lBRHJDO1FBRVUsYUFBUSxHQUFvQixJQUFJLENBQUM7UUFDakMsWUFBTyxHQUE2QixJQUFJLENBQUM7UUFDekMsYUFBUSxHQUFHLGlCQUFpQixDQUFDO0tBc0V0QztJQXBFQywrRUFBK0U7SUFDL0UsV0FBVyxDQUFDLEdBQVc7UUFDckIsSUFBSSxDQUFDLFFBQVEsR0FBRyxHQUFHLENBQUM7SUFDdEIsQ0FBQztJQUVELEtBQUssQ0FBQyxZQUFZLENBQ2hCLEtBQWlFLEVBQ2pFLFFBQThCO1FBRTlCLElBQUksaUJBQWlCLEdBQUcsS0FBSyxDQUFDO1FBQzlCLE1BQU0sRUFBRSxHQUFHLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FDNUIsQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLEVBQUU7WUFDaEIsSUFBSSxLQUFLO2dCQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUsQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLENBQUM7WUFDbEQsSUFBSSxNQUFNLEdBQUcsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQztnQkFDckMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDO2dCQUN6QixRQUFRLEVBQUUsUUFBUSxFQUFFLENBQUMsaUNBQWlDLENBQUMsQ0FBQztZQUMxRCxDQUFDO1FBQ0gsQ0FBQyxFQUNELENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxRQUFRLEVBQUUsUUFBUSxFQUFFLENBQUMsTUFBTSxDQUFDLENBQ3pDLENBQUM7UUFDRixRQUFRLEVBQUUsUUFBUSxFQUFFLENBQUMsc0JBQXNCLENBQUMsQ0FBQztRQUM3QyxNQUFNLEdBQUcsR0FBRyxNQUFNLEVBQUUsQ0FBQyxPQUFPLENBQzFCLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFLENBQUMsRUFBRSxFQUMzRTtZQUNFLDBFQUEwRTtZQUMxRSx5RUFBeUU7WUFDekUsMENBQTBDO1lBQzFDLGNBQWMsRUFBRSxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLFFBQVEsRUFBRSxRQUFRLEVBQUUsQ0FDbkQsSUFBSSxHQUFHLEtBQUssQ0FBQyxDQUFDLENBQUMsMkJBQTJCLElBQUksSUFBSSxLQUFLLElBQUksQ0FBQyxDQUFDLENBQUMsMEJBQTBCLENBQ3pGO1NBQ0YsQ0FDRixDQUFDO1FBQ0YsT0FBTyxFQUFFLE1BQU0sRUFBRSxHQUFHLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxHQUFHLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxHQUFHLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxHQUFHLENBQUMsS0FBSyxFQUFFLENBQUM7SUFDdkYsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNILFFBQVEsQ0FDTixVQUEyRCxFQUMzRCxRQUFtQztRQUVuQyxJQUFJLElBQUksQ0FBQyxRQUFRO1lBQUUsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN6RCxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2xCLElBQUksQ0FBQyxPQUFPLEdBQUcsQ0FBQyxLQUFLLElBQUksRUFBRTtnQkFDekIsc0VBQXNFO2dCQUN0RSxNQUFNLEVBQUUsUUFBUSxFQUFFLFlBQVksRUFBRSxHQUFHLE1BQU0sTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDO2dCQUMvRCxZQUFZLENBQUMsRUFBRSxTQUFTLEVBQUUsY0FBYyxFQUFFLEVBQUUsQ0FBQyxDQUFDO2dCQUM5QyxNQUFNLEVBQUUsR0FBRyxNQUFNLFFBQVEsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRTtvQkFDdEQsT0FBTyxFQUFFLElBQUk7b0JBQ2IsVUFBVSxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxDQUFDLFVBQVUsRUFBRSxDQUFDLE1BQU0sRUFBRSxLQUFLLENBQUM7b0JBQzlELFFBQVEsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQyxDQUFDO2lCQUMvQixDQUFDLENBQUM7Z0JBQ0gsSUFBSSxDQUFDLFFBQVEsR0FBRyxFQUFFLENBQUM7Z0JBQ25CLE9BQU8sRUFBRSxDQUFDO1lBQ1osQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUNQLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUM7SUFDdEIsQ0FBQztJQUVELHlEQUF5RDtJQUN6RCxRQUFRO1FBQ04sT0FBTyxJQUFJLENBQUMsUUFBUSxLQUFLLElBQUksQ0FBQztJQUNoQyxDQUFDOzhHQXhFVSx3QkFBd0I7a0hBQXhCLHdCQUF3QixjQURYLE1BQU07OzJGQUNuQix3QkFBd0I7a0JBRHBDLFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgZ2V0T3J0V2FzbUJhc2UgfSBmcm9tICcuL29ydC1ydW50aW1lLWNvbmZpZyc7XG5cbmltcG9ydCB0eXBlIHsgSUNlbGxTZWdtZW50ZXIsIENlbGxTZWdtZW50YXRpb24sIENlbGxTZWdtZW50UHJvZ3Jlc3MgfSBmcm9tICcuLi8uLi9jb250cmFjdHMvY2VsbC1zZWdtZW50ZXIuY29udHJhY3QnO1xuaW1wb3J0IHR5cGUgeyBDZWxscG9zZSB9IGZyb20gJ2NlbGxwb3NlLWpzJztcblxuLyoqIEhvc3RlZCBjZWxscG9zZS1TQU0gT05OWCAoQ1BTQU0sIGZwMTYpLiBPdmVycmlkZSB2aWEge0BsaW5rIHNldE1vZGVsVXJsfS4gKi9cbmNvbnN0IERFRkFVTFRfTU9ERUxfVVJMID1cbiAgJ2h0dHBzOi8vaHVnZ2luZ2ZhY2UuY28vYmFsbG9uOTk5L2NlbGxwb3NlLXNhbS1vbm54L3Jlc29sdmUvbWFpbi9jcHNhbV9mcDE2Lm9ubngnO1xuXG4vKipcbiAqIERlZmF1bHQgaW4tbGlicmFyeSB7QGxpbmsgSUNlbGxTZWdtZW50ZXJ9IGJhY2tlZCBieSBjZWxscG9zZS1qcyAoV2ViR1BVL1dBU01cbiAqIE9OTlgpIOKAlCBzbyB0aGUgdG9vbGJhcidzIGF1dG9tYXRpYyAqKkNlbGxwb3NlKiogdG9vbCB3b3JrcyBvdXQgb2YgdGhlIGJveCBpblxuICogYW55IGFwcCwgd2l0aCBubyBob3N0IHdpcmluZyAoaml0LXVpIzkwKS4gYGNlbGxwb3NlLWpzYCBpcyBhIHBlZXIgZGVwZW5kZW5jeVxuICogYW5kIGlzICoqbGF6eS1pbXBvcnRlZCoqIG9uIGZpcnN0IHVzZSwgc28gYXBwcyB0aGF0IG5ldmVyIHJ1biBDZWxscG9zZSBwYXlcbiAqIG5vdGhpbmcgZm9yIGl0LiBBIGhvc3QgY2FuIHN0aWxsIG92ZXJyaWRlIHRoZSB7QGxpbmsgQ0VMTF9TRUdNRU5URVJ9IHRva2VuIHRvXG4gKiBzdXBwbHkgYSBkaWZmZXJlbnQgaW1wbGVtZW50YXRpb24uXG4gKlxuICogT3ducyBhIHNpbmdsZSBzaGFyZWQge0BsaW5rIENlbGxwb3NlfSBpbnN0YW5jZSAob25lIG1vZGVsIGxvYWQsIG9uZSBXZWJHUFVcbiAqIHNlc3Npb24sIG9uZSB3b3JrZXIpLiB7QGxpbmsgZ2V0TW9kZWx9IGV4cG9zZXMgdGhhdCBpbnN0YW5jZSBzbyBhIGhvc3Qnc1xuICogcHJvY2Vzc2luZyBwaXBlbGluZSBjYW4gcmV1c2UgaXQgaW5zdGVhZCBvZiBsb2FkaW5nIHRoZSB+NTg4IE1CIG1vZGVsIHR3aWNlLlxuICovXG5ASW5qZWN0YWJsZSh7IHByb3ZpZGVkSW46ICdyb290JyB9KVxuZXhwb3J0IGNsYXNzIENlbGxwb3NlU2VnbWVudGVyU2VydmljZSBpbXBsZW1lbnRzIElDZWxsU2VnbWVudGVyIHtcbiAgcHJpdmF0ZSBpbnN0YW5jZTogQ2VsbHBvc2UgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBsb2FkaW5nOiBQcm9taXNlPENlbGxwb3NlPiB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIG1vZGVsVXJsID0gREVGQVVMVF9NT0RFTF9VUkw7XG5cbiAgLyoqIFBvaW50IHRoZSBzZWdtZW50ZXIgYXQgYSBkaWZmZXJlbnQgaG9zdGVkIENQU0FNIE9OTlggKGJlZm9yZSBmaXJzdCB1c2UpLiAqL1xuICBzZXRNb2RlbFVybCh1cmw6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMubW9kZWxVcmwgPSB1cmw7XG4gIH1cblxuICBhc3luYyBzZWdtZW50Q2VsbHMoXG4gICAgaW1hZ2U6IHsgZGF0YTogVWludDhDbGFtcGVkQXJyYXk7IHdpZHRoOiBudW1iZXI7IGhlaWdodDogbnVtYmVyIH0sXG4gICAgcHJvZ3Jlc3M/OiBDZWxsU2VnbWVudFByb2dyZXNzLFxuICApOiBQcm9taXNlPENlbGxTZWdtZW50YXRpb24+IHtcbiAgICBsZXQgYW5ub3VuY2VkRG93bmxvYWQgPSBmYWxzZTtcbiAgICBjb25zdCBjcCA9IGF3YWl0IHRoaXMuZ2V0TW9kZWwoXG4gICAgICAobG9hZGVkLCB0b3RhbCkgPT4ge1xuICAgICAgICBpZiAodG90YWwpIHByb2dyZXNzPy5vblByb2dyZXNzPy4obG9hZGVkIC8gdG90YWwpO1xuICAgICAgICBpZiAobG9hZGVkID4gMCAmJiAhYW5ub3VuY2VkRG93bmxvYWQpIHtcbiAgICAgICAgICBhbm5vdW5jZWREb3dubG9hZCA9IHRydWU7XG4gICAgICAgICAgcHJvZ3Jlc3M/Lm9uU3RhdHVzPy4oJ0Rvd25sb2FkaW5nIENlbGxwb3NlLVNBTSBtb2RlbOKApicpO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgKHN0YXR1cykgPT4gcHJvZ3Jlc3M/Lm9uU3RhdHVzPy4oc3RhdHVzKSxcbiAgICApO1xuICAgIHByb2dyZXNzPy5vblN0YXR1cz8uKCdQcmVwcm9jZXNzaW5nIGltYWdl4oCmJyk7XG4gICAgY29uc3Qgb3V0ID0gYXdhaXQgY3Auc2VnbWVudChcbiAgICAgIHsgZGF0YTogaW1hZ2UuZGF0YSwgd2lkdGg6IGltYWdlLndpZHRoLCBoZWlnaHQ6IGltYWdlLmhlaWdodCwgY2hhbm5lbHM6IDQgfSxcbiAgICAgIHtcbiAgICAgICAgLy8gY2VsbHBvc2UtanMgcnVucyBpbmZlcmVuY2UgaW4gaXRzIHdvcmtlciAodGhlc2UgZmlyZSBiZXR3ZWVuIHRpbGVzKSBhbmRcbiAgICAgICAgLy8gYXZlcmFnaW5nL2R5bmFtaWNzIG9uIHRoZSBtYWluIHRocmVhZDsgc3VyZmFjZSBib3RoIHNvIHRoZSB0b2FzdCBzaG93c1xuICAgICAgICAvLyByZWFsIHByb2dyZXNzIGluc3RlYWQgb2YgbG9va2luZyBzdHVjay5cbiAgICAgICAgb25UaWxlUHJvZ3Jlc3M6IChkb25lLCB0b3RhbCkgPT4gcHJvZ3Jlc3M/Lm9uU3RhdHVzPy4oXG4gICAgICAgICAgZG9uZSA8IHRvdGFsID8gYFJ1bm5pbmcgaW5mZXJlbmNlICh0aWxlICR7ZG9uZX0vJHt0b3RhbH0p4oCmYCA6ICdDb21wdXRpbmcgZmxvdyBkeW5hbWljc+KApicsXG4gICAgICAgICksXG4gICAgICB9LFxuICAgICk7XG4gICAgcmV0dXJuIHsgbGFiZWxzOiBvdXQubWFza3MsIHdpZHRoOiBvdXQud2lkdGgsIGhlaWdodDogb3V0LmhlaWdodCwgY291bnQ6IG91dC5jb3VudCB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBzaGFyZWQgQ2VsbHBvc2UgaW5zdGFuY2UsIGxhemlseSBjcmVhdGVkIG9uIGZpcnN0IHVzZSBhbmQgcmV1c2VkXG4gICAqIHRoZXJlYWZ0ZXIgKGRlZHVwZWQgYWNyb3NzIGNvbmN1cnJlbnQgY2FsbGVycykuIEV4cG9zZWQgc28gYSBob3N0IHBpcGVsaW5lXG4gICAqIGVuZ2luZSBjYW4gcnVuIHJpY2hlciBgc2VnbWVudCgpYCBvcHRpb25zIG9uIHRoZSBzYW1lIGluc3RhbmNlLiBgb25Qcm9ncmVzc2BcbiAgICogcmVwb3J0cyByYXcgZG93bmxvYWRlZC90b3RhbCBieXRlcyAoYHRvdGFsYCBpcyBudWxsIHdoZW4gdW5rbm93bik7IGBvblN0YXR1c2BcbiAgICogcmVwb3J0cyB3b3JrZXItaW5pdCBwaGFzZSBzdHJpbmdzLlxuICAgKi9cbiAgZ2V0TW9kZWwoXG4gICAgb25Qcm9ncmVzcz86IChsb2FkZWQ6IG51bWJlciwgdG90YWw6IG51bWJlciB8IG51bGwpID0+IHZvaWQsXG4gICAgb25TdGF0dXM/OiAoc3RhdHVzOiBzdHJpbmcpID0+IHZvaWQsXG4gICk6IFByb21pc2U8Q2VsbHBvc2U+IHtcbiAgICBpZiAodGhpcy5pbnN0YW5jZSkgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh0aGlzLmluc3RhbmNlKTtcbiAgICBpZiAoIXRoaXMubG9hZGluZykge1xuICAgICAgdGhpcy5sb2FkaW5nID0gKGFzeW5jICgpID0+IHtcbiAgICAgICAgLy8gTGF6eToga2VlcCBjZWxscG9zZS1qcyArIGl0cyBPUlQgcnVudGltZSBvdXQgb2YgdGhlIGluaXRpYWwgYnVuZGxlLlxuICAgICAgICBjb25zdCB7IENlbGxwb3NlLCBjb25maWd1cmVPcnQgfSA9IGF3YWl0IGltcG9ydCgnY2VsbHBvc2UtanMnKTtcbiAgICAgICAgY29uZmlndXJlT3J0KHsgd2FzbVBhdGhzOiBnZXRPcnRXYXNtQmFzZSgpIH0pO1xuICAgICAgICBjb25zdCBjcCA9IGF3YWl0IENlbGxwb3NlLmZyb21QcmV0cmFpbmVkKHRoaXMubW9kZWxVcmwsIHtcbiAgICAgICAgICBwcmVsb2FkOiB0cnVlLFxuICAgICAgICAgIG9uUHJvZ3Jlc3M6ICh7IGxvYWRlZCwgdG90YWwgfSkgPT4gb25Qcm9ncmVzcz8uKGxvYWRlZCwgdG90YWwpLFxuICAgICAgICAgIG9uU3RhdHVzOiAocykgPT4gb25TdGF0dXM/LihzKSxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuaW5zdGFuY2UgPSBjcDtcbiAgICAgICAgcmV0dXJuIGNwO1xuICAgICAgfSkoKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMubG9hZGluZztcbiAgfVxuXG4gIC8qKiBXaGV0aGVyIHRoZSBzaGFyZWQgbW9kZWwgaXMgYWxyZWFkeSBsb2FkZWQgKHdhcm0pLiAqL1xuICBpc0xvYWRlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5pbnN0YW5jZSAhPT0gbnVsbDtcbiAgfVxufVxuIl19
@@ -0,0 +1,133 @@
1
+ import * as ort from 'onnxruntime-web';
2
+ import { fetchModel, runEncoder, runDecoder } from './sam-onnx-core';
3
+ import { getOrtWasmBase } from './ort-runtime-config';
4
+ export class OnnxSamSession {
5
+ constructor() {
6
+ this.mode = null;
7
+ this.loaded = false;
8
+ this.model = null;
9
+ this.inputSize = 1024;
10
+ // ── worker mode ──
11
+ this.worker = null;
12
+ this.seq = 0;
13
+ this.pending = new Map();
14
+ // ── in-process mode ──
15
+ this.encoder = null;
16
+ this.decoder = null;
17
+ this.nextToken = 1;
18
+ this.embeddings = new Map();
19
+ }
20
+ async loadModel(model, onProgress) {
21
+ if (!model.encoderUrl || !model.decoderUrl) {
22
+ throw new Error(`SAM model "${model.id}" has no ONNX URLs configured.`);
23
+ }
24
+ this.model = model;
25
+ this.inputSize = model.inputSize;
26
+ const hasGpu = typeof navigator !== 'undefined' && 'gpu' in navigator;
27
+ const eps = model.encoderProviders ?? (hasGpu ? ['webgpu', 'wasm'] : ['wasm']);
28
+ const usesWebGpu = eps.includes('webgpu');
29
+ // WebGPU must run in the worker (else it freezes the main thread); small
30
+ // WASM models opt into the faster in-process path via `inProcess`.
31
+ this.mode = !usesWebGpu && model.inProcess ? 'inproc' : 'worker';
32
+ if (this.mode === 'inproc') {
33
+ ort.env.wasm.wasmPaths = getOrtWasmBase();
34
+ const encBuf = await fetchModel(model.encoderUrl, onProgress);
35
+ const decBuf = await fetchModel(model.decoderUrl);
36
+ this.encoder = await ort.InferenceSession.create(encBuf, { executionProviders: eps });
37
+ this.decoder = await ort.InferenceSession.create(decBuf, { executionProviders: ['wasm'] });
38
+ }
39
+ else {
40
+ await this.call({
41
+ type: 'load',
42
+ encoderUrl: model.encoderUrl,
43
+ decoderUrl: model.decoderUrl,
44
+ wasmPaths: getOrtWasmBase(),
45
+ inputSize: model.inputSize,
46
+ encoderProviders: model.encoderProviders,
47
+ }, [], onProgress);
48
+ }
49
+ this.loaded = true;
50
+ }
51
+ isLoaded() {
52
+ return this.loaded;
53
+ }
54
+ async embed(image) {
55
+ if (this.mode === 'inproc') {
56
+ const e = await runEncoder(this.encoder, image.data, image.width, image.height, this.inputSize);
57
+ const token = this.nextToken++;
58
+ this.embeddings.set(token, e);
59
+ if (this.embeddings.size > 3)
60
+ this.embeddings.delete(this.embeddings.keys().next().value);
61
+ return {
62
+ data: new Float32Array(0), dims: e.dims, scale: e.scale,
63
+ imageWidth: e.imageWidth, imageHeight: e.imageHeight, token,
64
+ };
65
+ }
66
+ // worker: transfer the RGBA buffer (callers pass a fresh frame buffer).
67
+ const buffer = image.data.buffer;
68
+ const res = await this.call({ type: 'embed', width: image.width, height: image.height, buffer }, [buffer]);
69
+ return {
70
+ data: new Float32Array(0), dims: res.dims, scale: res.scale,
71
+ imageWidth: res.imageWidth, imageHeight: res.imageHeight, token: res.token,
72
+ };
73
+ }
74
+ async decode(embedding, prompt) {
75
+ if (this.mode === 'inproc') {
76
+ const e = this.embeddings.get(embedding.token);
77
+ if (!e)
78
+ throw new Error('SAM embedding expired; re-encode the image.');
79
+ return runDecoder(this.decoder, e, prompt);
80
+ }
81
+ const res = await this.call({ type: 'decode', token: embedding.token, prompt });
82
+ return { mask: new Uint8Array(res.buffer), width: res.width, height: res.height, iou: res.iou };
83
+ }
84
+ dispose() {
85
+ this.worker?.terminate();
86
+ this.worker = null;
87
+ this.pending.clear();
88
+ this.encoder?.release?.();
89
+ this.decoder?.release?.();
90
+ this.encoder = this.decoder = null;
91
+ this.embeddings.clear();
92
+ this.loaded = false;
93
+ this.mode = null;
94
+ }
95
+ // ── worker plumbing ──────────────────────────────────────────────────────
96
+ ensureWorker() {
97
+ if (this.worker)
98
+ return this.worker;
99
+ const worker = new Worker(new URL('./onnx-sam.worker', import.meta.url), { type: 'module' });
100
+ worker.onmessage = (ev) => {
101
+ const m = ev.data;
102
+ const p = this.pending.get(m.id);
103
+ if (!p)
104
+ return;
105
+ if (m.type === 'progress') {
106
+ p.onProgress?.(m.fraction);
107
+ return;
108
+ }
109
+ this.pending.delete(m.id);
110
+ if (m.type === 'error')
111
+ p.reject(new Error(m.error));
112
+ else
113
+ p.resolve(m);
114
+ };
115
+ worker.onerror = (ev) => {
116
+ const err = new Error(ev.message || 'SAM worker crashed.');
117
+ for (const p of this.pending.values())
118
+ p.reject(err);
119
+ this.pending.clear();
120
+ };
121
+ this.worker = worker;
122
+ return worker;
123
+ }
124
+ call(msg, transfer = [], onProgress) {
125
+ const id = ++this.seq;
126
+ const worker = this.ensureWorker();
127
+ return new Promise((resolve, reject) => {
128
+ this.pending.set(id, { resolve, reject, onProgress });
129
+ worker.postMessage({ ...msg, id }, transfer);
130
+ });
131
+ }
132
+ }
133
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib25ueC1zYW0tc2Vzc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvdG9vbGJhci9zZWdtZW50YXRpb24vb25ueC1zYW0tc2Vzc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssR0FBRyxNQUFNLGlCQUFpQixDQUFDO0FBS3ZDLE9BQU8sRUFBRSxVQUFVLEVBQUUsVUFBVSxFQUFFLFVBQVUsRUFBc0IsTUFBTSxpQkFBaUIsQ0FBQztBQUN6RixPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUF3QnRELE1BQU0sT0FBTyxjQUFjO0lBQTNCO1FBQ1UsU0FBSSxHQUErQixJQUFJLENBQUM7UUFDeEMsV0FBTSxHQUFHLEtBQUssQ0FBQztRQUNmLFVBQUssR0FBdUIsSUFBSSxDQUFDO1FBQ2pDLGNBQVMsR0FBRyxJQUFJLENBQUM7UUFFekIsb0JBQW9CO1FBQ1osV0FBTSxHQUFrQixJQUFJLENBQUM7UUFDN0IsUUFBRyxHQUFHLENBQUMsQ0FBQztRQUNDLFlBQU8sR0FBRyxJQUFJLEdBQUcsRUFBbUIsQ0FBQztRQUV0RCx3QkFBd0I7UUFDaEIsWUFBTyxHQUFnQyxJQUFJLENBQUM7UUFDNUMsWUFBTyxHQUFnQyxJQUFJLENBQUM7UUFDNUMsY0FBUyxHQUFHLENBQUMsQ0FBQztRQUNMLGVBQVUsR0FBRyxJQUFJLEdBQUcsRUFBeUIsQ0FBQztJQThHakUsQ0FBQztJQTVHQyxLQUFLLENBQUMsU0FBUyxDQUFDLEtBQWtCLEVBQUUsVUFBdUM7UUFDekUsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDM0MsTUFBTSxJQUFJLEtBQUssQ0FBQyxjQUFjLEtBQUssQ0FBQyxFQUFFLGdDQUFnQyxDQUFDLENBQUM7UUFDMUUsQ0FBQztRQUNELElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO1FBQ25C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SSxDQUFDLEdBQVEsRUFBRSxXQUEyQixFQUFFLEVBQUUsVUFBZ0M7UUFDcEYsTUFBTSxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDO1FBQ3RCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNuQyxPQUFPLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ3JDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsVUFBVSxFQUFFLENBQUMsQ0FBQztZQUN0RCxNQUFNLENBQUMsV0FBVyxDQUFDLEVBQUUsR0FBRyxHQUFHLEVBQUUsRUFBRSxFQUFFLEVBQUUsUUFBUSxDQUFDLENBQUM7UUFDL0MsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBvcnQgZnJvbSAnb25ueHJ1bnRpbWUtd2ViJztcblxuaW1wb3J0IHtcbiAgSVNhbVNlc3Npb24sIFNhbUVtYmVkZGluZywgU2FtTWFza1Jlc3VsdCwgU2FtTW9kZWxEZWYsIFNhbVByb21wdCxcbn0gZnJvbSAnLi4vLi4vY29udHJhY3RzL3NhbS5jb250cmFjdCc7XG5pbXBvcnQgeyBmZXRjaE1vZGVsLCBydW5FbmNvZGVyLCBydW5EZWNvZGVyLCB0eXBlIENvcmVFbWJlZGRpbmcgfSBmcm9tICcuL3NhbS1vbm54LWNvcmUnO1xuaW1wb3J0IHsgZ2V0T3J0V2FzbUJhc2UgfSBmcm9tICcuL29ydC1ydW50aW1lLWNvbmZpZyc7XG5cbi8qKlxuICogb25ueHJ1bnRpbWUtd2ViIGltcGxlbWVudGF0aW9uIG9mIHtAbGluayBJU2FtU2Vzc2lvbn0gKGppdC11aSM5MCksIHdpdGggdHdvXG4gKiBleGVjdXRpb24gbW9kZXMgY2hvc2VuIHBlciBtb2RlbDpcbiAqXG4gKiAgLSAqKmluLXByb2Nlc3MqKiAobWFpbiB0aHJlYWQpIOKAlCBmb3Igc21hbGwgV0FTTSBtb2RlbHMgZmxhZ2dlZCBgaW5Qcm9jZXNzYFxuICogICAgKGUuZy4gbWljcm8tc2FtIFZpVC1UKS4gRmFzdCBsb2FkICsgaW5mZXJlbmNlIHdpdGggbm8gV2ViIFdvcmtlciBzcGF3biAvXG4gKiAgICBzZWNvbmQgT1JUIHJ1bnRpbWUgLyBtZXNzYWdlIHJvdW5kLXRyaXBzOyB0aGUgYnJpZWYgZW5jb2RlIHJ1bnMgb24gdGhlIG1haW5cbiAqICAgIHRocmVhZCAoZmluZSBmb3IgYSB0aW55IG1vZGVsKS5cbiAqICAtICoqd29ya2VyKiog4oCUIGZvciBXZWJHUFUgbW9kZWxzIChlLmcuIFZpVC1CLCBwYXRoby1zYW0gZnAxNikgd2hvc2UgaGVhdnlcbiAqICAgIGVuY29kZSB3b3VsZCBvdGhlcndpc2UgZnJlZXplIHRoZSB0YWIuIFJ1bnMgaW4ge0BsaW5rIC4vb25ueC1zYW0ud29ya2VyfSBzb1xuICogICAgdGhlIFVJIHN0YXlzIHJlc3BvbnNpdmUgKHRoZSBzcGlubmVyIGFuaW1hdGVzKS5cbiAqXG4gKiBCb3RoIG1vZGVzIHNoYXJlIHRoZWlyIGluZmVyZW5jZSBtYXRoIHZpYSB7QGxpbmsgLi9zYW0tb25ueC1jb3JlfS4gTGF6eS1pbXBvcnRlZFxuICogYnkgdGhlIFNBTSB0b29scyBzbyBvbm54cnVudGltZS13ZWIgLyB0aGUgd29ya2VyIG5ldmVyIGxvYWQgaW4gdW5pdCB0ZXN0cyBvclxuICogdGhlIGluaXRpYWwgYnVuZGxlLlxuICovXG50eXBlIFBlbmRpbmcgPSB7XG4gIHJlc29sdmU6IChtc2c6IGFueSkgPT4gdm9pZDtcbiAgcmVqZWN0OiAoZXJyOiBFcnJvcikgPT4gdm9pZDtcbiAgb25Qcm9ncmVzcz86IChmcmFjdGlvbjogbnVtYmVyKSA9PiB2b2lkO1xufTtcblxuZXhwb3J0IGNsYXNzIE9ubnhTYW1TZXNzaW9uIGltcGxlbWVudHMgSVNhbVNlc3Npb24ge1xuICBwcml2YXRlIG1vZGU6ICdpbnByb2MnIHwgJ3dvcmtlcicgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBsb2FkZWQgPSBmYWxzZTtcbiAgcHJpdmF0ZSBtb2RlbDogU2FtTW9kZWxEZWYgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBpbnB1dFNpemUgPSAxMDI0O1xuXG4gIC8vIOKUgOKUgCB3b3JrZXIgbW9kZSDilIDilIBcbiAgcHJpdmF0ZSB3b3JrZXI6IFdvcmtlciB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIHNlcSA9IDA7XG4gIHByaXZhdGUgcmVhZG9ubHkgcGVuZGluZyA9IG5ldyBNYXA8bnVtYmVyLCBQZW5kaW5nPigpO1xuXG4gIC8vIOKUgOKUgCBpbi1wcm9jZXNzIG1vZGUg4pSA4pSAXG4gIHByaXZhdGUgZW5jb2Rlcjogb3J0LkluZmVyZW5jZVNlc3Npb24gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBkZWNvZGVyOiBvcnQuSW5mZXJlbmNlU2Vzc2lvbiB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIG5leHRUb2tlbiA9IDE7XG4gIHByaXZhdGUgcmVhZG9ubHkgZW1iZWRkaW5ncyA9IG5ldyBNYXA8bnVtYmVyLCBDb3JlRW1iZWRkaW5nPigpO1xuXG4gIGFzeW5jIGxvYWRNb2RlbChtb2RlbDogU2FtTW9kZWxEZWYsIG9uUHJvZ3Jlc3M/OiAoZnJhY3Rpb246IG51bWJlcikgPT4gdm9pZCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghbW9kZWwuZW5jb2RlclVybCB8fCAhbW9kZWwuZGVjb2RlclVybCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBTQU0gbW9kZWwgXCIke21vZGVsLmlkfVwiIGhhcyBubyBPTk5YIFVSTHMgY29uZmlndXJlZC5gKTtcbiAgICB9XG4gICAgdGhpcy5tb2RlbCA9IG1vZGVsO1xuICAgIHRoaXMuaW5wdXRTaXplID0gbW9kZWwuaW5wdXRTaXplO1xuICAgIGNvbnN0IGhhc0dwdSA9IHR5cGVvZiBuYXZpZ2F0b3IgIT09ICd1bmRlZmluZWQnICYmICdncHUnIGluIG5hdmlnYXRvcjtcbiAgICBjb25zdCBlcHM6IHN0cmluZ1tdID0gbW9kZWwuZW5jb2RlclByb3ZpZGVycyA/PyAoaGFzR3B1ID8gWyd3ZWJncHUnLCAnd2FzbSddIDogWyd3YXNtJ10pO1xuICAgIGNvbnN0IHVzZXNXZWJHcHUgPSBlcHMuaW5jbHVkZXMoJ3dlYmdwdScpO1xuICAgIC8vIFdlYkdQVSBtdXN0IHJ1biBpbiB0aGUgd29ya2VyIChlbHNlIGl0IGZyZWV6ZXMgdGhlIG1haW4gdGhyZWFkKTsgc21hbGxcbiAgICAvLyBXQVNNIG1vZGVscyBvcHQgaW50byB0aGUgZmFzdGVyIGluLXByb2Nlc3MgcGF0aCB2aWEgYGluUHJvY2Vzc2AuXG4gICAgdGhpcy5tb2RlID0gIXVzZXNXZWJHcHUgJiYgbW9kZWwuaW5Qcm9jZXNzID8gJ2lucHJvYycgOiAnd29ya2VyJztcblxuICAgIGlmICh0aGlzLm1vZGUgPT09ICdpbnByb2MnKSB7XG4gICAgICBvcnQuZW52Lndhc20ud2FzbVBhdGhzID0gZ2V0T3J0V2FzbUJhc2UoKTtcbiAgICAgIGNvbnN0IGVuY0J1ZiA9IGF3YWl0IGZldGNoTW9kZWwobW9kZWwuZW5jb2RlclVybCwgb25Qcm9ncmVzcyk7XG4gICAgICBjb25zdCBkZWNCdWYgPSBhd2FpdCBmZXRjaE1vZGVsKG1vZGVsLmRlY29kZXJVcmwpO1xuICAgICAgdGhpcy5lbmNvZGVyID0gYXdhaXQgb3J0LkluZmVyZW5jZVNlc3Npb24uY3JlYXRlKGVuY0J1ZiwgeyBleGVjdXRpb25Qcm92aWRlcnM6IGVwcyB9KTtcbiAgICAgIHRoaXMuZGVjb2RlciA9IGF3YWl0IG9ydC5JbmZlcmVuY2VTZXNzaW9uLmNyZWF0ZShkZWNCdWYsIHsgZXhlY3V0aW9uUHJvdmlkZXJzOiBbJ3dhc20nXSB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXdhaXQgdGhpcy5jYWxsKHtcbiAgICAgICAgdHlwZTogJ2xvYWQnLFxuICAgICAgICBlbmNvZGVyVXJsOiBtb2RlbC5lbmNvZGVyVXJsLFxuICAgICAgICBkZWNvZGVyVXJsOiBtb2RlbC5kZWNvZGVyVXJsLFxuICAgICAgICB3YXNtUGF0aHM6IGdldE9ydFdhc21CYXNlKCksXG4gICAgICAgIGlucHV0U2l6ZTogbW9kZWwuaW5wdXRTaXplLFxuICAgICAgICBlbmNvZGVyUHJvdmlkZXJzOiBtb2RlbC5lbmNvZGVyUHJvdmlkZXJzLFxuICAgICAgfSwgW10sIG9uUHJvZ3Jlc3MpO1xuICAgIH1cbiAgICB0aGlzLmxvYWRlZCA9IHRydWU7XG4gIH1cblxuICBpc0xvYWRlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5sb2FkZWQ7XG4gIH1cblxuICBhc3luYyBlbWJlZChpbWFnZTogeyBkYXRhOiBVaW50OENsYW1wZWRBcnJheTsgd2lkdGg6IG51bWJlcjsgaGVpZ2h0OiBudW1iZXIgfSk6IFByb21pc2U8U2FtRW1iZWRkaW5nPiB7XG4gICAgaWYgKHRoaXMubW9kZSA9PT0gJ2lucHJvYycpIHtcbiAgICAgIGNvbnN0IGUgPSBhd2FpdCBydW5FbmNvZGVyKHRoaXMuZW5jb2RlciEsIGltYWdlLmRhdGEsIGltYWdlLndpZHRoLCBpbWFnZS5oZWlnaHQsIHRoaXMuaW5wdXRTaXplKTtcbiAgICAgIGNvbnN0IHRva2VuID0gdGhpcy5uZXh0VG9rZW4rKztcbiAgICAgIHRoaXMuZW1iZWRkaW5ncy5zZXQodG9rZW4sIGUpO1xuICAgICAgaWYgKHRoaXMuZW1iZWRkaW5ncy5zaXplID4gMykgdGhpcy5lbWJlZGRpbmdzLmRlbGV0ZSh0aGlzLmVtYmVkZGluZ3Mua2V5cygpLm5leHQoKS52YWx1ZSBhcyBudW1iZXIpO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgZGF0YTogbmV3IEZsb2F0MzJBcnJheSgwKSwgZGltczogZS5kaW1zLCBzY2FsZTogZS5zY2FsZSxcbiAgICAgICAgaW1hZ2VXaWR0aDogZS5pbWFnZVdpZHRoLCBpbWFnZUhlaWdodDogZS5pbWFnZUhlaWdodCwgdG9rZW4sXG4gICAgICB9O1xuICAgIH1cbiAgICAvLyB3b3JrZXI6IHRyYW5zZmVyIHRoZSBSR0JBIGJ1ZmZlciAoY2FsbGVycyBwYXNzIGEgZnJlc2ggZnJhbWUgYnVmZmVyKS5cbiAgICBjb25zdCBidWZmZXIgPSBpbWFnZS5kYXRhLmJ1ZmZlcjtcbiAgICBjb25zdCByZXMgPSBhd2FpdCB0aGlzLmNhbGwoeyB0eXBlOiAnZW1iZWQnLCB3aWR0aDogaW1hZ2Uud2lkdGgsIGhlaWdodDogaW1hZ2UuaGVpZ2h0LCBidWZmZXIgfSwgW2J1ZmZlcl0pO1xuICAgIHJldHVybiB7XG4gICAgICBkYXRhOiBuZXcgRmxvYXQzMkFycmF5KDApLCBkaW1zOiByZXMuZGltcywgc2NhbGU6IHJlcy5zY2FsZSxcbiAgICAgIGltYWdlV2lkdGg6IHJlcy5pbWFnZVdpZHRoLCBpbWFnZUhlaWdodDogcmVzLmltYWdlSGVpZ2h0LCB0b2tlbjogcmVzLnRva2VuLFxuICAgIH07XG4gIH1cblxuICBhc3luYyBkZWNvZGUoZW1iZWRkaW5nOiBTYW1FbWJlZGRpbmcsIHByb21wdDogU2FtUHJvbXB0KTogUHJvbWlzZTxTYW1NYXNrUmVzdWx0PiB7XG4gICAgaWYgKHRoaXMubW9kZSA9PT0gJ2lucHJvYycpIHtcbiAgICAgIGNvbnN0IGUgPSB0aGlzLmVtYmVkZGluZ3MuZ2V0KGVtYmVkZGluZy50b2tlbiBhcyBudW1iZXIpO1xuICAgICAgaWYgKCFlKSB0aHJvdyBuZXcgRXJyb3IoJ1NBTSBlbWJlZGRpbmcgZXhwaXJlZDsgcmUtZW5jb2RlIHRoZSBpbWFnZS4nKTtcbiAgICAgIHJldHVybiBydW5EZWNvZGVyKHRoaXMuZGVjb2RlciEsIGUsIHByb21wdCk7XG4gICAgfVxuICAgIGNvbnN0IHJlcyA9IGF3YWl0IHRoaXMuY2FsbCh7IHR5cGU6ICdkZWNvZGUnLCB0b2tlbjogZW1iZWRkaW5nLnRva2VuLCBwcm9tcHQgfSk7XG4gICAgcmV0dXJuIHsgbWFzazogbmV3IFVpbnQ4QXJyYXkocmVzLmJ1ZmZlciksIHdpZHRoOiByZXMud2lkdGgsIGhlaWdodDogcmVzLmhlaWdodCwgaW91OiByZXMuaW91IH07XG4gIH1cblxuICBkaXNwb3NlKCk6IHZvaWQge1xuICAgIHRoaXMud29ya2VyPy50ZXJtaW5hdGUoKTtcbiAgICB0aGlzLndvcmtlciA9IG51bGw7XG4gICAgdGhpcy5wZW5kaW5nLmNsZWFyKCk7XG4gICAgdGhpcy5lbmNvZGVyPy5yZWxlYXNlPy4oKTtcbiAgICB0aGlzLmRlY29kZXI/LnJlbGVhc2U/LigpO1xuICAgIHRoaXMuZW5jb2RlciA9IHRoaXMuZGVjb2RlciA9IG51bGw7XG4gICAgdGhpcy5lbWJlZGRpbmdzLmNsZWFyKCk7XG4gICAgdGhpcy5sb2FkZWQgPSBmYWxzZTtcbiAgICB0aGlzLm1vZGUgPSBudWxsO1xuICB9XG5cbiAgLy8g4pSA4pSAIHdvcmtlciBwbHVtYmluZyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgcHJpdmF0ZSBlbnN1cmVXb3JrZXIoKTogV29ya2VyIHtcbiAgICBpZiAodGhpcy53b3JrZXIpIHJldHVybiB0aGlzLndvcmtlcjtcbiAgICBjb25zdCB3b3JrZXIgPSBuZXcgV29ya2VyKG5ldyBVUkwoJy4vb25ueC1zYW0ud29ya2VyJywgaW1wb3J0Lm1ldGEudXJsKSwgeyB0eXBlOiAnbW9kdWxlJyB9KTtcbiAgICB3b3JrZXIub25tZXNzYWdlID0gKGV2OiBNZXNzYWdlRXZlbnQpID0+IHtcbiAgICAgIGNvbnN0IG0gPSBldi5kYXRhO1xuICAgICAgY29uc3QgcCA9IHRoaXMucGVuZGluZy5nZXQobS5pZCk7XG4gICAgICBpZiAoIXApIHJldHVybjtcbiAgICAgIGlmIChtLnR5cGUgPT09ICdwcm9ncmVzcycpIHsgcC5vblByb2dyZXNzPy4obS5mcmFjdGlvbik7IHJldHVybjsgfVxuICAgICAgdGhpcy5wZW5kaW5nLmRlbGV0ZShtLmlkKTtcbiAgICAgIGlmIChtLnR5cGUgPT09ICdlcnJvcicpIHAucmVqZWN0KG5ldyBFcnJvcihtLmVycm9yKSk7XG4gICAgICBlbHNlIHAucmVzb2x2ZShtKTtcbiAgICB9O1xuICAgIHdvcmtlci5vbmVycm9yID0gKGV2OiBFcnJvckV2ZW50KSA9PiB7XG4gICAgICBjb25zdCBlcnIgPSBuZXcgRXJyb3IoZXYubWVzc2FnZSB8fCAnU0FNIHdvcmtlciBjcmFzaGVkLicpO1xuICAgICAgZm9yIChjb25zdCBwIG9mIHRoaXMucGVuZGluZy52YWx1ZXMoKSkgcC5yZWplY3QoZXJyKTtcbiAgICAgIHRoaXMucGVuZGluZy5jbGVhcigpO1xuICAgIH07XG4gICAgdGhpcy53b3JrZXIgPSB3b3JrZXI7XG4gICAgcmV0dXJuIHdvcmtlcjtcbiAgfVxuXG4gIHByaXZhdGUgY2FsbChtc2c6IGFueSwgdHJhbnNmZXI6IFRyYW5zZmVyYWJsZVtdID0gW10sIG9uUHJvZ3Jlc3M/OiAoZjogbnVtYmVyKSA9PiB2b2lkKTogUHJvbWlzZTxhbnk+IHtcbiAgICBjb25zdCBpZCA9ICsrdGhpcy5zZXE7XG4gICAgY29uc3Qgd29ya2VyID0gdGhpcy5lbnN1cmVXb3JrZXIoKTtcbiAgICByZXR1cm4gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5wZW5kaW5nLnNldChpZCwgeyByZXNvbHZlLCByZWplY3QsIG9uUHJvZ3Jlc3MgfSk7XG4gICAgICB3b3JrZXIucG9zdE1lc3NhZ2UoeyAuLi5tc2csIGlkIH0sIHRyYW5zZmVyKTtcbiAgICB9KTtcbiAgfVxufVxuIl19
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Shared base URL/path for onnxruntime-web's WASM sidecar files
3
+ * (`ort-wasm-simd-threaded.wasm` / `.jsep.mjs`), used by every ONNX-model tool
4
+ * in the library: SAM (in-process and worker) and Cellpose-SAM.
5
+ *
6
+ * Defaults to `'/assets/ort/'` — a host that serves onnxruntime-web's `dist`
7
+ * WASM files there (as jit-ui does via its `project.json` asset glob) needs no
8
+ * configuration and behaves exactly as before this knob existed. A host that
9
+ * cannot serve them at that path — e.g. a static deployment behind an auth
10
+ * proxy, or one that prefers a CDN — calls {@link setOrtWasmBase} ONCE at app
11
+ * init to point the runtime elsewhere:
12
+ *
13
+ * ```ts
14
+ * // version MUST match the onnxruntime-web the library was built against
15
+ * setOrtWasmBase('https://cdn.jsdelivr.net/npm/onnxruntime-web@1.26.0/dist/');
16
+ * ```
17
+ *
18
+ * Must be set before the first segmentation runs; the value is read at use time
19
+ * by each tool (and passed into the SAM worker via its load message), so a
20
+ * single call at bootstrap covers SAM and Cellpose alike.
21
+ */
22
+ let ortWasmBase = '/assets/ort/';
23
+ /** Override where onnxruntime-web loads its WASM sidecars from. See module docs. */
24
+ export function setOrtWasmBase(base) {
25
+ ortWasmBase = base;
26
+ }
27
+ /** The configured onnxruntime-web WASM base (default `'/assets/ort/'`). */
28
+ export function getOrtWasmBase() {
29
+ return ortWasmBase;
30
+ }
31
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib3J0LXJ1bnRpbWUtY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi90b29sYmFyL3NlZ21lbnRhdGlvbi9vcnQtcnVudGltZS1jb25maWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JHO0FBQ0gsSUFBSSxXQUFXLEdBQUcsY0FBYyxDQUFDO0FBRWpDLG9GQUFvRjtBQUNwRixNQUFNLFVBQVUsY0FBYyxDQUFDLElBQVk7SUFDekMsV0FBVyxHQUFHLElBQUksQ0FBQztBQUNyQixDQUFDO0FBRUQsMkVBQTJFO0FBQzNFLE1BQU0sVUFBVSxjQUFjO0lBQzVCLE9BQU8sV0FBVyxDQUFDO0FBQ3JCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFNoYXJlZCBiYXNlIFVSTC9wYXRoIGZvciBvbm54cnVudGltZS13ZWIncyBXQVNNIHNpZGVjYXIgZmlsZXNcbiAqIChgb3J0LXdhc20tc2ltZC10aHJlYWRlZC53YXNtYCAvIGAuanNlcC5tanNgKSwgdXNlZCBieSBldmVyeSBPTk5YLW1vZGVsIHRvb2xcbiAqIGluIHRoZSBsaWJyYXJ5OiBTQU0gKGluLXByb2Nlc3MgYW5kIHdvcmtlcikgYW5kIENlbGxwb3NlLVNBTS5cbiAqXG4gKiBEZWZhdWx0cyB0byBgJy9hc3NldHMvb3J0LydgIOKAlCBhIGhvc3QgdGhhdCBzZXJ2ZXMgb25ueHJ1bnRpbWUtd2ViJ3MgYGRpc3RgXG4gKiBXQVNNIGZpbGVzIHRoZXJlIChhcyBqaXQtdWkgZG9lcyB2aWEgaXRzIGBwcm9qZWN0Lmpzb25gIGFzc2V0IGdsb2IpIG5lZWRzIG5vXG4gKiBjb25maWd1cmF0aW9uIGFuZCBiZWhhdmVzIGV4YWN0bHkgYXMgYmVmb3JlIHRoaXMga25vYiBleGlzdGVkLiBBIGhvc3QgdGhhdFxuICogY2Fubm90IHNlcnZlIHRoZW0gYXQgdGhhdCBwYXRoIOKAlCBlLmcuIGEgc3RhdGljIGRlcGxveW1lbnQgYmVoaW5kIGFuIGF1dGhcbiAqIHByb3h5LCBvciBvbmUgdGhhdCBwcmVmZXJzIGEgQ0ROIOKAlCBjYWxscyB7QGxpbmsgc2V0T3J0V2FzbUJhc2V9IE9OQ0UgYXQgYXBwXG4gKiBpbml0IHRvIHBvaW50IHRoZSBydW50aW1lIGVsc2V3aGVyZTpcbiAqXG4gKiBgYGB0c1xuICogLy8gdmVyc2lvbiBNVVNUIG1hdGNoIHRoZSBvbm54cnVudGltZS13ZWIgdGhlIGxpYnJhcnkgd2FzIGJ1aWx0IGFnYWluc3RcbiAqIHNldE9ydFdhc21CYXNlKCdodHRwczovL2Nkbi5qc2RlbGl2ci5uZXQvbnBtL29ubnhydW50aW1lLXdlYkAxLjI2LjAvZGlzdC8nKTtcbiAqIGBgYFxuICpcbiAqIE11c3QgYmUgc2V0IGJlZm9yZSB0aGUgZmlyc3Qgc2VnbWVudGF0aW9uIHJ1bnM7IHRoZSB2YWx1ZSBpcyByZWFkIGF0IHVzZSB0aW1lXG4gKiBieSBlYWNoIHRvb2wgKGFuZCBwYXNzZWQgaW50byB0aGUgU0FNIHdvcmtlciB2aWEgaXRzIGxvYWQgbWVzc2FnZSksIHNvIGFcbiAqIHNpbmdsZSBjYWxsIGF0IGJvb3RzdHJhcCBjb3ZlcnMgU0FNIGFuZCBDZWxscG9zZSBhbGlrZS5cbiAqL1xubGV0IG9ydFdhc21CYXNlID0gJy9hc3NldHMvb3J0Lyc7XG5cbi8qKiBPdmVycmlkZSB3aGVyZSBvbm54cnVudGltZS13ZWIgbG9hZHMgaXRzIFdBU00gc2lkZWNhcnMgZnJvbS4gU2VlIG1vZHVsZSBkb2NzLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldE9ydFdhc21CYXNlKGJhc2U6IHN0cmluZyk6IHZvaWQge1xuICBvcnRXYXNtQmFzZSA9IGJhc2U7XG59XG5cbi8qKiBUaGUgY29uZmlndXJlZCBvbm54cnVudGltZS13ZWIgV0FTTSBiYXNlIChkZWZhdWx0IGAnL2Fzc2V0cy9vcnQvJ2ApLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldE9ydFdhc21CYXNlKCk6IHN0cmluZyB7XG4gIHJldHVybiBvcnRXYXNtQmFzZTtcbn1cbiJdfQ==