@cornerstonejs/tools 0.1.1

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 (1417) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -0
  3. package/dist/cjs/cursors/ImageMouseCursor.d.ts +9 -0
  4. package/dist/cjs/cursors/ImageMouseCursor.js +29 -0
  5. package/dist/cjs/cursors/ImageMouseCursor.js.map +1 -0
  6. package/dist/cjs/cursors/MouseCursor.d.ts +12 -0
  7. package/dist/cjs/cursors/MouseCursor.js +93 -0
  8. package/dist/cjs/cursors/MouseCursor.js.map +1 -0
  9. package/dist/cjs/cursors/SVGCursorDescriptor.d.ts +8 -0
  10. package/dist/cjs/cursors/SVGCursorDescriptor.js +404 -0
  11. package/dist/cjs/cursors/SVGCursorDescriptor.js.map +1 -0
  12. package/dist/cjs/cursors/SVGMouseCursor.d.ts +6 -0
  13. package/dist/cjs/cursors/SVGMouseCursor.js +78 -0
  14. package/dist/cjs/cursors/SVGMouseCursor.js.map +1 -0
  15. package/dist/cjs/cursors/elementCursor.d.ts +6 -0
  16. package/dist/cjs/cursors/elementCursor.js +43 -0
  17. package/dist/cjs/cursors/elementCursor.js.map +1 -0
  18. package/dist/cjs/cursors/index.d.ts +8 -0
  19. package/dist/cjs/cursors/index.js +40 -0
  20. package/dist/cjs/cursors/index.js.map +1 -0
  21. package/dist/cjs/cursors/setCursorForElement.d.ts +2 -0
  22. package/dist/cjs/cursors/setCursorForElement.js +21 -0
  23. package/dist/cjs/cursors/setCursorForElement.js.map +1 -0
  24. package/dist/cjs/drawingSvg/_getHash.d.ts +2 -0
  25. package/dist/cjs/drawingSvg/_getHash.js +7 -0
  26. package/dist/cjs/drawingSvg/_getHash.js.map +1 -0
  27. package/dist/cjs/drawingSvg/_setAttributesIfNecessary.d.ts +2 -0
  28. package/dist/cjs/drawingSvg/_setAttributesIfNecessary.js +18 -0
  29. package/dist/cjs/drawingSvg/_setAttributesIfNecessary.js.map +1 -0
  30. package/dist/cjs/drawingSvg/_setNewAttributesIfValid.d.ts +2 -0
  31. package/dist/cjs/drawingSvg/_setNewAttributesIfValid.js +14 -0
  32. package/dist/cjs/drawingSvg/_setNewAttributesIfValid.js.map +1 -0
  33. package/dist/cjs/drawingSvg/clearByToolType.d.ts +2 -0
  34. package/dist/cjs/drawingSvg/clearByToolType.js +19 -0
  35. package/dist/cjs/drawingSvg/clearByToolType.js.map +1 -0
  36. package/dist/cjs/drawingSvg/draw.d.ts +2 -0
  37. package/dist/cjs/drawingSvg/draw.js +13 -0
  38. package/dist/cjs/drawingSvg/draw.js.map +1 -0
  39. package/dist/cjs/drawingSvg/drawCircle.d.ts +3 -0
  40. package/dist/cjs/drawingSvg/drawCircle.js +39 -0
  41. package/dist/cjs/drawingSvg/drawCircle.js.map +1 -0
  42. package/dist/cjs/drawingSvg/drawEllipse.d.ts +3 -0
  43. package/dist/cjs/drawingSvg/drawEllipse.js +48 -0
  44. package/dist/cjs/drawingSvg/drawEllipse.js.map +1 -0
  45. package/dist/cjs/drawingSvg/drawHandles.d.ts +3 -0
  46. package/dist/cjs/drawingSvg/drawHandles.js +66 -0
  47. package/dist/cjs/drawingSvg/drawHandles.js.map +1 -0
  48. package/dist/cjs/drawingSvg/drawLine.d.ts +2 -0
  49. package/dist/cjs/drawingSvg/drawLine.js +43 -0
  50. package/dist/cjs/drawingSvg/drawLine.js.map +1 -0
  51. package/dist/cjs/drawingSvg/drawLink.d.ts +4 -0
  52. package/dist/cjs/drawingSvg/drawLink.js +32 -0
  53. package/dist/cjs/drawingSvg/drawLink.js.map +1 -0
  54. package/dist/cjs/drawingSvg/drawLinkedTextBox.d.ts +3 -0
  55. package/dist/cjs/drawingSvg/drawLinkedTextBox.js +21 -0
  56. package/dist/cjs/drawingSvg/drawLinkedTextBox.js.map +1 -0
  57. package/dist/cjs/drawingSvg/drawRect.d.ts +2 -0
  58. package/dist/cjs/drawingSvg/drawRect.js +44 -0
  59. package/dist/cjs/drawingSvg/drawRect.js.map +1 -0
  60. package/dist/cjs/drawingSvg/drawTextBox.d.ts +3 -0
  61. package/dist/cjs/drawingSvg/drawTextBox.js +117 -0
  62. package/dist/cjs/drawingSvg/drawTextBox.js.map +1 -0
  63. package/dist/cjs/drawingSvg/getSvgDrawingHelper.d.ts +11 -0
  64. package/dist/cjs/drawingSvg/getSvgDrawingHelper.js +68 -0
  65. package/dist/cjs/drawingSvg/getSvgDrawingHelper.js.map +1 -0
  66. package/dist/cjs/drawingSvg/index.d.ts +20 -0
  67. package/dist/cjs/drawingSvg/index.js +33 -0
  68. package/dist/cjs/drawingSvg/index.js.map +1 -0
  69. package/dist/cjs/enums/AnnotationStyleStates.d.ts +7 -0
  70. package/dist/cjs/enums/AnnotationStyleStates.js +11 -0
  71. package/dist/cjs/enums/AnnotationStyleStates.js.map +1 -0
  72. package/dist/cjs/enums/Events.d.ts +23 -0
  73. package/dist/cjs/enums/Events.js +27 -0
  74. package/dist/cjs/enums/Events.js.map +1 -0
  75. package/dist/cjs/enums/SegmentationRepresentations.d.ts +4 -0
  76. package/dist/cjs/enums/SegmentationRepresentations.js +8 -0
  77. package/dist/cjs/enums/SegmentationRepresentations.js.map +1 -0
  78. package/dist/cjs/enums/ToolBindings.d.ts +17 -0
  79. package/dist/cjs/enums/ToolBindings.js +24 -0
  80. package/dist/cjs/enums/ToolBindings.js.map +1 -0
  81. package/dist/cjs/enums/ToolModes.d.ts +7 -0
  82. package/dist/cjs/enums/ToolModes.js +11 -0
  83. package/dist/cjs/enums/ToolModes.js.map +1 -0
  84. package/dist/cjs/enums/index.d.ts +7 -0
  85. package/dist/cjs/enums/index.js +18 -0
  86. package/dist/cjs/enums/index.js.map +1 -0
  87. package/dist/cjs/eventDispatchers/annotationModifiedEventDispatcher.d.ts +5 -0
  88. package/dist/cjs/eventDispatchers/annotationModifiedEventDispatcher.js +24 -0
  89. package/dist/cjs/eventDispatchers/annotationModifiedEventDispatcher.js.map +1 -0
  90. package/dist/cjs/eventDispatchers/cameraModifiedEventDispatcher.d.ts +5 -0
  91. package/dist/cjs/eventDispatchers/cameraModifiedEventDispatcher.js +32 -0
  92. package/dist/cjs/eventDispatchers/cameraModifiedEventDispatcher.js.map +1 -0
  93. package/dist/cjs/eventDispatchers/imageRenderedEventDispatcher.d.ts +5 -0
  94. package/dist/cjs/eventDispatchers/imageRenderedEventDispatcher.js +21 -0
  95. package/dist/cjs/eventDispatchers/imageRenderedEventDispatcher.js.map +1 -0
  96. package/dist/cjs/eventDispatchers/imageSpacingCalibratedEventDispatcher.d.ts +5 -0
  97. package/dist/cjs/eventDispatchers/imageSpacingCalibratedEventDispatcher.js +32 -0
  98. package/dist/cjs/eventDispatchers/imageSpacingCalibratedEventDispatcher.js.map +1 -0
  99. package/dist/cjs/eventDispatchers/index.d.ts +6 -0
  100. package/dist/cjs/eventDispatchers/index.js +17 -0
  101. package/dist/cjs/eventDispatchers/index.js.map +1 -0
  102. package/dist/cjs/eventDispatchers/keyboardEventHandlers/index.d.ts +3 -0
  103. package/dist/cjs/eventDispatchers/keyboardEventHandlers/index.js +11 -0
  104. package/dist/cjs/eventDispatchers/keyboardEventHandlers/index.js.map +1 -0
  105. package/dist/cjs/eventDispatchers/keyboardEventHandlers/keyDown.d.ts +2 -0
  106. package/dist/cjs/eventDispatchers/keyboardEventHandlers/keyDown.js +21 -0
  107. package/dist/cjs/eventDispatchers/keyboardEventHandlers/keyDown.js.map +1 -0
  108. package/dist/cjs/eventDispatchers/keyboardEventHandlers/keyUp.d.ts +2 -0
  109. package/dist/cjs/eventDispatchers/keyboardEventHandlers/keyUp.js +23 -0
  110. package/dist/cjs/eventDispatchers/keyboardEventHandlers/keyUp.js.map +1 -0
  111. package/dist/cjs/eventDispatchers/keyboardToolEventDispatcher.d.ts +5 -0
  112. package/dist/cjs/eventDispatchers/keyboardToolEventDispatcher.js +21 -0
  113. package/dist/cjs/eventDispatchers/keyboardToolEventDispatcher.js.map +1 -0
  114. package/dist/cjs/eventDispatchers/mouseEventHandlers/index.d.ts +9 -0
  115. package/dist/cjs/eventDispatchers/mouseEventHandlers/index.js +23 -0
  116. package/dist/cjs/eventDispatchers/mouseEventHandlers/index.js.map +1 -0
  117. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseClick.d.ts +2 -0
  118. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseClick.js +9 -0
  119. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseClick.js.map +1 -0
  120. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseDoubleClick.d.ts +2 -0
  121. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseDoubleClick.js +9 -0
  122. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseDoubleClick.js.map +1 -0
  123. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseDown.d.ts +2 -0
  124. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseDown.js +83 -0
  125. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseDown.js.map +1 -0
  126. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseDownActivate.d.ts +2 -0
  127. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseDownActivate.js +26 -0
  128. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseDownActivate.js.map +1 -0
  129. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseDrag.d.ts +2 -0
  130. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseDrag.js +20 -0
  131. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseDrag.js.map +1 -0
  132. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseMove.d.ts +2 -0
  133. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseMove.js +35 -0
  134. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseMove.js.map +1 -0
  135. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseUp.d.ts +2 -0
  136. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseUp.js +9 -0
  137. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseUp.js.map +1 -0
  138. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseWheel.d.ts +2 -0
  139. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseWheel.js +9 -0
  140. package/dist/cjs/eventDispatchers/mouseEventHandlers/mouseWheel.js.map +1 -0
  141. package/dist/cjs/eventDispatchers/mouseToolEventDispatcher.d.ts +5 -0
  142. package/dist/cjs/eventDispatchers/mouseToolEventDispatcher.js +33 -0
  143. package/dist/cjs/eventDispatchers/mouseToolEventDispatcher.js.map +1 -0
  144. package/dist/cjs/eventDispatchers/shared/customCallbackHandler.d.ts +1 -0
  145. package/dist/cjs/eventDispatchers/shared/customCallbackHandler.js +36 -0
  146. package/dist/cjs/eventDispatchers/shared/customCallbackHandler.js.map +1 -0
  147. package/dist/cjs/eventDispatchers/shared/getActiveToolForKeyboardEvent.d.ts +2 -0
  148. package/dist/cjs/eventDispatchers/shared/getActiveToolForKeyboardEvent.js +29 -0
  149. package/dist/cjs/eventDispatchers/shared/getActiveToolForKeyboardEvent.js.map +1 -0
  150. package/dist/cjs/eventDispatchers/shared/getActiveToolForMouseEvent.d.ts +2 -0
  151. package/dist/cjs/eventDispatchers/shared/getActiveToolForMouseEvent.js +29 -0
  152. package/dist/cjs/eventDispatchers/shared/getActiveToolForMouseEvent.js.map +1 -0
  153. package/dist/cjs/eventDispatchers/shared/getToolsWithModesForMouseEvent.d.ts +5 -0
  154. package/dist/cjs/eventDispatchers/shared/getToolsWithModesForMouseEvent.js +27 -0
  155. package/dist/cjs/eventDispatchers/shared/getToolsWithModesForMouseEvent.js.map +1 -0
  156. package/dist/cjs/eventListeners/annotations/annotationModifiedListener.d.ts +2 -0
  157. package/dist/cjs/eventListeners/annotations/annotationModifiedListener.js +14 -0
  158. package/dist/cjs/eventListeners/annotations/annotationModifiedListener.js.map +1 -0
  159. package/dist/cjs/eventListeners/annotations/annotationSelectionListener.d.ts +2 -0
  160. package/dist/cjs/eventListeners/annotations/annotationSelectionListener.js +18 -0
  161. package/dist/cjs/eventListeners/annotations/annotationSelectionListener.js.map +1 -0
  162. package/dist/cjs/eventListeners/annotations/index.d.ts +3 -0
  163. package/dist/cjs/eventListeners/annotations/index.js +11 -0
  164. package/dist/cjs/eventListeners/annotations/index.js.map +1 -0
  165. package/dist/cjs/eventListeners/index.d.ts +6 -0
  166. package/dist/cjs/eventListeners/index.js +19 -0
  167. package/dist/cjs/eventListeners/index.js.map +1 -0
  168. package/dist/cjs/eventListeners/keyboard/index.d.ts +9 -0
  169. package/dist/cjs/eventListeners/keyboard/index.js +35 -0
  170. package/dist/cjs/eventListeners/keyboard/index.js.map +1 -0
  171. package/dist/cjs/eventListeners/keyboard/keyDownListener.d.ts +4 -0
  172. package/dist/cjs/eventListeners/keyboard/keyDownListener.js +66 -0
  173. package/dist/cjs/eventListeners/keyboard/keyDownListener.js.map +1 -0
  174. package/dist/cjs/eventListeners/mouse/getMouseEventPoints.d.ts +2 -0
  175. package/dist/cjs/eventListeners/mouse/getMouseEventPoints.js +32 -0
  176. package/dist/cjs/eventListeners/mouse/getMouseEventPoints.js.map +1 -0
  177. package/dist/cjs/eventListeners/mouse/index.d.ts +7 -0
  178. package/dist/cjs/eventListeners/mouse/index.js +24 -0
  179. package/dist/cjs/eventListeners/mouse/index.js.map +1 -0
  180. package/dist/cjs/eventListeners/mouse/mouseDoubleClickListener.d.ts +2 -0
  181. package/dist/cjs/eventListeners/mouse/mouseDoubleClickListener.js +34 -0
  182. package/dist/cjs/eventListeners/mouse/mouseDoubleClickListener.js.map +1 -0
  183. package/dist/cjs/eventListeners/mouse/mouseDownListener.d.ts +3 -0
  184. package/dist/cjs/eventListeners/mouse/mouseDownListener.js +166 -0
  185. package/dist/cjs/eventListeners/mouse/mouseDownListener.js.map +1 -0
  186. package/dist/cjs/eventListeners/mouse/mouseMoveListener.d.ts +2 -0
  187. package/dist/cjs/eventListeners/mouse/mouseMoveListener.js +27 -0
  188. package/dist/cjs/eventListeners/mouse/mouseMoveListener.js.map +1 -0
  189. package/dist/cjs/eventListeners/segmentation/index.d.ts +3 -0
  190. package/dist/cjs/eventListeners/segmentation/index.js +11 -0
  191. package/dist/cjs/eventListeners/segmentation/index.js.map +1 -0
  192. package/dist/cjs/eventListeners/segmentation/segmentationDataModifiedEventListener.d.ts +3 -0
  193. package/dist/cjs/eventListeners/segmentation/segmentationDataModifiedEventListener.js +62 -0
  194. package/dist/cjs/eventListeners/segmentation/segmentationDataModifiedEventListener.js.map +1 -0
  195. package/dist/cjs/eventListeners/segmentation/segmentationStateModifiedEventListener.d.ts +3 -0
  196. package/dist/cjs/eventListeners/segmentation/segmentationStateModifiedEventListener.js +12 -0
  197. package/dist/cjs/eventListeners/segmentation/segmentationStateModifiedEventListener.js.map +1 -0
  198. package/dist/cjs/eventListeners/wheel/index.d.ts +7 -0
  199. package/dist/cjs/eventListeners/wheel/index.js +18 -0
  200. package/dist/cjs/eventListeners/wheel/index.js.map +1 -0
  201. package/dist/cjs/eventListeners/wheel/normalizeWheel.d.ts +6 -0
  202. package/dist/cjs/eventListeners/wheel/normalizeWheel.js +52 -0
  203. package/dist/cjs/eventListeners/wheel/normalizeWheel.js.map +1 -0
  204. package/dist/cjs/eventListeners/wheel/wheelListener.d.ts +2 -0
  205. package/dist/cjs/eventListeners/wheel/wheelListener.js +40 -0
  206. package/dist/cjs/eventListeners/wheel/wheelListener.js.map +1 -0
  207. package/dist/cjs/index.d.ts +19 -0
  208. package/dist/cjs/index.js +78 -0
  209. package/dist/cjs/index.js.map +1 -0
  210. package/dist/cjs/init.d.ts +3 -0
  211. package/dist/cjs/init.js +74 -0
  212. package/dist/cjs/init.js.map +1 -0
  213. package/dist/cjs/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.d.ts +23 -0
  214. package/dist/cjs/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.js +157 -0
  215. package/dist/cjs/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.js.map +1 -0
  216. package/dist/cjs/stateManagement/annotation/annotationLocking.d.ts +8 -0
  217. package/dist/cjs/stateManagement/annotation/annotationLocking.js +96 -0
  218. package/dist/cjs/stateManagement/annotation/annotationLocking.js.map +1 -0
  219. package/dist/cjs/stateManagement/annotation/annotationSelection.d.ts +8 -0
  220. package/dist/cjs/stateManagement/annotation/annotationSelection.js +83 -0
  221. package/dist/cjs/stateManagement/annotation/annotationSelection.js.map +1 -0
  222. package/dist/cjs/stateManagement/annotation/annotationState.d.ts +9 -0
  223. package/dist/cjs/stateManagement/annotation/annotationState.js +62 -0
  224. package/dist/cjs/stateManagement/annotation/annotationState.js.map +1 -0
  225. package/dist/cjs/stateManagement/annotation/config/annotationStyle.d.ts +5 -0
  226. package/dist/cjs/stateManagement/annotation/config/annotationStyle.js +74 -0
  227. package/dist/cjs/stateManagement/annotation/config/annotationStyle.js.map +1 -0
  228. package/dist/cjs/stateManagement/annotation/config/getFont.d.ts +4 -0
  229. package/dist/cjs/stateManagement/annotation/config/getFont.js +12 -0
  230. package/dist/cjs/stateManagement/annotation/config/getFont.js.map +1 -0
  231. package/dist/cjs/stateManagement/annotation/config/getState.d.ts +4 -0
  232. package/dist/cjs/stateManagement/annotation/config/getState.js +18 -0
  233. package/dist/cjs/stateManagement/annotation/config/getState.js.map +1 -0
  234. package/dist/cjs/stateManagement/annotation/config/getStyle.d.ts +2 -0
  235. package/dist/cjs/stateManagement/annotation/config/getStyle.js +22 -0
  236. package/dist/cjs/stateManagement/annotation/config/getStyle.js.map +1 -0
  237. package/dist/cjs/stateManagement/annotation/config/index.d.ts +7 -0
  238. package/dist/cjs/stateManagement/annotation/config/index.js +19 -0
  239. package/dist/cjs/stateManagement/annotation/config/index.js.map +1 -0
  240. package/dist/cjs/stateManagement/annotation/config/setAnnotationStyle.d.ts +2 -0
  241. package/dist/cjs/stateManagement/annotation/config/setAnnotationStyle.js +17 -0
  242. package/dist/cjs/stateManagement/annotation/config/setAnnotationStyle.js.map +1 -0
  243. package/dist/cjs/stateManagement/annotation/config/setGlobalStyle.d.ts +1 -0
  244. package/dist/cjs/stateManagement/annotation/config/setGlobalStyle.js +8 -0
  245. package/dist/cjs/stateManagement/annotation/config/setGlobalStyle.js.map +1 -0
  246. package/dist/cjs/stateManagement/annotation/config/setToolStyle.d.ts +1 -0
  247. package/dist/cjs/stateManagement/annotation/config/setToolStyle.js +17 -0
  248. package/dist/cjs/stateManagement/annotation/config/setToolStyle.js.map +1 -0
  249. package/dist/cjs/stateManagement/annotation/index.d.ts +5 -0
  250. package/dist/cjs/stateManagement/annotation/index.js +31 -0
  251. package/dist/cjs/stateManagement/annotation/index.js.map +1 -0
  252. package/dist/cjs/stateManagement/index.d.ts +16 -0
  253. package/dist/cjs/stateManagement/index.js +49 -0
  254. package/dist/cjs/stateManagement/index.js.map +1 -0
  255. package/dist/cjs/stateManagement/segmentation/SegmentationStateManager.d.ts +29 -0
  256. package/dist/cjs/stateManagement/segmentation/SegmentationStateManager.js +198 -0
  257. package/dist/cjs/stateManagement/segmentation/SegmentationStateManager.js.map +1 -0
  258. package/dist/cjs/stateManagement/segmentation/activeSegmentation.d.ts +12 -0
  259. package/dist/cjs/stateManagement/segmentation/activeSegmentation.js +26 -0
  260. package/dist/cjs/stateManagement/segmentation/activeSegmentation.js.map +1 -0
  261. package/dist/cjs/stateManagement/segmentation/addSegmentationsForToolGroup.d.ts +3 -0
  262. package/dist/cjs/stateManagement/segmentation/addSegmentationsForToolGroup.js +59 -0
  263. package/dist/cjs/stateManagement/segmentation/addSegmentationsForToolGroup.js.map +1 -0
  264. package/dist/cjs/stateManagement/segmentation/createNewSegmentationForToolGroup.d.ts +14 -0
  265. package/dist/cjs/stateManagement/segmentation/createNewSegmentationForToolGroup.js +47 -0
  266. package/dist/cjs/stateManagement/segmentation/createNewSegmentationForToolGroup.js.map +1 -0
  267. package/dist/cjs/stateManagement/segmentation/helpers/COLOR_LUT.d.ts +2 -0
  268. package/dist/cjs/stateManagement/segmentation/helpers/COLOR_LUT.js +261 -0
  269. package/dist/cjs/stateManagement/segmentation/helpers/COLOR_LUT.js.map +1 -0
  270. package/dist/cjs/stateManagement/segmentation/helpers/checkSegmentationDataIsValid.d.ts +3 -0
  271. package/dist/cjs/stateManagement/segmentation/helpers/checkSegmentationDataIsValid.js +14 -0
  272. package/dist/cjs/stateManagement/segmentation/helpers/checkSegmentationDataIsValid.js.map +1 -0
  273. package/dist/cjs/stateManagement/segmentation/helpers/index.d.ts +4 -0
  274. package/dist/cjs/stateManagement/segmentation/helpers/index.js +13 -0
  275. package/dist/cjs/stateManagement/segmentation/helpers/index.js.map +1 -0
  276. package/dist/cjs/stateManagement/segmentation/helpers/internalAddSegmentationToElement.d.ts +3 -0
  277. package/dist/cjs/stateManagement/segmentation/helpers/internalAddSegmentationToElement.js +43 -0
  278. package/dist/cjs/stateManagement/segmentation/helpers/internalAddSegmentationToElement.js.map +1 -0
  279. package/dist/cjs/stateManagement/segmentation/helpers/internalRemoveSegmentationFromElement.d.ts +3 -0
  280. package/dist/cjs/stateManagement/segmentation/helpers/internalRemoveSegmentationFromElement.js +23 -0
  281. package/dist/cjs/stateManagement/segmentation/helpers/internalRemoveSegmentationFromElement.js.map +1 -0
  282. package/dist/cjs/stateManagement/segmentation/index.d.ts +12 -0
  283. package/dist/cjs/stateManagement/segmentation/index.js +48 -0
  284. package/dist/cjs/stateManagement/segmentation/index.js.map +1 -0
  285. package/dist/cjs/stateManagement/segmentation/removeSegmentationsFromToolGroup.d.ts +2 -0
  286. package/dist/cjs/stateManagement/segmentation/removeSegmentationsFromToolGroup.js +37 -0
  287. package/dist/cjs/stateManagement/segmentation/removeSegmentationsFromToolGroup.js.map +1 -0
  288. package/dist/cjs/stateManagement/segmentation/segmentIndex.d.ts +12 -0
  289. package/dist/cjs/stateManagement/segmentation/segmentIndex.js +53 -0
  290. package/dist/cjs/stateManagement/segmentation/segmentIndex.js.map +1 -0
  291. package/dist/cjs/stateManagement/segmentation/segmentLocking.d.ts +14 -0
  292. package/dist/cjs/stateManagement/segmentation/segmentLocking.js +75 -0
  293. package/dist/cjs/stateManagement/segmentation/segmentLocking.js.map +1 -0
  294. package/dist/cjs/stateManagement/segmentation/segmentationColor.d.ts +10 -0
  295. package/dist/cjs/stateManagement/segmentation/segmentationColor.js +47 -0
  296. package/dist/cjs/stateManagement/segmentation/segmentationColor.js.map +1 -0
  297. package/dist/cjs/stateManagement/segmentation/segmentationConfig.d.ts +26 -0
  298. package/dist/cjs/stateManagement/segmentation/segmentationConfig.js +88 -0
  299. package/dist/cjs/stateManagement/segmentation/segmentationConfig.js.map +1 -0
  300. package/dist/cjs/stateManagement/segmentation/segmentationState.d.ts +20 -0
  301. package/dist/cjs/stateManagement/segmentation/segmentationState.js +149 -0
  302. package/dist/cjs/stateManagement/segmentation/segmentationState.js.map +1 -0
  303. package/dist/cjs/stateManagement/segmentation/segmentationVisibility.d.ts +8 -0
  304. package/dist/cjs/stateManagement/segmentation/segmentationVisibility.js +29 -0
  305. package/dist/cjs/stateManagement/segmentation/segmentationVisibility.js.map +1 -0
  306. package/dist/cjs/stateManagement/segmentation/triggerSegmentationEvents.d.ts +4 -0
  307. package/dist/cjs/stateManagement/segmentation/triggerSegmentationEvents.js +43 -0
  308. package/dist/cjs/stateManagement/segmentation/triggerSegmentationEvents.js.map +1 -0
  309. package/dist/cjs/store/SynchronizerManager/Synchronizer.d.ts +30 -0
  310. package/dist/cjs/store/SynchronizerManager/Synchronizer.js +159 -0
  311. package/dist/cjs/store/SynchronizerManager/Synchronizer.js.map +1 -0
  312. package/dist/cjs/store/SynchronizerManager/createSynchronizer.d.ts +3 -0
  313. package/dist/cjs/store/SynchronizerManager/createSynchronizer.js +18 -0
  314. package/dist/cjs/store/SynchronizerManager/createSynchronizer.js.map +1 -0
  315. package/dist/cjs/store/SynchronizerManager/destroy.d.ts +2 -0
  316. package/dist/cjs/store/SynchronizerManager/destroy.js +11 -0
  317. package/dist/cjs/store/SynchronizerManager/destroy.js.map +1 -0
  318. package/dist/cjs/store/SynchronizerManager/destroySynchronizerById.d.ts +2 -0
  319. package/dist/cjs/store/SynchronizerManager/destroySynchronizerById.js +13 -0
  320. package/dist/cjs/store/SynchronizerManager/destroySynchronizerById.js.map +1 -0
  321. package/dist/cjs/store/SynchronizerManager/getAllSynchronizers.d.ts +3 -0
  322. package/dist/cjs/store/SynchronizerManager/getAllSynchronizers.js +8 -0
  323. package/dist/cjs/store/SynchronizerManager/getAllSynchronizers.js.map +1 -0
  324. package/dist/cjs/store/SynchronizerManager/getSynchronizerById.d.ts +3 -0
  325. package/dist/cjs/store/SynchronizerManager/getSynchronizerById.js +8 -0
  326. package/dist/cjs/store/SynchronizerManager/getSynchronizerById.js.map +1 -0
  327. package/dist/cjs/store/SynchronizerManager/getSynchronizers.d.ts +3 -0
  328. package/dist/cjs/store/SynchronizerManager/getSynchronizers.js +20 -0
  329. package/dist/cjs/store/SynchronizerManager/getSynchronizers.js.map +1 -0
  330. package/dist/cjs/store/SynchronizerManager/index.d.ts +7 -0
  331. package/dist/cjs/store/SynchronizerManager/index.js +19 -0
  332. package/dist/cjs/store/SynchronizerManager/index.js.map +1 -0
  333. package/dist/cjs/store/ToolGroupManager/ToolGroup.d.ts +22 -0
  334. package/dist/cjs/store/ToolGroupManager/ToolGroup.js +196 -0
  335. package/dist/cjs/store/ToolGroupManager/ToolGroup.js.map +1 -0
  336. package/dist/cjs/store/ToolGroupManager/createToolGroup.d.ts +3 -0
  337. package/dist/cjs/store/ToolGroupManager/createToolGroup.js +19 -0
  338. package/dist/cjs/store/ToolGroupManager/createToolGroup.js.map +1 -0
  339. package/dist/cjs/store/ToolGroupManager/destroy.d.ts +2 -0
  340. package/dist/cjs/store/ToolGroupManager/destroy.js +16 -0
  341. package/dist/cjs/store/ToolGroupManager/destroy.js.map +1 -0
  342. package/dist/cjs/store/ToolGroupManager/destroyToolGroupByToolGroupUID.d.ts +2 -0
  343. package/dist/cjs/store/ToolGroupManager/destroyToolGroupByToolGroupUID.js +13 -0
  344. package/dist/cjs/store/ToolGroupManager/destroyToolGroupByToolGroupUID.js.map +1 -0
  345. package/dist/cjs/store/ToolGroupManager/getAllToolGroups.d.ts +3 -0
  346. package/dist/cjs/store/ToolGroupManager/getAllToolGroups.js +8 -0
  347. package/dist/cjs/store/ToolGroupManager/getAllToolGroups.js.map +1 -0
  348. package/dist/cjs/store/ToolGroupManager/getToolGroup.d.ts +3 -0
  349. package/dist/cjs/store/ToolGroupManager/getToolGroup.js +17 -0
  350. package/dist/cjs/store/ToolGroupManager/getToolGroup.js.map +1 -0
  351. package/dist/cjs/store/ToolGroupManager/getToolGroupByToolGroupUID.d.ts +3 -0
  352. package/dist/cjs/store/ToolGroupManager/getToolGroupByToolGroupUID.js +8 -0
  353. package/dist/cjs/store/ToolGroupManager/getToolGroupByToolGroupUID.js.map +1 -0
  354. package/dist/cjs/store/ToolGroupManager/index.d.ts +16 -0
  355. package/dist/cjs/store/ToolGroupManager/index.js +27 -0
  356. package/dist/cjs/store/ToolGroupManager/index.js.map +1 -0
  357. package/dist/cjs/store/addEnabledElement.d.ts +2 -0
  358. package/dist/cjs/store/addEnabledElement.js +73 -0
  359. package/dist/cjs/store/addEnabledElement.js.map +1 -0
  360. package/dist/cjs/store/addTool.d.ts +3 -0
  361. package/dist/cjs/store/addTool.js +33 -0
  362. package/dist/cjs/store/addTool.js.map +1 -0
  363. package/dist/cjs/store/cancelActiveManipulations.d.ts +1 -0
  364. package/dist/cjs/store/cancelActiveManipulations.js +23 -0
  365. package/dist/cjs/store/cancelActiveManipulations.js.map +1 -0
  366. package/dist/cjs/store/filterMoveableAnnotationTools.d.ts +3 -0
  367. package/dist/cjs/store/filterMoveableAnnotationTools.js +24 -0
  368. package/dist/cjs/store/filterMoveableAnnotationTools.js.map +1 -0
  369. package/dist/cjs/store/filterToolsWithAnnotationsForElement.d.ts +3 -0
  370. package/dist/cjs/store/filterToolsWithAnnotationsForElement.js +26 -0
  371. package/dist/cjs/store/filterToolsWithAnnotationsForElement.js.map +1 -0
  372. package/dist/cjs/store/filterToolsWithMoveableHandles.d.ts +3 -0
  373. package/dist/cjs/store/filterToolsWithMoveableHandles.js +25 -0
  374. package/dist/cjs/store/filterToolsWithMoveableHandles.js.map +1 -0
  375. package/dist/cjs/store/index.d.ts +10 -0
  376. package/dist/cjs/store/index.js +45 -0
  377. package/dist/cjs/store/index.js.map +1 -0
  378. package/dist/cjs/store/removeEnabledElement.d.ts +3 -0
  379. package/dist/cjs/store/removeEnabledElement.js +78 -0
  380. package/dist/cjs/store/removeEnabledElement.js.map +1 -0
  381. package/dist/cjs/store/state.d.ts +19 -0
  382. package/dist/cjs/store/state.js +55 -0
  383. package/dist/cjs/store/state.js.map +1 -0
  384. package/dist/cjs/store/svgNodeCache.d.ts +3 -0
  385. package/dist/cjs/store/svgNodeCache.js +10 -0
  386. package/dist/cjs/store/svgNodeCache.js.map +1 -0
  387. package/dist/cjs/synchronizers/callbacks/cameraSyncCallback.d.ts +2 -0
  388. package/dist/cjs/synchronizers/callbacks/cameraSyncCallback.js +19 -0
  389. package/dist/cjs/synchronizers/callbacks/cameraSyncCallback.js.map +1 -0
  390. package/dist/cjs/synchronizers/callbacks/voiSyncCallback.d.ts +2 -0
  391. package/dist/cjs/synchronizers/callbacks/voiSyncCallback.js +32 -0
  392. package/dist/cjs/synchronizers/callbacks/voiSyncCallback.js.map +1 -0
  393. package/dist/cjs/synchronizers/index.d.ts +3 -0
  394. package/dist/cjs/synchronizers/index.js +11 -0
  395. package/dist/cjs/synchronizers/index.js.map +1 -0
  396. package/dist/cjs/synchronizers/synchronizers/createCameraPositionSynchronizer.d.ts +2 -0
  397. package/dist/cjs/synchronizers/synchronizers/createCameraPositionSynchronizer.js +15 -0
  398. package/dist/cjs/synchronizers/synchronizers/createCameraPositionSynchronizer.js.map +1 -0
  399. package/dist/cjs/synchronizers/synchronizers/createVOISynchronizer.d.ts +2 -0
  400. package/dist/cjs/synchronizers/synchronizers/createVOISynchronizer.js +14 -0
  401. package/dist/cjs/synchronizers/synchronizers/createVOISynchronizer.js.map +1 -0
  402. package/dist/cjs/synchronizers/synchronizers/index.d.ts +3 -0
  403. package/dist/cjs/synchronizers/synchronizers/index.js +11 -0
  404. package/dist/cjs/synchronizers/synchronizers/index.js.map +1 -0
  405. package/dist/cjs/tools/CrosshairsTool.d.ts +63 -0
  406. package/dist/cjs/tools/CrosshairsTool.js +1280 -0
  407. package/dist/cjs/tools/CrosshairsTool.js.map +1 -0
  408. package/dist/cjs/tools/MIPJumpToClickTool.d.ts +8 -0
  409. package/dist/cjs/tools/MIPJumpToClickTool.js +49 -0
  410. package/dist/cjs/tools/MIPJumpToClickTool.js.map +1 -0
  411. package/dist/cjs/tools/PanTool.d.ts +9 -0
  412. package/dist/cjs/tools/PanTool.js +38 -0
  413. package/dist/cjs/tools/PanTool.js.map +1 -0
  414. package/dist/cjs/tools/StackScrollTool.d.ts +9 -0
  415. package/dist/cjs/tools/StackScrollTool.js +28 -0
  416. package/dist/cjs/tools/StackScrollTool.js.map +1 -0
  417. package/dist/cjs/tools/StackScrollToolMouseWheelTool.d.ts +11 -0
  418. package/dist/cjs/tools/StackScrollToolMouseWheelTool.js +21 -0
  419. package/dist/cjs/tools/StackScrollToolMouseWheelTool.js.map +1 -0
  420. package/dist/cjs/tools/VolumeRotateMouseWheelTool.d.ts +9 -0
  421. package/dist/cjs/tools/VolumeRotateMouseWheelTool.js +55 -0
  422. package/dist/cjs/tools/VolumeRotateMouseWheelTool.js.map +1 -0
  423. package/dist/cjs/tools/WindowLevelTool.d.ts +31 -0
  424. package/dist/cjs/tools/WindowLevelTool.js +138 -0
  425. package/dist/cjs/tools/WindowLevelTool.js.map +1 -0
  426. package/dist/cjs/tools/ZoomTool.d.ts +11 -0
  427. package/dist/cjs/tools/ZoomTool.js +66 -0
  428. package/dist/cjs/tools/ZoomTool.js.map +1 -0
  429. package/dist/cjs/tools/annotation/BidirectionalTool.d.ts +67 -0
  430. package/dist/cjs/tools/annotation/BidirectionalTool.js +681 -0
  431. package/dist/cjs/tools/annotation/BidirectionalTool.js.map +1 -0
  432. package/dist/cjs/tools/annotation/EllipticalRoiTool.d.ts +71 -0
  433. package/dist/cjs/tools/annotation/EllipticalRoiTool.js +633 -0
  434. package/dist/cjs/tools/annotation/EllipticalRoiTool.js.map +1 -0
  435. package/dist/cjs/tools/annotation/LengthTool.d.ts +61 -0
  436. package/dist/cjs/tools/annotation/LengthTool.js +397 -0
  437. package/dist/cjs/tools/annotation/LengthTool.js.map +1 -0
  438. package/dist/cjs/tools/annotation/ProbeTool.d.ts +49 -0
  439. package/dist/cjs/tools/annotation/ProbeTool.js +337 -0
  440. package/dist/cjs/tools/annotation/ProbeTool.js.map +1 -0
  441. package/dist/cjs/tools/annotation/RectangleRoiTool.d.ts +72 -0
  442. package/dist/cjs/tools/annotation/RectangleRoiTool.js +538 -0
  443. package/dist/cjs/tools/annotation/RectangleRoiTool.js.map +1 -0
  444. package/dist/cjs/tools/base/AnnotationTool.d.ts +21 -0
  445. package/dist/cjs/tools/base/AnnotationTool.js +149 -0
  446. package/dist/cjs/tools/base/AnnotationTool.js.map +1 -0
  447. package/dist/cjs/tools/base/BaseTool.d.ts +34 -0
  448. package/dist/cjs/tools/base/BaseTool.js +77 -0
  449. package/dist/cjs/tools/base/BaseTool.js.map +1 -0
  450. package/dist/cjs/tools/base/index.d.ts +3 -0
  451. package/dist/cjs/tools/base/index.js +11 -0
  452. package/dist/cjs/tools/base/index.js.map +1 -0
  453. package/dist/cjs/tools/displayTools/Labelmap/LabelmapConfig.d.ts +13 -0
  454. package/dist/cjs/tools/displayTools/Labelmap/LabelmapConfig.js +28 -0
  455. package/dist/cjs/tools/displayTools/Labelmap/LabelmapConfig.js.map +1 -0
  456. package/dist/cjs/tools/displayTools/Labelmap/LabelmapDisplay.d.ts +11 -0
  457. package/dist/cjs/tools/displayTools/Labelmap/LabelmapDisplay.js +184 -0
  458. package/dist/cjs/tools/displayTools/Labelmap/LabelmapDisplay.js.map +1 -0
  459. package/dist/cjs/tools/displayTools/Labelmap/index.d.ts +3 -0
  460. package/dist/cjs/tools/displayTools/Labelmap/index.js +11 -0
  461. package/dist/cjs/tools/displayTools/Labelmap/index.js.map +1 -0
  462. package/dist/cjs/tools/displayTools/SegmentationDisplayTool.d.ts +11 -0
  463. package/dist/cjs/tools/displayTools/SegmentationDisplayTool.js +80 -0
  464. package/dist/cjs/tools/displayTools/SegmentationDisplayTool.js.map +1 -0
  465. package/dist/cjs/tools/index.d.ts +21 -0
  466. package/dist/cjs/tools/index.js +48 -0
  467. package/dist/cjs/tools/index.js.map +1 -0
  468. package/dist/cjs/tools/segmentation/CircleScissorsTool.d.ts +29 -0
  469. package/dist/cjs/tools/segmentation/CircleScissorsTool.js +198 -0
  470. package/dist/cjs/tools/segmentation/CircleScissorsTool.js.map +1 -0
  471. package/dist/cjs/tools/segmentation/RectangleRoiStartEndThresholdTool.d.ts +82 -0
  472. package/dist/cjs/tools/segmentation/RectangleRoiStartEndThresholdTool.js +240 -0
  473. package/dist/cjs/tools/segmentation/RectangleRoiStartEndThresholdTool.js.map +1 -0
  474. package/dist/cjs/tools/segmentation/RectangleRoiThresholdTool.d.ts +65 -0
  475. package/dist/cjs/tools/segmentation/RectangleRoiThresholdTool.js +150 -0
  476. package/dist/cjs/tools/segmentation/RectangleRoiThresholdTool.js.map +1 -0
  477. package/dist/cjs/tools/segmentation/RectangleScissorsTool.d.ts +29 -0
  478. package/dist/cjs/tools/segmentation/RectangleScissorsTool.js +209 -0
  479. package/dist/cjs/tools/segmentation/RectangleScissorsTool.js.map +1 -0
  480. package/dist/cjs/tools/segmentation/SphereScissorsTool.d.ts +30 -0
  481. package/dist/cjs/tools/segmentation/SphereScissorsTool.js +199 -0
  482. package/dist/cjs/tools/segmentation/SphereScissorsTool.js.map +1 -0
  483. package/dist/cjs/tools/segmentation/strategies/eraseRectangle.d.ts +13 -0
  484. package/dist/cjs/tools/segmentation/strategies/eraseRectangle.js +39 -0
  485. package/dist/cjs/tools/segmentation/strategies/eraseRectangle.js.map +1 -0
  486. package/dist/cjs/tools/segmentation/strategies/fillCircle.d.ts +15 -0
  487. package/dist/cjs/tools/segmentation/strategies/fillCircle.js +57 -0
  488. package/dist/cjs/tools/segmentation/strategies/fillCircle.js.map +1 -0
  489. package/dist/cjs/tools/segmentation/strategies/fillRectangle.d.ts +14 -0
  490. package/dist/cjs/tools/segmentation/strategies/fillRectangle.js +50 -0
  491. package/dist/cjs/tools/segmentation/strategies/fillRectangle.js.map +1 -0
  492. package/dist/cjs/tools/segmentation/strategies/fillSphere.d.ts +15 -0
  493. package/dist/cjs/tools/segmentation/strategies/fillSphere.js +27 -0
  494. package/dist/cjs/tools/segmentation/strategies/fillSphere.js.map +1 -0
  495. package/dist/cjs/tools/segmentation/strategies/index.d.ts +3 -0
  496. package/dist/cjs/tools/segmentation/strategies/index.js +10 -0
  497. package/dist/cjs/tools/segmentation/strategies/index.js.map +1 -0
  498. package/dist/cjs/types/AnnotationTypes.d.ts +43 -0
  499. package/dist/cjs/types/AnnotationTypes.js +3 -0
  500. package/dist/cjs/types/AnnotationTypes.js.map +1 -0
  501. package/dist/cjs/types/CursorTypes.d.ts +11 -0
  502. package/dist/cjs/types/CursorTypes.js +3 -0
  503. package/dist/cjs/types/CursorTypes.js.map +1 -0
  504. package/dist/cjs/types/EventTypes.d.ts +140 -0
  505. package/dist/cjs/types/EventTypes.js +3 -0
  506. package/dist/cjs/types/EventTypes.js.map +1 -0
  507. package/dist/cjs/types/IPoints.d.ts +8 -0
  508. package/dist/cjs/types/IPoints.js +3 -0
  509. package/dist/cjs/types/IPoints.js.map +1 -0
  510. package/dist/cjs/types/ISetToolModeOptions.d.ts +15 -0
  511. package/dist/cjs/types/ISetToolModeOptions.js +3 -0
  512. package/dist/cjs/types/ISetToolModeOptions.js.map +1 -0
  513. package/dist/cjs/types/IToolGroup.d.ts +42 -0
  514. package/dist/cjs/types/IToolGroup.js +3 -0
  515. package/dist/cjs/types/IToolGroup.js.map +1 -0
  516. package/dist/cjs/types/InteractionTypes.d.ts +2 -0
  517. package/dist/cjs/types/InteractionTypes.js +3 -0
  518. package/dist/cjs/types/InteractionTypes.js.map +1 -0
  519. package/dist/cjs/types/InternalToolTypes.d.ts +15 -0
  520. package/dist/cjs/types/InternalToolTypes.js +3 -0
  521. package/dist/cjs/types/InternalToolTypes.js.map +1 -0
  522. package/dist/cjs/types/PlanarBoundingBox.d.ts +7 -0
  523. package/dist/cjs/types/PlanarBoundingBox.js +3 -0
  524. package/dist/cjs/types/PlanarBoundingBox.js.map +1 -0
  525. package/dist/cjs/types/SegmentationRepresentationTypes.d.ts +11 -0
  526. package/dist/cjs/types/SegmentationRepresentationTypes.js +3 -0
  527. package/dist/cjs/types/SegmentationRepresentationTypes.js.map +1 -0
  528. package/dist/cjs/types/SegmentationStateTypes.d.ts +51 -0
  529. package/dist/cjs/types/SegmentationStateTypes.js +3 -0
  530. package/dist/cjs/types/SegmentationStateTypes.js.map +1 -0
  531. package/dist/cjs/types/ToolHandle.d.ts +15 -0
  532. package/dist/cjs/types/ToolHandle.js +3 -0
  533. package/dist/cjs/types/ToolHandle.js.map +1 -0
  534. package/dist/cjs/types/ToolProps.d.ts +9 -0
  535. package/dist/cjs/types/ToolProps.js +3 -0
  536. package/dist/cjs/types/ToolProps.js.map +1 -0
  537. package/dist/cjs/types/index.d.ts +14 -0
  538. package/dist/cjs/types/index.js +3 -0
  539. package/dist/cjs/types/index.js.map +1 -0
  540. package/dist/cjs/utilities/calibrateImageSpacing.d.ts +2 -0
  541. package/dist/cjs/utilities/calibrateImageSpacing.js +22 -0
  542. package/dist/cjs/utilities/calibrateImageSpacing.js.map +1 -0
  543. package/dist/cjs/utilities/clip.d.ts +3 -0
  544. package/dist/cjs/utilities/clip.js +14 -0
  545. package/dist/cjs/utilities/clip.js.map +1 -0
  546. package/dist/cjs/utilities/debounce.d.ts +6 -0
  547. package/dist/cjs/utilities/debounce.js +119 -0
  548. package/dist/cjs/utilities/debounce.js.map +1 -0
  549. package/dist/cjs/utilities/deepMerge.d.ts +2 -0
  550. package/dist/cjs/utilities/deepMerge.js +63 -0
  551. package/dist/cjs/utilities/deepMerge.js.map +1 -0
  552. package/dist/cjs/utilities/drawing/getTextBoxCoordsCanvas.d.ts +2 -0
  553. package/dist/cjs/utilities/drawing/getTextBoxCoordsCanvas.js +28 -0
  554. package/dist/cjs/utilities/drawing/getTextBoxCoordsCanvas.js.map +1 -0
  555. package/dist/cjs/utilities/drawing/index.d.ts +6 -0
  556. package/dist/cjs/utilities/drawing/index.js +10 -0
  557. package/dist/cjs/utilities/drawing/index.js.map +1 -0
  558. package/dist/cjs/utilities/getAnnotationNearPoint.d.ts +5 -0
  559. package/dist/cjs/utilities/getAnnotationNearPoint.js +47 -0
  560. package/dist/cjs/utilities/getAnnotationNearPoint.js.map +1 -0
  561. package/dist/cjs/utilities/getToolsWithModesForElement.d.ts +4 -0
  562. package/dist/cjs/utilities/getToolsWithModesForElement.js +28 -0
  563. package/dist/cjs/utilities/getToolsWithModesForElement.js.map +1 -0
  564. package/dist/cjs/utilities/index.d.ts +39 -0
  565. package/dist/cjs/utilities/index.js +81 -0
  566. package/dist/cjs/utilities/index.js.map +1 -0
  567. package/dist/cjs/utilities/isObject.d.ts +2 -0
  568. package/dist/cjs/utilities/isObject.js +8 -0
  569. package/dist/cjs/utilities/isObject.js.map +1 -0
  570. package/dist/cjs/utilities/math/ellipse/getCanvasEllipseCorners.d.ts +9 -0
  571. package/dist/cjs/utilities/math/ellipse/getCanvasEllipseCorners.js +10 -0
  572. package/dist/cjs/utilities/math/ellipse/getCanvasEllipseCorners.js.map +1 -0
  573. package/dist/cjs/utilities/math/ellipse/index.d.ts +8 -0
  574. package/dist/cjs/utilities/math/ellipse/index.js +12 -0
  575. package/dist/cjs/utilities/math/ellipse/index.js.map +1 -0
  576. package/dist/cjs/utilities/math/ellipse/pointInEllipse.d.ts +9 -0
  577. package/dist/cjs/utilities/math/ellipse/pointInEllipse.js +20 -0
  578. package/dist/cjs/utilities/math/ellipse/pointInEllipse.js.map +1 -0
  579. package/dist/cjs/utilities/math/ellipse/pointInEllipsoidWithConstraint.d.ts +9 -0
  580. package/dist/cjs/utilities/math/ellipse/pointInEllipsoidWithConstraint.js +6 -0
  581. package/dist/cjs/utilities/math/ellipse/pointInEllipsoidWithConstraint.js.map +1 -0
  582. package/dist/cjs/utilities/math/index.d.ts +24 -0
  583. package/dist/cjs/utilities/math/index.js +16 -0
  584. package/dist/cjs/utilities/math/index.js.map +1 -0
  585. package/dist/cjs/utilities/math/line/distanceToPoint.d.ts +2 -0
  586. package/dist/cjs/utilities/math/line/distanceToPoint.js +14 -0
  587. package/dist/cjs/utilities/math/line/distanceToPoint.js.map +1 -0
  588. package/dist/cjs/utilities/math/line/distanceToPointSquared.d.ts +2 -0
  589. package/dist/cjs/utilities/math/line/distanceToPointSquared.js +27 -0
  590. package/dist/cjs/utilities/math/line/distanceToPointSquared.js.map +1 -0
  591. package/dist/cjs/utilities/math/line/index.d.ts +9 -0
  592. package/dist/cjs/utilities/math/line/index.js +15 -0
  593. package/dist/cjs/utilities/math/line/index.js.map +1 -0
  594. package/dist/cjs/utilities/math/line/intersectLine.d.ts +2 -0
  595. package/dist/cjs/utilities/math/line/intersectLine.js +45 -0
  596. package/dist/cjs/utilities/math/line/intersectLine.js.map +1 -0
  597. package/dist/cjs/utilities/math/rectangle/distanceToPoint.d.ts +2 -0
  598. package/dist/cjs/utilities/math/rectangle/distanceToPoint.js +41 -0
  599. package/dist/cjs/utilities/math/rectangle/distanceToPoint.js.map +1 -0
  600. package/dist/cjs/utilities/math/rectangle/index.d.ts +5 -0
  601. package/dist/cjs/utilities/math/rectangle/index.js +11 -0
  602. package/dist/cjs/utilities/math/rectangle/index.js.map +1 -0
  603. package/dist/cjs/utilities/math/sphere/index.d.ts +2 -0
  604. package/dist/cjs/utilities/math/sphere/index.js +9 -0
  605. package/dist/cjs/utilities/math/sphere/index.js.map +1 -0
  606. package/dist/cjs/utilities/math/sphere/pointInSphere.d.ts +8 -0
  607. package/dist/cjs/utilities/math/sphere/pointInSphere.js +10 -0
  608. package/dist/cjs/utilities/math/sphere/pointInSphere.js.map +1 -0
  609. package/dist/cjs/utilities/math/vec2/findClosestPoint.d.ts +2 -0
  610. package/dist/cjs/utilities/math/vec2/findClosestPoint.js +21 -0
  611. package/dist/cjs/utilities/math/vec2/findClosestPoint.js.map +1 -0
  612. package/dist/cjs/utilities/math/vec2/index.d.ts +7 -0
  613. package/dist/cjs/utilities/math/vec2/index.js +9 -0
  614. package/dist/cjs/utilities/math/vec2/index.js.map +1 -0
  615. package/dist/cjs/utilities/math/vec2/liangBarksyClip.d.ts +1 -0
  616. package/dist/cjs/utilities/math/vec2/liangBarksyClip.js +67 -0
  617. package/dist/cjs/utilities/math/vec2/liangBarksyClip.js.map +1 -0
  618. package/dist/cjs/utilities/planar/filterAnnotationsForDisplay.d.ts +3 -0
  619. package/dist/cjs/utilities/planar/filterAnnotationsForDisplay.js +27 -0
  620. package/dist/cjs/utilities/planar/filterAnnotationsForDisplay.js.map +1 -0
  621. package/dist/cjs/utilities/planar/filterAnnotationsWithinSlice.d.ts +3 -0
  622. package/dist/cjs/utilities/planar/filterAnnotationsWithinSlice.js +30 -0
  623. package/dist/cjs/utilities/planar/filterAnnotationsWithinSlice.js.map +1 -0
  624. package/dist/cjs/utilities/planar/getPointInLineOfSightWithCriteria.d.ts +2 -0
  625. package/dist/cjs/utilities/planar/getPointInLineOfSightWithCriteria.js +45 -0
  626. package/dist/cjs/utilities/planar/getPointInLineOfSightWithCriteria.js.map +1 -0
  627. package/dist/cjs/utilities/planar/getWorldWidthAndHeightFromCorners.d.ts +5 -0
  628. package/dist/cjs/utilities/planar/getWorldWidthAndHeightFromCorners.js +23 -0
  629. package/dist/cjs/utilities/planar/getWorldWidthAndHeightFromCorners.js.map +1 -0
  630. package/dist/cjs/utilities/planar/getWorldWidthAndHeightFromTwoPoints.d.ts +5 -0
  631. package/dist/cjs/utilities/planar/getWorldWidthAndHeightFromTwoPoints.js +23 -0
  632. package/dist/cjs/utilities/planar/getWorldWidthAndHeightFromTwoPoints.js.map +1 -0
  633. package/dist/cjs/utilities/planar/index.d.ts +12 -0
  634. package/dist/cjs/utilities/planar/index.js +21 -0
  635. package/dist/cjs/utilities/planar/index.js.map +1 -0
  636. package/dist/cjs/utilities/pointInShapeCallback.d.ts +12 -0
  637. package/dist/cjs/utilities/pointInShapeCallback.js +74 -0
  638. package/dist/cjs/utilities/pointInShapeCallback.js.map +1 -0
  639. package/dist/cjs/utilities/pointInSurroundingSphereCallback.d.ts +4 -0
  640. package/dist/cjs/utilities/pointInSurroundingSphereCallback.js +40 -0
  641. package/dist/cjs/utilities/pointInSurroundingSphereCallback.js.map +1 -0
  642. package/dist/cjs/utilities/segmentation/createMergedLabelmapForIndex.d.ts +3 -0
  643. package/dist/cjs/utilities/segmentation/createMergedLabelmapForIndex.js +37 -0
  644. package/dist/cjs/utilities/segmentation/createMergedLabelmapForIndex.js.map +1 -0
  645. package/dist/cjs/utilities/segmentation/getBoundingBoxUtils.d.ts +4 -0
  646. package/dist/cjs/utilities/segmentation/getBoundingBoxUtils.js +51 -0
  647. package/dist/cjs/utilities/segmentation/getBoundingBoxUtils.js.map +1 -0
  648. package/dist/cjs/utilities/segmentation/getDefaultRepresentationConfig.d.ts +1 -0
  649. package/dist/cjs/utilities/segmentation/getDefaultRepresentationConfig.js +17 -0
  650. package/dist/cjs/utilities/segmentation/getDefaultRepresentationConfig.js.map +1 -0
  651. package/dist/cjs/utilities/segmentation/index.d.ts +17 -0
  652. package/dist/cjs/utilities/segmentation/index.js +29 -0
  653. package/dist/cjs/utilities/segmentation/index.js.map +1 -0
  654. package/dist/cjs/utilities/segmentation/isValidRepresentationConfig.d.ts +2 -0
  655. package/dist/cjs/utilities/segmentation/isValidRepresentationConfig.js +17 -0
  656. package/dist/cjs/utilities/segmentation/isValidRepresentationConfig.js.map +1 -0
  657. package/dist/cjs/utilities/segmentation/thresholdVolumeByRange.d.ts +24 -0
  658. package/dist/cjs/utilities/segmentation/thresholdVolumeByRange.js +86 -0
  659. package/dist/cjs/utilities/segmentation/thresholdVolumeByRange.js.map +1 -0
  660. package/dist/cjs/utilities/segmentation/thresholdVolumeByRoiStats.d.ts +11 -0
  661. package/dist/cjs/utilities/segmentation/thresholdVolumeByRoiStats.js +111 -0
  662. package/dist/cjs/utilities/segmentation/thresholdVolumeByRoiStats.js.map +1 -0
  663. package/dist/cjs/utilities/stackScrollTool/getSliceRange.d.ts +6 -0
  664. package/dist/cjs/utilities/stackScrollTool/getSliceRange.js +32 -0
  665. package/dist/cjs/utilities/stackScrollTool/getSliceRange.js.map +1 -0
  666. package/dist/cjs/utilities/stackScrollTool/index.d.ts +10 -0
  667. package/dist/cjs/utilities/stackScrollTool/index.js +18 -0
  668. package/dist/cjs/utilities/stackScrollTool/index.js.map +1 -0
  669. package/dist/cjs/utilities/stackScrollTool/scrollThroughStack.d.ts +2 -0
  670. package/dist/cjs/utilities/stackScrollTool/scrollThroughStack.js +47 -0
  671. package/dist/cjs/utilities/stackScrollTool/scrollThroughStack.js.map +1 -0
  672. package/dist/cjs/utilities/stackScrollTool/snapFocalPointToSlice.d.ts +5 -0
  673. package/dist/cjs/utilities/stackScrollTool/snapFocalPointToSlice.js +41 -0
  674. package/dist/cjs/utilities/stackScrollTool/snapFocalPointToSlice.js.map +1 -0
  675. package/dist/cjs/utilities/throttle.d.ts +5 -0
  676. package/dist/cjs/utilities/throttle.js +25 -0
  677. package/dist/cjs/utilities/throttle.js.map +1 -0
  678. package/dist/cjs/utilities/transformPhysicalToIndex.d.ts +1 -0
  679. package/dist/cjs/utilities/transformPhysicalToIndex.js +9 -0
  680. package/dist/cjs/utilities/transformPhysicalToIndex.js.map +1 -0
  681. package/dist/cjs/utilities/triggerAnnotationRender.d.ts +21 -0
  682. package/dist/cjs/utilities/triggerAnnotationRender.js +112 -0
  683. package/dist/cjs/utilities/triggerAnnotationRender.js.map +1 -0
  684. package/dist/cjs/utilities/triggerAnnotationRenderForViewportUIDs.d.ts +3 -0
  685. package/dist/cjs/utilities/triggerAnnotationRenderForViewportUIDs.js +19 -0
  686. package/dist/cjs/utilities/triggerAnnotationRenderForViewportUIDs.js.map +1 -0
  687. package/dist/cjs/utilities/triggerSegmentationRender.d.ts +17 -0
  688. package/dist/cjs/utilities/triggerSegmentationRender.js +96 -0
  689. package/dist/cjs/utilities/triggerSegmentationRender.js.map +1 -0
  690. package/dist/cjs/utilities/viewport/jumpToWorld.d.ts +2 -0
  691. package/dist/cjs/utilities/viewport/jumpToWorld.js +36 -0
  692. package/dist/cjs/utilities/viewport/jumpToWorld.js.map +1 -0
  693. package/dist/cjs/utilities/viewportFilters/filterViewportsWithFrameOfReferenceUID.d.ts +2 -0
  694. package/dist/cjs/utilities/viewportFilters/filterViewportsWithFrameOfReferenceUID.js +15 -0
  695. package/dist/cjs/utilities/viewportFilters/filterViewportsWithFrameOfReferenceUID.js.map +1 -0
  696. package/dist/cjs/utilities/viewportFilters/filterViewportsWithSameOrientation.d.ts +2 -0
  697. package/dist/cjs/utilities/viewportFilters/filterViewportsWithSameOrientation.js +14 -0
  698. package/dist/cjs/utilities/viewportFilters/filterViewportsWithSameOrientation.js.map +1 -0
  699. package/dist/cjs/utilities/viewportFilters/filterViewportsWithToolEnabled.d.ts +2 -0
  700. package/dist/cjs/utilities/viewportFilters/filterViewportsWithToolEnabled.js +29 -0
  701. package/dist/cjs/utilities/viewportFilters/filterViewportsWithToolEnabled.js.map +1 -0
  702. package/dist/cjs/utilities/viewportFilters/getViewportUIDsWithToolToRender.d.ts +1 -0
  703. package/dist/cjs/utilities/viewportFilters/getViewportUIDsWithToolToRender.js +24 -0
  704. package/dist/cjs/utilities/viewportFilters/getViewportUIDsWithToolToRender.js.map +1 -0
  705. package/dist/cjs/utilities/viewportFilters/index.d.ts +10 -0
  706. package/dist/cjs/utilities/viewportFilters/index.js +18 -0
  707. package/dist/cjs/utilities/viewportFilters/index.js.map +1 -0
  708. package/dist/esm/cursors/ImageMouseCursor.d.ts +9 -0
  709. package/dist/esm/cursors/ImageMouseCursor.js +23 -0
  710. package/dist/esm/cursors/ImageMouseCursor.js.map +1 -0
  711. package/dist/esm/cursors/MouseCursor.d.ts +12 -0
  712. package/dist/esm/cursors/MouseCursor.js +89 -0
  713. package/dist/esm/cursors/MouseCursor.js.map +1 -0
  714. package/dist/esm/cursors/SVGCursorDescriptor.d.ts +8 -0
  715. package/dist/esm/cursors/SVGCursorDescriptor.js +399 -0
  716. package/dist/esm/cursors/SVGCursorDescriptor.js.map +1 -0
  717. package/dist/esm/cursors/SVGMouseCursor.d.ts +6 -0
  718. package/dist/esm/cursors/SVGMouseCursor.js +72 -0
  719. package/dist/esm/cursors/SVGMouseCursor.js.map +1 -0
  720. package/dist/esm/cursors/elementCursor.d.ts +6 -0
  721. package/dist/esm/cursors/elementCursor.js +37 -0
  722. package/dist/esm/cursors/elementCursor.js.map +1 -0
  723. package/dist/esm/cursors/index.d.ts +8 -0
  724. package/dist/esm/cursors/index.js +9 -0
  725. package/dist/esm/cursors/index.js.map +1 -0
  726. package/dist/esm/cursors/setCursorForElement.d.ts +2 -0
  727. package/dist/esm/cursors/setCursorForElement.js +16 -0
  728. package/dist/esm/cursors/setCursorForElement.js.map +1 -0
  729. package/dist/esm/drawingSvg/_getHash.d.ts +2 -0
  730. package/dist/esm/drawingSvg/_getHash.js +5 -0
  731. package/dist/esm/drawingSvg/_getHash.js.map +1 -0
  732. package/dist/esm/drawingSvg/_setAttributesIfNecessary.d.ts +2 -0
  733. package/dist/esm/drawingSvg/_setAttributesIfNecessary.js +14 -0
  734. package/dist/esm/drawingSvg/_setAttributesIfNecessary.js.map +1 -0
  735. package/dist/esm/drawingSvg/_setNewAttributesIfValid.d.ts +2 -0
  736. package/dist/esm/drawingSvg/_setNewAttributesIfValid.js +10 -0
  737. package/dist/esm/drawingSvg/_setNewAttributesIfValid.js.map +1 -0
  738. package/dist/esm/drawingSvg/clearByToolType.d.ts +2 -0
  739. package/dist/esm/drawingSvg/clearByToolType.js +14 -0
  740. package/dist/esm/drawingSvg/clearByToolType.js.map +1 -0
  741. package/dist/esm/drawingSvg/draw.d.ts +2 -0
  742. package/dist/esm/drawingSvg/draw.js +8 -0
  743. package/dist/esm/drawingSvg/draw.js.map +1 -0
  744. package/dist/esm/drawingSvg/drawCircle.d.ts +3 -0
  745. package/dist/esm/drawingSvg/drawCircle.js +34 -0
  746. package/dist/esm/drawingSvg/drawCircle.js.map +1 -0
  747. package/dist/esm/drawingSvg/drawEllipse.d.ts +3 -0
  748. package/dist/esm/drawingSvg/drawEllipse.js +43 -0
  749. package/dist/esm/drawingSvg/drawEllipse.js.map +1 -0
  750. package/dist/esm/drawingSvg/drawHandles.d.ts +3 -0
  751. package/dist/esm/drawingSvg/drawHandles.js +61 -0
  752. package/dist/esm/drawingSvg/drawHandles.js.map +1 -0
  753. package/dist/esm/drawingSvg/drawLine.d.ts +2 -0
  754. package/dist/esm/drawingSvg/drawLine.js +37 -0
  755. package/dist/esm/drawingSvg/drawLine.js.map +1 -0
  756. package/dist/esm/drawingSvg/drawLink.d.ts +4 -0
  757. package/dist/esm/drawingSvg/drawLink.js +27 -0
  758. package/dist/esm/drawingSvg/drawLink.js.map +1 -0
  759. package/dist/esm/drawingSvg/drawLinkedTextBox.d.ts +3 -0
  760. package/dist/esm/drawingSvg/drawLinkedTextBox.js +16 -0
  761. package/dist/esm/drawingSvg/drawLinkedTextBox.js.map +1 -0
  762. package/dist/esm/drawingSvg/drawRect.d.ts +2 -0
  763. package/dist/esm/drawingSvg/drawRect.js +38 -0
  764. package/dist/esm/drawingSvg/drawRect.js.map +1 -0
  765. package/dist/esm/drawingSvg/drawTextBox.d.ts +3 -0
  766. package/dist/esm/drawingSvg/drawTextBox.js +112 -0
  767. package/dist/esm/drawingSvg/drawTextBox.js.map +1 -0
  768. package/dist/esm/drawingSvg/getSvgDrawingHelper.d.ts +11 -0
  769. package/dist/esm/drawingSvg/getSvgDrawingHelper.js +66 -0
  770. package/dist/esm/drawingSvg/getSvgDrawingHelper.js.map +1 -0
  771. package/dist/esm/drawingSvg/index.d.ts +20 -0
  772. package/dist/esm/drawingSvg/index.js +20 -0
  773. package/dist/esm/drawingSvg/index.js.map +1 -0
  774. package/dist/esm/enums/AnnotationStyleStates.d.ts +7 -0
  775. package/dist/esm/enums/AnnotationStyleStates.js +9 -0
  776. package/dist/esm/enums/AnnotationStyleStates.js.map +1 -0
  777. package/dist/esm/enums/Events.d.ts +23 -0
  778. package/dist/esm/enums/Events.js +25 -0
  779. package/dist/esm/enums/Events.js.map +1 -0
  780. package/dist/esm/enums/SegmentationRepresentations.d.ts +4 -0
  781. package/dist/esm/enums/SegmentationRepresentations.js +6 -0
  782. package/dist/esm/enums/SegmentationRepresentations.js.map +1 -0
  783. package/dist/esm/enums/ToolBindings.d.ts +17 -0
  784. package/dist/esm/enums/ToolBindings.js +20 -0
  785. package/dist/esm/enums/ToolBindings.js.map +1 -0
  786. package/dist/esm/enums/ToolModes.d.ts +7 -0
  787. package/dist/esm/enums/ToolModes.js +9 -0
  788. package/dist/esm/enums/ToolModes.js.map +1 -0
  789. package/dist/esm/enums/index.d.ts +7 -0
  790. package/dist/esm/enums/index.js +7 -0
  791. package/dist/esm/enums/index.js.map +1 -0
  792. package/dist/esm/eventDispatchers/annotationModifiedEventDispatcher.d.ts +5 -0
  793. package/dist/esm/eventDispatchers/annotationModifiedEventDispatcher.js +19 -0
  794. package/dist/esm/eventDispatchers/annotationModifiedEventDispatcher.js.map +1 -0
  795. package/dist/esm/eventDispatchers/cameraModifiedEventDispatcher.d.ts +5 -0
  796. package/dist/esm/eventDispatchers/cameraModifiedEventDispatcher.js +27 -0
  797. package/dist/esm/eventDispatchers/cameraModifiedEventDispatcher.js.map +1 -0
  798. package/dist/esm/eventDispatchers/imageRenderedEventDispatcher.d.ts +5 -0
  799. package/dist/esm/eventDispatchers/imageRenderedEventDispatcher.js +16 -0
  800. package/dist/esm/eventDispatchers/imageRenderedEventDispatcher.js.map +1 -0
  801. package/dist/esm/eventDispatchers/imageSpacingCalibratedEventDispatcher.d.ts +5 -0
  802. package/dist/esm/eventDispatchers/imageSpacingCalibratedEventDispatcher.js +27 -0
  803. package/dist/esm/eventDispatchers/imageSpacingCalibratedEventDispatcher.js.map +1 -0
  804. package/dist/esm/eventDispatchers/index.d.ts +6 -0
  805. package/dist/esm/eventDispatchers/index.js +7 -0
  806. package/dist/esm/eventDispatchers/index.js.map +1 -0
  807. package/dist/esm/eventDispatchers/keyboardEventHandlers/index.d.ts +3 -0
  808. package/dist/esm/eventDispatchers/keyboardEventHandlers/index.js +4 -0
  809. package/dist/esm/eventDispatchers/keyboardEventHandlers/index.js.map +1 -0
  810. package/dist/esm/eventDispatchers/keyboardEventHandlers/keyDown.d.ts +2 -0
  811. package/dist/esm/eventDispatchers/keyboardEventHandlers/keyDown.js +15 -0
  812. package/dist/esm/eventDispatchers/keyboardEventHandlers/keyDown.js.map +1 -0
  813. package/dist/esm/eventDispatchers/keyboardEventHandlers/keyUp.d.ts +2 -0
  814. package/dist/esm/eventDispatchers/keyboardEventHandlers/keyUp.js +17 -0
  815. package/dist/esm/eventDispatchers/keyboardEventHandlers/keyUp.js.map +1 -0
  816. package/dist/esm/eventDispatchers/keyboardToolEventDispatcher.d.ts +5 -0
  817. package/dist/esm/eventDispatchers/keyboardToolEventDispatcher.js +16 -0
  818. package/dist/esm/eventDispatchers/keyboardToolEventDispatcher.js.map +1 -0
  819. package/dist/esm/eventDispatchers/mouseEventHandlers/index.d.ts +9 -0
  820. package/dist/esm/eventDispatchers/mouseEventHandlers/index.js +10 -0
  821. package/dist/esm/eventDispatchers/mouseEventHandlers/index.js.map +1 -0
  822. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseClick.d.ts +2 -0
  823. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseClick.js +4 -0
  824. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseClick.js.map +1 -0
  825. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseDoubleClick.d.ts +2 -0
  826. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseDoubleClick.js +4 -0
  827. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseDoubleClick.js.map +1 -0
  828. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseDown.d.ts +2 -0
  829. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseDown.js +77 -0
  830. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseDown.js.map +1 -0
  831. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseDownActivate.d.ts +2 -0
  832. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseDownActivate.js +20 -0
  833. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseDownActivate.js.map +1 -0
  834. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseDrag.d.ts +2 -0
  835. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseDrag.js +14 -0
  836. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseDrag.js.map +1 -0
  837. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseMove.d.ts +2 -0
  838. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseMove.js +29 -0
  839. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseMove.js.map +1 -0
  840. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseUp.d.ts +2 -0
  841. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseUp.js +4 -0
  842. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseUp.js.map +1 -0
  843. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseWheel.d.ts +2 -0
  844. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseWheel.js +4 -0
  845. package/dist/esm/eventDispatchers/mouseEventHandlers/mouseWheel.js.map +1 -0
  846. package/dist/esm/eventDispatchers/mouseToolEventDispatcher.d.ts +5 -0
  847. package/dist/esm/eventDispatchers/mouseToolEventDispatcher.js +28 -0
  848. package/dist/esm/eventDispatchers/mouseToolEventDispatcher.js.map +1 -0
  849. package/dist/esm/eventDispatchers/shared/customCallbackHandler.d.ts +1 -0
  850. package/dist/esm/eventDispatchers/shared/customCallbackHandler.js +30 -0
  851. package/dist/esm/eventDispatchers/shared/customCallbackHandler.js.map +1 -0
  852. package/dist/esm/eventDispatchers/shared/getActiveToolForKeyboardEvent.d.ts +2 -0
  853. package/dist/esm/eventDispatchers/shared/getActiveToolForKeyboardEvent.js +26 -0
  854. package/dist/esm/eventDispatchers/shared/getActiveToolForKeyboardEvent.js.map +1 -0
  855. package/dist/esm/eventDispatchers/shared/getActiveToolForMouseEvent.d.ts +2 -0
  856. package/dist/esm/eventDispatchers/shared/getActiveToolForMouseEvent.js +26 -0
  857. package/dist/esm/eventDispatchers/shared/getActiveToolForMouseEvent.js.map +1 -0
  858. package/dist/esm/eventDispatchers/shared/getToolsWithModesForMouseEvent.d.ts +5 -0
  859. package/dist/esm/eventDispatchers/shared/getToolsWithModesForMouseEvent.js +24 -0
  860. package/dist/esm/eventDispatchers/shared/getToolsWithModesForMouseEvent.js.map +1 -0
  861. package/dist/esm/eventListeners/annotations/annotationModifiedListener.d.ts +2 -0
  862. package/dist/esm/eventListeners/annotations/annotationModifiedListener.js +9 -0
  863. package/dist/esm/eventListeners/annotations/annotationModifiedListener.js.map +1 -0
  864. package/dist/esm/eventListeners/annotations/annotationSelectionListener.d.ts +2 -0
  865. package/dist/esm/eventListeners/annotations/annotationSelectionListener.js +16 -0
  866. package/dist/esm/eventListeners/annotations/annotationSelectionListener.js.map +1 -0
  867. package/dist/esm/eventListeners/annotations/index.d.ts +3 -0
  868. package/dist/esm/eventListeners/annotations/index.js +4 -0
  869. package/dist/esm/eventListeners/annotations/index.js.map +1 -0
  870. package/dist/esm/eventListeners/index.d.ts +6 -0
  871. package/dist/esm/eventListeners/index.js +7 -0
  872. package/dist/esm/eventListeners/index.js.map +1 -0
  873. package/dist/esm/eventListeners/keyboard/index.d.ts +9 -0
  874. package/dist/esm/eventListeners/keyboard/index.js +14 -0
  875. package/dist/esm/eventListeners/keyboard/index.js.map +1 -0
  876. package/dist/esm/eventListeners/keyboard/keyDownListener.d.ts +4 -0
  877. package/dist/esm/eventListeners/keyboard/keyDownListener.js +58 -0
  878. package/dist/esm/eventListeners/keyboard/keyDownListener.js.map +1 -0
  879. package/dist/esm/eventListeners/mouse/getMouseEventPoints.d.ts +2 -0
  880. package/dist/esm/eventListeners/mouse/getMouseEventPoints.js +29 -0
  881. package/dist/esm/eventListeners/mouse/getMouseEventPoints.js.map +1 -0
  882. package/dist/esm/eventListeners/mouse/index.d.ts +7 -0
  883. package/dist/esm/eventListeners/mouse/index.js +19 -0
  884. package/dist/esm/eventListeners/mouse/index.js.map +1 -0
  885. package/dist/esm/eventListeners/mouse/mouseDoubleClickListener.d.ts +2 -0
  886. package/dist/esm/eventListeners/mouse/mouseDoubleClickListener.js +29 -0
  887. package/dist/esm/eventListeners/mouse/mouseDoubleClickListener.js.map +1 -0
  888. package/dist/esm/eventListeners/mouse/mouseDownListener.d.ts +3 -0
  889. package/dist/esm/eventListeners/mouse/mouseDownListener.js +159 -0
  890. package/dist/esm/eventListeners/mouse/mouseDownListener.js.map +1 -0
  891. package/dist/esm/eventListeners/mouse/mouseMoveListener.d.ts +2 -0
  892. package/dist/esm/eventListeners/mouse/mouseMoveListener.js +22 -0
  893. package/dist/esm/eventListeners/mouse/mouseMoveListener.js.map +1 -0
  894. package/dist/esm/eventListeners/segmentation/index.d.ts +3 -0
  895. package/dist/esm/eventListeners/segmentation/index.js +4 -0
  896. package/dist/esm/eventListeners/segmentation/index.js.map +1 -0
  897. package/dist/esm/eventListeners/segmentation/segmentationDataModifiedEventListener.d.ts +3 -0
  898. package/dist/esm/eventListeners/segmentation/segmentationDataModifiedEventListener.js +38 -0
  899. package/dist/esm/eventListeners/segmentation/segmentationDataModifiedEventListener.js.map +1 -0
  900. package/dist/esm/eventListeners/segmentation/segmentationStateModifiedEventListener.d.ts +3 -0
  901. package/dist/esm/eventListeners/segmentation/segmentationStateModifiedEventListener.js +7 -0
  902. package/dist/esm/eventListeners/segmentation/segmentationStateModifiedEventListener.js.map +1 -0
  903. package/dist/esm/eventListeners/wheel/index.d.ts +7 -0
  904. package/dist/esm/eventListeners/wheel/index.js +13 -0
  905. package/dist/esm/eventListeners/wheel/index.js.map +1 -0
  906. package/dist/esm/eventListeners/wheel/normalizeWheel.d.ts +6 -0
  907. package/dist/esm/eventListeners/wheel/normalizeWheel.js +49 -0
  908. package/dist/esm/eventListeners/wheel/normalizeWheel.js.map +1 -0
  909. package/dist/esm/eventListeners/wheel/wheelListener.d.ts +2 -0
  910. package/dist/esm/eventListeners/wheel/wheelListener.js +35 -0
  911. package/dist/esm/eventListeners/wheel/wheelListener.js.map +1 -0
  912. package/dist/esm/index.d.ts +19 -0
  913. package/dist/esm/index.js +20 -0
  914. package/dist/esm/index.js.map +1 -0
  915. package/dist/esm/init.d.ts +3 -0
  916. package/dist/esm/init.js +66 -0
  917. package/dist/esm/init.js.map +1 -0
  918. package/dist/esm/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.d.ts +23 -0
  919. package/dist/esm/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.js +150 -0
  920. package/dist/esm/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.js.map +1 -0
  921. package/dist/esm/stateManagement/annotation/annotationLocking.d.ts +8 -0
  922. package/dist/esm/stateManagement/annotation/annotationLocking.js +88 -0
  923. package/dist/esm/stateManagement/annotation/annotationLocking.js.map +1 -0
  924. package/dist/esm/stateManagement/annotation/annotationSelection.d.ts +8 -0
  925. package/dist/esm/stateManagement/annotation/annotationSelection.js +75 -0
  926. package/dist/esm/stateManagement/annotation/annotationSelection.js.map +1 -0
  927. package/dist/esm/stateManagement/annotation/annotationState.d.ts +9 -0
  928. package/dist/esm/stateManagement/annotation/annotationState.js +54 -0
  929. package/dist/esm/stateManagement/annotation/annotationState.js.map +1 -0
  930. package/dist/esm/stateManagement/annotation/config/annotationStyle.d.ts +5 -0
  931. package/dist/esm/stateManagement/annotation/config/annotationStyle.js +70 -0
  932. package/dist/esm/stateManagement/annotation/config/annotationStyle.js.map +1 -0
  933. package/dist/esm/stateManagement/annotation/config/getFont.d.ts +4 -0
  934. package/dist/esm/stateManagement/annotation/config/getFont.js +10 -0
  935. package/dist/esm/stateManagement/annotation/config/getFont.js.map +1 -0
  936. package/dist/esm/stateManagement/annotation/config/getState.d.ts +4 -0
  937. package/dist/esm/stateManagement/annotation/config/getState.js +16 -0
  938. package/dist/esm/stateManagement/annotation/config/getState.js.map +1 -0
  939. package/dist/esm/stateManagement/annotation/config/getStyle.d.ts +2 -0
  940. package/dist/esm/stateManagement/annotation/config/getStyle.js +16 -0
  941. package/dist/esm/stateManagement/annotation/config/getStyle.js.map +1 -0
  942. package/dist/esm/stateManagement/annotation/config/index.d.ts +7 -0
  943. package/dist/esm/stateManagement/annotation/config/index.js +8 -0
  944. package/dist/esm/stateManagement/annotation/config/index.js.map +1 -0
  945. package/dist/esm/stateManagement/annotation/config/setAnnotationStyle.d.ts +2 -0
  946. package/dist/esm/stateManagement/annotation/config/setAnnotationStyle.js +12 -0
  947. package/dist/esm/stateManagement/annotation/config/setAnnotationStyle.js.map +1 -0
  948. package/dist/esm/stateManagement/annotation/config/setGlobalStyle.d.ts +1 -0
  949. package/dist/esm/stateManagement/annotation/config/setGlobalStyle.js +5 -0
  950. package/dist/esm/stateManagement/annotation/config/setGlobalStyle.js.map +1 -0
  951. package/dist/esm/stateManagement/annotation/config/setToolStyle.d.ts +1 -0
  952. package/dist/esm/stateManagement/annotation/config/setToolStyle.js +11 -0
  953. package/dist/esm/stateManagement/annotation/config/setToolStyle.js.map +1 -0
  954. package/dist/esm/stateManagement/annotation/index.d.ts +5 -0
  955. package/dist/esm/stateManagement/annotation/index.js +6 -0
  956. package/dist/esm/stateManagement/annotation/index.js.map +1 -0
  957. package/dist/esm/stateManagement/index.d.ts +16 -0
  958. package/dist/esm/stateManagement/index.js +10 -0
  959. package/dist/esm/stateManagement/index.js.map +1 -0
  960. package/dist/esm/stateManagement/segmentation/SegmentationStateManager.d.ts +29 -0
  961. package/dist/esm/stateManagement/segmentation/SegmentationStateManager.js +196 -0
  962. package/dist/esm/stateManagement/segmentation/SegmentationStateManager.js.map +1 -0
  963. package/dist/esm/stateManagement/segmentation/activeSegmentation.d.ts +12 -0
  964. package/dist/esm/stateManagement/segmentation/activeSegmentation.js +22 -0
  965. package/dist/esm/stateManagement/segmentation/activeSegmentation.js.map +1 -0
  966. package/dist/esm/stateManagement/segmentation/addSegmentationsForToolGroup.d.ts +3 -0
  967. package/dist/esm/stateManagement/segmentation/addSegmentationsForToolGroup.js +40 -0
  968. package/dist/esm/stateManagement/segmentation/addSegmentationsForToolGroup.js.map +1 -0
  969. package/dist/esm/stateManagement/segmentation/createNewSegmentationForToolGroup.d.ts +14 -0
  970. package/dist/esm/stateManagement/segmentation/createNewSegmentationForToolGroup.js +33 -0
  971. package/dist/esm/stateManagement/segmentation/createNewSegmentationForToolGroup.js.map +1 -0
  972. package/dist/esm/stateManagement/segmentation/helpers/COLOR_LUT.d.ts +2 -0
  973. package/dist/esm/stateManagement/segmentation/helpers/COLOR_LUT.js +259 -0
  974. package/dist/esm/stateManagement/segmentation/helpers/COLOR_LUT.js.map +1 -0
  975. package/dist/esm/stateManagement/segmentation/helpers/checkSegmentationDataIsValid.d.ts +3 -0
  976. package/dist/esm/stateManagement/segmentation/helpers/checkSegmentationDataIsValid.js +12 -0
  977. package/dist/esm/stateManagement/segmentation/helpers/checkSegmentationDataIsValid.js.map +1 -0
  978. package/dist/esm/stateManagement/segmentation/helpers/index.d.ts +4 -0
  979. package/dist/esm/stateManagement/segmentation/helpers/index.js +5 -0
  980. package/dist/esm/stateManagement/segmentation/helpers/index.js.map +1 -0
  981. package/dist/esm/stateManagement/segmentation/helpers/internalAddSegmentationToElement.d.ts +3 -0
  982. package/dist/esm/stateManagement/segmentation/helpers/internalAddSegmentationToElement.js +27 -0
  983. package/dist/esm/stateManagement/segmentation/helpers/internalAddSegmentationToElement.js.map +1 -0
  984. package/dist/esm/stateManagement/segmentation/helpers/internalRemoveSegmentationFromElement.d.ts +3 -0
  985. package/dist/esm/stateManagement/segmentation/helpers/internalRemoveSegmentationFromElement.js +18 -0
  986. package/dist/esm/stateManagement/segmentation/helpers/internalRemoveSegmentationFromElement.js.map +1 -0
  987. package/dist/esm/stateManagement/segmentation/index.d.ts +12 -0
  988. package/dist/esm/stateManagement/segmentation/index.js +13 -0
  989. package/dist/esm/stateManagement/segmentation/index.js.map +1 -0
  990. package/dist/esm/stateManagement/segmentation/removeSegmentationsFromToolGroup.d.ts +2 -0
  991. package/dist/esm/stateManagement/segmentation/removeSegmentationsFromToolGroup.js +32 -0
  992. package/dist/esm/stateManagement/segmentation/removeSegmentationsFromToolGroup.js.map +1 -0
  993. package/dist/esm/stateManagement/segmentation/segmentIndex.d.ts +12 -0
  994. package/dist/esm/stateManagement/segmentation/segmentIndex.js +47 -0
  995. package/dist/esm/stateManagement/segmentation/segmentIndex.js.map +1 -0
  996. package/dist/esm/stateManagement/segmentation/segmentLocking.d.ts +14 -0
  997. package/dist/esm/stateManagement/segmentation/segmentLocking.js +68 -0
  998. package/dist/esm/stateManagement/segmentation/segmentLocking.js.map +1 -0
  999. package/dist/esm/stateManagement/segmentation/segmentationColor.d.ts +10 -0
  1000. package/dist/esm/stateManagement/segmentation/segmentationColor.js +24 -0
  1001. package/dist/esm/stateManagement/segmentation/segmentationColor.js.map +1 -0
  1002. package/dist/esm/stateManagement/segmentation/segmentationConfig.d.ts +26 -0
  1003. package/dist/esm/stateManagement/segmentation/segmentationConfig.js +75 -0
  1004. package/dist/esm/stateManagement/segmentation/segmentationConfig.js.map +1 -0
  1005. package/dist/esm/stateManagement/segmentation/segmentationState.d.ts +20 -0
  1006. package/dist/esm/stateManagement/segmentation/segmentationState.js +135 -0
  1007. package/dist/esm/stateManagement/segmentation/segmentationState.js.map +1 -0
  1008. package/dist/esm/stateManagement/segmentation/segmentationVisibility.d.ts +8 -0
  1009. package/dist/esm/stateManagement/segmentation/segmentationVisibility.js +25 -0
  1010. package/dist/esm/stateManagement/segmentation/segmentationVisibility.js.map +1 -0
  1011. package/dist/esm/stateManagement/segmentation/triggerSegmentationEvents.d.ts +4 -0
  1012. package/dist/esm/stateManagement/segmentation/triggerSegmentationEvents.js +38 -0
  1013. package/dist/esm/stateManagement/segmentation/triggerSegmentationEvents.js.map +1 -0
  1014. package/dist/esm/store/SynchronizerManager/Synchronizer.d.ts +30 -0
  1015. package/dist/esm/store/SynchronizerManager/Synchronizer.js +157 -0
  1016. package/dist/esm/store/SynchronizerManager/Synchronizer.js.map +1 -0
  1017. package/dist/esm/store/SynchronizerManager/createSynchronizer.d.ts +3 -0
  1018. package/dist/esm/store/SynchronizerManager/createSynchronizer.js +13 -0
  1019. package/dist/esm/store/SynchronizerManager/createSynchronizer.js.map +1 -0
  1020. package/dist/esm/store/SynchronizerManager/destroy.d.ts +2 -0
  1021. package/dist/esm/store/SynchronizerManager/destroy.js +9 -0
  1022. package/dist/esm/store/SynchronizerManager/destroy.js.map +1 -0
  1023. package/dist/esm/store/SynchronizerManager/destroySynchronizerById.d.ts +2 -0
  1024. package/dist/esm/store/SynchronizerManager/destroySynchronizerById.js +11 -0
  1025. package/dist/esm/store/SynchronizerManager/destroySynchronizerById.js.map +1 -0
  1026. package/dist/esm/store/SynchronizerManager/getAllSynchronizers.d.ts +3 -0
  1027. package/dist/esm/store/SynchronizerManager/getAllSynchronizers.js +6 -0
  1028. package/dist/esm/store/SynchronizerManager/getAllSynchronizers.js.map +1 -0
  1029. package/dist/esm/store/SynchronizerManager/getSynchronizerById.d.ts +3 -0
  1030. package/dist/esm/store/SynchronizerManager/getSynchronizerById.js +6 -0
  1031. package/dist/esm/store/SynchronizerManager/getSynchronizerById.js.map +1 -0
  1032. package/dist/esm/store/SynchronizerManager/getSynchronizers.d.ts +3 -0
  1033. package/dist/esm/store/SynchronizerManager/getSynchronizers.js +18 -0
  1034. package/dist/esm/store/SynchronizerManager/getSynchronizers.js.map +1 -0
  1035. package/dist/esm/store/SynchronizerManager/index.d.ts +7 -0
  1036. package/dist/esm/store/SynchronizerManager/index.js +8 -0
  1037. package/dist/esm/store/SynchronizerManager/index.js.map +1 -0
  1038. package/dist/esm/store/ToolGroupManager/ToolGroup.d.ts +22 -0
  1039. package/dist/esm/store/ToolGroupManager/ToolGroup.js +192 -0
  1040. package/dist/esm/store/ToolGroupManager/ToolGroup.js.map +1 -0
  1041. package/dist/esm/store/ToolGroupManager/createToolGroup.d.ts +3 -0
  1042. package/dist/esm/store/ToolGroupManager/createToolGroup.js +14 -0
  1043. package/dist/esm/store/ToolGroupManager/createToolGroup.js.map +1 -0
  1044. package/dist/esm/store/ToolGroupManager/destroy.d.ts +2 -0
  1045. package/dist/esm/store/ToolGroupManager/destroy.js +11 -0
  1046. package/dist/esm/store/ToolGroupManager/destroy.js.map +1 -0
  1047. package/dist/esm/store/ToolGroupManager/destroyToolGroupByToolGroupUID.d.ts +2 -0
  1048. package/dist/esm/store/ToolGroupManager/destroyToolGroupByToolGroupUID.js +11 -0
  1049. package/dist/esm/store/ToolGroupManager/destroyToolGroupByToolGroupUID.js.map +1 -0
  1050. package/dist/esm/store/ToolGroupManager/getAllToolGroups.d.ts +3 -0
  1051. package/dist/esm/store/ToolGroupManager/getAllToolGroups.js +6 -0
  1052. package/dist/esm/store/ToolGroupManager/getAllToolGroups.js.map +1 -0
  1053. package/dist/esm/store/ToolGroupManager/getToolGroup.d.ts +3 -0
  1054. package/dist/esm/store/ToolGroupManager/getToolGroup.js +15 -0
  1055. package/dist/esm/store/ToolGroupManager/getToolGroup.js.map +1 -0
  1056. package/dist/esm/store/ToolGroupManager/getToolGroupByToolGroupUID.d.ts +3 -0
  1057. package/dist/esm/store/ToolGroupManager/getToolGroupByToolGroupUID.js +6 -0
  1058. package/dist/esm/store/ToolGroupManager/getToolGroupByToolGroupUID.js.map +1 -0
  1059. package/dist/esm/store/ToolGroupManager/index.d.ts +16 -0
  1060. package/dist/esm/store/ToolGroupManager/index.js +16 -0
  1061. package/dist/esm/store/ToolGroupManager/index.js.map +1 -0
  1062. package/dist/esm/store/addEnabledElement.d.ts +2 -0
  1063. package/dist/esm/store/addEnabledElement.js +70 -0
  1064. package/dist/esm/store/addEnabledElement.js.map +1 -0
  1065. package/dist/esm/store/addTool.d.ts +3 -0
  1066. package/dist/esm/store/addTool.js +28 -0
  1067. package/dist/esm/store/addTool.js.map +1 -0
  1068. package/dist/esm/store/cancelActiveManipulations.d.ts +1 -0
  1069. package/dist/esm/store/cancelActiveManipulations.js +17 -0
  1070. package/dist/esm/store/cancelActiveManipulations.js.map +1 -0
  1071. package/dist/esm/store/filterMoveableAnnotationTools.d.ts +3 -0
  1072. package/dist/esm/store/filterMoveableAnnotationTools.js +21 -0
  1073. package/dist/esm/store/filterMoveableAnnotationTools.js.map +1 -0
  1074. package/dist/esm/store/filterToolsWithAnnotationsForElement.d.ts +3 -0
  1075. package/dist/esm/store/filterToolsWithAnnotationsForElement.js +23 -0
  1076. package/dist/esm/store/filterToolsWithAnnotationsForElement.js.map +1 -0
  1077. package/dist/esm/store/filterToolsWithMoveableHandles.d.ts +3 -0
  1078. package/dist/esm/store/filterToolsWithMoveableHandles.js +22 -0
  1079. package/dist/esm/store/filterToolsWithMoveableHandles.js.map +1 -0
  1080. package/dist/esm/store/index.d.ts +10 -0
  1081. package/dist/esm/store/index.js +11 -0
  1082. package/dist/esm/store/index.js.map +1 -0
  1083. package/dist/esm/store/removeEnabledElement.d.ts +3 -0
  1084. package/dist/esm/store/removeEnabledElement.js +73 -0
  1085. package/dist/esm/store/removeEnabledElement.js.map +1 -0
  1086. package/dist/esm/store/state.d.ts +19 -0
  1087. package/dist/esm/store/state.js +28 -0
  1088. package/dist/esm/store/state.js.map +1 -0
  1089. package/dist/esm/store/svgNodeCache.d.ts +3 -0
  1090. package/dist/esm/store/svgNodeCache.js +6 -0
  1091. package/dist/esm/store/svgNodeCache.js.map +1 -0
  1092. package/dist/esm/synchronizers/callbacks/cameraSyncCallback.d.ts +2 -0
  1093. package/dist/esm/synchronizers/callbacks/cameraSyncCallback.js +16 -0
  1094. package/dist/esm/synchronizers/callbacks/cameraSyncCallback.js.map +1 -0
  1095. package/dist/esm/synchronizers/callbacks/voiSyncCallback.d.ts +2 -0
  1096. package/dist/esm/synchronizers/callbacks/voiSyncCallback.js +29 -0
  1097. package/dist/esm/synchronizers/callbacks/voiSyncCallback.js.map +1 -0
  1098. package/dist/esm/synchronizers/index.d.ts +3 -0
  1099. package/dist/esm/synchronizers/index.js +4 -0
  1100. package/dist/esm/synchronizers/index.js.map +1 -0
  1101. package/dist/esm/synchronizers/synchronizers/createCameraPositionSynchronizer.d.ts +2 -0
  1102. package/dist/esm/synchronizers/synchronizers/createCameraPositionSynchronizer.js +9 -0
  1103. package/dist/esm/synchronizers/synchronizers/createCameraPositionSynchronizer.js.map +1 -0
  1104. package/dist/esm/synchronizers/synchronizers/createVOISynchronizer.d.ts +2 -0
  1105. package/dist/esm/synchronizers/synchronizers/createVOISynchronizer.js +8 -0
  1106. package/dist/esm/synchronizers/synchronizers/createVOISynchronizer.js.map +1 -0
  1107. package/dist/esm/synchronizers/synchronizers/index.d.ts +3 -0
  1108. package/dist/esm/synchronizers/synchronizers/index.js +4 -0
  1109. package/dist/esm/synchronizers/synchronizers/index.js.map +1 -0
  1110. package/dist/esm/tools/CrosshairsTool.d.ts +63 -0
  1111. package/dist/esm/tools/CrosshairsTool.js +1273 -0
  1112. package/dist/esm/tools/CrosshairsTool.js.map +1 -0
  1113. package/dist/esm/tools/MIPJumpToClickTool.d.ts +8 -0
  1114. package/dist/esm/tools/MIPJumpToClickTool.js +43 -0
  1115. package/dist/esm/tools/MIPJumpToClickTool.js.map +1 -0
  1116. package/dist/esm/tools/PanTool.d.ts +9 -0
  1117. package/dist/esm/tools/PanTool.js +35 -0
  1118. package/dist/esm/tools/PanTool.js.map +1 -0
  1119. package/dist/esm/tools/StackScrollTool.d.ts +9 -0
  1120. package/dist/esm/tools/StackScrollTool.js +25 -0
  1121. package/dist/esm/tools/StackScrollTool.js.map +1 -0
  1122. package/dist/esm/tools/StackScrollToolMouseWheelTool.d.ts +11 -0
  1123. package/dist/esm/tools/StackScrollToolMouseWheelTool.js +18 -0
  1124. package/dist/esm/tools/StackScrollToolMouseWheelTool.js.map +1 -0
  1125. package/dist/esm/tools/VolumeRotateMouseWheelTool.d.ts +9 -0
  1126. package/dist/esm/tools/VolumeRotateMouseWheelTool.js +52 -0
  1127. package/dist/esm/tools/VolumeRotateMouseWheelTool.js.map +1 -0
  1128. package/dist/esm/tools/WindowLevelTool.d.ts +31 -0
  1129. package/dist/esm/tools/WindowLevelTool.js +135 -0
  1130. package/dist/esm/tools/WindowLevelTool.js.map +1 -0
  1131. package/dist/esm/tools/ZoomTool.d.ts +11 -0
  1132. package/dist/esm/tools/ZoomTool.js +63 -0
  1133. package/dist/esm/tools/ZoomTool.js.map +1 -0
  1134. package/dist/esm/tools/annotation/BidirectionalTool.d.ts +67 -0
  1135. package/dist/esm/tools/annotation/BidirectionalTool.js +675 -0
  1136. package/dist/esm/tools/annotation/BidirectionalTool.js.map +1 -0
  1137. package/dist/esm/tools/annotation/EllipticalRoiTool.d.ts +71 -0
  1138. package/dist/esm/tools/annotation/EllipticalRoiTool.js +627 -0
  1139. package/dist/esm/tools/annotation/EllipticalRoiTool.js.map +1 -0
  1140. package/dist/esm/tools/annotation/LengthTool.d.ts +61 -0
  1141. package/dist/esm/tools/annotation/LengthTool.js +392 -0
  1142. package/dist/esm/tools/annotation/LengthTool.js.map +1 -0
  1143. package/dist/esm/tools/annotation/ProbeTool.d.ts +49 -0
  1144. package/dist/esm/tools/annotation/ProbeTool.js +335 -0
  1145. package/dist/esm/tools/annotation/ProbeTool.js.map +1 -0
  1146. package/dist/esm/tools/annotation/RectangleRoiTool.d.ts +72 -0
  1147. package/dist/esm/tools/annotation/RectangleRoiTool.js +532 -0
  1148. package/dist/esm/tools/annotation/RectangleRoiTool.js.map +1 -0
  1149. package/dist/esm/tools/base/AnnotationTool.d.ts +21 -0
  1150. package/dist/esm/tools/base/AnnotationTool.js +144 -0
  1151. package/dist/esm/tools/base/AnnotationTool.js.map +1 -0
  1152. package/dist/esm/tools/base/BaseTool.d.ts +34 -0
  1153. package/dist/esm/tools/base/BaseTool.js +72 -0
  1154. package/dist/esm/tools/base/BaseTool.js.map +1 -0
  1155. package/dist/esm/tools/base/index.d.ts +3 -0
  1156. package/dist/esm/tools/base/index.js +4 -0
  1157. package/dist/esm/tools/base/index.js.map +1 -0
  1158. package/dist/esm/tools/displayTools/Labelmap/LabelmapConfig.d.ts +13 -0
  1159. package/dist/esm/tools/displayTools/Labelmap/LabelmapConfig.js +25 -0
  1160. package/dist/esm/tools/displayTools/Labelmap/LabelmapConfig.js.map +1 -0
  1161. package/dist/esm/tools/displayTools/Labelmap/LabelmapDisplay.d.ts +11 -0
  1162. package/dist/esm/tools/displayTools/Labelmap/LabelmapDisplay.js +149 -0
  1163. package/dist/esm/tools/displayTools/Labelmap/LabelmapDisplay.js.map +1 -0
  1164. package/dist/esm/tools/displayTools/Labelmap/index.d.ts +3 -0
  1165. package/dist/esm/tools/displayTools/Labelmap/index.js +4 -0
  1166. package/dist/esm/tools/displayTools/Labelmap/index.js.map +1 -0
  1167. package/dist/esm/tools/displayTools/SegmentationDisplayTool.d.ts +11 -0
  1168. package/dist/esm/tools/displayTools/SegmentationDisplayTool.js +74 -0
  1169. package/dist/esm/tools/displayTools/SegmentationDisplayTool.js.map +1 -0
  1170. package/dist/esm/tools/index.d.ts +21 -0
  1171. package/dist/esm/tools/index.js +22 -0
  1172. package/dist/esm/tools/index.js.map +1 -0
  1173. package/dist/esm/tools/segmentation/CircleScissorsTool.d.ts +29 -0
  1174. package/dist/esm/tools/segmentation/CircleScissorsTool.js +192 -0
  1175. package/dist/esm/tools/segmentation/CircleScissorsTool.js.map +1 -0
  1176. package/dist/esm/tools/segmentation/RectangleRoiStartEndThresholdTool.d.ts +82 -0
  1177. package/dist/esm/tools/segmentation/RectangleRoiStartEndThresholdTool.js +234 -0
  1178. package/dist/esm/tools/segmentation/RectangleRoiStartEndThresholdTool.js.map +1 -0
  1179. package/dist/esm/tools/segmentation/RectangleRoiThresholdTool.d.ts +65 -0
  1180. package/dist/esm/tools/segmentation/RectangleRoiThresholdTool.js +144 -0
  1181. package/dist/esm/tools/segmentation/RectangleRoiThresholdTool.js.map +1 -0
  1182. package/dist/esm/tools/segmentation/RectangleScissorsTool.d.ts +29 -0
  1183. package/dist/esm/tools/segmentation/RectangleScissorsTool.js +203 -0
  1184. package/dist/esm/tools/segmentation/RectangleScissorsTool.js.map +1 -0
  1185. package/dist/esm/tools/segmentation/SphereScissorsTool.d.ts +30 -0
  1186. package/dist/esm/tools/segmentation/SphereScissorsTool.js +193 -0
  1187. package/dist/esm/tools/segmentation/SphereScissorsTool.js.map +1 -0
  1188. package/dist/esm/tools/segmentation/strategies/eraseRectangle.d.ts +13 -0
  1189. package/dist/esm/tools/segmentation/strategies/eraseRectangle.js +31 -0
  1190. package/dist/esm/tools/segmentation/strategies/eraseRectangle.js.map +1 -0
  1191. package/dist/esm/tools/segmentation/strategies/fillCircle.d.ts +15 -0
  1192. package/dist/esm/tools/segmentation/strategies/fillCircle.js +49 -0
  1193. package/dist/esm/tools/segmentation/strategies/fillCircle.js.map +1 -0
  1194. package/dist/esm/tools/segmentation/strategies/fillRectangle.d.ts +14 -0
  1195. package/dist/esm/tools/segmentation/strategies/fillRectangle.js +42 -0
  1196. package/dist/esm/tools/segmentation/strategies/fillRectangle.js.map +1 -0
  1197. package/dist/esm/tools/segmentation/strategies/fillSphere.d.ts +15 -0
  1198. package/dist/esm/tools/segmentation/strategies/fillSphere.js +22 -0
  1199. package/dist/esm/tools/segmentation/strategies/fillSphere.js.map +1 -0
  1200. package/dist/esm/tools/segmentation/strategies/index.d.ts +3 -0
  1201. package/dist/esm/tools/segmentation/strategies/index.js +4 -0
  1202. package/dist/esm/tools/segmentation/strategies/index.js.map +1 -0
  1203. package/dist/esm/tsdoc-metadata.json +11 -0
  1204. package/dist/esm/types/AnnotationTypes.d.ts +43 -0
  1205. package/dist/esm/types/AnnotationTypes.js +2 -0
  1206. package/dist/esm/types/AnnotationTypes.js.map +1 -0
  1207. package/dist/esm/types/CursorTypes.d.ts +11 -0
  1208. package/dist/esm/types/CursorTypes.js +2 -0
  1209. package/dist/esm/types/CursorTypes.js.map +1 -0
  1210. package/dist/esm/types/EventTypes.d.ts +140 -0
  1211. package/dist/esm/types/EventTypes.js +2 -0
  1212. package/dist/esm/types/EventTypes.js.map +1 -0
  1213. package/dist/esm/types/IPoints.d.ts +8 -0
  1214. package/dist/esm/types/IPoints.js +2 -0
  1215. package/dist/esm/types/IPoints.js.map +1 -0
  1216. package/dist/esm/types/ISetToolModeOptions.d.ts +15 -0
  1217. package/dist/esm/types/ISetToolModeOptions.js +2 -0
  1218. package/dist/esm/types/ISetToolModeOptions.js.map +1 -0
  1219. package/dist/esm/types/IToolGroup.d.ts +42 -0
  1220. package/dist/esm/types/IToolGroup.js +2 -0
  1221. package/dist/esm/types/IToolGroup.js.map +1 -0
  1222. package/dist/esm/types/InteractionTypes.d.ts +2 -0
  1223. package/dist/esm/types/InteractionTypes.js +2 -0
  1224. package/dist/esm/types/InteractionTypes.js.map +1 -0
  1225. package/dist/esm/types/InternalToolTypes.d.ts +15 -0
  1226. package/dist/esm/types/InternalToolTypes.js +2 -0
  1227. package/dist/esm/types/InternalToolTypes.js.map +1 -0
  1228. package/dist/esm/types/PlanarBoundingBox.d.ts +7 -0
  1229. package/dist/esm/types/PlanarBoundingBox.js +2 -0
  1230. package/dist/esm/types/PlanarBoundingBox.js.map +1 -0
  1231. package/dist/esm/types/SegmentationRepresentationTypes.d.ts +11 -0
  1232. package/dist/esm/types/SegmentationRepresentationTypes.js +2 -0
  1233. package/dist/esm/types/SegmentationRepresentationTypes.js.map +1 -0
  1234. package/dist/esm/types/SegmentationStateTypes.d.ts +51 -0
  1235. package/dist/esm/types/SegmentationStateTypes.js +2 -0
  1236. package/dist/esm/types/SegmentationStateTypes.js.map +1 -0
  1237. package/dist/esm/types/ToolHandle.d.ts +15 -0
  1238. package/dist/esm/types/ToolHandle.js +2 -0
  1239. package/dist/esm/types/ToolHandle.js.map +1 -0
  1240. package/dist/esm/types/ToolProps.d.ts +9 -0
  1241. package/dist/esm/types/ToolProps.js +2 -0
  1242. package/dist/esm/types/ToolProps.js.map +1 -0
  1243. package/dist/esm/types/index.d.ts +14 -0
  1244. package/dist/esm/types/index.js +2 -0
  1245. package/dist/esm/types/index.js.map +1 -0
  1246. package/dist/esm/utilities/calibrateImageSpacing.d.ts +2 -0
  1247. package/dist/esm/utilities/calibrateImageSpacing.js +19 -0
  1248. package/dist/esm/utilities/calibrateImageSpacing.js.map +1 -0
  1249. package/dist/esm/utilities/clip.d.ts +3 -0
  1250. package/dist/esm/utilities/clip.js +9 -0
  1251. package/dist/esm/utilities/clip.js.map +1 -0
  1252. package/dist/esm/utilities/debounce.d.ts +6 -0
  1253. package/dist/esm/utilities/debounce.js +114 -0
  1254. package/dist/esm/utilities/debounce.js.map +1 -0
  1255. package/dist/esm/utilities/deepMerge.d.ts +2 -0
  1256. package/dist/esm/utilities/deepMerge.js +61 -0
  1257. package/dist/esm/utilities/deepMerge.js.map +1 -0
  1258. package/dist/esm/utilities/drawing/getTextBoxCoordsCanvas.d.ts +2 -0
  1259. package/dist/esm/utilities/drawing/getTextBoxCoordsCanvas.js +25 -0
  1260. package/dist/esm/utilities/drawing/getTextBoxCoordsCanvas.js.map +1 -0
  1261. package/dist/esm/utilities/drawing/index.d.ts +6 -0
  1262. package/dist/esm/utilities/drawing/index.js +4 -0
  1263. package/dist/esm/utilities/drawing/index.js.map +1 -0
  1264. package/dist/esm/utilities/getAnnotationNearPoint.d.ts +5 -0
  1265. package/dist/esm/utilities/getAnnotationNearPoint.js +40 -0
  1266. package/dist/esm/utilities/getAnnotationNearPoint.js.map +1 -0
  1267. package/dist/esm/utilities/getToolsWithModesForElement.d.ts +4 -0
  1268. package/dist/esm/utilities/getToolsWithModesForElement.js +25 -0
  1269. package/dist/esm/utilities/getToolsWithModesForElement.js.map +1 -0
  1270. package/dist/esm/utilities/index.d.ts +39 -0
  1271. package/dist/esm/utilities/index.js +39 -0
  1272. package/dist/esm/utilities/index.js.map +1 -0
  1273. package/dist/esm/utilities/isObject.d.ts +2 -0
  1274. package/dist/esm/utilities/isObject.js +6 -0
  1275. package/dist/esm/utilities/isObject.js.map +1 -0
  1276. package/dist/esm/utilities/math/ellipse/getCanvasEllipseCorners.d.ts +9 -0
  1277. package/dist/esm/utilities/math/ellipse/getCanvasEllipseCorners.js +7 -0
  1278. package/dist/esm/utilities/math/ellipse/getCanvasEllipseCorners.js.map +1 -0
  1279. package/dist/esm/utilities/math/ellipse/index.d.ts +8 -0
  1280. package/dist/esm/utilities/math/ellipse/index.js +5 -0
  1281. package/dist/esm/utilities/math/ellipse/index.js.map +1 -0
  1282. package/dist/esm/utilities/math/ellipse/pointInEllipse.d.ts +9 -0
  1283. package/dist/esm/utilities/math/ellipse/pointInEllipse.js +17 -0
  1284. package/dist/esm/utilities/math/ellipse/pointInEllipse.js.map +1 -0
  1285. package/dist/esm/utilities/math/ellipse/pointInEllipsoidWithConstraint.d.ts +9 -0
  1286. package/dist/esm/utilities/math/ellipse/pointInEllipsoidWithConstraint.js +3 -0
  1287. package/dist/esm/utilities/math/ellipse/pointInEllipsoidWithConstraint.js.map +1 -0
  1288. package/dist/esm/utilities/math/index.d.ts +24 -0
  1289. package/dist/esm/utilities/math/index.js +7 -0
  1290. package/dist/esm/utilities/math/index.js.map +1 -0
  1291. package/dist/esm/utilities/math/line/distanceToPoint.d.ts +2 -0
  1292. package/dist/esm/utilities/math/line/distanceToPoint.js +8 -0
  1293. package/dist/esm/utilities/math/line/distanceToPoint.js.map +1 -0
  1294. package/dist/esm/utilities/math/line/distanceToPointSquared.d.ts +2 -0
  1295. package/dist/esm/utilities/math/line/distanceToPointSquared.js +24 -0
  1296. package/dist/esm/utilities/math/line/distanceToPointSquared.js.map +1 -0
  1297. package/dist/esm/utilities/math/line/index.d.ts +9 -0
  1298. package/dist/esm/utilities/math/line/index.js +10 -0
  1299. package/dist/esm/utilities/math/line/index.js.map +1 -0
  1300. package/dist/esm/utilities/math/line/intersectLine.d.ts +2 -0
  1301. package/dist/esm/utilities/math/line/intersectLine.js +42 -0
  1302. package/dist/esm/utilities/math/line/intersectLine.js.map +1 -0
  1303. package/dist/esm/utilities/math/rectangle/distanceToPoint.d.ts +2 -0
  1304. package/dist/esm/utilities/math/rectangle/distanceToPoint.js +35 -0
  1305. package/dist/esm/utilities/math/rectangle/distanceToPoint.js.map +1 -0
  1306. package/dist/esm/utilities/math/rectangle/index.d.ts +5 -0
  1307. package/dist/esm/utilities/math/rectangle/index.js +6 -0
  1308. package/dist/esm/utilities/math/rectangle/index.js.map +1 -0
  1309. package/dist/esm/utilities/math/sphere/index.d.ts +2 -0
  1310. package/dist/esm/utilities/math/sphere/index.js +3 -0
  1311. package/dist/esm/utilities/math/sphere/index.js.map +1 -0
  1312. package/dist/esm/utilities/math/sphere/pointInSphere.d.ts +8 -0
  1313. package/dist/esm/utilities/math/sphere/pointInSphere.js +7 -0
  1314. package/dist/esm/utilities/math/sphere/pointInSphere.js.map +1 -0
  1315. package/dist/esm/utilities/math/vec2/findClosestPoint.d.ts +2 -0
  1316. package/dist/esm/utilities/math/vec2/findClosestPoint.js +18 -0
  1317. package/dist/esm/utilities/math/vec2/findClosestPoint.js.map +1 -0
  1318. package/dist/esm/utilities/math/vec2/index.d.ts +7 -0
  1319. package/dist/esm/utilities/math/vec2/index.js +4 -0
  1320. package/dist/esm/utilities/math/vec2/index.js.map +1 -0
  1321. package/dist/esm/utilities/math/vec2/liangBarksyClip.d.ts +1 -0
  1322. package/dist/esm/utilities/math/vec2/liangBarksyClip.js +64 -0
  1323. package/dist/esm/utilities/math/vec2/liangBarksyClip.js.map +1 -0
  1324. package/dist/esm/utilities/planar/filterAnnotationsForDisplay.d.ts +3 -0
  1325. package/dist/esm/utilities/planar/filterAnnotationsForDisplay.js +21 -0
  1326. package/dist/esm/utilities/planar/filterAnnotationsForDisplay.js.map +1 -0
  1327. package/dist/esm/utilities/planar/filterAnnotationsWithinSlice.d.ts +3 -0
  1328. package/dist/esm/utilities/planar/filterAnnotationsWithinSlice.js +27 -0
  1329. package/dist/esm/utilities/planar/filterAnnotationsWithinSlice.js.map +1 -0
  1330. package/dist/esm/utilities/planar/getPointInLineOfSightWithCriteria.d.ts +2 -0
  1331. package/dist/esm/utilities/planar/getPointInLineOfSightWithCriteria.js +39 -0
  1332. package/dist/esm/utilities/planar/getPointInLineOfSightWithCriteria.js.map +1 -0
  1333. package/dist/esm/utilities/planar/getWorldWidthAndHeightFromCorners.d.ts +5 -0
  1334. package/dist/esm/utilities/planar/getWorldWidthAndHeightFromCorners.js +20 -0
  1335. package/dist/esm/utilities/planar/getWorldWidthAndHeightFromCorners.js.map +1 -0
  1336. package/dist/esm/utilities/planar/getWorldWidthAndHeightFromTwoPoints.d.ts +5 -0
  1337. package/dist/esm/utilities/planar/getWorldWidthAndHeightFromTwoPoints.js +20 -0
  1338. package/dist/esm/utilities/planar/getWorldWidthAndHeightFromTwoPoints.js.map +1 -0
  1339. package/dist/esm/utilities/planar/index.d.ts +12 -0
  1340. package/dist/esm/utilities/planar/index.js +12 -0
  1341. package/dist/esm/utilities/planar/index.js.map +1 -0
  1342. package/dist/esm/utilities/pointInShapeCallback.d.ts +12 -0
  1343. package/dist/esm/utilities/pointInShapeCallback.js +71 -0
  1344. package/dist/esm/utilities/pointInShapeCallback.js.map +1 -0
  1345. package/dist/esm/utilities/pointInSurroundingSphereCallback.d.ts +4 -0
  1346. package/dist/esm/utilities/pointInSurroundingSphereCallback.js +34 -0
  1347. package/dist/esm/utilities/pointInSurroundingSphereCallback.js.map +1 -0
  1348. package/dist/esm/utilities/segmentation/createMergedLabelmapForIndex.d.ts +3 -0
  1349. package/dist/esm/utilities/segmentation/createMergedLabelmapForIndex.js +35 -0
  1350. package/dist/esm/utilities/segmentation/createMergedLabelmapForIndex.js.map +1 -0
  1351. package/dist/esm/utilities/segmentation/getBoundingBoxUtils.d.ts +4 -0
  1352. package/dist/esm/utilities/segmentation/getBoundingBoxUtils.js +47 -0
  1353. package/dist/esm/utilities/segmentation/getBoundingBoxUtils.js.map +1 -0
  1354. package/dist/esm/utilities/segmentation/getDefaultRepresentationConfig.d.ts +1 -0
  1355. package/dist/esm/utilities/segmentation/getDefaultRepresentationConfig.js +11 -0
  1356. package/dist/esm/utilities/segmentation/getDefaultRepresentationConfig.js.map +1 -0
  1357. package/dist/esm/utilities/segmentation/index.d.ts +17 -0
  1358. package/dist/esm/utilities/segmentation/index.js +17 -0
  1359. package/dist/esm/utilities/segmentation/index.js.map +1 -0
  1360. package/dist/esm/utilities/segmentation/isValidRepresentationConfig.d.ts +2 -0
  1361. package/dist/esm/utilities/segmentation/isValidRepresentationConfig.js +11 -0
  1362. package/dist/esm/utilities/segmentation/isValidRepresentationConfig.js.map +1 -0
  1363. package/dist/esm/utilities/segmentation/thresholdVolumeByRange.d.ts +24 -0
  1364. package/dist/esm/utilities/segmentation/thresholdVolumeByRange.js +59 -0
  1365. package/dist/esm/utilities/segmentation/thresholdVolumeByRange.js.map +1 -0
  1366. package/dist/esm/utilities/segmentation/thresholdVolumeByRoiStats.d.ts +11 -0
  1367. package/dist/esm/utilities/segmentation/thresholdVolumeByRoiStats.js +86 -0
  1368. package/dist/esm/utilities/segmentation/thresholdVolumeByRoiStats.js.map +1 -0
  1369. package/dist/esm/utilities/stackScrollTool/getSliceRange.d.ts +6 -0
  1370. package/dist/esm/utilities/stackScrollTool/getSliceRange.js +26 -0
  1371. package/dist/esm/utilities/stackScrollTool/getSliceRange.js.map +1 -0
  1372. package/dist/esm/utilities/stackScrollTool/index.d.ts +10 -0
  1373. package/dist/esm/utilities/stackScrollTool/index.js +10 -0
  1374. package/dist/esm/utilities/stackScrollTool/index.js.map +1 -0
  1375. package/dist/esm/utilities/stackScrollTool/scrollThroughStack.d.ts +2 -0
  1376. package/dist/esm/utilities/stackScrollTool/scrollThroughStack.js +41 -0
  1377. package/dist/esm/utilities/stackScrollTool/scrollThroughStack.js.map +1 -0
  1378. package/dist/esm/utilities/stackScrollTool/snapFocalPointToSlice.d.ts +5 -0
  1379. package/dist/esm/utilities/stackScrollTool/snapFocalPointToSlice.js +38 -0
  1380. package/dist/esm/utilities/stackScrollTool/snapFocalPointToSlice.js.map +1 -0
  1381. package/dist/esm/utilities/throttle.d.ts +5 -0
  1382. package/dist/esm/utilities/throttle.js +20 -0
  1383. package/dist/esm/utilities/throttle.js.map +1 -0
  1384. package/dist/esm/utilities/transformPhysicalToIndex.d.ts +1 -0
  1385. package/dist/esm/utilities/transformPhysicalToIndex.js +6 -0
  1386. package/dist/esm/utilities/transformPhysicalToIndex.js.map +1 -0
  1387. package/dist/esm/utilities/triggerAnnotationRender.d.ts +21 -0
  1388. package/dist/esm/utilities/triggerAnnotationRender.js +105 -0
  1389. package/dist/esm/utilities/triggerAnnotationRender.js.map +1 -0
  1390. package/dist/esm/utilities/triggerAnnotationRenderForViewportUIDs.d.ts +3 -0
  1391. package/dist/esm/utilities/triggerAnnotationRenderForViewportUIDs.js +12 -0
  1392. package/dist/esm/utilities/triggerAnnotationRenderForViewportUIDs.js.map +1 -0
  1393. package/dist/esm/utilities/triggerSegmentationRender.d.ts +17 -0
  1394. package/dist/esm/utilities/triggerSegmentationRender.js +91 -0
  1395. package/dist/esm/utilities/triggerSegmentationRender.js.map +1 -0
  1396. package/dist/esm/utilities/viewport/jumpToWorld.d.ts +2 -0
  1397. package/dist/esm/utilities/viewport/jumpToWorld.js +33 -0
  1398. package/dist/esm/utilities/viewport/jumpToWorld.js.map +1 -0
  1399. package/dist/esm/utilities/viewportFilters/filterViewportsWithFrameOfReferenceUID.d.ts +2 -0
  1400. package/dist/esm/utilities/viewportFilters/filterViewportsWithFrameOfReferenceUID.js +12 -0
  1401. package/dist/esm/utilities/viewportFilters/filterViewportsWithFrameOfReferenceUID.js.map +1 -0
  1402. package/dist/esm/utilities/viewportFilters/filterViewportsWithSameOrientation.d.ts +2 -0
  1403. package/dist/esm/utilities/viewportFilters/filterViewportsWithSameOrientation.js +10 -0
  1404. package/dist/esm/utilities/viewportFilters/filterViewportsWithSameOrientation.js.map +1 -0
  1405. package/dist/esm/utilities/viewportFilters/filterViewportsWithToolEnabled.d.ts +2 -0
  1406. package/dist/esm/utilities/viewportFilters/filterViewportsWithToolEnabled.js +26 -0
  1407. package/dist/esm/utilities/viewportFilters/filterViewportsWithToolEnabled.js.map +1 -0
  1408. package/dist/esm/utilities/viewportFilters/getViewportUIDsWithToolToRender.d.ts +1 -0
  1409. package/dist/esm/utilities/viewportFilters/getViewportUIDsWithToolToRender.js +18 -0
  1410. package/dist/esm/utilities/viewportFilters/getViewportUIDsWithToolToRender.js.map +1 -0
  1411. package/dist/esm/utilities/viewportFilters/index.d.ts +10 -0
  1412. package/dist/esm/utilities/viewportFilters/index.js +10 -0
  1413. package/dist/esm/utilities/viewportFilters/index.js.map +1 -0
  1414. package/dist/tools.d.ts +3997 -0
  1415. package/dist/umd/index.js +2 -0
  1416. package/dist/umd/index.js.map +1 -0
  1417. package/package.json +46 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","mappings":"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,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAA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TuG,EAAuB,CAACX,EAAK,IAAKA,EAAK,IAAKA,EAAK,IAAKA,EAAK,KAE3DY,EAA8B,CAClCz0C,EAASqB,cAAcwyC,EAAK,KAC5B1E,EACA0E,EAAK,GACLA,EAAK,IAEDa,EAA8B,CAClC10C,EAASqB,cAAcwyC,EAAK,KAC5B1E,EACA0E,EAAK,GACLA,EAAK,IAEDc,EAAgC,CACpC30C,EAASqB,cAAcwyC,EAAK,KAC5B1E,EACA0E,EAAK,GACLA,EAAK,IAEDe,EAA+B,CACnC50C,EAASqB,cAAcwyC,EAAK,KAC5B1E,EACA0E,EAAK,GACLA,EAAK,IASP,GAPAH,EAAYlpD,KACViqD,EACAC,EACAC,EACAC,GAIAX,IACCE,IACAI,GACDjF,GACAyE,EACA,CAEA,IAAIc,EAAY,GAAH,OAAMf,EAAN,OACbgB,GACE1rC,EACAokC,EAAel2C,SACfE,EACAq9C,EACAT,EACA,CACEzpC,MAAAA,EACApL,aAAc,EACdvV,KAAM,WAGV6qD,EAAY,GAAH,OAAMf,EAAN,OACTgB,GACE1rC,EACAokC,EAAel2C,SACfE,EACAq9C,EACAL,EACA,CACE7pC,MAAAA,EACApL,aAAc,EACdvV,KAAM,cAGL,GACLiqD,IACCE,IACAI,GACDjF,EACA,CACA,IAAMuF,EAAY,GAAH,OAAMf,GAErBgB,GACE1rC,EACAokC,EAAel2C,SACfE,EACAq9C,EACAT,EACA,CACEzpC,MAAAA,EACApL,aAAc,EACdvV,KAAM,gBAGL,GACLgqD,IACCG,IACAI,GACDR,EACA,CACA,IAAMc,EAAY,GAAH,OAAMf,GAErBgB,GACE1rC,EACAokC,EAAel2C,SACfE,EACAq9C,EACAL,EACA,CACE7pC,MAAAA,EACApL,aAAc,EACdvV,KAAM,cAGL,GAAImqD,GAAoB7E,EAA4B,CACzD,IAAMuF,EAAY,GAAH,OAAMf,GAErBgB,GACE1rC,EACAokC,EAAel2C,SACfE,EACAq9C,EACAT,EACA,CACEzpC,MAAAA,EACApL,aAAc,EACdqL,KAAMD,EACN3gB,KAAM,gBAIVuqD,GACAP,GACAD,GAGAe,GACE1rC,EACAokC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","sources":["webpack://cornerstoneTools3D/webpack/universalModuleDefinition","webpack://cornerstoneTools3D/../../node_modules/@babel/runtime/regenerator/index.js","webpack://cornerstoneTools3D/../../node_modules/lodash.clonedeep/index.js","webpack://cornerstoneTools3D/../../node_modules/regenerator-runtime/runtime.js","webpack://cornerstoneTools3D/external umd \"vtk.js/Sources/Common/Core/Math\"","webpack://cornerstoneTools3D/external umd \"vtk.js/Sources/Common/Core/MatrixBuilder\"","webpack://cornerstoneTools3D/external umd \"vtk.js/Sources/Common/DataModel/PiecewiseFunction\"","webpack://cornerstoneTools3D/external umd \"vtk.js/Sources/Rendering/Core/ColorTransferFunction\"","webpack://cornerstoneTools3D/external umd {\"root\":\"window\",\"commonjs\":\"cornerstone3D\",\"commonjs2\":\"cornerstone3D\",\"amd\":\"cornerstone3D\"}","webpack://cornerstoneTools3D/external umd {\"root\":\"window\",\"commonjs\":\"gl-matrix\",\"commonjs2\":\"gl-matrix\",\"amd\":\"gl-matrix\"}","webpack://cornerstoneTools3D/webpack/bootstrap","webpack://cornerstoneTools3D/webpack/runtime/compat get default export","webpack://cornerstoneTools3D/webpack/runtime/define property getters","webpack://cornerstoneTools3D/webpack/runtime/global","webpack://cornerstoneTools3D/webpack/runtime/hasOwnProperty shorthand","webpack://cornerstoneTools3D/webpack/runtime/make namespace object","webpack://cornerstoneTools3D/webpack/runtime/node module decorator","webpack://cornerstoneTools3D/./src/enums/ToolBindings.ts","webpack://cornerstoneTools3D/./src/enums/ToolModes.ts","webpack://cornerstoneTools3D/./src/enums/AnnotationStyleStates.ts","webpack://cornerstoneTools3D/./src/enums/Events.ts","webpack://cornerstoneTools3D/./src/enums/SegmentationRepresentations.ts","webpack://cornerstoneTools3D/../../node_modules/@babel/runtime/helpers/esm/classCallCheck.js","webpack://cornerstoneTools3D/../../node_modules/@babel/runtime/helpers/esm/createClass.js","webpack://cornerstoneTools3D/../../node_modules/@babel/runtime/helpers/esm/defineProperty.js","webpack://cornerstoneTools3D/./src/stateManagement/annotation/annotationLocking.ts","webpack://cornerstoneTools3D/./src/stateManagement/annotation/FrameOfReferenceSpecificAnnotationManager.ts","webpack://cornerstoneTools3D/./src/stateManagement/annotation/annotationState.ts","webpack://cornerstoneTools3D/./src/stateManagement/segmentation/helpers/COLOR_LUT.ts","webpack://cornerstoneTools3D/./src/stateManagement/segmentation/SegmentationStateManager.ts","webpack://cornerstoneTools3D/./src/stateManagement/segmentation/triggerSegmentationEvents.ts","webpack://cornerstoneTools3D/../../node_modules/@babel/runtime/helpers/esm/arrayLikeToArray.js","webpack://cornerstoneTools3D/../../node_modules/@babel/runtime/helpers/esm/unsupportedIterableToArray.js","webpack://cornerstoneTools3D/../../node_modules/@babel/runtime/helpers/esm/slicedToArray.js","webpack://cornerstoneTools3D/../../node_modules/@babel/runtime/helpers/esm/arrayWithHoles.js","webpack://cornerstoneTools3D/../../node_modules/@babel/runtime/helpers/esm/iterableToArrayLimit.js","webpack://cornerstoneTools3D/../../node_modules/@babel/runtime/helpers/esm/nonIterableRest.js","webpack://cornerstoneTools3D/./src/utilities/segmentation/getBoundingBoxUtils.ts","webpack://cornerstoneTools3D/../../node_modules/@babel/runtime/helpers/esm/toConsumableArray.js","webpack://cornerstoneTools3D/../../node_modules/@babel/runtime/helpers/esm/arrayWithoutHoles.js","webpack://cornerstoneTools3D/../../node_modules/@babel/runtime/helpers/esm/iterableToArray.js","webpack://cornerstoneTools3D/../../node_modules/@babel/runtime/helpers/esm/nonIterableSpread.js","webpack://cornerstoneTools3D/./src/store/svgNodeCache.ts","webpack://cornerstoneTools3D/./src/store/state.ts","webpack://cornerstoneTools3D/./src/store/addTool.ts","webpack://cornerstoneTools3D/./src/eventListeners/mouse/getMouseEventPoints.ts","webpack://cornerstoneTools3D/./src/eventListeners/mouse/mouseDoubleClickListener.ts","webpack://cornerstoneTools3D/./src/eventListeners/mouse/mouseMoveListener.ts","webpack://cornerstoneTools3D/./src/eventListeners/mouse/mouseDownListener.ts","webpack://cornerstoneTools3D/./src/eventListeners/mouse/index.ts","webpack://cornerstoneTools3D/./src/eventListeners/wheel/wheelListener.ts","webpack://cornerstoneTools3D/./src/eventListeners/wheel/normalizeWheel.ts","webpack://cornerstoneTools3D/./src/eventListeners/wheel/index.ts","webpack://cornerstoneTools3D/./src/eventListeners/keyboard/keyDownListener.ts","webpack://cornerstoneTools3D/./src/eventListeners/keyboard/index.ts","webpack://cornerstoneTools3D/../../node_modules/@babel/runtime/helpers/esm/assertThisInitialized.js","webpack://cornerstoneTools3D/../../node_modules/@babel/runtime/helpers/esm/setPrototypeOf.js","webpack://cornerstoneTools3D/../../node_modules/@babel/runtime/helpers/esm/inherits.js","webpack://cornerstoneTools3D/../../node_modules/@babel/runtime/helpers/esm/typeof.js","webpack://cornerstoneTools3D/../../node_modules/@babel/runtime/helpers/esm/possibleConstructorReturn.js","webpack://cornerstoneTools3D/../../node_modules/@babel/runtime/helpers/esm/getPrototypeOf.js","webpack://cornerstoneTools3D/./src/utilities/deepMerge.js","webpack://cornerstoneTools3D/./src/tools/base/BaseTool.ts","webpack://cornerstoneTools3D/./src/drawingSvg/getSvgDrawingHelper.ts","webpack://cornerstoneTools3D/./src/drawingSvg/draw.ts","webpack://cornerstoneTools3D/./src/drawingSvg/_getHash.ts","webpack://cornerstoneTools3D/./src/drawingSvg/_setAttributesIfNecessary.ts","webpack://cornerstoneTools3D/./src/drawingSvg/_setNewAttributesIfValid.ts","webpack://cornerstoneTools3D/./src/drawingSvg/drawCircle.ts","webpack://cornerstoneTools3D/./src/drawingSvg/drawEllipse.ts","webpack://cornerstoneTools3D/./src/drawingSvg/drawHandles.ts","webpack://cornerstoneTools3D/./src/drawingSvg/drawLine.ts","webpack://cornerstoneTools3D/./src/drawingSvg/drawTextBox.ts","webpack://cornerstoneTools3D/./src/utilities/math/vec2/findClosestPoint.ts","webpack://cornerstoneTools3D/./src/drawingSvg/drawLink.ts","webpack://cornerstoneTools3D/./src/drawingSvg/drawLinkedTextBox.ts","webpack://cornerstoneTools3D/./src/drawingSvg/drawRect.ts","webpack://cornerstoneTools3D/./src/drawingSvg/index.ts","webpack://cornerstoneTools3D/./src/utilities/getToolsWithModesForElement.ts","webpack://cornerstoneTools3D/./src/utilities/triggerAnnotationRender.ts","webpack://cornerstoneTools3D/./src/stateManagement/annotation/config/annotationStyle.ts","webpack://cornerstoneTools3D/./src/utilities/planar/filterAnnotationsWithinSlice.ts","webpack://cornerstoneTools3D/./src/utilities/planar/filterAnnotationsForDisplay.ts","webpack://cornerstoneTools3D/./src/stateManagement/annotation/annotationSelection.ts","webpack://cornerstoneTools3D/./src/stateManagement/annotation/config/getState.ts","webpack://cornerstoneTools3D/./src/stateManagement/annotation/config/getStyle.ts","webpack://cornerstoneTools3D/./src/stateManagement/annotation/config/getFont.ts","webpack://cornerstoneTools3D/./src/stateManagement/annotation/config/setAnnotationStyle.ts","webpack://cornerstoneTools3D/./src/stateManagement/annotation/config/setGlobalStyle.ts","webpack://cornerstoneTools3D/./src/stateManagement/annotation/config/setToolStyle.ts","webpack://cornerstoneTools3D/./src/tools/base/AnnotationTool.ts","webpack://cornerstoneTools3D/../../node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js","webpack://cornerstoneTools3D/./src/stateManagement/segmentation/helpers/checkSegmentationDataIsValid.ts","webpack://cornerstoneTools3D/./src/stateManagement/segmentation/helpers/internalAddSegmentationToElement.ts","webpack://cornerstoneTools3D/./src/stateManagement/segmentation/helpers/internalRemoveSegmentationFromElement.ts","webpack://cornerstoneTools3D/./src/tools/displayTools/Labelmap/LabelmapDisplay.ts","webpack://cornerstoneTools3D/./src/tools/displayTools/Labelmap/LabelmapConfig.ts","webpack://cornerstoneTools3D/./src/stateManagement/segmentation/addSegmentationsForToolGroup.ts","webpack://cornerstoneTools3D/./src/stateManagement/segmentation/removeSegmentationsFromToolGroup.ts","webpack://cornerstoneTools3D/./src/stateManagement/segmentation/createNewSegmentationForToolGroup.ts","webpack://cornerstoneTools3D/./src/stateManagement/segmentation/activeSegmentation.ts","webpack://cornerstoneTools3D/./src/stateManagement/segmentation/segmentLocking.ts","webpack://cornerstoneTools3D/./src/stateManagement/segmentation/segmentationColor.ts","webpack://cornerstoneTools3D/./src/stateManagement/segmentation/segmentationConfig.ts","webpack://cornerstoneTools3D/./src/stateManagement/segmentation/segmentationVisibility.ts","webpack://cornerstoneTools3D/./src/stateManagement/segmentation/segmentIndex.ts","webpack://cornerstoneTools3D/./src/tools/displayTools/SegmentationDisplayTool.ts","webpack://cornerstoneTools3D/./src/utilities/triggerSegmentationRender.ts","webpack://cornerstoneTools3D/./src/eventListeners/segmentation/segmentationStateModifiedEventListener.ts","webpack://cornerstoneTools3D/./src/eventListeners/segmentation/segmentationDataModifiedEventListener.ts","webpack://cornerstoneTools3D/./src/eventListeners/annotations/annotationSelectionListener.ts","webpack://cornerstoneTools3D/./src/utilities/triggerAnnotationRenderForViewportUIDs.ts","webpack://cornerstoneTools3D/./src/eventListeners/annotations/annotationModifiedListener.ts","webpack://cornerstoneTools3D/./src/eventDispatchers/imageRenderedEventDispatcher.ts","webpack://cornerstoneTools3D/./src/eventDispatchers/shared/customCallbackHandler.ts","webpack://cornerstoneTools3D/./src/eventDispatchers/mouseEventHandlers/mouseClick.ts","webpack://cornerstoneTools3D/./src/eventDispatchers/mouseEventHandlers/mouseDoubleClick.ts","webpack://cornerstoneTools3D/./src/store/filterToolsWithAnnotationsForElement.ts","webpack://cornerstoneTools3D/./src/eventDispatchers/shared/getActiveToolForMouseEvent.ts","webpack://cornerstoneTools3D/./src/eventDispatchers/shared/getToolsWithModesForMouseEvent.ts","webpack://cornerstoneTools3D/./src/eventDispatchers/mouseEventHandlers/mouseDown.ts","webpack://cornerstoneTools3D/./src/store/filterToolsWithMoveableHandles.ts","webpack://cornerstoneTools3D/./src/store/filterMoveableAnnotationTools.ts","webpack://cornerstoneTools3D/./src/eventDispatchers/mouseEventHandlers/mouseDownActivate.ts","webpack://cornerstoneTools3D/./src/eventDispatchers/mouseEventHandlers/mouseDrag.ts","webpack://cornerstoneTools3D/./src/eventDispatchers/mouseEventHandlers/mouseMove.ts","webpack://cornerstoneTools3D/./src/eventDispatchers/mouseEventHandlers/mouseUp.ts","webpack://cornerstoneTools3D/./src/eventDispatchers/mouseEventHandlers/mouseWheel.ts","webpack://cornerstoneTools3D/./src/eventDispatchers/mouseToolEventDispatcher.ts","webpack://cornerstoneTools3D/./src/eventDispatchers/shared/getActiveToolForKeyboardEvent.ts","webpack://cornerstoneTools3D/./src/eventDispatchers/keyboardEventHandlers/keyDown.ts","webpack://cornerstoneTools3D/./src/eventDispatchers/keyboardEventHandlers/keyUp.ts","webpack://cornerstoneTools3D/./src/eventDispatchers/keyboardToolEventDispatcher.ts","webpack://cornerstoneTools3D/./src/eventDispatchers/cameraModifiedEventDispatcher.ts","webpack://cornerstoneTools3D/./src/eventDispatchers/imageSpacingCalibratedEventDispatcher.ts","webpack://cornerstoneTools3D/./src/store/addEnabledElement.ts","webpack://cornerstoneTools3D/./src/store/SynchronizerManager/getSynchronizers.ts","webpack://cornerstoneTools3D/./src/store/ToolGroupManager/getToolGroup.ts","webpack://cornerstoneTools3D/./src/store/removeEnabledElement.ts","webpack://cornerstoneTools3D/./src/store/cancelActiveManipulations.ts","webpack://cornerstoneTools3D/./src/store/SynchronizerManager/Synchronizer.ts","webpack://cornerstoneTools3D/./src/store/SynchronizerManager/createSynchronizer.ts","webpack://cornerstoneTools3D/./src/store/SynchronizerManager/destroy.ts","webpack://cornerstoneTools3D/./src/store/SynchronizerManager/getSynchronizerById.ts","webpack://cornerstoneTools3D/./src/store/SynchronizerManager/getAllSynchronizers.ts","webpack://cornerstoneTools3D/./src/store/SynchronizerManager/destroySynchronizerById.ts","webpack://cornerstoneTools3D/./src/cursors/MouseCursor.ts","webpack://cornerstoneTools3D/./src/cursors/ImageMouseCursor.ts","webpack://cornerstoneTools3D/../../node_modules/@babel/runtime/helpers/esm/superPropBase.js","webpack://cornerstoneTools3D/../../node_modules/@babel/runtime/helpers/esm/get.js","webpack://cornerstoneTools3D/./src/cursors/SVGCursorDescriptor.ts","webpack://cornerstoneTools3D/./src/cursors/SVGMouseCursor.ts","webpack://cornerstoneTools3D/./src/cursors/elementCursor.ts","webpack://cornerstoneTools3D/./src/cursors/setCursorForElement.ts","webpack://cornerstoneTools3D/./src/cursors/index.ts","webpack://cornerstoneTools3D/./src/store/ToolGroupManager/ToolGroup.ts","webpack://cornerstoneTools3D/./src/store/ToolGroupManager/createToolGroup.ts","webpack://cornerstoneTools3D/./src/store/ToolGroupManager/destroyToolGroupByToolGroupUID.ts","webpack://cornerstoneTools3D/./src/store/ToolGroupManager/destroy.ts","webpack://cornerstoneTools3D/./src/store/ToolGroupManager/getToolGroupByToolGroupUID.ts","webpack://cornerstoneTools3D/./src/store/ToolGroupManager/getAllToolGroups.ts","webpack://cornerstoneTools3D/./src/store/ToolGroupManager/index.ts","webpack://cornerstoneTools3D/./src/utilities/getAnnotationNearPoint.ts","webpack://cornerstoneTools3D/./src/utilities/isObject.js","webpack://cornerstoneTools3D/./src/utilities/debounce.js","webpack://cornerstoneTools3D/./src/utilities/throttle.js","webpack://cornerstoneTools3D/./src/utilities/calibrateImageSpacing.ts","webpack://cornerstoneTools3D/./src/utilities/transformPhysicalToIndex.ts","webpack://cornerstoneTools3D/./src/utilities/pointInShapeCallback.ts","webpack://cornerstoneTools3D/./src/utilities/pointInSurroundingSphereCallback.ts","webpack://cornerstoneTools3D/./src/utilities/math/sphere/pointInSphere.ts","webpack://cornerstoneTools3D/./src/utilities/drawing/getTextBoxCoordsCanvas.ts","webpack://cornerstoneTools3D/./src/utilities/drawing/index.ts","webpack://cornerstoneTools3D/./src/utilities/math/vec2/liangBarksyClip.ts","webpack://cornerstoneTools3D/./src/utilities/math/vec2/index.ts","webpack://cornerstoneTools3D/./src/utilities/math/ellipse/pointInEllipse.ts","webpack://cornerstoneTools3D/./src/utilities/math/ellipse/getCanvasEllipseCorners.ts","webpack://cornerstoneTools3D/./src/utilities/math/ellipse/index.ts","webpack://cornerstoneTools3D/./src/utilities/math/line/distanceToPointSquared.ts","webpack://cornerstoneTools3D/./src/utilities/math/line/intersectLine.ts","webpack://cornerstoneTools3D/./src/utilities/math/line/index.ts","webpack://cornerstoneTools3D/./src/utilities/math/line/distanceToPoint.ts","webpack://cornerstoneTools3D/./src/utilities/math/rectangle/index.ts","webpack://cornerstoneTools3D/./src/utilities/math/rectangle/distanceToPoint.ts","webpack://cornerstoneTools3D/./src/utilities/math/index.ts","webpack://cornerstoneTools3D/./src/utilities/planar/getWorldWidthAndHeightFromCorners.ts","webpack://cornerstoneTools3D/./src/utilities/planar/getPointInLineOfSightWithCriteria.ts","webpack://cornerstoneTools3D/./src/utilities/planar/index.ts","webpack://cornerstoneTools3D/./src/utilities/stackScrollTool/snapFocalPointToSlice.ts","webpack://cornerstoneTools3D/./src/utilities/stackScrollTool/getSliceRange.ts","webpack://cornerstoneTools3D/./src/utilities/clip.js","webpack://cornerstoneTools3D/./src/utilities/stackScrollTool/scrollThroughStack.ts","webpack://cornerstoneTools3D/./src/utilities/stackScrollTool/index.ts","webpack://cornerstoneTools3D/./src/utilities/viewportFilters/filterViewportsWithFrameOfReferenceUID.ts","webpack://cornerstoneTools3D/./src/utilities/viewportFilters/filterViewportsWithToolEnabled.ts","webpack://cornerstoneTools3D/./src/utilities/viewportFilters/filterViewportsWithSameOrientation.ts","webpack://cornerstoneTools3D/./src/utilities/viewportFilters/getViewportUIDsWithToolToRender.ts","webpack://cornerstoneTools3D/./src/utilities/viewportFilters/index.ts","webpack://cornerstoneTools3D/./src/utilities/index.ts","webpack://cornerstoneTools3D/./src/utilities/segmentation/thresholdVolumeByRange.ts","webpack://cornerstoneTools3D/./src/utilities/segmentation/thresholdVolumeByRoiStats.ts","webpack://cornerstoneTools3D/./src/utilities/segmentation/createMergedLabelmapForIndex.ts","webpack://cornerstoneTools3D/./src/utilities/segmentation/isValidRepresentationConfig.ts","webpack://cornerstoneTools3D/./src/utilities/segmentation/getDefaultRepresentationConfig.ts","webpack://cornerstoneTools3D/./src/utilities/segmentation/index.ts","webpack://cornerstoneTools3D/./src/stateManagement/segmentation/segmentationState.ts","webpack://cornerstoneTools3D/./src/init.ts","webpack://cornerstoneTools3D/./src/synchronizers/callbacks/cameraSyncCallback.ts","webpack://cornerstoneTools3D/./src/synchronizers/synchronizers/createCameraPositionSynchronizer.ts","webpack://cornerstoneTools3D/./src/synchronizers/callbacks/voiSyncCallback.ts","webpack://cornerstoneTools3D/./src/synchronizers/synchronizers/createVOISynchronizer.ts","webpack://cornerstoneTools3D/./src/tools/PanTool.ts","webpack://cornerstoneTools3D/./src/tools/WindowLevelTool.ts","webpack://cornerstoneTools3D/./src/tools/StackScrollTool.ts","webpack://cornerstoneTools3D/./src/tools/StackScrollToolMouseWheelTool.ts","webpack://cornerstoneTools3D/./src/tools/ZoomTool.ts","webpack://cornerstoneTools3D/./src/tools/VolumeRotateMouseWheelTool.ts","webpack://cornerstoneTools3D/./src/tools/MIPJumpToClickTool.ts","webpack://cornerstoneTools3D/./src/utilities/viewport/jumpToWorld.ts","webpack://cornerstoneTools3D/./src/tools/CrosshairsTool.ts","webpack://cornerstoneTools3D/./src/tools/annotation/BidirectionalTool.ts","webpack://cornerstoneTools3D/./src/tools/annotation/LengthTool.ts","webpack://cornerstoneTools3D/./src/tools/annotation/ProbeTool.ts","webpack://cornerstoneTools3D/./src/tools/annotation/RectangleRoiTool.ts","webpack://cornerstoneTools3D/./src/utilities/planar/getWorldWidthAndHeightFromTwoPoints.ts","webpack://cornerstoneTools3D/./src/tools/annotation/EllipticalRoiTool.ts","webpack://cornerstoneTools3D/./src/tools/segmentation/strategies/fillRectangle.ts","webpack://cornerstoneTools3D/./src/tools/segmentation/strategies/eraseRectangle.ts","webpack://cornerstoneTools3D/./src/tools/segmentation/RectangleScissorsTool.ts","webpack://cornerstoneTools3D/./src/tools/segmentation/strategies/fillCircle.ts","webpack://cornerstoneTools3D/./src/tools/segmentation/CircleScissorsTool.ts","webpack://cornerstoneTools3D/./src/tools/segmentation/strategies/fillSphere.ts","webpack://cornerstoneTools3D/./src/tools/segmentation/SphereScissorsTool.ts","webpack://cornerstoneTools3D/./src/tools/segmentation/RectangleRoiThresholdTool.ts","webpack://cornerstoneTools3D/./src/tools/segmentation/RectangleRoiStartEndThresholdTool.ts","webpack://cornerstoneTools3D/./src/index.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"cornerstone3D\"), require(\"gl-matrix\"), require(\"vtk.js/Sources/Rendering/Core/ColorTransferFunction\"), require(\"vtk.js/Sources/Common/DataModel/PiecewiseFunction\"), require(\"vtk.js/Sources/Common/Core/Math\"), require(\"vtk.js/Sources/Common/Core/MatrixBuilder\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"cornerstone3D\", \"gl-matrix\", \"vtk.js/Sources/Rendering/Core/ColorTransferFunction\", \"vtk.js/Sources/Common/DataModel/PiecewiseFunction\", \"vtk.js/Sources/Common/Core/Math\", \"vtk.js/Sources/Common/Core/MatrixBuilder\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"cornerstoneTools3D\"] = factory(require(\"cornerstone3D\"), require(\"gl-matrix\"), require(\"vtk.js/Sources/Rendering/Core/ColorTransferFunction\"), require(\"vtk.js/Sources/Common/DataModel/PiecewiseFunction\"), require(\"vtk.js/Sources/Common/Core/Math\"), require(\"vtk.js/Sources/Common/Core/MatrixBuilder\"));\n\telse\n\t\troot[\"cornerstoneTools3D\"] = factory(root[\"window\"], root[\"window\"], root[\"vtk.js/Sources/Rendering/Core/ColorTransferFunction\"], root[\"vtk.js/Sources/Common/DataModel/PiecewiseFunction\"], root[\"vtk.js/Sources/Common/Core/Math\"], root[\"vtk.js/Sources/Common/Core/MatrixBuilder\"]);\n})(self, function(__WEBPACK_EXTERNAL_MODULE__571__, __WEBPACK_EXTERNAL_MODULE__976__, __WEBPACK_EXTERNAL_MODULE__103__, __WEBPACK_EXTERNAL_MODULE__634__, __WEBPACK_EXTERNAL_MODULE__4__, __WEBPACK_EXTERNAL_MODULE__611__) {\nreturn ","module.exports = require(\"regenerator-runtime\");\n","/**\n * lodash (Custom Build) <https://lodash.com/>\n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright jQuery Foundation and other contributors <https://jquery.org/>\n * Released under MIT license <https://lodash.com/license>\n * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>\n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as the size to enable large array optimizations. */\nvar LARGE_ARRAY_SIZE = 200;\n\n/** Used to stand-in for `undefined` hash values. */\nvar HASH_UNDEFINED = '__lodash_hash_undefined__';\n\n/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n arrayTag = '[object Array]',\n boolTag = '[object Boolean]',\n dateTag = '[object Date]',\n errorTag = '[object Error]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n mapTag = '[object Map]',\n numberTag = '[object Number]',\n objectTag = '[object Object]',\n promiseTag = '[object Promise]',\n regexpTag = '[object RegExp]',\n setTag = '[object Set]',\n stringTag = '[object String]',\n symbolTag = '[object Symbol]',\n weakMapTag = '[object WeakMap]';\n\nvar arrayBufferTag = '[object ArrayBuffer]',\n dataViewTag = '[object DataView]',\n float32Tag = '[object Float32Array]',\n float64Tag = '[object Float64Array]',\n int8Tag = '[object Int8Array]',\n int16Tag = '[object Int16Array]',\n int32Tag = '[object Int32Array]',\n uint8Tag = '[object Uint8Array]',\n uint8ClampedTag = '[object Uint8ClampedArray]',\n uint16Tag = '[object Uint16Array]',\n uint32Tag = '[object Uint32Array]';\n\n/**\n * Used to match `RegExp`\n * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).\n */\nvar reRegExpChar = /[\\\\^$.*+?()[\\]{}|]/g;\n\n/** Used to match `RegExp` flags from their coerced string values. */\nvar reFlags = /\\w*$/;\n\n/** Used to detect host constructors (Safari). */\nvar reIsHostCtor = /^\\[object .+?Constructor\\]$/;\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/** Used to identify `toStringTag` values supported by `_.clone`. */\nvar cloneableTags = {};\ncloneableTags[argsTag] = cloneableTags[arrayTag] =\ncloneableTags[arrayBufferTag] = cloneableTags[dataViewTag] =\ncloneableTags[boolTag] = cloneableTags[dateTag] =\ncloneableTags[float32Tag] = cloneableTags[float64Tag] =\ncloneableTags[int8Tag] = cloneableTags[int16Tag] =\ncloneableTags[int32Tag] = cloneableTags[mapTag] =\ncloneableTags[numberTag] = cloneableTags[objectTag] =\ncloneableTags[regexpTag] = cloneableTags[setTag] =\ncloneableTags[stringTag] = cloneableTags[symbolTag] =\ncloneableTags[uint8Tag] = cloneableTags[uint8ClampedTag] =\ncloneableTags[uint16Tag] = cloneableTags[uint32Tag] = true;\ncloneableTags[errorTag] = cloneableTags[funcTag] =\ncloneableTags[weakMapTag] = false;\n\n/** Detect free variable `global` from Node.js. */\nvar freeGlobal = typeof global == 'object' && global && global.Object === Object && global;\n\n/** Detect free variable `self`. */\nvar freeSelf = typeof self == 'object' && self && self.Object === Object && self;\n\n/** Used as a reference to the global object. */\nvar root = freeGlobal || freeSelf || Function('return this')();\n\n/** Detect free variable `exports`. */\nvar freeExports = typeof exports == 'object' && exports && !exports.nodeType && exports;\n\n/** Detect free variable `module`. */\nvar freeModule = freeExports && typeof module == 'object' && module && !module.nodeType && module;\n\n/** Detect the popular CommonJS extension `module.exports`. */\nvar moduleExports = freeModule && freeModule.exports === freeExports;\n\n/**\n * Adds the key-value `pair` to `map`.\n *\n * @private\n * @param {Object} map The map to modify.\n * @param {Array} pair The key-value pair to add.\n * @returns {Object} Returns `map`.\n */\nfunction addMapEntry(map, pair) {\n // Don't return `map.set` because it's not chainable in IE 11.\n map.set(pair[0], pair[1]);\n return map;\n}\n\n/**\n * Adds `value` to `set`.\n *\n * @private\n * @param {Object} set The set to modify.\n * @param {*} value The value to add.\n * @returns {Object} Returns `set`.\n */\nfunction addSetEntry(set, value) {\n // Don't return `set.add` because it's not chainable in IE 11.\n set.add(value);\n return set;\n}\n\n/**\n * A specialized version of `_.forEach` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns `array`.\n */\nfunction arrayEach(array, iteratee) {\n var index = -1,\n length = array ? array.length : 0;\n\n while (++index < length) {\n if (iteratee(array[index], index, array) === false) {\n break;\n }\n }\n return array;\n}\n\n/**\n * Appends the elements of `values` to `array`.\n *\n * @private\n * @param {Array} array The array to modify.\n * @param {Array} values The values to append.\n * @returns {Array} Returns `array`.\n */\nfunction arrayPush(array, values) {\n var index = -1,\n length = values.length,\n offset = array.length;\n\n while (++index < length) {\n array[offset + index] = values[index];\n }\n return array;\n}\n\n/**\n * A specialized version of `_.reduce` for arrays without support for\n * iteratee shorthands.\n *\n * @private\n * @param {Array} [array] The array to iterate over.\n * @param {Function} iteratee The function invoked per iteration.\n * @param {*} [accumulator] The initial value.\n * @param {boolean} [initAccum] Specify using the first element of `array` as\n * the initial value.\n * @returns {*} Returns the accumulated value.\n */\nfunction arrayReduce(array, iteratee, accumulator, initAccum) {\n var index = -1,\n length = array ? array.length : 0;\n\n if (initAccum && length) {\n accumulator = array[++index];\n }\n while (++index < length) {\n accumulator = iteratee(accumulator, array[index], index, array);\n }\n return accumulator;\n}\n\n/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n}\n\n/**\n * Gets the value at `key` of `object`.\n *\n * @private\n * @param {Object} [object] The object to query.\n * @param {string} key The key of the property to get.\n * @returns {*} Returns the property value.\n */\nfunction getValue(object, key) {\n return object == null ? undefined : object[key];\n}\n\n/**\n * Checks if `value` is a host object in IE < 9.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a host object, else `false`.\n */\nfunction isHostObject(value) {\n // Many host objects are `Object` objects that can coerce to strings\n // despite having improperly defined `toString` methods.\n var result = false;\n if (value != null && typeof value.toString != 'function') {\n try {\n result = !!(value + '');\n } catch (e) {}\n }\n return result;\n}\n\n/**\n * Converts `map` to its key-value pairs.\n *\n * @private\n * @param {Object} map The map to convert.\n * @returns {Array} Returns the key-value pairs.\n */\nfunction mapToArray(map) {\n var index = -1,\n result = Array(map.size);\n\n map.forEach(function(value, key) {\n result[++index] = [key, value];\n });\n return result;\n}\n\n/**\n * Creates a unary function that invokes `func` with its argument transformed.\n *\n * @private\n * @param {Function} func The function to wrap.\n * @param {Function} transform The argument transform.\n * @returns {Function} Returns the new function.\n */\nfunction overArg(func, transform) {\n return function(arg) {\n return func(transform(arg));\n };\n}\n\n/**\n * Converts `set` to an array of its values.\n *\n * @private\n * @param {Object} set The set to convert.\n * @returns {Array} Returns the values.\n */\nfunction setToArray(set) {\n var index = -1,\n result = Array(set.size);\n\n set.forEach(function(value) {\n result[++index] = value;\n });\n return result;\n}\n\n/** Used for built-in method references. */\nvar arrayProto = Array.prototype,\n funcProto = Function.prototype,\n objectProto = Object.prototype;\n\n/** Used to detect overreaching core-js shims. */\nvar coreJsData = root['__core-js_shared__'];\n\n/** Used to detect methods masquerading as native. */\nvar maskSrcKey = (function() {\n var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');\n return uid ? ('Symbol(src)_1.' + uid) : '';\n}());\n\n/** Used to resolve the decompiled source of functions. */\nvar funcToString = funcProto.toString;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/** Used to detect if a method is native. */\nvar reIsNative = RegExp('^' +\n funcToString.call(hasOwnProperty).replace(reRegExpChar, '\\\\$&')\n .replace(/hasOwnProperty|(function).*?(?=\\\\\\()| for .+?(?=\\\\\\])/g, '$1.*?') + '$'\n);\n\n/** Built-in value references. */\nvar Buffer = moduleExports ? root.Buffer : undefined,\n Symbol = root.Symbol,\n Uint8Array = root.Uint8Array,\n getPrototype = overArg(Object.getPrototypeOf, Object),\n objectCreate = Object.create,\n propertyIsEnumerable = objectProto.propertyIsEnumerable,\n splice = arrayProto.splice;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetSymbols = Object.getOwnPropertySymbols,\n nativeIsBuffer = Buffer ? Buffer.isBuffer : undefined,\n nativeKeys = overArg(Object.keys, Object);\n\n/* Built-in method references that are verified to be native. */\nvar DataView = getNative(root, 'DataView'),\n Map = getNative(root, 'Map'),\n Promise = getNative(root, 'Promise'),\n Set = getNative(root, 'Set'),\n WeakMap = getNative(root, 'WeakMap'),\n nativeCreate = getNative(Object, 'create');\n\n/** Used to detect maps, sets, and weakmaps. */\nvar dataViewCtorString = toSource(DataView),\n mapCtorString = toSource(Map),\n promiseCtorString = toSource(Promise),\n setCtorString = toSource(Set),\n weakMapCtorString = toSource(WeakMap);\n\n/** Used to convert symbols to primitives and strings. */\nvar symbolProto = Symbol ? Symbol.prototype : undefined,\n symbolValueOf = symbolProto ? symbolProto.valueOf : undefined;\n\n/**\n * Creates a hash object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Hash(entries) {\n var index = -1,\n length = entries ? entries.length : 0;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n/**\n * Removes all key-value entries from the hash.\n *\n * @private\n * @name clear\n * @memberOf Hash\n */\nfunction hashClear() {\n this.__data__ = nativeCreate ? nativeCreate(null) : {};\n}\n\n/**\n * Removes `key` and its value from the hash.\n *\n * @private\n * @name delete\n * @memberOf Hash\n * @param {Object} hash The hash to modify.\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction hashDelete(key) {\n return this.has(key) && delete this.__data__[key];\n}\n\n/**\n * Gets the hash value for `key`.\n *\n * @private\n * @name get\n * @memberOf Hash\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction hashGet(key) {\n var data = this.__data__;\n if (nativeCreate) {\n var result = data[key];\n return result === HASH_UNDEFINED ? undefined : result;\n }\n return hasOwnProperty.call(data, key) ? data[key] : undefined;\n}\n\n/**\n * Checks if a hash value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Hash\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction hashHas(key) {\n var data = this.__data__;\n return nativeCreate ? data[key] !== undefined : hasOwnProperty.call(data, key);\n}\n\n/**\n * Sets the hash `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Hash\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the hash instance.\n */\nfunction hashSet(key, value) {\n var data = this.__data__;\n data[key] = (nativeCreate && value === undefined) ? HASH_UNDEFINED : value;\n return this;\n}\n\n// Add methods to `Hash`.\nHash.prototype.clear = hashClear;\nHash.prototype['delete'] = hashDelete;\nHash.prototype.get = hashGet;\nHash.prototype.has = hashHas;\nHash.prototype.set = hashSet;\n\n/**\n * Creates an list cache object.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction ListCache(entries) {\n var index = -1,\n length = entries ? entries.length : 0;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n/**\n * Removes all key-value entries from the list cache.\n *\n * @private\n * @name clear\n * @memberOf ListCache\n */\nfunction listCacheClear() {\n this.__data__ = [];\n}\n\n/**\n * Removes `key` and its value from the list cache.\n *\n * @private\n * @name delete\n * @memberOf ListCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction listCacheDelete(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n return false;\n }\n var lastIndex = data.length - 1;\n if (index == lastIndex) {\n data.pop();\n } else {\n splice.call(data, index, 1);\n }\n return true;\n}\n\n/**\n * Gets the list cache value for `key`.\n *\n * @private\n * @name get\n * @memberOf ListCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction listCacheGet(key) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n return index < 0 ? undefined : data[index][1];\n}\n\n/**\n * Checks if a list cache value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf ListCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction listCacheHas(key) {\n return assocIndexOf(this.__data__, key) > -1;\n}\n\n/**\n * Sets the list cache `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf ListCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the list cache instance.\n */\nfunction listCacheSet(key, value) {\n var data = this.__data__,\n index = assocIndexOf(data, key);\n\n if (index < 0) {\n data.push([key, value]);\n } else {\n data[index][1] = value;\n }\n return this;\n}\n\n// Add methods to `ListCache`.\nListCache.prototype.clear = listCacheClear;\nListCache.prototype['delete'] = listCacheDelete;\nListCache.prototype.get = listCacheGet;\nListCache.prototype.has = listCacheHas;\nListCache.prototype.set = listCacheSet;\n\n/**\n * Creates a map cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction MapCache(entries) {\n var index = -1,\n length = entries ? entries.length : 0;\n\n this.clear();\n while (++index < length) {\n var entry = entries[index];\n this.set(entry[0], entry[1]);\n }\n}\n\n/**\n * Removes all key-value entries from the map.\n *\n * @private\n * @name clear\n * @memberOf MapCache\n */\nfunction mapCacheClear() {\n this.__data__ = {\n 'hash': new Hash,\n 'map': new (Map || ListCache),\n 'string': new Hash\n };\n}\n\n/**\n * Removes `key` and its value from the map.\n *\n * @private\n * @name delete\n * @memberOf MapCache\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction mapCacheDelete(key) {\n return getMapData(this, key)['delete'](key);\n}\n\n/**\n * Gets the map value for `key`.\n *\n * @private\n * @name get\n * @memberOf MapCache\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction mapCacheGet(key) {\n return getMapData(this, key).get(key);\n}\n\n/**\n * Checks if a map value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf MapCache\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction mapCacheHas(key) {\n return getMapData(this, key).has(key);\n}\n\n/**\n * Sets the map `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf MapCache\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the map cache instance.\n */\nfunction mapCacheSet(key, value) {\n getMapData(this, key).set(key, value);\n return this;\n}\n\n// Add methods to `MapCache`.\nMapCache.prototype.clear = mapCacheClear;\nMapCache.prototype['delete'] = mapCacheDelete;\nMapCache.prototype.get = mapCacheGet;\nMapCache.prototype.has = mapCacheHas;\nMapCache.prototype.set = mapCacheSet;\n\n/**\n * Creates a stack cache object to store key-value pairs.\n *\n * @private\n * @constructor\n * @param {Array} [entries] The key-value pairs to cache.\n */\nfunction Stack(entries) {\n this.__data__ = new ListCache(entries);\n}\n\n/**\n * Removes all key-value entries from the stack.\n *\n * @private\n * @name clear\n * @memberOf Stack\n */\nfunction stackClear() {\n this.__data__ = new ListCache;\n}\n\n/**\n * Removes `key` and its value from the stack.\n *\n * @private\n * @name delete\n * @memberOf Stack\n * @param {string} key The key of the value to remove.\n * @returns {boolean} Returns `true` if the entry was removed, else `false`.\n */\nfunction stackDelete(key) {\n return this.__data__['delete'](key);\n}\n\n/**\n * Gets the stack value for `key`.\n *\n * @private\n * @name get\n * @memberOf Stack\n * @param {string} key The key of the value to get.\n * @returns {*} Returns the entry value.\n */\nfunction stackGet(key) {\n return this.__data__.get(key);\n}\n\n/**\n * Checks if a stack value for `key` exists.\n *\n * @private\n * @name has\n * @memberOf Stack\n * @param {string} key The key of the entry to check.\n * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.\n */\nfunction stackHas(key) {\n return this.__data__.has(key);\n}\n\n/**\n * Sets the stack `key` to `value`.\n *\n * @private\n * @name set\n * @memberOf Stack\n * @param {string} key The key of the value to set.\n * @param {*} value The value to set.\n * @returns {Object} Returns the stack cache instance.\n */\nfunction stackSet(key, value) {\n var cache = this.__data__;\n if (cache instanceof ListCache) {\n var pairs = cache.__data__;\n if (!Map || (pairs.length < LARGE_ARRAY_SIZE - 1)) {\n pairs.push([key, value]);\n return this;\n }\n cache = this.__data__ = new MapCache(pairs);\n }\n cache.set(key, value);\n return this;\n}\n\n// Add methods to `Stack`.\nStack.prototype.clear = stackClear;\nStack.prototype['delete'] = stackDelete;\nStack.prototype.get = stackGet;\nStack.prototype.has = stackHas;\nStack.prototype.set = stackSet;\n\n/**\n * Creates an array of the enumerable property names of the array-like `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @param {boolean} inherited Specify returning inherited property names.\n * @returns {Array} Returns the array of property names.\n */\nfunction arrayLikeKeys(value, inherited) {\n // Safari 8.1 makes `arguments.callee` enumerable in strict mode.\n // Safari 9 makes `arguments.length` enumerable in strict mode.\n var result = (isArray(value) || isArguments(value))\n ? baseTimes(value.length, String)\n : [];\n\n var length = result.length,\n skipIndexes = !!length;\n\n for (var key in value) {\n if ((inherited || hasOwnProperty.call(value, key)) &&\n !(skipIndexes && (key == 'length' || isIndex(key, length)))) {\n result.push(key);\n }\n }\n return result;\n}\n\n/**\n * Assigns `value` to `key` of `object` if the existing value is not equivalent\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignValue(object, key, value) {\n var objValue = object[key];\n if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n (value === undefined && !(key in object))) {\n object[key] = value;\n }\n}\n\n/**\n * Gets the index at which the `key` is found in `array` of key-value pairs.\n *\n * @private\n * @param {Array} array The array to inspect.\n * @param {*} key The key to search for.\n * @returns {number} Returns the index of the matched value, else `-1`.\n */\nfunction assocIndexOf(array, key) {\n var length = array.length;\n while (length--) {\n if (eq(array[length][0], key)) {\n return length;\n }\n }\n return -1;\n}\n\n/**\n * The base implementation of `_.assign` without support for multiple sources\n * or `customizer` functions.\n *\n * @private\n * @param {Object} object The destination object.\n * @param {Object} source The source object.\n * @returns {Object} Returns `object`.\n */\nfunction baseAssign(object, source) {\n return object && copyObject(source, keys(source), object);\n}\n\n/**\n * The base implementation of `_.clone` and `_.cloneDeep` which tracks\n * traversed objects.\n *\n * @private\n * @param {*} value The value to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @param {boolean} [isFull] Specify a clone including symbols.\n * @param {Function} [customizer] The function to customize cloning.\n * @param {string} [key] The key of `value`.\n * @param {Object} [object] The parent object of `value`.\n * @param {Object} [stack] Tracks traversed objects and their clone counterparts.\n * @returns {*} Returns the cloned value.\n */\nfunction baseClone(value, isDeep, isFull, customizer, key, object, stack) {\n var result;\n if (customizer) {\n result = object ? customizer(value, key, object, stack) : customizer(value);\n }\n if (result !== undefined) {\n return result;\n }\n if (!isObject(value)) {\n return value;\n }\n var isArr = isArray(value);\n if (isArr) {\n result = initCloneArray(value);\n if (!isDeep) {\n return copyArray(value, result);\n }\n } else {\n var tag = getTag(value),\n isFunc = tag == funcTag || tag == genTag;\n\n if (isBuffer(value)) {\n return cloneBuffer(value, isDeep);\n }\n if (tag == objectTag || tag == argsTag || (isFunc && !object)) {\n if (isHostObject(value)) {\n return object ? value : {};\n }\n result = initCloneObject(isFunc ? {} : value);\n if (!isDeep) {\n return copySymbols(value, baseAssign(result, value));\n }\n } else {\n if (!cloneableTags[tag]) {\n return object ? value : {};\n }\n result = initCloneByTag(value, tag, baseClone, isDeep);\n }\n }\n // Check for circular references and return its corresponding clone.\n stack || (stack = new Stack);\n var stacked = stack.get(value);\n if (stacked) {\n return stacked;\n }\n stack.set(value, result);\n\n if (!isArr) {\n var props = isFull ? getAllKeys(value) : keys(value);\n }\n arrayEach(props || value, function(subValue, key) {\n if (props) {\n key = subValue;\n subValue = value[key];\n }\n // Recursively populate clone (susceptible to call stack limits).\n assignValue(result, key, baseClone(subValue, isDeep, isFull, customizer, key, value, stack));\n });\n return result;\n}\n\n/**\n * The base implementation of `_.create` without support for assigning\n * properties to the created object.\n *\n * @private\n * @param {Object} prototype The object to inherit from.\n * @returns {Object} Returns the new object.\n */\nfunction baseCreate(proto) {\n return isObject(proto) ? objectCreate(proto) : {};\n}\n\n/**\n * The base implementation of `getAllKeys` and `getAllKeysIn` which uses\n * `keysFunc` and `symbolsFunc` to get the enumerable property names and\n * symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Function} keysFunc The function to get the keys of `object`.\n * @param {Function} symbolsFunc The function to get the symbols of `object`.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction baseGetAllKeys(object, keysFunc, symbolsFunc) {\n var result = keysFunc(object);\n return isArray(object) ? result : arrayPush(result, symbolsFunc(object));\n}\n\n/**\n * The base implementation of `getTag`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nfunction baseGetTag(value) {\n return objectToString.call(value);\n}\n\n/**\n * The base implementation of `_.isNative` without bad shim checks.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a native function,\n * else `false`.\n */\nfunction baseIsNative(value) {\n if (!isObject(value) || isMasked(value)) {\n return false;\n }\n var pattern = (isFunction(value) || isHostObject(value)) ? reIsNative : reIsHostCtor;\n return pattern.test(toSource(value));\n}\n\n/**\n * The base implementation of `_.keys` which doesn't treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeys(object) {\n if (!isPrototype(object)) {\n return nativeKeys(object);\n }\n var result = [];\n for (var key in Object(object)) {\n if (hasOwnProperty.call(object, key) && key != 'constructor') {\n result.push(key);\n }\n }\n return result;\n}\n\n/**\n * Creates a clone of `buffer`.\n *\n * @private\n * @param {Buffer} buffer The buffer to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Buffer} Returns the cloned buffer.\n */\nfunction cloneBuffer(buffer, isDeep) {\n if (isDeep) {\n return buffer.slice();\n }\n var result = new buffer.constructor(buffer.length);\n buffer.copy(result);\n return result;\n}\n\n/**\n * Creates a clone of `arrayBuffer`.\n *\n * @private\n * @param {ArrayBuffer} arrayBuffer The array buffer to clone.\n * @returns {ArrayBuffer} Returns the cloned array buffer.\n */\nfunction cloneArrayBuffer(arrayBuffer) {\n var result = new arrayBuffer.constructor(arrayBuffer.byteLength);\n new Uint8Array(result).set(new Uint8Array(arrayBuffer));\n return result;\n}\n\n/**\n * Creates a clone of `dataView`.\n *\n * @private\n * @param {Object} dataView The data view to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned data view.\n */\nfunction cloneDataView(dataView, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(dataView.buffer) : dataView.buffer;\n return new dataView.constructor(buffer, dataView.byteOffset, dataView.byteLength);\n}\n\n/**\n * Creates a clone of `map`.\n *\n * @private\n * @param {Object} map The map to clone.\n * @param {Function} cloneFunc The function to clone values.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned map.\n */\nfunction cloneMap(map, isDeep, cloneFunc) {\n var array = isDeep ? cloneFunc(mapToArray(map), true) : mapToArray(map);\n return arrayReduce(array, addMapEntry, new map.constructor);\n}\n\n/**\n * Creates a clone of `regexp`.\n *\n * @private\n * @param {Object} regexp The regexp to clone.\n * @returns {Object} Returns the cloned regexp.\n */\nfunction cloneRegExp(regexp) {\n var result = new regexp.constructor(regexp.source, reFlags.exec(regexp));\n result.lastIndex = regexp.lastIndex;\n return result;\n}\n\n/**\n * Creates a clone of `set`.\n *\n * @private\n * @param {Object} set The set to clone.\n * @param {Function} cloneFunc The function to clone values.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned set.\n */\nfunction cloneSet(set, isDeep, cloneFunc) {\n var array = isDeep ? cloneFunc(setToArray(set), true) : setToArray(set);\n return arrayReduce(array, addSetEntry, new set.constructor);\n}\n\n/**\n * Creates a clone of the `symbol` object.\n *\n * @private\n * @param {Object} symbol The symbol object to clone.\n * @returns {Object} Returns the cloned symbol object.\n */\nfunction cloneSymbol(symbol) {\n return symbolValueOf ? Object(symbolValueOf.call(symbol)) : {};\n}\n\n/**\n * Creates a clone of `typedArray`.\n *\n * @private\n * @param {Object} typedArray The typed array to clone.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the cloned typed array.\n */\nfunction cloneTypedArray(typedArray, isDeep) {\n var buffer = isDeep ? cloneArrayBuffer(typedArray.buffer) : typedArray.buffer;\n return new typedArray.constructor(buffer, typedArray.byteOffset, typedArray.length);\n}\n\n/**\n * Copies the values of `source` to `array`.\n *\n * @private\n * @param {Array} source The array to copy values from.\n * @param {Array} [array=[]] The array to copy values to.\n * @returns {Array} Returns `array`.\n */\nfunction copyArray(source, array) {\n var index = -1,\n length = source.length;\n\n array || (array = Array(length));\n while (++index < length) {\n array[index] = source[index];\n }\n return array;\n}\n\n/**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property identifiers to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @param {Function} [customizer] The function to customize copied values.\n * @returns {Object} Returns `object`.\n */\nfunction copyObject(source, props, object, customizer) {\n object || (object = {});\n\n var index = -1,\n length = props.length;\n\n while (++index < length) {\n var key = props[index];\n\n var newValue = customizer\n ? customizer(object[key], source[key], key, object, source)\n : undefined;\n\n assignValue(object, key, newValue === undefined ? source[key] : newValue);\n }\n return object;\n}\n\n/**\n * Copies own symbol properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy symbols from.\n * @param {Object} [object={}] The object to copy symbols to.\n * @returns {Object} Returns `object`.\n */\nfunction copySymbols(source, object) {\n return copyObject(source, getSymbols(source), object);\n}\n\n/**\n * Creates an array of own enumerable property names and symbols of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names and symbols.\n */\nfunction getAllKeys(object) {\n return baseGetAllKeys(object, keys, getSymbols);\n}\n\n/**\n * Gets the data for `map`.\n *\n * @private\n * @param {Object} map The map to query.\n * @param {string} key The reference key.\n * @returns {*} Returns the map data.\n */\nfunction getMapData(map, key) {\n var data = map.__data__;\n return isKeyable(key)\n ? data[typeof key == 'string' ? 'string' : 'hash']\n : data.map;\n}\n\n/**\n * Gets the native function at `key` of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {string} key The key of the method to get.\n * @returns {*} Returns the function if it's native, else `undefined`.\n */\nfunction getNative(object, key) {\n var value = getValue(object, key);\n return baseIsNative(value) ? value : undefined;\n}\n\n/**\n * Creates an array of the own enumerable symbol properties of `object`.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of symbols.\n */\nvar getSymbols = nativeGetSymbols ? overArg(nativeGetSymbols, Object) : stubArray;\n\n/**\n * Gets the `toStringTag` of `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {string} Returns the `toStringTag`.\n */\nvar getTag = baseGetTag;\n\n// Fallback for data views, maps, sets, and weak maps in IE 11,\n// for data views in Edge < 14, and promises in Node.js.\nif ((DataView && getTag(new DataView(new ArrayBuffer(1))) != dataViewTag) ||\n (Map && getTag(new Map) != mapTag) ||\n (Promise && getTag(Promise.resolve()) != promiseTag) ||\n (Set && getTag(new Set) != setTag) ||\n (WeakMap && getTag(new WeakMap) != weakMapTag)) {\n getTag = function(value) {\n var result = objectToString.call(value),\n Ctor = result == objectTag ? value.constructor : undefined,\n ctorString = Ctor ? toSource(Ctor) : undefined;\n\n if (ctorString) {\n switch (ctorString) {\n case dataViewCtorString: return dataViewTag;\n case mapCtorString: return mapTag;\n case promiseCtorString: return promiseTag;\n case setCtorString: return setTag;\n case weakMapCtorString: return weakMapTag;\n }\n }\n return result;\n };\n}\n\n/**\n * Initializes an array clone.\n *\n * @private\n * @param {Array} array The array to clone.\n * @returns {Array} Returns the initialized clone.\n */\nfunction initCloneArray(array) {\n var length = array.length,\n result = array.constructor(length);\n\n // Add properties assigned by `RegExp#exec`.\n if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) {\n result.index = array.index;\n result.input = array.input;\n }\n return result;\n}\n\n/**\n * Initializes an object clone.\n *\n * @private\n * @param {Object} object The object to clone.\n * @returns {Object} Returns the initialized clone.\n */\nfunction initCloneObject(object) {\n return (typeof object.constructor == 'function' && !isPrototype(object))\n ? baseCreate(getPrototype(object))\n : {};\n}\n\n/**\n * Initializes an object clone based on its `toStringTag`.\n *\n * **Note:** This function only supports cloning values with tags of\n * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`.\n *\n * @private\n * @param {Object} object The object to clone.\n * @param {string} tag The `toStringTag` of the object to clone.\n * @param {Function} cloneFunc The function to clone values.\n * @param {boolean} [isDeep] Specify a deep clone.\n * @returns {Object} Returns the initialized clone.\n */\nfunction initCloneByTag(object, tag, cloneFunc, isDeep) {\n var Ctor = object.constructor;\n switch (tag) {\n case arrayBufferTag:\n return cloneArrayBuffer(object);\n\n case boolTag:\n case dateTag:\n return new Ctor(+object);\n\n case dataViewTag:\n return cloneDataView(object, isDeep);\n\n case float32Tag: case float64Tag:\n case int8Tag: case int16Tag: case int32Tag:\n case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag:\n return cloneTypedArray(object, isDeep);\n\n case mapTag:\n return cloneMap(object, isDeep, cloneFunc);\n\n case numberTag:\n case stringTag:\n return new Ctor(object);\n\n case regexpTag:\n return cloneRegExp(object);\n\n case setTag:\n return cloneSet(object, isDeep, cloneFunc);\n\n case symbolTag:\n return cloneSymbol(object);\n }\n}\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n length = length == null ? MAX_SAFE_INTEGER : length;\n return !!length &&\n (typeof value == 'number' || reIsUint.test(value)) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\n/**\n * Checks if `value` is suitable for use as unique object key.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is suitable, else `false`.\n */\nfunction isKeyable(value) {\n var type = typeof value;\n return (type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean')\n ? (value !== '__proto__')\n : (value === null);\n}\n\n/**\n * Checks if `func` has its source masked.\n *\n * @private\n * @param {Function} func The function to check.\n * @returns {boolean} Returns `true` if `func` is masked, else `false`.\n */\nfunction isMasked(func) {\n return !!maskSrcKey && (maskSrcKey in func);\n}\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\n/**\n * Converts `func` to its source code.\n *\n * @private\n * @param {Function} func The function to process.\n * @returns {string} Returns the source code.\n */\nfunction toSource(func) {\n if (func != null) {\n try {\n return funcToString.call(func);\n } catch (e) {}\n try {\n return (func + '');\n } catch (e) {}\n }\n return '';\n}\n\n/**\n * This method is like `_.clone` except that it recursively clones `value`.\n *\n * @static\n * @memberOf _\n * @since 1.0.0\n * @category Lang\n * @param {*} value The value to recursively clone.\n * @returns {*} Returns the deep cloned value.\n * @see _.clone\n * @example\n *\n * var objects = [{ 'a': 1 }, { 'b': 2 }];\n *\n * var deep = _.cloneDeep(objects);\n * console.log(deep[0] === objects[0]);\n * // => false\n */\nfunction cloneDeep(value) {\n return baseClone(value, true, true);\n}\n\n/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'a': 1 };\n * var other = { 'a': 1 };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an `arguments` object,\n * else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nfunction isArguments(value) {\n // Safari 8.1 makes `arguments.callee` enumerable in strict mode.\n return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&\n (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);\n}\n\n/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array, else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n return value != null && isLength(value.length) && !isFunction(value);\n}\n\n/**\n * This method is like `_.isArrayLike` except that it also checks if `value`\n * is an object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array-like object,\n * else `false`.\n * @example\n *\n * _.isArrayLikeObject([1, 2, 3]);\n * // => true\n *\n * _.isArrayLikeObject(document.body.children);\n * // => true\n *\n * _.isArrayLikeObject('abc');\n * // => false\n *\n * _.isArrayLikeObject(_.noop);\n * // => false\n */\nfunction isArrayLikeObject(value) {\n return isObjectLike(value) && isArrayLike(value);\n}\n\n/**\n * Checks if `value` is a buffer.\n *\n * @static\n * @memberOf _\n * @since 4.3.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a buffer, else `false`.\n * @example\n *\n * _.isBuffer(new Buffer(2));\n * // => true\n *\n * _.isBuffer(new Uint8Array(2));\n * // => false\n */\nvar isBuffer = nativeIsBuffer || stubFalse;\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a function, else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 8-9 which returns 'object' for typed array and other constructors.\n var tag = isObject(value) ? objectToString.call(value) : '';\n return tag == funcTag || tag == genTag;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This method is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/7.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length, else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return !!value && typeof value == 'object';\n}\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/7.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nfunction keys(object) {\n return isArrayLike(object) ? arrayLikeKeys(object) : baseKeys(object);\n}\n\n/**\n * This method returns a new empty array.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {Array} Returns the new empty array.\n * @example\n *\n * var arrays = _.times(2, _.stubArray);\n *\n * console.log(arrays);\n * // => [[], []]\n *\n * console.log(arrays[0] === arrays[1]);\n * // => false\n */\nfunction stubArray() {\n return [];\n}\n\n/**\n * This method returns `false`.\n *\n * @static\n * @memberOf _\n * @since 4.13.0\n * @category Util\n * @returns {boolean} Returns `false`.\n * @example\n *\n * _.times(2, _.stubFalse);\n * // => [false, false]\n */\nfunction stubFalse() {\n return false;\n}\n\nmodule.exports = cloneDeep;\n","/**\n * Copyright (c) 2014-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nvar runtime = (function (exports) {\n \"use strict\";\n\n var Op = Object.prototype;\n var hasOwn = Op.hasOwnProperty;\n var undefined; // More compressible than void 0.\n var $Symbol = typeof Symbol === \"function\" ? Symbol : {};\n var iteratorSymbol = $Symbol.iterator || \"@@iterator\";\n var asyncIteratorSymbol = $Symbol.asyncIterator || \"@@asyncIterator\";\n var toStringTagSymbol = $Symbol.toStringTag || \"@@toStringTag\";\n\n function define(obj, key, value) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n return obj[key];\n }\n try {\n // IE 8 has a broken Object.defineProperty that only works on DOM objects.\n define({}, \"\");\n } catch (err) {\n define = function(obj, key, value) {\n return obj[key] = value;\n };\n }\n\n function wrap(innerFn, outerFn, self, tryLocsList) {\n // If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.\n var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;\n var generator = Object.create(protoGenerator.prototype);\n var context = new Context(tryLocsList || []);\n\n // The ._invoke method unifies the implementations of the .next,\n // .throw, and .return methods.\n generator._invoke = makeInvokeMethod(innerFn, self, context);\n\n return generator;\n }\n exports.wrap = wrap;\n\n // Try/catch helper to minimize deoptimizations. Returns a completion\n // record like context.tryEntries[i].completion. This interface could\n // have been (and was previously) designed to take a closure to be\n // invoked without arguments, but in all the cases we care about we\n // already have an existing method we want to call, so there's no need\n // to create a new function object. We can even get away with assuming\n // the method takes exactly one argument, since that happens to be true\n // in every case, so we don't have to touch the arguments object. The\n // only additional allocation required is the completion record, which\n // has a stable shape and so hopefully should be cheap to allocate.\n function tryCatch(fn, obj, arg) {\n try {\n return { type: \"normal\", arg: fn.call(obj, arg) };\n } catch (err) {\n return { type: \"throw\", arg: err };\n }\n }\n\n var GenStateSuspendedStart = \"suspendedStart\";\n var GenStateSuspendedYield = \"suspendedYield\";\n var GenStateExecuting = \"executing\";\n var GenStateCompleted = \"completed\";\n\n // Returning this object from the innerFn has the same effect as\n // breaking out of the dispatch switch statement.\n var ContinueSentinel = {};\n\n // Dummy constructor functions that we use as the .constructor and\n // .constructor.prototype properties for functions that return Generator\n // objects. For full spec compliance, you may wish to configure your\n // minifier not to mangle the names of these two functions.\n function Generator() {}\n function GeneratorFunction() {}\n function GeneratorFunctionPrototype() {}\n\n // This is a polyfill for %IteratorPrototype% for environments that\n // don't natively support it.\n var IteratorPrototype = {};\n define(IteratorPrototype, iteratorSymbol, function () {\n return this;\n });\n\n var getProto = Object.getPrototypeOf;\n var NativeIteratorPrototype = getProto && getProto(getProto(values([])));\n if (NativeIteratorPrototype &&\n NativeIteratorPrototype !== Op &&\n hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {\n // This environment has a native %IteratorPrototype%; use it instead\n // of the polyfill.\n IteratorPrototype = NativeIteratorPrototype;\n }\n\n var Gp = GeneratorFunctionPrototype.prototype =\n Generator.prototype = Object.create(IteratorPrototype);\n GeneratorFunction.prototype = GeneratorFunctionPrototype;\n define(Gp, \"constructor\", GeneratorFunctionPrototype);\n define(GeneratorFunctionPrototype, \"constructor\", GeneratorFunction);\n GeneratorFunction.displayName = define(\n GeneratorFunctionPrototype,\n toStringTagSymbol,\n \"GeneratorFunction\"\n );\n\n // Helper for defining the .next, .throw, and .return methods of the\n // Iterator interface in terms of a single ._invoke method.\n function defineIteratorMethods(prototype) {\n [\"next\", \"throw\", \"return\"].forEach(function(method) {\n define(prototype, method, function(arg) {\n return this._invoke(method, arg);\n });\n });\n }\n\n exports.isGeneratorFunction = function(genFun) {\n var ctor = typeof genFun === \"function\" && genFun.constructor;\n return ctor\n ? ctor === GeneratorFunction ||\n // For the native GeneratorFunction constructor, the best we can\n // do is to check its .name property.\n (ctor.displayName || ctor.name) === \"GeneratorFunction\"\n : false;\n };\n\n exports.mark = function(genFun) {\n if (Object.setPrototypeOf) {\n Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);\n } else {\n genFun.__proto__ = GeneratorFunctionPrototype;\n define(genFun, toStringTagSymbol, \"GeneratorFunction\");\n }\n genFun.prototype = Object.create(Gp);\n return genFun;\n };\n\n // Within the body of any async function, `await x` is transformed to\n // `yield regeneratorRuntime.awrap(x)`, so that the runtime can test\n // `hasOwn.call(value, \"__await\")` to determine if the yielded value is\n // meant to be awaited.\n exports.awrap = function(arg) {\n return { __await: arg };\n };\n\n function AsyncIterator(generator, PromiseImpl) {\n function invoke(method, arg, resolve, reject) {\n var record = tryCatch(generator[method], generator, arg);\n if (record.type === \"throw\") {\n reject(record.arg);\n } else {\n var result = record.arg;\n var value = result.value;\n if (value &&\n typeof value === \"object\" &&\n hasOwn.call(value, \"__await\")) {\n return PromiseImpl.resolve(value.__await).then(function(value) {\n invoke(\"next\", value, resolve, reject);\n }, function(err) {\n invoke(\"throw\", err, resolve, reject);\n });\n }\n\n return PromiseImpl.resolve(value).then(function(unwrapped) {\n // When a yielded Promise is resolved, its final value becomes\n // the .value of the Promise<{value,done}> result for the\n // current iteration.\n result.value = unwrapped;\n resolve(result);\n }, function(error) {\n // If a rejected Promise was yielded, throw the rejection back\n // into the async generator function so it can be handled there.\n return invoke(\"throw\", error, resolve, reject);\n });\n }\n }\n\n var previousPromise;\n\n function enqueue(method, arg) {\n function callInvokeWithMethodAndArg() {\n return new PromiseImpl(function(resolve, reject) {\n invoke(method, arg, resolve, reject);\n });\n }\n\n return previousPromise =\n // If enqueue has been called before, then we want to wait until\n // all previous Promises have been resolved before calling invoke,\n // so that results are always delivered in the correct order. If\n // enqueue has not been called before, then it is important to\n // call invoke immediately, without waiting on a callback to fire,\n // so that the async generator function has the opportunity to do\n // any necessary setup in a predictable way. This predictability\n // is why the Promise constructor synchronously invokes its\n // executor callback, and why async functions synchronously\n // execute code before the first await. Since we implement simple\n // async functions in terms of async generators, it is especially\n // important to get this right, even though it requires care.\n previousPromise ? previousPromise.then(\n callInvokeWithMethodAndArg,\n // Avoid propagating failures to Promises returned by later\n // invocations of the iterator.\n callInvokeWithMethodAndArg\n ) : callInvokeWithMethodAndArg();\n }\n\n // Define the unified helper method that is used to implement .next,\n // .throw, and .return (see defineIteratorMethods).\n this._invoke = enqueue;\n }\n\n defineIteratorMethods(AsyncIterator.prototype);\n define(AsyncIterator.prototype, asyncIteratorSymbol, function () {\n return this;\n });\n exports.AsyncIterator = AsyncIterator;\n\n // Note that simple async functions are implemented on top of\n // AsyncIterator objects; they just return a Promise for the value of\n // the final result produced by the iterator.\n exports.async = function(innerFn, outerFn, self, tryLocsList, PromiseImpl) {\n if (PromiseImpl === void 0) PromiseImpl = Promise;\n\n var iter = new AsyncIterator(\n wrap(innerFn, outerFn, self, tryLocsList),\n PromiseImpl\n );\n\n return exports.isGeneratorFunction(outerFn)\n ? iter // If outerFn is a generator, return the full iterator.\n : iter.next().then(function(result) {\n return result.done ? result.value : iter.next();\n });\n };\n\n function makeInvokeMethod(innerFn, self, context) {\n var state = GenStateSuspendedStart;\n\n return function invoke(method, arg) {\n if (state === GenStateExecuting) {\n throw new Error(\"Generator is already running\");\n }\n\n if (state === GenStateCompleted) {\n if (method === \"throw\") {\n throw arg;\n }\n\n // Be forgiving, per 25.3.3.3.3 of the spec:\n // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume\n return doneResult();\n }\n\n context.method = method;\n context.arg = arg;\n\n while (true) {\n var delegate = context.delegate;\n if (delegate) {\n var delegateResult = maybeInvokeDelegate(delegate, context);\n if (delegateResult) {\n if (delegateResult === ContinueSentinel) continue;\n return delegateResult;\n }\n }\n\n if (context.method === \"next\") {\n // Setting context._sent for legacy support of Babel's\n // function.sent implementation.\n context.sent = context._sent = context.arg;\n\n } else if (context.method === \"throw\") {\n if (state === GenStateSuspendedStart) {\n state = GenStateCompleted;\n throw context.arg;\n }\n\n context.dispatchException(context.arg);\n\n } else if (context.method === \"return\") {\n context.abrupt(\"return\", context.arg);\n }\n\n state = GenStateExecuting;\n\n var record = tryCatch(innerFn, self, context);\n if (record.type === \"normal\") {\n // If an exception is thrown from innerFn, we leave state ===\n // GenStateExecuting and loop back for another invocation.\n state = context.done\n ? GenStateCompleted\n : GenStateSuspendedYield;\n\n if (record.arg === ContinueSentinel) {\n continue;\n }\n\n return {\n value: record.arg,\n done: context.done\n };\n\n } else if (record.type === \"throw\") {\n state = GenStateCompleted;\n // Dispatch the exception by looping back around to the\n // context.dispatchException(context.arg) call above.\n context.method = \"throw\";\n context.arg = record.arg;\n }\n }\n };\n }\n\n // Call delegate.iterator[context.method](context.arg) and handle the\n // result, either by returning a { value, done } result from the\n // delegate iterator, or by modifying context.method and context.arg,\n // setting context.delegate to null, and returning the ContinueSentinel.\n function maybeInvokeDelegate(delegate, context) {\n var method = delegate.iterator[context.method];\n if (method === undefined) {\n // A .throw or .return when the delegate iterator has no .throw\n // method always terminates the yield* loop.\n context.delegate = null;\n\n if (context.method === \"throw\") {\n // Note: [\"return\"] must be used for ES3 parsing compatibility.\n if (delegate.iterator[\"return\"]) {\n // If the delegate iterator has a return method, give it a\n // chance to clean up.\n context.method = \"return\";\n context.arg = undefined;\n maybeInvokeDelegate(delegate, context);\n\n if (context.method === \"throw\") {\n // If maybeInvokeDelegate(context) changed context.method from\n // \"return\" to \"throw\", let that override the TypeError below.\n return ContinueSentinel;\n }\n }\n\n context.method = \"throw\";\n context.arg = new TypeError(\n \"The iterator does not provide a 'throw' method\");\n }\n\n return ContinueSentinel;\n }\n\n var record = tryCatch(method, delegate.iterator, context.arg);\n\n if (record.type === \"throw\") {\n context.method = \"throw\";\n context.arg = record.arg;\n context.delegate = null;\n return ContinueSentinel;\n }\n\n var info = record.arg;\n\n if (! info) {\n context.method = \"throw\";\n context.arg = new TypeError(\"iterator result is not an object\");\n context.delegate = null;\n return ContinueSentinel;\n }\n\n if (info.done) {\n // Assign the result of the finished delegate to the temporary\n // variable specified by delegate.resultName (see delegateYield).\n context[delegate.resultName] = info.value;\n\n // Resume execution at the desired location (see delegateYield).\n context.next = delegate.nextLoc;\n\n // If context.method was \"throw\" but the delegate handled the\n // exception, let the outer generator proceed normally. If\n // context.method was \"next\", forget context.arg since it has been\n // \"consumed\" by the delegate iterator. If context.method was\n // \"return\", allow the original .return call to continue in the\n // outer generator.\n if (context.method !== \"return\") {\n context.method = \"next\";\n context.arg = undefined;\n }\n\n } else {\n // Re-yield the result returned by the delegate method.\n return info;\n }\n\n // The delegate iterator is finished, so forget it and continue with\n // the outer generator.\n context.delegate = null;\n return ContinueSentinel;\n }\n\n // Define Generator.prototype.{next,throw,return} in terms of the\n // unified ._invoke helper method.\n defineIteratorMethods(Gp);\n\n define(Gp, toStringTagSymbol, \"Generator\");\n\n // A Generator should always return itself as the iterator object when the\n // @@iterator function is called on it. Some browsers' implementations of the\n // iterator prototype chain incorrectly implement this, causing the Generator\n // object to not be returned from this call. This ensures that doesn't happen.\n // See https://github.com/facebook/regenerator/issues/274 for more details.\n define(Gp, iteratorSymbol, function() {\n return this;\n });\n\n define(Gp, \"toString\", function() {\n return \"[object Generator]\";\n });\n\n function pushTryEntry(locs) {\n var entry = { tryLoc: locs[0] };\n\n if (1 in locs) {\n entry.catchLoc = locs[1];\n }\n\n if (2 in locs) {\n entry.finallyLoc = locs[2];\n entry.afterLoc = locs[3];\n }\n\n this.tryEntries.push(entry);\n }\n\n function resetTryEntry(entry) {\n var record = entry.completion || {};\n record.type = \"normal\";\n delete record.arg;\n entry.completion = record;\n }\n\n function Context(tryLocsList) {\n // The root entry object (effectively a try statement without a catch\n // or a finally block) gives us a place to store values thrown from\n // locations where there is no enclosing try statement.\n this.tryEntries = [{ tryLoc: \"root\" }];\n tryLocsList.forEach(pushTryEntry, this);\n this.reset(true);\n }\n\n exports.keys = function(object) {\n var keys = [];\n for (var key in object) {\n keys.push(key);\n }\n keys.reverse();\n\n // Rather than returning an object with a next method, we keep\n // things simple and return the next function itself.\n return function next() {\n while (keys.length) {\n var key = keys.pop();\n if (key in object) {\n next.value = key;\n next.done = false;\n return next;\n }\n }\n\n // To avoid creating an additional object, we just hang the .value\n // and .done properties off the next function object itself. This\n // also ensures that the minifier will not anonymize the function.\n next.done = true;\n return next;\n };\n };\n\n function values(iterable) {\n if (iterable) {\n var iteratorMethod = iterable[iteratorSymbol];\n if (iteratorMethod) {\n return iteratorMethod.call(iterable);\n }\n\n if (typeof iterable.next === \"function\") {\n return iterable;\n }\n\n if (!isNaN(iterable.length)) {\n var i = -1, next = function next() {\n while (++i < iterable.length) {\n if (hasOwn.call(iterable, i)) {\n next.value = iterable[i];\n next.done = false;\n return next;\n }\n }\n\n next.value = undefined;\n next.done = true;\n\n return next;\n };\n\n return next.next = next;\n }\n }\n\n // Return an iterator with no values.\n return { next: doneResult };\n }\n exports.values = values;\n\n function doneResult() {\n return { value: undefined, done: true };\n }\n\n Context.prototype = {\n constructor: Context,\n\n reset: function(skipTempReset) {\n this.prev = 0;\n this.next = 0;\n // Resetting context._sent for legacy support of Babel's\n // function.sent implementation.\n this.sent = this._sent = undefined;\n this.done = false;\n this.delegate = null;\n\n this.method = \"next\";\n this.arg = undefined;\n\n this.tryEntries.forEach(resetTryEntry);\n\n if (!skipTempReset) {\n for (var name in this) {\n // Not sure about the optimal order of these conditions:\n if (name.charAt(0) === \"t\" &&\n hasOwn.call(this, name) &&\n !isNaN(+name.slice(1))) {\n this[name] = undefined;\n }\n }\n }\n },\n\n stop: function() {\n this.done = true;\n\n var rootEntry = this.tryEntries[0];\n var rootRecord = rootEntry.completion;\n if (rootRecord.type === \"throw\") {\n throw rootRecord.arg;\n }\n\n return this.rval;\n },\n\n dispatchException: function(exception) {\n if (this.done) {\n throw exception;\n }\n\n var context = this;\n function handle(loc, caught) {\n record.type = \"throw\";\n record.arg = exception;\n context.next = loc;\n\n if (caught) {\n // If the dispatched exception was caught by a catch block,\n // then let that catch block handle the exception normally.\n context.method = \"next\";\n context.arg = undefined;\n }\n\n return !! caught;\n }\n\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n var record = entry.completion;\n\n if (entry.tryLoc === \"root\") {\n // Exception thrown outside of any try block that could handle\n // it, so set the completion value of the entire function to\n // throw the exception.\n return handle(\"end\");\n }\n\n if (entry.tryLoc <= this.prev) {\n var hasCatch = hasOwn.call(entry, \"catchLoc\");\n var hasFinally = hasOwn.call(entry, \"finallyLoc\");\n\n if (hasCatch && hasFinally) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n } else if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else if (hasCatch) {\n if (this.prev < entry.catchLoc) {\n return handle(entry.catchLoc, true);\n }\n\n } else if (hasFinally) {\n if (this.prev < entry.finallyLoc) {\n return handle(entry.finallyLoc);\n }\n\n } else {\n throw new Error(\"try statement without catch or finally\");\n }\n }\n }\n },\n\n abrupt: function(type, arg) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc <= this.prev &&\n hasOwn.call(entry, \"finallyLoc\") &&\n this.prev < entry.finallyLoc) {\n var finallyEntry = entry;\n break;\n }\n }\n\n if (finallyEntry &&\n (type === \"break\" ||\n type === \"continue\") &&\n finallyEntry.tryLoc <= arg &&\n arg <= finallyEntry.finallyLoc) {\n // Ignore the finally entry if control is not jumping to a\n // location outside the try/catch block.\n finallyEntry = null;\n }\n\n var record = finallyEntry ? finallyEntry.completion : {};\n record.type = type;\n record.arg = arg;\n\n if (finallyEntry) {\n this.method = \"next\";\n this.next = finallyEntry.finallyLoc;\n return ContinueSentinel;\n }\n\n return this.complete(record);\n },\n\n complete: function(record, afterLoc) {\n if (record.type === \"throw\") {\n throw record.arg;\n }\n\n if (record.type === \"break\" ||\n record.type === \"continue\") {\n this.next = record.arg;\n } else if (record.type === \"return\") {\n this.rval = this.arg = record.arg;\n this.method = \"return\";\n this.next = \"end\";\n } else if (record.type === \"normal\" && afterLoc) {\n this.next = afterLoc;\n }\n\n return ContinueSentinel;\n },\n\n finish: function(finallyLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.finallyLoc === finallyLoc) {\n this.complete(entry.completion, entry.afterLoc);\n resetTryEntry(entry);\n return ContinueSentinel;\n }\n }\n },\n\n \"catch\": function(tryLoc) {\n for (var i = this.tryEntries.length - 1; i >= 0; --i) {\n var entry = this.tryEntries[i];\n if (entry.tryLoc === tryLoc) {\n var record = entry.completion;\n if (record.type === \"throw\") {\n var thrown = record.arg;\n resetTryEntry(entry);\n }\n return thrown;\n }\n }\n\n // The context.catch method must only be called with a location\n // argument that corresponds to a known catch block.\n throw new Error(\"illegal catch attempt\");\n },\n\n delegateYield: function(iterable, resultName, nextLoc) {\n this.delegate = {\n iterator: values(iterable),\n resultName: resultName,\n nextLoc: nextLoc\n };\n\n if (this.method === \"next\") {\n // Deliberately forget the last sent value so that we don't\n // accidentally pass it on to the delegate.\n this.arg = undefined;\n }\n\n return ContinueSentinel;\n }\n };\n\n // Regardless of whether this script is executing as a CommonJS module\n // or not, return the runtime object so that we can declare the variable\n // regeneratorRuntime in the outer scope, which allows this module to be\n // injected easily by `bin/regenerator --include-runtime script.js`.\n return exports;\n\n}(\n // If this script is executing as a CommonJS module, use module.exports\n // as the regeneratorRuntime namespace. Otherwise create a new empty\n // object. Either way, the resulting object will be used to initialize\n // the regeneratorRuntime variable at the top of this file.\n typeof module === \"object\" ? module.exports : {}\n));\n\ntry {\n regeneratorRuntime = runtime;\n} catch (accidentalStrictMode) {\n // This module should not be running in strict mode, so the above\n // assignment should always work unless something is misconfigured. Just\n // in case runtime.js accidentally runs in strict mode, in modern engines\n // we can explicitly access globalThis. In older engines we can escape\n // strict mode using a global Function call. This could conceivably fail\n // if a Content Security Policy forbids using Function, but in that case\n // the proper solution is to fix the accidental strict mode problem. If\n // you've misconfigured your bundler to force strict mode and applied a\n // CSP to forbid Function, and you're not willing to fix either of those\n // problems, please detail your unique predicament in a GitHub issue.\n if (typeof globalThis === \"object\") {\n globalThis.regeneratorRuntime = runtime;\n } else {\n Function(\"r\", \"regeneratorRuntime = r\")(runtime);\n }\n}\n","module.exports = __WEBPACK_EXTERNAL_MODULE__4__;","module.exports = __WEBPACK_EXTERNAL_MODULE__611__;","module.exports = __WEBPACK_EXTERNAL_MODULE__634__;","module.exports = __WEBPACK_EXTERNAL_MODULE__103__;","module.exports = __WEBPACK_EXTERNAL_MODULE__571__;","module.exports = __WEBPACK_EXTERNAL_MODULE__976__;","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\tloaded: false,\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Flag the module as loaded\n\tmodule.loaded = true;\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = function(module) {\n\tvar getter = module && module.__esModule ?\n\t\tfunction() { return module['default']; } :\n\t\tfunction() { return module; };\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","// define __esModule on exports\n__webpack_require__.r = function(exports) {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","__webpack_require__.nmd = function(module) {\n\tmodule.paths = [];\n\tif (!module.children) module.children = [];\n\treturn module;\n};","/**\n * Mouse This enum enumerates the different buttons returned by `.buttons` on the mouse event.\n * These values are used when setting a tool active in a tool group.\n *\n * See also: https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/buttons\n */\nenum MouseBindings {\n Primary = 1,\n Secondary = 2,\n Primary_And_Secondary = 3,\n Auxiliary = 4,\n Primary_And_Auxiliary = 5,\n Secondary_And_Auxiliary = 6,\n Primary_And_Secondary_And_Auxiliary = 7,\n Fourth_Button = 8,\n Fifth_Button = 16,\n}\n\nenum KeyboardBindings {\n Shift = 16,\n Ctrl = 18,\n Alt = 17,\n}\n\nexport { MouseBindings, KeyboardBindings }\n","/**\n * ToolModes - This enum defines the 4 tool states which are available.\n */\nenum ToolModes {\n /**\n * Active:\n * - Can be actively used by mouse/touch events mapped to its `ToolBinding`s.\n * - Can add data if an annotation tool.\n * - Can be passively interacted by grabbing a tool or its handles.\n * - Renders data if the tool has a `renderAnnotation` method.\n */\n Active = 'Active',\n /**\n * Passive:\n * - Can be passively interacted by grabbing a tool or its handles.\n * - Renders data if the tool has a `renderAnnotation` method.\n */\n Passive = 'Passive',\n /**\n * Enabled:\n * - Renders data if the tool has a `renderAnnotation` method.\n */\n Enabled = 'Enabled',\n /**\n * Disabled:\n * - Annotation does not render.\n */\n Disabled = 'Disabled',\n}\n\nexport default ToolModes\n","/**\n * AnnotationStyleStates - This enum defines the 4 possible states available for\n * a Annotation instance.\n *\n * Default:\n * The default state for the annotation instance\n * Highlighted:\n * The annotation should be rendered in \"highlighted\" mode in response to\n * direct user interaction;\n * Selected:\n * The annotation has been selected by the user;\n * Locked:\n * The annotation has been locked;\n */\nenum AnnotationStyleStates {\n Default = '',\n Highlighted = 'Highlighted',\n Selected = 'Selected',\n Locked = 'Locked',\n}\n\nexport default AnnotationStyleStates\n","/**\n * The events for cornerstoneTools3D Tools. Native Mouse and Keyboard events are\n * captured, normalized, and re-triggered with a `CORNERSTONE_TOOLS` prefix. This\n * allows us to handle events consistently across different browsers.\n *\n */\nenum Events {\n ///////////////////////////////////////\n // Annotations\n ///////////////////////////////////////\n\n /**\n * Triggers on the eventTarget when a new annotation is added.\n *\n * Make use of {@link EventTypes.AnnotationAddedEventType | Annotation Added Event Type }\n * for typing your event listeners for this annotation added event, and see what event\n * detail is included in {@link EventTypes.AnnotationAddedEventDetail | Annotation Added Event Detail}.\n */\n ANNOTATION_ADDED = 'CORNERSTONE_TOOLS_ANNOTATION_ADDED',\n\n /**\n * Triggers on the eventTarget when an annotation is modified (e.g. a handle is modified).\n * Make use of {@link EventTypes.AnnotationModifiedEventType | Annotation Modified Event Type}\n * for typing your event listeners for this annotation modified event, and see what\n * event detail is included in {@link EventTypes.AnnotationModifiedEventDetail | Annotation Modified Event Detail}.\n */\n ANNOTATION_MODIFIED = 'CORNERSTONE_TOOLS_ANNOTATION_MODIFIED',\n\n /**\n * Triggers on the eventTarget when an annotation is removed from the annotations manager.\n * Make use of {@link EventTypes.AnnotationRemovedEventType | Annotation Removed Event Type}\n * for typing your event listeners for this annotation removed event, and see what\n * event detail is included in {@link EventTypes.AnnotationRemovedEventDetail | Annotation Removed Event Detail}.\n */\n ANNOTATION_REMOVED = 'CORNERSTONE_TOOLS_ANNOTATION_REMOVED',\n\n /**\n * Triggers on the eventTarget when an annotation selection status is changed.\n * Make use of {@link EventTypes.AnnotationSelectionChangeEventType | Annotation Selection Change Event Type}\n * for typing your event listeners for this annotation selection change event, and see what\n * event detail is included in {@link EventTypes.AnnotationSelectionChangeEventDetail | Annotation Selection Change Event Detail}.\n */\n ANNOTATION_SELECTION_CHANGE = 'CORNERSTONE_TOOLS_ANNOTATION_SELECTION_CHANGE',\n\n /**\n * Triggers on the eventTarget when an annotation locked status is changed.\n * Make use of {@link EventTypes.AnnotationLockChangeEventType | Annotation Lock Change Event Type}\n * for typing your event listeners for this annotation lock change event, and see what\n * event detail is included in {@link EventTypes.AnnotationLockChangeEventDetail | Annotation Lock Change Event Detail}.\n */\n ANNOTATION_LOCK_CHANGE = 'CORNERSTONE_TOOLS_ANNOTATION_LOCK_CHANGE',\n\n /**\n * Triggers on the eventTarget when an annotation is rendered.\n * Make use of {@link EventTypes.AnnotationRenderedEventType | Annotation Rendered Event Type}\n * for typing your event listeners for this annotation rendered event, and see what\n * event detail is included in {@link EventTypes.AnnotationRenderedEventDetail | Annotation Rendered Event Detail}.\n */\n ANNOTATION_RENDERED = 'CORNERSTONE_TOOLS_ANNOTATION_RENDERED',\n\n ///////////////////////////////////////\n // Segmentations Events\n ///////////////////////////////////////\n\n /**\n * Triggers on the eventTarget when a Segmentation is rendered by the Segmentation Rendering Engine.\n * Make use of {@link EventTypes.SegmentationRenderedEventType | Segmentation Rendered Event Type}\n * for typing your event listeners for this segmentation rendered event, and see what\n * event detail is included in {@link EventTypes.SegmentationRenderedEventDetail | Segmentation Rendered Event Detail}.\n */\n SEGMENTATION_RENDERED = 'CORNERSTONE_TOOLS_SEGMENTATION_RENDERED',\n\n /**\n * Triggers on the eventTarget when a Segmentation state of a toolGroup is modified in the state manager.\n * Make use of {@link EventTypes.SegmentationStateModifiedEventType | Segmentation State Modified Event Type}\n * for typing your event listeners for this segmentation state modified event, and see what\n * event detail is included in {@link EventTypes.SegmentationStateModifiedEventDetail | Segmentation State Modified Event Detail}.\n */\n SEGMENTATION_STATE_MODIFIED = 'CORNERSTONE_TOOLS_SEGMENTATION_STATE_MODIFIED',\n\n /**\n * Triggers on the eventTarget when a Segmentation global state is updated in the state manager.\n * Make use of {@link EventTypes.SegmentationGlobalStateModifiedEventType | Segmentation Global State Modified Event Type}\n * for typing your event listeners for this segmentation global state modified event, and see what\n * event detail is included in {@link EventTypes.SegmentationGlobalStateModifiedEventDetail | Segmentation Global State Modified Event Detail}.\n */\n SEGMENTATION_GLOBAL_STATE_MODIFIED = 'CORNERSTONE_TOOLS_SEGMENTATION_GLOBAL_STATE_MODIFIED',\n\n /**\n * Triggers on the eventTarget when a Segmentation data is modified (e.g., by brush tool).\n * Make use of {@link EventTypes.SegmentationDataModifiedEventType | Segmentation Data Modified Event Type}\n * for typing your event listeners for this segmentation data modified event, and see what\n * event detail is included in {@link EventTypes.SegmentationDataModifiedEventDetail | Segmentation Data Modified Event Detail}.\n */\n SEGMENTATION_DATA_MODIFIED = 'CORNERSTONE_TOOLS_SEGMENTATION_DATA_MODIFIED',\n\n ///////////////////////////////////////\n // Keyboard Events\n ///////////////////////////////////////\n\n /**\n * Triggers on the eventTarget when a key on the keyboard is pressed.\n * Make use of {@link EventTypes.KeyDownEventType | Key Down Event Type}\n * for typing your event listeners for this key down event, and see what\n * event detail is included in {@link EventTypes.KeyDownEventDetail | Key Down Event Detail}.\n */\n KEY_DOWN = 'CORNERSTONE_TOOLS_KEY_DOWN',\n\n /**\n * Triggers on the eventTarget when a key on the keyboard is released.\n * Make use of {@link EventTypes.KeyUpEventType | Key Up Event Type}\n * for typing your event listeners for this key up event, and see what\n * event detail is included in {@link EventTypes.KeyUpEventDetail | Key Up Event Detail}.\n */\n KEY_UP = 'CORNERSTONE_TOOLS_KEY_UP',\n\n ///////////////////////////////////////\n // Mouse Events\n ///////////////////////////////////////\n\n /**\n * Triggers on the eventTarget when the mouse is pressed down, it is CornerstoneTools normalized event.\n * Make use of {@link EventTypes.MouseDownEventType | Mouse Down Event Type}\n * for typing your event listeners for this mouse down event, and see what\n * event detail is included in {@link EventTypes.MouseDownEventDetail | Mouse Down Event Detail}.\n */\n MOUSE_DOWN = 'CORNERSTONE_TOOLS_MOUSE_DOWN',\n\n /**\n * Triggers on the eventTarget when the mouse is released, it is CornerstoneTools normalized event.\n * Make use of {@link EventTypes.MouseUpEventType | Mouse Up Event Type}\n * for typing your event listeners for this mouse up event, and see what\n * event detail is included in {@link EventTypes.MouseUpEventDetail | Mouse Up Event Detail}.\n */\n MOUSE_UP = 'CORNERSTONE_TOOLS_MOUSE_UP',\n\n /**\n * Triggers on the eventTarget when a handled `MOUSE_DOWN` event does not `stopPropagation`. The hook\n * we use to create new annotation for mouse events.\n * Make use of {@link EventTypes.MouseDownActivateEventType | Mouse Down Activate Event Type}\n * for typing your event listeners for this mouse down activate event, and see what\n * event detail is included in {@link EventTypes.MouseDownActivateEventDetail | Mouse Down Activate Event Detail}.\n */\n MOUSE_DOWN_ACTIVATE = 'CORNERSTONE_TOOLS_MOUSE_DOWN_ACTIVATE',\n\n /**\n * Triggers on the event target when mouse is dragging an annotation or textBox.\n * Make use of {@link EventTypes.MouseDragEventType | Mouse Drag Event Type}\n * for typing your event listeners for this mouse drag event, and see what\n * event detail is included in {@link EventTypes.MouseDragEventDetail | Mouse Drag Event Detail}.\n */\n MOUSE_DRAG = 'CORNERSTONE_TOOLS_MOUSE_DRAG',\n\n /**\n * Triggers on the eventTarget, when the mouse is moved, it is CornerstoneTools normalized event.\n * It can be just a mouse move or when double click is performed and annotation\n * drawing can be performed with just mouse move.\n * Make use of {@link EventTypes.MouseMoveEventType | Mouse Move Event Type}\n * for typing your event listeners for this mouse move event, and see what\n * event detail is included in {@link EventTypes.MouseMoveEventDetail | Mouse Move Event Detail}.\n */\n MOUSE_MOVE = 'CORNERSTONE_TOOLS_MOUSE_MOVE',\n\n /**\n * Triggers on the eventTarget when a mouse click is detected. It is CornerstoneTools normalized event.\n * Make use of {@link EventTypes.MouseClickEventType | Mouse Click Event Type}\n * for typing your event listeners for this mouse click event, and see what\n * event detail is included in {@link EventTypes.MouseClickEventDetail | Mouse Click Event Detail}.\n */\n MOUSE_CLICK = 'CORNERSTONE_TOOLS_MOUSE_CLICK',\n\n /**\n * Triggers on the eventTarget when a mouse double click is detected. It is CornerstoneTools normalized event.\n * Make use of {@link EventTypes.MouseDoubleClickEventType | Mouse Double Click Event Type}\n * for typing your event listeners for this mouse double click event, and see what\n * event detail is included in {@link EventTypes.MouseDoubleClickEventDetail | Mouse Double Click Event Detail}.\n */\n MOUSE_DOUBLE_CLICK = 'CORNERSTONE_TOOLS_MOUSE_DOUBLE_CLICK',\n\n /**\n * Triggers on the eventTarget when a mouse wheel event is detected. It is CornerstoneTools normalized event.\n * Make use of {@link EventTypes.MouseWheelEventType | Mouse Wheel Event Type}\n * for typing your event listeners for this mouse wheel event, and see what\n * event detail is included in {@link EventTypes.MouseWheelEventDetail | Mouse Wheel Event Detail}.\n */\n MOUSE_WHEEL = 'CORNERSTONE_TOOLS_MOUSE_WHEEL',\n\n // Todo: not being fired as of now\n // ANNOTATION_COMPLETED = 'CORNERSTONE_TOOLS_ANNOTATION_COMPLETED',\n // Todo: not implemented yet\n // KEY_PRESS = 'CORNERSTONE_TOOLS_KEY_PRESS',\n\n ///////////////////////////////////////\n // Touch Events - Not Implemented yet\n ///////////////////////////////////////\n /**\n TOUCH_START = 'CORNERSTONE_TOOLS_TOUCH_START',\n TOUCH_START_ACTIVE = 'CORNERSTONE_TOOLS_TOUCH_START_ACTIVE',\n TOUCH_END = 'CORNERSTONE_TOOLS_TOUCH_END',\n TOUCH_DRAG = 'CORNERSTONE_TOOLS_TOUCH_DRAG',\n TOUCH_DRAG_END = 'CORNERSTONE_TOOLS_TOUCH_DRAG_END',\n // http://hammerjs.github.io/recognizer-pinch/\n TOUCH_PINCH = 'CORNERSTONE_TOOLS_TOUCH_PINCH',\n // http://hammerjs.github.io/recognizer-rotate/\n TOUCH_ROTATE = 'CORNERSTONE_TOOLS_TOUCH_ROTATE',\n // http://hammerjs.github.io/recognizer-press/\n TOUCH_PRESS = 'CORNERSTONE_TOOLS_TOUCH_PRESS',\n // http://hammerjs.github.io/recognizer-tap/\n TAP = 'CORNERSTONE_TOOLS_TAP',\n DOUBLE_TAP = 'CORNERSTONE_TOOLS_DOUBLE_TAP',\n MULTI_TOUCH_START = 'CORNERSTONE_TOOLS_MULTI_TOUCH_START',\n MULTI_TOUCH_START_ACTIVE = 'CORNERSTONE_TOOLS_MULTI_TOUCH_START_ACTIVE',\n MULTI_TOUCH_DRAG = 'CORNERSTONE_TOOLS_MULTI_TOUCH_DRAG',\n */\n}\n\nexport default Events\n","/**\n * Segmentations on viewports can be visualized in different ways. This enum\n * defines the different ways of visualizing segmentations. Currently, only\n * labelmap is supported.\n */\nenum SegmentationRepresentations {\n Labelmap = 'LABELMAP',\n // Todo: add more representations\n}\n\nexport default SegmentationRepresentations\n","export default function _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n}","function _defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n}\n\nexport default function _createClass(Constructor, protoProps, staticProps) {\n if (protoProps) _defineProperties(Constructor.prototype, protoProps);\n if (staticProps) _defineProperties(Constructor, staticProps);\n Object.defineProperty(Constructor, \"prototype\", {\n writable: false\n });\n return Constructor;\n}","export default function _defineProperty(obj, key, value) {\n if (key in obj) {\n Object.defineProperty(obj, key, {\n value: value,\n enumerable: true,\n configurable: true,\n writable: true\n });\n } else {\n obj[key] = value;\n }\n\n return obj;\n}","import { eventTarget, triggerEvent } from '@cornerstonejs/core'\nimport { Events } from '../../enums'\nimport { Annotation } from '../../types'\nimport { AnnotationLockChangeEventDetail } from '../../types/EventTypes'\n\n/*\n * Constants\n */\nconst globalLockedAnnotationsSet: Set<Annotation> = new Set()\n\n/*\n * Interface (Public API)\n */\n\n/**\n * Set the \"Locked\" state of a given annotation instance.\n *\n * @triggers ANNOTATION_LOCK_CHANGE\n *\n * @param annotation - The annotation instance which will have\n * its locked state changed. An event will only be triggered if the locked state\n * of the given annotation instance changed.\n * @param locked - A boolean value indicating if the instance should\n * be locked (true) or not (false)\n */\nfunction setAnnotationLocked(annotation: Annotation, locked = true): void {\n const detail = makeEventDetail()\n if (annotation) {\n if (locked) {\n lock(annotation, globalLockedAnnotationsSet, detail)\n } else {\n unlock(annotation, globalLockedAnnotationsSet, detail)\n }\n }\n publish(detail, globalLockedAnnotationsSet)\n}\n\n/**\n * Clears all the locked annotation\n *\n */\nfunction unlockAllAnnotations(): void {\n const detail = makeEventDetail()\n clearLockedAnnotationsSet(globalLockedAnnotationsSet, detail)\n publish(detail, globalLockedAnnotationsSet)\n}\n\n/**\n * Returns an array of all the annotation that is currently locked\n * @returns An array of tool specific annotation objects.\n *\n */\nfunction getAnnotationsLocked(): Array<Annotation> {\n return Array.from(globalLockedAnnotationsSet)\n}\n\n/**\n * Given a Annotation object, return true if it is locked.\n * @param annotation - Annotation\n * @returns A boolean value.\n */\nfunction isAnnotationLocked(annotation: Annotation): boolean {\n return globalLockedAnnotationsSet.has(annotation)\n}\n\n/**\n * Get the number of locked annotation objects in the global set of locked annotation\n * objects.\n * @returns The number of locked annotation objects.\n *\n */\nfunction getAnnotationsLockedCount(): number {\n return globalLockedAnnotationsSet.size\n}\n\n/**\n * Properly initialize the isLocked on annotation, and set it as locked if\n * isLocked is true.\n * @param annotation - The annotation object to be checked.\n */\nfunction checkAndDefineIsLockedProperty(annotation: Annotation): void {\n if (annotation) {\n const isLocked = !!annotation.isLocked\n if (shouldDefineIsLockedProperty(annotation)) {\n Object.defineProperty(annotation, 'isLocked', {\n configurable: false,\n enumerable: true,\n set: setIsLocked,\n get: getIsLocked,\n })\n }\n setAnnotationLocked(annotation, isLocked)\n }\n}\n\n/*\n * Private Helpers\n */\n\nfunction makeEventDetail(): AnnotationLockChangeEventDetail {\n return Object.freeze({\n added: [],\n removed: [],\n locked: [],\n })\n}\n\nfunction lock(\n annotation: Annotation,\n lockedAnnotationsSet: Set<Annotation>,\n detail: AnnotationLockChangeEventDetail\n): void {\n if (!lockedAnnotationsSet.has(annotation)) {\n lockedAnnotationsSet.add(annotation)\n detail.added.push(annotation)\n }\n}\n\nfunction unlock(\n annotation: Annotation,\n lockedAnnotationsSet: Set<Annotation>,\n detail: AnnotationLockChangeEventDetail\n): void {\n if (lockedAnnotationsSet.delete(annotation)) {\n detail.removed.push(annotation)\n }\n}\n\nfunction clearLockedAnnotationsSet(\n lockedAnnotationsSet: Set<Annotation>,\n detail: AnnotationLockChangeEventDetail\n): void {\n lockedAnnotationsSet.forEach((annotation) => {\n unlock(annotation, lockedAnnotationsSet, detail)\n })\n}\n\nfunction publish(\n detail: AnnotationLockChangeEventDetail,\n lockedAnnotationsSet: Set<Annotation>\n) {\n if (detail.added.length > 0 || detail.removed.length > 0) {\n lockedAnnotationsSet.forEach((item) => void detail.locked.push(item))\n triggerEvent(eventTarget, Events.ANNOTATION_LOCK_CHANGE, detail)\n }\n}\n\nfunction shouldDefineIsLockedProperty(annotation: Annotation): boolean {\n const descriptor = Object.getOwnPropertyDescriptor(annotation, 'isLocked')\n if (descriptor) {\n return (\n descriptor.configurable &&\n (descriptor.set !== setIsLocked || descriptor.get !== getIsLocked)\n )\n }\n return Object.isExtensible(annotation)\n}\n\nfunction setIsLocked(locked: boolean) {\n setAnnotationLocked(this as Annotation, locked)\n}\n\nfunction getIsLocked() {\n return isAnnotationLocked(this as Annotation)\n}\n\n/*\n * Exports\n */\n\nexport {\n setAnnotationLocked,\n getAnnotationsLocked,\n getAnnotationsLockedCount,\n unlockAllAnnotations,\n isAnnotationLocked,\n checkAndDefineIsLockedProperty,\n}\n","import {\n Annotation,\n Annotations,\n FrameOfReferenceSpecificAnnotations,\n AnnotationState,\n} from '../../types/AnnotationTypes'\nimport cloneDeep from 'lodash.clonedeep'\n\nimport {\n Enums,\n eventTarget,\n Types,\n utilities,\n} from '@cornerstonejs/core'\n\nimport { checkAndDefineIsLockedProperty } from './annotationLocking'\n\ninterface FilterInterface {\n FrameOfReferenceUID?: string\n toolName?: string\n}\n\n/**\n * This class stores annotations in per FrameOfReference. Tool coordinates are\n * in the world coordinates for the viewports, which is the patient coordinate system for DICOM.\n *\n * Each FrameOfReferenceSpecificAnnotationManager is separate, so it is be possible\n * to render different annotations of the same tool on different viewports that share\n * the same FrameOfReferenceUID, however no core tool in this library currently does this.\n * This could be useful for e.g. viewing two different reads of the same data side-by-side.\n *\n * Note that this class is a singleton and should not be instantiated directly.\n * To get the stored annotations information you can use ToolState helpers.\n *\n */\nexport default class FrameOfReferenceSpecificAnnotationManager {\n private annotations: AnnotationState\n public readonly uid: string\n\n /**\n * @param uid - The uid of the state manager. If omitted it is autogenerated.\n */\n constructor(uid?: string) {\n if (!uid) {\n uid = utilities.uuidv4()\n }\n this.annotations = {}\n this.uid = uid\n\n // Listen to the IMAGE_VOLUME_MODIFIED event to invalidate data.\n eventTarget.addEventListener(\n Enums.Events.IMAGE_VOLUME_MODIFIED,\n this._imageVolumeModifiedHandler\n )\n }\n\n /**\n * When a volume is modified we invalidate all of the `annotations` on the\n * volume's `FrameOfReferenceUID`. This is mainly to update statistics calculations\n * when an annotation is drawn whilst data is still loading.\n *\n * @param evt - The IMAGE_VOLUME_MODIFIED rendering event.\n */\n _imageVolumeModifiedHandler = (\n evt: Types.EventTypes.ImageVolumeModifiedEvent\n ) => {\n const eventDetail = evt.detail\n const { FrameOfReferenceUID } = eventDetail\n\n const annotations = this.annotations\n const frameOfReferenceSpecificAnnotations = annotations[FrameOfReferenceUID]\n\n if (!frameOfReferenceSpecificAnnotations) {\n return\n }\n\n Object.keys(frameOfReferenceSpecificAnnotations).forEach((toolName) => {\n const toolSpecificAnnotations =\n frameOfReferenceSpecificAnnotations[toolName]\n\n toolSpecificAnnotations.forEach((annotation) => {\n const invalidated = annotation.invalidated\n\n if (invalidated !== undefined) {\n annotation.invalidated = true\n }\n })\n })\n }\n\n /**\n * Returns all the available frameOfReferences inside the state manager\n * @returns - All the registered frame of references inside the manager\n */\n getFramesOfReference = (): Array<string> => {\n return Object.keys(this.annotations)\n }\n\n /**\n * get all tools `Annotations` for the provided FrameOfReference\n *\n * @param FrameOfReferenceUID - The UID of the FrameOfReference to retrieve data for.\n * @returns FrameOfReferenceSpecificAnnotations\n */\n getFrameOfReferenceAnnotations = (\n FrameOfReferenceUID: string\n ): FrameOfReferenceSpecificAnnotations => {\n return this.annotations[FrameOfReferenceUID]\n }\n\n /**\n * Get `Annotations` from the the manager given the `FrameOfReferenceUID` and `toolName`.\n *\n * @param FrameOfReferenceUID - The UID of the FrameOfReference to retrieve data for.\n * @param toolName - The name of the tool to retrieve data for.\n */\n get = (\n FrameOfReferenceUID: string,\n toolName: string\n ): Annotations | undefined => {\n const frameOfReferenceSpecificAnnotations =\n this.annotations[FrameOfReferenceUID]\n\n if (!frameOfReferenceSpecificAnnotations) {\n return\n }\n\n return frameOfReferenceSpecificAnnotations[toolName]\n }\n\n /**\n * Given the unique identified for the some `annotation`, returns the `annotation`\n * from the `annotations`. Searches are more efficient if either/both of\n * the `FrameOfReferenceUID` and the `toolName` are given by the `filter`.\n *\n * @param annotationUID - The unique identifier of the `annotation`.\n * @param filter - A `filter` which reduces the scope of the search.\n *\n * @returns The retrieved `annotation`.\n */\n getAnnotation = (\n annotationUID: string,\n filter: FilterInterface = {}\n ): Annotation | undefined => {\n const toolSpecificAnnotationsAndIndex =\n this._getToolSpecificAnnotationsAndIndex(annotationUID, filter)\n\n if (!toolSpecificAnnotationsAndIndex) {\n return\n }\n\n const { toolSpecificAnnotations, index } = toolSpecificAnnotationsAndIndex\n\n return toolSpecificAnnotations[index]\n }\n\n /**\n * Adds an instance of `Annotation` to the `annotations`.\n *\n * @param annotation - The annotation to add.\n */\n addAnnotation = (annotation: Annotation): void => {\n const { metadata } = annotation\n const { FrameOfReferenceUID, toolName } = metadata\n\n const annotations = this.annotations\n\n let frameOfReferenceSpecificAnnotations = annotations[FrameOfReferenceUID]\n\n if (!frameOfReferenceSpecificAnnotations) {\n annotations[FrameOfReferenceUID] = {}\n\n frameOfReferenceSpecificAnnotations = annotations[FrameOfReferenceUID]\n }\n\n let toolSpecificAnnotations = frameOfReferenceSpecificAnnotations[toolName]\n\n if (!toolSpecificAnnotations) {\n frameOfReferenceSpecificAnnotations[toolName] = []\n\n toolSpecificAnnotations = frameOfReferenceSpecificAnnotations[toolName]\n }\n\n toolSpecificAnnotations.push(annotation)\n checkAndDefineIsLockedProperty(annotation)\n }\n\n /**\n * Removes an instance of `Annotation` from the `annotations`.\n *\n * @param annotation - The annotation to remove.\n */\n // removeAnnotation = (annotation: Annotation): void => {\n // const { metadata } = annotation\n // const { FrameOfReferenceUID, toolName, annotationUID } = metadata\n // const annotations = this.annotations\n\n // const frameOfReferenceSpecificAnnotations = annotations[FrameOfReferenceUID]\n\n // if (!frameOfReferenceSpecificAnnotations) {\n // throw new Error(\n // `frameOfReferenceSpecificAnnotations with FrameOfReferenceUID ${FrameOfReferenceUID} does not exist.`\n // )\n // }\n\n // const toolSpecificAnnotations = frameOfReferenceSpecificAnnotations[toolName]\n // if (!toolSpecificAnnotations) {\n // throw new Error(\n // `toolSpecificAnnotations for toolName ${toolName} on FrameOfReferenceUID ${FrameOfReferenceUID} does not exist.`\n // )\n // }\n\n // const index = toolSpecificAnnotations.findIndex(\n // (annotation) => annotation.metadata.annotationUID === annotationUID\n // )\n\n // toolSpecificAnnotations.splice(index, 1)\n\n // // remove tool specific annotations if no annotation is left\n // if (!toolSpecificAnnotations.length) {\n // delete frameOfReferenceSpecificAnnotations[toolName]\n // }\n\n // // Make sure it is not held in the global set of locked instances\n // setAnnotationLocked(annotation, false)\n // }\n\n /**\n * Given the unique identified for the some `annotation`, removes the `annotation`\n * from the `annotations`. Searches are more efficient if either/both of\n * the `FrameOfReferenceUID` and the `toolName` are given by the `filter`.\n *\n * @param annotationUID - The unique identifier of the `annotation` to remove.\n * @param filter - A `filter` which reduces the scope of the search.\n */\n removeAnnotation = (annotationUID: string, filter: FilterInterface = {}) => {\n const toolSpecificAnnotationsAndIndex =\n this._getToolSpecificAnnotationsAndIndex(annotationUID, filter)\n\n if (!toolSpecificAnnotationsAndIndex) {\n return\n }\n\n const { toolSpecificAnnotations, index } = toolSpecificAnnotationsAndIndex\n const { metadata } = toolSpecificAnnotations[0]\n\n toolSpecificAnnotations.splice(index, 1)\n\n // remove tool specific annotations if no annotation is left\n if (!toolSpecificAnnotations.length) {\n const { toolName } = metadata\n delete this.annotations[metadata.FrameOfReferenceUID][toolName]\n }\n }\n\n /**\n * Returns a section of the annotations. Useful for serialization.\n *\n * - If no arguments are given, the entire `AnnotationState` instance is returned.\n * - If the `FrameOfReferenceUID` is given, the corresponding\n * `FrameOfReferenceSpecificAnnotations` instance is returned.\n * - If both the `FrameOfReferenceUID` and the `toolName` are are given, the\n * corresponding `Annotations` instance is returned.\n *\n * @param FrameOfReferenceUID - A filter string for returning the `annotations` of a specific frame of reference.\n * @param toolName - A filter string for returning `annotations` for a specific tool on a specific frame of reference.\n *\n * @returns The retrieved `annotation`.\n */\n saveAnnotations = (\n FrameOfReferenceUID?: string,\n toolName?: string\n ): AnnotationState | FrameOfReferenceSpecificAnnotations | Annotations => {\n const annotations = this.annotations\n\n if (FrameOfReferenceUID && toolName) {\n const frameOfReferenceSpecificAnnotations =\n annotations[FrameOfReferenceUID]\n\n if (!frameOfReferenceSpecificAnnotations) {\n return\n }\n\n const toolSpecificAnnotations =\n frameOfReferenceSpecificAnnotations[toolName]\n\n return cloneDeep(toolSpecificAnnotations)\n } else if (FrameOfReferenceUID) {\n const frameOfReferenceSpecificAnnotations =\n annotations[FrameOfReferenceUID]\n\n return cloneDeep(frameOfReferenceSpecificAnnotations)\n }\n\n return cloneDeep(annotations)\n }\n\n /**\n * Restores a section of the `annotations`. Useful for loading in serialized data.\n *\n * - If no arguments are given, the entire `AnnotationState` instance is restored.\n * - If the `FrameOfReferenceUID` is given, the corresponding\n * `FrameOfReferenceSpecificAnnotations` instance is restored.\n * - If both the `FrameOfReferenceUID` and the `toolName` are are given, the\n * corresponding `Annotations` instance is restored.\n *\n * @param FrameOfReferenceUID - A filter string for restoring only the `annotations` of a specific frame of reference.\n * @param toolName - A filter string for restoring `annotation` for a specific tool on a specific frame of reference.\n */\n restoreAnnotations = (\n state: AnnotationState | FrameOfReferenceSpecificAnnotations | Annotations,\n FrameOfReferenceUID?: string,\n toolName?: string\n ): void => {\n const annotations = this.annotations\n\n if (FrameOfReferenceUID && toolName) {\n // Set Annotations for FrameOfReferenceUID and toolName.\n\n let frameOfReferenceSpecificAnnotations = annotations[FrameOfReferenceUID]\n\n if (!frameOfReferenceSpecificAnnotations) {\n annotations[FrameOfReferenceUID] = {}\n\n frameOfReferenceSpecificAnnotations = annotations[FrameOfReferenceUID]\n }\n\n frameOfReferenceSpecificAnnotations[toolName] = <Annotations>state\n } else if (FrameOfReferenceUID) {\n // Set FrameOfReferenceSpecificAnnotations for FrameOfReferenceUID.\n\n annotations[FrameOfReferenceUID] = <FrameOfReferenceSpecificAnnotations>(\n state\n )\n } else {\n // Set entire annotations\n\n this.annotations = <AnnotationState>cloneDeep(state)\n }\n }\n\n /**\n * Given the unique identifier for a tool, returns the `Annotations`\n * it belongs to, and the `index` of its position in that array.\n *\n * @param annotationUID - The unique identifier of the `annotation`.\n * @param filter - A `filter` which reduces the scope of the search.\n *\n * @returns {object}\n * @returns {object.toolSpecificAnnotations} The `Annotations` instance containing the `annotation`.\n * @returns {object.index} The `index` of the `annotation` in the `toolSpecificAnnotations` array.\n *\n * @internal\n */\n private _getToolSpecificAnnotationsAndIndex(\n annotationUID: string,\n filter: FilterInterface\n ): { toolSpecificAnnotations: Annotations; index: number } {\n const { toolName, FrameOfReferenceUID } = filter\n const annotations = this.annotations\n\n let frameOfReferenceUIDKeys\n\n if (FrameOfReferenceUID) {\n frameOfReferenceUIDKeys = [FrameOfReferenceUID]\n } else {\n frameOfReferenceUIDKeys = Object.keys(annotations)\n }\n\n const numFrameOfReferenceUIDKeys = frameOfReferenceUIDKeys.length\n\n for (let i = 0; i < numFrameOfReferenceUIDKeys; i++) {\n const frameOfReferenceUID = frameOfReferenceUIDKeys[i]\n const frameOfReferenceSpecificAnnotations =\n annotations[frameOfReferenceUID]\n\n let toolNameKeys\n\n if (toolName) {\n toolNameKeys = [toolName]\n } else {\n toolNameKeys = Object.keys(frameOfReferenceSpecificAnnotations)\n }\n\n const numToolNameKeys = toolNameKeys.length\n\n for (let j = 0; j < numToolNameKeys; j++) {\n const toolName = toolNameKeys[j]\n\n const toolSpecificAnnotations =\n frameOfReferenceSpecificAnnotations[toolName]\n\n const index = toolSpecificAnnotations.findIndex(\n (annotation) => annotation.annotationUID === annotationUID\n )\n\n if (index !== -1) {\n return { toolSpecificAnnotations, index }\n }\n }\n }\n }\n}\n\nconst defaultFrameOfReferenceSpecificAnnotationManager =\n new FrameOfReferenceSpecificAnnotationManager('DEFAULT')\n\nexport { defaultFrameOfReferenceSpecificAnnotationManager }\n","import {\n getEnabledElement,\n triggerEvent,\n eventTarget,\n utilities as csUtils,\n} from '@cornerstonejs/core'\nimport { Events } from '../../enums'\nimport { Types } from '@cornerstonejs/core'\nimport { defaultFrameOfReferenceSpecificAnnotationManager } from './FrameOfReferenceSpecificAnnotationManager'\nimport { Annotations, Annotation } from '../../types/AnnotationTypes'\n\nimport {\n AnnotationAddedEventDetail,\n AnnotationRemovedEventDetail,\n} from '../../types/EventTypes'\n\n/**\n * It returns the default annotations manager.\n * @returns the singleton default annotations manager.\n */\nfunction getDefaultAnnotationManager() {\n return defaultFrameOfReferenceSpecificAnnotationManager\n}\n\n/**\n * Given an element, return the FrameOfReferenceSpecificStateManager for that\n * element\n * @param element - The element that the state manager is managing the state of.\n * @returns The default state manager\n */\nfunction getViewportSpecificAnnotationManager(\n element?: Types.IEnabledElement | HTMLElement\n) {\n // TODO:\n // We may want multiple FrameOfReferenceSpecificStateManagers.\n // E.g. displaying two different radiologists annotations on the same underlying data/FoR.\n\n // Just return the default for now.\n\n return defaultFrameOfReferenceSpecificAnnotationManager\n}\n\n/**\n * Returns the annotations for the `FrameOfReference` of the `Viewport`\n * being viewed by the cornerstone3D enabled `element`.\n *\n * @param element - The HTML element.\n * @param toolName - The name of the tool.\n * @returns The annotations corresponding to the Frame of Reference and the toolName.\n */\nfunction getAnnotations(element: HTMLElement, toolName: string): Annotations {\n const enabledElement = getEnabledElement(element)\n const annotationManager = getViewportSpecificAnnotationManager(enabledElement)\n const { FrameOfReferenceUID } = enabledElement\n\n return annotationManager.get(FrameOfReferenceUID, toolName)\n}\n\n/**\n * Add the annotation to the annotations for the `FrameOfReference` of the `Viewport`\n * being viewed by the cornerstone3D enabled `element`.\n *\n * @param element - HTMLElement\n * @param annotation - The annotation that is being added to the annotations manager.\n */\nfunction addAnnotation(element: HTMLElement, annotation: Annotation): void {\n const annotationManager = getViewportSpecificAnnotationManager(element)\n\n if (annotation.annotationUID === undefined) {\n annotation.annotationUID = csUtils.uuidv4() as string\n }\n\n annotationManager.addAnnotation(annotation)\n\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n const { viewportUID } = enabledElement\n\n const eventType = Events.ANNOTATION_ADDED\n\n const eventDetail: AnnotationAddedEventDetail = {\n annotation,\n viewportUID,\n renderingEngineUID: renderingEngine.uid,\n }\n\n triggerEvent(eventTarget, eventType, eventDetail)\n}\n\n/**\n * Remove the annotation by UID of the annotation.\n * @param element - HTMLElement\n * @param annotationUID - The unique identifier for the annotation.\n */\nfunction removeAnnotation(element: HTMLElement, annotationUID: string): void {\n const annotationManager = getViewportSpecificAnnotationManager(element)\n\n const annotation = annotationManager.getAnnotation(annotationUID)\n annotationManager.removeAnnotation(annotationUID)\n\n // trigger annotation removed\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n const { viewportUID } = enabledElement\n\n const eventType = Events.ANNOTATION_REMOVED\n\n const eventDetail: AnnotationRemovedEventDetail = {\n annotation,\n viewportUID,\n renderingEngineUID: renderingEngine.uid,\n }\n\n triggerEvent(eventTarget, eventType, eventDetail)\n}\n\n/**\n * Get the Annotation object by its UID\n * @param annotationUID - The unique identifier of the annotation.\n * @param element - The element that the tool is being used on.\n * @returns A Annotation object.\n */\nfunction getAnnotation(\n annotationUID: string,\n element?: HTMLElement\n): Annotation {\n const annotationManager = getViewportSpecificAnnotationManager(element)\n const annotation = annotationManager.getAnnotation(annotationUID)\n\n return annotation\n}\n\nexport {\n getAnnotations,\n addAnnotation,\n getAnnotation,\n removeAnnotation,\n getViewportSpecificAnnotationManager,\n getDefaultAnnotationManager,\n}\n","const CORNERSTONE_COLOR_LUT = [\n [0, 0, 0, 0],\n [221, 84, 84, 255],\n [77, 228, 121, 255],\n [166, 70, 235, 255],\n [189, 180, 116, 255],\n [109, 182, 196, 255],\n [204, 101, 157, 255],\n [123, 211, 94, 255],\n [93, 87, 218, 255],\n [225, 128, 80, 255],\n [73, 232, 172, 255],\n [181, 119, 186, 255],\n [176, 193, 112, 255],\n [105, 153, 200, 255],\n [208, 97, 120, 255],\n [90, 215, 101, 255],\n [135, 83, 222, 255],\n [229, 178, 76, 255],\n [122, 183, 181, 255],\n [190, 115, 171, 255],\n [149, 197, 108, 255],\n [100, 118, 205, 255],\n [212, 108, 93, 255],\n [86, 219, 141, 255],\n [183, 79, 226, 255],\n [233, 233, 72, 255],\n [118, 167, 187, 255],\n [194, 111, 146, 255],\n [116, 201, 104, 255],\n [115, 96, 209, 255],\n [216, 147, 89, 255],\n [82, 223, 188, 255],\n [230, 75, 224, 255],\n [163, 184, 121, 255],\n [114, 143, 191, 255],\n [198, 107, 114, 255],\n [99, 206, 122, 255],\n [153, 92, 213, 255],\n [220, 192, 85, 255],\n [78, 215, 227, 255],\n [234, 71, 173, 255],\n [141, 188, 117, 255],\n [110, 113, 195, 255],\n [202, 128, 103, 255],\n [95, 210, 157, 255],\n [195, 88, 217, 255],\n [206, 224, 81, 255],\n [74, 166, 231, 255],\n [185, 120, 139, 255],\n [113, 192, 113, 255],\n [133, 106, 199, 255],\n [207, 162, 98, 255],\n [91, 214, 198, 255],\n [221, 84, 198, 255],\n [159, 228, 77, 255],\n [70, 111, 235, 255],\n [189, 119, 116, 255],\n [109, 196, 138, 255],\n [165, 101, 204, 255],\n [211, 201, 94, 255],\n [87, 191, 218, 255],\n [225, 80, 153, 255],\n [106, 232, 73, 255],\n [124, 119, 186, 255],\n [193, 142, 112, 255],\n [105, 200, 168, 255],\n [203, 97, 208, 255],\n [184, 215, 90, 255],\n [83, 147, 222, 255],\n [229, 76, 101, 255],\n [122, 183, 130, 255],\n [146, 115, 190, 255],\n [197, 171, 108, 255],\n [100, 205, 205, 255],\n [212, 93, 177, 255],\n [141, 219, 86, 255],\n [79, 97, 226, 255],\n [233, 99, 72, 255],\n [118, 187, 150, 255],\n [173, 111, 194, 255],\n [197, 201, 104, 255],\n [96, 171, 209, 255],\n [216, 89, 137, 255],\n [94, 223, 82, 255],\n [107, 75, 230, 255],\n [184, 153, 121, 255],\n [114, 191, 175, 255],\n [198, 107, 191, 255],\n [166, 206, 99, 255],\n [92, 132, 213, 255],\n [220, 85, 91, 255],\n [78, 227, 115, 255],\n [159, 71, 234, 255],\n [188, 176, 117, 255],\n [110, 185, 195, 255],\n [202, 103, 161, 255],\n [129, 210, 95, 255],\n [88, 88, 217, 255],\n [224, 123, 81, 255],\n [74, 231, 166, 255],\n [177, 120, 185, 255],\n [179, 192, 113, 255],\n [106, 156, 199, 255],\n [207, 98, 125, 255],\n [91, 214, 96, 255],\n [130, 84, 221, 255],\n [228, 171, 77, 255],\n [70, 235, 221, 255],\n [189, 116, 174, 255],\n [153, 196, 109, 255],\n [101, 123, 204, 255],\n [211, 104, 94, 255],\n [87, 218, 136, 255],\n [177, 80, 225, 255],\n [232, 225, 73, 255],\n [119, 169, 186, 255],\n [193, 112, 149, 255],\n [121, 200, 105, 255],\n [111, 97, 208, 255],\n [215, 142, 90, 255],\n [83, 222, 181, 255],\n [229, 76, 229, 255],\n [165, 183, 122, 255],\n [115, 146, 190, 255],\n [197, 108, 119, 255],\n [100, 205, 118, 255],\n [148, 93, 212, 255],\n [219, 186, 86, 255],\n [79, 220, 226, 255],\n [233, 72, 179, 255],\n [144, 187, 118, 255],\n [111, 118, 194, 255],\n [201, 124, 104, 255],\n [96, 209, 153, 255],\n [189, 89, 216, 255],\n [211, 223, 82, 255],\n [75, 172, 230, 255],\n [184, 121, 142, 255],\n [117, 191, 114, 255],\n [130, 107, 198, 255],\n [206, 157, 99, 255],\n [92, 213, 193, 255],\n [220, 85, 203, 255],\n [165, 227, 78, 255],\n [71, 118, 234, 255],\n [188, 117, 117, 255],\n [110, 195, 135, 255],\n [161, 103, 202, 255],\n [210, 195, 95, 255],\n [88, 195, 217, 255],\n [224, 81, 158, 255],\n [113, 231, 74, 255],\n [123, 120, 185, 255],\n [192, 139, 113, 255],\n [106, 199, 164, 255],\n [198, 98, 207, 255],\n [188, 214, 91, 255],\n [84, 153, 221, 255],\n [228, 77, 108, 255],\n [70, 235, 84, 255],\n [143, 116, 189, 255],\n [196, 167, 109, 255],\n [101, 204, 199, 255],\n [211, 94, 182, 255],\n [147, 218, 87, 255],\n [80, 104, 225, 255],\n [232, 93, 73, 255],\n [119, 186, 147, 255],\n [170, 112, 193, 255],\n [200, 200, 105, 255],\n [97, 175, 208, 255],\n [215, 90, 142, 255],\n [100, 222, 83, 255],\n [101, 76, 229, 255],\n [183, 150, 122, 255],\n [115, 190, 171, 255],\n [197, 108, 194, 255],\n [170, 205, 100, 255],\n [93, 138, 212, 255],\n [219, 86, 97, 255],\n [79, 226, 110, 255],\n [153, 72, 233, 255],\n [187, 173, 118, 255],\n [111, 187, 194, 255],\n [201, 104, 165, 255],\n [134, 209, 96, 255],\n [89, 95, 216, 255],\n [223, 117, 82, 255],\n [75, 230, 159, 255],\n [174, 121, 184, 255],\n [182, 191, 114, 255],\n [107, 160, 198, 255],\n [206, 99, 130, 255],\n [92, 213, 92, 255],\n [124, 85, 220, 255],\n [227, 165, 78, 255],\n [71, 234, 214, 255],\n [188, 117, 176, 255],\n [156, 195, 110, 255],\n [103, 128, 202, 255],\n [210, 100, 95, 255],\n [88, 217, 131, 255],\n [170, 81, 224, 255],\n [231, 218, 74, 255],\n [120, 172, 185, 255],\n [192, 113, 153, 255],\n [125, 199, 106, 255],\n [107, 98, 207, 255],\n [214, 137, 91, 255],\n [84, 221, 175, 255],\n [222, 77, 228, 255],\n [194, 235, 70, 255],\n [116, 149, 189, 255],\n [196, 109, 123, 255],\n [101, 204, 114, 255],\n [143, 94, 211, 255],\n [218, 180, 87, 255],\n [80, 225, 225, 255],\n [232, 73, 186, 255],\n [147, 186, 119, 255],\n [112, 122, 193, 255],\n [200, 121, 105, 255],\n [97, 208, 148, 255],\n [184, 90, 215, 255],\n [216, 222, 83, 255],\n [76, 178, 229, 255],\n [183, 122, 145, 255],\n [121, 190, 115, 255],\n [126, 108, 197, 255],\n [205, 153, 100, 255],\n [93, 212, 187, 255],\n [219, 86, 208, 255],\n [171, 226, 79, 255],\n [72, 126, 233, 255],\n [187, 118, 121, 255],\n [111, 194, 132, 255],\n [157, 104, 201, 255],\n [209, 190, 96, 255],\n [89, 200, 216, 255],\n [223, 82, 164, 255],\n [120, 230, 75, 255],\n [121, 121, 184, 255],\n [191, 136, 114, 255],\n [107, 198, 160, 255],\n [192, 99, 206, 255],\n [193, 213, 92, 255],\n [85, 158, 220, 255],\n [227, 78, 115, 255],\n [71, 234, 78, 255],\n [141, 117, 188, 255],\n [195, 163, 110, 255],\n [103, 202, 194, 255],\n [210, 95, 186, 255],\n [153, 217, 88, 255],\n [81, 111, 224, 255],\n]\n\nexport default CORNERSTONE_COLOR_LUT\n","import cloneDeep from 'lodash.clonedeep'\nimport { utilities as csUtils } from '@cornerstonejs/core'\n\nimport CORNERSTONE_COLOR_LUT from './helpers/COLOR_LUT'\n\nimport {\n SegmentationState,\n GlobalSegmentationState,\n GlobalSegmentationData,\n ColorLUT,\n ToolGroupSpecificSegmentationData,\n ToolGroupSpecificSegmentationState,\n SegmentationConfig,\n} from '../../types/SegmentationStateTypes'\n\n/* A default initial state for the segmentation manager. */\nconst initialDefaultState = {\n colorLutTables: [],\n global: {\n segmentations: [],\n config: {\n renderInactiveSegmentations: true,\n representations: {},\n },\n },\n toolGroups: {},\n}\n\n/**\n * The SegmentationStateManager Class is responsible for managing the state of the\n * segmentations. It stores a global state and a toolGroup specific state.\n * In global state it stores the global configuration of each segmentation,\n * but in toolGroup specific state it stores the toolGroup specific configuration\n * which will override the global configuration.\n *\n * Note that this is a singleton state manager.\n */\nexport default class SegmentationStateManager {\n private state: SegmentationState\n public readonly uid: string\n\n constructor(uid?: string) {\n if (!uid) {\n uid = csUtils.uuidv4()\n }\n this.state = cloneDeep(initialDefaultState)\n this.uid = uid\n }\n\n /**\n * It returns a copy of the current state of the segmentation\n * @returns A deep copy of the state.\n */\n getState(): SegmentationState {\n return cloneDeep(this.state)\n }\n\n /**\n * It returns an array of toolGroupUIDs currently in the segmentation state.\n * @returns An array of strings.\n */\n getToolGroups(): string[] {\n return Object.keys(this.state.toolGroups)\n }\n\n /**\n * It returns the colorLut at the specified index.\n * @param lutIndex - The index of the color LUT to retrieve.\n * @returns A ColorLUT object.\n */\n getColorLut(lutIndex: number): ColorLUT | undefined {\n return this.state.colorLutTables[lutIndex]\n }\n\n /**\n * Reset the state to the default state\n */\n resetState(): void {\n this.state = cloneDeep(initialDefaultState)\n }\n\n /**\n * Given a segmentation UID, return the global segmentation data for that\n * segmentation\n * @param segmentationUID - The UID of the segmentation to get the\n * global data for.\n * @returns - The global segmentation data for the\n * segmentation with the given UID.\n */\n getGlobalSegmentationData(\n segmentationUID: string\n ): GlobalSegmentationData | undefined {\n return this.state.global.segmentations?.find(\n (segmentationState) => segmentationState.volumeUID === segmentationUID\n )\n }\n\n /**\n * Get the global segmentation state for all the segmentations in the\n * segmentation state manager.\n * @returns An array of GlobalSegmentationData.\n */\n getGlobalSegmentationState(): GlobalSegmentationState | [] {\n return this.state.global.segmentations\n }\n\n /**\n * Get the global config containing both representation config\n * and render inactive segmentations config\n * @returns The global config object.\n */\n getGlobalSegmentationConfig(): SegmentationConfig {\n return this.state.global.config\n }\n\n /**\n * It sets the global segmentation config including both representation config\n * and render inactive segmentations config\n * @param config - The global configuration for the segmentations.\n */\n setGlobalSegmentationConfig(config: SegmentationConfig): void {\n this.state.global.config = config\n }\n\n /**\n * Given a segmentation UID, return a list of tool group UIDs that have that\n * segmentation in their segmentation state (segmentation has been added\n * to the tool group).\n * @param segmentationUID - The UID of the segmentation volume.\n * @returns An array of toolGroupUIDs.\n */\n getToolGroupsWithSegmentation(segmentationUID: string): string[] {\n const toolGroupUIDs = Object.keys(this.state.toolGroups)\n\n const foundToolGroupUIDs = []\n toolGroupUIDs.forEach((toolGroupUID) => {\n const toolGroupSegmentationState = this.getSegmentationState(\n toolGroupUID\n ) as ToolGroupSpecificSegmentationState\n\n const segmentationData = toolGroupSegmentationState.find(\n (segmentationData) => segmentationData.volumeUID === segmentationUID\n )\n\n if (segmentationData) {\n foundToolGroupUIDs.push(toolGroupUID)\n }\n })\n\n return foundToolGroupUIDs\n }\n\n /**\n * Get the segmentation state for the toolGroup containing array of\n * segmentation data objects.\n *\n * @param toolGroupUID - The UID of the tool group that the segmentation\n * belongs to.\n * @returns An array of objects, each of which contains the data for a single\n * segmentation data\n */\n getSegmentationState(\n toolGroupUID: string\n ): ToolGroupSpecificSegmentationState | [] {\n const toolGroupSegmentationState = this.state.toolGroups[toolGroupUID]\n\n if (!toolGroupSegmentationState) {\n return []\n }\n\n return this.state.toolGroups[toolGroupUID].segmentations\n }\n\n /**\n * Given a tool group UID and a representation type, return toolGroup specific\n * config for that representation type.\n *\n * @param toolGroupUID - The UID of the tool group\n * @param representationType - The type of representation, currently only Labelmap\n * @returns A SegmentationConfig object.\n */\n getSegmentationConfig(toolGroupUID: string): SegmentationConfig | undefined {\n const toolGroupStateWithConfig = this.state.toolGroups[toolGroupUID]\n\n if (!toolGroupStateWithConfig) {\n return\n }\n\n return toolGroupStateWithConfig.config\n }\n\n /**\n * Set the segmentation config for a given tool group. It will create a new\n * tool group specific config if one does not exist.\n *\n * @param toolGroupUID - The UID of the tool group that the segmentation\n * belongs to.\n * @param config - SegmentationConfig\n */\n setSegmentationConfig(\n toolGroupUID: string,\n config: SegmentationConfig\n ): void {\n let toolGroupStateWithConfig = this.state.toolGroups[toolGroupUID]\n\n if (!toolGroupStateWithConfig) {\n this.state.toolGroups[toolGroupUID] = {\n segmentations: [],\n config: {\n renderInactiveSegmentations: true,\n representations: {},\n },\n }\n\n toolGroupStateWithConfig = this.state.toolGroups[toolGroupUID]\n }\n\n toolGroupStateWithConfig.config = {\n ...toolGroupStateWithConfig.config,\n ...config,\n }\n }\n\n /**\n * Given a toolGroupUID and a segmentationDataUID, return the segmentation data for that tool group.\n * @param toolGroupUID - The UID of the tool group that the segmentation\n * data belongs to.\n * @param segmentationDataUID - string\n * @returns A ToolGroupSpecificSegmentationData object.\n */\n getSegmentationDataByUID(\n toolGroupUID: string,\n segmentationDataUID: string\n ): ToolGroupSpecificSegmentationData | undefined {\n const toolGroupSegState = this.getSegmentationState(\n toolGroupUID\n ) as ToolGroupSpecificSegmentationState\n\n const segmentationData = toolGroupSegState.find(\n (segData) => segData.segmentationDataUID === segmentationDataUID\n )\n\n return segmentationData\n }\n\n /**\n * Get the active segmentation data for a tool group\n * @param toolGroupUID - The UID of the tool group that the segmentation\n * data belongs to.\n * @returns A ToolGroupSpecificSegmentationData object.\n */\n getActiveSegmentationData(\n toolGroupUID: string\n ): ToolGroupSpecificSegmentationData | undefined {\n const toolGroupSegState = this.getSegmentationState(\n toolGroupUID\n ) as ToolGroupSpecificSegmentationState\n\n return toolGroupSegState.find((segmentationData) => segmentationData.active)\n }\n\n /**\n * It adds a color LUT to the state.\n * @param colorLut - ColorLUT\n * @param lutIndex - The index of the color LUT table to add.\n */\n addColorLUT(colorLut: ColorLUT, lutIndex: number): void {\n if (this.state.colorLutTables[lutIndex]) {\n console.log('Color LUT table already exists, overwriting')\n }\n\n this.state.colorLutTables[lutIndex] = colorLut\n }\n\n /**\n * It adds a new segmentation to the global segmentation state. It will merge\n * the segmentation data with the existing global segmentation data if it exists.\n * @param segmentationData - GlobalSegmentationData\n */\n addGlobalSegmentationData(segmentationData: GlobalSegmentationData): void {\n const { volumeUID } = segmentationData\n\n // Creating the default color LUT if not created yet\n this._initDefaultColorLutIfNecessary()\n\n // Don't allow overwriting existing labelmapState with the same labelmapUID\n const existingGlobalSegmentationData =\n this.getGlobalSegmentationData(volumeUID)\n\n // merge the new state with the existing state\n const updatedState = {\n ...existingGlobalSegmentationData,\n ...segmentationData,\n }\n\n // Is there any existing state?\n if (!existingGlobalSegmentationData) {\n this.state.global.segmentations.push({\n volumeUID,\n label: segmentationData.label,\n referenceVolumeUID: segmentationData.referenceVolumeUID,\n cachedStats: segmentationData.cachedStats,\n referenceImageId: segmentationData.referenceImageId,\n activeSegmentIndex: segmentationData.activeSegmentIndex,\n segmentsLocked: segmentationData.segmentsLocked,\n })\n\n return\n }\n\n // If there is an existing state, replace it\n const index = this.state.global.segmentations.findIndex(\n (segmentationState) => segmentationState.volumeUID === volumeUID\n )\n this.state.global.segmentations[index] = updatedState\n }\n\n /**\n * Add a new segmentation data to the toolGroup's segmentation state\n * @param toolGroupUID - The UID of the tool group that the segmentation\n * belongs to.\n * @param segmentationData - ToolGroupSpecificSegmentationData\n */\n addSegmentationData(\n toolGroupUID: string,\n segmentationData: ToolGroupSpecificSegmentationData\n ): void {\n // Initialize the default toolGroup state if not created yet\n if (!this.state.toolGroups[toolGroupUID]) {\n this.state.toolGroups[toolGroupUID] = {\n segmentations: [],\n config: {} as SegmentationConfig,\n }\n }\n\n // local toolGroupSpecificSegmentationState\n this.state.toolGroups[toolGroupUID].segmentations.push(segmentationData)\n this._handleActiveSegmentation(toolGroupUID, segmentationData)\n }\n\n /**\n * Set the active segmentation data for a tool group\n * @param toolGroupUID - The UID of the tool group that owns the\n * segmentation data.\n * @param segmentationDataUID - string\n */\n setActiveSegmentationData(\n toolGroupUID: string,\n segmentationDataUID: string\n ): void {\n const toolGroupSegmentations = this.getSegmentationState(toolGroupUID)\n\n if (!toolGroupSegmentations || !toolGroupSegmentations.length) {\n throw new Error(\n `No segmentation data found for toolGroupUID: ${toolGroupUID}`\n )\n }\n\n const segmentationData = toolGroupSegmentations.find(\n (segmentationData) =>\n segmentationData.segmentationDataUID === segmentationDataUID\n )\n\n if (!segmentationData) {\n throw new Error(\n `No segmentation data found for segmentation data UID ${segmentationDataUID}`\n )\n }\n\n segmentationData.active = true\n this._handleActiveSegmentation(toolGroupUID, segmentationData)\n }\n\n /**\n * Remove a segmentation data from the toolGroup specific segmentation state\n * @param toolGroupUID - The UID of the tool group that the segmentation\n * data is associated with.\n * @param segmentationDataUID - string\n */\n removeSegmentationData(\n toolGroupUID: string,\n segmentationDataUID: string\n ): void {\n const toolGroupSegmentations = this.getSegmentationState(toolGroupUID)\n\n if (!toolGroupSegmentations || !toolGroupSegmentations.length) {\n throw new Error(\n `No viewport specific segmentation state found for viewport ${toolGroupUID}`\n )\n }\n\n const state = toolGroupSegmentations as ToolGroupSpecificSegmentationState\n const index = state.findIndex(\n (segData) => segData.segmentationDataUID === segmentationDataUID\n )\n\n if (index === -1) {\n console.warn(\n `No viewport specific segmentation state data found for viewport ${toolGroupUID} and segmentation data UID ${segmentationDataUID}`\n )\n }\n\n const removedSegmentationData = toolGroupSegmentations[index]\n toolGroupSegmentations.splice(index, 1)\n this._handleActiveSegmentation(toolGroupUID, removedSegmentationData)\n }\n\n /**\n * It handles the active segmentation data based on the active status of the\n * segmentation data that was added or removed.\n *\n * @param toolGroupUID - The UID of the tool group that the segmentation\n * data belongs to.\n * @param recentlyAddedOrRemovedSegmentationData - ToolGroupSpecificSegmentationData\n */\n _handleActiveSegmentation(\n toolGroupUID: string,\n recentlyAddedOrRemovedSegmentationData: ToolGroupSpecificSegmentationData\n ): void {\n const state = this.getSegmentationState(\n toolGroupUID\n ) as ToolGroupSpecificSegmentationState\n\n // 1. If there is no segmentationData, return early\n if (state.length === 0) {\n return\n }\n\n // 2. If there is only one segmentationData, make that one active\n if (state.length === 1) {\n state[0].active = true\n return\n }\n\n // 3. If removed SegmentationData was active, make the first one active\n const activeSegmentations = state.filter(\n (segmentationData) => segmentationData.active\n )\n\n if (activeSegmentations.length === 0) {\n state[0].active = true\n return\n }\n\n // 4. If the added segmentation data is active, make other segmentation data inactive\n if (recentlyAddedOrRemovedSegmentationData.active) {\n state.forEach((segmentationData) => {\n if (\n segmentationData.segmentationDataUID !==\n recentlyAddedOrRemovedSegmentationData.segmentationDataUID\n ) {\n segmentationData.active = false\n }\n })\n }\n\n // 5. if added/removed segmentation is is inactive, do nothing\n }\n\n _initDefaultColorLutIfNecessary() {\n // if colorLutTable is not specified or the default one is not found\n if (\n this.state.colorLutTables.length === 0 ||\n !this.state.colorLutTables[0]\n ) {\n this.addColorLUT(CORNERSTONE_COLOR_LUT as ColorLUT, 0)\n }\n }\n}\n\nconst defaultSegmentationStateManager = new SegmentationStateManager('DEFAULT')\nexport { defaultSegmentationStateManager }\n","import { triggerEvent, eventTarget } from '@cornerstonejs/core'\n\nimport { Events } from '../../enums'\nimport {\n getToolGroupsWithSegmentation,\n getToolGroups,\n getGlobalSegmentationState,\n} from '../../stateManagement/segmentation/segmentationState'\nimport {\n SegmentationStateModifiedEventDetail,\n SegmentationDataModifiedEventDetail,\n SegmentationGlobalStateModifiedEventDetail,\n} from '../../types/EventTypes'\n\n/**\n * Trigger an event on the eventTarget that the segmentation state for\n * toolGroupUID has been updated\n * @param toolGroupUID - The UID of the toolGroup\n */\nfunction triggerSegmentationStateModified(toolGroupUID: string): void {\n const eventDetail: SegmentationStateModifiedEventDetail = {\n toolGroupUID,\n }\n\n triggerEvent(eventTarget, Events.SEGMENTATION_STATE_MODIFIED, eventDetail)\n}\n\n/**\n * Triggers segmentation global state updated event, notifying all toolGroups\n * that the global state has been updated, If a segmentationUID is provided\n * the event will only be triggered for that segmentation, otherwise it will\n * be triggered for all segmentations.\n *\n * @param segmentationUID - The UID of the segmentation that has been updated\n */\nfunction triggerSegmentationGlobalStateModified(\n segmentationUID?: string\n): void {\n let toolGroupUIDs, segmentationUIDs\n\n if (segmentationUID) {\n toolGroupUIDs = getToolGroupsWithSegmentation(segmentationUID)\n segmentationUIDs = [segmentationUID]\n } else {\n // get all toolGroups\n toolGroupUIDs = getToolGroups()\n segmentationUIDs = getGlobalSegmentationState().map(\n ({ volumeUID }) => volumeUID\n )\n }\n\n // 1. Trigger an event notifying all listeners about the segmentationUID\n // that has been updated.\n segmentationUIDs.forEach((segmentationUID) => {\n const eventDetail: SegmentationGlobalStateModifiedEventDetail = {\n segmentationUID,\n }\n triggerEvent(\n eventTarget,\n Events.SEGMENTATION_GLOBAL_STATE_MODIFIED,\n eventDetail\n )\n })\n\n // 2. Notify all viewports that render the segmentationUID in order to update the\n // rendering based on the new global state.\n toolGroupUIDs.forEach((toolGroupUID) => {\n triggerSegmentationStateModified(toolGroupUID)\n })\n}\n\n/**\n * Trigger an event that a segmentation data has been modified\n * @param toolGroupUID - The UID of the tool group that triggered the event.\n * @param segmentationDataUID - The UID of the segmentation data that was modified.\n */\nfunction triggerSegmentationDataModified(\n toolGroupUID: string,\n segmentationDataUID: string\n): void {\n const eventDetail: SegmentationDataModifiedEventDetail = {\n toolGroupUID,\n segmentationDataUID,\n }\n\n triggerEvent(eventTarget, Events.SEGMENTATION_DATA_MODIFIED, eventDetail)\n}\n\nexport {\n // ToolGroup Specific\n triggerSegmentationStateModified,\n // Global\n triggerSegmentationDataModified,\n triggerSegmentationGlobalStateModified,\n}\n","export default function _arrayLikeToArray(arr, len) {\n if (len == null || len > arr.length) len = arr.length;\n\n for (var i = 0, arr2 = new Array(len); i < len; i++) {\n arr2[i] = arr[i];\n }\n\n return arr2;\n}","import arrayLikeToArray from \"./arrayLikeToArray.js\";\nexport default function _unsupportedIterableToArray(o, minLen) {\n if (!o) return;\n if (typeof o === \"string\") return arrayLikeToArray(o, minLen);\n var n = Object.prototype.toString.call(o).slice(8, -1);\n if (n === \"Object\" && o.constructor) n = o.constructor.name;\n if (n === \"Map\" || n === \"Set\") return Array.from(o);\n if (n === \"Arguments\" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return arrayLikeToArray(o, minLen);\n}","import arrayWithHoles from \"./arrayWithHoles.js\";\nimport iterableToArrayLimit from \"./iterableToArrayLimit.js\";\nimport unsupportedIterableToArray from \"./unsupportedIterableToArray.js\";\nimport nonIterableRest from \"./nonIterableRest.js\";\nexport default function _slicedToArray(arr, i) {\n return arrayWithHoles(arr) || iterableToArrayLimit(arr, i) || unsupportedIterableToArray(arr, i) || nonIterableRest();\n}","export default function _arrayWithHoles(arr) {\n if (Array.isArray(arr)) return arr;\n}","export default function _iterableToArrayLimit(arr, i) {\n var _i = arr == null ? null : typeof Symbol !== \"undefined\" && arr[Symbol.iterator] || arr[\"@@iterator\"];\n\n if (_i == null) return;\n var _arr = [];\n var _n = true;\n var _d = false;\n\n var _s, _e;\n\n try {\n for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) {\n _arr.push(_s.value);\n\n if (i && _arr.length === i) break;\n }\n } catch (err) {\n _d = true;\n _e = err;\n } finally {\n try {\n if (!_n && _i[\"return\"] != null) _i[\"return\"]();\n } finally {\n if (_d) throw _e;\n }\n }\n\n return _arr;\n}","export default function _nonIterableRest() {\n throw new TypeError(\"Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}","import type { Types } from '@cornerstonejs/core'\n\n/**\n * With a given vertices coordinates in IJK, it calculates the minimum and maximum\n * coordinate in each axis, and returns them. If dimensions are provided it also\n * clip the min, max to the provided width, height and depth\n *\n * @param vertices - shape vertices coordinates\n * @param dimensions - dimensions of the image\n * @returns [[xMin,xMax],[yMin,yMax], [zMin,zMax]]\n */\nfunction getBoundingBoxAroundShape(\n vertices: Types.Point3[],\n dimensions?: Types.Point3\n): [Types.Point2, Types.Point2, Types.Point2] {\n let xMin = Infinity\n let xMax = 0\n let yMin = Infinity\n let yMax = 0\n let zMin = Infinity\n let zMax = 0\n\n vertices.forEach((v) => {\n xMin = Math.min(v[0], xMin)\n xMax = Math.max(v[0], xMax)\n yMin = Math.min(v[1], yMin)\n yMax = Math.max(v[1], yMax)\n zMin = Math.min(v[2], zMin)\n zMax = Math.max(v[2], zMax)\n })\n\n xMin = Math.floor(xMin)\n xMax = Math.floor(xMax)\n yMin = Math.floor(yMin)\n yMax = Math.floor(yMax)\n zMin = Math.floor(zMin)\n zMax = Math.floor(zMax)\n\n if (dimensions) {\n const [width, height, depth] = dimensions\n xMin = Math.max(0, xMin)\n xMax = Math.min(width, xMax)\n yMin = Math.max(0, yMin)\n yMax = Math.min(height, yMax)\n zMin = Math.max(0, zMin)\n zMax = Math.min(depth, zMax)\n }\n\n return [\n [xMin, xMax],\n [yMin, yMax],\n [zMin, zMax],\n ]\n}\n\n/**\n * Used the current bounds of the 2D rectangle and extends it in the view axis by numSlices\n * It compares min and max of each IJK to find the view axis (for axial, zMin === zMax) and\n * then calculates the extended range. It will assume the slice is relative to the\n * current slice and will add the given slices to the current max of the boundingBox.\n * @param boundsIJK [[iMin, iMax], [jMin, jMax], [kMin, kMax]]\n * @param slices number of slices to project before and after\n * @returns extended bounds\n */\nfunction extend2DBoundingBoxInViewAxis(\n boundsIJK: [Types.Point2, Types.Point2, Types.Point2],\n numSlicesToProject: number\n): [Types.Point2, Types.Point2, Types.Point2] {\n // find which index in boundsIJK has the same first and last value\n const sliceNormalIndex = boundsIJK.findIndex(([min, max]) => min === max)\n\n if (sliceNormalIndex === -1) {\n throw new Error('3D bounding boxes not supported in an oblique plane')\n }\n\n // if (slices instanceof Array) {\n // boundsIJK[sliceNormalIndex][0] = Math.min(...slices)\n // boundsIJK[sliceNormalIndex][1] = Math.max(...slices)\n // return boundsIJK\n // }\n\n // get the index and subtract slices from the min and add to the max\n boundsIJK[sliceNormalIndex][0] -= numSlicesToProject\n boundsIJK[sliceNormalIndex][1] += numSlicesToProject\n return boundsIJK\n}\n\nexport { getBoundingBoxAroundShape, extend2DBoundingBoxInViewAxis }\n\n/**\n * This method takes a bounding box in IJK, and uses the camera, to find the\n * direction of projection (slice normal), then replaces the min and max of the\n * slice number on the correct index of the bounding box.\n * @param boundsIJK [[iMin, iMax], [jMin, jMax], [kMin, kMax]] of bounding box\n * @param sliceNumbers Slice number min and max\n * @param vtkImageData The image data to get the direction from\n * @param viewPlaneNormal The camera view plane normal\n * @returns\n */\n// function extendBoundingBox\n\n// function extend2DBoundingBoxInViewAxis(\n// boundsIJK: [Types.Point2, Types.Point2, Types.Point2],\n// sliceNumbers: number[],\n// vtkImageData: any,\n// viewPlaneNormal: Types.Point3\n// ): [Types.Point2, Types.Point2, Types.Point2] {\n// const direction = vtkImageData.getDirection()\n\n// // Calculate size of spacing vector in normal direction\n// const iVector = direction.slice(0, 3)\n// const jVector = direction.slice(3, 6)\n// const kVector = direction.slice(6, 9)\n\n// const dotProducts = [\n// vec3.dot(iVector, <vec3>viewPlaneNormal),\n// vec3.dot(jVector, <vec3>viewPlaneNormal),\n// vec3.dot(kVector, <vec3>viewPlaneNormal),\n// ]\n\n// // absolute value of dot products\n// const absDotProducts = dotProducts.map((dotProduct) => Math.abs(dotProduct))\n\n// // the dot product will be one for the slice normal\n// const sliceNormalIndex = absDotProducts.indexOf(1)\n\n// boundsIJK[sliceNormalIndex][0] = sliceNumbers[0]\n// boundsIJK[sliceNormalIndex][1] = sliceNumbers[1]\n\n// return boundsIJK\n// }\n","import arrayWithoutHoles from \"./arrayWithoutHoles.js\";\nimport iterableToArray from \"./iterableToArray.js\";\nimport unsupportedIterableToArray from \"./unsupportedIterableToArray.js\";\nimport nonIterableSpread from \"./nonIterableSpread.js\";\nexport default function _toConsumableArray(arr) {\n return arrayWithoutHoles(arr) || iterableToArray(arr) || unsupportedIterableToArray(arr) || nonIterableSpread();\n}","import arrayLikeToArray from \"./arrayLikeToArray.js\";\nexport default function _arrayWithoutHoles(arr) {\n if (Array.isArray(arr)) return arrayLikeToArray(arr);\n}","export default function _iterableToArray(iter) {\n if (typeof Symbol !== \"undefined\" && iter[Symbol.iterator] != null || iter[\"@@iterator\"] != null) return Array.from(iter);\n}","export default function _nonIterableSpread() {\n throw new TypeError(\"Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.\");\n}","let svgNodeCache = {}\n\nexport function resetSvgNodeCache(): void {\n svgNodeCache = {}\n}\n\nexport default svgNodeCache\n","import _cloneDeep from 'lodash.clonedeep'\n\nimport { IToolGroup } from '../types'\nimport Synchronizer from './SynchronizerManager/Synchronizer'\nimport svgNodeCache, { resetSvgNodeCache } from './svgNodeCache'\nimport { BaseTool } from '../tools'\n\ninterface IToolClassReference {\n toolClass: new <T extends BaseTool>(config: any) => T\n}\n\ninterface ICornerstoneTools3dState {\n isInteractingWithTool: boolean\n isMultiPartToolActive: boolean\n tools: Record<string, IToolClassReference>\n toolGroups: Array<IToolGroup>\n synchronizers: Array<Synchronizer>\n svgNodeCache: Record<string, unknown>\n enabledElements: Array<unknown>\n handleRadius: number\n}\n\nconst defaultState: ICornerstoneTools3dState = {\n isInteractingWithTool: false,\n isMultiPartToolActive: false,\n tools: {},\n toolGroups: [],\n synchronizers: [],\n svgNodeCache: svgNodeCache,\n // Should this be named... canvases?\n enabledElements: [], // switch to Uids?\n handleRadius: 6,\n}\n\nlet state: ICornerstoneTools3dState = {\n isInteractingWithTool: false,\n isMultiPartToolActive: false,\n tools: {},\n toolGroups: [],\n synchronizers: [],\n svgNodeCache: svgNodeCache,\n // Should this be named... canvases?\n enabledElements: [], // switch to Uids?\n handleRadius: 6,\n}\n\nfunction resetCornerstoneToolsState(): void {\n resetSvgNodeCache()\n state = _cloneDeep(defaultState)\n}\n\nexport {\n ICornerstoneTools3dState,\n resetCornerstoneToolsState,\n state,\n state as default,\n}\n","import { state } from './state'\n\n/**\n * Adds the tool class to the cornerstoneTools to be used later. This function\n * should be called before creating the toolGroups and adding tools and setting their mode.\n * The flow is:\n * - addTool(ToolClass) // where ToolClass is the tool constructor imported from CornerstoneTools or created by a 3rd party\n * - createToolGroup(toolGroupUID)\n * - toolGroup.addTool(${toolName}) // NOT THE TOOL CLASS\n * - toolGroup.setToolActive(${toolName})\n *\n * @param ToolClass - A tool calls to instantiate.\n * @param toolOptions - The tool-specific configuration options for the tool.\n * @returns\n */\nexport function addTool(ToolClass): void {\n // Check if tool exists and name is not undefined\n const toolName = ToolClass.toolName\n const toolAlreadyAdded = state.tools[toolName] !== undefined\n\n if (!toolName) {\n throw new Error(`No Tool Found for the ToolClass ${ToolClass.name}`)\n }\n\n if (toolAlreadyAdded) {\n throw new Error(`${toolName} has already been added globally`)\n }\n\n // Stores the toolNames and ToolClass to be instantiated in the toolGroup on toolGroup.addTool\n state.tools[toolName] = {\n toolClass: ToolClass,\n }\n}\n\n/**\n * Removes the tool class from the cornerstoneTools.\n *\n * @param ToolClass - A tool calls to instantiate.\n */\nexport function removeTool(ToolClass): void {\n const toolName = ToolClass.toolName\n\n if (!toolName) {\n throw new Error(`No tool found for: ${ToolClass.name}`)\n }\n\n if (!state.tools[toolName] !== undefined) {\n delete state.tools[toolName]\n } else {\n throw new Error(\n `${toolName} cannot be removed because it has not been added`\n )\n }\n}\n\nexport default addTool\n","import { getEnabledElement } from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\n\nimport { IPoints } from '../../types'\n\n/**\n * Given a native mouse event, get the associated cornerstone3D enabled element\n * and derive a set of coordinates useful for tools.\n * @param evt - The Mouse event.\n * @param element - The DOM HTMLElement that the event was triggered on.\n * @returns The points related to the event in the form of a `IPoints` object containing\n * the following properties: `page`, `client`, `canvas`, and `world` details of the event.\n */\nexport default function getMouseEventPoints(\n evt: MouseEvent,\n element?: HTMLElement\n): IPoints {\n const elementToUse = element || (evt.currentTarget as HTMLElement)\n const { viewport } = getEnabledElement(elementToUse)\n const clientPoint = _clientToPoint(evt)\n const pagePoint = _pageToPoint(evt)\n const canvasPoint = _pagePointsToCanvasPoints(elementToUse, pagePoint)\n const worldPoint = viewport.canvasToWorld(canvasPoint)\n\n return {\n page: pagePoint,\n client: clientPoint,\n canvas: canvasPoint,\n world: worldPoint,\n }\n}\n\n/**\n * Converts point from page coordinates to canvas coordinates.\n * @param element - HTMLElement\n * @param pagePoint - Point in page coordinates pageX and pageY\n *\n * @returns The canvas coordinate points\n */\nfunction _pagePointsToCanvasPoints(\n element: HTMLElement,\n pagePoint: Types.Point2\n): Types.Point2 {\n const rect = element.getBoundingClientRect()\n return [\n pagePoint[0] - rect.left - window.pageXOffset,\n pagePoint[1] - rect.top - window.pageYOffset,\n ]\n}\n\n/**\n * Converts the event's `pageX` and `pageY` properties to Types.Point2 format\n *\n * @param evt - The Mouse `Event`\n */\nfunction _pageToPoint(evt: MouseEvent): Types.Point2 {\n return [evt.pageX, evt.pageY]\n}\n\n/**\n * Converts the event's `clientX` and `clientY` properties to Types.Point2 format\n * @param evt - The Mouse `Event`\n */\nfunction _clientToPoint(evt: MouseEvent): Types.Point2 {\n return [evt.clientX, evt.clientY]\n}\n","import {\n getEnabledElement,\n triggerEvent,\n} from '@cornerstonejs/core'\nimport Events from '../../enums/Events'\nimport getMouseEventPoints from './getMouseEventPoints'\nimport { EventTypes, IPoints } from '../../types'\n\n/**\n * Captures and normalizes the double click event. Emits as a cornerstoneTools3D\n * double click event.\n *\n * @param evt - The mouse event.\n */\nfunction mouseDoubleClickListener(evt: MouseEvent): void {\n const element = <HTMLElement>evt.currentTarget\n\n const { viewportUID, renderingEngineUID } = getEnabledElement(element)\n\n const startPoints = getMouseEventPoints(evt, element)\n const deltaPoints: IPoints = {\n page: [0, 0],\n client: [0, 0],\n canvas: [0, 0],\n world: [0, 0, 0],\n }\n\n const eventDetail: EventTypes.MouseDoubleClickEventDetail = {\n event: evt,\n eventName: Events.MOUSE_DOUBLE_CLICK,\n viewportUID,\n renderingEngineUID,\n camera: {},\n element,\n startPoints,\n lastPoints: startPoints,\n currentPoints: startPoints,\n deltaPoints,\n }\n\n triggerEvent(element, Events.MOUSE_DOUBLE_CLICK, eventDetail)\n}\n\nexport default mouseDoubleClickListener\n","import {\n getEnabledElement,\n triggerEvent,\n} from '@cornerstonejs/core'\nimport Events from '../../enums/Events'\nimport getMouseEventPoints from './getMouseEventPoints'\nimport { MouseMoveEventDetail } from '../../types/EventTypes'\n\nconst eventName = Events.MOUSE_MOVE\n\n/**\n * Captures and normalizes the mouse move event. Emits as a cornerstoneTools3D\n * mouse move event.\n *\n * @param evt - The mouse event.\n */\nfunction mouseMoveListener(evt: MouseEvent) {\n const element = <HTMLElement>evt.currentTarget\n const enabledElement = getEnabledElement(element)\n const { renderingEngineUID, viewportUID } = enabledElement\n\n const currentPoints = getMouseEventPoints(evt)\n const eventDetail: MouseMoveEventDetail = {\n renderingEngineUID,\n viewportUID,\n camera: {},\n element,\n currentPoints,\n eventName,\n event: evt,\n }\n\n triggerEvent(element, eventName, eventDetail)\n}\n\nexport default mouseMoveListener\n","import {\n getEnabledElement,\n triggerEvent,\n} from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\n\nimport Events from '../../enums/Events'\nimport mouseMoveListener from './mouseMoveListener'\nimport { EventTypes, IPoints } from '../../types'\nimport getMouseEventPoints from './getMouseEventPoints'\n\nconst { MOUSE_DOWN, MOUSE_DOWN_ACTIVATE, MOUSE_CLICK, MOUSE_UP, MOUSE_DRAG } =\n Events\n\ninterface IMouseDownListenerState {\n mouseButton: number\n element: HTMLElement\n renderingEngineUID: string\n viewportUID: string\n isClickEvent: boolean\n clickDelay: number\n preventClickTimeout: ReturnType<typeof setTimeout>\n startPoints: IPoints\n lastPoints: IPoints\n}\n\n// STATE\nconst defaultState: IMouseDownListenerState = {\n mouseButton: undefined,\n //\n element: null,\n renderingEngineUID: undefined,\n viewportUID: undefined,\n //\n isClickEvent: true,\n clickDelay: 200,\n preventClickTimeout: null,\n startPoints: {\n page: [0, 0],\n client: [0, 0],\n canvas: [0, 0],\n world: [0, 0, 0],\n },\n lastPoints: {\n page: [0, 0],\n client: [0, 0],\n canvas: [0, 0],\n world: [0, 0, 0],\n },\n}\n\nlet state: IMouseDownListenerState = {\n mouseButton: undefined,\n //\n renderingEngineUID: undefined,\n viewportUID: undefined,\n //\n isClickEvent: true,\n clickDelay: 200,\n element: null,\n preventClickTimeout: null,\n startPoints: {\n page: [0, 0],\n client: [0, 0],\n canvas: [0, 0],\n world: [0, 0, 0],\n },\n lastPoints: {\n page: [0, 0],\n client: [0, 0],\n canvas: [0, 0],\n world: [0, 0, 0],\n },\n}\n\n/**\n * Listens to mouse down events from the DOM and depending on interaction and further\n * interaction can emit the following mouse events:\n *\n * - MOUSE_DOWN\n * - MOUSE_DOWN_ACTIVATE\n * - MOUSE_DRAG (move while down)\n * - MOUSE_UP\n * - MOUSE_CLICK\n *\n * @param evt - The Mouse event.\n * @private\n */\nfunction mouseDownListener(evt: MouseEvent) {\n state.element = <HTMLElement>evt.currentTarget\n\n state.mouseButton = evt.button\n\n const enabledElement = getEnabledElement(state.element)\n const { renderingEngineUID, viewportUID } = enabledElement\n\n state.renderingEngineUID = renderingEngineUID\n state.viewportUID = viewportUID\n\n state.preventClickTimeout = setTimeout(_preventClickHandler, state.clickDelay)\n\n // Prevent CornerstoneToolsMouseMove while mouse is down\n state.element.removeEventListener('mousemove', mouseMoveListener)\n\n const startPoints = getMouseEventPoints(evt, state.element)\n const deltaPoints = _getDeltaPoints(startPoints, startPoints)\n\n const eventDetail: EventTypes.MouseDownEventDetail = {\n event: evt,\n eventName: MOUSE_DOWN,\n element: state.element,\n mouseButton: state.mouseButton,\n renderingEngineUID: state.renderingEngineUID,\n viewportUID: state.viewportUID,\n camera: {},\n startPoints,\n lastPoints: startPoints,\n currentPoints: startPoints,\n deltaPoints,\n }\n\n state.startPoints = _copyPoints(eventDetail.startPoints)\n state.lastPoints = _copyPoints(eventDetail.lastPoints)\n\n // by triggering MOUSE_DOWN it checks if this is toolSelection, handle modification etc.\n // of already existing tools\n const eventDidPropagate = triggerEvent(\n eventDetail.element,\n MOUSE_DOWN,\n eventDetail\n )\n\n // if no tools responded to this event and prevented its default propagation behavior,\n // create a new tool\n if (eventDidPropagate) {\n triggerEvent(eventDetail.element, MOUSE_DOWN_ACTIVATE, eventDetail)\n }\n\n document.addEventListener('mousemove', _onMouseDrag)\n document.addEventListener('mouseup', _onMouseUp)\n}\n\n/**\n *_onMouseDrag - Handle emission of drag events whilst the mouse is depressed.\n *\n * @private\n * @param evt - The mouse event.\n */\nfunction _onMouseDrag(evt: MouseEvent) {\n const currentPoints = getMouseEventPoints(evt, state.element)\n const lastPoints = _updateMouseEventsLastPoints(\n state.element,\n state.lastPoints\n )\n\n const deltaPoints = _getDeltaPoints(currentPoints, lastPoints)\n\n const eventDetail: EventTypes.MouseDragEventDetail = {\n event: evt,\n eventName: MOUSE_DRAG,\n mouseButton: state.mouseButton,\n renderingEngineUID: state.renderingEngineUID,\n viewportUID: state.viewportUID,\n camera: {},\n element: state.element,\n startPoints: _copyPoints(state.startPoints),\n lastPoints: _copyPoints(lastPoints),\n currentPoints,\n deltaPoints,\n }\n\n triggerEvent(state.element, MOUSE_DRAG, eventDetail)\n\n // Update the last points\n state.lastPoints = _copyPoints(currentPoints)\n}\n\n/**\n *_onMouseDrag - Handle emission of mouse up events, and re-enabling mouse move events.\n *\n * @private\n * @param evt - The mouse event.\n */\nfunction _onMouseUp(evt: MouseEvent): void {\n // Cancel the timeout preventing the click event from triggering\n clearTimeout(state.preventClickTimeout)\n\n const eventName = state.isClickEvent ? MOUSE_CLICK : MOUSE_UP\n\n const currentPoints = getMouseEventPoints(evt, state.element)\n const deltaPoints = _getDeltaPoints(currentPoints, state.lastPoints)\n const eventDetail:\n | EventTypes.MouseUpEventDetail\n | EventTypes.MouseClickEventType = {\n event: evt,\n eventName,\n mouseButton: state.mouseButton,\n element: state.element,\n renderingEngineUID: state.renderingEngineUID,\n viewportUID: state.viewportUID,\n camera: {},\n startPoints: _copyPoints(state.startPoints),\n lastPoints: _copyPoints(state.lastPoints),\n currentPoints,\n deltaPoints,\n }\n\n triggerEvent(eventDetail.element, eventName, eventDetail)\n\n // Remove our temporary handlers\n document.removeEventListener('mousemove', _onMouseDrag)\n document.removeEventListener('mouseup', _onMouseUp)\n\n // Restore our global mousemove listener\n state.element.addEventListener('mousemove', mouseMoveListener)\n\n // Restore `state` to `defaultState`\n state = JSON.parse(JSON.stringify(defaultState))\n}\n\nfunction _preventClickHandler() {\n state.isClickEvent = false\n}\n\n/**\n * Copies a set of points.\n * @param points - The `IPoints` instance to copy.\n *\n * @returns A copy of the points.\n */\nfunction _copyPoints(points: IPoints): IPoints {\n return JSON.parse(JSON.stringify(points))\n}\n\n/**\n * Recalculates the last world coordinate, as the linear transform from client\n * to world could be different if the camera was updated.\n * @param element - The HTML element\n * @param lastPoints - The last points\n */\nfunction _updateMouseEventsLastPoints(\n element: HTMLElement,\n lastPoints: IPoints\n): IPoints {\n const { viewport } = getEnabledElement(element)\n // Need to update the world point to be calculated from the current reference frame,\n // Which might have changed since the last interaction.\n const world = viewport.canvasToWorld(lastPoints.canvas)\n\n return {\n page: lastPoints.page,\n client: lastPoints.client,\n canvas: lastPoints.canvas,\n world,\n }\n}\n\n/**\n * Returns the difference between two `IPoints` instances.\n * @param currentPoints - The current points.\n * @param lastPoints -- The last points, to be subtracted from the `currentPoints`.\n *\n * @returns The difference in IPoints format\n */\nfunction _getDeltaPoints(currentPoints: IPoints, lastPoints: IPoints): IPoints {\n return {\n page: _subtractPoints2D(currentPoints.page, lastPoints.page),\n client: _subtractPoints2D(currentPoints.client, lastPoints.client),\n canvas: _subtractPoints2D(currentPoints.canvas, lastPoints.canvas),\n world: _subtractPoints3D(currentPoints.world, lastPoints.world),\n }\n}\n\n/**\n * _subtractPoints - Subtracts `point1` from `point0`.\n * @param point0 - The first point.\n * @param point1 - The second point to subtract from the first.\n *\n * @returns The difference.\n */\nfunction _subtractPoints2D(\n point0: Types.Point2,\n point1: Types.Point2\n): Types.Point2 {\n return [point0[0] - point1[0], point0[1] - point1[1]]\n}\n\nfunction _subtractPoints3D(\n point0: Types.Point3,\n point1: Types.Point3\n): Types.Point3 {\n return [point0[0] - point1[0], point0[1] - point1[1], point0[2] - point1[2]]\n}\n\nexport function getMouseButton(): number {\n return state.mouseButton\n}\n\nexport default mouseDownListener\n","import mouseDoubleClickListener from './mouseDoubleClickListener'\nimport mouseDownListener from './mouseDownListener'\nimport mouseMoveListener from './mouseMoveListener'\n\n/**\n * Removes mouse event listeners for native mouse event. Enables\n * vtk.js tools flavored events that build on top of existing events to\n * provide more helpful information.\n *\n * @private\n * @param element - The DOM element to remove event listeners from.\n */\nfunction disable(element: HTMLElement): void {\n element.removeEventListener('dblclick', mouseDoubleClickListener)\n element.removeEventListener('mousedown', mouseDownListener)\n element.removeEventListener('mousemove', mouseMoveListener)\n}\n\n/**\n * Registers mouse event listeners for native mouse event. Enables\n * vtk.js tools flavored events that build on top of existing events to\n * provide more helpful information.\n *\n * @private\n * @param element - The DOM element to register event listeners on.\n */\nfunction enable(element: HTMLElement): void {\n // Prevent handlers from being attached multiple times\n disable(element)\n\n element.addEventListener('dblclick', mouseDoubleClickListener)\n element.addEventListener('mousedown', mouseDownListener)\n element.addEventListener('mousemove', mouseMoveListener)\n}\n\nexport default {\n enable,\n disable,\n}\n","import {\n getEnabledElement,\n triggerEvent,\n} from '@cornerstonejs/core'\nimport normalizeWheel from './normalizeWheel'\nimport Events from '../../enums/Events'\n// ~~ VIEWPORT LIBRARY\nimport getMouseEventPoints from '../mouse/getMouseEventPoints'\nimport { MouseWheelEventDetail } from '../../types/EventTypes'\n\n/**\n * wheelListener - Captures and normalizes mouse wheel events. Emits as a\n * cornerstoneTools3D mouse wheel event.\n * @param evt - The mouse wheel event.\n */\nfunction wheelListener(evt: WheelEvent) {\n const element = <HTMLElement>evt.currentTarget\n const enabledElement = getEnabledElement(element)\n const { renderingEngineUID, viewportUID } = enabledElement\n\n // Prevent triggering MouseWheel events that are not real scroll events:\n // E.g. when clicking the MiddleMouseWheelButton, a deltaY of 0 is emitted.\n // See https://github.com/cornerstonejs/cornerstoneTools/issues/935\n if (evt.deltaY > -1 && evt.deltaY < 1) {\n return\n }\n\n evt.preventDefault()\n\n const { spinX, spinY, pixelX, pixelY } = normalizeWheel(evt)\n const direction = spinY < 0 ? -1 : 1\n\n const eventDetail: MouseWheelEventDetail = {\n event: evt,\n eventName: Events.MOUSE_WHEEL,\n renderingEngineUID,\n viewportUID,\n element,\n camera: {},\n detail: evt,\n wheel: {\n spinX,\n spinY,\n pixelX,\n pixelY,\n direction,\n },\n points: getMouseEventPoints(evt),\n }\n\n triggerEvent(element, Events.MOUSE_WHEEL, eventDetail)\n}\n\nexport default wheelListener\n","// Reasonable defaults\nconst PIXEL_STEP = 10\nconst LINE_HEIGHT = 40\nconst PAGE_HEIGHT = 800\n\n/**\n * Normalizes wheel events and provides properties that are more\n * consistent and helpful across different browsers\n *\n * @param event - the original mouse event\n * @returns a normalized eventDetail\n */\nexport default function normalizeWheel(event) {\n let spinX = 0,\n spinY = 0,\n pixelX = 0,\n pixelY = 0\n\n // Legacy\n if ('detail' in event) {\n spinY = event.detail\n }\n if ('wheelDelta' in event) {\n spinY = -event.wheelDelta / 120\n }\n if ('wheelDeltaY' in event) {\n spinY = -event.wheelDeltaY / 120\n }\n if ('wheelDeltaX' in event) {\n spinX = -event.wheelDeltaX / 120\n }\n\n pixelX = spinX * PIXEL_STEP\n pixelY = spinY * PIXEL_STEP\n\n if ('deltaY' in event) {\n pixelY = event.deltaY\n }\n if ('deltaX' in event) {\n pixelX = event.deltaX\n }\n\n if ((pixelX || pixelY) && event.deltaMode) {\n if (event.deltaMode === 1) {\n // Delta in LINE units\n pixelX *= LINE_HEIGHT\n pixelY *= LINE_HEIGHT\n } else {\n // Delta in PAGE units\n pixelX *= PAGE_HEIGHT\n pixelY *= PAGE_HEIGHT\n }\n }\n\n // Fall-back if spin cannot be determined\n if (pixelX && !spinX) {\n spinX = pixelX < 1 ? -1 : 1\n }\n if (pixelY && !spinY) {\n spinY = pixelY < 1 ? -1 : 1\n }\n\n return {\n spinX,\n spinY,\n pixelX,\n pixelY,\n }\n}\n","import wheelListener from './wheelListener'\n\n/**\n * Listens for the wheel event, and handles it. Handled event\n * will be \"normalized\" and re-emitted as `Events.MOUSE_WHEEL`\n *\n * @param element - The HTML element\n */\nfunction enable(element: HTMLElement) {\n disable(element)\n element.addEventListener('wheel', wheelListener, { passive: false })\n}\n\n/**\n * Removes listener and handler for wheel event. `Events.MOUSE_WHEEL`\n * will no longer be emitted.\n *\n * @param element - THe HTML element\n */\nfunction disable(element: HTMLElement) {\n element.removeEventListener('wheel', wheelListener)\n}\n\nexport default {\n enable,\n disable,\n}\n","import _cloneDeep from 'lodash.clonedeep'\nimport {\n getEnabledElement,\n triggerEvent,\n} from '@cornerstonejs/core'\nimport Events from '../../enums/Events'\nimport { KeyDownEventDetail, KeyUpEventDetail } from '../../types/EventTypes'\n\ninterface IKeyDownListenerState {\n renderingEngineUID: string\n viewportUID: string\n key: string | null\n keyCode: number | null\n element: HTMLElement\n}\n\nconst defaultState: IKeyDownListenerState = {\n //\n renderingEngineUID: undefined,\n viewportUID: undefined,\n //\n key: undefined,\n keyCode: undefined,\n element: null,\n}\n\nlet state: IKeyDownListenerState = {\n //\n renderingEngineUID: undefined,\n viewportUID: undefined,\n //\n key: undefined,\n keyCode: undefined,\n element: null,\n}\n\n/**\n * Normalizes the keyboard event and triggers KEY_DOWN event from CornerstoneTools3D events\n * @param evt - DOM Keyboard event\n */\nfunction keyListener(evt: KeyboardEvent): void {\n state.element = <HTMLElement>evt.currentTarget\n\n const enabledElement = getEnabledElement(state.element)\n const { renderingEngineUID, viewportUID } = enabledElement\n\n state.renderingEngineUID = renderingEngineUID\n state.viewportUID = viewportUID\n state.key = evt.key\n state.keyCode = evt.keyCode\n\n evt.preventDefault()\n const eventDetail: KeyDownEventDetail = {\n renderingEngineUID: state.renderingEngineUID,\n viewportUID: state.viewportUID,\n element: state.element,\n key: state.key,\n keyCode: state.keyCode,\n\n // detail: evt,\n // Todo: mouse event points can be used later for placing tools with a key\n // e.g., putting an arrow/probe/etc. on the mouse position. Another use case\n // hovering and deleting the tool\n // points: getMouseEventPoints(evt),\n }\n\n triggerEvent(eventDetail.element, Events.KEY_DOWN, eventDetail)\n\n document.addEventListener('keyup', _onKeyUp)\n\n // Todo: handle combination of keys\n state.element.removeEventListener('keydown', keyListener)\n}\n\nfunction _onKeyUp(evt: KeyboardEvent): void {\n const eventDetail: KeyUpEventDetail = {\n renderingEngineUID: state.renderingEngineUID,\n viewportUID: state.viewportUID,\n element: state.element,\n key: state.key,\n keyCode: state.keyCode,\n // detail: evt,\n }\n\n // Remove our temporary handlers\n document.removeEventListener('keyup', _onKeyUp)\n state.element.addEventListener('keydown', keyListener)\n\n // Restore `state` to `defaultState`\n state = _cloneDeep(defaultState)\n triggerEvent(eventDetail.element, Events.KEY_UP, eventDetail)\n}\n\nexport function getModifierKey(): number | undefined {\n return state.keyCode\n}\n\nexport function resetModifierKey(): void {\n state.keyCode = undefined\n}\n\nexport default keyListener\n","import keyDownListener, { getModifierKey } from './keyDownListener'\n\nfunction enable(element: HTMLElement): void {\n disable(element)\n element.addEventListener('keydown', keyDownListener)\n}\n\nfunction disable(element: HTMLElement): void {\n element.removeEventListener('keydown', keyDownListener)\n}\n\nexport default {\n enable,\n disable,\n getModifierKey,\n}\n","export default function _assertThisInitialized(self) {\n if (self === void 0) {\n throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n }\n\n return self;\n}","export default function _setPrototypeOf(o, p) {\n _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) {\n o.__proto__ = p;\n return o;\n };\n\n return _setPrototypeOf(o, p);\n}","import setPrototypeOf from \"./setPrototypeOf.js\";\nexport default function _inherits(subClass, superClass) {\n if (typeof superClass !== \"function\" && superClass !== null) {\n throw new TypeError(\"Super expression must either be null or a function\");\n }\n\n subClass.prototype = Object.create(superClass && superClass.prototype, {\n constructor: {\n value: subClass,\n writable: true,\n configurable: true\n }\n });\n Object.defineProperty(subClass, \"prototype\", {\n writable: false\n });\n if (superClass) setPrototypeOf(subClass, superClass);\n}","export default function _typeof(obj) {\n \"@babel/helpers - typeof\";\n\n return _typeof = \"function\" == typeof Symbol && \"symbol\" == typeof Symbol.iterator ? function (obj) {\n return typeof obj;\n } : function (obj) {\n return obj && \"function\" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n }, _typeof(obj);\n}","import _typeof from \"./typeof.js\";\nimport assertThisInitialized from \"./assertThisInitialized.js\";\nexport default function _possibleConstructorReturn(self, call) {\n if (call && (_typeof(call) === \"object\" || typeof call === \"function\")) {\n return call;\n } else if (call !== void 0) {\n throw new TypeError(\"Derived constructors may only return object or undefined\");\n }\n\n return assertThisInitialized(self);\n}","export default function _getPrototypeOf(o) {\n _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) {\n return o.__proto__ || Object.getPrototypeOf(o);\n };\n return _getPrototypeOf(o);\n}","const isMergeableObject = (val) => {\n const nonNullObject = val && typeof val === 'object'\n\n return (\n nonNullObject &&\n Object.prototype.toString.call(val) !== '[object RegExp]' &&\n Object.prototype.toString.call(val) !== '[object Date]'\n )\n}\n\nconst emptyTarget = (val) => {\n const isEmpty = Array.isArray(val) ? [] : {}\n\n return isEmpty\n}\n\nconst cloneIfNecessary = (value, optionsArgument) => {\n const clone = optionsArgument && optionsArgument.clone === true\n\n return clone && isMergeableObject(value)\n ? deepmerge(emptyTarget(value), value, optionsArgument)\n : value\n}\n\nconst defaultArrayMerge = (target, source, optionsArgument) => {\n const destination = target.slice()\n\n source.forEach(function (e, i) {\n if (typeof destination[i] === 'undefined') {\n destination[i] = cloneIfNecessary(e, optionsArgument)\n } else if (isMergeableObject(e)) {\n destination[i] = deepmerge(target[i], e, optionsArgument)\n } else if (target.indexOf(e) === -1) {\n destination.push(cloneIfNecessary(e, optionsArgument))\n }\n })\n\n return destination\n}\n\nconst mergeObject = (target, source, optionsArgument) => {\n const destination = {}\n\n if (isMergeableObject(target)) {\n Object.keys(target).forEach(function (key) {\n destination[key] = cloneIfNecessary(target[key], optionsArgument)\n })\n }\n Object.keys(source).forEach(function (key) {\n if (!isMergeableObject(source[key]) || !target[key]) {\n destination[key] = cloneIfNecessary(source[key], optionsArgument)\n } else {\n destination[key] = deepmerge(target[key], source[key], optionsArgument)\n }\n })\n\n return destination\n}\n\n/**\n * Merge two objects, recursively merging any objects that are arrays\n * @param [target] - The target object.\n * @param [source] - The source object to merge into the target object.\n * @param [optionsArgument] - The options object.\n * @returns The merged object.\n */\nconst deepmerge = (target = {}, source = {}, optionsArgument = undefined) => {\n const array = Array.isArray(source)\n const options = optionsArgument || { arrayMerge: defaultArrayMerge }\n const arrayMerge = options.arrayMerge || defaultArrayMerge\n\n if (array) {\n return Array.isArray(target)\n ? arrayMerge(target, source, optionsArgument)\n : cloneIfNecessary(source, optionsArgument)\n }\n\n return mergeObject(target, source, optionsArgument)\n}\n\nexport default deepmerge\n","import { StackViewport, VolumeViewport, cache } from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\nimport deepMerge from '../../utilities/deepMerge'\nimport { ToolModes } from '../../enums'\nimport { InteractionTypes, ToolProps, PublicToolProps } from '../../types'\n\ninterface IBaseTool {\n /** ToolGroup UID the tool instance belongs to */\n toolGroupUID: string\n /** Tool supported interaction types */\n supportedInteractionTypes: InteractionTypes[]\n /** Tool Mode : Active, Passive, Enabled, Disabled */\n mode: ToolModes\n /** Tool Configuration */\n configuration: {\n preventHandleOutsideImage?: boolean\n strategies?: Record<string, any>\n defaultStrategy?: string\n activeStrategy?: string\n strategyOptions?: Record<string, unknown>\n }\n}\n\n/**\n * Abstract base class from which all tools derive.\n * Deals with cleanly merging custom and default configuration, and strategy\n * application.\n */\nabstract class BaseTool implements IBaseTool {\n static toolName = 'BaseTool'\n /** Supported Interaction Types - currently only Mouse */\n public supportedInteractionTypes: InteractionTypes[]\n public configuration: Record<string, any>\n /** ToolGroup UID the tool instance belongs to */\n public toolGroupUID: string\n /** Tool Mode - Active/Passive/Enabled/Disabled/ */\n public mode: ToolModes\n\n constructor(toolProps: PublicToolProps, defaultToolProps: ToolProps) {\n const initialProps = deepMerge(defaultToolProps, toolProps)\n\n const {\n configuration = {},\n supportedInteractionTypes,\n toolGroupUID,\n } = initialProps\n\n // If strategies are not initialized in the tool config\n if (!configuration.strategies) {\n configuration.strategies = {}\n configuration.defaultStrategy = undefined\n configuration.activeStrategy = undefined\n configuration.strategyOptions = {}\n }\n\n this.toolGroupUID = toolGroupUID\n this.supportedInteractionTypes = supportedInteractionTypes || []\n this.configuration = Object.assign({}, configuration)\n this.mode = ToolModes.Disabled\n }\n\n /**\n * Returns the name of the tool\n * @returns The name of the tool.\n */\n public getToolName(): string {\n // Since toolName is static we get it from the class constructor\n return (<typeof BaseTool>this.constructor).toolName\n }\n\n /**\n * It applies the active strategy to the enabled element.\n * @param enabledElement - The element that is being operated on.\n * @param operationData - The data that needs to be passed to the strategy.\n * @returns The result of the strategy.\n */\n public applyActiveStrategy(\n enabledElement: Types.IEnabledElement,\n operationData: unknown\n ): any {\n const { strategies, activeStrategy } = this.configuration\n return strategies[activeStrategy].call(this, enabledElement, operationData)\n }\n\n /**\n * merges the new configuration with the tool configuration\n * @param configuration - toolConfiguration\n */\n public setConfiguration(newConfiguration: Record<string, any>): void {\n this.configuration = deepMerge(this.configuration, newConfiguration)\n }\n\n /**\n * Sets the active strategy for a tool. Strategies are\n * multiple implementations of tool behavior that can be switched by tool\n * configuration.\n *\n * @param strategyName - name of the strategy to be set as active\n */\n public setActiveStrategy(strategyName: string): void {\n this.setConfiguration({ activeStrategy: strategyName })\n }\n\n /**\n * Returns the volumeUID for the volume viewport. It will grabbed the volumeUID\n * from the volumeUID if particularly specified in the tool configuration, or if\n * not, the first actorUID in the viewport is returned as the volumeUID. NOTE: for\n * segmentations, actorUID is not necessarily the volumeUID since the segmentation\n * can have multiple representations, use segmentation helpers to get the volumeUID\n * based on the actorUID.\n *\n * @param viewport - Volume viewport\n * @returns the volumeUID for the viewport if specified in the tool configuration,\n * or the first actorUID in the viewport if not.\n */\n private getTargetVolumeUID(viewport: Types.IViewport): string | undefined {\n if (!(viewport instanceof VolumeViewport)) {\n throw new Error('getTargetVolumeUID: viewport must be a VolumeViewport')\n }\n\n if (this.configuration.volumeUID) {\n return this.configuration.volumeUID\n }\n\n // If volume not specified, then return the actorUID for the\n // default actor - first actor\n const actors = viewport.getActors()\n\n if (!actors && !actors.length) {\n return\n }\n\n return actors[0].uid\n }\n\n /**\n * Get the viewport and image for the targetUID. Since we are using the\n * schema of stackTarget:<viewportUID>, we can get the viewport and image\n * from the stack. For the volumeViewports, the targetUID is the actual\n * volumeUID, so we can get the viewport and image.\n *\n * @param targetUID - annotation targetUID\n * @param renderingEngine - The rendering engine\n * @returns The viewport and image data for the target.\n */\n protected getTargetUIDViewportAndImage(\n targetUID: string,\n renderingEngine: Types.IRenderingEngine\n ): {\n viewport: Types.IViewport\n image: Types.IImageData\n } {\n let image, viewport\n if (targetUID.startsWith('stackTarget')) {\n const coloneIndex = targetUID.indexOf(':')\n const viewportUID = targetUID.substring(coloneIndex + 1)\n viewport = renderingEngine.getViewport(viewportUID)\n image = viewport.getImageData()\n } else {\n image = cache.getVolume(targetUID)\n }\n\n return { image, viewport }\n }\n\n /**\n * Get the target UID for the viewport which will be used to store the cached\n * statistics scoped to that target in the annotations.\n * For StackViewport, targetUID is the viewportUID, but for the volume viewport,\n * the targetUID will be grabbed from the volumeUID if particularly specified\n * in the tool configuration, or if not, the first actorUID in the viewport.\n *\n * @param viewport - viewport to get the targetUID for\n * @returns targetUID\n */\n protected getTargetUID(viewport: Types.IViewport): string | undefined {\n if (viewport instanceof StackViewport) {\n return `stackTarget:${viewport.uid}`\n } else if (viewport instanceof VolumeViewport) {\n return this.getTargetVolumeUID(viewport)\n } else {\n throw new Error(\n 'getTargetUID: viewport must be a StackViewport or VolumeViewport'\n )\n }\n }\n}\n\nexport default BaseTool\n","import { state } from '../store'\nimport { getEnabledElement } from '@cornerstonejs/core'\n\n/**\n * Returns the SVG drawing helper for the given HTML element.\n * @param element - The HTML element to get the SVG drawing helper for.\n * @private\n */\nfunction getSvgDrawingHelper(element: HTMLElement) {\n const enabledElement = getEnabledElement(element)\n const { viewportUID, renderingEngineUID } = enabledElement\n const canvasHash = `${viewportUID}:${renderingEngineUID}`\n const svgLayerElement = _getSvgLayer(element)\n\n // Reset touched\n Object.keys(state.svgNodeCache[canvasHash]).forEach((cacheKey) => {\n state.svgNodeCache[canvasHash][cacheKey].touched = false\n })\n\n return {\n // Todo: not sure if we need enabledElement and _element anymore here\n enabledElement: enabledElement,\n _element: element,\n _svgLayerElement: svgLayerElement,\n _svgNodeCacheForCanvas: state.svgNodeCache,\n _getSvgNode: getSvgNode.bind(this, canvasHash),\n _appendNode: appendNode.bind(this, svgLayerElement, canvasHash),\n _setNodeTouched: setNodeTouched.bind(this, canvasHash),\n _clearUntouched: clearUntouched.bind(this, svgLayerElement, canvasHash),\n // _drawnAnnotations: drawnAnnotations,\n }\n}\n\n/**\n *\n * @param canvasElement\n * @private\n */\nfunction _getSvgLayer(element) {\n const internalDivElement = element.firstChild\n const svgLayer = internalDivElement.querySelector('.svg-layer')\n\n return svgLayer\n}\n\nfunction getSvgNode(canvasHash, cacheKey) {\n // If state has been reset\n if (!state.svgNodeCache[canvasHash]) {\n return\n }\n\n if (state.svgNodeCache[canvasHash][cacheKey]) {\n return state.svgNodeCache[canvasHash][cacheKey].domRef\n }\n}\n\nfunction appendNode(svgLayerElement, canvasHash, svgNode, cacheKey) {\n // If state has been reset\n if (!state.svgNodeCache[canvasHash]) {\n return null\n }\n\n state.svgNodeCache[canvasHash][cacheKey] = {\n touched: true,\n domRef: svgNode,\n }\n\n svgLayerElement.appendChild(svgNode)\n}\n\nfunction setNodeTouched(canvasHash, cacheKey) {\n // If state has been reset\n if (!state.svgNodeCache[canvasHash]) {\n return\n }\n\n if (state.svgNodeCache[canvasHash][cacheKey]) {\n state.svgNodeCache[canvasHash][cacheKey].touched = true\n }\n}\n\nfunction clearUntouched(svgLayerElement, canvasHash) {\n // If state has been reset\n if (!state.svgNodeCache[canvasHash]) {\n return\n }\n\n Object.keys(state.svgNodeCache[canvasHash]).forEach((cacheKey) => {\n const cacheEntry = state.svgNodeCache[canvasHash][cacheKey]\n\n if (!cacheEntry.touched && cacheEntry.domRef) {\n svgLayerElement.removeChild(cacheEntry.domRef)\n delete state.svgNodeCache[canvasHash][cacheKey]\n }\n })\n}\n\nexport default getSvgDrawingHelper\n","import getSvgDrawingHelper from './getSvgDrawingHelper'\n\nfunction draw(element: HTMLElement, fn: (svgDrawingElement: any) => any): void {\n const svgDrawingHelper = getSvgDrawingHelper(element)\n\n // Save...\n fn(svgDrawingHelper)\n // Restore...\n\n svgDrawingHelper._clearUntouched()\n}\n\nexport default draw\n","function _getHash(\n toolName: string,\n annotationUID: string,\n drawingElementType: string,\n nodeUID: string\n): string {\n return `${toolName}::${annotationUID}::${drawingElementType}::${nodeUID}`\n}\n\nexport default _getHash\n","export function _setAttributesIfNecessary(attributes, svgNode) {\n Object.keys(attributes).forEach((key) => {\n const currentValue = svgNode.getAttribute(key)\n const newValue = attributes[key]\n if (newValue === undefined || newValue === '') {\n svgNode.removeAttribute(key)\n } else if (currentValue !== newValue) {\n svgNode.setAttribute(key, newValue)\n }\n })\n}\n\nexport default _setAttributesIfNecessary\n","export function _setNewAttributesIfValid(attributes, svgNode) {\n Object.keys(attributes).forEach((key) => {\n const newValue = attributes[key]\n if (newValue !== undefined && newValue !== '') {\n svgNode.setAttribute(key, newValue)\n }\n })\n}\n\nexport default _setNewAttributesIfValid\n","import type { Types } from '@cornerstonejs/core'\n\nimport _getHash from './_getHash'\n\nimport _setAttributesIfNecessary from './_setAttributesIfNecessary'\nimport _setNewAttributesIfValid from './_setNewAttributesIfValid'\n\nfunction drawCircle(\n svgDrawingHelper: any,\n toolName: string,\n annotationUID: string,\n circleUID: string,\n center: Types.Point2,\n radius: number,\n options = {}\n): void {\n const { color, fill, width, lineWidth } = Object.assign(\n {\n color: 'dodgerblue',\n fill: 'transparent',\n width: '2',\n lineWidth: undefined,\n },\n options\n )\n\n // for supporting both lineWidth and width options\n const strokeWidth = lineWidth || width\n\n // variable for the namespace\n const svgns = 'http://www.w3.org/2000/svg'\n const svgNodeHash = _getHash(toolName, annotationUID, 'circle', circleUID)\n const existingCircleElement = svgDrawingHelper._getSvgNode(svgNodeHash)\n\n const attributes = {\n cx: `${center[0]}`,\n cy: `${center[1]}`,\n r: `${radius}`,\n stroke: color,\n fill,\n 'stroke-width': strokeWidth,\n }\n\n if (existingCircleElement) {\n _setAttributesIfNecessary(attributes, existingCircleElement)\n\n svgDrawingHelper._setNodeTouched(svgNodeHash)\n } else {\n const newCircleElement = document.createElementNS(svgns, 'circle')\n\n _setNewAttributesIfValid(attributes, newCircleElement)\n\n svgDrawingHelper._appendNode(newCircleElement, svgNodeHash)\n }\n}\n\nexport default drawCircle\n","import type { Types } from '@cornerstonejs/core'\n\nimport _getHash from './_getHash'\nimport _setAttributesIfNecessary from './_setAttributesIfNecessary'\nimport _setNewAttributesIfValid from './_setNewAttributesIfValid'\n\nfunction drawEllipse(\n svgDrawingHelper: any,\n toolName: string,\n annotationUID: string,\n ellipseUID: string,\n corner1: Types.Point2,\n corner2: Types.Point2,\n options = {}\n): void {\n const { color, width, lineWidth, lineDash } = Object.assign(\n {\n color: 'dodgerblue',\n width: '2',\n lineWidth: undefined,\n lineDash: undefined,\n },\n options\n )\n\n // for supporting both lineWidth and width options\n const strokeWidth = lineWidth || width\n\n const svgns = 'http://www.w3.org/2000/svg'\n const svgNodeHash = _getHash(toolName, annotationUID, 'ellipse', ellipseUID)\n const existingEllipse = svgDrawingHelper._getSvgNode(svgNodeHash)\n\n const w = Math.abs(corner1[0] - corner2[0])\n const h = Math.abs(corner1[1] - corner2[1])\n const xMin = Math.min(corner1[0], corner2[0])\n const yMin = Math.min(corner1[1], corner2[1])\n\n const center = [xMin + w / 2, yMin + h / 2]\n const radiusX = w / 2\n const radiusY = h / 2\n\n const attributes = {\n cx: `${center[0]}`,\n cy: `${center[1]}`,\n rx: `${radiusX}`,\n ry: `${radiusY}`,\n stroke: color,\n fill: 'transparent',\n 'stroke-width': strokeWidth,\n 'stroke-dasharray': lineDash,\n }\n\n if (existingEllipse) {\n _setAttributesIfNecessary(attributes, existingEllipse)\n\n svgDrawingHelper._setNodeTouched(svgNodeHash)\n } else {\n const svgEllipseElement = document.createElementNS(svgns, 'ellipse')\n\n _setNewAttributesIfValid(attributes, svgEllipseElement)\n\n svgDrawingHelper._appendNode(svgEllipseElement, svgNodeHash)\n }\n}\n\nexport default drawEllipse\n","import type { Types } from '@cornerstonejs/core'\n\nimport _getHash from './_getHash'\nimport _setNewAttributesIfValid from './_setNewAttributesIfValid'\nimport _setAttributesIfNecessary from './_setAttributesIfNecessary'\n\nfunction drawHandles(\n svgDrawingHelper: any,\n toolName: string,\n annotationUID: string,\n handleGroupUID: string,\n handlePoints: Array<Types.Point2>,\n options = {}\n): void {\n const { color, handleRadius, width, lineWidth, fill, type } = Object.assign(\n {\n color: 'dodgerblue',\n handleRadius: '6',\n width: '2',\n lineWidth: undefined,\n fill: 'transparent',\n type: 'circle',\n },\n options\n )\n\n // for supporting both lineWidth and width options\n const strokeWidth = lineWidth || width\n\n for (let i = 0; i < handlePoints.length; i++) {\n const handle = handlePoints[i]\n\n // variable for the namespace\n const svgns = 'http://www.w3.org/2000/svg'\n const svgNodeHash = _getHash(\n toolName,\n annotationUID,\n 'handle',\n `hg-${handleGroupUID}-index-${i}`\n )\n\n let attributes\n if (type === 'circle') {\n attributes = {\n cx: `${handle[0]}`,\n cy: `${handle[1]}`,\n r: handleRadius,\n stroke: color,\n fill,\n 'stroke-width': strokeWidth,\n }\n } else if (type === 'rect') {\n const handleRadiusFloat = parseFloat(handleRadius)\n const side = handleRadiusFloat * 1.5\n const x = handle[0] - side * 0.5\n const y = handle[1] - side * 0.5\n\n attributes = {\n x: `${x}`,\n y: `${y}`,\n width: `${side}`,\n height: `${side}`,\n stroke: color,\n fill,\n 'stroke-width': strokeWidth,\n rx: `${side * 0.1}`,\n }\n } else {\n throw new Error(`Unsupported handle type: ${type}`)\n }\n\n const existingHandleElement = svgDrawingHelper._getSvgNode(svgNodeHash)\n\n if (existingHandleElement) {\n _setAttributesIfNecessary(attributes, existingHandleElement)\n\n svgDrawingHelper._setNodeTouched(svgNodeHash)\n } else {\n const newHandleElement = document.createElementNS(svgns, type)\n\n _setNewAttributesIfValid(attributes, newHandleElement)\n\n svgDrawingHelper._appendNode(newHandleElement, svgNodeHash)\n }\n }\n}\n\nexport default drawHandles\n","import type { Types } from '@cornerstonejs/core'\n\nimport _getHash from './_getHash'\nimport _setNewAttributesIfValid from './_setNewAttributesIfValid'\nimport _setAttributesIfNecessary from './_setAttributesIfNecessary'\n\nexport default function drawLine(\n svgDrawingHelper: any,\n toolName: string,\n annotationUID: string,\n lineUID: string,\n start: Types.Point2,\n end: Types.Point2,\n options = {}\n): void {\n // if length is NaN return\n if (isNaN(start[0]) || isNaN(start[1]) || isNaN(end[0]) || isNaN(end[1])) {\n return\n }\n\n const { color, width, lineWidth, lineDash } = Object.assign(\n {\n color: 'dodgerblue',\n width: '2',\n lineWidth: undefined,\n lineDash: undefined,\n },\n options\n )\n\n // for supporting both lineWidth and width options\n const strokeWidth = lineWidth || width\n\n const svgns = 'http://www.w3.org/2000/svg'\n const svgNodeHash = _getHash(toolName, annotationUID, 'line', lineUID)\n const existingLine = svgDrawingHelper._getSvgNode(svgNodeHash)\n\n const attributes = {\n x1: `${start[0]}`,\n y1: `${start[1]}`,\n x2: `${end[0]}`,\n y2: `${end[1]}`,\n stroke: color,\n 'stroke-width': strokeWidth,\n 'stroke-dasharray': lineDash,\n }\n\n if (existingLine) {\n // This is run to avoid re-rendering annotations that actually haven't changed\n _setAttributesIfNecessary(attributes, existingLine)\n\n svgDrawingHelper._setNodeTouched(svgNodeHash)\n } else {\n const newLine = document.createElementNS(svgns, 'line')\n\n _setNewAttributesIfValid(attributes, newLine)\n\n svgDrawingHelper._appendNode(newLine, svgNodeHash)\n }\n}\n","import type { Types } from '@cornerstonejs/core'\n\nimport _getHash from './_getHash'\nimport _setAttributesIfNecessary from './_setAttributesIfNecessary'\n\n/**\n * Draws a textBox.\n *\n * @param textLines - The text to display.\n * @param position - The x/y position of the textbox\n * @param options - Options for the textBox.\n * @returns Bounding box; can be used for isPointNearTool\n */\nfunction drawTextBox(\n svgDrawingHelper: Record<string, unknown>,\n toolName: string,\n annotationUID: string,\n textUID: string,\n textLines: Array<string>,\n position: Types.Point2,\n options = {}\n): SVGRect {\n const mergedOptions = Object.assign(\n {\n fontFamily: 'Helvetica, Arial, sans-serif',\n fontSize: '14px',\n color: 'rgb(255, 255, 0)',\n background: '',\n padding: 25,\n centerX: false,\n centerY: true,\n },\n options\n )\n\n // Draw each of the text lines on top of the background box\n const textGroupBoundingBox = _drawTextGroup(\n svgDrawingHelper,\n toolName,\n annotationUID,\n textUID,\n textLines,\n position,\n mergedOptions\n )\n\n return textGroupBoundingBox\n}\n\nfunction _drawTextGroup(\n svgDrawingHelper: any,\n toolName: any,\n annotationUID: string,\n textUID: string,\n textLines: Array<string>,\n position: Types.Point2,\n options: any\n): SVGRect {\n const { padding, color, fontFamily, fontSize, background } = options\n\n let textGroupBoundingBox\n const [x, y] = [position[0] + padding, position[1] + padding]\n const svgns = 'http://www.w3.org/2000/svg'\n const svgNodeHash = _getHash(toolName, annotationUID, 'text', textUID)\n const existingTextGroup = svgDrawingHelper._getSvgNode(svgNodeHash)\n\n // Todo: right now textBox gets a re-render even if the textBox has not changed\n // and evenIf the attributes are not set again since they are the same.\n if (existingTextGroup) {\n // TODO: Iterate each node and update color? font-size?\n // TODO: Does not support change in # of text lines\n const textElement = existingTextGroup.querySelector('text')\n const textSpans = Array.from(textElement.children) as Array<SVGElement>\n\n for (let i = 0; i < textSpans.length; i++) {\n const textSpanElement = textSpans[i]\n const text = textLines[i] || ''\n\n textSpanElement.textContent = text\n }\n\n const textAttributes = {\n fill: color,\n 'font-size': fontSize,\n 'font-family': fontFamily,\n }\n\n const textGroupAttributes = {\n transform: `translate(${x} ${y})`,\n }\n\n // Todo: for some reason this does not work to not re-render the textBox\n _setAttributesIfNecessary(textAttributes, textElement)\n _setAttributesIfNecessary(textGroupAttributes, existingTextGroup)\n\n textGroupBoundingBox = _drawTextBackground(existingTextGroup, background)\n\n svgDrawingHelper._setNodeTouched(svgNodeHash)\n } else {\n const textGroup = document.createElementNS(svgns, 'g')\n\n textGroup.setAttribute('transform', `translate(${x} ${y})`)\n\n //\n const textElement = _createTextElement(options)\n for (let i = 0; i < textLines.length; i++) {\n const textLine = textLines[i]\n const textSpan = _createTextSpan(textLine)\n\n textElement.appendChild(textSpan)\n }\n\n textGroup.appendChild(textElement)\n svgDrawingHelper._appendNode(textGroup, svgNodeHash)\n textGroupBoundingBox = _drawTextBackground(textGroup, background)\n }\n\n // We translate the group using `position`\n // which means we also need to pluck those values when returning\n // the bounding box\n return Object.assign({}, textGroupBoundingBox, {\n x,\n y,\n height: textGroupBoundingBox.height + padding,\n width: textGroupBoundingBox.width + padding,\n })\n}\n\nfunction _createTextElement(options: any): SVGElement {\n const { color, fontFamily, fontSize } = options\n const svgns = 'http://www.w3.org/2000/svg'\n const textElement = document.createElementNS(svgns, 'text')\n const noSelectStyle =\n 'user-select: none; pointer-events: none; -webkit-tap-highlight-color: rgba(255, 255, 255, 0);'\n const dropShadowStyle = 'filter:url(#shadow);'\n const combinedStyle = `${noSelectStyle}${dropShadowStyle}`\n\n // font-size=\"100\"\n textElement.setAttribute('x', '0')\n textElement.setAttribute('y', '0')\n textElement.setAttribute('fill', color)\n textElement.setAttribute('font-family', fontFamily)\n textElement.setAttribute('font-size', fontSize)\n textElement.setAttribute('style', combinedStyle)\n\n return textElement\n}\n\nfunction _createTextSpan(text): SVGElement {\n const svgns = 'http://www.w3.org/2000/svg'\n const textSpanElement = document.createElementNS(svgns, 'tspan')\n\n // TODO: centerX\n // (parent width / 2) - my width\n // TODO: centerY\n\n textSpanElement.setAttribute('x', '0')\n textSpanElement.setAttribute('dy', '1.2em')\n textSpanElement.textContent = text\n\n return textSpanElement\n}\n\nfunction _drawTextBackground(group: SVGGElement, color: string) {\n let element = group.querySelector('rect.background')\n\n // If we have no background color, remove any element that exists and return\n // the bounding box of the text\n if (!color) {\n if (element) {\n group.removeChild(element)\n }\n\n return group.getBBox()\n }\n\n // Otherwise, check if we have a <rect> element. If not, create one\n if (!element) {\n element = document.createElementNS('http://www.w3.org/2000/svg', 'rect')\n element.setAttribute('class', 'background')\n group.insertBefore(element, group.firstChild)\n }\n\n // Get the text groups's bounding box and use it to draw the background rectangle\n const bBox = group.getBBox()\n\n const attributes = {\n x: `${bBox.x}`,\n y: `${bBox.y}`,\n width: `${bBox.width}`,\n height: `${bBox.height}`,\n fill: color,\n }\n\n _setAttributesIfNecessary(attributes, element)\n\n return bBox\n}\n\nexport default drawTextBox\n","import type { Types } from '@cornerstonejs/core'\n\n/**\n * Find the closest point to the target point\n *\n * @param sourcePoints - The potential source points.\n * @param targetPoint - The target point, used to find the closest source.\n * @returns The closest point in the array of point sources\n */\nexport default function findClosestPoint(\n sourcePoints: Array<Types.Point2>,\n targetPoint: Types.Point2\n): Types.Point2 {\n let minPoint = [0, 0]\n let minDistance = Number.MAX_SAFE_INTEGER\n\n sourcePoints.forEach(function (sourcePoint) {\n const distance = _distanceBetween(targetPoint, sourcePoint)\n\n if (distance < minDistance) {\n minDistance = distance\n minPoint = [...sourcePoint]\n }\n })\n\n return minPoint as Types.Point2\n}\n\n/**\n *\n * @private\n * @param p1\n * @param p2\n */\nfunction _distanceBetween(p1: Types.Point2, p2: Types.Point2): number {\n const [x1, y1] = p1\n const [x2, y2] = p2\n\n return Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2))\n}\n","import type { Types } from '@cornerstonejs/core'\n\nimport drawLine from './drawLine'\nimport findClosestPoint from '../utilities/math/vec2/findClosestPoint'\nimport { PlanarBoundingBox } from '../types'\n\n/**\n * Draw a link between an annotation to a box.\n */\nfunction drawLink(\n svgDrawingHelper: Record<string, unknown>,\n toolName: string,\n annotationUID: string,\n linkUID: string,\n // Find closest point to approx. bounding box\n annotationAnchorPoints: Array<Types.Point2>,\n refPoint: Types.Point2,\n // Find bounding box point that's closest to our identified\n // start point\n boundingBox: PlanarBoundingBox,\n options = {}\n): void {\n // The closest anchor point (for the annotation) to the\n // text box / bounding box\n const start =\n annotationAnchorPoints.length > 0\n ? findClosestPoint(annotationAnchorPoints, refPoint)\n : refPoint\n\n // Calculate the midpoints of the bounding box\n const boundingBoxPoints = _boundingBoxPoints(boundingBox)\n // Find the closest textBox midpoint to the annotation's anchor/start point\n const end = findClosestPoint(boundingBoxPoints, start)\n\n // Finally we draw the dashed linking line\n const mergedOptions = Object.assign(\n {\n color: 'rgb(255, 255, 0)',\n lineWidth: '1',\n lineDash: '2,3',\n },\n options\n )\n\n drawLine(\n svgDrawingHelper,\n toolName,\n annotationUID,\n `link-${linkUID}`,\n start,\n end,\n mergedOptions\n )\n}\n\n/**\n * Find potential anchor points for a given bounding box. For example, it may\n * look nicer to draw a line from the \"middle left\" of a bounding box to an\n * annotation (instead of from a corner). This function calculates those points\n *\n * @param boundingBox\n */\nfunction _boundingBoxPoints(\n boundingBox: PlanarBoundingBox\n): Array<Types.Point2> {\n const { x: left, y: top, height, width } = boundingBox\n const halfWidth = width / 2\n const halfHeight = height / 2\n\n const topMiddle = [left + halfWidth, top] as Types.Point2\n const leftMiddle = [left, top + halfHeight] as Types.Point2\n const bottomMiddle = [left + halfWidth, top + height] as Types.Point2\n const rightMiddle = [left + width, top + halfHeight] as Types.Point2\n\n return [topMiddle, leftMiddle, bottomMiddle, rightMiddle]\n}\n\nexport default drawLink\n","import type { Types } from '@cornerstonejs/core'\n\nimport drawTextBox from './drawTextBox'\nimport drawLink from './drawLink'\n\nfunction drawLinkedTextBox(\n svgDrawingHelper: Record<string, unknown>,\n //\n toolName: string,\n annotationUID: string,\n textBoxUID: string,\n //\n textLines: Array<string>,\n textBoxPosition: Types.Point2,\n annotationAnchorPoints: Array<Types.Point2>,\n textBox: unknown,\n options = {}\n // TODO: yCenter as an option\n): SVGRect {\n const mergedOptions = Object.assign(\n {\n handleRadius: '6',\n centering: {\n x: false,\n y: true, // yCenter,\n },\n },\n options\n )\n\n // Draw the text box\n const canvasBoundingBox = drawTextBox(\n svgDrawingHelper,\n toolName,\n annotationUID,\n textBoxUID,\n textLines,\n textBoxPosition,\n mergedOptions\n )\n // if (textBox.hasMoved) {\n // // Draw dashed link line between tool and text\n drawLink(\n svgDrawingHelper,\n toolName,\n annotationUID,\n textBoxUID,\n annotationAnchorPoints, // annotationAnchorPoints\n textBoxPosition, // refPoint (text)\n canvasBoundingBox, // textBoxBoundingBox\n mergedOptions\n )\n // }\n\n // const { top, left, width, height } = canvasBoundingBox\n\n // textBox.worldBoundingBox = {\n // topLeft: canvasToWorld([left, top]),\n // topRight: canvasToWorld([left + width, top]),\n // bottomLeft: canvasToWorld([left, top + height]),\n // bottomRight: canvasToWorld([left + width, top + height]),\n // }\n\n return canvasBoundingBox\n}\n\nexport default drawLinkedTextBox\n","import type { Types } from '@cornerstonejs/core'\n\nimport _getHash from './_getHash'\nimport _setAttributesIfNecessary from './_setAttributesIfNecessary'\nimport _setNewAttributesIfValid from './_setNewAttributesIfValid'\n\n// <rect x=\"120\" y=\"100\" width=\"100\" height=\"100\" />\nexport default function drawRect(\n svgDrawingHelper: any,\n toolName: string,\n annotationUID: string,\n rectangleUID: string,\n start: Types.Point2,\n end: Types.Point2,\n options = {}\n): void {\n const {\n color,\n width: _width,\n lineWidth,\n lineDash,\n } = Object.assign(\n {\n color: 'dodgerblue',\n width: '2',\n lineWidth: undefined,\n lineDash: undefined,\n },\n options\n )\n\n // for supporting both lineWidth and width options\n const strokeWidth = lineWidth || _width\n\n const svgns = 'http://www.w3.org/2000/svg'\n const svgNodeHash = _getHash(toolName, annotationUID, 'rect', rectangleUID)\n const existingRect = svgDrawingHelper._getSvgNode(svgNodeHash)\n\n const tlhc = [Math.min(start[0], end[0]), Math.min(start[1], end[1])]\n const width = Math.abs(start[0] - end[0])\n const height = Math.abs(start[1] - end[1])\n\n const attributes = {\n x: `${tlhc[0]}`,\n y: `${tlhc[1]}`,\n width: `${width}`,\n height: `${height}`,\n stroke: color,\n fill: 'transparent',\n 'stroke-width': strokeWidth,\n 'stroke-dasharray': lineDash,\n }\n\n if (existingRect) {\n _setAttributesIfNecessary(attributes, existingRect)\n\n svgDrawingHelper._setNodeTouched(svgNodeHash)\n } else {\n const svgRectElement = document.createElementNS(svgns, 'rect')\n\n _setNewAttributesIfValid(attributes, svgRectElement)\n\n svgDrawingHelper._appendNode(svgRectElement, svgNodeHash)\n }\n}\n","// import clearByToolType from './clearByToolType'\nimport draw from './draw'\nimport drawCircle from './drawCircle'\nimport drawEllipse from './drawEllipse'\nimport drawHandles from './drawHandles'\nimport drawLine from './drawLine'\nimport drawLinkedTextBox from './drawLinkedTextBox'\nimport drawRect from './drawRect'\nimport drawTextBox from './drawTextBox'\n\nexport {\n // @TODO: May no longer have a use for this\n // clearByToolType,\n // @TODO: This becomes an internal method only?\n draw,\n drawCircle,\n drawEllipse,\n drawHandles,\n drawLine,\n drawLinkedTextBox,\n drawRect,\n drawTextBox,\n}\n\nexport default {\n draw,\n drawCircle,\n drawEllipse,\n drawHandles,\n drawLine,\n drawLinkedTextBox,\n drawRect,\n drawTextBox,\n}\n","import { ToolGroupManager } from '../store'\nimport { ToolModes } from '../enums'\nimport { getEnabledElement } from '@cornerstonejs/core'\n\ntype ModesFilter = Array<ToolModes>\n\n/**\n * Finds the enabled element, and iterates over the tools inside its\n * toolGroup. Returns the list of tool instances that are valid based\n * on the provided tool mode.\n *\n * @param element Canvas element\n * @param modesFilter tool modes: active, passive, enabled, disabled\n * @returns enabled tool instances\n */\nexport default function getToolsWithModesForElement(\n element: HTMLElement,\n modesFilter: ModesFilter\n) {\n const enabledElement = getEnabledElement(element)\n const { renderingEngineUID, viewportUID } = enabledElement\n\n const toolGroup = ToolGroupManager.getToolGroup(\n viewportUID,\n renderingEngineUID\n )\n\n if (!toolGroup) {\n return []\n }\n\n const enabledTools = []\n\n const toolGroupToolNames = Object.keys(toolGroup.toolOptions)\n\n for (let j = 0; j < toolGroupToolNames.length; j++) {\n const toolName = toolGroupToolNames[j]\n const toolOptions = toolGroup.toolOptions[toolName]\n\n /* filter out tools that don't have options */\n if (!toolOptions) {\n continue\n }\n\n if (modesFilter.includes(toolOptions.mode)) {\n const toolInstance = toolGroup.getToolInstance(toolName)\n enabledTools.push(toolInstance)\n }\n }\n\n return enabledTools\n}\n","import {\n getEnabledElement,\n triggerEvent,\n getRenderingEngine,\n} from '@cornerstonejs/core'\nimport { Events, ToolModes } from '../enums'\nimport { draw as drawSvg } from '../drawingSvg'\nimport getToolsWithModesForElement from './getToolsWithModesForElement'\nimport SegmentationDisplayTool from '../tools/displayTools/SegmentationDisplayTool'\nimport { AnnotationRenderedEventDetail } from '../types/EventTypes'\n\nconst { Active, Passive, Enabled } = ToolModes\n\n/**\n * AnnotationRenderingEngine is a class that is responsible for rendering\n * annotations defined in the renderAnnotation method of annotation tools on the page.\n * It mimics the RenderingEngine in the Cornerstone Core. Here it uses requestAnimationFrame\n * is used to render annotations by calling renderAnnotations() on each enabled tool. Note: This\n * is a Singleton class and should not be instantiated directly. To trigger\n * an annotation render for an HTML element containing a viewport you can use\n *\n * ```\n * triggerAnnotationRender(element)\n * ```\n */\nclass AnnotationRenderingEngine {\n public hasBeenDestroyed: boolean\n private _needsRender: Set<HTMLElement> = new Set()\n private _animationFrameSet = false\n private _animationFrameHandle: number | null = null\n private _viewportElements: Map<string, HTMLElement>\n\n constructor() {\n this._viewportElements = new Map()\n }\n\n /**\n * Add the viewport's HTMLElement to the viewports for rendering. This method\n * just informs the annotationRenderingEngine about the viewport and\n * does not initiate a render.\n * @param viewportUID - Viewport Unique identifier\n * @param element - HTMLElement\n */\n public addViewportElement(viewportUID: string, element: HTMLElement) {\n this._viewportElements.set(viewportUID, element)\n }\n\n /**\n * Remove the viewport's HTMLElement from subsequent annotation renders\n * @param viewportUID - Viewport Unique identifier\n */\n public removeViewportElement(viewportUID: string) {\n this._viewportElements.delete(viewportUID)\n\n // Reset the request animation frame if no enabled elements\n if (this._viewportElements.size === 0) {\n this._reset()\n }\n }\n\n /**\n * It tells the AnnotationRenderingEngine to render the viewport element the next\n * time it renders.\n *\n * @param element - The element to render.\n */\n public renderViewport(element: HTMLElement): void {\n this._setViewportsToBeRenderedNextFrame([element])\n }\n\n /**\n * _throwIfDestroyed Throws an error if trying to interact with the `RenderingEngine`\n * instance after its `destroy` method has been called.\n */\n private _throwIfDestroyed() {\n if (this.hasBeenDestroyed) {\n throw new Error(\n 'this.destroy() has been manually called to free up memory, can not longer use this instance. Instead make a new one.'\n )\n }\n }\n\n private _renderFlaggedViewports = () => {\n this._throwIfDestroyed()\n\n const elements = Array.from(this._viewportElements.values())\n\n for (let i = 0; i < elements.length; i++) {\n const element = elements[i]\n if (this._needsRender.has(element)) {\n this._triggerRender(element)\n\n // This viewport has been rendered, we can remove it from the set\n this._needsRender.delete(element)\n\n // If there is nothing left that is flagged for rendering, stop here\n // and allow RAF to be called again\n if (this._needsRender.size === 0) {\n this._animationFrameSet = false\n this._animationFrameHandle = null\n return\n }\n }\n }\n }\n\n private _setViewportsToBeRenderedNextFrame(elements: HTMLElement[]) {\n // Add the viewports to the set of flagged viewports\n elements.forEach((element) => {\n this._needsRender.add(element)\n })\n\n // Render any flagged viewports\n this._render()\n }\n\n /**\n * _render Sets up animation frame if necessary\n */\n private _render() {\n // If we have viewports that need rendering and we have not already\n // set the RAF callback to run on the next frame.\n if (this._needsRender.size > 0 && this._animationFrameSet === false) {\n this._animationFrameHandle = window.requestAnimationFrame(\n this._renderFlaggedViewports\n )\n\n // Set the flag that we have already set up the next RAF call.\n this._animationFrameSet = true\n }\n }\n\n _triggerRender(element) {\n const enabledElement = getEnabledElement(element)\n\n if (!enabledElement) {\n console.warn('Element has been disabled')\n return\n }\n\n const renderingEngine = getRenderingEngine(\n enabledElement.renderingEngineUID\n )\n if (!renderingEngine) {\n console.warn('rendering Engine has been destroyed')\n return\n }\n\n const enabledTools = getToolsWithModesForElement(element, [\n Active,\n Passive,\n Enabled,\n ])\n\n const { renderingEngineUID, viewportUID } = enabledElement\n const eventDetail: AnnotationRenderedEventDetail = {\n element,\n renderingEngineUID,\n viewportUID,\n }\n\n // const enabledToolsWithAnnotations = enabledTools.filter((tool) => {\n // const annotations = getAnnotations(element, (tool.constructor as typeof BaseTool).toolName)\n // return annotations && annotations.length\n // })\n\n drawSvg(element, (svgDrawingHelper) => {\n const handleDrawSvg = (tool) => {\n // Todo: we should not have the need to check tool if it is instance\n // of SegmentationDisplayTool, but right now SegmentationScissors\n // are instance of BaseTool and we cannot simply check if tool is\n // instance of AnnotationTool\n if (\n !(tool instanceof SegmentationDisplayTool) &&\n tool.renderAnnotation\n ) {\n tool.renderAnnotation(enabledElement, svgDrawingHelper)\n triggerEvent(element, Events.ANNOTATION_RENDERED, { ...eventDetail })\n }\n }\n\n enabledTools.forEach(handleDrawSvg)\n })\n }\n\n /**\n * _reset Resets the `RenderingEngine`\n */\n private _reset() {\n window.cancelAnimationFrame(this._animationFrameHandle)\n\n this._needsRender.clear()\n this._animationFrameSet = false\n this._animationFrameHandle = null\n }\n}\n\nconst annotationRenderingEngine = new AnnotationRenderingEngine()\n\n/**\n * It triggers the rendering of the annotations for the given HTML element using\n * the `AnnotationRenderingEngine`\n * @param element - The element to render the annotation on.\n */\nfunction triggerAnnotationRender(element: HTMLElement): void {\n annotationRenderingEngine.renderViewport(element)\n}\n\nexport { annotationRenderingEngine, triggerAnnotationRender }\n\nexport default triggerAnnotationRender\n","import { Settings } from '@cornerstonejs/core'\nimport { ToolModes, AnnotationStyleStates } from '../../../enums'\n\nSettings.getDefaultSettings().set('tool.style', {\n color: 'rgb(255, 255, 0)',\n colorHighlighted: 'rgb(0, 255, 0)',\n colorSelected: 'rgb(0, 255, 0)',\n colorLocked: 'rgb(255, 255, 0)',\n lineWidth: '1',\n lineDash: '',\n textBox: {\n fontFamily: 'Helvetica Neue, Helvetica, Arial, sans-serif',\n fontSize: '14px',\n color: 'rgb(255, 255, 0)',\n colorHighlighted: 'rgb(0, 255, 0)',\n colorSelected: 'rgb(0, 255, 0)',\n colorLocked: 'rgb(255, 255, 0)',\n background: '',\n link: {\n lineWidth: '1',\n lineDash: '2,3',\n },\n },\n})\n\ninitializeDefaultStyleAlternatives()\n\n/**\n * For each tool style states (Default, Highlighted, Selected, Locked),\n * and each Mode (None, Active, Inactive), it initializes the default\n * settings for the tool style.\n */\nfunction initializeDefaultStyleAlternatives(): void {\n // Todo: why there is an empty string here?\n const modes = ['', ToolModes.Active, ToolModes.Passive]\n const states = [\n AnnotationStyleStates.Default,\n AnnotationStyleStates.Highlighted,\n AnnotationStyleStates.Selected,\n AnnotationStyleStates.Locked,\n ]\n const defaultSettings = Settings.getDefaultSettings()\n defaultSettings.forEach((name: string) => {\n const nameEndsWith = (string) => string.length > 0 && name.endsWith(string)\n if (\n !name.startsWith('tool.style.') ||\n states.some(nameEndsWith) ||\n modes.some(nameEndsWith)\n ) {\n return\n }\n states.forEach((state) => {\n modes.forEach((mode) => {\n const key = `${name}${state}${mode}`\n // Todo: Is the following because of not setting object with undefined or null?\n defaultSettings.set(key, defaultSettings.get(key))\n })\n })\n })\n}\n\n/**\n * Build a list of alternative property names in ascending order of priority\n * @param property - The base property name -- e.g., 'color'\n * @param state - An optional state to determine the final property name\n * @param mode - An optional mode to determine the final property name\n * @returns A list of alternative property names\n */\nfunction getStyleAlternatives(\n property: string,\n state?: AnnotationStyleStates,\n mode?: ToolModes\n): string[] {\n const list = [`tool.style.${property}`]\n if (state) list.push(`${list[0]}${state}`)\n if (mode) list.push(`${list[list.length - 1]}${mode}`)\n return list\n}\n\n/**\n * Get the value of a style property from the settings\n * @param settings - The settings object.\n * @param property - The name of the property to get.\n * @param state - The state of the tool (Default, Locked etc.)\n * @param mode - The current tool mode. (Active, Passive etc.)\n * @returns The value of the property.\n */\nfunction getStyleProperty(\n settings: Settings,\n property: string,\n state?: AnnotationStyleStates,\n mode?: ToolModes\n): unknown {\n // `alternatives` is a list of property names with priority in ascending\n // order like: ['color', 'colorSelected', 'colorSelectedActive']\n // Thus, we attempt resolving property names in reverse order\n const alternatives = getStyleAlternatives(property, state, mode)\n for (let i = alternatives.length - 1; i >= 0; --i) {\n const style = settings.get(alternatives[i])\n if (style !== undefined) {\n return style\n }\n }\n}\n\n/**\n * Get the default value of a style property\n * @param property - The name of the style property to get.\n * @param state - The state of the tool (Default, Locked etc.)\n * @param mode - The current tool mode. (Active, Passive etc.)\n * @returns The value of the property.\n */\nfunction getDefaultStyleProperty(\n property: string,\n state?: AnnotationStyleStates,\n mode?: ToolModes\n): unknown {\n return getStyleProperty(Settings.getRuntimeSettings(), property, state, mode)\n}\n\nexport { getStyleProperty, getDefaultStyleProperty }\n","import { vec3 } from 'gl-matrix'\nimport { utilities as csUtils } from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\nimport { Annotations, Annotation } from '../../types'\n\n/**\n * given some `Annotations`, and the slice defined by the camera's normal\n * direction and the spacing in the normal, filter the `Annotations` which\n * is within the slice.\n *\n * @param annotations - Annotations\n * @param camera - The camera\n * @param spacingInNormalDirection - The spacing in the normal direction\n * @returns The filtered `Annotations`.\n */\nexport default function filterAnnotationsWithinSlice(\n annotations: Annotations,\n camera: Types.ICamera,\n spacingInNormalDirection: number\n): Annotations {\n const { viewPlaneNormal } = camera\n const annotationsWithSameNormal = annotations.filter((td: Annotation) => {\n const annotationViewPlaneNormal = td.metadata.viewPlaneNormal\n return csUtils.isEqual(annotationViewPlaneNormal, viewPlaneNormal)\n })\n\n // No in plane annotations.\n if (!annotationsWithSameNormal.length) {\n return []\n }\n\n // Annotation should be within the slice, which means that it should be between\n // camera's focalPoint +/- spacingInNormalDirection.\n\n const halfSpacingInNormalDirection = spacingInNormalDirection / 2\n const { focalPoint } = camera\n\n const annotationsWithinSlice = []\n\n for (const annotation of annotationsWithSameNormal) {\n const data = annotation.data\n const point = data.handles.points[0]\n\n // A = point\n // B = focal point\n // P = normal\n\n // B-A dot P => Distance in the view direction.\n // this should be less than half the slice distance.\n\n const dir = vec3.create()\n\n vec3.sub(dir, focalPoint, point)\n\n const dot = vec3.dot(dir, viewPlaneNormal)\n\n if (Math.abs(dot) < halfSpacingInNormalDirection) {\n annotationsWithinSlice.push(annotation)\n }\n }\n\n return annotationsWithinSlice\n}\n","import {\n StackViewport,\n VolumeViewport,\n Types,\n utilities as csUtils,\n} from '@cornerstonejs/core'\n\nimport filterAnnotationsWithinSlice from './filterAnnotationsWithinSlice'\nimport { Annotations } from '../../types'\n\n/**\n * Given the viewport and the annotations, it filters the annotations array and only\n * return those annotation that should be displayed on the viewport\n * @param annotations - Annotations\n * @returns A filtered version of the annotations.\n */\nexport default function filterAnnotationsForDisplay(\n viewport: Types.IViewport,\n annotations: Annotations\n): Annotations {\n if (viewport instanceof StackViewport) {\n // 1. Get the currently displayed imageId from the StackViewport\n const imageId = viewport.getCurrentImageId()\n\n // 2. remove the dataLoader scheme since it might be an annotation that was\n // created on the volumeViewport initially and has the volumeLoader scheme\n // but shares the same imageId\n const colonIndex = imageId.indexOf(':')\n const imageURI = imageId.substring(colonIndex + 1)\n\n // 3. Filter annotation in the frame of reference by the referenced image ID property\n return annotations.filter((annotation) => {\n return annotation.metadata.referencedImageId === imageURI\n })\n } else if (viewport instanceof VolumeViewport) {\n const camera = viewport.getCamera()\n\n const { spacingInNormalDirection } =\n csUtils.getTargetVolumeAndSpacingInNormalDir(viewport, camera)\n\n // Get data with same normal and within the same slice\n return filterAnnotationsWithinSlice(\n annotations,\n camera,\n spacingInNormalDirection\n )\n } else {\n throw new Error(`Viewport Type ${viewport.type} not supported`)\n }\n}\n","import { eventTarget, triggerEvent } from '@cornerstonejs/core'\nimport { Events } from '../../enums'\nimport { Annotation } from '../../types'\nimport { AnnotationSelectionChangeEventDetail } from '../../types/EventTypes'\n\n/*\n * Constants\n */\n\nconst selectedAnnotations: Set<Annotation> = new Set()\n\n/*\n * Interface (Public API)\n */\n\n/**\n * Set a given annotation as selected or deselected based on the provided\n * selected value.\n *\n * @param annotation - The annotation to be selected\n * @param selected - When true, the annotation is selected. When false, the annotation is deselected.\n * @param preserveSelected - When true, preserves existing\n * selections (i.e., the given annotation is appended to the selection set).\n * When false (the default behavior) the currently selected items are discarded\n * (i.e., the given annotation instance replaces the currently selected ones).\n */\nfunction setAnnotationSelected(\n annotation: Annotation,\n selected = true,\n preserveSelected = false\n): void {\n if (selected) {\n selectAnnotation(annotation, preserveSelected)\n } else {\n deselectAnnotation(annotation)\n }\n}\n\n/**\n * Set a given annotation as selected.\n *\n * @param annotation - The annotation to be selected\n * @param preserveSelected - When true, preserves existing\n * selections (i.e., the given annotation is appended to the selection set).\n * When false (the default behavior) the currently selected items are discarded\n * (i.e., the given annotation instance replaces the currently selected ones).\n */\nfunction selectAnnotation(\n annotation: Annotation,\n preserveSelected = false\n): void {\n const detail = makeEventDetail()\n if (!preserveSelected) {\n clearSelectionSet(selectedAnnotations, detail)\n }\n if (annotation && !selectedAnnotations.has(annotation)) {\n selectedAnnotations.add(annotation)\n detail.added.push(annotation)\n }\n publish(detail, selectedAnnotations)\n}\n\n/**\n * Deselect one or all annotation instances.\n *\n * @param annotation - If an annotation is provided that instance will be removed from\n * the internal selection set. If none is given, ALL selections will be cleared.\n */\nfunction deselectAnnotation(annotation?: Annotation): void {\n const detail = makeEventDetail()\n if (annotation) {\n if (selectedAnnotations.delete(annotation)) {\n detail.removed.push(annotation)\n }\n } else {\n clearSelectionSet(selectedAnnotations, detail)\n }\n publish(detail, selectedAnnotations)\n}\n\n/**\n * Return an array of ALL the selected annotation\n * @returns An array of Annotation objects.\n */\nfunction getAnnotationsSelected(): Array<Annotation> {\n return Array.from(selectedAnnotations)\n}\n\n/**\n * Given a annotationUID, return the Annotation object that has that\n * annotationUID\n * @param annotationUID - The UID of the annotation to be retrieved.\n * @returns A Annotation object.\n */\nfunction getAnnotationSelected(annotationUID: string): Annotation {\n return getAnnotationsSelected().find((annotation) => {\n return annotation.annotationUID === annotationUID\n })\n}\n\n/**\n * Given a tool name, return ALL the annotation for that tool that are selected\n * @param toolName - The name of the tool you want to get the selected annotation for\n * @returns An array of tool specific annotation that are selected\n */\nfunction getAnnotationsSelectedByToolName(toolName: string): Array<Annotation> {\n return getAnnotationsSelected().filter((annotation) => {\n return annotation.metadata.toolName === toolName\n })\n}\n\n/**\n * Given an annotation object, return true if it is selected, false\n * otherwise.\n * @param annotation - Annotation\n * @returns A boolean value.\n */\nfunction isAnnotationSelected(annotation: Annotation): boolean {\n return selectedAnnotations.has(annotation)\n}\n\n/**\n * Return the number of the selected annotation\n * @returns The size of the selected annotation set\n */\nfunction getAnnotationsSelectedCount(): number {\n return selectedAnnotations.size\n}\n\n/*\n * Private Helpers\n */\n\nfunction makeEventDetail(): AnnotationSelectionChangeEventDetail {\n return Object.freeze({\n added: [],\n removed: [],\n selection: [],\n })\n}\n\nfunction clearSelectionSet(\n selectionSet: Set<Annotation>,\n detail: AnnotationSelectionChangeEventDetail\n): void {\n selectionSet.forEach((value) => {\n if (selectionSet.delete(value)) {\n detail.removed.push(value)\n }\n })\n}\n\nfunction publish(\n detail: AnnotationSelectionChangeEventDetail,\n selectionSet: Set<Annotation>\n) {\n if (detail.added.length > 0 || detail.removed.length > 0) {\n selectionSet.forEach((item) => void detail.selection.push(item))\n triggerEvent(eventTarget, Events.ANNOTATION_SELECTION_CHANGE, detail)\n }\n}\n\n/*\n * Exports\n */\n\nexport {\n setAnnotationSelected,\n getAnnotationsSelected,\n getAnnotationSelected,\n getAnnotationsSelectedByToolName,\n getAnnotationsSelectedCount,\n isAnnotationSelected,\n}\n","import { Annotation } from '../../../types'\nimport { isAnnotationLocked } from '../annotationLocking'\nimport { isAnnotationSelected } from '../annotationSelection'\nimport { AnnotationStyleStates } from '../../../enums'\n\n/**\n * Given a Annotation object, return the annotationStyle State that it\n * should be in based on its data\n * @param annotation - The annotation that we want to style.\n * @returns The state of the annotation whether it is Default, Highlighted, Locked, or Selected.\n */\nfunction getState(annotation?: Annotation): AnnotationStyleStates {\n if (annotation) {\n if (annotation.data && annotation.highlighted)\n return AnnotationStyleStates.Highlighted\n if (isAnnotationSelected(annotation)) return AnnotationStyleStates.Selected\n if (isAnnotationLocked(annotation)) return AnnotationStyleStates.Locked\n }\n\n return AnnotationStyleStates.Default\n}\n\nexport default getState\n","import { Settings } from '@cornerstonejs/core'\nimport state from '../../../store/state'\n\n/**\n * Get the style for a tool based on provided information.\n *\n * No toolName or annotation provided:\n * - It returns the runtime setting style which applies to all tools.\n *\n * toolName provided:\n * - It returns the object setting for the Tool class\n *\n * toolName and annotation provided:\n * - It returns the object setting for the Tool class AND that specific annotation.\n *\n * @param toolName - The name of the tool.\n * @param annotation - The annotation object that was passed to the\n * @returns A `Settings` object.\n */\nexport default function getStyle(\n toolName?: string,\n annotation?: Record<string, unknown>\n): Settings {\n if (toolName) {\n const descriptor = state.tools[toolName]\n if (descriptor) {\n const { toolClass } = descriptor\n if (annotation) {\n return Settings.getObjectSettings(annotation, toolClass)\n }\n return Settings.getObjectSettings(toolClass)\n }\n }\n return Settings.getRuntimeSettings()\n}\n","import { Settings } from '@cornerstonejs/core'\nimport { ToolModes, AnnotationStyleStates } from '../../../enums'\nimport { getStyleProperty } from './annotationStyle'\n\n/**\n * getFont - Returns a font string of the form \"{fontSize}px fontName\" used by `canvas`.\n * @param settings - An optional Settings instance to read from.\n * @param state - An optional state to determine the final property name\n * @param mode - An optional mode to determine the final property name\n * @returns The font string.\n */\nfunction getFont(\n settings?: Settings,\n state?: AnnotationStyleStates,\n mode?: ToolModes\n): string {\n const sty = Settings.assert(settings)\n const fontSize = getStyleProperty(sty, 'textBox.fontSize', state, mode)\n const fontFamily = getStyleProperty(sty, 'textBox.fontFamily', state, mode)\n return `${fontSize}px ${fontFamily}`\n}\n\nexport default getFont\n","import { Settings } from '@cornerstonejs/core'\nimport state from '../../../store/state'\n\n/**\n * Set the style of an annotation object\n * @param string - toolName - The name of the tool.\n * @param annotation - The annotation object.\n * @param style - The style object to set.\n * @returns A boolean value indicating whether the style was set.\n */\nfunction setAnnotationStyle(\n toolName: string,\n annotation: Record<string, unknown>,\n style: Record<string, unknown>\n): boolean {\n const descriptor = state.tools[toolName]\n if (descriptor) {\n const { toolClass } = descriptor\n return Settings.getObjectSettings(annotation, toolClass).set(\n 'tool.style',\n style\n )\n }\n return false\n}\n\nexport default setAnnotationStyle\n","import { Settings } from '@cornerstonejs/core'\n\n/**\n * Takes a `style` object and sets it as the\n * global style\n * @param style - The style object to set.\n * @returns A boolean value.\n */\nexport default function setGlobalStyle(\n style: Record<string, unknown>\n): boolean {\n return Settings.getRuntimeSettings().set('tool.style', style)\n}\n","import { Settings } from '@cornerstonejs/core'\nimport state from '../../../store/state'\n\n/**\n * Set the style of a specific tool with the provided toolName\n * @param toolName - The name of the tool.\n * @param style - The style object to set.\n * @returns A boolean indicating whether the style was set correctly or not.\n */\nexport default function setToolStyle(\n toolName: string,\n style: Record<string, unknown>\n): boolean {\n const descriptor = state.tools[toolName]\n if (descriptor) {\n const { toolClass } = descriptor\n return Settings.getObjectSettings(toolClass).set('tool.style', style)\n }\n return false\n}\n","import {\n utilities,\n getEnabledElement,\n VolumeViewport,\n Settings,\n} from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\n\nimport { vec4, vec2 } from 'gl-matrix'\n\nimport BaseTool from './BaseTool'\nimport { isAnnotationLocked } from '../../stateManagement/annotation/annotationLocking'\nimport { getViewportSpecificAnnotationManager } from '../../stateManagement/annotation/annotationState'\nimport {\n Annotation,\n Annotations,\n EventTypes,\n ToolHandle,\n InteractionTypes,\n} from '../../types'\nimport triggerAnnotationRender from '../../utilities/triggerAnnotationRender'\nimport filterAnnotationsForDisplay from '../../utilities/planar/filterAnnotationsForDisplay'\nimport { getStyleProperty } from '../../stateManagement/annotation/config/annotationStyle'\nimport { getState } from '../../stateManagement/annotation/config'\n\n/**\n * Abstract class for tools which create and display annotations on the\n * cornerstone3D canvas. In addition, it provides a base class for segmentation\n * tools that require drawing an annotation before running the segmentation strategy\n * for instance threshold segmentation based on an area and a threshold.\n * Annotation tools make use of drawing utilities to draw SVG elements on the viewport.\n *\n * To create a new annotation tool, derive from this class and implement the\n * abstract methods.\n */\nabstract class AnnotationTool extends BaseTool {\n static toolName = 'AnnotationTool'\n // ===================================================================\n // Abstract Methods - Must be implemented.\n // ===================================================================\n\n /**\n * @abstract addNewAnnotation Creates a new annotation based on the clicked mouse position\n *\n * @param evt - The normalized mouse event\n * @param interactionType - The interaction type used to add the annotation.\n */\n abstract addNewAnnotation(\n evt: EventTypes.MouseDownActivateEventType,\n interactionType: InteractionTypes\n ): Annotation\n\n /**\n * @abstract renderAnnotation it used to draw the tool's annotation in each\n * request animation frame\n *\n * @param enabledElement - The Cornerstone's enabledElement.\n * @param svgDrawingHelper - The svgDrawingHelper providing the context for drawing.\n */\n abstract renderAnnotation(\n enabledElement: Types.IEnabledElement,\n svgDrawingHelper: any\n )\n\n /**\n * @abstract cancel Used to cancel the ongoing tool drawing and manipulation\n *\n */\n abstract cancel(element: HTMLElement)\n\n /**\n * handleSelectedCallback Custom callback for when a handle is selected.\n *\n * @param evt - The normalized mouse event\n * @param annotation - The annotation selected.\n * @param handle - The selected handle (either Types.Point3 in space for annotations, or TextBoxHandle object for text boxes).\n * @param interactionType - The interaction type the handle was selected with.\n */\n abstract handleSelectedCallback(\n evt: EventTypes.MouseDownEventType,\n annotation: Annotation,\n handle: ToolHandle,\n interactionType: InteractionTypes\n ): void\n\n /**\n * Custom callback for when an annotation is selected\n *\n * @param evt - The normalized mouse event\n * @param annotation - The `Annotation` to check.\n * @param interactionType - The interaction type used to select the tool.\n */\n abstract toolSelectedCallback(\n evt: EventTypes.MouseDownEventType,\n annotation: Annotation,\n interactionType: InteractionTypes\n ): void\n\n /**\n * Returns true if the provided canvas coordinate tool is near the annotation\n *\n * @param element - The HTML element\n * @param annotation - The annotation to check\n * @param canvasCoords - The canvas coordinate to check\n * @param proximity - The minimum proximity to consider the point near\n * @param interactionType - The interaction type used to select the tool.\n *\n * @returns boolean if the point is near.\n */\n abstract isPointNearTool(\n element: HTMLElement,\n annotation: Annotation,\n canvasCoords: Types.Point2,\n proximity: number,\n interactionType: string\n ): boolean\n\n /**\n * @virtual Given the element and annotations which is an array of annotation, it\n * filters the annotations array to only include the annotation based on the viewportType.\n * If the viewport is StackViewport, it filters based on the current imageId of the viewport,\n * if the viewport is volumeViewport, it only returns those that are within the\n * same slice as the current rendered slice in the volume viewport.\n * imageId as the enabledElement.\n * @param element - The HTML element\n * @param annotations - The annotations to filter (array of annotation)\n * @returns The filtered annotations\n */\n filterInteractableAnnotationsForElement(\n element: HTMLElement,\n annotations: Annotations\n ): Annotations | undefined {\n if (!annotations || !annotations.length) {\n return\n }\n\n const enabledElement = getEnabledElement(element)\n const { viewport } = enabledElement\n\n return filterAnnotationsForDisplay(viewport, annotations)\n }\n\n /**\n * @virtual Event handler for Cornerstone MOUSE_MOVE event.\n *\n *\n * @param evt - The normalized mouse event\n * @param filteredAnnotations - The annotations to check for hover interactions\n * @returns True if the annotation needs to be re-drawn by the annotationRenderingEngine.\n */\n public mouseMoveCallback = (\n evt: EventTypes.MouseMoveEventType,\n filteredAnnotations: Annotations\n ): boolean => {\n const { element, currentPoints } = evt.detail\n const canvasCoords = currentPoints.canvas\n let annotationsNeedToBeRedrawn = false\n\n for (const annotation of filteredAnnotations) {\n // Do not do anything if the annotation is locked\n if (isAnnotationLocked(annotation)) {\n continue\n }\n\n const { data } = annotation\n const activateHandleIndex = data.handles\n ? data.handles.activeHandleIndex\n : undefined\n\n // Perform tool specific imagePointNearToolOrHandle to determine if the mouse\n // is near the tool or its handles or its textBox.\n const near = this._imagePointNearToolOrHandle(\n element,\n annotation,\n canvasCoords,\n 6 // Todo: This should come from the state\n )\n\n const nearToolAndNotMarkedActive = near && !annotation.highlighted\n const notNearToolAndMarkedActive = !near && annotation.highlighted\n if (nearToolAndNotMarkedActive || notNearToolAndMarkedActive) {\n annotation.highlighted = !annotation.highlighted\n annotationsNeedToBeRedrawn = true\n } else if (\n data.handles &&\n data.handles.activeHandleIndex !== activateHandleIndex\n ) {\n // Active handle index has changed, re-render.\n annotationsNeedToBeRedrawn = true\n }\n }\n\n return annotationsNeedToBeRedrawn\n }\n\n /**\n * On Image Calibration, take all the annotation from the AnnotationState manager,\n * and invalidate them to force them to be re-rendered and their stats to be recalculated.\n * Then use the old and new imageData (non-calibrated and calibrated) to calculate the\n * new position for the annotations in the space of the new imageData.\n *\n * @param evt - The calibration event\n *\n */\n public onImageSpacingCalibrated = (\n evt: Types.EventTypes.ImageSpacingCalibratedEvent\n ) => {\n const {\n element,\n rowScale,\n columnScale,\n imageId,\n imageData: calibratedImageData,\n worldToIndex: noneCalibratedWorldToIndex,\n } = evt.detail\n\n const { viewport } = getEnabledElement(element)\n\n if (viewport instanceof VolumeViewport) {\n throw new Error('Cannot calibrate a volume viewport')\n }\n\n const calibratedIndexToWorld = calibratedImageData.getIndexToWorld()\n\n const imageURI = utilities.imageIdToURI(imageId)\n const stateManager = getViewportSpecificAnnotationManager(element)\n const framesOfReference = stateManager.getFramesOfReference()\n\n // For each frame Of Reference\n framesOfReference.forEach((frameOfReference) => {\n const frameOfReferenceSpecificAnnotations =\n stateManager.getFrameOfReferenceAnnotations(frameOfReference)\n\n const toolSpecificAnnotations =\n frameOfReferenceSpecificAnnotations[this.getToolName()]\n\n if (!toolSpecificAnnotations || !toolSpecificAnnotations.length) {\n return\n }\n\n // for this specific tool\n toolSpecificAnnotations.forEach((annotation) => {\n // if the annotation is drawn on the same imageId\n if (annotation.metadata.referencedImageId === imageURI) {\n // make them invalid since the image has been calibrated so that\n // we can update the cachedStats and also rendering\n annotation.invalidated = true\n annotation.data.cachedStats = {}\n\n // Update annotation points to the new calibrated points. Basically,\n // using the worldToIndex function we get the index on the non-calibrated\n // image and then using the calibratedIndexToWorld function we get the\n // corresponding point on the calibrated image world.\n annotation.data.handles.points = annotation.data.handles.points.map(\n (point) => {\n const p = vec4.fromValues(...point, 1)\n const pCalibrated = vec4.fromValues(0, 0, 0, 1)\n const nonCalibratedIndexVec4 = vec4.create()\n vec4.transformMat4(\n nonCalibratedIndexVec4,\n p,\n noneCalibratedWorldToIndex\n )\n const calibratedIndex = [\n columnScale * nonCalibratedIndexVec4[0],\n rowScale * nonCalibratedIndexVec4[1],\n nonCalibratedIndexVec4[2],\n ]\n\n vec4.transformMat4(\n pCalibrated,\n vec4.fromValues(\n calibratedIndex[0],\n calibratedIndex[1],\n calibratedIndex[2],\n 1\n ),\n calibratedIndexToWorld\n )\n\n return pCalibrated.slice(0, 3) as Types.Point3\n }\n )\n }\n })\n\n triggerAnnotationRender(element)\n })\n }\n\n /**\n * It checks if the mouse click is near TextBoxHandle or AnnotationHandle itself, and\n * return either it. It prioritize TextBoxHandle over AnnotationHandle. If\n * the mouse click is not near any of the handles, it does not return anything.\n *\n * @param element - The element that the tool is attached to.\n * @param annotation - The annotation object associated with the annotation\n * @param canvasCoords - The coordinates of the mouse click on canvas\n * @param proximity - The distance from the mouse cursor to the point\n * that is considered \"near\".\n * @returns The handle that is closest to the cursor, or null if the cursor\n * is not near any of the handles.\n */\n getHandleNearImagePoint(\n element: HTMLElement,\n annotation: Annotation,\n canvasCoords: Types.Point2,\n proximity: number\n ): ToolHandle | undefined {\n const enabledElement = getEnabledElement(element)\n const { viewport } = enabledElement\n\n const { data } = annotation\n const { points, textBox } = data.handles\n const { worldBoundingBox } = textBox\n\n if (worldBoundingBox) {\n const canvasBoundingBox = {\n topLeft: viewport.worldToCanvas(worldBoundingBox.topLeft),\n topRight: viewport.worldToCanvas(worldBoundingBox.topRight),\n bottomLeft: viewport.worldToCanvas(worldBoundingBox.bottomLeft),\n bottomRight: viewport.worldToCanvas(worldBoundingBox.bottomRight),\n }\n\n if (\n canvasCoords[0] >= canvasBoundingBox.topLeft[0] &&\n canvasCoords[0] <= canvasBoundingBox.bottomRight[0] &&\n canvasCoords[1] >= canvasBoundingBox.topLeft[1] &&\n canvasCoords[1] <= canvasBoundingBox.bottomRight[1]\n ) {\n data.handles.activeHandleIndex = null\n return textBox\n }\n }\n\n for (let i = 0; i < points.length; i++) {\n const point = points[i]\n const annotationCanvasCoordinate = viewport.worldToCanvas(point)\n\n const near =\n vec2.distance(canvasCoords, annotationCanvasCoordinate) < proximity\n\n if (near === true) {\n data.handles.activeHandleIndex = i\n return point\n }\n }\n\n data.handles.activeHandleIndex = null\n }\n\n /**\n * It takes the settings (e.g., global, or runtime setting), the property (e.g., 'lineWidth'),\n * and the annotation, and returns the value of the property\n * of the property\n * @param settings - The settings object for the tool.\n * @param property - The name of the style property to get.\n * @param annotation - The annotation for the tool that is\n * currently active.\n * @returns The value of the property.\n */\n public getStyle(\n settings: Settings,\n property: string,\n annotation?: Annotation\n ): unknown {\n return getStyleProperty(settings, property, getState(annotation), this.mode)\n }\n\n /**\n * It returns the style for the text box\n * @param settings - The settings object for the tool.\n * @param annotation - The annotation for the tool that is\n * currently active.\n * @returns An object of the style settings for the text box.\n */\n public getLinkedTextBoxStyle(\n settings: Settings,\n annotation?: Annotation\n ): Record<string, unknown> {\n // Todo: this function can be used to set different styles for different toolMode\n // for the textBox.\n\n return {\n fontFamily: this.getStyle(settings, 'textBox.fontFamily', annotation),\n fontSize: this.getStyle(settings, 'textBox.fontSize', annotation),\n color: this.getStyle(settings, 'textBox.color', annotation),\n background: this.getStyle(settings, 'textBox.background', annotation),\n lineWidth: this.getStyle(settings, 'textBox.link.lineWidth', annotation),\n lineDash: this.getStyle(settings, 'textBox.link.lineDash', annotation),\n }\n }\n\n /**\n * Returns true if the `canvasCoords` are near a handle or selectable part of the tool\n *\n * @param element - The HTML element\n * @param annotation - The annotation to check\n * @param canvasCoords - The canvas coordinates to check\n * @param proximity - The proximity to consider\n *\n * @returns If the point is near.\n */\n private _imagePointNearToolOrHandle(\n element: HTMLElement,\n annotation: Annotation,\n canvasCoords: Types.Point2,\n proximity: number\n ): boolean {\n // Based on the tool instance type, check if the point is near the tool handles\n const handleNearImagePoint = this.getHandleNearImagePoint(\n element,\n annotation,\n canvasCoords,\n proximity\n )\n\n if (handleNearImagePoint) {\n return true\n }\n\n // If the point is not near the handles, check if the point is near the tool\n const toolNewImagePoint = this.isPointNearTool(\n element,\n annotation,\n canvasCoords,\n proximity,\n 'mouse'\n )\n\n if (toolNewImagePoint) {\n return true\n }\n }\n}\n\nexport default AnnotationTool\n","function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {\n try {\n var info = gen[key](arg);\n var value = info.value;\n } catch (error) {\n reject(error);\n return;\n }\n\n if (info.done) {\n resolve(value);\n } else {\n Promise.resolve(value).then(_next, _throw);\n }\n}\n\nexport default function _asyncToGenerator(fn) {\n return function () {\n var self = this,\n args = arguments;\n return new Promise(function (resolve, reject) {\n var gen = fn.apply(self, args);\n\n function _next(value) {\n asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"next\", value);\n }\n\n function _throw(err) {\n asyncGeneratorStep(gen, resolve, reject, _next, _throw, \"throw\", err);\n }\n\n _next(undefined);\n });\n };\n}","import { SegmentationDataInput } from '../../../types/SegmentationStateTypes'\n\n/**\n * Checks if the segmentationDataArray is valid meaning it contains\n * volumeUID of the segmentation.\n *\n * @param segmentationDataArray - Array of segmentationData\n * @internal\n */\nfunction checkSegmentationDataIsValid(\n segmentationDataArray: SegmentationDataInput[]\n): void {\n if (!segmentationDataArray || !segmentationDataArray.length) {\n throw new Error('The segmentationDataArray undefined or empty array')\n }\n\n // check if volumeUID is present in all the segmentationDataArray\n segmentationDataArray.forEach((segmentationData) => {\n if (!segmentationData.volumeUID) {\n throw new Error('volumeUID is missing in the segmentationData')\n }\n })\n}\n\nexport default checkSegmentationDataIsValid\n","import {\n getEnabledElement,\n addVolumesToViewports,\n} from '@cornerstonejs/core'\n\nimport SegmentationRepresentations from '../../../enums/SegmentationRepresentations'\nimport { ToolGroupSpecificSegmentationData } from '../../../types/SegmentationStateTypes'\n\n/**\n * It adds a segmentation data to the viewport's HTML Element. NOTE: This function\n * should not be called directly. You should use addSegmentationToToolGroup instead.\n * Remember that segmentations are not added directly to the viewport's HTML Element,\n * you should create a toolGroup on the viewports and add the segmentation to the\n * toolGroup.\n *\n * @param element - The element that will be rendered.\n * @param segmentationData - ToolGroupSpecificSegmentationData\n *\n * @internal\n */\nasync function internalAddSegmentationToElement(\n element: HTMLElement,\n segmentationData: ToolGroupSpecificSegmentationData\n): Promise<void> {\n if (!element || !segmentationData) {\n throw new Error('You need to provide an element and a segmentation')\n }\n\n const enabledElement = getEnabledElement(element)\n const { renderingEngine, viewport } = enabledElement\n const { uid: viewportUID } = viewport\n\n // Default to true since we are setting a new segmentation, however,\n // in the event listener, we will make other segmentations visible/invisible\n // based on the config\n const visibility = true\n\n const { representation, segmentationDataUID } = segmentationData\n\n if (representation.type === SegmentationRepresentations.Labelmap) {\n const { volumeUID } = segmentationData\n // Add labelmap volumes to the viewports to be be rendered, but not force the render\n await addVolumesToViewports(\n renderingEngine,\n [\n {\n volumeUID,\n actorUID: segmentationDataUID,\n visibility,\n },\n ],\n [viewportUID]\n )\n } else {\n throw new Error('Only labelmap representation is supported for now')\n }\n}\n\nexport default internalAddSegmentationToElement\n","import { getEnabledElement } from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\nimport { ToolGroupSpecificSegmentationData } from '../../../types/SegmentationStateTypes'\nimport SegmentationRepresentations from '../../../enums/SegmentationRepresentations'\n\n/**\n * Remove the segmentation from the viewport's HTML Element.\n * NOTE: This function should not be called directly. You should use removeSegmentationFromToolGroup instead.\n * Remember that segmentations are not removed directly to the viewport's HTML Element,\n * you should use the toolGroups to do that\n *\n * @param element - The element that the segmentation is being added\n * to.\n * @param segmentationData - ToolGroupSpecificSegmentationData\n * @param removeFromCache - boolean\n *\n * @internal\n */\nfunction internalRemoveSegmentationFromElement(\n element: HTMLElement,\n segmentationData: ToolGroupSpecificSegmentationData,\n removeFromCache = false // Todo\n): void {\n const enabledElement = getEnabledElement(element)\n const { viewport } = enabledElement\n\n const { representation, segmentationDataUID } = segmentationData\n\n if (representation.type === SegmentationRepresentations.Labelmap) {\n ;(viewport as Types.IVolumeViewport).removeVolumeActors([\n segmentationDataUID,\n ])\n } else {\n throw new Error('Only labelmap representation is supported for now')\n }\n}\n\nexport default internalRemoveSegmentationFromElement\n","import vtkColorTransferFunction from 'vtk.js/Sources/Rendering/Core/ColorTransferFunction'\nimport vtkPiecewiseFunction from 'vtk.js/Sources/Common/DataModel/PiecewiseFunction'\n\nimport { cache, getEnabledElementByUIDs, Types } from '@cornerstonejs/core'\n\nimport * as SegmentationState from '../../../stateManagement/segmentation/segmentationState'\nimport { LabelmapRepresentation } from '../../../types/SegmentationRepresentationTypes'\nimport Representations from '../../../enums/SegmentationRepresentations'\nimport { getToolGroupByToolGroupUID } from '../../../store/ToolGroupManager'\nimport type { LabelmapConfig } from './LabelmapConfig'\nimport {\n SegmentationConfig,\n ToolGroupSpecificSegmentationData,\n} from '../../../types/SegmentationStateTypes'\n\nimport {\n internalAddSegmentationToElement,\n internalRemoveSegmentationFromElement,\n} from '../../../stateManagement/segmentation/helpers'\n\nimport { deepMerge } from '../../../utilities'\nimport { IToolGroup } from '../../../types'\n\nconst MAX_NUMBER_COLORS = 255\nconst labelMapConfigCache = new Map()\n\n/**\n * For each viewport, and for each segmentation, set the segmentation for the viewport's enabled element\n * Initializes the global and viewport specific state for the segmentation in the\n * SegmentationStateManager.\n * @param toolGroup - the tool group that contains the viewports\n * @param segmentationDataArray - the array of segmentation data\n */\nasync function addSegmentationData(\n toolGroupUID: string,\n segmentationData: Partial<ToolGroupSpecificSegmentationData>,\n toolGroupSpecificConfig?: SegmentationConfig\n): Promise<void> {\n const { volumeUID, segmentationDataUID, representation } = segmentationData\n\n await _addLabelmapToToolGroupViewports(toolGroupUID, segmentationData)\n\n // Viewport Specific Rendering State for the segmentation\n // Merging the default configuration with the configuration passed in the arguments\n const segmentsHidden =\n segmentationData.segmentsHidden !== undefined\n ? segmentationData.segmentsHidden\n : (new Set() as Set<number>)\n\n const visibility =\n segmentationData.visibility !== undefined\n ? segmentationData.visibility\n : true\n\n const colorLUTIndex =\n segmentationData.colorLUTIndex !== undefined\n ? segmentationData.colorLUTIndex\n : 0\n\n const active =\n segmentationData.active !== undefined ? segmentationData.active : true\n\n const cfun =\n representation.config.cfun || vtkColorTransferFunction.newInstance()\n const ofun = representation.config.ofun || vtkPiecewiseFunction.newInstance()\n\n const mergedSegmentationData = {\n volumeUID,\n segmentationDataUID,\n segmentsHidden,\n visibility,\n colorLUTIndex,\n active,\n representation: {\n type: Representations.Labelmap,\n config: {\n cfun,\n ofun,\n },\n },\n } as ToolGroupSpecificSegmentationData\n\n // Update the toolGroup specific configuration\n if (toolGroupSpecificConfig) {\n // Since setting configuration on toolGroup will trigger a segmentationState\n // updated event, we don't want to trigger the event twice, so we suppress\n // the first one\n const suppressEvents = true\n const currentToolGroupConfig =\n SegmentationState.getSegmentationConfig(toolGroupUID)\n\n const mergedConfig = deepMerge(\n currentToolGroupConfig,\n toolGroupSpecificConfig\n )\n\n SegmentationState.setSegmentationConfig(\n toolGroupUID,\n {\n renderInactiveSegmentations:\n mergedConfig.renderInactiveSegmentations || true,\n representations: {\n ...mergedConfig.representations,\n },\n },\n suppressEvents\n )\n }\n\n // Add data first\n SegmentationState.addSegmentationData(toolGroupUID, mergedSegmentationData)\n}\n\n/**\n * For each viewport, and for each segmentation, set the segmentation for the viewport's enabled element\n * Initializes the global and viewport specific state for the segmentation in the\n * SegmentationStateManager.\n * @param toolGroup - the tool group that contains the viewports\n * @param segmentationDataArray - the array of segmentation data\n */\nfunction removeSegmentationData(\n toolGroupUID: string,\n segmentationDataUID: string\n): void {\n _removeLabelmapFromToolGroupViewports(toolGroupUID, segmentationDataUID)\n SegmentationState.removeSegmentationData(toolGroupUID, segmentationDataUID)\n}\n\n/**\n * It takes the enabled element, the segmentation UID, and the configuration, and\n * it sets the segmentation for the enabled element as a labelmap\n * @param enabledElement - The cornerstone enabled element\n * @param segmentationUID - The UID of the segmentation to be rendered.\n * @param configuration - The configuration object for the labelmap.\n */\nfunction render(\n viewport: Types.IViewport,\n segmentationData: ToolGroupSpecificSegmentationData,\n config: SegmentationConfig\n): void {\n const {\n volumeUID: labelmapUID,\n colorLUTIndex,\n active,\n representation,\n segmentationDataUID,\n visibility,\n } = segmentationData\n\n const labelmapRepresentation = representation as LabelmapRepresentation\n\n const labelmap = cache.getVolume(labelmapUID)\n\n if (!labelmap) {\n throw new Error(`No Labelmap found for UID: ${labelmapUID}`)\n }\n\n const actor = viewport.getActor(segmentationDataUID)\n if (!actor) {\n console.warn('No actor found for actorUID: ', segmentationDataUID)\n return\n }\n\n const { cfun, ofun } = labelmapRepresentation.config\n\n const labelmapConfig = config.representations[Representations.Labelmap]\n const renderInactiveSegmentations = config.renderInactiveSegmentations\n\n _setLabelmapColorAndOpacity(\n viewport.uid,\n actor,\n cfun,\n ofun,\n colorLUTIndex,\n labelmapConfig,\n active,\n renderInactiveSegmentations,\n visibility\n )\n}\n\nfunction _setLabelmapColorAndOpacity(\n viewportUID: string,\n actor: Types.ActorEntry,\n cfun: vtkColorTransferFunction,\n ofun: vtkPiecewiseFunction,\n colorLUTIndex: number,\n labelmapConfig: LabelmapConfig,\n isActiveLabelmap: boolean,\n renderInactiveSegmentations: boolean,\n visibility = true\n): void {\n ofun.addPoint(0, 0)\n\n const fillAlpha = isActiveLabelmap\n ? labelmapConfig.fillAlpha\n : labelmapConfig.fillAlphaInactive\n const outlineWidth = isActiveLabelmap\n ? labelmapConfig.outlineWidthActive\n : labelmapConfig.outlineWidthInactive\n\n // Note: MAX_NUMBER_COLORS = 256 is needed because the current method to generate\n // the default color table uses RGB.\n\n const colorLUT = SegmentationState.getColorLut(colorLUTIndex)\n const numColors = Math.min(256, colorLUT.length)\n const { volumeActor, uid } = actor\n\n const needUpdate = _needsTransferFunctionUpdateUpdate(\n viewportUID,\n actor.uid,\n fillAlpha,\n colorLUTIndex\n )\n\n // recent change to ColorTransferFunction has aff\n\n if (needUpdate) {\n for (let i = 0; i < numColors; i++) {\n const color = colorLUT[i]\n cfun.addRGBPoint(\n i,\n color[0] / MAX_NUMBER_COLORS,\n color[1] / MAX_NUMBER_COLORS,\n color[2] / MAX_NUMBER_COLORS\n )\n\n // Set the opacity per label.\n const segmentOpacity = (color[3] / 255) * fillAlpha\n ofun.addPoint(i, segmentOpacity)\n }\n ofun.setClamping(false)\n volumeActor.getProperty().setRGBTransferFunction(0, cfun)\n volumeActor.getProperty().setScalarOpacity(0, ofun)\n }\n\n volumeActor.getProperty().setInterpolationTypeToNearest()\n\n volumeActor.getProperty().setUseLabelOutline(labelmapConfig.renderOutline)\n volumeActor.getProperty().setLabelOutlineThickness(outlineWidth)\n\n // Set visibility based on whether actor visibility is specifically asked\n // to be turned on/off (on by default) AND whether is is in active but\n // we are rendering inactive labelmap\n const visible =\n visibility && (isActiveLabelmap || renderInactiveSegmentations)\n volumeActor.setVisibility(visible)\n}\n\nfunction _needsTransferFunctionUpdateUpdate(\n viewportUID: string,\n actorUID: string,\n fillAlpha: number,\n colorLUTIndex: number\n): boolean {\n const cacheUID = `${viewportUID}-${actorUID}`\n const config = labelMapConfigCache.get(cacheUID)\n\n if (\n config &&\n config.fillAlpha === fillAlpha &&\n config.colorLUTIndex === colorLUTIndex\n ) {\n return false\n }\n\n labelMapConfigCache.set(cacheUID, {\n fillAlpha,\n colorLUTIndex,\n })\n\n return true\n}\n\nfunction _removeLabelmapFromToolGroupViewports(\n toolGroupUID: string,\n segmentationDataUID: string\n): void {\n const toolGroup = getToolGroupByToolGroupUID(toolGroupUID)\n\n if (toolGroup === undefined) {\n throw new Error(\n `ToolGroup with ToolGroupUID ${toolGroupUID} does not exist`\n )\n }\n\n const { viewportsInfo } = toolGroup\n\n const segmentationData = SegmentationState.getSegmentationDataByUID(\n toolGroupUID,\n segmentationDataUID\n )\n\n for (const viewportInfo of viewportsInfo) {\n const { viewportUID, renderingEngineUID } = viewportInfo\n const enabledElement = getEnabledElementByUIDs(\n viewportUID,\n renderingEngineUID\n )\n internalRemoveSegmentationFromElement(\n enabledElement.viewport.element,\n segmentationData\n )\n }\n}\n\nasync function _addLabelmapToToolGroupViewports(\n toolGroupUID,\n segmentationData\n): Promise<void> {\n const toolGroup = getToolGroupByToolGroupUID(toolGroupUID) as IToolGroup\n const { viewportsInfo } = toolGroup\n\n for (const viewportInfo of viewportsInfo) {\n const { viewportUID, renderingEngineUID } = viewportInfo\n const enabledElement = getEnabledElementByUIDs(\n viewportUID,\n renderingEngineUID\n )\n\n if (!enabledElement) {\n throw new Error(\n `No enabled element found for rendering engine: ${renderingEngineUID} and viewport: ${viewportUID}`\n )\n }\n\n const { viewport } = enabledElement\n internalAddSegmentationToElement(viewport.element, segmentationData)\n }\n}\n\nexport default {\n render,\n addSegmentationData,\n removeSegmentationData,\n}\n","/**\n * Label map config for the label map representation\n */\nexport type LabelmapConfig = {\n /** whether to render segmentation outline */\n renderOutline?: boolean\n /** thickness of the outline */\n outlineWidth?: number\n /** thickness of the outline when segmentation is active */\n outlineWidthActive?: number\n /** thickness of the outline when segmentation is inactive */\n outlineWidthInactive?: number\n /** whether to render segmentation filling */\n renderFill?: boolean\n /** alpha of the fill */\n fillAlpha?: number\n /** alpha of the fill when inactive */\n fillAlphaInactive?: number\n}\n\nconst defaultLabelmapConfig: LabelmapConfig = {\n renderOutline: true,\n outlineWidth: 3,\n outlineWidthActive: 3,\n outlineWidthInactive: 2,\n renderFill: true,\n fillAlpha: 0.9,\n fillAlphaInactive: 0.85,\n // Todo: not supported yet\n // outlineAlpha: 0.7,\n // outlineAlphaInactive: 0.35,\n // Fill inside the render maps\n}\n\nfunction getDefaultLabelmapConfig(): LabelmapConfig {\n return defaultLabelmapConfig\n}\n\n// Checks if the labelmap config is valid, which means\n// if all the required fields are present and have the correct type\nfunction isValidLabelmapConfig(config): boolean {\n return (\n config &&\n typeof config.renderOutline === 'boolean' &&\n typeof config.outlineWidth === 'number' &&\n typeof config.outlineWidthActive === 'number' &&\n typeof config.outlineWidthInactive === 'number' &&\n typeof config.renderFill === 'boolean' &&\n typeof config.fillAlpha === 'number' &&\n typeof config.fillAlphaInactive === 'number'\n )\n}\n\nexport default getDefaultLabelmapConfig\nexport { isValidLabelmapConfig }\n","import { utilities as csUtils } from '@cornerstonejs/core'\n\nimport _cloneDeep from 'lodash.clonedeep'\nimport {\n SegmentationDataInput,\n SegmentationConfig,\n} from '../../types/SegmentationStateTypes'\nimport { checkSegmentationDataIsValid } from './helpers'\nimport Representations from '../../enums/SegmentationRepresentations'\nimport { getToolGroupByToolGroupUID } from '../../store/ToolGroupManager'\n\nimport { LabelmapDisplay } from '../../tools/displayTools/Labelmap'\n\n/**\n * Add a segmentation to the viewports of the toolGroup. It will use the\n * provided segmentationDataArray to create and configure the segmentation based\n * on the representation type and representation specific configuration.\n * @param toolGroupUID - The UID of the toolGroup to add the segmentation to.\n * @param segmentationDataArray - minimum of volumeUID should be provided, it will\n * throw an error if not. If no representation type is provided, it will use\n * the default labelmap representation.\n * @param toolGroupSpecificConfig - The toolGroup specific configuration\n * for the segmentation display.\n */\nasync function addSegmentationsForToolGroup(\n toolGroupUID: string,\n segmentationDataArray: SegmentationDataInput[],\n toolGroupSpecificConfig?: SegmentationConfig\n): Promise<void> {\n checkSegmentationDataIsValid(segmentationDataArray)\n\n // Check if there exists a toolGroup with the toolGroupUID\n const toolGroup = getToolGroupByToolGroupUID(toolGroupUID)\n\n if (!toolGroup) {\n throw new Error(`No tool group found for toolGroupUID: ${toolGroupUID}`)\n }\n\n const promises = segmentationDataArray.map(async (segData) => {\n const segmentationData = _cloneDeep(segData)\n\n segmentationData.segmentationDataUID = csUtils.uuidv4()\n return _addSegmentation(\n toolGroupUID,\n segmentationData,\n toolGroupSpecificConfig\n )\n })\n\n await Promise.all(promises)\n}\n\nasync function _addSegmentation(\n toolGroupUID,\n segmentationData,\n toolGroupSpecificConfig\n) {\n const representationType = segmentationData.representation?.type\n ? segmentationData.representation.type\n : Representations.Labelmap\n\n // create representation config if not provided by\n if (!segmentationData.representation) {\n segmentationData.representation = {\n type: representationType,\n }\n }\n\n // Create empty config if not provided by.\n // Note: this is representation-required configuration for the segmentation\n // For Labelmap, it is the cfun and ofun. Todo: maybe we change this to props?\n if (!segmentationData.representation.config) {\n segmentationData.representation.config = {}\n }\n\n if (representationType === Representations.Labelmap) {\n await LabelmapDisplay.addSegmentationData(\n toolGroupUID,\n segmentationData,\n toolGroupSpecificConfig\n )\n } else {\n throw new Error(\n `The representation type ${representationType} is not supported yet`\n )\n }\n}\n\nexport default addSegmentationsForToolGroup\n","import SegmentationRepresentations from '../../enums/SegmentationRepresentations'\nimport { LabelmapDisplay } from '../../tools/displayTools/Labelmap'\n\nimport {\n getSegmentationState,\n getSegmentationDataByUID,\n} from './segmentationState'\n\n/**\n * Remove the segmentation data (representation) from the viewports of the toolGroup.\n * @param toolGroupUID - The UID of the toolGroup to remove the segmentation from.\n * @param segmentationDataArray - Array of segmentationData\n * containing at least volumeUID. If no representation type is provided, it will\n * assume the default labelmap representation should be removed from the viewports.\n */\nfunction removeSegmentationsFromToolGroup(\n toolGroupUID: string,\n segmentationDataUIDs?: string[] | undefined\n): void {\n const toolGroupSegmentations = getSegmentationState(toolGroupUID)\n const toolGroupSegmentationDataUIDs = toolGroupSegmentations.map(\n (segData) => segData.segmentationDataUID\n )\n\n let segmentationDataUIDsToRemove = segmentationDataUIDs\n if (segmentationDataUIDsToRemove) {\n // make sure the segmentationDataUIDs that are going to be removed belong\n // to the toolGroup\n const invalidSegmentationDataUIDs = segmentationDataUIDs.filter(\n (segmentationDataUID) =>\n !toolGroupSegmentationDataUIDs.includes(segmentationDataUID)\n )\n\n if (invalidSegmentationDataUIDs.length > 0) {\n throw new Error(\n `You are trying to remove segmentationDataUIDs that are not in the toolGroup: segmentationDataUID: ${invalidSegmentationDataUIDs}`\n )\n }\n } else {\n // remove all segmentations\n segmentationDataUIDsToRemove = toolGroupSegmentationDataUIDs\n }\n\n segmentationDataUIDsToRemove.forEach((segmentationDataUID) => {\n _removeSegmentation(toolGroupUID, segmentationDataUID)\n })\n}\n\nfunction _removeSegmentation(\n toolGroupUID: string,\n segmentationDataUID: string\n): void {\n const segmentationData = getSegmentationDataByUID(\n toolGroupUID,\n segmentationDataUID\n )\n\n const { representation } = segmentationData\n\n if (representation.type === SegmentationRepresentations.Labelmap) {\n LabelmapDisplay.removeSegmentationData(toolGroupUID, segmentationDataUID)\n } else {\n throw new Error(`The representation ${representation} is not supported`)\n }\n}\n\nexport default removeSegmentationsFromToolGroup\n","import { _cloneDeep } from 'lodash.clonedeep'\nimport {\n getEnabledElementByUIDs,\n volumeLoader,\n VolumeViewport,\n utilities as csUtils,\n} from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\n\nimport { getToolGroupByToolGroupUID } from '../../store/ToolGroupManager'\n\n/**\n * Create a new 3D segmentation volume from the default imageData presented in\n * the first viewport of the toolGroup. It looks at the metadata of the imageData\n * to determine the volume dimensions and spacing if particular options are not provided.\n *\n * @param toolGroupUID - The UID of the toolGroup\n * @param options - LabelmapOptions\n * @returns A promise that resolves to the UID of the new labelmap.\n */\nasync function createNewSegmentationForToolGroup(\n toolGroupUID: string,\n options?: {\n volumeUID?: string\n scalarData?: Float32Array | Uint8Array\n targetBuffer?: {\n type: 'Float32Array' | 'Uint8Array'\n }\n metadata?: any\n dimensions?: Types.Point3\n spacing?: Types.Point3\n origin?: Types.Point3\n direction?: Float32Array\n }\n): Promise<string> {\n const toolGroup = getToolGroupByToolGroupUID(toolGroupUID)\n\n if (!toolGroup) {\n throw new Error(`ToolGroup with UID ${toolGroupUID} not found`)\n }\n\n const { viewportUID, renderingEngineUID } = toolGroup.viewportsInfo[0]\n\n const enabledElement = getEnabledElementByUIDs(\n viewportUID,\n renderingEngineUID\n )\n\n if (!enabledElement) {\n throw new Error('element disabled')\n }\n\n const { viewport } = enabledElement\n if (!(viewport instanceof VolumeViewport)) {\n throw new Error('Segmentation not ready for stackViewport')\n }\n\n const { uid } = viewport.getDefaultActor()\n // Name the segmentation volume with the viewport UID\n const segmentationUID = `${uid}-based-segmentation-${\n options?.volumeUID ?? csUtils.uuidv4().slice(0, 8)\n }`\n\n if (options) {\n // create a new labelmap with its own properties\n // This allows creation of a higher resolution labelmap vs reference volume\n const properties = _cloneDeep(options)\n await volumeLoader.createLocalVolume(properties, segmentationUID)\n } else {\n // create a labelmap from a reference volume\n const { uid: volumeUID } = viewport.getDefaultActor()\n await volumeLoader.createAndCacheDerivedVolume(volumeUID, {\n uid: segmentationUID,\n })\n }\n\n return segmentationUID\n}\n\nexport default createNewSegmentationForToolGroup\n","import {\n getActiveSegmentationData,\n setActiveSegmentationData,\n getGlobalSegmentationDataByUID,\n} from './segmentationState'\n\n/**\n * Get the active segmentation info for the first viewport in the tool group with\n * the given toolGroupUID.\n * @param toolGroupUID - The UID of the tool group that the user is\n * currently interacting with.\n */\nfunction getActiveSegmentationInfo(toolGroupUID: string): {\n volumeUID: string\n segmentationDataUID: string\n activeSegmentIndex: number\n} {\n const activeSegmentationData = getActiveSegmentationData(toolGroupUID)\n\n if (!activeSegmentationData) {\n return null\n }\n\n const globalState = getGlobalSegmentationDataByUID(\n activeSegmentationData.volumeUID\n )\n\n return {\n volumeUID: activeSegmentationData.volumeUID,\n segmentationDataUID: activeSegmentationData.segmentationDataUID,\n activeSegmentIndex: globalState.activeSegmentIndex,\n }\n}\n\n/**\n * Set the active segmentation for the given tool group for all its viewports\n *\n * @param toolGroupUID - The ID of the tool group to set the active\n * segmentation for.\n * @param segmentationDataUID - The UID of the segmentation data to set as\n * active.\n */\nfunction setActiveSegmentation(\n toolGroupUID: string,\n segmentationDataUID: string\n): void {\n setActiveSegmentationData(toolGroupUID, segmentationDataUID)\n}\n\nexport {\n // get\n getActiveSegmentationInfo,\n // set\n setActiveSegmentation,\n}\n\nexport default {\n // get\n getActiveSegmentationInfo,\n // set\n setActiveSegmentation,\n}\n","import { getActiveSegmentationInfo } from './activeSegmentation'\n\nimport { getGlobalSegmentationDataByUID } from '../../stateManagement/segmentation/segmentationState'\nimport { triggerSegmentationGlobalStateModified } from './triggerSegmentationEvents'\n\n/**\n * Get the locked status of a segment index in a segmentation\n *\n * @param toolGroupUID - The UID of the tool group that contains the\n * segmentation.\n * @param segmentIndex - The index of the segment\n * @returns A boolean value indicating whether the segment is locked or not for modification\n */\n// Todo: should this be based on a segmentationUID instead of a toolGroupUID?\nfunction getSegmentIndexLocked(\n toolGroupUID: string,\n segmentIndex: number\n): boolean {\n const activeSegmentationInfo = getActiveSegmentationInfo(toolGroupUID)\n\n if (!activeSegmentationInfo) {\n throw new Error('element does not contain an active segmentation')\n }\n\n const { volumeUID: segmentationUID } = activeSegmentationInfo\n const segmentationGlobalState =\n getGlobalSegmentationDataByUID(segmentationUID)\n\n const lockedSegments = segmentationGlobalState.segmentsLocked\n\n return lockedSegments.has(segmentIndex)\n}\n\n/**\n * Set the locked status of a segment in a segmentation globally. It fires\n * a global state modified event.\n *\n * @triggers {SegmentationGlobalStateModifiedEvent}\n *\n * @param toolGroupUID - the UID of the tool group that contains the\n * segmentation\n * @param segmentIndex - the index of the segment to lock/unlock\n * @param locked - boolean\n */\n// Todo: shouldn't this be a based on a segmentationUID instead of a toolGroupUID?\nfunction setSegmentIndexLocked(\n toolGroupUID: string,\n segmentIndex: number,\n locked = true\n): void {\n const activeSegmentationInfo = getActiveSegmentationInfo(toolGroupUID)\n\n if (!activeSegmentationInfo) {\n throw new Error('element does not contain an active segmentation')\n }\n\n const { volumeUID: segmentationUID } = activeSegmentationInfo\n\n const segmentationGlobalState =\n getGlobalSegmentationDataByUID(segmentationUID)\n\n const { segmentsLocked } = segmentationGlobalState\n\n if (locked) {\n segmentsLocked.add(segmentIndex)\n } else {\n segmentsLocked.delete(segmentIndex)\n }\n\n triggerSegmentationGlobalStateModified(segmentationUID)\n}\n\n/**\n * Get the locked status for a segment index in a segmentation\n * @param segmentationUID - The UID of the segmentation that the segment\n * belongs to.\n * @param segmentIndex - The index of the segment\n * @returns A boolean value indicating whether the segment is locked or not.\n */\nfunction getSegmentIndexLockedForSegmentation(\n segmentationUID: string,\n segmentIndex: number\n): boolean {\n const globalState = getGlobalSegmentationDataByUID(segmentationUID)\n\n if (!globalState) {\n throw new Error(`No segmentation state found for ${segmentationUID}`)\n }\n\n const { segmentsLocked } = globalState\n return segmentsLocked.has(segmentIndex)\n}\n\n/**\n * Set the locked status of a segment index in a segmentation\n * @param segmentationUID - The UID of the segmentation whose segment\n * index is being modified.\n * @param segmentIndex - The index of the segment to lock/unlock.\n */\nfunction setSegmentIndexLockedForSegmentation(\n segmentationUID: string,\n segmentIndex: number,\n locked = true\n): void {\n const segmentationGlobalState =\n getGlobalSegmentationDataByUID(segmentationUID)\n\n if (!segmentationGlobalState) {\n throw new Error(`No segmentation state found for ${segmentationUID}`)\n }\n\n const { segmentsLocked } = segmentationGlobalState\n\n if (locked) {\n segmentsLocked.add(segmentIndex)\n } else {\n segmentsLocked.delete(segmentIndex)\n }\n\n triggerSegmentationGlobalStateModified(segmentationUID)\n}\n\n/**\n * Get the locked segments for a segmentation\n * @param segmentationUID - The UID of the segmentation to get locked\n * segments for.\n * @returns An array of locked segment indices.\n */\nfunction getSegmentsLockedForSegmentation(\n segmentationUID: string\n): number[] | [] {\n const globalState = getGlobalSegmentationDataByUID(segmentationUID)\n\n if (!globalState) {\n throw new Error(`No segmentation state found for ${segmentationUID}`)\n }\n\n const { segmentsLocked } = globalState\n return Array.from(segmentsLocked)\n}\n\nexport {\n // toolGroup active segmentation\n getSegmentIndexLocked,\n setSegmentIndexLocked,\n // set\n getSegmentIndexLockedForSegmentation,\n setSegmentIndexLockedForSegmentation,\n getSegmentsLockedForSegmentation,\n}\n\nexport default {\n // toolGroup active segmentation\n getSegmentIndexLocked,\n setSegmentIndexLocked,\n // set\n getSegmentIndexLockedForSegmentation,\n setSegmentIndexLockedForSegmentation,\n getSegmentsLockedForSegmentation,\n}\n","import { utilities } from '@cornerstonejs/core'\nimport * as SegmentationState from '../../stateManagement/segmentation/segmentationState'\nimport { Color } from '../../types/SegmentationStateTypes'\nimport { ColorLUT } from '../../types/SegmentationStateTypes'\n\n/**\n * addColorLUT - Adds a new color LUT to the state at the given colorLUTIndex.\n * If no colorLUT is provided, a new color LUT is generated.\n *\n * @param colorLUTIndex - the index of the colorLUT in the state\n * @param colorLUT - An array of The colorLUT to set.\n * @returns\n */\nfunction addColorLUT(colorLUT: ColorLUT, colorLUTIndex: number): void {\n if (!colorLUT) {\n throw new Error('addColorLUT: colorLUT is required')\n }\n\n // Append the \"zero\" (no label) color to the front of the LUT, if necessary.\n if (!utilities.isEqual(colorLUT[0], [0, 0, 0, 0])) {\n console.warn(\n 'addColorLUT: [0, 0, 0, 0] color is not provided for the background color (segmentIndex =0), automatically adding it'\n )\n colorLUT.unshift([0, 0, 0, 0])\n }\n\n SegmentationState.addColorLUT(colorLUT, colorLUTIndex)\n}\n\n/**\n * Given a tool group UID, a segmentation data UID, and a segment index, return the\n * color for that segment. It can be used for segmentation tools that need to\n * display the color of their annotation.\n *\n * @param toolGroupUID - The UID of the tool group that owns the segmentation data.\n * @param segmentationDataUID - The UID of the segmentation data\n * @param segmentIndex - The index of the segment in the segmentation\n * @returns A color.\n */\nfunction getColorForSegmentIndex(\n toolGroupUID: string,\n segmentationDataUID: string,\n segmentIndex: number\n): Color {\n const segmentationData = SegmentationState.getSegmentationDataByUID(\n toolGroupUID,\n segmentationDataUID\n )\n\n if (!segmentationData) {\n throw new Error(\n `Segmentation data with UID ${segmentationDataUID} does not exist for tool group ${toolGroupUID}`\n )\n }\n\n const { colorLUTIndex } = segmentationData\n\n // get colorLUT\n const colorLut = SegmentationState.getColorLut(colorLUTIndex)\n return colorLut[segmentIndex]\n}\n\nexport default { getColorForSegmentIndex, addColorLUT }\nexport { getColorForSegmentIndex, addColorLUT }\n","import SegmentationRepresentations from '../../enums/SegmentationRepresentations'\nimport * as SegmentationState from '../../stateManagement/segmentation/segmentationState'\n\nimport {\n RepresentationConfig,\n SegmentationConfig,\n} from '../../types/SegmentationStateTypes'\n\n/**\n * It returns the global segmentation config.\n * @returns The global segmentation config containing the representations\n * config for each representation type and renderInactiveSegmentations flag.\n */\nfunction getGlobalSegmentationConfig(): SegmentationConfig {\n const globalConfig = SegmentationState.getGlobalSegmentationConfig()\n return globalConfig\n}\n\n/**\n * Set the global segmentation config\n * @param segmentationConfig - SegmentationConfig\n */\nfunction setGlobalSegmentationConfig(\n segmentationConfig: SegmentationConfig\n): void {\n SegmentationState.setGlobalSegmentationConfig(segmentationConfig)\n}\n\n/**\n * Given a representation type, return the corresponding global representation config\n * @param representationType - The type of representation to query\n * @returns A representation configuration object.\n */\nfunction getGlobalRepresentationConfig(\n representationType: SegmentationRepresentations\n): RepresentationConfig {\n const globalConfig = getGlobalSegmentationConfig()\n return globalConfig.representations[representationType]\n}\n\n/**\n * Set the global configuration for a given representation type. It fires\n * a SEGMENTATION_GLOBAL_STATE_MODIFIED event.\n *\n * @triggers SEGMENTATION_GLOBAL_STATE_MODIFIED\n * @param representationType - The type of representation to set config for\n * @param config - The configuration for the representation.\n */\nfunction setGlobalRepresentationConfig(\n representationType: SegmentationRepresentations,\n config: RepresentationConfig\n): void {\n const globalConfig = getGlobalSegmentationConfig()\n\n setGlobalSegmentationConfig({\n ...globalConfig,\n representations: {\n ...globalConfig.representations,\n [representationType]: config,\n },\n })\n}\n\n/**\n * It takes a representation type and a partial representation config, and updates\n * the global representation config with the partial config. It fires a\n * SEGMENTATION_GLOBAL_STATE_MODIFIED event.\n *\n * @triggers SEGMENTATION_GLOBAL_STATE_MODIFIED\n * @param representationType - The type of representation to update.\n * @param config - Partial<RepresentationConfig>\n */\nfunction updateGlobalRepresentationConfig(\n representationType: SegmentationRepresentations,\n config: Partial<RepresentationConfig>\n): void {\n const representationConfig = getGlobalRepresentationConfig(representationType)\n\n setGlobalRepresentationConfig(representationType, {\n ...representationConfig,\n ...config,\n })\n}\n\n/**\n * It takes a partial config object and updates the global config with it\n * @param config - Partial<SegmentationConfig>\n */\nfunction updateGlobalSegmentationConfig(\n config: Partial<SegmentationConfig>\n): void {\n const globalConfig = getGlobalSegmentationConfig()\n\n setGlobalSegmentationConfig({\n ...globalConfig,\n ...config,\n })\n}\n\n/**\n * Get the toolGroup specific segmentation config\n * @param toolGroupUID - The UID of the tool group\n * @returns A SegmentationConfig object.\n */\nfunction getSegmentationConfig(toolGroupUID: string): SegmentationConfig {\n return SegmentationState.getSegmentationConfig(toolGroupUID)\n}\n\n/**\n * Set the toolGroup specific segmentation config.\n * It fires a SEGMENTATION_STATE_MODIFIED event.\n *\n * @param toolGroupUID - The UID of the tool group that the segmentation config is for.\n * @param segmentationConfig - The segmentation config to set.\n */\nfunction setSegmentationConfig(\n toolGroupUID: string,\n segmentationConfig: SegmentationConfig\n): void {\n SegmentationState.setSegmentationConfig(toolGroupUID, segmentationConfig)\n}\n\n/**\n * Set the representation config for a given tool group for the given representation type.\n * It fires a SEGMENTATION_STATE_MODIFIED event.\n *\n * @param toolGroupUID - The unique identifier of the tool group.\n * @param representationType - The type of representation to set config for.\n * @param representationConfig - The configuration for the representation.\n */\nfunction setRepresentationConfig(\n toolGroupUID: string,\n representationType: SegmentationRepresentations,\n representationConfig: RepresentationConfig\n): void {\n const segmentationConfig =\n SegmentationState.getSegmentationConfig(toolGroupUID)\n\n if (segmentationConfig) {\n const config = {\n ...segmentationConfig,\n representations: {\n ...segmentationConfig.representations,\n [representationType]: representationConfig,\n },\n }\n\n setSegmentationConfig(toolGroupUID, config)\n }\n}\n\n/**\n * Get the representation config for a given tool group and representation type\n * @param toolGroupUID - The UID of the tool group that contains the tool that you\n * want to get the representation config for.\n * @param representationType - The type of representation to get.\n * @returns A RepresentationConfig object.\n */\nfunction getRepresentationConfig(\n toolGroupUID: string,\n representationType: SegmentationRepresentations\n): RepresentationConfig {\n const segmentationConfig = getSegmentationConfig(toolGroupUID)\n\n if (segmentationConfig) {\n return segmentationConfig.representations[representationType]\n }\n}\n\nexport {\n getGlobalSegmentationConfig,\n setGlobalSegmentationConfig,\n getGlobalRepresentationConfig,\n setGlobalRepresentationConfig,\n updateGlobalSegmentationConfig,\n updateGlobalRepresentationConfig,\n getSegmentationConfig,\n setSegmentationConfig,\n setRepresentationConfig,\n getRepresentationConfig,\n}\n\nexport default {\n getGlobalSegmentationConfig,\n setGlobalSegmentationConfig,\n getGlobalRepresentationConfig,\n setGlobalRepresentationConfig,\n updateGlobalSegmentationConfig,\n updateGlobalRepresentationConfig,\n getSegmentationConfig,\n setSegmentationConfig,\n setRepresentationConfig,\n getRepresentationConfig,\n}\n","import { triggerSegmentationStateModified } from './triggerSegmentationEvents'\nimport { getSegmentationState } from '../../stateManagement/segmentation/segmentationState'\nimport { ToolGroupSpecificSegmentationData } from '../../types/SegmentationStateTypes'\n\n/**\n * Set the visibility of a segmentation data for a given tool group. It fires\n * a SEGMENTATION_STATE_MODIFIED event.\n *\n * @triggers SEGMENTATION_STATE_MODIFIED\n * @param toolGroupUID - The UID of the tool group that contains the segmentation.\n * @param segmentationDataUID - The UID of the segmentation data to modify its visibility.\n * @param visibility - boolean\n */\nfunction setSegmentationVisibility(\n toolGroupUID: string,\n segmentationDataUID: string,\n visibility: boolean\n): void {\n const toolGroupSegmentations = getSegmentationState(toolGroupUID)\n\n if (!toolGroupSegmentations) {\n return\n }\n\n toolGroupSegmentations.forEach(\n (segmentationData: ToolGroupSpecificSegmentationData) => {\n if (segmentationData.segmentationDataUID === segmentationDataUID) {\n segmentationData.visibility = visibility\n triggerSegmentationStateModified(toolGroupUID)\n }\n }\n )\n}\n\n/**\n * Get the visibility of a segmentation data for a given tool group.\n *\n * @param toolGroupUID - The UID of the tool group that the segmentation\n * data belongs to.\n * @param segmentationDataUID - The UID of the segmentation data to get\n * @returns A boolean value that indicates whether the segmentation data is visible or\n * not on the toolGroup\n */\nfunction getSegmentationVisibility(\n toolGroupUID: string,\n segmentationDataUID: string\n): boolean | undefined {\n const toolGroupSegmentations = getSegmentationState(toolGroupUID)\n\n const segmentationData = toolGroupSegmentations.find(\n (segmentationData: ToolGroupSpecificSegmentationData) =>\n segmentationData.segmentationDataUID === segmentationDataUID\n )\n\n if (!segmentationData) {\n return\n }\n\n return segmentationData.visibility\n}\n\nexport default { setSegmentationVisibility, getSegmentationVisibility }\nexport { setSegmentationVisibility, getSegmentationVisibility }\n","import { getActiveSegmentationInfo } from './activeSegmentation'\nimport { getGlobalSegmentationDataByUID } from './segmentationState'\nimport { triggerSegmentationGlobalStateModified } from './triggerSegmentationEvents'\n\n/**\n * Returns the active segment index for the active segmentation in the tool group\n *\n * @param toolGroupUID - The UID of the tool group that contains an active segmentation.\n * @returns The active segment index.\n */\nfunction getActiveSegmentIndex(toolGroupUID: string): number | undefined {\n const segmentationInfo = getActiveSegmentationInfo(toolGroupUID)\n\n if (!segmentationInfo) {\n throw new Error('toolGroup does not contain an active segmentation')\n }\n\n const { volumeUID } = segmentationInfo\n const activeSegmentationGlobalState =\n getGlobalSegmentationDataByUID(volumeUID)\n\n if (activeSegmentationGlobalState) {\n return activeSegmentationGlobalState.activeSegmentIndex\n }\n}\n\n/**\n * Set the active segment index for the active segmentation of the toolGroup.\n * It fires a global state modified event.\n *\n * @triggers SEGMENTATION_GLOBAL_STATE_MODIFIED\n * @param toolGroupUID - The UID of the tool group that contains the segmentation.\n * @param segmentIndex - The index of the segment to be activated.\n */\nfunction setActiveSegmentIndex(\n toolGroupUID: string,\n segmentIndex: number\n): void {\n const segmentationInfo = getActiveSegmentationInfo(toolGroupUID)\n\n if (!segmentationInfo) {\n throw new Error('element does not contain an active segmentation')\n }\n\n const { volumeUID: segmentationUID } = segmentationInfo\n const activeSegmentationGlobalState =\n getGlobalSegmentationDataByUID(segmentationUID)\n\n if (activeSegmentationGlobalState?.activeSegmentIndex !== segmentIndex) {\n activeSegmentationGlobalState.activeSegmentIndex = segmentIndex\n\n triggerSegmentationGlobalStateModified(segmentationUID)\n }\n}\n\n/**\n * Set the active segment index for a segmentation UID. It fires a global state\n * modified event.\n *\n * @triggers SEGMENTATION_GLOBAL_STATE_MODIFIED\n * @param segmentationUID - The UID of the segmentation that the segment belongs to.\n * @param segmentIndex - The index of the segment to be activated.\n */\nfunction setActiveSegmentIndexForSegmentation(\n segmentationUID: string,\n segmentIndex: number\n): void {\n const activeSegmentationGlobalState =\n getGlobalSegmentationDataByUID(segmentationUID)\n\n if (activeSegmentationGlobalState?.activeSegmentIndex !== segmentIndex) {\n activeSegmentationGlobalState.activeSegmentIndex = segmentIndex\n\n triggerSegmentationGlobalStateModified(segmentationUID)\n }\n}\n\n/**\n * Get the active segment index for a segmentation in the global state\n * @param segmentationUID - The UID of the segmentation to get the active segment index from.\n * @returns The active segment index for the given segmentation.\n */\nfunction getActiveSegmentIndexForSegmentation(\n segmentationUID: string\n): number | undefined {\n const activeSegmentationGlobalState =\n getGlobalSegmentationDataByUID(segmentationUID)\n\n if (activeSegmentationGlobalState) {\n return activeSegmentationGlobalState.activeSegmentIndex\n }\n}\n\nexport default {\n // toolGroup Active Segmentation\n getActiveSegmentIndex,\n setActiveSegmentIndex,\n // global segmentation\n getActiveSegmentIndexForSegmentation,\n setActiveSegmentIndexForSegmentation,\n}\n\nexport {\n // toolGroup Active Segmentation\n getActiveSegmentIndex,\n setActiveSegmentIndex,\n // global segmentation\n getActiveSegmentIndexForSegmentation,\n setActiveSegmentIndexForSegmentation,\n}\n","import { BaseTool } from '../base'\nimport { getEnabledElementByUIDs } from '@cornerstonejs/core'\nimport Representations from '../../enums/SegmentationRepresentations'\nimport { getSegmentationState } from '../../stateManagement/segmentation/segmentationState'\nimport { LabelmapDisplay } from './Labelmap'\nimport { segmentationConfig } from '../../stateManagement/segmentation'\nimport { triggerSegmentationStateModified } from '../../stateManagement/segmentation/triggerSegmentationEvents'\nimport { getToolGroupByToolGroupUID } from '../../store/ToolGroupManager'\nimport {\n ToolGroupSpecificSegmentationData,\n SegmentationConfig,\n} from '../../types/SegmentationStateTypes'\n\nimport { PublicToolProps, ToolProps } from '../../types'\n\nimport { deepMerge } from '../../utilities'\n\n/**\n * In Cornerstone3DTools, displaying of segmentations are handled by the SegmentationDisplayTool.\n * Generally, any Segmentation can be viewed in various representations such as\n * labelmap (3d), contours, surface etc. As of now, Cornerstone3DTools only implements\n * Labelmap representation (default).\n *\n * SegmentationDisplayTool works at ToolGroup level, and is responsible for displaying the\n * segmentation for ALL viewports of a toolGroup, this way we can support complex\n * scenarios for displaying segmentations.\n *\n * Current Limitations:\n * - Only supports rendering of the volumetric segmentations in 3D space. (StackViewport segmentations are not supported yet)\n * - Labelmap representation is the only supported representation for now.\n *\n * Similar to other tools in Cornerstone3DTools, the SegmentationDisplayTool should\n * be added to the CornerstoneTools by calling cornerstoneTools.addTool(SegmentationDisplayTool)\n * and a toolGroup should be created for it using the ToolGroupManager API, finally\n * viewports information such as viewportUID and renderingEngineUID should be provided\n * to the toolGroup and the SegmentationDisplayTool should be set to be activated.\n * For adding segmentations to be displayed you can addSegmentationsForToolGroup helper.\n *\n * ```js\n *\n * addSegmentationsForToolGroup('toolGroupUID', [\n * {\n * volumeUID: segmentationUID,\n * },\n * ])\n *\n * ```\n */\nexport default class SegmentationDisplayTool extends BaseTool {\n static toolName = 'SegmentationDisplay'\n constructor(\n toolProps: PublicToolProps = {},\n defaultToolProps: ToolProps = {\n configuration: {},\n }\n ) {\n super(toolProps, defaultToolProps)\n }\n\n enableCallback(): void {\n const toolGroupUID = this.toolGroupUID\n const toolGroupSegmentationState = getSegmentationState(toolGroupUID)\n\n if (toolGroupSegmentationState.length === 0) {\n return\n }\n\n // for each segmentationData, make the visibility false\n for (const segmentationData of toolGroupSegmentationState) {\n segmentationData.visibility = true\n }\n\n // trigger the update\n triggerSegmentationStateModified(toolGroupUID)\n }\n\n disableCallback(): void {\n const toolGroupUID = this.toolGroupUID\n const toolGroupSegmentationState = getSegmentationState(toolGroupUID)\n\n if (toolGroupSegmentationState.length === 0) {\n return\n }\n\n // for each segmentationData, make the visibility false\n for (const segmentationData of toolGroupSegmentationState) {\n segmentationData.visibility = false\n }\n\n // trigger the update\n triggerSegmentationStateModified(toolGroupUID)\n }\n\n /**\n * It is used to trigger the render for each segmentations in the toolGroup.\n * Based on the segmentation representation type, it will call the corresponding\n * render function.\n *\n * @param toolGroupUID - the toolGroupUID\n */\n renderSegmentation = (toolGroupUID: string): void => {\n const toolGroup = getToolGroupByToolGroupUID(toolGroupUID)\n\n if (!toolGroup) {\n return\n }\n\n const toolGroupSegmentationState = getSegmentationState(toolGroupUID)\n\n // toolGroup Viewports\n const toolGroupViewports = toolGroup.viewportsInfo.map(\n ({ renderingEngineUID, viewportUID }) => {\n const enabledElement = getEnabledElementByUIDs(\n viewportUID,\n renderingEngineUID\n )\n\n if (enabledElement) {\n return enabledElement.viewport\n }\n }\n )\n\n // Render each segmentationData, in each viewport in the toolGroup\n toolGroupSegmentationState.forEach(\n (segmentationData: ToolGroupSpecificSegmentationData) => {\n const config = this._getSegmentationConfig(toolGroupUID)\n const { representation } = segmentationData\n\n toolGroupViewports.forEach((viewport) => {\n if (representation.type == Representations.Labelmap) {\n LabelmapDisplay.render(viewport, segmentationData, config)\n } else {\n throw new Error(\n `Render for ${representation.type} is not supported yet`\n )\n }\n })\n }\n )\n\n // for all viewports in the toolGroup trigger a re-render\n toolGroupViewports.forEach((viewport) => {\n viewport.render()\n })\n }\n\n _getSegmentationConfig(toolGroupUID: string): SegmentationConfig {\n const toolGroupConfig =\n segmentationConfig.getSegmentationConfig(toolGroupUID)\n\n const globalConfig = segmentationConfig.getGlobalSegmentationConfig()\n\n // merge two configurations and override the global config\n const mergedConfig = deepMerge(globalConfig, toolGroupConfig)\n\n return mergedConfig\n }\n}\n","import {\n triggerEvent,\n eventTarget,\n getRenderingEngine,\n Enums,\n Types,\n} from '@cornerstonejs/core'\nimport { Events as csToolsEvents } from '../enums'\nimport {\n getToolGroupByToolGroupUID,\n getToolGroup,\n} from '../store/ToolGroupManager'\n\nimport SegmentationDisplayTool from '../tools/displayTools/SegmentationDisplayTool'\nimport { SegmentationRenderedEventDetail } from '../types/EventTypes'\n\n/**\n * SegmentationRenderingEngine is a class that is responsible for rendering\n * segmentations for a toolGroup. It will call SegmentationDisplayTool to render the segmentation\n * based on the segmentation data and their configurations. Note: This is a Singleton class\n * and should not be instantiated directly. To trigger a render for all the\n * segmentations of a tool group you can use.\n *\n * ```\n * triggerSegmentationRender(toolGroupUID)\n * ```\n */\nclass SegmentationRenderingEngine {\n private _needsRender: Set<string> = new Set()\n private _animationFrameSet = false\n private _animationFrameHandle: number | null = null\n public hasBeenDestroyed: boolean\n\n public renderToolGroupSegmentations(toolGroupUID): void {\n this._setToolGroupSegmentationToBeRenderedNextFrame([toolGroupUID])\n }\n\n /**\n * _throwIfDestroyed Throws an error if trying to interact with the `RenderingEngine`\n * instance after its `destroy` method has been called.\n */\n private _throwIfDestroyed() {\n if (this.hasBeenDestroyed) {\n throw new Error(\n 'this.destroy() has been manually called to free up memory, can not longer use this instance. Instead make a new one.'\n )\n }\n }\n\n private _setToolGroupSegmentationToBeRenderedNextFrame(\n toolGroupUIDs: string[]\n ) {\n // Add the viewports to the set of flagged viewports\n toolGroupUIDs.forEach((toolGroupUID) => {\n this._needsRender.add(toolGroupUID)\n })\n\n // Render any flagged viewports\n this._render()\n }\n\n /**\n * _render Sets up animation frame if necessary\n */\n private _render() {\n // If we have viewports that need rendering and we have not already\n // set the RAF callback to run on the next frame.\n if (this._needsRender.size > 0 && this._animationFrameSet === false) {\n this._animationFrameHandle = window.requestAnimationFrame(\n this._renderFlaggedToolGroups\n )\n\n // Set the flag that we have already set up the next RAF call.\n this._animationFrameSet = true\n }\n }\n\n private _renderFlaggedToolGroups = () => {\n this._throwIfDestroyed()\n\n // for each toolGroupUID insides the _needsRender set, render the segmentation\n const toolGroupUIDs = Array.from(this._needsRender.values())\n\n for (const toolGroupUID of toolGroupUIDs) {\n this._triggerRender(toolGroupUID)\n\n // This viewport has been rendered, we can remove it from the set\n this._needsRender.delete(toolGroupUID)\n\n // If there is nothing left that is flagged for rendering, stop here\n // and allow RAF to be called again\n if (this._needsRender.size === 0) {\n this._animationFrameSet = false\n this._animationFrameHandle = null\n return\n }\n }\n }\n _triggerRender(toolGroupUID) {\n const toolGroup = getToolGroupByToolGroupUID(toolGroupUID)\n\n if (!toolGroup) {\n console.warn(`No tool group found with toolGroupUID: ${toolGroupUID}`)\n return\n }\n\n const { viewportsInfo } = toolGroup\n const viewports = []\n\n viewportsInfo.forEach(({ viewportUID, renderingEngineUID }) => {\n const renderingEngine = getRenderingEngine(renderingEngineUID)\n\n if (!renderingEngine) {\n console.warn('rendering Engine has been destroyed')\n return\n }\n\n viewports.push(renderingEngine.getViewport(viewportUID))\n })\n\n const segmentationDisplayToolInstance = toolGroup.getToolInstance(\n SegmentationDisplayTool.toolName\n ) as SegmentationDisplayTool\n\n function onSegmentationRender(evt: Types.EventTypes.ImageRenderedEvent) {\n const { element, viewportUID, renderingEngineUID } = evt.detail\n\n element.removeEventListener(\n Enums.Events.IMAGE_RENDERED,\n onSegmentationRender\n )\n\n const toolGroup = getToolGroup(viewportUID, renderingEngineUID)\n\n const eventDetail: SegmentationRenderedEventDetail = {\n toolGroupUID: toolGroup.uid,\n viewportUID,\n }\n\n triggerEvent(eventTarget, csToolsEvents.SEGMENTATION_RENDERED, {\n ...eventDetail,\n })\n }\n\n // Todo: for other representations we probably need the drawSVG, but right now we are not using it\n // drawSvg(element, (svgDrawingHelper) => {\n // const handleDrawSvg = (tool) => {\n // if (tool instanceof SegmentationDisplayTool && tool.renderAnnotation) {\n // tool.renderAnnotation({ detail: eventDetail })\n // triggerEvent(element, csToolsEvents.SEGMENTATION_RENDERED, { ...eventDetail })\n // }\n // }\n // enabledTools.forEach(handleDrawSvg)\n // })\n\n viewports.forEach(({ element }) => {\n element.addEventListener(\n Enums.Events.IMAGE_RENDERED,\n onSegmentationRender\n )\n })\n\n segmentationDisplayToolInstance.renderSegmentation(toolGroupUID)\n }\n\n /**\n * _reset Resets the `RenderingEngine`\n */\n private _reset() {\n window.cancelAnimationFrame(this._animationFrameHandle)\n\n this._needsRender.clear()\n this._animationFrameSet = false\n this._animationFrameHandle = null\n }\n}\n\nconst segmentationRenderingEngine = new SegmentationRenderingEngine()\n\n/**\n * It triggers a render for all the segmentations of the tool group with the given UID.\n * @param toolGroupUID - The UID of the tool group to render.\n */\nfunction triggerSegmentationRender(toolGroupUID: string): void {\n segmentationRenderingEngine.renderToolGroupSegmentations(toolGroupUID)\n}\n\nexport { segmentationRenderingEngine, triggerSegmentationRender }\nexport default triggerSegmentationRender\n","import triggerSegmentationRender from '../../utilities/triggerSegmentationRender'\n\nimport { SegmentationStateModifiedEventType } from '../../types/EventTypes'\n\n/** A function that listens to the `segmentationStateModified` event and triggers\n * the `triggerSegmentationRender` function. This function is called when the\n * segmentation state or config is modified.\n */\nconst segmentationStateModifiedEventListener = function (\n evt: SegmentationStateModifiedEventType\n): void {\n const { toolGroupUID } = evt.detail\n triggerSegmentationRender(toolGroupUID)\n}\n\nexport default segmentationStateModifiedEventListener\n","import { cache } from '@cornerstonejs/core'\n\nimport triggerSegmentationRender from '../../utilities/triggerSegmentationRender'\nimport SegmentationRepresentations from '../../enums/SegmentationRepresentations'\nimport * as SegmentationState from '../../stateManagement/segmentation/segmentationState'\nimport { SegmentationDataModifiedEventType } from '../../types/EventTypes'\n\n/** A callback function that is called when the segmentation data is modified which\n * often is as a result of tool interactions e.g., scissors, eraser, etc.\n */\nconst onSegmentationDataModified = function (\n evt: SegmentationDataModifiedEventType\n): void {\n const { toolGroupUID, segmentationDataUID } = evt.detail\n\n const segmentationData = SegmentationState.getSegmentationDataByUID(\n toolGroupUID,\n segmentationDataUID\n )\n\n if (!segmentationData) {\n console.warn(\n `onSegmentationDataModified: segmentationDataUID ${segmentationDataUID} not found in toolGroupUID ${toolGroupUID}`\n )\n return\n }\n\n const {\n representation: { type },\n } = segmentationData\n\n let toolGroupUIDs\n if (type === SegmentationRepresentations.Labelmap) {\n // get the volume from cache, we need the openGLTexture to be updated to GPU\n const { volumeUID } = segmentationData\n const segmentation = cache.getVolume(volumeUID)\n\n if (!segmentation) {\n console.warn('segmentation not found in cache')\n return\n }\n const { imageData, vtkOpenGLTexture, uid } = segmentation\n\n // Todo: this can be optimized to not use the full texture from all slices\n const numSlices = imageData.getDimensions()[2]\n const modifiedSlicesToUse = [...Array(numSlices).keys()]\n\n // Update the texture for the volume in the GPU\n modifiedSlicesToUse.forEach((i) => {\n vtkOpenGLTexture.setUpdatedFrame(i)\n })\n\n // Trigger modified on the imageData to update the image\n imageData.modified()\n toolGroupUIDs = SegmentationState.getToolGroupsWithSegmentation(uid)\n } else {\n throw new Error(\n `onSegmentationDataModified: representationType ${type} not supported yet`\n )\n }\n\n toolGroupUIDs.forEach((toolGroupUID) => {\n triggerSegmentationRender(toolGroupUID)\n })\n}\n\nexport default onSegmentationDataModified\n","import { getRenderingEngines } from '@cornerstonejs/core'\nimport { triggerAnnotationRenderForViewportUIDs } from '../../utilities'\n\n/**\n * When an annotation is deselected, trigger an annotation render for all viewports.\n * The reason for this is that, drawing an annotation in a different viewport\n * should deselect all other annotations in other viewports. In order to achieve\n * this, we need to trigger an annotation render for all viewports.\n * Todo: Although this is inefficient, but since annotations are only rendered if necessary,\n * it's probably not going to have a noticeable impact on performance.\n * @param evt - The event object.\n */\nfunction annotationSelectionListener(evt): void {\n const deselectedAnnotation = evt.detail.removed\n\n if (!deselectedAnnotation.length) {\n return\n }\n\n const renderingEngines = getRenderingEngines()\n\n renderingEngines.forEach((renderingEngine) => {\n const viewports = renderingEngine.getViewports()\n const viewportUIDs = viewports.map((vp) => vp.uid)\n triggerAnnotationRenderForViewportUIDs(renderingEngine, viewportUIDs)\n })\n}\n\nexport default annotationSelectionListener\n","import type { Types } from '@cornerstonejs/core'\nimport triggerAnnotationRender from './triggerAnnotationRender'\n\nexport function triggerAnnotationRenderForViewportUIDs(\n renderingEngine: Types.IRenderingEngine,\n viewportUIDsToRender: string[]\n): void {\n if (!viewportUIDsToRender.length) {\n return\n }\n\n viewportUIDsToRender.forEach((viewportUID) => {\n const { element } = renderingEngine.getViewport(viewportUID)\n triggerAnnotationRender(element)\n })\n}\n\nexport default triggerAnnotationRenderForViewportUIDs\n","import { getRenderingEngine } from '@cornerstonejs/core'\nimport triggerAnnotationRenderForViewportUIDs from '../../utilities/triggerAnnotationRenderForViewportUIDs'\n\n/**\n * This is a callback function that is called when an annotation is modified.\n * Since we are throttling the cachedStats calculation for annotation tools,\n * we need to trigger a final render for the annotation. so that the annotation\n * textBox is updated.\n * Todo: This will trigger all the annotation tools to re-render, although DOM\n * will update those that have changed, but more efficient would be to only\n * update the changed annotation.\n * Todo: A better way is to extract the textBox render logic from the renderAnnotation\n * of all tools and just trigger a render for that (instead of the entire annotation., even if\n * no svg update happens since the attributes for handles are the same)\n */\nfunction annotationModifiedListener(evt): void {\n const { viewportUID, renderingEngineUID } = evt.detail\n const renderingEngine = getRenderingEngine(renderingEngineUID)\n triggerAnnotationRenderForViewportUIDs(renderingEngine, [viewportUID])\n}\n\nexport default annotationModifiedListener\n","import { Enums, Types } from '@cornerstonejs/core'\nimport triggerAnnotationRender from '../utilities/triggerAnnotationRender'\n\n/**\n * When the image is rendered, check what tools can be rendered for this element.\n *\n * - First we get all tools which are active, passive or enabled on the element.\n * - If any of these tools have a `renderAnnotation` method, then we render them.\n * - Note that these tools don't necessarily have to be instances of `AnnotationTool`,\n * Any tool may register a `renderAnnotation` method (e.g. a tool that displays an overlay).\n *\n * @param evt - The normalized IMAGE_RENDERED event.\n */\nconst onImageRendered = function (evt: Types.EventTypes.ImageRenderedEvent) {\n // TODO: should we do this on camera modified instead of image rendered?\n // e.g. no need to re-render annotations if only the VOI has changed\n triggerAnnotationRender(evt.detail.element)\n}\n\nconst enable = function (element: HTMLElement): void {\n element.addEventListener(Enums.Events.IMAGE_RENDERED, onImageRendered)\n}\n\nconst disable = function (element: HTMLElement): void {\n element.removeEventListener(Enums.Events.IMAGE_RENDERED, onImageRendered)\n}\n\nexport default {\n enable,\n disable,\n}\n","import { state, ToolGroupManager } from '../../store'\nimport ToolModes from '../../enums/ToolModes'\n\nconst { Active } = ToolModes\n\n/**\n * @function customCallbackHandler This is used as a generic event handler for tool events\n * on viewports. It:\n *\n * - Finds an \"active\" tool with:\n * - A matching `handlerType`\n * - A matching `customFunction` on its tool instance\n *\n * Then calls that custom function with raised event.\n *\n * @param handlerType - 'Mouse' | 'Touch' | 'MouseWheel'\n * @param customFunction - Function name that's expected to live on implementing\n * (and event handling) active tool ex. 'doubleClickCallback'\n * @param evt\n */\nexport default function customCallbackHandler(\n handlerType: string,\n customFunction: string,\n evt\n) {\n if (state.isInteractingWithTool) {\n return false\n }\n\n const { renderingEngineUID, viewportUID } = evt.detail\n const toolGroup = ToolGroupManager.getToolGroup(\n viewportUID,\n renderingEngineUID\n )\n\n if (!toolGroup) {\n return false\n }\n\n // TODO: Filter tools by interaction type?\n /**\n * Iterate tool group tools until we find a tool that is:\n * - active\n * - has the custom callback function\n *\n */\n let activeTool\n const toolGroupToolNames = Object.keys(toolGroup.toolOptions)\n\n for (let j = 0; j < toolGroupToolNames.length; j++) {\n const toolName = toolGroupToolNames[j]\n const tool = toolGroup.toolOptions[toolName]\n // TODO: Should be getter\n const toolInstance = toolGroup.getToolInstance(toolName)\n\n if (\n // TODO: Should be enum?\n tool.mode === Active &&\n // TODO: Should be implements interface?\n // Weird that we need concrete instance. Other options to filter / get callback?\n typeof toolInstance[customFunction] === 'function'\n ) {\n activeTool = toolGroup.getToolInstance(toolName)\n break\n }\n }\n\n if (!activeTool) {\n return\n }\n\n activeTool[customFunction](evt)\n}\n","import customCallbackHandler from '../shared/customCallbackHandler'\n\n/**\n * mouseClick - Event handler for mouse click events. Uses `customCallbackHandler` to fire\n * the `mouseClickCallback` function on active tools.\n */\nconst mouseClick = customCallbackHandler.bind(\n null,\n 'Mouse',\n 'mouseClickCallback'\n)\n\nexport default mouseClick\n","import customCallbackHandler from '../shared/customCallbackHandler'\n\n/**\n * @function mouseDoubleClick - Event handler for mouse double click events. Uses `customCallbackHandler` to fire\n * the `doubleClickCallback` function on active tools.\n */\nconst mouseDoubleClick = customCallbackHandler.bind(\n null,\n 'Mouse',\n 'doubleClickCallback'\n)\n\nexport default mouseDoubleClick\n","import { getAnnotations } from '../stateManagement/annotation/annotationState'\nimport { ToolAnnotationsPair } from '../types/InternalToolTypes'\nimport type AnnotationTool from '../tools/base/AnnotationTool'\nimport BaseTool from '../tools/base/BaseTool'\n\n/**\n * Filters an array of tools, returning only tools which have annotation.\n *\n * @param element - The cornerstone3D enabled element.\n * @param tools - The array of tools to check.\n *\n * @returns The array of tools with their found annotations.\n */\nexport default function filterToolsWithAnnotationsForElement(\n element: HTMLElement,\n tools: AnnotationTool[]\n): ToolAnnotationsPair[] {\n const result = []\n\n for (let i = 0; i < tools.length; i++) {\n const tool = tools[i]\n\n if (!tool) {\n console.warn('undefined tool in filterToolsWithAnnotationsForElement')\n continue\n }\n\n let annotations = getAnnotations(\n element,\n (tool.constructor as typeof BaseTool).toolName\n )\n\n if (!annotations) {\n continue\n }\n\n if (typeof tool.filterInteractableAnnotationsForElement === 'function') {\n // If the tool has a annotations filter (e.g. with in-plane-annotations-only filtering), use it.\n annotations = tool.filterInteractableAnnotationsForElement(\n element,\n annotations\n )\n }\n\n if (annotations.length > 0) {\n result.push({ tool, annotations })\n }\n }\n\n return result\n}\n","import { ToolGroupManager } from '../../store'\nimport { MouseBindings, ToolModes } from '../../enums'\nimport { keyEventListener } from '../../eventListeners'\nimport { EventTypes } from '../../types'\n\nconst { Active } = ToolModes\n\n/**\n * Iterate tool group tools until we find a tool that has a \"ToolBinding\"\n * that matches our MouseEvent's `buttons`. It's possible there will be no match\n * (no active tool for that mouse button combination).\n *\n * @param evt - The event dispatcher mouse event.\n *\n * @returns tool\n */\nexport default function getActiveToolForMouseEvent(\n evt: EventTypes.NormalizedMouseEventType\n) {\n // Todo: we should refactor this to use getToolsWithModesForMouseEvent instead\n const { renderingEngineUID, viewportUID } = evt.detail\n const mouseEvent = evt.detail.event\n\n // If any keyboard modifier key is also pressed\n const modifierKey = keyEventListener.getModifierKey()\n\n const toolGroup = ToolGroupManager.getToolGroup(\n viewportUID,\n renderingEngineUID\n )\n\n if (!toolGroup) {\n return null\n }\n\n const toolGroupToolNames = Object.keys(toolGroup.toolOptions)\n\n for (let j = 0; j < toolGroupToolNames.length; j++) {\n const toolName = toolGroupToolNames[j]\n const toolOptions = toolGroup.toolOptions[toolName]\n\n // tool has binding that matches the mouse button, if mouseEvent is undefined\n // it uses the primary button\n const correctBinding =\n toolOptions.bindings.length &&\n toolOptions.bindings.some(\n (binding) =>\n binding.mouseButton ===\n (mouseEvent ? mouseEvent.buttons : MouseBindings.Primary) &&\n binding.modifierKey === modifierKey\n )\n\n if (toolOptions.mode === Active && correctBinding) {\n return toolGroup.getToolInstance(toolName)\n }\n }\n}\n","import { ToolGroupManager } from '../../store'\nimport { ToolModes } from '../../enums'\nimport { EventTypes } from '../../types'\n\ntype ModesFilter = Array<ToolModes>\n\n/**\n * Given the normalized mouse event and a filter of modes,\n * find all the tools on the element that are in one of the specified modes.\n * If the evtButton is specified, only tools with a matching binding will be returned.\n * @param evt - The normalized mouseDown event.\n * @param modesFilter - An array of entries from the `ToolModes` enum.\n */\nexport default function getToolsWithModesForMouseEvent(\n evt: EventTypes.NormalizedMouseEventType,\n modesFilter: ModesFilter,\n evtButton?: any\n) {\n const { renderingEngineUID, viewportUID } = evt.detail\n const toolGroup = ToolGroupManager.getToolGroup(\n viewportUID,\n renderingEngineUID\n )\n\n if (!toolGroup) {\n return []\n }\n\n const enabledTools = []\n\n const toolGroupToolNames = Object.keys(toolGroup.toolOptions)\n\n for (let j = 0; j < toolGroupToolNames.length; j++) {\n const toolName = toolGroupToolNames[j]\n const tool = toolGroup.toolOptions[toolName]\n\n // tool has binding that matches the mouse button - we match those with\n // any modifier keys too since they can be passively interacted with\n const correctBinding =\n evtButton != null && // not null or undefined\n tool.bindings.length &&\n tool.bindings.some((binding) => binding.mouseButton === evtButton)\n\n if (\n modesFilter.includes(tool.mode) &&\n // Should not filter by event's button\n // or should, and the tool binding includes the event's button\n (!evtButton || correctBinding)\n ) {\n const toolInstance = toolGroup.getToolInstance(toolName)\n enabledTools.push(toolInstance)\n }\n }\n\n return enabledTools\n}\n","import { state } from '../../store'\nimport { ToolModes } from '../../enums'\nimport { Annotation, EventTypes } from '../../types'\nimport {\n ToolAnnotationPair,\n ToolsWithMoveableHandles,\n} from '../../types/InternalToolTypes'\n\nimport {\n setAnnotationSelected,\n isAnnotationSelected,\n} from '../../stateManagement/annotation/annotationSelection'\n\nimport { isAnnotationLocked } from '../../stateManagement/annotation/annotationLocking'\n\n// Util\nimport filterToolsWithMoveableHandles from '../../store/filterToolsWithMoveableHandles'\nimport filterToolsWithAnnotationsForElement from '../../store/filterToolsWithAnnotationsForElement'\nimport filterMoveableAnnotationTools from '../../store/filterMoveableAnnotationTools'\nimport getActiveToolForMouseEvent from '../shared/getActiveToolForMouseEvent'\nimport getToolsWithModesForMouseEvent from '../shared/getToolsWithModesForMouseEvent'\n\nconst { Active, Passive } = ToolModes\n\n/**\n * When the mouse is depressed we check which entities can process these events in the following manner:\n *\n * - First we get the `activeTool` for the mouse button pressed.\n * - If the `activeTool` has a `preMouseDownCallback`, this is called. If the callback returns `true`,\n * the event does not propagate further.\n * - Next we get all tools which are active or passive (`activeAndPassiveTools`), as annotation. for these tools could\n * possibly catch and handle these events. We then filter the `activeAndPassiveTools` using `filterToolsWithAnnotationsForElement`, which filters tools with annotations\n * for this frame of reference. Optionally a tool can employ a further filtering (via a\n * `filterInteractableAnnotationsForElement` callback) for tools interactable within the current camera view\n * (e.g. tools that only render when viewed from a certain direction).\n * - Next we check if any handles are interactable for each tool (`filterToolsWithMoveableHandles`). If interactable\n * handles are found, the first tool/handle found consumes the event and the event does not propagate further.\n * - Next we check any tools are interactable (e.g. moving an entire length annotation rather than one of its handles:\n * `filterMoveableAnnotationTools`). If interactable tools are found, the first tool found consumes the event and the\n * event does not propagate further.\n * - Finally, if the `activeTool` has `postMouseDownCallback`, this is called. If the callback returns `true`,\n * the event does not propagate further.\n *\n * If the event is not consumed the event will bubble to the `mouseDownActivate` handler.\n *\n * @param evt - The normalized mouseDown event.\n */\nexport default function mouseDown(evt: EventTypes.MouseDownEventType) {\n // If a tool has locked the current state it is dealing with an interaction within its own eventLoop.\n if (state.isInteractingWithTool) {\n return\n }\n\n const activeTool = getActiveToolForMouseEvent(evt)\n\n // Check for preMouseDownCallbacks,\n // If the tool claims it consumed the event, prevent further checks.\n if (activeTool && typeof activeTool.preMouseDownCallback === 'function') {\n const consumedEvent = activeTool.preMouseDownCallback(evt)\n\n if (consumedEvent) {\n return\n }\n }\n\n // Find all tools that might respond to this mouse down\n const isPrimaryClick = evt.detail.event.buttons === 1\n const activeToolsWithEventBinding = getToolsWithModesForMouseEvent(\n evt,\n [Active],\n evt.detail.event.buttons\n )\n const passiveToolsIfEventWasPrimaryMouseButton = isPrimaryClick\n ? getToolsWithModesForMouseEvent(evt, [Passive])\n : undefined\n const applicableTools = [\n ...(activeToolsWithEventBinding || []),\n ...(passiveToolsIfEventWasPrimaryMouseButton || []),\n ]\n\n const eventDetail = evt.detail\n const { element } = eventDetail\n\n // Filter tools with annotations for this element\n const annotationToolsWithAnnotations = filterToolsWithAnnotationsForElement(\n element,\n applicableTools\n )\n\n const canvasCoords = eventDetail.currentPoints.canvas\n\n // For the canvas coordinates, find all tools that might respond to this mouse down\n // on their handles. This filter will call getHandleNearImagePoint for each tool\n // instance (each annotation)\n const annotationToolsWithMoveableHandles = filterToolsWithMoveableHandles(\n element,\n annotationToolsWithAnnotations,\n canvasCoords,\n 'mouse'\n )\n\n // Preserve existing selections when shift key is pressed\n const isMultiSelect = !!evt.detail.event.shiftKey\n\n // If there are annotation tools whose handle is near the mouse, select the first one\n // that isn't locked. If there's only one annotation tool, select it.\n if (annotationToolsWithMoveableHandles.length > 0) {\n const { tool, annotation, handle } = getAnnotationForSelection(\n annotationToolsWithMoveableHandles\n ) as ToolsWithMoveableHandles\n\n toggleAnnotationSelection(annotation, isMultiSelect)\n tool.handleSelectedCallback(evt, annotation, handle, 'Mouse')\n\n return\n }\n\n // If there were no annotation tools whose handle was near the mouse, try to check\n // if any of the annotation tools are interactable (e.g. moving an entire length annotation)\n const moveableAnnotationTools = filterMoveableAnnotationTools(\n element,\n annotationToolsWithAnnotations,\n canvasCoords,\n 'mouse'\n )\n\n // If there are annotation tools that are interactable, select the first one\n // that isn't locked. If there's only one annotation tool, select it.\n if (moveableAnnotationTools.length > 0) {\n const { tool, annotation } = getAnnotationForSelection(\n moveableAnnotationTools\n )\n\n toggleAnnotationSelection(annotation, isMultiSelect)\n tool.toolSelectedCallback(evt, annotation, 'Mouse')\n\n return\n }\n\n // Run the postMouseDownCallback for the active tool if it exists\n if (activeTool && typeof activeTool.postMouseDownCallback === 'function') {\n const consumedEvent = activeTool.postMouseDownCallback(evt)\n\n if (consumedEvent) {\n // If the tool claims it consumed the event, prevent further checks.\n return\n }\n }\n\n // Don't stop propagation so that mouseDownActivate can handle the event\n}\n\n/**\n * If there are multiple annotation tools, return the first one that isn't locked.\n * If there's only one annotation tool, return it\n * @param annotationTools - An array of tools and annotation.\n * @returns The candidate for selection\n */\nfunction getAnnotationForSelection(\n toolsWithMovableHandles: ToolAnnotationPair[]\n): ToolAnnotationPair {\n return (\n (toolsWithMovableHandles.length > 1 &&\n toolsWithMovableHandles.find(\n (item) => !isAnnotationLocked(item.annotation)\n )) ||\n toolsWithMovableHandles[0]\n )\n}\n\n/**\n * If the annotation is selected, deselect it. If it's not selected, select it\n * @param annotation - The Annotation object that we\n * want to toggle the selection of.\n * @param isMultiSelect - If true, the annotation. will be deselected if it is\n * already selected, or deselected if it is selected.\n */\nfunction toggleAnnotationSelection(\n annotation: Annotation,\n isMultiSelect = false\n): void {\n if (isMultiSelect) {\n if (isAnnotationSelected(annotation)) {\n setAnnotationSelected(annotation, false)\n } else {\n const preserveSelected = true\n setAnnotationSelected(annotation, true, preserveSelected)\n }\n } else {\n const preserveSelected = false\n setAnnotationSelected(annotation, true, preserveSelected)\n }\n}\n","import type { Types } from '@cornerstonejs/core'\n\nimport {\n ToolAnnotationsPair,\n ToolsWithMoveableHandles,\n} from '../types/InternalToolTypes'\n\n/**\n * Filters an array of tools, returning only tools with moveable handles at the mouse location that are not locked\n *\n * @param element - The element\n * @param ToolAndAnnotations - The input tool array.\n * @param canvasCoords - The coordinates of the mouse position.\n * @param interactionType - The type of interaction (e.g. 'mouse' or 'touch')\n * @returns The filtered array.\n */\nexport default function filterToolsWithMoveableHandles(\n element: HTMLElement,\n ToolAndAnnotations: ToolAnnotationsPair[],\n canvasCoords: Types.Point2,\n interactionType = 'mouse'\n): ToolsWithMoveableHandles[] {\n const proximity = 6\n const toolsWithMoveableHandles = []\n\n ToolAndAnnotations.forEach(({ tool, annotations }) => {\n for (const annotation of annotations) {\n if (annotation.isLocked) {\n continue\n }\n\n const handle = tool.getHandleNearImagePoint(\n element,\n annotation,\n canvasCoords,\n proximity\n )\n\n if (handle) {\n toolsWithMoveableHandles.push({\n tool,\n annotation,\n handle,\n })\n break\n }\n }\n })\n\n return toolsWithMoveableHandles\n}\n","import type { Types } from '@cornerstonejs/core'\n\nimport {\n ToolAnnotationPair,\n ToolAnnotationsPair,\n} from '../types/InternalToolTypes'\n\n/**\n * Filters an array of tools with annotations, returning the first annotation\n * for each tool that is moveable and at the mouse location. It results in\n * one annotation per tool.\n *\n *\n * @param element - The HTML element\n * @param ToolAndAnnotations - The input tool array.\n * @param canvasCoords - The coordinates of the mouse position.\n * @param interactionType - The type of interaction that is taking place.\n * @returns The filtered array containing ToolAndAnnotation\n */\nexport default function filterMoveableAnnotationTools(\n element: HTMLElement,\n ToolAndAnnotations: ToolAnnotationsPair[],\n canvasCoords: Types.Point2,\n interactionType = 'mouse'\n): ToolAnnotationPair[] {\n const proximity = 6\n\n // TODO - This could get pretty expensive pretty quickly. We don't want to fetch the camera\n // And do world to canvas on each coord.\n\n // We want to produce a matrix from canvas to world for the viewport and just do a matrix operation on each handle.\n // This could still be expensive for ROIs, but we probably shouldn't have \"handles\" for them anyway.\n\n const moveableAnnotationTools = []\n\n ToolAndAnnotations.forEach(({ tool, annotations }) => {\n for (const annotation of annotations) {\n if (annotation.isLocked) {\n continue\n }\n\n const near = tool.isPointNearTool(\n element,\n annotation,\n canvasCoords,\n proximity,\n interactionType\n )\n\n if (near) {\n moveableAnnotationTools.push({\n tool,\n annotation,\n })\n break\n }\n }\n })\n\n return moveableAnnotationTools\n}\n","import { state } from '../../store'\nimport getActiveToolForMouseEvent from '../shared/getActiveToolForMouseEvent'\nimport { setAnnotationSelected } from '../../stateManagement/annotation/annotationSelection'\nimport { EventTypes } from '../../types'\n\n/**\n * If the `mouseDown` handler does not consume an event,\n * activate the creation loop of the active tool, if one is found for the\n * mouse button pressed.\n *\n * @param evt - The normalized mouseDown event.\n */\nexport default function mouseDownActivate(\n evt: EventTypes.MouseDownActivateEventType\n) {\n // If a tool has locked the current state it is dealing with an interaction within its own eventLoop.\n if (state.isInteractingWithTool) {\n return\n }\n\n const activeTool = getActiveToolForMouseEvent(evt)\n\n if (!activeTool) {\n return\n }\n\n if (state.isMultiPartToolActive) {\n return\n }\n\n if (activeTool.addNewAnnotation) {\n const annotation = activeTool.addNewAnnotation(evt, 'mouse')\n setAnnotationSelected(annotation)\n }\n}\n","import getActiveToolForMouseEvent from '../shared/getActiveToolForMouseEvent'\nimport { state } from '../../store'\nimport { MouseDragEventType } from '../../types/EventTypes'\n\n/**\n * mouseDrag - Event handler for mouse drag events. Fires the `mouseDragCallback`\n * function on active tools.\n *\n * @param evt - The normalized mouseDown event.\n */\nexport default function mouseDrag(evt: MouseDragEventType) {\n if (state.isInteractingWithTool) {\n return\n }\n\n const activeTool = getActiveToolForMouseEvent(evt)\n\n const noFoundToolOrDoesNotHaveMouseDragCallback =\n !activeTool || typeof activeTool.mouseDragCallback !== 'function'\n if (noFoundToolOrDoesNotHaveMouseDragCallback) {\n return\n }\n\n activeTool.mouseDragCallback(evt)\n}\n","// // State\nimport { state } from '../../store'\nimport { ToolModes } from '../../enums'\n\n// // Util\nimport filterToolsWithAnnotationsForElement from '../../store/filterToolsWithAnnotationsForElement'\nimport getToolsWithModesForMouseEvent from '../shared/getToolsWithModesForMouseEvent'\nimport triggerAnnotationRender from '../../utilities/triggerAnnotationRender'\nimport { MouseMoveEventType } from '../../types/EventTypes'\n\nconst { Active, Passive } = ToolModes\n\n/**\n * mouseMove - On mouse move when not dragging, fire tools `mouseMoveCallback`s.\n * This is mostly used to update the [un]hover state\n * of a tool.\n *\n * @param evt - The normalized mouseDown event.\n */\nexport default function mouseMove(evt: MouseMoveEventType) {\n // Tool interactions when mouse moved are handled inside each tool.\n // This function is mostly used to update the [un]hover state\n if (state.isInteractingWithTool || state.isMultiPartToolActive) {\n return\n }\n\n const activeAndPassiveTools = getToolsWithModesForMouseEvent(evt, [\n Active,\n Passive,\n ])\n\n const eventDetail = evt.detail\n const { element } = eventDetail\n\n // Annotation tool specific\n const toolsWithAnnotations = filterToolsWithAnnotationsForElement(\n element,\n activeAndPassiveTools\n )\n\n let annotationsNeedToBeRedrawn = false\n\n for (const { tool, annotations } of toolsWithAnnotations) {\n if (typeof tool.mouseMoveCallback === 'function') {\n annotationsNeedToBeRedrawn =\n tool.mouseMoveCallback(evt, annotations) || annotationsNeedToBeRedrawn\n }\n }\n\n // Annotation activation status changed, redraw the annotations\n if (annotationsNeedToBeRedrawn === true) {\n triggerAnnotationRender(element)\n }\n}\n","import customCallbackHandler from '../shared/customCallbackHandler'\n\n/**\n * mouseClick - Event handler for mouse up events. Uses `customCallbackHandler` to fire\n * the `mouseUpCallback` function on active tools.\n */\nconst mouseUp = customCallbackHandler.bind(null, 'Mouse', 'mouseUpCallback')\n\nexport default mouseUp\n","import customCallbackHandler from '../shared/customCallbackHandler'\n\n/**\n * Event handler for mouse wheel events. Uses `customCallbackHandler` to fire\n * the `mouseWheelCallback` function on active tools.\n */\nconst mouseWheel = customCallbackHandler.bind(\n null,\n 'MouseWheel',\n 'mouseWheelCallback'\n)\n\nexport default mouseWheel\n","import Events from '../enums/Events'\n\nimport {\n mouseClick,\n mouseDown,\n mouseDownActivate,\n mouseDoubleClick,\n mouseDrag,\n mouseMove,\n mouseUp,\n mouseWheel,\n} from './mouseEventHandlers'\n\n/**\n * Enable these listeners are emitted in order, and can be cancelled/prevented from bubbling\n * by any previous event.\n *\n * @param element - The element to add the event listeners to.\n */\nconst enable = function (element: HTMLElement): void {\n element.addEventListener(Events.MOUSE_CLICK, mouseClick)\n element.addEventListener(Events.MOUSE_DOWN, mouseDown)\n element.addEventListener(Events.MOUSE_DOWN_ACTIVATE, mouseDownActivate)\n element.addEventListener(Events.MOUSE_DOUBLE_CLICK, mouseDoubleClick)\n element.addEventListener(Events.MOUSE_DRAG, mouseDrag)\n element.addEventListener(Events.MOUSE_MOVE, mouseMove)\n element.addEventListener(Events.MOUSE_UP, mouseUp)\n element.addEventListener(Events.MOUSE_WHEEL, mouseWheel)\n}\n\n/**\n * Disable and Remove the MouseToolEventDispatcher handlers from the element.\n *\n * @param element - HTMLElement\n */\nconst disable = function (element: HTMLElement) {\n element.removeEventListener(Events.MOUSE_CLICK, mouseClick)\n element.removeEventListener(Events.MOUSE_DOWN, mouseDown)\n element.removeEventListener(Events.MOUSE_DOWN_ACTIVATE, mouseDownActivate)\n element.removeEventListener(Events.MOUSE_DOUBLE_CLICK, mouseDoubleClick)\n element.removeEventListener(Events.MOUSE_DRAG, mouseDrag)\n element.removeEventListener(Events.MOUSE_MOVE, mouseMove)\n element.removeEventListener(Events.MOUSE_UP, mouseUp)\n element.removeEventListener(Events.MOUSE_WHEEL, mouseWheel)\n}\n\nconst mouseToolEventDispatcher = {\n enable,\n disable,\n}\n\nexport default mouseToolEventDispatcher\n","import { ToolGroupManager } from '../../store'\nimport { ToolModes, MouseBindings } from '../../enums'\nimport { keyEventListener } from '../../eventListeners'\nimport { EventTypes } from '../../types'\nimport { getMouseButton } from '../../eventListeners/mouse/mouseDownListener'\n\nconst { Active } = ToolModes\n\n/**\n * Iterate tool group tools until we find a tool that has a \"ToolBinding\"\n * that matches our Keyboard pressed keys. It's possible there will be no match\n * (no active tool for that mouse button combination).\n *\n * @param evt - The normalized keyboard event.\n *\n * @returns tool\n */\nexport default function getActiveToolForKeyboardEvent(\n evt: EventTypes.KeyDownEventType\n) {\n const { renderingEngineUID, viewportUID } = evt.detail\n\n // Get the current mouse button clicked\n const mouseButton = getMouseButton()\n\n // If any keyboard modifier key is also pressed\n const modifierKey = keyEventListener.getModifierKey()\n\n const toolGroup = ToolGroupManager.getToolGroup(\n viewportUID,\n renderingEngineUID\n )\n\n if (!toolGroup) {\n return null\n }\n\n const toolGroupToolNames = Object.keys(toolGroup.toolOptions)\n\n for (let j = 0; j < toolGroupToolNames.length; j++) {\n const toolName = toolGroupToolNames[j]\n const toolOptions = toolGroup.toolOptions[toolName]\n\n // tool has binding that matches the mouse button, if mouseEvent is undefined\n // it uses the primary button\n const correctBinding =\n toolOptions.bindings.length &&\n toolOptions.bindings.some(\n (binding) =>\n binding.mouseButton === (mouseButton ?? MouseBindings.Primary) &&\n binding.modifierKey === modifierKey\n )\n\n if (toolOptions.mode === Active && correctBinding) {\n return toolGroup.getToolInstance(toolName)\n }\n }\n}\n","import { ToolGroupManager } from '../../store'\nimport getActiveToolForKeyboardEvent from '../shared/getActiveToolForKeyboardEvent'\nimport { KeyDownEventType } from '../../types/EventTypes'\n\n/**\n * KeyDown event listener to handle viewport cursor icon changes\n *\n * @param evt - The KeyboardEvent\n */\nexport default function keyDown(evt: KeyDownEventType): void {\n // get the active tool given the key and mouse button\n const activeTool = getActiveToolForKeyboardEvent(evt)\n\n if (!activeTool) {\n return\n }\n\n const { renderingEngineUID, viewportUID } = evt.detail\n\n const toolGroup = ToolGroupManager.getToolGroup(\n viewportUID,\n renderingEngineUID\n )\n\n const toolName = activeTool.getToolName()\n if (Object.keys(toolGroup.toolOptions).includes(toolName)) {\n toolGroup.setViewportsCursorByToolName(toolName)\n }\n}\n","import { resetModifierKey } from '../../eventListeners/keyboard/keyDownListener'\nimport { ToolGroupManager } from '../../store'\nimport getActiveToolForKeyboardEvent from '../shared/getActiveToolForKeyboardEvent'\nimport { KeyDownEventType } from '../../types/EventTypes'\n\n/**\n * KeyDown event listener to handle viewport cursor icon changes\n *\n * @param evt - The KeyboardEvent\n */\nexport default function keyUp(evt: KeyDownEventType): void {\n // get the active tool for the primary mouse button\n const activeTool = getActiveToolForKeyboardEvent(evt)\n\n if (!activeTool) {\n return\n }\n\n const { renderingEngineUID, viewportUID } = evt.detail\n\n const toolGroup = ToolGroupManager.getToolGroup(\n viewportUID,\n renderingEngineUID\n )\n\n // Reset the modifier key\n resetModifierKey()\n\n const toolName = activeTool.getToolName()\n if (Object.keys(toolGroup.toolOptions).includes(toolName)) {\n toolGroup.setViewportsCursorByToolName(toolName)\n }\n}\n","import Events from '../enums/Events'\nimport { keyDown, keyUp } from './keyboardEventHandlers'\n\n/**\n * Enable Key down and key up listeners\n *\n * @param element - The HTML element to attach the event listeners to.\n */\nconst enable = function (element: HTMLElement) {\n element.addEventListener(Events.KEY_DOWN, keyDown)\n element.addEventListener(Events.KEY_UP, keyUp)\n}\n\n/**\n * Disable Key down and key up listeners\n * @param element - The HTML element to attach the event listeners to.\n */\nconst disable = function (element: HTMLElement) {\n element.removeEventListener(Events.KEY_DOWN, keyDown)\n element.removeEventListener(Events.KEY_UP, keyUp)\n}\n\nconst keyboardToolEventDispatcher = {\n enable,\n disable,\n}\n\nexport default keyboardToolEventDispatcher\n","import { Enums, Types } from '@cornerstonejs/core'\nimport { ToolModes } from '../enums'\nimport getToolsWithModesForMouseEvent from './shared/getToolsWithModesForMouseEvent'\n\nconst { Active, Passive, Enabled } = ToolModes\n\n/**\n * When the camera is modified, check what tools need to react to this.\n *\n * - First we get all tools which are active, passive or enabled on the element.\n * - If any of these tools have a `onCameraModified` method, we call it.\n *\n * @param evt - The normalized camera modified event.\n */\nconst onCameraModified = function (evt: Types.EventTypes.CameraModifiedEvent) {\n // @ts-ignore\n const enabledTools = getToolsWithModesForMouseEvent(evt, [\n Active,\n Passive,\n Enabled,\n ])\n\n enabledTools.forEach((tool) => {\n if (tool.onCameraModified) {\n tool.onCameraModified(evt)\n }\n })\n}\n\nconst enable = function (element) {\n element.addEventListener(Enums.Events.CAMERA_MODIFIED, onCameraModified)\n}\n\nconst disable = function (element) {\n element.removeEventListener(Enums.Events.CAMERA_MODIFIED, onCameraModified)\n}\n\nexport default {\n enable,\n disable,\n}\n","import { Enums, Types } from '@cornerstonejs/core'\nimport { ToolModes } from '../enums'\nimport getToolsWithModesForMouseEvent from './shared/getToolsWithModesForMouseEvent'\n\nconst { Active, Passive, Enabled } = ToolModes\n\n/**\n * When image spacing is calibrated modify the annotations for all of its tools\n * to consider the new calibration info.\n *\n * - First we get all tools which are active, passive or enabled on the element.\n * - If any of these tools have a `onImageSpacingCalibrated` method, we call it.\n *\n * @param evt - The normalized image calibration event.\n */\nconst onImageSpacingCalibrated = function (\n evt: Types.EventTypes.ImageSpacingCalibratedEvent\n) {\n // @ts-ignore\n const enabledTools = getToolsWithModesForMouseEvent(evt, [\n Active,\n Passive,\n Enabled,\n ])\n\n enabledTools.forEach((tool) => {\n if (tool.onImageSpacingCalibrated) {\n tool.onImageSpacingCalibrated(evt)\n }\n })\n}\n\nconst enable = function (element: HTMLElement) {\n element.addEventListener(\n Enums.Events.IMAGE_SPACING_CALIBRATED,\n onImageSpacingCalibrated\n )\n}\n\nconst disable = function (element: HTMLElement) {\n element.removeEventListener(\n Enums.Events.IMAGE_SPACING_CALIBRATED,\n onImageSpacingCalibrated\n )\n}\n\nexport default {\n enable,\n disable,\n}\n","import { Types } from '@cornerstonejs/core'\nimport {\n mouseEventListeners,\n wheelEventListener,\n keyEventListener,\n} from '../eventListeners'\nimport {\n imageRenderedEventDispatcher,\n cameraModifiedEventDispatcher,\n mouseToolEventDispatcher,\n keyboardToolEventDispatcher,\n imageSpacingCalibratedEventDispatcher,\n} from '../eventDispatchers'\nimport { state } from './state'\n\nimport { annotationRenderingEngine } from '../utilities/triggerAnnotationRender'\n\n/**\n * When an element is \"enabled\", add event listeners and dispatchers to it\n * so we can use interactions to affect tool behaviors\n *\n * @param evt - The ELEMENT_ENABLED event\n */\nexport default function addEnabledElement(\n evt: Types.EventTypes.ElementEnabledEvent\n): void {\n const { element, viewportUID } = evt.detail\n const svgLayer = _createSvgAnnotationLayer()\n\n // Reset/Create svgNodeCache for element\n _setSvgNodeCache(element)\n _appendChild(svgLayer, element)\n\n // Add this element to the annotation rendering engine\n annotationRenderingEngine.addViewportElement(viewportUID, element)\n\n // Listeners\n mouseEventListeners.enable(element)\n wheelEventListener.enable(element)\n keyEventListener.enable(element)\n\n // Dispatchers: renderer\n imageRenderedEventDispatcher.enable(element)\n cameraModifiedEventDispatcher.enable(element)\n imageSpacingCalibratedEventDispatcher.enable(element)\n // Dispatchers: interaction\n mouseToolEventDispatcher.enable(element)\n keyboardToolEventDispatcher.enable(element)\n // touchToolEventDispatcher.enable(enabledElement);\n\n // labelmap\n // State\n state.enabledElements.push(element)\n}\n\n/**\n *\n */\nfunction _createSvgAnnotationLayer(): SVGElement {\n const svgns = 'http://www.w3.org/2000/svg'\n const svgLayer = document.createElementNS(svgns, 'svg')\n\n svgLayer.classList.add('svg-layer')\n svgLayer.setAttribute('id', 'svg-layer')\n svgLayer.setAttribute('xmlns', 'http://www.w3.org/2000/svg')\n svgLayer.style.width = '100%'\n svgLayer.style.height = '100%'\n svgLayer.style.pointerEvents = 'none'\n svgLayer.style.position = 'absolute'\n // TODO: we should test this on high-res monitors\n //svgLayer.style.textRendering = 'optimizeSpeed'\n\n // Single dropshadow config for now\n const defs = document.createElementNS(svgns, 'defs')\n const filter = document.createElementNS(svgns, 'filter')\n const feOffset = document.createElementNS(svgns, 'feOffset')\n const feColorMatrix = document.createElementNS(svgns, 'feColorMatrix')\n const feGaussianBlur = document.createElementNS(svgns, 'feGaussianBlur')\n const feBlend = document.createElementNS(svgns, 'feBlend')\n\n //\n filter.setAttribute('id', 'shadow')\n filter.setAttribute('width', '110%')\n filter.setAttribute('height', '110%')\n\n //\n feOffset.setAttribute('result', 'offOut')\n feOffset.setAttribute('in', 'SourceGraphic')\n feOffset.setAttribute('dx', '0.5')\n feOffset.setAttribute('dy', '0.5')\n\n //\n feColorMatrix.setAttribute('result', 'matrixOut')\n feColorMatrix.setAttribute('in', 'offOut')\n feColorMatrix.setAttribute('type', 'matrix')\n feColorMatrix.setAttribute(\n 'values',\n '0.2 0 0 0 0 0 0.2 0 0 0 0 0 0.2 0 0 0 0 0 1 0'\n )\n\n //\n feGaussianBlur.setAttribute('result', 'blurOut')\n feGaussianBlur.setAttribute('in', 'matrixOut')\n feGaussianBlur.setAttribute('stdDeviation', '0.25')\n\n //\n feBlend.setAttribute('in', 'SourceGraphic')\n feBlend.setAttribute('in2', 'blurOut')\n feBlend.setAttribute('mode', 'normal')\n\n filter.appendChild(feOffset)\n filter.appendChild(feColorMatrix)\n filter.appendChild(feGaussianBlur)\n filter.appendChild(feBlend)\n defs.appendChild(filter)\n svgLayer.appendChild(defs)\n\n return svgLayer\n}\n\nfunction _setSvgNodeCache(element) {\n const { viewportUid: viewportUID, renderingEngineUid: renderingEngineUID } =\n element.dataset\n const elementHash = `${viewportUID}:${renderingEngineUID}`\n\n // Create or reset\n // TODO: If... Reset, we should blow out any nodes in DOM\n state.svgNodeCache[elementHash] = {}\n}\n\n/**\n *\n * @param newNode\n * @param referenceNode\n */\nfunction _appendChild(newNode: SVGElement, referenceNode: HTMLElement): void {\n referenceNode.querySelector('div.viewport-element').appendChild(newNode)\n}\n","import { state } from '../index'\nimport Synchronizer from './Synchronizer'\n\n/**\n * It returns all synchronizers that are not disabled and have a source viewport\n * with the given rendering engine UID and viewport UID\n * @param renderingEngineUID - The UID of the rendering engine\n * @param viewportUID - The UID of the viewport\n * @returns An array of synchronizers\n */\nfunction getSynchronizers(\n renderingEngineUID: string,\n viewportUID: string\n): Array<Synchronizer> {\n const synchronizersFilteredByUIDs = []\n\n if (!renderingEngineUID && !viewportUID) {\n throw new Error(\n 'At least one of renderingEngineUID or viewportUID should be given'\n )\n }\n\n for (let i = 0; i < state.synchronizers.length; i++) {\n const synchronizer = state.synchronizers[i]\n const notDisabled = !synchronizer.isDisabled()\n const hasSourceViewport = synchronizer.hasSourceViewport(\n renderingEngineUID,\n viewportUID\n )\n\n if (notDisabled && hasSourceViewport) {\n synchronizersFilteredByUIDs.push(synchronizer)\n }\n }\n\n return synchronizersFilteredByUIDs\n}\n\nexport default getSynchronizers\n","import { state } from '../index'\nimport { IToolGroup } from '../../types'\n\n/**\n * Given a rendering engine UID and a viewport UID, return the tool group that\n * contains that rendering engine and viewport. Note: A viewport can only be\n * associated with a single tool group. You cannot have a viewport that belongs\n * to multiple tool groups. To achieve so, create a new viewport and a new toolGroup\n * for it. This will not impact memory usage much as the volume textures are\n * shared across all viewports rendering the same image.\n *\n * @param viewportUID - The UID of the viewport that the tool is being\n * added to.\n * @param renderingEngineUID - The UID of the rendering engine that the\n * tool group is associated with.\n * @returns A tool group.\n */\nfunction getToolGroup(\n viewportUID: string,\n renderingEngineUID: string\n): IToolGroup | undefined {\n const toolGroupFilteredByUIDs = state.toolGroups.filter((tg) =>\n tg.viewportsInfo.some(\n (vp) =>\n vp.renderingEngineUID === renderingEngineUID &&\n (!vp.viewportUID || vp.viewportUID === viewportUID)\n )\n )\n\n if (!toolGroupFilteredByUIDs.length) {\n return\n }\n\n if (toolGroupFilteredByUIDs.length > 1) {\n throw new Error(\n `Multiple tool groups found for renderingEngineUID: ${renderingEngineUID} and viewportUID: ${viewportUID}. You should only\n have one tool group per viewport in a renderingEngine.`\n )\n }\n\n return toolGroupFilteredByUIDs[0]\n}\n\nexport default getToolGroup\n","import { getEnabledElement, Types } from '@cornerstonejs/core'\nimport {\n mouseEventListeners,\n wheelEventListener,\n keyEventListener,\n} from '../eventListeners'\nimport {\n imageRenderedEventDispatcher,\n cameraModifiedEventDispatcher,\n mouseToolEventDispatcher,\n keyboardToolEventDispatcher,\n imageSpacingCalibratedEventDispatcher,\n // touchToolEventDispatcher,\n} from '../eventDispatchers'\n// ~~\n\nimport filterToolsWithAnnotationsForElement from './filterToolsWithAnnotationsForElement'\nimport { state } from './state'\nimport getToolsWithModesForElement from '../utilities/getToolsWithModesForElement'\nimport { ToolModes } from '../enums'\nimport { removeAnnotation } from '../stateManagement'\nimport getSynchronizers from './SynchronizerManager/getSynchronizers'\nimport getToolGroup from './ToolGroupManager/getToolGroup'\nimport { annotationRenderingEngine } from '../utilities/triggerAnnotationRender'\n\nconst VIEWPORT_ELEMENT = 'viewport-element'\n\nfunction removeEnabledElement(\n elementDisabledEvt: Types.EventTypes.ElementDisabledEvent\n): void {\n // Is DOM element\n const { element, viewportUID } = elementDisabledEvt.detail\n\n _resetSvgNodeCache(element)\n\n // Todo: shouldn't this also remove the canvas?\n const viewportNode = element\n const svgLayer = viewportNode.querySelector('svg')\n const internalViewportNode = element.querySelector(`div.${VIEWPORT_ELEMENT}`)\n // element.removeChild(internalViewportNode)\n if (svgLayer) {\n internalViewportNode.removeChild(svgLayer)\n }\n\n // Remove this element from the annotation rendering engine\n annotationRenderingEngine.removeViewportElement(viewportUID)\n\n // Listeners\n mouseEventListeners.disable(element)\n wheelEventListener.disable(element)\n keyEventListener.disable(element)\n // labelmap\n\n // Dispatchers: renderer\n imageRenderedEventDispatcher.disable(element)\n cameraModifiedEventDispatcher.disable(element)\n imageSpacingCalibratedEventDispatcher.disable(element)\n // Dispatchers: interaction\n mouseToolEventDispatcher.disable(element)\n keyboardToolEventDispatcher.disable(element)\n // touchToolEventDispatcher.disable(canvas);\n\n // State\n // @TODO: We used to \"disable\" the tool before removal. Should we preserve the hook that would call on tools?\n _removeViewportFromSynchronizers(element)\n _removeViewportFromToolGroup(element)\n\n // _removeAllToolsForElement(canvas)\n _removeEnabledElement(element)\n}\n\nconst _removeViewportFromSynchronizers = (element: HTMLElement) => {\n const enabledElement = getEnabledElement(element)\n\n const synchronizers = getSynchronizers(\n enabledElement.renderingEngineUID,\n enabledElement.viewportUID\n )\n synchronizers.forEach((sync) => {\n sync.remove(enabledElement)\n })\n}\n\nconst _removeViewportFromToolGroup = (element: HTMLElement) => {\n const { renderingEngineUID, viewportUID } = getEnabledElement(element)\n\n const toolGroup = getToolGroup(viewportUID, renderingEngineUID)\n\n if (toolGroup) {\n toolGroup.removeViewports(renderingEngineUID, viewportUID)\n }\n}\n\nconst _removeAllToolsForElement = function (element) {\n const tools = getToolsWithModesForElement(element, [\n ToolModes.Active,\n ToolModes.Passive,\n ])\n\n const toolsWithData = filterToolsWithAnnotationsForElement(element, tools)\n toolsWithData.forEach(({ annotations }) => {\n annotations.forEach((annotation) => {\n removeAnnotation(element, annotation.annotationUID)\n })\n })\n}\n\nfunction _resetSvgNodeCache(element: HTMLElement) {\n const { viewportUid: viewportUID, renderingEngineUid: renderingEngineUID } =\n element.dataset\n const elementHash = `${viewportUID}:${renderingEngineUID}`\n\n delete state.svgNodeCache[elementHash]\n}\n\n/**\n * @private\n * @param enabledElement\n */\nconst _removeEnabledElement = function (element: HTMLElement) {\n const foundElementIndex = state.enabledElements.findIndex(\n (el) => el === element\n )\n\n if (foundElementIndex > -1) {\n state.enabledElements.splice(foundElementIndex, 1)\n }\n}\n\nexport default removeEnabledElement\n","import { ToolModes } from '../enums'\nimport getToolsWithModesForElement from '../utilities/getToolsWithModesForElement'\nimport filterToolsWithAnnotationsForElement from './filterToolsWithAnnotationsForElement'\n\n/**\n * Cancel the current active manipulation that is being performed on the provided\n * element. It filters all the active and passive tools for the enabledElement\n * and calls cancel() method for all of them, and returns the tool that has executed its\n * cancellation (returned its annotationUID), since tools that are not being manipulated will\n * short circuit early. Note: not all tools currently implement a cancel method.\n *\n * @param element - canvas element\n * @returns annotationUID that is cancelled\n */\nexport default function cancelActiveManipulations(\n element: HTMLElement\n): string | undefined {\n const tools = getToolsWithModesForElement(element, [\n ToolModes.Active,\n ToolModes.Passive,\n ])\n\n const toolsWithData = filterToolsWithAnnotationsForElement(element, tools)\n for (const { tool } of toolsWithData) {\n const annotationUID = tool.cancel(element)\n if (annotationUID) {\n return annotationUID\n }\n }\n}\n","import {\n getRenderingEngine,\n getEnabledElement,\n Enums,\n Types,\n} from '@cornerstonejs/core'\n\nexport interface ISynchronizerEventHandler {\n (\n synchronizer: Synchronizer,\n sourceViewport: Types.IViewportUID,\n targetViewport: Types.IViewportUID,\n sourceEvent: any\n ): void\n}\n\n/**\n * Synchronizer is a class that listens to a specific event on a specific source\n * targets and fires a specific event on a specific target elements. Use cases\n * include: synchronizing a camera between two viewports, synchronizing a\n * windowLevel between various viewports.\n */\nclass Synchronizer {\n //\n private _enabled: boolean\n private _eventName: string\n private _eventHandler: ISynchronizerEventHandler\n private _ignoreFiredEvents: boolean\n private _sourceViewports: Array<Types.IViewportUID>\n private _targetViewports: Array<Types.IViewportUID>\n //\n public id: string\n\n constructor(\n synchronizerId: string,\n eventName: string,\n eventHandler: ISynchronizerEventHandler\n ) {\n this._enabled = true\n this._eventName = eventName\n this._eventHandler = eventHandler\n this._ignoreFiredEvents = false\n this._sourceViewports = []\n this._targetViewports = []\n\n //\n this.id = synchronizerId\n }\n\n /**\n * \"Returns true if the synchronizer is disabled.\"\n * @returns A boolean value.\n */\n public isDisabled(): boolean {\n return !this._enabled || !this._hasSourceElements()\n }\n\n /**\n * Add a viewport to the list of targets and sources both.\n * @param viewportInfo - The viewportUID and its renderingEngineUID to add to the list of targets and sources.\n */\n public add(viewportInfo: Types.IViewportUID): void {\n this.addTarget(viewportInfo)\n this.addSource(viewportInfo)\n }\n\n /**\n * Add a viewport to the list of sources (source ONLY)\n * @param viewportInfo - The viewportUID and its renderingEngineUID to add to the list of targets and sources.\n */\n public addSource(viewportInfo: Types.IViewportUID): void {\n if (_containsViewport(this._sourceViewports, viewportInfo)) {\n return\n }\n\n const { renderingEngineUID, viewportUID } = viewportInfo\n\n const { element } =\n getRenderingEngine(renderingEngineUID).getViewport(viewportUID)\n\n // @ts-ignore\n element.addEventListener(this._eventName, this._onEvent.bind(this))\n this._updateDisableHandlers()\n\n this._sourceViewports.push(viewportInfo)\n }\n\n /**\n * Add a viewport to the list of viewports that will get the eventHandler\n * executed when the event is fired on the source viewport.\n * @param viewportInfo - The viewportUID and its renderingEngineUID to add to the list of targets and sources.\n */\n public addTarget(viewportInfo: Types.IViewportUID): void {\n if (_containsViewport(this._targetViewports, viewportInfo)) {\n return\n }\n\n this._targetViewports.push(viewportInfo)\n this._updateDisableHandlers()\n }\n\n /**\n * Get the list of source viewports (as {viewportUID, renderingEngineUID} objects)\n * @returns An array of {viewportUID, renderingEngineUID} objects.\n */\n public getSourceViewports(): Array<Types.IViewportUID> {\n return this._sourceViewports\n }\n\n /**\n * Get the list of target viewports (as {viewportUID, renderingEngineUID} objects)\n * @returns An array of {viewportUID, renderingEngineUID} objects.\n */\n public getTargetViewports(): Array<Types.IViewportUID> {\n return this._targetViewports\n }\n\n public destroy(): void {\n this._sourceViewports.forEach((s) => this.removeSource(s))\n this._targetViewports.forEach((t) => this.removeTarget(t))\n }\n\n /**\n * Remove the viewport from the list of targets and sources\n * @param viewportInfo - The viewport info including viewportUID and renderingEngineUID.\n */\n public remove(viewportInfo: Types.IViewportUID): void {\n this.removeTarget(viewportInfo)\n this.removeSource(viewportInfo)\n }\n\n /**\n * Remove the viewport from the list of source viewports\n * @param viewportInfo - The viewport info including viewportUID and renderingEngineUID.\n */\n public removeSource(viewportInfo: Types.IViewportUID): void {\n const index = _getViewportIndex(this._sourceViewports, viewportInfo)\n\n if (index === -1) {\n return\n }\n\n const element = _getViewportElement(viewportInfo)\n\n this._sourceViewports.splice(index, 1)\n // @ts-ignore\n element.removeEventListener(this._eventName, this._eventHandler)\n this._updateDisableHandlers()\n }\n\n /**\n * Remove the viewport from the list of viewports that are currently targeted by\n * this handler\n * @param viewportInfo - The viewport info including viewportUID and renderingEngineUID.\n *\n */\n public removeTarget(viewportInfo: Types.IViewportUID): void {\n const index = _getViewportIndex(this._targetViewports, viewportInfo)\n\n if (index === -1) {\n return\n }\n\n this._targetViewports.splice(index, 1)\n this._updateDisableHandlers()\n }\n\n public hasSourceViewport(\n renderingEngineUID: string,\n viewportUID: string\n ): boolean {\n return _containsViewport(this._sourceViewports, {\n renderingEngineUID,\n viewportUID,\n })\n }\n\n private fireEvent(\n sourceViewport: Types.IViewportUID,\n sourceEvent: any\n ): void {\n if (this.isDisabled() || this._ignoreFiredEvents) {\n return\n }\n\n this._ignoreFiredEvents = true\n try {\n for (let i = 0; i < this._targetViewports.length; i++) {\n const targetViewport = this._targetViewports[i]\n const targetIsSource =\n sourceViewport.viewportUID === targetViewport.viewportUID\n\n if (targetIsSource) {\n continue\n }\n\n this._eventHandler(this, sourceViewport, targetViewport, sourceEvent)\n }\n } catch (ex) {\n console.warn(`Synchronizer, for: ${this._eventName}`, ex)\n } finally {\n this._ignoreFiredEvents = false\n }\n }\n\n private _onEvent = (evt: any): void => {\n if (this._ignoreFiredEvents === true) {\n return\n }\n\n // If no target viewports, then return immediately, this is useful\n // when switching between layouts, when previous layout has disabled\n // its viewports, and the new layout has not yet enabled them.\n // Right now we don't \"delete\" the synchronizer if all source and targets\n // are removed, but we may want to do that in the future.\n if (!this._targetViewports.length) {\n return\n }\n\n const enabledElement = getEnabledElement(evt.currentTarget)\n\n if (!enabledElement) {\n return\n }\n\n const { renderingEngineUID, viewportUID } = enabledElement\n\n this.fireEvent(\n {\n renderingEngineUID,\n viewportUID,\n },\n evt\n )\n }\n\n private _hasSourceElements(): boolean {\n return this._sourceViewports.length !== 0\n }\n\n private _updateDisableHandlers(): void {\n const viewports = _getUniqueViewports(\n this._sourceViewports,\n this._targetViewports\n )\n const _remove = this.remove\n const disableHandler = (elementDisabledEvent) => {\n _remove(elementDisabledEvent.detail.element)\n }\n\n viewports.forEach(function (vUid) {\n const { element } = getRenderingEngine(\n vUid.renderingEngineUID\n ).getViewport(vUid.viewportUID)\n\n element.removeEventListener(Enums.Events.ELEMENT_DISABLED, disableHandler)\n element.addEventListener(Enums.Events.ELEMENT_DISABLED, disableHandler)\n })\n }\n}\n\nfunction _getUniqueViewports(\n vp1: Array<Types.IViewportUID>,\n vp2: Array<Types.IViewportUID>\n): Array<Types.IViewportUID> {\n const unique = []\n\n const vps = vp1.concat(vp2)\n\n for (let i = 0; i < vps.length; i++) {\n const vp = vps[i]\n if (\n !unique.some(\n (u) =>\n vp.renderingEngineUID === u.renderingEngineUID &&\n vp.viewportUID === u.viewportUID\n )\n ) {\n unique.push(vp)\n }\n }\n\n return unique\n}\n\nfunction _getViewportIndex(\n arr: Array<Types.IViewportUID>,\n vp: Types.IViewportUID\n): number {\n return arr.findIndex(\n (ar) =>\n vp.renderingEngineUID === ar.renderingEngineUID &&\n vp.viewportUID === ar.viewportUID\n )\n}\n\nfunction _containsViewport(\n arr: Array<Types.IViewportUID>,\n vp: Types.IViewportUID\n) {\n return arr.some(\n (ar) =>\n ar.renderingEngineUID === vp.renderingEngineUID &&\n ar.viewportUID === vp.viewportUID\n )\n}\n\nfunction _getViewportElement(vp: Types.IViewportUID): HTMLElement {\n const renderingEngine = getRenderingEngine(vp.renderingEngineUID)\n if (!renderingEngine) {\n throw new Error(`No RenderingEngine for UID: ${vp.renderingEngineUID}`)\n }\n\n return renderingEngine.getViewport(vp.viewportUID).element\n}\n\nexport default Synchronizer\n","import { state } from '../index'\nimport Synchronizer, { ISynchronizerEventHandler } from './Synchronizer'\n\n/**\n * Create a new synchronizer instance from Synchronizer class\n * @param synchronizerId - The id of the synchronizer.\n * @param eventName - The name of the event that will be emitted by the\n * synchronizer.\n * @param eventHandler - The event handler that will be\n * called when the event is emitted.\n * @returns A reference to the synchronizer.\n */\nfunction createSynchronizer(\n synchronizerId: string,\n eventName: string,\n eventHandler: ISynchronizerEventHandler\n): Synchronizer {\n const synchronizerWithSameIdExists = state.synchronizers.some(\n (sync) => sync.id === synchronizerId\n )\n\n if (synchronizerWithSameIdExists) {\n throw new Error(`Synchronizer with id '${synchronizerId}' already exists.`)\n }\n\n // Create\n const synchronizer = new Synchronizer(synchronizerId, eventName, eventHandler)\n\n // Update state\n state.synchronizers.push(synchronizer)\n\n // Return reference\n return synchronizer\n}\n\nexport default createSynchronizer\n","import { state } from '../index'\n\n/**\n * \"Destroy all synchronizers.\"\n */\nfunction destroy(): void {\n while (state.synchronizers.length > 0) {\n const synchronizer = state.synchronizers.pop()\n\n synchronizer.destroy()\n }\n}\n\nexport default destroy\n","import { state } from '../index'\nimport Synchronizer from './Synchronizer'\n\n/**\n * Get the synchronizer with the given id from the state.\n * @param synchronizerId - The id of the synchronizer to be retrieved.\n * @returns A synchronizer object.\n */\nfunction getSynchronizerById(synchronizerId: string): Synchronizer | void {\n return state.synchronizers.find((s) => s.id === synchronizerId)\n}\n\nexport default getSynchronizerById\n","import { state } from '../index'\nimport Synchronizer from './Synchronizer'\n\n/**\n * Return the array of synchronizers\n * @returns An array of synchronizers.\n */\nfunction getAllSynchronizers(): Array<Synchronizer> {\n return state.synchronizers\n}\n\nexport default getAllSynchronizers\n","import { state } from '../index'\n\n// Synchronizers are a bit more tenacious. We need to make sure we remove\n// any attached events\n// We should probably just have a destroySynchronizer call\n// then use getByX to allow versatility in how we can call destroy\n\n/**\n * Destroy a synchronizer by its ID.\n * @param synchronizerId - The id of the synchronizer to destroy.\n */\nfunction destroySynchronizerById(synchronizerId: string): void {\n const synchronizerIndex = state.synchronizers.findIndex(\n (sync) => sync.id === synchronizerId\n )\n\n if (synchronizerIndex > -1) {\n const synchronizer = state.synchronizers[synchronizerIndex]\n\n synchronizer.destroy()\n state.synchronizers.splice(synchronizerIndex, 1)\n }\n}\n\nexport default destroySynchronizerById\n","const DEFINED_CURSORS = Symbol('DefinedCursors')\nconst STANDARD_CURSORS = new Set([\n 'alias',\n 'all-scroll',\n 'auto',\n 'cell',\n 'col-resize',\n 'context-menu',\n 'copy',\n 'crosshair',\n 'default',\n 'e-resize',\n 'ew-resize',\n 'grab',\n 'grabbing',\n 'help',\n 'move',\n 'ne-resize',\n 'nesw-resize',\n 'no-drop',\n 'none',\n 'not-allowed',\n 'n-resize',\n 'ns-resize',\n 'nw-resize',\n 'nwse-resize',\n 'pointer',\n 'progress',\n 'row-resize',\n 'se-resize',\n 's-resize',\n 'sw-resize',\n 'text',\n 'vertical-text',\n 'wait',\n 'w-resize',\n 'zoom-in',\n 'zoom-out',\n])\n\nexport default class MouseCursor {\n private name: string\n private fallback: MouseCursor | undefined\n\n constructor(name: string, fallback?: MouseCursor | undefined) {\n this.name = name + ''\n this.fallback = fallback\n }\n\n getName(): string {\n return this.name + ''\n }\n\n addFallbackStyleProperty(style: string): string {\n const { fallback } = this\n if (fallback instanceof MouseCursor) {\n return `${style}, ${fallback.getStyleProperty()}`\n }\n return style + ''\n }\n\n getStyleProperty(): string {\n return this.addFallbackStyleProperty(this.name) + ''\n }\n\n static getDefinedCursor(name: string): MouseCursor | undefined {\n const definedCursors = getDefinedCursors(\n // @ts-ignore\n MouseCursor as Record<symbol, Map<string, MouseCursor>>,\n DEFINED_CURSORS\n )\n let mouseCursor = definedCursors.get(name)\n if (mouseCursor instanceof MouseCursor) {\n return mouseCursor\n }\n if (STANDARD_CURSORS.has(name)) {\n mouseCursor = new MouseCursor(name)\n definedCursors.set(name, mouseCursor)\n return mouseCursor\n }\n }\n\n static setDefinedCursor(name: string, cursor: MouseCursor): boolean {\n if (cursor instanceof MouseCursor) {\n const definedCursors = getDefinedCursors(\n // @ts-ignore\n MouseCursor as Record<symbol, Map<string, MouseCursor>>,\n DEFINED_CURSORS\n )\n definedCursors.set(name, cursor)\n return true\n }\n return false\n }\n}\n\n/*\n * Helpers\n */\n\nfunction getDefinedCursors(\n context: Record<symbol, Map<string, MouseCursor>>,\n symbol: symbol\n): Map<string, MouseCursor> {\n let definedCursors = context[symbol]\n if (!(definedCursors instanceof Map)) {\n definedCursors = new Map()\n Object.defineProperty(context, symbol, { value: definedCursors })\n }\n return definedCursors\n}\n\nconst standardCursorNames = STANDARD_CURSORS.values()\nexport { standardCursorNames }\n","import { utilities } from '@cornerstonejs/core'\nimport MouseCursor from './MouseCursor'\n\nconst DEFAULT_NAME = 'image-cursor'\n\nexport default class ImageMouseCursor extends MouseCursor {\n private url: string\n private x: number\n private y: number\n\n constructor(\n url: string,\n x?: number,\n y?: number,\n name?: string | undefined,\n fallback?: MouseCursor | undefined\n ) {\n super(\n name || ImageMouseCursor.getUniqueInstanceName(DEFAULT_NAME),\n fallback\n )\n this.url = url\n this.x = Number(x) || 0\n this.y = Number(y) || 0\n }\n\n getStyleProperty(): string {\n const { url, x, y } = this\n let style = `url('${url}')`\n if (x >= 0 && y >= 0 && (x > 0 || y > 0)) {\n style += ` ${x} ${y}`\n }\n return this.addFallbackStyleProperty(style)\n }\n\n static getUniqueInstanceName(prefix: string): string {\n return `${prefix}-${utilities.getRuntimeId(ImageMouseCursor)}`\n }\n}\n","import getPrototypeOf from \"./getPrototypeOf.js\";\nexport default function _superPropBase(object, property) {\n while (!Object.prototype.hasOwnProperty.call(object, property)) {\n object = getPrototypeOf(object);\n if (object === null) break;\n }\n\n return object;\n}","import superPropBase from \"./superPropBase.js\";\nexport default function _get() {\n if (typeof Reflect !== \"undefined\" && Reflect.get) {\n _get = Reflect.get;\n } else {\n _get = function _get(target, property, receiver) {\n var base = superPropBase(target, property);\n if (!base) return;\n var desc = Object.getOwnPropertyDescriptor(base, property);\n\n if (desc.get) {\n return desc.get.call(arguments.length < 3 ? target : receiver);\n }\n\n return desc.value;\n };\n }\n\n return _get.apply(this, arguments);\n}","import { SVGCursorDescriptor } from '../types'\n\n/*\n * Definitions\n */\n\nconst BASE: SVGCursorDescriptor = {\n iconContent: '',\n iconSize: 16,\n viewBox: {\n x: 16,\n y: 16,\n },\n mousePoint: {\n x: 8,\n y: 8,\n },\n mousePointerGroupString: `\n <path stroke=\"{{color}}\" d=\"M8 16L8 0\"></path>\n <path stroke=\"{{color}}\" d=\"M16 8L0 8\"></path>\n `,\n}\n\nconst SEGMENTATION_CURSOR_BOUNDARIES = {\n x: 127,\n y: 60,\n}\n\nconst MINUS_RECT = `\n<rect fill=\"{{color}}\" x=\"80.19\" y=\"25.03\" width=\"47.14\" height=\"15.85\"/>\n`\n\nconst PLUS_RECT = `\n<rect fill=\"{{color}}\" x=\"80.19\" y=\"25.03\" width=\"47.14\" height=\"15.85\"/>\n<rect fill=\"{{color}}\" x=\"95.84\" y=\"9.38\" width=\"15.85\" height=\"47.14\"/>\n`\n\nconst SCISSOR_ICON = `<path fill=\"{{color}}\" d=\"M82.89,10a12.09,12.09,0,0,0-16.8-2.5l-27.5,20.4-8.5-6.3a2.93,2.93,0,0,1-1.1-3,14.66,14.66,0,0,0,.1-6.6,14.08,14.08,0,1,0-6.5,15.2,2.87,2.87,0,0,1,3.2.2l8.2,6.1-8.2,6.1a2.87,2.87,0,0,1-3.2.2,14.16,14.16,0,1,0,6.7,14.4,14,14,0,0,0-.3-5.8,2.93,2.93,0,0,1,1.1-3l8.5-6.3,27.5,20.4A11.91,11.91,0,0,0,82.89,57l-31.7-23.5ZM15.29,21a5.9,5.9,0,1,1,5.9-5.9A5.91,5.91,0,0,1,15.29,21Zm0,36.8a5.9,5.9,0,1,1,5.9-5.9A5.91,5.91,0,0,1,15.29,57.77Zm28.3-21.5a2.8,2.8,0,1,1,2.8-2.8A2.8,2.8,0,0,1,43.59,36.27Z\" transform=\"translate(-1.17 -0.96)\"/>`\nconst RECTANGLE_ICON = `<path fill=\"{{color}}\" d=\"M8.86,2.25V66.08H72.69V2.25H8.86ZM65.28,58.67h-49v-49h49v49Z\" transform=\"translate(-8.86 -2.25)\"/>`\nconst CIRCLE_ICON = `<path fill=\"{{color}}\" d=\"M40.77,2.25A31.92,31.92,0,1,0,72.69,34.16,31.92,31.92,0,0,0,40.77,2.25Zm0,57.63A25.71,25.71,0,1,1,66.48,34.16,25.71,25.71,0,0,1,40.77,59.87Z\" transform=\"translate(-8.86 -2.25)\"/>`\n\nconst DefinedDescriptorsMap = {\n Angle: extend(BASE, {\n iconContent: `<path fill=\"{{color}}\" d=\"M1203 544q0 13-10 23l-393 393 393 393q10 10 10 23t-10 23l-50\n 50q-10 10-23 10t-23-10l-466-466q-10-10-10-23t10-23l466-466q10-10 23-10t23\n 10l50 50q10 10 10 23z\" />`,\n viewBox: {\n x: 1792,\n y: 1792,\n },\n }),\n ArrowAnnotate: extend(BASE, {\n iconContent: `<g id=\"arrowAnnotate-group\" fill=\"none\" stroke-width=\"1\" stroke=\"{{color}}\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path id=\"arrowAnnotate-arrow\" d=\"M23,7 l-15,15 M7,17 l0,6 6,0\" stroke-width=\"2\" />\n </g>`,\n viewBox: {\n x: 24,\n y: 24,\n },\n }),\n Bidirectional: extend(BASE, {\n iconContent: `<g fill=\"{{color}}\" stroke-width=\"3\" stroke=\"{{color}}\">\n <path d=\"M27.63 3.21L3.12 28.81\"></path>\n <path d=\"M27.63 15.75L15.27 4.43\"></path>\n <path d=\"M16.5 4.28C16.5 4.96 15.95 5.51 15.27 5.51C14.59 5.51 14.03 4.96 14.03 4.28C14.03 3.59 14.59 3.04 15.27 3.04C15.95 3.04 16.5 3.59 16.5 4.28Z\" ></path>\n <path d=\"M28.87 3.19C28.87 3.87 28.31 4.43 27.63 4.43C26.95 4.43 26.4 3.87 26.4 3.19C26.4 2.51 26.95 1.95 27.63 1.95C28.31 1.95 28.87 2.51 28.87 3.19Z\"></path>\n <path d=\"M28.87 15.75C28.87 16.43 28.31 16.99 27.63 16.99C26.95 16.99 26.4 16.43 26.4 15.75C26.4 15.07 26.95 14.51 27.63 14.51C28.31 14.51 28.87 15.07 28.87 15.75Z\"></path>\n <path d=\"M4.73 28.44C4.73 29.12 4.17 29.68 3.49 29.68C2.81 29.68 2.25 29.12 2.25 28.44C2.25 27.76 2.81 27.2 3.49 27.2C4.17 27.2 4.73 27.76 4.73 28.44Z\"></path>\n </g>`,\n viewBox: {\n x: 48,\n y: 48,\n },\n }),\n CobbAngle: extend(BASE, {\n iconContent: `<g stroke=\"{{color}}\" stroke-width=\"3\">\n <path d=\"M28.59 2.34L3.82 12.32\"></path>\n <path d=\"M28.59 29.66L3.82 19.68\"></path>\n <path stroke-dasharray=\"2\" fill-opacity=\"0\" d=\"M12.37\n 23.06C12.67 22.36 12.85 21.93 12.92 21.76C14.6 17.8 14.68 13.35 13.15\n 9.33C13.11 9.24 13.02 9 12.88 8.63\">\n </path>\n </g>`,\n viewBox: {\n x: 32,\n y: 32,\n },\n }),\n CircleRoi: extend(BASE, {\n iconContent: `<circle stroke=\"{{color}}\" fill=\"none\" stroke-width=\"3\" cx=\"16\" cy=\"16\" r=\"14\" />`,\n viewBox: {\n x: 32,\n y: 32,\n },\n }),\n EllipticalRoi: extend(BASE, {\n iconContent: `<path stroke=\"{{color}}\" fill=\"none\" stroke-width=\"3\" d=\"M30.74 15.76C30.74 20.99 24.14 25.23 16\n 25.23C7.86 25.23 1.26 20.99 1.26 15.76C1.26 10.54 7.86 6.3 16 6.3C24.14\n 6.3 30.74 10.54 30.74 15.76Z\" />`,\n viewBox: {\n x: 32,\n y: 32,\n },\n }),\n FreehandRoi: extend(BASE, {\n iconContent: `<g fill=\"{{color}}\" stroke=\"{{color}}\" stroke-width=\"2\">\n <ellipse ry=\"1\" rx=\"1\" id=\"svg_3\" cy=\"4.240343\" cx=\"14.306499\"/>\n <line id=\"svg_4\" y2=\"3.58462\" x2=\"12.242186\" y1=\"3.997482\" x1=\"13.432202\"/>\n <line id=\"svg_5\" y2=\"3.268901\" x2=\"10.857882\" y1=\"3.608906\" x1=\"12.387902\"/>\n <line id=\"svg_6\" y2=\"3.147471\" x2=\"9.740724\" y1=\"3.293187\" x1=\"10.955026\"/>\n <line id=\"svg_7\" y2=\"3.147471\" x2=\"8.089274\" y1=\"3.196043\" x1=\"9.983585\"/>\n <line id=\"svg_8\" y2=\"3.268901\" x2=\"6.874972\" y1=\"3.123185\" x1=\"8.307848\"/>\n <line id=\"svg_9\" y2=\"3.657478\" x2=\"5.587812\" y1=\"3.220329\" x1=\"7.020688\"/>\n <line id=\"svg_10\" y2=\"4.046054\" x2=\"4.737801\" y1=\"3.560334\" x1=\"5.854959\"/>\n <line id=\"svg_11\" y2=\"4.337487\" x2=\"4.300652\" y1=\"3.997482\" x1=\"4.834945\"/>\n <line id=\"svg_12\" y2=\"4.726063\" x2=\"3.88779\" y1=\"4.191771\" x1=\"4.470655\"/>\n <line id=\"svg_15\" y2=\"5.3575\" x2=\"3.377783\" y1=\"4.604633\" x1=\"3.960648\"/>\n <line id=\"svg_16\" y2=\"6.183226\" x2=\"2.916348\" y1=\"5.138926\" x1=\"3.547785\"/>\n <line id=\"svg_17\" y2=\"6.960379\" x2=\"2.770632\" y1=\"5.867507\" x1=\"3.037779\"/>\n <line id=\"svg_18\" y2=\"7.713246\" x2=\"2.673488\" y1=\"6.741804\" x1=\"2.819204\"/>\n <line id=\"svg_19\" y2=\"8.684687\" x2=\"2.697774\" y1=\"7.616102\" x1=\"2.673488\"/>\n <line id=\"svg_20\" y2=\"9.753273\" x2=\"2.892062\" y1=\"8.611829\" x1=\"2.697774\"/>\n <line id=\"svg_21\" y2=\"10.724714\" x2=\"3.134923\" y1=\"9.534698\" x1=\"2.84349\"/>\n <line id=\"svg_23\" y2=\"11.647583\" x2=\"3.596357\" y1=\"10.578998\" x1=\"3.086351\"/>\n <line id=\"svg_25\" y2=\"12.521881\" x2=\"4.276366\" y1=\"11.501867\" x1=\"3.499213\"/>\n <line id=\"svg_26\" y2=\"13.930471\" x2=\"5.830673\" y1=\"12.376165\" x1=\"4.13065\"/>\n <line id=\"svg_28\" y2=\"14.707624\" x2=\"7.263549\" y1=\"13.881899\" x1=\"5.733528\"/>\n <line id=\"svg_29\" y2=\"15.339061\" x2=\"8.963571\" y1=\"14.61048\" x1=\"7.06926\"/>\n <line id=\"svg_30\" y2=\"15.581921\" x2=\"10.882168\" y1=\"15.314775\" x1=\"8.817855\"/>\n <line id=\"svg_31\" y2=\"15.460491\" x2=\"12.023612\" y1=\"15.581921\" x1=\"10.785024\"/>\n <line id=\"svg_33\" y2=\"15.120487\" x2=\"13.092197\" y1=\"15.484777\" x1=\"11.877895\"/>\n <line id=\"svg_34\" y2=\"14.586194\" x2=\"13.86935\" y1=\"15.217631\" x1=\"12.897909\"/>\n <line id=\"svg_35\" y2=\"13.833327\" x2=\"14.597931\" y1=\"14.756196\" x1=\"13.699348\"/>\n <line id=\"svg_37\" y2=\"12.716169\" x2=\"15.180796\" y1=\"13.881899\" x1=\"14.549359\"/>\n <line id=\"svg_39\" y2=\"11.429009\" x2=\"15.520801\" y1=\"12.813313\" x1=\"15.15651\"/>\n <ellipse ry=\"1\" rx=\"1\" id=\"svg_40\" cy=\"10.967574\" cx=\"15.520801\"/>\n </g>`,\n viewBox: {\n x: 18,\n y: 18,\n },\n }),\n FreehandRoiSculptor: extend(BASE, {\n iconContent: `<g id=\"icon-freehand-sculpt\" fill=\"none\" stroke-width=\"1.5\" stroke=\"{{color}}\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <line id=\"svg_1\" y2=\"2.559367\" x2=\"10.184807\" y1=\"4.467781\" x1=\"8.81711\"/>\n <line id=\"svg_4\" y2=\"1.493836\" x2=\"11.727442\" y1=\"2.766112\" x1=\"10.089386\"/>\n <line id=\"svg_7\" y2=\"1.080346\" x2=\"13.047428\" y1=\"1.748291\" x1=\"11.345759\"/>\n <line id=\"svg_8\" y2=\"1.000829\" x2=\"14.351511\" y1=\"1.112153\" x1=\"12.77707\"/>\n <line id=\"svg_9\" y2=\"1.350705\" x2=\"15.242104\" y1=\"0.905408\" x1=\"13.969828\"/>\n <line id=\"svg_10\" y2=\"2.098167\" x2=\"15.862339\" y1=\"1.14396\" x1=\"14.955842\"/>\n <line id=\"svg_11\" y2=\"3.195505\" x2=\"16.41896\" y1=\"1.939133\" x1=\"15.766918\"/>\n <line id=\"svg_12\" y2=\"4.292843\" x2=\"16.530284\" y1=\"2.925147\" x1=\"16.387153\"/>\n <line id=\"svg_16\" y2=\"5.644637\" x2=\"16.196311\" y1=\"3.831643\" x1=\"16.593898\"/>\n <line id=\"svg_18\" y2=\"7.266789\" x2=\"15.623787\" y1=\"5.19934\" x1=\"16.275829\"/>\n <line id=\"svg_19\" y2=\"10.813258\" x2=\"14.526449\" y1=\"6.726071\" x1=\"15.766918\"/>\n <line id=\"svg_20\" y2=\"5.056209\" x2=\"8.085552\" y1=\"4.181519\" x1=\"8.976145\"/>\n <line id=\"svg_23\" y2=\"5.326568\" x2=\"7.481221\" y1=\"4.78585\" x1=\"8.403621\"/>\n <line id=\"svg_24\" y2=\"5.565119\" x2=\"6.749662\" y1=\"5.294761\" x1=\"7.624352\"/>\n <line id=\"svg_25\" y2=\"5.994512\" x2=\"5.429675\" y1=\"5.533312\" x1=\"6.956407\"/>\n <line id=\"svg_27\" y2=\"6.551133\" x2=\"4.284627\" y1=\"5.962706\" x1=\"5.572807\"/>\n <line id=\"svg_28\" y2=\"7.584858\" x2=\"3.044158\" y1=\"6.392099\" x1=\"4.427758\"/>\n <line id=\"svg_29\" y2=\"8.84123\" x2=\"2.185372\" y1=\"7.489437\" x1=\"3.219096\"/>\n <line id=\"svg_31\" y2=\"10.606513\" x2=\"1.644654\" y1=\"8.602678\" x1=\"2.280792\"/>\n <line id=\"svg_32\" y2=\"13.214679\" x2=\"1.48562\" y1=\"10.352058\" x1=\"1.724171\"/>\n <line id=\"svg_33\" y2=\"14.375631\" x2=\"1.676461\" y1=\"12.992031\" x1=\"1.453813\"/>\n <line id=\"svg_34\" y2=\"15.298031\" x2=\"2.264889\" y1=\"14.152983\" x1=\"1.517427\"/>\n <line id=\"svg_35\" y2=\"16.172721\" x2=\"3.521261\" y1=\"14.948155\" x1=\"1.915013\"/>\n <line id=\"svg_36\" y2=\"16.824762\" x2=\"5.207027\" y1=\"15.997783\" x1=\"3.28271\"/>\n <line id=\"svg_38\" y2=\"17.063314\" x2=\"7.035924\" y1=\"16.745245\" x1=\"4.968475\"/>\n <line id=\"svg_39\" y2=\"16.888376\" x2=\"9.278311\" y1=\"17.047411\" x1=\"6.733758\"/>\n <line id=\"svg_40\" y2=\"16.284045\" x2=\"10.661911\" y1=\"16.983797\" x1=\"8.992048\"/>\n <line id=\"svg_41\" y2=\"15.313934\" x2=\"11.647925\" y1=\"16.395369\" x1=\"10.455166\"/>\n <line id=\"svg_44\" y2=\"13.898527\" x2=\"12.82478\" y1=\"15.425259\" x1=\"11.504794\"/>\n <line id=\"svg_45\" y2=\"12.037824\" x2=\"14.144766\" y1=\"14.312017\" x1=\"12.522614\"/>\n <line id=\"svg_47\" y2=\"10.59061\" x2=\"14.605966\" y1=\"12.228665\" x1=\"13.953925\"/>\n <ellipse ry=\"1\" rx=\"1\" id=\"svg_48\" cy=\"3.982726\" cx=\"13.460918\"/>\n </g>`,\n viewBox: {\n x: 18,\n y: 18,\n },\n }),\n Length: extend(BASE, {\n iconContent: `<g id=\"length-group\" fill=\"none\" stroke-width=\"1\" stroke=\"{{color}}\" stroke-linecap=\"round\" stroke-linejoin=\"round\">\n <path id=\"length-dashes\" d=\"m22.5,6 -16.5,16.5\" stroke-width=\"3\" stroke-dasharray=\"0.6666,5\" />\n </g>`,\n viewBox: {\n x: 24,\n y: 24,\n },\n }),\n Probe: extend(BASE, {\n iconContent: `<path fill=\"{{color}}\" d=\"M1152 896q0 106-75 181t-181 75-181-75-75-181 75-181 181-75 181 75\n 75 181zm-256-544q-148 0-273 73t-198 198-73 273 73 273 198 198 273 73 273-73\n 198-198 73-273-73-273-198-198-273-73zm768 544q0 209-103 385.5t-279.5\n 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5\n 385.5-103 385.5 103 279.5 279.5 103 385.5z\" />`,\n viewBox: {\n x: 1792,\n y: 1792,\n },\n }),\n RectangleRoi: extend(BASE, {\n iconContent: `<path fill=\"{{color}}\" d=\"M1312 256h-832q-66 0-113 47t-47 113v832q0 66 47\n 113t113 47h832q66 0 113-47t47-113v-832q0-66-47-113t-113-47zm288 160v832q0\n 119-84.5 203.5t-203.5 84.5h-832q-119 0-203.5-84.5t-84.5-203.5v-832q0-119\n 84.5-203.5t203.5-84.5h832q119 0 203.5 84.5t84.5 203.5z\" />`,\n viewBox: {\n x: 1792,\n y: 1792,\n },\n }),\n TextMarker: extend(BASE, {\n iconContent: `<path fill=\"{{color}}\" d=\"M789 559l-170 450q33 0 136.5 2t160.5 2q19 0\n 57-2-87-253-184-452zm-725 1105l2-79q23-7 56-12.5t57-10.5 49.5-14.5 44.5-29\n 31-50.5l237-616 280-724h128q8 14 11 21l205 480q33 78 106 257.5t114 274.5q15\n 34 58 144.5t72 168.5q20 45 35 57 19 15 88 29.5t84 20.5q6 38 6 57 0 5-.5\n 13.5t-.5 12.5q-63 0-190-8t-191-8q-76 0-215 7t-178 8q0-43 4-78l131-28q1 0\n 12.5-2.5t15.5-3.5 14.5-4.5 15-6.5 11-8 9-11\n 2.5-14q0-16-31-96.5t-72-177.5-42-100l-450-2q-26 58-76.5 195.5t-50.5 162.5q0\n 22 14 37.5t43.5 24.5 48.5 13.5 57 8.5 41 4q1 19 1 58 0 9-2 27-58\n 0-174.5-10t-174.5-10q-8 0-26.5 4t-21.5 4q-80 14-188 14z\" />`,\n viewBox: {\n x: 1792,\n y: 1792,\n },\n }),\n Crosshairs: extend(BASE, {\n iconContent: `<path fill=\"{{color}}\" d=\"M1325 1024h-109q-26 0-45-19t-19-45v-128q0-26\n 19-45t45-19h109q-32-108-112.5-188.5t-188.5-112.5v109q0 26-19 45t-45\n 19h-128q-26 0-45-19t-19-45v-109q-108 32-188.5 112.5t-112.5 188.5h109q26\n 0 45 19t19 45v128q0 26-19 45t-45 19h-109q32 108 112.5 188.5t188.5\n 112.5v-109q0-26 19-45t45-19h128q26 0 45 19t19 45v109q108-32\n 188.5-112.5t112.5-188.5zm339-192v128q0 26-19 45t-45 19h-143q-37 161-154.5\n 278.5t-278.5 154.5v143q0 26-19 45t-45 19h-128q-26\n 0-45-19t-19-45v-143q-161-37-278.5-154.5t-154.5-278.5h-143q-26\n 0-45-19t-19-45v-128q0-26 19-45t45-19h143q37-161\n 154.5-278.5t278.5-154.5v-143q0-26 19-45t45-19h128q26 0 45 19t19 45v143q161\n 37 278.5 154.5t154.5 278.5h143q26 0 45 19t19 45z\" />`,\n viewBox: {\n x: 1792,\n y: 1792,\n },\n }),\n Eraser: extend(BASE, {\n iconContent: `<path transform=\"translate(0,1792) scale(1,-1)\" fill=\"{{color}}\" d=\"M960 1408l336-384h-768l-336 384h768zm1013-1077q15\n 34 9.5 71.5t-30.5 65.5l-896 1024q-38 44-96 44h-768q-38\n 0-69.5-20.5t-47.5-54.5q-15-34-9.5-71.5t30.5-65.5l896-1024q38-44 96-44h768q38\n 0 69.5 20.5t47.5 54.5z\" />`,\n viewBox: {\n x: 2048,\n y: 1792,\n },\n }),\n Magnify: extend(BASE, {\n iconContent: `<path fill=\"{{color}}\" d=\"M508.5 481.6l-129-129c-2.3-2.3-5.3-3.5-8.5-3.5h-10.3C395\n 312 416 262.5 416 208 416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c54.5\n 0 104-21 141.1-55.2V371c0 3.2 1.3 6.2 3.5 8.5l129 129c4.7 4.7 12.3 4.7 17\n 0l9.9-9.9c4.7-4.7 4.7-12.3 0-17zM208 384c-97.3 0-176-78.7-176-176S110.7 32 208\n 32s176 78.7 176 176-78.7 176-176 176z\" />`,\n viewBox: {\n x: 512,\n y: 512,\n },\n }),\n Pan: extend(BASE, {\n iconContent: `<path fill=\"{{color}}\" d=\"M1411 541l-355 355 355 355 144-144q29-31 70-14 39 17\n 39 59v448q0 26-19 45t-45 19h-448q-42 0-59-40-17-39 14-69l144-144-355-355-355\n 355 144 144q31 30 14 69-17 40-59 40h-448q-26 0-45-19t-19-45v-448q0-42 40-59\n 39-17 69 14l144 144 355-355-355-355-144 144q-19 19-45 19-12\n 0-24-5-40-17-40-59v-448q0-26 19-45t45-19h448q42 0 59 40 17 39-14 69l-144\n 144 355 355 355-355-144-144q-31-30-14-69 17-40 59-40h448q26 0 45 19t19\n 45v448q0 42-39 59-13 5-25 5-26 0-45-19z\" />`,\n viewBox: {\n x: 1792,\n y: 1792,\n },\n }),\n Rotate: extend(BASE, {\n iconContent: `<path fill=\"{{color}}\" d=\"M1664 256v448q0 26-19 45t-45 19h-448q-42 0-59-40-17-39\n 14-69l138-138q-148-137-349-137-104 0-198.5 40.5t-163.5 109.5-109.5\n 163.5-40.5 198.5 40.5 198.5 109.5 163.5 163.5 109.5 198.5 40.5q119 0\n 225-52t179-147q7-10 23-12 15 0 25 9l137 138q9 8 9.5 20.5t-7.5 22.5q-109\n 132-264 204.5t-327 72.5q-156 0-298-61t-245-164-164-245-61-298 61-298\n 164-245 245-164 298-61q147 0 284.5 55.5t244.5 156.5l130-129q29-31 70-14\n 39 17 39 59z\" />`,\n viewBox: {\n x: 1792,\n y: 1792,\n },\n }),\n StackScroll: extend(BASE, {\n iconContent: `<path fill=\"{{color}}\" d=\"M24 21v2c0 0.547-0.453 1-1 1h-22c-0.547\n 0-1-0.453-1-1v-2c0-0.547 0.453-1 1-1h22c0.547 0 1 0.453 1 1zM24 13v2c0\n 0.547-0.453 1-1 1h-22c-0.547 0-1-0.453-1-1v-2c0-0.547 0.453-1 1-1h22c0.547\n 0 1 0.453 1 1zM24 5v2c0 0.547-0.453 1-1 1h-22c-0.547\n 0-1-0.453-1-1v-2c0-0.547 0.453-1 1-1h22c0.547 0 1 0.453 1 1z\" />`,\n viewBox: {\n x: 24,\n y: 28,\n },\n }),\n WindowLevelRegion: extend(BASE, {\n iconContent: `<path fill=\"{{color}}\" d=\"M1664 416v960q0 119-84.5 203.5t-203.5 84.5h-960q-119\n 0-203.5-84.5t-84.5-203.5v-960q0-119 84.5-203.5t203.5-84.5h960q119 0 203.5\n 84.5t84.5 203.5z\" />`,\n viewBox: {\n x: 1792,\n y: 1792,\n },\n }),\n WindowLevel: extend(BASE, {\n iconContent: `\n <path fill=\"{{color}}\" d=\"M14.5,3.5 a1 1 0 0 1 -11,11 Z\" stroke=\"none\" opacity=\"0.8\" />\n <circle cx=\"9\" cy=\"9\" r=\"8\" fill=\"none\" stroke-width=\"2\" stroke=\"{{color}}\" />`,\n viewBox: {\n x: 18,\n y: 18,\n },\n }),\n Zoom: extend(BASE, {\n iconContent: `\n <path fill=\"{{color}}\" d=\"M508.5 481.6l-129-129c-2.3-2.3-5.3-3.5-8.5-3.5h-10.3C395\n 312 416 262.5 416 208 416 93.1 322.9 0 208 0S0 93.1 0 208s93.1 208 208 208c54.5\n 0 104-21 141.1-55.2V371c0 3.2 1.3 6.2 3.5 8.5l129 129c4.7 4.7 12.3 4.7 17\n 0l9.9-9.9c4.7-4.7 4.7-12.3 0-17zM208 384c-97.3 0-176-78.7-176-176S110.7 32 208\n 32s176 78.7 176 176-78.7 176-176 176z\" />\n <path fill=\"{{color}}\" transform=\"scale(0.22,0.22) translate(1400,0)\" d=\"M1216\n 320q0 26-19 45t-45 19h-128v1024h128q26 0 45 19t19 45-19 45l-256 256q-19\n 19-45 19t-45-19l-256-256q-19-19-19-45t19-45 45-19h128v-1024h-128q-26\n 0-45-19t-19-45 19-45l256-256q19-19 45-19t45 19l256 256q19 19 19 45z\" />`,\n viewBox: {\n x: 640,\n y: 512,\n },\n }),\n\n /*\n * Segmentation Cursors\n */\n\n segmentationFreeHandEraseInside: extend(BASE, {\n iconContent: `${SCISSOR_ICON} ${MINUS_RECT}`,\n viewBox: SEGMENTATION_CURSOR_BOUNDARIES,\n }),\n\n segmentationFreeHandFillInside: extend(BASE, {\n iconContent: `${SCISSOR_ICON} ${PLUS_RECT}`,\n viewBox: SEGMENTATION_CURSOR_BOUNDARIES,\n }),\n\n segmentationFreeHandEraseOutside: extend(BASE, {\n iconContent: `${SCISSOR_ICON} ${MINUS_RECT}`,\n viewBox: SEGMENTATION_CURSOR_BOUNDARIES,\n }),\n\n segmentationFreeHandFillOutside: extend(BASE, {\n iconContent: `${SCISSOR_ICON} ${PLUS_RECT}`,\n viewBox: SEGMENTATION_CURSOR_BOUNDARIES,\n }),\n\n segmentationRectangleEraseInside: extend(BASE, {\n iconContent: `${RECTANGLE_ICON} ${MINUS_RECT}`,\n viewBox: SEGMENTATION_CURSOR_BOUNDARIES,\n }),\n\n // Default Rectangle Scissors\n RectangleScissor: extend(BASE, {\n iconContent: `${RECTANGLE_ICON} ${PLUS_RECT}`,\n viewBox: SEGMENTATION_CURSOR_BOUNDARIES,\n }),\n\n 'RectangleScissor.FILL_INSIDE': extend(BASE, {\n iconContent: `${RECTANGLE_ICON} ${PLUS_RECT}`,\n viewBox: SEGMENTATION_CURSOR_BOUNDARIES,\n }),\n\n 'RectangleScissor.FILL_OUTSIDE': extend(BASE, {\n iconContent: `${RECTANGLE_ICON} ${PLUS_RECT}`,\n viewBox: SEGMENTATION_CURSOR_BOUNDARIES,\n }),\n\n 'RectangleScissor.ERASE_OUTSIDE': extend(BASE, {\n iconContent: `${RECTANGLE_ICON} ${MINUS_RECT}`,\n viewBox: SEGMENTATION_CURSOR_BOUNDARIES,\n }),\n\n 'RectangleScissor.ERASE_INSIDE': extend(BASE, {\n iconContent: `${RECTANGLE_ICON} ${MINUS_RECT}`,\n viewBox: SEGMENTATION_CURSOR_BOUNDARIES,\n }),\n\n CircleScissor: extend(BASE, {\n iconContent: `${CIRCLE_ICON} ${PLUS_RECT}`,\n viewBox: SEGMENTATION_CURSOR_BOUNDARIES,\n }),\n\n 'CircleScissor.FILL_INSIDE': extend(BASE, {\n iconContent: `${CIRCLE_ICON} ${PLUS_RECT}`,\n viewBox: SEGMENTATION_CURSOR_BOUNDARIES,\n }),\n\n 'CircleScissor.ERASE_OUTSIDE': extend(BASE, {\n iconContent: `${CIRCLE_ICON} ${MINUS_RECT}`,\n viewBox: SEGMENTATION_CURSOR_BOUNDARIES,\n }),\n\n 'CircleScissor.FILL_OUTSIDE': extend(BASE, {\n iconContent: `${CIRCLE_ICON} ${PLUS_RECT}`,\n viewBox: SEGMENTATION_CURSOR_BOUNDARIES,\n }),\n}\n\n/*\n * Utils\n */\n\nfunction extend(\n base: SVGCursorDescriptor,\n values: Record<string, unknown>\n): SVGCursorDescriptor {\n return Object.assign(Object.create(base), values)\n}\n\n/**\n * Registers a cursor to the list, so that it will be used for the given `toolName`.\n * Overwrites the given cursor if it is already set.\n *\n * @param toolName - The name of the tool to assign a cursor to.\n * @param iconContent - The SVG icon content of the cursor.\n * @param viewBox - The viewBox of the cursor object.\n */\nfunction registerCursor(\n toolName: string,\n iconContent: string,\n viewBox: { x: number; y: number }\n) {\n DefinedDescriptorsMap[toolName] = extend(BASE, {\n iconContent,\n viewBox,\n })\n}\n\nfunction getDefinedSVGCursorDescriptor(\n name: string\n): SVGCursorDescriptor | undefined {\n if (Object.prototype.hasOwnProperty.call(DefinedDescriptorsMap, name)) {\n return DefinedDescriptorsMap[name]\n }\n}\n\n/*\n * Exports\n */\nconst svgCursorNames = Object.keys(DefinedDescriptorsMap)\n\nexport {\n getDefinedSVGCursorDescriptor,\n registerCursor,\n svgCursorNames,\n}\n","import { ToolModes, AnnotationStyleStates } from '../enums'\nimport { getDefaultStyleProperty } from '../stateManagement/annotation/config/annotationStyle'\nimport MouseCursor from './MouseCursor'\nimport ImageMouseCursor from './ImageMouseCursor'\nimport { getDefinedSVGCursorDescriptor } from './SVGCursorDescriptor'\nimport type { SVGCursorDescriptor } from '../types'\n\nconst PROPERTY = 'color'\nconst STATE = AnnotationStyleStates.Highlighted\nconst MODE = ToolModes.Active\n\nexport default class SVGMouseCursor extends ImageMouseCursor {\n constructor(\n url: string,\n x?: number,\n y?: number,\n name?: string | undefined,\n fallback?: MouseCursor | undefined\n ) {\n super(url, x, y, name, fallback)\n }\n\n /**\n * Get a shared instance of the SVGMouseCursor class satisfying the given parameters.\n *\n * @param name - The name of the cursor (defined in SVGCursorDescriptor.ts);\n * @param pointer - Should be true to use the version of the cursor containing\n * a mouse pointer. Defaults to false (which does not add a pointer to the cursor);\n * @param color - The color of the cursor. Defaults to tool.style.colorHighlightedActive;\n * @returns a SVGMouseCursor instance or\n * undefined if no SVG cursor descriptor was found with the given name;\n */\n static getDefinedCursor(\n name: string,\n pointer = false,\n color?: string\n ): MouseCursor {\n if (!color) {\n color = getDefaultStyleProperty(PROPERTY, STATE, MODE) as string\n }\n const urn = getCursorURN(name, pointer, color)\n let cursor = super.getDefinedCursor(urn)\n if (!cursor) {\n const descriptor = getDefinedSVGCursorDescriptor(name)\n if (descriptor) {\n cursor = createSVGMouseCursor(\n descriptor,\n urn,\n pointer,\n color,\n super.getDefinedCursor('default')\n )\n super.setDefinedCursor(urn, cursor)\n }\n }\n return cursor\n }\n}\n\n/*\n * Helpers\n */\n\nfunction format(template: string, dictionary: Record<string, unknown>): string {\n const dict = Object(dictionary)\n const defined = Object.prototype.hasOwnProperty.bind(dict)\n return (template + '').replace(/\\{\\{(\\w+)\\}\\}/g, (match, key) => {\n return defined(key) ? dict[key] + '' : ''\n })\n}\n\nfunction getCursorURN(name: string, pointer: boolean, color: string) {\n const type = pointer ? 'pointer' : 'cursor'\n return `${type}:${name}/${color}`\n}\n\nfunction createSVGMouseCursor(\n descriptor: SVGCursorDescriptor,\n name: string,\n pointer: boolean,\n color: string,\n fallback: MouseCursor\n): SVGMouseCursor {\n const { x, y } = descriptor.mousePoint\n return new SVGMouseCursor(\n createSVGIconUrl(descriptor, pointer, { color }),\n x,\n y,\n name,\n fallback\n )\n}\n\nfunction createSVGIconUrl(\n descriptor: SVGCursorDescriptor,\n pointer: boolean,\n options: Record<string, unknown>\n): string {\n return URL.createObjectURL(createSVGIconBlob(descriptor, pointer, options))\n}\n\nfunction createSVGIconBlob(\n descriptor: SVGCursorDescriptor,\n pointer: boolean,\n options: Record<string, unknown>\n): Blob {\n const svgString = (pointer ? createSVGIconWithPointer : createSVGIcon)(\n descriptor,\n options\n )\n return new Blob([svgString], { type: 'image/svg+xml' })\n}\n\nfunction createSVGIcon(\n descriptor: SVGCursorDescriptor,\n options: Record<string, unknown>\n): string {\n const { iconContent, iconSize, viewBox } = descriptor\n const svgString = `\n <svg data-icon=\"cursor\" role=\"img\" xmlns=\"http://www.w3.org/2000/svg\"\n width=\"${iconSize}\" height=\"${iconSize}\" viewBox=\"0 0\n ${viewBox.x} ${viewBox.y}\">\n ${iconContent}\n </svg>`\n return format(svgString, options)\n}\n\nfunction createSVGIconWithPointer(\n descriptor: SVGCursorDescriptor,\n options: Record<string, unknown>\n) {\n const { iconContent, iconSize, viewBox, mousePointerGroupString } = descriptor\n const scale = iconSize / Math.max(viewBox.x, viewBox.y, 1)\n const svgSize = 16 + iconSize\n const svgString = `\n <svg data-icon=\"cursor\" role=\"img\" xmlns=\"http://www.w3.org/2000/svg\"\n width=\"${svgSize}\" height=\"${svgSize}\" viewBox=\"0 0 ${svgSize} ${svgSize}\">\n <g>${mousePointerGroupString}</g>\n <g transform=\"translate(16, 16) scale(${scale})\">${iconContent}</g>\n </svg>`\n return format(svgString, options)\n}\n","import { MouseCursor } from '.'\n\nconst ELEMENT_CURSORS_MAP = Symbol('ElementCursorsMap')\n\n/*\n * Public Methods\n */\n\nfunction initElementCursor(\n element: HTMLElement,\n cursor: MouseCursor | null\n): void {\n _getElementCursors(element)[0] = cursor\n _setElementCursor(element, cursor)\n}\n\nfunction _setElementCursor(\n element: HTMLElement,\n cursor: MouseCursor | null\n): void {\n const cursors = _getElementCursors(element)\n cursors[1] = cursors[0]\n cursors[0] = cursor\n element.style.cursor = (\n cursor instanceof MouseCursor\n ? cursor\n : MouseCursor.getDefinedCursor('auto')\n ).getStyleProperty()\n}\n\nfunction resetElementCursor(element: HTMLElement): void {\n _setElementCursor(element, _getElementCursors(element)[1])\n}\n\nfunction hideElementCursor(element: HTMLElement): void {\n _setElementCursor(element, MouseCursor.getDefinedCursor('none'))\n}\n\n/*\n * Helpers\n */\n\nfunction _getElementCursors(\n element: HTMLElement\n): [MouseCursor | null, MouseCursor | null] {\n let map = _getElementCursors[ELEMENT_CURSORS_MAP]\n if (!(map instanceof WeakMap)) {\n map = new WeakMap()\n Object.defineProperty(_getElementCursors, ELEMENT_CURSORS_MAP, {\n value: map,\n })\n }\n let cursors = map.get(element)\n if (!cursors) {\n cursors = [null, null]\n map.set(element, cursors)\n }\n return cursors\n}\n\n/*\n * Exports\n */\nexport {\n initElementCursor,\n resetElementCursor,\n hideElementCursor,\n _setElementCursor as setElementCursor,\n}\n","import { setElementCursor } from './elementCursor'\nimport MouseCursor from './MouseCursor'\nimport SVGMouseCursor from './SVGMouseCursor'\n\n/**\n * Set the cursor for an HTML element. cursorNames can be either\n * cornerstone3DTools cursors or standard cursors.\n *\n * @param element - The element to set the cursor on.\n * @param cursorName - The name of the cursor to set. This can be\n * any cursor name either Cornerstone-specific cursor names or the standard\n * CSS cursor names.\n */\nfunction setCursorForElement(element: HTMLElement, cursorName: string): void {\n let cursor = SVGMouseCursor.getDefinedCursor(cursorName, true)\n if (!cursor) {\n cursor = MouseCursor.getDefinedCursor(cursorName)\n }\n\n if (!cursor) {\n console.log(\n `Cursor ${cursorName} is not defined either as SVG or as a standard cursor.`\n )\n cursor = MouseCursor.getDefinedCursor(cursorName)\n }\n\n setElementCursor(element, cursor)\n}\n\nexport default setCursorForElement\n","import MouseCursor, { standardCursorNames } from './MouseCursor'\nimport ImageMouseCursor from './ImageMouseCursor'\nimport SVGMouseCursor from './SVGMouseCursor'\nimport * as elementCursor from './elementCursor'\nimport setCursorForElement from './setCursorForElement'\nimport { registerCursor, svgCursorNames } from './SVGCursorDescriptor'\n\n// Todo: this should be enum\nconst CursorNames = [...svgCursorNames, ...standardCursorNames]\n\nexport {\n MouseCursor,\n ImageMouseCursor,\n SVGMouseCursor,\n elementCursor,\n registerCursor,\n CursorNames,\n setCursorForElement,\n}\n","import { MouseBindings, ToolModes } from '../../enums'\nimport {\n getRenderingEngine,\n getRenderingEngines,\n} from '@cornerstonejs/core'\nimport { state } from '../index'\nimport { IToolGroup, SetToolBindingsType, ToolOptionsType } from '../../types'\n\nimport { MouseCursor, SVGMouseCursor } from '../../cursors'\nimport { initElementCursor } from '../../cursors/elementCursor'\n\nconst { Active, Passive, Enabled, Disabled } = ToolModes\n\n/**\n * ToolGroup class which is a container for tools and their modes and states.\n * In Cornerstone3DTools, you need to create a tool group in order to use the\n * tools. ToolGroup is a way to share tool configuration, state (enabled, disabled, etc.)\n * across a set of viewports. Tools can set to be activated, enabled or disabled\n * in a toolGroup. You should not directly instantiate a ToolGroup. You need to use\n * ToolGroupManager helpers to create a new toolGroup or get a reference to an existing toolGroup.\n *\n * ```js\n * const toolGroup = csTools.ToolGroupManager.createToolGroup('toolGroupUID')\n * ```\n */\nexport default class ToolGroup implements IToolGroup {\n uid: string\n viewportsInfo = []\n toolOptions = {}\n _toolInstances = {}\n\n constructor(uid: string) {\n this.uid = uid\n }\n\n /**\n * Get the viewport UIDs of all the viewports in the current viewport\n * @returns An array of viewport UIDs.\n */\n getViewportUIDs(): string[] {\n return this.viewportsInfo.map(({ viewportUID }) => viewportUID)\n }\n\n /**\n * Get the tool instance for a given tool name in the toolGroup\n * @param toolName - The name of the tool.\n * @returns A tool instance.\n */\n getToolInstance(toolName: string) {\n const toolInstance = this._toolInstances[toolName]\n if (!toolInstance) {\n console.warn(`'${toolName}' is not registered with this toolGroup.`)\n return\n }\n return toolInstance\n }\n\n /**\n * Add a tool to the tool group with the given tool name and tool configuration.\n * Note that adding a tool to a tool group will not automatically set the tool\n * to be active. You must call setToolActive or setToolPassive and other methods\n * to set the tool to be active or passive or in other states.\n *\n * @param toolName - string\n * @param configuration - Tool configuration objects\n */\n addTool(toolName: string, configuration = {}): void {\n const toolDefinition = state.tools[toolName]\n const hasToolName = typeof toolName !== 'undefined' && toolName !== ''\n const localToolInstance = this.toolOptions[toolName]\n\n if (!hasToolName) {\n console.warn(\n 'Tool with configuration did not produce a toolName: ',\n configuration\n )\n return\n }\n\n if (!toolDefinition) {\n console.warn(`'${toolName}' is not registered with the library.`)\n return\n }\n\n if (localToolInstance) {\n console.warn(\n `'${toolName}' is already registered for ToolGroup ${this.uid}.`\n )\n return\n }\n\n // Should these be renamed higher up, so we don't have to alias?\n // Wrap in try-catch so 3rd party tools don't explode?\n const { toolClass: ToolClass } = toolDefinition\n\n const toolProps = {\n name: toolName,\n toolGroupUID: this.uid,\n configuration,\n }\n\n const instantiatedTool = new ToolClass(toolProps)\n\n // API instead of directly exposing schema?\n // Maybe not here, but feels like a \"must\" for any method outside of the ToolGroup itself\n this._toolInstances[toolName] = instantiatedTool\n }\n\n /**\n * Add a viewport to the ToolGroup. It accepts viewportUID and optional\n * renderingEngineUID parameter. If renderingEngineUID is not provided,\n * it checks if cornerstone-core has more than one renderingEngine; If so,\n * it will throw an error. If cornerstone-core has only one renderingEngine,\n * it will use that renderingEngine.\n *\n * @param viewportUID - The unique identifier for the viewport.\n * @param renderingEngineUID - The rendering engine to use.\n */\n addViewport(viewportUID: string, renderingEngineUID?: string): void {\n const renderingEngines = getRenderingEngines()\n\n if (!renderingEngineUID && renderingEngines.length > 1) {\n throw new Error(\n 'You must specify a renderingEngineUID when there are multiple rendering engines.'\n )\n }\n\n const renderingEngineUIDToUse =\n renderingEngineUID || renderingEngines[0].uid\n\n this.viewportsInfo.push({\n viewportUID,\n renderingEngineUID: renderingEngineUIDToUse,\n })\n }\n\n /**\n * Removes viewport from the toolGroup. If only renderingEngineUID is defined\n * it removes all the viewports with the same renderingEngineUID, if viewportUID\n * is also provided, it will remove that specific viewport from the ToolGroup.\n *\n * @param renderingEngineUID - renderingEngine uid\n * @param viewportUID - viewport uid\n */\n removeViewports(renderingEngineUID: string, viewportUID?: string): void {\n const indices = []\n\n this.viewportsInfo.forEach((vpInfo, index) => {\n let match = false\n if (vpInfo.renderingEngineUID === renderingEngineUID) {\n match = true\n\n if (viewportUID && vpInfo.viewportUID !== viewportUID) {\n match = false\n }\n }\n if (match) {\n indices.push(index)\n }\n })\n\n if (indices.length) {\n // going in reverse to not wrongly choose the indexes to be removed\n for (let i = indices.length - 1; i >= 0; i--) {\n this.viewportsInfo.splice(indices[i], 1)\n }\n }\n }\n\n /**\n * Set the tool mode on the toolGroup to be Active. This means the tool\n * can be actively used by the defined bindings (e.g., Mouse primary click)\n *\n * - Can be actively used by mouse/touch events mapped to its `ToolBinding`s.\n * - Can add data if an annotation tool.\n * - Can be passively interacted by grabbing a tool or its handles.\n * - Renders data if the tool has a `renderAnnotation` method.\n *\n * @param toolName - tool name\n * @param toolBindingsOptions - tool bindings\n */\n setToolActive(\n toolName: string,\n toolBindingsOptions = {} as SetToolBindingsType\n ): void {\n if (this._toolInstances[toolName] === undefined) {\n console.warn(\n `Tool ${toolName} not added to toolGroup, can't set tool mode.`\n )\n\n return\n }\n\n const prevBindings = this.toolOptions[toolName]\n ? this.toolOptions[toolName].bindings\n : []\n\n const newBindings = toolBindingsOptions.bindings\n ? toolBindingsOptions.bindings\n : []\n\n // We should not override the bindings if they are already set\n const toolOptions: ToolOptionsType = {\n bindings: [...prevBindings, ...newBindings],\n mode: Active,\n }\n\n this.toolOptions[toolName] = toolOptions\n this._toolInstances[toolName].mode = Active\n\n // reset the mouse cursor if tool has left click binding\n if (this._hasMousePrimaryButtonBinding(toolBindingsOptions)) {\n this.setViewportsCursorByToolName(toolName)\n }\n\n if (typeof this._toolInstances[toolName].init === 'function') {\n this._toolInstances[toolName].init(this.viewportsInfo)\n }\n this._renderViewports()\n }\n\n /**\n * Set the tool mode on the toolGroup to be Passive.\n *\n * - Can be passively interacted by grabbing a tool or its handles.\n * - Renders data if the tool has a `renderAnnotation` method.\n *\n * @param toolName - tool name\n */\n setToolPassive(toolName: string): void {\n if (this._toolInstances[toolName] === undefined) {\n console.warn(\n `Tool ${toolName} not added to toolGroup, can't set tool mode.`\n )\n\n return\n }\n\n // Wwe should only remove the primary button bindings and keep\n // the other ones (Zoom on right click)\n const prevToolOptions = this.getToolOptions(toolName)\n const toolOptions = Object.assign(\n {\n bindings: prevToolOptions ? prevToolOptions.bindings : [],\n },\n prevToolOptions,\n {\n mode: Passive,\n }\n )\n\n // Remove the primary button bindings if they exist\n toolOptions.bindings = toolOptions.bindings.filter(\n (binding) => binding.mouseButton !== MouseBindings.Primary\n )\n\n // If there are other bindings, set the tool to be active\n let mode = Passive\n if (toolOptions.bindings.length !== 0) {\n mode = Active\n toolOptions.mode = mode\n }\n\n this.toolOptions[toolName] = toolOptions\n this._toolInstances[toolName].mode = mode\n this._renderViewports()\n }\n\n /**\n * Set the tool mode on the toolGroup to be Enabled.\n *\n * - Renders data if the tool has a `renderAnnotation` method..\n *\n * @param toolName - tool name\n */\n setToolEnabled(toolName: string): void {\n if (this._toolInstances[toolName] === undefined) {\n console.warn(\n `Tool ${toolName} not added to toolGroup, can't set tool mode.`\n )\n\n return\n }\n\n const toolOptions = {\n bindings: [],\n mode: Enabled,\n }\n\n this.toolOptions[toolName] = toolOptions\n this._toolInstances[toolName].mode = Enabled\n\n if (this._toolInstances[toolName].enableCallback) {\n this._toolInstances[toolName].enableCallback(this.uid)\n }\n\n this._renderViewports()\n }\n\n /**\n * Set the tool mode on the toolGroup to be Disabled.\n *\n * - Annotation does not render.\n *\n * @param toolName - tool name\n */\n setToolDisabled(toolName: string): void {\n if (this._toolInstances[toolName] === undefined) {\n console.warn(\n `Tool ${toolName} not added to toolGroup, can't set tool mode.`\n )\n return\n }\n\n // Would only need this for sanity check if not instantiating/hydrating\n // const tool = this.toolOptions[toolName];\n const toolOptions = {\n bindings: [],\n mode: Disabled,\n }\n\n this.toolOptions[toolName] = toolOptions\n this._toolInstances[toolName].mode = Disabled\n\n if (this._toolInstances[toolName].disableCallback) {\n this._toolInstances[toolName].disableCallback(this.uid)\n }\n this._renderViewports()\n }\n\n /**\n * Get the options for a given tool\n * @param toolName - The name of the tool.\n * @returns the tool options\n */\n getToolOptions(toolName: string): ToolOptionsType {\n return this.toolOptions[toolName]\n }\n\n /**\n * Find the name of the tool that is Active and has a primary button binding\n * (Mouse primary click)\n *\n * @returns The name of the tool\n */\n getActivePrimaryMouseButtonTool(): string {\n return Object.keys(this.toolOptions).find((toolName) => {\n const toolOptions = this.toolOptions[toolName]\n return (\n toolOptions.mode === Active &&\n this._hasMousePrimaryButtonBinding(toolOptions)\n )\n })\n }\n\n /**\n * Set the cursor of all viewports of the toolGroup to the cursor defined by the\n * provided toolName and its strategy (if any).\n * @param toolName - The name of the tool.\n * @param strategyName - The name of the strategy if exists. For segmentation tools\n * for example the strategy can be FILL_INSIDE or FILL_OUTSIDE\n */\n setViewportsCursorByToolName(toolName: string, strategyName?: string): void {\n const cursorName = strategyName ? `${toolName}.${strategyName}` : toolName\n let cursor = SVGMouseCursor.getDefinedCursor(cursorName, true)\n if (!cursor) {\n cursor = MouseCursor.getDefinedCursor('default')\n }\n this.viewportsInfo.forEach(({ renderingEngineUID, viewportUID }) => {\n const viewport =\n getRenderingEngine(renderingEngineUID).getViewport(viewportUID)\n if (viewport && viewport.element) {\n initElementCursor(viewport.element, cursor)\n }\n })\n }\n\n /**\n * Check if the tool binding is set to be primary mouse button.\n * @param toolOptions - The options for the tool mode.\n * @returns A boolean value.\n */\n private _hasMousePrimaryButtonBinding(toolOptions) {\n return toolOptions?.bindings?.some(\n (binding) =>\n binding.mouseButton === MouseBindings.Primary &&\n binding.modifierKey === undefined\n )\n }\n\n /**\n * It re-renders the viewports in the toolGroup\n */\n private _renderViewports(): void {\n this.viewportsInfo.forEach(({ renderingEngineUID, viewportUID }) => {\n getRenderingEngine(renderingEngineUID).renderViewport(viewportUID)\n })\n }\n}\n","import { state } from '../index'\nimport ToolGroup from './ToolGroup'\nimport { IToolGroup } from '../../types'\n\n/**\n * Create a new tool group with the given name. ToolGroups are the new way\n * in Cornerstone3DTools to share tool configuration, state (enabled, disabled, etc.)\n * across a set of viewports.\n *\n * @param toolGroupUID - The unique ID of the tool group.\n * @returns A reference to the tool group that was created.\n */\nfunction createToolGroup(toolGroupUID: string): IToolGroup | undefined {\n // Exit early if ID conflict\n const toolGroupWithIdExists = state.toolGroups.some(\n (tg) => tg.uid === toolGroupUID\n )\n\n if (toolGroupWithIdExists) {\n console.warn(`'${toolGroupUID}' already exists.`)\n return\n }\n\n const toolGroup = new ToolGroup(toolGroupUID)\n\n // Update state\n state.toolGroups.push(toolGroup)\n\n // Return reference\n return toolGroup\n}\n\nexport default createToolGroup\n","import { state } from '../index'\nimport { removeSegmentationsFromToolGroup } from '../../stateManagement/segmentation'\n\n// ToolGroups function entirely by their \"state\" being queried and leveraged\n// removing a ToolGroup from state is equivalent to killing it\n\n/**\n * Given a tool group UID, destroy the toolGroup. It will also cleanup all segmentations\n * associated with that tool group too\n *\n * @param toolGroupUID - The UID of the tool group to be destroyed.\n */\nfunction destroyToolGroupByToolGroupUID(toolGroupUID: string): void {\n const toolGroupIndex = state.toolGroups.findIndex(\n (tg) => tg.uid === toolGroupUID\n )\n\n if (toolGroupIndex > -1) {\n // Todo: this should not happen here)\n removeSegmentationsFromToolGroup(toolGroupUID)\n state.toolGroups.splice(toolGroupIndex, 1)\n }\n}\n\nexport default destroyToolGroupByToolGroupUID\n","// `BaseManager` or IManager interface for duplicate API between ToolGroup/Synchronizer?\nimport { state as csToolsState } from '../index'\nimport destroyToolGroupByToolGroupUID from './destroyToolGroupByToolGroupUID'\n\n// ToolGroups function entirely by their \"state\" being queried and leveraged\n// removing a ToolGroup from state is equivalent to killing it. Calling\n// destroyToolGroupByToolGroupUID() to make sure the SegmentationDisplayTools\n// have been removed from the toolGroup Viewports. //Todo: this makes more sense\n// to be based on events, but we don't have any toolGroup created/removed events\n\n/**\n * Destroy all tool groups\n */\nfunction destroy(): void {\n const toolGroups = [...csToolsState.toolGroups]\n\n for (const toolGroup of toolGroups) {\n destroyToolGroupByToolGroupUID(toolGroup.uid)\n }\n\n csToolsState.toolGroups = []\n}\n\nexport default destroy\n","import { state } from '../index'\nimport { IToolGroup } from '../../types'\n\n/**\n * Given a tool group UID, return the tool group\n * @param toolGroupUID - The UID of the tool group to be retrieved.\n * @returns The tool group that has the same uid as the tool group uid that was\n * passed in.\n */\nfunction getToolGroupByToolGroupUID(\n toolGroupUID: string\n): IToolGroup | undefined {\n return state.toolGroups.find((s) => s.uid === toolGroupUID)\n}\n\nexport default getToolGroupByToolGroupUID\n","import { state } from '../index'\nimport { IToolGroup } from '../../types'\n\n/**\n * Return the array of tool groups\n * @returns An array of tool groups.\n */\nfunction getAllToolGroups(): Array<IToolGroup> {\n return state.toolGroups\n}\n\nexport default getAllToolGroups\n","import createToolGroup from './createToolGroup'\nimport destroyToolGroupByToolGroupUID from './destroyToolGroupByToolGroupUID'\nimport destroy from './destroy'\nimport getToolGroupByToolGroupUID from './getToolGroupByToolGroupUID'\nimport getToolGroup from './getToolGroup'\nimport getAllToolGroups from './getAllToolGroups'\n\nexport default {\n createToolGroup,\n destroy,\n destroyToolGroupByToolGroupUID,\n getToolGroupByToolGroupUID,\n getToolGroup,\n getAllToolGroups,\n}\n\nexport {\n createToolGroup,\n destroy,\n destroyToolGroupByToolGroupUID,\n getToolGroupByToolGroupUID,\n getToolGroup,\n getAllToolGroups,\n}\n","import { getEnabledElement } from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\n\nimport { AnnotationTool, BaseTool } from '../tools'\nimport { Annotation } from '../types'\nimport { getAnnotations } from '../stateManagement/annotation/annotationState'\nimport ToolGroupManager from '../store/ToolGroupManager'\n\n/**\n * Get the annotation that is close to the provided canvas point, it will return\n * the first annotation that is found.\n *\n * @param element - The element to search for an annotation on.\n * @param canvasPoint - The canvasPoint on the page where the user clicked.\n * @param proximity - The distance from the canvasPoint to the annotation.\n * @returns The annotation for the element\n */\nfunction getAnnotationNearPoint(\n element: HTMLElement,\n canvasPoint: Types.Point2,\n proximity = 5\n): Annotation | null {\n // Todo: this function should return closest annotation, BUT, we are not using\n // the function anywhere.\n const enabledElement = getEnabledElement(element)\n if (!enabledElement) {\n throw new Error('getAnnotationNearPoint: enabledElement not found')\n }\n\n return getAnnotationNearPointOnEnabledElement(\n enabledElement,\n canvasPoint,\n proximity\n )\n}\n\n/**\n * \"Find the annotation near the point on the enabled element.\" it will return the\n * first annotation that is found.\n *\n * @param enabledElement - The element that is currently active.\n * @param point - The point to search near.\n * @param proximity - The distance from the point that the annotation must\n * be within.\n * @returns A Annotation object.\n */\nfunction getAnnotationNearPointOnEnabledElement(\n enabledElement: Types.IEnabledElement,\n point: Types.Point2,\n proximity: number\n): Annotation | null {\n // Todo: this function should return closest annotation, BUT, we are not using\n // the function anywhere.\n const { renderingEngineUID, viewportUID } = enabledElement\n const toolGroup = ToolGroupManager.getToolGroup(\n viewportUID,\n renderingEngineUID\n )\n\n if (!toolGroup) {\n return null\n }\n\n const { _toolInstances: tools } = toolGroup\n for (const name in tools) {\n const found = findAnnotationNearPointByTool(\n tools[name],\n enabledElement,\n point,\n proximity\n )\n if (found) {\n return found\n }\n }\n\n return null\n}\n\n/**\n * For the provided toolClass, it will find the annotation that is near the point,\n * it will return the first annotation that is found.\n *\n * @param tool - AnnotationTool\n * @param enabledElement - The element that is currently active.\n * @param point - The point in the image where the user clicked.\n * @param proximity - The distance from the point that the tool must be\n * within to be considered \"near\" the point.\n * @returns The annotation object that is being returned is the annotation object that\n * is being used in the tool.\n */\nfunction findAnnotationNearPointByTool(\n tool: AnnotationTool,\n enabledElement: Types.IEnabledElement,\n point: Types.Point2,\n proximity: number\n): Annotation | null {\n // Todo: this function does not return closest annotation. It just returns\n // the first annotation that is found in the proximity. BUT, we are not using\n // the function anywhere.\n const annotations = getAnnotations(\n enabledElement.viewport.element,\n (tool.constructor as typeof BaseTool).toolName\n )\n if (annotations?.length) {\n const { element } = enabledElement.viewport\n for (const annotation of annotations) {\n if (\n tool.isPointNearTool(element, annotation, point, proximity, '') ||\n tool.getHandleNearImagePoint(element, annotation, point, proximity)\n ) {\n return annotation\n }\n }\n }\n return null\n}\n\nexport { getAnnotationNearPoint, getAnnotationNearPointOnEnabledElement }\n","/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @since 0.1.0\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * isObject({})\n * // => true\n *\n * isObject([1, 2, 3])\n * // => true\n *\n * isObject(Function)\n * // => true\n *\n * isObject(null)\n * // => false\n */\nfunction isObject(value) {\n const type = typeof value\n\n return value !== null && (type === 'object' || type === 'function')\n}\n\nexport default isObject\n","import isObject from './isObject'\n\n/**\n * Creates a debounced function that delays invoking `func` until after `wait`\n * milliseconds have elapsed since the last time the debounced function was\n * invoked, or until the next browser frame is drawn. The debounced function\n * comes with a `cancel` method to cancel delayed `func` invocations and a\n * `flush` method to immediately invoke them. Provide `options` to indicate\n * whether `func` should be invoked on the leading and/or trailing edge of the\n * `wait` timeout. The `func` is invoked with the last arguments provided to the\n * debounced function. Subsequent calls to the debounced function return the\n * result of the last `func` invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is\n * invoked on the trailing edge of the timeout only if the debounced function\n * is invoked more than once during the `wait` timeout.\n *\n * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n * until the next tick, similar to `setTimeout` with a timeout of `0`.\n *\n * If `wait` is omitted in an environment with `requestAnimationFrame`, `func`\n * invocation will be deferred until the next frame is drawn (typically about\n * 16ms).\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `debounce` and `throttle`.\n *\n * @param {Function} func The function to debounce.\n * @param {number} [wait=0]\n * The number of milliseconds to delay; if omitted, `requestAnimationFrame` is\n * used (if available).\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=false]\n * Specify invoking on the leading edge of the timeout.\n * @param {number} [options.maxWait]\n * The maximum time `func` is allowed to be delayed before it's invoked.\n * @param {boolean} [options.trailing=true]\n * Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new debounced function.\n * @example\n *\n * // Avoid costly calculations while the window size is in flux.\n * jQuery(window).on('resize', debounce(calculateLayout, 150))\n *\n * // Invoke `sendMail` when clicked, debouncing subsequent calls.\n * jQuery(element).on('click', debounce(sendMail, 300, {\n * 'leading': true,\n * 'trailing': false\n * }))\n *\n * // Ensure `batchLog` is invoked once after 1 second of debounced calls.\n * const debounced = debounce(batchLog, 250, { 'maxWait': 1000 })\n * const source = new EventSource('/stream')\n * jQuery(source).on('message', debounced)\n *\n * // Cancel the trailing debounced invocation.\n * jQuery(window).on('popstate', debounced.cancel)\n *\n * // Check for pending invocations.\n * const status = debounced.pending() ? \"Pending...\" : \"Ready\"\n */\nfunction debounce(func, wait, options) {\n let lastArgs, lastThis, maxWait, result, timerId, lastCallTime\n\n let lastInvokeTime = 0\n let leading = false\n let maxing = false\n let trailing = true\n\n // Bypass `requestAnimationFrame` by explicitly setting `wait=0`.\n const useRAF =\n !wait && wait !== 0 && typeof window.requestAnimationFrame === 'function'\n\n if (typeof func !== 'function') {\n throw new TypeError('Expected a function')\n }\n wait = Number(wait) || 0\n if (isObject(options)) {\n leading = Boolean(options.leading)\n maxing = 'maxWait' in options\n maxWait = maxing ? Math.max(Number(options.maxWait) || 0, wait) : maxWait\n trailing = 'trailing' in options ? Boolean(options.trailing) : trailing\n }\n\n function invokeFunc(time) {\n const args = lastArgs\n const thisArg = lastThis\n\n lastArgs = lastThis = undefined\n lastInvokeTime = time\n result = func.apply(thisArg, args)\n\n return result\n }\n\n function startTimer(pendingFunc, wait) {\n if (useRAF) {\n return window.requestAnimationFrame(pendingFunc)\n }\n\n return setTimeout(pendingFunc, wait)\n }\n\n function cancelTimer(id) {\n if (useRAF) {\n return window.cancelAnimationFrame(id)\n }\n clearTimeout(id)\n }\n\n function leadingEdge(time) {\n // Reset any `maxWait` timer.\n lastInvokeTime = time\n // Start the timer for the trailing edge.\n timerId = startTimer(timerExpired, wait)\n\n // Invoke the leading edge.\n return leading ? invokeFunc(time) : result\n }\n\n function remainingWait(time) {\n const timeSinceLastCall = time - lastCallTime\n const timeSinceLastInvoke = time - lastInvokeTime\n const timeWaiting = wait - timeSinceLastCall\n\n return maxing\n ? Math.min(timeWaiting, maxWait - timeSinceLastInvoke)\n : timeWaiting\n }\n\n function shouldInvoke(time) {\n const timeSinceLastCall = time - lastCallTime\n const timeSinceLastInvoke = time - lastInvokeTime\n\n // Either this is the first call, activity has stopped and we're at the\n // trailing edge, the system time has gone backwards and we're treating\n // it as the trailing edge, or we've hit the `maxWait` limit.\n return (\n lastCallTime === undefined ||\n timeSinceLastCall >= wait ||\n timeSinceLastCall < 0 ||\n (maxing && timeSinceLastInvoke >= maxWait)\n )\n }\n\n function timerExpired() {\n const time = Date.now()\n\n if (shouldInvoke(time)) {\n return trailingEdge(time)\n }\n // Restart the timer.\n timerId = startTimer(timerExpired, remainingWait(time))\n }\n\n function trailingEdge(time) {\n timerId = undefined\n\n // Only invoke if we have `lastArgs` which means `func` has been\n // debounced at least once.\n if (trailing && lastArgs) {\n return invokeFunc(time)\n }\n lastArgs = lastThis = undefined\n\n return result\n }\n\n function cancel() {\n if (timerId !== undefined) {\n cancelTimer(timerId)\n }\n lastInvokeTime = 0\n lastArgs = lastCallTime = lastThis = timerId = undefined\n }\n\n function flush() {\n return timerId === undefined ? result : trailingEdge(Date.now())\n }\n\n function pending() {\n return timerId !== undefined\n }\n\n function debounced(...args) {\n const time = Date.now()\n const isInvoking = shouldInvoke(time)\n\n lastArgs = args\n lastThis = this // eslint-disable-line consistent-this\n lastCallTime = time\n\n if (isInvoking) {\n if (timerId === undefined) {\n return leadingEdge(lastCallTime)\n }\n if (maxing) {\n // Handle invocations in a tight loop.\n timerId = startTimer(timerExpired, wait)\n\n return invokeFunc(lastCallTime)\n }\n }\n if (timerId === undefined) {\n timerId = startTimer(timerExpired, wait)\n }\n\n return result\n }\n debounced.cancel = cancel\n debounced.flush = flush\n debounced.pending = pending\n\n return debounced\n}\n\nexport default debounce\n","import debounce from './debounce'\nimport isObject from './isObject'\n\n/**\n * Creates a throttled function that only invokes `func` at most once per\n * every `wait` milliseconds (or once per browser frame). The throttled function\n * comes with a `cancel` method to cancel delayed `func` invocations and a\n * `flush` method to immediately invoke them. Provide `options` to indicate\n * whether `func` should be invoked on the leading and/or trailing edge of the\n * `wait` timeout. The `func` is invoked with the last arguments provided to the\n * throttled function. Subsequent calls to the throttled function return the\n * result of the last `func` invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is\n * invoked on the trailing edge of the timeout only if the throttled function\n * is invoked more than once during the `wait` timeout.\n *\n * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred\n * until the next tick, similar to `setTimeout` with a timeout of `0`.\n *\n * If `wait` is omitted in an environment with `requestAnimationFrame`, `func`\n * invocation will be deferred until the next frame is drawn (typically about\n * 16ms).\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `throttle` and `debounce`.\n *\n * @param {Function} func The function to throttle.\n * @param {number} [wait=0]\n * The number of milliseconds to throttle invocations to; if omitted,\n * `requestAnimationFrame` is used (if available).\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=true]\n * Specify invoking on the leading edge of the timeout.\n * @param {boolean} [options.trailing=true]\n * Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new throttled function.\n * @example\n *\n * // Avoid excessively updating the position while scrolling.\n * jQuery(window).on('scroll', throttle(updatePosition, 100))\n *\n * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.\n * const throttled = throttle(renewToken, 300000, { 'trailing': false })\n * jQuery(element).on('click', throttled)\n *\n * // Cancel the trailing throttled invocation.\n * jQuery(window).on('popstate', throttled.cancel)\n */\nfunction throttle(func, wait, options) {\n let leading = true\n let trailing = true\n\n if (typeof func !== 'function') {\n throw new TypeError('Expected a function')\n }\n if (isObject(options)) {\n leading = 'leading' in options ? Boolean(options.leading) : leading\n trailing = 'trailing' in options ? Boolean(options.trailing) : trailing\n }\n\n return debounce(func, wait, {\n leading,\n trailing,\n maxWait: wait,\n })\n}\n\nexport default throttle\n","import { utilities } from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\n\nconst { calibratedPixelSpacingMetadataProvider } = utilities\n\n/**\n * It adds the provided spacing to the Cornerstone internal calibratedPixelSpacing\n * metadata provider, then it invalidates all the tools that have the imageId as\n * their reference imageIds. Finally, it triggers a re-render for invalidated annotations.\n * @param imageId - ImageId for the calibrated image\n * @param rowPixelSpacing - Spacing in row direction\n * @param columnPixelSpacing - Spacing in column direction\n * @param renderingEngine - Cornerstone RenderingEngine instance\n */\nexport default function calibrateImageSpacing(\n imageId: string,\n renderingEngine: Types.IRenderingEngine,\n rowPixelSpacing: number,\n columnPixelSpacing: number\n): void {\n // 1. Add the calibratedPixelSpacing metadata to the metadata provider\n // If no column spacing provided, assume square pixels\n if (!columnPixelSpacing) {\n columnPixelSpacing = rowPixelSpacing\n }\n\n calibratedPixelSpacingMetadataProvider.add(imageId, [\n rowPixelSpacing,\n columnPixelSpacing,\n ])\n\n // 2. Update the actor for stackViewports\n const viewports = renderingEngine.getStackViewports()\n\n // 2.1 If imageId is already being used in a stackViewport -> update actor\n viewports.forEach((viewport) => {\n const imageIds = viewport.getImageIds()\n if (imageIds.includes(imageId)) {\n viewport.calibrateSpacing(imageId)\n }\n })\n\n // 2.2 If imageId is cached but not being displayed in a viewport, stackViewport\n // will handle using the calibratedPixelSpacing since it has been added\n // to the provider\n}\n","/**\n * Given an imageData object and a point in physical space, return the index of the\n * voxel that contains the point. TODO: this should be pushed to vtk upstream.\n * @param imageData - The image data object.\n * @param physicalPoint - The point in physical space that you want to transform to\n * index space.\n * @returns An array of integers.\n */\nexport default function transformPhysicalToIndex(imageData, physicalPoint) {\n const continuousIndex = imageData.worldToIndex(physicalPoint)\n const index = continuousIndex.map(Math.round)\n\n return index\n}\n","import { vec3 } from 'gl-matrix'\nimport type { Types } from '@cornerstonejs/core'\nimport type { vtkImageData } from 'vtk.js/Sources/Common/DataModel/ImageData'\n\nexport type PointInShapeCallback = ({\n value,\n index,\n pointIJK,\n pointLPS,\n}: {\n value: number\n index: number\n pointIJK: Types.Point3\n pointLPS: Types.Point3\n}) => void\n\nexport type ShapeFnCriteria = (\n pointIJK: Types.Point3,\n pointLPS: Types.Point3\n) => boolean\n\ntype BoundsIJK = [Types.Point2, Types.Point2, Types.Point2]\n\n/**\n * For each point in the image (If boundsIJK is not provided, otherwise, for each\n * point in the provided bounding box), It runs the provided callback IF the point\n * passes the provided criteria to be inside the shape (which is defined by the\n * provided pointInShapeFn)\n *\n * @param imageData - The image data object.\n * @param dimensions - The dimensions of the image.\n * @param pointInShapeFn - A function that takes a point in LPS space and returns\n * true if the point is in the shape and false if it is not.\n * @param callback - A function that will be called for\n * every point in the shape.\n * @param boundsIJK - The bounds of the volume in IJK coordinates.\n */\nexport default function pointInShapeCallback(\n imageData: vtkImageData | Types.CPUImageData,\n pointInShapeFn: ShapeFnCriteria,\n callback: PointInShapeCallback,\n boundsIJK?: BoundsIJK\n): void {\n let iMin, iMax, jMin, jMax, kMin, kMax\n\n let scalarData\n\n // if getScalarData is a method on imageData\n if ((imageData as Types.CPUImageData).getScalarData) {\n scalarData = (imageData as Types.CPUImageData).getScalarData()\n } else {\n scalarData = (imageData as vtkImageData)\n .getPointData()\n .getScalars()\n .getData()\n }\n\n const dimensions = imageData.getDimensions()\n\n if (!boundsIJK) {\n iMin = 0\n iMax = dimensions[0]\n jMin = 0\n jMax = dimensions[1]\n kMin = 0\n kMax = dimensions[2]\n } else {\n ;[[iMin, iMax], [jMin, jMax], [kMin, kMax]] = boundsIJK\n }\n\n const start = vec3.fromValues(iMin, jMin, kMin)\n\n const direction = imageData.getDirection()\n const rowCosines = direction.slice(0, 3)\n const columnCosines = direction.slice(3, 6)\n const scanAxisNormal = direction.slice(6, 9)\n\n const spacing = imageData.getSpacing()\n const [rowSpacing, columnSpacing, scanAxisSpacing] = spacing\n\n // @ts-ignore will be fixed in vtk-master\n const worldPosStart = imageData.indexToWorld(start)\n\n const rowStep = vec3.fromValues(\n rowCosines[0] * rowSpacing,\n rowCosines[1] * rowSpacing,\n rowCosines[2] * rowSpacing\n )\n\n const columnStep = vec3.fromValues(\n columnCosines[0] * columnSpacing,\n columnCosines[1] * columnSpacing,\n columnCosines[2] * columnSpacing\n )\n\n const scanAxisStep = vec3.fromValues(\n scanAxisNormal[0] * scanAxisSpacing,\n scanAxisNormal[1] * scanAxisSpacing,\n scanAxisNormal[2] * scanAxisSpacing\n )\n\n const yMultiple = dimensions[0]\n const zMultiple = dimensions[0] * dimensions[1]\n\n for (let k = kMin; k <= kMax; k++) {\n for (let j = jMin; j <= jMax; j++) {\n for (let i = iMin; i <= iMax; i++) {\n const pointIJK: Types.Point3 = [i, j, k]\n const dI = i - iMin\n const dJ = j - jMin\n const dK = k - kMin\n\n const startWorld = worldPosStart\n\n const pointLPS: Types.Point3 = [\n startWorld[0] +\n dI * rowStep[0] +\n dJ * columnStep[0] +\n dK * scanAxisStep[0],\n startWorld[1] +\n dI * rowStep[1] +\n dJ * columnStep[1] +\n dK * scanAxisStep[1],\n startWorld[2] +\n dI * rowStep[2] +\n dJ * columnStep[2] +\n dK * scanAxisStep[2],\n ]\n\n if (pointInShapeFn(pointLPS, pointIJK)) {\n const index = k * zMultiple + j * yMultiple + i\n const value = scalarData[index]\n\n callback({ value, index, pointIJK, pointLPS })\n }\n }\n }\n }\n}\n","import type { Types } from '@cornerstonejs/core'\n\nimport type { vtkImageData } from 'vtk.js/Sources/Common/DataModel/ImageData'\nimport { vec3 } from 'gl-matrix'\nimport { pointInSphere } from './math/sphere'\nimport { getBoundingBoxAroundShape } from './segmentation/getBoundingBoxUtils'\nimport pointInShapeCallback, {\n PointInShapeCallback,\n} from './pointInShapeCallback'\nimport transformPhysicalToIndex from './transformPhysicalToIndex'\n\n// Todo: I *think* this can be done without the need to access viewport's camera\n// since sphere's center circle can be in any plane as long as its center\n// is the center of the sphere ..\n\n/**\n * Given a viewport, an imageData, and a circle points in the viewport, it will\n * run the callback for each point in sphere whose great circle (biggest circle\n * that can be drawn chopping a sphere) is the provided circle points.\n *\n * @param viewport - VolumeViewport\n * @param imageData - The volume imageData\n * @param circlePoints - [Types.Point3, Types.Point3]\n * @param callback - A callback function that will be called for each point in the shape.\n */\nexport default function pointInSurroundingSphereCallback(\n viewport: Types.IVolumeViewport,\n imageData: vtkImageData,\n circlePoints: [Types.Point3, Types.Point3],\n callback: PointInShapeCallback\n): void {\n const dimensions = imageData.getDimensions() as Types.Point3\n const camera = viewport.getCamera()\n\n // Calculate viewRight from the camera, this will get used in order to\n // calculate circles topLeft and bottomRight on different planes of intersection\n // between sphere and viewPlane\n const viewUp = vec3.fromValues(\n camera.viewUp[0],\n camera.viewUp[1],\n camera.viewUp[2]\n )\n const viewPlaneNormal = vec3.fromValues(\n camera.viewPlaneNormal[0],\n camera.viewPlaneNormal[1],\n camera.viewPlaneNormal[2]\n )\n let viewRight = vec3.create()\n\n vec3.cross(viewRight, viewUp, viewPlaneNormal)\n viewRight = [-viewRight[0], -viewRight[1], -viewRight[2]]\n\n const [bottom, top] = circlePoints\n\n // Put the sphere's center on the middle of the drawn circle\n const sphereCenterWorld = vec3.fromValues(\n (bottom[0] + top[0]) / 2,\n (bottom[1] + top[1]) / 2,\n (bottom[2] + top[2]) / 2\n )\n\n // Drawn radius of the circle in the world\n const radiusWorld = vec3.distance(bottom, top) / 2\n\n // we need to find the bounding box of the sphere in the image, e.g., the\n // topLeftWorld and bottomRightWorld points of the bounding box.\n // We go from the sphereCenter in the normal direction of amount radius, and\n // we go left to find the topLeftWorld point of the bounding box. Next we go\n // in the opposite direction and go right to find the bottomRightWorld point\n // of the bounding box.\n const topLeftWorld = vec3.create()\n const bottomRightWorld = vec3.create()\n\n vec3.scaleAndAdd(topLeftWorld, top, viewPlaneNormal, radiusWorld)\n vec3.scaleAndAdd(bottomRightWorld, bottom, viewPlaneNormal, -radiusWorld)\n\n // go in the direction of viewRight with the value of radius\n vec3.scaleAndAdd(topLeftWorld, topLeftWorld, viewRight, -radiusWorld)\n vec3.scaleAndAdd(bottomRightWorld, bottomRightWorld, viewRight, radiusWorld)\n\n // convert the world coordinates to index coordinates\n\n const sphereCornersIJK = [\n <Types.Point3>transformPhysicalToIndex(imageData, topLeftWorld),\n <Types.Point3>transformPhysicalToIndex(imageData, bottomRightWorld),\n ]\n\n // get the bounding box of the sphere in the image\n const boundsIJK = getBoundingBoxAroundShape(sphereCornersIJK, dimensions)\n\n const sphereObj = {\n center: sphereCenterWorld,\n radius: radiusWorld,\n }\n\n pointInShapeCallback(\n imageData,\n (pointLPS) => pointInSphere(sphereObj, pointLPS),\n callback,\n boundsIJK\n )\n}\n","import type { Types } from '@cornerstonejs/core'\nimport { vec3 } from 'gl-matrix'\n\ntype Sphere = {\n center: Types.Point3 | vec3\n radius: number\n}\n\n/**\n * Checks if a point is inside a sphere. Note: this is similar to the\n * `pointInEllipse` function, but since we don't need checks for the\n * ellipse's rotation in different views, we can use a simpler equation\n * which would be faster (no if statements).\n *\n * @param sphere - Sphere object with center and radius\n * @param pointLPS - the point to check in world coordinates\n * @returns boolean\n */\nexport default function pointInSphere(\n sphere: Sphere,\n pointLPS: Types.Point3\n): boolean {\n const { center, radius } = sphere\n const [x, y, z] = pointLPS\n const [x0, y0, z0] = center\n\n return (x - x0) ** 2 + (y - y0) ** 2 + (z - z0) ** 2 <= radius ** 2\n}\n","import type { Types } from '@cornerstonejs/core'\n\n/**\n * Determine the coordinates that will place the textbox to the right of the\n * annotation.\n *\n * @param annotationCanvasPoints - The canvas points of the annotation's handles.\n * @returns - The coordinates for default placement of the textbox.\n */\nexport default function getTextBoxCoordsCanvas(\n annotationCanvasPoints: Array<Types.Point2>\n): Types.Point2 {\n const corners = _determineCorners(annotationCanvasPoints)\n const centerY = (corners.top[1] + corners.bottom[1]) / 2\n const textBoxCanvas = <Types.Point2>[corners.right[0], centerY]\n\n return textBoxCanvas\n}\n\n/**\n * Determine the handles that have the min/max x and y values.\n *\n * @param canvasPoints - The canvas points of the annotation's handles.\n * @returns - The top, left, bottom, and right handles.\n */\nfunction _determineCorners(canvasPoints: Array<Types.Point2>) {\n const handlesLeftToRight = [canvasPoints[0], canvasPoints[1]].sort(_compareX)\n const handlesTopToBottom = [canvasPoints[0], canvasPoints[1]].sort(_compareY)\n const right = handlesLeftToRight[handlesLeftToRight.length - 1]\n const top = handlesTopToBottom[0]\n const bottom = handlesTopToBottom[handlesTopToBottom.length - 1]\n\n return {\n top,\n bottom,\n right,\n }\n\n function _compareX(a, b) {\n return a[0] < b[0] ? -1 : 1\n }\n function _compareY(a, b) {\n return a[1] < b[1] ? -1 : 1\n }\n}\n","import getTextBoxCoordsCanvas from './getTextBoxCoordsCanvas'\n\nexport { getTextBoxCoordsCanvas }\nexport default { getTextBoxCoordsCanvas }\n","// Pulled from source: https://github.com/w8r/liang-barsky\n// MIT Licensed.\n\n/**\n * Fast, destructive implementation of Liang-Barsky line clipping algorithm.\n * It clips a 2D segment by a rectangle.\n * @author Alexander Milevski <info@w8r.name>\n * @license MIT\n */\n\nconst EPSILON = 1e-6\nconst INSIDE = 1\nconst OUTSIDE = 0\n\nfunction clipT(num, denom, c) {\n const [tE, tL] = c\n if (Math.abs(denom) < EPSILON) return num < 0\n const t = num / denom\n\n if (denom > 0) {\n if (t > tL) return 0\n if (t > tE) c[0] = t\n } else {\n if (t < tE) return 0\n if (t < tL) c[1] = t\n }\n return 1\n}\n\n/**\n * @param {Point} a\n * @param {Point} b\n * @param {BoundingBox} box [xmin, ymin, xmax, ymax]\n * @param {Point?} [da]\n * @param {Point?} [db]\n * @return {number}\n */\nexport default function clip(a, b, box, da?, db?) {\n const [x1, y1] = a\n const [x2, y2] = b\n const dx = x2 - x1\n const dy = y2 - y1\n\n if (da === undefined || db === undefined) {\n da = a\n db = b\n } else {\n da[0] = a[0]\n da[1] = a[1]\n db[0] = b[0]\n db[1] = b[1]\n }\n\n if (\n Math.abs(dx) < EPSILON &&\n Math.abs(dy) < EPSILON &&\n x1 >= box[0] &&\n x1 <= box[2] &&\n y1 >= box[1] &&\n y1 <= box[3]\n ) {\n return INSIDE\n }\n\n const c = [0, 1]\n if (\n clipT(box[0] - x1, dx, c) &&\n clipT(x1 - box[2], -dx, c) &&\n clipT(box[1] - y1, dy, c) &&\n clipT(y1 - box[3], -dy, c)\n ) {\n const [tE, tL] = c\n if (tL < 1) {\n db[0] = x1 + tL * dx\n db[1] = y1 + tL * dy\n }\n if (tE > 0) {\n da[0] += tE * dx\n da[1] += tE * dy\n }\n return INSIDE\n }\n return OUTSIDE\n}\n","import findClosestPoint from './findClosestPoint'\nimport liangBarksyClip from './liangBarksyClip'\n\nexport default { findClosestPoint, liangBarksyClip }\n","import type { Types } from '@cornerstonejs/core'\n\ntype Ellipse = {\n center: Types.Point3\n xRadius: number\n yRadius: number\n zRadius: number\n}\n\n/**\n * Given an ellipse and a point, return true if the point is inside the ellipse\n * @param ellipse - The ellipse object to check against.\n * @param pointLPS - The point in LPS space to test.\n * @returns A boolean value.\n */\nexport default function pointInEllipse(\n ellipse: Ellipse,\n pointLPS: Types.Point3\n): boolean {\n const { center: circleCenterWorld, xRadius, yRadius, zRadius } = ellipse\n const [x, y, z] = pointLPS\n const [x0, y0, z0] = circleCenterWorld\n\n let inside = 0\n if (xRadius !== 0) {\n inside += ((x - x0) * (x - x0)) / (xRadius * xRadius)\n }\n\n if (yRadius !== 0) {\n inside += ((y - y0) * (y - y0)) / (yRadius * yRadius)\n }\n\n if (zRadius !== 0) {\n inside += ((z - z0) * (z - z0)) / (zRadius * zRadius)\n }\n\n return inside <= 1\n}\n","import type { Types } from '@cornerstonejs/core'\n\ntype canvasCoordinates = [\n Types.Point2, // bottom\n Types.Point2, // top\n Types.Point2, // left\n Types.Point2 // right\n]\n\n/**\n * It takes the canvas coordinates of the ellipse corners and returns the top left and bottom right\n * corners of it\n *\n * @param ellipseCanvasPoints - The coordinates of the ellipse in the canvas.\n * @returns An array of two points.\n */\nexport default function getCanvasEllipseCorners(\n ellipseCanvasPoints: canvasCoordinates\n): Array<Types.Point2> {\n const [bottom, top, left, right] = ellipseCanvasPoints\n\n const topLeft = <Types.Point2>[left[0], top[1]]\n const bottomRight = <Types.Point2>[right[0], bottom[1]]\n\n return [topLeft, bottomRight]\n}\n","import pointInEllipse from './pointInEllipse'\nimport getCanvasEllipseCorners from './getCanvasEllipseCorners'\n\nexport { pointInEllipse, getCanvasEllipseCorners }\nexport default { pointInEllipse, getCanvasEllipseCorners }\n","import { Types } from '@cornerstonejs/core'\n\nfunction dist2(p1: Types.Point2, p2: Types.Point2): number {\n return (p1[0] - p2[0]) * (p1[0] - p2[0]) + (p1[1] - p2[1]) * (p1[1] - p2[1])\n}\n\n/**\n * Calculates the distance-squared of a point to a line\n *\n * @param lineStart - x,y coordinates of the start of the line\n * @param lineEnd - x,y coordinates of the end of the line\n * @param point - x,y of the point\n * @returns distance-squared\n */\nexport default function distanceToPointSquared(\n lineStart: Types.Point2,\n lineEnd: Types.Point2,\n point: Types.Point2\n): number {\n const d2 = dist2(lineStart, lineEnd)\n\n if (d2 === 0) {\n return dist2(point, lineStart)\n }\n\n const t =\n ((point[0] - lineStart[0]) * (lineEnd[0] - lineStart[0]) +\n (point[1] - lineStart[1]) * (lineEnd[1] - lineStart[1])) /\n d2\n\n if (t < 0) {\n return dist2(point, lineStart)\n }\n if (t > 1) {\n return dist2(point, lineEnd)\n }\n\n const pt: Types.Point2 = [\n lineStart[0] + t * (lineEnd[0] - lineStart[0]),\n lineStart[1] + t * (lineEnd[1] - lineStart[1]),\n ]\n\n return dist2(point, pt)\n}\n","import { Types } from '@cornerstonejs/core'\n\n// Returns sign of number\nfunction sign(x: any) {\n return typeof x === 'number'\n ? x\n ? x < 0\n ? -1\n : 1\n : x === x\n ? 0\n : NaN\n : NaN\n}\n\n/**\n * Calculates the intersection point between two lines in the 2D plane\n *\n * @param line1Start - x,y coordinates of the start of the first line\n * @param line1End - x,y coordinates of the end of the first line\n * @param line2Start - x,y coordinates of the start of the second line\n * @param line2End - x,y coordinates of the end of the second line\n * @returns [x,y] - point x,y of the point\n */\n\nexport default function intersectLine(\n line1Start: Types.Point2,\n line1End: Types.Point2,\n line2Start: Types.Point2,\n line2End: Types.Point2\n): number[] {\n const [x1, y1] = line1Start\n const [x2, y2] = line1End\n const [x3, y3] = line2Start\n const [x4, y4] = line2End\n\n // Compute a1, b1, c1, where line joining points 1 and 2 is \"a1 x + b1 y + c1 = 0\"\n const a1 = y2 - y1\n const b1 = x1 - x2\n const c1 = x2 * y1 - x1 * y2\n\n // Compute r3 and r4\n const r3 = a1 * x3 + b1 * y3 + c1\n const r4 = a1 * x4 + b1 * y4 + c1\n\n /* Check signs of r3 and r4. If both point 3 and point 4 lie on\n * same side of line 1, the line segments do not intersect.\n */\n\n if (r3 !== 0 && r4 !== 0 && sign(r3) === sign(r4)) {\n return\n }\n\n // Compute a2, b2, c2\n const a2 = y4 - y3\n const b2 = x3 - x4\n const c2 = x4 * y3 - x3 * y4\n\n // Compute r1 and r2\n const r1 = a2 * x1 + b2 * y1 + c2\n const r2 = a2 * x2 + b2 * y2 + c2\n\n /* Check signs of r1 and r2. If both point 1 and point 2 lie\n * on same side of second line segment, the line segments do\n * not intersect.\n */\n\n if (r1 !== 0 && r2 !== 0 && sign(r1) === sign(r2)) {\n return\n }\n\n /* Line segments intersect: compute intersection point.\n */\n\n const denom = a1 * b2 - a2 * b1\n let num\n\n /* The denom/2 is to get rounding instead of truncating. It\n * is added or subtracted to the numerator, depending upon the\n * sign of the numerator.\n */\n\n num = b1 * c2 - b2 * c1\n const x = num / denom\n\n num = a2 * c1 - a1 * c2\n const y = num / denom\n\n const intersectionPoint = [x, y]\n\n return intersectionPoint\n}\n","import distanceToPoint from './distanceToPoint'\nimport distanceToPointSquared from './distanceToPointSquared'\nimport intersectLine from './intersectLine'\n\nconst lineSegment = {\n distanceToPoint,\n distanceToPointSquared,\n intersectLine,\n}\n\nexport default lineSegment\n","import distanceToPointSquared from './distanceToPointSquared'\nimport { Types } from '@cornerstonejs/core'\n\n/**\n * Calculates the distance of a point to a line\n *\n * @param lineStart - x,y coordinates of the start of the line\n * @param lineEnd - x,y coordinates of the end of the line\n * @param point - x,y of the point\n * @returns distance\n */\nexport default function distanceToPoint(\n lineStart: Types.Point2,\n lineEnd: Types.Point2,\n point: Types.Point2\n): number {\n if (lineStart.length !== 2 || lineEnd.length !== 2 || point.length !== 2) {\n throw Error(\n 'lineStart, lineEnd, and point should have 2 elements of [x, y]'\n )\n }\n\n return Math.sqrt(distanceToPointSquared(lineStart, lineEnd, point))\n}\n","import distanceToPoint from './distanceToPoint'\n\nconst rectangle = {\n distanceToPoint,\n}\n\nexport default rectangle\n","import type { Types } from '@cornerstonejs/core'\nimport lineSegment from '../line'\n\ntype rectLineSegments = {\n top: Types.Point2[]\n right: Types.Point2[]\n bottom: Types.Point2[]\n left: Types.Point2[]\n}\n\n/**\n * Given a rectangle left, top, width and height, return an object containing the\n * line segments that make up the rectangle's four sides\n * @param left - The x-coordinate of the left edge of the rectangle.\n * @param top - The y-coordinate of the top edge of the rectangle.\n * @param width - The width of the rectangle.\n * @param height - The height of the rectangle.\n * @returns An object with four keys, each of which contains an array of two\n * points.\n */\nfunction rectToLineSegments(\n left: number,\n top: number,\n width: number,\n height: number\n): rectLineSegments {\n const topLineStart: Types.Point2 = [left, top]\n const topLineEnd: Types.Point2 = [left + width, top]\n\n const rightLineStart: Types.Point2 = [left + width, top]\n const rightLineEnd: Types.Point2 = [left + width, top + height]\n\n const bottomLineStart: Types.Point2 = [left + width, top + height]\n const bottomLineEnd: Types.Point2 = [left, top + height]\n\n const leftLineStart: Types.Point2 = [left, top + height]\n const leftLineEnd: Types.Point2 = [left, top]\n\n const lineSegments = {\n top: [topLineStart, topLineEnd],\n right: [rightLineStart, rightLineEnd],\n bottom: [bottomLineStart, bottomLineEnd],\n left: [leftLineStart, leftLineEnd],\n }\n\n return lineSegments\n}\n\n/**\n * Calculates distance of the point to the rectangle. It calculates the minimum\n * distance between the point and each line segment of the rectangle.\n *\n * @param rect - coordinates of the rectangle [left, top, width, height]\n * @param point - [x,y] coordinates of a point\n * @returns\n */\nexport default function distanceToPoint(\n rect: number[],\n point: Types.Point2\n): number {\n if (rect.length !== 4 || point.length !== 2) {\n throw Error(\n 'rectangle:[left, top, width, height] or point: [x,y] not defined correctly'\n )\n }\n\n const [left, top, width, height] = rect\n\n let minDistance = 655535\n const lineSegments = rectToLineSegments(left, top, width, height)\n\n Object.keys(lineSegments).forEach((segment) => {\n const [lineStart, lineEnd] = lineSegments[segment]\n const distance = lineSegment.distanceToPoint(lineStart, lineEnd, point)\n\n if (distance < minDistance) {\n minDistance = distance\n }\n })\n\n return minDistance\n}\n","import vec2 from './vec2'\nimport ellipse from './ellipse'\nimport lineSegment from './line'\nimport rectangle from './rectangle'\n\nexport default { vec2, ellipse, lineSegment, rectangle }\nexport { vec2, ellipse, lineSegment, rectangle }\n","import { vec3 } from 'gl-matrix'\nimport type { Types } from '@cornerstonejs/core'\n\n/**\n * Given two world positions and an orthogonal view to an `imageVolume` defined\n * by a `viewPlaneNormal` and a `viewUp`, get the width and height in world coordinates\n * of the rectangle defined by the two points. The implementation works both with orthogonal\n * non-orthogonal rectangles.\n *\n * @param viewPlaneNormal - The normal of the view.\n * @param viewUp - The up direction of the view.\n * @param imageVolume - The imageVolume to use to measure.\n * @param topLeftWorld - The first world position.\n * @param bottomRightWorld - The second world position.\n *\n * @returns The `worldWidth` and `worldHeight`.\n */\nexport default function getWorldWidthAndHeightFromCorners(\n viewPlaneNormal: Types.Point3,\n viewUp: Types.Point3,\n topLeftWorld: Types.Point3,\n bottomRightWorld: Types.Point3\n): { worldWidth: number; worldHeight: number } {\n let viewRight = vec3.create()\n\n vec3.cross(viewRight, <vec3>viewUp, <vec3>viewPlaneNormal)\n\n viewRight = [-viewRight[0], -viewRight[1], -viewRight[2]]\n\n const pos1 = vec3.fromValues(...topLeftWorld)\n const pos2 = vec3.fromValues(...bottomRightWorld)\n\n const diagonal = vec3.create()\n vec3.subtract(diagonal, pos1, pos2)\n\n const diagonalLength = vec3.length(diagonal)\n\n // When the two points are very close to each other return width as 0\n // to avoid NaN the cosTheta formula calculation\n if (diagonalLength < 0.0001) {\n return { worldWidth: 0, worldHeight: 0 }\n }\n\n const cosTheta =\n vec3.dot(diagonal, viewRight) / (diagonalLength * vec3.length(viewRight))\n\n const sinTheta = Math.sqrt(1 - cosTheta * cosTheta)\n\n const worldWidth = sinTheta * diagonalLength\n const worldHeight = cosTheta * diagonalLength\n\n return { worldWidth, worldHeight }\n}\n","import vtkMath from 'vtk.js/Sources/Common/Core/Math'\nimport { utilities as csUtils } from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\nimport { VolumeViewport } from '@cornerstonejs/core'\n/**\n * Returns a point based on some criteria (e.g., minimum or maximum intensity) in\n * the line of sight (on the line between the passed worldPosition and camera position).\n * It iterated over the points with a step size on the line.\n *\n * @param viewport - Volume viewport\n * @param worldPos - World coordinates of the clicked location\n * @param targetVolumeUID - target Volume UID in the viewport\n * @param criteriaFunction - A function that returns the point if it passes a certain\n * written logic, for instance, it can be a maxValue function that keeps the\n * records of all intensity values, and only return the point if its intensity\n * is greater than the maximum intensity of the points passed before.\n * @param stepsSize - Percentage of the spacing in the normal direction, default value\n * is 0.25 which means steps = 1/4 of the spacing in the normal direction.\n * @returns the World pos of the point that passes the criteriaFunction\n */\nexport default function getPointInLineOfSightWithCriteria(\n viewport: Types.IVolumeViewport,\n worldPos: Types.Point3,\n targetVolumeUID: string,\n criteriaFunction: (intensity: number, point: Types.Point3) => Types.Point3,\n stepSize = 0.25\n): Types.Point3 {\n // 1. Getting the camera from the event details\n const camera = viewport.getCamera()\n const { position: cameraPosition } = camera\n\n // 2. Calculating the spacing in the normal direction, this will get\n // used as the step size for iterating over the points in the line of sight\n const { spacingInNormalDirection } =\n csUtils.getTargetVolumeAndSpacingInNormalDir(\n viewport,\n camera,\n targetVolumeUID\n )\n // 2.1 Making sure, we are not missing any point\n const step = spacingInNormalDirection * stepSize\n\n // 3. Getting the bounds of the viewports. Search for brightest point is\n // limited to the visible bound\n // Todo: this might be a problem since bounds will change to spatial bounds.\n const bounds = viewport.getBounds()\n const xMin = bounds[0]\n const xMax = bounds[1]\n\n // 5. Calculating the line, we use a parametric line definition\n const vector = <Types.Point3>[0, 0, 0]\n\n // 5.1 Point coordinate on the line\n let point = <Types.Point3>[0, 0, 0]\n\n // 5.2 Calculating the line direction, and storing in vector\n vtkMath.subtract(worldPos, cameraPosition, vector)\n\n let pickedPoint\n\n // 6. Iterating over the line from the lower bound to the upper bound, with the\n // specified step size\n for (let pointT = xMin; pointT <= xMax; pointT = pointT + step) {\n // 6.1 Calculating the point x location\n point = [pointT, 0, 0]\n // 6.2 Calculating the point y,z location based on the line equation\n const t = (pointT - cameraPosition[0]) / vector[0]\n point[1] = t * vector[1] + cameraPosition[1]\n point[2] = t * vector[2] + cameraPosition[2]\n\n // 6.3 Checking if the points is inside the bounds\n if (_inBounds(point, bounds)) {\n // 6.4 Getting the intensity of the point\n const intensity = viewport.getIntensityFromWorld(point)\n // 6.5 Passing the intensity to the maximum value functions which decides\n // whether the current point is of interest based on some criteria\n const pointToPick = criteriaFunction(intensity, point)\n if (pointToPick) {\n pickedPoint = pointToPick\n }\n }\n }\n\n return pickedPoint\n}\n\n/**\n * Returns whether the point in the world is inside the bounds of the viewport\n * @param point - coordinates in the world\n * @returns boolean\n */\nconst _inBounds = function (\n point: Types.Point3,\n bounds: Array<number>\n): boolean {\n const [xMin, xMax, yMin, yMax, zMin, zMax] = bounds\n return (\n point[0] > xMin &&\n point[0] < xMax &&\n point[1] > yMin &&\n point[1] < yMax &&\n point[2] > zMin &&\n point[2] < zMax\n )\n}\n","import filterAnnotationsWithinSlice from './filterAnnotationsWithinSlice'\nimport getWorldWidthAndHeightFromCorners from './getWorldWidthAndHeightFromCorners'\nimport filterAnnotationsForDisplay from './filterAnnotationsForDisplay'\nimport getPointInLineOfSightWithCriteria from './getPointInLineOfSightWithCriteria'\n\nexport default {\n filterAnnotationsWithinSlice,\n getWorldWidthAndHeightFromCorners,\n filterAnnotationsForDisplay,\n getPointInLineOfSightWithCriteria,\n}\n\nexport {\n filterAnnotationsWithinSlice,\n getWorldWidthAndHeightFromCorners,\n filterAnnotationsForDisplay,\n getPointInLineOfSightWithCriteria,\n}\n","import { vec3 } from 'gl-matrix'\n\nimport type { Types } from '@cornerstonejs/core'\n\n/**\n * Given a number of frames, `deltaFrames`,\n * move the `focalPoint` and camera `position` so that it moves forward/backwards\n * `deltaFrames` in the camera's normal direction, and snaps to the nearest frame.\n *\n * @param focalPoint - The focal point to move.\n * @param position - The camera position to move.\n * @param scrollRange - The scroll range used to find the current\n * position in the stack, as well as prevent scrolling past the extent of the volume.\n * @param viewPlaneNormal - The normal direction of the camera.\n * @param spacingInNormalDirection - The spacing of frames the normal direction of the camera.\n * @param deltaFrames - The number of frames to jump.\n *\n * @returns The `newFocalPoint` and `newPosition` of the camera.\n */\nexport default function snapFocalPointToSlice(\n focalPoint: Types.Point3,\n position: Types.Point3,\n scrollRange,\n viewPlaneNormal: Types.Point3,\n spacingInNormalDirection: number,\n deltaFrames: number\n): { newFocalPoint: Types.Point3; newPosition: Types.Point3 } {\n const { min, max, current } = scrollRange\n\n // Get the current offset off the camera position so we can add it on at the end.\n const posDiffFromFocalPoint = vec3.create()\n\n vec3.sub(posDiffFromFocalPoint, <vec3>position, <vec3>focalPoint)\n\n // Now we can see how many steps there are in this direction\n const steps = Math.round((max - min) / spacingInNormalDirection)\n\n // Find out current frameIndex\n const fraction = (current - min) / (max - min)\n const floatingStepNumber = fraction * steps\n let frameIndex = Math.round(floatingStepNumber)\n\n // Dolly the focal point back to min slice focal point.\n let newFocalPoint = <Types.Point3>[\n focalPoint[0] -\n viewPlaneNormal[0] * floatingStepNumber * spacingInNormalDirection,\n focalPoint[1] -\n viewPlaneNormal[1] * floatingStepNumber * spacingInNormalDirection,\n focalPoint[2] -\n viewPlaneNormal[2] * floatingStepNumber * spacingInNormalDirection,\n ]\n\n // Increment the slice number by deltaFrames.\n frameIndex += deltaFrames\n\n // Clamp sliceNumber to volume.\n if (frameIndex > steps) {\n frameIndex = steps\n } else if (frameIndex < 0) {\n frameIndex = 0\n }\n\n // Dolly the focal towards to the correct frame focal point.\n const newSlicePosFromMin = frameIndex * spacingInNormalDirection\n\n newFocalPoint = <Types.Point3>[\n newFocalPoint[0] + viewPlaneNormal[0] * newSlicePosFromMin,\n newFocalPoint[1] + viewPlaneNormal[1] * newSlicePosFromMin,\n newFocalPoint[2] + viewPlaneNormal[2] * newSlicePosFromMin,\n ]\n\n const newPosition = <Types.Point3>[\n newFocalPoint[0] + posDiffFromFocalPoint[0],\n newFocalPoint[1] + posDiffFromFocalPoint[1],\n newFocalPoint[2] + posDiffFromFocalPoint[2],\n ]\n\n return { newFocalPoint, newPosition }\n}\n","import { utilities as csUtils } from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\nimport vtkMatrixBuilder from 'vtk.js/Sources/Common/Core/MatrixBuilder'\n\n/**\n * Given a `vtkVolumeActor`, and a normal direction,\n * calculate the range of slices in the focal normal direction that encapsulate\n * the volume. Also project the `focalPoint` onto this range.\n *\n * @param volumeActor - The `vtkVolumeActor`.\n * @param viewPlaneNormal - The normal to the camera view.\n * @param focalPoint - The focal point of the camera.\n *\n * @returns an object containing the `min`, `max` and `current`\n * positions in the normal direction.\n */\nexport default function getSliceRange(\n volumeActor: Types.VolumeActor,\n viewPlaneNormal: Types.Point3,\n focalPoint: Types.Point3\n): { min: number; max: number; current: number } {\n const corners = csUtils.getVolumeActorCorners(volumeActor)\n\n // Get rotation matrix from normal to +X (since bounds is aligned to XYZ)\n const transform = vtkMatrixBuilder\n .buildFromDegree()\n .identity()\n .rotateFromDirections(viewPlaneNormal, [1, 0, 0])\n\n corners.forEach((pt) => transform.apply(pt))\n\n const transformedFocalPoint = [...focalPoint]\n\n transform.apply(transformedFocalPoint)\n\n const currentSlice = transformedFocalPoint[0]\n\n // range is now maximum X distance\n let minX = Infinity\n let maxX = -Infinity\n for (let i = 0; i < 8; i++) {\n const x = corners[i][0]\n if (x > maxX) {\n maxX = x\n }\n if (x < minX) {\n minX = x\n }\n }\n\n return { min: minX, max: maxX, current: currentSlice }\n}\n","/**\n * Clips a value to an upper and lower bound.\n * @export @public @method\n * @name clip\n *\n * @param {number} val The value to clip.\n * @param {number} low The lower bound.\n * @param {number} high The upper bound.\n * @returns {number} The clipped value.\n */\nexport function clip(val, low, high) {\n return Math.min(Math.max(low, val), high)\n}\n\n/**\n * Clips a value within a box.\n * @export @public @method\n * @name clipToBox\n *\n * @param {Object} point The point to clip\n * @param {Object} box The bounding box to clip to.\n * @returns {Object} The clipped point.\n */\nexport function clipToBox(point, box) {\n // Clip an {x, y} point to a box of size {width, height}\n point.x = clip(point.x, 0, box.width)\n point.y = clip(point.y, 0, box.height)\n}\n\nexport default clip\n","import {\n getEnabledElement,\n StackViewport,\n VolumeViewport,\n utilities as csUtils,\n} from '@cornerstonejs/core'\nimport clip from '../clip'\nimport getSliceRange from './getSliceRange'\nimport snapFocalPointToSlice from './snapFocalPointToSlice'\nimport { MouseDragEventType, MouseWheelEventType } from '../../types/EventTypes'\n\n/**\n * Scroll the stack defined by the event (`evt`)\n * and volume with `volumeUID` `deltaFrames number of frames`.\n * Frames are defined as increasing in the view direction.\n *\n * @param evt - The event corresponding to an interaction with a\n * specific viewport.\n * @param deltaFrames - The number of frames to jump through.\n * @param volumeUID - The `volumeUID` of the volume to scroll through\n * @param invert - inversion of the scrolling\n * on the viewport.\n */\nexport default function scrollThroughStack(\n evt: MouseWheelEventType | MouseDragEventType,\n deltaFrames: number,\n volumeUID: string,\n invert = false\n): void {\n const { element } = evt.detail\n const { viewport } = getEnabledElement(element)\n const { type: viewportType } = viewport\n const camera = viewport.getCamera()\n const { focalPoint, viewPlaneNormal, position } = camera\n const delta = invert ? -deltaFrames : deltaFrames\n\n if (viewport instanceof StackViewport) {\n // stack viewport\n const currentImageIdIndex = viewport.getCurrentImageIdIndex()\n const numberOfFrames = viewport.getImageIds().length\n let newImageIdIndex = currentImageIdIndex + delta\n newImageIdIndex = clip(newImageIdIndex, 0, numberOfFrames - 1)\n\n viewport.setImageIdIndex(newImageIdIndex)\n } else if (viewport instanceof VolumeViewport) {\n // If volumeUID is specified, scroll through that specific volume\n const { spacingInNormalDirection, imageVolume } =\n csUtils.getTargetVolumeAndSpacingInNormalDir(viewport, camera, volumeUID)\n\n if (!imageVolume) {\n return\n }\n\n const actor = viewport.getActor(imageVolume.uid)\n\n if (!actor) {\n console.warn('No actor found for with actorUID of', imageVolume.uid)\n }\n\n const { volumeActor } = actor\n const scrollRange = getSliceRange(volumeActor, viewPlaneNormal, focalPoint)\n\n const { newFocalPoint, newPosition } = snapFocalPointToSlice(\n focalPoint,\n position,\n scrollRange,\n viewPlaneNormal,\n spacingInNormalDirection,\n delta\n )\n\n viewport.setCamera({\n focalPoint: newFocalPoint,\n position: newPosition,\n })\n viewport.render()\n } else {\n throw new Error(`Not implemented for Viewport Type: ${viewportType}`)\n }\n}\n","import snapFocalPointToSlice from './snapFocalPointToSlice'\nimport getSliceRange from './getSliceRange'\nimport scrollThroughStack from './scrollThroughStack'\n\nexport { snapFocalPointToSlice, getSliceRange, scrollThroughStack }\nexport default {\n snapFocalPointToSlice,\n getSliceRange,\n scrollThroughStack,\n}\n","import type { Types } from '@cornerstonejs/core'\n\n/**\n * Given an array of viewports, returns a list of viewports that are viewing a\n * world space with the given `FrameOfReferenceUID`.\n *\n * @param viewports - An array of viewports.\n * @param FrameOfReferenceUID - The UID defining a particular world space/Frame Of Reference.\n *\n * @returns A filtered array of viewports.\n */\nexport default function filterViewportsWithFrameOfReferenceUID(\n viewports: Array<Types.IStackViewport | Types.IVolumeViewport>,\n FrameOfReferenceUID: string\n): Array<Types.IStackViewport | Types.IVolumeViewport> {\n const numViewports = viewports.length\n const viewportsWithFrameOfReferenceUID = []\n\n for (let vp = 0; vp < numViewports; vp++) {\n const viewport = viewports[vp]\n\n if (viewport.getFrameOfReferenceUID() === FrameOfReferenceUID) {\n viewportsWithFrameOfReferenceUID.push(viewport)\n }\n }\n\n return viewportsWithFrameOfReferenceUID\n}\n","import type { Types } from '@cornerstonejs/core'\nimport type { IToolGroup } from '../../types'\nimport { ToolGroupManager } from '../../store'\nimport { ToolModes } from '../../enums'\n\nconst { Active, Passive, Enabled } = ToolModes\n\n/**\n * Given an array of viewports, returns a list of viewports that have the the specified tool enabled.\n *\n * @param viewports - An array of viewports.\n * @param toolName - The name of the tool to filter on.\n *\n * @returns A filtered array of viewports.\n */\nexport default function filterViewportsWithToolEnabled(\n viewports: Array<Types.IStackViewport | Types.IVolumeViewport>,\n toolName: string\n): Array<Types.IStackViewport | Types.IVolumeViewport> {\n const numViewports = viewports.length\n\n const viewportsWithToolEnabled = []\n\n for (let vp = 0; vp < numViewports; vp++) {\n const viewport = viewports[vp]\n\n const toolGroup = ToolGroupManager.getToolGroup(\n viewport.uid,\n viewport.renderingEngineUID\n )\n\n const hasTool = _toolGroupHasActiveEnabledOrPassiveTool(toolGroup, toolName)\n\n if (hasTool) {\n viewportsWithToolEnabled.push(viewport)\n }\n }\n\n return viewportsWithToolEnabled\n}\n\n/**\n * Given a toolGroup, return true if it contains the tool with the given `toolName` and it is\n * active, passive or enabled.\n *\n * @param toolGroup - The `toolGroup` to check.\n * @param toolName - The name of the tool.\n *\n * @returns True if the tool is enabled, passive or active in the `toolGroup`.\n */\nfunction _toolGroupHasActiveEnabledOrPassiveTool(\n toolGroup: IToolGroup,\n toolName: string\n) {\n const { toolOptions } = toolGroup\n const tool = toolOptions[toolName]\n\n if (!tool) {\n return false\n }\n\n const toolMode = tool.mode\n\n return toolMode === Active || toolMode === Passive || toolMode === Enabled\n}\n","import { utilities as csUtils } from '@cornerstonejs/core'\n\nexport function filterViewportsWithSameOrientation(viewports, camera) {\n return viewports.filter((viewport) => {\n const vpCamera = viewport.getCamera()\n\n // TODO: do we need any other checks, or is this sufficient?\n return (\n csUtils.isEqual(vpCamera.viewPlaneNormal, camera.viewPlaneNormal) &&\n csUtils.isEqual(vpCamera.viewUp, camera.viewUp)\n )\n })\n}\n\nexport default filterViewportsWithSameOrientation\n","import { getEnabledElement } from '@cornerstonejs/core'\nimport filterViewportsWithFrameOfReferenceUID from './filterViewportsWithFrameOfReferenceUID'\nimport filterViewportsWithToolEnabled from './filterViewportsWithToolEnabled'\nimport filterViewportsWithSameOrientation from './filterViewportsWithSameOrientation'\n\n/**\n * Given a cornerstone3D enabled `element`, and a `toolName`, find all viewportUIDs\n * looking at the same Frame Of Reference that have the tool with the given `toolName`\n * active, passive or enabled.\n *\n * @param element - The target cornerstone3D enabled element.\n * @param toolName - The string toolName.\n * @param requireSameOrientation - If true, only return viewports matching the orientation of the original viewport\n *\n * @returns An array of viewportUIDs.\n */\nexport default function getViewportUIDsWithToolToRender(\n element: HTMLElement,\n toolName: string,\n requireSameOrientation = true\n): string[] {\n const enabledElement = getEnabledElement(element)\n const { renderingEngine, FrameOfReferenceUID } = enabledElement\n\n let viewports = renderingEngine.getViewports()\n\n viewports = filterViewportsWithFrameOfReferenceUID(\n viewports,\n FrameOfReferenceUID\n )\n viewports = filterViewportsWithToolEnabled(viewports, toolName)\n\n const viewport = renderingEngine.getViewport(enabledElement.viewportUID)\n\n if (requireSameOrientation) {\n viewports = filterViewportsWithSameOrientation(\n viewports,\n viewport.getCamera()\n )\n }\n\n const viewportUIDs = viewports.map((vp) => vp.uid)\n\n return viewportUIDs\n}\n","import filterViewportsWithFrameOfReferenceUID from './filterViewportsWithFrameOfReferenceUID'\nimport filterViewportsWithToolEnabled from './filterViewportsWithToolEnabled'\nimport getViewportUIDsWithToolToRender from './getViewportUIDsWithToolToRender'\n\nexport default {\n filterViewportsWithToolEnabled,\n filterViewportsWithFrameOfReferenceUID,\n getViewportUIDsWithToolToRender,\n}\n\nexport {\n filterViewportsWithToolEnabled,\n filterViewportsWithFrameOfReferenceUID,\n getViewportUIDsWithToolToRender,\n}\n","import {\n getAnnotationNearPoint,\n getAnnotationNearPointOnEnabledElement,\n} from './getAnnotationNearPoint'\n\n// Lodash/common JS functionality\nimport debounce from './debounce'\nimport deepMerge from './deepMerge'\nimport throttle from './throttle'\nimport isObject from './isObject'\nimport calibrateImageSpacing from './calibrateImageSpacing'\nimport triggerAnnotationRenderForViewportUIDs from './triggerAnnotationRenderForViewportUIDs'\nimport transformPhysicalToIndex from './transformPhysicalToIndex'\n\nimport pointInShapeCallback from './pointInShapeCallback'\nimport pointInSurroundingSphereCallback from './pointInSurroundingSphereCallback'\n\n// name spaces\nimport * as segmentation from './segmentation'\nimport * as drawing from './drawing'\nimport * as math from './math'\nimport * as planar from './planar'\nimport * as stackScrollTool from './stackScrollTool'\nimport * as viewportFilters from './viewportFilters'\n\n// Events\nimport { triggerEvent } from '@cornerstonejs/core'\n\nexport {\n math,\n planar,\n viewportFilters,\n stackScrollTool,\n drawing,\n debounce,\n deepMerge,\n throttle,\n isObject,\n triggerEvent,\n calibrateImageSpacing,\n segmentation,\n triggerAnnotationRenderForViewportUIDs,\n pointInShapeCallback,\n pointInSurroundingSphereCallback,\n getAnnotationNearPoint,\n getAnnotationNearPointOnEnabledElement,\n transformPhysicalToIndex,\n}\n\nexport default {\n math,\n planar,\n viewportFilters,\n stackScrollTool,\n drawing,\n debounce,\n deepMerge,\n throttle,\n isObject,\n triggerEvent,\n calibrateImageSpacing,\n transformPhysicalToIndex,\n segmentation,\n triggerAnnotationRenderForViewportUIDs,\n pointInShapeCallback,\n pointInSurroundingSphereCallback,\n getAnnotationNearPoint,\n getAnnotationNearPointOnEnabledElement,\n}\n","import { cache } from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\n\nimport {\n getBoundingBoxAroundShape,\n extend2DBoundingBoxInViewAxis,\n} from '../segmentation'\nimport { pointInShapeCallback } from '../../utilities'\nimport { triggerSegmentationDataModified } from '../../stateManagement/segmentation/triggerSegmentationEvents'\nimport { ToolGroupSpecificSegmentationData } from '../../types/SegmentationStateTypes'\nimport transformPhysicalToIndex from '../transformPhysicalToIndex'\nimport * as SegmentationState from '../../stateManagement/segmentation/segmentationState'\n\nexport type ThresholdRangeOptions = {\n higherThreshold: number\n lowerThreshold: number\n numSlicesToProject?: number // number of slices to project before and after current slice\n overwrite: boolean\n}\n\nexport type AnnotationForThresholding = {\n metadata: {\n enabledElement: Types.IEnabledElement\n }\n data: {\n handles: {\n points: Types.Point3[]\n }\n cachedStats: {\n projectionPoints: Types.Point3[][]\n }\n }\n}\n\n/**\n * Given an array of rectangle annotation, and a segmentation and referenceVolumes:\n * It fills the segmentation at SegmentIndex=1 based on a range of thresholds of the referenceVolumes\n * inside the drawn annotations.\n * @param toolGroupUID - - The toolGroupUID of the tool that is performing the operation\n * @param annotations - Array of rectangle annotations\n * @param segmentationData - - The segmentation data to be modified\n * @param segmentation - segmentation volume\n * @param options - Options for thresholding\n */\nfunction thresholdVolumeByRange(\n toolGroupUID: string,\n annotations: AnnotationForThresholding[],\n referenceVolumes: Types.IImageVolume[],\n segmentationData: ToolGroupSpecificSegmentationData,\n options: ThresholdRangeOptions\n): Types.IImageVolume {\n if (referenceVolumes.length > 1) {\n throw new Error('thresholding more than one volumes is not supported yet')\n }\n\n const globalState = SegmentationState.getGlobalSegmentationDataByUID(\n segmentationData.volumeUID\n )\n\n if (!globalState) {\n throw new Error('No Segmentation Found')\n }\n\n const { volumeUID } = globalState\n const segmentation = cache.getVolume(volumeUID)\n\n const { segmentationDataUID } = segmentationData\n\n const { scalarData, imageData: segmentationImageData } = segmentation\n const { lowerThreshold, higherThreshold, numSlicesToProject, overwrite } =\n options\n\n // set the segmentation to all zeros\n if (overwrite) {\n for (let i = 0; i < scalarData.length; i++) {\n scalarData[i] = 0\n }\n }\n\n annotations.forEach((annotation) => {\n // Threshold Options\n const { data } = annotation\n const { points } = data.handles\n\n const referenceVolume = referenceVolumes[0]\n const { imageData, dimensions } = referenceVolume\n\n // Todo: get directly from scalarData?\n const values = imageData.getPointData().getScalars().getData()\n\n let pointsToUse = points\n // If the tool is a 2D tool but has projection points, use them\n if (data.cachedStats?.projectionPoints) {\n const { projectionPoints } = data.cachedStats\n pointsToUse = [].concat(...projectionPoints) // cannot use flat() because of typescript compiler right now\n }\n\n const rectangleCornersIJK = pointsToUse.map(\n (world) => transformPhysicalToIndex(imageData, world) as Types.Point3\n )\n let boundsIJK = getBoundingBoxAroundShape(rectangleCornersIJK, dimensions)\n\n // If the tool is 2D but it is configured to project to X amount of slices\n // Don't project the slices if projectionPoints have been used to define the extents\n if (numSlicesToProject && !data.cachedStats?.projectionPoints) {\n boundsIJK = extendBoundingBoxInSliceAxisIfNecessary(\n boundsIJK,\n numSlicesToProject\n )\n }\n\n const callback = ({ index, pointIJK }) => {\n const offset = imageData.computeOffsetIndex(pointIJK)\n const value = values[offset]\n if (value <= lowerThreshold || value >= higherThreshold) {\n return\n }\n\n scalarData[index] = 1\n }\n\n pointInShapeCallback(segmentationImageData, () => true, callback, boundsIJK)\n })\n\n triggerSegmentationDataModified(toolGroupUID, segmentationDataUID)\n\n return segmentation\n}\n\nexport function extendBoundingBoxInSliceAxisIfNecessary(\n boundsIJK: [Types.Point2, Types.Point2, Types.Point2],\n numSlicesToProject: number\n): [Types.Point2, Types.Point2, Types.Point2] {\n const extendedBoundsIJK = extend2DBoundingBoxInViewAxis(\n boundsIJK,\n numSlicesToProject\n )\n return extendedBoundsIJK\n}\n\nexport default thresholdVolumeByRange\n","import type { Types } from '@cornerstonejs/core'\n\nimport transformPhysicalToIndex from '../../utilities/transformPhysicalToIndex'\nimport { getBoundingBoxAroundShape } from '../segmentation'\nimport { ToolGroupSpecificSegmentationData } from '../../types'\nimport thresholdVolumeByRange, {\n AnnotationForThresholding,\n extendBoundingBoxInSliceAxisIfNecessary,\n} from './thresholdVolumeByRange'\nimport * as SegmentationState from '../../stateManagement/segmentation/segmentationState'\nimport { cache } from '@cornerstonejs/core'\n\nexport type ThresholdRoiStatsOptions = {\n statistic: 'max' | 'min'\n weight: number\n numSlicesToProject?: number\n overwrite: boolean\n}\n\n/**\n * Given an array of rectangle annotation, and a labelmap and referenceVolumes:\n * It loops over the drawn annotations ROIs (3D, 3rd dimension is determined by numSlices),\n * and calculates the `statistic` (given in options) for the merged Roi. Then,\n * it thresholds the referenceVolumes based on a weighted value of the statistic.\n * For instance in radiation oncology, usually 41% of the maximum of the ROI is used\n * in radiation planning.\n * @param toolGroupUID - The toolGroupUID of the tool that is performing the operation\n * @param annotations Array of rectangle annotation annotation\n * @param segmentationData - The segmentation data to be modified\n * @param labelmap segmentation volume\n * @param options Options for thresholding\n */\nfunction thresholdVolumeByRoiStats(\n toolGroupUID: string,\n annotations: AnnotationForThresholding[],\n referenceVolumes: Types.IImageVolume[],\n segmentationData: ToolGroupSpecificSegmentationData,\n options: ThresholdRoiStatsOptions\n): void {\n if (referenceVolumes.length > 1) {\n throw new Error('thresholding more than one volumes is not supported yet')\n }\n\n const globalState = SegmentationState.getGlobalSegmentationDataByUID(\n segmentationData.volumeUID\n )\n\n if (!globalState) {\n throw new Error('No Segmentation Found')\n }\n\n const { volumeUID } = globalState\n const segmentation = cache.getVolume(volumeUID)\n\n const { numSlicesToProject, overwrite } = options\n\n const { scalarData } = segmentation\n if (overwrite) {\n for (let i = 0; i < scalarData.length; i++) {\n scalarData[i] = 0\n }\n }\n\n const referenceVolume = referenceVolumes[0]\n const { imageData, dimensions } = referenceVolume\n\n const values = imageData.getPointData().getScalars().getData()\n\n const { statistic } = options\n const [fn, baseValue] = _getStrategyFn(statistic)\n let value = baseValue\n\n annotations.forEach((annotation) => {\n const { data } = annotation\n const { points } = data.handles\n\n let pointsToUse = points\n // If the tool is a 2D tool but has projection points, use them\n if (data.cachedStats?.projectionPoints) {\n const { projectionPoints } = data.cachedStats\n pointsToUse = [].concat(...projectionPoints) // cannot use flat() because of typescript compiler right now\n }\n\n const rectangleCornersIJK = pointsToUse.map(\n (world) => transformPhysicalToIndex(imageData, world) as Types.Point3\n )\n let boundsIJK = getBoundingBoxAroundShape(rectangleCornersIJK, dimensions)\n\n // Don't project the slices if projectionPoints have been used to define the extents\n if (numSlicesToProject && !data.cachedStats?.projectionPoints) {\n boundsIJK = extendBoundingBoxInSliceAxisIfNecessary(\n boundsIJK,\n numSlicesToProject\n )\n }\n\n const [[iMin, iMax], [jMin, jMax], [kMin, kMax]] = boundsIJK\n\n for (let i = iMin; i <= iMax; i++) {\n for (let j = jMin; j <= jMax; j++) {\n for (let k = kMin; k <= kMax; k++) {\n const offset = imageData.computeOffsetIndex([i, j, k])\n value = fn(values[offset], value)\n }\n }\n }\n })\n\n const rangeOptions = {\n lowerThreshold: options.weight * value,\n higherThreshold: +Infinity,\n numSlicesToProject,\n overwrite,\n }\n\n // Run threshold volume by the new range\n thresholdVolumeByRange(\n toolGroupUID,\n annotations,\n referenceVolumes,\n segmentationData,\n rangeOptions\n )\n}\n\nfunction _getStrategyFn(statistic) {\n let fn, baseValue\n if (statistic === 'min') {\n baseValue = Infinity\n fn = (number, minValue) => {\n if (number < minValue) {\n minValue = number\n }\n return minValue\n }\n } else if (statistic === 'max') {\n baseValue = -Infinity\n fn = (number, maxValue) => {\n if (number > maxValue) {\n maxValue = number\n }\n return maxValue\n }\n } else {\n throw new Error('Statistics other than min or max are not supported yet')\n }\n return [fn, baseValue]\n}\n\nexport default thresholdVolumeByRoiStats\n","import { Types } from '@cornerstonejs/core'\nimport {\n volumeLoader,\n utilities as csUtils,\n} from '@cornerstonejs/core'\n\n/**\n * Given a list of labelmaps (with the possibility of overlapping regions), and\n * a segmentIndex it creates a new labelmap with the same dimensions as the input labelmaps,\n * but merges them into a single labelmap for the segmentIndex. It wipes out\n * all other segment Indices. This is useful for calculating statistics regarding\n * a specific segment when there are overlapping regions between labelmap (e.g. TMTV)\n *\n * @param labelmaps - Array of labelmaps\n * @param segmentIndex - The segment index to merge\n * @returns Merged labelmap\n */\nfunction createMergedLabelmapForIndex(\n labelmaps: Array<Types.IImageVolume>,\n segmentIndex = 1,\n uid = 'mergedLabelmap'\n): Types.IImageVolume {\n labelmaps.forEach(({ direction, dimensions, origin, spacing }) => {\n if (\n !csUtils.isEqual(dimensions, labelmaps[0].dimensions) ||\n !csUtils.isEqual(direction, labelmaps[0].direction) ||\n !csUtils.isEqual(spacing, labelmaps[0].spacing) ||\n !csUtils.isEqual(origin, labelmaps[0].origin)\n ) {\n throw new Error('labelmaps must have the same size and shape')\n }\n })\n\n const labelmap = labelmaps[0]\n\n const arrayType = labelmap.scalarData.constructor\n const outputData = new arrayType(labelmap.scalarData.length)\n\n labelmaps.forEach((labelmap) => {\n const { scalarData } = labelmap\n for (let i = 0; i < scalarData.length; i++) {\n if (scalarData[i] === segmentIndex) {\n outputData[i] = segmentIndex\n }\n }\n })\n\n const options = {\n scalarData: outputData,\n metadata: labelmap.metadata,\n spacing: labelmap.spacing,\n origin: labelmap.origin,\n direction: labelmap.direction,\n dimensions: labelmap.dimensions,\n }\n\n const preventCache = true\n // Todo: following should be async\n const mergedVolume = volumeLoader.createLocalVolume(\n options,\n uid,\n preventCache\n )\n\n return mergedVolume\n}\n\nexport default createMergedLabelmapForIndex\n","import { isValidLabelmapConfig } from '../../tools/displayTools/Labelmap/LabelmapConfig'\nimport SegmentationRepresentation from '../../enums/SegmentationRepresentations'\nimport { RepresentationConfig } from '../../types/SegmentationStateTypes'\n\n/**\n * Given a representation type and a configuration, return true if the\n * configuration is valid for that representation type\n * @param representationType - The type of segmentation representation\n * @param config - RepresentationConfig\n * @returns A boolean value.\n */\nexport default function isValidRepresentationConfig(\n representationType: string,\n config: RepresentationConfig\n): boolean {\n switch (representationType) {\n case SegmentationRepresentation.Labelmap:\n return isValidLabelmapConfig(config)\n default:\n throw new Error(`Unknown representation type: ${representationType}`)\n }\n}\n","import getDefaultLabelmapConfig from '../../tools/displayTools/Labelmap/LabelmapConfig'\nimport SegmentationRepresentation from '../../enums/SegmentationRepresentations'\n\n/**\n * It returns a configuration object for the given representation type.\n * @param representationType - The type of segmentation representation\n * @returns A representation configuration object.\n */\nexport default function getDefaultRepresentationConfig(\n representationType: string\n) {\n switch (representationType) {\n case SegmentationRepresentation.Labelmap:\n return getDefaultLabelmapConfig()\n default:\n throw new Error(`Unknown representation type: ${representationType}`)\n }\n}\n","// import fillOutsideBoundingBox from './fillOutsideBoundingBox'\nimport {\n getBoundingBoxAroundShape,\n extend2DBoundingBoxInViewAxis,\n} from './getBoundingBoxUtils'\nimport thresholdVolumeByRange from './thresholdVolumeByRange'\nimport thresholdVolumeByRoiStats from './thresholdVolumeByRoiStats'\nimport createMergedLabelmapForIndex from './createMergedLabelmapForIndex'\nimport isValidRepresentationConfig from './isValidRepresentationConfig'\nimport getDefaultRepresentationConfig from './getDefaultRepresentationConfig'\n\nexport {\n getBoundingBoxAroundShape,\n extend2DBoundingBoxInViewAxis,\n // fillOutsideBoundingBox,\n thresholdVolumeByRange,\n thresholdVolumeByRoiStats,\n createMergedLabelmapForIndex,\n isValidRepresentationConfig,\n getDefaultRepresentationConfig,\n}\n\nexport default {\n getBoundingBoxAroundShape,\n extend2DBoundingBoxInViewAxis,\n // fillOutsideBoundingBox,\n thresholdVolumeByRange,\n thresholdVolumeByRoiStats,\n createMergedLabelmapForIndex,\n isValidRepresentationConfig,\n getDefaultRepresentationConfig,\n}\n","import { defaultSegmentationStateManager } from './SegmentationStateManager'\nimport {\n triggerSegmentationStateModified,\n triggerSegmentationGlobalStateModified,\n} from './triggerSegmentationEvents'\nimport {\n GlobalSegmentationState,\n GlobalSegmentationData,\n ColorLUT,\n ToolGroupSpecificSegmentationState,\n ToolGroupSpecificSegmentationData,\n SegmentationConfig,\n} from '../../types/SegmentationStateTypes'\n\nimport {\n getDefaultRepresentationConfig,\n isValidRepresentationConfig,\n} from '../../utilities/segmentation'\nimport { deepMerge } from '../../utilities'\n\n/**\n * It returns the defaultSegmentationStateManager.\n */\nfunction getDefaultSegmentationStateManager() {\n return defaultSegmentationStateManager\n}\n\n/*************************\n *\n * GLOBAL STATE\n *\n **************************/\n\n/**\n * Get the global segmentation data for a given segmentation UID\n * @param segmentationUID - The UID of the segmentation to get the global\n * data for.\n * @returns A GlobalSegmentationData object\n */\nfunction getGlobalSegmentationDataByUID(\n segmentationUID: string\n): GlobalSegmentationData {\n const segmentationStateManager = getDefaultSegmentationStateManager()\n return segmentationStateManager.getGlobalSegmentationData(segmentationUID)\n}\n\n/**\n * Add a new global segmentation data to the segmentation state manager, and\n * triggers SEGMENTATION_STATE_MODIFIED event if not suppressed.\n *\n * @param segmentationData - The data to add to the global segmentation state\n * @param suppressEvents - If true, the event will not be triggered.\n */\nfunction addGlobalSegmentationData(\n segmentationData: GlobalSegmentationData,\n suppressEvents?: boolean\n): void {\n const segmentationStateManager = getDefaultSegmentationStateManager()\n segmentationStateManager.addGlobalSegmentationData(segmentationData)\n\n if (!suppressEvents) {\n triggerSegmentationGlobalStateModified(segmentationData.volumeUID)\n }\n}\n\n/**\n * Get all global segmentation states, which includes array of all global\n * segmentation data.\n * @returns An array of objects, each of which represents a global segmentation\n * data.\n */\nfunction getGlobalSegmentationState(): GlobalSegmentationState | [] {\n const segmentationStateManager = getDefaultSegmentationStateManager()\n return segmentationStateManager.getGlobalSegmentationState()\n}\n\n/***************************\n *\n * ToolGroup Specific State\n *\n ***************************/\n\n/**\n * Get the segmentation state for a tool group. It will return an array of\n * segmentation data objects.\n * @param toolGroupUID - The unique identifier of the tool group.\n * @returns An array of segmentation data objects.\n */\nfunction getSegmentationState(\n toolGroupUID: string\n): ToolGroupSpecificSegmentationState | [] {\n const segmentationStateManager = getDefaultSegmentationStateManager()\n return segmentationStateManager.getSegmentationState(toolGroupUID)\n}\n\n/**\n * Get the segmentation data object for a given tool group and\n * segmentation data UID. It searches all the toolGroup specific segmentation\n * data objects and returns the first one that matches the UID.\n * @param toolGroupUID - The UID of the tool group that the segmentation\n * data belongs to.\n * @param segmentationDataUID - The UID of the segmentation data to\n * retrieve.\n * @returns Segmentation Data object.\n */\nfunction getSegmentationDataByUID(\n toolGroupUID: string,\n segmentationDataUID: string\n): ToolGroupSpecificSegmentationData | undefined {\n const segmentationStateManager = getDefaultSegmentationStateManager()\n return segmentationStateManager.getSegmentationDataByUID(\n toolGroupUID,\n segmentationDataUID\n )\n}\n\n/**\n * Remove a segmentation data from the segmentation state manager for a toolGroup.\n * It fires SEGMENTATION_STATE_MODIFIED event.\n *\n * @triggers SEGMENTATION_STATE_MODIFIED\n *\n * @param toolGroupUID - The UID of the tool group that the segmentation\n * data belongs to.\n * @param segmentationDataUID - The UID of the segmentation data to\n * remove.\n */\nfunction removeSegmentationData(\n toolGroupUID: string,\n segmentationDataUID: string\n): void {\n const segmentationStateManager = getDefaultSegmentationStateManager()\n segmentationStateManager.removeSegmentationData(\n toolGroupUID,\n segmentationDataUID\n )\n\n triggerSegmentationStateModified(toolGroupUID)\n}\n\n/**\n * Add the given segmentation data to the given tool group state. It fires\n * SEGMENTATION_STATE_MODIFIED event if not suppressed.\n *\n * @triggers SEGMENTATION_STATE_MODIFIED\n *\n * @param toolGroupUID - The UID of the tool group that the segmentation data is for.\n * @param segmentationData - The data to add to the segmentation state.\n * @param suppressEvents - boolean\n */\nfunction addSegmentationData(\n toolGroupUID: string,\n segmentationData: ToolGroupSpecificSegmentationData,\n suppressEvents?: boolean\n): void {\n const segmentationStateManager = getDefaultSegmentationStateManager()\n _initGlobalStateIfNecessary(segmentationStateManager, segmentationData)\n\n segmentationStateManager.addSegmentationData(toolGroupUID, segmentationData)\n\n if (!suppressEvents) {\n triggerSegmentationStateModified(toolGroupUID)\n }\n}\n\n/***************************\n *\n * Global Configuration\n *\n ***************************/\n\n/**\n * It returns the global segmentation config. Note that the toolGroup-specific\n * configuration has higher priority than the global configuration and overwrites\n * the global configuration for each representation.\n * @returns The global segmentation configuration for all segmentations.\n */\nfunction getGlobalSegmentationConfig(): SegmentationConfig {\n const segmentationStateManager = getDefaultSegmentationStateManager()\n return segmentationStateManager.getGlobalSegmentationConfig()\n}\n\n/**\n * Set the global segmentation configuration. It fires SEGMENTATION_GLOBAL_STATE_MODIFIED\n * event if not suppressed.\n *\n * @triggers SEGMENTATION_GLOBAL_STATE_MODIFIED\n * @param config - The new global segmentation config.\n * @param suppressEvents - If true, the `segmentationGlobalStateModified` event will not be triggered.\n */\nfunction setGlobalSegmentationConfig(\n config: SegmentationConfig,\n suppressEvents?: boolean\n): void {\n const segmentationStateManager = getDefaultSegmentationStateManager()\n segmentationStateManager.setGlobalSegmentationConfig(config)\n\n if (!suppressEvents) {\n triggerSegmentationGlobalStateModified()\n }\n}\n\n/***************************\n *\n * ToolGroup Specific Configuration\n *\n ***************************/\n\n/**\n * Set the segmentation config for the provided toolGroup. ToolGroup specific\n * configuration overwrites the global configuration for each representation.\n * It fires SEGMENTATION_STATE_MODIFIED event if not suppressed.\n *\n * @triggers SEGMENTATION_STATE_MODIFIED\n * @param toolGroupUID - The UID of the tool group that the segmentation\n * config is being set for.\n * @param config - The new configuration for the tool group.\n * @param suppressEvents - If true, the event will not be triggered.\n */\nfunction setSegmentationConfig(\n toolGroupUID: string,\n config: SegmentationConfig,\n suppressEvents?: boolean\n): void {\n const segmentationStateManager = getDefaultSegmentationStateManager()\n segmentationStateManager.setSegmentationConfig(toolGroupUID, config)\n\n if (!suppressEvents) {\n triggerSegmentationStateModified(toolGroupUID)\n }\n}\n\n/**\n * Get the segmentation config for a given tool group which contains each\n * segmentation representation configuration.\n * @param toolGroupUID - The UID of the tool group that the segmentation\n * config belongs to.\n * @returns A SegmentationConfig object.\n */\nfunction getSegmentationConfig(toolGroupUID: string): SegmentationConfig {\n const segmentationStateManager = getDefaultSegmentationStateManager()\n return segmentationStateManager.getSegmentationConfig(toolGroupUID)\n}\n\n/***************************\n *\n * Utilities\n *\n ***************************/\n\n/**\n * Get the tool group UIDs that have a segmentation with the given UID\n * @param segmentationUID - The UID of the segmentation to get the tool\n * groups for.\n * @returns An array of tool group UIDs.\n */\nfunction getToolGroupsWithSegmentation(segmentationUID: string): string[] {\n const segmentationStateManager = getDefaultSegmentationStateManager()\n return segmentationStateManager.getToolGroupsWithSegmentation(segmentationUID)\n}\n\n/**\n * Get the list of all tool groups currently in the segmentation state manager.\n * @returns An array of tool group UIDs.\n */\nfunction getToolGroups(): string[] {\n const segmentationStateManager = getDefaultSegmentationStateManager()\n return segmentationStateManager.getToolGroups()\n}\n\n/**\n * Get the color lut for a given index\n * @param index - The index of the color lut to retrieve.\n * @returns A ColorLUT array.\n */\nfunction getColorLut(index: number): ColorLUT | undefined {\n const segmentationStateManager = getDefaultSegmentationStateManager()\n return segmentationStateManager.getColorLut(index)\n}\n\n/**\n * Add a color LUT to the segmentation state manager\n * @param colorLut - The color LUT array to add.\n * @param index - The index of the color LUT to add.\n */\nfunction addColorLUT(colorLut: ColorLUT, index: number): void {\n const segmentationStateManager = getDefaultSegmentationStateManager()\n segmentationStateManager.addColorLUT(colorLut, index)\n // Todo: trigger event color LUT added\n}\n\n/**\n * Set the active segmentation data for a tool group. It searches the segmentation\n * state of the toolGroup and sets the active segmentation data to the one with\n * the given UID. It fires SEGMENTATION_STATE_MODIFIED event if not suppressed.\n *\n * @triggers SEGMENTATION_STATE_MODIFIED\n *\n * @param toolGroupUID - The UID of the tool group that owns the segmentation data.\n * @param segmentationDataUID - The UID of the segmentation data to set as active.\n * @param suppressEvents - If true, the segmentation state will be updated, but no events will be triggered.\n */\nfunction setActiveSegmentationData(\n toolGroupUID: string,\n segmentationDataUID: string,\n suppressEvents?: boolean\n): void {\n const segmentationStateManager = getDefaultSegmentationStateManager()\n segmentationStateManager.setActiveSegmentationData(\n toolGroupUID,\n segmentationDataUID\n )\n\n if (!suppressEvents) {\n triggerSegmentationStateModified(toolGroupUID)\n }\n}\n\n/**\n * Get the active segmentation data for a given tool group by searching the\n * segmentation state of the tool group and returning the segmentation data with\n * the given UID.\n *\n * @param toolGroupUID - The UID of the tool group that the segmentation\n * data belongs to.\n * @returns The active segmentation data for the tool group.\n */\nfunction getActiveSegmentationData(\n toolGroupUID: string\n): ToolGroupSpecificSegmentationData | undefined {\n const segmentationStateManager = getDefaultSegmentationStateManager()\n\n const toolGroupSegmentations =\n segmentationStateManager.getSegmentationState(toolGroupUID)\n\n if (toolGroupSegmentations.length === 0) {\n return\n }\n\n const activeSegmentationData = toolGroupSegmentations.find(\n (segmentationData: ToolGroupSpecificSegmentationData) =>\n segmentationData.active\n )\n\n return activeSegmentationData\n}\n\n/**\n * If no global state exists, it create a default one and If the global config\n * is not valid, create a default one\n *\n * @param segmentationStateManager - The state manager for the segmentation.\n * @param segmentationData - The segmentation data that we want to add to the\n * global state.\n */\nfunction _initGlobalStateIfNecessary(\n segmentationStateManager,\n segmentationData\n) {\n const globalSegmentationData = getGlobalSegmentationDataByUID(\n segmentationData.volumeUID\n )\n // for the representation, if no global config exists, create default one\n const {\n representation: { type: representationType },\n } = segmentationData\n\n const globalConfig = getGlobalSegmentationConfig()\n const globalRepresentationConfig =\n globalConfig.representations[representationType]\n const validConfig = isValidRepresentationConfig(\n representationType,\n globalRepresentationConfig\n )\n\n // If global segmentationData is not found, or if the global config is not\n // valid, we use default values to create both, but we need to only\n // fire the event for global state modified once, so we suppress each events.\n const suppressEvents = !globalSegmentationData || !validConfig\n\n // if no global state exists, create a default one\n if (!globalSegmentationData) {\n const { volumeUID } = segmentationData\n\n const defaultGlobalData: GlobalSegmentationData = {\n volumeUID: volumeUID,\n label: volumeUID,\n referenceVolumeUID: null,\n cachedStats: {},\n referenceImageId: null,\n activeSegmentIndex: 1,\n segmentsLocked: new Set(),\n }\n\n addGlobalSegmentationData(defaultGlobalData, suppressEvents)\n }\n\n // Todo: we can check the validity of global config for each representation\n // when we are setting it up at the setGlobalSegmentationConfig function, not here\n if (!validConfig) {\n // create default config\n const defaultRepresentationConfig =\n getDefaultRepresentationConfig(representationType)\n\n const mergedRepresentationConfig = deepMerge(\n defaultRepresentationConfig,\n globalRepresentationConfig\n )\n\n const newGlobalConfig = {\n ...globalConfig,\n representations: {\n ...globalConfig.representations,\n [representationType]: mergedRepresentationConfig,\n },\n }\n\n setGlobalSegmentationConfig(newGlobalConfig, suppressEvents)\n }\n\n // If we have suppressed events, means that we have created a new global state\n // and/or a new default config for the representation, so we need to trigger\n // the event to notify the listeners.\n if (suppressEvents) {\n triggerSegmentationGlobalStateModified(segmentationData.volumeUID)\n }\n}\n\nexport {\n // config\n getGlobalSegmentationConfig,\n getSegmentationConfig,\n setGlobalSegmentationConfig,\n setSegmentationConfig,\n // colorLUT\n addColorLUT,\n getColorLut,\n // get/set global state\n getGlobalSegmentationState,\n getGlobalSegmentationDataByUID,\n addGlobalSegmentationData,\n // toolGroup state\n getSegmentationState,\n addSegmentationData,\n removeSegmentationData,\n getSegmentationDataByUID,\n setActiveSegmentationData,\n getActiveSegmentationData,\n getToolGroupsWithSegmentation,\n getToolGroups,\n // Utility\n getDefaultSegmentationStateManager,\n}\n","import { eventTarget, Enums } from '@cornerstonejs/core'\nimport { getDefaultAnnotationManager } from './stateManagement/annotation/annotationState'\nimport { getDefaultSegmentationStateManager } from './stateManagement/segmentation/segmentationState'\nimport { Events as TOOLS_EVENTS } from './enums'\nimport { addEnabledElement, removeEnabledElement } from './store'\nimport { resetCornerstoneToolsState } from './store/state'\nimport {\n annotationSelectionListener,\n segmentationDataModifiedEventListener,\n segmentationStateModifiedEventListener,\n annotationModifiedListener,\n} from './eventListeners'\n\nimport ToolGroupManager from './store/ToolGroupManager'\n\nlet csToolsInitialized = false\n\n/**\n * Initialize the cornerstoneTools package. It will add event listeners for mouse\n * and keyboard events.\n * @param defaultConfiguration - A configuration object that will be used to\n * initialize the tool.\n */\nexport function init(defaultConfiguration = {}): void {\n if (csToolsInitialized) {\n return\n }\n\n _addCornerstoneEventListeners()\n _addCornerstoneToolsEventListeners()\n\n csToolsInitialized = true\n}\n\n/**\n * It destroys and cleanup state for cornerstone3DTools. It removes all the tools\n * that were added to the tool groups and restore states. It also removes all\n * event listeners.\n */\nexport function destroy(): void {\n _removeCornerstoneEventListeners()\n _removeCornerstoneToolsEventListeners()\n\n // Important: destroy ToolGroups first, in order for cleanup to work correctly for the\n // added tools.\n ToolGroupManager.destroy()\n\n // Remove all tools\n resetCornerstoneToolsState()\n\n // remove all annotation.\n const annotationManager = getDefaultAnnotationManager()\n const segmentationStateManager = getDefaultSegmentationStateManager()\n\n annotationManager.restoreAnnotations({})\n segmentationStateManager.resetState()\n csToolsInitialized = false\n}\n\n/**\n * Wires up event listeners for the Cornerstone#ElementDisabled and\n * Cornerstone#ElementEnabled events.\n *\n * @internal\n */\nfunction _addCornerstoneEventListeners(): void {\n // Clear any listeners that may already be set\n _removeCornerstoneEventListeners()\n\n const elementEnabledEvent = Enums.Events.ELEMENT_ENABLED\n const elementDisabledEvent = Enums.Events.ELEMENT_DISABLED\n\n eventTarget.addEventListener(elementEnabledEvent, addEnabledElement)\n eventTarget.addEventListener(elementDisabledEvent, removeEnabledElement)\n}\n\n/**\n * Removes event listeners for the Cornerstone#ElementDisabled and\n * Cornerstone#ElementEnabled events.\n *\n */\nfunction _removeCornerstoneEventListeners(): void {\n const elementEnabledEvent = Enums.Events.ELEMENT_ENABLED\n const elementDisabledEvent = Enums.Events.ELEMENT_DISABLED\n\n eventTarget.removeEventListener(elementEnabledEvent, addEnabledElement)\n eventTarget.removeEventListener(elementDisabledEvent, removeEnabledElement)\n}\n\n/**\n * It adds an event listener to the event target (the cornerstoneTools object) for\n * the annotation selected and annotation modified events.\n */\nfunction _addCornerstoneToolsEventListeners() {\n // Clear any listeners that may already be set\n _removeCornerstoneToolsEventListeners()\n\n const selectionEvent = TOOLS_EVENTS.ANNOTATION_SELECTION_CHANGE\n const segmentationDataModified = TOOLS_EVENTS.SEGMENTATION_DATA_MODIFIED\n const segmentationStateModified = TOOLS_EVENTS.SEGMENTATION_STATE_MODIFIED\n const modifiedEvent = TOOLS_EVENTS.ANNOTATION_MODIFIED\n\n eventTarget.addEventListener(selectionEvent, annotationSelectionListener)\n eventTarget.addEventListener(\n segmentationDataModified,\n segmentationDataModifiedEventListener\n )\n eventTarget.addEventListener(\n segmentationStateModified,\n segmentationStateModifiedEventListener\n )\n\n eventTarget.addEventListener(selectionEvent, annotationSelectionListener)\n eventTarget.addEventListener(modifiedEvent, annotationModifiedListener)\n}\n\n/**\n * Remove the event listener for the the annotation selected and annotation modified events.\n */\nfunction _removeCornerstoneToolsEventListeners() {\n const selectionEvent = TOOLS_EVENTS.ANNOTATION_SELECTION_CHANGE\n const modifiedEvent = TOOLS_EVENTS.ANNOTATION_MODIFIED\n const segmentationDataModified = TOOLS_EVENTS.SEGMENTATION_DATA_MODIFIED\n const segmentationStateModified = TOOLS_EVENTS.SEGMENTATION_STATE_MODIFIED\n\n eventTarget.removeEventListener(selectionEvent, annotationSelectionListener)\n eventTarget.removeEventListener(\n segmentationDataModified,\n segmentationDataModifiedEventListener\n )\n eventTarget.removeEventListener(\n segmentationStateModified,\n segmentationStateModifiedEventListener\n )\n\n eventTarget.removeEventListener(selectionEvent, annotationSelectionListener)\n eventTarget.removeEventListener(modifiedEvent, annotationModifiedListener)\n}\n\nexport default init\n","import { getRenderingEngine, Types } from '@cornerstonejs/core'\n\n/**\n * Synchronizer callback to synchronize the camera. Synchronization\n *\n * @param synchronizerInstance - The Instance of the Synchronizer\n * @param sourceViewport - The list of UIDs defining the source viewport.\n * @param targetViewport - The list of UIDs defining the target viewport.\n * @param cameraModifiedEvent - The CAMERA_MODIFIED event.\n */\nexport default function cameraSyncCallback(\n synchronizerInstance,\n sourceViewport: Types.IViewportUID,\n targetViewport: Types.IViewportUID,\n cameraModifiedEvent: CustomEvent\n): void {\n // We need a helper for this\n if (\n sourceViewport.renderingEngineUID === targetViewport.renderingEngineUID &&\n sourceViewport.viewportUID === targetViewport.viewportUID\n ) {\n return\n }\n\n const { camera } = cameraModifiedEvent.detail\n\n const renderingEngine = getRenderingEngine(targetViewport.renderingEngineUID)\n if (!renderingEngine) {\n throw new Error(\n `No RenderingEngine for UID: ${targetViewport.renderingEngineUID}`\n )\n }\n\n const tViewport = renderingEngine.getViewport(targetViewport.viewportUID)\n\n // TODO: only sync in-plane movements if one viewport is a stack viewport\n\n // Todo: we shouldn't set camera, we should set the focalPoint\n // to the nearest slice center world position\n tViewport.setCamera(camera)\n tViewport.render()\n}\n","import { createSynchronizer } from '../../store/SynchronizerManager'\nimport { Enums } from '@cornerstonejs/core'\nimport cameraSyncCallback from '../callbacks/cameraSyncCallback'\nimport Synchronizer from '../../store/SynchronizerManager/Synchronizer'\n\nconst { CAMERA_MODIFIED } = Enums.Events\n\n/**\n * A helper that creates a new `Synchronizer` which listens to the `CAMERA_MODIFIED`\n * rendering event and calls the `cameraSyncCallback`.\n *\n * @param synchronizerName - The name of the synchronizer.\n *\n * @returns A new `Synchronizer` instance.\n */\nexport default function createCameraPositionSynchronizer(\n synchronizerName: string\n): Synchronizer {\n const cameraPositionSynchronizer = createSynchronizer(\n synchronizerName,\n CAMERA_MODIFIED,\n cameraSyncCallback\n )\n\n return cameraPositionSynchronizer\n}\n","import {\n getRenderingEngine,\n StackViewport,\n Types,\n VolumeViewport,\n} from '@cornerstonejs/core'\n\n/**\n * Synchronizer callback to synchronize the voi of volumeActors of identical volumes\n * in different viewports.\n *\n * @param synchronizerInstance - The Instance of the Synchronizer\n * @param sourceViewport - The list of UIDs defining the source viewport.\n * @param targetViewport - The list of UIDs defining the target viewport.\n * @param voiModifiedEvent - The VOI_MODIFIED event.\n */\nexport default function voiSyncCallback(\n synchronizerInstance,\n sourceViewport: Types.IViewportUID,\n targetViewport: Types.IViewportUID,\n voiModifiedEvent: Types.EventTypes.VoiModifiedEvent\n): void {\n const eventDetail = voiModifiedEvent.detail\n const { volumeUID, range } = eventDetail\n\n const renderingEngine = getRenderingEngine(targetViewport.renderingEngineUID)\n if (!renderingEngine) {\n throw new Error(\n `Rendering Engine does not exist: ${targetViewport.renderingEngineUID}`\n )\n }\n\n const tViewport = renderingEngine.getViewport(targetViewport.viewportUID)\n\n if (tViewport instanceof VolumeViewport) {\n const actor = tViewport.getActor(volumeUID)\n\n if (actor) {\n actor.volumeActor\n .getProperty()\n .getRGBTransferFunction(0)\n .setRange(range.lower, range.upper)\n }\n } else if (tViewport instanceof StackViewport) {\n tViewport.setProperties({\n voiRange: range,\n })\n } else {\n throw new Error('Viewport type not supported.')\n }\n\n tViewport.render()\n}\n","import { createSynchronizer } from '../../store/SynchronizerManager'\nimport { Enums } from '@cornerstonejs/core'\nimport voiSyncCallback from '../callbacks/voiSyncCallback'\nimport Synchronizer from '../../store/SynchronizerManager/Synchronizer'\n\n/**\n * A helper that creates a new `Synchronizer`\n * which listens to the `VOI_MODIFIED` rendering event and calls the `voiSyncCallback`.\n *\n * @param synchronizerName - The name of the synchronizer.\n *\n * @returns A new `Synchronizer` instance.\n */\nexport default function createVOISynchronizer(\n synchronizerName: string\n): Synchronizer {\n const VOISynchronizer = createSynchronizer(\n synchronizerName,\n Enums.Events.VOI_MODIFIED,\n voiSyncCallback\n )\n\n return VOISynchronizer\n}\n","import { BaseTool } from './base'\nimport { getEnabledElement } from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\n\nimport { PublicToolProps, ToolProps } from '../types'\n\n/**\n * Tool that pans the camera in the plane defined by the sliceNormal and the viewUp.\n */\nexport default class PanTool extends BaseTool {\n static toolName = 'Pan'\n touchDragCallback: () => void\n mouseDragCallback: () => void\n\n constructor(\n toolProps: PublicToolProps = {},\n defaultToolProps: ToolProps = {\n supportedInteractionTypes: ['Mouse', 'Touch'],\n }\n ) {\n super(toolProps, defaultToolProps)\n\n this.touchDragCallback = this._dragCallback.bind(this)\n this.mouseDragCallback = this._dragCallback.bind(this)\n }\n\n _dragCallback(evt) {\n const { element, deltaPoints } = evt.detail\n const enabledElement = getEnabledElement(element)\n\n const deltaPointsWorld = deltaPoints.world\n const camera = enabledElement.viewport.getCamera()\n const { focalPoint, position } = camera\n\n const updatedPosition = <Types.Point3>[\n position[0] - deltaPointsWorld[0],\n position[1] - deltaPointsWorld[1],\n position[2] - deltaPointsWorld[2],\n ]\n\n const updatedFocalPoint = <Types.Point3>[\n focalPoint[0] - deltaPointsWorld[0],\n focalPoint[1] - deltaPointsWorld[1],\n focalPoint[2] - deltaPointsWorld[2],\n ]\n\n enabledElement.viewport.setCamera({\n focalPoint: updatedFocalPoint,\n position: updatedPosition,\n })\n enabledElement.viewport.render()\n }\n}\n","import { BaseTool } from './base'\nimport {\n getEnabledElement,\n Enums,\n triggerEvent,\n VolumeViewport,\n StackViewport,\n utilities,\n cache,\n} from '@cornerstonejs/core'\n\nimport type { Types } from '@cornerstonejs/core'\n\n// Todo: should move to configuration\nconst DEFAULT_MULTIPLIER = 4\nconst DEFAULT_IMAGE_DYNAMIC_RANGE = 1024\nconst PT = 'PT'\n\n/**\n * WindowLevel tool manipulates the windowLevel applied to a viewport. It\n * provides a way to set the windowCenter and windowWidth of a viewport\n * by dragging mouse over the image.\n *\n */\nexport default class WindowLevelTool extends BaseTool {\n static toolName = 'WindowLevel'\n touchDragCallback: () => void\n mouseDragCallback: () => void\n\n constructor(\n toolProps = {},\n defaultToolProps = {\n supportedInteractionTypes: ['Mouse', 'Touch'],\n }\n ) {\n super(toolProps, defaultToolProps)\n\n this.touchDragCallback = this._dragCallback.bind(this)\n this.mouseDragCallback = this._dragCallback.bind(this)\n }\n\n _dragCallback(evt) {\n const { element, deltaPoints } = evt.detail\n const enabledElement = getEnabledElement(element)\n const { renderingEngine, viewportUID, viewport } = enabledElement\n\n let volumeUID,\n volumeActor,\n lower,\n upper,\n rgbTransferFunction,\n modality,\n newRange,\n viewportsContainingVolumeUID\n let useDynamicRange = false\n\n if (viewport instanceof VolumeViewport) {\n volumeUID = this.getTargetUID(viewport as Types.IVolumeViewport)\n ;({ volumeActor } = viewport.getActor(volumeUID))\n rgbTransferFunction = volumeActor.getProperty().getRGBTransferFunction(0)\n viewportsContainingVolumeUID =\n utilities.getVolumeViewportsContainingVolumeUID(\n volumeUID,\n renderingEngine.uid\n )\n ;[lower, upper] = rgbTransferFunction.getRange()\n modality = cache.getVolume(volumeUID).metadata.Modality\n useDynamicRange = true\n } else {\n const properties = viewport.getProperties()\n modality = (viewport as Types.IStackViewport).modality\n ;({ lower, upper } = properties.voiRange)\n }\n\n // If modality is PT, treat it special to not include the canvas delta in\n // the x direction. For other modalities, use the canvas delta in both\n // directions, and if the viewport is a volumeViewport, the multiplier\n // is calculate using the volume min and max.\n if (modality === PT) {\n newRange = this.getPTNewRange({\n deltaPointsCanvas: deltaPoints.canvas,\n lower,\n upper,\n clientHeight: element.clientHeight,\n })\n } else {\n newRange = this.getNewRange({\n deltaPointsCanvas: deltaPoints.canvas,\n useDynamicRange,\n volumeUID,\n lower,\n upper,\n })\n }\n\n const eventDetail: Types.EventTypes.VoiModifiedEventDetail = {\n volumeUID,\n viewportUID,\n range: newRange,\n }\n\n triggerEvent(element, Enums.Events.VOI_MODIFIED, eventDetail)\n\n if (viewport instanceof StackViewport) {\n viewport.setProperties({\n voiRange: newRange,\n })\n\n viewport.render()\n return\n }\n\n rgbTransferFunction.setRange(newRange.lower, newRange.upper)\n viewportsContainingVolumeUID.forEach((vp) => {\n vp.render()\n })\n }\n\n getPTNewRange({ deltaPointsCanvas, lower, upper, clientHeight }) {\n const deltaY = deltaPointsCanvas[1]\n const multiplier = 5 / clientHeight\n const wcDelta = deltaY * multiplier\n\n upper -= wcDelta\n upper = Math.max(upper, 0.1)\n\n return { lower, upper }\n }\n\n getNewRange({ deltaPointsCanvas, useDynamicRange, volumeUID, lower, upper }) {\n // Todo: enabling a viewport twice in a row sets the imageDynamicRange to be zero for some reason\n // 1 was too little\n const multiplier = useDynamicRange\n ? this._getMultiplyerFromDynamicRange(volumeUID)\n : DEFAULT_MULTIPLIER\n\n const wwDelta = deltaPointsCanvas[0] * multiplier\n const wcDelta = deltaPointsCanvas[1] * multiplier\n\n let { windowWidth, windowCenter } = utilities.windowLevel.toWindowLevel(\n lower,\n upper\n )\n\n windowWidth += wwDelta\n windowCenter += wcDelta\n\n windowWidth = Math.max(windowWidth, 1)\n\n // Convert back to range\n return utilities.windowLevel.toLowHighRange(windowWidth, windowCenter)\n }\n\n _getMultiplyerFromDynamicRange(volumeUID) {\n if (!volumeUID) {\n throw new Error('No volumeUID provided for the volume Viewport')\n }\n\n let multiplier = DEFAULT_MULTIPLIER\n const imageDynamicRange = this._getImageDynamicRange(volumeUID)\n\n const ratio = imageDynamicRange / DEFAULT_IMAGE_DYNAMIC_RANGE\n\n if (ratio > 1) {\n multiplier = Math.round(ratio)\n }\n\n return multiplier\n }\n\n _getImageDynamicRange = (volumeUID: string) => {\n const imageVolume = cache.getVolume(volumeUID)\n const { dimensions, scalarData } = imageVolume\n const middleSliceIndex = Math.floor(dimensions[2] / 2)\n\n // Todo: volume shouldn't only be streaming image volume, it can be imageVolume\n // if (!(imageVolume instanceof StreamingImageVolume)) {\n // return\n // }\n\n // const streamingVolume = <StreamingImageVolume>imageVolume\n\n // if (!streamingVolume.loadStatus.cachedFrames[middleSliceIndex]) {\n // return DEFAULT_IMAGE_DYNAMIC_RANGE\n // }\n\n const frameLength = dimensions[0] * dimensions[1]\n let bytesPerVoxel\n let TypedArrayConstructor\n\n if (scalarData instanceof Float32Array) {\n bytesPerVoxel = 4\n TypedArrayConstructor = Float32Array\n } else if (scalarData instanceof Uint8Array) {\n bytesPerVoxel = 1\n TypedArrayConstructor = Uint8Array\n }\n\n const buffer = scalarData.buffer\n const byteOffset = middleSliceIndex * frameLength * bytesPerVoxel\n const frame = new TypedArrayConstructor(buffer, byteOffset, frameLength)\n\n let min = Infinity\n let max = -Infinity\n\n for (let i = 0; i < frameLength; i++) {\n const voxel = frame[i]\n\n if (voxel < min) {\n min = voxel\n }\n\n if (voxel > max) {\n max = voxel\n }\n }\n\n return max - min\n }\n}\n","import { getEnabledElementByUIDs } from '@cornerstonejs/core'\nimport { BaseTool } from './base'\nimport { scrollThroughStack } from '../utilities/stackScrollTool'\nimport { PublicToolProps, ToolProps, EventTypes } from '../types'\n\n/**\n * The StackScrollTool is a tool that allows the user to scroll through a\n * stack of images by pressing the mouse click and dragging\n */\nexport default class StackScrollTool extends BaseTool {\n static toolName = 'StackScroll'\n touchDragCallback: () => void\n mouseDragCallback: () => void\n\n constructor(\n toolProps: PublicToolProps = {},\n defaultToolProps: ToolProps = {\n supportedInteractionTypes: ['Mouse', 'Touch'],\n configuration: {\n invert: false,\n },\n }\n ) {\n super(toolProps, defaultToolProps)\n\n this.touchDragCallback = this._dragCallback.bind(this)\n this.mouseDragCallback = this._dragCallback.bind(this)\n }\n\n _dragCallback(evt: EventTypes.MouseDragEventType) {\n const { deltaPoints, viewportUID, renderingEngineUID } = evt.detail\n const deltaFrames = deltaPoints.canvas[1]\n const { viewport } = getEnabledElementByUIDs(\n viewportUID,\n renderingEngineUID,\n )\n const volumeUID = this.getTargetUID(viewport)\n const { invert } = this.configuration\n\n scrollThroughStack(evt, deltaFrames, volumeUID, invert)\n }\n}\n","import { BaseTool } from './base'\nimport { scrollThroughStack } from '../utilities/stackScrollTool'\nimport { MouseWheelEventType } from '../types/EventTypes'\n\n/**\n * The StackScrollMouseWheelTool is a tool that allows the user to scroll through a\n * stack of images using the mouse wheel\n */\nexport default class StackScrollMouseWheelTool extends BaseTool {\n static toolName = 'StackScrollMouseWheel'\n\n _configuration: any\n\n constructor(\n toolProps = {},\n defaultToolProps = {\n supportedInteractionTypes: ['Mouse', 'Touch'],\n invert: false,\n }\n ) {\n super(toolProps, defaultToolProps)\n }\n\n mouseWheelCallback(evt: MouseWheelEventType): void {\n const { wheel } = evt.detail\n const { direction: deltaFrames } = wheel\n const { invert, volumeUID } = this.configuration\n scrollThroughStack(evt, deltaFrames, volumeUID, invert)\n }\n}\n","import { BaseTool } from './base'\n\nimport { getEnabledElement } from '@cornerstonejs/core'\nimport { PublicToolProps, ToolProps } from '../types'\n\n/**\n * ZoomTool tool manipulates the camera zoom applied to a viewport. It\n * provides a way to set the zoom of a viewport by dragging mouse over the image.\n *\n */\nexport default class ZoomTool extends BaseTool {\n static toolName = 'Zoom'\n touchDragCallback: () => void\n mouseDragCallback: () => void\n\n // Apparently TS says super _must_ be the first call? This seems a bit opinionated.\n constructor(\n toolProps: PublicToolProps = {},\n defaultToolProps: ToolProps = {\n supportedInteractionTypes: ['Mouse', 'Touch'],\n }\n ) {\n super(toolProps, defaultToolProps)\n\n /**\n * Will only fire two cornerstone events:\n * - TOUCH_DRAG\n * - MOUSE_DRAG\n *\n * Given that the tool is active and has matching bindings for the\n * underlying touch/mouse event.\n */\n this.touchDragCallback = this._dragCallback.bind(this)\n this.mouseDragCallback = this._dragCallback.bind(this)\n }\n\n // Takes ICornerstoneEvent, Mouse or Touch\n _dragCallback(evt) {\n const { element } = evt.detail\n const enabledElement = getEnabledElement(element)\n const { viewport } = enabledElement\n\n const camera = viewport.getCamera()\n\n if (camera.parallelProjection) {\n this._dragParallelProjection(evt, camera)\n } else {\n this._dragPerspectiveProjection(evt, camera)\n }\n\n viewport.render()\n }\n\n _dragParallelProjection = (evt, camera) => {\n const { element, deltaPoints } = evt.detail\n const enabledElement = getEnabledElement(element)\n const { viewport } = enabledElement\n const size = [element.clientWidth, element.clientHeight]\n\n const zoomScale = 1.5 / size[1]\n\n const deltaY = deltaPoints.canvas[1]\n\n const k = deltaY * zoomScale\n\n const newParallelScale = (1.0 - k) * camera.parallelScale\n\n // viewport.setCamera({ parallelScale: newParallelScale, deltaPoints });\n viewport.setCamera({ parallelScale: newParallelScale })\n }\n\n _dragPerspectiveProjection = (evt, camera) => {\n const { element, deltaPoints } = evt.detail\n const enabledElement = getEnabledElement(element)\n const { viewport } = enabledElement\n const size = [element.clientWidth, element.clientHeight]\n\n const range = camera.clippingRange\n const zoomScale = 1.5 * (range[1] / size[1])\n\n const { position, focalPoint, viewPlaneNormal } = camera\n\n const directionOfProjection = [\n -viewPlaneNormal[0],\n -viewPlaneNormal[1],\n -viewPlaneNormal[2],\n ]\n\n const deltaY = deltaPoints.canvas[1]\n\n const k = deltaY * zoomScale\n\n let tmp = k * directionOfProjection[0]\n position[0] += tmp\n focalPoint[0] += tmp\n\n tmp = k * directionOfProjection[1]\n position[1] += tmp\n focalPoint[1] += tmp\n\n tmp = k * directionOfProjection[2]\n position[2] += tmp\n focalPoint[2] += tmp\n\n viewport.setCamera({ position, focalPoint })\n }\n}\n","import { BaseTool } from './base'\nimport { getEnabledElement } from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\n\nimport { mat4, vec3 } from 'gl-matrix'\nimport { PublicToolProps, ToolProps } from '../types'\nimport { MouseWheelEventType } from '../types/EventTypes'\n\nconst DIRECTIONS = {\n X: [1, 0, 0],\n Y: [0, 1, 0],\n Z: [0, 0, 1],\n CUSTOM: [],\n}\n\n/**\n * Tool that rotates the camera on mouse wheel.\n * It rotates the camera around the focal point, and around a defined axis. Default\n * axis is set to be Z axis, but it can be configured to any custom normalized axis.\n *\n */\nexport default class VolumeRotateMouseWheelTool extends BaseTool {\n static toolName = 'VolumeRotateMouseWheel'\n _configuration: any\n\n constructor(\n toolProps: PublicToolProps = {},\n defaultToolProps: ToolProps = {\n supportedInteractionTypes: ['Mouse', 'Touch'],\n configuration: {\n direction: DIRECTIONS.Z,\n rotateIncrementDegrees: 0.5,\n },\n }\n ) {\n super(toolProps, defaultToolProps)\n }\n\n mouseWheelCallback(evt: MouseWheelEventType) {\n // https://github.com/kitware/vtk-js/blob/HEAD/Sources/Interaction/Manipulators/MouseCameraUnicamRotateManipulator/index.js#L73\n const { element, wheel } = evt.detail\n const enabledElement = getEnabledElement(element)\n const { viewport } = enabledElement\n const { direction, rotateIncrementDegrees } = this.configuration\n\n const camera = viewport.getCamera()\n const { viewUp, position, focalPoint } = camera\n\n const { direction: deltaY } = wheel\n\n const [cx, cy, cz] = focalPoint\n const [ax, ay, az] = direction\n\n const angle = deltaY * rotateIncrementDegrees\n\n // position[3] = 1.0\n // focalPoint[3] = 1.0\n // viewUp[3] = 0.0\n\n const newPosition: Types.Point3 = [0, 0, 0]\n const newFocalPoint: Types.Point3 = [0, 0, 0]\n const newViewUp: Types.Point3 = [0, 0, 0]\n\n const transform = mat4.identity(new Float32Array(16))\n mat4.translate(transform, transform, [cx, cy, cz])\n mat4.rotate(transform, transform, angle, [ax, ay, az])\n mat4.translate(transform, transform, [-cx, -cy, -cz])\n vec3.transformMat4(newPosition, position, transform)\n vec3.transformMat4(newFocalPoint, focalPoint, transform)\n\n mat4.identity(transform)\n mat4.rotate(transform, transform, angle, [ax, ay, az])\n vec3.transformMat4(<Types.Point3>newViewUp, viewUp, transform)\n\n viewport.setCamera({\n position: newPosition,\n viewUp: newViewUp,\n focalPoint: newFocalPoint,\n })\n\n viewport.render()\n }\n}\n","import { BaseTool } from './base'\nimport { getEnabledElement, VolumeViewport } from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\nimport { getPointInLineOfSightWithCriteria } from '../utilities/planar'\nimport jumpToWorld from '../utilities/viewport/jumpToWorld'\nimport { PublicToolProps, ToolProps } from '../types'\n\n/**\n * On a Maximum Intensity Projection (MIP) viewport, MIPJumpToClickTool allows the\n * user to click on a point in the MIP and the targetViewportUIDS (provided in the\n * tool configuration) will be scrolled (jumped) to the location of the point with\n * the highest intensity value in the MIP.\n */\nexport default class MIPJumpToClickTool extends BaseTool {\n static toolName = 'MIPJumpToClickTool'\n\n _bounds: any\n\n constructor(\n toolProps: PublicToolProps = {},\n defaultToolProps: ToolProps = {\n supportedInteractionTypes: ['Mouse', 'Touch'],\n configuration: {\n targetViewportUIDs: [],\n },\n }\n ) {\n super(toolProps, defaultToolProps)\n }\n\n /**\n * Handles the click event, and move the camera's focal point the brightest\n * point that is in the line of sight of camera. This function 1) search for the\n * brightest point in the line of sight, 2) move the camera to that point,\n * this triggers a cameraModified event which then 4) moves all other synced\n * viewports and their crosshairs.\n *\n * @param evt - click event\n */\n mouseClickCallback(evt): void {\n const { element, currentPoints } = evt.detail\n\n // 1. Getting the enabled element\n const enabledElement = getEnabledElement(element)\n const { viewport, renderingEngine } = enabledElement\n\n // 2. Getting the target volume that is clicked on\n const targetVolumeUID = this.getTargetUID(viewport as Types.IVolumeViewport)\n\n // 3. Criteria function to search for the point (maximum intensity)\n let maxIntensity = -Infinity\n const maxFn = (intensity, point) => {\n if (intensity > maxIntensity) {\n maxIntensity = intensity\n return point\n }\n }\n\n // 4. Search for the brightest point location in the line of sight\n const brightestPoint = getPointInLineOfSightWithCriteria(\n viewport as Types.IVolumeViewport,\n currentPoints.world,\n targetVolumeUID,\n maxFn\n )\n\n if (!brightestPoint || !brightestPoint.length) {\n return\n }\n\n const { targetViewportUIDs } = this.configuration\n\n // 6. Update all the targetedViewports to jump\n targetViewportUIDs.forEach((viewportUID) => {\n // Todo: current limitation is that we cannot jump in viewports\n // that don't belong to the renderingEngine of the source clicked viewport\n const viewport = renderingEngine.getViewport(viewportUID)\n\n if (viewport instanceof VolumeViewport) {\n jumpToWorld(viewport, brightestPoint)\n } else {\n console.warn(\n 'Cannot jump to specified world coordinates for a viewport that is not a VolumeViewport'\n )\n }\n })\n }\n}\n","import { VolumeViewport } from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\n\nimport { vec3 } from 'gl-matrix'\n\n// Todo: merge this utility functionality with Crosshair _jump\n/**\n * Uses the viewport's current camera to jump to a specific world coordinate\n * @param enabledElement - enabled element\n * @param jumpWorld - location in the world to jump to\n * @returns True if successful\n */\nexport default function jumpToWorld(\n viewport: Types.IVolumeViewport,\n jumpWorld: Types.Point3\n): true | undefined {\n // if not instance of volumeViewport, return\n if (!(viewport instanceof VolumeViewport)) {\n return\n }\n\n const { focalPoint } = viewport.getCamera()\n\n const delta: Types.Point3 = [0, 0, 0]\n vec3.sub(delta, jumpWorld, focalPoint)\n\n _applyShift(viewport, delta)\n\n return true\n}\n\nfunction _applyShift(viewport, delta) {\n const camera = viewport.getCamera()\n const normal = camera.viewPlaneNormal\n\n const dotProd = vec3.dot(delta, normal)\n const projectedDelta = vec3.fromValues(normal[0], normal[1], normal[2])\n\n vec3.scale(projectedDelta, projectedDelta, dotProd)\n\n if (\n Math.abs(projectedDelta[0]) > 1e-3 ||\n Math.abs(projectedDelta[1]) > 1e-3 ||\n Math.abs(projectedDelta[2]) > 1e-3\n ) {\n const newFocalPoint: Types.Point3 = [0, 0, 0]\n const newPosition: Types.Point3 = [0, 0, 0]\n\n vec3.add(newFocalPoint, camera.focalPoint, projectedDelta)\n vec3.add(newPosition, camera.position, projectedDelta)\n\n viewport.setCamera({\n focalPoint: newFocalPoint,\n position: newPosition,\n })\n viewport.render()\n }\n}\n","import { AnnotationTool } from './base'\n\nimport {\n getEnabledElementByUIDs,\n getEnabledElement,\n utilities as csUtils,\n} from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\n\nimport {\n addAnnotation,\n getAnnotations,\n removeAnnotation,\n} from '../stateManagement/annotation/annotationState'\nimport {\n drawCircle as drawCircleSvg,\n drawHandles as drawHandlesSvg,\n drawLine as drawLineSvg,\n} from '../drawingSvg'\nimport { vec2, vec3 } from 'gl-matrix'\nimport { state } from '../store'\nimport { Events } from '../enums'\nimport { getViewportUIDsWithToolToRender } from '../utilities/viewportFilters'\nimport { resetElementCursor, hideElementCursor } from '../cursors/elementCursor'\nimport { math } from '../utilities'\nimport vtkMath from 'vtk.js/Sources/Common/Core/Math'\nimport vtkMatrixBuilder from 'vtk.js/Sources/Common/Core/MatrixBuilder'\nimport { lineSegment } from '../utilities/math'\nimport {\n Annotation,\n Annotations,\n EventTypes,\n ToolHandle,\n PublicToolProps,\n ToolProps,\n InteractionTypes,\n} from '../types'\nimport { isAnnotationLocked } from '../stateManagement/annotation/annotationLocking'\nimport triggerAnnotationRenderForViewportUIDs from '../utilities/triggerAnnotationRenderForViewportUIDs'\nimport { MouseDragEventType } from '../types/EventTypes'\n\nconst { liangBarksyClip } = math.vec2\n\n// TODO: nested config is weird\ninterface ToolConfiguration {\n configuration?: {\n getReferenceLineColor?: (viewportUID: string) => string\n getReferenceLineControllable?: (viewportUID: string) => boolean\n getReferenceLineDraggableRotatable?: (viewportUID: string) => boolean\n getReferenceLineSlabThicknessControlsOn?: (viewportUID: string) => boolean\n shadow?: boolean\n }\n}\n\ntype ViewportInputs = Array<Types.IViewportUID>\n\ninterface CrosshairsAnnotation extends Annotation {\n data: {\n handles: {\n rotationPoints: any[] // rotation handles, used for rotation interactions\n slabThicknessPoints: any[] // slab thickness handles, used for setting the slab thickness\n activeOperation: number | null // 0 translation, 1 rotation handles, 2 slab thickness handles\n toolCenter: Types.Point3\n }\n activeViewportUIDs: string[] // a list of the viewport uids connected to the reference lines being translated\n viewportUID: string\n }\n}\n\nfunction defaultReferenceLineColor() {\n return 'rgb(200, 200, 200)'\n}\n\nfunction defaultReferenceLineControllable() {\n return true\n}\n\nfunction defaultReferenceLineDraggableRotatable() {\n return true\n}\n\nfunction defaultReferenceLineSlabThicknessControlsOn() {\n return false\n}\n\nconst OPERATION = {\n DRAG: 1,\n ROTATE: 2,\n SLAB: 3,\n}\n\nconst EPSILON = 1e-3\n\n/**\n * CrosshairsTool is a tool that provides reference lines between different viewports\n * of a toolGroup. Using crosshairs, you can jump to a specific location in one\n * viewport and the rest of the viewports in the toolGroup will be aligned to that location.\n * Crosshairs have grababble handles that can be used to rotate and translate the\n * reference lines. They can also be used to set the slab thickness of the viewports\n * by modifying the slab thickness handles.\n *\n */\nexport default class CrosshairsTool extends AnnotationTool {\n static toolName = 'Crosshairs'\n\n toolCenter: Types.Point3 = [0, 0, 0] // NOTE: it is assumed that all the active/linked viewports share the same crosshair center.\n // This because the rotation operation rotates also all the other active/intersecting reference lines of the same angle\n _getReferenceLineColor?: (viewportUID: string) => string\n _getReferenceLineControllable?: (viewportUID: string) => boolean\n _getReferenceLineDraggableRotatable?: (viewportUID: string) => boolean\n _getReferenceLineSlabThicknessControlsOn?: (viewportUID: string) => boolean\n editData: {\n annotation: any\n } | null\n\n constructor(\n toolProps: PublicToolProps = {},\n defaultToolProps: ToolProps = {\n supportedInteractionTypes: ['Mouse'],\n configuration: {\n shadow: true,\n // Auto pan is a configuration which will update pan\n // other viewports in the toolGroup if the center of the crosshairs\n // is outside of the viewport. This might be useful for the case\n // when the user is scrolling through an image (usually in the zoomed view)\n // and the crosshairs will eventually get outside of the viewport for\n // the other viewports.\n autoPan: {\n enabled: false,\n panSize: 10,\n },\n },\n }\n ) {\n super(toolProps, defaultToolProps)\n\n this._getReferenceLineColor =\n toolProps.configuration?.getReferenceLineColor ||\n defaultReferenceLineColor\n this._getReferenceLineControllable =\n toolProps.configuration?.getReferenceLineControllable ||\n defaultReferenceLineControllable\n this._getReferenceLineDraggableRotatable =\n toolProps.configuration?.getReferenceLineDraggableRotatable ||\n defaultReferenceLineDraggableRotatable\n this._getReferenceLineSlabThicknessControlsOn =\n toolProps.configuration?.getReferenceLineSlabThicknessControlsOn ||\n defaultReferenceLineSlabThicknessControlsOn\n }\n\n /**\n * Gets the camera from the viewport, and adds crosshairs annotation for the viewport\n * to the annotationManager. If any annotation is found in the annotationManager, it\n * overwrites it.\n * @param viewportInfo - The viewportInfo for the viewport to add the crosshairs\n * @returns viewPlaneNormal and center of viewport canvas in world space\n */\n initializeViewport = ({\n renderingEngineUID,\n viewportUID,\n }: Types.IViewportUID): {\n normal: Types.Point3\n point: Types.Point3\n } => {\n const enabledElement = getEnabledElementByUIDs(\n viewportUID,\n renderingEngineUID\n )\n const { FrameOfReferenceUID, viewport } = enabledElement\n const { element } = viewport\n const { position, focalPoint, viewPlaneNormal } = viewport.getCamera()\n\n // Check if there is already annotation for this viewport\n let annotations = getAnnotations(element, CrosshairsTool.toolName)\n annotations = this.filterInteractableAnnotationsForElement(\n element,\n annotations\n )\n\n if (annotations.length) {\n // If found, it will override it by removing the annotation and adding it later\n removeAnnotation(element, annotations[0].annotationUID)\n }\n\n const annotation = {\n highlighted: false,\n metadata: {\n cameraPosition: <Types.Point3>[...position],\n cameraFocalPoint: <Types.Point3>[...focalPoint],\n FrameOfReferenceUID,\n toolName: CrosshairsTool.toolName,\n },\n data: {\n handles: {\n rotationPoints: [], // rotation handles, used for rotation interactions\n slabThicknessPoints: [], // slab thickness handles, used for setting the slab thickness\n toolCenter: this.toolCenter,\n },\n // Todo: add enum for active Operations\n activeOperation: null, // 0 translation, 1 rotation handles, 2 slab thickness handles\n activeViewportUIDs: [], // a list of the viewport uids connected to the reference lines being translated\n viewportUID,\n },\n }\n\n resetElementCursor(element)\n\n addAnnotation(element, annotation)\n\n return {\n normal: viewPlaneNormal,\n point: viewport.canvasToWorld([\n viewport.sWidth / 2,\n viewport.sHeight / 2,\n ]),\n }\n }\n\n /**\n * When activated, it initializes the crosshairs. It begins by computing\n * the intersection of viewports associated with the crosshairs instance.\n * When all three views are accessible, the intersection (e.g., crosshairs tool centre)\n * will be an exact point in space; however, with two viewports, because the\n * intersection of two planes is a line, it assumes the last view is between the centre\n * of the two rendering viewports.\n * @param viewports Array of viewportInputs which each item containing {viewportUID, renderingEngineUID}\n */\n init = (viewports: ViewportInputs): void => {\n if (!viewports.length || viewports.length === 1) {\n throw new Error(\n 'For crosshairs to operate, at least two viewports must be given.'\n )\n }\n\n // Todo: handle two same view viewport, or more than 3 viewports\n const [firstViewport, secondViewport, thirdViewport] = viewports\n\n // Initialize first viewport\n const { normal: normal1, point: point1 } =\n this.initializeViewport(firstViewport)\n\n // Initialize second viewport\n const { normal: normal2, point: point2 } =\n this.initializeViewport(secondViewport)\n\n let normal3 = <Types.Point3>[0, 0, 0]\n let point3 = vec3.create()\n\n // If there are three viewports\n if (thirdViewport) {\n ;({ normal: normal3, point: point3 } =\n this.initializeViewport(thirdViewport))\n } else {\n // If there are only two views (viewport) associated with the crosshairs:\n // In this situation, we don't have a third information to find the\n // exact intersection, and we \"assume\" the third view is looking at\n // a location in between the first and second view centers\n vec3.add(point3, point1, point2)\n vec3.scale(point3, point3, 0.5)\n vec3.cross(normal3, normal1, normal2)\n }\n\n // Planes of each viewport\n const firstPlane = csUtils.planar.planeEquation(normal1, point1)\n const secondPlane = csUtils.planar.planeEquation(normal2, point2)\n const thirdPlane = csUtils.planar.planeEquation(normal3, point3)\n\n // Calculating the intersection of 3 planes\n // prettier-ignore\n this.toolCenter = csUtils.planar.threePlaneIntersection(firstPlane, secondPlane, thirdPlane)\n }\n\n /**\n * addNewAnnotation acts as jump for the crosshairs tool. It is called when\n * the user clicks on the image. It does not store the annotation in the stateManager though.\n *\n * @param evt - The mouse event\n * @param interactionType - The type of interaction (e.g., mouse, touch, etc.)\n * @returns Crosshairs annotation\n */\n addNewAnnotation = (\n evt: EventTypes.MouseDownActivateEventType,\n interactionType: string\n ): CrosshairsAnnotation => {\n const eventDetail = evt.detail\n const { element } = eventDetail\n\n const { currentPoints } = eventDetail\n const jumpWorld = currentPoints.world\n\n const enabledElement = getEnabledElement(element)\n const { viewport } = enabledElement\n this._jump(enabledElement, jumpWorld)\n\n const annotations = getAnnotations(element, CrosshairsTool.toolName)\n const filteredAnnotations = this.filterInteractableAnnotationsForElement(\n viewport.element,\n annotations\n )\n\n // viewport Annotation\n const { data } = filteredAnnotations[0]\n\n const { rotationPoints } = data.handles\n const viewportUIDArray = []\n // put all the draggable reference lines in the viewportUIDArray\n for (let i = 0; i < rotationPoints.length - 1; ++i) {\n const otherViewport = rotationPoints[i][1]\n const viewportControllable = this._getReferenceLineControllable(\n otherViewport.uid\n )\n const viewportDraggableRotatable =\n this._getReferenceLineDraggableRotatable(otherViewport.uid)\n if (!viewportControllable || !viewportDraggableRotatable) {\n continue\n }\n viewportUIDArray.push(otherViewport.uid)\n // rotation handles are two per viewport\n i++\n }\n\n data.activeViewportUIDs = [...viewportUIDArray]\n // set translation operation\n data.handles.activeOperation = OPERATION.DRAG\n\n evt.preventDefault()\n\n hideElementCursor(element)\n\n this._activateModify(element)\n return filteredAnnotations[0]\n }\n\n cancel = () => {\n console.log('Not implemented yet')\n }\n\n /**\n * It checks if the mouse click is near crosshairs handles, if yes\n * it returns the handle location. If the mouse click is not near any\n * of the handles, it does not return anything.\n *\n * @param element - The element that the tool is attached to.\n * @param annotation - The annotation object associated with the annotation\n * @param canvasCoords - The coordinates of the mouse click on canvas\n * @param proximity - The distance from the mouse cursor to the point\n * that is considered \"near\".\n * @returns The handle that is closest to the cursor, or null if the cursor\n * is not near any of the handles.\n */\n getHandleNearImagePoint(\n element: HTMLElement,\n annotation: Annotation,\n canvasCoords: Types.Point2,\n proximity: number\n ): ToolHandle | undefined {\n const enabledElement = getEnabledElement(element)\n const { viewport } = enabledElement\n\n let point = this._getRotationHandleNearImagePoint(\n viewport,\n annotation,\n canvasCoords,\n proximity\n )\n\n if (point !== null) {\n return point\n }\n\n point = this._getSlabThicknessHandleNearImagePoint(\n viewport,\n annotation,\n canvasCoords,\n proximity\n )\n\n if (point !== null) {\n return point\n }\n }\n\n handleSelectedCallback = (\n evt: EventTypes.MouseDownEventType,\n annotation: Annotation,\n handle: ToolHandle,\n interactionType = 'mouse'\n ): void => {\n const eventDetail = evt.detail\n const { element } = eventDetail\n\n annotation.highlighted = true\n\n // NOTE: handle index or coordinates are not used when dragging.\n // This because the handle points are actually generated in the renderTool and they are a derivative\n // from the camera variables of the viewports and of the slab thickness variable.\n // Remember that the translation and rotation operations operate on the camera\n // variables and not really on the handles. Similar for the slab thickness.\n this._activateModify(element)\n\n hideElementCursor(element)\n\n evt.preventDefault()\n }\n\n /**\n * It returns if the canvas point is near the provided crosshairs annotation in the\n * provided element or not. A proximity is passed to the function to determine the\n * proximity of the point to the annotation in number of pixels.\n *\n * @param element - HTML Element\n * @param annotation - Annotation\n * @param canvasCoords - Canvas coordinates\n * @param proximity - Proximity to tool to consider\n * @returns Boolean, whether the canvas point is near tool\n */\n isPointNearTool = (\n element: HTMLElement,\n annotation: CrosshairsAnnotation,\n canvasCoords: Types.Point2,\n proximity: number\n ): boolean => {\n if (this._pointNearTool(element, annotation, canvasCoords, 6)) {\n return true\n }\n\n return false\n }\n\n toolSelectedCallback = (\n evt: EventTypes.MouseDownEventType,\n annotation: Annotation,\n interactionType: InteractionTypes\n ): void => {\n const eventDetail = evt.detail\n const { element } = eventDetail\n annotation.highlighted = true\n\n this._activateModify(element)\n\n hideElementCursor(element)\n\n evt.preventDefault()\n }\n\n onCameraModified = (evt) => {\n const eventDetail = evt.detail\n const { element } = eventDetail\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n const viewport = enabledElement.viewport as Types.IVolumeViewport\n\n const requireSameOrientation = false\n const viewportUIDsToRender = getViewportUIDsWithToolToRender(\n element,\n CrosshairsTool.toolName,\n requireSameOrientation\n )\n\n const annotations = getAnnotations(element, CrosshairsTool.toolName)\n const filteredToolAnnotations =\n this.filterInteractableAnnotationsForElement(element, annotations)\n\n // viewport Annotation\n const viewportAnnotation =\n filteredToolAnnotations[0] as CrosshairsAnnotation\n\n if (!viewportAnnotation) {\n return\n }\n\n // -- Update the camera of other linked viewports containing the same volumeUID that\n // have the same camera in case of translation\n // -- Update the crosshair center in world coordinates in annotation.\n // This is necessary because other tools can modify the position of the slices,\n // e.g. stackscroll tool at wheel scroll. So we update the coordinates of the center always here.\n // NOTE: rotation and slab thickness handles are created/updated in renderTool.\n const currentCamera = viewport.getCamera()\n const oldCameraPosition = viewportAnnotation.metadata.cameraPosition\n const deltaCameraPosition: Types.Point3 = [0, 0, 0]\n vtkMath.subtract(\n currentCamera.position,\n oldCameraPosition,\n deltaCameraPosition\n )\n\n const oldCameraFocalPoint = viewportAnnotation.metadata.cameraFocalPoint\n const deltaCameraFocalPoint: Types.Point3 = [0, 0, 0]\n vtkMath.subtract(\n currentCamera.focalPoint,\n oldCameraFocalPoint,\n deltaCameraFocalPoint\n )\n\n // updated cached \"previous\" camera position and focal point\n viewportAnnotation.metadata.cameraPosition = [...currentCamera.position]\n viewportAnnotation.metadata.cameraFocalPoint = [...currentCamera.focalPoint]\n\n const viewportControllable = this._getReferenceLineControllable(\n viewport.uid\n )\n const viewportDraggableRotatable = this._getReferenceLineDraggableRotatable(\n viewport.uid\n )\n if (\n !csUtils.isEqual(currentCamera.position, oldCameraPosition, 1e-3) &&\n viewportControllable &&\n viewportDraggableRotatable\n ) {\n // Is camera Modified a TRANSLATION or ROTATION?\n let IsTranslation = true\n\n // NOTE: it is a translation if the the focal point and camera position shifts are the same\n if (!csUtils.isEqual(deltaCameraPosition, deltaCameraFocalPoint, 1e-3)) {\n IsTranslation = false\n }\n\n // TRANSLATION\n // NOTE1: if it's a panning don't update the crosshair center\n // NOTE2: rotation handles are updates in renderTool\n // panning check is:\n // -- deltaCameraPosition dot viewPlaneNormal > 1e-2\n if (\n IsTranslation &&\n Math.abs(\n vtkMath.dot(deltaCameraPosition, currentCamera.viewPlaneNormal)\n ) > 1e-2\n ) {\n // update linked view in the same scene that have the same camera\n // this goes here, because the parent viewport translation may happen in another tool\n // const otherLinkedViewportsAnnotationsWithSameCameraDirection =\n // this._filterLinkedViewportWithSameOrientationAndScene(\n // enabledElement,\n // annotations\n // )\n\n // for (\n // let i = 0;\n // i < otherLinkedViewportsAnnotationsWithSameCameraDirection.length;\n // ++i\n // ) {\n // const annotation =\n // otherLinkedViewportsAnnotationsWithSameCameraDirection[i]\n // const { data } = annotation\n // const scene = renderingEngine.getScene(data.sceneUID)\n // const otherViewport = scene.getViewport(data.viewportUID)\n // const camera = otherViewport.getCamera()\n\n // const newFocalPoint = [0, 0, 0]\n // const newPosition = [0, 0, 0]\n\n // vtkMath.add(camera.focalPoint, deltaCameraPosition, newFocalPoint)\n // vtkMath.add(camera.position, deltaCameraPosition, newPosition)\n\n // // updated cached \"previous\" camera position and focal point\n // annotation.metadata.cameraPosition = [...currentCamera.position]\n // annotation.metadata.cameraFocalPoint = [...currentCamera.focalPoint]\n // }\n\n // update center of the crosshair\n this.toolCenter[0] += deltaCameraPosition[0]\n this.toolCenter[1] += deltaCameraPosition[1]\n this.toolCenter[2] += deltaCameraPosition[2]\n }\n }\n\n // AutoPan modification\n if (this.configuration.autoPan.enabled) {\n const viewports = csUtils.getVolumeViewportsContainingSameVolumes(\n viewport,\n renderingEngine.uid\n )\n\n viewports.forEach(({ uid: viewportUID }) => {\n // other viewports in the scene\n if (viewportUID !== viewport.uid) {\n this._autoPanViewportIfNecessary(viewportUID, renderingEngine)\n }\n })\n }\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n }\n\n mouseMoveCallback = (\n evt: EventTypes.MouseMoveEventType,\n filteredToolAnnotations: Annotations\n ): boolean => {\n const { element, currentPoints } = evt.detail\n const canvasCoords = currentPoints.canvas\n let imageNeedsUpdate = false\n\n for (let i = 0; i < filteredToolAnnotations.length; i++) {\n const annotation = filteredToolAnnotations[i] as CrosshairsAnnotation\n\n if (isAnnotationLocked(annotation)) {\n continue\n }\n\n const { data, highlighted } = annotation\n if (!data.handles) {\n continue\n }\n\n const previousActiveOperation = data.handles.activeOperation\n const previousActiveViewportUIDs =\n data.activeViewportUIDs && data.activeViewportUIDs.length > 0\n ? [...data.activeViewportUIDs]\n : []\n\n // This init are necessary, because when we move the mouse they are not cleaned by _mouseUpCallback\n data.activeViewportUIDs = []\n data.handles.activeOperation = null\n\n const handleNearImagePoint = this.getHandleNearImagePoint(\n element,\n annotation,\n canvasCoords,\n 6\n )\n\n let near = false\n if (handleNearImagePoint) {\n near = true\n } else {\n near = this._pointNearTool(element, annotation, canvasCoords, 6)\n }\n\n const nearToolAndNotMarkedActive = near && !highlighted\n const notNearToolAndMarkedActive = !near && highlighted\n if (nearToolAndNotMarkedActive || notNearToolAndMarkedActive) {\n annotation.highlighted = !highlighted\n imageNeedsUpdate = true\n } else if (\n data.handles.activeOperation !== previousActiveOperation ||\n !this._areViewportUIDArraysEqual(\n data.activeViewportUIDs,\n previousActiveViewportUIDs\n )\n ) {\n imageNeedsUpdate = true\n }\n }\n\n return imageNeedsUpdate\n }\n\n filterInteractableAnnotationsForElement = (element, annotations) => {\n if (!annotations || !annotations.length) {\n return []\n }\n\n const enabledElement = getEnabledElement(element)\n const { viewportUID } = enabledElement\n\n const viewportUIDSpecificCrosshairs = annotations.filter(\n (annotation) => annotation.data.viewportUID === viewportUID\n )\n\n return viewportUIDSpecificCrosshairs\n }\n\n /**\n * renders the crosshairs lines and handles in the requestAnimationFrame callback\n *\n * @param enabledElement - The Cornerstone's enabledElement.\n * @param svgDrawingHelper - The svgDrawingHelper providing the context for drawing.\n */\n renderAnnotation = (\n enabledElement: Types.IEnabledElement,\n svgDrawingHelper: any\n ): void => {\n const { viewport, renderingEngine } = enabledElement\n const { element } = viewport\n const annotations = getAnnotations(element, CrosshairsTool.toolName)\n const camera = viewport.getCamera()\n\n const filteredToolAnnotations =\n this.filterInteractableAnnotationsForElement(element, annotations)\n\n // viewport Annotation\n const viewportAnnotation = filteredToolAnnotations[0]\n if (!annotations || !viewportAnnotation || !viewportAnnotation.data) {\n // No annotations yet, and didn't just create it as we likely don't have a FrameOfReference/any data loaded yet.\n return\n }\n\n const annotationUID = viewportAnnotation.annotationUID\n\n // Get cameras/canvases for each of these.\n // -- Get two world positions for this canvas in this line (e.g. the diagonal)\n // -- Convert these world positions to this canvas.\n // -- Extend/confine this line to fit in this canvas.\n // -- Render this line.\n\n const { sWidth, sHeight } = viewport\n const canvasDiagonalLength = Math.sqrt(sWidth * sWidth + sHeight * sHeight)\n\n const data = viewportAnnotation.data\n const crosshairCenterCanvas = viewport.worldToCanvas(this.toolCenter)\n\n const otherViewportAnnotations =\n this._filterAnnotationsByUniqueViewportOrientations(\n enabledElement,\n annotations\n )\n\n const referenceLines = []\n\n otherViewportAnnotations.forEach((annotation) => {\n const { data } = annotation\n\n data.handles.toolCenter = this.toolCenter\n\n const otherViewport = renderingEngine.getViewport(\n data.viewportUID\n ) as Types.IVolumeViewport\n\n const otherCamera = otherViewport.getCamera()\n\n const otherViewportControllable = this._getReferenceLineControllable(\n otherViewport.uid\n )\n const otherViewportDraggableRotatable =\n this._getReferenceLineDraggableRotatable(otherViewport.uid)\n const otherViewportSlabThicknessControlsOn =\n this._getReferenceLineSlabThicknessControlsOn(otherViewport.uid)\n\n // get coordinates for the reference line\n const { sWidth, sHeight } = otherViewport\n const otherCanvasDiagonalLength = Math.sqrt(\n sWidth * sWidth + sHeight * sHeight\n )\n const otherCanvasCenter: Types.Point2 = [sWidth * 0.5, sHeight * 0.5]\n const otherViewportCenterWorld =\n otherViewport.canvasToWorld(otherCanvasCenter)\n\n const direction: Types.Point3 = [0, 0, 0]\n vtkMath.cross(\n camera.viewPlaneNormal,\n otherCamera.viewPlaneNormal,\n direction\n )\n vtkMath.normalize(direction)\n vtkMath.multiplyScalar(<Types.Point3>direction, otherCanvasDiagonalLength)\n\n const pointWorld0: Types.Point3 = [0, 0, 0]\n vtkMath.add(otherViewportCenterWorld, direction, pointWorld0)\n\n const pointWorld1: Types.Point3 = [0, 0, 0]\n vtkMath.subtract(otherViewportCenterWorld, direction, pointWorld1)\n\n // get canvas information for points and lines (canvas box, canvas horizontal distances)\n const canvasBox = [0, 0, sWidth, sHeight]\n\n const pointCanvas0 = viewport.worldToCanvas(pointWorld0)\n\n const otherViewportCenterCanvas = viewport.worldToCanvas(\n otherViewportCenterWorld\n )\n\n const canvasUnitVectorFromCenter = vec2.create()\n vec2.subtract(\n canvasUnitVectorFromCenter,\n pointCanvas0,\n otherViewportCenterCanvas\n )\n vec2.normalize(canvasUnitVectorFromCenter, canvasUnitVectorFromCenter)\n\n // Graphic:\n // Mid -> SlabThickness handle\n // Short -> Rotation handle\n // Long\n // |\n // |\n // |\n // Mid\n // |\n // |\n // |\n // Short\n // |\n // |\n // |\n // Long --- Mid--- Short--- Center --- Short --- Mid --- Long\n // |\n // |\n // |\n // Short\n // |\n // |\n // |\n // Mid\n // |\n // |\n // |\n // Long\n const canvasVectorFromCenterLong = vec2.create()\n\n // Todo: configuration should provide constants below (100, 0.25, 0.15, 0.04)\n vec2.scale(\n canvasVectorFromCenterLong,\n canvasUnitVectorFromCenter,\n canvasDiagonalLength * 100\n )\n const canvasVectorFromCenterMid = vec2.create()\n vec2.scale(\n canvasVectorFromCenterMid,\n canvasUnitVectorFromCenter,\n canvasDiagonalLength * 0.25\n )\n const canvasVectorFromCenterShort = vec2.create()\n vec2.scale(\n canvasVectorFromCenterShort,\n canvasUnitVectorFromCenter,\n canvasDiagonalLength * 0.15\n )\n const canvasVectorFromCenterStart = vec2.create()\n vec2.scale(\n canvasVectorFromCenterStart,\n canvasUnitVectorFromCenter,\n // Don't put a gap if the the third view is missing\n otherViewportAnnotations.length === 2 ? canvasDiagonalLength * 0.04 : 0\n )\n\n // Computing Reference start and end (4 lines per viewport in case of 3 view MPR)\n const refLinePointOne = vec2.create()\n const refLinePointTwo = vec2.create()\n const refLinePointThree = vec2.create()\n const refLinePointFour = vec2.create()\n\n let refLinesCenter = vec2.clone(crosshairCenterCanvas)\n if (!otherViewportDraggableRotatable || !otherViewportControllable) {\n refLinesCenter = vec2.clone(otherViewportCenterCanvas)\n }\n\n vec2.add(refLinePointOne, refLinesCenter, canvasVectorFromCenterStart)\n vec2.add(refLinePointTwo, refLinesCenter, canvasVectorFromCenterLong)\n vec2.subtract(\n refLinePointThree,\n refLinesCenter,\n canvasVectorFromCenterStart\n )\n vec2.subtract(\n refLinePointFour,\n refLinesCenter,\n canvasVectorFromCenterLong\n )\n\n // Clipping lines to be only included in a box (canvas), we don't want\n // the lines goes beyond canvas\n liangBarksyClip(refLinePointOne, refLinePointTwo, canvasBox)\n liangBarksyClip(refLinePointThree, refLinePointFour, canvasBox)\n\n // Computing rotation handle positions\n const rotHandleOne = vec2.create()\n vec2.subtract(\n rotHandleOne,\n crosshairCenterCanvas,\n canvasVectorFromCenterMid\n )\n\n const rotHandleTwo = vec2.create()\n vec2.add(rotHandleTwo, crosshairCenterCanvas, canvasVectorFromCenterMid)\n\n // Computing SlabThickness (st below) position\n\n // SlabThickness center in canvas\n let stHandlesCenterCanvas = vec2.clone(crosshairCenterCanvas)\n if (\n !otherViewportDraggableRotatable &&\n otherViewportSlabThicknessControlsOn\n ) {\n stHandlesCenterCanvas = vec2.clone(otherViewportCenterCanvas)\n }\n\n // SlabThickness center in world\n let stHandlesCenterWorld: Types.Point3 = [...this.toolCenter]\n if (\n !otherViewportDraggableRotatable &&\n otherViewportSlabThicknessControlsOn\n ) {\n stHandlesCenterWorld = [...otherViewportCenterWorld]\n }\n\n const worldUnitVectorFromCenter: Types.Point3 = [0, 0, 0]\n vtkMath.subtract(pointWorld0, pointWorld1, worldUnitVectorFromCenter)\n vtkMath.normalize(worldUnitVectorFromCenter)\n\n const { viewPlaneNormal } = camera\n // @ts-ignore // Todo: fix after vtk pr merged\n const { matrix } = vtkMatrixBuilder\n .buildFromDegree()\n // @ts-ignore fix after vtk pr merged\n .rotate(90, viewPlaneNormal)\n\n const worldUnitOrthoVectorFromCenter: Types.Point3 = [0, 0, 0]\n vec3.transformMat4(\n worldUnitOrthoVectorFromCenter,\n worldUnitVectorFromCenter,\n matrix\n )\n\n const slabThicknessValue = otherViewport.getSlabThickness()\n const worldOrthoVectorFromCenter: Types.Point3 = [\n ...worldUnitOrthoVectorFromCenter,\n ]\n vtkMath.multiplyScalar(worldOrthoVectorFromCenter, slabThicknessValue)\n\n const worldVerticalRefPoint: Types.Point3 = [0, 0, 0]\n vtkMath.add(\n stHandlesCenterWorld,\n worldOrthoVectorFromCenter,\n worldVerticalRefPoint\n )\n\n // convert vertical world distances in canvas coordinates\n const canvasVerticalRefPoint = viewport.worldToCanvas(\n worldVerticalRefPoint\n )\n\n // points for slab thickness lines\n const canvasOrthoVectorFromCenter = vec2.create()\n vec2.subtract(\n canvasOrthoVectorFromCenter,\n stHandlesCenterCanvas,\n canvasVerticalRefPoint\n )\n\n const stLinePointOne = vec2.create()\n vec2.subtract(\n stLinePointOne,\n stHandlesCenterCanvas,\n canvasVectorFromCenterLong\n )\n vec2.add(stLinePointOne, stLinePointOne, canvasOrthoVectorFromCenter)\n\n const stLinePointTwo = vec2.create()\n vec2.add(\n stLinePointTwo,\n stHandlesCenterCanvas,\n canvasVectorFromCenterLong\n )\n vec2.add(stLinePointTwo, stLinePointTwo, canvasOrthoVectorFromCenter)\n\n liangBarksyClip(stLinePointOne, stLinePointTwo, canvasBox)\n\n const stLinePointThree = vec2.create()\n vec2.add(\n stLinePointThree,\n stHandlesCenterCanvas,\n canvasVectorFromCenterLong\n )\n vec2.subtract(\n stLinePointThree,\n stLinePointThree,\n canvasOrthoVectorFromCenter\n )\n\n const stLinePointFour = vec2.create()\n vec2.subtract(\n stLinePointFour,\n stHandlesCenterCanvas,\n canvasVectorFromCenterLong\n )\n vec2.subtract(\n stLinePointFour,\n stLinePointFour,\n canvasOrthoVectorFromCenter\n )\n\n liangBarksyClip(stLinePointThree, stLinePointFour, canvasBox)\n\n // points for slab thickness handles\n const stHandleOne = vec2.create()\n const stHandleTwo = vec2.create()\n const stHandleThree = vec2.create()\n const stHandleFour = vec2.create()\n\n vec2.subtract(\n stHandleOne,\n stHandlesCenterCanvas,\n canvasVectorFromCenterShort\n )\n vec2.add(stHandleOne, stHandleOne, canvasOrthoVectorFromCenter)\n vec2.add(stHandleTwo, stHandlesCenterCanvas, canvasVectorFromCenterShort)\n vec2.add(stHandleTwo, stHandleTwo, canvasOrthoVectorFromCenter)\n vec2.subtract(\n stHandleThree,\n stHandlesCenterCanvas,\n canvasVectorFromCenterShort\n )\n vec2.subtract(stHandleThree, stHandleThree, canvasOrthoVectorFromCenter)\n vec2.add(stHandleFour, stHandlesCenterCanvas, canvasVectorFromCenterShort)\n vec2.subtract(stHandleFour, stHandleFour, canvasOrthoVectorFromCenter)\n\n referenceLines.push([\n otherViewport,\n refLinePointOne,\n refLinePointTwo,\n refLinePointThree,\n refLinePointFour,\n stLinePointOne,\n stLinePointTwo,\n stLinePointThree,\n stLinePointFour,\n rotHandleOne,\n rotHandleTwo,\n stHandleOne,\n stHandleTwo,\n stHandleThree,\n stHandleFour,\n ])\n })\n\n const newRtpoints = []\n const newStpoints = []\n const viewportColor = this._getReferenceLineColor(viewport.uid)\n const color =\n viewportColor !== undefined ? viewportColor : 'rgb(200, 200, 200)'\n\n referenceLines.forEach((line, lineIndex) => {\n // get color for the reference line\n const otherViewport = line[0]\n const viewportColor = this._getReferenceLineColor(otherViewport.uid)\n const viewportControllable = this._getReferenceLineControllable(\n otherViewport.uid\n )\n const viewportDraggableRotatable =\n this._getReferenceLineDraggableRotatable(otherViewport.uid)\n const viewportSlabThicknessControlsOn =\n this._getReferenceLineSlabThicknessControlsOn(otherViewport.uid)\n const selectedViewportUID = data.activeViewportUIDs.find(\n (uid) => uid === otherViewport.uid\n )\n\n let color =\n viewportColor !== undefined ? viewportColor : 'rgb(200, 200, 200)'\n let lineWidth = 1\n const lineActive =\n data.handles.activeOperation !== null &&\n data.handles.activeOperation === OPERATION.DRAG &&\n selectedViewportUID\n\n if (lineActive) {\n lineWidth = 2.5\n }\n\n let lineUID = `${lineIndex}`\n if (viewportControllable && viewportDraggableRotatable) {\n lineUID = `${lineIndex}One`\n drawLineSvg(\n svgDrawingHelper,\n CrosshairsTool.toolName,\n annotationUID,\n lineUID,\n line[1],\n line[2],\n {\n color,\n lineWidth,\n }\n )\n\n lineUID = `${lineIndex}Two`\n drawLineSvg(\n svgDrawingHelper,\n CrosshairsTool.toolName,\n annotationUID,\n lineUID,\n line[3],\n line[4],\n {\n color,\n lineWidth,\n }\n )\n } else {\n drawLineSvg(\n svgDrawingHelper,\n CrosshairsTool.toolName,\n annotationUID,\n lineUID,\n line[2],\n line[4],\n {\n color,\n lineWidth,\n }\n )\n }\n\n if (viewportControllable) {\n color =\n viewportColor !== undefined ? viewportColor : 'rgb(200, 200, 200)'\n\n const rotHandlesActive =\n data.handles.activeOperation === OPERATION.ROTATE\n const rotationHandles = [line[9], line[10]]\n\n const rotHandleWorldOne = [\n viewport.canvasToWorld(line[9]),\n otherViewport,\n line[1],\n line[2],\n ]\n const rotHandleWorldTwo = [\n viewport.canvasToWorld(line[10]),\n otherViewport,\n line[3],\n line[4],\n ]\n newRtpoints.push(rotHandleWorldOne, rotHandleWorldTwo)\n\n const slabThicknessHandlesActive =\n data.handles.activeOperation === OPERATION.SLAB\n const slabThicknessHandles = [line[11], line[12], line[13], line[14]]\n\n const slabThicknessHandleWorldOne = [\n viewport.canvasToWorld(line[11]),\n otherViewport,\n line[5],\n line[6],\n ]\n const slabThicknessHandleWorldTwo = [\n viewport.canvasToWorld(line[12]),\n otherViewport,\n line[5],\n line[6],\n ]\n const slabThicknessHandleWorldThree = [\n viewport.canvasToWorld(line[13]),\n otherViewport,\n line[7],\n line[8],\n ]\n const slabThicknessHandleWorldFour = [\n viewport.canvasToWorld(line[14]),\n otherViewport,\n line[7],\n line[8],\n ]\n newStpoints.push(\n slabThicknessHandleWorldOne,\n slabThicknessHandleWorldTwo,\n slabThicknessHandleWorldThree,\n slabThicknessHandleWorldFour\n )\n\n if (\n lineActive &&\n !rotHandlesActive &&\n !slabThicknessHandlesActive &&\n viewportDraggableRotatable &&\n viewportSlabThicknessControlsOn\n ) {\n // draw all handles inactive (rotation and slab thickness)\n let handleUID = `${lineIndex}One`\n drawHandlesSvg(\n svgDrawingHelper,\n CrosshairsTool.toolName,\n annotationUID,\n handleUID,\n rotationHandles,\n {\n color,\n handleRadius: 3,\n type: 'circle',\n }\n )\n handleUID = `${lineIndex}Two`\n drawHandlesSvg(\n svgDrawingHelper,\n CrosshairsTool.toolName,\n annotationUID,\n handleUID,\n slabThicknessHandles,\n {\n color,\n handleRadius: 3,\n type: 'rect',\n }\n )\n } else if (\n lineActive &&\n !rotHandlesActive &&\n !slabThicknessHandlesActive &&\n viewportDraggableRotatable\n ) {\n const handleUID = `${lineIndex}`\n // draw rotation handles inactive\n drawHandlesSvg(\n svgDrawingHelper,\n CrosshairsTool.toolName,\n annotationUID,\n handleUID,\n rotationHandles,\n {\n color,\n handleRadius: 3,\n type: 'circle',\n }\n )\n } else if (\n selectedViewportUID &&\n !rotHandlesActive &&\n !slabThicknessHandlesActive &&\n viewportSlabThicknessControlsOn\n ) {\n const handleUID = `${lineIndex}`\n // draw slab thickness handles inactive\n drawHandlesSvg(\n svgDrawingHelper,\n CrosshairsTool.toolName,\n annotationUID,\n handleUID,\n slabThicknessHandles,\n {\n color,\n handleRadius: 3,\n type: 'rect',\n }\n )\n } else if (rotHandlesActive && viewportDraggableRotatable) {\n const handleUID = `${lineIndex}`\n // draw all rotation handles as active\n drawHandlesSvg(\n svgDrawingHelper,\n CrosshairsTool.toolName,\n annotationUID,\n handleUID,\n rotationHandles,\n {\n color,\n handleRadius: 2,\n fill: color,\n type: 'circle',\n }\n )\n } else if (\n slabThicknessHandlesActive &&\n selectedViewportUID &&\n viewportSlabThicknessControlsOn\n ) {\n // draw only the slab thickness handles for the active viewport as active\n drawHandlesSvg(\n svgDrawingHelper,\n CrosshairsTool.toolName,\n annotationUID,\n lineUID,\n slabThicknessHandles,\n {\n color,\n handleRadius: 2,\n fill: color,\n type: 'rect',\n }\n )\n }\n const slabThicknessValue = otherViewport.getSlabThickness()\n if (slabThicknessValue > 0.5 && viewportSlabThicknessControlsOn) {\n // draw slab thickness reference lines\n lineUID = `${lineIndex}STOne`\n drawLineSvg(\n svgDrawingHelper,\n CrosshairsTool.toolName,\n annotationUID,\n lineUID,\n line[5],\n line[6],\n {\n color,\n width: 1,\n lineDash: [2, 3],\n }\n )\n\n lineUID = `${lineIndex}STTwo`\n drawLineSvg(\n svgDrawingHelper,\n CrosshairsTool.toolName,\n annotationUID,\n lineUID,\n line[7],\n line[8],\n {\n color,\n width: line,\n lineDash: [2, 3],\n }\n )\n }\n }\n })\n\n // Save new handles points in annotation\n data.handles.rotationPoints = newRtpoints\n data.handles.slabThicknessPoints = newStpoints\n\n // render a circle to pin point the viewport color\n // TODO: This should not be part of the tool, and definitely not part of the renderAnnotation loop\n const referenceColorCoordinates = [\n sWidth * 0.95,\n sHeight * 0.05,\n ] as Types.Point2\n const circleRadius = canvasDiagonalLength * 0.01\n\n const circleUID = '0'\n drawCircleSvg(\n svgDrawingHelper,\n CrosshairsTool.toolName,\n annotationUID,\n circleUID,\n referenceColorCoordinates,\n circleRadius,\n { color, fill: color }\n )\n }\n\n _autoPanViewportIfNecessary(\n viewportUID: string,\n renderingEngine: Types.IRenderingEngine\n ): void {\n // 1. Compute the current world bounding box of the viewport from corner to corner\n // 2. Check if the toolCenter is outside of the world bounding box\n // 3. If it is outside, pan the viewport to fit in the toolCenter\n\n const viewport = renderingEngine.getViewport(viewportUID)\n const { sWidth, sHeight } = viewport\n\n const topLefWorld = viewport.canvasToWorld([0, 0])\n const bottomRightWorld = viewport.canvasToWorld([sWidth, sHeight])\n const topRightWorld = viewport.canvasToWorld([sWidth, 0])\n const bottomLeftWorld = viewport.canvasToWorld([0, sHeight])\n\n // find the minimum and maximum world coordinates in each x,y,z\n const minX = Math.min(\n topLefWorld[0],\n bottomRightWorld[0],\n topRightWorld[0],\n bottomLeftWorld[0]\n )\n const maxX = Math.max(\n topLefWorld[0],\n bottomRightWorld[0],\n topRightWorld[0],\n bottomLeftWorld[0]\n )\n const minY = Math.min(\n topLefWorld[1],\n bottomRightWorld[1],\n topRightWorld[1],\n bottomLeftWorld[1]\n )\n const maxY = Math.max(\n topLefWorld[1],\n bottomRightWorld[1],\n topRightWorld[1],\n bottomLeftWorld[1]\n )\n const minZ = Math.min(\n topLefWorld[2],\n bottomRightWorld[2],\n topRightWorld[2],\n bottomLeftWorld[2]\n )\n const maxZ = Math.max(\n topLefWorld[2],\n bottomRightWorld[2],\n topRightWorld[2],\n bottomLeftWorld[2]\n )\n\n // pan the viewport to fit the toolCenter in the direction\n // that is out of bounds\n let deltaPointsWorld\n const pan = this.configuration.autoPan.panSize\n\n if (this.toolCenter[0] < minX - EPSILON) {\n deltaPointsWorld = [minX - this.toolCenter[0] + pan, 0, 0]\n } else if (this.toolCenter[0] > maxX + EPSILON) {\n deltaPointsWorld = [maxX - this.toolCenter[0] - pan, 0, 0]\n } else if (this.toolCenter[1] < minY - EPSILON) {\n deltaPointsWorld = [0, minY - this.toolCenter[1] + pan, 0]\n } else if (this.toolCenter[1] > maxY + EPSILON) {\n deltaPointsWorld = [0, maxY - this.toolCenter[1] - pan, 0]\n } else if (this.toolCenter[2] < minZ - EPSILON) {\n deltaPointsWorld = [0, 0, minZ - this.toolCenter[2] + pan]\n } else if (this.toolCenter[2] > maxZ + EPSILON) {\n deltaPointsWorld = [0, 0, maxZ - this.toolCenter[2] - pan]\n } else {\n return\n }\n\n const camera = viewport.getCamera()\n const { focalPoint, position } = camera\n\n const updatedPosition = <Types.Point3>[\n position[0] - deltaPointsWorld[0],\n position[1] - deltaPointsWorld[1],\n position[2] - deltaPointsWorld[2],\n ]\n\n const updatedFocalPoint = <Types.Point3>[\n focalPoint[0] - deltaPointsWorld[0],\n focalPoint[1] - deltaPointsWorld[1],\n focalPoint[2] - deltaPointsWorld[2],\n ]\n\n viewport.setCamera({\n focalPoint: updatedFocalPoint,\n position: updatedPosition,\n })\n\n viewport.render()\n }\n\n _areViewportUIDArraysEqual = (viewportUIDArrayOne, viewportUIDArrayTwo) => {\n if (viewportUIDArrayOne.length !== viewportUIDArrayTwo.length) {\n return false\n }\n\n viewportUIDArrayOne.forEach((uid) => {\n let itemFound = false\n for (let i = 0; i < viewportUIDArrayTwo.length; ++i) {\n if (uid === viewportUIDArrayTwo[i]) {\n itemFound = true\n break\n }\n }\n if (itemFound === false) {\n return false\n }\n })\n\n return true\n }\n\n // It filters the viewports with crosshairs and only return viewports\n // that have different camera.\n _getAnnotationsForViewportsWithDifferentCameras = (\n enabledElement,\n annotations\n ) => {\n const { viewportUID, renderingEngine, viewport } = enabledElement\n\n const otherViewportAnnotations = annotations.filter(\n (annotation) => annotation.data.viewportUID !== viewportUID\n )\n\n if (!otherViewportAnnotations || !otherViewportAnnotations.length) {\n return []\n }\n\n const camera = viewport.getCamera()\n const { viewPlaneNormal, position } = camera\n\n const viewportsWithDifferentCameras = otherViewportAnnotations.filter(\n (annotation) => {\n const { viewportUID } = annotation.data\n const targetViewport = renderingEngine.getViewport(viewportUID)\n const cameraOfTarget = targetViewport.getCamera()\n\n return !(\n csUtils.isEqual(\n cameraOfTarget.viewPlaneNormal,\n viewPlaneNormal,\n 1e-2\n ) && csUtils.isEqual(cameraOfTarget.position, position, 1)\n )\n }\n )\n\n return viewportsWithDifferentCameras\n }\n\n _filterLinkedViewportWithSameOrientationAndScene = (\n enabledElement,\n annotations\n ) => {\n const { renderingEngine, viewport } = enabledElement\n const viewportControllable = this._getReferenceLineControllable(\n viewport.uid\n )\n\n const otherLinkedViewportAnnotationsFromSameScene = annotations.filter(\n (annotation) => {\n const { data } = annotation\n const otherViewport = renderingEngine.getViewport(data.viewportUID)\n const otherViewportControllable = this._getReferenceLineControllable(\n otherViewport.uid\n )\n\n return (\n viewport !== otherViewport &&\n // scene === otherScene &&\n otherViewportControllable === true &&\n viewportControllable === true\n )\n }\n )\n\n if (\n !otherLinkedViewportAnnotationsFromSameScene ||\n !otherLinkedViewportAnnotationsFromSameScene.length\n ) {\n return []\n }\n\n const camera = viewport.getCamera()\n const viewPlaneNormal = camera.viewPlaneNormal\n vtkMath.normalize(viewPlaneNormal)\n\n const otherLinkedViewportsAnnotationsWithSameCameraDirection =\n otherLinkedViewportAnnotationsFromSameScene.filter((annotation) => {\n const { viewportUID } = annotation.data\n const otherViewport = renderingEngine.getViewport(viewportUID)\n const otherCamera = otherViewport.getCamera()\n const otherViewPlaneNormal = otherCamera.viewPlaneNormal\n vtkMath.normalize(otherViewPlaneNormal)\n\n return (\n csUtils.isEqual(viewPlaneNormal, otherViewPlaneNormal, 1e-2) &&\n csUtils.isEqual(camera.viewUp, otherCamera.viewUp, 1e-2)\n )\n })\n\n return otherLinkedViewportsAnnotationsWithSameCameraDirection\n }\n\n _filterAnnotationsByUniqueViewportOrientations = (\n enabledElement,\n annotations\n ) => {\n const { renderingEngine, viewport } = enabledElement\n const camera = viewport.getCamera()\n const viewPlaneNormal = camera.viewPlaneNormal\n vtkMath.normalize(viewPlaneNormal)\n\n const otherLinkedViewportAnnotationsFromSameScene = annotations.filter(\n (annotation) => {\n const { data } = annotation\n const otherViewport = renderingEngine.getViewport(data.viewportUID)\n const otherViewportControllable = this._getReferenceLineControllable(\n otherViewport.uid\n )\n\n return (\n viewport !== otherViewport &&\n // scene === otherScene &&\n otherViewportControllable === true\n )\n }\n )\n\n const otherViewportsAnnotationsWithUniqueCameras = []\n // Iterate first on other viewport from the same scene linked\n for (\n let i = 0;\n i < otherLinkedViewportAnnotationsFromSameScene.length;\n ++i\n ) {\n const annotation = otherLinkedViewportAnnotationsFromSameScene[i]\n const { viewportUID } = annotation.data\n const otherViewport = renderingEngine.getViewport(viewportUID)\n const otherCamera = otherViewport.getCamera()\n const otherViewPlaneNormal = otherCamera.viewPlaneNormal\n vtkMath.normalize(otherViewPlaneNormal)\n\n if (\n csUtils.isEqual(viewPlaneNormal, otherViewPlaneNormal, 1e-2) ||\n csUtils.isOpposite(viewPlaneNormal, otherViewPlaneNormal, 1e-2)\n ) {\n continue\n }\n\n let cameraFound = false\n for (\n let jj = 0;\n jj < otherViewportsAnnotationsWithUniqueCameras.length;\n ++jj\n ) {\n const annotation = otherViewportsAnnotationsWithUniqueCameras[jj]\n const { viewportUID } = annotation.data\n const stockedViewport = renderingEngine.getViewport(viewportUID)\n const cameraOfStocked = stockedViewport.getCamera()\n\n if (\n csUtils.isEqual(\n cameraOfStocked.viewPlaneNormal,\n otherCamera.viewPlaneNormal,\n 1e-2\n ) &&\n csUtils.isEqual(cameraOfStocked.position, otherCamera.position, 1)\n ) {\n cameraFound = true\n }\n }\n\n if (!cameraFound) {\n otherViewportsAnnotationsWithUniqueCameras.push(annotation)\n }\n }\n\n const otherNonLinkedViewportAnnotationsFromSameScene = annotations.filter(\n (annotation) => {\n const { data } = annotation\n const otherViewport = renderingEngine.getViewport(data.viewportUID)\n const otherViewportControllable = this._getReferenceLineControllable(\n otherViewport.uid\n )\n\n return (\n viewport !== otherViewport &&\n // scene === otherScene &&\n otherViewportControllable !== true\n )\n }\n )\n\n // Iterate second on other viewport from the same scene non linked\n for (\n let i = 0;\n i < otherNonLinkedViewportAnnotationsFromSameScene.length;\n ++i\n ) {\n const annotation = otherNonLinkedViewportAnnotationsFromSameScene[i]\n const { viewportUID } = annotation.data\n const otherViewport = renderingEngine.getViewport(viewportUID)\n\n const otherCamera = otherViewport.getCamera()\n const otherViewPlaneNormal = otherCamera.viewPlaneNormal\n vtkMath.normalize(otherViewPlaneNormal)\n\n if (\n csUtils.isEqual(viewPlaneNormal, otherViewPlaneNormal, 1e-2) ||\n csUtils.isOpposite(viewPlaneNormal, otherViewPlaneNormal, 1e-2)\n ) {\n continue\n }\n\n let cameraFound = false\n for (\n let jj = 0;\n jj < otherViewportsAnnotationsWithUniqueCameras.length;\n ++jj\n ) {\n const annotation = otherViewportsAnnotationsWithUniqueCameras[jj]\n const { viewportUID } = annotation.data\n const stockedViewport = renderingEngine.getViewport(viewportUID)\n const cameraOfStocked = stockedViewport.getCamera()\n\n if (\n csUtils.isEqual(\n cameraOfStocked.viewPlaneNormal,\n otherCamera.viewPlaneNormal,\n 1e-2\n ) &&\n csUtils.isEqual(cameraOfStocked.position, otherCamera.position, 1)\n ) {\n cameraFound = true\n }\n }\n\n if (!cameraFound) {\n otherViewportsAnnotationsWithUniqueCameras.push(annotation)\n }\n }\n\n // Iterate on all the viewport\n const otherViewportAnnotations =\n this._getAnnotationsForViewportsWithDifferentCameras(\n enabledElement,\n annotations\n )\n\n for (let i = 0; i < otherViewportAnnotations.length; ++i) {\n const annotation = otherViewportAnnotations[i]\n if (\n otherViewportsAnnotationsWithUniqueCameras.find(\n (element) => element === annotation\n ) === true\n ) {\n continue\n }\n\n const { viewportUID } = annotation.data\n const otherViewport = renderingEngine.getViewport(viewportUID)\n const otherCamera = otherViewport.getCamera()\n const otherViewPlaneNormal = otherCamera.viewPlaneNormal\n vtkMath.normalize(otherViewPlaneNormal)\n\n if (\n csUtils.isEqual(viewPlaneNormal, otherViewPlaneNormal, 1e-2) ||\n csUtils.isOpposite(viewPlaneNormal, otherViewPlaneNormal, 1e-2)\n ) {\n continue\n }\n\n let cameraFound = false\n for (\n let jj = 0;\n jj < otherViewportsAnnotationsWithUniqueCameras.length;\n ++jj\n ) {\n const annotation = otherViewportsAnnotationsWithUniqueCameras[jj]\n const { viewportUID } = annotation.data\n const stockedViewport = renderingEngine.getViewport(viewportUID)\n const cameraOfStocked = stockedViewport.getCamera()\n\n if (\n csUtils.isEqual(\n cameraOfStocked.viewPlaneNormal,\n otherCamera.viewPlaneNormal,\n 1e-2\n ) &&\n csUtils.isEqual(cameraOfStocked.position, otherCamera.position, 1)\n ) {\n cameraFound = true\n }\n }\n\n if (!cameraFound) {\n otherViewportsAnnotationsWithUniqueCameras.push(annotation)\n }\n }\n\n return otherViewportsAnnotationsWithUniqueCameras\n }\n\n _checkIfViewportsRenderingSameScene = (viewport, otherViewport) => {\n const actors = viewport.getActors()\n const otherViewportActors = otherViewport.getActors()\n\n let sameScene = true\n\n actors.forEach((actor) => {\n if (\n actors.length !== otherViewportActors.length ||\n otherViewportActors.find(({ uid }) => uid === actor.uid) === undefined\n ) {\n sameScene = false\n }\n })\n\n return sameScene\n }\n\n _jump = (enabledElement, jumpWorld) => {\n state.isInteractingWithTool = true\n const { viewport, renderingEngine } = enabledElement\n\n const annotations = getAnnotations(\n viewport.element,\n CrosshairsTool.toolName\n )\n\n const delta: Types.Point3 = [0, 0, 0]\n vtkMath.subtract(jumpWorld, this.toolCenter, delta)\n\n // TRANSLATION\n // get the annotation of the other viewport which are parallel to the delta shift and are of the same scene\n const otherViewportAnnotations =\n this._getAnnotationsForViewportsWithDifferentCameras(\n enabledElement,\n annotations\n )\n\n const viewportsAnnotationsToUpdate = otherViewportAnnotations.filter(\n (annotation) => {\n const { data } = annotation\n const otherViewport = renderingEngine.getViewport(data.viewportUID)\n\n const sameScene = this._checkIfViewportsRenderingSameScene(\n viewport,\n otherViewport\n )\n\n return (\n this._getReferenceLineControllable(otherViewport.uid) &&\n this._getReferenceLineDraggableRotatable(otherViewport.uid) &&\n sameScene\n )\n }\n )\n\n if (viewportsAnnotationsToUpdate.length === 0) {\n state.isInteractingWithTool = false\n return false\n }\n\n this._applyDeltaShiftToSelectedViewportCameras(\n renderingEngine,\n viewportsAnnotationsToUpdate,\n delta\n )\n\n state.isInteractingWithTool = false\n\n return true\n }\n\n _activateModify = (element) => {\n state.isInteractingWithTool = true\n\n element.addEventListener(Events.MOUSE_UP, this._mouseUpCallback)\n element.addEventListener(Events.MOUSE_DRAG, this._mouseDragCallback)\n element.addEventListener(Events.MOUSE_CLICK, this._mouseUpCallback)\n\n // element.addEventListener(Events.TOUCH_END, this._mouseUpCallback)\n // element.addEventListener(Events.TOUCH_DRAG, this._mouseDragCallback)\n }\n\n _deactivateModify = (element) => {\n state.isInteractingWithTool = false\n\n element.removeEventListener(Events.MOUSE_UP, this._mouseUpCallback)\n element.removeEventListener(Events.MOUSE_DRAG, this._mouseDragCallback)\n element.removeEventListener(Events.MOUSE_CLICK, this._mouseUpCallback)\n\n // element.removeEventListener(Events.TOUCH_END, this._mouseUpCallback)\n // element.removeEventListener(Events.TOUCH_DRAG, this._mouseDragCallback)\n }\n\n _mouseUpCallback = (\n evt: EventTypes.MouseUpEventType | EventTypes.MouseClickEventType\n ) => {\n const eventDetail = evt.detail\n const { element } = eventDetail\n\n this.editData.annotation.highlighted = false\n this.editData.annotation.data.handles.activeOperation = null\n this.editData.annotation.data.activeViewportUIDs = []\n\n this._deactivateModify(element)\n\n resetElementCursor(element)\n\n this.editData = null\n\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n\n const requireSameOrientation = false\n const viewportUIDsToRender = getViewportUIDsWithToolToRender(\n element,\n CrosshairsTool.toolName,\n requireSameOrientation\n )\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n }\n\n _mouseDragCallback = (evt: MouseDragEventType) => {\n const eventDetail = evt.detail\n const delta = eventDetail.deltaPoints.world\n\n if (\n Math.abs(delta[0]) < 1e-3 &&\n Math.abs(delta[1]) < 1e-3 &&\n Math.abs(delta[2]) < 1e-3\n ) {\n return\n }\n\n const { element } = eventDetail\n const enabledElement = getEnabledElement(element)\n const { renderingEngine, viewport } = enabledElement\n const annotations = getAnnotations(\n element,\n CrosshairsTool.toolName\n ) as CrosshairsAnnotation[]\n const filteredToolAnnotations =\n this.filterInteractableAnnotationsForElement(element, annotations)\n\n // viewport Annotation\n const viewportAnnotation = filteredToolAnnotations[0]\n if (!viewportAnnotation) {\n return\n }\n\n const { handles } = viewportAnnotation.data\n const { currentPoints } = evt.detail\n const canvasCoords = currentPoints.canvas\n\n if (handles.activeOperation === OPERATION.DRAG) {\n // TRANSLATION\n // get the annotation of the other viewport which are parallel to the delta shift and are of the same scene\n const otherViewportAnnotations =\n this._getAnnotationsForViewportsWithDifferentCameras(\n enabledElement,\n annotations\n )\n\n const viewportsAnnotationsToUpdate = otherViewportAnnotations.filter(\n (annotation) => {\n const { data } = annotation\n const otherViewport = renderingEngine.getViewport(data.viewportUID)\n\n return viewportAnnotation.data.activeViewportUIDs.find(\n (uid) => uid === otherViewport.uid\n )\n }\n )\n\n this._applyDeltaShiftToSelectedViewportCameras(\n renderingEngine,\n viewportsAnnotationsToUpdate,\n delta\n )\n } else if (handles.activeOperation === OPERATION.ROTATE) {\n // ROTATION\n const otherViewportAnnotations =\n this._getAnnotationsForViewportsWithDifferentCameras(\n enabledElement,\n annotations\n )\n\n const viewportsAnnotationsToUpdate = otherViewportAnnotations.filter(\n (annotation) => {\n const { data } = annotation\n data.handles.toolCenter = center\n const otherViewport = renderingEngine.getViewport(data.viewportUID)\n const otherViewportControllable = this._getReferenceLineControllable(\n otherViewport.uid\n )\n const otherViewportRotatable =\n this._getReferenceLineDraggableRotatable(otherViewport.uid)\n\n return (\n // scene === otherScene &&\n otherViewportControllable === true &&\n otherViewportRotatable === true\n )\n }\n )\n\n const dir1 = vec2.create()\n const dir2 = vec2.create()\n\n const center: Types.Point3 = [\n this.toolCenter[0],\n this.toolCenter[1],\n this.toolCenter[2],\n ]\n\n const centerCanvas = viewport.worldToCanvas(center)\n\n const finalPointCanvas = eventDetail.currentPoints.canvas\n const originalPointCanvas = vec2.create()\n vec2.sub(\n originalPointCanvas,\n finalPointCanvas,\n eventDetail.deltaPoints.canvas\n )\n vec2.sub(dir1, originalPointCanvas, <vec2>centerCanvas)\n vec2.sub(dir2, finalPointCanvas, <vec2>centerCanvas)\n\n let angle = vec2.angle(dir1, dir2)\n\n if (\n this._isClockWise(centerCanvas, originalPointCanvas, finalPointCanvas)\n ) {\n angle *= -1\n }\n\n // Rounding the angle to allow rotated handles to be undone\n // If we don't round and rotate handles clockwise by 0.0131233 radians,\n // there's no assurance that the counter-clockwise rotation occurs at\n // precisely -0.0131233, resulting in the drawn annotations being lost.\n angle = Math.round(angle * 100) / 100\n\n const rotationAxis = viewport.getCamera().viewPlaneNormal\n // @ts-ignore : vtkjs incorrect typing\n const { matrix } = vtkMatrixBuilder\n .buildFromRadian()\n .translate(center[0], center[1], center[2])\n // @ts-ignore\n .rotate(angle, rotationAxis) //todo: why we are passing\n .translate(-center[0], -center[1], -center[2])\n\n const otherViewportsUIDs = []\n // update camera for the other viewports.\n // NOTE: The lines then are rendered by the onCameraModified\n viewportsAnnotationsToUpdate.forEach((annotation) => {\n const { data } = annotation\n data.handles.toolCenter = center\n\n const otherViewport = renderingEngine.getViewport(data.viewportUID)\n const camera = otherViewport.getCamera()\n const { viewUp, position, focalPoint } = camera\n\n viewUp[0] += position[0]\n viewUp[1] += position[1]\n viewUp[2] += position[2]\n\n vec3.transformMat4(focalPoint, focalPoint, matrix)\n vec3.transformMat4(position, position, matrix)\n vec3.transformMat4(viewUp, viewUp, matrix)\n\n viewUp[0] -= position[0]\n viewUp[1] -= position[1]\n viewUp[2] -= position[2]\n\n otherViewport.setCamera({\n position,\n viewUp,\n focalPoint,\n })\n otherViewportsUIDs.push(otherViewport.uid)\n })\n renderingEngine.renderViewports(otherViewportsUIDs)\n } else if (handles.activeOperation === OPERATION.SLAB) {\n // SLAB THICKNESS\n // this should be just the active one under the mouse,\n const viewportsAnnotationsToUpdate = annotations.filter(\n (annotation: CrosshairsAnnotation) => {\n const { data } = annotation\n const otherViewport = renderingEngine.getViewport(data.viewportUID)\n\n return viewportAnnotation.data.activeViewportUIDs.find(\n (uid) => uid === otherViewport.uid\n )\n }\n )\n\n viewportsAnnotationsToUpdate.forEach(\n (annotation: CrosshairsAnnotation) => {\n const { data } = annotation\n\n const otherViewport = renderingEngine.getViewport(\n data.viewportUID\n ) as Types.IVolumeViewport\n const camera = otherViewport.getCamera()\n const normal = camera.viewPlaneNormal\n\n const dotProd = vtkMath.dot(delta, normal)\n const projectedDelta: Types.Point3 = [...normal]\n vtkMath.multiplyScalar(projectedDelta, dotProd)\n\n if (\n Math.abs(projectedDelta[0]) > 1e-3 ||\n Math.abs(projectedDelta[1]) > 1e-3 ||\n Math.abs(projectedDelta[2]) > 1e-3\n ) {\n const mod = Math.sqrt(\n projectedDelta[0] * projectedDelta[0] +\n projectedDelta[1] * projectedDelta[1] +\n projectedDelta[2] * projectedDelta[2]\n )\n\n const currentPoint = eventDetail.lastPoints.world\n const direction: Types.Point3 = [0, 0, 0]\n\n const currentCenter: Types.Point3 = [\n this.toolCenter[0],\n this.toolCenter[1],\n this.toolCenter[2],\n ]\n\n // use this.toolCenter only if viewportDraggableRotatable\n const viewportDraggableRotatable =\n this._getReferenceLineDraggableRotatable(otherViewport.uid)\n if (!viewportDraggableRotatable) {\n const { rotationPoints } = this.editData.annotation.data.handles\n const otherViewportRotationPoints = rotationPoints.filter(\n (point) => point[1].uid === otherViewport.uid\n )\n if (otherViewportRotationPoints.length === 2) {\n const point1 = viewport.canvasToWorld(\n otherViewportRotationPoints[0][3]\n )\n const point2 = viewport.canvasToWorld(\n otherViewportRotationPoints[1][3]\n )\n vtkMath.add(point1, point2, currentCenter)\n vtkMath.multiplyScalar(<Types.Point3>currentCenter, 0.5)\n }\n }\n\n vtkMath.subtract(currentPoint, currentCenter, direction)\n const dotProdDirection = vtkMath.dot(direction, normal)\n const projectedDirection: Types.Point3 = [...normal]\n vtkMath.multiplyScalar(projectedDirection, dotProdDirection)\n const normalizedProjectedDirection: Types.Point3 = [\n projectedDirection[0],\n projectedDirection[1],\n projectedDirection[2],\n ]\n vec3.normalize(\n normalizedProjectedDirection,\n normalizedProjectedDirection\n )\n const normalizedProjectedDelta: Types.Point3 = [\n projectedDelta[0],\n projectedDelta[1],\n projectedDelta[2],\n ]\n vec3.normalize(normalizedProjectedDelta, normalizedProjectedDelta)\n\n let slabThicknessValue = otherViewport.getSlabThickness()\n if (\n csUtils.isOpposite(\n normalizedProjectedDirection,\n normalizedProjectedDelta,\n 1e-3\n )\n ) {\n slabThicknessValue -= mod\n } else {\n slabThicknessValue += mod\n }\n\n slabThicknessValue = Math.abs(slabThicknessValue)\n slabThicknessValue = Math.max(0.1, slabThicknessValue)\n\n const near = this._pointNearReferenceLine(\n viewportAnnotation,\n canvasCoords,\n 6,\n otherViewport\n )\n\n if (near) {\n otherViewport.setSlabThickness(null)\n } else {\n otherViewport.setSlabThickness(slabThicknessValue)\n }\n otherViewport.render()\n }\n }\n )\n }\n }\n\n _isClockWise(a, b, c) {\n // return true if the rotation is clockwise\n return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]) > 0\n }\n\n _applyDeltaShiftToSelectedViewportCameras(\n renderingEngine,\n viewportsAnnotationsToUpdate,\n delta\n ) {\n // update camera for the other viewports.\n // NOTE1: The lines then are rendered by the onCameraModified\n // NOTE2: crosshair center are automatically updated in the onCameraModified event\n viewportsAnnotationsToUpdate.forEach((annotation) => {\n this._applyDeltaShiftToViewportCamera(renderingEngine, annotation, delta)\n })\n }\n _applyDeltaShiftToViewportCamera(\n renderingEngine: Types.IRenderingEngine,\n annotation,\n delta\n ) {\n // update camera for the other viewports.\n // NOTE1: The lines then are rendered by the onCameraModified\n // NOTE2: crosshair center are automatically updated in the onCameraModified event\n const { data } = annotation\n\n const viewport = renderingEngine.getViewport(data.viewportUID)\n const camera = viewport.getCamera()\n const normal = camera.viewPlaneNormal\n\n // Project delta over camera normal\n // (we don't need to pan, we need only to scroll the camera as in the wheel stack scroll tool)\n const dotProd = vtkMath.dot(delta, normal)\n const projectedDelta: Types.Point3 = [...normal]\n vtkMath.multiplyScalar(projectedDelta, dotProd)\n\n if (\n Math.abs(projectedDelta[0]) > 1e-3 ||\n Math.abs(projectedDelta[1]) > 1e-3 ||\n Math.abs(projectedDelta[2]) > 1e-3\n ) {\n const newFocalPoint: Types.Point3 = [0, 0, 0]\n const newPosition: Types.Point3 = [0, 0, 0]\n\n vtkMath.add(camera.focalPoint, projectedDelta, newFocalPoint)\n vtkMath.add(camera.position, projectedDelta, newPosition)\n\n viewport.setCamera({\n focalPoint: newFocalPoint,\n position: newPosition,\n })\n viewport.render()\n }\n }\n\n _pointNearReferenceLine = (\n annotation,\n canvasCoords,\n proximity,\n lineViewport\n ) => {\n const { data } = annotation\n const { rotationPoints } = data.handles\n\n for (let i = 0; i < rotationPoints.length - 1; ++i) {\n const otherViewport = rotationPoints[i][1]\n if (otherViewport.uid !== lineViewport.uid) {\n continue\n }\n\n const viewportControllable = this._getReferenceLineControllable(\n otherViewport.uid\n )\n if (!viewportControllable) {\n continue\n }\n\n const lineSegment1 = {\n start: {\n x: rotationPoints[i][2][0],\n y: rotationPoints[i][2][1],\n },\n end: {\n x: rotationPoints[i][3][0],\n y: rotationPoints[i][3][1],\n },\n }\n\n const distanceToPoint1 = lineSegment.distanceToPoint(\n [lineSegment1.start.x, lineSegment1.start.y],\n [lineSegment1.end.x, lineSegment1.end.y],\n [canvasCoords[0], canvasCoords[1]]\n )\n\n const lineSegment2 = {\n start: {\n x: rotationPoints[i + 1][2][0],\n y: rotationPoints[i + 1][2][1],\n },\n end: {\n x: rotationPoints[i + 1][3][0],\n y: rotationPoints[i + 1][3][1],\n },\n }\n\n const distanceToPoint2 = lineSegment.distanceToPoint(\n [lineSegment2.start.x, lineSegment2.start.y],\n [lineSegment2.end.x, lineSegment2.end.y],\n [canvasCoords[0], canvasCoords[1]]\n )\n\n if (distanceToPoint1 <= proximity || distanceToPoint2 <= proximity) {\n return true\n }\n\n // rotation handles are two for viewport\n i++\n }\n\n return false\n }\n\n _getRotationHandleNearImagePoint(\n viewport,\n annotation,\n canvasCoords,\n proximity\n ) {\n const { data } = annotation\n const { rotationPoints } = data.handles\n\n for (let i = 0; i < rotationPoints.length; i++) {\n const point = rotationPoints[i][0]\n const otherViewport = rotationPoints[i][1]\n const viewportControllable = this._getReferenceLineControllable(\n otherViewport.uid\n )\n if (!viewportControllable) {\n continue\n }\n\n const viewportDraggableRotatable =\n this._getReferenceLineDraggableRotatable(otherViewport.uid)\n if (!viewportDraggableRotatable) {\n continue\n }\n\n const annotationCanvasCoordinate = viewport.worldToCanvas(point)\n if (vec2.distance(canvasCoords, annotationCanvasCoordinate) < proximity) {\n data.handles.activeOperation = OPERATION.ROTATE\n\n this.editData = {\n annotation,\n }\n\n return point\n }\n }\n\n return null\n }\n\n _getSlabThicknessHandleNearImagePoint(\n viewport,\n annotation,\n canvasCoords,\n proximity\n ) {\n const { data } = annotation\n const { slabThicknessPoints } = data.handles\n\n for (let i = 0; i < slabThicknessPoints.length; i++) {\n const point = slabThicknessPoints[i][0]\n const otherViewport = slabThicknessPoints[i][1]\n const viewportControllable = this._getReferenceLineControllable(\n otherViewport.uid\n )\n if (!viewportControllable) {\n continue\n }\n\n const viewportSlabThicknessControlsOn =\n this._getReferenceLineSlabThicknessControlsOn(otherViewport.uid)\n if (!viewportSlabThicknessControlsOn) {\n continue\n }\n\n const annotationCanvasCoordinate = viewport.worldToCanvas(point)\n if (vec2.distance(canvasCoords, annotationCanvasCoordinate) < proximity) {\n data.handles.activeOperation = OPERATION.SLAB\n\n data.activeViewportUIDs = [otherViewport.uid]\n\n this.editData = {\n annotation,\n }\n\n return point\n }\n }\n\n return null\n }\n\n _pointNearTool(element, annotation, canvasCoords, proximity) {\n const enabledElement = getEnabledElement(element)\n const { viewport } = enabledElement\n const { sWidth, sHeight } = viewport\n const canvasDiagonalLength = Math.sqrt(sWidth * sWidth + sHeight * sHeight)\n const { data } = annotation\n\n const { rotationPoints } = data.handles\n const { slabThicknessPoints } = data.handles\n const viewportUIDArray = []\n\n for (let i = 0; i < rotationPoints.length - 1; ++i) {\n const otherViewport = rotationPoints[i][1]\n const viewportControllable = this._getReferenceLineControllable(\n otherViewport.uid\n )\n const viewportDraggableRotatable =\n this._getReferenceLineDraggableRotatable(otherViewport.uid)\n\n if (!viewportControllable || !viewportDraggableRotatable) {\n continue\n }\n\n const lineSegment1 = {\n start: {\n x: rotationPoints[i][2][0],\n y: rotationPoints[i][2][1],\n },\n end: {\n x: rotationPoints[i][3][0],\n y: rotationPoints[i][3][1],\n },\n }\n\n const distanceToPoint1 = lineSegment.distanceToPoint(\n [lineSegment1.start.x, lineSegment1.start.y],\n [lineSegment1.end.x, lineSegment1.end.y],\n [canvasCoords[0], canvasCoords[1]]\n )\n\n const lineSegment2 = {\n start: {\n x: rotationPoints[i + 1][2][0],\n y: rotationPoints[i + 1][2][1],\n },\n end: {\n x: rotationPoints[i + 1][3][0],\n y: rotationPoints[i + 1][3][1],\n },\n }\n\n const distanceToPoint2 = lineSegment.distanceToPoint(\n [lineSegment2.start.x, lineSegment2.start.y],\n [lineSegment2.end.x, lineSegment2.end.y],\n [canvasCoords[0], canvasCoords[1]]\n )\n\n if (distanceToPoint1 <= proximity || distanceToPoint2 <= proximity) {\n viewportUIDArray.push(otherViewport.uid)\n data.handles.activeOperation = OPERATION.DRAG\n }\n\n // rotation handles are two for viewport\n i++\n }\n\n for (let i = 0; i < slabThicknessPoints.length - 1; ++i) {\n const otherViewport = slabThicknessPoints[i][1]\n if (viewportUIDArray.find((uid) => uid === otherViewport.uid)) {\n continue\n }\n\n const viewportControllable = this._getReferenceLineControllable(\n otherViewport.uid\n )\n const viewportSlabThicknessControlsOn =\n this._getReferenceLineSlabThicknessControlsOn(otherViewport.uid)\n\n if (!viewportControllable || !viewportSlabThicknessControlsOn) {\n continue\n }\n\n const stPointLineCanvas1 = slabThicknessPoints[i][2]\n const stPointLineCanvas2 = slabThicknessPoints[i][3]\n\n const centerCanvas = vec2.create()\n vec2.add(centerCanvas, stPointLineCanvas1, stPointLineCanvas2)\n vec2.scale(centerCanvas, centerCanvas, 0.5)\n\n const canvasUnitVectorFromCenter = vec2.create()\n vec2.subtract(\n canvasUnitVectorFromCenter,\n stPointLineCanvas1,\n centerCanvas\n )\n vec2.normalize(canvasUnitVectorFromCenter, canvasUnitVectorFromCenter)\n\n const canvasVectorFromCenterStart = vec2.create()\n vec2.scale(\n canvasVectorFromCenterStart,\n canvasUnitVectorFromCenter,\n canvasDiagonalLength * 0.05\n )\n\n const stPointLineCanvas1Start = vec2.create()\n const stPointLineCanvas2Start = vec2.create()\n vec2.add(\n stPointLineCanvas1Start,\n centerCanvas,\n canvasVectorFromCenterStart\n )\n vec2.subtract(\n stPointLineCanvas2Start,\n centerCanvas,\n canvasVectorFromCenterStart\n )\n\n const lineSegment1 = {\n start: {\n x: stPointLineCanvas1Start[0],\n y: stPointLineCanvas1Start[1],\n },\n end: {\n x: stPointLineCanvas1[0],\n y: stPointLineCanvas1[1],\n },\n }\n\n const distanceToPoint1 = lineSegment.distanceToPoint(\n [lineSegment1.start.x, lineSegment1.start.y],\n [lineSegment1.end.x, lineSegment1.end.y],\n [canvasCoords[0], canvasCoords[1]]\n )\n\n const lineSegment2 = {\n start: {\n x: stPointLineCanvas2Start[0],\n y: stPointLineCanvas2Start[1],\n },\n end: {\n x: stPointLineCanvas2[0],\n y: stPointLineCanvas2[1],\n },\n }\n\n const distanceToPoint2 = lineSegment.distanceToPoint(\n [lineSegment2.start.x, lineSegment2.start.y],\n [lineSegment2.end.x, lineSegment2.end.y],\n [canvasCoords[0], canvasCoords[1]]\n )\n\n if (distanceToPoint1 <= proximity || distanceToPoint2 <= proximity) {\n viewportUIDArray.push(otherViewport.uid) // we still need this to draw inactive slab thickness handles\n data.handles.activeOperation = null // no operation\n }\n\n // slab thickness handles are in couples\n i++\n }\n\n data.activeViewportUIDs = [...viewportUIDArray]\n\n this.editData = {\n annotation,\n }\n\n return data.handles.activeOperation === OPERATION.DRAG ? true : false\n }\n}\n","import { vec2, vec3 } from 'gl-matrix'\nimport {\n Settings,\n getEnabledElement,\n StackViewport,\n triggerEvent,\n eventTarget,\n cache,\n utilities as csUtils,\n} from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\n\nimport { AnnotationTool } from '../base'\nimport throttle from '../../utilities/throttle'\nimport {\n addAnnotation,\n getAnnotations,\n removeAnnotation,\n} from '../../stateManagement/annotation/annotationState'\nimport { isAnnotationLocked } from '../../stateManagement/annotation/annotationLocking'\nimport {\n drawLine as drawLineSvg,\n drawHandles as drawHandlesSvg,\n drawLinkedTextBox as drawLinkedTextBoxSvg,\n} from '../../drawingSvg'\nimport { state } from '../../store'\nimport { Events } from '../../enums'\nimport { getViewportUIDsWithToolToRender } from '../../utilities/viewportFilters'\nimport lineSegment from '../../utilities/math/line'\nimport { getTextBoxCoordsCanvas } from '../../utilities/drawing'\nimport transformPhysicalToIndex from '../../utilities/transformPhysicalToIndex'\nimport {\n resetElementCursor,\n hideElementCursor,\n} from '../../cursors/elementCursor'\nimport {\n Annotation,\n EventTypes,\n ToolHandle,\n TextBoxHandle,\n PublicToolProps,\n ToolProps,\n InteractionTypes,\n} from '../../types'\nimport {\n AnnotationModifiedEventDetail,\n MouseDragEventType,\n MouseMoveEventType,\n} from '../../types/EventTypes'\nimport triggerAnnotationRenderForViewportUIDs from '../../utilities/triggerAnnotationRenderForViewportUIDs'\n\ninterface BidirectionalAnnotation extends Annotation {\n data: {\n handles: {\n points: Types.Point3[]\n activeHandleIndex: number | null\n textBox: {\n hasMoved: boolean\n worldPosition: Types.Point3\n worldBoundingBox: {\n topLeft: Types.Point3\n topRight: Types.Point3\n bottomLeft: Types.Point3\n bottomRight: Types.Point3\n }\n }\n }\n label: string\n cachedStats: {\n [targetUID: string]: {\n length: number\n width: number\n }\n }\n }\n}\n\n/**\n * BidirectionalTool let you draw annotations that measures the length and\n * width at the same time in `mm` unit. It is consisted of two perpendicular lines and\n * a text box. You can use the BidirectionalTool in all planes even in oblique\n * reconstructed planes. Note: annotation tools in cornerstone3DTools exists in the exact location\n * in the physical 3d space, as a result, by default, all annotations that are\n * drawing in the same frameOfReference will get shared between viewports that\n * are in the same frameOfReference.\n *\n * The resulting annotation's data (statistics) and metadata (the\n * state of the viewport while drawing was happening) will get added to the\n * ToolState manager and can be accessed from the ToolState by calling getAnnotations\n * or similar methods.\n *\n * ```js\n * cornerstoneTools.addTool(BidirectionalTool)\n *\n * const toolGroup = ToolGroupManager.createToolGroup('toolGroupUID')\n *\n * toolGroup.addTool(BidirectionalTool.toolName)\n *\n * toolGroup.addViewport('viewportUID', 'renderingEngineUID')\n *\n * toolGroup.setToolActive(BidirectionalTool.toolName, {\n * bindings: [\n * {\n * mouseButton: MouseBindings.Primary, // Left Click\n * },\n * ],\n * })\n * ```\n *\n * Read more in the Docs section of the website.\n */\nexport default class BidirectionalTool extends AnnotationTool {\n static toolName = 'Bidirectional'\n\n touchDragCallback: any\n mouseDragCallback: any\n _throttledCalculateCachedStats: any\n editData: {\n annotation: any\n viewportUIDsToRender: string[]\n handleIndex?: number\n movingTextBox: boolean\n newAnnotation?: boolean\n hasMoved?: boolean\n } | null\n isDrawing: boolean\n isHandleOutsideImage: boolean\n preventHandleOutsideImage: boolean\n\n constructor(\n toolProps: PublicToolProps = {},\n defaultToolProps: ToolProps = {\n supportedInteractionTypes: ['Mouse', 'Touch'],\n configuration: {\n shadow: true,\n preventHandleOutsideImage: false,\n },\n }\n ) {\n super(toolProps, defaultToolProps)\n\n this._throttledCalculateCachedStats = throttle(\n this._calculateCachedStats,\n 100,\n { trailing: true }\n )\n }\n\n /**\n * Based on the current position of the mouse and the current imageId to create\n * a Bidirectional Annotation and stores it in the annotationManager\n *\n * @param evt - EventTypes.NormalizedMouseEventType\n * @returns The annotation object.\n *\n */\n addNewAnnotation(\n evt: EventTypes.MouseDownActivateEventType\n ): BidirectionalAnnotation {\n const eventDetail = evt.detail\n const { currentPoints, element } = eventDetail\n const worldPos = currentPoints.world\n const enabledElement = getEnabledElement(element)\n const { viewport, renderingEngine } = enabledElement\n\n this.isDrawing = true\n\n const camera = viewport.getCamera()\n const { viewPlaneNormal, viewUp } = camera\n\n let referencedImageId\n if (viewport instanceof StackViewport) {\n referencedImageId =\n viewport.getCurrentImageId && viewport.getCurrentImageId()\n } else {\n const volumeUID = this.getTargetUID(viewport)\n const imageVolume = cache.getVolume(volumeUID)\n referencedImageId = csUtils.getClosestImageId(\n imageVolume,\n worldPos,\n viewPlaneNormal,\n viewUp\n )\n }\n\n if (referencedImageId) {\n const colonIndex = referencedImageId.indexOf(':')\n referencedImageId = referencedImageId.substring(colonIndex + 1)\n }\n\n const annotation: BidirectionalAnnotation = {\n highlighted: true,\n invalidated: true,\n metadata: {\n viewPlaneNormal: <Types.Point3>[...viewPlaneNormal],\n viewUp: <Types.Point3>[...viewUp],\n FrameOfReferenceUID: viewport.getFrameOfReferenceUID(),\n toolName: BidirectionalTool.toolName,\n referencedImageId,\n },\n data: {\n handles: {\n points: [\n // long\n <Types.Point3>[...worldPos],\n <Types.Point3>[...worldPos],\n // short\n <Types.Point3>[...worldPos],\n <Types.Point3>[...worldPos],\n ],\n textBox: {\n hasMoved: false,\n worldPosition: <Types.Point3>[0, 0, 0],\n worldBoundingBox: {\n topLeft: <Types.Point3>[0, 0, 0],\n topRight: <Types.Point3>[0, 0, 0],\n bottomLeft: <Types.Point3>[0, 0, 0],\n bottomRight: <Types.Point3>[0, 0, 0],\n },\n },\n activeHandleIndex: null,\n },\n label: '',\n cachedStats: {},\n },\n }\n\n // Ensure settings are initialized after annotation instantiation\n Settings.getObjectSettings(annotation, BidirectionalTool)\n\n addAnnotation(element, annotation)\n\n const viewportUIDsToRender = getViewportUIDsWithToolToRender(\n element,\n BidirectionalTool.toolName\n )\n\n this.editData = {\n annotation,\n viewportUIDsToRender,\n handleIndex: 1,\n movingTextBox: false,\n newAnnotation: true,\n hasMoved: false,\n }\n this._activateDraw(element)\n\n hideElementCursor(element)\n\n evt.preventDefault()\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n\n return annotation\n }\n\n /**\n * It returns if the canvas point is near the provided annotation in the provided\n * element or not. A proximity is passed to the function to determine the\n * proximity of the point to the annotation in number of pixels.\n *\n * @param element - HTML Element\n * @param annotation - Annotation\n * @param canvasCoords - Canvas coordinates\n * @param proximity - Proximity to tool to consider\n * @returns Boolean, whether the canvas point is near tool\n */\n isPointNearTool = (\n element: HTMLElement,\n annotation: BidirectionalAnnotation,\n canvasCoords: Types.Point2,\n proximity: number\n ): boolean => {\n const enabledElement = getEnabledElement(element)\n const { viewport } = enabledElement\n const { data } = annotation\n const { points } = data.handles\n\n // Check long axis\n let canvasPoint1 = viewport.worldToCanvas(points[0])\n let canvasPoint2 = viewport.worldToCanvas(points[1])\n\n let line = {\n start: {\n x: canvasPoint1[0],\n y: canvasPoint1[1],\n },\n end: {\n x: canvasPoint2[0],\n y: canvasPoint2[1],\n },\n }\n\n let distanceToPoint = lineSegment.distanceToPoint(\n [line.start.x, line.start.y],\n [line.end.x, line.end.y],\n [canvasCoords[0], canvasCoords[1]]\n )\n\n if (distanceToPoint <= proximity) {\n return true\n }\n\n // Check short axis\n canvasPoint1 = viewport.worldToCanvas(points[2])\n canvasPoint2 = viewport.worldToCanvas(points[3])\n\n line = {\n start: {\n x: canvasPoint1[0],\n y: canvasPoint1[1],\n },\n end: {\n x: canvasPoint2[0],\n y: canvasPoint2[1],\n },\n }\n\n distanceToPoint = lineSegment.distanceToPoint(\n [line.start.x, line.start.y],\n [line.end.x, line.end.y],\n [canvasCoords[0], canvasCoords[1]]\n )\n\n if (distanceToPoint <= proximity) {\n return true\n }\n\n return false\n }\n\n /**\n * Handles the toolSelected callback for bidirectional tool\n * @param evt - EventTypes.MouseDownEventType\n * @param annotation - Bidirectional annotation\n * @param interactionType - interaction type (mouse, touch)\n */\n toolSelectedCallback = (\n evt: EventTypes.MouseDownEventType,\n annotation: BidirectionalAnnotation,\n interactionType: InteractionTypes\n ): void => {\n const eventDetail = evt.detail\n const { element } = eventDetail\n\n annotation.highlighted = true\n\n const viewportUIDsToRender = getViewportUIDsWithToolToRender(\n element,\n BidirectionalTool.toolName\n )\n\n this.editData = {\n annotation,\n viewportUIDsToRender,\n movingTextBox: false,\n }\n\n this._activateModify(element)\n\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n\n hideElementCursor(element)\n\n evt.preventDefault()\n }\n\n /**\n * Executes the callback for when mouse has selected a handle (anchor point) of\n * the bidirectional tool or when the text box has been selected.\n *\n * @param evt - EventTypes.MouseDownEventType\n * @param annotation - Bidirectional annotation\n * @param handle - Handle index or selected textBox information\n * @param interactionType - interaction type (mouse, touch)\n */\n handleSelectedCallback = (\n evt: EventTypes.MouseDownEventType,\n annotation: BidirectionalAnnotation,\n handle: ToolHandle,\n interactionType = 'mouse'\n ): void => {\n const eventDetail = evt.detail\n const { element } = eventDetail\n const data = annotation.data\n\n annotation.highlighted = true\n\n let movingTextBox = false\n let handleIndex\n\n if ((handle as TextBoxHandle).worldPosition) {\n movingTextBox = true\n } else {\n handleIndex = data.handles.points.findIndex((p) => p === handle)\n }\n\n // Find viewports to render on drag.\n const viewportUIDsToRender = getViewportUIDsWithToolToRender(\n element,\n BidirectionalTool.toolName\n )\n\n hideElementCursor(element)\n\n this.editData = {\n annotation,\n viewportUIDsToRender,\n handleIndex,\n movingTextBox,\n }\n this._activateModify(element)\n\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n\n evt.preventDefault()\n }\n\n /**\n * Handles the mouse up action for the bidirectional tool. It can be at the end\n * of the annotation drawing (MouseUpEventType) or when the user clicks and release\n * the mouse button instantly which let to the annotation to draw without holding\n * the mouse button (MouseClickEventType).\n *\n * @param evt - mouse up or mouse click event types\n */\n _mouseUpCallback = (\n evt: EventTypes.MouseUpEventType | EventTypes.MouseClickEventType\n ) => {\n const eventDetail = evt.detail\n const { element } = eventDetail\n\n const { annotation, viewportUIDsToRender, newAnnotation, hasMoved } =\n this.editData\n const { data } = annotation\n\n if (newAnnotation && !hasMoved) {\n return\n }\n\n annotation.highlighted = false\n data.handles.activeHandleIndex = null\n\n this._deactivateModify(element)\n this._deactivateDraw(element)\n\n resetElementCursor(element)\n\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n\n if (this.editData.handleIndex !== undefined) {\n const { points } = data.handles\n const firstLineSegmentLength = vec3.distance(points[0], points[1])\n const secondLineSegmentLength = vec3.distance(points[2], points[3])\n\n if (secondLineSegmentLength > firstLineSegmentLength) {\n // Switch points so [0,1] is the long axis and [2,3] is the short axis.\n\n const longAxis = [[...points[2]], [...points[3]]]\n\n const shortAxisPoint0 = [...points[0]]\n const shortAxisPoint1 = [...points[1]]\n\n // shortAxis[0->1] should be perpendicular (counter-clockwise) to longAxis[0->1]\n const longAxisVector = vec2.create()\n\n vec2.set(\n longAxisVector,\n longAxis[1][0] - longAxis[0][0],\n longAxis[1][1] - longAxis[1][0]\n )\n\n const counterClockWisePerpendicularToLongAxis = vec2.create()\n\n vec2.set(\n counterClockWisePerpendicularToLongAxis,\n -longAxisVector[1],\n longAxisVector[0]\n )\n\n const currentShortAxisVector = vec2.create()\n\n vec2.set(\n currentShortAxisVector,\n shortAxisPoint1[0] - shortAxisPoint0[0],\n shortAxisPoint1[1] - shortAxisPoint0[0]\n )\n\n let shortAxis\n\n if (\n vec2.dot(\n currentShortAxisVector,\n counterClockWisePerpendicularToLongAxis\n ) > 0\n ) {\n shortAxis = [shortAxisPoint0, shortAxisPoint1]\n } else {\n shortAxis = [shortAxisPoint1, shortAxisPoint0]\n }\n\n data.handles.points = [\n longAxis[0],\n longAxis[1],\n shortAxis[0],\n shortAxis[1],\n ]\n }\n }\n\n if (\n this.isHandleOutsideImage &&\n this.configuration.preventHandleOutsideImage\n ) {\n removeAnnotation(element, annotation.annotationUID)\n }\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n\n this.editData = null\n this.isDrawing = false\n }\n\n /**\n * @param evt - mouse move event type or mouse drag\n */\n _mouseDragDrawCallback = (evt: MouseMoveEventType | MouseDragEventType) => {\n this.isDrawing = true\n\n const eventDetail = evt.detail\n const { currentPoints, element } = eventDetail\n const enabledElement = getEnabledElement(element)\n const { renderingEngine, viewport } = enabledElement\n const { worldToCanvas } = viewport\n const { annotation, viewportUIDsToRender, handleIndex } = this.editData\n const { data } = annotation\n\n const worldPos = currentPoints.world\n\n // Update first move handle\n data.handles.points[handleIndex] = [...worldPos]\n\n const canvasCoordPoints = data.handles.points.map(worldToCanvas)\n\n const canvasCoords = {\n longLineSegment: {\n start: {\n x: canvasCoordPoints[0][0],\n y: canvasCoordPoints[0][1],\n },\n end: {\n x: canvasCoordPoints[1][0],\n y: canvasCoordPoints[1][1],\n },\n },\n shortLineSegment: {\n start: {\n x: canvasCoordPoints[2][0],\n y: canvasCoordPoints[2][1],\n },\n end: {\n x: canvasCoordPoints[3][0],\n y: canvasCoordPoints[3][1],\n },\n },\n }\n\n // ~~ calculate worldPos of our short axis handles\n // 1/3 distance between long points\n const dist = vec2.distance(canvasCoordPoints[0], canvasCoordPoints[1])\n\n const shortAxisDistFromCenter = dist / 3\n // Calculate long line's incline\n const dx =\n canvasCoords.longLineSegment.start.x - canvasCoords.longLineSegment.end.x\n const dy =\n canvasCoords.longLineSegment.start.y - canvasCoords.longLineSegment.end.y\n const length = Math.sqrt(dx * dx + dy * dy)\n const vectorX = dx / length\n const vectorY = dy / length\n // middle point between long line segment's points\n const xMid =\n (canvasCoords.longLineSegment.start.x +\n canvasCoords.longLineSegment.end.x) /\n 2\n const yMid =\n (canvasCoords.longLineSegment.start.y +\n canvasCoords.longLineSegment.end.y) /\n 2\n // short points 1/3 distance from center of long points\n const startX = xMid + shortAxisDistFromCenter * vectorY\n const startY = yMid - shortAxisDistFromCenter * vectorX\n const endX = xMid - shortAxisDistFromCenter * vectorY\n const endY = yMid + shortAxisDistFromCenter * vectorX\n\n // Update perpendicular line segment's points\n data.handles.points[2] = viewport.canvasToWorld([startX, startY])\n data.handles.points[3] = viewport.canvasToWorld([endX, endY])\n\n annotation.invalidated = true\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n\n this.editData.hasMoved = true\n }\n\n /**\n * Mouse drag to edit annotation callback\n * @param evt - mouse drag event\n */\n _mouseDragModifyCallback = (evt: MouseDragEventType) => {\n this.isDrawing = true\n\n const eventDetail = evt.detail\n const { element } = eventDetail\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n const { annotation, viewportUIDsToRender, handleIndex, movingTextBox } =\n this.editData\n const { data } = annotation\n if (movingTextBox) {\n const { deltaPoints } = eventDetail\n const worldPosDelta = deltaPoints.world\n\n const { textBox } = data.handles\n const { worldPosition } = textBox\n\n worldPosition[0] += worldPosDelta[0]\n worldPosition[1] += worldPosDelta[1]\n worldPosition[2] += worldPosDelta[2]\n\n textBox.hasMoved = true\n } else if (handleIndex === undefined) {\n // Moving tool\n const { deltaPoints } = eventDetail\n const worldPosDelta = deltaPoints.world\n const points = data.handles.points\n\n points.forEach((point) => {\n point[0] += worldPosDelta[0]\n point[1] += worldPosDelta[1]\n point[2] += worldPosDelta[2]\n })\n annotation.invalidated = true\n } else {\n this._mouseDragModifyHandle(evt)\n annotation.invalidated = true\n }\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n }\n\n /**\n * Mouse dragging a handle callback\n * @param evt - mouse drag event\n */\n _mouseDragModifyHandle = (evt) => {\n const eventDetail = evt.detail\n const { currentPoints, element } = eventDetail\n const enabledElement = getEnabledElement(element)\n const { viewport } = enabledElement\n const { annotation, handleIndex } = this.editData\n const { data } = annotation\n\n // Moving handle\n const worldPos = currentPoints.world\n const canvasCoordHandlesCurrent = [\n viewport.worldToCanvas(data.handles.points[0]),\n viewport.worldToCanvas(data.handles.points[1]),\n viewport.worldToCanvas(data.handles.points[2]),\n viewport.worldToCanvas(data.handles.points[3]),\n ]\n // Which line is long? Which line is short?\n const firstLineSegment = {\n start: {\n x: canvasCoordHandlesCurrent[0][0],\n y: canvasCoordHandlesCurrent[0][1],\n },\n end: {\n x: canvasCoordHandlesCurrent[1][0],\n y: canvasCoordHandlesCurrent[1][1],\n },\n }\n const secondLineSegment = {\n start: {\n x: canvasCoordHandlesCurrent[2][0],\n y: canvasCoordHandlesCurrent[2][1],\n },\n end: {\n x: canvasCoordHandlesCurrent[3][0],\n y: canvasCoordHandlesCurrent[3][1],\n },\n }\n\n // Handle we've selected's proposed point\n const proposedPoint = <Types.Point3>[...worldPos]\n const proposedCanvasCoord = viewport.worldToCanvas(proposedPoint)\n\n if (handleIndex === 0 || handleIndex === 1) {\n const fixedHandleIndex = handleIndex === 0 ? 1 : 0\n\n const fixedCanvasCoord = canvasCoordHandlesCurrent[fixedHandleIndex]\n\n // Check whether this\n const proposedFirstLineSegment = {\n start: {\n x: fixedCanvasCoord[0],\n y: fixedCanvasCoord[1],\n },\n end: {\n x: proposedCanvasCoord[0],\n y: proposedCanvasCoord[1],\n },\n }\n\n if (\n this._movingLongAxisWouldPutItThroughShortAxis(\n proposedFirstLineSegment,\n secondLineSegment\n )\n ) {\n return\n }\n\n // --> We need to preserve this distance\n const intersectionPoint = lineSegment.intersectLine(\n [secondLineSegment.start.x, secondLineSegment.start.y],\n [secondLineSegment.end.x, secondLineSegment.end.y],\n [firstLineSegment.start.x, firstLineSegment.start.y],\n [firstLineSegment.end.x, firstLineSegment.end.y]\n )\n\n const intersectionCoord = vec2.create()\n\n vec2.set(intersectionCoord, intersectionPoint[0], intersectionPoint[1])\n\n // 1. distance from intersection point to start handle?\n const distFromLeftHandle = vec2.distance(\n <vec2>canvasCoordHandlesCurrent[2],\n intersectionCoord\n )\n\n // 2. distance from intersection point to end handle?\n const distFromRightHandle = vec2.distance(\n <vec2>canvasCoordHandlesCurrent[3],\n intersectionCoord\n )\n\n // 3. distance from long's opposite handle and intersect point\n // Need new intersect x/y\n const distIntersectAndFixedPoint = Math.abs(\n vec2.distance(<vec2>fixedCanvasCoord, intersectionCoord)\n )\n\n // Find inclination of perpindicular\n // Should use proposed point to find new inclination\n const dx = fixedCanvasCoord[0] - proposedCanvasCoord[0]\n const dy = fixedCanvasCoord[1] - proposedCanvasCoord[1]\n const length = Math.sqrt(dx * dx + dy * dy)\n const vectorX = dx / length\n const vectorY = dy / length\n\n // Find new intersection point\n // --> fixedPoint, magnitude in perpendicular\n // minus if right\n // add if left\n const intersectX =\n fixedCanvasCoord[0] - distIntersectAndFixedPoint * vectorX\n const intersectY =\n fixedCanvasCoord[1] - distIntersectAndFixedPoint * vectorY\n\n // short points 1/4 distance from center of long points\n // Flip signs depending on grabbed handle\n const mod = handleIndex === 0 ? -1 : 1\n const leftX = intersectX + distFromLeftHandle * vectorY * mod\n const leftY = intersectY - distFromLeftHandle * vectorX * mod\n const rightX = intersectX - distFromRightHandle * vectorY * mod\n const rightY = intersectY + distFromRightHandle * vectorX * mod\n\n data.handles.points[handleIndex] = proposedPoint\n data.handles.points[2] = viewport.canvasToWorld([leftX, leftY])\n data.handles.points[3] = viewport.canvasToWorld([rightX, rightY])\n } else {\n // Translation manipulator\n const translateHandleIndex = handleIndex === 2 ? 3 : 2\n\n // does not rotate, but can translate entire line (other end of short)\n const proposedCanvasCoordPoint = {\n x: proposedCanvasCoord[0],\n y: proposedCanvasCoord[1],\n }\n const canvasCoordsCurrent = {\n longLineSegment: {\n start: firstLineSegment.start,\n end: firstLineSegment.end,\n },\n shortLineSegment: {\n start: secondLineSegment.start,\n end: secondLineSegment.end,\n },\n }\n\n // get incline of other line (should not change w/ this movement)\n const dx =\n canvasCoordsCurrent.longLineSegment.start.x -\n canvasCoordsCurrent.longLineSegment.end.x\n const dy =\n canvasCoordsCurrent.longLineSegment.start.y -\n canvasCoordsCurrent.longLineSegment.end.y\n const length = Math.sqrt(dx * dx + dy * dy)\n const vectorX = dx / length\n const vectorY = dy / length\n // Create a helper line to find the intesection point in the long line\n const highNumber = Number.MAX_SAFE_INTEGER\n // Get the multiplier\n // +1 or -1 depending on which perp end we grabbed (and if it was \"fixed\" end)\n const mod = handleIndex === 0 || handleIndex === 3 ? 1 : -1\n const multiplier = mod * highNumber\n const helperLine = {\n start: proposedCanvasCoordPoint, // could be start or end\n end: {\n x: proposedCanvasCoordPoint.x + vectorY * multiplier,\n y: proposedCanvasCoordPoint.y + vectorX * multiplier * -1,\n },\n }\n\n const newIntersectionPoint = lineSegment.intersectLine(\n [\n canvasCoordsCurrent.longLineSegment.start.x,\n canvasCoordsCurrent.longLineSegment.start.y,\n ],\n [\n canvasCoordsCurrent.longLineSegment.end.x,\n canvasCoordsCurrent.longLineSegment.end.y,\n ],\n [helperLine.start.x, helperLine.start.y],\n [helperLine.end.x, helperLine.end.y]\n )\n\n // short-circuit\n if (newIntersectionPoint === undefined) {\n return\n }\n\n // 1. distance from intersection point to start handle?\n const distFromTranslateHandle = vec2.distance(\n <vec2>canvasCoordHandlesCurrent[translateHandleIndex],\n [newIntersectionPoint[0], newIntersectionPoint[1]]\n )\n\n // isStart if index is 0 or 2\n const shortLineSegment = {\n start: {\n x: newIntersectionPoint[0] + vectorY * distFromTranslateHandle,\n y: newIntersectionPoint[1] + vectorX * distFromTranslateHandle * -1,\n },\n end: {\n x: newIntersectionPoint[0] + vectorY * distFromTranslateHandle * -1,\n y: newIntersectionPoint[1] + vectorX * distFromTranslateHandle,\n },\n }\n const translatedHandleCoords =\n translateHandleIndex === 2\n ? shortLineSegment.start\n : shortLineSegment.end\n\n data.handles.points[translateHandleIndex] = viewport.canvasToWorld([\n translatedHandleCoords.x,\n translatedHandleCoords.y,\n ])\n data.handles.points[handleIndex] = proposedPoint\n }\n }\n\n /**\n * Cancels an ongoing drawing of a bidirectional annotation\n * @param element - HTML Element\n */\n cancel = (element: HTMLElement) => {\n // If it is mid-draw or mid-modify\n if (this.isDrawing) {\n this.isDrawing = false\n this._deactivateDraw(element)\n this._deactivateModify(element)\n resetElementCursor(element)\n\n const { annotation, viewportUIDsToRender } = this.editData\n const { data } = annotation\n\n annotation.highlighted = false\n data.handles.activeHandleIndex = null\n\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n\n this.editData = null\n return annotation.annotationUID\n }\n }\n\n _activateDraw = (element) => {\n state.isInteractingWithTool = true\n\n element.addEventListener(Events.MOUSE_UP, this._mouseUpCallback)\n element.addEventListener(Events.MOUSE_DRAG, this._mouseDragDrawCallback)\n element.addEventListener(Events.MOUSE_MOVE, this._mouseDragDrawCallback)\n element.addEventListener(Events.MOUSE_CLICK, this._mouseUpCallback)\n\n // element.addEventListener(Events.TOUCH_END, this._mouseUpCallback)\n // element.addEventListener(Events.TOUCH_DRAG, this._mouseDragDrawCallback)\n }\n\n _deactivateDraw = (element) => {\n state.isInteractingWithTool = false\n\n element.removeEventListener(Events.MOUSE_UP, this._mouseUpCallback)\n element.removeEventListener(Events.MOUSE_DRAG, this._mouseDragDrawCallback)\n element.removeEventListener(Events.MOUSE_MOVE, this._mouseDragDrawCallback)\n element.removeEventListener(Events.MOUSE_CLICK, this._mouseUpCallback)\n\n // element.removeEventListener(Events.TOUCH_END, this._mouseUpCallback)\n // element.removeEventListener(Events.TOUCH_DRAG, this._mouseDragDrawCallback)\n }\n\n _activateModify = (element) => {\n state.isInteractingWithTool = true\n\n element.addEventListener(Events.MOUSE_UP, this._mouseUpCallback)\n element.addEventListener(Events.MOUSE_DRAG, this._mouseDragModifyCallback)\n element.addEventListener(Events.MOUSE_CLICK, this._mouseUpCallback)\n\n // element.addEventListener(Events.TOUCH_END, this._mouseUpCallback)\n // element.addEventListener(Events.TOUCH_DRAG, this._mouseDragModifyCallback)\n }\n\n _deactivateModify = (element) => {\n state.isInteractingWithTool = false\n\n element.removeEventListener(Events.MOUSE_UP, this._mouseUpCallback)\n element.removeEventListener(\n Events.MOUSE_DRAG,\n this._mouseDragModifyCallback\n )\n element.removeEventListener(Events.MOUSE_CLICK, this._mouseUpCallback)\n\n // element.removeEventListener(Events.TOUCH_END, this._mouseUpCallback)\n // element.removeEventListener(\n // Events.TOUCH_DRAG,\n // this._mouseDragModifyCallback\n // )\n }\n\n /**\n * it is used to draw the bidirectional annotation in each\n * request animation frame. It calculates the updated cached statistics if\n * data is invalidated and cache it.\n *\n * @param enabledElement - The Cornerstone's enabledElement.\n * @param svgDrawingHelper - The svgDrawingHelper providing the context for drawing.\n */\n renderAnnotation = (\n enabledElement: Types.IEnabledElement,\n svgDrawingHelper: any\n ): void => {\n const { viewport } = enabledElement\n const { element } = viewport\n let annotations = getAnnotations(\n viewport.element,\n BidirectionalTool.toolName\n )\n\n if (!annotations?.length) {\n return\n }\n\n annotations = this.filterInteractableAnnotationsForElement(\n element,\n annotations\n )\n\n if (!annotations?.length) {\n return\n }\n\n const targetUID = this.getTargetUID(viewport)\n\n const renderingEngine = viewport.getRenderingEngine()\n\n for (let i = 0; i < annotations.length; i++) {\n const annotation = annotations[i] as BidirectionalAnnotation\n const settings = Settings.getObjectSettings(annotation, BidirectionalTool)\n const annotationUID = annotation.annotationUID\n const data = annotation.data\n const { points, activeHandleIndex } = data.handles\n const canvasCoordinates = points.map((p) => viewport.worldToCanvas(p))\n const lineWidth = this.getStyle(settings, 'lineWidth', annotation)\n const lineDash = this.getStyle(settings, 'lineDash', annotation)\n const color = this.getStyle(settings, 'color', annotation)\n\n if (!data.cachedStats[targetUID]) {\n data.cachedStats[targetUID] = {\n length: null,\n width: null,\n }\n\n this._calculateCachedStats(annotation, renderingEngine, enabledElement)\n } else if (annotation.invalidated) {\n this._throttledCalculateCachedStats(\n annotation,\n renderingEngine,\n enabledElement\n )\n }\n\n // If rendering engine has been destroyed while rendering\n if (!viewport.getRenderingEngine()) {\n console.warn('Rendering Engine has been destroyed')\n return\n }\n\n let activeHandleCanvasCoords\n\n if (\n !isAnnotationLocked(annotation) &&\n !this.editData &&\n activeHandleIndex !== null\n ) {\n // Not locked or creating and hovering over handle, so render handle.\n activeHandleCanvasCoords = [canvasCoordinates[activeHandleIndex]]\n }\n\n if (activeHandleCanvasCoords) {\n const handleGroupUID = '0'\n\n drawHandlesSvg(\n svgDrawingHelper,\n BidirectionalTool.toolName,\n annotationUID,\n handleGroupUID,\n activeHandleCanvasCoords,\n {\n color,\n }\n )\n }\n\n const lineUID = '0'\n drawLineSvg(\n svgDrawingHelper,\n BidirectionalTool.toolName,\n annotationUID,\n lineUID,\n canvasCoordinates[0],\n canvasCoordinates[1],\n {\n color,\n lineDash,\n lineWidth,\n }\n )\n\n const secondLineUID = '1'\n drawLineSvg(\n svgDrawingHelper,\n BidirectionalTool.toolName,\n annotationUID,\n secondLineUID,\n canvasCoordinates[2],\n canvasCoordinates[3],\n {\n color,\n lineDash,\n lineWidth,\n }\n )\n\n const textLines = this._getTextLines(data, targetUID)\n\n if (!textLines || textLines.length === 0) {\n continue\n }\n let canvasTextBoxCoords\n\n if (!data.handles.textBox.hasMoved) {\n canvasTextBoxCoords = getTextBoxCoordsCanvas(canvasCoordinates)\n\n data.handles.textBox.worldPosition =\n viewport.canvasToWorld(canvasTextBoxCoords)\n }\n\n const textBoxPosition = viewport.worldToCanvas(\n data.handles.textBox.worldPosition\n )\n\n const textBoxUID = '1'\n const boundingBox = drawLinkedTextBoxSvg(\n svgDrawingHelper,\n BidirectionalTool.toolName,\n annotationUID,\n textBoxUID,\n textLines,\n textBoxPosition,\n canvasCoordinates,\n {},\n this.getLinkedTextBoxStyle(settings, annotation)\n )\n\n const { x: left, y: top, width, height } = boundingBox\n\n data.handles.textBox.worldBoundingBox = {\n topLeft: viewport.canvasToWorld([left, top]),\n topRight: viewport.canvasToWorld([left + width, top]),\n bottomLeft: viewport.canvasToWorld([left, top + height]),\n bottomRight: viewport.canvasToWorld([left + width, top + height]),\n }\n }\n }\n\n _movingLongAxisWouldPutItThroughShortAxis = (\n proposedFirstLineSegment,\n secondLineSegment\n ) => {\n const vectorInSecondLineDirection = vec2.create()\n\n vec2.set(\n vectorInSecondLineDirection,\n secondLineSegment.end.x - secondLineSegment.start.x,\n secondLineSegment.end.y - secondLineSegment.start.y\n )\n\n vec2.normalize(vectorInSecondLineDirection, vectorInSecondLineDirection)\n\n const extendedSecondLineSegment = {\n start: {\n x: secondLineSegment.start.x - vectorInSecondLineDirection[0] * 10,\n y: secondLineSegment.start.y - vectorInSecondLineDirection[1] * 10,\n },\n end: {\n x: secondLineSegment.end.x + vectorInSecondLineDirection[0] * 10,\n y: secondLineSegment.end.y + vectorInSecondLineDirection[1] * 10,\n },\n }\n\n // Add some buffer in the secondLineSegment when finding the proposedIntersectionPoint\n // Of points to stop us getting stack when rotating quickly.\n\n const proposedIntersectionPoint = lineSegment.intersectLine(\n [extendedSecondLineSegment.start.x, extendedSecondLineSegment.start.y],\n [extendedSecondLineSegment.end.x, extendedSecondLineSegment.end.y],\n [proposedFirstLineSegment.start.x, proposedFirstLineSegment.start.y],\n [proposedFirstLineSegment.end.x, proposedFirstLineSegment.end.y]\n )\n\n const wouldPutThroughShortAxis = !proposedIntersectionPoint\n\n return wouldPutThroughShortAxis\n }\n\n /**\n * get text box content\n */\n _getTextLines = (data, targetUID) => {\n const { cachedStats } = data\n const { length, width } = cachedStats[targetUID]\n\n if (length === undefined) {\n return\n }\n\n // spaceBetweenSlices & pixelSpacing &\n // magnitude in each direction? Otherwise, this is \"px\"?\n const textLines = [\n `L: ${length.toFixed(2)} mm`,\n `W: ${width.toFixed(2)} mm`,\n ]\n\n return textLines\n }\n\n _calculateLength(pos1, pos2) {\n const dx = pos1[0] - pos2[0]\n const dy = pos1[1] - pos2[1]\n const dz = pos1[2] - pos2[2]\n\n return Math.sqrt(dx * dx + dy * dy + dz * dz)\n }\n\n _calculateCachedStats = (annotation, renderingEngine, enabledElement) => {\n const { data } = annotation\n const { viewportUID, renderingEngineUID } = enabledElement\n\n const worldPos1 = data.handles.points[0]\n const worldPos2 = data.handles.points[1]\n const worldPos3 = data.handles.points[2]\n const worldPos4 = data.handles.points[3]\n\n const { cachedStats } = data\n const targetUIDs = Object.keys(cachedStats)\n\n for (let i = 0; i < targetUIDs.length; i++) {\n const targetUID = targetUIDs[i]\n\n const { image } = this.getTargetUIDViewportAndImage(\n targetUID,\n renderingEngine\n )\n\n const { imageData, dimensions } = image\n\n const dist1 = this._calculateLength(worldPos1, worldPos2)\n const dist2 = this._calculateLength(worldPos3, worldPos4)\n const length = dist1 > dist2 ? dist1 : dist2\n const width = dist1 > dist2 ? dist2 : dist1\n\n const index1 = transformPhysicalToIndex(imageData, worldPos1)\n const index2 = transformPhysicalToIndex(imageData, worldPos2)\n const index3 = transformPhysicalToIndex(imageData, worldPos3)\n const index4 = transformPhysicalToIndex(imageData, worldPos4)\n\n this._isInsideVolume(index1, index2, index3, index4, dimensions)\n ? (this.isHandleOutsideImage = false)\n : (this.isHandleOutsideImage = true)\n\n cachedStats[targetUID] = {\n length,\n width,\n }\n }\n\n annotation.invalidated = false\n\n // Dispatching annotation modified\n const eventType = Events.ANNOTATION_MODIFIED\n\n const eventDetail: AnnotationModifiedEventDetail = {\n annotation,\n viewportUID,\n renderingEngineUID,\n }\n triggerEvent(eventTarget, eventType, eventDetail)\n\n return cachedStats\n }\n\n _isInsideVolume = (index1, index2, index3, index4, dimensions): boolean => {\n return (\n csUtils.indexWithinDimensions(index1, dimensions) &&\n csUtils.indexWithinDimensions(index2, dimensions) &&\n csUtils.indexWithinDimensions(index3, dimensions) &&\n csUtils.indexWithinDimensions(index4, dimensions)\n )\n }\n}\n","import { Events } from '../../enums'\nimport {\n getEnabledElement,\n cache,\n StackViewport,\n Settings,\n triggerEvent,\n eventTarget,\n utilities as csUtils,\n} from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\n\nimport { AnnotationTool } from '../base'\nimport throttle from '../../utilities/throttle'\nimport transformPhysicalToIndex from '../../utilities/transformPhysicalToIndex'\nimport {\n addAnnotation,\n getAnnotations,\n removeAnnotation,\n} from '../../stateManagement/annotation/annotationState'\nimport { isAnnotationLocked } from '../../stateManagement/annotation/annotationLocking'\nimport { lineSegment } from '../../utilities/math'\n\nimport {\n drawHandles as drawHandlesSvg,\n drawLine as drawLineSvg,\n drawLinkedTextBox as drawLinkedTextBoxSvg,\n} from '../../drawingSvg'\nimport { state } from '../../store'\nimport { getViewportUIDsWithToolToRender } from '../../utilities/viewportFilters'\nimport { getTextBoxCoordsCanvas } from '../../utilities/drawing'\nimport triggerAnnotationRenderForViewportUIDs from '../../utilities/triggerAnnotationRenderForViewportUIDs'\nimport { AnnotationModifiedEventDetail } from '../../types/EventTypes'\n\nimport {\n resetElementCursor,\n hideElementCursor,\n} from '../../cursors/elementCursor'\n\nimport {\n Annotation,\n EventTypes,\n ToolHandle,\n TextBoxHandle,\n PublicToolProps,\n ToolProps,\n InteractionTypes,\n} from '../../types'\n\ninterface LengthAnnotation extends Annotation {\n data: {\n handles: {\n points: Types.Point3[]\n activeHandleIndex: number | null\n textBox: {\n hasMoved: boolean\n worldPosition: Types.Point3\n worldBoundingBox: {\n topLeft: Types.Point3\n topRight: Types.Point3\n bottomLeft: Types.Point3\n bottomRight: Types.Point3\n }\n }\n }\n label: string\n cachedStats: {\n [targetUID: string]: {\n length: number\n }\n }\n }\n}\n\n/**\n * LengthTool let you draw annotations that measures the length of two drawing\n * points on a slice. You can use the LengthTool in all imaging planes even in oblique\n * reconstructed planes. Note: annotation tools in cornerstone3DTools exists in the exact location\n * in the physical 3d space, as a result, by default, all annotations that are\n * drawing in the same frameOfReference will get shared between viewports that\n * are in the same frameOfReference.\n *\n * The resulting annotation's data (statistics) and metadata (the\n * state of the viewport while drawing was happening) will get added to the\n * ToolState manager and can be accessed from the ToolState by calling getAnnotations\n * or similar methods.\n *\n * ```js\n * cornerstoneTools.addTool(LengthTool)\n *\n * const toolGroup = ToolGroupManager.createToolGroup('toolGroupUID')\n *\n * toolGroup.addTool(LengthTool.toolName)\n *\n * toolGroup.addViewport('viewportUID', 'renderingEngineUID')\n *\n * toolGroup.setToolActive(LengthTool.toolName, {\n * bindings: [\n * {\n * mouseButton: MouseBindings.Primary, // Left Click\n * },\n * ],\n * })\n * ```\n *\n * Read more in the Docs section of the website.\n\n */\n\nclass LengthTool extends AnnotationTool {\n static toolName = 'Length'\n\n public touchDragCallback: any\n public mouseDragCallback: any\n _throttledCalculateCachedStats: any\n editData: {\n annotation: any\n viewportUIDsToRender: string[]\n handleIndex?: number\n movingTextBox?: boolean\n newAnnotation?: boolean\n hasMoved?: boolean\n } | null\n isDrawing: boolean\n isHandleOutsideImage: boolean\n\n constructor(\n toolProps: PublicToolProps = {},\n defaultToolProps: ToolProps = {\n supportedInteractionTypes: ['Mouse', 'Touch'],\n configuration: {\n shadow: true,\n preventHandleOutsideImage: false,\n },\n }\n ) {\n super(toolProps, defaultToolProps)\n\n this._throttledCalculateCachedStats = throttle(\n this._calculateCachedStats,\n 100,\n { trailing: true }\n )\n }\n\n /**\n * Based on the current position of the mouse and the current imageId to create\n * a Length Annotation and stores it in the annotationManager\n *\n * @param evt - EventTypes.NormalizedMouseEventType\n * @returns The annotation object.\n *\n */\n addNewAnnotation = (\n evt: EventTypes.MouseDownActivateEventType\n ): LengthAnnotation => {\n const eventDetail = evt.detail\n const { currentPoints, element } = eventDetail\n const worldPos = currentPoints.world\n const enabledElement = getEnabledElement(element)\n const { viewport, renderingEngine } = enabledElement\n\n hideElementCursor(element)\n this.isDrawing = true\n\n const camera = viewport.getCamera()\n const { viewPlaneNormal, viewUp } = camera\n\n // TODO: what do we do here? this feels wrong\n let referencedImageId\n if (viewport instanceof StackViewport) {\n referencedImageId =\n viewport.getCurrentImageId && viewport.getCurrentImageId()\n } else {\n const volumeUID = this.getTargetUID(viewport)\n const imageVolume = cache.getVolume(volumeUID)\n referencedImageId = csUtils.getClosestImageId(\n imageVolume,\n worldPos,\n viewPlaneNormal,\n viewUp\n )\n }\n\n if (referencedImageId) {\n const colonIndex = referencedImageId.indexOf(':')\n referencedImageId = referencedImageId.substring(colonIndex + 1)\n }\n\n const annotation = {\n highlighted: true,\n invalidated: true,\n metadata: {\n viewPlaneNormal: <Types.Point3>[...viewPlaneNormal],\n viewUp: <Types.Point3>[...viewUp],\n FrameOfReferenceUID: viewport.getFrameOfReferenceUID(),\n referencedImageId,\n toolName: LengthTool.toolName,\n },\n data: {\n handles: {\n points: [<Types.Point3>[...worldPos], <Types.Point3>[...worldPos]],\n activeHandleIndex: null,\n textBox: {\n hasMoved: false,\n worldPosition: <Types.Point3>[0, 0, 0],\n worldBoundingBox: {\n topLeft: <Types.Point3>[0, 0, 0],\n topRight: <Types.Point3>[0, 0, 0],\n bottomLeft: <Types.Point3>[0, 0, 0],\n bottomRight: <Types.Point3>[0, 0, 0],\n },\n },\n },\n label: '',\n cachedStats: {},\n },\n }\n\n // Ensure settings are initialized after annotation instantiation\n Settings.getObjectSettings(annotation, LengthTool)\n\n addAnnotation(element, annotation)\n\n const viewportUIDsToRender = getViewportUIDsWithToolToRender(\n element,\n LengthTool.toolName\n )\n\n this.editData = {\n annotation,\n viewportUIDsToRender,\n handleIndex: 1,\n movingTextBox: false,\n newAnnotation: true,\n hasMoved: false,\n }\n this._activateDraw(element)\n\n evt.preventDefault()\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n\n return annotation\n }\n\n /**\n * It returns if the canvas point is near the provided length annotation in the provided\n * element or not. A proximity is passed to the function to determine the\n * proximity of the point to the annotation in number of pixels.\n *\n * @param element - HTML Element\n * @param annotation - Annotation\n * @param canvasCoords - Canvas coordinates\n * @param proximity - Proximity to tool to consider\n * @returns Boolean, whether the canvas point is near tool\n */\n isPointNearTool = (\n element: HTMLElement,\n annotation: LengthAnnotation,\n canvasCoords: Types.Point2,\n proximity: number\n ): boolean => {\n const enabledElement = getEnabledElement(element)\n const { viewport } = enabledElement\n const { data } = annotation\n const [point1, point2] = data.handles.points\n const canvasPoint1 = viewport.worldToCanvas(point1)\n const canvasPoint2 = viewport.worldToCanvas(point2)\n\n const line = {\n start: {\n x: canvasPoint1[0],\n y: canvasPoint1[1],\n },\n end: {\n x: canvasPoint2[0],\n y: canvasPoint2[1],\n },\n }\n\n const distanceToPoint = lineSegment.distanceToPoint(\n [line.start.x, line.start.y],\n [line.end.x, line.end.y],\n [canvasCoords[0], canvasCoords[1]]\n )\n\n if (distanceToPoint <= proximity) {\n return true\n }\n\n return false\n }\n\n toolSelectedCallback = (\n evt: EventTypes.MouseDownEventType,\n annotation: LengthAnnotation,\n interactionType: InteractionTypes\n ): void => {\n const eventDetail = evt.detail\n const { element } = eventDetail\n\n annotation.highlighted = true\n\n const viewportUIDsToRender = getViewportUIDsWithToolToRender(\n element,\n LengthTool.toolName\n )\n\n this.editData = {\n annotation,\n viewportUIDsToRender,\n movingTextBox: false,\n }\n\n this._activateModify(element)\n\n hideElementCursor(element)\n\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n\n evt.preventDefault()\n }\n\n handleSelectedCallback(\n evt: EventTypes.MouseDownEventType,\n annotation: LengthAnnotation,\n handle: ToolHandle,\n interactionType = 'mouse'\n ): void {\n const eventDetail = evt.detail\n const { element } = eventDetail\n const { data } = annotation\n\n annotation.highlighted = true\n\n let movingTextBox = false\n let handleIndex\n\n if ((handle as TextBoxHandle).worldPosition) {\n movingTextBox = true\n } else {\n handleIndex = data.handles.points.findIndex((p) => p === handle)\n }\n\n // Find viewports to render on drag.\n const viewportUIDsToRender = getViewportUIDsWithToolToRender(\n element,\n LengthTool.toolName\n )\n\n this.editData = {\n annotation,\n viewportUIDsToRender,\n handleIndex,\n movingTextBox,\n }\n this._activateModify(element)\n\n hideElementCursor(element)\n\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n\n evt.preventDefault()\n }\n\n _mouseUpCallback = (\n evt: EventTypes.MouseUpEventType | EventTypes.MouseClickEventType\n ) => {\n const eventDetail = evt.detail\n const { element } = eventDetail\n\n const { annotation, viewportUIDsToRender, newAnnotation, hasMoved } =\n this.editData\n const { data } = annotation\n\n if (newAnnotation && !hasMoved) {\n // when user starts the drawing by click, and moving the mouse, instead\n // of click and drag\n return\n }\n\n annotation.highlighted = false\n data.handles.activeHandleIndex = null\n\n this._deactivateModify(element)\n this._deactivateDraw(element)\n resetElementCursor(element)\n\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n\n if (\n this.isHandleOutsideImage &&\n this.configuration.preventHandleOutsideImage\n ) {\n removeAnnotation(element, annotation.annotationUID)\n }\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n\n this.editData = null\n this.isDrawing = false\n }\n\n _mouseDragCallback = (\n evt: EventTypes.MouseDragEventType | EventTypes.MouseMoveEventType\n ) => {\n this.isDrawing = true\n const eventDetail = evt.detail\n const { element } = eventDetail\n\n const { annotation, viewportUIDsToRender, handleIndex, movingTextBox } =\n this.editData\n const { data } = annotation\n\n if (movingTextBox) {\n // Drag mode - moving text box\n const { deltaPoints } = eventDetail as EventTypes.MouseDragEventDetail\n const worldPosDelta = deltaPoints.world\n\n const { textBox } = data.handles\n const { worldPosition } = textBox\n\n worldPosition[0] += worldPosDelta[0]\n worldPosition[1] += worldPosDelta[1]\n worldPosition[2] += worldPosDelta[2]\n\n textBox.hasMoved = true\n } else if (handleIndex === undefined) {\n // Drag mode - moving handle\n const { deltaPoints } = eventDetail as EventTypes.MouseDragEventDetail\n const worldPosDelta = deltaPoints.world\n\n const points = data.handles.points\n\n points.forEach((point) => {\n point[0] += worldPosDelta[0]\n point[1] += worldPosDelta[1]\n point[2] += worldPosDelta[2]\n })\n annotation.invalidated = true\n } else {\n // Move mode - after double click, and mouse move to draw\n const { currentPoints } = eventDetail\n const worldPos = currentPoints.world\n\n data.handles.points[handleIndex] = [...worldPos]\n annotation.invalidated = true\n }\n\n this.editData.hasMoved = true\n\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n }\n\n cancel = (element: HTMLElement) => {\n // If it is mid-draw or mid-modify\n if (this.isDrawing) {\n this.isDrawing = false\n this._deactivateDraw(element)\n this._deactivateModify(element)\n resetElementCursor(element)\n\n const { annotation, viewportUIDsToRender } = this.editData\n const { data } = annotation\n\n annotation.highlighted = false\n data.handles.activeHandleIndex = null\n\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n\n this.editData = null\n return annotation.annotationUID\n }\n }\n\n _activateModify = (element: HTMLElement) => {\n state.isInteractingWithTool = true\n\n element.addEventListener(Events.MOUSE_UP, this._mouseUpCallback)\n element.addEventListener(Events.MOUSE_DRAG, this._mouseDragCallback)\n element.addEventListener(Events.MOUSE_CLICK, this._mouseUpCallback)\n\n // element.addEventListener(Events.TOUCH_END, this._mouseUpCallback)\n // element.addEventListener(Events.TOUCH_DRAG, this._mouseDragCallback)\n }\n\n _deactivateModify = (element: HTMLElement) => {\n state.isInteractingWithTool = false\n\n element.removeEventListener(Events.MOUSE_UP, this._mouseUpCallback)\n element.removeEventListener(Events.MOUSE_DRAG, this._mouseDragCallback)\n element.removeEventListener(Events.MOUSE_CLICK, this._mouseUpCallback)\n\n // element.removeEventListener(Events.TOUCH_END, this._mouseUpCallback)\n // element.removeEventListener(Events.TOUCH_DRAG, this._mouseDragCallback)\n }\n\n _activateDraw = (element: HTMLElement) => {\n state.isInteractingWithTool = true\n\n element.addEventListener(Events.MOUSE_UP, this._mouseUpCallback)\n element.addEventListener(Events.MOUSE_DRAG, this._mouseDragCallback)\n element.addEventListener(Events.MOUSE_MOVE, this._mouseDragCallback)\n element.addEventListener(Events.MOUSE_CLICK, this._mouseUpCallback)\n\n // element.addEventListener(Events.TOUCH_END, this._mouseUpCallback)\n // element.addEventListener(Events.TOUCH_DRAG, this._mouseDragCallback)\n }\n\n _deactivateDraw = (element: HTMLElement) => {\n state.isInteractingWithTool = false\n\n element.removeEventListener(Events.MOUSE_UP, this._mouseUpCallback)\n element.removeEventListener(Events.MOUSE_DRAG, this._mouseDragCallback)\n element.removeEventListener(Events.MOUSE_MOVE, this._mouseDragCallback)\n element.removeEventListener(Events.MOUSE_CLICK, this._mouseUpCallback)\n\n // element.removeEventListener(Events.TOUCH_END, this._mouseUpCallback)\n // element.removeEventListener(Events.TOUCH_DRAG, this._mouseDragCallback)\n }\n\n /**\n * it is used to draw the length annotation in each\n * request animation frame. It calculates the updated cached statistics if\n * data is invalidated and cache it.\n *\n * @param enabledElement - The Cornerstone's enabledElement.\n * @param svgDrawingHelper - The svgDrawingHelper providing the context for drawing.\n */\n renderAnnotation = (\n enabledElement: Types.IEnabledElement,\n svgDrawingHelper: any\n ): void => {\n const { viewport } = enabledElement\n const { element } = viewport\n\n let annotations = getAnnotations(element, LengthTool.toolName)\n\n // Todo: We don't need this anymore, filtering happens in triggerAnnotationRender\n if (!annotations?.length) {\n return\n }\n\n annotations = this.filterInteractableAnnotationsForElement(\n element,\n annotations\n )\n\n if (!annotations?.length) {\n return\n }\n\n const targetUID = this.getTargetUID(viewport)\n const renderingEngine = viewport.getRenderingEngine()\n\n // Draw SVG\n for (let i = 0; i < annotations.length; i++) {\n const annotation = annotations[i] as LengthAnnotation\n const settings = Settings.getObjectSettings(annotation, LengthTool)\n const annotationUID = annotation.annotationUID\n const data = annotation.data\n const { points, activeHandleIndex } = data.handles\n const lineWidth = this.getStyle(settings, 'lineWidth', annotation)\n const lineDash = this.getStyle(settings, 'lineDash', annotation)\n const color = this.getStyle(settings, 'color', annotation)\n\n const canvasCoordinates = points.map((p) => viewport.worldToCanvas(p))\n\n let activeHandleCanvasCoords\n\n if (\n !isAnnotationLocked(annotation) &&\n !this.editData &&\n activeHandleIndex !== null\n ) {\n // Not locked or creating and hovering over handle, so render handle.\n activeHandleCanvasCoords = [canvasCoordinates[activeHandleIndex]]\n }\n\n if (activeHandleCanvasCoords) {\n const handleGroupUID = '0'\n\n drawHandlesSvg(\n svgDrawingHelper,\n LengthTool.toolName,\n annotationUID,\n handleGroupUID,\n canvasCoordinates,\n {\n color,\n lineDash,\n lineWidth,\n }\n )\n }\n\n const lineUID = '1'\n drawLineSvg(\n svgDrawingHelper,\n LengthTool.toolName,\n annotationUID,\n lineUID,\n canvasCoordinates[0],\n canvasCoordinates[1],\n {\n color,\n width: lineWidth,\n }\n )\n\n // WE HAVE TO CACHE STATS BEFORE FETCHING TEXT\n if (!data.cachedStats[targetUID]) {\n data.cachedStats[targetUID] = {\n length: null,\n }\n\n this._calculateCachedStats(annotation, renderingEngine, enabledElement)\n } else if (annotation.invalidated) {\n this._throttledCalculateCachedStats(\n annotation,\n renderingEngine,\n enabledElement\n )\n }\n\n // If rendering engine has been destroyed while rendering\n if (!viewport.getRenderingEngine()) {\n console.warn('Rendering Engine has been destroyed')\n return\n }\n\n const textLines = this._getTextLines(data, targetUID)\n\n // Need to update to sync w/ annotation while unlinked/not moved\n if (!data.handles.textBox.hasMoved) {\n const canvasTextBoxCoords = getTextBoxCoordsCanvas(canvasCoordinates)\n\n data.handles.textBox.worldPosition =\n viewport.canvasToWorld(canvasTextBoxCoords)\n }\n\n const textBoxPosition = viewport.worldToCanvas(\n data.handles.textBox.worldPosition\n )\n\n const textBoxUID = '1'\n const boundingBox = drawLinkedTextBoxSvg(\n svgDrawingHelper,\n LengthTool.toolName,\n annotationUID,\n textBoxUID,\n textLines,\n textBoxPosition,\n canvasCoordinates,\n {},\n this.getLinkedTextBoxStyle(settings, annotation)\n )\n\n const { x: left, y: top, width, height } = boundingBox\n\n data.handles.textBox.worldBoundingBox = {\n topLeft: viewport.canvasToWorld([left, top]),\n topRight: viewport.canvasToWorld([left + width, top]),\n bottomLeft: viewport.canvasToWorld([left, top + height]),\n bottomRight: viewport.canvasToWorld([left + width, top + height]),\n }\n }\n }\n\n // text line for the current active length annotation\n _getTextLines(data, targetUID) {\n const cachedVolumeStats = data.cachedStats[targetUID]\n const { length } = cachedVolumeStats\n\n if (length === undefined) {\n return\n }\n\n // spaceBetweenSlices & pixelSpacing &\n // magnitude in each direction? Otherwise, this is \"px\"?\n const textLines = [`${length.toFixed(2)} mm`]\n\n return textLines\n }\n\n _calculateLength(pos1, pos2) {\n const dx = pos1[0] - pos2[0]\n const dy = pos1[1] - pos2[1]\n const dz = pos1[2] - pos2[2]\n\n return Math.sqrt(dx * dx + dy * dy + dz * dz)\n }\n\n _calculateCachedStats(annotation, renderingEngine, enabledElement) {\n const data = annotation.data\n const { viewportUID, renderingEngineUID } = enabledElement\n\n const worldPos1 = data.handles.points[0]\n const worldPos2 = data.handles.points[1]\n const { cachedStats } = data\n const targetUIDs = Object.keys(cachedStats)\n\n // TODO clean up, this doesn't need a length per volume, it has no stats derived from volumes.\n\n for (let i = 0; i < targetUIDs.length; i++) {\n const targetUID = targetUIDs[i]\n\n const { image } = this.getTargetUIDViewportAndImage(\n targetUID,\n renderingEngine\n )\n\n const { imageData, dimensions } = image\n\n const length = this._calculateLength(worldPos1, worldPos2)\n\n const index1 = transformPhysicalToIndex(imageData, worldPos1)\n const index2 = transformPhysicalToIndex(imageData, worldPos2)\n\n this._isInsideVolume(index1, index2, dimensions)\n ? (this.isHandleOutsideImage = false)\n : (this.isHandleOutsideImage = true)\n\n // TODO -> Do we instead want to clip to the bounds of the volume and only include that portion?\n // Seems like a lot of work for an unrealistic case. At the moment bail out of stat calculation if either\n // corner is off the canvas.\n\n // todo: add insideVolume calculation, for removing tool if outside\n cachedStats[targetUID] = {\n length,\n }\n }\n\n annotation.invalidated = false\n\n // Dispatching annotation modified\n const eventType = Events.ANNOTATION_MODIFIED\n\n const eventDetail: AnnotationModifiedEventDetail = {\n annotation,\n viewportUID,\n renderingEngineUID,\n }\n triggerEvent(eventTarget, eventType, eventDetail)\n\n return cachedStats\n }\n\n _isInsideVolume(index1, index2, dimensions) {\n return (\n csUtils.indexWithinDimensions(index1, dimensions) &&\n csUtils.indexWithinDimensions(index2, dimensions)\n )\n }\n}\n\nexport default LengthTool\n","/* eslint-disable @typescript-eslint/no-empty-function */\nimport { vec2 } from 'gl-matrix'\n\nimport {\n getEnabledElement,\n Settings,\n cache,\n StackViewport,\n VolumeViewport,\n triggerEvent,\n eventTarget,\n utilities as csUtils,\n} from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\n\nimport { AnnotationTool } from '../base'\nimport {\n addAnnotation,\n getAnnotations,\n removeAnnotation,\n} from '../../stateManagement/annotation/annotationState'\nimport {\n drawHandles as drawHandlesSvg,\n drawTextBox as drawTextBoxSvg,\n} from '../../drawingSvg'\nimport { state } from '../../store'\nimport transformPhysicalToIndex from '../../utilities/transformPhysicalToIndex'\nimport { Events } from '../../enums'\nimport { getViewportUIDsWithToolToRender } from '../../utilities/viewportFilters'\nimport {\n resetElementCursor,\n hideElementCursor,\n} from '../../cursors/elementCursor'\nimport { AnnotationModifiedEventDetail } from '../../types/EventTypes'\n\nimport triggerAnnotationRenderForViewportUIDs from '../../utilities/triggerAnnotationRenderForViewportUIDs'\n\nimport {\n Annotation,\n EventTypes,\n ToolHandle,\n PublicToolProps,\n ToolProps,\n} from '../../types'\n\ninterface ProbeAnnotation extends Annotation {\n data: {\n handles: { points: Types.Point3[] }\n cachedStats: {\n [targetUID: string]: {\n Modality: string\n index: Types.Point3\n value: number\n }\n }\n label: string\n }\n}\n\n/**\n * ProbeTool let you get the underlying voxel value by putting a probe in that\n * location. It will give index of the location and value of the voxel.\n * You can use ProbeTool in all perpendicular views (axial, sagittal, coronal).\n * Note: annotation tools in cornerstone3DTools exists in the exact location\n * in the physical 3d space, as a result, by default, all annotations that are\n * drawing in the same frameOfReference will get shared between viewports that\n * are in the same frameOfReference. Probe tool's text box are dynamically\n * generated based on the viewport's underlying Modality. For instance, if\n * the viewport is displaying CT, the text box will shown the statistics in Hounsfield units,\n * and if the viewport is displaying PET, the text box will show the statistics in\n * SUV units.\n *\n * The resulting annotation's data (statistics) and metadata (the\n * state of the viewport while drawing was happening) will get added to the\n * ToolState manager and can be accessed from the ToolState by calling getAnnotations\n * or similar methods.\n *\n * To use the ProbeTool, you first need to add it to cornerstoneTools, then create\n * a toolGroup and add the ProbeTool to it. Finally, setToolActive on the toolGroup\n *\n * ```js\n * cornerstoneTools.addTool(ProbeTool)\n *\n * const toolGroup = ToolGroupManager.createToolGroup('toolGroupUID')\n *\n * toolGroup.addTool(ProbeTool.toolName)\n *\n * toolGroup.addViewport('viewportUID', 'renderingEngineUID')\n *\n * toolGroup.setToolActive(ProbeTool.toolName, {\n * bindings: [\n * {\n * mouseButton: MouseBindings.Primary, // Left Click\n * },\n * ],\n * })\n * ```\n *\n * Read more in the Docs section of the website.\n *\n */\nexport default class ProbeTool extends AnnotationTool {\n static toolName = 'Probe'\n\n touchDragCallback: any\n mouseDragCallback: any\n editData: { annotation: any; viewportUIDsToRender: string[] } | null\n eventDispatchDetail: {\n viewportUID: string\n renderingEngineUID: string\n }\n isDrawing: boolean\n isHandleOutsideImage: boolean\n\n constructor(\n toolProps: PublicToolProps = {},\n defaultToolProps: ToolProps = {\n supportedInteractionTypes: ['Mouse', 'Touch'],\n configuration: {\n shadow: true,\n preventHandleOutsideImage: false,\n },\n }\n ) {\n super(toolProps, defaultToolProps)\n }\n\n // Not necessary for this tool but needs to be defined since it's an abstract\n // method from the parent class.\n isPointNearTool(): boolean {\n return false\n }\n\n toolSelectedCallback() {}\n\n /**\n * Based on the current position of the mouse and the current imageId to create\n * a Probe Annotation and stores it in the annotationManager\n *\n * @param evt - EventTypes.NormalizedMouseEventType\n * @returns The annotation object.\n *\n */\n addNewAnnotation = (\n evt: EventTypes.MouseDownActivateEventType\n ): ProbeAnnotation => {\n const eventDetail = evt.detail\n const { currentPoints, element } = eventDetail\n const worldPos = currentPoints.world\n\n const enabledElement = getEnabledElement(element)\n const { viewport, renderingEngine } = enabledElement\n\n this.isDrawing = true\n const camera = viewport.getCamera()\n const { viewPlaneNormal, viewUp } = camera\n\n let referencedImageId\n if (viewport instanceof StackViewport) {\n referencedImageId =\n viewport.getCurrentImageId && viewport.getCurrentImageId()\n } else {\n const volumeUID = this.getTargetUID(viewport)\n const imageVolume = cache.getVolume(volumeUID)\n referencedImageId = csUtils.getClosestImageId(\n imageVolume,\n worldPos,\n viewPlaneNormal,\n viewUp\n )\n }\n\n if (referencedImageId) {\n const colonIndex = referencedImageId.indexOf(':')\n referencedImageId = referencedImageId.substring(colonIndex + 1)\n }\n\n const annotation = {\n invalidated: true,\n highlighted: true,\n metadata: {\n viewPlaneNormal: <Types.Point3>[...viewPlaneNormal],\n viewUp: <Types.Point3>[...viewUp],\n FrameOfReferenceUID: viewport.getFrameOfReferenceUID(),\n referencedImageId,\n toolName: ProbeTool.toolName,\n },\n data: {\n label: '',\n handles: { points: [<Types.Point3>[...worldPos]] },\n cachedStats: {},\n },\n }\n\n // Ensure settings are initialized after annotation instantiation\n Settings.getObjectSettings(annotation, ProbeTool)\n\n addAnnotation(element, annotation)\n\n const viewportUIDsToRender = getViewportUIDsWithToolToRender(\n element,\n ProbeTool.toolName\n )\n\n this.editData = {\n annotation,\n viewportUIDsToRender,\n }\n this._activateModify(element)\n\n hideElementCursor(element)\n\n evt.preventDefault()\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n\n return annotation\n }\n\n /**\n * It checks if the mouse click is near ProveTool, it overwrites the baseAnnotationTool\n * getHandleNearImagePoint method.\n *\n * @param element - The element that the tool is attached to.\n * @param annotation - The annotation object associated with the annotation\n * @param canvasCoords - The coordinates of the mouse click on canvas\n * @param proximity - The distance from the mouse cursor to the point\n * that is considered \"near\".\n * @returns The handle that is closest to the cursor, or null if the cursor\n * is not near any of the handles.\n */\n getHandleNearImagePoint(\n element: HTMLElement,\n annotation: ProbeAnnotation,\n canvasCoords: Types.Point2,\n proximity: number\n ): ToolHandle | undefined {\n const enabledElement = getEnabledElement(element)\n const { viewport } = enabledElement\n\n const { data } = annotation\n const point = data.handles.points[0]\n const annotationCanvasCoordinate = viewport.worldToCanvas(point)\n\n const near =\n vec2.distance(canvasCoords, annotationCanvasCoordinate) < proximity\n\n if (near === true) {\n return point\n }\n }\n\n handleSelectedCallback(\n evt: EventTypes.MouseDownEventType,\n annotation: ProbeAnnotation,\n handle: ToolHandle,\n interactionType = 'mouse'\n ): void {\n const eventDetail = evt.detail\n const { element } = eventDetail\n\n annotation.highlighted = true\n\n const viewportUIDsToRender = getViewportUIDsWithToolToRender(\n element,\n ProbeTool.toolName\n )\n\n // Find viewports to render on drag.\n\n this.editData = {\n //handle, // This would be useful for other tools with more than one handle\n annotation,\n viewportUIDsToRender,\n }\n this._activateModify(element)\n\n hideElementCursor(element)\n\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n\n evt.preventDefault()\n }\n\n _mouseUpCallback = (\n evt: EventTypes.MouseUpEventType | EventTypes.MouseClickEventType\n ) => {\n const eventDetail = evt.detail\n const { element } = eventDetail\n\n const { annotation, viewportUIDsToRender } = this.editData\n\n annotation.highlighted = false\n\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n\n const { viewportUID } = enabledElement\n this.eventDispatchDetail = {\n viewportUID,\n renderingEngineUID: renderingEngine.uid,\n }\n\n this._deactivateModify(element)\n\n resetElementCursor(element)\n\n this.editData = null\n this.isDrawing = false\n\n if (\n this.isHandleOutsideImage &&\n this.configuration.preventHandleOutsideImage\n ) {\n removeAnnotation(element, annotation.annotationUID)\n }\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n }\n\n _mouseDragCallback = (evt) => {\n this.isDrawing = true\n const eventDetail = evt.detail\n const { currentPoints, element } = eventDetail\n const worldPos = currentPoints.world\n\n const { annotation, viewportUIDsToRender } = this.editData\n const { data } = annotation\n\n data.handles.points[0] = [...worldPos]\n annotation.invalidated = true\n\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n }\n\n cancel = (element: HTMLElement) => {\n // If it is mid-draw or mid-modify\n if (this.isDrawing) {\n this.isDrawing = false\n this._deactivateModify(element)\n resetElementCursor(element)\n\n const { annotation, viewportUIDsToRender } = this.editData\n const { data } = annotation\n\n annotation.highlighted = false\n data.handles.activeHandleIndex = null\n\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n\n this.editData = null\n return annotation.annotationUID\n }\n }\n\n _activateModify = (element) => {\n state.isInteractingWithTool = true\n\n element.addEventListener(Events.MOUSE_UP, this._mouseUpCallback)\n element.addEventListener(Events.MOUSE_DRAG, this._mouseDragCallback)\n element.addEventListener(Events.MOUSE_CLICK, this._mouseUpCallback)\n\n // element.addEventListener(Events.TOUCH_END, this._mouseUpCallback)\n // element.addEventListener(Events.TOUCH_DRAG, this._mouseDragCallback)\n }\n\n _deactivateModify = (element) => {\n state.isInteractingWithTool = false\n\n element.removeEventListener(Events.MOUSE_UP, this._mouseUpCallback)\n element.removeEventListener(Events.MOUSE_DRAG, this._mouseDragCallback)\n element.removeEventListener(Events.MOUSE_CLICK, this._mouseUpCallback)\n\n // element.removeEventListener(Events.TOUCH_END, this._mouseUpCallback)\n // element.removeEventListener(Events.TOUCH_DRAG, this._mouseDragCallback)\n }\n\n /**\n * it is used to draw the probe annotation in each\n * request animation frame. It calculates the updated cached statistics if\n * data is invalidated and cache it.\n *\n * @param enabledElement - The Cornerstone's enabledElement.\n * @param svgDrawingHelper - The svgDrawingHelper providing the context for drawing.\n */\n renderAnnotation = (\n enabledElement: Types.IEnabledElement,\n svgDrawingHelper: any\n ): void => {\n const { viewport } = enabledElement\n const { element } = viewport\n\n let annotations = getAnnotations(element, ProbeTool.toolName)\n\n if (!annotations?.length) {\n return\n }\n\n annotations = this.filterInteractableAnnotationsForElement(\n element,\n annotations\n )\n\n if (!annotations?.length) {\n return\n }\n\n const targetUID = this.getTargetUID(viewport)\n const renderingEngine = viewport.getRenderingEngine()\n\n for (let i = 0; i < annotations.length; i++) {\n const annotation = annotations[i] as ProbeAnnotation\n const settings = Settings.getObjectSettings(annotation, ProbeTool)\n const annotationUID = annotation.annotationUID\n const data = annotation.data\n const point = data.handles.points[0]\n const canvasCoordinates = viewport.worldToCanvas(point)\n const color = this.getStyle(settings, 'color', annotation)\n\n if (!data.cachedStats[targetUID]) {\n data.cachedStats[targetUID] = {\n Modality: null,\n index: null,\n value: null,\n }\n\n this._calculateCachedStats(annotation, renderingEngine, enabledElement)\n } else if (annotation.invalidated) {\n this._calculateCachedStats(annotation, renderingEngine, enabledElement)\n\n // If the invalidated data is as a result of volumeViewport manipulation\n // of the tools, we need to invalidate the related stackViewports data if\n // they are not at the referencedImageId, so that\n // when scrolling to the related slice in which the tool were manipulated\n // we re-render the correct tool position. This is due to stackViewport\n // which doesn't have the full volume at each time, and we are only working\n // on one slice at a time.\n if (viewport instanceof VolumeViewport) {\n const { referencedImageId } = annotation.metadata\n\n // todo: this is not efficient, but necessary\n // invalidate all the relevant stackViewports if they are not\n // at the referencedImageId\n const viewports = renderingEngine.getViewports()\n viewports.forEach((vp) => {\n const stackTargetUID = this.getTargetUID(vp)\n // only delete the cachedStats for the stackedViewports if the tool\n // is dragged inside the volume and the stackViewports are not at the\n // referencedImageId for the tool\n if (\n vp instanceof StackViewport &&\n !vp.getCurrentImageId().includes(referencedImageId) &&\n data.cachedStats[stackTargetUID]\n ) {\n delete data.cachedStats[stackTargetUID]\n }\n })\n }\n }\n\n // If rendering engine has been destroyed while rendering\n if (!viewport.getRenderingEngine()) {\n console.warn('Rendering Engine has been destroyed')\n return\n }\n\n const handleGroupUID = '0'\n\n drawHandlesSvg(\n svgDrawingHelper,\n ProbeTool.toolName,\n annotationUID,\n handleGroupUID,\n [canvasCoordinates],\n { color }\n )\n\n const textLines = this._getTextLines(data, targetUID)\n if (textLines) {\n const textCanvasCoorinates = [\n canvasCoordinates[0] + 6,\n canvasCoordinates[1] - 6,\n ]\n\n const textUID = '0'\n drawTextBoxSvg(\n svgDrawingHelper,\n ProbeTool.toolName,\n annotationUID,\n textUID,\n textLines,\n [textCanvasCoorinates[0], textCanvasCoorinates[1]],\n this.getLinkedTextBoxStyle(settings, annotation)\n )\n }\n }\n }\n\n _getTextLines(data, targetUID) {\n const cachedVolumeStats = data.cachedStats[targetUID]\n const { index, Modality, value, SUVBw, SUVLbm, SUVBsa } = cachedVolumeStats\n\n if (value === undefined && SUVBw === undefined) {\n return\n }\n\n const textLines = []\n\n textLines.push(`(${index[0]}, ${index[1]}, ${index[2]})`)\n\n if (Modality === 'PT') {\n // Check if we have scaling for the other 2 SUV types for the PET.\n // If we have scaling, value should be undefined\n if (value) {\n textLines.push(`${value.toFixed(2)} SUV`)\n } else {\n textLines.push(`${SUVBw.toFixed(2)} SUV bw`)\n\n if (SUVLbm) {\n textLines.push(`${SUVLbm.toFixed(2)} SUV lbm`)\n }\n if (SUVBsa) {\n textLines.push(`${SUVBsa.toFixed(2)} SUV bsa`)\n }\n }\n } else if (Modality === 'CT') {\n textLines.push(`${value.toFixed(2)} HU`)\n } else {\n textLines.push(`${value.toFixed(2)} MO`)\n }\n\n return textLines\n }\n\n _getValueForModality(value, imageVolume, modality) {\n const values = {}\n\n if (modality === 'PT') {\n // Check if we have scaling for the other 2 SUV types for the PET.\n if (\n imageVolume.scaling.PET &&\n (imageVolume.scaling.PET.suvbwToSuvbsa ||\n imageVolume.scaling.PET.suvbwToSuvlbm)\n ) {\n const { suvbwToSuvlbm, suvbwToSuvbsa } = imageVolume.scaling.PET\n\n values['SUVBw'] = value\n\n if (suvbwToSuvlbm) {\n const SUVLbm = value * suvbwToSuvlbm\n\n values['SUVLbm'] = SUVLbm\n }\n\n if (suvbwToSuvlbm) {\n const SUVBsa = value * suvbwToSuvbsa\n\n values['SUVBsa'] = SUVBsa\n }\n } else {\n values['value'] = value\n }\n } else {\n values['value'] = value\n }\n\n return values\n }\n\n _calculateCachedStats(annotation, renderingEngine, enabledElement) {\n const data = annotation.data\n const { viewportUID, renderingEngineUID } = enabledElement\n\n const worldPos = data.handles.points[0]\n const { cachedStats } = data\n\n const targetUIDs = Object.keys(cachedStats)\n\n for (let i = 0; i < targetUIDs.length; i++) {\n const targetUID = targetUIDs[i]\n\n const { image, viewport } = this.getTargetUIDViewportAndImage(\n targetUID,\n renderingEngine\n )\n\n const { dimensions, scalarData, imageData, metadata } = image\n\n const modality = metadata.Modality\n const index = transformPhysicalToIndex(imageData, worldPos)\n\n index[0] = Math.round(index[0])\n index[1] = Math.round(index[1])\n index[2] = Math.round(index[2])\n\n if (csUtils.indexWithinDimensions(index, dimensions)) {\n this.isHandleOutsideImage = false\n const yMultiple = dimensions[0]\n const zMultiple = dimensions[0] * dimensions[1]\n\n const value =\n scalarData[index[2] * zMultiple + index[1] * yMultiple + index[0]]\n\n // Index[2] for stackViewport is always 0, but for visualization\n // we reset it to be imageId index\n if (viewport instanceof StackViewport) {\n index[2] = viewport.getCurrentImageIdIndex()\n }\n\n const values = this._getValueForModality(value, image, modality)\n\n cachedStats[targetUID] = {\n index,\n ...values,\n Modality: modality,\n }\n } else {\n this.isHandleOutsideImage = true\n cachedStats[targetUID] = {\n index,\n Modality: modality,\n }\n }\n\n annotation.invalidated = false\n\n // Dispatching annotation modified\n const eventType = Events.ANNOTATION_MODIFIED\n\n const eventDetail: AnnotationModifiedEventDetail = {\n annotation,\n viewportUID,\n renderingEngineUID,\n }\n\n triggerEvent(eventTarget, eventType, eventDetail)\n }\n\n return cachedStats\n }\n}\n","import { AnnotationTool } from '../base'\n\nimport {\n getEnabledElement,\n cache,\n Settings,\n StackViewport,\n VolumeViewport,\n triggerEvent,\n eventTarget,\n utilities as csUtils,\n} from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\n\nimport throttle from '../../utilities/throttle'\nimport transformPhysicalToIndex from '../../utilities/transformPhysicalToIndex'\nimport {\n addAnnotation,\n getAnnotations,\n removeAnnotation,\n} from '../../stateManagement'\nimport { isAnnotationLocked } from '../../stateManagement/annotation/annotationLocking'\n\nimport {\n drawHandles as drawHandlesSvg,\n drawLinkedTextBox as drawLinkedTextBoxSvg,\n drawRect as drawRectSvg,\n} from '../../drawingSvg'\nimport { state } from '../../store'\nimport { Events } from '../../enums'\nimport { getViewportUIDsWithToolToRender } from '../../utilities/viewportFilters'\nimport rectangle from '../../utilities/math/rectangle'\nimport { getTextBoxCoordsCanvas } from '../../utilities/drawing'\nimport getWorldWidthAndHeightFromCorners from '../../utilities/planar/getWorldWidthAndHeightFromCorners'\nimport {\n resetElementCursor,\n hideElementCursor,\n} from '../../cursors/elementCursor'\nimport triggerAnnotationRenderForViewportUIDs from '../../utilities/triggerAnnotationRenderForViewportUIDs'\n\nimport {\n Annotation,\n EventTypes,\n ToolHandle,\n TextBoxHandle,\n ToolProps,\n PublicToolProps,\n InteractionTypes,\n} from '../../types'\nimport { AnnotationModifiedEventDetail } from '../../types/EventTypes'\n\ninterface RectangleRoiCachedStats {\n [targetUID: string]: {\n Modality: string\n area: number\n max: number\n mean: number\n stdDev: number\n }\n}\n\n/**\n * RectangleRoiAnnotation let you draw annotations that measures the statistics\n * such as area, max, mean and stdDev of a Rectangular region of interest.\n * You can use RectangleRoiAnnotation in all perpendicular views (axial, sagittal, coronal).\n * Note: annotation tools in cornerstone3DTools exists in the exact location\n * in the physical 3d space, as a result, by default, all annotations that are\n * drawing in the same frameOfReference will get shared between viewports that\n * are in the same frameOfReference. RectangleRoi tool's text box lines are dynamically\n * generated based on the viewport's underlying Modality. For instance, if\n * the viewport is displaying CT, the text box will shown the statistics in Hounsfield units,\n * and if the viewport is displaying PET, the text box will show the statistics in\n * SUV units.\n *\n * The resulting annotation's data (statistics) and metadata (the\n * state of the viewport while drawing was happening) will get added to the\n * ToolState manager and can be accessed from the ToolState by calling getAnnotations\n * or similar methods.\n *\n * ```js\n * cornerstoneTools.addTool(RectangleRoiAnnotation)\n *\n * const toolGroup = ToolGroupManager.createToolGroup('toolGroupUID')\n *\n * toolGroup.addTool(RectangleRoiAnnotation.toolName)\n *\n * toolGroup.addViewport('viewportUID', 'renderingEngineUID')\n *\n * toolGroup.setToolActive(RectangleRoiAnnotation.toolName, {\n * bindings: [\n * {\n * mouseButton: MouseBindings.Primary, // Left Click\n * },\n * ],\n * })\n * ```\n *\n * Read more in the Docs section of the website.\n */\nexport interface RectangleRoiAnnotation extends Annotation {\n data: {\n handles: {\n points: Types.Point3[]\n activeHandleIndex: number | null\n textBox: {\n hasMoved: boolean\n worldPosition: Types.Point3\n worldBoundingBox: {\n topLeft: Types.Point3\n topRight: Types.Point3\n bottomLeft: Types.Point3\n bottomRight: Types.Point3\n }\n }\n }\n label: string\n cachedStats?:\n | RectangleRoiCachedStats\n | {\n projectionPoints?: Types.Point3[]\n projectionPointsImageIds?: string[]\n }\n }\n}\n\nexport default class RectangleRoiTool extends AnnotationTool {\n static toolName = 'RectangleRoi'\n\n _throttledCalculateCachedStats: any\n editData: {\n annotation: any\n viewportUIDsToRender: string[]\n handleIndex?: number\n movingTextBox?: boolean\n newAnnotation?: boolean\n hasMoved?: boolean\n } | null\n isDrawing: boolean\n isHandleOutsideImage: boolean\n\n constructor(\n toolProps: PublicToolProps = {},\n defaultToolProps: ToolProps = {\n supportedInteractionTypes: ['Mouse', 'Touch'],\n configuration: {\n shadow: true,\n preventHandleOutsideImage: false,\n },\n }\n ) {\n super(toolProps, defaultToolProps)\n\n this._throttledCalculateCachedStats = throttle(\n this._calculateCachedStats,\n 100,\n { trailing: true }\n )\n }\n\n /**\n * Based on the current position of the mouse and the current imageId to create\n * a RectangleRoi Annotation and stores it in the annotationManager\n *\n * @param evt - EventTypes.NormalizedMouseEventType\n * @returns The annotation object.\n *\n */\n addNewAnnotation = (\n evt: EventTypes.MouseDownActivateEventType\n ): RectangleRoiAnnotation => {\n const eventDetail = evt.detail\n const { currentPoints, element } = eventDetail\n const worldPos = currentPoints.world\n\n const enabledElement = getEnabledElement(element)\n const { viewport, renderingEngine } = enabledElement\n\n this.isDrawing = true\n\n const camera = viewport.getCamera()\n const { viewPlaneNormal, viewUp } = camera\n\n let referencedImageId\n if (viewport instanceof StackViewport) {\n referencedImageId =\n viewport.getCurrentImageId && viewport.getCurrentImageId()\n } else {\n const volumeUID = this.getTargetUID(viewport)\n const imageVolume = cache.getVolume(volumeUID)\n referencedImageId = csUtils.getClosestImageId(\n imageVolume,\n worldPos,\n viewPlaneNormal,\n viewUp\n )\n }\n\n if (referencedImageId) {\n const colonIndex = referencedImageId.indexOf(':')\n referencedImageId = referencedImageId.substring(colonIndex + 1)\n }\n\n const annotation = {\n invalidated: true,\n highlighted: true,\n metadata: {\n viewPlaneNormal: <Types.Point3>[...viewPlaneNormal],\n viewUp: <Types.Point3>[...viewUp],\n FrameOfReferenceUID: viewport.getFrameOfReferenceUID(),\n referencedImageId,\n toolName: RectangleRoiTool.toolName,\n },\n data: {\n label: '',\n handles: {\n points: [\n <Types.Point3>[...worldPos],\n <Types.Point3>[...worldPos],\n <Types.Point3>[...worldPos],\n <Types.Point3>[...worldPos],\n ],\n textBox: {\n hasMoved: false,\n worldPosition: <Types.Point3>[0, 0, 0],\n worldBoundingBox: {\n topLeft: <Types.Point3>[0, 0, 0],\n topRight: <Types.Point3>[0, 0, 0],\n bottomLeft: <Types.Point3>[0, 0, 0],\n bottomRight: <Types.Point3>[0, 0, 0],\n },\n },\n activeHandleIndex: null,\n },\n cachedStats: {},\n },\n }\n\n // Ensure settings are initialized after annotation instantiation\n Settings.getObjectSettings(annotation, RectangleRoiTool)\n\n addAnnotation(element, annotation)\n\n const viewportUIDsToRender = getViewportUIDsWithToolToRender(\n element,\n RectangleRoiTool.toolName\n )\n\n this.editData = {\n annotation,\n viewportUIDsToRender,\n handleIndex: 3,\n movingTextBox: false,\n newAnnotation: true,\n hasMoved: false,\n }\n this._activateDraw(element)\n\n hideElementCursor(element)\n\n evt.preventDefault()\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n\n return annotation\n }\n\n /**\n * It returns if the canvas point is near the provided annotation in the provided\n * element or not. A proximity is passed to the function to determine the\n * proximity of the point to the annotation in number of pixels.\n *\n * @param element - HTML Element\n * @param annotation - Annotation\n * @param canvasCoords - Canvas coordinates\n * @param proximity - Proximity to tool to consider\n * @returns Boolean, whether the canvas point is near tool\n */\n isPointNearTool = (\n element: HTMLElement,\n annotation: RectangleRoiAnnotation,\n canvasCoords: Types.Point2,\n proximity: number\n ): boolean => {\n const enabledElement = getEnabledElement(element)\n const { viewport } = enabledElement\n\n const { data } = annotation\n const { points } = data.handles\n\n const canvasPoint1 = viewport.worldToCanvas(points[0])\n const canvasPoint2 = viewport.worldToCanvas(points[3])\n\n const rect = this._getRectangleImageCoordinates([\n canvasPoint1,\n canvasPoint2,\n ])\n\n const point = [canvasCoords[0], canvasCoords[1]]\n const { left, top, width, height } = rect\n\n const distanceToPoint = rectangle.distanceToPoint(\n [left, top, width, height],\n point as Types.Point2\n )\n\n if (distanceToPoint <= proximity) {\n return true\n }\n\n return false\n }\n\n toolSelectedCallback = (\n evt: EventTypes.MouseDownEventType,\n annotation: RectangleRoiAnnotation,\n interactionType: InteractionTypes\n ): void => {\n const eventDetail = evt.detail\n const { element } = eventDetail\n\n annotation.highlighted = true\n\n const viewportUIDsToRender = getViewportUIDsWithToolToRender(\n element,\n RectangleRoiTool.toolName\n )\n\n this.editData = {\n annotation,\n viewportUIDsToRender,\n movingTextBox: false,\n }\n\n this._activateModify(element)\n\n hideElementCursor(element)\n\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n\n evt.preventDefault()\n }\n\n handleSelectedCallback = (\n evt: EventTypes.MouseDownEventType,\n annotation: RectangleRoiAnnotation,\n handle: ToolHandle,\n interactionType = 'mouse'\n ): void => {\n const eventDetail = evt.detail\n const { element } = eventDetail\n const { data } = annotation\n\n annotation.highlighted = true\n\n let movingTextBox = false\n let handleIndex\n\n if ((handle as TextBoxHandle).worldPosition) {\n movingTextBox = true\n } else {\n handleIndex = data.handles.points.findIndex((p) => p === handle)\n }\n\n // Find viewports to render on drag.\n const viewportUIDsToRender = getViewportUIDsWithToolToRender(\n element,\n RectangleRoiTool.toolName\n )\n\n this.editData = {\n annotation,\n viewportUIDsToRender,\n handleIndex,\n movingTextBox,\n }\n this._activateModify(element)\n\n hideElementCursor(element)\n\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n\n evt.preventDefault()\n }\n\n _mouseUpCallback = (\n evt: EventTypes.MouseUpEventType | EventTypes.MouseClickEventType\n ) => {\n const eventDetail = evt.detail\n const { element } = eventDetail\n\n const { annotation, viewportUIDsToRender, newAnnotation, hasMoved } =\n this.editData\n const { data } = annotation\n\n if (newAnnotation && !hasMoved) {\n return\n }\n\n annotation.highlighted = false\n data.handles.activeHandleIndex = null\n\n this._deactivateModify(element)\n this._deactivateDraw(element)\n\n resetElementCursor(element)\n\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n\n this.editData = null\n this.isDrawing = false\n\n if (\n this.isHandleOutsideImage &&\n this.configuration.preventHandleOutsideImage\n ) {\n removeAnnotation(element, annotation.annotationUID)\n }\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n }\n\n _mouseDragCallback = (\n evt: EventTypes.MouseMoveEventType | EventTypes.MouseDragEventType\n ) => {\n this.isDrawing = true\n\n const eventDetail = evt.detail\n const { element } = eventDetail\n\n const { annotation, viewportUIDsToRender, handleIndex, movingTextBox } =\n this.editData\n const { data } = annotation\n\n if (movingTextBox) {\n // Drag mode - Move the text boxes world position\n const { deltaPoints } = eventDetail as EventTypes.MouseDragEventDetail\n const worldPosDelta = deltaPoints.world\n\n const { textBox } = data.handles\n const { worldPosition } = textBox\n\n worldPosition[0] += worldPosDelta[0]\n worldPosition[1] += worldPosDelta[1]\n worldPosition[2] += worldPosDelta[2]\n\n textBox.hasMoved = true\n } else if (handleIndex === undefined) {\n // Drag mode - Moving tool, so move all points by the world points delta\n const { deltaPoints } = eventDetail as EventTypes.MouseDragEventDetail\n const worldPosDelta = deltaPoints.world\n\n const { points } = data.handles\n\n points.forEach((point) => {\n point[0] += worldPosDelta[0]\n point[1] += worldPosDelta[1]\n point[2] += worldPosDelta[2]\n })\n annotation.invalidated = true\n } else {\n // Moving handle.\n const { currentPoints } = eventDetail\n const enabledElement = getEnabledElement(element)\n const { worldToCanvas, canvasToWorld } = enabledElement.viewport\n const worldPos = currentPoints.world\n\n const { points } = data.handles\n\n // Move this handle.\n points[handleIndex] = [...worldPos]\n\n let bottomLeftCanvas\n let bottomRightCanvas\n let topLeftCanvas\n let topRightCanvas\n\n let bottomLeftWorld\n let bottomRightWorld\n let topLeftWorld\n let topRightWorld\n\n switch (handleIndex) {\n case 0:\n case 3:\n // Moving bottomLeft or topRight\n\n bottomLeftCanvas = worldToCanvas(points[0])\n topRightCanvas = worldToCanvas(points[3])\n\n bottomRightCanvas = [topRightCanvas[0], bottomLeftCanvas[1]]\n topLeftCanvas = [bottomLeftCanvas[0], topRightCanvas[1]]\n\n bottomRightWorld = canvasToWorld(bottomRightCanvas)\n topLeftWorld = canvasToWorld(topLeftCanvas)\n\n points[1] = bottomRightWorld\n points[2] = topLeftWorld\n\n break\n case 1:\n case 2:\n // Moving bottomRight or topLeft\n bottomRightCanvas = worldToCanvas(points[1])\n topLeftCanvas = worldToCanvas(points[2])\n\n bottomLeftCanvas = <Types.Point2>[\n topLeftCanvas[0],\n bottomRightCanvas[1],\n ]\n topRightCanvas = <Types.Point2>[\n bottomRightCanvas[0],\n topLeftCanvas[1],\n ]\n\n bottomLeftWorld = canvasToWorld(bottomLeftCanvas)\n topRightWorld = canvasToWorld(topRightCanvas)\n\n points[0] = bottomLeftWorld\n points[3] = topRightWorld\n\n break\n }\n annotation.invalidated = true\n }\n\n this.editData.hasMoved = true\n\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n }\n\n cancel = (element: HTMLElement) => {\n // If it is mid-draw or mid-modify\n if (this.isDrawing) {\n this.isDrawing = false\n this._deactivateDraw(element)\n this._deactivateModify(element)\n resetElementCursor(element)\n\n const { annotation, viewportUIDsToRender } = this.editData\n\n const { data } = annotation\n\n annotation.highlighted = false\n data.handles.activeHandleIndex = null\n\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n\n this.editData = null\n return annotation.annotationUID\n }\n }\n /**\n * Add event handlers for the modify event loop, and prevent default event prapogation.\n */\n _activateDraw = (element) => {\n state.isInteractingWithTool = true\n\n element.addEventListener(Events.MOUSE_UP, this._mouseUpCallback)\n element.addEventListener(Events.MOUSE_DRAG, this._mouseDragCallback)\n element.addEventListener(Events.MOUSE_MOVE, this._mouseDragCallback)\n element.addEventListener(Events.MOUSE_CLICK, this._mouseUpCallback)\n\n // element.addEventListener(Events.TOUCH_END, this._mouseUpCallback)\n // element.addEventListener(Events.TOUCH_DRAG, this._mouseDragCallback)\n }\n\n /**\n * Add event handlers for the modify event loop, and prevent default event prapogation.\n */\n _deactivateDraw = (element) => {\n state.isInteractingWithTool = false\n\n element.removeEventListener(Events.MOUSE_UP, this._mouseUpCallback)\n element.removeEventListener(Events.MOUSE_DRAG, this._mouseDragCallback)\n element.removeEventListener(Events.MOUSE_MOVE, this._mouseDragCallback)\n element.removeEventListener(Events.MOUSE_CLICK, this._mouseUpCallback)\n\n // element.removeEventListener(Events.TOUCH_END, this._mouseUpCallback)\n // element.removeEventListener(Events.TOUCH_DRAG, this._mouseDragCallback)\n }\n\n /**\n * Add event handlers for the modify event loop, and prevent default event prapogation.\n */\n _activateModify = (element) => {\n state.isInteractingWithTool = true\n\n element.addEventListener(Events.MOUSE_UP, this._mouseUpCallback)\n element.addEventListener(Events.MOUSE_DRAG, this._mouseDragCallback)\n element.addEventListener(Events.MOUSE_CLICK, this._mouseUpCallback)\n\n // element.addEventListener(Events.TOUCH_END, this._mouseUpCallback)\n // element.addEventListener(Events.TOUCH_DRAG, this._mouseDragCallback)\n }\n\n /**\n * Remove event handlers for the modify event loop, and enable default event propagation.\n */\n _deactivateModify = (element) => {\n state.isInteractingWithTool = false\n\n element.removeEventListener(Events.MOUSE_UP, this._mouseUpCallback)\n element.removeEventListener(Events.MOUSE_DRAG, this._mouseDragCallback)\n element.removeEventListener(Events.MOUSE_CLICK, this._mouseUpCallback)\n\n // element.removeEventListener(Events.TOUCH_END, this._mouseUpCallback)\n // element.removeEventListener(Events.TOUCH_DRAG, this._mouseDragCallback)\n }\n\n /**\n * it is used to draw the rectangleRoi annotation in each\n * request animation frame. It calculates the updated cached statistics if\n * data is invalidated and cache it.\n *\n * @param enabledElement - The Cornerstone's enabledElement.\n * @param svgDrawingHelper - The svgDrawingHelper providing the context for drawing.\n */\n renderAnnotation = (\n enabledElement: Types.IEnabledElement,\n svgDrawingHelper: any\n ): void => {\n const { viewport } = enabledElement\n const { element } = viewport\n\n let annotations = getAnnotations(element, RectangleRoiTool.toolName)\n\n if (!annotations?.length) {\n return\n }\n\n annotations = this.filterInteractableAnnotationsForElement(\n element,\n annotations\n )\n\n if (!annotations?.length) {\n return\n }\n\n const targetUID = this.getTargetUID(viewport)\n const renderingEngine = viewport.getRenderingEngine()\n\n for (let i = 0; i < annotations.length; i++) {\n const annotation = annotations[i] as RectangleRoiAnnotation\n const settings = Settings.getObjectSettings(annotation, RectangleRoiTool)\n const annotationUID = annotation.annotationUID\n\n const data = annotation.data\n const { points, activeHandleIndex } = data.handles\n const canvasCoordinates = points.map((p) => viewport.worldToCanvas(p))\n const lineWidth = this.getStyle(settings, 'lineWidth', annotation)\n const lineDash = this.getStyle(settings, 'lineDash', annotation)\n const color = this.getStyle(settings, 'color', annotation)\n\n const { viewPlaneNormal, viewUp } = viewport.getCamera()\n\n if (!data.cachedStats[targetUID]) {\n data.cachedStats[targetUID] = {\n Modality: null,\n area: null,\n max: null,\n mean: null,\n stdDev: null,\n }\n\n this._calculateCachedStats(\n annotation,\n viewPlaneNormal,\n viewUp,\n renderingEngine,\n enabledElement\n )\n } else if (annotation.invalidated) {\n this._throttledCalculateCachedStats(\n annotation,\n viewPlaneNormal,\n viewUp,\n renderingEngine,\n enabledElement\n )\n\n // If the invalidated data is as a result of volumeViewport manipulation\n // of the tools, we need to invalidate the related stackViewports data if\n // they are not at the referencedImageId, so that\n // when scrolling to the related slice in which the tool were manipulated\n // we re-render the correct tool position. This is due to stackViewport\n // which doesn't have the full volume at each time, and we are only working\n // on one slice at a time.\n if (viewport instanceof VolumeViewport) {\n const { referencedImageId } = annotation.metadata\n\n // todo: this is not efficient, but necessary\n // invalidate all the relevant stackViewports if they are not\n // at the referencedImageId\n const viewports = renderingEngine.getViewports()\n viewports.forEach((vp) => {\n const stackTargetUID = this.getTargetUID(vp)\n // only delete the cachedStats for the stackedViewports if the tool\n // is dragged inside the volume and the stackViewports are not at the\n // referencedImageId for the tool\n if (\n vp instanceof StackViewport &&\n !vp.getCurrentImageId().includes(referencedImageId) &&\n data.cachedStats[stackTargetUID]\n ) {\n delete data.cachedStats[stackTargetUID]\n }\n })\n }\n }\n\n // If rendering engine has been destroyed while rendering\n if (!viewport.getRenderingEngine()) {\n console.warn('Rendering Engine has been destroyed')\n return\n }\n\n let activeHandleCanvasCoords\n\n if (\n !isAnnotationLocked(annotation) &&\n !this.editData &&\n activeHandleIndex !== null\n ) {\n // Not locked or creating and hovering over handle, so render handle.\n activeHandleCanvasCoords = [canvasCoordinates[activeHandleIndex]]\n }\n\n if (activeHandleCanvasCoords) {\n const handleGroupUID = '0'\n\n drawHandlesSvg(\n svgDrawingHelper,\n RectangleRoiTool.toolName,\n annotationUID,\n handleGroupUID,\n activeHandleCanvasCoords,\n {\n color,\n }\n )\n }\n\n const rectangleUID = '0'\n drawRectSvg(\n svgDrawingHelper,\n RectangleRoiTool.toolName,\n annotationUID,\n rectangleUID,\n canvasCoordinates[0],\n canvasCoordinates[3],\n {\n color,\n lineDash,\n lineWidth,\n }\n )\n\n const textLines = this._getTextLines(data, targetUID)\n if (!textLines || textLines.length === 0) {\n continue\n }\n\n if (!data.handles.textBox.hasMoved) {\n const canvasTextBoxCoords = getTextBoxCoordsCanvas(canvasCoordinates)\n\n data.handles.textBox.worldPosition =\n viewport.canvasToWorld(canvasTextBoxCoords)\n }\n\n const textBoxPosition = viewport.worldToCanvas(\n data.handles.textBox.worldPosition\n )\n\n const textBoxUID = '1'\n const boundingBox = drawLinkedTextBoxSvg(\n svgDrawingHelper,\n RectangleRoiTool.toolName,\n annotationUID,\n textBoxUID,\n textLines,\n textBoxPosition,\n canvasCoordinates,\n {},\n this.getLinkedTextBoxStyle(settings, annotation)\n )\n\n const { x: left, y: top, width, height } = boundingBox\n\n data.handles.textBox.worldBoundingBox = {\n topLeft: viewport.canvasToWorld([left, top]),\n topRight: viewport.canvasToWorld([left + width, top]),\n bottomLeft: viewport.canvasToWorld([left, top + height]),\n bottomRight: viewport.canvasToWorld([left + width, top + height]),\n }\n }\n }\n\n _getRectangleImageCoordinates = (\n points: Array<Types.Point2>\n ): {\n left: number\n top: number\n width: number\n height: number\n } => {\n const [point0, point1] = points\n\n return {\n left: Math.min(point0[0], point1[0]),\n top: Math.min(point0[1], point1[1]),\n width: Math.abs(point0[0] - point1[0]),\n height: Math.abs(point0[1] - point1[1]),\n }\n }\n\n /**\n * _getTextLines - Returns the Area, mean and std deviation of the area of the\n * target volume enclosed by the rectangle.\n *\n * @param data - The annotation tool-specific data.\n * @param targetUID - The volumeUID of the volume to display the stats for.\n */\n _getTextLines = (data, targetUID: string) => {\n const cachedVolumeStats = data.cachedStats[targetUID]\n const { area, mean, max, stdDev, Modality } = cachedVolumeStats\n\n if (mean === undefined) {\n return\n }\n\n const textLines = []\n\n const areaLine = `Area: ${area.toFixed(2)} mm${String.fromCharCode(178)}`\n let meanLine = `Mean: ${mean.toFixed(2)}`\n let maxLine = `Max: ${max.toFixed(2)}`\n let stdDevLine = `Std Dev: ${stdDev.toFixed(2)}`\n\n // Give appropriate units for the modality.\n if (Modality === 'PT') {\n meanLine += ' SUV'\n maxLine += ' SUV'\n stdDevLine += ' SUV'\n } else if (Modality === 'CT') {\n meanLine += ' HU'\n maxLine += ' HU'\n stdDevLine += ' HU'\n } else {\n meanLine += ' MO'\n maxLine += ' MO'\n stdDevLine += ' MO'\n }\n\n textLines.push(areaLine)\n textLines.push(maxLine)\n textLines.push(meanLine)\n textLines.push(stdDevLine)\n\n return textLines\n }\n\n /**\n * _calculateCachedStats - For each volume in the frame of reference that a\n * tool instance in particular viewport defines as its target volume, find the\n * volume coordinates (i,j,k) being probed by the two corners. One of i,j or k\n * will be constant across the two points. In the other two directions iterate\n * over the voxels and calculate the first and second-order statistics.\n *\n * @param data - The annotation tool-specific data.\n * @param viewPlaneNormal - The normal vector of the camera.\n * @param viewUp - The viewUp vector of the camera.\n */\n _calculateCachedStats = (\n annotation,\n viewPlaneNormal,\n viewUp,\n renderingEngine,\n enabledElement\n ) => {\n const { data } = annotation\n const { viewportUID, renderingEngineUID } = enabledElement\n\n const worldPos1 = data.handles.points[0]\n const worldPos2 = data.handles.points[3]\n const { cachedStats } = data\n\n const targetUIDs = Object.keys(cachedStats)\n\n for (let i = 0; i < targetUIDs.length; i++) {\n const targetUID = targetUIDs[i]\n\n const { image } = this.getTargetUIDViewportAndImage(\n targetUID,\n renderingEngine\n )\n\n const { dimensions, scalarData, imageData, metadata } = image\n\n const worldPos1Index = transformPhysicalToIndex(imageData, worldPos1)\n\n worldPos1Index[0] = Math.floor(worldPos1Index[0])\n worldPos1Index[1] = Math.floor(worldPos1Index[1])\n worldPos1Index[2] = Math.floor(worldPos1Index[2])\n\n const worldPos2Index = transformPhysicalToIndex(imageData, worldPos2)\n\n worldPos2Index[0] = Math.floor(worldPos2Index[0])\n worldPos2Index[1] = Math.floor(worldPos2Index[1])\n worldPos2Index[2] = Math.floor(worldPos2Index[2])\n\n // Check if one of the indexes are inside the volume, this then gives us\n // Some area to do stats over.\n\n if (this._isInsideVolume(worldPos1Index, worldPos2Index, dimensions)) {\n this.isHandleOutsideImage = false\n\n // Calculate index bounds to iterate over\n\n const iMin = Math.min(worldPos1Index[0], worldPos2Index[0])\n const iMax = Math.max(worldPos1Index[0], worldPos2Index[0])\n\n const jMin = Math.min(worldPos1Index[1], worldPos2Index[1])\n const jMax = Math.max(worldPos1Index[1], worldPos2Index[1])\n\n const kMin = Math.min(worldPos1Index[2], worldPos2Index[2])\n const kMax = Math.max(worldPos1Index[2], worldPos2Index[2])\n\n const { worldWidth, worldHeight } = getWorldWidthAndHeightFromCorners(\n viewPlaneNormal,\n viewUp,\n worldPos1,\n worldPos2\n )\n\n const area = worldWidth * worldHeight\n\n let count = 0\n let mean = 0\n let stdDev = 0\n let max = -Infinity\n\n const yMultiple = dimensions[0]\n const zMultiple = dimensions[0] * dimensions[1]\n\n //Todo: this can be replaced by pointInShapeCallback....\n // This is a triple loop, but one of these 3 values will be constant\n // In the planar view.\n for (let k = kMin; k <= kMax; k++) {\n for (let j = jMin; j <= jMax; j++) {\n for (let i = iMin; i <= iMax; i++) {\n const value = scalarData[k * zMultiple + j * yMultiple + i]\n\n if (value > max) {\n max = value\n }\n\n count++\n mean += value\n }\n }\n }\n\n mean /= count\n\n for (let k = kMin; k <= kMax; k++) {\n for (let j = jMin; j <= jMax; j++) {\n for (let i = iMin; i <= iMax; i++) {\n const value = scalarData[k * zMultiple + j * yMultiple + i]\n\n const valueMinusMean = value - mean\n\n stdDev += valueMinusMean * valueMinusMean\n }\n }\n }\n\n stdDev /= count\n stdDev = Math.sqrt(stdDev)\n\n cachedStats[targetUID] = {\n Modality: metadata.Modality,\n area,\n mean,\n stdDev,\n max,\n }\n } else {\n this.isHandleOutsideImage = true\n cachedStats[targetUID] = {\n Modality: metadata.Modality,\n }\n }\n }\n\n annotation.invalidated = false\n\n // Dispatching annotation modified\n const eventType = Events.ANNOTATION_MODIFIED\n\n const eventDetail: AnnotationModifiedEventDetail = {\n annotation,\n viewportUID,\n renderingEngineUID,\n }\n triggerEvent(eventTarget, eventType, eventDetail)\n\n return cachedStats\n }\n\n _isInsideVolume = (index1, index2, dimensions) => {\n return (\n csUtils.indexWithinDimensions(index1, dimensions) &&\n csUtils.indexWithinDimensions(index2, dimensions)\n )\n }\n}\n","import { vec3 } from 'gl-matrix'\nimport type { Types } from '@cornerstonejs/core'\n\n/**\n * Given two world positions and an orthogonal view to an `imageVolume` defined by\n * a `viewPlaneNormal` and a `viewUp`, get the width and height in world coordinates of the rectangle\n * defined by the two points. The implementation works both with orthogonal\n * non-orthogonal rectangles.\n *\n * @param viewPlaneNormal - The normal of the view.\n * @param viewUp - The up direction of the view.\n * @param imageVolume - The imageVolume to use to measure.\n * @param worldPos1 - The first world position.\n * @param worldPos2 - The second world position.\n *\n * @returns The `worldWidth` and `worldHeight`.\n */\nexport default function getWorldWidthAndHeightFromTwoPoints(\n viewPlaneNormal: Types.Point3,\n viewUp: Types.Point3,\n worldPos1: Types.Point3,\n worldPos2: Types.Point3\n): { worldWidth: number; worldHeight: number } {\n let viewRight = vec3.create()\n\n vec3.cross(viewRight, <vec3>viewUp, <vec3>viewPlaneNormal)\n\n viewRight = [-viewRight[0], -viewRight[1], -viewRight[2]]\n\n const pos1 = vec3.fromValues(...worldPos1)\n const pos2 = vec3.fromValues(...worldPos2)\n\n const diagonal = vec3.create()\n vec3.subtract(diagonal, pos1, pos2)\n\n const diagonalLength = vec3.length(diagonal)\n\n // When the two points are very close to each other return width as 0\n // to avoid NaN the cosTheta formula calculation\n if (diagonalLength < 0.0001) {\n return { worldWidth: 0, worldHeight: 0 }\n }\n\n const cosTheta =\n vec3.dot(diagonal, viewRight) / (diagonalLength * vec3.length(viewRight))\n\n const sinTheta = Math.sqrt(1 - cosTheta * cosTheta)\n\n const worldWidth = sinTheta * diagonalLength\n const worldHeight = cosTheta * diagonalLength\n\n return { worldWidth, worldHeight }\n}\n","import { AnnotationTool } from '../base'\n\nimport {\n getEnabledElement,\n Settings,\n StackViewport,\n VolumeViewport,\n eventTarget,\n triggerEvent,\n cache,\n utilities as csUtils,\n} from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\n\nimport throttle from '../../utilities/throttle'\nimport transformPhysicalToIndex from '../../utilities/transformPhysicalToIndex'\nimport {\n addAnnotation,\n getAnnotations,\n removeAnnotation,\n} from '../../stateManagement/annotation/annotationState'\nimport { isAnnotationLocked } from '../../stateManagement/annotation/annotationLocking'\nimport {\n drawEllipse as drawEllipseSvg,\n drawHandles as drawHandlesSvg,\n drawLinkedTextBox as drawLinkedTextBoxSvg,\n} from '../../drawingSvg'\nimport { state } from '../../store'\nimport { Events } from '../../enums'\nimport { getViewportUIDsWithToolToRender } from '../../utilities/viewportFilters'\nimport { getTextBoxCoordsCanvas } from '../../utilities/drawing'\nimport getWorldWidthAndHeightFromTwoPoints from '../../utilities/planar/getWorldWidthAndHeightFromTwoPoints'\nimport {\n pointInEllipse,\n getCanvasEllipseCorners,\n} from '../../utilities/math/ellipse'\nimport {\n resetElementCursor,\n hideElementCursor,\n} from '../../cursors/elementCursor'\nimport {\n Annotation,\n EventTypes,\n ToolHandle,\n TextBoxHandle,\n PublicToolProps,\n ToolProps,\n InteractionTypes,\n} from '../../types'\nimport {\n AnnotationModifiedEventDetail,\n MouseDragEventType,\n MouseMoveEventType,\n} from '../../types/EventTypes'\nimport triggerAnnotationRenderForViewportUIDs from '../../utilities/triggerAnnotationRenderForViewportUIDs'\nimport { pointInShapeCallback } from '../../utilities/'\n\nexport interface EllipticalRoiAnnotation extends Annotation {\n data: {\n handles: {\n points: [Types.Point3, Types.Point3, Types.Point3, Types.Point3] // [bottom, top, left, right]\n activeHandleIndex: number | null\n textBox?: {\n hasMoved: boolean\n worldPosition: Types.Point3\n worldBoundingBox: {\n topLeft: Types.Point3\n topRight: Types.Point3\n bottomLeft: Types.Point3\n bottomRight: Types.Point3\n }\n }\n }\n label: string\n cachedStats?: {\n [targetUID: string]: {\n Modality: string\n area: number\n max: number\n mean: number\n stdDev: number\n }\n }\n }\n}\n\n/**\n * EllipticalRoiTool let you draw annotations that measures the statistics\n * such as area, max, mean and stdDev of an elliptical region of interest.\n * You can use EllipticalRoiTool in all perpendicular views (axial, sagittal, coronal).\n * Note: annotation tools in cornerstone3DTools exists in the exact location\n * in the physical 3d space, as a result, by default, all annotations that are\n * drawing in the same frameOfReference will get shared between viewports that\n * are in the same frameOfReference. Elliptical tool's text box lines are dynamically\n * generated based on the viewport's underlying Modality. For instance, if\n * the viewport is displaying CT, the text box will shown the statistics in Hounsfield units,\n * and if the viewport is displaying PET, the text box will show the statistics in\n * SUV units.\n *\n * The resulting annotation's data (statistics) and metadata (the\n * state of the viewport while drawing was happening) will get added to the\n * ToolState manager and can be accessed from the ToolState by calling getAnnotations\n * or similar methods.\n *\n * ```js\n * cornerstoneTools.addTool(EllipticalRoiTool)\n *\n * const toolGroup = ToolGroupManager.createToolGroup('toolGroupUID')\n *\n * toolGroup.addTool(EllipticalRoiTool.toolName)\n *\n * toolGroup.addViewport('viewportUID', 'renderingEngineUID')\n *\n * toolGroup.setToolActive(EllipticalRoiTool.toolName, {\n * bindings: [\n * {\n * mouseButton: MouseBindings.Primary, // Left Click\n * },\n * ],\n * })\n * ```\n *\n * Read more in the Docs section of the website.\n */\nexport default class EllipticalRoiTool extends AnnotationTool {\n static toolName = 'EllipticalRoi'\n touchDragCallback: any\n mouseDragCallback: any\n _throttledCalculateCachedStats: any\n editData: {\n annotation: any\n viewportUIDsToRender: Array<string>\n handleIndex?: number\n movingTextBox?: boolean\n centerCanvas?: Array<number>\n canvasWidth?: number\n canvasHeight?: number\n originalHandleCanvas?: Array<number>\n newAnnotation?: boolean\n hasMoved?: boolean\n } | null\n isDrawing: boolean\n isHandleOutsideImage = false\n\n constructor(\n toolProps: PublicToolProps = {},\n defaultToolProps: ToolProps = {\n supportedInteractionTypes: ['Mouse', 'Touch'],\n configuration: {\n shadow: true,\n preventHandleOutsideImage: false,\n },\n }\n ) {\n super(toolProps, defaultToolProps)\n\n this._throttledCalculateCachedStats = throttle(\n this._calculateCachedStats,\n 100,\n { trailing: true }\n )\n }\n\n /**\n * Based on the current position of the mouse and the current imageId to create\n * a EllipticalRoi Annotation and stores it in the annotationManager\n *\n * @param evt - EventTypes.NormalizedMouseEventType\n * @returns The annotation object.\n *\n */\n addNewAnnotation = (\n evt: EventTypes.MouseDownActivateEventType\n ): EllipticalRoiAnnotation => {\n const eventDetail = evt.detail\n const { currentPoints, element } = eventDetail\n const worldPos = currentPoints.world\n const canvasPos = currentPoints.canvas\n\n const enabledElement = getEnabledElement(element)\n const { viewport, renderingEngine } = enabledElement\n\n this.isDrawing = true\n\n const camera = viewport.getCamera()\n const { viewPlaneNormal, viewUp } = camera\n\n let referencedImageId\n if (viewport instanceof StackViewport) {\n referencedImageId =\n viewport.getCurrentImageId && viewport.getCurrentImageId()\n } else {\n const volumeUID = this.getTargetUID(viewport)\n const imageVolume = cache.getVolume(volumeUID)\n referencedImageId = csUtils.getClosestImageId(\n imageVolume,\n worldPos,\n viewPlaneNormal,\n viewUp\n )\n }\n\n if (referencedImageId) {\n const colonIndex = referencedImageId.indexOf(':')\n referencedImageId = referencedImageId.substring(colonIndex + 1)\n }\n\n this.isDrawing = true\n\n const annotation = {\n highlighted: true,\n invalidated: true,\n metadata: {\n viewPlaneNormal: <Types.Point3>[...viewPlaneNormal],\n viewUp: <Types.Point3>[...viewUp],\n FrameOfReferenceUID: viewport.getFrameOfReferenceUID(),\n referencedImageId,\n toolName: EllipticalRoiTool.toolName,\n },\n data: {\n label: '',\n handles: {\n textBox: {\n hasMoved: false,\n worldPosition: <Types.Point3>[0, 0, 0],\n worldBoundingBox: {\n topLeft: <Types.Point3>[0, 0, 0],\n topRight: <Types.Point3>[0, 0, 0],\n bottomLeft: <Types.Point3>[0, 0, 0],\n bottomRight: <Types.Point3>[0, 0, 0],\n },\n },\n points: [\n [...worldPos],\n [...worldPos],\n [...worldPos],\n [...worldPos],\n ] as [Types.Point3, Types.Point3, Types.Point3, Types.Point3],\n activeHandleIndex: null,\n },\n cachedStats: {},\n },\n }\n\n // Ensure settings are initialized after annotation instantiation\n Settings.getObjectSettings(annotation, EllipticalRoiTool)\n\n addAnnotation(element, annotation)\n\n const viewportUIDsToRender = getViewportUIDsWithToolToRender(\n element,\n EllipticalRoiTool.toolName\n )\n\n this.editData = {\n annotation,\n viewportUIDsToRender,\n centerCanvas: canvasPos,\n newAnnotation: true,\n hasMoved: false,\n }\n this._activateDraw(element)\n\n hideElementCursor(element)\n\n evt.preventDefault()\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n\n return annotation\n }\n\n /**\n * It returns if the canvas point is near the provided annotation in the provided\n * element or not. A proximity is passed to the function to determine the\n * proximity of the point to the annotation in number of pixels.\n *\n * @param element - HTML Element\n * @param annotation - Annotation\n * @param canvasCoords - Canvas coordinates\n * @param proximity - Proximity to tool to consider\n * @returns Boolean, whether the canvas point is near tool\n */\n isPointNearTool = (\n element: HTMLElement,\n annotation: EllipticalRoiAnnotation,\n canvasCoords: Types.Point2,\n proximity: number\n ): boolean => {\n const enabledElement = getEnabledElement(element)\n const { viewport } = enabledElement\n\n const { data } = annotation\n const { points } = data.handles\n\n // For some reason Typescript doesn't understand this, so we need to be\n // more specific about the type\n const canvasCoordinates = points.map((p) => viewport.worldToCanvas(p)) as [\n Types.Point2,\n Types.Point2,\n Types.Point2,\n Types.Point2\n ]\n const canvasCorners = getCanvasEllipseCorners(canvasCoordinates)\n\n const [canvasPoint1, canvasPoint2] = canvasCorners\n\n const minorEllipse = {\n left: Math.min(canvasPoint1[0], canvasPoint2[0]) + proximity / 2,\n top: Math.min(canvasPoint1[1], canvasPoint2[1]) + proximity / 2,\n width: Math.abs(canvasPoint1[0] - canvasPoint2[0]) - proximity,\n height: Math.abs(canvasPoint1[1] - canvasPoint2[1]) - proximity,\n }\n\n const majorEllipse = {\n left: Math.min(canvasPoint1[0], canvasPoint2[0]) - proximity / 2,\n top: Math.min(canvasPoint1[1], canvasPoint2[1]) - proximity / 2,\n width: Math.abs(canvasPoint1[0] - canvasPoint2[0]) + proximity,\n height: Math.abs(canvasPoint1[1] - canvasPoint2[1]) + proximity,\n }\n\n const pointInMinorEllipse = this._pointInEllipseCanvas(\n minorEllipse,\n canvasCoords\n )\n const pointInMajorEllipse = this._pointInEllipseCanvas(\n majorEllipse,\n canvasCoords\n )\n\n if (pointInMajorEllipse && !pointInMinorEllipse) {\n return true\n }\n\n return false\n }\n\n toolSelectedCallback = (\n evt: EventTypes.MouseDownEventType,\n annotation: EllipticalRoiAnnotation,\n interactionType: InteractionTypes\n ): void => {\n const eventDetail = evt.detail\n const { element } = eventDetail\n\n annotation.highlighted = true\n\n const viewportUIDsToRender = getViewportUIDsWithToolToRender(\n element,\n EllipticalRoiTool.toolName\n )\n\n this.editData = {\n annotation,\n viewportUIDsToRender,\n movingTextBox: false,\n }\n\n hideElementCursor(element)\n\n this._activateModify(element)\n\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n\n evt.preventDefault()\n }\n\n handleSelectedCallback = (\n evt: EventTypes.MouseDownEventType,\n annotation: EllipticalRoiAnnotation,\n handle: ToolHandle,\n interactionType = 'mouse'\n ): void => {\n const eventDetail = evt.detail\n const { element } = eventDetail\n const { data } = annotation\n\n annotation.highlighted = true\n\n let movingTextBox = false\n let handleIndex\n\n let centerCanvas\n let canvasWidth\n let canvasHeight\n let originalHandleCanvas\n\n if ((handle as TextBoxHandle).worldPosition) {\n movingTextBox = true\n } else {\n const { points } = data.handles\n const enabledElement = getEnabledElement(element)\n const { worldToCanvas } = enabledElement.viewport\n\n handleIndex = points.findIndex((p) => p === handle)\n\n const pointsCanvas = points.map(worldToCanvas)\n\n originalHandleCanvas = pointsCanvas[handleIndex]\n\n canvasWidth = Math.abs(pointsCanvas[2][0] - pointsCanvas[3][0])\n canvasHeight = Math.abs(pointsCanvas[0][1] - pointsCanvas[1][1])\n\n centerCanvas = [\n (pointsCanvas[2][0] + pointsCanvas[3][0]) / 2,\n (pointsCanvas[0][1] + pointsCanvas[1][1]) / 2,\n ]\n }\n\n // Find viewports to render on drag.\n const viewportUIDsToRender = getViewportUIDsWithToolToRender(\n element,\n EllipticalRoiTool.toolName\n )\n\n this.editData = {\n annotation,\n viewportUIDsToRender,\n handleIndex,\n canvasWidth,\n canvasHeight,\n centerCanvas,\n originalHandleCanvas,\n movingTextBox,\n }\n this._activateModify(element)\n\n hideElementCursor(element)\n\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n\n evt.preventDefault()\n }\n\n _mouseUpCallback = (\n evt: EventTypes.MouseUpEventType | EventTypes.MouseClickEventType\n ) => {\n const eventDetail = evt.detail\n const { element } = eventDetail\n\n const { annotation, viewportUIDsToRender, newAnnotation, hasMoved } =\n this.editData\n const { data } = annotation\n\n if (newAnnotation && !hasMoved) {\n return\n }\n\n annotation.highlighted = false\n data.handles.activeHandleIndex = null\n\n this._deactivateModify(element)\n this._deactivateDraw(element)\n\n resetElementCursor(element)\n\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n\n this.editData = null\n this.isDrawing = false\n\n if (\n this.isHandleOutsideImage &&\n this.configuration.preventHandleOutsideImage\n ) {\n removeAnnotation(element, annotation.annotationUID)\n }\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n }\n\n _mouseDragDrawCallback = (evt: MouseMoveEventType | MouseDragEventType) => {\n this.isDrawing = true\n const eventDetail = evt.detail\n const { element } = eventDetail\n const { currentPoints } = eventDetail\n const currentCanvasPoints = currentPoints.canvas\n const enabledElement = getEnabledElement(element)\n const { renderingEngine, viewport } = enabledElement\n const { canvasToWorld } = viewport\n\n //////\n const { annotation, viewportUIDsToRender, centerCanvas } = this.editData\n const { data } = annotation\n\n const dX = Math.abs(currentCanvasPoints[0] - centerCanvas[0])\n const dY = Math.abs(currentCanvasPoints[1] - centerCanvas[1])\n\n // Todo: why bottom is -dY, it should be +dY\n const bottomCanvas = <Types.Point2>[centerCanvas[0], centerCanvas[1] - dY]\n const topCanvas = <Types.Point2>[centerCanvas[0], centerCanvas[1] + dY]\n const leftCanvas = <Types.Point2>[centerCanvas[0] - dX, centerCanvas[1]]\n const rightCanvas = <Types.Point2>[centerCanvas[0] + dX, centerCanvas[1]]\n\n data.handles.points = [\n canvasToWorld(bottomCanvas),\n canvasToWorld(topCanvas),\n canvasToWorld(leftCanvas),\n canvasToWorld(rightCanvas),\n ]\n\n annotation.invalidated = true\n\n this.editData.hasMoved = true\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n }\n\n _mouseDragModifyCallback = (evt: MouseDragEventType) => {\n this.isDrawing = true\n const eventDetail = evt.detail\n const { element } = eventDetail\n\n const { annotation, viewportUIDsToRender, handleIndex, movingTextBox } =\n this.editData\n const { data } = annotation\n\n if (movingTextBox) {\n const { deltaPoints } = eventDetail\n const worldPosDelta = deltaPoints.world\n\n const { textBox } = data.handles\n const { worldPosition } = textBox\n\n worldPosition[0] += worldPosDelta[0]\n worldPosition[1] += worldPosDelta[1]\n worldPosition[2] += worldPosDelta[2]\n\n textBox.hasMoved = true\n } else if (handleIndex === undefined) {\n // Moving tool\n const { deltaPoints } = eventDetail\n const worldPosDelta = deltaPoints.world\n\n const points = data.handles.points\n\n points.forEach((point) => {\n point[0] += worldPosDelta[0]\n point[1] += worldPosDelta[1]\n point[2] += worldPosDelta[2]\n })\n annotation.invalidated = true\n } else {\n this._dragHandle(evt)\n annotation.invalidated = true\n }\n\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n }\n\n _dragHandle = (evt) => {\n const eventDetail = evt.detail\n const { element } = eventDetail\n const enabledElement = getEnabledElement(element)\n const { canvasToWorld } = enabledElement.viewport\n\n const {\n annotation,\n canvasWidth,\n canvasHeight,\n handleIndex,\n centerCanvas,\n originalHandleCanvas,\n } = this.editData\n const { data } = annotation\n const { points } = data.handles\n\n // Move current point in that direction.\n // Move other points in opposite direction.\n\n const { currentPoints } = eventDetail\n const currentCanvasPoints = currentPoints.canvas\n\n if (handleIndex === 0 || handleIndex === 1) {\n // Dragging top or bottom point\n const dYCanvas = Math.abs(currentCanvasPoints[1] - centerCanvas[1])\n const canvasBottom = <Types.Point2>[\n centerCanvas[0],\n centerCanvas[1] - dYCanvas,\n ]\n const canvasTop = <Types.Point2>[\n centerCanvas[0],\n centerCanvas[1] + dYCanvas,\n ]\n\n points[0] = canvasToWorld(canvasBottom)\n points[1] = canvasToWorld(canvasTop)\n\n const dXCanvas = currentCanvasPoints[0] - originalHandleCanvas[0]\n const newHalfCanvasWidth = canvasWidth / 2 + dXCanvas\n const canvasLeft = <Types.Point2>[\n centerCanvas[0] - newHalfCanvasWidth,\n centerCanvas[1],\n ]\n const canvasRight = <Types.Point2>[\n centerCanvas[0] + newHalfCanvasWidth,\n centerCanvas[1],\n ]\n\n points[2] = canvasToWorld(canvasLeft)\n points[3] = canvasToWorld(canvasRight)\n } else {\n // Dragging left or right point\n const dXCanvas = Math.abs(currentCanvasPoints[0] - centerCanvas[0])\n const canvasLeft = <Types.Point2>[\n centerCanvas[0] - dXCanvas,\n centerCanvas[1],\n ]\n const canvasRight = <Types.Point2>[\n centerCanvas[0] + dXCanvas,\n centerCanvas[1],\n ]\n\n points[2] = canvasToWorld(canvasLeft)\n points[3] = canvasToWorld(canvasRight)\n\n const dYCanvas = currentCanvasPoints[1] - originalHandleCanvas[1]\n const newHalfCanvasHeight = canvasHeight / 2 + dYCanvas\n const canvasBottom = <Types.Point2>[\n centerCanvas[0],\n centerCanvas[1] - newHalfCanvasHeight,\n ]\n const canvasTop = <Types.Point2>[\n centerCanvas[0],\n centerCanvas[1] + newHalfCanvasHeight,\n ]\n\n points[0] = canvasToWorld(canvasBottom)\n points[1] = canvasToWorld(canvasTop)\n }\n }\n\n cancel = (element: HTMLElement) => {\n // If it is mid-draw or mid-modify\n if (this.isDrawing) {\n this.isDrawing = false\n this._deactivateDraw(element)\n this._deactivateModify(element)\n resetElementCursor(element)\n\n const { annotation, viewportUIDsToRender } = this.editData\n const { data } = annotation\n\n annotation.highlighted = false\n data.handles.activeHandleIndex = null\n\n const enabledElement = getEnabledElement(element)\n const { renderingEngine } = enabledElement\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n\n this.editData = null\n return annotation.annotationUID\n }\n }\n\n _activateModify = (element) => {\n state.isInteractingWithTool = true\n\n element.addEventListener(Events.MOUSE_UP, this._mouseUpCallback)\n element.addEventListener(Events.MOUSE_DRAG, this._mouseDragModifyCallback)\n element.addEventListener(Events.MOUSE_CLICK, this._mouseUpCallback)\n\n // element.addEventListener(Events.TOUCH_END, this._mouseUpCallback)\n // element.addEventListener(Events.TOUCH_DRAG, this._mouseDragModifyCallback)\n }\n\n _deactivateModify = (element) => {\n state.isInteractingWithTool = false\n\n element.removeEventListener(Events.MOUSE_UP, this._mouseUpCallback)\n element.removeEventListener(\n Events.MOUSE_DRAG,\n this._mouseDragModifyCallback\n )\n element.removeEventListener(Events.MOUSE_CLICK, this._mouseUpCallback)\n\n // element.removeEventListener(Events.TOUCH_END, this._mouseUpCallback)\n // element.removeEventListener(\n // Events.TOUCH_DRAG,\n // this._mouseDragModifyCallback\n // )\n }\n\n _activateDraw = (element) => {\n state.isInteractingWithTool = true\n\n element.addEventListener(Events.MOUSE_UP, this._mouseUpCallback)\n element.addEventListener(Events.MOUSE_DRAG, this._mouseDragDrawCallback)\n element.addEventListener(Events.MOUSE_MOVE, this._mouseDragDrawCallback)\n element.addEventListener(Events.MOUSE_CLICK, this._mouseUpCallback)\n\n // element.addEventListener(Events.TOUCH_END, this._mouseUpCallback)\n // element.addEventListener(Events.TOUCH_DRAG, this._mouseDragDrawCallback)\n }\n\n _deactivateDraw = (element) => {\n state.isInteractingWithTool = false\n\n element.removeEventListener(Events.MOUSE_UP, this._mouseUpCallback)\n element.removeEventListener(Events.MOUSE_DRAG, this._mouseDragDrawCallback)\n element.removeEventListener(Events.MOUSE_MOVE, this._mouseDragDrawCallback)\n element.removeEventListener(Events.MOUSE_CLICK, this._mouseUpCallback)\n\n // element.removeEventListener(Events.TOUCH_END, this._mouseUpCallback)\n // element.removeEventListener(Events.TOUCH_DRAG, this._mouseDragDrawCallback)\n }\n\n /**\n * it is used to draw the ellipticalRoi annotation in each\n * request animation frame. It calculates the updated cached statistics if\n * data is invalidated and cache it.\n *\n * @param enabledElement - The Cornerstone's enabledElement.\n * @param svgDrawingHelper - The svgDrawingHelper providing the context for drawing.\n */\n renderAnnotation = (\n enabledElement: Types.IEnabledElement,\n svgDrawingHelper: any\n ): void => {\n const { viewport } = enabledElement\n const { element } = viewport\n\n let annotations = getAnnotations(element, EllipticalRoiTool.toolName)\n\n if (!annotations?.length) {\n return\n }\n\n annotations = this.filterInteractableAnnotationsForElement(\n element,\n annotations\n )\n\n if (!annotations?.length) {\n return\n }\n\n const targetUID = this.getTargetUID(viewport)\n\n const renderingEngine = viewport.getRenderingEngine()\n\n for (let i = 0; i < annotations.length; i++) {\n const annotation = annotations[i] as EllipticalRoiAnnotation\n const settings = Settings.getObjectSettings(annotation, EllipticalRoiTool)\n const annotationUID = annotation.annotationUID\n const data = annotation.data\n\n const { handles } = data\n const { points, activeHandleIndex } = handles\n\n const lineWidth = this.getStyle(settings, 'lineWidth', annotation)\n const lineDash = this.getStyle(settings, 'lineDash', annotation)\n const color = this.getStyle(settings, 'color', annotation)\n\n const canvasCoordinates = points.map((p) =>\n viewport.worldToCanvas(p)\n ) as [Types.Point2, Types.Point2, Types.Point2, Types.Point2]\n const canvasCorners = <Array<Types.Point2>>(\n getCanvasEllipseCorners(canvasCoordinates)\n )\n if (!data.cachedStats[targetUID]) {\n data.cachedStats[targetUID] = {\n Modality: null,\n area: null,\n max: null,\n mean: null,\n stdDev: null,\n }\n\n this._calculateCachedStats(\n annotation,\n viewport,\n renderingEngine,\n enabledElement\n )\n } else if (annotation.invalidated) {\n this._throttledCalculateCachedStats(\n annotation,\n viewport,\n renderingEngine,\n enabledElement\n )\n\n // If the invalidated data is as a result of volumeViewport manipulation\n // of the tools, we need to invalidate the related viewports data, so that\n // when scrolling to the related slice in which the tool were manipulated\n // we re-render the correct tool position. This is due to stackViewport\n // which doesn't have the full volume at each time, and we are only working\n // on one slice at a time.\n if (viewport instanceof VolumeViewport) {\n const { referencedImageId } = annotation.metadata\n\n // todo: this is not efficient, but necessary\n // invalidate all the relevant stackViewports if they are not\n // at the referencedImageId\n const viewports = renderingEngine.getViewports()\n viewports.forEach((vp) => {\n const stackTargetUID = this.getTargetUID(vp)\n // only delete the cachedStats for the stackedViewports if the tool\n // is dragged inside the volume and the stackViewports are not at the\n // referencedImageId for the tool\n if (\n vp instanceof StackViewport &&\n !vp.getCurrentImageId().includes(referencedImageId) &&\n data.cachedStats[stackTargetUID]\n ) {\n delete data.cachedStats[stackTargetUID]\n }\n })\n }\n }\n\n // If rendering engine has been destroyed while rendering\n if (!viewport.getRenderingEngine()) {\n console.warn('Rendering Engine has been destroyed')\n return\n }\n\n let activeHandleCanvasCoords\n\n if (\n !isAnnotationLocked(annotation) &&\n !this.editData &&\n activeHandleIndex !== null\n ) {\n // Not locked or creating and hovering over handle, so render handle.\n activeHandleCanvasCoords = [canvasCoordinates[activeHandleIndex]]\n }\n\n if (activeHandleCanvasCoords) {\n const handleGroupUID = '0'\n drawHandlesSvg(\n svgDrawingHelper,\n EllipticalRoiTool.toolName,\n annotationUID,\n handleGroupUID,\n activeHandleCanvasCoords,\n {\n color,\n }\n )\n }\n\n const ellipseUID = '0'\n drawEllipseSvg(\n svgDrawingHelper,\n EllipticalRoiTool.toolName,\n annotationUID,\n ellipseUID,\n canvasCorners[0],\n canvasCorners[1],\n {\n color,\n lineDash,\n lineWidth,\n }\n )\n\n const textLines = this._getTextLines(data, targetUID)\n if (!textLines || textLines.length === 0) {\n continue\n }\n\n // Poor man's cached?\n let canvasTextBoxCoords\n\n if (!data.handles.textBox.hasMoved) {\n canvasTextBoxCoords = getTextBoxCoordsCanvas(canvasCorners)\n\n data.handles.textBox.worldPosition =\n viewport.canvasToWorld(canvasTextBoxCoords)\n }\n\n const textBoxPosition = viewport.worldToCanvas(\n data.handles.textBox.worldPosition\n )\n\n const textBoxUID = '1'\n const boundingBox = drawLinkedTextBoxSvg(\n svgDrawingHelper,\n EllipticalRoiTool.toolName,\n annotationUID,\n textBoxUID,\n textLines,\n textBoxPosition,\n canvasCoordinates,\n {},\n this.getLinkedTextBoxStyle(settings, annotation)\n )\n\n const { x: left, y: top, width, height } = boundingBox\n\n data.handles.textBox.worldBoundingBox = {\n topLeft: viewport.canvasToWorld([left, top]),\n topRight: viewport.canvasToWorld([left + width, top]),\n bottomLeft: viewport.canvasToWorld([left, top + height]),\n bottomRight: viewport.canvasToWorld([left + width, top + height]),\n }\n }\n }\n\n _getTextLines = (data, targetUID) => {\n const cachedVolumeStats = data.cachedStats[targetUID]\n const { area, mean, stdDev, max, isEmptyArea, Modality } = cachedVolumeStats\n\n if (mean === undefined) {\n return\n }\n\n const textLines = []\n\n const areaLine = isEmptyArea\n ? `Area: Oblique not supported`\n : `Area: ${area.toFixed(2)} mm${String.fromCharCode(178)}`\n let meanLine = `Mean: ${mean.toFixed(2)}`\n let maxLine = `Max: ${max.toFixed(2)}`\n let stdDevLine = `Std Dev: ${stdDev.toFixed(2)}`\n\n if (Modality === 'PT') {\n meanLine += ' SUV'\n maxLine += ' SUV'\n stdDevLine += ' SUV'\n } else if (Modality === 'CT') {\n meanLine += ' HU'\n maxLine += ' HU'\n stdDevLine += ' HU'\n } else {\n meanLine += ' MO'\n maxLine += ' MO'\n stdDevLine += ' MO'\n }\n\n textLines.push(areaLine)\n textLines.push(maxLine)\n textLines.push(meanLine)\n textLines.push(stdDevLine)\n\n return textLines\n }\n\n _calculateCachedStats = (\n annotation,\n viewport,\n renderingEngine,\n enabledElement\n ) => {\n const data = annotation.data\n const { viewportUID, renderingEngineUID } = enabledElement\n\n const { points } = data.handles\n\n const canvasCoordinates = points.map((p) => viewport.worldToCanvas(p))\n const { viewPlaneNormal, viewUp } = viewport.getCamera()\n\n const [topLeftCanvas, bottomRightCanvas] = <Array<Types.Point2>>(\n getCanvasEllipseCorners(canvasCoordinates)\n )\n\n const topLeftWorld = viewport.canvasToWorld(topLeftCanvas)\n const bottomRightWorld = viewport.canvasToWorld(bottomRightCanvas)\n const { cachedStats } = data\n\n const targetUIDs = Object.keys(cachedStats)\n const worldPos1 = topLeftWorld\n const worldPos2 = bottomRightWorld\n\n for (let i = 0; i < targetUIDs.length; i++) {\n const targetUID = targetUIDs[i]\n\n const { image } = this.getTargetUIDViewportAndImage(\n targetUID,\n renderingEngine\n )\n\n const { dimensions, imageData, metadata } = image\n\n const worldPos1Index = transformPhysicalToIndex(imageData, worldPos1)\n\n worldPos1Index[0] = Math.floor(worldPos1Index[0])\n worldPos1Index[1] = Math.floor(worldPos1Index[1])\n worldPos1Index[2] = Math.floor(worldPos1Index[2])\n\n const worldPos2Index = transformPhysicalToIndex(imageData, worldPos2)\n\n worldPos2Index[0] = Math.floor(worldPos2Index[0])\n worldPos2Index[1] = Math.floor(worldPos2Index[1])\n worldPos2Index[2] = Math.floor(worldPos2Index[2])\n\n // Check if one of the indexes are inside the volume, this then gives us\n // Some area to do stats over.\n\n if (this._isInsideVolume(worldPos1Index, worldPos2Index, dimensions)) {\n const iMin = Math.min(worldPos1Index[0], worldPos2Index[0])\n const iMax = Math.max(worldPos1Index[0], worldPos2Index[0])\n\n const jMin = Math.min(worldPos1Index[1], worldPos2Index[1])\n const jMax = Math.max(worldPos1Index[1], worldPos2Index[1])\n\n const kMin = Math.min(worldPos1Index[2], worldPos2Index[2])\n const kMax = Math.max(worldPos1Index[2], worldPos2Index[2])\n\n const boundsIJK = [\n [iMin, iMax],\n [jMin, jMax],\n [kMin, kMax],\n ] as [Types.Point2, Types.Point2, Types.Point2]\n\n const center = [\n (topLeftWorld[0] + bottomRightWorld[0]) / 2,\n (topLeftWorld[1] + bottomRightWorld[1]) / 2,\n (topLeftWorld[2] + bottomRightWorld[2]) / 2,\n ] as Types.Point3\n\n const ellipseObj = {\n center,\n xRadius: Math.abs(topLeftWorld[0] - bottomRightWorld[0]) / 2,\n yRadius: Math.abs(topLeftWorld[1] - bottomRightWorld[1]) / 2,\n zRadius: Math.abs(topLeftWorld[2] - bottomRightWorld[2]) / 2,\n }\n\n const { worldWidth, worldHeight } = getWorldWidthAndHeightFromTwoPoints(\n viewPlaneNormal,\n viewUp,\n worldPos1,\n worldPos2\n )\n const isEmptyArea = worldWidth === 0 && worldHeight === 0\n const area = Math.PI * (worldWidth / 2) * (worldHeight / 2)\n\n let count = 0\n let mean = 0\n let stdDev = 0\n let max = -Infinity\n\n const meanMaxCalculator = ({ value: newValue }) => {\n if (newValue > max) {\n max = newValue\n }\n\n mean += newValue\n count += 1\n }\n\n pointInShapeCallback(\n imageData,\n (pointLPS, pointIJK) => pointInEllipse(ellipseObj, pointLPS),\n meanMaxCalculator,\n boundsIJK\n )\n\n mean /= count\n\n const stdCalculator = ({ value }) => {\n const valueMinusMean = value - mean\n\n stdDev += valueMinusMean * valueMinusMean\n }\n\n pointInShapeCallback(\n imageData,\n (pointLPS, pointIJK) => pointInEllipse(ellipseObj, pointLPS),\n stdCalculator,\n boundsIJK\n )\n\n stdDev /= count\n stdDev = Math.sqrt(stdDev)\n\n cachedStats[targetUID] = {\n Modality: metadata.Modality,\n area,\n mean,\n max,\n stdDev,\n isEmptyArea,\n }\n } else {\n this.isHandleOutsideImage = true\n\n cachedStats[targetUID] = {\n Modality: metadata.Modality,\n }\n }\n }\n\n annotation.invalidated = false\n\n // Dispatching annotation modified\n const eventType = Events.ANNOTATION_MODIFIED\n\n const eventDetail: AnnotationModifiedEventDetail = {\n annotation,\n viewportUID,\n renderingEngineUID,\n }\n\n triggerEvent(eventTarget, eventType, eventDetail)\n\n return cachedStats\n }\n\n _isInsideVolume = (index1, index2, dimensions) => {\n return (\n csUtils.indexWithinDimensions(index1, dimensions) &&\n csUtils.indexWithinDimensions(index2, dimensions)\n )\n }\n\n /**\n * This is a temporary function to use the old ellipse's canvas-based\n * calculation for isPointNearTool, we should move the the world-based\n * calculation to the tool's isPointNearTool function.\n *\n * @param ellipse - The ellipse object\n * @param location - The location to check\n * @returns True if the point is inside the ellipse\n */\n _pointInEllipseCanvas(ellipse, location: Types.Point2): boolean {\n const xRadius = ellipse.width / 2\n const yRadius = ellipse.height / 2\n\n if (xRadius <= 0.0 || yRadius <= 0.0) {\n return false\n }\n\n const center = [ellipse.left + xRadius, ellipse.top + yRadius]\n const normalized = [location[0] - center[0], location[1] - center[1]]\n\n const inEllipse =\n (normalized[0] * normalized[0]) / (xRadius * xRadius) +\n (normalized[1] * normalized[1]) / (yRadius * yRadius) <=\n 1.0\n\n return inEllipse\n }\n}\n","import { ImageVolume } from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\n\nimport { getBoundingBoxAroundShape } from '../../../utilities/segmentation'\nimport { pointInShapeCallback } from '../../../utilities'\nimport transformPhysicalToIndex from '../../../utilities/transformPhysicalToIndex'\nimport { triggerSegmentationDataModified } from '../../../stateManagement/segmentation/triggerSegmentationEvents'\n\ntype OperationData = {\n toolGroupUID: string\n segmentationDataUID: string\n points: [Types.Point3, Types.Point3, Types.Point3, Types.Point3]\n volume: ImageVolume\n constraintFn: (x: [number, number, number]) => boolean\n segmentIndex: number\n segmentsLocked: number[]\n}\n\n/**\n * For each point in the bounding box around the rectangle, if the point is inside\n * the rectangle, set the scalar value to the segmentIndex\n * @param toolGroupUID - string\n * @param operationData - OperationData\n * @param constraintFn - can be used to perform threshold segmentation\n * @param inside - boolean\n */\n// Todo: why we have another constraintFn? in addition to the one in the operationData?\nfunction fillRectangle(\n enabledElement: Types.IEnabledElement,\n operationData: OperationData,\n inside = true\n): void {\n const {\n volume: segmentation,\n points,\n segmentsLocked,\n segmentIndex,\n segmentationDataUID,\n toolGroupUID,\n constraintFn,\n } = operationData\n const { imageData, dimensions, scalarData } = segmentation\n\n let rectangleCornersIJK = points.map((world) => {\n return transformPhysicalToIndex(imageData, world)\n })\n\n // math round\n rectangleCornersIJK = rectangleCornersIJK.map((point) => {\n return point.map((coord) => {\n return Math.round(coord)\n })\n })\n\n const boundsIJK = getBoundingBoxAroundShape(rectangleCornersIJK, dimensions)\n\n if (boundsIJK.every(([min, max]) => min !== max)) {\n throw new Error('Oblique segmentation tools are not supported yet')\n }\n\n // Since always all points inside the boundsIJK is inside the rectangle...\n const pointInRectangle = () => true\n\n const callback = ({ value, index, pointIJK }) => {\n if (segmentsLocked.includes(value)) {\n return\n }\n\n if (!constraintFn) {\n scalarData[index] = segmentIndex\n return\n }\n\n if (constraintFn(pointIJK)) {\n scalarData[index] = segmentIndex\n }\n }\n\n pointInShapeCallback(imageData, pointInRectangle, callback, boundsIJK)\n\n triggerSegmentationDataModified(toolGroupUID, segmentationDataUID)\n}\n\n/**\n * Fill the inside of a rectangle\n * @param toolGroupUID - The unique identifier of the tool group.\n * @param operationData - The data that will be used to create the\n * new rectangle.\n * @param constraintFn - can be used to perform threshold segmentation\n */\nexport function fillInsideRectangle(\n enabledElement: Types.IEnabledElement,\n operationData: OperationData\n): void {\n fillRectangle(enabledElement, operationData, true)\n}\n\n/**\n * Fill the area outside of a rectangle for the toolGroupUID and segmentationDataUID.\n * @param toolGroupUID - The unique identifier of the tool group.\n * @param operationData - The data that will be used to create the\n * new rectangle.\n * @param constraintFn - can be used to perform threshold segmentation\n */\nexport function fillOutsideRectangle(\n enabledElement: Types.IEnabledElement,\n operationData: OperationData\n): void {\n fillRectangle(enabledElement, operationData, false)\n}\n","import { ImageVolume } from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\n\nimport { getBoundingBoxAroundShape } from '../../../utilities/segmentation'\nimport transformPhysicalToIndex from '../../../utilities/transformPhysicalToIndex'\nimport { triggerSegmentationDataModified } from '../../../stateManagement/segmentation/triggerSegmentationEvents'\nimport { pointInShapeCallback } from '../../../utilities'\n\ntype EraseOperationData = {\n toolGroupUID: string\n segmentationDataUID: string\n points: [Types.Point3, Types.Point3, Types.Point3, Types.Point3]\n volume: ImageVolume\n constraintFn: (x: [number, number, number]) => boolean\n segmentsLocked: number[]\n}\n\nfunction eraseRectangle(\n enabledElement: Types.IEnabledElement,\n operationData: EraseOperationData,\n inside = true\n): void {\n const {\n volume: segmentation,\n points,\n segmentsLocked,\n segmentationDataUID,\n toolGroupUID,\n } = operationData\n const { imageData, dimensions, scalarData } = segmentation\n\n const rectangleCornersIJK = points.map((world) => {\n return transformPhysicalToIndex(imageData, world)\n })\n\n const boundsIJK = getBoundingBoxAroundShape(rectangleCornersIJK, dimensions)\n\n if (boundsIJK.every(([min, max]) => min !== max)) {\n throw new Error('Oblique segmentation tools are not supported yet')\n }\n\n // Since always all points inside the boundsIJK is inside the rectangle...\n const pointInShape = () => true\n\n const callback = ({ value, index }) => {\n if (segmentsLocked.includes(value)) {\n return\n }\n scalarData[index] = 0\n }\n\n pointInShapeCallback(imageData, pointInShape, callback, boundsIJK)\n\n triggerSegmentationDataModified(toolGroupUID, segmentationDataUID)\n}\n\n/**\n * Erase the rectangle region segment inside the segmentation defined by the operationData.\n * It erases the segmentation pixels inside the defined rectangle.\n * @param enabledElement - The element for which the segment is being erased.\n * @param operationData - EraseOperationData\n */\nexport function eraseInsideRectangle(\n enabledElement: Types.IEnabledElement,\n operationData: EraseOperationData\n): void {\n eraseRectangle(enabledElement, operationData, true)\n}\n\n/**\n * Erase the rectangle region segment inside the segmentation defined by the operationData.\n * It erases the segmentation pixels outside the defined rectangle.\n * @param enabledElement - The element for which the segment is being erased.\n * @param operationData - EraseOperationData\n */\nexport function eraseOutsideRectangle(\n enabledElement: Types.IEnabledElement,\n operationData: EraseOperationData\n): void {\n eraseRectangle(enabledElement, operationData, false)\n}\n","import {\n cache,\n getEnabledElement,\n Settings,\n StackViewport,\n} from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\n\nimport { BaseTool } from '../base'\nimport { PublicToolProps, ToolProps, EventTypes } from '../../types'\nimport { fillInsideRectangle } from './strategies/fillRectangle'\nimport { eraseInsideRectangle } from './strategies/eraseRectangle'\nimport { getViewportUIDsWithToolToRender } from '../../utilities/viewportFilters'\n\nimport { Events } from '../../enums'\nimport RectangleRoiTool from '../annotation/RectangleRoiTool'\nimport { drawRect as drawRectSvg } from '../../drawingSvg'\nimport {\n resetElementCursor,\n hideElementCursor,\n} from '../../cursors/elementCursor'\n\nimport triggerAnnotationRenderForViewportUIDs from '../../utilities/triggerAnnotationRenderForViewportUIDs'\nimport {\n segmentationColor,\n segmentLocking,\n segmentIndex as segmentIndexController,\n activeSegmentation,\n} from '../../stateManagement/segmentation'\n\n/**\n * Tool for manipulating segmentation data by drawing a rectangle. It acts on the\n * active Segmentation on the viewport (enabled element) and requires an active\n * segmentation to be already present. By default it will use the activeSegmentIndex\n * for the segmentation to modify. You can use SegmentationModule to set the active\n * segmentation and segmentIndex.\n */\nexport default class RectangleScissorsTool extends BaseTool {\n static toolName = 'RectangleScissor'\n _throttledCalculateCachedStats: any\n editData: {\n annotation: any\n segmentationDataUID: string\n segmentation: any\n segmentIndex: number\n segmentsLocked: number[]\n segmentColor: [number, number, number, number]\n viewportUIDsToRender: string[]\n handleIndex?: number\n movingTextBox: boolean\n newAnnotation?: boolean\n hasMoved?: boolean\n } | null\n isDrawing: boolean\n isHandleOutsideImage: boolean\n\n constructor(\n toolProps: PublicToolProps = {},\n defaultToolProps: ToolProps = {\n supportedInteractionTypes: ['Mouse', 'Touch'],\n configuration: {\n strategies: {\n FILL_INSIDE: fillInsideRectangle,\n ERASE_INSIDE: eraseInsideRectangle,\n },\n defaultStrategy: 'FILL_INSIDE',\n activeStrategy: 'FILL_INSIDE',\n },\n }\n ) {\n super(toolProps, defaultToolProps)\n }\n\n /**\n * Based on the current position of the mouse and the enabledElement, it\n * finds the active segmentation info and use it for the current tool.\n *\n * @param evt - EventTypes.NormalizedMouseEventType\n * @returns The annotation object.\n *\n */\n addNewAnnotation = (evt: EventTypes.MouseDownActivateEventType) => {\n const eventDetail = evt.detail\n const { currentPoints, element } = eventDetail\n const worldPos = currentPoints.world\n\n const enabledElement = getEnabledElement(element)\n const { viewport, renderingEngine } = enabledElement\n\n this.isDrawing = true\n\n const camera = viewport.getCamera()\n const { viewPlaneNormal, viewUp } = camera\n const toolGroupUID = this.toolGroupUID\n\n const activeSegmentationInfo =\n activeSegmentation.getActiveSegmentationInfo(toolGroupUID)\n if (!activeSegmentationInfo) {\n throw new Error(\n 'No active segmentation detected, create one before using scissors tool'\n )\n }\n\n // Todo: we should have representation type check if we are going to use this\n // tool in other representations other than labelmap\n const { segmentationDataUID, volumeUID } = activeSegmentationInfo\n const segmentIndex =\n segmentIndexController.getActiveSegmentIndex(toolGroupUID)\n const segmentsLocked =\n segmentLocking.getSegmentsLockedForSegmentation(volumeUID)\n const segmentColor = segmentationColor.getColorForSegmentIndex(\n toolGroupUID,\n activeSegmentationInfo.segmentationDataUID,\n segmentIndex\n )\n\n const segmentation = cache.getVolume(volumeUID)\n\n // Todo: Used for drawing the svg only, we might not need it at all\n const annotation = {\n highlighted: true,\n invalidated: true,\n metadata: {\n viewPlaneNormal: <Types.Point3>[...viewPlaneNormal],\n viewUp: <Types.Point3>[...viewUp],\n FrameOfReferenceUID: viewport.getFrameOfReferenceUID(),\n referencedImageId: '',\n toolName: RectangleScissorsTool.toolName,\n segmentColor,\n },\n data: {\n handles: {\n points: [\n <Types.Point3>[...worldPos],\n <Types.Point3>[...worldPos],\n <Types.Point3>[...worldPos],\n <Types.Point3>[...worldPos],\n ],\n activeHandleIndex: null,\n },\n },\n }\n\n // Ensure settings are initialized after annotation instantiation\n Settings.getObjectSettings(annotation, RectangleRoiTool)\n\n const viewportUIDsToRender = getViewportUIDsWithToolToRender(\n element,\n RectangleScissorsTool.toolName\n )\n\n this.editData = {\n annotation,\n segmentation,\n segmentIndex,\n segmentsLocked,\n segmentColor,\n segmentationDataUID,\n viewportUIDsToRender,\n handleIndex: 3,\n movingTextBox: false,\n newAnnotation: true,\n hasMoved: false,\n }\n\n this._activateDraw(element)\n\n hideElementCursor(element)\n\n evt.preventDefault()\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n }\n\n _mouseDragCallback = (evt: EventTypes.MouseDragEventType) => {\n this.isDrawing = true\n\n const eventDetail = evt.detail\n const { element } = eventDetail\n\n const { annotation, viewportUIDsToRender, handleIndex } = this.editData\n const { data } = annotation\n\n // Moving handle.\n const { currentPoints } = eventDetail\n const enabledElement = getEnabledElement(element)\n const { worldToCanvas, canvasToWorld } = enabledElement.viewport\n const worldPos = currentPoints.world\n\n const { points } = data.handles\n\n // Move this handle.\n points[handleIndex] = [...worldPos]\n\n let bottomLeftCanvas\n let bottomRightCanvas\n let topLeftCanvas\n let topRightCanvas\n\n let bottomLeftWorld\n let bottomRightWorld\n let topLeftWorld\n let topRightWorld\n\n switch (handleIndex) {\n case 0:\n case 3:\n // Moving bottomLeft or topRight\n\n bottomLeftCanvas = worldToCanvas(points[0])\n topRightCanvas = worldToCanvas(points[3])\n\n bottomRightCanvas = [topRightCanvas[0], bottomLeftCanvas[1]]\n topLeftCanvas = [bottomLeftCanvas[0], topRightCanvas[1]]\n\n bottomRightWorld = canvasToWorld(bottomRightCanvas)\n topLeftWorld = canvasToWorld(topLeftCanvas)\n\n points[1] = bottomRightWorld\n points[2] = topLeftWorld\n\n break\n case 1:\n case 2:\n // Moving bottomRight or topLeft\n bottomRightCanvas = worldToCanvas(points[1])\n topLeftCanvas = worldToCanvas(points[2])\n\n bottomLeftCanvas = <Types.Point2>[\n topLeftCanvas[0],\n bottomRightCanvas[1],\n ]\n topRightCanvas = <Types.Point2>[bottomRightCanvas[0], topLeftCanvas[1]]\n\n bottomLeftWorld = canvasToWorld(bottomLeftCanvas)\n topRightWorld = canvasToWorld(topRightCanvas)\n\n points[0] = bottomLeftWorld\n points[3] = topRightWorld\n\n break\n }\n annotation.invalidated = true\n\n this.editData.hasMoved = true\n\n const { renderingEngine } = enabledElement\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n }\n\n _mouseUpCallback = (\n evt: EventTypes.MouseUpEventType | EventTypes.MouseClickEventType\n ) => {\n const eventDetail = evt.detail\n const { element } = eventDetail\n\n const {\n annotation,\n newAnnotation,\n hasMoved,\n segmentation,\n segmentationDataUID,\n segmentIndex,\n segmentsLocked,\n } = this.editData\n const { data } = annotation\n\n if (newAnnotation && !hasMoved) {\n return\n }\n\n annotation.highlighted = false\n data.handles.activeHandleIndex = null\n\n this._deactivateDraw(element)\n\n resetElementCursor(element)\n\n const enabledElement = getEnabledElement(element)\n const { viewport } = enabledElement\n\n this.editData = null\n this.isDrawing = false\n\n if (viewport instanceof StackViewport) {\n throw new Error('Not implemented yet')\n }\n\n const operationData = {\n points: data.handles.points,\n volume: segmentation,\n segmentationDataUID,\n segmentIndex,\n segmentsLocked,\n toolGroupUID: this.toolGroupUID,\n }\n\n this.applyActiveStrategy(enabledElement, operationData)\n }\n\n /**\n * Add event handlers for the modify event loop, and prevent default event propagation.\n */\n _activateDraw = (element) => {\n element.addEventListener(Events.MOUSE_UP, this._mouseUpCallback)\n element.addEventListener(Events.MOUSE_DRAG, this._mouseDragCallback)\n element.addEventListener(Events.MOUSE_CLICK, this._mouseUpCallback)\n\n // element.addEventListener(Events.TOUCH_END, this._mouseUpCallback)\n // element.addEventListener(Events.TOUCH_DRAG, this._mouseDragCallback)\n }\n\n /**\n * Add event handlers for the modify event loop, and prevent default event prapogation.\n */\n _deactivateDraw = (element) => {\n element.removeEventListener(Events.MOUSE_UP, this._mouseUpCallback)\n element.removeEventListener(Events.MOUSE_DRAG, this._mouseDragCallback)\n element.removeEventListener(Events.MOUSE_CLICK, this._mouseUpCallback)\n\n // element.removeEventListener(Events.TOUCH_END, this._mouseUpCallback)\n // element.removeEventListener(Events.TOUCH_DRAG, this._mouseDragCallback)\n }\n\n /**\n * it is used to draw the rectangleScissor annotation in each\n * request animation frame. Note that the annotation are disappeared\n * after the segmentation modification.\n *\n * @param enabledElement - The Cornerstone's enabledElement.\n * @param svgDrawingHelper - The svgDrawingHelper providing the context for drawing.\n */\n renderAnnotation = (\n enabledElement: Types.IEnabledElement,\n svgDrawingHelper: any\n ): void => {\n if (!this.editData) {\n return\n }\n\n const { viewport } = enabledElement\n const { annotation } = this.editData\n\n // Todo: rectangle color based on segment index\n const settings = Settings.getObjectSettings(annotation, RectangleRoiTool)\n const toolMetadata = annotation.metadata\n const annotationUID = annotation.annotationUID\n\n const data = annotation.data\n const { points } = data.handles\n const canvasCoordinates = points.map((p) => viewport.worldToCanvas(p))\n const color = `rgb(${toolMetadata.segmentColor.slice(0, 3)})`\n\n // If rendering engine has been destroyed while rendering\n if (!viewport.getRenderingEngine()) {\n console.warn('Rendering Engine has been destroyed')\n return\n }\n\n const rectangleUID = '0'\n drawRectSvg(\n svgDrawingHelper,\n RectangleScissorsTool.toolName,\n annotationUID,\n rectangleUID,\n canvasCoordinates[0],\n canvasCoordinates[3],\n {\n color,\n }\n )\n }\n}\n","import { vec3 } from 'gl-matrix'\nimport type { Types } from '@cornerstonejs/core'\n\nimport {\n getCanvasEllipseCorners,\n pointInEllipse,\n} from '../../../utilities/math/ellipse'\nimport { getBoundingBoxAroundShape } from '../../../utilities/segmentation'\nimport transformPhysicalToIndex from '../../../utilities/transformPhysicalToIndex'\nimport { triggerSegmentationDataModified } from '../../../stateManagement/segmentation/triggerSegmentationEvents'\nimport { pointInShapeCallback } from '../../../utilities'\n\ntype OperationData = {\n toolGroupUID: string\n segmentationDataUID: string\n points: any // Todo:fix\n volume: Types.IImageVolume\n segmentIndex: number\n segmentsLocked: number[]\n viewPlaneNormal: number[]\n viewUp: number[]\n constraintFn: () => boolean\n}\n\nfunction fillCircle(\n enabledElement: Types.IEnabledElement,\n operationData: OperationData,\n inside = true\n): void {\n const {\n volume: segmentationVolume,\n points,\n segmentsLocked,\n segmentIndex,\n toolGroupUID,\n segmentationDataUID,\n } = operationData\n const { imageData, dimensions, scalarData } = segmentationVolume\n const { viewport } = enabledElement\n\n // Average the points to get the center of the ellipse\n const center = vec3.fromValues(0, 0, 0)\n points.forEach((point) => {\n vec3.add(center, center, point)\n })\n vec3.scale(center, center, 1 / points.length)\n\n const canvasCoordinates = points.map((p) => viewport.worldToCanvas(p))\n\n // 1. From the drawn tool: Get the ellipse (circle) topLeft and bottomRight\n // corners in canvas coordinates\n const [topLeftCanvas, bottomRightCanvas] =\n getCanvasEllipseCorners(canvasCoordinates)\n\n // 2. Find the extent of the ellipse (circle) in IJK index space of the image\n const topLeftWorld = viewport.canvasToWorld(topLeftCanvas)\n const bottomRightWorld = viewport.canvasToWorld(bottomRightCanvas)\n\n const ellipsoidCornersIJK = [\n <Types.Point3>transformPhysicalToIndex(imageData, topLeftWorld),\n <Types.Point3>transformPhysicalToIndex(imageData, bottomRightWorld),\n ]\n\n const boundsIJK = getBoundingBoxAroundShape(ellipsoidCornersIJK, dimensions)\n\n if (boundsIJK.every(([min, max]) => min !== max)) {\n throw new Error('Oblique segmentation tools are not supported yet')\n }\n\n // using circle as a form of ellipse\n const ellipseObj = {\n center: center as Types.Point3,\n xRadius: Math.abs(topLeftWorld[0] - bottomRightWorld[0]) / 2,\n yRadius: Math.abs(topLeftWorld[1] - bottomRightWorld[1]) / 2,\n zRadius: Math.abs(topLeftWorld[2] - bottomRightWorld[2]) / 2,\n }\n\n const callback = ({ value, index }) => {\n if (segmentsLocked.includes(value)) {\n return\n }\n scalarData[index] = segmentIndex\n }\n\n pointInShapeCallback(\n imageData,\n (pointLPS, pointIJK) => pointInEllipse(ellipseObj, pointLPS),\n callback,\n boundsIJK\n )\n\n triggerSegmentationDataModified(toolGroupUID, segmentationDataUID)\n}\n\n/**\n * Fill inside the circular region segment inside the segmentation defined by the operationData.\n * It fills the segmentation pixels inside the defined circle.\n * @param enabledElement - The element for which the segment is being erased.\n * @param operationData - EraseOperationData\n */\nexport function fillInsideCircle(\n enabledElement: Types.IEnabledElement,\n operationData: OperationData\n): void {\n fillCircle(enabledElement, operationData, true)\n}\n\n/**\n * Fill outside the circular region segment inside the segmentation defined by the operationData.\n * It fills the segmentation pixels outside the defined circle.\n * @param enabledElement - The element for which the segment is being erased.\n * @param operationData - EraseOperationData\n */\nexport function fillOutsideCircle(\n enabledElement: Types.IEnabledElement,\n operationData: OperationData\n): void {\n fillCircle(enabledElement, operationData, false)\n}\n","import {\n cache,\n getEnabledElement,\n StackViewport,\n} from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\n\nimport { BaseTool } from '../base'\nimport { PublicToolProps, ToolProps, EventTypes } from '../../types'\n\nimport { fillInsideCircle } from './strategies/fillCircle'\nimport { Events } from '../../enums'\nimport { drawCircle as drawCircleSvg } from '../../drawingSvg'\nimport {\n resetElementCursor,\n hideElementCursor,\n} from '../../cursors/elementCursor'\n\nimport triggerAnnotationRenderForViewportUIDs from '../../utilities/triggerAnnotationRenderForViewportUIDs'\nimport {\n segmentLocking,\n activeSegmentation,\n segmentIndex as segmentIndexController,\n segmentationColor,\n} from '../../stateManagement/segmentation'\n\n/**\n * Tool for manipulating segmentation data by drawing a circle. It acts on the\n * active Segmentation on the viewport (enabled element) and requires an active\n * segmentation to be already present. By default it will use the activeSegmentIndex\n * for the segmentation to modify. You can use SegmentationModule to set the active\n * segmentation and segmentIndex.\n */\nexport default class CircleScissorsTool extends BaseTool {\n static toolName = 'CircleScissor'\n editData: {\n annotation: any\n segmentation: any\n segmentIndex: number\n segmentationDataUID: string\n segmentsLocked: number[]\n segmentColor: [number, number, number, number]\n viewportUIDsToRender: string[]\n handleIndex?: number\n movingTextBox: boolean\n newAnnotation?: boolean\n hasMoved?: boolean\n centerCanvas?: Array<number>\n } | null\n isDrawing: boolean\n isHandleOutsideImage: boolean\n\n constructor(\n toolProps: PublicToolProps = {},\n defaultToolProps: ToolProps = {\n supportedInteractionTypes: ['Mouse', 'Touch'],\n configuration: {\n strategies: {\n FILL_INSIDE: fillInsideCircle,\n // ERASE_INSIDE: eraseInsideCircle,\n },\n defaultStrategy: 'FILL_INSIDE',\n activeStrategy: 'FILL_INSIDE',\n },\n }\n ) {\n super(toolProps, defaultToolProps)\n }\n\n /**\n * Based on the current position of the mouse and the enabledElement, it\n * finds the active segmentation info and use it for the current tool.\n *\n * @param evt - EventTypes.NormalizedMouseEventType\n * @returns The annotation object.\n *\n */\n addNewAnnotation = (evt: EventTypes.MouseDownActivateEventType) => {\n const eventDetail = evt.detail\n const { currentPoints, element } = eventDetail\n const worldPos = currentPoints.world\n const canvasPos = currentPoints.canvas\n\n const enabledElement = getEnabledElement(element)\n const { viewport, renderingEngine } = enabledElement\n\n this.isDrawing = true\n\n const camera = viewport.getCamera()\n const { viewPlaneNormal, viewUp } = camera\n const toolGroupUID = this.toolGroupUID\n\n const activeSegmentationInfo =\n activeSegmentation.getActiveSegmentationInfo(toolGroupUID)\n if (!activeSegmentationInfo) {\n throw new Error(\n 'No active segmentation detected, create one before using scissors tool'\n )\n }\n\n const { volumeUID, segmentationDataUID } = activeSegmentationInfo\n const segmentIndex =\n segmentIndexController.getActiveSegmentIndex(toolGroupUID)\n const segmentsLocked =\n segmentLocking.getSegmentsLockedForSegmentation(volumeUID)\n const segmentColor = segmentationColor.getColorForSegmentIndex(\n toolGroupUID,\n activeSegmentationInfo.segmentationDataUID,\n segmentIndex\n )\n\n const segmentation = cache.getVolume(volumeUID)\n\n // Todo: Used for drawing the svg only, we might not need it at all\n const annotation = {\n invalidated: true,\n highlighted: true,\n metadata: {\n viewPlaneNormal: <Types.Point3>[...viewPlaneNormal],\n viewUp: <Types.Point3>[...viewUp],\n FrameOfReferenceUID: viewport.getFrameOfReferenceUID(),\n referencedImageId: '',\n toolName: CircleScissorsTool.toolName,\n segmentColor,\n },\n data: {\n handles: {\n points: [[...worldPos], [...worldPos], [...worldPos], [...worldPos]],\n activeHandleIndex: null,\n },\n isDrawing: true,\n cachedStats: {},\n },\n }\n\n const viewportUIDsToRender = [viewport.uid]\n\n this.editData = {\n annotation,\n segmentation,\n centerCanvas: canvasPos,\n segmentIndex,\n segmentationDataUID,\n segmentsLocked,\n segmentColor,\n viewportUIDsToRender,\n handleIndex: 3,\n movingTextBox: false,\n newAnnotation: true,\n hasMoved: false,\n }\n\n this._activateDraw(element)\n\n hideElementCursor(element)\n\n evt.preventDefault()\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n }\n\n _mouseDragCallback = (evt: EventTypes.MouseDragEventType) => {\n this.isDrawing = true\n const eventDetail = evt.detail\n const { element } = eventDetail\n const { currentPoints } = eventDetail\n const currentCanvasPoints = currentPoints.canvas\n const enabledElement = getEnabledElement(element)\n const { renderingEngine, viewport } = enabledElement\n const { canvasToWorld } = viewport\n\n //////\n const { annotation, viewportUIDsToRender, centerCanvas } = this.editData\n const { data } = annotation\n\n // Center of circle in canvas Coordinates\n\n const dX = Math.abs(currentCanvasPoints[0] - centerCanvas[0])\n const dY = Math.abs(currentCanvasPoints[1] - centerCanvas[1])\n const radius = Math.sqrt(dX * dX + dY * dY)\n\n const bottomCanvas: Types.Point2 = [\n centerCanvas[0],\n centerCanvas[1] + radius,\n ]\n const topCanvas: Types.Point2 = [centerCanvas[0], centerCanvas[1] - radius]\n const leftCanvas: Types.Point2 = [centerCanvas[0] - radius, centerCanvas[1]]\n const rightCanvas: Types.Point2 = [\n centerCanvas[0] + radius,\n centerCanvas[1],\n ]\n\n data.handles.points = [\n canvasToWorld(bottomCanvas),\n canvasToWorld(topCanvas),\n canvasToWorld(leftCanvas),\n canvasToWorld(rightCanvas),\n ]\n\n annotation.invalidated = true\n\n this.editData.hasMoved = true\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n }\n\n _mouseUpCallback = (\n evt: EventTypes.MouseUpEventType | EventTypes.MouseClickEventType\n ) => {\n const eventDetail = evt.detail\n const { element } = eventDetail\n\n const {\n annotation,\n newAnnotation,\n hasMoved,\n segmentation,\n segmentIndex,\n segmentsLocked,\n segmentationDataUID,\n } = this.editData\n const { data } = annotation\n const { viewPlaneNormal, viewUp } = annotation.metadata\n\n if (newAnnotation && !hasMoved) {\n return\n }\n\n annotation.highlighted = false\n data.handles.activeHandleIndex = null\n\n this._deactivateDraw(element)\n\n resetElementCursor(element)\n\n const enabledElement = getEnabledElement(element)\n const { viewport } = enabledElement\n\n this.editData = null\n this.isDrawing = false\n\n if (viewport instanceof StackViewport) {\n throw new Error('Not implemented yet')\n }\n\n const operationData = {\n points: data.handles.points,\n volume: segmentation,\n segmentIndex,\n segmentsLocked,\n viewPlaneNormal,\n toolGroupUID: this.toolGroupUID,\n segmentationDataUID,\n viewUp,\n }\n\n this.applyActiveStrategy(enabledElement, operationData)\n }\n\n /**\n * Add event handlers for the modify event loop, and prevent default event propagation.\n */\n _activateDraw = (element) => {\n element.addEventListener(Events.MOUSE_UP, this._mouseUpCallback)\n element.addEventListener(Events.MOUSE_DRAG, this._mouseDragCallback)\n element.addEventListener(Events.MOUSE_CLICK, this._mouseUpCallback)\n\n // element.addEventListener(Events.TOUCH_END, this._mouseUpCallback)\n // element.addEventListener(Events.TOUCH_DRAG, this._mouseDragCallback)\n }\n\n /**\n * Add event handlers for the modify event loop, and prevent default event prapogation.\n */\n _deactivateDraw = (element) => {\n element.removeEventListener(Events.MOUSE_UP, this._mouseUpCallback)\n element.removeEventListener(Events.MOUSE_DRAG, this._mouseDragCallback)\n element.removeEventListener(Events.MOUSE_CLICK, this._mouseUpCallback)\n\n // element.removeEventListener(Events.TOUCH_END, this._mouseUpCallback)\n // element.removeEventListener(Events.TOUCH_DRAG, this._mouseDragCallback)\n }\n\n /**\n * it is used to draw the circleScissor annotation in each\n * request animation frame. Note that the annotation are disappeared\n * after the segmentation modification.\n *\n * @param enabledElement - The Cornerstone's enabledElement.\n * @param svgDrawingHelper - The svgDrawingHelper providing the context for drawing.\n */\n renderAnnotation = (\n enabledElement: Types.IEnabledElement,\n svgDrawingHelper: any\n ): void => {\n if (!this.editData) {\n return\n }\n\n const { viewport } = enabledElement\n const { viewportUIDsToRender } = this.editData\n\n if (!viewportUIDsToRender.includes(viewport.uid)) {\n return\n }\n\n const { annotation } = this.editData\n\n // Todo: rectangle color based on segment index\n const toolMetadata = annotation.metadata\n const annotationUID = annotation.annotationUID\n\n const data = annotation.data\n const { points } = data.handles\n const canvasCoordinates = points.map((p) => viewport.worldToCanvas(p))\n\n const bottom = canvasCoordinates[0]\n const top = canvasCoordinates[1]\n\n const center = [\n Math.floor((bottom[0] + top[0]) / 2),\n Math.floor((bottom[1] + top[1]) / 2),\n ]\n\n const radius = Math.abs(bottom[1] - Math.floor((bottom[1] + top[1]) / 2))\n\n const color = `rgb(${toolMetadata.segmentColor.slice(0, 3)})`\n\n // If rendering engine has been destroyed while rendering\n if (!viewport.getRenderingEngine()) {\n console.warn('Rendering Engine has been destroyed')\n return\n }\n\n const circleUID = '0'\n drawCircleSvg(\n svgDrawingHelper,\n CircleScissorsTool.toolName,\n annotationUID,\n circleUID,\n center as Types.Point2,\n radius,\n {\n color,\n }\n )\n }\n}\n","import type { Types } from '@cornerstonejs/core'\n\nimport { triggerSegmentationDataModified } from '../../../stateManagement/segmentation/triggerSegmentationEvents'\nimport { pointInSurroundingSphereCallback } from '../../../utilities'\n\ntype OperationData = {\n points: [Types.Point3, Types.Point3, Types.Point3, Types.Point3]\n volume: Types.IImageVolume\n toolGroupUID: string\n segmentIndex: number\n segmentationDataUID: string\n segmentsLocked: number[]\n viewPlaneNormal: Types.Point3\n viewUp: Types.Point3\n constraintFn: () => boolean\n}\n\nfunction fillSphere(\n enabledElement: Types.IEnabledElement,\n operationData: OperationData,\n _inside = true\n): void {\n const { viewport } = enabledElement\n const {\n volume: segmentation,\n segmentsLocked,\n segmentIndex,\n toolGroupUID,\n segmentationDataUID,\n points,\n } = operationData\n\n const { scalarData, imageData } = segmentation\n\n const callback = ({ index, value }) => {\n if (segmentsLocked.includes(value)) {\n return\n }\n scalarData[index] = segmentIndex\n }\n\n pointInSurroundingSphereCallback(\n viewport as Types.IVolumeViewport,\n imageData,\n [points[0], points[1]],\n callback\n )\n\n triggerSegmentationDataModified(toolGroupUID, segmentationDataUID)\n}\n\n/**\n * Fill inside a sphere with the given segment index in the given operation data. The\n * operation data contains the sphere required points.\n * @param enabledElement - The element that is enabled and selected.\n * @param operationData - OperationData\n */\nexport function fillInsideSphere(\n enabledElement: Types.IEnabledElement,\n operationData: OperationData\n): void {\n fillSphere(enabledElement, operationData, true)\n}\n\n/**\n * Fill outside a sphere with the given segment index in the given operation data. The\n * operation data contains the sphere required points.\n * @param enabledElement - The element that is enabled and selected.\n * @param operationData - OperationData\n */\nexport function fillOutsideSphere(\n enabledElement: Types.IEnabledElement,\n operationData: OperationData\n): void {\n fillSphere(enabledElement, operationData, false)\n}\n","import {\n cache,\n getEnabledElement,\n StackViewport,\n} from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\n\nimport { BaseTool } from '../base'\nimport { PublicToolProps, ToolProps, EventTypes } from '../../types'\n\nimport { fillInsideSphere } from './strategies/fillSphere'\nimport { Events } from '../../enums'\nimport { drawCircle as drawCircleSvg } from '../../drawingSvg'\nimport {\n resetElementCursor,\n hideElementCursor,\n} from '../../cursors/elementCursor'\n\nimport triggerAnnotationRenderForViewportUIDs from '../../utilities/triggerAnnotationRenderForViewportUIDs'\nimport {\n segmentationColor,\n segmentLocking,\n segmentIndex as segmentIndexController,\n activeSegmentation,\n} from '../../stateManagement/segmentation'\n\n/**\n * Tool for manipulating segmentation data by drawing a sphere in 3d space. It acts on the\n * active Segmentation on the viewport (enabled element) and requires an active\n * segmentation to be already present. By default it will use the activeSegmentIndex\n * for the segmentation to modify. You can use SegmentationModule to set the active\n * segmentation and segmentIndex. Todo: sphere scissor has some memory problem which\n * lead to ui blocking behavior that needs to be fixed.\n */\nexport default class SphereScissorsTool extends BaseTool {\n static toolName = 'SphereScissor'\n editData: {\n annotation: any\n segmentation: any\n segmentIndex: number\n segmentsLocked: number[]\n segmentationDataUID: string\n toolGroupUID: string\n segmentColor: [number, number, number, number]\n viewportUIDsToRender: string[]\n handleIndex?: number\n movingTextBox: boolean\n newAnnotation?: boolean\n hasMoved?: boolean\n centerCanvas?: Array<number>\n } | null\n isDrawing: boolean\n isHandleOutsideImage: boolean\n\n constructor(\n toolProps: PublicToolProps = {},\n defaultToolProps: ToolProps = {\n supportedInteractionTypes: ['Mouse', 'Touch'],\n configuration: {\n strategies: {\n FILL_INSIDE: fillInsideSphere,\n },\n defaultStrategy: 'FILL_INSIDE',\n activeStrategy: 'FILL_INSIDE',\n },\n }\n ) {\n super(toolProps, defaultToolProps)\n }\n\n /**\n * Based on the current position of the mouse and the enabledElement, it\n * finds the active segmentation info and use it for the current tool.\n *\n * @param evt - EventTypes.NormalizedMouseEventType\n * @returns The annotation object.\n *\n */\n addNewAnnotation = (evt: EventTypes.MouseDownActivateEventType) => {\n const eventDetail = evt.detail\n const { currentPoints, element } = eventDetail\n const worldPos = currentPoints.world\n const canvasPos = currentPoints.canvas\n\n const enabledElement = getEnabledElement(element)\n const { viewport, renderingEngine } = enabledElement\n\n this.isDrawing = true\n\n const camera = viewport.getCamera()\n const { viewPlaneNormal, viewUp } = camera\n const toolGroupUID = this.toolGroupUID\n\n const activeSegmentationInfo =\n activeSegmentation.getActiveSegmentationInfo(toolGroupUID)\n if (!activeSegmentationInfo) {\n throw new Error(\n 'No active segmentation detected, create one before using scissors tool'\n )\n }\n\n const { volumeUID, segmentationDataUID } = activeSegmentationInfo\n const segmentIndex =\n segmentIndexController.getActiveSegmentIndex(toolGroupUID)\n const segmentsLocked =\n segmentLocking.getSegmentsLockedForSegmentation(volumeUID)\n const segmentColor = segmentationColor.getColorForSegmentIndex(\n toolGroupUID,\n activeSegmentationInfo.segmentationDataUID,\n segmentIndex\n )\n\n const segmentation = cache.getVolume(volumeUID)\n this.isDrawing = true\n\n // Used for drawing the svg only, we might not need it at all\n const annotation = {\n metadata: {\n viewPlaneNormal: <Types.Point3>[...viewPlaneNormal],\n viewUp: <Types.Point3>[...viewUp],\n FrameOfReferenceUID: viewport.getFrameOfReferenceUID(),\n referencedImageId: '',\n toolName: SphereScissorsTool.toolName,\n segmentColor,\n },\n data: {\n invalidated: true,\n handles: {\n points: [[...worldPos], [...worldPos], [...worldPos], [...worldPos]],\n activeHandleIndex: null,\n },\n cachedStats: {},\n highlighted: true,\n },\n }\n\n const viewportUIDsToRender = [viewport.uid]\n\n this.editData = {\n annotation,\n segmentation,\n centerCanvas: canvasPos,\n segmentIndex,\n segmentsLocked,\n segmentColor,\n segmentationDataUID,\n toolGroupUID,\n viewportUIDsToRender,\n handleIndex: 3,\n movingTextBox: false,\n newAnnotation: true,\n hasMoved: false,\n }\n\n this._activateDraw(element)\n\n hideElementCursor(element)\n\n evt.preventDefault()\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n }\n\n _mouseDragCallback = (evt: EventTypes.MouseDragEventType) => {\n this.isDrawing = true\n const eventDetail = evt.detail\n const { element } = eventDetail\n const { currentPoints } = eventDetail\n const currentCanvasPoints = currentPoints.canvas\n const enabledElement = getEnabledElement(element)\n const { renderingEngine, viewport } = enabledElement\n const { canvasToWorld } = viewport\n\n //////\n const { annotation, viewportUIDsToRender, centerCanvas } = this.editData\n const { data } = annotation\n\n const dX = Math.abs(currentCanvasPoints[0] - centerCanvas[0])\n const dY = Math.abs(currentCanvasPoints[1] - centerCanvas[1])\n const radius = Math.sqrt(dX * dX + dY * dY)\n\n const bottomCanvas: Types.Point2 = [\n centerCanvas[0],\n centerCanvas[1] + radius,\n ]\n const topCanvas: Types.Point2 = [centerCanvas[0], centerCanvas[1] - radius]\n const leftCanvas: Types.Point2 = [centerCanvas[0] - radius, centerCanvas[1]]\n const rightCanvas: Types.Point2 = [\n centerCanvas[0] + radius,\n centerCanvas[1],\n ]\n\n data.handles.points = [\n canvasToWorld(bottomCanvas),\n canvasToWorld(topCanvas),\n canvasToWorld(leftCanvas),\n canvasToWorld(rightCanvas),\n ]\n\n annotation.invalidated = true\n\n this.editData.hasMoved = true\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n }\n\n _mouseUpCallback = (\n evt: EventTypes.MouseUpEventType | EventTypes.MouseClickEventType\n ) => {\n const eventDetail = evt.detail\n const { element } = eventDetail\n\n const {\n annotation,\n newAnnotation,\n hasMoved,\n segmentation,\n segmentIndex,\n segmentsLocked,\n segmentationDataUID,\n } = this.editData\n const { data } = annotation\n const { viewPlaneNormal, viewUp } = annotation.metadata\n\n if (newAnnotation && !hasMoved) {\n return\n }\n\n annotation.highlighted = false\n data.handles.activeHandleIndex = null\n\n this._deactivateDraw(element)\n\n resetElementCursor(element)\n\n const enabledElement = getEnabledElement(element)\n const { viewport } = enabledElement\n\n this.editData = null\n this.isDrawing = false\n\n if (viewport instanceof StackViewport) {\n throw new Error('Not implemented yet')\n }\n\n const operationData = {\n points: data.handles.points,\n volume: segmentation,\n segmentIndex,\n segmentsLocked,\n segmentationDataUID,\n toolGroupUID: this.toolGroupUID,\n viewPlaneNormal,\n viewUp,\n }\n\n this.applyActiveStrategy(enabledElement, operationData)\n }\n\n /**\n * Add event handlers for the modify event loop, and prevent default event propagation.\n */\n _activateDraw = (element) => {\n element.addEventListener(Events.MOUSE_UP, this._mouseUpCallback)\n element.addEventListener(Events.MOUSE_DRAG, this._mouseDragCallback)\n element.addEventListener(Events.MOUSE_CLICK, this._mouseUpCallback)\n\n // element.addEventListener(Events.TOUCH_END, this._mouseUpCallback)\n // element.addEventListener(Events.TOUCH_DRAG, this._mouseDragCallback)\n }\n\n /**\n * Add event handlers for the modify event loop, and prevent default event prapogation.\n */\n _deactivateDraw = (element) => {\n element.removeEventListener(Events.MOUSE_UP, this._mouseUpCallback)\n element.removeEventListener(Events.MOUSE_DRAG, this._mouseDragCallback)\n element.removeEventListener(Events.MOUSE_CLICK, this._mouseUpCallback)\n\n // element.removeEventListener(Events.TOUCH_END, this._mouseUpCallback)\n // element.removeEventListener(Events.TOUCH_DRAG, this._mouseDragCallback)\n }\n\n /**\n * it is used to draw the sphereScissor annotation in each\n * request animation frame. Note that the annotation are disappeared\n * after the segmentation modification.\n *\n * @param enabledElement - The Cornerstone's enabledElement.\n * @param svgDrawingHelper - The svgDrawingHelper providing the context for drawing.\n */\n renderAnnotation = (\n enabledElement: Types.IEnabledElement,\n svgDrawingHelper: any\n ): void => {\n if (!this.editData) {\n return\n }\n\n const { viewport } = enabledElement\n const { viewportUIDsToRender } = this.editData\n\n if (!viewportUIDsToRender.includes(viewport.uid)) {\n return\n }\n\n const { annotation } = this.editData\n\n // Todo: rectangle color based on segment index\n const toolMetadata = annotation.metadata\n const annotationUID = annotation.annotationUID\n\n const data = annotation.data\n const { points } = data.handles\n const canvasCoordinates = points.map((p) => viewport.worldToCanvas(p))\n\n const bottom = canvasCoordinates[0]\n const top = canvasCoordinates[1]\n\n const center = [\n Math.floor((bottom[0] + top[0]) / 2),\n Math.floor((bottom[1] + top[1]) / 2),\n ]\n\n const radius = Math.abs(bottom[1] - Math.floor((bottom[1] + top[1]) / 2))\n\n const color = `rgb(${toolMetadata.segmentColor.slice(0, 3)})`\n\n // If rendering engine has been destroyed while rendering\n if (!viewport.getRenderingEngine()) {\n console.warn('Rendering Engine has been destroyed')\n return\n }\n\n const circleUID = '0'\n drawCircleSvg(\n svgDrawingHelper,\n SphereScissorsTool.toolName,\n annotationUID,\n circleUID,\n center as Types.Point2,\n radius,\n {\n color,\n }\n )\n }\n}\n","import {\n getEnabledElement,\n cache,\n Settings,\n StackViewport,\n triggerEvent,\n eventTarget,\n utilities as csUtils,\n} from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\n\nimport { addAnnotation, getAnnotations } from '../../stateManagement'\nimport { isAnnotationLocked } from '../../stateManagement/annotation/annotationLocking'\nimport { Events } from '../../enums'\n\nimport {\n drawHandles as drawHandlesSvg,\n drawRect as drawRectSvg,\n} from '../../drawingSvg'\nimport { getViewportUIDsWithToolToRender } from '../../utilities/viewportFilters'\nimport { hideElementCursor } from '../../cursors/elementCursor'\nimport triggerAnnotationRenderForViewportUIDs from '../../utilities/triggerAnnotationRenderForViewportUIDs'\n\nimport { Annotation, PublicToolProps, ToolProps, EventTypes } from '../../types'\nimport { AnnotationModifiedEventDetail } from '../../types/EventTypes'\nimport RectangleRoiTool from '../annotation/RectangleRoiTool'\n\nexport interface RectangleRoiThresholdAnnotation extends Annotation {\n metadata: {\n cameraPosition?: Types.Point3\n cameraFocalPoint?: Types.Point3\n viewPlaneNormal?: Types.Point3\n viewUp?: Types.Point3\n annotationUID?: string\n FrameOfReferenceUID: string\n referencedImageId?: string\n toolName: string\n enabledElement: any // Todo: how to remove this from the annotation??\n volumeUID: string\n }\n data: {\n label: string\n handles: {\n points: Types.Point3[]\n activeHandleIndex: number | null\n }\n // segmentationUID: string\n }\n}\n\n/**\n * This tool is exactly the RectangleRoiTool but only draws a rectangle on the image,\n * and by using utility functions such as thresholdByRange and thresholdByRoiStat it can be used to\n * create a segmentation. This tool, however, does not calculate the statistics\n * as RectangleRoiTool does.\n */\nexport default class RectangleRoiThresholdTool extends RectangleRoiTool {\n static toolName = 'RectangleRoiThreshold'\n _throttledCalculateCachedStats: any\n editData: {\n annotation: any\n viewportUIDsToRender: string[]\n handleIndex?: number\n newAnnotation?: boolean\n hasMoved?: boolean\n } | null\n isDrawing: boolean\n isHandleOutsideImage: boolean\n\n constructor(\n toolProps: PublicToolProps = {},\n defaultToolProps: ToolProps = {\n supportedInteractionTypes: ['Mouse', 'Touch'],\n configuration: {\n shadow: true,\n preventHandleOutsideImage: false,\n },\n }\n ) {\n super(toolProps, defaultToolProps)\n }\n\n /**\n * Based on the current position of the mouse and the enabledElement it creates\n * the edit data for the tool.\n *\n * @param evt - EventTypes.NormalizedMouseEventType\n * @returns The annotation object.\n *\n */\n addNewAnnotation = (evt: EventTypes.MouseDownActivateEventType) => {\n const eventDetail = evt.detail\n const { currentPoints, element } = eventDetail\n const worldPos = currentPoints.world\n\n const enabledElement = getEnabledElement(element)\n const { viewport, renderingEngine } = enabledElement\n\n this.isDrawing = true\n\n const camera = viewport.getCamera()\n const { viewPlaneNormal, viewUp } = camera\n\n let referencedImageId, volumeUID\n if (viewport instanceof StackViewport) {\n referencedImageId =\n viewport.getCurrentImageId && viewport.getCurrentImageId()\n } else {\n volumeUID = this.getTargetUID(viewport)\n const imageVolume = cache.getVolume(volumeUID)\n referencedImageId = csUtils.getClosestImageId(\n imageVolume,\n worldPos,\n viewPlaneNormal,\n viewUp\n )\n }\n\n if (referencedImageId) {\n const colonIndex = referencedImageId.indexOf(':')\n referencedImageId = referencedImageId.substring(colonIndex + 1)\n }\n\n // Todo: how not to store enabledElement on the annotation, segmentationModule needs the element to\n // decide on the active segmentIndex, active segmentationIndex etc.\n const annotation = {\n highlighted: true,\n invalidated: true,\n metadata: {\n viewPlaneNormal: <Types.Point3>[...viewPlaneNormal],\n enabledElement,\n viewUp: <Types.Point3>[...viewUp],\n FrameOfReferenceUID: viewport.getFrameOfReferenceUID(),\n referencedImageId,\n toolName: RectangleRoiThresholdTool.toolName,\n volumeUID,\n },\n data: {\n label: '',\n handles: {\n // No need a textBox\n textBox: {\n hasMoved: false,\n worldPosition: null,\n worldBoundingBox: null,\n },\n points: [\n <Types.Point3>[...worldPos],\n <Types.Point3>[...worldPos],\n <Types.Point3>[...worldPos],\n <Types.Point3>[...worldPos],\n ],\n activeHandleIndex: null,\n },\n segmentationUID: null,\n },\n }\n\n // Ensure settings are initialized after annotation instantiation\n Settings.getObjectSettings(annotation, RectangleRoiThresholdTool)\n\n addAnnotation(element, annotation)\n\n const viewportUIDsToRender = getViewportUIDsWithToolToRender(\n element,\n RectangleRoiThresholdTool.toolName\n )\n\n this.editData = {\n annotation,\n viewportUIDsToRender,\n handleIndex: 3,\n newAnnotation: true,\n hasMoved: false,\n }\n this._activateDraw(element)\n\n hideElementCursor(element)\n\n evt.preventDefault()\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n\n return annotation\n }\n\n /**\n * it is used to draw the RectangleRoi Threshold annotation in each\n * request animation frame.\n *\n * @param enabledElement - The Cornerstone's enabledElement.\n * @param svgDrawingHelper - The svgDrawingHelper providing the context for drawing.\n */\n renderAnnotation = (\n enabledElement: Types.IEnabledElement,\n svgDrawingHelper: any\n ): void => {\n const { viewport, renderingEngineUID } = enabledElement\n const { element } = viewport\n let annotations = getAnnotations(\n element,\n RectangleRoiThresholdTool.toolName\n )\n\n if (!annotations?.length) {\n return\n }\n\n annotations = this.filterInteractableAnnotationsForElement(\n element,\n annotations\n )\n\n if (!annotations?.length) {\n return\n }\n\n for (let i = 0; i < annotations.length; i++) {\n const annotation = annotations[i] as RectangleRoiThresholdAnnotation\n const settings = Settings.getObjectSettings(\n annotation,\n RectangleRoiThresholdTool\n )\n const annotationUID = annotation.annotationUID\n\n const data = annotation.data\n const { points, activeHandleIndex } = data.handles\n const canvasCoordinates = points.map((p) => viewport.worldToCanvas(p))\n const lineWidth = this.getStyle(settings, 'lineWidth', annotation)\n const lineDash = this.getStyle(settings, 'lineDash', annotation)\n const color = this.getStyle(settings, 'color', annotation)\n\n // If rendering engine has been destroyed while rendering\n if (!viewport.getRenderingEngine()) {\n console.warn('Rendering Engine has been destroyed')\n return\n }\n\n // Todo: This is not correct way to add the event trigger,\n // this will trigger on all mouse hover too. Problem is that we don't\n // have a cached stats mechanism for this tool yet?\n const eventType = Events.ANNOTATION_MODIFIED\n\n const eventDetail: AnnotationModifiedEventDetail = {\n annotation,\n viewportUID: viewport.uid,\n renderingEngineUID,\n }\n\n triggerEvent(eventTarget, eventType, eventDetail)\n\n let activeHandleCanvasCoords\n\n if (\n !isAnnotationLocked(annotation) &&\n !this.editData &&\n activeHandleIndex !== null\n ) {\n // Not locked or creating and hovering over handle, so render handle.\n activeHandleCanvasCoords = [canvasCoordinates[activeHandleIndex]]\n }\n\n if (activeHandleCanvasCoords) {\n const handleGroupUID = '0'\n\n drawHandlesSvg(\n svgDrawingHelper,\n RectangleRoiThresholdTool.toolName,\n annotationUID,\n handleGroupUID,\n activeHandleCanvasCoords,\n {\n color,\n }\n )\n }\n\n const rectangleUID = '0'\n drawRectSvg(\n svgDrawingHelper,\n RectangleRoiThresholdTool.toolName,\n annotationUID,\n rectangleUID,\n canvasCoordinates[0],\n canvasCoordinates[3],\n {\n color,\n lineDash,\n lineWidth,\n }\n )\n }\n }\n}\n","import {\n getEnabledElement,\n cache,\n Settings,\n StackViewport,\n metaData,\n triggerEvent,\n eventTarget,\n utilities as csUtils,\n} from '@cornerstonejs/core'\nimport type { Types } from '@cornerstonejs/core'\n\nimport { vec3 } from 'gl-matrix'\nimport { Events } from '../../enums'\nimport { addAnnotation, getAnnotations } from '../../stateManagement'\nimport { isAnnotationLocked } from '../../stateManagement/annotation/annotationLocking'\nimport {\n drawHandles as drawHandlesSvg,\n drawRect as drawRectSvg,\n} from '../../drawingSvg'\nimport { getViewportUIDsWithToolToRender } from '../../utilities/viewportFilters'\nimport throttle from '../../utilities/throttle'\nimport { AnnotationModifiedEventDetail } from '../../types/EventTypes'\nimport { hideElementCursor } from '../../cursors/elementCursor'\nimport triggerAnnotationRenderForViewportUIDs from '../../utilities/triggerAnnotationRenderForViewportUIDs'\n\nimport { Annotation, PublicToolProps, ToolProps, EventTypes } from '../../types'\nimport RectangleRoiTool from '../annotation/RectangleRoiTool'\n\nexport interface RectangleRoiStartEndThresholdAnnotation extends Annotation {\n metadata: {\n cameraPosition?: Types.Point3\n cameraFocalPoint?: Types.Point3\n viewPlaneNormal?: Types.Point3\n viewUp?: Types.Point3\n annotationUID?: string\n FrameOfReferenceUID: string\n referencedImageId?: string\n toolName: string\n enabledElement: any // Todo: how to remove this from the annotation??\n volumeUID: string\n spacingInNormal: number\n }\n data: {\n label: string\n startSlice: number\n endSlice: number\n cachedStats: {\n projectionPoints: Types.Point3[][] // first slice p1, p2, p3, p4; second slice p1, p2, p3, p4 ...\n projectionPointsImageIds: string[]\n }\n handles: {\n points: Types.Point3[]\n activeHandleIndex: number | null\n }\n }\n}\n\n/**\n * This tool is similar to the RectangleRoiThresholdTool which\n * only draws a rectangle on the image, and by using utility functions\n * such as thresholdByRange and thresholdByRoiStat it can be used to\n * create a segmentation. The only difference is that it only acts on the\n * acquisition plane and not the 3D volume, and accepts a start and end\n * slice, and renders a dashed rectangle on the image between the start and end\n * but a solid rectangle on start and end slice. Utility functions should be used\n * to modify the start and end slice.\n * // Todo: right now only the first slice has grabbable handles, need to make\n * // it so that the handles are grabbable on all slices.\n */\nexport default class RectangleRoiStartEndThresholdTool extends RectangleRoiTool {\n static toolName = 'RectangleRoiStartEndThreshold'\n _throttledCalculateCachedStats: any\n editData: {\n annotation: any\n viewportUIDsToRender: string[]\n handleIndex?: number\n newAnnotation?: boolean\n hasMoved?: boolean\n } | null\n isDrawing: boolean\n isHandleOutsideImage: boolean\n\n constructor(\n toolProps: PublicToolProps = {},\n defaultToolProps: ToolProps = {\n configuration: {\n numSlicesToPropagate: 10,\n },\n }\n ) {\n super(toolProps, defaultToolProps)\n\n this._throttledCalculateCachedStats = throttle(\n this._calculateCachedStatsTool,\n 100,\n { trailing: true }\n )\n }\n\n /**\n * Based on the current position of the mouse and the enabledElement it creates\n * the edit data for the tool.\n *\n * @param evt - EventTypes.NormalizedMouseEventType\n * @returns The annotation object.\n *\n */\n addNewAnnotation = (evt: EventTypes.MouseDownActivateEventType) => {\n const eventDetail = evt.detail\n const { currentPoints, element } = eventDetail\n const worldPos = currentPoints.world\n\n const enabledElement = getEnabledElement(element)\n const { viewport, renderingEngine } = enabledElement\n\n this.isDrawing = true\n\n const camera = viewport.getCamera()\n const { viewPlaneNormal, viewUp } = camera\n\n let referencedImageId, imageVolume, volumeUID\n if (viewport instanceof StackViewport) {\n throw new Error('Stack Viewport Not implemented')\n } else {\n volumeUID = this.getTargetUID(viewport)\n imageVolume = cache.getVolume(volumeUID)\n referencedImageId = csUtils.getClosestImageId(\n imageVolume,\n worldPos,\n viewPlaneNormal,\n viewUp\n )\n }\n\n if (referencedImageId) {\n const colonIndex = referencedImageId.indexOf(':')\n referencedImageId = referencedImageId.substring(colonIndex + 1)\n } else {\n throw new Error('This tool does not work on non-acquisition planes')\n }\n\n const startIndex = viewport.getCurrentImageIdIndex()\n const spacingInNormal = csUtils.getSpacingInNormalDirection(\n imageVolume,\n viewPlaneNormal\n )\n\n // We cannot simply add numSlicesToPropagate to startIndex because\n // the order of imageIds can be from top to bottom or bottom to top and\n // we want to make sure it is always propagated in the direction of the\n // view and also to make sure we don't go out of bounds.\n const endIndex = this._getEndSliceIndex(\n imageVolume,\n worldPos,\n spacingInNormal,\n viewPlaneNormal\n )\n\n const annotation = {\n highlighted: true,\n invalidated: true,\n metadata: {\n viewPlaneNormal: <Types.Point3>[...viewPlaneNormal],\n enabledElement,\n viewUp: <Types.Point3>[...viewUp],\n FrameOfReferenceUID: viewport.getFrameOfReferenceUID(),\n referencedImageId,\n toolName: RectangleRoiStartEndThresholdTool.toolName,\n volumeUID,\n spacingInNormal,\n },\n data: {\n label: '',\n startSlice: startIndex,\n endSlice: endIndex,\n cachedStats: {\n projectionPoints: [],\n projectionPointsImageIds: [referencedImageId],\n },\n handles: {\n // No need a textBox\n textBox: {\n hasMoved: false,\n worldPosition: null,\n worldBoundingBox: null,\n },\n points: [\n <Types.Point3>[...worldPos],\n <Types.Point3>[...worldPos],\n <Types.Point3>[...worldPos],\n <Types.Point3>[...worldPos],\n ],\n activeHandleIndex: null,\n },\n labelmapUID: null,\n },\n }\n\n // update the projection points in 3D space, since we are projecting\n // the points to the slice plane, we need to make sure the points are\n // computed for later export\n this._computeProjectionPoints(annotation, imageVolume)\n\n // Ensure settings are initialized after annotation instantiation\n Settings.getObjectSettings(annotation, RectangleRoiStartEndThresholdTool)\n\n addAnnotation(element, annotation)\n\n const viewportUIDsToRender = getViewportUIDsWithToolToRender(\n element,\n RectangleRoiStartEndThresholdTool.toolName\n )\n\n this.editData = {\n annotation,\n viewportUIDsToRender,\n handleIndex: 3,\n newAnnotation: true,\n hasMoved: false,\n }\n this._activateDraw(element)\n\n hideElementCursor(element)\n\n evt.preventDefault()\n\n triggerAnnotationRenderForViewportUIDs(\n renderingEngine,\n viewportUIDsToRender\n )\n\n return annotation\n }\n\n // Todo: make it work for other acquisition planes\n _computeProjectionPoints(\n annotation: RectangleRoiStartEndThresholdAnnotation,\n imageVolume: Types.IImageVolume\n ): void {\n const { data, metadata } = annotation\n const { viewPlaneNormal, spacingInNormal } = metadata\n const { imageData } = imageVolume\n const { startSlice, endSlice } = data\n const { projectionPoints } = data.cachedStats\n const { points } = data.handles\n\n const startIJK = vec3.create()\n imageData.worldToIndexVec3(points[0], startIJK)\n\n if (startIJK[2] !== startSlice) {\n throw new Error('Start slice does not match')\n }\n\n // subtitute the end slice index 2 with startIJK index 2\n const endIJK = vec3.fromValues(startIJK[0], startIJK[1], endSlice)\n\n const startWorld = vec3.create()\n imageData.indexToWorldVec3(startIJK, startWorld)\n\n const endWorld = vec3.create()\n imageData.indexToWorldVec3(endIJK, endWorld)\n\n // distance between start and end slice in the world coordinate\n const distance = vec3.distance(startWorld, endWorld)\n\n // for each point inside points, navigate in the direction of the viewPlaneNormal\n // with amount of spacingInNormal, and calculate the next slice until we reach the distance\n const newProjectionPoints = []\n for (let dist = 0; dist < distance; dist += spacingInNormal) {\n newProjectionPoints.push(\n points.map((point) => {\n const newPoint = vec3.create()\n vec3.scaleAndAdd(newPoint, point, viewPlaneNormal, dist)\n return Array.from(newPoint)\n })\n )\n }\n\n data.cachedStats.projectionPoints = newProjectionPoints\n\n // Find the imageIds for the projection points\n const projectionPointsImageIds = []\n for (const RectanglePoints of newProjectionPoints) {\n const imageId = csUtils.getClosestImageId(\n imageVolume,\n RectanglePoints[0],\n viewPlaneNormal,\n metadata.viewUp\n )\n projectionPointsImageIds.push(imageId)\n }\n\n data.cachedStats.projectionPointsImageIds = projectionPointsImageIds\n }\n\n _calculateCachedStatsTool(annotation, enabledElement) {\n const data = annotation.data\n const { viewportUID, renderingEngineUID, viewport } = enabledElement\n\n const { cachedStats } = data\n const volumeUID = this.getTargetUID(viewport)\n const imageVolume = cache.getVolume(volumeUID)\n\n // Todo: this shouldn't be here, this is a performance issue\n // Since we are extending the RectangleRoi class, we need to\n // bring the logic for handle to some cachedStats calculation\n this._computeProjectionPoints(annotation, imageVolume)\n\n annotation.invalidated = false\n\n // Dispatching annotation modified\n const eventType = Events.ANNOTATION_MODIFIED\n\n const eventDetail: AnnotationModifiedEventDetail = {\n annotation,\n viewportUID,\n renderingEngineUID,\n }\n triggerEvent(eventTarget, eventType, eventDetail)\n\n return cachedStats\n }\n\n /**\n * it is used to draw the rectangleRoiStartEnd annotation in each\n * request animation frame.\n *\n * @param enabledElement - The Cornerstone's enabledElement.\n * @param svgDrawingHelper - The svgDrawingHelper providing the context for drawing.\n */\n renderAnnotation = (\n enabledElement: Types.IEnabledElement,\n svgDrawingHelper: any\n ): void => {\n const annotations = getAnnotations(\n enabledElement.viewport.element,\n RectangleRoiStartEndThresholdTool.toolName\n )\n\n if (!annotations?.length) {\n return\n }\n\n // annotations = this.filterInteractableAnnotationsForElement(element, annotations)\n\n // if (!annotations?.length) {\n // return\n // }\n\n const { viewport } = enabledElement\n const sliceIndex = viewport.getCurrentImageIdIndex()\n\n for (let i = 0; i < annotations.length; i++) {\n const annotation = annotations[\n i\n ] as RectangleRoiStartEndThresholdAnnotation\n const settings = Settings.getObjectSettings(\n annotation,\n RectangleRoiStartEndThresholdTool\n )\n const annotationUID = annotation.annotationUID\n\n const data = annotation.data\n const { startSlice, endSlice } = data\n const { points, activeHandleIndex } = data.handles\n\n const canvasCoordinates = points.map((p) => viewport.worldToCanvas(p))\n const lineWidth = this.getStyle(settings, 'lineWidth', annotation)\n const lineDash = this.getStyle(settings, 'lineDash', annotation)\n const color = this.getStyle(settings, 'color', annotation)\n\n // range of slices to render based on the start and end slice, like\n // np.arange\n\n // if indexIJK is outside the start/end slice, we don't render\n if (\n sliceIndex < Math.min(startSlice, endSlice) ||\n sliceIndex > Math.max(startSlice, endSlice)\n ) {\n continue\n }\n\n // WE HAVE TO CACHE STATS BEFORE FETCHING TEXT\n\n if (annotation.invalidated) {\n this._throttledCalculateCachedStats(annotation, enabledElement)\n }\n\n // if it is inside the start/end slice, but not exactly the first or\n // last slice, we render the line in dash, but not the handles\n let firstOrLastSlice = false\n if (sliceIndex === startSlice || sliceIndex === endSlice) {\n firstOrLastSlice = true\n }\n\n // If rendering engine has been destroyed while rendering\n if (!viewport.getRenderingEngine()) {\n console.warn('Rendering Engine has been destroyed')\n return\n }\n\n let activeHandleCanvasCoords\n\n if (\n !isAnnotationLocked(annotation) &&\n !this.editData &&\n activeHandleIndex !== null &&\n firstOrLastSlice\n ) {\n // Not locked or creating and hovering over handle, so render handle.\n activeHandleCanvasCoords = [canvasCoordinates[activeHandleIndex]]\n }\n\n if (activeHandleCanvasCoords) {\n const handleGroupUID = '0'\n\n drawHandlesSvg(\n svgDrawingHelper,\n RectangleRoiStartEndThresholdTool.toolName,\n annotationUID,\n handleGroupUID,\n activeHandleCanvasCoords,\n {\n color,\n }\n )\n }\n\n let lineDashToUse = lineDash\n\n if (!firstOrLastSlice) {\n lineDashToUse = 2\n }\n\n const rectangleUID = '0'\n drawRectSvg(\n svgDrawingHelper,\n RectangleRoiStartEndThresholdTool.toolName,\n annotationUID,\n rectangleUID,\n canvasCoordinates[0],\n canvasCoordinates[3],\n {\n color,\n lineDash: lineDashToUse,\n lineWidth,\n }\n )\n }\n }\n\n _getEndSliceIndex(\n imageVolume: Types.IImageVolume,\n worldPos: Types.Point3,\n spacingInNormal: number,\n viewPlaneNormal: Types.Point3\n ): number | undefined {\n const numSlicesToPropagate = this.configuration.numSlicesToPropagate\n\n // get end position by moving from worldPos in the direction of viewplaneNormal\n // with amount of numSlicesToPropagate * spacingInNormal\n const endPos = vec3.create()\n vec3.scaleAndAdd(\n endPos,\n worldPos,\n viewPlaneNormal,\n numSlicesToPropagate * spacingInNormal\n )\n\n const halfSpacingInNormalDirection = spacingInNormal / 2\n // Loop through imageIds of the imageVolume and find the one that is closest to endPos\n const { imageIds } = imageVolume\n let imageIdIndex\n for (let i = 0; i < imageIds.length; i++) {\n const imageId = imageIds[i]\n\n const { imagePositionPatient } = metaData.get('imagePlaneModule', imageId)\n\n const dir = vec3.create()\n vec3.sub(dir, endPos, imagePositionPatient)\n\n const dot = vec3.dot(dir, viewPlaneNormal)\n\n if (Math.abs(dot) < halfSpacingInNormalDirection) {\n imageIdIndex = i\n }\n }\n\n return imageIdIndex\n }\n}\n","import { init, destroy } from './init'\nimport {\n addTool,\n removeTool,\n ToolGroupManager,\n SynchronizerManager,\n Synchronizer,\n cancelActiveManipulations,\n} from './store'\n\n// Name spaces\nimport * as synchronizers from './synchronizers'\nimport * as drawing from './drawingSvg'\nimport * as utilities from './utilities'\nimport * as cursors from './cursors'\nimport * as Types from './types'\nimport * as annotation from './stateManagement/annotation'\nimport * as segmentation from './stateManagement/segmentation'\n\nimport {\n BaseTool,\n AnnotationTool,\n PanTool,\n WindowLevelTool,\n ZoomTool,\n StackScrollTool,\n StackScrollMouseWheelTool,\n VolumeRotateMouseWheelTool,\n MIPJumpToClickTool,\n LengthTool,\n ProbeTool,\n RectangleRoiTool,\n EllipticalRoiTool,\n BidirectionalTool,\n CrosshairsTool,\n RectangleScissorsTool,\n CircleScissorsTool,\n SphereScissorsTool,\n RectangleRoiThresholdTool,\n RectangleRoiStartEndThresholdTool,\n SegmentationDisplayTool,\n} from './tools'\n\nimport {\n MouseBindings,\n KeyboardBindings,\n ToolModes,\n Events,\n SegmentationRepresentations,\n} from './enums'\n\nconst Enums = {\n MouseBindings,\n KeyboardBindings,\n ToolModes,\n Events,\n SegmentationRepresentations,\n}\n\nexport {\n //\n init,\n destroy,\n addTool,\n removeTool,\n cancelActiveManipulations,\n // Base Tools\n BaseTool,\n AnnotationTool,\n // Manipulation Tools\n PanTool,\n WindowLevelTool,\n ZoomTool,\n StackScrollTool,\n StackScrollMouseWheelTool,\n VolumeRotateMouseWheelTool,\n MIPJumpToClickTool,\n // Annotation Tools\n LengthTool,\n CrosshairsTool,\n ProbeTool,\n RectangleRoiTool,\n EllipticalRoiTool,\n BidirectionalTool,\n // Segmentation Display\n SegmentationDisplayTool,\n // Segmentation Editing Tools\n RectangleScissorsTool,\n CircleScissorsTool,\n SphereScissorsTool,\n RectangleRoiThresholdTool,\n RectangleRoiStartEndThresholdTool,\n // Synchronizers\n synchronizers,\n Synchronizer,\n SynchronizerManager,\n Types,\n // ToolGroups\n ToolGroupManager,\n // Enums\n Enums,\n // Drawing API\n drawing,\n // Annotation\n annotation,\n // Segmentations\n segmentation,\n // Utilities\n utilities,\n cursors,\n}\n"],"names":["root","factory","exports","module","require","define","amd","self","__WEBPACK_EXTERNAL_MODULE__571__","__WEBPACK_EXTERNAL_MODULE__976__","__WEBPACK_EXTERNAL_MODULE__103__","__WEBPACK_EXTERNAL_MODULE__634__","__WEBPACK_EXTERNAL_MODULE__4__","__WEBPACK_EXTERNAL_MODULE__611__","HASH_UNDEFINED","MAX_SAFE_INTEGER","argsTag","boolTag","dateTag","funcTag","genTag","mapTag","numberTag","objectTag","promiseTag","regexpTag","setTag","stringTag","symbolTag","weakMapTag","arrayBufferTag","dataViewTag","float32Tag","float64Tag","int8Tag","int16Tag","int32Tag","uint8Tag","uint8ClampedTag","uint16Tag","uint32Tag","reFlags","reIsHostCtor","reIsUint","cloneableTags","freeGlobal","g","Object","freeSelf","Function","freeExports","nodeType","freeModule","moduleExports","addMapEntry","map","pair","set","addSetEntry","value","add","arrayReduce","array","iteratee","accumulator","initAccum","index","length","isHostObject","result","toString","e","mapToArray","Array","size","forEach","key","overArg","func","transform","arg","setToArray","uid","arrayProto","prototype","funcProto","objectProto","coreJsData","maskSrcKey","exec","keys","IE_PROTO","funcToString","hasOwnProperty","objectToString","reIsNative","RegExp","call","replace","Buffer","undefined","Symbol","Uint8Array","getPrototype","getPrototypeOf","objectCreate","create","propertyIsEnumerable","splice","nativeGetSymbols","getOwnPropertySymbols","nativeIsBuffer","isBuffer","nativeKeys","DataView","getNative","Map","Promise","Set","WeakMap","nativeCreate","dataViewCtorString","toSource","mapCtorString","promiseCtorString","setCtorString","weakMapCtorString","symbolProto","symbolValueOf","valueOf","Hash","entries","this","clear","entry","ListCache","MapCache","Stack","__data__","assignValue","object","objValue","eq","assocIndexOf","baseClone","isDeep","isFull","customizer","stack","isObject","isArr","isArray","constructor","input","initCloneArray","source","copyArray","tag","getTag","isFunc","buffer","slice","copy","cloneBuffer","isPrototype","proto","initCloneObject","copyObject","getSymbols","copySymbols","baseAssign","cloneFunc","symbol","Ctor","cloneArrayBuffer","dataView","byteOffset","byteLength","cloneDataView","typedArray","cloneTypedArray","cloneMap","regexp","lastIndex","cloneRegExp","cloneSet","initCloneByTag","stacked","get","props","keysFunc","symbolsFunc","values","offset","arrayPush","baseGetAllKeys","getAllKeys","arrayEach","subValue","arrayBuffer","newValue","getMapData","type","data","getValue","isFunction","test","baseIsNative","has","pop","push","cache","pairs","LARGE_ARRAY_SIZE","isIndex","other","ArrayBuffer","resolve","ctorString","isArrayLike","isLength","inherited","isObjectLike","isArrayLikeObject","isArguments","n","baseTimes","String","skipIndexes","arrayLikeKeys","baseKeys","runtime","Op","hasOwn","$Symbol","iteratorSymbol","iterator","asyncIteratorSymbol","asyncIterator","toStringTagSymbol","toStringTag","obj","defineProperty","enumerable","configurable","writable","err","wrap","innerFn","outerFn","tryLocsList","protoGenerator","Generator","generator","context","Context","_invoke","state","GenStateSuspendedStart","method","GenStateExecuting","Error","GenStateCompleted","doneResult","delegate","delegateResult","maybeInvokeDelegate","ContinueSentinel","sent","_sent","dispatchException","abrupt","record","tryCatch","done","GenStateSuspendedYield","makeInvokeMethod","fn","GeneratorFunction","GeneratorFunctionPrototype","IteratorPrototype","getProto","NativeIteratorPrototype","Gp","defineIteratorMethods","AsyncIterator","PromiseImpl","invoke","reject","__await","then","unwrapped","error","previousPromise","callInvokeWithMethodAndArg","TypeError","info","resultName","next","nextLoc","pushTryEntry","locs","tryLoc","catchLoc","finallyLoc","afterLoc","tryEntries","resetTryEntry","completion","reset","iterable","iteratorMethod","isNaN","i","displayName","isGeneratorFunction","genFun","ctor","name","mark","setPrototypeOf","__proto__","awrap","async","iter","reverse","skipTempReset","prev","charAt","stop","rootRecord","rval","exception","handle","loc","caught","hasCatch","hasFinally","finallyEntry","complete","finish","thrown","delegateYield","regeneratorRuntime","accidentalStrictMode","globalThis","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","id","loaded","__webpack_modules__","getter","__esModule","d","a","definition","o","window","prop","r","nmd","paths","children","MouseBindings","KeyboardBindings","ToolModes","AnnotationStyleStates","Events","SegmentationRepresentations","_classCallCheck","instance","Constructor","_defineProperties","target","descriptor","_createClass","protoProps","staticProps","_defineProperty","globalLockedAnnotationsSet","setAnnotationLocked","annotation","locked","detail","makeEventDetail","lock","unlock","publish","unlockAllAnnotations","lockedAnnotationsSet","clearLockedAnnotationsSet","getAnnotationsLocked","from","isAnnotationLocked","getAnnotationsLockedCount","checkAndDefineIsLockedProperty","isLocked","getOwnPropertyDescriptor","setIsLocked","getIsLocked","isExtensible","shouldDefineIsLockedProperty","freeze","added","removed","delete","item","triggerEvent","eventTarget","FrameOfReferenceSpecificAnnotationManager","evt","FrameOfReferenceUID","frameOfReferenceSpecificAnnotations","annotations","toolName","invalidated","annotationUID","filter","toolSpecificAnnotationsAndIndex","_getToolSpecificAnnotationsAndIndex","toolSpecificAnnotations","metadata","cloneDeep","utilities","Enums","_imageVolumeModifiedHandler","frameOfReferenceUIDKeys","numFrameOfReferenceUIDKeys","toolNameKeys","numToolNameKeys","j","findIndex","defaultFrameOfReferenceSpecificAnnotationManager","getDefaultAnnotationManager","getViewportSpecificAnnotationManager","element","getAnnotations","enabledElement","getEnabledElement","annotationManager","addAnnotation","csUtils","renderingEngine","viewportUID","eventType","eventDetail","renderingEngineUID","removeAnnotation","getAnnotation","initialDefaultState","colorLutTables","global","segmentations","config","renderInactiveSegmentations","representations","toolGroups","SegmentationStateManager","lutIndex","segmentationUID","find","segmentationState","volumeUID","toolGroupUIDs","foundToolGroupUIDs","toolGroupUID","getSegmentationState","segmentationData","toolGroupStateWithConfig","segmentationDataUID","segData","active","colorLut","console","log","_initDefaultColorLutIfNecessary","existingGlobalSegmentationData","getGlobalSegmentationData","updatedState","label","referenceVolumeUID","cachedStats","referenceImageId","activeSegmentIndex","segmentsLocked","_handleActiveSegmentation","toolGroupSegmentations","warn","removedSegmentationData","recentlyAddedOrRemovedSegmentationData","addColorLUT","CORNERSTONE_COLOR_LUT","defaultSegmentationStateManager","triggerSegmentationStateModified","triggerSegmentationGlobalStateModified","segmentationUIDs","getToolGroupsWithSegmentation","getToolGroups","getGlobalSegmentationState","triggerSegmentationDataModified","_arrayLikeToArray","arr","len","arr2","_unsupportedIterableToArray","minLen","_slicedToArray","_i","_s","_e","_arr","_n","_d","getBoundingBoxAroundShape","vertices","dimensions","xMin","Infinity","xMax","yMin","yMax","zMin","zMax","v","Math","min","max","floor","width","height","depth","extend2DBoundingBoxInViewAxis","boundsIJK","numSlicesToProject","sliceNormalIndex","_toConsumableArray","svgNodeCache","defaultState","isInteractingWithTool","isMultiPartToolActive","tools","synchronizers","enabledElements","handleRadius","addTool","ToolClass","toolAlreadyAdded","toolClass","removeTool","getMouseEventPoints","elementToUse","currentTarget","viewport","clientPoint","clientX","clientY","_clientToPoint","pagePoint","pageX","pageY","_pageToPoint","canvasPoint","rect","getBoundingClientRect","left","pageXOffset","top","pageYOffset","_pagePointsToCanvasPoints","page","client","canvas","world","canvasToWorld","startPoints","event","eventName","camera","lastPoints","currentPoints","deltaPoints","MOUSE_DOWN","MOUSE_DOWN_ACTIVATE","MOUSE_CLICK","MOUSE_UP","MOUSE_DRAG","mouseButton","isClickEvent","clickDelay","preventClickTimeout","_onMouseDrag","_updateMouseEventsLastPoints","_getDeltaPoints","_copyPoints","_onMouseUp","clearTimeout","document","removeEventListener","addEventListener","mouseMoveListener","JSON","parse","stringify","_preventClickHandler","points","_subtractPoints2D","point0","point1","button","setTimeout","disable","mouseDoubleClickListener","mouseDownListener","enable","deltaY","preventDefault","spinX","spinY","pixelX","pixelY","wheelDelta","wheelDeltaY","wheelDeltaX","deltaX","deltaMode","normalizeWheel","direction","wheel","wheelListener","passive","keyCode","keyListener","_onKeyUp","_cloneDeep","keyDownListener","getModifierKey","_assertThisInitialized","ReferenceError","_setPrototypeOf","p","_inherits","subClass","superClass","_typeof","_possibleConstructorReturn","_getPrototypeOf","isMergeableObject","val","cloneIfNecessary","optionsArgument","clone","deepmerge","defaultArrayMerge","destination","indexOf","mergeObject","options","arrayMerge","BaseTool","toolProps","defaultToolProps","initialProps","deepMerge","configuration","supportedInteractionTypes","strategies","defaultStrategy","activeStrategy","strategyOptions","assign","mode","operationData","newConfiguration","strategyName","setConfiguration","VolumeViewport","actors","getActors","targetUID","image","startsWith","coloneIndex","substring","getViewport","getImageData","StackViewport","getTargetVolumeUID","getSvgNode","canvasHash","cacheKey","domRef","appendNode","svgLayerElement","svgNode","touched","appendChild","setNodeTouched","clearUntouched","cacheEntry","removeChild","svgDrawingHelper","firstChild","querySelector","_getSvgLayer","_element","_svgLayerElement","_svgNodeCacheForCanvas","_getSvgNode","bind","_appendNode","_setNodeTouched","_clearUntouched","getSvgDrawingHelper","drawingElementType","nodeUID","attributes","currentValue","getAttribute","removeAttribute","setAttribute","circleUID","center","radius","color","fill","lineWidth","strokeWidth","svgns","svgNodeHash","_getHash","existingCircleElement","cx","cy","stroke","_setAttributesIfNecessary","newCircleElement","createElementNS","_setNewAttributesIfValid","ellipseUID","corner1","corner2","lineDash","existingEllipse","w","abs","h","radiusX","radiusY","rx","ry","svgEllipseElement","handleGroupUID","handlePoints","handleRadiusFloat","parseFloat","side","x","y","existingHandleElement","newHandleElement","drawLine","lineUID","start","end","existingLine","x1","y1","x2","y2","newLine","_drawTextGroup","textUID","textLines","position","textGroupBoundingBox","padding","fontFamily","fontSize","background","existingTextGroup","textElement","textSpans","textSpanElement","text","textContent","textAttributes","textGroupAttributes","_drawTextBackground","textGroup","combinedStyle","_createTextElement","textSpan","_createTextSpan","group","getBBox","insertBefore","bBox","mergedOptions","centerX","centerY","findClosestPoint","sourcePoints","targetPoint","minPoint","minDistance","Number","sourcePoint","p2","distance","sqrt","pow","_boundingBoxPoints","boundingBox","halfWidth","halfHeight","linkUID","annotationAnchorPoints","refPoint","boundingBoxPoints","textBoxUID","textBoxPosition","textBox","centering","canvasBoundingBox","drawTextBox","drawLink","drawRect","rectangleUID","_width","existingRect","tlhc","svgRectElement","draw","drawCircle","drawEllipse","drawHandles","drawLinkedTextBox","getToolsWithModesForElement","modesFilter","toolGroup","ToolGroupManager","enabledTools","toolGroupToolNames","toolOptions","includes","toolInstance","getToolInstance","modes","states","defaultSettings","Active","Passive","Enabled","AnnotationRenderingEngine","_throwIfDestroyed","elements","_viewportElements","_needsRender","_triggerRender","_animationFrameSet","_animationFrameHandle","_reset","_setViewportsToBeRenderedNextFrame","hasBeenDestroyed","_render","requestAnimationFrame","_renderFlaggedViewports","getRenderingEngine","drawSvg","tool","SegmentationDisplayTool","renderAnnotation","cancelAnimationFrame","annotationRenderingEngine","renderViewport","filterAnnotationsWithinSlice","spacingInNormalDirection","viewPlaneNormal","annotationsWithSameNormal","td","annotationViewPlaneNormal","halfSpacingInNormalDirection","focalPoint","annotationsWithinSlice","point","handles","dir","vec3","dot","filterAnnotationsForDisplay","imageId","getCurrentImageId","colonIndex","imageURI","referencedImageId","getCamera","getStyleProperty","settings","property","alternatives","list","getStyleAlternatives","style","getDefaultStyleProperty","Settings","colorHighlighted","colorSelected","colorLocked","link","nameEndsWith","string","endsWith","some","selectedAnnotations","setAnnotationSelected","selected","preserveSelected","selectAnnotation","deselectAnnotation","clearSelectionSet","getAnnotationsSelected","getAnnotationSelected","getAnnotationsSelectedByToolName","isAnnotationSelected","getAnnotationsSelectedCount","selection","selectionSet","highlighted","getStyle","sty","setGlobalStyle","setToolStyle","AnnotationTool","filteredAnnotations","canvasCoords","annotationsNeedToBeRedrawn","activateHandleIndex","activeHandleIndex","near","_imagePointNearToolOrHandle","nearToolAndNotMarkedActive","notNearToolAndMarkedActive","rowScale","columnScale","calibratedImageData","imageData","noneCalibratedWorldToIndex","worldToIndex","calibratedIndexToWorld","getIndexToWorld","stateManager","getFramesOfReference","frameOfReference","getFrameOfReferenceAnnotations","getToolName","vec4","pCalibrated","nonCalibratedIndexVec4","calibratedIndex","triggerAnnotationRender","proximity","worldBoundingBox","topLeft","worldToCanvas","topRight","bottomLeft","bottomRight","annotationCanvasCoordinate","vec2","getState","getHandleNearImagePoint","isPointNearTool","asyncGeneratorStep","gen","_next","_throw","_asyncToGenerator","args","arguments","apply","segmentationDataArray","representation","addVolumesToViewports","actorUID","visibility","internalAddSegmentationToElement","removeVolumeActors","MAX_NUMBER_COLORS","labelMapConfigCache","toolGroupSpecificConfig","_addLabelmapToToolGroupViewports","segmentsHidden","colorLUTIndex","cfun","vtkColorTransferFunction","ofun","vtkPiecewiseFunction","mergedSegmentationData","Representations","currentToolGroupConfig","SegmentationState","mergedConfig","_needsTransferFunctionUpdateUpdate","fillAlpha","cacheUID","getToolGroupByToolGroupUID","viewportsInfo","viewportInfo","getEnabledElementByUIDs","render","labelmapUID","labelmapRepresentation","actor","getActor","labelmapConfig","isActiveLabelmap","addPoint","fillAlphaInactive","outlineWidth","outlineWidthActive","outlineWidthInactive","colorLUT","numColors","volumeActor","addRGBPoint","segmentOpacity","setClamping","getProperty","setRGBTransferFunction","setScalarOpacity","setInterpolationTypeToNearest","setUseLabelOutline","renderOutline","setLabelOutlineThickness","visible","setVisibility","_setLabelmapColorAndOpacity","addSegmentationData","removeSegmentationData","internalRemoveSegmentationFromElement","_removeLabelmapFromToolGroupViewports","defaultLabelmapConfig","renderFill","checkSegmentationDataIsValid","promises","_addSegmentation","all","representationType","LabelmapDisplay","addSegmentationsForToolGroup","segmentationDataUIDs","toolGroupSegmentationDataUIDs","segmentationDataUIDsToRemove","invalidSegmentationDataUIDs","getSegmentationDataByUID","_removeSegmentation","getDefaultActor","properties","volumeLoader","createNewSegmentationForToolGroup","getActiveSegmentationInfo","activeSegmentationData","getActiveSegmentationData","globalState","getGlobalSegmentationDataByUID","setActiveSegmentation","setActiveSegmentationData","getSegmentIndexLocked","segmentIndex","activeSegmentationInfo","setSegmentIndexLocked","segmentationGlobalState","getSegmentIndexLockedForSegmentation","setSegmentIndexLockedForSegmentation","getSegmentsLockedForSegmentation","unshift","getColorForSegmentIndex","getGlobalSegmentationConfig","setGlobalSegmentationConfig","segmentationConfig","getGlobalRepresentationConfig","setGlobalRepresentationConfig","globalConfig","updateGlobalRepresentationConfig","updateGlobalSegmentationConfig","getSegmentationConfig","setSegmentationConfig","setRepresentationConfig","representationConfig","getRepresentationConfig","setSegmentationVisibility","getSegmentationVisibility","getActiveSegmentIndex","segmentationInfo","activeSegmentationGlobalState","setActiveSegmentIndex","setActiveSegmentIndexForSegmentation","getActiveSegmentIndexForSegmentation","toolGroupSegmentationState","toolGroupViewports","_getSegmentationConfig","toolGroupConfig","SegmentationRenderingEngine","_setToolGroupSegmentationToBeRenderedNextFrame","_renderFlaggedToolGroups","viewports","segmentationDisplayToolInstance","onSegmentationRender","renderSegmentation","getToolGroup","csToolsEvents","segmentationRenderingEngine","renderToolGroupSegmentations","triggerSegmentationRender","segmentation","vtkOpenGLTexture","numSlices","getDimensions","setUpdatedFrame","modified","getRenderingEngines","viewportUIDs","getViewports","vp","triggerAnnotationRenderForViewportUIDs","viewportUIDsToRender","onImageRendered","customCallbackHandler","handlerType","customFunction","activeTool","filterToolsWithAnnotationsForElement","filterInteractableAnnotationsForElement","getActiveToolForMouseEvent","mouseEvent","modifierKey","keyEventListener","correctBinding","bindings","binding","buttons","Primary","getToolsWithModesForMouseEvent","evtButton","mouseDown","preMouseDownCallback","isPrimaryClick","activeToolsWithEventBinding","passiveToolsIfEventWasPrimaryMouseButton","applicableTools","annotationToolsWithAnnotations","annotationToolsWithMoveableHandles","ToolAndAnnotations","toolsWithMoveableHandles","filterToolsWithMoveableHandles","isMultiSelect","shiftKey","getAnnotationForSelection","toggleAnnotationSelection","handleSelectedCallback","moveableAnnotationTools","interactionType","filterMoveableAnnotationTools","toolSelectedCallback","postMouseDownCallback","toolsWithMovableHandles","mouseDownActivate","addNewAnnotation","mouseDrag","mouseDragCallback","mouseMove","activeAndPassiveTools","mouseMoveCallback","mouseClick","mouseDoubleClick","mouseUp","mouseWheel","getActiveToolForKeyboardEvent","keyDown","setViewportsCursorByToolName","keyUp","onCameraModified","onImageSpacingCalibrated","addEnabledElement","newNode","svgLayer","classList","pointerEvents","defs","feOffset","feColorMatrix","feGaussianBlur","feBlend","_createSvgAnnotationLayer","dataset","viewportUid","renderingEngineUid","elementHash","_setSvgNodeCache","addViewportElement","mouseEventListeners","wheelEventListener","imageRenderedEventDispatcher","cameraModifiedEventDispatcher","imageSpacingCalibratedEventDispatcher","mouseToolEventDispatcher","keyboardToolEventDispatcher","synchronizersFilteredByUIDs","synchronizer","notDisabled","isDisabled","hasSourceViewport","toolGroupFilteredByUIDs","tg","elementDisabledEvt","_resetSvgNodeCache","internalViewportNode","removeViewportElement","getSynchronizers","sync","remove","_removeViewportFromSynchronizers","removeViewports","_removeViewportFromToolGroup","foundElementIndex","el","_removeEnabledElement","cancelActiveManipulations","cancel","Synchronizer","synchronizerId","eventHandler","_ignoreFiredEvents","_targetViewports","fireEvent","_enabled","_eventName","_eventHandler","_sourceViewports","_hasSourceElements","addTarget","addSource","_containsViewport","_onEvent","_updateDisableHandlers","s","removeSource","t","removeTarget","_getViewportIndex","_getViewportElement","sourceViewport","sourceEvent","targetViewport","ex","vp1","vp2","unique","vps","concat","u","_getUniqueViewports","_remove","disableHandler","elementDisabledEvent","vUid","ar","destroy","synchronizerIndex","DEFINED_CURSORS","STANDARD_CURSORS","MouseCursor","fallback","addFallbackStyleProperty","definedCursors","getDefinedCursors","mouseCursor","cursor","standardCursorNames","ImageMouseCursor","url","getUniqueInstanceName","prefix","_superPropBase","_get","Reflect","receiver","base","desc","BASE","iconContent","iconSize","viewBox","mousePoint","mousePointerGroupString","SEGMENTATION_CURSOR_BOUNDARIES","MINUS_RECT","PLUS_RECT","SCISSOR_ICON","RECTANGLE_ICON","CIRCLE_ICON","DefinedDescriptorsMap","Angle","extend","ArrowAnnotate","Bidirectional","CobbAngle","CircleRoi","EllipticalRoi","FreehandRoi","FreehandRoiSculptor","Length","Probe","RectangleRoi","TextMarker","Crosshairs","Eraser","Magnify","Pan","Rotate","StackScroll","WindowLevelRegion","WindowLevel","Zoom","segmentationFreeHandEraseInside","segmentationFreeHandFillInside","segmentationFreeHandEraseOutside","segmentationFreeHandFillOutside","segmentationRectangleEraseInside","RectangleScissor","CircleScissor","registerCursor","getDefinedSVGCursorDescriptor","svgCursorNames","PROPERTY","STATE","MODE","SVGMouseCursor","pointer","urn","getCursorURN","createSVGMouseCursor","format","template","dictionary","dict","defined","match","URL","createObjectURL","svgString","createSVGIconWithPointer","createSVGIcon","Blob","createSVGIconBlob","createSVGIconUrl","scale","svgSize","ELEMENT_CURSORS_MAP","initElementCursor","_getElementCursors","_setElementCursor","cursors","getDefinedCursor","resetElementCursor","hideElementCursor","cursorName","setElementCursor","CursorNames","Disabled","ToolGroup","_toolInstances","toolDefinition","hasToolName","localToolInstance","instantiatedTool","renderingEngines","renderingEngineUIDToUse","indices","vpInfo","toolBindingsOptions","prevBindings","newBindings","_hasMousePrimaryButtonBinding","init","_renderViewports","prevToolOptions","getToolOptions","enableCallback","disableCallback","toolGroupIndex","removeSegmentationsFromToolGroup","csToolsState","destroyToolGroupByToolGroupUID","createToolGroup","getAllToolGroups","getAnnotationNearPoint","getAnnotationNearPointOnEnabledElement","found","findAnnotationNearPointByTool","wait","lastArgs","lastThis","maxWait","timerId","lastCallTime","lastInvokeTime","leading","maxing","trailing","useRAF","invokeFunc","time","thisArg","startTimer","pendingFunc","leadingEdge","timerExpired","shouldInvoke","timeSinceLastCall","Date","now","trailingEdge","timeSinceLastInvoke","timeWaiting","remainingWait","debounced","isInvoking","Boolean","cancelTimer","flush","pending","debounce","calibratedPixelSpacingMetadataProvider","calibrateImageSpacing","rowPixelSpacing","columnPixelSpacing","getStackViewports","getImageIds","calibrateSpacing","transformPhysicalToIndex","physicalPoint","round","pointInShapeCallback","pointInShapeFn","callback","iMin","iMax","jMin","jMax","kMin","kMax","scalarData","getScalarData","getPointData","getScalars","getData","getDirection","rowCosines","columnCosines","scanAxisNormal","getSpacing","rowSpacing","columnSpacing","scanAxisSpacing","worldPosStart","indexToWorld","rowStep","columnStep","scanAxisStep","yMultiple","zMultiple","k","pointIJK","dI","dJ","dK","startWorld","pointLPS","pointInSurroundingSphereCallback","circlePoints","viewUp","viewRight","bottom","sphereCenterWorld","radiusWorld","topLeftWorld","bottomRightWorld","sphereObj","sphere","z","x0","y0","z0","pointInSphere","getTextBoxCoordsCanvas","annotationCanvasPoints","canvasPoints","handlesLeftToRight","handlesTopToBottom","right","corners","sort","b","EPSILON","clipT","num","denom","c","tE","tL","liangBarksyClip","box","da","db","dx","dy","pointInEllipse","ellipse","circleCenterWorld","xRadius","yRadius","zRadius","inside","getCanvasEllipseCorners","ellipseCanvasPoints","dist2","p1","distanceToPointSquared","lineStart","lineEnd","d2","sign","NaN","distanceToPoint","intersectLine","line1Start","line1End","line2Start","line2End","x3","y3","x4","y4","a1","b1","c1","r3","r4","a2","b2","c2","r1","r2","lineSegments","rectToLineSegments","segment","lineSegment","rectangle","getWorldWidthAndHeightFromCorners","pos1","pos2","diagonal","diagonalLength","worldWidth","worldHeight","cosTheta","getPointInLineOfSightWithCriteria","worldPos","targetVolumeUID","criteriaFunction","pickedPoint","stepSize","cameraPosition","step","bounds","getBounds","vector","vtkMath","pointT","_inBounds","intensity","getIntensityFromWorld","pointToPick","snapFocalPointToSlice","scrollRange","deltaFrames","current","posDiffFromFocalPoint","steps","floatingStepNumber","frameIndex","newFocalPoint","newSlicePosFromMin","newPosition","getSliceRange","vtkMatrixBuilder","identity","rotateFromDirections","pt","transformedFocalPoint","currentSlice","minX","maxX","low","high","scrollThroughStack","invert","viewportType","delta","currentImageIdIndex","getCurrentImageIdIndex","numberOfFrames","newImageIdIndex","clip","setImageIdIndex","imageVolume","setCamera","filterViewportsWithFrameOfReferenceUID","numViewports","viewportsWithFrameOfReferenceUID","getFrameOfReferenceUID","filterViewportsWithToolEnabled","viewportsWithToolEnabled","_toolGroupHasActiveEnabledOrPassiveTool","toolMode","vpCamera","getViewportUIDsWithToolToRender","requireSameOrientation","filterViewportsWithSameOrientation","math","planar","viewportFilters","stackScrollTool","drawing","throttle","extendBoundingBoxInSliceAxisIfNecessary","referenceVolumes","segmentationImageData","lowerThreshold","higherThreshold","overwrite","referenceVolume","pointsToUse","projectionPoints","computeOffsetIndex","statistic","baseValue","number","minValue","maxValue","_getStrategyFn","rangeOptions","weight","thresholdVolumeByRange","labelmaps","origin","spacing","labelmap","arrayType","outputData","preventCache","mergedVolume","isValidRepresentationConfig","SegmentationRepresentation","isValidLabelmapConfig","getDefaultRepresentationConfig","thresholdVolumeByRoiStats","createMergedLabelmapForIndex","getDefaultSegmentationStateManager","addGlobalSegmentationData","suppressEvents","segmentationStateManager","globalSegmentationData","globalRepresentationConfig","validConfig","defaultRepresentationConfig","mergedRepresentationConfig","_initGlobalStateIfNecessary","getColorLut","csToolsInitialized","_removeCornerstoneEventListeners","elementEnabledEvent","removeEnabledElement","_addCornerstoneEventListeners","_removeCornerstoneToolsEventListeners","selectionEvent","TOOLS_EVENTS","segmentationDataModified","segmentationStateModified","modifiedEvent","annotationSelectionListener","segmentationDataModifiedEventListener","segmentationStateModifiedEventListener","annotationModifiedListener","_addCornerstoneToolsEventListeners","restoreAnnotations","resetState","cameraSyncCallback","synchronizerInstance","cameraModifiedEvent","tViewport","CAMERA_MODIFIED","createCameraPositionSynchronizer","synchronizerName","createSynchronizer","voiSyncCallback","voiModifiedEvent","range","getRGBTransferFunction","setRange","lower","upper","setProperties","voiRange","createVOISynchronizer","PanTool","touchDragCallback","_dragCallback","deltaPointsWorld","updatedPosition","updatedFocalPoint","WindowLevelTool","bytesPerVoxel","TypedArrayConstructor","middleSliceIndex","frameLength","Float32Array","frame","voxel","rgbTransferFunction","modality","newRange","viewportsContainingVolumeUID","useDynamicRange","getTargetUID","getRange","Modality","getProperties","getPTNewRange","deltaPointsCanvas","clientHeight","getNewRange","multiplier","_getMultiplyerFromDynamicRange","wwDelta","wcDelta","windowWidth","windowCenter","ratio","_getImageDynamicRange","StackScrollTool","StackScrollMouseWheelTool","ZoomTool","zoomScale","clientWidth","newParallelScale","parallelScale","clippingRange","directionOfProjection","tmp","parallelProjection","_dragParallelProjection","_dragPerspectiveProjection","DIRECTIONS","X","Y","Z","CUSTOM","VolumeRotateMouseWheelTool","rotateIncrementDegrees","cz","ax","ay","az","angle","newViewUp","mat4","MIPJumpToClickTool","targetViewportUIDs","maxIntensity","brightestPoint","jumpWorld","normal","dotProd","projectedDelta","_applyShift","jumpToWorld","defaultReferenceLineColor","defaultReferenceLineControllable","defaultReferenceLineDraggableRotatable","defaultReferenceLineSlabThicknessControlsOn","CrosshairsTool","shadow","autoPan","enabled","panSize","cameraFocalPoint","rotationPoints","slabThicknessPoints","toolCenter","activeOperation","activeViewportUIDs","sWidth","sHeight","firstViewport","secondViewport","thirdViewport","initializeViewport","normal1","normal2","point2","normal3","point3","firstPlane","secondPlane","thirdPlane","_jump","viewportUIDArray","otherViewport","viewportControllable","_getReferenceLineControllable","viewportDraggableRotatable","_getReferenceLineDraggableRotatable","_activateModify","_pointNearTool","viewportAnnotation","currentCamera","oldCameraPosition","deltaCameraPosition","oldCameraFocalPoint","deltaCameraFocalPoint","IsTranslation","_autoPanViewportIfNecessary","filteredToolAnnotations","imageNeedsUpdate","previousActiveOperation","previousActiveViewportUIDs","_areViewportUIDArraysEqual","canvasDiagonalLength","crosshairCenterCanvas","otherViewportAnnotations","_filterAnnotationsByUniqueViewportOrientations","referenceLines","otherCamera","otherViewportControllable","otherViewportDraggableRotatable","otherViewportSlabThicknessControlsOn","_getReferenceLineSlabThicknessControlsOn","otherCanvasDiagonalLength","otherCanvasCenter","otherViewportCenterWorld","pointWorld0","pointWorld1","canvasBox","pointCanvas0","otherViewportCenterCanvas","canvasUnitVectorFromCenter","canvasVectorFromCenterLong","canvasVectorFromCenterMid","canvasVectorFromCenterShort","canvasVectorFromCenterStart","refLinePointOne","refLinePointTwo","refLinePointThree","refLinePointFour","refLinesCenter","rotHandleOne","rotHandleTwo","stHandlesCenterCanvas","stHandlesCenterWorld","worldUnitVectorFromCenter","matrix","rotate","worldUnitOrthoVectorFromCenter","slabThicknessValue","getSlabThickness","worldOrthoVectorFromCenter","worldVerticalRefPoint","canvasVerticalRefPoint","canvasOrthoVectorFromCenter","stLinePointOne","stLinePointTwo","stLinePointThree","stLinePointFour","stHandleOne","stHandleTwo","stHandleThree","stHandleFour","newRtpoints","newStpoints","viewportColor","_getReferenceLineColor","line","lineIndex","viewportSlabThicknessControlsOn","selectedViewportUID","lineActive","drawLineSvg","rotHandlesActive","rotationHandles","rotHandleWorldOne","rotHandleWorldTwo","slabThicknessHandlesActive","slabThicknessHandles","slabThicknessHandleWorldOne","slabThicknessHandleWorldTwo","slabThicknessHandleWorldThree","slabThicknessHandleWorldFour","handleUID","drawHandlesSvg","referenceColorCoordinates","circleRadius","drawCircleSvg","viewportUIDArrayOne","viewportUIDArrayTwo","itemFound","viewportsWithDifferentCameras","cameraOfTarget","otherLinkedViewportAnnotationsFromSameScene","otherViewPlaneNormal","otherViewportsAnnotationsWithUniqueCameras","cameraFound","jj","cameraOfStocked","otherNonLinkedViewportAnnotationsFromSameScene","_getAnnotationsForViewportsWithDifferentCameras","otherViewportActors","sameScene","viewportsAnnotationsToUpdate","_checkIfViewportsRenderingSameScene","_applyDeltaShiftToSelectedViewportCameras","_mouseUpCallback","_mouseDragCallback","editData","_deactivateModify","otherViewportRotatable","dir1","dir2","centerCanvas","finalPointCanvas","originalPointCanvas","_isClockWise","rotationAxis","translate","otherViewportsUIDs","renderViewports","mod","currentPoint","currentCenter","otherViewportRotationPoints","dotProdDirection","projectedDirection","normalizedProjectedDirection","normalizedProjectedDelta","_pointNearReferenceLine","setSlabThickness","lineViewport","lineSegment1","distanceToPoint1","lineSegment2","distanceToPoint2","getReferenceLineColor","getReferenceLineControllable","getReferenceLineDraggableRotatable","getReferenceLineSlabThicknessControlsOn","_getRotationHandleNearImagePoint","_getSlabThicknessHandleNearImagePoint","topLefWorld","topRightWorld","bottomLeftWorld","minY","maxY","minZ","maxZ","pan","_applyDeltaShiftToViewportCamera","stPointLineCanvas1","stPointLineCanvas2","stPointLineCanvas1Start","stPointLineCanvas2Start","BidirectionalTool","preventHandleOutsideImage","canvasPoint1","canvasPoint2","movingTextBox","handleIndex","worldPosition","newAnnotation","hasMoved","_deactivateDraw","firstLineSegmentLength","longAxis","shortAxisPoint0","shortAxisPoint1","longAxisVector","counterClockWisePerpendicularToLongAxis","shortAxis","currentShortAxisVector","isHandleOutsideImage","isDrawing","canvasCoordPoints","shortAxisDistFromCenter","vectorX","vectorY","xMid","yMid","startX","startY","endX","endY","worldPosDelta","_mouseDragModifyHandle","canvasCoordHandlesCurrent","firstLineSegment","secondLineSegment","proposedPoint","proposedCanvasCoord","fixedCanvasCoord","proposedFirstLineSegment","_movingLongAxisWouldPutItThroughShortAxis","intersectionPoint","intersectionCoord","distFromLeftHandle","distFromRightHandle","distIntersectAndFixedPoint","intersectX","intersectY","leftX","leftY","rightX","rightY","translateHandleIndex","proposedCanvasCoordPoint","canvasCoordsCurrent","longLineSegment","shortLineSegment","helperLine","newIntersectionPoint","distFromTranslateHandle","translatedHandleCoords","_mouseDragDrawCallback","_mouseDragModifyCallback","canvasCoordinates","_throttledCalculateCachedStats","_calculateCachedStats","activeHandleCanvasCoords","_getTextLines","canvasTextBoxCoords","drawLinkedTextBoxSvg","getLinkedTextBoxStyle","vectorInSecondLineDirection","extendedSecondLineSegment","toFixed","worldPos1","worldPos2","worldPos3","worldPos4","targetUIDs","getTargetUIDViewportAndImage","dist1","_calculateLength","index1","index2","index3","index4","_isInsideVolume","_activateDraw","dz","LengthTool","ProbeTool","eventDispatchDetail","stackTargetUID","textCanvasCoorinates","drawTextBoxSvg","cachedVolumeStats","SUVBw","SUVLbm","SUVBsa","scaling","PET","suvbwToSuvbsa","suvbwToSuvlbm","_getValueForModality","RectangleRoiTool","_getRectangleImageCoordinates","bottomLeftCanvas","bottomRightCanvas","topLeftCanvas","topRightCanvas","area","mean","stdDev","drawRectSvg","areaLine","fromCharCode","meanLine","maxLine","stdDevLine","worldPos1Index","worldPos2Index","count","valueMinusMean","getWorldWidthAndHeightFromTwoPoints","EllipticalRoiTool","canvasPos","minorEllipse","majorEllipse","pointInMinorEllipse","_pointInEllipseCanvas","canvasWidth","canvasHeight","originalHandleCanvas","pointsCanvas","currentCanvasPoints","dX","dY","bottomCanvas","topCanvas","leftCanvas","rightCanvas","_dragHandle","dYCanvas","canvasBottom","canvasTop","newHalfCanvasWidth","canvasLeft","canvasRight","dXCanvas","newHalfCanvasHeight","canvasCorners","drawEllipseSvg","isEmptyArea","ellipseObj","PI","location","normalized","fillInsideRectangle","volume","constraintFn","rectangleCornersIJK","coord","every","fillRectangle","eraseInsideRectangle","eraseRectangle","RectangleScissorsTool","FILL_INSIDE","ERASE_INSIDE","activeSegmentation","segmentIndexController","segmentLocking","segmentColor","segmentationColor","applyActiveStrategy","toolMetadata","fillInsideCircle","segmentationVolume","fillCircle","CircleScissorsTool","fillInsideSphere","fillSphere","SphereScissorsTool","RectangleRoiThresholdTool","RectangleRoiStartEndThresholdTool","numSlicesToPropagate","startIndex","spacingInNormal","endIndex","_getEndSliceIndex","startSlice","endSlice","projectionPointsImageIds","_computeProjectionPoints","sliceIndex","firstOrLastSlice","lineDashToUse","_calculateCachedStatsTool","startIJK","worldToIndexVec3","endIJK","indexToWorldVec3","endWorld","newProjectionPoints","dist","newPoint","RectanglePoints","endPos","imageIdIndex","imageIds","imagePositionPatient","metaData"],"sourceRoot":""}