@cornerstonejs/core 2.0.0-beta.8 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1860) hide show
  1. package/dist/esm/RenderingEngine/BaseVolumeViewport.d.ts +86 -0
  2. package/dist/esm/RenderingEngine/BaseVolumeViewport.js +129 -98
  3. package/dist/esm/RenderingEngine/CanvasActor/CanvasMapper.d.ts +6 -0
  4. package/dist/esm/RenderingEngine/CanvasActor/CanvasMapper.js +0 -1
  5. package/dist/esm/RenderingEngine/CanvasActor/CanvasProperties.d.ts +15 -0
  6. package/dist/esm/RenderingEngine/CanvasActor/CanvasProperties.js +0 -1
  7. package/dist/esm/RenderingEngine/CanvasActor/index.d.ts +22 -0
  8. package/dist/esm/RenderingEngine/CanvasActor/index.js +2 -2
  9. package/dist/esm/RenderingEngine/RenderingEngine.d.ts +57 -0
  10. package/dist/esm/RenderingEngine/RenderingEngine.js +29 -29
  11. package/dist/esm/RenderingEngine/StackViewport.d.ts +222 -0
  12. package/dist/esm/RenderingEngine/StackViewport.js +252 -168
  13. package/dist/esm/RenderingEngine/VideoViewport.d.ts +122 -0
  14. package/dist/esm/RenderingEngine/VideoViewport.js +105 -44
  15. package/dist/esm/RenderingEngine/Viewport.d.ts +136 -0
  16. package/dist/esm/RenderingEngine/Viewport.js +55 -31
  17. package/dist/esm/RenderingEngine/VolumeViewport.d.ts +50 -0
  18. package/dist/esm/RenderingEngine/VolumeViewport.js +141 -20
  19. package/dist/esm/RenderingEngine/VolumeViewport3D.d.ts +24 -0
  20. package/dist/esm/RenderingEngine/VolumeViewport3D.js +71 -7
  21. package/dist/esm/RenderingEngine/WSIViewport.d.ts +65 -0
  22. package/dist/esm/RenderingEngine/WSIViewport.js +458 -0
  23. package/dist/esm/RenderingEngine/getRenderingEngine.d.ts +4 -0
  24. package/dist/esm/RenderingEngine/getRenderingEngine.js +0 -1
  25. package/dist/esm/RenderingEngine/helpers/addImageSlicesToViewports.d.ts +3 -0
  26. package/dist/esm/RenderingEngine/helpers/addImageSlicesToViewports.js +3 -4
  27. package/dist/esm/RenderingEngine/helpers/addVolumesToViewports.d.ts +3 -0
  28. package/dist/esm/RenderingEngine/helpers/addVolumesToViewports.js +0 -1
  29. package/dist/esm/RenderingEngine/helpers/cpuFallback/colors/colormap.d.ts +3 -0
  30. package/dist/esm/RenderingEngine/helpers/cpuFallback/colors/colormap.js +1 -2
  31. package/dist/esm/RenderingEngine/helpers/cpuFallback/colors/index.d.ts +3 -0
  32. package/dist/esm/RenderingEngine/helpers/cpuFallback/colors/index.js +0 -1
  33. package/dist/esm/RenderingEngine/helpers/cpuFallback/colors/lookupTable.d.ts +33 -0
  34. package/dist/esm/RenderingEngine/helpers/cpuFallback/colors/lookupTable.js +15 -6
  35. package/dist/esm/RenderingEngine/helpers/cpuFallback/drawImageSync.d.ts +2 -0
  36. package/dist/esm/RenderingEngine/helpers/cpuFallback/drawImageSync.js +0 -1
  37. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/calculateTransform.d.ts +2 -0
  38. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/calculateTransform.js +0 -1
  39. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/canvasToPixel.d.ts +2 -0
  40. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/canvasToPixel.js +0 -1
  41. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/computeAutoVoi.d.ts +2 -0
  42. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/computeAutoVoi.js +0 -1
  43. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/correctShift.d.ts +7 -0
  44. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/correctShift.js +0 -1
  45. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/createViewport.d.ts +2 -0
  46. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/createViewport.js +0 -1
  47. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/doesImageNeedToBeRendered.d.ts +2 -0
  48. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/doesImageNeedToBeRendered.js +0 -1
  49. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/fitToWindow.d.ts +2 -0
  50. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/fitToWindow.js +0 -1
  51. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/generateColorLUT.d.ts +2 -0
  52. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/generateColorLUT.js +1 -2
  53. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/generateLut.d.ts +2 -0
  54. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/generateLut.js +2 -3
  55. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/getDefaultViewport.d.ts +2 -0
  56. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/getDefaultViewport.js +0 -1
  57. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/getImageFitScale.d.ts +6 -0
  58. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/getImageFitScale.js +0 -1
  59. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/getImageSize.d.ts +5 -0
  60. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/getImageSize.js +0 -1
  61. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/getLut.d.ts +2 -0
  62. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/getLut.js +1 -2
  63. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/getModalityLut.d.ts +1 -0
  64. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/getModalityLut.js +0 -1
  65. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/getTransform.d.ts +2 -0
  66. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/getTransform.js +0 -1
  67. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/getVOILut.d.ts +1 -0
  68. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/getVOILut.js +0 -1
  69. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/initializeRenderCanvas.d.ts +2 -0
  70. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/initializeRenderCanvas.js +0 -1
  71. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/lutMatches.d.ts +2 -0
  72. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/lutMatches.js +1 -2
  73. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/now.d.ts +1 -0
  74. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/now.js +0 -1
  75. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/pixelToCanvas.d.ts +2 -0
  76. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/pixelToCanvas.js +0 -1
  77. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/renderColorImage.d.ts +2 -0
  78. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/renderColorImage.js +3 -5
  79. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/renderGrayscaleImage.d.ts +2 -0
  80. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/renderGrayscaleImage.js +2 -4
  81. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/renderPseudoColorImage.d.ts +2 -0
  82. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/renderPseudoColorImage.js +3 -4
  83. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/resetCamera.d.ts +2 -0
  84. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/resetCamera.js +0 -1
  85. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/resize.d.ts +2 -0
  86. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/resize.js +0 -1
  87. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/saveLastRendered.d.ts +2 -0
  88. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/saveLastRendered.js +0 -1
  89. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/setDefaultViewport.d.ts +6 -0
  90. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/setDefaultViewport.js +0 -1
  91. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/setToPixelCoordinateSystem.d.ts +2 -0
  92. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/setToPixelCoordinateSystem.js +0 -1
  93. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/storedColorPixelDataToCanvasImageData.d.ts +2 -0
  94. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/storedColorPixelDataToCanvasImageData.js +1 -2
  95. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageData.d.ts +2 -0
  96. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageData.js +1 -2
  97. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataColorLUT.d.ts +3 -0
  98. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataColorLUT.js +1 -2
  99. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPET.d.ts +2 -0
  100. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPET.js +1 -2
  101. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPseudocolorLUT.d.ts +3 -0
  102. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPseudocolorLUT.js +1 -2
  103. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPseudocolorLUTPET.d.ts +3 -0
  104. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPseudocolorLUTPET.js +1 -2
  105. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataRGBA.d.ts +2 -0
  106. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataRGBA.js +1 -2
  107. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/storedRGBAPixelDataToCanvasImageData.d.ts +2 -0
  108. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/storedRGBAPixelDataToCanvasImageData.js +1 -2
  109. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/transform.d.ts +14 -0
  110. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/transform.js +0 -1
  111. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/validator.d.ts +2 -0
  112. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/validator.js +0 -1
  113. package/dist/esm/RenderingEngine/helpers/createVolumeActor.d.ts +12 -0
  114. package/dist/esm/RenderingEngine/helpers/createVolumeActor.js +6 -8
  115. package/dist/esm/RenderingEngine/helpers/createVolumeMapper.d.ts +4 -0
  116. package/dist/esm/RenderingEngine/helpers/createVolumeMapper.js +0 -1
  117. package/dist/esm/RenderingEngine/helpers/getOrCreateCanvas.d.ts +3 -0
  118. package/dist/esm/RenderingEngine/helpers/getOrCreateCanvas.js +5 -5
  119. package/dist/esm/RenderingEngine/helpers/index.d.ts +8 -0
  120. package/dist/esm/RenderingEngine/helpers/index.js +0 -1
  121. package/dist/esm/RenderingEngine/helpers/isRgbaSourceRgbDest.d.ts +2 -0
  122. package/dist/esm/RenderingEngine/helpers/isRgbaSourceRgbDest.js +0 -1
  123. package/dist/esm/RenderingEngine/helpers/setDefaultVolumeVOI.d.ts +3 -0
  124. package/dist/esm/RenderingEngine/helpers/setDefaultVolumeVOI.js +23 -49
  125. package/dist/esm/RenderingEngine/helpers/setVolumesForViewports.d.ts +3 -0
  126. package/dist/esm/RenderingEngine/helpers/setVolumesForViewports.js +0 -1
  127. package/dist/esm/RenderingEngine/helpers/viewportTypeToViewportClass.d.ts +8 -0
  128. package/dist/esm/RenderingEngine/helpers/viewportTypeToViewportClass.js +2 -1
  129. package/dist/esm/RenderingEngine/helpers/viewportTypeUsesCustomRenderingPipeline.d.ts +1 -0
  130. package/dist/esm/RenderingEngine/helpers/viewportTypeUsesCustomRenderingPipeline.js +0 -1
  131. package/dist/esm/RenderingEngine/helpers/volumeNewImageEventDispatcher.d.ts +4 -0
  132. package/dist/esm/RenderingEngine/helpers/volumeNewImageEventDispatcher.js +4 -5
  133. package/dist/esm/RenderingEngine/index.d.ts +8 -0
  134. package/dist/esm/RenderingEngine/index.js +0 -1
  135. package/dist/esm/RenderingEngine/renderingEngineCache.d.ts +8 -0
  136. package/dist/esm/RenderingEngine/renderingEngineCache.js +0 -1
  137. package/dist/esm/RenderingEngine/vtkClasses/index.d.ts +5 -0
  138. package/dist/esm/RenderingEngine/vtkClasses/index.js +0 -1
  139. package/dist/esm/RenderingEngine/vtkClasses/vtkOffscreenMultiRenderWindow.d.ts +7 -0
  140. package/dist/esm/RenderingEngine/vtkClasses/vtkOffscreenMultiRenderWindow.js +0 -1
  141. package/dist/esm/RenderingEngine/vtkClasses/vtkSharedVolumeMapper.d.ts +7 -0
  142. package/dist/esm/RenderingEngine/vtkClasses/vtkSharedVolumeMapper.js +0 -1
  143. package/dist/esm/RenderingEngine/vtkClasses/vtkSlabCamera.d.ts +142 -0
  144. package/dist/esm/RenderingEngine/vtkClasses/vtkSlabCamera.js +0 -1
  145. package/dist/esm/RenderingEngine/vtkClasses/vtkStreamingOpenGLRenderWindow.d.ts +7 -0
  146. package/dist/esm/RenderingEngine/vtkClasses/vtkStreamingOpenGLRenderWindow.js +0 -1
  147. package/dist/esm/RenderingEngine/vtkClasses/vtkStreamingOpenGLTexture.d.ts +7 -0
  148. package/dist/esm/RenderingEngine/vtkClasses/vtkStreamingOpenGLTexture.js +94 -79
  149. package/dist/esm/RenderingEngine/vtkClasses/vtkStreamingOpenGLViewNodeFactory.d.ts +8 -0
  150. package/dist/esm/RenderingEngine/vtkClasses/vtkStreamingOpenGLViewNodeFactory.js +1 -2
  151. package/dist/esm/RenderingEngine/vtkClasses/vtkStreamingOpenGLVolumeMapper.d.ts +7 -0
  152. package/dist/esm/RenderingEngine/vtkClasses/vtkStreamingOpenGLVolumeMapper.js +87 -46
  153. package/dist/esm/Settings.d.ts +15 -0
  154. package/dist/esm/Settings.js +0 -1
  155. package/dist/esm/cache/cache.d.ts +56 -0
  156. package/dist/esm/cache/cache.js +344 -146
  157. package/dist/esm/cache/classes/BaseStreamingImageVolume.d.ts +85 -0
  158. package/dist/esm/cache/classes/BaseStreamingImageVolume.js +343 -0
  159. package/dist/esm/cache/classes/Contour.d.ts +28 -0
  160. package/dist/esm/cache/classes/Contour.js +28 -16
  161. package/dist/esm/cache/classes/ContourSet.d.ts +34 -0
  162. package/dist/esm/cache/classes/ContourSet.js +45 -44
  163. package/dist/esm/cache/classes/ImageVolume.d.ts +61 -0
  164. package/dist/esm/cache/classes/ImageVolume.js +49 -264
  165. package/dist/esm/cache/classes/StreamingDynamicImageVolume.d.ts +56 -0
  166. package/dist/esm/cache/classes/StreamingDynamicImageVolume.js +105 -0
  167. package/dist/esm/cache/classes/StreamingImageVolume.d.ts +8 -0
  168. package/dist/esm/cache/classes/StreamingImageVolume.js +21 -0
  169. package/dist/esm/cache/classes/Surface.d.ts +26 -0
  170. package/dist/esm/cache/classes/Surface.js +45 -20
  171. package/dist/esm/cache/index.d.ts +6 -0
  172. package/dist/esm/cache/index.js +4 -4
  173. package/dist/esm/constants/backgroundColors.d.ts +4 -0
  174. package/dist/esm/constants/backgroundColors.js +0 -1
  175. package/dist/esm/constants/cpuColormaps.d.ts +3 -0
  176. package/dist/esm/constants/cpuColormaps.js +0 -1
  177. package/dist/esm/constants/epsilon.d.ts +2 -0
  178. package/dist/esm/constants/epsilon.js +0 -1
  179. package/dist/esm/constants/index.d.ts +7 -0
  180. package/dist/esm/constants/index.js +0 -1
  181. package/dist/esm/constants/microscopyViewportCss.d.ts +2 -0
  182. package/dist/esm/constants/microscopyViewportCss.js +368 -0
  183. package/dist/esm/constants/mprCameraValues.d.ts +2 -0
  184. package/dist/esm/constants/mprCameraValues.js +3 -1
  185. package/dist/esm/constants/rendering.d.ts +5 -0
  186. package/dist/esm/constants/rendering.js +0 -1
  187. package/dist/esm/constants/viewportPresets.d.ts +3 -0
  188. package/dist/esm/constants/viewportPresets.js +0 -1
  189. package/dist/esm/enums/BlendModes.d.ts +7 -0
  190. package/dist/esm/enums/BlendModes.js +0 -1
  191. package/dist/esm/enums/CalibrationTypes.d.ts +10 -0
  192. package/dist/esm/enums/CalibrationTypes.js +0 -1
  193. package/dist/esm/enums/ContourType.d.ts +5 -0
  194. package/dist/esm/enums/ContourType.js +0 -1
  195. package/dist/esm/enums/DynamicOperatorType.d.ts +6 -0
  196. package/dist/esm/enums/DynamicOperatorType.js +0 -1
  197. package/dist/esm/enums/Events.d.ts +44 -0
  198. package/dist/esm/enums/Events.js +8 -3
  199. package/dist/esm/enums/GenerateImageType.d.ts +5 -0
  200. package/dist/esm/enums/GenerateImageType.js +6 -0
  201. package/dist/esm/enums/GeometryType.d.ts +5 -0
  202. package/dist/esm/enums/GeometryType.js +2 -3
  203. package/dist/esm/enums/ImageQualityStatus.d.ts +8 -0
  204. package/dist/esm/enums/ImageQualityStatus.js +0 -1
  205. package/dist/esm/enums/InterpolationType.d.ts +6 -0
  206. package/dist/esm/enums/InterpolationType.js +0 -1
  207. package/dist/esm/enums/MetadataModules.d.ts +24 -0
  208. package/dist/esm/enums/MetadataModules.js +1 -1
  209. package/dist/esm/enums/OrientationAxis.d.ts +7 -0
  210. package/dist/esm/enums/OrientationAxis.js +0 -1
  211. package/dist/esm/enums/RequestType.d.ts +7 -0
  212. package/dist/esm/enums/RequestType.js +0 -1
  213. package/dist/esm/enums/VOILUTFunctionType.d.ts +5 -0
  214. package/dist/esm/enums/VOILUTFunctionType.js +0 -1
  215. package/dist/esm/enums/VideoEnums.d.ts +5 -0
  216. package/dist/esm/enums/VideoEnums.js +0 -1
  217. package/dist/esm/enums/ViewportStatus.d.ts +8 -0
  218. package/dist/esm/enums/ViewportStatus.js +0 -1
  219. package/dist/esm/enums/ViewportType.d.ts +9 -0
  220. package/dist/esm/enums/ViewportType.js +1 -1
  221. package/dist/esm/enums/index.d.ts +17 -0
  222. package/dist/esm/enums/index.js +2 -3
  223. package/dist/esm/eventTarget.d.ts +14 -0
  224. package/dist/esm/eventTarget.js +2 -4
  225. package/dist/esm/getEnabledElement.d.ts +5 -0
  226. package/dist/esm/getEnabledElement.js +0 -1
  227. package/dist/esm/global.d.ts +6 -0
  228. package/dist/esm/global.js +0 -1
  229. package/dist/esm/index.d.ts +38 -0
  230. package/dist/esm/index.js +10 -5
  231. package/dist/esm/init.d.ts +14 -0
  232. package/dist/esm/init.js +29 -92
  233. package/dist/esm/loaders/ProgressiveRetrieveImages.d.ts +37 -0
  234. package/dist/esm/loaders/ProgressiveRetrieveImages.js +12 -11
  235. package/dist/esm/loaders/configuration/interleavedRetrieve.d.ts +3 -0
  236. package/dist/esm/loaders/configuration/interleavedRetrieve.js +0 -1
  237. package/dist/esm/loaders/configuration/sequentialRetrieve.d.ts +3 -0
  238. package/dist/esm/loaders/configuration/sequentialRetrieve.js +0 -1
  239. package/dist/esm/loaders/configuration/singleRetrieve.d.ts +3 -0
  240. package/dist/esm/loaders/configuration/singleRetrieve.js +0 -4
  241. package/dist/esm/loaders/cornerstoneStreamingDynamicImageVolumeLoader.d.ts +10 -0
  242. package/dist/esm/loaders/cornerstoneStreamingDynamicImageVolumeLoader.js +59 -0
  243. package/dist/esm/loaders/cornerstoneStreamingImageVolumeLoader.d.ts +12 -0
  244. package/dist/esm/loaders/cornerstoneStreamingImageVolumeLoader.js +73 -0
  245. package/dist/esm/loaders/fillNearbyFrames.d.ts +2 -0
  246. package/dist/esm/loaders/fillNearbyFrames.js +7 -17
  247. package/dist/esm/loaders/geometryLoader.d.ts +15 -0
  248. package/dist/esm/loaders/geometryLoader.js +66 -9
  249. package/dist/esm/loaders/imageLoader.d.ts +44 -0
  250. package/dist/esm/loaders/imageLoader.js +205 -107
  251. package/dist/esm/loaders/index.d.ts +6 -0
  252. package/dist/esm/loaders/index.js +7 -0
  253. package/dist/esm/loaders/utils/contourSet/createContourSet.d.ts +2 -0
  254. package/dist/esm/loaders/utils/contourSet/createContourSet.js +1 -2
  255. package/dist/esm/loaders/utils/contourSet/validateContourSet.d.ts +2 -0
  256. package/dist/esm/loaders/utils/contourSet/validateContourSet.js +0 -1
  257. package/dist/esm/loaders/utils/surface/createSurface.d.ts +2 -0
  258. package/dist/esm/loaders/utils/surface/createSurface.js +9 -11
  259. package/dist/esm/loaders/utils/surface/validateSurface.d.ts +2 -0
  260. package/dist/esm/loaders/utils/surface/validateSurface.js +12 -5
  261. package/dist/esm/loaders/volumeLoader.d.ts +40 -0
  262. package/dist/esm/loaders/volumeLoader.js +112 -196
  263. package/dist/esm/metaData.d.ts +5 -0
  264. package/dist/esm/metaData.js +0 -1
  265. package/dist/esm/requestPool/imageLoadPoolManager.d.ts +3 -0
  266. package/dist/esm/requestPool/imageLoadPoolManager.js +0 -1
  267. package/dist/esm/requestPool/imageRetrievalPoolManager.d.ts +3 -0
  268. package/dist/esm/requestPool/imageRetrievalPoolManager.js +0 -1
  269. package/dist/esm/requestPool/requestPoolManager.d.ts +42 -0
  270. package/dist/esm/requestPool/requestPoolManager.js +17 -18
  271. package/dist/esm/types/AABB2.d.ts +7 -0
  272. package/dist/esm/types/AABB2.js +0 -2
  273. package/dist/esm/types/AABB3.d.ts +9 -0
  274. package/dist/esm/types/AABB3.js +0 -2
  275. package/dist/esm/types/ActorSliceRange.d.ts +11 -0
  276. package/dist/esm/types/ActorSliceRange.js +0 -2
  277. package/dist/esm/types/AffineMatrix.d.ts +27 -0
  278. package/dist/esm/types/AffineMatrix.js +0 -2
  279. package/dist/esm/types/BoundsIJK.d.ts +3 -0
  280. package/dist/esm/types/BoundsIJK.js +0 -2
  281. package/dist/esm/types/BoundsLPS.d.ts +3 -0
  282. package/dist/esm/types/BoundsLPS.js +0 -2
  283. package/dist/esm/types/CPUFallbackColormap.d.ts +20 -0
  284. package/dist/esm/types/CPUFallbackColormap.js +0 -2
  285. package/dist/esm/types/CPUFallbackColormapData.d.ts +10 -0
  286. package/dist/esm/types/CPUFallbackColormapData.js +0 -2
  287. package/dist/esm/types/CPUFallbackColormapsData.d.ts +3 -0
  288. package/dist/esm/types/CPUFallbackColormapsData.js +0 -2
  289. package/dist/esm/types/CPUFallbackEnabledElement.d.ts +2 -0
  290. package/dist/esm/types/CPUFallbackEnabledElement.js +0 -2
  291. package/dist/esm/types/CPUFallbackLUT.d.ts +5 -0
  292. package/dist/esm/types/CPUFallbackLUT.js +0 -2
  293. package/dist/esm/types/CPUFallbackLookupTable.d.ts +15 -0
  294. package/dist/esm/types/CPUFallbackLookupTable.js +0 -2
  295. package/dist/esm/types/CPUFallbackRenderingTools.d.ts +23 -0
  296. package/dist/esm/types/CPUFallbackRenderingTools.js +0 -2
  297. package/dist/esm/types/CPUFallbackTransform.d.ts +14 -0
  298. package/dist/esm/types/CPUFallbackTransform.js +0 -2
  299. package/dist/esm/types/CPUFallbackViewport.d.ts +27 -0
  300. package/dist/esm/types/CPUFallbackViewport.js +0 -2
  301. package/dist/esm/types/CPUFallbackViewportDisplayedArea.d.ts +14 -0
  302. package/dist/esm/types/CPUFallbackViewportDisplayedArea.js +0 -2
  303. package/dist/esm/types/CPUIImageData.d.ts +46 -0
  304. package/dist/esm/types/CPUIImageData.js +0 -2
  305. package/dist/esm/types/Color.d.ts +2 -0
  306. package/dist/esm/types/Color.js +0 -2
  307. package/dist/esm/types/Colormap.d.ts +15 -0
  308. package/dist/esm/types/Colormap.js +0 -2
  309. package/dist/esm/types/ContourData.d.ts +17 -0
  310. package/dist/esm/types/ContourData.js +0 -2
  311. package/dist/esm/types/Cornerstone3DConfig.d.ts +13 -0
  312. package/dist/esm/types/Cornerstone3DConfig.js +0 -2
  313. package/dist/esm/types/CustomEventType.d.ts +5 -0
  314. package/dist/esm/types/CustomEventType.js +0 -2
  315. package/dist/esm/types/EventTypes.d.ts +187 -0
  316. package/dist/esm/types/EventTypes.js +0 -2
  317. package/dist/esm/types/FlipDirection.d.ts +5 -0
  318. package/dist/esm/types/FlipDirection.js +0 -2
  319. package/dist/esm/types/GeometryLoaderFn.d.ts +7 -0
  320. package/dist/esm/types/GeometryLoaderFn.js +0 -0
  321. package/dist/esm/types/IActor.d.ts +16 -0
  322. package/dist/esm/types/IActor.js +0 -2
  323. package/dist/esm/types/IBaseVolumeViewport.d.ts +2 -0
  324. package/dist/esm/types/IBaseVolumeViewport.js +0 -0
  325. package/dist/esm/types/ICache.d.ts +12 -0
  326. package/dist/esm/types/ICache.js +0 -2
  327. package/dist/esm/types/ICachedGeometry.d.ts +11 -0
  328. package/dist/esm/types/ICachedGeometry.js +0 -2
  329. package/dist/esm/types/ICachedImage.d.ts +12 -0
  330. package/dist/esm/types/ICachedImage.js +0 -2
  331. package/dist/esm/types/ICachedVolume.d.ts +11 -0
  332. package/dist/esm/types/ICachedVolume.js +0 -2
  333. package/dist/esm/types/ICamera.d.ts +17 -0
  334. package/dist/esm/types/ICamera.js +0 -2
  335. package/dist/esm/types/IContour.d.ts +2 -0
  336. package/dist/esm/types/IContour.js +0 -2
  337. package/dist/esm/types/IContourSet.d.ts +2 -0
  338. package/dist/esm/types/IContourSet.js +0 -2
  339. package/dist/esm/types/IDynamicImageVolume.d.ts +8 -0
  340. package/dist/esm/types/IDynamicImageVolume.js +0 -2
  341. package/dist/esm/types/IEnabledElement.d.ts +11 -0
  342. package/dist/esm/types/IEnabledElement.js +0 -2
  343. package/dist/esm/types/IGeometry.d.ts +10 -0
  344. package/dist/esm/types/IGeometry.js +0 -2
  345. package/dist/esm/types/IImage.d.ts +123 -0
  346. package/dist/esm/types/IImage.js +0 -2
  347. package/dist/esm/types/IImageCalibration.d.ts +11 -0
  348. package/dist/esm/types/IImageCalibration.js +0 -2
  349. package/dist/esm/types/IImageData.d.ts +35 -0
  350. package/dist/esm/types/IImageData.js +0 -2
  351. package/dist/esm/types/IImageFrame.d.ts +42 -0
  352. package/dist/esm/types/IImageFrame.js +0 -0
  353. package/dist/esm/types/IImageVolume.d.ts +3 -0
  354. package/dist/esm/types/IImageVolume.js +0 -2
  355. package/dist/esm/types/ILoadObject.d.ts +18 -0
  356. package/dist/esm/types/ILoadObject.js +0 -2
  357. package/dist/esm/types/IPointsManager.d.ts +7 -0
  358. package/dist/esm/types/IPointsManager.js +0 -0
  359. package/dist/esm/types/IRLEVoxelMap.d.ts +7 -0
  360. package/dist/esm/types/IRLEVoxelMap.js +0 -0
  361. package/dist/esm/types/IRegisterImageLoader.d.ts +5 -0
  362. package/dist/esm/types/IRegisterImageLoader.js +0 -2
  363. package/dist/esm/types/IRenderingEngine.d.ts +3 -0
  364. package/dist/esm/types/IRenderingEngine.js +0 -2
  365. package/dist/esm/types/IRetrieveConfiguration.d.ts +38 -0
  366. package/dist/esm/types/IRetrieveConfiguration.js +0 -2
  367. package/dist/esm/types/IStackInput.d.ts +13 -0
  368. package/dist/esm/types/IStackInput.js +0 -2
  369. package/dist/esm/types/IStackViewport.d.ts +2 -0
  370. package/dist/esm/types/IStackViewport.js +0 -2
  371. package/dist/esm/types/IStreamingImageVolume.d.ts +6 -0
  372. package/dist/esm/types/IStreamingImageVolume.js +0 -2
  373. package/dist/esm/types/IStreamingVolumeProperties.d.ts +12 -0
  374. package/dist/esm/types/IStreamingVolumeProperties.js +0 -2
  375. package/dist/esm/types/ISurface.d.ts +2 -0
  376. package/dist/esm/types/ISurface.js +0 -2
  377. package/dist/esm/types/ITransferFunctionNode.d.ts +9 -0
  378. package/dist/esm/types/ITransferFunctionNode.js +0 -0
  379. package/dist/esm/types/IVideoViewport.d.ts +2 -0
  380. package/dist/esm/types/IVideoViewport.js +0 -2
  381. package/dist/esm/types/IViewport.d.ts +85 -0
  382. package/dist/esm/types/IViewport.js +0 -2
  383. package/dist/esm/types/IViewportId.d.ts +4 -0
  384. package/dist/esm/types/IViewportId.js +0 -2
  385. package/dist/esm/types/IVolume.d.ts +3 -0
  386. package/dist/esm/types/IVolume.js +0 -2
  387. package/dist/esm/types/IVolumeInput.d.ts +16 -0
  388. package/dist/esm/types/IVolumeInput.js +0 -2
  389. package/dist/esm/types/IVolumeViewport.d.ts +3 -0
  390. package/dist/esm/types/IVolumeViewport.js +0 -2
  391. package/dist/esm/types/IVoxelManager.d.ts +2 -0
  392. package/dist/esm/types/IVoxelManager.js +0 -0
  393. package/dist/esm/types/IWSIViewport.d.ts +3 -0
  394. package/dist/esm/types/IWSIViewport.js +0 -0
  395. package/dist/esm/types/ImageLoadListener.d.ts +5 -0
  396. package/dist/esm/types/ImageLoadListener.js +0 -2
  397. package/dist/esm/types/ImageLoadRequests.d.ts +24 -0
  398. package/dist/esm/types/ImageLoadRequests.js +0 -0
  399. package/dist/esm/types/ImageLoaderFn.d.ts +6 -0
  400. package/dist/esm/types/ImageLoaderFn.js +0 -2
  401. package/dist/esm/types/ImagePixelModule.d.ts +13 -0
  402. package/dist/esm/types/ImagePixelModule.js +0 -2
  403. package/dist/esm/types/ImagePlaneModule.d.ts +16 -0
  404. package/dist/esm/types/ImagePlaneModule.js +0 -2
  405. package/dist/esm/types/ImageSliceData.d.ts +5 -0
  406. package/dist/esm/types/ImageSliceData.js +0 -2
  407. package/dist/esm/types/ImageVolumeProps.d.ts +6 -0
  408. package/dist/esm/types/ImageVolumeProps.js +0 -2
  409. package/dist/esm/types/JumpToSliceOptions.d.ts +6 -0
  410. package/dist/esm/types/JumpToSliceOptions.js +0 -0
  411. package/dist/esm/types/Mat3.d.ts +2 -0
  412. package/dist/esm/types/Mat3.js +0 -2
  413. package/dist/esm/types/Metadata.d.ts +19 -0
  414. package/dist/esm/types/Metadata.js +0 -2
  415. package/dist/esm/types/MetadataModuleTypes.d.ts +66 -0
  416. package/dist/esm/types/MetadataModuleTypes.js +0 -0
  417. package/dist/esm/types/OrientationVectors.d.ts +6 -0
  418. package/dist/esm/types/OrientationVectors.js +0 -2
  419. package/dist/esm/types/PixelDataTypedArray.d.ts +2 -0
  420. package/dist/esm/types/PixelDataTypedArray.js +0 -2
  421. package/dist/esm/types/Plane.d.ts +2 -0
  422. package/dist/esm/types/Plane.js +0 -2
  423. package/dist/esm/types/Point2.d.ts +2 -0
  424. package/dist/esm/types/Point2.js +0 -2
  425. package/dist/esm/types/Point3.d.ts +7 -0
  426. package/dist/esm/types/Point3.js +0 -2
  427. package/dist/esm/types/Point4.d.ts +2 -0
  428. package/dist/esm/types/Point4.js +0 -2
  429. package/dist/esm/types/RGB.d.ts +2 -0
  430. package/dist/esm/types/RGB.js +0 -2
  431. package/dist/esm/types/ScalingParameters.d.ts +19 -0
  432. package/dist/esm/types/ScalingParameters.js +0 -2
  433. package/dist/esm/types/ScrollOptions.d.ts +8 -0
  434. package/dist/esm/types/ScrollOptions.js +0 -0
  435. package/dist/esm/types/StackViewportProperties.d.ts +8 -0
  436. package/dist/esm/types/StackViewportProperties.js +0 -2
  437. package/dist/esm/types/SurfaceData.d.ts +11 -0
  438. package/dist/esm/types/SurfaceData.js +0 -2
  439. package/dist/esm/types/TransformMatrix2D.d.ts +2 -0
  440. package/dist/esm/types/TransformMatrix2D.js +0 -2
  441. package/dist/esm/types/VideoViewportProperties.d.ts +10 -0
  442. package/dist/esm/types/VideoViewportProperties.js +0 -2
  443. package/dist/esm/types/VideoViewportTypes.d.ts +18 -0
  444. package/dist/esm/types/VideoViewportTypes.js +0 -2
  445. package/dist/esm/types/ViewportInputOptions.d.ts +12 -0
  446. package/dist/esm/types/ViewportInputOptions.js +0 -2
  447. package/dist/esm/types/ViewportPreset.d.ts +13 -0
  448. package/dist/esm/types/ViewportPreset.js +0 -2
  449. package/dist/esm/types/ViewportProperties.d.ts +11 -0
  450. package/dist/esm/types/ViewportProperties.js +0 -2
  451. package/dist/esm/types/VolumeLoaderFn.d.ts +7 -0
  452. package/dist/esm/types/VolumeLoaderFn.js +0 -2
  453. package/dist/esm/types/VolumeProps.d.ts +32 -0
  454. package/dist/esm/types/VolumeProps.js +0 -2
  455. package/dist/esm/types/VolumeViewportProperties.d.ts +8 -0
  456. package/dist/esm/types/VolumeViewportProperties.js +0 -2
  457. package/dist/esm/types/WSIViewportProperties.d.ts +3 -0
  458. package/dist/esm/types/WSIViewportProperties.js +0 -0
  459. package/dist/esm/types/displayArea.d.ts +13 -0
  460. package/dist/esm/types/displayArea.js +0 -2
  461. package/dist/esm/types/index.d.ts +99 -0
  462. package/dist/esm/types/index.js +0 -2
  463. package/dist/esm/types/voi.d.ts +9 -0
  464. package/dist/esm/types/voi.js +0 -2
  465. package/dist/esm/utilities/PointsManager.d.ts +31 -0
  466. package/dist/esm/utilities/PointsManager.js +0 -1
  467. package/dist/esm/utilities/ProgressiveIterator.d.ts +24 -0
  468. package/dist/esm/utilities/ProgressiveIterator.js +3 -2
  469. package/dist/esm/utilities/RLEVoxelMap.d.ts +21 -0
  470. package/dist/esm/utilities/RLEVoxelMap.js +9 -10
  471. package/dist/esm/utilities/VoxelManager.d.ts +109 -0
  472. package/dist/esm/utilities/VoxelManager.js +499 -66
  473. package/dist/esm/utilities/actorCheck.d.ts +5 -0
  474. package/dist/esm/utilities/actorCheck.js +0 -1
  475. package/dist/esm/utilities/applyPreset.d.ts +3 -0
  476. package/dist/esm/utilities/applyPreset.js +0 -1
  477. package/dist/esm/utilities/autoLoad.d.ts +2 -0
  478. package/dist/esm/utilities/autoLoad.js +28 -0
  479. package/dist/esm/utilities/calculateViewportsSpatialRegistration.d.ts +3 -0
  480. package/dist/esm/utilities/calculateViewportsSpatialRegistration.js +5 -6
  481. package/dist/esm/utilities/calibratedPixelSpacingMetadataProvider.d.ts +6 -0
  482. package/dist/esm/utilities/calibratedPixelSpacingMetadataProvider.js +0 -1
  483. package/dist/esm/utilities/clamp.d.ts +2 -0
  484. package/dist/esm/utilities/clamp.js +0 -1
  485. package/dist/esm/utilities/clip.d.ts +9 -0
  486. package/dist/esm/utilities/clip.js +8 -0
  487. package/dist/esm/utilities/color.d.ts +7 -0
  488. package/dist/esm/utilities/color.js +0 -1
  489. package/dist/esm/utilities/colormap.d.ts +6 -0
  490. package/dist/esm/utilities/colormap.js +0 -1
  491. package/dist/esm/utilities/convertStackToVolumeViewport.d.ts +12 -0
  492. package/dist/esm/utilities/convertStackToVolumeViewport.js +12 -14
  493. package/dist/esm/utilities/convertToGrayscale.d.ts +1 -0
  494. package/dist/esm/utilities/convertToGrayscale.js +0 -1
  495. package/dist/esm/utilities/convertVolumeToStackViewport.d.ts +9 -0
  496. package/dist/esm/utilities/convertVolumeToStackViewport.js +7 -35
  497. package/dist/esm/utilities/createLinearRGBTransferFunction.d.ts +3 -0
  498. package/dist/esm/utilities/createLinearRGBTransferFunction.js +1 -4
  499. package/dist/esm/utilities/createSigmoidRGBTransferFunction.d.ts +3 -0
  500. package/dist/esm/utilities/createSigmoidRGBTransferFunction.js +8 -8
  501. package/dist/esm/utilities/decimate.d.ts +1 -0
  502. package/dist/esm/utilities/decimate.js +0 -1
  503. package/dist/esm/utilities/deepClone.d.ts +1 -0
  504. package/dist/esm/utilities/deepClone.js +23 -0
  505. package/dist/esm/utilities/deepEqual.d.ts +1 -0
  506. package/dist/esm/utilities/deepEqual.js +15 -0
  507. package/dist/esm/utilities/deepFreeze.d.ts +2 -0
  508. package/dist/esm/utilities/deepFreeze.js +0 -1
  509. package/dist/esm/utilities/deepMerge.d.ts +2 -0
  510. package/dist/esm/utilities/deepMerge.js +0 -1
  511. package/dist/esm/utilities/eventListener/MultiTargetEventListenerManager.d.ts +7 -0
  512. package/dist/esm/utilities/eventListener/MultiTargetEventListenerManager.js +0 -1
  513. package/dist/esm/utilities/eventListener/TargetEventListeners.d.ts +15 -0
  514. package/dist/esm/utilities/eventListener/TargetEventListeners.js +4 -3
  515. package/dist/esm/utilities/eventListener/index.js +0 -1
  516. package/dist/esm/utilities/generateVolumePropsFromImageIds.d.ts +3 -0
  517. package/dist/esm/utilities/generateVolumePropsFromImageIds.js +34 -82
  518. package/dist/esm/utilities/genericMetadataProvider.d.ts +13 -0
  519. package/dist/esm/utilities/genericMetadataProvider.js +7 -2
  520. package/dist/esm/utilities/getBufferConfiguration.d.ts +9 -0
  521. package/dist/esm/utilities/getBufferConfiguration.js +17 -29
  522. package/dist/esm/utilities/getClosestImageId.d.ts +7 -0
  523. package/dist/esm/utilities/getClosestImageId.js +3 -7
  524. package/dist/esm/utilities/getClosestStackImageIndexForPoint.d.ts +6 -0
  525. package/dist/esm/utilities/getClosestStackImageIndexForPoint.js +2 -3
  526. package/dist/esm/utilities/getCurrentVolumeViewportSlice.d.ts +9 -0
  527. package/dist/esm/utilities/getCurrentVolumeViewportSlice.js +8 -59
  528. package/dist/esm/utilities/getDynamicVolumeInfo.d.ts +6 -0
  529. package/dist/esm/utilities/getDynamicVolumeInfo.js +7 -0
  530. package/dist/esm/utilities/getImageLegacy.d.ts +3 -0
  531. package/dist/esm/utilities/getImageLegacy.js +1 -2
  532. package/dist/esm/utilities/getImageSliceDataForVolumeViewport.d.ts +3 -0
  533. package/dist/esm/utilities/getImageSliceDataForVolumeViewport.js +2 -2
  534. package/dist/esm/utilities/getMinMax.d.ts +5 -0
  535. package/dist/esm/utilities/getMinMax.js +0 -1
  536. package/dist/esm/utilities/getRandomSampleFromArray.d.ts +1 -0
  537. package/dist/esm/utilities/getRandomSampleFromArray.js +0 -1
  538. package/dist/esm/utilities/getRuntimeId.d.ts +1 -0
  539. package/dist/esm/utilities/getRuntimeId.js +0 -1
  540. package/dist/esm/utilities/getScalingParameters.d.ts +2 -0
  541. package/dist/esm/utilities/getScalingParameters.js +4 -5
  542. package/dist/esm/utilities/getSliceRange.d.ts +2 -0
  543. package/dist/esm/utilities/getSliceRange.js +0 -1
  544. package/dist/esm/utilities/getSpacingInNormalDirection.d.ts +6 -0
  545. package/dist/esm/utilities/getSpacingInNormalDirection.js +0 -1
  546. package/dist/esm/utilities/getTargetVolumeAndSpacingInNormalDir.d.ts +6 -0
  547. package/dist/esm/utilities/getTargetVolumeAndSpacingInNormalDir.js +3 -4
  548. package/dist/esm/utilities/getViewportImageCornersInWorld.d.ts +2 -0
  549. package/dist/esm/utilities/getViewportImageCornersInWorld.js +0 -1
  550. package/dist/esm/utilities/getViewportImageIds.d.ts +3 -0
  551. package/dist/esm/utilities/getViewportImageIds.js +2 -5
  552. package/dist/esm/utilities/getViewportModality.d.ts +7 -0
  553. package/dist/esm/utilities/getViewportModality.js +9 -7
  554. package/dist/esm/utilities/getViewportsWithImageURI.d.ts +4 -0
  555. package/dist/esm/utilities/getViewportsWithImageURI.js +2 -10
  556. package/dist/esm/utilities/getViewportsWithVolumeId.d.ts +3 -0
  557. package/dist/esm/utilities/getViewportsWithVolumeId.js +3 -10
  558. package/dist/esm/utilities/getViewportsWithVolumeURI.d.ts +3 -0
  559. package/dist/esm/utilities/getViewportsWithVolumeURI.js +14 -0
  560. package/dist/esm/utilities/getVoiFromSigmoidRGBTransferFunction.d.ts +2 -0
  561. package/dist/esm/utilities/getVoiFromSigmoidRGBTransferFunction.js +0 -1
  562. package/dist/esm/utilities/getVolumeActorCorners.d.ts +2 -0
  563. package/dist/esm/utilities/getVolumeActorCorners.js +0 -1
  564. package/dist/esm/utilities/getVolumeId.d.ts +1 -0
  565. package/dist/esm/utilities/getVolumeId.js +2 -3
  566. package/dist/esm/utilities/getVolumeSliceRangeInfo.d.ts +7 -0
  567. package/dist/esm/utilities/getVolumeSliceRangeInfo.js +0 -1
  568. package/dist/esm/utilities/getVolumeViewportScrollInfo.d.ts +11 -0
  569. package/dist/esm/utilities/getVolumeViewportScrollInfo.js +0 -1
  570. package/dist/esm/utilities/getVolumeViewportsContainingSameVolumes.d.ts +3 -0
  571. package/dist/esm/utilities/getVolumeViewportsContainingSameVolumes.js +0 -1
  572. package/dist/esm/utilities/hasFloatScalingParameters.d.ts +2 -0
  573. package/dist/esm/utilities/hasFloatScalingParameters.js +0 -1
  574. package/dist/esm/utilities/hasNaNValues.d.ts +1 -0
  575. package/dist/esm/utilities/hasNaNValues.js +0 -1
  576. package/dist/esm/utilities/imageIdToURI.d.ts +1 -0
  577. package/dist/esm/utilities/imageIdToURI.js +0 -1
  578. package/dist/esm/utilities/imageRetrieveMetadataProvider.d.ts +7 -0
  579. package/dist/esm/utilities/imageRetrieveMetadataProvider.js +0 -1
  580. package/dist/esm/utilities/imageToWorldCoords.d.ts +2 -0
  581. package/dist/esm/utilities/imageToWorldCoords.js +2 -3
  582. package/dist/esm/utilities/index.d.ts +87 -0
  583. package/dist/esm/utilities/index.js +14 -9
  584. package/dist/esm/utilities/indexWithinDimensions.d.ts +2 -0
  585. package/dist/esm/utilities/indexWithinDimensions.js +0 -1
  586. package/dist/esm/utilities/invertRgbTransferFunction.d.ts +2 -0
  587. package/dist/esm/utilities/invertRgbTransferFunction.js +0 -1
  588. package/dist/esm/utilities/isEqual.d.ts +4 -0
  589. package/dist/esm/utilities/isEqual.js +6 -2
  590. package/dist/esm/utilities/isOpposite.d.ts +2 -0
  591. package/dist/esm/utilities/isOpposite.js +0 -1
  592. package/dist/esm/utilities/isPTPrescaledWithSUV.d.ts +3 -0
  593. package/dist/esm/utilities/isPTPrescaledWithSUV.js +1 -2
  594. package/dist/esm/utilities/isValidVolume.d.ts +2 -0
  595. package/dist/esm/utilities/isValidVolume.js +1 -2
  596. package/dist/esm/utilities/isVideoTransferSyntax.d.ts +2 -0
  597. package/dist/esm/utilities/isVideoTransferSyntax.js +0 -1
  598. package/dist/esm/utilities/jumpToSlice.d.ts +3 -0
  599. package/dist/esm/utilities/jumpToSlice.js +35 -0
  600. package/dist/esm/utilities/loadImageToCanvas.d.ts +31 -0
  601. package/dist/esm/utilities/loadImageToCanvas.js +1 -9
  602. package/dist/esm/utilities/makeVolumeMetadata.d.ts +2 -0
  603. package/dist/esm/utilities/makeVolumeMetadata.js +5 -6
  604. package/dist/esm/utilities/planar.d.ts +7 -0
  605. package/dist/esm/utilities/planar.js +0 -1
  606. package/dist/esm/utilities/pointInShapeCallback.d.ts +24 -0
  607. package/dist/esm/utilities/pointInShapeCallback.js +92 -0
  608. package/dist/esm/utilities/renderToCanvasCPU.d.ts +3 -0
  609. package/dist/esm/utilities/renderToCanvasCPU.js +0 -1
  610. package/dist/esm/utilities/renderToCanvasGPU.d.ts +5 -0
  611. package/dist/esm/utilities/renderToCanvasGPU.js +1 -2
  612. package/dist/esm/utilities/roundNumber.d.ts +4 -0
  613. package/dist/esm/utilities/roundNumber.js +0 -1
  614. package/dist/esm/utilities/scaleArray.d.ts +2 -0
  615. package/dist/esm/utilities/scaleArray.js +15 -0
  616. package/dist/esm/utilities/scaleRgbTransferFunction.d.ts +2 -0
  617. package/dist/esm/utilities/scaleRgbTransferFunction.js +0 -1
  618. package/dist/esm/utilities/scroll.d.ts +4 -0
  619. package/dist/esm/utilities/scroll.js +66 -0
  620. package/dist/esm/utilities/snapFocalPointToSlice.d.ts +5 -0
  621. package/dist/esm/utilities/snapFocalPointToSlice.js +0 -1
  622. package/dist/esm/utilities/sortImageIdsAndGetSpacing.d.ts +9 -0
  623. package/dist/esm/utilities/sortImageIdsAndGetSpacing.js +2 -2
  624. package/dist/esm/utilities/spatialRegistrationMetadataProvider.d.ts +6 -0
  625. package/dist/esm/utilities/spatialRegistrationMetadataProvider.js +0 -1
  626. package/dist/esm/utilities/splitImageIdsBy4DTags.d.ts +5 -0
  627. package/dist/esm/utilities/splitImageIdsBy4DTags.js +161 -0
  628. package/dist/esm/utilities/transferFunctionUtils.d.ts +3 -0
  629. package/dist/esm/utilities/transferFunctionUtils.js +0 -1
  630. package/dist/esm/utilities/transformCanvasToIJK.d.ts +2 -0
  631. package/dist/esm/utilities/transformCanvasToIJK.js +0 -1
  632. package/dist/esm/utilities/transformIJKToCanvas.d.ts +2 -0
  633. package/dist/esm/utilities/transformIJKToCanvas.js +0 -1
  634. package/dist/esm/utilities/transformIndexToWorld.d.ts +2 -0
  635. package/dist/esm/utilities/transformIndexToWorld.js +0 -1
  636. package/dist/esm/utilities/transformWorldToIndex.d.ts +2 -0
  637. package/dist/esm/utilities/transformWorldToIndex.js +0 -1
  638. package/dist/esm/utilities/triggerEvent.d.ts +1 -0
  639. package/dist/esm/utilities/triggerEvent.js +1 -2
  640. package/dist/esm/utilities/updateVTKImageDataWithCornerstoneImage.d.ts +4 -0
  641. package/dist/esm/utilities/updateVTKImageDataWithCornerstoneImage.js +1 -2
  642. package/dist/esm/utilities/uuidv4.d.ts +1 -0
  643. package/dist/esm/utilities/uuidv4.js +5 -2
  644. package/dist/esm/utilities/windowLevel.d.ts +9 -0
  645. package/dist/esm/utilities/windowLevel.js +0 -1
  646. package/dist/esm/utilities/worldToImageCoords.d.ts +3 -0
  647. package/dist/esm/utilities/worldToImageCoords.js +2 -3
  648. package/dist/esm/webWorkerManager/webWorkerManager.d.ts +28 -0
  649. package/dist/esm/webWorkerManager/webWorkerManager.js +0 -1
  650. package/package.json +57 -24
  651. package/dist/esm/RenderingEngine/BaseVolumeViewport.js.map +0 -1
  652. package/dist/esm/RenderingEngine/CanvasActor/CanvasMapper.js.map +0 -1
  653. package/dist/esm/RenderingEngine/CanvasActor/CanvasProperties.js.map +0 -1
  654. package/dist/esm/RenderingEngine/CanvasActor/index.js.map +0 -1
  655. package/dist/esm/RenderingEngine/RenderingEngine.js.map +0 -1
  656. package/dist/esm/RenderingEngine/StackViewport.js.map +0 -1
  657. package/dist/esm/RenderingEngine/VideoViewport.js.map +0 -1
  658. package/dist/esm/RenderingEngine/Viewport.js.map +0 -1
  659. package/dist/esm/RenderingEngine/VolumeViewport.js.map +0 -1
  660. package/dist/esm/RenderingEngine/VolumeViewport3D.js.map +0 -1
  661. package/dist/esm/RenderingEngine/getRenderingEngine.js.map +0 -1
  662. package/dist/esm/RenderingEngine/helpers/addImageSlicesToViewports.js.map +0 -1
  663. package/dist/esm/RenderingEngine/helpers/addVolumesToViewports.js.map +0 -1
  664. package/dist/esm/RenderingEngine/helpers/cpuFallback/colors/colormap.js.map +0 -1
  665. package/dist/esm/RenderingEngine/helpers/cpuFallback/colors/index.js.map +0 -1
  666. package/dist/esm/RenderingEngine/helpers/cpuFallback/colors/lookupTable.js.map +0 -1
  667. package/dist/esm/RenderingEngine/helpers/cpuFallback/drawImageSync.js.map +0 -1
  668. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/calculateTransform.js.map +0 -1
  669. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/canvasToPixel.js.map +0 -1
  670. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/computeAutoVoi.js.map +0 -1
  671. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/correctShift.js.map +0 -1
  672. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/createViewport.js.map +0 -1
  673. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/doesImageNeedToBeRendered.js.map +0 -1
  674. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/fitToWindow.js.map +0 -1
  675. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/generateColorLUT.js.map +0 -1
  676. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/generateLut.js.map +0 -1
  677. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/getDefaultViewport.js.map +0 -1
  678. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/getImageFitScale.js.map +0 -1
  679. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/getImageSize.js.map +0 -1
  680. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/getLut.js.map +0 -1
  681. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/getModalityLut.js.map +0 -1
  682. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/getTransform.js.map +0 -1
  683. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/getVOILut.js.map +0 -1
  684. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/initializeRenderCanvas.js.map +0 -1
  685. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/lutMatches.js.map +0 -1
  686. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/now.js.map +0 -1
  687. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/pixelToCanvas.js.map +0 -1
  688. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/renderColorImage.js.map +0 -1
  689. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/renderGrayscaleImage.js.map +0 -1
  690. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/renderPseudoColorImage.js.map +0 -1
  691. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/resetCamera.js.map +0 -1
  692. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/resize.js.map +0 -1
  693. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/saveLastRendered.js.map +0 -1
  694. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/setDefaultViewport.js.map +0 -1
  695. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/setToPixelCoordinateSystem.js.map +0 -1
  696. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/storedColorPixelDataToCanvasImageData.js.map +0 -1
  697. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageData.js.map +0 -1
  698. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataColorLUT.js.map +0 -1
  699. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPET.js.map +0 -1
  700. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPseudocolorLUT.js.map +0 -1
  701. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPseudocolorLUTPET.js.map +0 -1
  702. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataRGBA.js.map +0 -1
  703. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/storedRGBAPixelDataToCanvasImageData.js.map +0 -1
  704. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/transform.js.map +0 -1
  705. package/dist/esm/RenderingEngine/helpers/cpuFallback/rendering/validator.js.map +0 -1
  706. package/dist/esm/RenderingEngine/helpers/createVolumeActor.js.map +0 -1
  707. package/dist/esm/RenderingEngine/helpers/createVolumeMapper.js.map +0 -1
  708. package/dist/esm/RenderingEngine/helpers/getOrCreateCanvas.js.map +0 -1
  709. package/dist/esm/RenderingEngine/helpers/index.js.map +0 -1
  710. package/dist/esm/RenderingEngine/helpers/isRgbaSourceRgbDest.js.map +0 -1
  711. package/dist/esm/RenderingEngine/helpers/setDefaultVolumeVOI.js.map +0 -1
  712. package/dist/esm/RenderingEngine/helpers/setVolumesForViewports.js.map +0 -1
  713. package/dist/esm/RenderingEngine/helpers/viewportTypeToViewportClass.js.map +0 -1
  714. package/dist/esm/RenderingEngine/helpers/viewportTypeUsesCustomRenderingPipeline.js.map +0 -1
  715. package/dist/esm/RenderingEngine/helpers/volumeNewImageEventDispatcher.js.map +0 -1
  716. package/dist/esm/RenderingEngine/index.js.map +0 -1
  717. package/dist/esm/RenderingEngine/renderingEngineCache.js.map +0 -1
  718. package/dist/esm/RenderingEngine/vtkClasses/index.js.map +0 -1
  719. package/dist/esm/RenderingEngine/vtkClasses/vtkOffscreenMultiRenderWindow.js.map +0 -1
  720. package/dist/esm/RenderingEngine/vtkClasses/vtkSharedVolumeMapper.js.map +0 -1
  721. package/dist/esm/RenderingEngine/vtkClasses/vtkSlabCamera.js.map +0 -1
  722. package/dist/esm/RenderingEngine/vtkClasses/vtkStreamingOpenGLRenderWindow.js.map +0 -1
  723. package/dist/esm/RenderingEngine/vtkClasses/vtkStreamingOpenGLTexture.js.map +0 -1
  724. package/dist/esm/RenderingEngine/vtkClasses/vtkStreamingOpenGLViewNodeFactory.js.map +0 -1
  725. package/dist/esm/RenderingEngine/vtkClasses/vtkStreamingOpenGLVolumeMapper.js.map +0 -1
  726. package/dist/esm/Settings.js.map +0 -1
  727. package/dist/esm/cache/cache.js.map +0 -1
  728. package/dist/esm/cache/classes/Contour.js.map +0 -1
  729. package/dist/esm/cache/classes/ContourSet.js.map +0 -1
  730. package/dist/esm/cache/classes/ImageVolume.js.map +0 -1
  731. package/dist/esm/cache/classes/Surface.js.map +0 -1
  732. package/dist/esm/cache/index.js.map +0 -1
  733. package/dist/esm/constants/backgroundColors.js.map +0 -1
  734. package/dist/esm/constants/cpuColormaps.js.map +0 -1
  735. package/dist/esm/constants/epsilon.js.map +0 -1
  736. package/dist/esm/constants/index.js.map +0 -1
  737. package/dist/esm/constants/mprCameraValues.js.map +0 -1
  738. package/dist/esm/constants/rendering.js.map +0 -1
  739. package/dist/esm/constants/viewportPresets.js.map +0 -1
  740. package/dist/esm/enums/BlendModes.js.map +0 -1
  741. package/dist/esm/enums/CalibrationTypes.js.map +0 -1
  742. package/dist/esm/enums/ContourType.js.map +0 -1
  743. package/dist/esm/enums/DynamicOperatorType.js.map +0 -1
  744. package/dist/esm/enums/Events.js.map +0 -1
  745. package/dist/esm/enums/GeometryType.js.map +0 -1
  746. package/dist/esm/enums/ImageQualityStatus.js.map +0 -1
  747. package/dist/esm/enums/InterpolationType.js.map +0 -1
  748. package/dist/esm/enums/MetadataModules.js.map +0 -1
  749. package/dist/esm/enums/OrientationAxis.js.map +0 -1
  750. package/dist/esm/enums/RequestType.js.map +0 -1
  751. package/dist/esm/enums/SharedArrayBufferModes.js +0 -8
  752. package/dist/esm/enums/SharedArrayBufferModes.js.map +0 -1
  753. package/dist/esm/enums/VOILUTFunctionType.js.map +0 -1
  754. package/dist/esm/enums/VideoEnums.js.map +0 -1
  755. package/dist/esm/enums/ViewportStatus.js.map +0 -1
  756. package/dist/esm/enums/ViewportType.js.map +0 -1
  757. package/dist/esm/enums/index.js.map +0 -1
  758. package/dist/esm/eventTarget.js.map +0 -1
  759. package/dist/esm/getEnabledElement.js.map +0 -1
  760. package/dist/esm/global.js.map +0 -1
  761. package/dist/esm/index.js.map +0 -1
  762. package/dist/esm/init.js.map +0 -1
  763. package/dist/esm/loaders/ProgressiveRetrieveImages.js.map +0 -1
  764. package/dist/esm/loaders/configuration/interleavedRetrieve.js.map +0 -1
  765. package/dist/esm/loaders/configuration/sequentialRetrieve.js.map +0 -1
  766. package/dist/esm/loaders/configuration/singleRetrieve.js.map +0 -1
  767. package/dist/esm/loaders/fillNearbyFrames.js.map +0 -1
  768. package/dist/esm/loaders/geometryLoader.js.map +0 -1
  769. package/dist/esm/loaders/imageLoader.js.map +0 -1
  770. package/dist/esm/loaders/utils/contourSet/createContourSet.js.map +0 -1
  771. package/dist/esm/loaders/utils/contourSet/validateContourSet.js.map +0 -1
  772. package/dist/esm/loaders/utils/surface/createSurface.js.map +0 -1
  773. package/dist/esm/loaders/utils/surface/validateSurface.js.map +0 -1
  774. package/dist/esm/loaders/volumeLoader.js.map +0 -1
  775. package/dist/esm/metaData.js.map +0 -1
  776. package/dist/esm/requestPool/imageLoadPoolManager.js.map +0 -1
  777. package/dist/esm/requestPool/imageRetrievalPoolManager.js.map +0 -1
  778. package/dist/esm/requestPool/requestPoolManager.js.map +0 -1
  779. package/dist/esm/types/AABB2.js.map +0 -1
  780. package/dist/esm/types/AABB3.js.map +0 -1
  781. package/dist/esm/types/ActorSliceRange.js.map +0 -1
  782. package/dist/esm/types/AffineMatrix.js.map +0 -1
  783. package/dist/esm/types/BoundsIJK.js.map +0 -1
  784. package/dist/esm/types/BoundsLPS.js.map +0 -1
  785. package/dist/esm/types/CPUFallbackColormap.js.map +0 -1
  786. package/dist/esm/types/CPUFallbackColormapData.js.map +0 -1
  787. package/dist/esm/types/CPUFallbackColormapsData.js.map +0 -1
  788. package/dist/esm/types/CPUFallbackEnabledElement.js.map +0 -1
  789. package/dist/esm/types/CPUFallbackLUT.js.map +0 -1
  790. package/dist/esm/types/CPUFallbackLookupTable.js.map +0 -1
  791. package/dist/esm/types/CPUFallbackRenderingTools.js.map +0 -1
  792. package/dist/esm/types/CPUFallbackTransform.js.map +0 -1
  793. package/dist/esm/types/CPUFallbackViewport.js.map +0 -1
  794. package/dist/esm/types/CPUFallbackViewportDisplayedArea.js.map +0 -1
  795. package/dist/esm/types/CPUIImageData.js.map +0 -1
  796. package/dist/esm/types/Color.js.map +0 -1
  797. package/dist/esm/types/Colormap.js.map +0 -1
  798. package/dist/esm/types/ContourData.js.map +0 -1
  799. package/dist/esm/types/Cornerstone3DConfig.js.map +0 -1
  800. package/dist/esm/types/CustomEventType.js.map +0 -1
  801. package/dist/esm/types/EventTypes.js.map +0 -1
  802. package/dist/esm/types/FlipDirection.js.map +0 -1
  803. package/dist/esm/types/IActor.js.map +0 -1
  804. package/dist/esm/types/ICache.js.map +0 -1
  805. package/dist/esm/types/ICachedGeometry.js.map +0 -1
  806. package/dist/esm/types/ICachedImage.js.map +0 -1
  807. package/dist/esm/types/ICachedVolume.js.map +0 -1
  808. package/dist/esm/types/ICamera.js.map +0 -1
  809. package/dist/esm/types/IContour.js.map +0 -1
  810. package/dist/esm/types/IContourSet.js.map +0 -1
  811. package/dist/esm/types/IDynamicImageVolume.js.map +0 -1
  812. package/dist/esm/types/IEnabledElement.js.map +0 -1
  813. package/dist/esm/types/IGeometry.js.map +0 -1
  814. package/dist/esm/types/IImage.js.map +0 -1
  815. package/dist/esm/types/IImageCalibration.js.map +0 -1
  816. package/dist/esm/types/IImageData.js.map +0 -1
  817. package/dist/esm/types/IImageVolume.js.map +0 -1
  818. package/dist/esm/types/ILoadObject.js.map +0 -1
  819. package/dist/esm/types/IRegisterImageLoader.js.map +0 -1
  820. package/dist/esm/types/IRenderingEngine.js.map +0 -1
  821. package/dist/esm/types/IRetrieveConfiguration.js.map +0 -1
  822. package/dist/esm/types/IStackInput.js.map +0 -1
  823. package/dist/esm/types/IStackViewport.js.map +0 -1
  824. package/dist/esm/types/IStreamingImageVolume.js.map +0 -1
  825. package/dist/esm/types/IStreamingVolumeProperties.js.map +0 -1
  826. package/dist/esm/types/ISurface.js.map +0 -1
  827. package/dist/esm/types/IVideoViewport.js.map +0 -1
  828. package/dist/esm/types/IViewport.js.map +0 -1
  829. package/dist/esm/types/IViewportId.js.map +0 -1
  830. package/dist/esm/types/IVolume.js.map +0 -1
  831. package/dist/esm/types/IVolumeInput.js.map +0 -1
  832. package/dist/esm/types/IVolumeViewport.js.map +0 -1
  833. package/dist/esm/types/ImageLoadListener.js.map +0 -1
  834. package/dist/esm/types/ImageLoaderFn.js.map +0 -1
  835. package/dist/esm/types/ImagePixelModule.js.map +0 -1
  836. package/dist/esm/types/ImagePlaneModule.js.map +0 -1
  837. package/dist/esm/types/ImageSliceData.js.map +0 -1
  838. package/dist/esm/types/ImageVolumeProps.js.map +0 -1
  839. package/dist/esm/types/Mat3.js.map +0 -1
  840. package/dist/esm/types/Metadata.js.map +0 -1
  841. package/dist/esm/types/OrientationVectors.js.map +0 -1
  842. package/dist/esm/types/PixelDataTypedArray.js.map +0 -1
  843. package/dist/esm/types/Plane.js.map +0 -1
  844. package/dist/esm/types/Point2.js.map +0 -1
  845. package/dist/esm/types/Point3.js.map +0 -1
  846. package/dist/esm/types/Point4.js.map +0 -1
  847. package/dist/esm/types/RGB.js.map +0 -1
  848. package/dist/esm/types/ScalingParameters.js.map +0 -1
  849. package/dist/esm/types/StackViewportProperties.js.map +0 -1
  850. package/dist/esm/types/SurfaceData.js.map +0 -1
  851. package/dist/esm/types/TransformMatrix2D.js.map +0 -1
  852. package/dist/esm/types/VideoViewportProperties.js.map +0 -1
  853. package/dist/esm/types/VideoViewportTypes.js.map +0 -1
  854. package/dist/esm/types/ViewportInputOptions.js.map +0 -1
  855. package/dist/esm/types/ViewportPreset.js.map +0 -1
  856. package/dist/esm/types/ViewportProperties.js.map +0 -1
  857. package/dist/esm/types/VolumeLoaderFn.js.map +0 -1
  858. package/dist/esm/types/VolumeProps.js.map +0 -1
  859. package/dist/esm/types/VolumeViewportProperties.js.map +0 -1
  860. package/dist/esm/types/displayArea.js.map +0 -1
  861. package/dist/esm/types/index.js.map +0 -1
  862. package/dist/esm/types/voi.js.map +0 -1
  863. package/dist/esm/utilities/PointsManager.js.map +0 -1
  864. package/dist/esm/utilities/ProgressiveIterator.js.map +0 -1
  865. package/dist/esm/utilities/RLEVoxelMap.js.map +0 -1
  866. package/dist/esm/utilities/VoxelManager.js.map +0 -1
  867. package/dist/esm/utilities/actorCheck.js.map +0 -1
  868. package/dist/esm/utilities/applyPreset.js.map +0 -1
  869. package/dist/esm/utilities/cacheUtils.js +0 -79
  870. package/dist/esm/utilities/cacheUtils.js.map +0 -1
  871. package/dist/esm/utilities/calculateViewportsSpatialRegistration.js.map +0 -1
  872. package/dist/esm/utilities/calibratedPixelSpacingMetadataProvider.js.map +0 -1
  873. package/dist/esm/utilities/clamp.js.map +0 -1
  874. package/dist/esm/utilities/color.js.map +0 -1
  875. package/dist/esm/utilities/colormap.js.map +0 -1
  876. package/dist/esm/utilities/convertStackToVolumeViewport.js.map +0 -1
  877. package/dist/esm/utilities/convertToGrayscale.js.map +0 -1
  878. package/dist/esm/utilities/convertVolumeToStackViewport.js.map +0 -1
  879. package/dist/esm/utilities/createFloat32SharedArray.js +0 -28
  880. package/dist/esm/utilities/createFloat32SharedArray.js.map +0 -1
  881. package/dist/esm/utilities/createInt16SharedArray.js +0 -12
  882. package/dist/esm/utilities/createInt16SharedArray.js.map +0 -1
  883. package/dist/esm/utilities/createLinearRGBTransferFunction.js.map +0 -1
  884. package/dist/esm/utilities/createSigmoidRGBTransferFunction.js.map +0 -1
  885. package/dist/esm/utilities/createUInt16SharedArray.js +0 -12
  886. package/dist/esm/utilities/createUInt16SharedArray.js.map +0 -1
  887. package/dist/esm/utilities/createUint8SharedArray.js +0 -13
  888. package/dist/esm/utilities/createUint8SharedArray.js.map +0 -1
  889. package/dist/esm/utilities/decimate.js.map +0 -1
  890. package/dist/esm/utilities/deepFreeze.js.map +0 -1
  891. package/dist/esm/utilities/deepMerge.js.map +0 -1
  892. package/dist/esm/utilities/eventListener/MultiTargetEventListenerManager.js.map +0 -1
  893. package/dist/esm/utilities/eventListener/TargetEventListeners.js.map +0 -1
  894. package/dist/esm/utilities/eventListener/index.js.map +0 -1
  895. package/dist/esm/utilities/generateVolumePropsFromImageIds.js.map +0 -1
  896. package/dist/esm/utilities/genericMetadataProvider.js.map +0 -1
  897. package/dist/esm/utilities/getBufferConfiguration.js.map +0 -1
  898. package/dist/esm/utilities/getClosestImageId.js.map +0 -1
  899. package/dist/esm/utilities/getClosestStackImageIndexForPoint.js.map +0 -1
  900. package/dist/esm/utilities/getCurrentVolumeViewportSlice.js.map +0 -1
  901. package/dist/esm/utilities/getImageLegacy.js.map +0 -1
  902. package/dist/esm/utilities/getImageSliceDataForVolumeViewport.js.map +0 -1
  903. package/dist/esm/utilities/getMinMax.js.map +0 -1
  904. package/dist/esm/utilities/getRandomSampleFromArray.js.map +0 -1
  905. package/dist/esm/utilities/getRuntimeId.js.map +0 -1
  906. package/dist/esm/utilities/getScalarDataType.js +0 -20
  907. package/dist/esm/utilities/getScalarDataType.js.map +0 -1
  908. package/dist/esm/utilities/getScalingParameters.js.map +0 -1
  909. package/dist/esm/utilities/getSliceRange.js.map +0 -1
  910. package/dist/esm/utilities/getSpacingInNormalDirection.js.map +0 -1
  911. package/dist/esm/utilities/getTargetVolumeAndSpacingInNormalDir.js.map +0 -1
  912. package/dist/esm/utilities/getViewportImageCornersInWorld.js.map +0 -1
  913. package/dist/esm/utilities/getViewportImageIds.js.map +0 -1
  914. package/dist/esm/utilities/getViewportModality.js.map +0 -1
  915. package/dist/esm/utilities/getViewportsWithImageURI.js.map +0 -1
  916. package/dist/esm/utilities/getViewportsWithVolumeId.js.map +0 -1
  917. package/dist/esm/utilities/getVoiFromSigmoidRGBTransferFunction.js.map +0 -1
  918. package/dist/esm/utilities/getVolumeActorCorners.js.map +0 -1
  919. package/dist/esm/utilities/getVolumeId.js.map +0 -1
  920. package/dist/esm/utilities/getVolumeSliceRangeInfo.js.map +0 -1
  921. package/dist/esm/utilities/getVolumeViewportScrollInfo.js.map +0 -1
  922. package/dist/esm/utilities/getVolumeViewportsContainingSameVolumes.js.map +0 -1
  923. package/dist/esm/utilities/hasFloatScalingParameters.js.map +0 -1
  924. package/dist/esm/utilities/hasNaNValues.js.map +0 -1
  925. package/dist/esm/utilities/imageIdToURI.js.map +0 -1
  926. package/dist/esm/utilities/imageRetrieveMetadataProvider.js.map +0 -1
  927. package/dist/esm/utilities/imageToWorldCoords.js.map +0 -1
  928. package/dist/esm/utilities/index.js.map +0 -1
  929. package/dist/esm/utilities/indexWithinDimensions.js.map +0 -1
  930. package/dist/esm/utilities/invertRgbTransferFunction.js.map +0 -1
  931. package/dist/esm/utilities/isEqual.js.map +0 -1
  932. package/dist/esm/utilities/isOpposite.js.map +0 -1
  933. package/dist/esm/utilities/isPTPrescaledWithSUV.js.map +0 -1
  934. package/dist/esm/utilities/isTypedArray.js +0 -12
  935. package/dist/esm/utilities/isTypedArray.js.map +0 -1
  936. package/dist/esm/utilities/isValidVolume.js.map +0 -1
  937. package/dist/esm/utilities/isVideoTransferSyntax.js.map +0 -1
  938. package/dist/esm/utilities/loadImageToCanvas.js.map +0 -1
  939. package/dist/esm/utilities/makeVolumeMetadata.js.map +0 -1
  940. package/dist/esm/utilities/planar.js.map +0 -1
  941. package/dist/esm/utilities/renderToCanvasCPU.js.map +0 -1
  942. package/dist/esm/utilities/renderToCanvasGPU.js.map +0 -1
  943. package/dist/esm/utilities/roundNumber.js.map +0 -1
  944. package/dist/esm/utilities/scaleRgbTransferFunction.js.map +0 -1
  945. package/dist/esm/utilities/snapFocalPointToSlice.js.map +0 -1
  946. package/dist/esm/utilities/sortImageIdsAndGetSpacing.js.map +0 -1
  947. package/dist/esm/utilities/spatialRegistrationMetadataProvider.js.map +0 -1
  948. package/dist/esm/utilities/transferFunctionUtils.js.map +0 -1
  949. package/dist/esm/utilities/transformCanvasToIJK.js.map +0 -1
  950. package/dist/esm/utilities/transformIJKToCanvas.js.map +0 -1
  951. package/dist/esm/utilities/transformIndexToWorld.js.map +0 -1
  952. package/dist/esm/utilities/transformWorldToIndex.js.map +0 -1
  953. package/dist/esm/utilities/triggerEvent.js.map +0 -1
  954. package/dist/esm/utilities/updateVTKImageDataWithCornerstoneImage.js.map +0 -1
  955. package/dist/esm/utilities/uuidv4.js.map +0 -1
  956. package/dist/esm/utilities/windowLevel.js.map +0 -1
  957. package/dist/esm/utilities/worldToImageCoords.js.map +0 -1
  958. package/dist/esm/webWorkerManager/webWorkerManager.js.map +0 -1
  959. package/dist/types/RenderingEngine/BaseVolumeViewport.d.ts +0 -72
  960. package/dist/types/RenderingEngine/BaseVolumeViewport.d.ts.map +0 -1
  961. package/dist/types/RenderingEngine/CanvasActor/CanvasMapper.d.ts +0 -7
  962. package/dist/types/RenderingEngine/CanvasActor/CanvasMapper.d.ts.map +0 -1
  963. package/dist/types/RenderingEngine/CanvasActor/CanvasProperties.d.ts +0 -16
  964. package/dist/types/RenderingEngine/CanvasActor/CanvasProperties.d.ts.map +0 -1
  965. package/dist/types/RenderingEngine/CanvasActor/index.d.ts +0 -24
  966. package/dist/types/RenderingEngine/CanvasActor/index.d.ts.map +0 -1
  967. package/dist/types/RenderingEngine/RenderingEngine.d.ts +0 -61
  968. package/dist/types/RenderingEngine/RenderingEngine.d.ts.map +0 -1
  969. package/dist/types/RenderingEngine/StackViewport.d.ts +0 -210
  970. package/dist/types/RenderingEngine/StackViewport.d.ts.map +0 -1
  971. package/dist/types/RenderingEngine/VideoViewport.d.ts +0 -132
  972. package/dist/types/RenderingEngine/VideoViewport.d.ts.map +0 -1
  973. package/dist/types/RenderingEngine/Viewport.d.ts +0 -118
  974. package/dist/types/RenderingEngine/Viewport.d.ts.map +0 -1
  975. package/dist/types/RenderingEngine/VolumeViewport.d.ts +0 -37
  976. package/dist/types/RenderingEngine/VolumeViewport.d.ts.map +0 -1
  977. package/dist/types/RenderingEngine/VolumeViewport3D.d.ts +0 -16
  978. package/dist/types/RenderingEngine/VolumeViewport3D.d.ts.map +0 -1
  979. package/dist/types/RenderingEngine/getRenderingEngine.d.ts +0 -5
  980. package/dist/types/RenderingEngine/getRenderingEngine.d.ts.map +0 -1
  981. package/dist/types/RenderingEngine/helpers/addImageSlicesToViewports.d.ts +0 -4
  982. package/dist/types/RenderingEngine/helpers/addImageSlicesToViewports.d.ts.map +0 -1
  983. package/dist/types/RenderingEngine/helpers/addVolumesToViewports.d.ts +0 -4
  984. package/dist/types/RenderingEngine/helpers/addVolumesToViewports.d.ts.map +0 -1
  985. package/dist/types/RenderingEngine/helpers/cpuFallback/colors/colormap.d.ts +0 -4
  986. package/dist/types/RenderingEngine/helpers/cpuFallback/colors/colormap.d.ts.map +0 -1
  987. package/dist/types/RenderingEngine/helpers/cpuFallback/colors/index.d.ts +0 -4
  988. package/dist/types/RenderingEngine/helpers/cpuFallback/colors/index.d.ts.map +0 -1
  989. package/dist/types/RenderingEngine/helpers/cpuFallback/colors/lookupTable.d.ts +0 -34
  990. package/dist/types/RenderingEngine/helpers/cpuFallback/colors/lookupTable.d.ts.map +0 -1
  991. package/dist/types/RenderingEngine/helpers/cpuFallback/drawImageSync.d.ts +0 -3
  992. package/dist/types/RenderingEngine/helpers/cpuFallback/drawImageSync.d.ts.map +0 -1
  993. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/calculateTransform.d.ts +0 -3
  994. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/calculateTransform.d.ts.map +0 -1
  995. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/canvasToPixel.d.ts +0 -3
  996. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/canvasToPixel.d.ts.map +0 -1
  997. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/computeAutoVoi.d.ts +0 -3
  998. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/computeAutoVoi.d.ts.map +0 -1
  999. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/correctShift.d.ts +0 -8
  1000. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/correctShift.d.ts.map +0 -1
  1001. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/createViewport.d.ts +0 -3
  1002. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/createViewport.d.ts.map +0 -1
  1003. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/doesImageNeedToBeRendered.d.ts +0 -3
  1004. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/doesImageNeedToBeRendered.d.ts.map +0 -1
  1005. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/fitToWindow.d.ts +0 -3
  1006. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/fitToWindow.d.ts.map +0 -1
  1007. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/generateColorLUT.d.ts +0 -3
  1008. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/generateColorLUT.d.ts.map +0 -1
  1009. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/generateLut.d.ts +0 -3
  1010. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/generateLut.d.ts.map +0 -1
  1011. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/getDefaultViewport.d.ts +0 -3
  1012. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/getDefaultViewport.d.ts.map +0 -1
  1013. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/getImageFitScale.d.ts +0 -7
  1014. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/getImageFitScale.d.ts.map +0 -1
  1015. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/getImageSize.d.ts +0 -6
  1016. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/getImageSize.d.ts.map +0 -1
  1017. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/getLut.d.ts +0 -3
  1018. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/getLut.d.ts.map +0 -1
  1019. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/getModalityLut.d.ts +0 -2
  1020. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/getModalityLut.d.ts.map +0 -1
  1021. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/getTransform.d.ts +0 -3
  1022. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/getTransform.d.ts.map +0 -1
  1023. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/getVOILut.d.ts +0 -2
  1024. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/getVOILut.d.ts.map +0 -1
  1025. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/initializeRenderCanvas.d.ts +0 -3
  1026. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/initializeRenderCanvas.d.ts.map +0 -1
  1027. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/lutMatches.d.ts +0 -2
  1028. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/lutMatches.d.ts.map +0 -1
  1029. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/now.d.ts +0 -2
  1030. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/now.d.ts.map +0 -1
  1031. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/pixelToCanvas.d.ts +0 -3
  1032. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/pixelToCanvas.d.ts.map +0 -1
  1033. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/renderColorImage.d.ts +0 -3
  1034. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/renderColorImage.d.ts.map +0 -1
  1035. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/renderGrayscaleImage.d.ts +0 -3
  1036. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/renderGrayscaleImage.d.ts.map +0 -1
  1037. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/renderPseudoColorImage.d.ts +0 -3
  1038. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/renderPseudoColorImage.d.ts.map +0 -1
  1039. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/resetCamera.d.ts +0 -3
  1040. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/resetCamera.d.ts.map +0 -1
  1041. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/resize.d.ts +0 -3
  1042. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/resize.d.ts.map +0 -1
  1043. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/saveLastRendered.d.ts +0 -3
  1044. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/saveLastRendered.d.ts.map +0 -1
  1045. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/setDefaultViewport.d.ts +0 -7
  1046. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/setDefaultViewport.d.ts.map +0 -1
  1047. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/setToPixelCoordinateSystem.d.ts +0 -3
  1048. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/setToPixelCoordinateSystem.d.ts.map +0 -1
  1049. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/storedColorPixelDataToCanvasImageData.d.ts +0 -3
  1050. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/storedColorPixelDataToCanvasImageData.d.ts.map +0 -1
  1051. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageData.d.ts +0 -3
  1052. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageData.d.ts.map +0 -1
  1053. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataColorLUT.d.ts +0 -4
  1054. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataColorLUT.d.ts.map +0 -1
  1055. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPET.d.ts +0 -3
  1056. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPET.d.ts.map +0 -1
  1057. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPseudocolorLUT.d.ts +0 -4
  1058. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPseudocolorLUT.d.ts.map +0 -1
  1059. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPseudocolorLUTPET.d.ts +0 -4
  1060. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPseudocolorLUTPET.d.ts.map +0 -1
  1061. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataRGBA.d.ts +0 -3
  1062. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataRGBA.d.ts.map +0 -1
  1063. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/storedRGBAPixelDataToCanvasImageData.d.ts +0 -3
  1064. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/storedRGBAPixelDataToCanvasImageData.d.ts.map +0 -1
  1065. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/transform.d.ts +0 -15
  1066. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/transform.d.ts.map +0 -1
  1067. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/validator.d.ts +0 -3
  1068. package/dist/types/RenderingEngine/helpers/cpuFallback/rendering/validator.d.ts.map +0 -1
  1069. package/dist/types/RenderingEngine/helpers/createVolumeActor.d.ts +0 -13
  1070. package/dist/types/RenderingEngine/helpers/createVolumeActor.d.ts.map +0 -1
  1071. package/dist/types/RenderingEngine/helpers/createVolumeMapper.d.ts +0 -2
  1072. package/dist/types/RenderingEngine/helpers/createVolumeMapper.d.ts.map +0 -1
  1073. package/dist/types/RenderingEngine/helpers/getOrCreateCanvas.d.ts +0 -4
  1074. package/dist/types/RenderingEngine/helpers/getOrCreateCanvas.d.ts.map +0 -1
  1075. package/dist/types/RenderingEngine/helpers/index.d.ts +0 -9
  1076. package/dist/types/RenderingEngine/helpers/index.d.ts.map +0 -1
  1077. package/dist/types/RenderingEngine/helpers/isRgbaSourceRgbDest.d.ts +0 -3
  1078. package/dist/types/RenderingEngine/helpers/isRgbaSourceRgbDest.d.ts.map +0 -1
  1079. package/dist/types/RenderingEngine/helpers/setDefaultVolumeVOI.d.ts +0 -4
  1080. package/dist/types/RenderingEngine/helpers/setDefaultVolumeVOI.d.ts.map +0 -1
  1081. package/dist/types/RenderingEngine/helpers/setVolumesForViewports.d.ts +0 -4
  1082. package/dist/types/RenderingEngine/helpers/setVolumesForViewports.d.ts.map +0 -1
  1083. package/dist/types/RenderingEngine/helpers/viewportTypeToViewportClass.d.ts +0 -13
  1084. package/dist/types/RenderingEngine/helpers/viewportTypeToViewportClass.d.ts.map +0 -1
  1085. package/dist/types/RenderingEngine/helpers/viewportTypeUsesCustomRenderingPipeline.d.ts +0 -2
  1086. package/dist/types/RenderingEngine/helpers/viewportTypeUsesCustomRenderingPipeline.d.ts.map +0 -1
  1087. package/dist/types/RenderingEngine/helpers/volumeNewImageEventDispatcher.d.ts +0 -5
  1088. package/dist/types/RenderingEngine/helpers/volumeNewImageEventDispatcher.d.ts.map +0 -1
  1089. package/dist/types/RenderingEngine/index.d.ts +0 -9
  1090. package/dist/types/RenderingEngine/index.d.ts.map +0 -1
  1091. package/dist/types/RenderingEngine/renderingEngineCache.d.ts +0 -9
  1092. package/dist/types/RenderingEngine/renderingEngineCache.d.ts.map +0 -1
  1093. package/dist/types/RenderingEngine/vtkClasses/index.d.ts +0 -6
  1094. package/dist/types/RenderingEngine/vtkClasses/index.d.ts.map +0 -1
  1095. package/dist/types/RenderingEngine/vtkClasses/vtkOffscreenMultiRenderWindow.d.ts +0 -8
  1096. package/dist/types/RenderingEngine/vtkClasses/vtkOffscreenMultiRenderWindow.d.ts.map +0 -1
  1097. package/dist/types/RenderingEngine/vtkClasses/vtkSharedVolumeMapper.d.ts +0 -8
  1098. package/dist/types/RenderingEngine/vtkClasses/vtkSharedVolumeMapper.d.ts.map +0 -1
  1099. package/dist/types/RenderingEngine/vtkClasses/vtkSlabCamera.d.ts +0 -141
  1100. package/dist/types/RenderingEngine/vtkClasses/vtkSlabCamera.d.ts.map +0 -1
  1101. package/dist/types/RenderingEngine/vtkClasses/vtkStreamingOpenGLRenderWindow.d.ts +0 -8
  1102. package/dist/types/RenderingEngine/vtkClasses/vtkStreamingOpenGLRenderWindow.d.ts.map +0 -1
  1103. package/dist/types/RenderingEngine/vtkClasses/vtkStreamingOpenGLTexture.d.ts +0 -8
  1104. package/dist/types/RenderingEngine/vtkClasses/vtkStreamingOpenGLTexture.d.ts.map +0 -1
  1105. package/dist/types/RenderingEngine/vtkClasses/vtkStreamingOpenGLViewNodeFactory.d.ts +0 -9
  1106. package/dist/types/RenderingEngine/vtkClasses/vtkStreamingOpenGLViewNodeFactory.d.ts.map +0 -1
  1107. package/dist/types/RenderingEngine/vtkClasses/vtkStreamingOpenGLVolumeMapper.d.ts +0 -8
  1108. package/dist/types/RenderingEngine/vtkClasses/vtkStreamingOpenGLVolumeMapper.d.ts.map +0 -1
  1109. package/dist/types/Settings.d.ts +0 -16
  1110. package/dist/types/Settings.d.ts.map +0 -1
  1111. package/dist/types/cache/cache.d.ts +0 -49
  1112. package/dist/types/cache/cache.d.ts.map +0 -1
  1113. package/dist/types/cache/classes/Contour.d.ts +0 -24
  1114. package/dist/types/cache/classes/Contour.d.ts.map +0 -1
  1115. package/dist/types/cache/classes/ContourSet.d.ts +0 -37
  1116. package/dist/types/cache/classes/ContourSet.d.ts.map +0 -1
  1117. package/dist/types/cache/classes/ImageVolume.d.ts +0 -63
  1118. package/dist/types/cache/classes/ImageVolume.d.ts.map +0 -1
  1119. package/dist/types/cache/classes/Surface.d.ts +0 -26
  1120. package/dist/types/cache/classes/Surface.d.ts.map +0 -1
  1121. package/dist/types/cache/index.d.ts +0 -6
  1122. package/dist/types/cache/index.d.ts.map +0 -1
  1123. package/dist/types/constants/backgroundColors.d.ts +0 -5
  1124. package/dist/types/constants/backgroundColors.d.ts.map +0 -1
  1125. package/dist/types/constants/cpuColormaps.d.ts +0 -4
  1126. package/dist/types/constants/cpuColormaps.d.ts.map +0 -1
  1127. package/dist/types/constants/epsilon.d.ts +0 -3
  1128. package/dist/types/constants/epsilon.d.ts.map +0 -1
  1129. package/dist/types/constants/index.d.ts +0 -8
  1130. package/dist/types/constants/index.d.ts.map +0 -1
  1131. package/dist/types/constants/mprCameraValues.d.ts +0 -3
  1132. package/dist/types/constants/mprCameraValues.d.ts.map +0 -1
  1133. package/dist/types/constants/rendering.d.ts +0 -6
  1134. package/dist/types/constants/rendering.d.ts.map +0 -1
  1135. package/dist/types/constants/viewportPresets.d.ts +0 -4
  1136. package/dist/types/constants/viewportPresets.d.ts.map +0 -1
  1137. package/dist/types/enums/BlendModes.d.ts +0 -8
  1138. package/dist/types/enums/BlendModes.d.ts.map +0 -1
  1139. package/dist/types/enums/CalibrationTypes.d.ts +0 -11
  1140. package/dist/types/enums/CalibrationTypes.d.ts.map +0 -1
  1141. package/dist/types/enums/ContourType.d.ts +0 -6
  1142. package/dist/types/enums/ContourType.d.ts.map +0 -1
  1143. package/dist/types/enums/DynamicOperatorType.d.ts +0 -7
  1144. package/dist/types/enums/DynamicOperatorType.d.ts.map +0 -1
  1145. package/dist/types/enums/Events.d.ts +0 -39
  1146. package/dist/types/enums/Events.d.ts.map +0 -1
  1147. package/dist/types/enums/GeometryType.d.ts +0 -6
  1148. package/dist/types/enums/GeometryType.d.ts.map +0 -1
  1149. package/dist/types/enums/ImageQualityStatus.d.ts +0 -9
  1150. package/dist/types/enums/ImageQualityStatus.d.ts.map +0 -1
  1151. package/dist/types/enums/InterpolationType.d.ts +0 -7
  1152. package/dist/types/enums/InterpolationType.d.ts.map +0 -1
  1153. package/dist/types/enums/MetadataModules.d.ts +0 -24
  1154. package/dist/types/enums/MetadataModules.d.ts.map +0 -1
  1155. package/dist/types/enums/OrientationAxis.d.ts +0 -8
  1156. package/dist/types/enums/OrientationAxis.d.ts.map +0 -1
  1157. package/dist/types/enums/RequestType.d.ts +0 -8
  1158. package/dist/types/enums/RequestType.d.ts.map +0 -1
  1159. package/dist/types/enums/SharedArrayBufferModes.d.ts +0 -7
  1160. package/dist/types/enums/SharedArrayBufferModes.d.ts.map +0 -1
  1161. package/dist/types/enums/VOILUTFunctionType.d.ts +0 -6
  1162. package/dist/types/enums/VOILUTFunctionType.d.ts.map +0 -1
  1163. package/dist/types/enums/VideoEnums.d.ts +0 -6
  1164. package/dist/types/enums/VideoEnums.d.ts.map +0 -1
  1165. package/dist/types/enums/ViewportStatus.d.ts +0 -9
  1166. package/dist/types/enums/ViewportStatus.d.ts.map +0 -1
  1167. package/dist/types/enums/ViewportType.d.ts +0 -9
  1168. package/dist/types/enums/ViewportType.d.ts.map +0 -1
  1169. package/dist/types/enums/index.d.ts +0 -18
  1170. package/dist/types/enums/index.d.ts.map +0 -1
  1171. package/dist/types/eventTarget.d.ts +0 -15
  1172. package/dist/types/eventTarget.d.ts.map +0 -1
  1173. package/dist/types/getEnabledElement.d.ts +0 -6
  1174. package/dist/types/getEnabledElement.d.ts.map +0 -1
  1175. package/dist/types/global.d.ts +0 -8
  1176. package/dist/types/global.d.ts.map +0 -1
  1177. package/dist/types/index.d.ts +0 -33
  1178. package/dist/types/index.d.ts.map +0 -1
  1179. package/dist/types/init.d.ts +0 -17
  1180. package/dist/types/init.d.ts.map +0 -1
  1181. package/dist/types/loaders/ProgressiveRetrieveImages.d.ts +0 -36
  1182. package/dist/types/loaders/ProgressiveRetrieveImages.d.ts.map +0 -1
  1183. package/dist/types/loaders/configuration/interleavedRetrieve.d.ts +0 -4
  1184. package/dist/types/loaders/configuration/interleavedRetrieve.d.ts.map +0 -1
  1185. package/dist/types/loaders/configuration/sequentialRetrieve.d.ts +0 -4
  1186. package/dist/types/loaders/configuration/sequentialRetrieve.d.ts.map +0 -1
  1187. package/dist/types/loaders/configuration/singleRetrieve.d.ts +0 -4
  1188. package/dist/types/loaders/configuration/singleRetrieve.d.ts.map +0 -1
  1189. package/dist/types/loaders/fillNearbyFrames.d.ts +0 -4
  1190. package/dist/types/loaders/fillNearbyFrames.d.ts.map +0 -1
  1191. package/dist/types/loaders/geometryLoader.d.ts +0 -10
  1192. package/dist/types/loaders/geometryLoader.d.ts.map +0 -1
  1193. package/dist/types/loaders/imageLoader.d.ts +0 -44
  1194. package/dist/types/loaders/imageLoader.d.ts.map +0 -1
  1195. package/dist/types/loaders/utils/contourSet/createContourSet.d.ts +0 -3
  1196. package/dist/types/loaders/utils/contourSet/createContourSet.d.ts.map +0 -1
  1197. package/dist/types/loaders/utils/contourSet/validateContourSet.d.ts +0 -3
  1198. package/dist/types/loaders/utils/contourSet/validateContourSet.d.ts.map +0 -1
  1199. package/dist/types/loaders/utils/surface/createSurface.d.ts +0 -3
  1200. package/dist/types/loaders/utils/surface/createSurface.d.ts.map +0 -1
  1201. package/dist/types/loaders/utils/surface/validateSurface.d.ts +0 -3
  1202. package/dist/types/loaders/utils/surface/validateSurface.d.ts.map +0 -1
  1203. package/dist/types/loaders/volumeLoader.d.ts +0 -43
  1204. package/dist/types/loaders/volumeLoader.d.ts.map +0 -1
  1205. package/dist/types/metaData.d.ts +0 -8
  1206. package/dist/types/metaData.d.ts.map +0 -1
  1207. package/dist/types/requestPool/imageLoadPoolManager.d.ts +0 -4
  1208. package/dist/types/requestPool/imageLoadPoolManager.d.ts.map +0 -1
  1209. package/dist/types/requestPool/imageRetrievalPoolManager.d.ts +0 -4
  1210. package/dist/types/requestPool/imageRetrievalPoolManager.d.ts.map +0 -1
  1211. package/dist/types/requestPool/requestPoolManager.d.ts +0 -45
  1212. package/dist/types/requestPool/requestPoolManager.d.ts.map +0 -1
  1213. package/dist/types/types/AABB2.d.ts +0 -8
  1214. package/dist/types/types/AABB2.d.ts.map +0 -1
  1215. package/dist/types/types/AABB3.d.ts +0 -10
  1216. package/dist/types/types/AABB3.d.ts.map +0 -1
  1217. package/dist/types/types/ActorSliceRange.d.ts +0 -12
  1218. package/dist/types/types/ActorSliceRange.d.ts.map +0 -1
  1219. package/dist/types/types/AffineMatrix.d.ts +0 -28
  1220. package/dist/types/types/AffineMatrix.d.ts.map +0 -1
  1221. package/dist/types/types/BoundsIJK.d.ts +0 -4
  1222. package/dist/types/types/BoundsIJK.d.ts.map +0 -1
  1223. package/dist/types/types/BoundsLPS.d.ts +0 -4
  1224. package/dist/types/types/BoundsLPS.d.ts.map +0 -1
  1225. package/dist/types/types/CPUFallbackColormap.d.ts +0 -21
  1226. package/dist/types/types/CPUFallbackColormap.d.ts.map +0 -1
  1227. package/dist/types/types/CPUFallbackColormapData.d.ts +0 -11
  1228. package/dist/types/types/CPUFallbackColormapData.d.ts.map +0 -1
  1229. package/dist/types/types/CPUFallbackColormapsData.d.ts +0 -6
  1230. package/dist/types/types/CPUFallbackColormapsData.d.ts.map +0 -1
  1231. package/dist/types/types/CPUFallbackEnabledElement.d.ts +0 -38
  1232. package/dist/types/types/CPUFallbackEnabledElement.d.ts.map +0 -1
  1233. package/dist/types/types/CPUFallbackLUT.d.ts +0 -5
  1234. package/dist/types/types/CPUFallbackLUT.d.ts.map +0 -1
  1235. package/dist/types/types/CPUFallbackLookupTable.d.ts +0 -16
  1236. package/dist/types/types/CPUFallbackLookupTable.d.ts.map +0 -1
  1237. package/dist/types/types/CPUFallbackRenderingTools.d.ts +0 -24
  1238. package/dist/types/types/CPUFallbackRenderingTools.d.ts.map +0 -1
  1239. package/dist/types/types/CPUFallbackTransform.d.ts +0 -15
  1240. package/dist/types/types/CPUFallbackTransform.d.ts.map +0 -1
  1241. package/dist/types/types/CPUFallbackViewport.d.ts +0 -28
  1242. package/dist/types/types/CPUFallbackViewport.d.ts.map +0 -1
  1243. package/dist/types/types/CPUFallbackViewportDisplayedArea.d.ts +0 -15
  1244. package/dist/types/types/CPUFallbackViewportDisplayedArea.d.ts.map +0 -1
  1245. package/dist/types/types/CPUIImageData.d.ts +0 -38
  1246. package/dist/types/types/CPUIImageData.d.ts.map +0 -1
  1247. package/dist/types/types/Color.d.ts +0 -3
  1248. package/dist/types/types/Color.d.ts.map +0 -1
  1249. package/dist/types/types/Colormap.d.ts +0 -16
  1250. package/dist/types/types/Colormap.d.ts.map +0 -1
  1251. package/dist/types/types/ContourData.d.ts +0 -18
  1252. package/dist/types/types/ContourData.d.ts.map +0 -1
  1253. package/dist/types/types/Cornerstone3DConfig.d.ts +0 -15
  1254. package/dist/types/types/Cornerstone3DConfig.d.ts.map +0 -1
  1255. package/dist/types/types/CustomEventType.d.ts +0 -6
  1256. package/dist/types/types/CustomEventType.d.ts.map +0 -1
  1257. package/dist/types/types/EventTypes.d.ts +0 -173
  1258. package/dist/types/types/EventTypes.d.ts.map +0 -1
  1259. package/dist/types/types/FlipDirection.d.ts +0 -6
  1260. package/dist/types/types/FlipDirection.d.ts.map +0 -1
  1261. package/dist/types/types/IActor.d.ts +0 -21
  1262. package/dist/types/types/IActor.d.ts.map +0 -1
  1263. package/dist/types/types/ICache.d.ts +0 -13
  1264. package/dist/types/types/ICache.d.ts.map +0 -1
  1265. package/dist/types/types/ICachedGeometry.d.ts +0 -12
  1266. package/dist/types/types/ICachedGeometry.d.ts.map +0 -1
  1267. package/dist/types/types/ICachedImage.d.ts +0 -12
  1268. package/dist/types/types/ICachedImage.d.ts.map +0 -1
  1269. package/dist/types/types/ICachedVolume.d.ts +0 -11
  1270. package/dist/types/types/ICachedVolume.d.ts.map +0 -1
  1271. package/dist/types/types/ICamera.d.ts +0 -17
  1272. package/dist/types/types/ICamera.d.ts.map +0 -1
  1273. package/dist/types/types/IContour.d.ts +0 -14
  1274. package/dist/types/types/IContour.d.ts.map +0 -1
  1275. package/dist/types/types/IContourSet.d.ts +0 -20
  1276. package/dist/types/types/IContourSet.d.ts.map +0 -1
  1277. package/dist/types/types/IDynamicImageVolume.d.ts +0 -9
  1278. package/dist/types/types/IDynamicImageVolume.d.ts.map +0 -1
  1279. package/dist/types/types/IEnabledElement.d.ts +0 -12
  1280. package/dist/types/types/IEnabledElement.d.ts.map +0 -1
  1281. package/dist/types/types/IGeometry.d.ts +0 -11
  1282. package/dist/types/types/IGeometry.d.ts.map +0 -1
  1283. package/dist/types/types/IImage.d.ts +0 -86
  1284. package/dist/types/types/IImage.d.ts.map +0 -1
  1285. package/dist/types/types/IImageCalibration.d.ts +0 -12
  1286. package/dist/types/types/IImageCalibration.d.ts.map +0 -1
  1287. package/dist/types/types/IImageData.d.ts +0 -28
  1288. package/dist/types/types/IImageData.d.ts.map +0 -1
  1289. package/dist/types/types/IImageVolume.d.ts +0 -44
  1290. package/dist/types/types/IImageVolume.d.ts.map +0 -1
  1291. package/dist/types/types/ILoadObject.d.ts +0 -19
  1292. package/dist/types/types/ILoadObject.d.ts.map +0 -1
  1293. package/dist/types/types/IRegisterImageLoader.d.ts +0 -6
  1294. package/dist/types/types/IRegisterImageLoader.d.ts.map +0 -1
  1295. package/dist/types/types/IRenderingEngine.d.ts +0 -28
  1296. package/dist/types/types/IRenderingEngine.d.ts.map +0 -1
  1297. package/dist/types/types/IRetrieveConfiguration.d.ts +0 -39
  1298. package/dist/types/types/IRetrieveConfiguration.d.ts.map +0 -1
  1299. package/dist/types/types/IStackInput.d.ts +0 -13
  1300. package/dist/types/types/IStackInput.d.ts.map +0 -1
  1301. package/dist/types/types/IStackViewport.d.ts +0 -3
  1302. package/dist/types/types/IStackViewport.d.ts.map +0 -1
  1303. package/dist/types/types/IStreamingImageVolume.d.ts +0 -7
  1304. package/dist/types/types/IStreamingImageVolume.d.ts.map +0 -1
  1305. package/dist/types/types/IStreamingVolumeProperties.d.ts +0 -13
  1306. package/dist/types/types/IStreamingVolumeProperties.d.ts.map +0 -1
  1307. package/dist/types/types/ISurface.d.ts +0 -14
  1308. package/dist/types/types/ISurface.d.ts.map +0 -1
  1309. package/dist/types/types/IVideoViewport.d.ts +0 -20
  1310. package/dist/types/types/IVideoViewport.d.ts.map +0 -1
  1311. package/dist/types/types/IViewport.d.ts +0 -144
  1312. package/dist/types/types/IViewport.d.ts.map +0 -1
  1313. package/dist/types/types/IViewportId.d.ts +0 -5
  1314. package/dist/types/types/IViewportId.d.ts.map +0 -1
  1315. package/dist/types/types/IVolume.d.ts +0 -4
  1316. package/dist/types/types/IVolume.d.ts.map +0 -1
  1317. package/dist/types/types/IVolumeInput.d.ts +0 -16
  1318. package/dist/types/types/IVolumeInput.d.ts.map +0 -1
  1319. package/dist/types/types/IVolumeViewport.d.ts +0 -39
  1320. package/dist/types/types/IVolumeViewport.d.ts.map +0 -1
  1321. package/dist/types/types/ImageLoadListener.d.ts +0 -6
  1322. package/dist/types/types/ImageLoadListener.d.ts.map +0 -1
  1323. package/dist/types/types/ImageLoaderFn.d.ts +0 -7
  1324. package/dist/types/types/ImageLoaderFn.d.ts.map +0 -1
  1325. package/dist/types/types/ImagePixelModule.d.ts +0 -14
  1326. package/dist/types/types/ImagePixelModule.d.ts.map +0 -1
  1327. package/dist/types/types/ImagePlaneModule.d.ts +0 -17
  1328. package/dist/types/types/ImagePlaneModule.d.ts.map +0 -1
  1329. package/dist/types/types/ImageSliceData.d.ts +0 -6
  1330. package/dist/types/types/ImageSliceData.d.ts.map +0 -1
  1331. package/dist/types/types/ImageVolumeProps.d.ts +0 -7
  1332. package/dist/types/types/ImageVolumeProps.d.ts.map +0 -1
  1333. package/dist/types/types/Mat3.d.ts +0 -3
  1334. package/dist/types/types/Mat3.d.ts.map +0 -1
  1335. package/dist/types/types/Metadata.d.ts +0 -20
  1336. package/dist/types/types/Metadata.d.ts.map +0 -1
  1337. package/dist/types/types/OrientationVectors.d.ts +0 -7
  1338. package/dist/types/types/OrientationVectors.d.ts.map +0 -1
  1339. package/dist/types/types/PixelDataTypedArray.d.ts +0 -3
  1340. package/dist/types/types/PixelDataTypedArray.d.ts.map +0 -1
  1341. package/dist/types/types/Plane.d.ts +0 -3
  1342. package/dist/types/types/Plane.d.ts.map +0 -1
  1343. package/dist/types/types/Point2.d.ts +0 -3
  1344. package/dist/types/types/Point2.d.ts.map +0 -1
  1345. package/dist/types/types/Point3.d.ts +0 -8
  1346. package/dist/types/types/Point3.d.ts.map +0 -1
  1347. package/dist/types/types/Point4.d.ts +0 -3
  1348. package/dist/types/types/Point4.d.ts.map +0 -1
  1349. package/dist/types/types/RGB.d.ts +0 -3
  1350. package/dist/types/types/RGB.d.ts.map +0 -1
  1351. package/dist/types/types/ScalingParameters.d.ts +0 -20
  1352. package/dist/types/types/ScalingParameters.d.ts.map +0 -1
  1353. package/dist/types/types/StackViewportProperties.d.ts +0 -10
  1354. package/dist/types/types/StackViewportProperties.d.ts.map +0 -1
  1355. package/dist/types/types/SurfaceData.d.ts +0 -13
  1356. package/dist/types/types/SurfaceData.d.ts.map +0 -1
  1357. package/dist/types/types/TransformMatrix2D.d.ts +0 -3
  1358. package/dist/types/types/TransformMatrix2D.d.ts.map +0 -1
  1359. package/dist/types/types/VideoViewportProperties.d.ts +0 -11
  1360. package/dist/types/types/VideoViewportProperties.d.ts.map +0 -1
  1361. package/dist/types/types/VideoViewportTypes.d.ts +0 -19
  1362. package/dist/types/types/VideoViewportTypes.d.ts.map +0 -1
  1363. package/dist/types/types/ViewportInputOptions.d.ts +0 -13
  1364. package/dist/types/types/ViewportInputOptions.d.ts.map +0 -1
  1365. package/dist/types/types/ViewportPreset.d.ts +0 -14
  1366. package/dist/types/types/ViewportPreset.d.ts.map +0 -1
  1367. package/dist/types/types/ViewportProperties.d.ts +0 -12
  1368. package/dist/types/types/ViewportProperties.d.ts.map +0 -1
  1369. package/dist/types/types/VolumeLoaderFn.d.ts +0 -7
  1370. package/dist/types/types/VolumeLoaderFn.d.ts.map +0 -1
  1371. package/dist/types/types/VolumeProps.d.ts +0 -28
  1372. package/dist/types/types/VolumeProps.d.ts.map +0 -1
  1373. package/dist/types/types/VolumeViewportProperties.d.ts +0 -9
  1374. package/dist/types/types/VolumeViewportProperties.d.ts.map +0 -1
  1375. package/dist/types/types/displayArea.d.ts +0 -14
  1376. package/dist/types/types/displayArea.d.ts.map +0 -1
  1377. package/dist/types/types/index.d.ts +0 -88
  1378. package/dist/types/types/index.d.ts.map +0 -1
  1379. package/dist/types/types/voi.d.ts +0 -10
  1380. package/dist/types/types/voi.d.ts.map +0 -1
  1381. package/dist/types/utilities/PointsManager.d.ts +0 -34
  1382. package/dist/types/utilities/PointsManager.d.ts.map +0 -1
  1383. package/dist/types/utilities/ProgressiveIterator.d.ts +0 -25
  1384. package/dist/types/utilities/ProgressiveIterator.d.ts.map +0 -1
  1385. package/dist/types/utilities/RLEVoxelMap.d.ts +0 -27
  1386. package/dist/types/utilities/RLEVoxelMap.d.ts.map +0 -1
  1387. package/dist/types/utilities/VoxelManager.d.ts +0 -45
  1388. package/dist/types/utilities/VoxelManager.d.ts.map +0 -1
  1389. package/dist/types/utilities/actorCheck.d.ts +0 -6
  1390. package/dist/types/utilities/actorCheck.d.ts.map +0 -1
  1391. package/dist/types/utilities/applyPreset.d.ts +0 -4
  1392. package/dist/types/utilities/applyPreset.d.ts.map +0 -1
  1393. package/dist/types/utilities/cacheUtils.d.ts +0 -3
  1394. package/dist/types/utilities/cacheUtils.d.ts.map +0 -1
  1395. package/dist/types/utilities/calculateViewportsSpatialRegistration.d.ts +0 -4
  1396. package/dist/types/utilities/calculateViewportsSpatialRegistration.d.ts.map +0 -1
  1397. package/dist/types/utilities/calibratedPixelSpacingMetadataProvider.d.ts +0 -7
  1398. package/dist/types/utilities/calibratedPixelSpacingMetadataProvider.d.ts.map +0 -1
  1399. package/dist/types/utilities/clamp.d.ts +0 -3
  1400. package/dist/types/utilities/clamp.d.ts.map +0 -1
  1401. package/dist/types/utilities/color.d.ts +0 -8
  1402. package/dist/types/utilities/color.d.ts.map +0 -1
  1403. package/dist/types/utilities/colormap.d.ts +0 -7
  1404. package/dist/types/utilities/colormap.d.ts.map +0 -1
  1405. package/dist/types/utilities/convertStackToVolumeViewport.d.ts +0 -13
  1406. package/dist/types/utilities/convertStackToVolumeViewport.d.ts.map +0 -1
  1407. package/dist/types/utilities/convertToGrayscale.d.ts +0 -2
  1408. package/dist/types/utilities/convertToGrayscale.d.ts.map +0 -1
  1409. package/dist/types/utilities/convertVolumeToStackViewport.d.ts +0 -10
  1410. package/dist/types/utilities/convertVolumeToStackViewport.d.ts.map +0 -1
  1411. package/dist/types/utilities/createFloat32SharedArray.d.ts +0 -3
  1412. package/dist/types/utilities/createFloat32SharedArray.d.ts.map +0 -1
  1413. package/dist/types/utilities/createInt16SharedArray.d.ts +0 -3
  1414. package/dist/types/utilities/createInt16SharedArray.d.ts.map +0 -1
  1415. package/dist/types/utilities/createLinearRGBTransferFunction.d.ts +0 -4
  1416. package/dist/types/utilities/createLinearRGBTransferFunction.d.ts.map +0 -1
  1417. package/dist/types/utilities/createSigmoidRGBTransferFunction.d.ts +0 -4
  1418. package/dist/types/utilities/createSigmoidRGBTransferFunction.d.ts.map +0 -1
  1419. package/dist/types/utilities/createUInt16SharedArray.d.ts +0 -3
  1420. package/dist/types/utilities/createUInt16SharedArray.d.ts.map +0 -1
  1421. package/dist/types/utilities/createUint8SharedArray.d.ts +0 -3
  1422. package/dist/types/utilities/createUint8SharedArray.d.ts.map +0 -1
  1423. package/dist/types/utilities/decimate.d.ts +0 -2
  1424. package/dist/types/utilities/decimate.d.ts.map +0 -1
  1425. package/dist/types/utilities/deepFreeze.d.ts +0 -3
  1426. package/dist/types/utilities/deepFreeze.d.ts.map +0 -1
  1427. package/dist/types/utilities/deepMerge.d.ts +0 -3
  1428. package/dist/types/utilities/deepMerge.d.ts.map +0 -1
  1429. package/dist/types/utilities/eventListener/MultiTargetEventListenerManager.d.ts +0 -8
  1430. package/dist/types/utilities/eventListener/MultiTargetEventListenerManager.d.ts.map +0 -1
  1431. package/dist/types/utilities/eventListener/TargetEventListeners.d.ts +0 -16
  1432. package/dist/types/utilities/eventListener/TargetEventListeners.d.ts.map +0 -1
  1433. package/dist/types/utilities/eventListener/index.d.ts +0 -3
  1434. package/dist/types/utilities/eventListener/index.d.ts.map +0 -1
  1435. package/dist/types/utilities/generateVolumePropsFromImageIds.d.ts +0 -4
  1436. package/dist/types/utilities/generateVolumePropsFromImageIds.d.ts.map +0 -1
  1437. package/dist/types/utilities/genericMetadataProvider.d.ts +0 -7
  1438. package/dist/types/utilities/genericMetadataProvider.d.ts.map +0 -1
  1439. package/dist/types/utilities/getBufferConfiguration.d.ts +0 -10
  1440. package/dist/types/utilities/getBufferConfiguration.d.ts.map +0 -1
  1441. package/dist/types/utilities/getClosestImageId.d.ts +0 -3
  1442. package/dist/types/utilities/getClosestImageId.d.ts.map +0 -1
  1443. package/dist/types/utilities/getClosestStackImageIndexForPoint.d.ts +0 -7
  1444. package/dist/types/utilities/getClosestStackImageIndexForPoint.d.ts.map +0 -1
  1445. package/dist/types/utilities/getCurrentVolumeViewportSlice.d.ts +0 -11
  1446. package/dist/types/utilities/getCurrentVolumeViewportSlice.d.ts.map +0 -1
  1447. package/dist/types/utilities/getImageLegacy.d.ts +0 -4
  1448. package/dist/types/utilities/getImageLegacy.d.ts.map +0 -1
  1449. package/dist/types/utilities/getImageSliceDataForVolumeViewport.d.ts +0 -4
  1450. package/dist/types/utilities/getImageSliceDataForVolumeViewport.d.ts.map +0 -1
  1451. package/dist/types/utilities/getMinMax.d.ts +0 -5
  1452. package/dist/types/utilities/getMinMax.d.ts.map +0 -1
  1453. package/dist/types/utilities/getRandomSampleFromArray.d.ts +0 -2
  1454. package/dist/types/utilities/getRandomSampleFromArray.d.ts.map +0 -1
  1455. package/dist/types/utilities/getRuntimeId.d.ts +0 -2
  1456. package/dist/types/utilities/getRuntimeId.d.ts.map +0 -1
  1457. package/dist/types/utilities/getScalarDataType.d.ts +0 -3
  1458. package/dist/types/utilities/getScalarDataType.d.ts.map +0 -1
  1459. package/dist/types/utilities/getScalingParameters.d.ts +0 -3
  1460. package/dist/types/utilities/getScalingParameters.d.ts.map +0 -1
  1461. package/dist/types/utilities/getSliceRange.d.ts +0 -3
  1462. package/dist/types/utilities/getSliceRange.d.ts.map +0 -1
  1463. package/dist/types/utilities/getSpacingInNormalDirection.d.ts +0 -7
  1464. package/dist/types/utilities/getSpacingInNormalDirection.d.ts.map +0 -1
  1465. package/dist/types/utilities/getTargetVolumeAndSpacingInNormalDir.d.ts +0 -7
  1466. package/dist/types/utilities/getTargetVolumeAndSpacingInNormalDir.d.ts.map +0 -1
  1467. package/dist/types/utilities/getViewportImageCornersInWorld.d.ts +0 -3
  1468. package/dist/types/utilities/getViewportImageCornersInWorld.d.ts.map +0 -1
  1469. package/dist/types/utilities/getViewportImageIds.d.ts +0 -4
  1470. package/dist/types/utilities/getViewportImageIds.d.ts.map +0 -1
  1471. package/dist/types/utilities/getViewportModality.d.ts +0 -4
  1472. package/dist/types/utilities/getViewportModality.d.ts.map +0 -1
  1473. package/dist/types/utilities/getViewportsWithImageURI.d.ts +0 -5
  1474. package/dist/types/utilities/getViewportsWithImageURI.d.ts.map +0 -1
  1475. package/dist/types/utilities/getViewportsWithVolumeId.d.ts +0 -4
  1476. package/dist/types/utilities/getViewportsWithVolumeId.d.ts.map +0 -1
  1477. package/dist/types/utilities/getVoiFromSigmoidRGBTransferFunction.d.ts +0 -3
  1478. package/dist/types/utilities/getVoiFromSigmoidRGBTransferFunction.d.ts.map +0 -1
  1479. package/dist/types/utilities/getVolumeActorCorners.d.ts +0 -3
  1480. package/dist/types/utilities/getVolumeActorCorners.d.ts.map +0 -1
  1481. package/dist/types/utilities/getVolumeId.d.ts +0 -2
  1482. package/dist/types/utilities/getVolumeId.d.ts.map +0 -1
  1483. package/dist/types/utilities/getVolumeSliceRangeInfo.d.ts +0 -8
  1484. package/dist/types/utilities/getVolumeSliceRangeInfo.d.ts.map +0 -1
  1485. package/dist/types/utilities/getVolumeViewportScrollInfo.d.ts +0 -12
  1486. package/dist/types/utilities/getVolumeViewportScrollInfo.d.ts.map +0 -1
  1487. package/dist/types/utilities/getVolumeViewportsContainingSameVolumes.d.ts +0 -4
  1488. package/dist/types/utilities/getVolumeViewportsContainingSameVolumes.d.ts.map +0 -1
  1489. package/dist/types/utilities/hasFloatScalingParameters.d.ts +0 -3
  1490. package/dist/types/utilities/hasFloatScalingParameters.d.ts.map +0 -1
  1491. package/dist/types/utilities/hasNaNValues.d.ts +0 -2
  1492. package/dist/types/utilities/hasNaNValues.d.ts.map +0 -1
  1493. package/dist/types/utilities/imageIdToURI.d.ts +0 -2
  1494. package/dist/types/utilities/imageIdToURI.d.ts.map +0 -1
  1495. package/dist/types/utilities/imageRetrieveMetadataProvider.d.ts +0 -8
  1496. package/dist/types/utilities/imageRetrieveMetadataProvider.d.ts.map +0 -1
  1497. package/dist/types/utilities/imageToWorldCoords.d.ts +0 -3
  1498. package/dist/types/utilities/imageToWorldCoords.d.ts.map +0 -1
  1499. package/dist/types/utilities/index.d.ts +0 -83
  1500. package/dist/types/utilities/index.d.ts.map +0 -1
  1501. package/dist/types/utilities/indexWithinDimensions.d.ts +0 -3
  1502. package/dist/types/utilities/indexWithinDimensions.d.ts.map +0 -1
  1503. package/dist/types/utilities/invertRgbTransferFunction.d.ts +0 -2
  1504. package/dist/types/utilities/invertRgbTransferFunction.d.ts.map +0 -1
  1505. package/dist/types/utilities/isEqual.d.ts +0 -5
  1506. package/dist/types/utilities/isEqual.d.ts.map +0 -1
  1507. package/dist/types/utilities/isOpposite.d.ts +0 -3
  1508. package/dist/types/utilities/isOpposite.d.ts.map +0 -1
  1509. package/dist/types/utilities/isPTPrescaledWithSUV.d.ts +0 -4
  1510. package/dist/types/utilities/isPTPrescaledWithSUV.d.ts.map +0 -1
  1511. package/dist/types/utilities/isTypedArray.d.ts +0 -2
  1512. package/dist/types/utilities/isTypedArray.d.ts.map +0 -1
  1513. package/dist/types/utilities/isValidVolume.d.ts +0 -3
  1514. package/dist/types/utilities/isValidVolume.d.ts.map +0 -1
  1515. package/dist/types/utilities/isVideoTransferSyntax.d.ts +0 -3
  1516. package/dist/types/utilities/isVideoTransferSyntax.d.ts.map +0 -1
  1517. package/dist/types/utilities/loadImageToCanvas.d.ts +0 -32
  1518. package/dist/types/utilities/loadImageToCanvas.d.ts.map +0 -1
  1519. package/dist/types/utilities/makeVolumeMetadata.d.ts +0 -3
  1520. package/dist/types/utilities/makeVolumeMetadata.d.ts.map +0 -1
  1521. package/dist/types/utilities/planar.d.ts +0 -8
  1522. package/dist/types/utilities/planar.d.ts.map +0 -1
  1523. package/dist/types/utilities/renderToCanvasCPU.d.ts +0 -4
  1524. package/dist/types/utilities/renderToCanvasCPU.d.ts.map +0 -1
  1525. package/dist/types/utilities/renderToCanvasGPU.d.ts +0 -6
  1526. package/dist/types/utilities/renderToCanvasGPU.d.ts.map +0 -1
  1527. package/dist/types/utilities/roundNumber.d.ts +0 -5
  1528. package/dist/types/utilities/roundNumber.d.ts.map +0 -1
  1529. package/dist/types/utilities/scaleRgbTransferFunction.d.ts +0 -2
  1530. package/dist/types/utilities/scaleRgbTransferFunction.d.ts.map +0 -1
  1531. package/dist/types/utilities/snapFocalPointToSlice.d.ts +0 -6
  1532. package/dist/types/utilities/snapFocalPointToSlice.d.ts.map +0 -1
  1533. package/dist/types/utilities/sortImageIdsAndGetSpacing.d.ts +0 -10
  1534. package/dist/types/utilities/sortImageIdsAndGetSpacing.d.ts.map +0 -1
  1535. package/dist/types/utilities/spatialRegistrationMetadataProvider.d.ts +0 -7
  1536. package/dist/types/utilities/spatialRegistrationMetadataProvider.d.ts.map +0 -1
  1537. package/dist/types/utilities/transferFunctionUtils.d.ts +0 -4
  1538. package/dist/types/utilities/transferFunctionUtils.d.ts.map +0 -1
  1539. package/dist/types/utilities/transformCanvasToIJK.d.ts +0 -3
  1540. package/dist/types/utilities/transformCanvasToIJK.d.ts.map +0 -1
  1541. package/dist/types/utilities/transformIJKToCanvas.d.ts +0 -3
  1542. package/dist/types/utilities/transformIJKToCanvas.d.ts.map +0 -1
  1543. package/dist/types/utilities/transformIndexToWorld.d.ts +0 -3
  1544. package/dist/types/utilities/transformIndexToWorld.d.ts.map +0 -1
  1545. package/dist/types/utilities/transformWorldToIndex.d.ts +0 -3
  1546. package/dist/types/utilities/transformWorldToIndex.d.ts.map +0 -1
  1547. package/dist/types/utilities/triggerEvent.d.ts +0 -2
  1548. package/dist/types/utilities/triggerEvent.d.ts.map +0 -1
  1549. package/dist/types/utilities/updateVTKImageDataWithCornerstoneImage.d.ts +0 -5
  1550. package/dist/types/utilities/updateVTKImageDataWithCornerstoneImage.d.ts.map +0 -1
  1551. package/dist/types/utilities/uuidv4.d.ts +0 -2
  1552. package/dist/types/utilities/uuidv4.d.ts.map +0 -1
  1553. package/dist/types/utilities/windowLevel.d.ts +0 -10
  1554. package/dist/types/utilities/windowLevel.d.ts.map +0 -1
  1555. package/dist/types/utilities/worldToImageCoords.d.ts +0 -4
  1556. package/dist/types/utilities/worldToImageCoords.d.ts.map +0 -1
  1557. package/dist/types/webWorkerManager/webWorkerManager.d.ts +0 -22
  1558. package/dist/types/webWorkerManager/webWorkerManager.d.ts.map +0 -1
  1559. package/dist/umd/index.js +0 -2
  1560. package/dist/umd/index.js.map +0 -1
  1561. package/src/RenderingEngine/BaseVolumeViewport.ts +0 -1785
  1562. package/src/RenderingEngine/CanvasActor/CanvasMapper.ts +0 -17
  1563. package/src/RenderingEngine/CanvasActor/CanvasProperties.ts +0 -49
  1564. package/src/RenderingEngine/CanvasActor/index.ts +0 -232
  1565. package/src/RenderingEngine/RenderingEngine.ts +0 -1420
  1566. package/src/RenderingEngine/StackViewport.ts +0 -3309
  1567. package/src/RenderingEngine/VideoViewport.ts +0 -1116
  1568. package/src/RenderingEngine/Viewport.ts +0 -1873
  1569. package/src/RenderingEngine/VolumeViewport.ts +0 -638
  1570. package/src/RenderingEngine/VolumeViewport3D.ts +0 -73
  1571. package/src/RenderingEngine/getRenderingEngine.ts +0 -34
  1572. package/src/RenderingEngine/helpers/addImageSlicesToViewports.ts +0 -51
  1573. package/src/RenderingEngine/helpers/addVolumesToViewports.ts +0 -55
  1574. package/src/RenderingEngine/helpers/cpuFallback/colors/colormap.ts +0 -343
  1575. package/src/RenderingEngine/helpers/cpuFallback/colors/index.ts +0 -4
  1576. package/src/RenderingEngine/helpers/cpuFallback/colors/lookupTable.ts +0 -469
  1577. package/src/RenderingEngine/helpers/cpuFallback/drawImageSync.ts +0 -58
  1578. package/src/RenderingEngine/helpers/cpuFallback/rendering/calculateTransform.ts +0 -136
  1579. package/src/RenderingEngine/helpers/cpuFallback/rendering/canvasToPixel.ts +0 -25
  1580. package/src/RenderingEngine/helpers/cpuFallback/rendering/computeAutoVoi.ts +0 -47
  1581. package/src/RenderingEngine/helpers/cpuFallback/rendering/correctShift.ts +0 -38
  1582. package/src/RenderingEngine/helpers/cpuFallback/rendering/createViewport.ts +0 -64
  1583. package/src/RenderingEngine/helpers/cpuFallback/rendering/doesImageNeedToBeRendered.ts +0 -36
  1584. package/src/RenderingEngine/helpers/cpuFallback/rendering/fitToWindow.ts +0 -22
  1585. package/src/RenderingEngine/helpers/cpuFallback/rendering/generateColorLUT.ts +0 -60
  1586. package/src/RenderingEngine/helpers/cpuFallback/rendering/generateLut.ts +0 -83
  1587. package/src/RenderingEngine/helpers/cpuFallback/rendering/getDefaultViewport.ts +0 -88
  1588. package/src/RenderingEngine/helpers/cpuFallback/rendering/getImageFitScale.ts +0 -52
  1589. package/src/RenderingEngine/helpers/cpuFallback/rendering/getImageSize.ts +0 -55
  1590. package/src/RenderingEngine/helpers/cpuFallback/rendering/getLut.ts +0 -53
  1591. package/src/RenderingEngine/helpers/cpuFallback/rendering/getModalityLut.ts +0 -55
  1592. package/src/RenderingEngine/helpers/cpuFallback/rendering/getTransform.ts +0 -17
  1593. package/src/RenderingEngine/helpers/cpuFallback/rendering/getVOILut.ts +0 -82
  1594. package/src/RenderingEngine/helpers/cpuFallback/rendering/initializeRenderCanvas.ts +0 -37
  1595. package/src/RenderingEngine/helpers/cpuFallback/rendering/lutMatches.ts +0 -21
  1596. package/src/RenderingEngine/helpers/cpuFallback/rendering/now.ts +0 -13
  1597. package/src/RenderingEngine/helpers/cpuFallback/rendering/pixelToCanvas.ts +0 -22
  1598. package/src/RenderingEngine/helpers/cpuFallback/rendering/renderColorImage.ts +0 -195
  1599. package/src/RenderingEngine/helpers/cpuFallback/rendering/renderGrayscaleImage.ts +0 -166
  1600. package/src/RenderingEngine/helpers/cpuFallback/rendering/renderPseudoColorImage.ts +0 -200
  1601. package/src/RenderingEngine/helpers/cpuFallback/rendering/resetCamera.ts +0 -32
  1602. package/src/RenderingEngine/helpers/cpuFallback/rendering/resize.ts +0 -109
  1603. package/src/RenderingEngine/helpers/cpuFallback/rendering/saveLastRendered.ts +0 -36
  1604. package/src/RenderingEngine/helpers/cpuFallback/rendering/setDefaultViewport.ts +0 -17
  1605. package/src/RenderingEngine/helpers/cpuFallback/rendering/setToPixelCoordinateSystem.ts +0 -32
  1606. package/src/RenderingEngine/helpers/cpuFallback/rendering/storedColorPixelDataToCanvasImageData.ts +0 -58
  1607. package/src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageData.ts +0 -76
  1608. package/src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataColorLUT.ts +0 -60
  1609. package/src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPET.ts +0 -50
  1610. package/src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPseudocolorLUT.ts +0 -66
  1611. package/src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPseudocolorLUTPET.ts +0 -68
  1612. package/src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataRGBA.ts +0 -81
  1613. package/src/RenderingEngine/helpers/cpuFallback/rendering/storedRGBAPixelDataToCanvasImageData.ts +0 -56
  1614. package/src/RenderingEngine/helpers/cpuFallback/rendering/transform.ts +0 -126
  1615. package/src/RenderingEngine/helpers/cpuFallback/rendering/validator.ts +0 -31
  1616. package/src/RenderingEngine/helpers/createVolumeActor.ts +0 -105
  1617. package/src/RenderingEngine/helpers/createVolumeMapper.ts +0 -37
  1618. package/src/RenderingEngine/helpers/getOrCreateCanvas.ts +0 -89
  1619. package/src/RenderingEngine/helpers/index.ts +0 -17
  1620. package/src/RenderingEngine/helpers/isRgbaSourceRgbDest.ts +0 -1
  1621. package/src/RenderingEngine/helpers/setDefaultVolumeVOI.ts +0 -251
  1622. package/src/RenderingEngine/helpers/setVolumesForViewports.ts +0 -54
  1623. package/src/RenderingEngine/helpers/viewportTypeToViewportClass.ts +0 -16
  1624. package/src/RenderingEngine/helpers/viewportTypeUsesCustomRenderingPipeline.ts +0 -7
  1625. package/src/RenderingEngine/helpers/volumeNewImageEventDispatcher.ts +0 -75
  1626. package/src/RenderingEngine/index.ts +0 -23
  1627. package/src/RenderingEngine/renderingEngineCache.ts +0 -58
  1628. package/src/RenderingEngine/vtkClasses/index.js +0 -11
  1629. package/src/RenderingEngine/vtkClasses/vtkOffscreenMultiRenderWindow.js +0 -149
  1630. package/src/RenderingEngine/vtkClasses/vtkSharedVolumeMapper.js +0 -52
  1631. package/src/RenderingEngine/vtkClasses/vtkSlabCamera.ts +0 -922
  1632. package/src/RenderingEngine/vtkClasses/vtkStreamingOpenGLRenderWindow.js +0 -48
  1633. package/src/RenderingEngine/vtkClasses/vtkStreamingOpenGLTexture.js +0 -272
  1634. package/src/RenderingEngine/vtkClasses/vtkStreamingOpenGLViewNodeFactory.js +0 -152
  1635. package/src/RenderingEngine/vtkClasses/vtkStreamingOpenGLVolumeMapper.js +0 -308
  1636. package/src/Settings.ts +0 -300
  1637. package/src/cache/cache.ts +0 -1005
  1638. package/src/cache/classes/Contour.ts +0 -73
  1639. package/src/cache/classes/ContourSet.ts +0 -217
  1640. package/src/cache/classes/ImageVolume.ts +0 -710
  1641. package/src/cache/classes/Surface.ts +0 -61
  1642. package/src/cache/index.ts +0 -6
  1643. package/src/constants/backgroundColors.ts +0 -5
  1644. package/src/constants/cpuColormaps.ts +0 -1537
  1645. package/src/constants/epsilon.ts +0 -3
  1646. package/src/constants/index.ts +0 -15
  1647. package/src/constants/mprCameraValues.ts +0 -20
  1648. package/src/constants/rendering.ts +0 -8
  1649. package/src/constants/viewportPresets.ts +0 -357
  1650. package/src/enums/BlendModes.ts +0 -23
  1651. package/src/enums/CalibrationTypes.ts +0 -55
  1652. package/src/enums/ContourType.ts +0 -6
  1653. package/src/enums/DynamicOperatorType.ts +0 -14
  1654. package/src/enums/Events.ts +0 -250
  1655. package/src/enums/GeometryType.ts +0 -6
  1656. package/src/enums/ImageQualityStatus.ts +0 -37
  1657. package/src/enums/InterpolationType.ts +0 -13
  1658. package/src/enums/MetadataModules.ts +0 -32
  1659. package/src/enums/OrientationAxis.ts +0 -8
  1660. package/src/enums/RequestType.ts +0 -15
  1661. package/src/enums/SharedArrayBufferModes.ts +0 -11
  1662. package/src/enums/VOILUTFunctionType.ts +0 -10
  1663. package/src/enums/VideoEnums.ts +0 -9
  1664. package/src/enums/ViewportStatus.ts +0 -14
  1665. package/src/enums/ViewportType.ts +0 -22
  1666. package/src/enums/index.ts +0 -35
  1667. package/src/eventTarget.ts +0 -144
  1668. package/src/getEnabledElement.ts +0 -127
  1669. package/src/global.ts +0 -8
  1670. package/src/index.ts +0 -153
  1671. package/src/init.ts +0 -330
  1672. package/src/loaders/ProgressiveRetrieveImages.ts +0 -380
  1673. package/src/loaders/configuration/interleavedRetrieve.ts +0 -96
  1674. package/src/loaders/configuration/sequentialRetrieve.ts +0 -17
  1675. package/src/loaders/configuration/singleRetrieve.ts +0 -18
  1676. package/src/loaders/fillNearbyFrames.ts +0 -53
  1677. package/src/loaders/geometryLoader.ts +0 -59
  1678. package/src/loaders/imageLoader.ts +0 -587
  1679. package/src/loaders/utils/contourSet/createContourSet.ts +0 -29
  1680. package/src/loaders/utils/contourSet/validateContourSet.ts +0 -38
  1681. package/src/loaders/utils/surface/createSurface.ts +0 -31
  1682. package/src/loaders/utils/surface/validateSurface.ts +0 -9
  1683. package/src/loaders/volumeLoader.ts +0 -670
  1684. package/src/metaData.ts +0 -86
  1685. package/src/requestPool/imageLoadPoolManager.ts +0 -43
  1686. package/src/requestPool/imageRetrievalPoolManager.ts +0 -25
  1687. package/src/requestPool/requestPoolManager.ts +0 -348
  1688. package/src/types/AABB2.ts +0 -4
  1689. package/src/types/AABB3.ts +0 -11
  1690. package/src/types/ActorSliceRange.ts +0 -17
  1691. package/src/types/AffineMatrix.ts +0 -8
  1692. package/src/types/BoundsIJK.ts +0 -5
  1693. package/src/types/BoundsLPS.ts +0 -5
  1694. package/src/types/CPUFallbackColormap.ts +0 -23
  1695. package/src/types/CPUFallbackColormapData.ts +0 -12
  1696. package/src/types/CPUFallbackColormapsData.ts +0 -7
  1697. package/src/types/CPUFallbackEnabledElement.ts +0 -41
  1698. package/src/types/CPUFallbackLUT.ts +0 -5
  1699. package/src/types/CPUFallbackLookupTable.ts +0 -17
  1700. package/src/types/CPUFallbackRenderingTools.ts +0 -25
  1701. package/src/types/CPUFallbackTransform.ts +0 -16
  1702. package/src/types/CPUFallbackViewport.ts +0 -29
  1703. package/src/types/CPUFallbackViewportDisplayedArea.ts +0 -15
  1704. package/src/types/CPUIImageData.ts +0 -50
  1705. package/src/types/Color.ts +0 -10
  1706. package/src/types/Colormap.ts +0 -31
  1707. package/src/types/ContourData.ts +0 -21
  1708. package/src/types/Cornerstone3DConfig.ts +0 -73
  1709. package/src/types/CustomEventType.ts +0 -14
  1710. package/src/types/EventTypes.ts +0 -483
  1711. package/src/types/FlipDirection.ts +0 -9
  1712. package/src/types/IActor.ts +0 -37
  1713. package/src/types/ICache.ts +0 -29
  1714. package/src/types/ICachedGeometry.ts +0 -13
  1715. package/src/types/ICachedImage.ts +0 -13
  1716. package/src/types/ICachedVolume.ts +0 -12
  1717. package/src/types/ICamera.ts +0 -36
  1718. package/src/types/IContour.ts +0 -18
  1719. package/src/types/IContourSet.ts +0 -59
  1720. package/src/types/IDynamicImageVolume.ts +0 -18
  1721. package/src/types/IEnabledElement.ts +0 -24
  1722. package/src/types/IGeometry.ts +0 -13
  1723. package/src/types/IImage.ts +0 -136
  1724. package/src/types/IImageCalibration.ts +0 -41
  1725. package/src/types/IImageData.ts +0 -49
  1726. package/src/types/IImageVolume.ts +0 -103
  1727. package/src/types/ILoadObject.ts +0 -36
  1728. package/src/types/IRegisterImageLoader.ts +0 -10
  1729. package/src/types/IRenderingEngine.ts +0 -31
  1730. package/src/types/IRetrieveConfiguration.ts +0 -194
  1731. package/src/types/IStackInput.ts +0 -30
  1732. package/src/types/IStackViewport.ts +0 -3
  1733. package/src/types/IStreamingImageVolume.ts +0 -13
  1734. package/src/types/IStreamingVolumeProperties.ts +0 -17
  1735. package/src/types/ISurface.ts +0 -14
  1736. package/src/types/IVideoViewport.ts +0 -87
  1737. package/src/types/IViewport.ts +0 -464
  1738. package/src/types/IViewportId.ts +0 -9
  1739. package/src/types/IVolume.ts +0 -8
  1740. package/src/types/IVolumeInput.ts +0 -36
  1741. package/src/types/IVolumeViewport.ts +0 -177
  1742. package/src/types/ImageLoadListener.ts +0 -20
  1743. package/src/types/ImageLoaderFn.ts +0 -16
  1744. package/src/types/ImagePixelModule.ts +0 -14
  1745. package/src/types/ImagePlaneModule.ts +0 -17
  1746. package/src/types/ImageSliceData.ts +0 -6
  1747. package/src/types/ImageVolumeProps.ts +0 -15
  1748. package/src/types/Mat3.ts +0 -8
  1749. package/src/types/Metadata.ts +0 -39
  1750. package/src/types/OrientationVectors.ts +0 -36
  1751. package/src/types/PixelDataTypedArray.ts +0 -15
  1752. package/src/types/Plane.ts +0 -6
  1753. package/src/types/Point2.ts +0 -6
  1754. package/src/types/Point3.ts +0 -15
  1755. package/src/types/Point4.ts +0 -6
  1756. package/src/types/RGB.ts +0 -6
  1757. package/src/types/ScalingParameters.ts +0 -33
  1758. package/src/types/StackViewportProperties.ts +0 -18
  1759. package/src/types/SurfaceData.ts +0 -15
  1760. package/src/types/TransformMatrix2D.ts +0 -4
  1761. package/src/types/VideoViewportProperties.ts +0 -15
  1762. package/src/types/VideoViewportTypes.ts +0 -20
  1763. package/src/types/ViewportInputOptions.ts +0 -25
  1764. package/src/types/ViewportPreset.ts +0 -14
  1765. package/src/types/ViewportProperties.ts +0 -21
  1766. package/src/types/VolumeLoaderFn.ts +0 -18
  1767. package/src/types/VolumeProps.ts +0 -57
  1768. package/src/types/VolumeViewportProperties.ts +0 -16
  1769. package/src/types/displayArea.ts +0 -42
  1770. package/src/types/index.ts +0 -254
  1771. package/src/types/voi.ts +0 -15
  1772. package/src/utilities/PointsManager.ts +0 -260
  1773. package/src/utilities/ProgressiveIterator.ts +0 -190
  1774. package/src/utilities/RLEVoxelMap.ts +0 -331
  1775. package/src/utilities/VoxelManager.ts +0 -483
  1776. package/src/utilities/actorCheck.ts +0 -24
  1777. package/src/utilities/applyPreset.ts +0 -138
  1778. package/src/utilities/cacheUtils.ts +0 -145
  1779. package/src/utilities/calculateViewportsSpatialRegistration.ts +0 -67
  1780. package/src/utilities/calibratedPixelSpacingMetadataProvider.ts +0 -36
  1781. package/src/utilities/clamp.ts +0 -5
  1782. package/src/utilities/color.ts +0 -33
  1783. package/src/utilities/colormap.ts +0 -111
  1784. package/src/utilities/convertStackToVolumeViewport.ts +0 -117
  1785. package/src/utilities/convertToGrayscale.ts +0 -27
  1786. package/src/utilities/convertVolumeToStackViewport.ts +0 -125
  1787. package/src/utilities/createFloat32SharedArray.ts +0 -60
  1788. package/src/utilities/createInt16SharedArray.ts +0 -43
  1789. package/src/utilities/createLinearRGBTransferFunction.ts +0 -22
  1790. package/src/utilities/createSigmoidRGBTransferFunction.ts +0 -63
  1791. package/src/utilities/createUInt16SharedArray.ts +0 -43
  1792. package/src/utilities/createUint8SharedArray.ts +0 -45
  1793. package/src/utilities/decimate.ts +0 -17
  1794. package/src/utilities/deepFreeze.ts +0 -19
  1795. package/src/utilities/deepMerge.ts +0 -86
  1796. package/src/utilities/eventListener/MultiTargetEventListenerManager.ts +0 -90
  1797. package/src/utilities/eventListener/TargetEventListeners.ts +0 -278
  1798. package/src/utilities/generateVolumePropsFromImageIds.ts +0 -186
  1799. package/src/utilities/genericMetadataProvider.ts +0 -43
  1800. package/src/utilities/getBufferConfiguration.ts +0 -69
  1801. package/src/utilities/getClosestImageId.ts +0 -79
  1802. package/src/utilities/getClosestStackImageIndexForPoint.ts +0 -128
  1803. package/src/utilities/getCurrentVolumeViewportSlice.ts +0 -166
  1804. package/src/utilities/getImageLegacy.ts +0 -29
  1805. package/src/utilities/getImageSliceDataForVolumeViewport.ts +0 -61
  1806. package/src/utilities/getMinMax.ts +0 -31
  1807. package/src/utilities/getRandomSampleFromArray.ts +0 -30
  1808. package/src/utilities/getRuntimeId.ts +0 -56
  1809. package/src/utilities/getScalarDataType.ts +0 -31
  1810. package/src/utilities/getScalingParameters.ts +0 -35
  1811. package/src/utilities/getSliceRange.ts +0 -86
  1812. package/src/utilities/getSpacingInNormalDirection.ts +0 -44
  1813. package/src/utilities/getTargetVolumeAndSpacingInNormalDir.ts +0 -150
  1814. package/src/utilities/getViewportImageCornersInWorld.ts +0 -109
  1815. package/src/utilities/getViewportImageIds.ts +0 -22
  1816. package/src/utilities/getViewportModality.ts +0 -22
  1817. package/src/utilities/getViewportsWithImageURI.ts +0 -39
  1818. package/src/utilities/getViewportsWithVolumeId.ts +0 -38
  1819. package/src/utilities/getVoiFromSigmoidRGBTransferFunction.ts +0 -23
  1820. package/src/utilities/getVolumeActorCorners.ts +0 -24
  1821. package/src/utilities/getVolumeId.ts +0 -16
  1822. package/src/utilities/getVolumeSliceRangeInfo.ts +0 -60
  1823. package/src/utilities/getVolumeViewportScrollInfo.ts +0 -41
  1824. package/src/utilities/getVolumeViewportsContainingSameVolumes.ts +0 -58
  1825. package/src/utilities/hasFloatScalingParameters.ts +0 -15
  1826. package/src/utilities/hasNaNValues.ts +0 -12
  1827. package/src/utilities/imageIdToURI.ts +0 -10
  1828. package/src/utilities/imageRetrieveMetadataProvider.ts +0 -36
  1829. package/src/utilities/imageToWorldCoords.ts +0 -57
  1830. package/src/utilities/index.ts +0 -171
  1831. package/src/utilities/indexWithinDimensions.ts +0 -27
  1832. package/src/utilities/invertRgbTransferFunction.ts +0 -41
  1833. package/src/utilities/isEqual.ts +0 -92
  1834. package/src/utilities/isOpposite.ts +0 -23
  1835. package/src/utilities/isPTPrescaledWithSUV.ts +0 -7
  1836. package/src/utilities/isTypedArray.ts +0 -20
  1837. package/src/utilities/isValidVolume.ts +0 -59
  1838. package/src/utilities/isVideoTransferSyntax.ts +0 -26
  1839. package/src/utilities/loadImageToCanvas.ts +0 -202
  1840. package/src/utilities/makeVolumeMetadata.ts +0 -87
  1841. package/src/utilities/planar.ts +0 -102
  1842. package/src/utilities/renderToCanvasCPU.ts +0 -48
  1843. package/src/utilities/renderToCanvasGPU.ts +0 -195
  1844. package/src/utilities/roundNumber.ts +0 -57
  1845. package/src/utilities/scaleRgbTransferFunction.ts +0 -37
  1846. package/src/utilities/snapFocalPointToSlice.ts +0 -78
  1847. package/src/utilities/sortImageIdsAndGetSpacing.ts +0 -180
  1848. package/src/utilities/spatialRegistrationMetadataProvider.ts +0 -48
  1849. package/src/utilities/transferFunctionUtils.ts +0 -27
  1850. package/src/utilities/transformCanvasToIJK.ts +0 -18
  1851. package/src/utilities/transformIJKToCanvas.ts +0 -18
  1852. package/src/utilities/transformIndexToWorld.ts +0 -14
  1853. package/src/utilities/transformWorldToIndex.ts +0 -16
  1854. package/src/utilities/triggerEvent.ts +0 -38
  1855. package/src/utilities/updateVTKImageDataWithCornerstoneImage.ts +0 -42
  1856. package/src/utilities/uuidv4.ts +0 -13
  1857. package/src/utilities/windowLevel.ts +0 -48
  1858. package/src/utilities/worldToImageCoords.ts +0 -65
  1859. package/src/webWorkerManager/webWorkerManager.js +0 -254
  1860. /package/{src/utilities/eventListener/index.ts → dist/esm/utilities/eventListener/index.d.ts} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","mappings":"CAAA,SAA2CA,EAAMC,GAC1B,iBAAZC,SAA0C,iBAAXC,OACxCA,OAAOD,QAAUD,EAAQG,QAAQ,cAAeA,QAAQ,yDAA0DA,QAAQ,wDAAyDA,QAAQ,kEAAmEA,QAAQ,sDAAuDA,QAAQ,aAAcA,QAAQ,6CAA8CA,QAAQ,oCAAqCA,QAAQ,0CAA2CA,QAAQ,8CAA+CA,QAAQ,yCAA0CA,QAAQ,0BAA2BA,QAAQ,4CAA6CA,QAAQ,yCAA0CA,QAAQ,yCAA0CA,QAAQ,6CAA8CA,QAAQ,yCAA0CA,QAAQ,+CAAgDA,QAAQ,8CAA+CA,QAAQ,6CAA8CA,QAAQ,2CAA4CA,QAAQ,+CAAgDA,QAAQ,yDAA0DA,QAAQ,sCAAuCA,QAAQ,6CAA8CA,QAAQ,wCAAyCA,QAAQ,yCAA0CA,QAAQ,iDAAkDA,QAAQ,0CAA2CA,QAAQ,4CAA6CA,QAAQ,2CAA4CA,QAAQ,kDAAmDA,QAAQ,gDAAiDA,QAAQ,+CAAgDA,QAAQ,6DAA8DA,QAAQ,mDAAoDA,QAAQ,6CAA8CA,QAAQ,2CAA4CA,QAAQ,iDAAkDA,QAAQ,gDAAiDA,QAAQ,2CAA4CA,QAAQ,iDAAkDA,QAAQ,wDAAyDA,QAAQ,sDAAuDA,QAAQ,mDAAoDA,QAAQ,qDAAsDA,QAAQ,gDACz8E,mBAAXC,QAAyBA,OAAOC,IAC9CD,OAAO,CAAC,aAAc,wDAAyD,uDAAwD,iEAAkE,qDAAsD,YAAa,4CAA6C,mCAAoC,yCAA0C,6CAA8C,wCAAyC,yBAA0B,2CAA4C,wCAAyC,wCAAyC,4CAA6C,wCAAyC,8CAA+C,6CAA8C,4CAA6C,0CAA2C,8CAA+C,wDAAyD,qCAAsC,4CAA6C,uCAAwC,wCAAyC,gDAAiD,yCAA0C,2CAA4C,0CAA2C,iDAAkD,+CAAgD,8CAA+C,4DAA6D,kDAAmD,4CAA6C,0CAA2C,gDAAiD,+CAAgD,0CAA2C,gDAAiD,uDAAwD,qDAAsD,kDAAmD,oDAAqD,+CAAgDJ,GACjkE,iBAAZC,QACdA,QAAuB,cAAID,EAAQG,QAAQ,cAAeA,QAAQ,yDAA0DA,QAAQ,wDAAyDA,QAAQ,kEAAmEA,QAAQ,sDAAuDA,QAAQ,aAAcA,QAAQ,6CAA8CA,QAAQ,oCAAqCA,QAAQ,0CAA2CA,QAAQ,8CAA+CA,QAAQ,yCAA0CA,QAAQ,0BAA2BA,QAAQ,4CAA6CA,QAAQ,yCAA0CA,QAAQ,yCAA0CA,QAAQ,6CAA8CA,QAAQ,yCAA0CA,QAAQ,+CAAgDA,QAAQ,8CAA+CA,QAAQ,6CAA8CA,QAAQ,2CAA4CA,QAAQ,+CAAgDA,QAAQ,yDAA0DA,QAAQ,sCAAuCA,QAAQ,6CAA8CA,QAAQ,wCAAyCA,QAAQ,yCAA0CA,QAAQ,iDAAkDA,QAAQ,0CAA2CA,QAAQ,4CAA6CA,QAAQ,2CAA4CA,QAAQ,kDAAmDA,QAAQ,gDAAiDA,QAAQ,+CAAgDA,QAAQ,6DAA8DA,QAAQ,mDAAoDA,QAAQ,6CAA8CA,QAAQ,2CAA4CA,QAAQ,iDAAkDA,QAAQ,gDAAiDA,QAAQ,2CAA4CA,QAAQ,iDAAkDA,QAAQ,wDAAyDA,QAAQ,sDAAuDA,QAAQ,mDAAoDA,QAAQ,qDAAsDA,QAAQ,gDAE5+EJ,EAAoB,cAAIC,EAAQD,EAAa,OAAGA,EAAK,yDAA0DA,EAAK,wDAAyDA,EAAK,kEAAmEA,EAAK,sDAAuDA,EAAa,OAAGA,EAAK,6CAA8CA,EAAK,oCAAqCA,EAAK,0CAA2CA,EAAK,8CAA+CA,EAAK,yCAA0CA,EAAK,0BAA2BA,EAAK,4CAA6CA,EAAK,yCAA0CA,EAAK,yCAA0CA,EAAK,6CAA8CA,EAAK,yCAA0CA,EAAK,+CAAgDA,EAAK,8CAA+CA,EAAK,6CAA8CA,EAAK,2CAA4CA,EAAK,+CAAgDA,EAAK,yDAA0DA,EAAK,sCAAuCA,EAAK,6CAA8CA,EAAK,wCAAyCA,EAAK,yCAA0CA,EAAK,iDAAkDA,EAAK,0CAA2CA,EAAK,4CAA6CA,EAAK,2CAA4CA,EAAK,kDAAmDA,EAAK,gDAAiDA,EAAK,+CAAgDA,EAAK,6DAA8DA,EAAK,mDAAoDA,EAAK,6CAA8CA,EAAK,2CAA4CA,EAAK,iDAAkDA,EAAK,gDAAiDA,EAAK,2CAA4CA,EAAK,iDAAkDA,EAAK,wDAAyDA,EAAK,sDAAuDA,EAAK,mDAAoDA,EAAK,qDAAsDA,EAAK,+CACt1E,CATD,CASGO,MAAM,CAACC,EAAkCC,EAAkCC,EAAkCC,EAAiCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,EAAgCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,EAAiCC,EAAkCC,EAAkCC,EAAiCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,EAAkCC,I,kCCTjiDnD,EAAOD,QAAUgB,C,UCAjBf,EAAOD,QAAUkD,C,UCAjBjD,EAAOD,QAAUmB,C,UCAjBlB,EAAOD,QAAUa,C,UCAjBZ,EAAOD,QAAUY,C,UCAjBX,EAAOD,QAAU6B,C,UCAjB5B,EAAOD,QAAUe,C,UCAjBd,EAAOD,QAAUU,C,UCAjBT,EAAOD,QAAUc,C,SCAjBb,EAAOD,QAAU8B,C,UCAjB7B,EAAOD,QAAU+B,C,UCAjB9B,EAAOD,QAAUoB,C,UCAjBnB,EAAOD,QAAUQ,C,SCAjBP,EAAOD,QAAUS,C,UCAjBR,EAAOD,QAAUwB,C,UCAjBvB,EAAOD,QAAUyB,C,UCAjBxB,EAAOD,QAAUgC,C,UCAjB/B,EAAOD,QAAUmD,C,UCAjBlD,EAAOD,QAAU2B,C,UCAjB1B,EAAOD,QAAU4B,C,UCAjB3B,EAAOD,QAAU0B,C,UCAjBzB,EAAOD,QAAUsB,C,QCAjBrB,EAAOD,QAAUuB,C,UCAjBtB,EAAOD,QAAUO,C,UCAjBN,EAAOD,QAAUkC,C,UCAjBjC,EAAOD,QAAUmC,C,UCAjBlC,EAAOD,QAAUoC,C,UCAjBnC,EAAOD,QAAUqC,C,UCAjBpC,EAAOD,QAAUsC,C,UCAjBrC,EAAOD,QAAUuC,C,UCAjBtC,EAAOD,QAAUwC,C,UCAjBvC,EAAOD,QAAUyC,C,SCAjBxC,EAAOD,QAAUiC,C,UCAjBhC,EAAOD,QAAU0C,C,UCAjBzC,EAAOD,QAAU2C,C,UCAjB1C,EAAOD,QAAU4C,C,UCAjB3C,EAAOD,QAAU6C,C,UCAjB5C,EAAOD,QAAUkB,C,UCAjBjB,EAAOD,QAAUiD,C,UCAjBhD,EAAOD,QAAU8C,C,UCAjB7C,EAAOD,QAAU+C,C,UCAjB9C,EAAOD,QAAUoD,C,UCAjBnD,EAAOD,QAAUqB,C,UCAjBpB,EAAOD,QAAUgD,C,UCAjB/C,EAAOD,QAAUiB,C,UCAjBhB,EAAOD,QAAUM,C,UCAjBL,EAAOD,QAAUW,C,GCCb0C,EAA2B,CAAC,EAGhC,SAASC,EAAoBC,GAE5B,IAAIC,EAAeH,EAAyBE,GAC5C,QAAqBE,IAAjBD,EACH,OAAOA,EAAaxD,QAGrB,IAAIC,EAASoD,EAAyBE,GAAY,CAGjDvD,QAAS,CAAC,GAOX,OAHA0D,EAAoBH,GAAUtD,EAAQA,EAAOD,QAASsD,GAG/CrD,EAAOD,OACf,CCrBAsD,EAAoBK,EAAK1D,IACxB,IAAI2D,EAAS3D,GAAUA,EAAO4D,WAC7B,IAAO5D,EAAiB,QACxB,IAAM,EAEP,OADAqD,EAAoBQ,EAAEF,EAAQ,CAAEG,EAAGH,IAC5BA,CAAM,ECLdN,EAAoBQ,EAAI,CAAC9D,EAASgE,KACjC,IAAI,IAAIC,KAAOD,EACXV,EAAoBY,EAAEF,EAAYC,KAASX,EAAoBY,EAAElE,EAASiE,IAC5EE,OAAOC,eAAepE,EAASiE,EAAK,CAAEI,YAAY,EAAMC,IAAKN,EAAWC,IAE1E,ECNDX,EAAoBY,EAAI,CAACK,EAAKC,IAAUL,OAAOM,UAAUC,eAAeC,KAAKJ,EAAKC,GCClFlB,EAAoBsB,EAAK5E,IACH,oBAAX6E,QAA0BA,OAAOC,aAC1CX,OAAOC,eAAepE,EAAS6E,OAAOC,YAAa,CAAEC,MAAO,WAE7DZ,OAAOC,eAAepE,EAAS,aAAc,CAAE+E,OAAO,GAAO,E,4uLCL9D,IAGKC,EAAM,SAANA,GAAM,OAANA,EAAM,gCAANA,EAAM,0CAANA,EAAM,oCAANA,EAAM,8CAANA,EAAM,wCAANA,EAAM,wCAANA,EAAM,iEAANA,EAAM,0DAANA,EAAM,gDAANA,EAAM,8CAANA,EAAM,4CAANA,EAAM,0DAANA,EAAM,4EAANA,EAAM,wCAANA,EAAM,0DAANA,EAAM,kDAANA,EAAM,oEAANA,EAAM,0CAANA,EAAM,wDAANA,EAAM,8DAANA,EAAM,kEAANA,EAAM,kEAANA,EAAM,sEAANA,EAAM,8CAANA,EAAM,gDAANA,EAAM,sDAANA,EAAM,gEAANA,EAAM,gEAANA,EAAM,0DAANA,EAAM,0EAANA,EAAM,0DAANA,EAAM,gDAANA,EAAM,8DAANA,EAAM,sDAANA,EAAM,kDAANA,CAAM,EAANA,GAAM,IAsPX,UCzPA,IAGKC,EAAW,SAAXA,GAAW,OAAXA,EAAW,0BAAXA,EAAW,sBAAXA,EAAW,oBAAXA,EAAW,kBAAXA,CAAW,EAAXA,GAAW,IAWhB,UCdA,IAIKC,EAAY,SAAZA,GAAY,OAAZA,EAAY,cAAZA,EAAY,4BAAZA,EAAY,0BAAZA,EAAY,qBAAZA,EAAY,cAAZA,CAAY,EAAZA,GAAY,IAiBjB,UCrBA,IAGKC,EAAiB,SAAjBA,GAAiB,OAAjBA,EAAAA,EAAiB,qBAAjBA,EAAAA,EAAiB,mBAAjBA,EAAAA,EAAiB,6BAAjBA,CAAiB,EAAjBA,GAAiB,IAStB,U,sBCVA,MAAM,UAAEC,GAAcC,IAEtB,IAOKC,EAAU,SAAVA,GAQwD,OARxDA,EAAAA,EAAU,UAEDF,EAAUG,iBAAe,YAFlCD,EAAAA,EAAU,wBAIaF,EAAUI,yBAAuB,0BAJxDF,EAAAA,EAAU,wBAMaF,EAAUK,yBAAuB,0BANxDH,EAAAA,EAAU,wBAQaF,EAAUM,yBAAuB,0BARxDJ,CAAU,EAAVA,GAAU,IAWf,U,ICtBKK,EAAe,SAAfA,GAAe,OAAfA,EAAe,cAAfA,EAAe,kBAAfA,EAAe,oBAAfA,EAAe,0BAAfA,CAAe,EAAfA,GAAe,IAOpB,UCPA,IAGKC,EAAsB,SAAtBA,GAAsB,OAAtBA,EAAsB,YAAtBA,EAAsB,cAAtBA,EAAsB,YAAtBA,CAAsB,EAAtBA,GAAsB,IAO3B,U,ICVKC,EAAY,SAAZA,GAAY,OAAZA,EAAY,kBAAZA,EAAY,kBAAZA,CAAY,EAAZA,GAAY,IAKjB,U,ICLKC,EAAW,SAAXA,GAAW,OAAXA,EAAW,8BAAXA,EAAW,0BAAXA,CAAW,EAAXA,GAAW,IAKhB,UCLA,IAGKC,EAAkB,SAAlBA,GAAkB,OAAlBA,EAAkB,gBAAlBA,EAAkB,0BAAlBA,CAAkB,EAAlBA,GAAkB,IAMvB,UCTA,IAIKC,EAAmB,SAAnBA,GAAmB,OAAnBA,EAAmB,UAAnBA,EAAmB,kBAAnBA,EAAmB,oBAAnBA,CAAmB,EAAnBA,GAAmB,IASxB,UCyCA,EAlD4B,SAAhBC,GAAgB,OAAhBA,EAAgB,kBAAhBA,EAAgB,YAAhBA,EAAgB,YAAhBA,EAAgB,kBAAhBA,EAAgB,gBAAhBA,EAAgB,cAAhBA,EAAgB,4BAAhBA,CAAgB,M,ICJvBC,EAAc,SAAdA,GAAc,OAAdA,EAAc,iBAAdA,EAAc,kBAAdA,EAAc,uBAAdA,EAAc,gBAAdA,EAAc,oBAAdA,CAAc,EAAdA,GAAc,IAanB,UCbA,IAIKC,EAAkB,SAAlBA,GAAkB,OAAlBA,EAAAA,EAAkB,iCAAlBA,EAAAA,EAAkB,2CAAlBA,EAAAA,EAAkB,iCAAlBA,EAAAA,EAAkB,iBAAlBA,EAAAA,EAAkB,qCAAlBA,CAAkB,EAAlBA,GAAkB,IAgCvB,UCpCA,IAGKC,EAAS,SAATA,GAAS,OAATA,EAAS,UAATA,EAAS,WAATA,CAAS,EAATA,GAAS,ICKTC,EAAe,SAAfA,GAAe,OAAfA,EAAe,gCAAfA,EAAe,kBAAfA,EAAe,mCAAfA,EAAe,qCAAfA,EAAe,mCAAfA,EAAe,+BAAfA,EAAe,+BAAfA,EAAe,2BAAfA,EAAe,iCAAfA,EAAe,8BAAfA,EAAe,oDAAfA,EAAe,mCAAfA,EAAe,wBAAfA,EAAe,mCAAfA,EAAe,2BAAfA,EAAe,+BAAfA,EAAe,6BAAfA,EAAe,6BAAfA,EAAe,4DAAfA,EAAe,uBAAfA,CAAe,EAAfA,GAAe,IAuBpB,UCi+CA,EAr/CgD,CAC9CC,QAAS,CACPC,KAAM,WACNC,YAAa,IACbC,OAAQ,CACN,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,GAAI,EAAG,EAAG,KACX,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,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,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,OAGpBC,IAAK,CACHH,KAAM,MACNI,UAAW,IACXF,OAAQ,CACN,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,GAAI,EAAG,KACX,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,GAAI,GAAI,KACZ,CAAC,EAAG,IAAK,GAAI,KACb,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,EAAG,IAAK,IAAK,KACd,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,GAAI,IAAK,IAAK,KACf,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,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,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,OAGpBG,aAAc,CACZL,KAAM,iBACNI,UAAW,IACXF,OAAQ,CACN,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,GAAI,KACX,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,EAAG,EAAG,IAAK,KACZ,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,GAAI,EAAG,IAAK,KACb,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,EAAG,IAAK,KACd,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,IAAK,KACf,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,GAAI,KACd,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,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,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,OAGpBI,UAAW,CACTN,KAAM,cACNI,UAAW,IACXF,OAAQ,CACN,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,EAAG,EAAG,EAAG,KACV,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,EAAG,GAAI,KACZ,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,GAAI,GAAI,IAAK,KACd,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,IAAK,IAAK,IAAK,KAChB,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,GAAI,GAAI,KACb,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,GAAI,IAAK,GAAI,KACd,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,GAAI,KACf,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,IAAK,EAAG,KACd,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,GAAI,EAAG,KACb,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,EAAG,KACZ,CAAC,IAAK,EAAG,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TC,cACE,+NACFC,QAAS,MACTC,cAAe,KAEjB,CACE/C,KAAM,UACNuC,gBAAiB,cACjBC,cAAe,KACfC,cAAe,sDACfC,SAAU,MACVC,MAAO,IACPC,QAAS,MACTC,cACE,mGACFC,QAAS,MACTC,cAAe,KAEjB,CACE/C,KAAM,WACNuC,gBAAiB,iBACjBC,cAAe,IACfC,cAAe,6CACfC,SAAU,IACVC,MAAO,IACPC,QAAS,MACTC,cACE,2FACFC,QAAS,IACTC,cAAe,KAEjB,CACE/C,KAAM,aACNuC,gBAAiB,cACjBC,cAAe,KACfC,cACE,sFACFC,SAAU,MACVC,MAAO,IACPC,QAAS,MACTC,cACE,+JACFC,QAAS,MACTC,cAAe,KAEjB,CACE/C,KAAM,cACNuC,gBAAiB,cACjBC,cAAe,KACfC,cACE,qFACFC,SAAU,MACVC,MAAO,IACPC,QAAS,MACTC,cACE,qJACFC,QAAS,MACTC,cAAe,KAEjB,CACE/C,KAAM,cACNuC,gBAAiB,cACjBC,cAAe,KACfC,cACE,0GACFC,SAAU,MACVC,MAAO,IACPC,QAAS,MACTC,cACE,2IACFC,QAAS,MACTC,cAAe,KAEjB,CACE/C,KAAM,6BACNuC,gBAAiB,cACjBC,cAAe,KACfC,cACE,oEACFC,SAAU,MACVC,MAAO,IACPC,QAAS,MACTC,cACE,yIACFC,QAAS,MACTC,cAAe,KAEjB,CACE/C,KAAM,mBACNuC,gBAAiB,cACjBC,cAAe,IACfC,cACE,qEACFC,SAAU,IACVC,MAAO,IACPC,QAAS,MACTC,cACE,0IACFC,QAAS,IACTC,cAAe,KAEjB,CACE/C,KAAM,uBACNuC,gBAAiB,cACjBC,cAAe,IACfC,cACE,+EACFC,SAAU,IACVC,MAAO,IACPC,QAAS,MACTC,cACE,4HACFC,QAAS,IACTC,cAAe,KAEjB,CACE/C,KAAM,yBACNuC,gBAAiB,cACjBC,cAAe,IACfC,cACE,sGACFC,SAAU,IACVC,MAAO,IACPC,QAAS,MACTC,cACE,iKACFC,QAAS,IACTC,cAAe,KAEjB,CACE/C,KAAM,yBACNuC,gBAAiB,cACjBC,cAAe,KACfC,cACE,m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","sources":["webpack://cornerstone3D/webpack/universalModuleDefinition","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/Core/DataArray\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/Core/DataArray/Constants\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/Core/HalfFloat\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/Core/Math\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/Core/MatrixBuilder\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/Core/Points\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/DataModel/ImageData\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/DataModel/PiecewiseFunction\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/DataModel/Plane\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Common/DataModel/PolyData\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/Actor\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/Camera\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/ColorTransferFunction\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/ColorTransferFunction/ColorMaps\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/ImageMapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/ImageSlice\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/Mapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/Property/Constants\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/RenderWindow\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/RenderWindowInteractor\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/Renderer\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/Volume\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/VolumeMapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Core/VolumeMapper/Constants\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/Actor\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/Actor2D\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/Camera\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/Glyph3DMapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/ImageMapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/ImageSlice\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/PixelSpaceCallbackMapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/PolyDataMapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/RenderWindow\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/Renderer\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/Skybox\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/SphereMapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/StickMapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/Texture\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/Texture/Constants\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/Volume\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/OpenGL/VolumeMapper\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Profiles/Geometry\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/Profiles/Volume\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/Rendering/SceneGraph/ViewNodeFactory\"","webpack://cornerstone3D/external umd \"@kitware/vtk.js/macros\"","webpack://cornerstone3D/external umd {\"root\":\"window\",\"commonjs\":\"detect-gpu\",\"commonjs2\":\"detect-gpu\",\"amd\":\"detect-gpu\"}","webpack://cornerstone3D/external umd {\"root\":\"window\",\"commonjs\":\"gl-matrix\",\"commonjs2\":\"gl-matrix\",\"amd\":\"gl-matrix\"}","webpack://cornerstone3D/webpack/bootstrap","webpack://cornerstone3D/webpack/runtime/compat get default export","webpack://cornerstone3D/webpack/runtime/define property getters","webpack://cornerstone3D/webpack/runtime/hasOwnProperty shorthand","webpack://cornerstone3D/webpack/runtime/make namespace object","webpack://cornerstone3D/./src/enums/Events.ts","webpack://cornerstone3D/./src/enums/RequestType.ts","webpack://cornerstone3D/./src/enums/ViewportType.ts","webpack://cornerstone3D/./src/enums/InterpolationType.ts","webpack://cornerstone3D/./src/enums/BlendModes.ts","webpack://cornerstone3D/./src/enums/OrientationAxis.ts","webpack://cornerstone3D/./src/enums/SharedArrayBufferModes.ts","webpack://cornerstone3D/./src/enums/GeometryType.ts","webpack://cornerstone3D/./src/enums/ContourType.ts","webpack://cornerstone3D/./src/enums/VOILUTFunctionType.ts","webpack://cornerstone3D/./src/enums/DynamicOperatorType.ts","webpack://cornerstone3D/./src/enums/CalibrationTypes.ts","webpack://cornerstone3D/./src/enums/ViewportStatus.ts","webpack://cornerstone3D/./src/enums/ImageQualityStatus.ts","webpack://cornerstone3D/./src/enums/VideoEnums.ts","webpack://cornerstone3D/./src/enums/MetadataModules.ts","webpack://cornerstone3D/./src/constants/cpuColormaps.ts","webpack://cornerstone3D/./src/constants/rendering.ts","webpack://cornerstone3D/./src/constants/epsilon.ts","webpack://cornerstone3D/./src/constants/mprCameraValues.ts","webpack://cornerstone3D/./src/utilities/deepFreeze.ts","webpack://cornerstone3D/./src/constants/viewportPresets.ts","webpack://cornerstone3D/./src/constants/backgroundColors.ts","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/typeof.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/defineProperty.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/toPropertyKey.js","webpack://cornerstone3D/../../node_modules/@babel/runtime/helpers/esm/toPrimitive.js","webpack://cornerstone3D/./src/utilities/imageIdToURI.ts","webpack://cornerstone3D/./src/utilities/getMinMax.ts","webpack://cornerstone3D/./src/metaData.ts","webpack://cornerstone3D/./src/utilities/genericMetadataProvider.ts","webpack://cornerstone3D/./src/RenderingEngine/renderingEngineCache.ts","webpack://cornerstone3D/./src/RenderingEngine/getRenderingEngine.ts","webpack://cornerstone3D/./src/utilities/deepMerge.ts","webpack://cornerstone3D/../../node_modules/comlink/dist/esm/comlink.mjs","webpack://cornerstone3D/./src/utilities/uuidv4.ts","webpack://cornerstone3D/./src/requestPool/requestPoolManager.ts","webpack://cornerstone3D/./src/webWorkerManager/webWorkerManager.js","webpack://cornerstone3D/./src/init.ts","webpack://cornerstone3D/./src/RenderingEngine/vtkClasses/vtkStreamingOpenGLTexture.js","webpack://cornerstone3D/./src/eventTarget.ts","webpack://cornerstone3D/./src/utilities/triggerEvent.ts","webpack://cornerstone3D/./src/cache/cache.ts","webpack://cornerstone3D/./src/cache/classes/ImageVolume.ts","webpack://cornerstone3D/./src/utilities/isTypedArray.ts","webpack://cornerstone3D/./src/utilities/createFloat32SharedArray.ts","webpack://cornerstone3D/./src/utilities/createInt16SharedArray.ts","webpack://cornerstone3D/./src/utilities/createUInt16SharedArray.ts","webpack://cornerstone3D/./src/utilities/createUint8SharedArray.ts","webpack://cornerstone3D/./src/utilities/getScalingParameters.ts","webpack://cornerstone3D/./src/utilities/makeVolumeMetadata.ts","webpack://cornerstone3D/./src/utilities/sortImageIdsAndGetSpacing.ts","webpack://cornerstone3D/./src/utilities/hasFloatScalingParameters.ts","webpack://cornerstone3D/./src/cache/index.ts","webpack://cornerstone3D/./src/utilities/generateVolumePropsFromImageIds.ts","webpack://cornerstone3D/./src/utilities/getBufferConfiguration.ts","webpack://cornerstone3D/./src/utilities/cacheUtils.ts","webpack://cornerstone3D/./src/loaders/volumeLoader.ts","webpack://cornerstone3D/./src/RenderingEngine/vtkClasses/vtkSharedVolumeMapper.js","webpack://cornerstone3D/./src/RenderingEngine/helpers/createVolumeMapper.ts","webpack://cornerstone3D/./src/requestPool/imageLoadPoolManager.ts","webpack://cornerstone3D/./src/loaders/imageLoader.ts","webpack://cornerstone3D/./src/utilities/windowLevel.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/setDefaultVolumeVOI.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/createVolumeActor.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/getOrCreateCanvas.ts","webpack://cornerstone3D/./src/RenderingEngine/vtkClasses/vtkStreamingOpenGLVolumeMapper.js","webpack://cornerstone3D/./src/RenderingEngine/vtkClasses/vtkStreamingOpenGLViewNodeFactory.js","webpack://cornerstone3D/./src/RenderingEngine/vtkClasses/vtkStreamingOpenGLRenderWindow.js","webpack://cornerstone3D/./src/RenderingEngine/vtkClasses/vtkOffscreenMultiRenderWindow.js","webpack://cornerstone3D/./src/utilities/getSpacingInNormalDirection.ts","webpack://cornerstone3D/./src/utilities/actorCheck.ts","webpack://cornerstone3D/./src/utilities/getClosestImageId.ts","webpack://cornerstone3D/./src/utilities/getVolumeActorCorners.ts","webpack://cornerstone3D/./src/utilities/getSliceRange.ts","webpack://cornerstone3D/./src/utilities/snapFocalPointToSlice.ts","webpack://cornerstone3D/./src/utilities/getVoiFromSigmoidRGBTransferFunction.ts","webpack://cornerstone3D/./src/utilities/isEqual.ts","webpack://cornerstone3D/./src/utilities/colormap.ts","webpack://cornerstone3D/./src/utilities/invertRgbTransferFunction.ts","webpack://cornerstone3D/./src/utilities/createSigmoidRGBTransferFunction.ts","webpack://cornerstone3D/./src/utilities/getVolumeId.ts","webpack://cornerstone3D/./src/utilities/getTargetVolumeAndSpacingInNormalDir.ts","webpack://cornerstone3D/./src/utilities/getVolumeSliceRangeInfo.ts","webpack://cornerstone3D/./src/utilities/getVolumeViewportScrollInfo.ts","webpack://cornerstone3D/./src/utilities/applyPreset.ts","webpack://cornerstone3D/./src/utilities/getImageSliceDataForVolumeViewport.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/volumeNewImageEventDispatcher.ts","webpack://cornerstone3D/./src/utilities/planar.ts","webpack://cornerstone3D/./src/utilities/hasNaNValues.ts","webpack://cornerstone3D/./src/RenderingEngine/Viewport.ts","webpack://cornerstone3D/./src/RenderingEngine/vtkClasses/vtkSlabCamera.ts","webpack://cornerstone3D/./src/utilities/transformWorldToIndex.ts","webpack://cornerstone3D/./src/utilities/transferFunctionUtils.ts","webpack://cornerstone3D/./src/RenderingEngine/BaseVolumeViewport.ts","webpack://cornerstone3D/./src/RenderingEngine/VolumeViewport.ts","webpack://cornerstone3D/./src/utilities/imageRetrieveMetadataProvider.ts","webpack://cornerstone3D/./src/utilities/updateVTKImageDataWithCornerstoneImage.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/colors/lookupTable.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/colors/colormap.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/now.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/getVOILut.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/transform.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/calculateTransform.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/setToPixelCoordinateSystem.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/doesImageNeedToBeRendered.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/initializeRenderCanvas.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/saveLastRendered.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/renderColorImage.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/generateColorLUT.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/storedRGBAPixelDataToCanvasImageData.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/storedColorPixelDataToCanvasImageData.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/lutMatches.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/getLut.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/computeAutoVoi.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/generateLut.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/getModalityLut.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/renderGrayscaleImage.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPET.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageData.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataRGBA.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPseudocolorLUT.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/storedPixelDataToCanvasImageDataPseudocolorLUTPET.ts","webpack://cornerstone3D/./src/utilities/clamp.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/renderPseudoColorImage.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/drawImageSync.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/getTransform.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/canvasToPixel.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/setDefaultViewport.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/validator.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/getImageSize.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/getImageFitScale.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/getDefaultViewport.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/createViewport.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/pixelToCanvas.ts","webpack://cornerstone3D/./src/loaders/configuration/singleRetrieve.ts","webpack://cornerstone3D/./src/loaders/configuration/interleavedRetrieve.ts","webpack://cornerstone3D/./src/utilities/ProgressiveIterator.ts","webpack://cornerstone3D/./src/utilities/decimate.ts","webpack://cornerstone3D/./src/loaders/ProgressiveRetrieveImages.ts","webpack://cornerstone3D/./src/loaders/configuration/sequentialRetrieve.ts","webpack://cornerstone3D/./src/loaders/fillNearbyFrames.ts","webpack://cornerstone3D/./src/utilities/createLinearRGBTransferFunction.ts","webpack://cornerstone3D/./src/RenderingEngine/StackViewport.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/resize.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/fitToWindow.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/correctShift.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/cpuFallback/rendering/resetCamera.ts","webpack://cornerstone3D/./src/RenderingEngine/VolumeViewport3D.ts","webpack://cornerstone3D/./src/RenderingEngine/CanvasActor/CanvasProperties.ts","webpack://cornerstone3D/./src/RenderingEngine/CanvasActor/CanvasMapper.ts","webpack://cornerstone3D/./src/RenderingEngine/CanvasActor/index.ts","webpack://cornerstone3D/./src/RenderingEngine/VideoViewport.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/viewportTypeToViewportClass.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/viewportTypeUsesCustomRenderingPipeline.ts","webpack://cornerstone3D/./src/RenderingEngine/index.ts","webpack://cornerstone3D/./src/RenderingEngine/RenderingEngine.ts","webpack://cornerstone3D/./src/cache/classes/Surface.ts","webpack://cornerstone3D/./src/requestPool/imageRetrievalPoolManager.ts","webpack://cornerstone3D/./src/getEnabledElement.ts","webpack://cornerstone3D/./src/Settings.ts","webpack://cornerstone3D/./src/cache/classes/Contour.ts","webpack://cornerstone3D/./src/cache/classes/ContourSet.ts","webpack://cornerstone3D/./src/loaders/geometryLoader.ts","webpack://cornerstone3D/./src/loaders/utils/contourSet/createContourSet.ts","webpack://cornerstone3D/./src/loaders/utils/contourSet/validateContourSet.ts","webpack://cornerstone3D/./src/loaders/utils/surface/createSurface.ts","webpack://cornerstone3D/./src/loaders/utils/surface/validateSurface.ts","webpack://cornerstone3D/./src/utilities/eventListener/TargetEventListeners.ts","webpack://cornerstone3D/./src/utilities/eventListener/MultiTargetEventListenerManager.ts","webpack://cornerstone3D/./src/utilities/scaleRgbTransferFunction.ts","webpack://cornerstone3D/./src/utilities/getRuntimeId.ts","webpack://cornerstone3D/./src/utilities/calibratedPixelSpacingMetadataProvider.ts","webpack://cornerstone3D/./src/utilities/isOpposite.ts","webpack://cornerstone3D/./src/utilities/getViewportModality.ts","webpack://cornerstone3D/./src/utilities/indexWithinDimensions.ts","webpack://cornerstone3D/./src/utilities/getVolumeViewportsContainingSameVolumes.ts","webpack://cornerstone3D/./src/utilities/getViewportsWithVolumeId.ts","webpack://cornerstone3D/./src/utilities/transformIndexToWorld.ts","webpack://cornerstone3D/./src/utilities/isPTPrescaledWithSUV.ts","webpack://cornerstone3D/./src/utilities/renderToCanvasGPU.ts","webpack://cornerstone3D/./src/utilities/renderToCanvasCPU.ts","webpack://cornerstone3D/./src/utilities/loadImageToCanvas.ts","webpack://cornerstone3D/./src/utilities/worldToImageCoords.ts","webpack://cornerstone3D/./src/utilities/imageToWorldCoords.ts","webpack://cornerstone3D/./src/utilities/getViewportsWithImageURI.ts","webpack://cornerstone3D/./src/utilities/getClosestStackImageIndexForPoint.ts","webpack://cornerstone3D/./src/utilities/transformCanvasToIJK.ts","webpack://cornerstone3D/./src/utilities/getCurrentVolumeViewportSlice.ts","webpack://cornerstone3D/./src/utilities/transformIJKToCanvas.ts","webpack://cornerstone3D/./src/utilities/spatialRegistrationMetadataProvider.ts","webpack://cornerstone3D/./src/utilities/calculateViewportsSpatialRegistration.ts","webpack://cornerstone3D/./src/utilities/getViewportImageCornersInWorld.ts","webpack://cornerstone3D/./src/utilities/PointsManager.ts","webpack://cornerstone3D/./src/utilities/getScalarDataType.ts","webpack://cornerstone3D/./src/utilities/getImageLegacy.ts","webpack://cornerstone3D/./src/utilities/isValidVolume.ts","webpack://cornerstone3D/./src/utilities/isVideoTransferSyntax.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/setVolumesForViewports.ts","webpack://cornerstone3D/./src/utilities/convertStackToVolumeViewport.ts","webpack://cornerstone3D/./src/utilities/convertVolumeToStackViewport.ts","webpack://cornerstone3D/./src/utilities/RLEVoxelMap.ts","webpack://cornerstone3D/./src/utilities/VoxelManager.ts","webpack://cornerstone3D/./src/utilities/roundNumber.ts","webpack://cornerstone3D/./src/utilities/convertToGrayscale.ts","webpack://cornerstone3D/./src/utilities/getViewportImageIds.ts","webpack://cornerstone3D/./src/utilities/getRandomSampleFromArray.ts","webpack://cornerstone3D/./src/utilities/color.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/addVolumesToViewports.ts","webpack://cornerstone3D/./src/RenderingEngine/helpers/addImageSlicesToViewports.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"detect-gpu\"), require(\"@kitware/vtk.js/Rendering/Core/VolumeMapper/Constants\"), require(\"@kitware/vtk.js/Rendering/Core/ColorTransferFunction\"), require(\"@kitware/vtk.js/Rendering/Core/ColorTransferFunction/ColorMaps\"), require(\"@kitware/vtk.js/Common/DataModel/PiecewiseFunction\"), require(\"gl-matrix\"), require(\"@kitware/vtk.js/Common/Core/MatrixBuilder\"), require(\"@kitware/vtk.js/Common/Core/Math\"), require(\"@kitware/vtk.js/Common/DataModel/Plane\"), require(\"@kitware/vtk.js/Common/DataModel/ImageData\"), require(\"@kitware/vtk.js/Common/Core/DataArray\"), require(\"@kitware/vtk.js/macros\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Texture\"), require(\"@kitware/vtk.js/Common/Core/HalfFloat\"), require(\"@kitware/vtk.js/Rendering/Core/Camera\"), require(\"@kitware/vtk.js/Rendering/Profiles/Volume\"), require(\"@kitware/vtk.js/Rendering/Core/Volume\"), require(\"@kitware/vtk.js/Rendering/Core/VolumeMapper\"), require(\"@kitware/vtk.js/Rendering/Core/ImageMapper\"), require(\"@kitware/vtk.js/Rendering/Core/ImageSlice\"), require(\"@kitware/vtk.js/Rendering/Core/Renderer\"), require(\"@kitware/vtk.js/Rendering/Core/RenderWindow\"), require(\"@kitware/vtk.js/Rendering/Core/RenderWindowInteractor\"), require(\"@kitware/vtk.js/Common/Core/Points\"), require(\"@kitware/vtk.js/Common/DataModel/PolyData\"), require(\"@kitware/vtk.js/Rendering/Core/Actor\"), require(\"@kitware/vtk.js/Rendering/Core/Mapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/RenderWindow\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Actor\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Actor2D\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Camera\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Glyph3DMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/ImageMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/ImageSlice\"), require(\"@kitware/vtk.js/Rendering/OpenGL/PixelSpaceCallbackMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/PolyDataMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Renderer\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Skybox\"), require(\"@kitware/vtk.js/Rendering/OpenGL/SphereMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/StickMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Volume\"), require(\"@kitware/vtk.js/Rendering/OpenGL/VolumeMapper\"), require(\"@kitware/vtk.js/Rendering/SceneGraph/ViewNodeFactory\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Texture/Constants\"), require(\"@kitware/vtk.js/Common/Core/DataArray/Constants\"), require(\"@kitware/vtk.js/Rendering/Core/Property/Constants\"), require(\"@kitware/vtk.js/Rendering/Profiles/Geometry\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"detect-gpu\", \"@kitware/vtk.js/Rendering/Core/VolumeMapper/Constants\", \"@kitware/vtk.js/Rendering/Core/ColorTransferFunction\", \"@kitware/vtk.js/Rendering/Core/ColorTransferFunction/ColorMaps\", \"@kitware/vtk.js/Common/DataModel/PiecewiseFunction\", \"gl-matrix\", \"@kitware/vtk.js/Common/Core/MatrixBuilder\", \"@kitware/vtk.js/Common/Core/Math\", \"@kitware/vtk.js/Common/DataModel/Plane\", \"@kitware/vtk.js/Common/DataModel/ImageData\", \"@kitware/vtk.js/Common/Core/DataArray\", \"@kitware/vtk.js/macros\", \"@kitware/vtk.js/Rendering/OpenGL/Texture\", \"@kitware/vtk.js/Common/Core/HalfFloat\", \"@kitware/vtk.js/Rendering/Core/Camera\", \"@kitware/vtk.js/Rendering/Profiles/Volume\", \"@kitware/vtk.js/Rendering/Core/Volume\", \"@kitware/vtk.js/Rendering/Core/VolumeMapper\", \"@kitware/vtk.js/Rendering/Core/ImageMapper\", \"@kitware/vtk.js/Rendering/Core/ImageSlice\", \"@kitware/vtk.js/Rendering/Core/Renderer\", \"@kitware/vtk.js/Rendering/Core/RenderWindow\", \"@kitware/vtk.js/Rendering/Core/RenderWindowInteractor\", \"@kitware/vtk.js/Common/Core/Points\", \"@kitware/vtk.js/Common/DataModel/PolyData\", \"@kitware/vtk.js/Rendering/Core/Actor\", \"@kitware/vtk.js/Rendering/Core/Mapper\", \"@kitware/vtk.js/Rendering/OpenGL/RenderWindow\", \"@kitware/vtk.js/Rendering/OpenGL/Actor\", \"@kitware/vtk.js/Rendering/OpenGL/Actor2D\", \"@kitware/vtk.js/Rendering/OpenGL/Camera\", \"@kitware/vtk.js/Rendering/OpenGL/Glyph3DMapper\", \"@kitware/vtk.js/Rendering/OpenGL/ImageMapper\", \"@kitware/vtk.js/Rendering/OpenGL/ImageSlice\", \"@kitware/vtk.js/Rendering/OpenGL/PixelSpaceCallbackMapper\", \"@kitware/vtk.js/Rendering/OpenGL/PolyDataMapper\", \"@kitware/vtk.js/Rendering/OpenGL/Renderer\", \"@kitware/vtk.js/Rendering/OpenGL/Skybox\", \"@kitware/vtk.js/Rendering/OpenGL/SphereMapper\", \"@kitware/vtk.js/Rendering/OpenGL/StickMapper\", \"@kitware/vtk.js/Rendering/OpenGL/Volume\", \"@kitware/vtk.js/Rendering/OpenGL/VolumeMapper\", \"@kitware/vtk.js/Rendering/SceneGraph/ViewNodeFactory\", \"@kitware/vtk.js/Rendering/OpenGL/Texture/Constants\", \"@kitware/vtk.js/Common/Core/DataArray/Constants\", \"@kitware/vtk.js/Rendering/Core/Property/Constants\", \"@kitware/vtk.js/Rendering/Profiles/Geometry\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"cornerstone3D\"] = factory(require(\"detect-gpu\"), require(\"@kitware/vtk.js/Rendering/Core/VolumeMapper/Constants\"), require(\"@kitware/vtk.js/Rendering/Core/ColorTransferFunction\"), require(\"@kitware/vtk.js/Rendering/Core/ColorTransferFunction/ColorMaps\"), require(\"@kitware/vtk.js/Common/DataModel/PiecewiseFunction\"), require(\"gl-matrix\"), require(\"@kitware/vtk.js/Common/Core/MatrixBuilder\"), require(\"@kitware/vtk.js/Common/Core/Math\"), require(\"@kitware/vtk.js/Common/DataModel/Plane\"), require(\"@kitware/vtk.js/Common/DataModel/ImageData\"), require(\"@kitware/vtk.js/Common/Core/DataArray\"), require(\"@kitware/vtk.js/macros\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Texture\"), require(\"@kitware/vtk.js/Common/Core/HalfFloat\"), require(\"@kitware/vtk.js/Rendering/Core/Camera\"), require(\"@kitware/vtk.js/Rendering/Profiles/Volume\"), require(\"@kitware/vtk.js/Rendering/Core/Volume\"), require(\"@kitware/vtk.js/Rendering/Core/VolumeMapper\"), require(\"@kitware/vtk.js/Rendering/Core/ImageMapper\"), require(\"@kitware/vtk.js/Rendering/Core/ImageSlice\"), require(\"@kitware/vtk.js/Rendering/Core/Renderer\"), require(\"@kitware/vtk.js/Rendering/Core/RenderWindow\"), require(\"@kitware/vtk.js/Rendering/Core/RenderWindowInteractor\"), require(\"@kitware/vtk.js/Common/Core/Points\"), require(\"@kitware/vtk.js/Common/DataModel/PolyData\"), require(\"@kitware/vtk.js/Rendering/Core/Actor\"), require(\"@kitware/vtk.js/Rendering/Core/Mapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/RenderWindow\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Actor\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Actor2D\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Camera\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Glyph3DMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/ImageMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/ImageSlice\"), require(\"@kitware/vtk.js/Rendering/OpenGL/PixelSpaceCallbackMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/PolyDataMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Renderer\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Skybox\"), require(\"@kitware/vtk.js/Rendering/OpenGL/SphereMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/StickMapper\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Volume\"), require(\"@kitware/vtk.js/Rendering/OpenGL/VolumeMapper\"), require(\"@kitware/vtk.js/Rendering/SceneGraph/ViewNodeFactory\"), require(\"@kitware/vtk.js/Rendering/OpenGL/Texture/Constants\"), require(\"@kitware/vtk.js/Common/Core/DataArray/Constants\"), require(\"@kitware/vtk.js/Rendering/Core/Property/Constants\"), require(\"@kitware/vtk.js/Rendering/Profiles/Geometry\"));\n\telse\n\t\troot[\"cornerstone3D\"] = factory(root[\"window\"], root[\"@kitware/vtk.js/Rendering/Core/VolumeMapper/Constants\"], root[\"@kitware/vtk.js/Rendering/Core/ColorTransferFunction\"], root[\"@kitware/vtk.js/Rendering/Core/ColorTransferFunction/ColorMaps\"], root[\"@kitware/vtk.js/Common/DataModel/PiecewiseFunction\"], root[\"window\"], root[\"@kitware/vtk.js/Common/Core/MatrixBuilder\"], root[\"@kitware/vtk.js/Common/Core/Math\"], root[\"@kitware/vtk.js/Common/DataModel/Plane\"], root[\"@kitware/vtk.js/Common/DataModel/ImageData\"], root[\"@kitware/vtk.js/Common/Core/DataArray\"], root[\"@kitware/vtk.js/macros\"], root[\"@kitware/vtk.js/Rendering/OpenGL/Texture\"], root[\"@kitware/vtk.js/Common/Core/HalfFloat\"], root[\"@kitware/vtk.js/Rendering/Core/Camera\"], root[\"@kitware/vtk.js/Rendering/Profiles/Volume\"], root[\"@kitware/vtk.js/Rendering/Core/Volume\"], root[\"@kitware/vtk.js/Rendering/Core/VolumeMapper\"], root[\"@kitware/vtk.js/Rendering/Core/ImageMapper\"], root[\"@kitware/vtk.js/Rendering/Core/ImageSlice\"], root[\"@kitware/vtk.js/Rendering/Core/Renderer\"], root[\"@kitware/vtk.js/Rendering/Core/RenderWindow\"], root[\"@kitware/vtk.js/Rendering/Core/RenderWindowInteractor\"], root[\"@kitware/vtk.js/Common/Core/Points\"], root[\"@kitware/vtk.js/Common/DataModel/PolyData\"], root[\"@kitware/vtk.js/Rendering/Core/Actor\"], root[\"@kitware/vtk.js/Rendering/Core/Mapper\"], root[\"@kitware/vtk.js/Rendering/OpenGL/RenderWindow\"], root[\"@kitware/vtk.js/Rendering/OpenGL/Actor\"], root[\"@kitware/vtk.js/Rendering/OpenGL/Actor2D\"], root[\"@kitware/vtk.js/Rendering/OpenGL/Camera\"], root[\"@kitware/vtk.js/Rendering/OpenGL/Glyph3DMapper\"], root[\"@kitware/vtk.js/Rendering/OpenGL/ImageMapper\"], root[\"@kitware/vtk.js/Rendering/OpenGL/ImageSlice\"], root[\"@kitware/vtk.js/Rendering/OpenGL/PixelSpaceCallbackMapper\"], root[\"@kitware/vtk.js/Rendering/OpenGL/PolyDataMapper\"], root[\"@kitware/vtk.js/Rendering/OpenGL/Renderer\"], root[\"@kitware/vtk.js/Rendering/OpenGL/Skybox\"], root[\"@kitware/vtk.js/Rendering/OpenGL/SphereMapper\"], root[\"@kitware/vtk.js/Rendering/OpenGL/StickMapper\"], root[\"@kitware/vtk.js/Rendering/OpenGL/Volume\"], root[\"@kitware/vtk.js/Rendering/OpenGL/VolumeMapper\"], root[\"@kitware/vtk.js/Rendering/SceneGraph/ViewNodeFactory\"], root[\"@kitware/vtk.js/Rendering/OpenGL/Texture/Constants\"], root[\"@kitware/vtk.js/Common/Core/DataArray/Constants\"], root[\"@kitware/vtk.js/Rendering/Core/Property/Constants\"], root[\"@kitware/vtk.js/Rendering/Profiles/Geometry\"]);\n})(self, (__WEBPACK_EXTERNAL_MODULE__199__, __WEBPACK_EXTERNAL_MODULE__468__, __WEBPACK_EXTERNAL_MODULE__795__, __WEBPACK_EXTERNAL_MODULE__38__, __WEBPACK_EXTERNAL_MODULE__441__, __WEBPACK_EXTERNAL_MODULE__976__, __WEBPACK_EXTERNAL_MODULE__847__, __WEBPACK_EXTERNAL_MODULE__807__, __WEBPACK_EXTERNAL_MODULE__864__, __WEBPACK_EXTERNAL_MODULE__283__, __WEBPACK_EXTERNAL_MODULE__785__, __WEBPACK_EXTERNAL_MODULE__197__, __WEBPACK_EXTERNAL_MODULE__953__, __WEBPACK_EXTERNAL_MODULE__903__, __WEBPACK_EXTERNAL_MODULE__821__, __WEBPACK_EXTERNAL_MODULE__215__, __WEBPACK_EXTERNAL_MODULE__739__, __WEBPACK_EXTERNAL_MODULE__9__, __WEBPACK_EXTERNAL_MODULE__896__, __WEBPACK_EXTERNAL_MODULE__861__, __WEBPACK_EXTERNAL_MODULE__281__, __WEBPACK_EXTERNAL_MODULE__329__, __WEBPACK_EXTERNAL_MODULE__673__, __WEBPACK_EXTERNAL_MODULE__348__, __WEBPACK_EXTERNAL_MODULE__70__, __WEBPACK_EXTERNAL_MODULE__474__, __WEBPACK_EXTERNAL_MODULE__610__, __WEBPACK_EXTERNAL_MODULE__21__, __WEBPACK_EXTERNAL_MODULE__643__, __WEBPACK_EXTERNAL_MODULE__128__, __WEBPACK_EXTERNAL_MODULE__664__, __WEBPACK_EXTERNAL_MODULE__973__, __WEBPACK_EXTERNAL_MODULE__394__, __WEBPACK_EXTERNAL_MODULE__582__, __WEBPACK_EXTERNAL_MODULE__482__, __WEBPACK_EXTERNAL_MODULE__343__, __WEBPACK_EXTERNAL_MODULE__363__, __WEBPACK_EXTERNAL_MODULE__982__, __WEBPACK_EXTERNAL_MODULE__130__, __WEBPACK_EXTERNAL_MODULE__298__, __WEBPACK_EXTERNAL_MODULE__398__, __WEBPACK_EXTERNAL_MODULE__388__, __WEBPACK_EXTERNAL_MODULE__120__, __WEBPACK_EXTERNAL_MODULE__395__, __WEBPACK_EXTERNAL_MODULE__948__, __WEBPACK_EXTERNAL_MODULE__478__, __WEBPACK_EXTERNAL_MODULE__914__) => {\nreturn ","module.exports = __WEBPACK_EXTERNAL_MODULE__785__;","module.exports = __WEBPACK_EXTERNAL_MODULE__948__;","module.exports = __WEBPACK_EXTERNAL_MODULE__903__;","module.exports = __WEBPACK_EXTERNAL_MODULE__807__;","module.exports = __WEBPACK_EXTERNAL_MODULE__847__;","module.exports = __WEBPACK_EXTERNAL_MODULE__348__;","module.exports = __WEBPACK_EXTERNAL_MODULE__283__;","module.exports = __WEBPACK_EXTERNAL_MODULE__441__;","module.exports = __WEBPACK_EXTERNAL_MODULE__864__;","module.exports = __WEBPACK_EXTERNAL_MODULE__70__;","module.exports = __WEBPACK_EXTERNAL_MODULE__474__;","module.exports = __WEBPACK_EXTERNAL_MODULE__821__;","module.exports = __WEBPACK_EXTERNAL_MODULE__795__;","module.exports = __WEBPACK_EXTERNAL_MODULE__38__;","module.exports = __WEBPACK_EXTERNAL_MODULE__896__;","module.exports = __WEBPACK_EXTERNAL_MODULE__861__;","module.exports = __WEBPACK_EXTERNAL_MODULE__610__;","module.exports = __WEBPACK_EXTERNAL_MODULE__478__;","module.exports = __WEBPACK_EXTERNAL_MODULE__329__;","module.exports = __WEBPACK_EXTERNAL_MODULE__673__;","module.exports = __WEBPACK_EXTERNAL_MODULE__281__;","module.exports = __WEBPACK_EXTERNAL_MODULE__739__;","module.exports = __WEBPACK_EXTERNAL_MODULE__9__;","module.exports = __WEBPACK_EXTERNAL_MODULE__468__;","module.exports = __WEBPACK_EXTERNAL_MODULE__643__;","module.exports = __WEBPACK_EXTERNAL_MODULE__128__;","module.exports = __WEBPACK_EXTERNAL_MODULE__664__;","module.exports = __WEBPACK_EXTERNAL_MODULE__973__;","module.exports = __WEBPACK_EXTERNAL_MODULE__394__;","module.exports = __WEBPACK_EXTERNAL_MODULE__582__;","module.exports = __WEBPACK_EXTERNAL_MODULE__482__;","module.exports = __WEBPACK_EXTERNAL_MODULE__343__;","module.exports = __WEBPACK_EXTERNAL_MODULE__21__;","module.exports = __WEBPACK_EXTERNAL_MODULE__363__;","module.exports = __WEBPACK_EXTERNAL_MODULE__982__;","module.exports = __WEBPACK_EXTERNAL_MODULE__130__;","module.exports = __WEBPACK_EXTERNAL_MODULE__298__;","module.exports = __WEBPACK_EXTERNAL_MODULE__953__;","module.exports = __WEBPACK_EXTERNAL_MODULE__395__;","module.exports = __WEBPACK_EXTERNAL_MODULE__398__;","module.exports = __WEBPACK_EXTERNAL_MODULE__388__;","module.exports = __WEBPACK_EXTERNAL_MODULE__914__;","module.exports = __WEBPACK_EXTERNAL_MODULE__215__;","module.exports = __WEBPACK_EXTERNAL_MODULE__120__;","module.exports = __WEBPACK_EXTERNAL_MODULE__197__;","module.exports = __WEBPACK_EXTERNAL_MODULE__199__;","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\t// no module.id needed\n\t\t// no module.loaded needed\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// 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 = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (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__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (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};","/**\n * Cornerstone Core events\n */\nenum Events {\n /**\n * ERROR CODES\n */\n ERROR_EVENT = 'CORNERSTONE_ERROR',\n\n /**\n * Error that is thrown when the ImageCache exceeds its max cache size.\n * This can happen for both volumes and stack images.\n */\n CACHE_SIZE_EXCEEDED = 'CACHE_SIZE_EXCEEDED',\n /**\n * Happens if an image (either a single image in stack viewport) or a slice\n * of a volume fails to load by the image/volume loaders.\n */\n IMAGE_LOAD_ERROR = 'IMAGE_LOAD_ERROR',\n\n /**\n * Triggers on the HTML element when the viewport camera changes.\n *\n * Make use of {@link EventTypes.CameraModifiedEvent | CameraModified Event Type } for typing your event listeners for CAMERA_MODIFIED event,\n * and see what event detail is included in {@link EventTypes.CameraModifiedEventDetail | CameraModified Event Detail }\n */\n CAMERA_MODIFIED = 'CORNERSTONE_CAMERA_MODIFIED',\n /**\n * Triggers on the HTML element when the viewport camera resets\n *\n * Make use of {@link EventTypes.CameraResetEvent | CameraReset Event Type } for typing your event listeners for CAMERA_RESET event,\n * and see what event detail is included in {@link EventTypes.CameraResetEventDetail | CameraReset Event Detail }\n */\n CAMERA_RESET = 'CORNERSTONE_CAMERA_RESET',\n /**\n * Triggers on the HTML element when viewport modifies its VOI\n *\n * Make use of {@link EventTypes.VoiModifiedEvent | VoiModified Event Type } for typing your event listeners for VOI_MODIFIED event,\n * and see what event detail is included in {@link EventTypes.VoiModifiedEventDetail | VoiModified Event Detail }\n */\n VOI_MODIFIED = 'CORNERSTONE_VOI_MODIFIED',\n /**\n * Triggers on the HTML element when viewport modifies its preset (used in volume viewport 3D)\n *\n * Make use of {@link EventTypes.PresetModifiedEvent | PresetModified Event Type } for typing your event listeners for PRESET_MODIFIED event,\n */\n PRESET_MODIFIED = 'CORNERSTONE_VIEWPORT_RENDERING_PRESET_MODIFIED',\n /**\n * Triggers on the HTML element when viewport modifies its display area\n *\n * Make use of {@link EventTypes.DisplayAreaModifiedEvent | DisplayAreaModified Event Type } for typing your event listeners for DISPLAY_AREA_MODIFIED event,\n * and see what event detail is included in {@link EventTypes.DisplayAreaModifiedEventDetail | DisplayAreaModified Event Detail }\n */\n DISPLAY_AREA_MODIFIED = 'CORNERSTONE_DISPLAY_AREA_MODIFIED',\n /**\n * Triggers on the eventTarget when the element is disabled\n *\n * Make use of {@link EventTypes.ElementDisabledEvent | ElementDisabled Event Type } for typing your event listeners for ELEMENT_DISABLED event,\n * and see what event detail is included in {@link EventTypes.ElementDisabledEventDetail | ElementDisabled Event Detail }\n */\n ELEMENT_DISABLED = 'CORNERSTONE_ELEMENT_DISABLED',\n /**\n * Triggers on the eventTarget when the element is enabled\n *\n * Make use of {@link EventTypes.ElementEnabledEvent | ElementEnabled Event Type } for typing your event listeners for ELEMENT_ENABLED event,\n * and see what event detail is included in {@link EventTypes.ElementEnabledEventDetail | ElementEnabled Event Detail }\n */\n ELEMENT_ENABLED = 'CORNERSTONE_ELEMENT_ENABLED',\n /**\n * Triggers on the element when the image in the element has been rendered\n *\n * Make use of {@link EventTypes.ImageRenderedEvent | ImageRendered Event Type } for typing your event listeners for IMAGE_RENDERED event,\n * and see what event detail is included in {@link EventTypes.ImageRenderedEventDetail | ImageRendered Event Detail }\n */\n IMAGE_RENDERED = 'CORNERSTONE_IMAGE_RENDERED',\n /**\n * Triggers on the eventTarget when the image volume data is modified. This happens\n * in the streamingImageLoader when each frame is loaded and inserted into a volume.\n *\n *\n * Make use of {@link EventTypes.ImageVolumeModifiedEvent | ImageVolumeModified Event Type } for typing your event listeners for IMAGE_VOLUME_MODIFIED event,\n * and see what event detail is included in {@link EventTypes.ImageVolumeModifiedEventDetail | ImageVolumeModified Event Detail }\n */\n IMAGE_VOLUME_MODIFIED = 'CORNERSTONE_IMAGE_VOLUME_MODIFIED',\n /**\n * Triggers on the eventTarget when the image volume loading is completed and all\n * frames are loaded and inserted into a volume.\n *\n * Make use of {@link EventTypes.ImageVolumeLoadingCompletedEvent | ImageVolumeLoadingCompleted Event Type } for typing your\n * event listeners for IMAGE_VOLUME_LOADING_COMPLETED event, and see what event detail is included\n * in {@link EventTypes.ImageVolumeLoadingCompletedEventDetail | ImageVolumeLoadingCompleted Event Detail }\n */\n IMAGE_VOLUME_LOADING_COMPLETED = 'CORNERSTONE_IMAGE_VOLUME_LOADING_COMPLETED',\n /**\n * Triggers on the eventTarget when the image has successfully loaded by imageLoaders.\n * This event may be fired multiple times for different statuses as the image data gets loaded.\n *\n * Make use of {@link EventTypes.ImageLoadedEvent | ImageLoaded Event Type } for typing your event listeners for IMAGE_LOADED event,\n * and see what event detail is included in {@link EventTypes.ImageLoadedEventDetail | ImageLoaded Event Detail }\n */\n IMAGE_LOADED = 'CORNERSTONE_IMAGE_LOADED',\n /**\n * Triggers on the eventTarget when progressive loading stages are completed.\n * That is, the stage is complete for all images included in that stage (which\n * can be zero). If you need individual image load information related to\n * the stage, see the status attribute on the IMAGE_LOADED event - which has\n * the status of the image, but not the actual stage that loaded it.\n */\n IMAGE_RETRIEVAL_STAGE = 'CORNERSTONE_IMAGE_RETRIEVAL_STAGE',\n /**\n * Triggers on the eventTarget when the image has failed loading by imageLoaders\n *\n * Make use of {@link EventTypes.ImageLoadedFailedEvent | ImageLoadedFailed Event Type } for typing your event listeners for IMAGE_LOADED_FAILED event,\n * and see what event detail is included in {@link EventTypes.ImageLoadedFailedEventDetail | ImageLoadedFailed Event Detail }\n */\n IMAGE_LOAD_FAILED = 'CORNERSTONE_IMAGE_LOAD_FAILED',\n /**\n * Triggers on element when a new voluem is set on the volume viewport\n */\n VOLUME_VIEWPORT_NEW_VOLUME = 'CORNERSTONE_VOLUME_VIEWPORT_NEW_VOLUME',\n\n /**\n * Triggers on the eventTarget when the volume has successfully loaded by volumeLoaders\n *\n * Make use of {@link EventTypes.VolumeLoadedEvent | VolumeLoaded Event Type } for typing your event listeners for VOLUME_LOADED event,\n * and see what event detail is included in {@link EventTypes.VolumeLoadedEventDetail | VolumeLoaded Event Detail }\n */\n VOLUME_LOADED = 'CORNERSTONE_VOLUME_LOADED',\n /**\n * Triggers on the eventTarget when the image has failed loading by volumeLoaders\n *\n * Make use of {@link EventTypes.VolumeLoadedFailedEvent | VolumeLoadedFailed Event Type } for typing your event listeners for VOLUME_LOADED_FAILED event,\n * and see what event detail is included in {@link EventTypes.VolumeLoadedFailedEventDetail | VolumeLoadedFailed Event Detail }\n */\n VOLUME_LOADED_FAILED = 'CORNERSTONE_VOLUME_LOADED_FAILED',\n /**\n * Triggers on the eventTarget when an image is added to the image cache\n *\n * Make use of {@link EventTypes.ImageCacheImageAddedEvent | ImageCacheAdded Event Type } for typing your event listeners for IMAGE_CACHE_ADDED event,\n * and see what event detail is included in {@link EventTypes.ImageCacheImageAddedEventDetail | ImageCacheAdded Event Detail }\n */\n IMAGE_CACHE_IMAGE_ADDED = 'CORNERSTONE_IMAGE_CACHE_IMAGE_ADDED',\n /**\n * Triggers on the eventTarget when an image is removed from the image cache\n *\n * Make use of {@link EventTypes.ImageCacheImageRemovedEvent | ImageCacheRemoved Event Type } for typing your event listeners for IMAGE_CACHE_REMOVED event,\n * and see what event detail is included in {@link EventTypes.ImageCacheImageRemovedEventDetail | ImageCacheRemoved Event Detail }\n */\n IMAGE_CACHE_IMAGE_REMOVED = 'CORNERSTONE_IMAGE_CACHE_IMAGE_REMOVED',\n /**\n * Triggers on the eventTarget when a volume is added to the volume cache\n *\n * Make use of {@link EventTypes.VolumeCacheVolumeAddedEvent | VolumeCacheAdded Event Type } for typing your event listeners for VOLUME_CACHE_ADDED event,\n * and see what event detail is included in {@link EventTypes.VolumeCacheVolumeAddedEventDetail | VolumeCacheAdded Event Detail }\n */\n VOLUME_CACHE_VOLUME_ADDED = 'CORNERSTONE_VOLUME_CACHE_VOLUME_ADDED',\n /**\n * Triggers on the eventTarget when a volume is removed from the volume cache\n *\n * Make use of {@link EventTypes.VolumeCacheVolumeRemovedEvent | VolumeCacheRemoved Event Type } for typing your event listeners for VOLUME_CACHE_REMOVED event,\n * and see what event detail is included in {@link EventTypes.VolumeCacheVolumeRemovedEventDetail | VolumeCacheRemoved Event Detail }\n */\n VOLUME_CACHE_VOLUME_REMOVED = 'CORNERSTONE_VOLUME_CACHE_VOLUME_REMOVED',\n /**\n * Triggers on the element when a new image is set on the stackViewport\n *\n * Make use of {@link EventTypes.StackNewImageEvent | StackNewImage Event Type } for typing your event listeners for STACK_NEW_IMAGE event,\n * and see what event detail is included in {@link EventTypes.StackNewImageEventDetail | StackNewImage Event Detail }\n */\n STACK_NEW_IMAGE = 'CORNERSTONE_STACK_NEW_IMAGE',\n\n /**\n * Triggers on the element when a new image is set on the volumeViewport, this can be due to scrolling or other\n * tools that change the camera position or focal point.\n *\n * Make use of {@link EventTypes.VolumeNewImageEvent | VolumeNewImage Event Type } for typing your event listeners for VOLUME_NEW_IMAGE event,\n * and see what event detail is included in {@link EventTypes.VolumeNewImageEventDetail | VolumeNewImage Event Detail }\n */\n VOLUME_NEW_IMAGE = 'CORNERSTONE_VOLUME_NEW_IMAGE',\n\n /**\n * Triggers on the element when a new image is about to be set on the stackViewport, pre display\n *\n * Make use of {@link EventTypes.PreStackNewImageEvent | PreStackNewImage Event Type } for typing your event listeners for PRE_STACK_NEW_IMAGE event,\n * and see what event detail is included in {@link EventTypes.PreStackNewImageEventDetail | PreStackNewImage Event Detail }\n */\n PRE_STACK_NEW_IMAGE = 'CORNERSTONE_PRE_STACK_NEW_IMAGE',\n /**\n * Triggers on the element when the viewport's image has calibrated its pixel spacings\n *\n * Make use of {@link EventTypes.ImageSpacingCalibratedEvent | ImageSpacingCalibrated Event Type } for typing your event listeners for IMAGE_SPACING_CALIBRATED event,\n * and see what event detail is included in {@link EventTypes.ImageSpacingCalibratedEventDetail | ImageSpacingCalibrated Event Detail }\n */\n IMAGE_SPACING_CALIBRATED = 'CORNERSTONE_IMAGE_SPACING_CALIBRATED',\n\n /**\n * Triggers on the event target when a new stack is set on its stack viewport.\n * Make use of {@link EventTypes.StackViewportNewStack | StackViewportNewStack Event Type } for typing your event listeners for STACK_VIEWPORT_NEW_STACK event,\n * and see what event detail is included in {@link EventTypes.StackViewportNewStackEventDetail | StackViewportNewStack Event Detail }\n */\n STACK_VIEWPORT_NEW_STACK = 'CORNERSTONE_STACK_VIEWPORT_NEW_STACK',\n\n /**\n * Triggers on the element when the underlying StackViewport is scrolled.\n * Make use of {@link EventTypes.StackViewportScroll | StackViewportScroll Event Type } for typing your event listeners for STACK_VIEWPORT_SCROLL event,\n * and see what event detail is included in {@link EventTypes.StackViewportScrollEventDetail | StackViewportScroll Event Detail }\n */\n STACK_VIEWPORT_SCROLL = 'CORNERSTONE_STACK_VIEWPORT_SCROLL',\n\n /**\n * Triggers on the eventTarget when a new geometry is added to the geometry cache\n */\n GEOMETRY_CACHE_GEOMETRY_ADDED = 'CORNERSTONE_GEOMETRY_CACHE_GEOMETRY_ADDED',\n\n /**\n * Triggers when the scroll function is called with a delta that is out of bounds.\n * This is usually for signaling that the user may want a different volume for partially loaded volumes which is meant to optimize memory.\n */\n VOLUME_SCROLL_OUT_OF_BOUNDS = 'VOLUME_SCROLL_OUT_OF_BOUNDS',\n\n /**\n * Triggers when the scroll function is called on a volume.\n */\n VOLUME_VIEWPORT_SCROLL = 'VOLUME_VIEWPORT_SCROLL',\n\n /**\n * Triggers when the clipping planes has been updated\n */\n CLIPPING_PLANES_UPDATED = 'CORNERSTONE_CLIPPING_PLANES_UPDATED',\n\n /**\n * Triggers when the webworker has made progress\n * You should use it with a workerType to indicate the type of worker that is making progress\n * Checkout the polySEG convertors in the cornerstone tools\n * to lean how to use it\n */\n WEB_WORKER_PROGRESS = 'CORNERSTONE_WEB_WORKER_PROGRESS',\n // IMAGE_CACHE_FULL = 'CORNERSTONE_IMAGE_CACHE_FULL',\n // PRE_RENDER = 'CORNERSTONE_PRE_RENDER',\n // ELEMENT_RESIZED = 'CORNERSTONE_ELEMENT_RESIZED',\n\n /**\n * Triggers on the HTML element when viewport modifies its colormap\n * Make use of {@link EventTypes.ColormapModifiedEvent | ColormapModified Event Type } for typing your event listeners for COLORMAP_MODIFIED event,\n * and see what event detail is included in {@link EventTypes.ColormapModifiedEventDetail | ColormapModified Event Detail }\n */\n COLORMAP_MODIFIED = 'CORNERSTONE_COLORMAP_MODIFIED',\n}\n\nexport default Events;\n","/**\n * Request types for requesting images from the imageLoadPoolManager\n */\nenum RequestType {\n /** Highest priority for loading*/\n Interaction = 'interaction',\n /** Second highest priority for loading*/\n Thumbnail = 'thumbnail',\n /** Third highest priority for loading, usually used for image loading in the background*/\n Prefetch = 'prefetch',\n /** Lower priority, often used for background computations in the worker */\n Compute = 'compute',\n}\n\nexport default RequestType;\n","/**\n * ViewportType enum for cornerstone-render which defines the type of viewport.\n * It can be either STACK, PERSPECTIVE, ORTHOGRAPHIC.\n */\nenum ViewportType {\n /**\n * - Suitable for rendering a stack of images, that might or might not belong to the same image.\n * - Stack can include 2D images of different shapes, size and direction\n */\n STACK = 'stack',\n /**\n * - Suitable for rendering a volumetric data which is considered as one 3D image.\n * - Having a VolumeViewport enables Multi-planar reformation or reconstruction (MPR) by design, in which you can visualize the volume from various different orientations without addition of performance costs.\n */\n ORTHOGRAPHIC = 'orthographic',\n /** Perspective Viewport: Not Implemented yet */\n PERSPECTIVE = 'perspective',\n VOLUME_3D = 'volume3d',\n VIDEO = 'video',\n}\n\nexport default ViewportType;\n","/**\n * Interpolation types for image rendering\n */\nenum InterpolationType {\n /** nearest neighbor interpolation */\n NEAREST,\n /** linear interpolation - Default */\n LINEAR,\n /** */\n FAST_LINEAR,\n}\n\nexport default InterpolationType;\n","import vtkConstants from '@kitware/vtk.js/Rendering/Core/VolumeMapper/Constants';\n\nconst { BlendMode } = vtkConstants;\n\n/**\n * Enums for blendModes for viewport images based on vtk.js\n *\n * It should be noted that if crosshairs are enabled and can modify the slab thickness,\n * then it will not show any difference unless MAXIMUM_INTENSITY_BLEND is set on the viewport\n * as the blend.\n */\nenum BlendModes {\n /** composite blending - suitable for compositing multiple images */\n COMPOSITE = BlendMode.COMPOSITE_BLEND,\n /** maximum intensity projection */\n MAXIMUM_INTENSITY_BLEND = BlendMode.MAXIMUM_INTENSITY_BLEND,\n /** minimum intensity projection */\n MINIMUM_INTENSITY_BLEND = BlendMode.MINIMUM_INTENSITY_BLEND,\n /** average intensity projection */\n AVERAGE_INTENSITY_BLEND = BlendMode.AVERAGE_INTENSITY_BLEND,\n}\n\nexport default BlendModes;\n","enum OrientationAxis {\n AXIAL = 'axial',\n CORONAL = 'coronal',\n SAGITTAL = 'sagittal',\n ACQUISITION = 'acquisition',\n}\n\nexport default OrientationAxis;\n","/**\n * SharedArrayBuffer Modes\n */\nenum SharedArrayBufferModes {\n TRUE = 'true',\n FALSE = 'false',\n /** use SharedArrayBuffer if avalaible */\n AUTO = 'auto',\n}\n\nexport default SharedArrayBufferModes;\n","enum GeometryType {\n CONTOUR = 'contour',\n SURFACE = 'Surface',\n}\n\nexport default GeometryType;\n","enum ContourType {\n CLOSED_PLANAR = 'CLOSED_PLANAR',\n OPEN_PLANAR = 'OPEN_PLANAR',\n}\n\nexport default ContourType;\n","/**\n * Interpolation types for image rendering\n */\nenum VOILUTFunctionType {\n LINEAR = 'LINEAR',\n SAMPLED_SIGMOID = 'SIGMOID', // SIGMOID is sampled in 1024 even steps so we call it SAMPLED_SIGMOID\n // EXACT_LINEAR = 'EXACT_LINEAR', TODO: Add EXACT_LINEAR option from DICOM NEMA\n}\n\nexport default VOILUTFunctionType;\n","/**\n * DynamicOperatorType enum for cornerstone-render which defines the operator to use for generateImageFromTimeData.\n * It can be either SUM, AVERAGE or SUBTRACT.\n */\nenum DynamicOperatorType {\n /** For summing the time frames. */\n SUM = 'SUM',\n /** For averaging the time frames. */\n AVERAGE = 'AVERAGE',\n /** For subtracting two time frames */\n SUBTRACT = 'SUBTRACT',\n}\n\nexport default DynamicOperatorType;\n","/**\n * Defines the calibration types available. These define how the units\n * for measurements are specified.\n */\nexport enum CalibrationTypes {\n /**\n * Not applicable means the units are directly defind by the underlying\n * hardware, such as CT and MR volumetric displays, so no special handling\n * or notification is required.\n */\n NOT_APPLICABLE = '',\n /**\n * ERMF is estimated radiographic magnification factor. This defines how\n * much the image is magnified at the detector as opposed to the location in\n * the body of interest. This occurs because the radiation beam is expanding\n * and effectively magnifies the image on the detector compared to where the\n * point of interest in the body is.\n * This suggests that measurements can be partially trusted, but the user\n * still needs to be aware that different depths within the body have differing\n * ERMF values, so precise measurements would still need to be manually calibrated.\n */\n ERMF = 'ERMF',\n /**\n * User calibration means that the user has provided a custom calibration\n * specifying how large the image data is. This type can occur on\n * volumetric images, eg for scout images that might have invalid spacing\n * tags.\n */\n USER = 'User',\n /**\n * A projection calibration means the raw detector size, without any\n * ERMF applied, meaning that the size in the body cannot be trusted and\n * that a calibration should be applied.\n * This is different from Error in that there is simply no magnification\n * factor applied as opposed to having multiple, inconsistent magnification\n * factors.\n */\n PROJECTION = 'Proj',\n /**\n * A region calibration is used for other types of images, typically\n * ultrasouunds where the distance in the image may mean something other than\n * physical distance, such as mV or Hz or some other measurement values.\n */\n REGION = 'Region',\n /**\n * Error is used to define mismatches between various units, such as when\n * there are two different ERMF values specified. This is an indication to\n * NOT trust the measurement values but to manually calibrate.\n */\n ERROR = 'Error',\n /** Uncalibrated image */\n UNCALIBRATED = 'Uncalibrated',\n}\n\nexport default CalibrationTypes;\n","enum ViewportStatus {\n /** Initial state before any volumes or stacks are available*/\n NO_DATA = 'noData',\n /** Stack/volumes are available but are in progress */\n LOADING = 'loading',\n /** Ready to be rendered */\n PRE_RENDER = 'preRender',\n /** In the midst of a resize */\n RESIZE = 'resize',\n /** Rendered image data */\n RENDERED = 'rendered',\n}\n\nexport default ViewportStatus;\n","/**\n * Status of a frame as it gets loaded. This is ordered, with lower\n * values being more lossy, and higher values being less lossy.\n */\nenum ImageQualityStatus {\n /**\n * Replicate is a duplicated image, from some larger distance\n */\n FAR_REPLICATE = 1,\n\n // Skipping a value here and after the next replicate to allow for interpolation\n // enum values.\n\n /**\n * Adjacent replicate is a duplicated image of a nearby image\n */\n ADJACENT_REPLICATE = 3,\n\n /**\n * Sub resolution images are encodings of smaller than full resolution\n * images. The encoding may or may not be lossy, but the lower resolution\n * means it has lost information already compared to full resolution/lossless.\n */\n SUBRESOLUTION = 6,\n\n /**\n * Lossy images, encoded with a lossy encoding, but full resolution or size.\n */\n LOSSY = 7,\n /**\n * Full resolution means the image is full resolution/complete data/lossless\n * (or at least as lossless as the image is going to get)\n */\n FULL_RESOLUTION = 8,\n}\n\nexport default ImageQualityStatus;\n","/**\n * video viewport speed units\n */\nenum SpeedUnit {\n FRAME = 'f',\n SECOND = 's',\n}\n\nexport { SpeedUnit };\n","/**\n * Contains the names for the metadata modules.\n * Recommendation is to add all module names here rather than having them\n * just use string names.\n * The naming convention is that the enum has the modules in it, so the\n * enum key does not repeat the Modules, but the enum value does (to agree\n * with existing naming conventions)\n */\nenum MetadataModules {\n CALIBRATION = 'calibrationModule',\n CINE = 'cineModule',\n GENERAL_IMAGE = 'generalImageModule',\n GENERAL_SERIES = 'generalSeriesModule',\n GENERAL_STUDY = 'generalStudyModule',\n IMAGE_PIXEL = 'imagePixelModule',\n IMAGE_PLANE = 'imagePlaneModule',\n IMAGE_URL = 'imageUrlModule',\n MODALITY_LUT = 'modalityLutModule',\n MULTIFRAME = 'multiframeModule',\n NM_MULTIFRAME_GEOMETRY = 'nmMultiframeGeometryModule',\n OVERLAY_PLANE = 'overlayPlaneModule',\n PATIENT = 'patientModule',\n PATIENT_STUDY = 'patientStudyModule',\n PET_IMAGE = 'petImageModule',\n PET_ISOTOPE = 'petIsotopeModule',\n PET_SERIES = 'petSeriesModule',\n SOP_COMMON = 'sopCommonModule',\n ULTRASOUND_ENHANCED_REGION = 'ultrasoundEnhancedRegionModule',\n VOI_LUT = 'voiLutModule',\n}\n\nexport default MetadataModules;\n","import { CPUFallbackColormapsData } from '../types';\n\n// Colormaps\n//\n// Hot Iron, PET, Hot Metal Blue and PET 20 Step are color palettes\n// Defined by the DICOM standard\n// http://dicom.nema.org/dicom/2013/output/chtml/part06/chapter_B.html\n//\n// All Linear Segmented Colormaps were copied from matplotlib\n// https://github.com/stefanv/matplotlib/blob/master/lib/matplotlib/_cm.py\n\nconst colormapsData: CPUFallbackColormapsData = {\n hotIron: {\n name: 'Hot Iron',\n numOfColors: 256,\n colors: [\n [0, 0, 0, 255],\n [2, 0, 0, 255],\n [4, 0, 0, 255],\n [6, 0, 0, 255],\n [8, 0, 0, 255],\n [10, 0, 0, 255],\n [12, 0, 0, 255],\n [14, 0, 0, 255],\n [16, 0, 0, 255],\n [18, 0, 0, 255],\n [20, 0, 0, 255],\n [22, 0, 0, 255],\n [24, 0, 0, 255],\n [26, 0, 0, 255],\n [28, 0, 0, 255],\n [30, 0, 0, 255],\n [32, 0, 0, 255],\n [34, 0, 0, 255],\n [36, 0, 0, 255],\n [38, 0, 0, 255],\n [40, 0, 0, 255],\n [42, 0, 0, 255],\n [44, 0, 0, 255],\n [46, 0, 0, 255],\n [48, 0, 0, 255],\n [50, 0, 0, 255],\n [52, 0, 0, 255],\n [54, 0, 0, 255],\n [56, 0, 0, 255],\n [58, 0, 0, 255],\n [60, 0, 0, 255],\n [62, 0, 0, 255],\n [64, 0, 0, 255],\n [66, 0, 0, 255],\n [68, 0, 0, 255],\n [70, 0, 0, 255],\n [72, 0, 0, 255],\n [74, 0, 0, 255],\n [76, 0, 0, 255],\n [78, 0, 0, 255],\n [80, 0, 0, 255],\n [82, 0, 0, 255],\n [84, 0, 0, 255],\n [86, 0, 0, 255],\n [88, 0, 0, 255],\n [90, 0, 0, 255],\n [92, 0, 0, 255],\n [94, 0, 0, 255],\n [96, 0, 0, 255],\n [98, 0, 0, 255],\n [100, 0, 0, 255],\n [102, 0, 0, 255],\n [104, 0, 0, 255],\n [106, 0, 0, 255],\n [108, 0, 0, 255],\n [110, 0, 0, 255],\n [112, 0, 0, 255],\n [114, 0, 0, 255],\n [116, 0, 0, 255],\n [118, 0, 0, 255],\n [120, 0, 0, 255],\n [122, 0, 0, 255],\n [124, 0, 0, 255],\n [126, 0, 0, 255],\n [128, 0, 0, 255],\n [130, 0, 0, 255],\n [132, 0, 0, 255],\n [134, 0, 0, 255],\n [136, 0, 0, 255],\n [138, 0, 0, 255],\n [140, 0, 0, 255],\n [142, 0, 0, 255],\n [144, 0, 0, 255],\n [146, 0, 0, 255],\n [148, 0, 0, 255],\n [150, 0, 0, 255],\n [152, 0, 0, 255],\n [154, 0, 0, 255],\n [156, 0, 0, 255],\n [158, 0, 0, 255],\n [160, 0, 0, 255],\n [162, 0, 0, 255],\n [164, 0, 0, 255],\n [166, 0, 0, 255],\n [168, 0, 0, 255],\n [170, 0, 0, 255],\n [172, 0, 0, 255],\n [174, 0, 0, 255],\n [176, 0, 0, 255],\n [178, 0, 0, 255],\n [180, 0, 0, 255],\n [182, 0, 0, 255],\n [184, 0, 0, 255],\n [186, 0, 0, 255],\n [188, 0, 0, 255],\n [190, 0, 0, 255],\n [192, 0, 0, 255],\n [194, 0, 0, 255],\n [196, 0, 0, 255],\n [198, 0, 0, 255],\n [200, 0, 0, 255],\n [202, 0, 0, 255],\n [204, 0, 0, 255],\n [206, 0, 0, 255],\n [208, 0, 0, 255],\n [210, 0, 0, 255],\n [212, 0, 0, 255],\n [214, 0, 0, 255],\n [216, 0, 0, 255],\n [218, 0, 0, 255],\n [220, 0, 0, 255],\n [222, 0, 0, 255],\n [224, 0, 0, 255],\n [226, 0, 0, 255],\n [228, 0, 0, 255],\n [230, 0, 0, 255],\n [232, 0, 0, 255],\n [234, 0, 0, 255],\n [236, 0, 0, 255],\n [238, 0, 0, 255],\n [240, 0, 0, 255],\n [242, 0, 0, 255],\n [244, 0, 0, 255],\n [246, 0, 0, 255],\n [248, 0, 0, 255],\n [250, 0, 0, 255],\n [252, 0, 0, 255],\n [254, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 2, 0, 255],\n [255, 4, 0, 255],\n [255, 6, 0, 255],\n [255, 8, 0, 255],\n [255, 10, 0, 255],\n [255, 12, 0, 255],\n [255, 14, 0, 255],\n [255, 16, 0, 255],\n [255, 18, 0, 255],\n [255, 20, 0, 255],\n [255, 22, 0, 255],\n [255, 24, 0, 255],\n [255, 26, 0, 255],\n [255, 28, 0, 255],\n [255, 30, 0, 255],\n [255, 32, 0, 255],\n [255, 34, 0, 255],\n [255, 36, 0, 255],\n [255, 38, 0, 255],\n [255, 40, 0, 255],\n [255, 42, 0, 255],\n [255, 44, 0, 255],\n [255, 46, 0, 255],\n [255, 48, 0, 255],\n [255, 50, 0, 255],\n [255, 52, 0, 255],\n [255, 54, 0, 255],\n [255, 56, 0, 255],\n [255, 58, 0, 255],\n [255, 60, 0, 255],\n [255, 62, 0, 255],\n [255, 64, 0, 255],\n [255, 66, 0, 255],\n [255, 68, 0, 255],\n [255, 70, 0, 255],\n [255, 72, 0, 255],\n [255, 74, 0, 255],\n [255, 76, 0, 255],\n [255, 78, 0, 255],\n [255, 80, 0, 255],\n [255, 82, 0, 255],\n [255, 84, 0, 255],\n [255, 86, 0, 255],\n [255, 88, 0, 255],\n [255, 90, 0, 255],\n [255, 92, 0, 255],\n [255, 94, 0, 255],\n [255, 96, 0, 255],\n [255, 98, 0, 255],\n [255, 100, 0, 255],\n [255, 102, 0, 255],\n [255, 104, 0, 255],\n [255, 106, 0, 255],\n [255, 108, 0, 255],\n [255, 110, 0, 255],\n [255, 112, 0, 255],\n [255, 114, 0, 255],\n [255, 116, 0, 255],\n [255, 118, 0, 255],\n [255, 120, 0, 255],\n [255, 122, 0, 255],\n [255, 124, 0, 255],\n [255, 126, 0, 255],\n [255, 128, 4, 255],\n [255, 130, 8, 255],\n [255, 132, 12, 255],\n [255, 134, 16, 255],\n [255, 136, 20, 255],\n [255, 138, 24, 255],\n [255, 140, 28, 255],\n [255, 142, 32, 255],\n [255, 144, 36, 255],\n [255, 146, 40, 255],\n [255, 148, 44, 255],\n [255, 150, 48, 255],\n [255, 152, 52, 255],\n [255, 154, 56, 255],\n [255, 156, 60, 255],\n [255, 158, 64, 255],\n [255, 160, 68, 255],\n [255, 162, 72, 255],\n [255, 164, 76, 255],\n [255, 166, 80, 255],\n [255, 168, 84, 255],\n [255, 170, 88, 255],\n [255, 172, 92, 255],\n [255, 174, 96, 255],\n [255, 176, 100, 255],\n [255, 178, 104, 255],\n [255, 180, 108, 255],\n [255, 182, 112, 255],\n [255, 184, 116, 255],\n [255, 186, 120, 255],\n [255, 188, 124, 255],\n [255, 190, 128, 255],\n [255, 192, 132, 255],\n [255, 194, 136, 255],\n [255, 196, 140, 255],\n [255, 198, 144, 255],\n [255, 200, 148, 255],\n [255, 202, 152, 255],\n [255, 204, 156, 255],\n [255, 206, 160, 255],\n [255, 208, 164, 255],\n [255, 210, 168, 255],\n [255, 212, 172, 255],\n [255, 214, 176, 255],\n [255, 216, 180, 255],\n [255, 218, 184, 255],\n [255, 220, 188, 255],\n [255, 222, 192, 255],\n [255, 224, 196, 255],\n [255, 226, 200, 255],\n [255, 228, 204, 255],\n [255, 230, 208, 255],\n [255, 232, 212, 255],\n [255, 234, 216, 255],\n [255, 236, 220, 255],\n [255, 238, 224, 255],\n [255, 240, 228, 255],\n [255, 242, 232, 255],\n [255, 244, 236, 255],\n [255, 246, 240, 255],\n [255, 248, 244, 255],\n [255, 250, 248, 255],\n [255, 252, 252, 255],\n [255, 255, 255, 255],\n ],\n },\n pet: {\n name: 'PET',\n numColors: 256,\n colors: [\n [0, 0, 0, 255],\n [0, 2, 1, 255],\n [0, 4, 3, 255],\n [0, 6, 5, 255],\n [0, 8, 7, 255],\n [0, 10, 9, 255],\n [0, 12, 11, 255],\n [0, 14, 13, 255],\n [0, 16, 15, 255],\n [0, 18, 17, 255],\n [0, 20, 19, 255],\n [0, 22, 21, 255],\n [0, 24, 23, 255],\n [0, 26, 25, 255],\n [0, 28, 27, 255],\n [0, 30, 29, 255],\n [0, 32, 31, 255],\n [0, 34, 33, 255],\n [0, 36, 35, 255],\n [0, 38, 37, 255],\n [0, 40, 39, 255],\n [0, 42, 41, 255],\n [0, 44, 43, 255],\n [0, 46, 45, 255],\n [0, 48, 47, 255],\n [0, 50, 49, 255],\n [0, 52, 51, 255],\n [0, 54, 53, 255],\n [0, 56, 55, 255],\n [0, 58, 57, 255],\n [0, 60, 59, 255],\n [0, 62, 61, 255],\n [0, 65, 63, 255],\n [0, 67, 65, 255],\n [0, 69, 67, 255],\n [0, 71, 69, 255],\n [0, 73, 71, 255],\n [0, 75, 73, 255],\n [0, 77, 75, 255],\n [0, 79, 77, 255],\n [0, 81, 79, 255],\n [0, 83, 81, 255],\n [0, 85, 83, 255],\n [0, 87, 85, 255],\n [0, 89, 87, 255],\n [0, 91, 89, 255],\n [0, 93, 91, 255],\n [0, 95, 93, 255],\n [0, 97, 95, 255],\n [0, 99, 97, 255],\n [0, 101, 99, 255],\n [0, 103, 101, 255],\n [0, 105, 103, 255],\n [0, 107, 105, 255],\n [0, 109, 107, 255],\n [0, 111, 109, 255],\n [0, 113, 111, 255],\n [0, 115, 113, 255],\n [0, 117, 115, 255],\n [0, 119, 117, 255],\n [0, 121, 119, 255],\n [0, 123, 121, 255],\n [0, 125, 123, 255],\n [0, 128, 125, 255],\n [1, 126, 127, 255],\n [3, 124, 129, 255],\n [5, 122, 131, 255],\n [7, 120, 133, 255],\n [9, 118, 135, 255],\n [11, 116, 137, 255],\n [13, 114, 139, 255],\n [15, 112, 141, 255],\n [17, 110, 143, 255],\n [19, 108, 145, 255],\n [21, 106, 147, 255],\n [23, 104, 149, 255],\n [25, 102, 151, 255],\n [27, 100, 153, 255],\n [29, 98, 155, 255],\n [31, 96, 157, 255],\n [33, 94, 159, 255],\n [35, 92, 161, 255],\n [37, 90, 163, 255],\n [39, 88, 165, 255],\n [41, 86, 167, 255],\n [43, 84, 169, 255],\n [45, 82, 171, 255],\n [47, 80, 173, 255],\n [49, 78, 175, 255],\n [51, 76, 177, 255],\n [53, 74, 179, 255],\n [55, 72, 181, 255],\n [57, 70, 183, 255],\n [59, 68, 185, 255],\n [61, 66, 187, 255],\n [63, 64, 189, 255],\n [65, 63, 191, 255],\n [67, 61, 193, 255],\n [69, 59, 195, 255],\n [71, 57, 197, 255],\n [73, 55, 199, 255],\n [75, 53, 201, 255],\n [77, 51, 203, 255],\n [79, 49, 205, 255],\n [81, 47, 207, 255],\n [83, 45, 209, 255],\n [85, 43, 211, 255],\n [86, 41, 213, 255],\n [88, 39, 215, 255],\n [90, 37, 217, 255],\n [92, 35, 219, 255],\n [94, 33, 221, 255],\n [96, 31, 223, 255],\n [98, 29, 225, 255],\n [100, 27, 227, 255],\n [102, 25, 229, 255],\n [104, 23, 231, 255],\n [106, 21, 233, 255],\n [108, 19, 235, 255],\n [110, 17, 237, 255],\n [112, 15, 239, 255],\n [114, 13, 241, 255],\n [116, 11, 243, 255],\n [118, 9, 245, 255],\n [120, 7, 247, 255],\n [122, 5, 249, 255],\n [124, 3, 251, 255],\n [126, 1, 253, 255],\n [128, 0, 255, 255],\n [130, 2, 252, 255],\n [132, 4, 248, 255],\n [134, 6, 244, 255],\n [136, 8, 240, 255],\n [138, 10, 236, 255],\n [140, 12, 232, 255],\n [142, 14, 228, 255],\n [144, 16, 224, 255],\n [146, 18, 220, 255],\n [148, 20, 216, 255],\n [150, 22, 212, 255],\n [152, 24, 208, 255],\n [154, 26, 204, 255],\n [156, 28, 200, 255],\n [158, 30, 196, 255],\n [160, 32, 192, 255],\n [162, 34, 188, 255],\n [164, 36, 184, 255],\n [166, 38, 180, 255],\n [168, 40, 176, 255],\n [170, 42, 172, 255],\n [171, 44, 168, 255],\n [173, 46, 164, 255],\n [175, 48, 160, 255],\n [177, 50, 156, 255],\n [179, 52, 152, 255],\n [181, 54, 148, 255],\n [183, 56, 144, 255],\n [185, 58, 140, 255],\n [187, 60, 136, 255],\n [189, 62, 132, 255],\n [191, 64, 128, 255],\n [193, 66, 124, 255],\n [195, 68, 120, 255],\n [197, 70, 116, 255],\n [199, 72, 112, 255],\n [201, 74, 108, 255],\n [203, 76, 104, 255],\n [205, 78, 100, 255],\n [207, 80, 96, 255],\n [209, 82, 92, 255],\n [211, 84, 88, 255],\n [213, 86, 84, 255],\n [215, 88, 80, 255],\n [217, 90, 76, 255],\n [219, 92, 72, 255],\n [221, 94, 68, 255],\n [223, 96, 64, 255],\n [225, 98, 60, 255],\n [227, 100, 56, 255],\n [229, 102, 52, 255],\n [231, 104, 48, 255],\n [233, 106, 44, 255],\n [235, 108, 40, 255],\n [237, 110, 36, 255],\n [239, 112, 32, 255],\n [241, 114, 28, 255],\n [243, 116, 24, 255],\n [245, 118, 20, 255],\n [247, 120, 16, 255],\n [249, 122, 12, 255],\n [251, 124, 8, 255],\n [253, 126, 4, 255],\n [255, 128, 0, 255],\n [255, 130, 4, 255],\n [255, 132, 8, 255],\n [255, 134, 12, 255],\n [255, 136, 16, 255],\n [255, 138, 20, 255],\n [255, 140, 24, 255],\n [255, 142, 28, 255],\n [255, 144, 32, 255],\n [255, 146, 36, 255],\n [255, 148, 40, 255],\n [255, 150, 44, 255],\n [255, 152, 48, 255],\n [255, 154, 52, 255],\n [255, 156, 56, 255],\n [255, 158, 60, 255],\n [255, 160, 64, 255],\n [255, 162, 68, 255],\n [255, 164, 72, 255],\n [255, 166, 76, 255],\n [255, 168, 80, 255],\n [255, 170, 85, 255],\n [255, 172, 89, 255],\n [255, 174, 93, 255],\n [255, 176, 97, 255],\n [255, 178, 101, 255],\n [255, 180, 105, 255],\n [255, 182, 109, 255],\n [255, 184, 113, 255],\n [255, 186, 117, 255],\n [255, 188, 121, 255],\n [255, 190, 125, 255],\n [255, 192, 129, 255],\n [255, 194, 133, 255],\n [255, 196, 137, 255],\n [255, 198, 141, 255],\n [255, 200, 145, 255],\n [255, 202, 149, 255],\n [255, 204, 153, 255],\n [255, 206, 157, 255],\n [255, 208, 161, 255],\n [255, 210, 165, 255],\n [255, 212, 170, 255],\n [255, 214, 174, 255],\n [255, 216, 178, 255],\n [255, 218, 182, 255],\n [255, 220, 186, 255],\n [255, 222, 190, 255],\n [255, 224, 194, 255],\n [255, 226, 198, 255],\n [255, 228, 202, 255],\n [255, 230, 206, 255],\n [255, 232, 210, 255],\n [255, 234, 214, 255],\n [255, 236, 218, 255],\n [255, 238, 222, 255],\n [255, 240, 226, 255],\n [255, 242, 230, 255],\n [255, 244, 234, 255],\n [255, 246, 238, 255],\n [255, 248, 242, 255],\n [255, 250, 246, 255],\n [255, 252, 250, 255],\n [255, 255, 255, 255],\n ],\n },\n hotMetalBlue: {\n name: 'Hot Metal Blue',\n numColors: 256,\n colors: [\n [0, 0, 0, 255],\n [0, 0, 2, 255],\n [0, 0, 4, 255],\n [0, 0, 6, 255],\n [0, 0, 8, 255],\n [0, 0, 10, 255],\n [0, 0, 12, 255],\n [0, 0, 14, 255],\n [0, 0, 16, 255],\n [0, 0, 17, 255],\n [0, 0, 19, 255],\n [0, 0, 21, 255],\n [0, 0, 23, 255],\n [0, 0, 25, 255],\n [0, 0, 27, 255],\n [0, 0, 29, 255],\n [0, 0, 31, 255],\n [0, 0, 33, 255],\n [0, 0, 35, 255],\n [0, 0, 37, 255],\n [0, 0, 39, 255],\n [0, 0, 41, 255],\n [0, 0, 43, 255],\n [0, 0, 45, 255],\n [0, 0, 47, 255],\n [0, 0, 49, 255],\n [0, 0, 51, 255],\n [0, 0, 53, 255],\n [0, 0, 55, 255],\n [0, 0, 57, 255],\n [0, 0, 59, 255],\n [0, 0, 61, 255],\n [0, 0, 63, 255],\n [0, 0, 65, 255],\n [0, 0, 67, 255],\n [0, 0, 69, 255],\n [0, 0, 71, 255],\n [0, 0, 73, 255],\n [0, 0, 75, 255],\n [0, 0, 77, 255],\n [0, 0, 79, 255],\n [0, 0, 81, 255],\n [0, 0, 83, 255],\n [0, 0, 84, 255],\n [0, 0, 86, 255],\n [0, 0, 88, 255],\n [0, 0, 90, 255],\n [0, 0, 92, 255],\n [0, 0, 94, 255],\n [0, 0, 96, 255],\n [0, 0, 98, 255],\n [0, 0, 100, 255],\n [0, 0, 102, 255],\n [0, 0, 104, 255],\n [0, 0, 106, 255],\n [0, 0, 108, 255],\n [0, 0, 110, 255],\n [0, 0, 112, 255],\n [0, 0, 114, 255],\n [0, 0, 116, 255],\n [0, 0, 117, 255],\n [0, 0, 119, 255],\n [0, 0, 121, 255],\n [0, 0, 123, 255],\n [0, 0, 125, 255],\n [0, 0, 127, 255],\n [0, 0, 129, 255],\n [0, 0, 131, 255],\n [0, 0, 133, 255],\n [0, 0, 135, 255],\n [0, 0, 137, 255],\n [0, 0, 139, 255],\n [0, 0, 141, 255],\n [0, 0, 143, 255],\n [0, 0, 145, 255],\n [0, 0, 147, 255],\n [0, 0, 149, 255],\n [0, 0, 151, 255],\n [0, 0, 153, 255],\n [0, 0, 155, 255],\n [0, 0, 157, 255],\n [0, 0, 159, 255],\n [0, 0, 161, 255],\n [0, 0, 163, 255],\n [0, 0, 165, 255],\n [0, 0, 167, 255],\n [3, 0, 169, 255],\n [6, 0, 171, 255],\n [9, 0, 173, 255],\n [12, 0, 175, 255],\n [15, 0, 177, 255],\n [18, 0, 179, 255],\n [21, 0, 181, 255],\n [24, 0, 183, 255],\n [26, 0, 184, 255],\n [29, 0, 186, 255],\n [32, 0, 188, 255],\n [35, 0, 190, 255],\n [38, 0, 192, 255],\n [41, 0, 194, 255],\n [44, 0, 196, 255],\n [47, 0, 198, 255],\n [50, 0, 200, 255],\n [52, 0, 197, 255],\n [55, 0, 194, 255],\n [57, 0, 191, 255],\n [59, 0, 188, 255],\n [62, 0, 185, 255],\n [64, 0, 182, 255],\n [66, 0, 179, 255],\n [69, 0, 176, 255],\n [71, 0, 174, 255],\n [74, 0, 171, 255],\n [76, 0, 168, 255],\n [78, 0, 165, 255],\n [81, 0, 162, 255],\n [83, 0, 159, 255],\n [85, 0, 156, 255],\n [88, 0, 153, 255],\n [90, 0, 150, 255],\n [93, 2, 144, 255],\n [96, 4, 138, 255],\n [99, 6, 132, 255],\n [102, 8, 126, 255],\n [105, 9, 121, 255],\n [108, 11, 115, 255],\n [111, 13, 109, 255],\n [114, 15, 103, 255],\n [116, 17, 97, 255],\n [119, 19, 91, 255],\n [122, 21, 85, 255],\n [125, 23, 79, 255],\n [128, 24, 74, 255],\n [131, 26, 68, 255],\n [134, 28, 62, 255],\n [137, 30, 56, 255],\n [140, 32, 50, 255],\n [143, 34, 47, 255],\n [146, 36, 44, 255],\n [149, 38, 41, 255],\n [152, 40, 38, 255],\n [155, 41, 35, 255],\n [158, 43, 32, 255],\n [161, 45, 29, 255],\n [164, 47, 26, 255],\n [166, 49, 24, 255],\n [169, 51, 21, 255],\n [172, 53, 18, 255],\n [175, 55, 15, 255],\n [178, 56, 12, 255],\n [181, 58, 9, 255],\n [184, 60, 6, 255],\n [187, 62, 3, 255],\n [190, 64, 0, 255],\n [194, 66, 0, 255],\n [198, 68, 0, 255],\n [201, 70, 0, 255],\n [205, 72, 0, 255],\n [209, 73, 0, 255],\n [213, 75, 0, 255],\n [217, 77, 0, 255],\n [221, 79, 0, 255],\n [224, 81, 0, 255],\n [228, 83, 0, 255],\n [232, 85, 0, 255],\n [236, 87, 0, 255],\n [240, 88, 0, 255],\n [244, 90, 0, 255],\n [247, 92, 0, 255],\n [251, 94, 0, 255],\n [255, 96, 0, 255],\n [255, 98, 3, 255],\n [255, 100, 6, 255],\n [255, 102, 9, 255],\n [255, 104, 12, 255],\n [255, 105, 15, 255],\n [255, 107, 18, 255],\n [255, 109, 21, 255],\n [255, 111, 24, 255],\n [255, 113, 26, 255],\n [255, 115, 29, 255],\n [255, 117, 32, 255],\n [255, 119, 35, 255],\n [255, 120, 38, 255],\n [255, 122, 41, 255],\n [255, 124, 44, 255],\n [255, 126, 47, 255],\n [255, 128, 50, 255],\n [255, 130, 53, 255],\n [255, 132, 56, 255],\n [255, 134, 59, 255],\n [255, 136, 62, 255],\n [255, 137, 65, 255],\n [255, 139, 68, 255],\n [255, 141, 71, 255],\n [255, 143, 74, 255],\n [255, 145, 76, 255],\n [255, 147, 79, 255],\n [255, 149, 82, 255],\n [255, 151, 85, 255],\n [255, 152, 88, 255],\n [255, 154, 91, 255],\n [255, 156, 94, 255],\n [255, 158, 97, 255],\n [255, 160, 100, 255],\n [255, 162, 103, 255],\n [255, 164, 106, 255],\n [255, 166, 109, 255],\n [255, 168, 112, 255],\n [255, 169, 115, 255],\n [255, 171, 118, 255],\n [255, 173, 121, 255],\n [255, 175, 124, 255],\n [255, 177, 126, 255],\n [255, 179, 129, 255],\n [255, 181, 132, 255],\n [255, 183, 135, 255],\n [255, 184, 138, 255],\n [255, 186, 141, 255],\n [255, 188, 144, 255],\n [255, 190, 147, 255],\n [255, 192, 150, 255],\n [255, 194, 153, 255],\n [255, 196, 156, 255],\n [255, 198, 159, 255],\n [255, 200, 162, 255],\n [255, 201, 165, 255],\n [255, 203, 168, 255],\n [255, 205, 171, 255],\n [255, 207, 174, 255],\n [255, 209, 176, 255],\n [255, 211, 179, 255],\n [255, 213, 182, 255],\n [255, 215, 185, 255],\n [255, 216, 188, 255],\n [255, 218, 191, 255],\n [255, 220, 194, 255],\n [255, 222, 197, 255],\n [255, 224, 200, 255],\n [255, 226, 203, 255],\n [255, 228, 206, 255],\n [255, 229, 210, 255],\n [255, 231, 213, 255],\n [255, 233, 216, 255],\n [255, 235, 219, 255],\n [255, 237, 223, 255],\n [255, 239, 226, 255],\n [255, 240, 229, 255],\n [255, 242, 232, 255],\n [255, 244, 236, 255],\n [255, 246, 239, 255],\n [255, 248, 242, 255],\n [255, 250, 245, 255],\n [255, 251, 249, 255],\n [255, 253, 252, 255],\n [255, 255, 255, 255],\n ],\n },\n pet20Step: {\n name: 'PET 20 Step',\n numColors: 256,\n colors: [\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [0, 0, 0, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [96, 0, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 80, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [48, 48, 112, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [80, 80, 128, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [96, 96, 176, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [112, 112, 192, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [128, 128, 224, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 96, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [48, 144, 48, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [80, 192, 80, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [64, 224, 64, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [224, 224, 80, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 208, 96, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 176, 64, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [208, 144, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [192, 96, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [176, 48, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 0, 0, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n [255, 255, 255, 255],\n ],\n },\n gray: {\n name: 'Gray',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0, 0],\n [1, 1, 1],\n ],\n green: [\n [0, 0, 0],\n [1, 1, 1],\n ],\n blue: [\n [0, 0, 0],\n [1, 1, 1],\n ],\n },\n },\n jet: {\n name: 'Jet',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0, 0],\n [0.35, 0, 0],\n [0.66, 1, 1],\n [0.89, 1, 1],\n [1, 0.5, 0.5],\n ],\n green: [\n [0, 0, 0],\n [0.125, 0, 0],\n [0.375, 1, 1],\n [0.64, 1, 1],\n [0.91, 0, 0],\n [1, 0, 0],\n ],\n blue: [\n [0, 0.5, 0.5],\n [0.11, 1, 1],\n [0.34, 1, 1],\n [0.65, 0, 0],\n [1, 0, 0],\n ],\n },\n },\n hsv: {\n name: 'HSV',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 1, 1],\n [0.15873, 1, 1],\n [0.174603, 0.96875, 0.96875],\n [0.333333, 0.03125, 0.03125],\n [0.349206, 0, 0],\n [0.666667, 0, 0],\n [0.68254, 0.03125, 0.03125],\n [0.84127, 0.96875, 0.96875],\n [0.857143, 1, 1],\n [1, 1, 1],\n ],\n green: [\n [0, 0, 0],\n [0.15873, 0.9375, 0.9375],\n [0.174603, 1, 1],\n [0.507937, 1, 1],\n [0.666667, 0.0625, 0.0625],\n [0.68254, 0, 0],\n [1, 0, 0],\n ],\n blue: [\n [0, 0, 0],\n [0.333333, 0, 0],\n [0.349206, 0.0625, 0.0625],\n [0.507937, 1, 1],\n [0.84127, 1, 1],\n [0.857143, 0.9375, 0.9375],\n [1, 0.09375, 0.09375],\n ],\n },\n },\n hot: {\n name: 'Hot',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0.0416, 0.0416],\n [0.365079, 1, 1],\n [1, 1, 1],\n ],\n green: [\n [0, 0, 0],\n [0.365079, 0, 0],\n [0.746032, 1, 1],\n [1, 1, 1],\n ],\n blue: [\n [0, 0, 0],\n [0.746032, 0, 0],\n [1, 1, 1],\n ],\n },\n },\n cool: {\n name: 'Cool',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0, 0],\n [1, 1, 1],\n ],\n green: [\n [0, 1, 1],\n [1, 0, 0],\n ],\n blue: [\n [0, 1, 1],\n [1, 1, 1],\n ],\n },\n },\n spring: {\n name: 'Spring',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 1, 1],\n [1, 1, 1],\n ],\n green: [\n [0, 0, 0],\n [1, 1, 1],\n ],\n blue: [\n [0, 1, 1],\n [1, 0, 0],\n ],\n },\n },\n summer: {\n name: 'Summer',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0, 0],\n [1, 1, 1],\n ],\n green: [\n [0, 0.5, 0.5],\n [1, 1, 1],\n ],\n blue: [\n [0, 0.4, 0.4],\n [1, 0.4, 0.4],\n ],\n },\n },\n autumn: {\n name: 'Autumn',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 1, 1],\n [1, 1, 1],\n ],\n green: [\n [0, 0, 0],\n [1, 1, 1],\n ],\n blue: [\n [0, 0, 0],\n [1, 0, 0],\n ],\n },\n },\n winter: {\n name: 'Winter',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0, 0],\n [1, 0, 0],\n ],\n green: [\n [0, 0, 0],\n [1, 1, 1],\n ],\n blue: [\n [0, 1, 1],\n [1, 0.5, 0.5],\n ],\n },\n },\n bone: {\n name: 'Bone',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0, 0],\n [0.746032, 0.652778, 0.652778],\n [1, 1, 1],\n ],\n green: [\n [0, 0, 0],\n [0.365079, 0.319444, 0.319444],\n [0.746032, 0.777778, 0.777778],\n [1, 1, 1],\n ],\n blue: [\n [0, 0, 0],\n [0.365079, 0.444444, 0.444444],\n [1, 1, 1],\n ],\n },\n },\n copper: {\n name: 'Copper',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0, 0],\n [0.809524, 1, 1],\n [1, 1, 1],\n ],\n green: [\n [0, 0, 0],\n [1, 0.7812, 0.7812],\n ],\n blue: [\n [0, 0, 0],\n [1, 0.4975, 0.4975],\n ],\n },\n },\n spectral: {\n name: 'Spectral',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0, 0],\n [0.05, 0.4667, 0.4667],\n [0.1, 0.5333, 0.5333],\n [0.15, 0, 0],\n [0.2, 0, 0],\n [0.25, 0, 0],\n [0.3, 0, 0],\n [0.35, 0, 0],\n [0.4, 0, 0],\n [0.45, 0, 0],\n [0.5, 0, 0],\n [0.55, 0, 0],\n [0.6, 0, 0],\n [0.65, 0.7333, 0.7333],\n [0.7, 0.9333, 0.9333],\n [0.75, 1, 1],\n [0.8, 1, 1],\n [0.85, 1, 1],\n [0.9, 0.8667, 0.8667],\n [0.95, 0.8, 0.8],\n [1, 0.8, 0.8],\n ],\n green: [\n [0, 0, 0],\n [0.05, 0, 0],\n [0.1, 0, 0],\n [0.15, 0, 0],\n [0.2, 0, 0],\n [0.25, 0.4667, 0.4667],\n [0.3, 0.6, 0.6],\n [0.35, 0.6667, 0.6667],\n [0.4, 0.6667, 0.6667],\n [0.45, 0.6, 0.6],\n [0.5, 0.7333, 0.7333],\n [0.55, 0.8667, 0.8667],\n [0.6, 1, 1],\n [0.65, 1, 1],\n [0.7, 0.9333, 0.9333],\n [0.75, 0.8, 0.8],\n [0.8, 0.6, 0.6],\n [0.85, 0, 0],\n [0.9, 0, 0],\n [0.95, 0, 0],\n [1, 0.8, 0.8],\n ],\n blue: [\n [0, 0, 0],\n [0.05, 0.5333, 0.5333],\n [0.1, 0.6, 0.6],\n [0.15, 0.6667, 0.6667],\n [0.2, 0.8667, 0.8667],\n [0.25, 0.8667, 0.8667],\n [0.3, 0.8667, 0.8667],\n [0.35, 0.6667, 0.6667],\n [0.4, 0.5333, 0.5333],\n [0.45, 0, 0],\n [0.5, 0, 0],\n [0.55, 0, 0],\n [0.6, 0, 0],\n [0.65, 0, 0],\n [0.7, 0, 0],\n [0.75, 0, 0],\n [0.8, 0, 0],\n [0.85, 0, 0],\n [0.9, 0, 0],\n [0.95, 0, 0],\n [1, 0.8, 0.8],\n ],\n },\n },\n coolwarm: {\n name: 'CoolWarm',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0.2298057, 0.2298057],\n [0.03125, 0.26623388, 0.26623388],\n [0.0625, 0.30386891, 0.30386891],\n [0.09375, 0.342804478, 0.342804478],\n [0.125, 0.38301334, 0.38301334],\n [0.15625, 0.424369608, 0.424369608],\n [0.1875, 0.46666708, 0.46666708],\n [0.21875, 0.509635204, 0.509635204],\n [0.25, 0.552953156, 0.552953156],\n [0.28125, 0.596262162, 0.596262162],\n [0.3125, 0.639176211, 0.639176211],\n [0.34375, 0.681291281, 0.681291281],\n [0.375, 0.722193294, 0.722193294],\n [0.40625, 0.761464949, 0.761464949],\n [0.4375, 0.798691636, 0.798691636],\n [0.46875, 0.833466556, 0.833466556],\n [0.5, 0.865395197, 0.865395197],\n [0.53125, 0.897787179, 0.897787179],\n [0.5625, 0.924127593, 0.924127593],\n [0.59375, 0.944468518, 0.944468518],\n [0.625, 0.958852946, 0.958852946],\n [0.65625, 0.96732803, 0.96732803],\n [0.6875, 0.969954137, 0.969954137],\n [0.71875, 0.966811177, 0.966811177],\n [0.75, 0.958003065, 0.958003065],\n [0.78125, 0.943660866, 0.943660866],\n [0.8125, 0.923944917, 0.923944917],\n [0.84375, 0.89904617, 0.89904617],\n [0.875, 0.869186849, 0.869186849],\n [0.90625, 0.834620542, 0.834620542],\n [0.9375, 0.795631745, 0.795631745],\n [0.96875, 0.752534934, 0.752534934],\n [1, 0.705673158, 0.705673158],\n ],\n green: [\n [0, 0.298717966, 0.298717966],\n [0.03125, 0.353094838, 0.353094838],\n [0.0625, 0.406535296, 0.406535296],\n [0.09375, 0.458757618, 0.458757618],\n [0.125, 0.50941904, 0.50941904],\n [0.15625, 0.558148092, 0.558148092],\n [0.1875, 0.604562568, 0.604562568],\n [0.21875, 0.648280772, 0.648280772],\n [0.25, 0.688929332, 0.688929332],\n [0.28125, 0.726149107, 0.726149107],\n [0.3125, 0.759599947, 0.759599947],\n [0.34375, 0.788964712, 0.788964712],\n [0.375, 0.813952739, 0.813952739],\n [0.40625, 0.834302879, 0.834302879],\n [0.4375, 0.849786142, 0.849786142],\n [0.46875, 0.860207984, 0.860207984],\n [0.5, 0.86541021, 0.86541021],\n [0.53125, 0.848937047, 0.848937047],\n [0.5625, 0.827384882, 0.827384882],\n [0.59375, 0.800927443, 0.800927443],\n [0.625, 0.769767752, 0.769767752],\n [0.65625, 0.734132809, 0.734132809],\n [0.6875, 0.694266682, 0.694266682],\n [0.71875, 0.650421156, 0.650421156],\n [0.75, 0.602842431, 0.602842431],\n [0.78125, 0.551750968, 0.551750968],\n [0.8125, 0.49730856, 0.49730856],\n [0.84375, 0.439559467, 0.439559467],\n [0.875, 0.378313092, 0.378313092],\n [0.90625, 0.312874446, 0.312874446],\n [0.9375, 0.24128379, 0.24128379],\n [0.96875, 0.157246067, 0.157246067],\n [1, 0.01555616, 0.01555616],\n ],\n blue: [\n [0, 0.753683153, 0.753683153],\n [0.03125, 0.801466763, 0.801466763],\n [0.0625, 0.84495867, 0.84495867],\n [0.09375, 0.883725899, 0.883725899],\n [0.125, 0.917387822, 0.917387822],\n [0.15625, 0.945619588, 0.945619588],\n [0.1875, 0.968154911, 0.968154911],\n [0.21875, 0.98478814, 0.98478814],\n [0.25, 0.995375608, 0.995375608],\n [0.28125, 0.999836203, 0.999836203],\n [0.3125, 0.998151185, 0.998151185],\n [0.34375, 0.990363227, 0.990363227],\n [0.375, 0.976574709, 0.976574709],\n [0.40625, 0.956945269, 0.956945269],\n [0.4375, 0.931688648, 0.931688648],\n [0.46875, 0.901068838, 0.901068838],\n [0.5, 0.865395561, 0.865395561],\n [0.53125, 0.820880546, 0.820880546],\n [0.5625, 0.774508472, 0.774508472],\n [0.59375, 0.726736146, 0.726736146],\n [0.625, 0.678007945, 0.678007945],\n [0.65625, 0.628751763, 0.628751763],\n [0.6875, 0.579375448, 0.579375448],\n [0.71875, 0.530263762, 0.530263762],\n [0.75, 0.481775914, 0.481775914],\n [0.78125, 0.434243684, 0.434243684],\n [0.8125, 0.387970225, 0.387970225],\n [0.84375, 0.343229596, 0.343229596],\n [0.875, 0.300267182, 0.300267182],\n [0.90625, 0.259301199, 0.259301199],\n [0.9375, 0.220525627, 0.220525627],\n [0.96875, 0.184115123, 0.184115123],\n [1, 0.150232812, 0.150232812],\n ],\n },\n },\n blues: {\n name: 'Blues',\n numColors: 256,\n gamma: 1,\n segmentedData: {\n red: [\n [0, 0.9686274528503418, 0.9686274528503418],\n [0.125, 0.87058824300765991, 0.87058824300765991],\n [0.25, 0.7764706015586853, 0.7764706015586853],\n [0.375, 0.61960786581039429, 0.61960786581039429],\n [0.5, 0.41960784792900085, 0.41960784792900085],\n [0.625, 0.25882354378700256, 0.25882354378700256],\n [0.75, 0.12941177189350128, 0.12941177189350128],\n [0.875, 0.031372550874948502, 0.031372550874948502],\n [1, 0.031372550874948502, 0.031372550874948502],\n ],\n green: [\n [0, 0.9843137264251709, 0.9843137264251709],\n [0.125, 0.92156863212585449, 0.92156863212585449],\n [0.25, 0.85882353782653809, 0.85882353782653809],\n [0.375, 0.7921568751335144, 0.7921568751335144],\n [0.5, 0.68235296010971069, 0.68235296010971069],\n [0.625, 0.57254904508590698, 0.57254904508590698],\n [0.75, 0.44313725829124451, 0.44313725829124451],\n [0.875, 0.31764706969261169, 0.31764706969261169],\n [1, 0.18823529779911041, 0.18823529779911041],\n ],\n blue: [\n [0, 1, 1],\n [0.125, 0.9686274528503418, 0.9686274528503418],\n [0.25, 0.93725490570068359, 0.93725490570068359],\n [0.375, 0.88235294818878174, 0.88235294818878174],\n [0.5, 0.83921569585800171, 0.83921569585800171],\n [0.625, 0.7764706015586853, 0.7764706015586853],\n [0.75, 0.70980393886566162, 0.70980393886566162],\n [0.875, 0.61176472902297974, 0.61176472902297974],\n [1, 0.41960784792900085, 0.41960784792900085],\n ],\n },\n },\n};\n\nexport default colormapsData;\n","const RENDERING_DEFAULTS = {\n MINIMUM_SLAB_THICKNESS: 5e-2,\n MAXIMUM_RAY_DISTANCE: 1e6,\n};\n\nObject.freeze(RENDERING_DEFAULTS);\n\nexport default RENDERING_DEFAULTS;\n","const EPSILON = 1e-3;\n\nexport default EPSILON;\n","import deepFreeze from '../utilities/deepFreeze';\n\nconst MPR_CAMERA_VALUES = {\n axial: {\n viewPlaneNormal: [0, 0, -1],\n viewUp: [0, -1, 0],\n },\n sagittal: {\n viewPlaneNormal: [1, 0, 0],\n viewUp: [0, 0, 1],\n },\n coronal: {\n viewPlaneNormal: [0, -1, 0],\n viewUp: [0, 0, 1],\n },\n};\n\n// Note: Object.freeze is only shallow, so we need to deepFreeze\nconst mprCameraValues = deepFreeze(MPR_CAMERA_VALUES);\nexport default mprCameraValues;\n","// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#examples\nfunction deepFreeze(object) {\n // Retrieve the property names defined on object\n const propNames = Object.getOwnPropertyNames(object);\n\n // Freeze properties before freezing self\n\n for (const name of propNames) {\n const value = object[name];\n\n if (value && typeof value === 'object') {\n deepFreeze(value);\n }\n }\n\n return Object.freeze(object);\n}\n\nexport default deepFreeze;\n","import { ViewportPreset } from '../types';\n\nconst presets: ViewportPreset[] = [\n {\n name: 'CT-AAA',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity:\n '12 -3024 0 143.556 0 166.222 0.686275 214.389 0.696078 419.736 0.833333 3071 0.803922',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '24 -3024 0 0 0 143.556 0.615686 0.356863 0.184314 166.222 0.882353 0.603922 0.290196 214.389 1 1 1 419.736 1 0.937033 0.954531 3071 0.827451 0.658824 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-AAA2',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity:\n '16 -3024 0 129.542 0 145.244 0.166667 157.02 0.5 169.918 0.627451 395.575 0.8125 1578.73 0.8125 3071 0.8125',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '32 -3024 0 0 0 129.542 0.54902 0.25098 0.14902 145.244 0.6 0.627451 0.843137 157.02 0.890196 0.47451 0.6 169.918 0.992157 0.870588 0.392157 395.575 1 0.886275 0.658824 1578.73 1 0.829256 0.957922 3071 0.827451 0.658824 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-Bone',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity: '8 -3024 0 -16.4458 0 641.385 0.715686 3071 0.705882',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '16 -3024 0 0 0 -16.4458 0.729412 0.254902 0.301961 641.385 0.905882 0.815686 0.552941 3071 1 1 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-Bones',\n gradientOpacity: '4 0 1 985.12 1',\n specularPower: '1',\n scalarOpacity: '8 -1000 0 152.19 0 278.93 0.190476 952 0.2',\n specular: '0',\n shade: '1',\n ambient: '0.2',\n colorTransfer:\n '20 -1000 0.3 0.3 1 -488 0.3 1 0.3 463.28 1 0 0 659.15 1 0.912535 0.0374849 953 1 0.3 0.3',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-Cardiac',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity:\n '12 -3024 0 -77.6875 0 94.9518 0.285714 179.052 0.553571 260.439 0.848214 3071 0.875',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '24 -3024 0 0 0 -77.6875 0.54902 0.25098 0.14902 94.9518 0.882353 0.603922 0.290196 179.052 1 0.937033 0.954531 260.439 0.615686 0 0 3071 0.827451 0.658824 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-Cardiac2',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity:\n '12 -3024 0 42.8964 0 163.488 0.428571 277.642 0.776786 1587 0.754902 3071 0.754902',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '24 -3024 0 0 0 42.8964 0.54902 0.25098 0.14902 163.488 0.917647 0.639216 0.0588235 277.642 1 0.878431 0.623529 1587 1 1 1 3071 0.827451 0.658824 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-Cardiac3',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity:\n '14 -3024 0 -86.9767 0 45.3791 0.169643 139.919 0.589286 347.907 0.607143 1224.16 0.607143 3071 0.616071',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '28 -3024 0 0 0 -86.9767 0 0.25098 1 45.3791 1 0 0 139.919 1 0.894893 0.894893 347.907 1 1 0.25098 1224.16 1 1 1 3071 0.827451 0.658824 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-Chest-Contrast-Enhanced',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity:\n '10 -3024 0 67.0106 0 251.105 0.446429 439.291 0.625 3071 0.616071',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '20 -3024 0 0 0 67.0106 0.54902 0.25098 0.14902 251.105 0.882353 0.603922 0.290196 439.291 1 0.937033 0.954531 3071 0.827451 0.658824 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-Chest-Vessels',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity:\n '10 -3024 0 -1278.35 0 22.8277 0.428571 439.291 0.625 3071 0.616071',\n specular: '0',\n shade: '1',\n ambient: '0.2',\n colorTransfer:\n '20 -3024 0 0 0 -1278.35 0.54902 0.25098 0.14902 22.8277 0.882353 0.603922 0.290196 439.291 1 0.937033 0.954531 3071 0.827451 0.658824 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-Coronary-Arteries',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity:\n '12 -2048 0 136.47 0 159.215 0.258929 318.43 0.571429 478.693 0.776786 3661 1',\n specular: '0',\n shade: '0',\n ambient: '0.2',\n colorTransfer:\n '24 -2048 0 0 0 136.47 0 0 0 159.215 0.159804 0.159804 0.159804 318.43 0.764706 0.764706 0.764706 478.693 1 1 1 3661 1 1 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-Coronary-Arteries-2',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity:\n '14 -2048 0 142.677 0 145.016 0.116071 192.174 0.5625 217.24 0.776786 384.347 0.830357 3661 0.830357',\n specular: '0',\n shade: '1',\n ambient: '0.2',\n colorTransfer:\n '28 -2048 0 0 0 142.677 0 0 0 145.016 0.615686 0 0.0156863 192.174 0.909804 0.454902 0 217.24 0.972549 0.807843 0.611765 384.347 0.909804 0.909804 1 3661 1 1 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-Coronary-Arteries-3',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity:\n '14 -2048 0 128.643 0 129.982 0.0982143 173.636 0.669643 255.884 0.857143 584.878 0.866071 3661 1',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '28 -2048 0 0 0 128.643 0 0 0 129.982 0.615686 0 0.0156863 173.636 0.909804 0.454902 0 255.884 0.886275 0.886275 0.886275 584.878 0.968627 0.968627 0.968627 3661 1 1 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-Cropped-Volume-Bone',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity: '10 -2048 0 -451 0 -450 1 1050 1 3661 1',\n specular: '0',\n shade: '0',\n ambient: '0.2',\n colorTransfer:\n '20 -2048 0 0 0 -451 0 0 0 -450 0.0556356 0.0556356 0.0556356 1050 1 1 1 3661 1 1 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-Fat',\n gradientOpacity: '6 0 1 985.12 1 988 1',\n specularPower: '1',\n scalarOpacity: '14 -1000 0 -100 0 -99 0.15 -60 0.15 -59 0 101.2 0 952 0',\n specular: '0',\n shade: '0',\n ambient: '0.2',\n colorTransfer:\n '36 -1000 0.3 0.3 1 -497.5 0.3 1 0.3 -99 0 0 1 -76.946 0 1 0 -65.481 0.835431 0.888889 0.0165387 83.89 1 0 0 463.28 1 0 0 659.15 1 0.912535 0.0374849 2952 1 0.300267 0.299886',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-Liver-Vasculature',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity:\n '14 -2048 0 149.113 0 157.884 0.482143 339.96 0.660714 388.526 0.830357 1197.95 0.839286 3661 0.848214',\n specular: '0',\n shade: '0',\n ambient: '0.2',\n colorTransfer:\n '28 -2048 0 0 0 149.113 0 0 0 157.884 0.501961 0.25098 0 339.96 0.695386 0.59603 0.36886 388.526 0.854902 0.85098 0.827451 1197.95 1 1 1 3661 1 1 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-Lung',\n gradientOpacity: '6 0 1 985.12 1 988 1',\n specularPower: '1',\n scalarOpacity: '12 -1000 0 -600 0 -599 0.15 -400 0.15 -399 0 2952 0',\n specular: '0',\n shade: '1',\n ambient: '0.2',\n colorTransfer:\n '24 -1000 0.3 0.3 1 -600 0 0 1 -530 0.134704 0.781726 0.0724558 -460 0.929244 1 0.109473 -400 0.888889 0.254949 0.0240258 2952 1 0.3 0.3',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-MIP',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity: '8 -3024 0 -637.62 0 700 1 3071 1',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer: '16 -3024 0 0 0 -637.62 1 1 1 700 1 1 1 3071 1 1 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-Muscle',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity:\n '10 -3024 0 -155.407 0 217.641 0.676471 419.736 0.833333 3071 0.803922',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '20 -3024 0 0 0 -155.407 0.54902 0.25098 0.14902 217.641 0.882353 0.603922 0.290196 419.736 1 0.937033 0.954531 3071 0.827451 0.658824 1',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'CT-Pulmonary-Arteries',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity:\n '14 -2048 0 -568.625 0 -364.081 0.0714286 -244.813 0.401786 18.2775 0.607143 447.798 0.830357 3592.73 0.839286',\n specular: '0',\n shade: '1',\n ambient: '0.2',\n colorTransfer:\n '28 -2048 0 0 0 -568.625 0 0 0 -364.081 0.396078 0.301961 0.180392 -244.813 0.611765 0.352941 0.0705882 18.2775 0.843137 0.0156863 0.156863 447.798 0.752941 0.752941 0.752941 3592.73 1 1 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-Soft-Tissue',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity: '10 -2048 0 -167.01 0 -160 1 240 1 3661 1',\n specular: '0',\n shade: '0',\n ambient: '0.2',\n colorTransfer:\n '20 -2048 0 0 0 -167.01 0 0 0 -160 0.0556356 0.0556356 0.0556356 240 1 1 1 3661 1 1 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'CT-Air',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '10',\n scalarOpacity: '8 -3024 0.705882 -900.0 0.715686 -500.0 0 3071 0',\n specular: '0.2',\n shade: '1',\n ambient: '0.1',\n colorTransfer:\n '16 -3024 1 1 1 -900.0 0.2 1.0 1.0 -500.0 0.3 0.3 1.0 3071 0 0 0 ',\n diffuse: '0.9',\n interpolation: '1',\n },\n {\n name: 'MR-Angio',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity:\n '12 -2048 0 151.354 0 158.279 0.4375 190.112 0.580357 200.873 0.732143 3661 0.741071',\n specular: '0',\n shade: '1',\n ambient: '0.2',\n colorTransfer:\n '24 -2048 0 0 0 151.354 0 0 0 158.279 0.74902 0.376471 0 190.112 1 0.866667 0.733333 200.873 0.937255 0.937255 0.937255 3661 1 1 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'MR-Default',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity: '12 0 0 20 0 40 0.15 120 0.3 220 0.375 1024 0.5',\n specular: '0',\n shade: '1',\n ambient: '0.2',\n colorTransfer:\n '24 0 0 0 0 20 0.168627 0 0 40 0.403922 0.145098 0.0784314 120 0.780392 0.607843 0.380392 220 0.847059 0.835294 0.788235 1024 1 1 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'MR-MIP',\n gradientOpacity: '4 0 1 255 1',\n specularPower: '1',\n scalarOpacity: '8 0 0 98.3725 0 416.637 1 2800 1',\n specular: '0',\n shade: '0',\n ambient: '0.2',\n colorTransfer: '16 0 1 1 1 98.3725 1 1 1 416.637 1 1 1 2800 1 1 1',\n diffuse: '1',\n interpolation: '1',\n },\n {\n name: 'MR-T2-Brain',\n gradientOpacity: '4 0 1 160.25 1',\n specularPower: '40',\n scalarOpacity: '10 0 0 36.05 0 218.302 0.171429 412.406 1 641 1',\n specular: '0.5',\n shade: '1',\n ambient: '0.3',\n colorTransfer:\n '16 0 0 0 0 98.7223 0.956863 0.839216 0.192157 412.406 0 0.592157 0.807843 641 1 1 1',\n diffuse: '0.6',\n interpolation: '1',\n },\n {\n name: 'DTI-FA-Brain',\n gradientOpacity: '4 0 1 0.9950 1',\n specularPower: '40',\n scalarOpacity:\n '16 0 0 0 0 0.3501 0.0158 0.49379 0.7619 0.6419 1 0.9920 1 0.9950 0 0.9950 0',\n specular: '0.5',\n shade: '1',\n ambient: '0.3',\n colorTransfer:\n '28 0 1 0 0 0 1 0 0 0.24974 0.4941 1 0 0.49949 0 0.9882 1 0.7492 0.51764 0 1 0.9950 1 0 0 0.9950 1 0 0',\n diffuse: '0.9',\n interpolation: '1',\n },\n];\n\nexport default presets;\n","const backgroundColors = {\n slicer3D: [160 / 255, 164 / 255, 217 / 255],\n};\n\nexport default backgroundColors;\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 toPropertyKey from \"./toPropertyKey.js\";\nexport default function _defineProperty(obj, key, value) {\n key = toPropertyKey(key);\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 return obj;\n}","import _typeof from \"./typeof.js\";\nimport toPrimitive from \"./toPrimitive.js\";\nexport default function _toPropertyKey(arg) {\n var key = toPrimitive(arg, \"string\");\n return _typeof(key) === \"symbol\" ? key : String(key);\n}","import _typeof from \"./typeof.js\";\nexport default function _toPrimitive(input, hint) {\n if (_typeof(input) !== \"object\" || input === null) return input;\n var prim = input[Symbol.toPrimitive];\n if (prim !== undefined) {\n var res = prim.call(input, hint || \"default\");\n if (_typeof(res) !== \"object\") return res;\n throw new TypeError(\"@@toPrimitive must return a primitive value.\");\n }\n return (hint === \"string\" ? String : Number)(input);\n}","/**\n * Removes the data loader scheme from the imageId\n *\n * @param imageId - Image ID\n * @returns imageId without the data loader scheme\n */\nexport default function imageIdToURI(imageId: string): string {\n const colonIndex = imageId.indexOf(':');\n return imageId.substring(colonIndex + 1);\n}\n","/**\n * Calculate the minimum and maximum values in an Array\n *\n * @param storedPixelData - The pixel data to calculate the min and max values for\n * @returns an object with two properties: min and max\n */\nexport default function getMinMax(storedPixelData: number[]): {\n min: number;\n max: number;\n} {\n // we always calculate the min max values since they are not always\n // present in DICOM and we don't want to trust them anyway as cornerstone\n // depends on us providing reliable values for these\n let min = storedPixelData[0];\n\n let max = storedPixelData[0];\n\n let storedPixel;\n const numPixels = storedPixelData.length;\n\n for (let index = 1; index < numPixels; index++) {\n storedPixel = storedPixelData[index];\n min = Math.min(min, storedPixel);\n max = Math.max(max, storedPixel);\n }\n\n return {\n min,\n max,\n };\n}\n","// This module defines a way to access various metadata about an imageId. This layer of abstraction exists\n// So metadata can be provided in different ways (e.g. by parsing DICOM P10 or by a WADO-RS document)\n\nconst providers = [];\n\n/**\n * Adds a metadata provider with the specified priority\n * @param provider - Metadata provider function\n * @param priority - 0 is default/normal, > 0 is high, < 0 is low\n *\n * @category MetaData\n */\nexport function addProvider(\n provider: (type: string, ...query: string[]) => any,\n priority = 0\n): void {\n let i;\n\n // Find the right spot to insert this provider based on priority\n for (i = 0; i < providers.length; i++) {\n if (providers[i].priority <= priority) {\n break;\n }\n }\n\n // Insert the decode task at position i\n providers.splice(i, 0, {\n priority,\n provider,\n });\n}\n\n/**\n * Removes the specified provider\n *\n * @param provider - Metadata provider function\n *\n * @category MetaData\n */\nexport function removeProvider(\n provider: (type: string, query: any) => { any }\n): void {\n for (let i = 0; i < providers.length; i++) {\n if (providers[i].provider === provider) {\n providers.splice(i, 1);\n\n break;\n }\n }\n}\n\n/**\n * Removes all providers\n *\n * @category MetaData\n */\nexport function removeAllProviders(): void {\n while (providers.length > 0) {\n providers.pop();\n }\n}\n\n/**\n * Gets metadata from the registered metadata providers. Will call each one from highest priority to lowest\n * until one responds\n *\n * @param type - The type of metadata requested from the metadata store\n * @param query - The query for the metadata store, often imageId\n * Some metadata providers support multi-valued strings, which are interpretted\n * as the provider chooses.\n *\n * @returns The metadata retrieved from the metadata store\n * @category MetaData\n */\nfunction getMetaData(type: string, ...queries): any {\n // Invoke each provider in priority order until one returns something\n for (let i = 0; i < providers.length; i++) {\n const result = providers[i].provider(type, ...queries);\n\n if (result !== undefined) {\n return result;\n }\n }\n}\n\nexport { getMetaData as get };\n","import { addProvider } from '../metaData';\n\nlet state: Record<string, any> = {}; // Calibrated pixel spacing per imageId\n/**\n * Simple metadata provider that stores some sort of meta data for each imageId.\n */\nconst metadataProvider = {\n /**\n * Adds metadata for an imageId.\n * @param imageId - the imageId for the metadata to store\n * @param payload - the payload\n */\n add: (imageId: string, payload: any): void => {\n const type = payload.type;\n\n if (!state[imageId]) {\n state[imageId] = {};\n }\n\n // Create a deep copy of payload.metadata\n state[imageId][type] = JSON.parse(JSON.stringify(payload.metadata));\n },\n\n /**\n * Returns the metadata for an imageId if it exists.\n * @param type - the type of metadata to enquire about\n * @param imageId - the imageId to enquire about\n */\n get: (type: string, imageId: string): any => {\n return state[imageId]?.[type];\n },\n\n /**\n * Clears all metadata.\n */\n clear: (): void => {\n state = {};\n },\n};\n\naddProvider(metadataProvider.get);\n\nexport default metadataProvider;\n","import type { IRenderingEngine } from '../types';\n\nconst cache = {};\n\nconst renderingEngineCache = {\n /**\n * Returns the `RenderingEngine` instance with the given `id`.\n *\n * @param id - The `id` of the `RenderingEngine` instance to fetch.\n * @returns The `RenderingEngine` instance.\n */\n get: (id: string): IRenderingEngine => {\n return cache[id];\n },\n /**\n * Adds the `RenderingEngine` instance to the cache.\n *\n * @param re - The `RenderingEngine` to add.\n */\n set: (re: IRenderingEngine): void => {\n const renderingEngineId = re.id;\n\n cache[renderingEngineId] = re;\n },\n /**\n * Deletes the `RenderingEngine` instance from the cache.\n *\n * @param id - The `id` of the `RenderingEngine` instance to delete.\n * @returns True if the delete was successful.\n */\n delete: (id: string) => {\n return delete cache[id];\n },\n\n getAll: (): Array<IRenderingEngine> => {\n const renderingEngineIds = Object.keys(cache);\n const renderingEngines = renderingEngineIds.map((id) => cache[id]);\n\n // sort the rendering engines so that the ones that start with _\n // are at the end of the array. The reason is for not breaking\n // the code that used getRenderingEngines(), but since we moved\n // the renderToCanvas utility to use GPU hence it needs a\n // rendering engine and we don't want to use the default one.\n renderingEngines.sort((a, b) => {\n if (a.id[0] === '_' && b.id[0] !== '_') {\n return 1;\n } else if (a.id[0] !== '_' && b.id[0] === '_') {\n return -1;\n } else {\n return 0;\n }\n });\n\n return renderingEngines;\n },\n};\n\nexport default renderingEngineCache;\n","import renderingEngineCache from './renderingEngineCache';\nimport type { IRenderingEngine } from '../types';\n\n/**\n * Method to retrieve a RenderingEngine by its unique identifier.\n *\n * @example\n * How to get a RenderingEngine that was created earlier:\n * ```javascript\n * import { RenderingEngine, getRenderingEngine } from 'vtkjs-viewport';\n *\n * const renderingEngine = new RenderingEngine('my-engine');\n *\n * // getting reference to rendering engine later...\n * const renderingEngine = getRenderingEngine('my-engine');\n * ```\n *\n * @param id - The identifier that was used to create the RenderingEngine\n * @returns the matching RenderingEngine, or `undefined` if there is no match\n * @public\n */\nexport function getRenderingEngine(id: string): IRenderingEngine | undefined {\n return renderingEngineCache.get(id);\n}\n\n/**\n * Get all the rendering engines that are currently registered\n * @returns An array of rendering engines.\n */\nexport function getRenderingEngines(): IRenderingEngine[] | undefined {\n return renderingEngineCache.getAll();\n}\n\nexport default getRenderingEngine;\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 // IMPORTANT: WE SHOULD NOT PUSH NEW ELEMENTS TO THE ARRAY\n // INSTEAD WE SHOULD REPLACE THE ELEMENT, this will result\n // in unexpected behaviors if the initial tool parameters\n // are desired to override the default tool parameters that are\n // arrays\n destination[i] = 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","/**\n * @license\n * Copyright 2019 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\nconst proxyMarker = Symbol(\"Comlink.proxy\");\nconst createEndpoint = Symbol(\"Comlink.endpoint\");\nconst releaseProxy = Symbol(\"Comlink.releaseProxy\");\nconst finalizer = Symbol(\"Comlink.finalizer\");\nconst throwMarker = Symbol(\"Comlink.thrown\");\nconst isObject = (val) => (typeof val === \"object\" && val !== null) || typeof val === \"function\";\n/**\n * Internal transfer handle to handle objects marked to proxy.\n */\nconst proxyTransferHandler = {\n canHandle: (val) => isObject(val) && val[proxyMarker],\n serialize(obj) {\n const { port1, port2 } = new MessageChannel();\n expose(obj, port1);\n return [port2, [port2]];\n },\n deserialize(port) {\n port.start();\n return wrap(port);\n },\n};\n/**\n * Internal transfer handler to handle thrown exceptions.\n */\nconst throwTransferHandler = {\n canHandle: (value) => isObject(value) && throwMarker in value,\n serialize({ value }) {\n let serialized;\n if (value instanceof Error) {\n serialized = {\n isError: true,\n value: {\n message: value.message,\n name: value.name,\n stack: value.stack,\n },\n };\n }\n else {\n serialized = { isError: false, value };\n }\n return [serialized, []];\n },\n deserialize(serialized) {\n if (serialized.isError) {\n throw Object.assign(new Error(serialized.value.message), serialized.value);\n }\n throw serialized.value;\n },\n};\n/**\n * Allows customizing the serialization of certain values.\n */\nconst transferHandlers = new Map([\n [\"proxy\", proxyTransferHandler],\n [\"throw\", throwTransferHandler],\n]);\nfunction isAllowedOrigin(allowedOrigins, origin) {\n for (const allowedOrigin of allowedOrigins) {\n if (origin === allowedOrigin || allowedOrigin === \"*\") {\n return true;\n }\n if (allowedOrigin instanceof RegExp && allowedOrigin.test(origin)) {\n return true;\n }\n }\n return false;\n}\nfunction expose(obj, ep = globalThis, allowedOrigins = [\"*\"]) {\n ep.addEventListener(\"message\", function callback(ev) {\n if (!ev || !ev.data) {\n return;\n }\n if (!isAllowedOrigin(allowedOrigins, ev.origin)) {\n console.warn(`Invalid origin '${ev.origin}' for comlink proxy`);\n return;\n }\n const { id, type, path } = Object.assign({ path: [] }, ev.data);\n const argumentList = (ev.data.argumentList || []).map(fromWireValue);\n let returnValue;\n try {\n const parent = path.slice(0, -1).reduce((obj, prop) => obj[prop], obj);\n const rawValue = path.reduce((obj, prop) => obj[prop], obj);\n switch (type) {\n case \"GET\" /* MessageType.GET */:\n {\n returnValue = rawValue;\n }\n break;\n case \"SET\" /* MessageType.SET */:\n {\n parent[path.slice(-1)[0]] = fromWireValue(ev.data.value);\n returnValue = true;\n }\n break;\n case \"APPLY\" /* MessageType.APPLY */:\n {\n returnValue = rawValue.apply(parent, argumentList);\n }\n break;\n case \"CONSTRUCT\" /* MessageType.CONSTRUCT */:\n {\n const value = new rawValue(...argumentList);\n returnValue = proxy(value);\n }\n break;\n case \"ENDPOINT\" /* MessageType.ENDPOINT */:\n {\n const { port1, port2 } = new MessageChannel();\n expose(obj, port2);\n returnValue = transfer(port1, [port1]);\n }\n break;\n case \"RELEASE\" /* MessageType.RELEASE */:\n {\n returnValue = undefined;\n }\n break;\n default:\n return;\n }\n }\n catch (value) {\n returnValue = { value, [throwMarker]: 0 };\n }\n Promise.resolve(returnValue)\n .catch((value) => {\n return { value, [throwMarker]: 0 };\n })\n .then((returnValue) => {\n const [wireValue, transferables] = toWireValue(returnValue);\n ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);\n if (type === \"RELEASE\" /* MessageType.RELEASE */) {\n // detach and deactive after sending release response above.\n ep.removeEventListener(\"message\", callback);\n closeEndPoint(ep);\n if (finalizer in obj && typeof obj[finalizer] === \"function\") {\n obj[finalizer]();\n }\n }\n })\n .catch((error) => {\n // Send Serialization Error To Caller\n const [wireValue, transferables] = toWireValue({\n value: new TypeError(\"Unserializable return value\"),\n [throwMarker]: 0,\n });\n ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables);\n });\n });\n if (ep.start) {\n ep.start();\n }\n}\nfunction isMessagePort(endpoint) {\n return endpoint.constructor.name === \"MessagePort\";\n}\nfunction closeEndPoint(endpoint) {\n if (isMessagePort(endpoint))\n endpoint.close();\n}\nfunction wrap(ep, target) {\n return createProxy(ep, [], target);\n}\nfunction throwIfProxyReleased(isReleased) {\n if (isReleased) {\n throw new Error(\"Proxy has been released and is not useable\");\n }\n}\nfunction releaseEndpoint(ep) {\n return requestResponseMessage(ep, {\n type: \"RELEASE\" /* MessageType.RELEASE */,\n }).then(() => {\n closeEndPoint(ep);\n });\n}\nconst proxyCounter = new WeakMap();\nconst proxyFinalizers = \"FinalizationRegistry\" in globalThis &&\n new FinalizationRegistry((ep) => {\n const newCount = (proxyCounter.get(ep) || 0) - 1;\n proxyCounter.set(ep, newCount);\n if (newCount === 0) {\n releaseEndpoint(ep);\n }\n });\nfunction registerProxy(proxy, ep) {\n const newCount = (proxyCounter.get(ep) || 0) + 1;\n proxyCounter.set(ep, newCount);\n if (proxyFinalizers) {\n proxyFinalizers.register(proxy, ep, proxy);\n }\n}\nfunction unregisterProxy(proxy) {\n if (proxyFinalizers) {\n proxyFinalizers.unregister(proxy);\n }\n}\nfunction createProxy(ep, path = [], target = function () { }) {\n let isProxyReleased = false;\n const proxy = new Proxy(target, {\n get(_target, prop) {\n throwIfProxyReleased(isProxyReleased);\n if (prop === releaseProxy) {\n return () => {\n unregisterProxy(proxy);\n releaseEndpoint(ep);\n isProxyReleased = true;\n };\n }\n if (prop === \"then\") {\n if (path.length === 0) {\n return { then: () => proxy };\n }\n const r = requestResponseMessage(ep, {\n type: \"GET\" /* MessageType.GET */,\n path: path.map((p) => p.toString()),\n }).then(fromWireValue);\n return r.then.bind(r);\n }\n return createProxy(ep, [...path, prop]);\n },\n set(_target, prop, rawValue) {\n throwIfProxyReleased(isProxyReleased);\n // FIXME: ES6 Proxy Handler `set` methods are supposed to return a\n // boolean. To show good will, we return true asynchronously ¯\\_(ツ)_/¯\n const [value, transferables] = toWireValue(rawValue);\n return requestResponseMessage(ep, {\n type: \"SET\" /* MessageType.SET */,\n path: [...path, prop].map((p) => p.toString()),\n value,\n }, transferables).then(fromWireValue);\n },\n apply(_target, _thisArg, rawArgumentList) {\n throwIfProxyReleased(isProxyReleased);\n const last = path[path.length - 1];\n if (last === createEndpoint) {\n return requestResponseMessage(ep, {\n type: \"ENDPOINT\" /* MessageType.ENDPOINT */,\n }).then(fromWireValue);\n }\n // We just pretend that `bind()` didn’t happen.\n if (last === \"bind\") {\n return createProxy(ep, path.slice(0, -1));\n }\n const [argumentList, transferables] = processArguments(rawArgumentList);\n return requestResponseMessage(ep, {\n type: \"APPLY\" /* MessageType.APPLY */,\n path: path.map((p) => p.toString()),\n argumentList,\n }, transferables).then(fromWireValue);\n },\n construct(_target, rawArgumentList) {\n throwIfProxyReleased(isProxyReleased);\n const [argumentList, transferables] = processArguments(rawArgumentList);\n return requestResponseMessage(ep, {\n type: \"CONSTRUCT\" /* MessageType.CONSTRUCT */,\n path: path.map((p) => p.toString()),\n argumentList,\n }, transferables).then(fromWireValue);\n },\n });\n registerProxy(proxy, ep);\n return proxy;\n}\nfunction myFlat(arr) {\n return Array.prototype.concat.apply([], arr);\n}\nfunction processArguments(argumentList) {\n const processed = argumentList.map(toWireValue);\n return [processed.map((v) => v[0]), myFlat(processed.map((v) => v[1]))];\n}\nconst transferCache = new WeakMap();\nfunction transfer(obj, transfers) {\n transferCache.set(obj, transfers);\n return obj;\n}\nfunction proxy(obj) {\n return Object.assign(obj, { [proxyMarker]: true });\n}\nfunction windowEndpoint(w, context = globalThis, targetOrigin = \"*\") {\n return {\n postMessage: (msg, transferables) => w.postMessage(msg, targetOrigin, transferables),\n addEventListener: context.addEventListener.bind(context),\n removeEventListener: context.removeEventListener.bind(context),\n };\n}\nfunction toWireValue(value) {\n for (const [name, handler] of transferHandlers) {\n if (handler.canHandle(value)) {\n const [serializedValue, transferables] = handler.serialize(value);\n return [\n {\n type: \"HANDLER\" /* WireValueType.HANDLER */,\n name,\n value: serializedValue,\n },\n transferables,\n ];\n }\n }\n return [\n {\n type: \"RAW\" /* WireValueType.RAW */,\n value,\n },\n transferCache.get(value) || [],\n ];\n}\nfunction fromWireValue(value) {\n switch (value.type) {\n case \"HANDLER\" /* WireValueType.HANDLER */:\n return transferHandlers.get(value.name).deserialize(value.value);\n case \"RAW\" /* WireValueType.RAW */:\n return value.value;\n }\n}\nfunction requestResponseMessage(ep, msg, transfers) {\n return new Promise((resolve) => {\n const id = generateUUID();\n ep.addEventListener(\"message\", function l(ev) {\n if (!ev.data || !ev.data.id || ev.data.id !== id) {\n return;\n }\n ep.removeEventListener(\"message\", l);\n resolve(ev.data);\n });\n if (ep.start) {\n ep.start();\n }\n ep.postMessage(Object.assign({ id }, msg), transfers);\n });\n}\nfunction generateUUID() {\n return new Array(4)\n .fill(0)\n .map(() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16))\n .join(\"-\");\n}\n\nexport { createEndpoint, expose, finalizer, proxy, proxyMarker, releaseProxy, transfer, transferHandlers, windowEndpoint, wrap };\n//# sourceMappingURL=comlink.mjs.map\n","// prettier-ignore\n// @ts-nocheck\n/**\n * Generates a unique id that has limited chance of collision\n *\n * @see {@link https://stackoverflow.com/a/2117523/1867984|StackOverflow: Source}\n * @returns a v4 compliant GUID\n */\nexport default function uuidv4(): string {\n return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>\n (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)\n );\n}\n","import RequestType from '../enums/RequestType';\nimport { IImage } from '../types';\nimport { uuidv4 } from '../utilities';\n\ntype AdditionalDetails = {\n imageId?: string;\n volumeId?: string;\n};\n\ntype RequestDetailsInterface = {\n requestFn: () => Promise<IImage | void>;\n type: RequestType;\n additionalDetails: AdditionalDetails;\n};\n\ntype RequestPool = {\n [name in RequestType]: { [key: number]: RequestDetailsInterface[] };\n};\n\n/**\n * RequestPool manager class is a base class that manages the request pools.\n * It is used imageRetrievalPoolManager, and imageLoadPoolManager to retrieve and load images.\n * Previously requestPoolManager was used to manage the retrieval and loading and decoding\n * of the images in a way that new requests were sent after the image was both loaded and decoded\n * which was not performant since it was waiting for the image to be loaded and decoded before\n * sending the next request which is a network request and can be done in parallel.\n * Now, we use separate imageRetrievalPoolManager and imageLoadPoolManager\n * to improve performance and both are extending the RequestPoolManager class which\n * is a basic queueing pool.\n *\n * A new requestPool can be created by instantiating a new RequestPoolManager class.\n *\n * ```javascript\n * const requestPoolManager = new RequestPoolManager()\n * ```\n *\n * ## ImageLoadPoolManager\n *\n * You can use the imageLoadPoolManager to load images, by providing a `requestFn`\n * that returns a promise for the image. You can provide a `type` to specify the type of\n * request (interaction, thumbnail, prefetch), and you can provide additional details\n * that will be passed to the requestFn. Below is an example of a requestFn that loads\n * an image from an imageId:\n *\n * ```javascript\n *\n * const priority = -5\n * const requestType = RequestType.Interaction\n * const additionalDetails = { imageId }\n * const options = {\n * targetBuffer: {\n * type: 'Float32Array',\n * offset: null,\n * length: null,\n * },\n * preScale: {\n * enabled: true,\n * },\n * }\n *\n * imageLoadPoolManager.addRequest(\n * loadAndCacheImage(imageId, options).then(() => { // set on viewport}),\n * requestType,\n * additionalDetails,\n * priority\n * )\n * ```\n * ### ImageRetrievalPoolManager\n * You don't need to directly use the imageRetrievalPoolManager to load images\n * since the imageLoadPoolManager will automatically use it for retrieval. However,\n * maximum number of concurrent requests can be set by calling `setMaxConcurrentRequests`.\n */\nclass RequestPoolManager {\n private id: string;\n private awake: boolean;\n private requestPool: RequestPool;\n private numRequests = {\n interaction: 0,\n thumbnail: 0,\n prefetch: 0,\n compute: 0,\n };\n /* maximum number of requests of each type. */\n public maxNumRequests: {\n interaction: number;\n thumbnail: number;\n prefetch: number;\n compute: number;\n };\n /* A public property that is used to set the delay between requests. */\n public grabDelay: number;\n private timeoutHandle: number;\n\n /**\n * By default a request pool containing three priority groups, one for each\n * of the request types, is created. Maximum number of requests of each type\n * is set to 6.\n */\n constructor(id?: string) {\n this.id = id ? id : uuidv4();\n\n this.requestPool = {\n interaction: { 0: [] },\n thumbnail: { 0: [] },\n prefetch: { 0: [] },\n compute: { 0: [] },\n };\n\n this.grabDelay = 5;\n this.awake = false;\n\n this.numRequests = {\n interaction: 0,\n thumbnail: 0,\n prefetch: 0,\n compute: 0,\n };\n\n this.maxNumRequests = {\n interaction: 6,\n thumbnail: 6,\n prefetch: 5,\n // I believe there is a bug right now, where if there are two workers\n // and one wants to run a compute job 6 times and the limit is just 5, then\n // the other worker will never get a chance to run its compute job.\n // we should probably have a separate limit for compute jobs per worker\n // context as there is another layer of parallelism there. For this reason\n // I'm setting the limit to 1000 for now.\n compute: 1000,\n };\n }\n\n /**\n * This function sets the maximum number of requests for a given request type.\n * @param type - The type of request you want to set the max number\n * of requests for it can be either of interaction, prefetch, or thumbnail.\n * @param maxNumRequests - The maximum number of requests that can be\n * made at a time.\n */\n public setMaxSimultaneousRequests(\n type: RequestType,\n maxNumRequests: number\n ): void {\n this.maxNumRequests[type] = maxNumRequests;\n }\n\n /**\n * It returns the maximum number of requests of a given type that can be made\n * @param type - The type of request.\n * @returns The maximum number of requests of a given type.\n */\n public getMaxSimultaneousRequests(type: RequestType): number {\n return this.maxNumRequests[type];\n }\n\n /**\n * Stops further fetching of the requests, all the ongoing requests will still\n * be retrieved\n */\n public destroy(): void {\n if (this.timeoutHandle) {\n window.clearTimeout(this.timeoutHandle);\n }\n }\n\n /**\n * Adds the requests to the pool of requests.\n *\n * @param requestFn - A function that returns a promise which resolves in the image\n * @param type - Priority category, it can be either of interaction, prefetch,\n * or thumbnail.\n * @param additionalDetails - Additional details that requests can contain.\n * For instance the volumeId for the volume requests\n * @param priority - Priority number for each category of requests. Its default\n * value is priority 0. The lower the priority number, the higher the priority number\n *\n */\n public addRequest(\n requestFn: () => Promise<IImage | void>,\n type: RequestType,\n additionalDetails: Record<string, unknown>,\n priority = 0\n ): void {\n // Describe the request\n const requestDetails: RequestDetailsInterface = {\n requestFn,\n type,\n additionalDetails,\n };\n\n // Check if the priority group exists on the request type\n if (this.requestPool[type][priority] === undefined) {\n this.requestPool[type][priority] = [];\n }\n\n // Adding the request to the correct priority group of the request type\n this.requestPool[type][priority].push(requestDetails);\n\n this.startGrabbing();\n }\n\n /**\n * Filter the requestPoolManager's pool of request based on the result of\n * provided filter function. The provided filter function needs to return false or true\n *\n * @param filterFunction - The filter function for filtering of the requests to keep\n */\n public filterRequests(\n filterFunction: (requestDetails: RequestDetailsInterface) => boolean\n ): void {\n Object.keys(this.requestPool).forEach((type: string) => {\n const requestType = this.requestPool[type];\n Object.keys(requestType).forEach((priority) => {\n requestType[priority] = requestType[priority].filter(\n (requestDetails: RequestDetailsInterface) => {\n return filterFunction(requestDetails);\n }\n );\n });\n });\n }\n\n /**\n * Clears the requests specific to the provided type. For instance, the\n * pool of requests of type 'interaction' can be cleared via this function.\n *\n *\n * @param type - category of the request (either interaction, prefetch or thumbnail)\n */\n public clearRequestStack(type: string): void {\n if (!this.requestPool[type]) {\n throw new Error(`No category for the type ${type} found`);\n }\n this.requestPool[type] = { 0: [] };\n }\n\n private sendRequests(type) {\n const requestsToSend = this.maxNumRequests[type] - this.numRequests[type];\n let syncImageCount = 0;\n\n for (let i = 0; i < requestsToSend; i++) {\n const requestDetails = this.getNextRequest(type);\n if (requestDetails === null) {\n return false;\n } else if (requestDetails) {\n this.numRequests[type]++;\n this.awake = true;\n\n let requestResult;\n try {\n requestResult = requestDetails.requestFn();\n } catch (e) {\n // This is the only warning one will get, so need a warn message\n console.warn('sendRequest failed', e);\n }\n if (requestResult?.finally) {\n requestResult.finally(() => {\n this.numRequests[type]--;\n this.startAgain();\n });\n } else {\n // Handle non-async request functions too - typically just short circuit ones\n this.numRequests[type]--;\n syncImageCount++;\n }\n }\n }\n if (syncImageCount) {\n this.startAgain();\n }\n\n return true;\n }\n\n private getNextRequest(type): RequestDetailsInterface | null {\n const interactionPriorities = this.getSortedPriorityGroups(type);\n for (const priority of interactionPriorities) {\n if (this.requestPool[type][priority].length) {\n return this.requestPool[type][priority].shift();\n }\n }\n\n return null;\n }\n\n protected startGrabbing(): void {\n const hasRemainingInteractionRequests = this.sendRequests(\n RequestType.Interaction\n );\n const hasRemainingThumbnailRequests = this.sendRequests(\n RequestType.Thumbnail\n );\n const hasRemainingPrefetchRequests = this.sendRequests(\n RequestType.Prefetch\n );\n const hasRemainingComputeRequests = this.sendRequests(RequestType.Compute);\n\n if (\n !hasRemainingInteractionRequests &&\n !hasRemainingThumbnailRequests &&\n !hasRemainingPrefetchRequests &&\n !hasRemainingComputeRequests\n ) {\n this.awake = false;\n }\n }\n\n protected startAgain(): void {\n if (!this.awake) {\n return;\n }\n\n if (this.grabDelay !== undefined) {\n // Prevents calling setTimeout hundreds of times when hundreds of requests\n // are added which make it slower and works in an unexpected way when\n // destroy/clearTimeout is called because only the last handle is stored.\n if (!this.timeoutHandle) {\n this.timeoutHandle = window.setTimeout(() => {\n this.timeoutHandle = null;\n this.startGrabbing();\n }, this.grabDelay);\n }\n } else {\n this.startGrabbing();\n }\n }\n\n protected getSortedPriorityGroups(type: string): Array<number> {\n const priorities = Object.keys(this.requestPool[type])\n .map(Number)\n .filter((priority) => this.requestPool[type][priority].length)\n .sort((a, b) => a - b);\n return priorities;\n }\n\n /**\n * Returns the request pool containing different categories, their priority and\n * the added request details.\n *\n * @returns the request pool which contains different categories, their priority and\n * the added request details\n */\n getRequestPool(): RequestPool {\n return this.requestPool;\n }\n}\n\nexport { RequestPoolManager };\n","import * as Comlink from 'comlink';\nimport { RequestType } from '../enums/';\nimport { RequestPoolManager } from '../requestPool/requestPoolManager';\n\nclass CentralizedWorkerManager {\n constructor() {\n this.workerRegistry = {};\n this.workerPoolManager = new RequestPoolManager('webworker');\n }\n\n /**\n * Registers a new worker, it doesn't mean that the function will get executed.\n *\n * @param workerName - The name of the worker.\n * @param workerFn - The function that creates a new instance of the worker.\n * @param options - Optional parameters.\n * @param options.maxWorkerInstances - The maximum number of instances of this worker that can be created.\n * For instance if you create a worker with maxWorkerInstances = 2, then only 2 instances of this worker will be created\n * and in case there are 10 tasks that need to be executed, each will get assigned 5 tasks.\n * @param options.overwrite - Whether to overwrite the worker if it's already registered.\n * @param options.autoTerminateOnIdle - Whether to automatically terminate idle workers.\n */\n registerWorker(workerName, workerFn, options = {}) {\n const {\n maxWorkerInstances = 1,\n overwrite = false,\n autoTerminateOnIdle = {\n enabled: false,\n idleTimeThreshold: 3000, // 3 seconds\n },\n } = options;\n\n if (this.workerRegistry[workerName] && !overwrite) {\n console.warn(`Worker type '${workerName}' is already registered...`);\n return;\n }\n\n if (overwrite && this.workerRegistry[workerName]?.idleCheckIntervalId) {\n clearInterval(this.workerRegistry[workerName].idleCheckIntervalId);\n }\n\n const workerProperties = {\n workerFn: null,\n instances: [],\n loadCounters: [],\n lastActiveTime: [],\n // used for termination\n nativeWorkers: [],\n // auto termination\n autoTerminateOnIdle: autoTerminateOnIdle.enabled,\n idleCheckIntervalId: null,\n idleTimeThreshold: autoTerminateOnIdle.idleTimeThreshold,\n };\n\n workerProperties.loadCounters = Array(maxWorkerInstances).fill(0);\n workerProperties.lastActiveTime = Array(maxWorkerInstances).fill(null);\n\n for (let i = 0; i < maxWorkerInstances; i++) {\n const worker = workerFn();\n workerProperties.instances.push(Comlink.wrap(worker));\n workerProperties.nativeWorkers.push(worker);\n workerProperties.workerFn = workerFn;\n }\n\n this.workerRegistry[workerName] = workerProperties;\n }\n\n getNextWorkerAPI(workerName) {\n const workerProperties = this.workerRegistry[workerName];\n\n if (!workerProperties) {\n console.error(`Worker type '${workerName}' is not registered.`);\n return null;\n }\n\n // Find the worker with the minimum load.\n const workerInstances = workerProperties.instances.filter(\n (instance) => instance !== null\n );\n\n let minLoadIndex = 0;\n let minLoadValue = workerProperties.loadCounters[0] || 0;\n for (let i = 1; i < workerInstances.length; i++) {\n const currentLoadValue = workerProperties.loadCounters[i] || 0;\n if (currentLoadValue < minLoadValue) {\n minLoadIndex = i;\n minLoadValue = currentLoadValue;\n }\n }\n\n // Check and recreate the worker if it was terminated.\n if (workerProperties.instances[minLoadIndex] === null) {\n const worker = workerProperties.workerFn();\n workerProperties.instances[minLoadIndex] = Comlink.wrap(worker);\n workerProperties.nativeWorkers[minLoadIndex] = worker;\n }\n\n // Update the load counter.\n workerProperties.loadCounters[minLoadIndex] += 1;\n\n // return the worker that has the minimum load.\n return {\n api: workerProperties.instances[minLoadIndex],\n index: minLoadIndex,\n };\n }\n\n /**\n * Executes a task on a worker.\n *\n * @param workerName - The name of the worker to execute the task on.\n * @param methodName - The name of the method to execute on the worker.\n * @param args - The arguments to pass to the method. Default is an array\n * You should put your transferable objects in the first argument as object\n * and from the second argument you can put your non-transferable objects such\n * as functions, classes, etc.\n * @param options - An object containing options for the request. Default is an empty object.\n * @param options.requestType - The type of the request. Default is RequestType.Compute.\n * @param options.priority - The priority of the request. Default is 0.\n * @param options.options - Additional options for the request. Default is an empty object.\n *\n * @returns A promise that resolves with the result of the task.\n */\n executeTask(\n workerName,\n methodName,\n args = {},\n {\n requestType = RequestType.Compute,\n priority = 0,\n options = {},\n callbacks = [],\n } = {}\n ) {\n return new Promise((resolve, reject) => {\n const requestFn = async () => {\n const { api, index } = this.getNextWorkerAPI(workerName);\n if (!api) {\n const error = new Error(\n `No available worker instance for '${workerName}'`\n );\n console.error(error);\n reject(error);\n return;\n }\n\n try {\n // fix if any of the args keys are a function then we need to proxy it\n // for the worker to be able to call it\n let finalCallbacks = [];\n if (callbacks.length) {\n finalCallbacks = callbacks.map((cb) => {\n return Comlink.proxy(cb);\n });\n }\n const workerProperties = this.workerRegistry[workerName];\n\n workerProperties.processing = true;\n\n const results = await api[methodName](args, ...finalCallbacks);\n\n workerProperties.processing = false;\n workerProperties.lastActiveTime[index] = Date.now();\n\n // If auto termination is enabled and the interval is not set, set it.\n if (\n workerProperties.autoTerminateOnIdle &&\n !workerProperties.idleCheckIntervalId &&\n workerProperties.idleTimeThreshold\n ) {\n workerProperties.idleCheckIntervalId = setInterval(() => {\n this.terminateIdleWorkers(\n workerName,\n workerProperties.idleTimeThreshold\n );\n }, workerProperties.idleTimeThreshold);\n }\n\n resolve(results);\n } catch (err) {\n console.error(\n `Error executing method '${methodName}' on worker '${workerName}':`,\n err\n );\n reject(err);\n } finally {\n this.workerRegistry[workerName].loadCounters[index]--;\n }\n };\n\n // I believe there is a bug right now, where if there are two workers\n // and one wants to run a compute job 6 times and the limit is just 5, then\n // the other worker will never get a chance to run its compute job.\n // we should probably have a separate limit for compute jobs per worker\n // context as there is another layer of parallelism there.\n this.workerPoolManager.addRequest(\n requestFn,\n requestType,\n options,\n priority\n );\n });\n }\n\n terminateIdleWorkers(workerName, idleTimeThreshold) {\n const workerProperties = this.workerRegistry[workerName];\n\n if (workerProperties.processing) {\n return;\n }\n\n const now = Date.now();\n\n workerProperties.instances.forEach((_, index) => {\n const lastActiveTime = workerProperties.lastActiveTime[index];\n const isWorkerActive =\n lastActiveTime !== null && workerProperties.loadCounters[index] > 0;\n const idleTime = now - lastActiveTime;\n\n if (!isWorkerActive && idleTime > idleTimeThreshold) {\n this.terminateWorkerInstance(workerName, index);\n }\n });\n }\n\n terminate(workerName) {\n const workerProperties = this.workerRegistry[workerName];\n if (!workerProperties) {\n console.error(`Worker type '${workerName}' is not registered.`);\n return;\n }\n\n workerProperties.instances.forEach((_, index) => {\n this.terminateWorkerInstance(workerName, index);\n });\n }\n\n // New method to handle individual worker termination\n terminateWorkerInstance(workerName, index) {\n const workerProperties = this.workerRegistry[workerName];\n const workerInstance = workerProperties.instances[index];\n\n if (workerInstance !== null) {\n workerInstance[Comlink.releaseProxy]();\n workerProperties.nativeWorkers[index].terminate();\n\n // Set the worker instance to null after termination\n workerProperties.instances[index] = null;\n workerProperties.lastActiveTime[index] = null;\n }\n }\n}\n\nexport default CentralizedWorkerManager;\n","import { getGPUTier } from 'detect-gpu';\nimport { SharedArrayBufferModes } from './enums';\nimport { getRenderingEngines } from './RenderingEngine/getRenderingEngine';\nlet csRenderInitialized = false;\nlet useSharedArrayBuffer = true;\nlet sharedArrayBufferMode = SharedArrayBufferModes.TRUE;\nimport { deepMerge } from './utilities';\nimport { Cornerstone3DConfig } from './types';\nimport CentralizedWebWorkerManager from './webWorkerManager/webWorkerManager';\n\n// TODO: move sharedArrayBuffer into config.\n// TODO: change config into a class with methods to better control get/set\nconst defaultConfig: Cornerstone3DConfig = {\n gpuTier: undefined,\n detectGPUConfig: {},\n isMobile: false, // is mobile device\n rendering: {\n useCPURendering: false,\n // GPU rendering options\n preferSizeOverAccuracy: false,\n useNorm16Texture: false,\n strictZSpacingForVolumeViewport: true,\n },\n // cache\n enableCacheOptimization: true,\n};\n\nlet config: Cornerstone3DConfig = {\n gpuTier: undefined,\n detectGPUConfig: {},\n isMobile: false, // is mobile device\n rendering: {\n useCPURendering: false,\n // GPU rendering options\n preferSizeOverAccuracy: false,\n useNorm16Texture: false,\n strictZSpacingForVolumeViewport: true,\n },\n // cache\n enableCacheOptimization: true,\n};\n\nlet webWorkerManager = null;\n\nfunction _getGLContext(): RenderingContext {\n // Create canvas element. The canvas is not added to the\n // document itself, so it is never displayed in the\n // browser window.\n const canvas = document.createElement('canvas');\n // Get WebGLRenderingContext from canvas element.\n const gl =\n canvas.getContext('webgl2') ||\n canvas.getContext('webgl') ||\n canvas.getContext('experimental-webgl');\n\n return gl;\n}\n\n// https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/By_example/Detect_WebGL\nfunction _hasActiveWebGLContext() {\n const gl = _getGLContext();\n\n // Check if the context is either WebGLRenderingContext or WebGL2RenderingContext\n return (\n gl instanceof WebGLRenderingContext || gl instanceof WebGL2RenderingContext\n );\n}\n\nfunction hasSharedArrayBuffer() {\n try {\n /*eslint-disable no-constant-condition */\n if (new SharedArrayBuffer(0)) {\n return true;\n } else {\n return false;\n }\n } catch {\n return false;\n }\n}\n\nfunction _hasNorm16TextureSupport() {\n const gl = _getGLContext();\n\n if (gl) {\n const ext = (gl as WebGL2RenderingContext).getExtension(\n 'EXT_texture_norm16'\n );\n\n if (ext) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction isIOS() {\n if (/iPad|iPhone|iPod/.test(navigator.platform)) {\n return true;\n } else {\n return (\n navigator.maxTouchPoints &&\n navigator.maxTouchPoints > 2 &&\n /MacIntel/.test(navigator.platform)\n );\n }\n}\n\n/**\n * Initialize the cornerstone-core. If the browser has a webgl context and\n * the detected gpu (by detect-gpu library) indicates the GPU is not low end we\n * will use webgl GPU rendering. Otherwise we will use cpu rendering.\n *\n * @param configuration - A configuration object\n * @returns A promise that resolves to true cornerstone has been initialized successfully.\n * @category Initialization\n */\nasync function init(configuration = config): Promise<boolean> {\n if (csRenderInitialized) {\n return csRenderInitialized;\n }\n\n // merge configs\n config = deepMerge(defaultConfig, configuration);\n\n if (isIOS()) {\n // iOS devices don't have support for OES_texture_float_linear\n // and thus we should use native data type if we are on iOS\n config.rendering.useNorm16Texture = _hasNorm16TextureSupport();\n\n if (!config.rendering.useNorm16Texture) {\n if (configuration.rendering?.preferSizeOverAccuracy) {\n config.rendering.preferSizeOverAccuracy = true;\n } else {\n console.log(\n 'norm16 texture not supported, you can turn on the preferSizeOverAccuracy flag to use native data type, but be aware of the inaccuracy of the rendering in high bits'\n );\n }\n }\n }\n\n // gpuTier\n const hasWebGLContext = _hasActiveWebGLContext();\n if (!hasWebGLContext) {\n console.log('CornerstoneRender: GPU not detected, using CPU rendering');\n config.rendering.useCPURendering = true;\n } else {\n config.gpuTier =\n config.gpuTier || (await getGPUTier(config.detectGPUConfig));\n console.log(\n 'CornerstoneRender: Using detect-gpu to get the GPU benchmark:',\n config.gpuTier\n );\n if (config.gpuTier?.tier < 1) {\n console.log(\n 'CornerstoneRender: GPU is not powerful enough, using CPU rendering'\n );\n config.rendering.useCPURendering = true;\n } else {\n console.log('CornerstoneRender: using GPU rendering');\n }\n }\n\n setUseSharedArrayBuffer(sharedArrayBufferMode);\n\n csRenderInitialized = true;\n\n if (!webWorkerManager) {\n webWorkerManager = new CentralizedWebWorkerManager();\n }\n\n return csRenderInitialized;\n}\n\n/**\n * It sets the useCPURenderingOnlyForDebugOrTests variable to the status value.\n * This only should be used for debugging or tests. DO NOT USE IT IF YOU ARE NOT\n * SURE WHAT YOU ARE DOING.\n * @param status - boolean\n * @category Initialization\n *\n */\nfunction setUseCPURendering(status: boolean): void {\n config.rendering.useCPURendering = status;\n csRenderInitialized = true;\n _updateRenderingPipelinesForAllViewports();\n}\n\nfunction setPreferSizeOverAccuracy(status: boolean): void {\n config.rendering.preferSizeOverAccuracy = status;\n csRenderInitialized = true;\n _updateRenderingPipelinesForAllViewports();\n}\n\n/**\n * Only IPhone IOS cannot render float textures right now due to the lack of support for OES_texture_float_linear.\n * So we should not use float textures on IOS devices.\n */\nfunction canRenderFloatTextures(): boolean {\n if (!isIOS()) {\n return true;\n }\n\n return false;\n}\n\n/**\n * Resets the cornerstone-core init state if it has been manually\n * initialized to force use the cpu rendering (e.g., for tests)\n * @category Initialization\n *\n */\nfunction resetUseCPURendering(): void {\n config.rendering.useCPURendering = !_hasActiveWebGLContext();\n _updateRenderingPipelinesForAllViewports();\n}\n\n/**\n * Returns whether or not we are using CPU rendering.\n * @returns true if we are using CPU rendering.\n * @category Initialization\n *\n */\nfunction getShouldUseCPURendering(): boolean {\n return config.rendering.useCPURendering;\n}\n\nfunction setUseSharedArrayBuffer(mode: SharedArrayBufferModes | boolean): void {\n if (mode == SharedArrayBufferModes.AUTO) {\n sharedArrayBufferMode = SharedArrayBufferModes.AUTO;\n const hasSharedBuffer = hasSharedArrayBuffer();\n if (!hasSharedBuffer) {\n useSharedArrayBuffer = false;\n console.warn(\n `CornerstoneRender: SharedArray Buffer not allowed, performance may be slower.\n Try ensuring page is cross-origin isolated to enable SharedArrayBuffer.`\n );\n } else {\n useSharedArrayBuffer = true;\n // eslint-disable-next-line no-console\n console.log('CornerstoneRender: using SharedArrayBuffer');\n }\n return;\n }\n\n if (mode == SharedArrayBufferModes.TRUE || mode == true) {\n sharedArrayBufferMode = SharedArrayBufferModes.TRUE;\n useSharedArrayBuffer = true;\n return;\n }\n\n if (mode == SharedArrayBufferModes.FALSE || mode == false) {\n sharedArrayBufferMode = SharedArrayBufferModes.FALSE;\n useSharedArrayBuffer = false;\n return;\n }\n}\n\nfunction resetUseSharedArrayBuffer(): void {\n setUseSharedArrayBuffer(sharedArrayBufferMode);\n}\n\nfunction getShouldUseSharedArrayBuffer(): boolean {\n return useSharedArrayBuffer;\n}\n\n/**\n *\n * Returns whether or not cornerstone-core has been initialized.\n * @returns true if the cornerstone render has been initialized.\n * @category Initialization\n *\n */\nfunction isCornerstoneInitialized(): boolean {\n return csRenderInitialized;\n}\n\n/**\n * This function returns a copy of the config object. This is used to prevent the\n * config object from being modified by other parts of the program.\n * @returns A copy of the config object.\n */\nfunction getConfiguration(): Cornerstone3DConfig {\n // return a copy\n // return JSON.parse(JSON.stringify(config));\n return config;\n}\n\nfunction setConfiguration(c: Cornerstone3DConfig) {\n config = c;\n _updateRenderingPipelinesForAllViewports();\n}\n\n/**\n * Update rendering pipelines for all viewports in all rendering engines.\n * @returns {void}\n * @category Initialization\n */\nfunction _updateRenderingPipelinesForAllViewports(): void {\n getRenderingEngines().forEach((engine) =>\n engine\n .getViewports()\n .forEach((viewport) => viewport.updateRenderingPipeline?.())\n );\n}\n\nfunction getWebWorkerManager() {\n if (!webWorkerManager) {\n webWorkerManager = new CentralizedWebWorkerManager();\n }\n\n return webWorkerManager;\n}\n\nexport {\n init,\n getShouldUseCPURendering,\n getShouldUseSharedArrayBuffer,\n isCornerstoneInitialized,\n setUseCPURendering,\n setUseSharedArrayBuffer,\n setPreferSizeOverAccuracy,\n resetUseCPURendering,\n resetUseSharedArrayBuffer,\n getConfiguration,\n setConfiguration,\n getWebWorkerManager,\n canRenderFloatTextures,\n};\n","import macro from '@kitware/vtk.js/macros';\nimport vtkOpenGLTexture from '@kitware/vtk.js/Rendering/OpenGL/Texture';\nimport HalfFloat from '@kitware/vtk.js/Common/Core/HalfFloat';\nimport { getConfiguration } from '../../init';\n\n/**\n * vtkStreamingOpenGLTexture - A derived class of the core vtkOpenGLTexture.\n * This class has methods to update the texture memory on the GPU slice by slice\n * in an efficient yet GPU-architecture friendly manner.\n *\n *\n * @param {*} publicAPI The public API to extend\n * @param {*} model The private model to extend.\n */\nfunction vtkStreamingOpenGLTexture(publicAPI, model) {\n model.classHierarchy.push('vtkStreamingOpenGLTexture');\n\n const superCreate3DFilterableFromRaw = publicAPI.create3DFilterableFromRaw;\n\n publicAPI.create3DFilterableFromRaw = (\n width,\n height,\n depth,\n numComps,\n dataType,\n data,\n preferSizeOverAccuracy\n ) => {\n model.inputDataType = dataType;\n model.inputNumComps = numComps;\n\n superCreate3DFilterableFromRaw(\n width,\n height,\n depth,\n numComps,\n dataType,\n data,\n preferSizeOverAccuracy\n );\n };\n\n /**\n * This function updates the GPU texture memory to match the current\n * representation of data held in RAM.\n *\n * @param {Float32Array|Uint8Array|Int16Array|Uint16Array} data The data array which has been updated.\n */\n publicAPI.update3DFromRaw = (data) => {\n const { updatedFrames } = model;\n\n if (!updatedFrames.length) {\n return;\n }\n model._openGLRenderWindow.activateTexture(publicAPI);\n publicAPI.createTexture();\n publicAPI.bind();\n\n let bytesPerVoxel;\n let TypedArrayConstructor;\n\n if (data instanceof Uint8Array) {\n bytesPerVoxel = 1;\n TypedArrayConstructor = Uint8Array;\n } else if (data instanceof Int16Array) {\n bytesPerVoxel = 2;\n TypedArrayConstructor = Int16Array;\n } else if (data instanceof Uint16Array) {\n bytesPerVoxel = 2;\n TypedArrayConstructor = Uint16Array;\n } else if (data instanceof Float32Array) {\n bytesPerVoxel = 4;\n TypedArrayConstructor = Float32Array;\n } else {\n throw new Error(`No support for given TypedArray.`);\n }\n\n for (let i = 0; i < updatedFrames.length; i++) {\n if (updatedFrames[i]) {\n model.fillSubImage3D(data, i, bytesPerVoxel, TypedArrayConstructor);\n }\n }\n\n // Reset updatedFrames\n model.updatedFrames = [];\n\n if (model.generateMipmap) {\n model.context.generateMipmap(model.target);\n }\n\n publicAPI.deactivate();\n return true;\n };\n\n /**\n * This function updates the GPU texture memory to match the current\n * representation of data held in RAM.\n *\n * @param {Float32Array|Uint8Array} data The data array which has been updated.\n * @param {number} frameIndex The frame to load in.\n * @param {number} BytesPerVoxel The number of bytes per voxel in the data, so we don't have to constantly\n * check the array type.\n * @param {object} TypedArrayConstructor The constructor for the array type. Again so we don't have to constantly check.\n */\n model.fillSubImage3D = (\n data,\n frameIndex,\n bytesPerVoxel,\n TypedArrayConstructor\n ) => {\n const buffer = data.buffer;\n\n const frameLength = model.width * model.height;\n const frameLengthInBytes = frameLength * model.components * bytesPerVoxel;\n\n const zOffset = frameIndex * frameLengthInBytes;\n const rowLength = model.width * model.components;\n\n const gl = model.context;\n\n /**\n * It appears that the implementation of texSubImage3D uses 2D textures to do the texture copy if\n * MAX_TEXTURE_SIZE is greater than MAX_TEXTURE_SIZE_3D. As such if you make a single block too big\n * the transfer messes up cleanly and you render a black box or some data if you are lucky.\n *\n * This block-size based on 2D texture size seems like the safest approach that should work on most systems.\n *\n * There are certainly further optimizations that could be done here, we can do bigger chunks with other systems\n * But we need to find the _exact_ criteria. And then its not even guaranteed it'll be much faster.\n */\n const MAX_TEXTURE_SIZE = gl.getParameter(gl.MAX_TEXTURE_SIZE);\n let blockHeight = Math.floor(\n (bytesPerVoxel * MAX_TEXTURE_SIZE) / model.width\n );\n\n // Cap to actual frame height:\n blockHeight = Math.min(blockHeight, model.height);\n const { useNorm16Texture, preferSizeOverAccuracy } =\n getConfiguration().rendering;\n // TODO: there is currently a bug in chrome and safari which requires\n // blockheight = 1 for norm16 textures:\n // https://bugs.chromium.org/p/chromium/issues/detail?id=1408247\n // https://bugs.webkit.org/show_bug.cgi?id=252039\n if (useNorm16Texture && !preferSizeOverAccuracy) {\n blockHeight = 1;\n }\n\n const multiRowBlockLength = rowLength * blockHeight;\n const multiRowBlockLengthInBytes = multiRowBlockLength * bytesPerVoxel;\n\n const normalBlocks = Math.floor(model.height / blockHeight);\n\n const lastBlockHeight = model.height % blockHeight;\n const multiRowLastBlockLength = rowLength * lastBlockHeight;\n\n // Perform most blocks.\n for (let block = 0; block < normalBlocks; block++) {\n const yOffset = block * blockHeight;\n\n let dataView = new TypedArrayConstructor(\n buffer,\n zOffset + block * multiRowBlockLengthInBytes,\n multiRowBlockLength\n );\n\n if (\n model.useHalfFloat &&\n (TypedArrayConstructor === Uint16Array ||\n TypedArrayConstructor === Int16Array)\n ) {\n // in the case we want to use halfFloat rendering (preferSizeOverAccuracy = true),\n // we need to convert uint16 and int16 into fp16 format.\n // This is the step where precision is lost for streaming volume viewport.\n for (let idx = 0; idx < dataView.length; idx++) {\n dataView[idx] = HalfFloat.toHalf(dataView[idx]);\n }\n if (TypedArrayConstructor === Int16Array) {\n dataView = new Uint16Array(dataView);\n }\n }\n\n gl.texSubImage3D(\n model.target, // target\n 0, // mipMap level (always zero)\n 0, // xOffset\n yOffset, // yOffset\n frameIndex,\n model.width,\n blockHeight, //model.height,\n 1, // numFramesInBlock,\n model.format,\n model.openGLDataType,\n dataView\n );\n }\n\n // perform last block if present\n\n if (lastBlockHeight !== 0) {\n const yOffset = normalBlocks * blockHeight;\n\n // Dataview of last block\n const dataView = new TypedArrayConstructor(\n buffer,\n zOffset + normalBlocks * multiRowBlockLengthInBytes,\n multiRowLastBlockLength\n );\n\n gl.texSubImage3D(\n model.target, // target\n 0, // mipMap level (always zero)\n 0, // xOffset\n yOffset, // yOffset\n frameIndex,\n model.width,\n lastBlockHeight, //model.height,\n 1, // numFramesInBlock,\n model.format,\n model.openGLDataType,\n dataView\n );\n }\n };\n\n publicAPI.getTextureParameters = () => {\n return {\n width: model.width,\n height: model.height,\n depth: model.depth,\n numComps: model.inputNumComps,\n dataType: model.inputDataType,\n };\n };\n\n /**\n * Called when a frame is loaded so that on next render we know which data to load in.\n * @param {number} frameIndex The frame to load in.\n */\n publicAPI.setUpdatedFrame = (frameIndex) => {\n model.updatedFrames[frameIndex] = true;\n };\n}\n\n// ----------------------------------------------------------------------------\n// Object factory\n// ----------------------------------------------------------------------------\n\n// ----------------------------------------------------------------------------\n\nconst DEFAULT_VALUES = {\n updatedFrames: [],\n};\n\nexport function extend(publicAPI, model, initialValues = {}) {\n Object.assign(model, DEFAULT_VALUES, initialValues);\n\n vtkOpenGLTexture.extend(publicAPI, model, initialValues);\n\n // Object methods\n vtkStreamingOpenGLTexture(publicAPI, model);\n}\n\n// ----------------------------------------------------------------------------\n\nexport const newInstance = macro.newInstance(\n extend,\n 'vtkStreamingOpenGLTexture'\n);\n\n// ----------------------------------------------------------------------------\n\nexport default { newInstance, extend };\n","/**\n * EventTarget - Provides the [EventTarget](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget) interface\n */\nclass CornerstoneEventTarget implements EventTarget {\n private listeners;\n private debouncedListeners;\n\n constructor() {\n this.listeners = {};\n this.debouncedListeners = {};\n }\n\n public reset() {\n this.listeners = {};\n this.debouncedListeners = {};\n }\n\n public addEventListenerOnce(type, callback) {\n // Create a wrapper function to encapsulate the original callback\n const onceWrapper = (event) => {\n // Remove the listener after its first invocation\n this.removeEventListener(type, onceWrapper);\n\n // Call the original callback\n callback.call(this, event);\n };\n\n // Add the wrapper as the listener\n this.addEventListener(type, onceWrapper);\n }\n\n public addEventListener(type, callback) {\n if (!this.listeners[type]) {\n this.listeners[type] = [];\n }\n\n // prevent multiple callbacks from firing\n if (this.listeners[type].indexOf(callback) !== -1) {\n return;\n }\n\n this.listeners[type].push(callback);\n }\n\n /**\n * Adds a debounced event listener to the event target.\n *\n * @param type - The type of the event to listen for.\n * @param callback - The callback function to be executed when the event is triggered.\n * @param delay - The delay in milliseconds before the callback is invoked after the last event.\n */\n public addEventListenerDebounced(type, callback, delay) {\n // Ensure the dictionary for the type exists\n this.debouncedListeners[type] = this.debouncedListeners[type] || {};\n const debouncedCallbacks = this.debouncedListeners[type];\n\n // Check if there's already a debounced version of this callback registered\n if (!debouncedCallbacks[callback]) {\n const handle = (event) => {\n // Clear any existing timeout to reset the debounce timer\n if (debouncedCallbacks[callback]) {\n clearTimeout(debouncedCallbacks[callback].timeoutId);\n }\n\n // Set a new timeout\n debouncedCallbacks[callback].timeoutId = setTimeout(() => {\n callback.call(this, event);\n }, delay);\n };\n\n // Store the handle and initial timeoutId (null initially)\n debouncedCallbacks[callback] = {\n original: callback,\n handle,\n timeoutId: null,\n };\n\n // Register the debounced handler\n this.addEventListener(type, handle);\n }\n }\n\n /**\n * Removes a debounced event listener from the event target.\n *\n * @param type - The type of the event.\n * @param callback - The callback function to be removed.\n */\n public removeEventListenerDebounced(type, callback) {\n if (\n this.debouncedListeners[type] &&\n this.debouncedListeners[type][callback]\n ) {\n const debounced = this.debouncedListeners[type][callback];\n this.removeEventListener(type, debounced.handle);\n clearTimeout(debounced.timeoutId);\n delete this.debouncedListeners[type][callback];\n }\n }\n\n public removeEventListener(type, callback) {\n if (!this.listeners[type]) {\n return;\n }\n\n const stack = this.listeners[type];\n const stackLength = stack.length;\n\n for (let i = 0; i < stackLength; i++) {\n if (stack[i] === callback) {\n stack.splice(i, 1);\n\n return;\n }\n }\n }\n\n dispatchEvent(event) {\n if (!this.listeners[event.type]) {\n //console.warn(`Skipping dispatch since there are no listeners for ${event.type}`);\n return;\n }\n\n const stack = this.listeners[event.type].slice();\n const stackLength = stack.length;\n\n for (let i = 0; i < stackLength; i++) {\n try {\n stack[i].call(this, event);\n } catch (error) {\n console.error(`error in event listener of type: ${event.type}`, error);\n }\n }\n\n return !event.defaultPrevented;\n }\n}\n\n/**\n * EventTarget - Provides the [EventTarget](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget) interface\n */\nconst eventTarget = new CornerstoneEventTarget();\n\nexport default eventTarget;\n","import eventTarget from '../eventTarget';\n\n/**\n * Small utility to trigger a custom event for a given EventTarget.\n *\n * @example\n *\n * ```javascript\n * triggerEvent(element, Events.IMAGE_RENDERED, { element })\n * ```\n * or it can trigger event on the eventTarget itself\n *\n * ```javascript\n * triggerEvent(eventTarget, CSTOOLS_EVENTS.ANNOTATION_MODIFIED, { viewportId, annotationUID })\n * ```\n *\n * @param el - The element or EventTarget to trigger the event upon\n * @param type - The event type name\n * @param detail - The event detail to be sent\n * @returns false if event is cancelable and at least one of the event handlers\n * which received event called Event.preventDefault(). Otherwise it returns true.\n */\nexport default function triggerEvent(\n el: EventTarget = eventTarget,\n type: string,\n detail: unknown = null\n): boolean {\n if (!type) {\n throw new Error('Event type was not defined');\n }\n\n const event = new CustomEvent(type, {\n detail,\n cancelable: true,\n });\n\n return el.dispatchEvent(event);\n}\n","import {\n ICache,\n IImage,\n IGeometry,\n IImageLoadObject,\n IVolumeLoadObject,\n IGeometryLoadObject,\n ICachedImage,\n ICachedVolume,\n ICachedGeometry,\n EventTypes,\n IImageVolume,\n} from '../types';\nimport { triggerEvent, imageIdToURI } from '../utilities';\nimport eventTarget from '../eventTarget';\nimport Events from '../enums/Events';\nimport { ImageVolume } from './classes/ImageVolume';\n\nconst ONE_GB = 1073741824;\n\n/**\n * Stores images, volumes and geometry.\n * There are two sizes - the max cache size, that controls the overal maximum\n * size, and the instance size, which controls how big any single object can\n * be. Defaults are 3 GB and 2 GB - 8 bytes (just enough to allow allocating it\n * without crashing).\n * The 3 gb is tuned to the chromium garbage collection cycle to allow image volumes\n * to be used/discarded.\n */\nclass Cache implements ICache {\n // used to store image data (2d)\n private readonly _imageCache = new Map<string, ICachedImage>(); // volatile space\n // used to store volume data (3d)\n private readonly _volumeCache = new Map<string, ICachedVolume>(); // non-volatile space\n // Todo: contour for now, but will be used for surface, etc.\n private readonly _geometryCache: Map<string, ICachedGeometry>;\n\n private _imageCacheSize = 0;\n private _volumeCacheSize = 0;\n private _maxCacheSize = 3 * ONE_GB;\n private _maxInstanceSize = 4 * ONE_GB - 8;\n\n constructor() {\n // used to store object data (contour, surface, etc.)\n this._geometryCache = new Map();\n }\n\n /**\n * Set the maximum cache Size\n *\n * Maximum cache size should be set before adding the data. If set after,\n * and it is smaller than the current size, will cause issues.\n *\n * @param newMaxCacheSize - new maximum cache size\n *\n */\n public setMaxCacheSize = (newMaxCacheSize: number): void => {\n if (!newMaxCacheSize || typeof newMaxCacheSize !== 'number') {\n const errorMessage = `New max cacheSize ${this._maxCacheSize} should be defined and should be a number.`;\n throw new Error(errorMessage);\n }\n\n this._maxCacheSize = newMaxCacheSize;\n };\n\n /**\n * Checks if there is enough space in the cache for requested byte size\n *\n * It returns false, if the sum of volatile (image) cache and unallocated cache\n * is less than the requested byteLength\n *\n * @param byteLength - byte length of requested byte size\n *\n * @returns - boolean indicating if there is enough space in the cache\n */\n public isCacheable = (byteLength: number): boolean => {\n if (byteLength > this._maxInstanceSize) {\n return false;\n }\n const unallocatedSpace = this.getBytesAvailable();\n const imageCacheSize = this._imageCacheSize;\n const availableSpace = unallocatedSpace + imageCacheSize;\n\n return availableSpace > byteLength;\n };\n\n /**\n * Returns maximum CacheSize allowed\n *\n * @returns maximum allowed cache size\n */\n public getMaxCacheSize = (): number => this._maxCacheSize;\n\n /**\n * Returns maximum size of a single instance (volume or single image)\n *\n * @returns maximum instance size\n */\n public getMaxInstanceSize = (): number => this._maxInstanceSize;\n\n /**\n * Returns current size of the cache\n *\n * @returns current size of the cache\n */\n public getCacheSize = (): number =>\n this._imageCacheSize + this._volumeCacheSize;\n\n /**\n * Returns the unallocated size of the cache\n *\n */\n public getBytesAvailable(): number {\n return this.getMaxCacheSize() - this.getCacheSize();\n }\n\n /**\n * Deletes the imageId from the image cache\n *\n * @param imageId - imageId\n *\n */\n private _decacheImage = (imageId: string) => {\n const { imageLoadObject } = this._imageCache.get(imageId);\n\n // Cancel any in-progress loading\n if (imageLoadObject.cancelFn) {\n imageLoadObject.cancelFn();\n }\n\n if (imageLoadObject.decache) {\n imageLoadObject.decache();\n }\n\n this._imageCache.delete(imageId);\n };\n\n /**\n * Deletes the volumeId from the volume cache\n *\n * @param volumeId - volumeId\n *\n */\n private _decacheVolume = (volumeId: string) => {\n const cachedVolume = this._volumeCache.get(volumeId);\n const { volumeLoadObject, volume } = cachedVolume;\n\n if (volume.cancelLoading) {\n volume.cancelLoading();\n }\n\n if (volume.imageData) {\n volume.imageData.delete();\n }\n\n // if we had views for the images of the volume, we need to restore them\n // to avoid memory leaks\n this._restoreImagesFromBuffer(volume);\n\n if (volumeLoadObject.cancelFn) {\n // Cancel any in-progress loading\n volumeLoadObject.cancelFn();\n }\n\n if (volumeLoadObject.decache) {\n volumeLoadObject.decache();\n }\n\n this._volumeCache.delete(volumeId);\n };\n\n /**\n * Deletes all the images and volumes in the cache\n *\n * Relevant events are fired for each decached image (IMAGE_CACHE_IMAGE_REMOVED) and\n * the decached volume (VOLUME_CACHE_VOLUME_REMOVED).\n *\n * @fires Events.IMAGE_CACHE_IMAGE_REMOVED\n * @fires Events.VOLUME_CACHE_VOLUME_REMOVED\n *\n */\n public purgeCache = (): void => {\n const imageIterator = this._imageCache.keys();\n\n /* eslint-disable no-constant-condition */\n while (true) {\n const { value: imageId, done } = imageIterator.next();\n\n if (done) {\n break;\n }\n\n this.removeImageLoadObject(imageId);\n\n triggerEvent(eventTarget, Events.IMAGE_CACHE_IMAGE_REMOVED, { imageId });\n }\n\n this.purgeVolumeCache();\n };\n\n /**\n * Deletes all the volumes in the cache\n */\n public purgeVolumeCache = (): void => {\n const volumeIterator = this._volumeCache.keys();\n\n /* eslint-disable no-constant-condition */\n while (true) {\n const { value: volumeId, done } = volumeIterator.next();\n\n if (done) {\n break;\n }\n\n this.removeVolumeLoadObject(volumeId);\n\n triggerEvent(eventTarget, Events.VOLUME_CACHE_VOLUME_REMOVED, {\n volumeId,\n });\n }\n };\n\n /**\n * Purges the cache if necessary based on the requested number of bytes\n *\n * 1) it sorts the volatile (image) cache based on the most recent used images\n * and starts purging from the oldest ones.\n * Note: for a volume, if the volume-related image Ids is provided, it starts\n * by purging the none-related image Ids (those that are not related to the\n * current volume)\n * 2) For a volume, if we purge all images that won't be included in this volume and still\n * don't have enough unallocated space, purge images that will be included\n * in this volume until we have enough space. These will need to be\n * re-fetched, but we must do this not to straddle over the given memory\n * limit, even for a short time, as this may crash the application.\n *\n * @fires Events.IMAGE_CACHE_IMAGE_REMOVED\n *\n * @param numBytes - Number of bytes for the image/volume that is\n * going to be stored inside the cache\n * @param volumeImageIds - list of imageIds that correspond to the\n * volume whose numberOfBytes we want to store in the cache.\n * @returns bytesAvailable or undefined in purging cache\n * does not successfully make enough space for the requested number of bytes\n */\n public decacheIfNecessaryUntilBytesAvailable(\n numBytes: number,\n volumeImageIds?: Array<string>\n ): number | undefined {\n let bytesAvailable = this.getBytesAvailable();\n\n // If max cache size has not been exceeded, do nothing\n if (bytesAvailable >= numBytes) {\n return bytesAvailable;\n }\n\n let cachedImages = Array.from(this._imageCache.values());\n\n // Cache size has been exceeded, create list of images sorted by timeStamp\n // So we can purge the least recently used image\n function compare(a, b) {\n if (a.timeStamp > b.timeStamp) {\n return 1;\n }\n if (a.timeStamp < b.timeStamp) {\n return -1;\n }\n\n return 0;\n }\n\n cachedImages.sort(compare);\n let cachedImageIds = cachedImages.map((im) => im.imageId);\n\n let imageIdsToPurge = cachedImageIds;\n\n // if we are making space for a volume, we start by purging the imageIds\n // that are not related to the volume\n if (volumeImageIds) {\n imageIdsToPurge = cachedImageIds.filter(\n (id) => !volumeImageIds.includes(id)\n );\n }\n\n // Remove images (that are not related to the volume) from volatile cache\n // until the requested number of bytes become available\n for (const imageId of imageIdsToPurge) {\n this.removeImageLoadObject(imageId);\n\n triggerEvent(eventTarget, Events.IMAGE_CACHE_IMAGE_REMOVED, { imageId });\n\n bytesAvailable = this.getBytesAvailable();\n if (bytesAvailable >= numBytes) {\n return bytesAvailable;\n }\n }\n\n // Remove the imageIds (both volume related and not related)\n cachedImages = Array.from(this._imageCache.values());\n cachedImageIds = cachedImages.map((im) => im.imageId);\n\n // Remove volume-image Ids from volatile cache until the requested number of bytes\n // become available\n for (const imageId of cachedImageIds) {\n this.removeImageLoadObject(imageId);\n\n triggerEvent(eventTarget, Events.IMAGE_CACHE_IMAGE_REMOVED, { imageId });\n\n bytesAvailable = this.getBytesAvailable();\n if (bytesAvailable >= numBytes) {\n return bytesAvailable;\n }\n }\n\n // Technically we should not reach here, since isCacheable will throw an\n // error if unallocated + volatile (image) cache cannot fit the upcoming\n // number of bytes\n }\n\n /**\n * Puts a new image load object into the cache\n *\n * First, it creates a CachedImage object and put it inside the imageCache for\n * the imageId. After the imageLoadObject promise resolves to an image,\n * it: 1) adds the image into the correct CachedImage object 2) increments the\n * cache size, 3) triggers IMAGE_CACHE_IMAGE_ADDED 4) Purge the cache if\n * necessary -- if the cache size is greater than the maximum cache size, it\n * iterates over the imageCache and decache them one by one until the cache\n * size becomes less than the maximum allowed cache size\n *\n * @fires Events.IMAGE_CACHE_IMAGE_ADDED\n * @fires Events.CACHE_SIZE_EXCEEDED if the cache size exceeds the maximum\n *\n * @param imageId - ImageId for the image\n * @param imageLoadObject - The object that is loading or loaded the image\n */\n public putImageLoadObject(\n imageId: string,\n imageLoadObject: IImageLoadObject\n ): Promise<any> {\n if (imageId === undefined) {\n throw new Error('putImageLoadObject: imageId must not be undefined');\n }\n\n if (imageLoadObject.promise === undefined) {\n throw new Error(\n 'putImageLoadObject: imageLoadObject.promise must not be undefined'\n );\n }\n\n if (this._imageCache.has(imageId)) {\n throw new Error('putImageLoadObject: imageId already in cache');\n }\n\n if (\n imageLoadObject.cancelFn &&\n typeof imageLoadObject.cancelFn !== 'function'\n ) {\n throw new Error(\n 'putImageLoadObject: imageLoadObject.cancel must be a function'\n );\n }\n\n const cachedImage: ICachedImage = {\n loaded: false,\n imageId,\n sharedCacheKey: undefined, // The sharedCacheKey for this imageId. undefined by default\n imageLoadObject,\n timeStamp: Date.now(),\n sizeInBytes: 0,\n };\n\n this._imageCache.set(imageId, cachedImage);\n\n return imageLoadObject.promise\n .then((image: IImage) => {\n if (!this._imageCache.get(imageId)) {\n // If the image has been purged before being loaded, we stop here.\n console.warn(\n 'The image was purged from the cache before it completed loading.'\n );\n return;\n }\n\n if (\n image.sizeInBytes === undefined ||\n Number.isNaN(image.sizeInBytes)\n ) {\n throw new Error(\n 'putImageLoadObject: image.sizeInBytes must not be undefined'\n );\n }\n if (image.sizeInBytes.toFixed === undefined) {\n throw new Error(\n 'putImageLoadObject: image.sizeInBytes is not a number'\n );\n }\n\n // check if there is enough space in unallocated + image Cache\n if (!this.isCacheable(image.sizeInBytes)) {\n throw new Error(Events.CACHE_SIZE_EXCEEDED);\n }\n\n // if there is, decache if necessary\n this.decacheIfNecessaryUntilBytesAvailable(image.sizeInBytes);\n\n cachedImage.loaded = true;\n cachedImage.image = image;\n cachedImage.sizeInBytes = image.sizeInBytes;\n this.incrementImageCacheSize(cachedImage.sizeInBytes);\n const eventDetails: EventTypes.ImageCacheImageAddedEventDetail = {\n image: cachedImage,\n };\n\n triggerEvent(eventTarget, Events.IMAGE_CACHE_IMAGE_ADDED, eventDetails);\n\n cachedImage.sharedCacheKey = image.sharedCacheKey;\n })\n .catch((error) => {\n // console.warn(error)\n this._imageCache.delete(imageId);\n throw error;\n });\n }\n\n /**\n * Returns the object that is loading a given imageId\n *\n * @param imageId - Image ID\n * @returns IImageLoadObject\n */\n public getImageLoadObject(imageId: string): IImageLoadObject {\n if (imageId === undefined) {\n throw new Error('getImageLoadObject: imageId must not be undefined');\n }\n const cachedImage = this._imageCache.get(imageId);\n\n if (cachedImage === undefined) {\n return;\n }\n\n // Bump time stamp for cached image\n cachedImage.timeStamp = Date.now();\n\n return cachedImage.imageLoadObject;\n }\n\n /**\n * It checks the imageCache for the provided imageId, and returns true\n * if the image is loaded, false otherwise. Note, this only checks the imageCache\n * and does not check the volume cache.\n * @param imageId - image Id to check\n * @returns boolean\n */\n public isLoaded(imageId: string): boolean {\n const cachedImage = this._imageCache.get(imageId);\n\n if (!cachedImage) {\n return false;\n }\n\n return cachedImage.loaded;\n }\n\n /**\n * Returns the volume that contains the requested imageId. It will check the\n * imageIds inside the volume to find a match.\n *\n * @param imageId - ImageId\n * @returns - Volume object\n */\n public getVolumeContainingImageId(imageId: string): {\n volume: IImageVolume;\n imageIdIndex: number;\n } {\n const volumeIds = Array.from(this._volumeCache.keys());\n const imageIdToUse = imageIdToURI(imageId);\n\n for (const volumeId of volumeIds) {\n const cachedVolume = this._volumeCache.get(volumeId);\n const { volume } = cachedVolume;\n\n if (!volume?.imageIds?.length) {\n return;\n }\n\n const imageIdIndex = volume.getImageURIIndex(imageIdToUse);\n\n if (imageIdIndex > -1) {\n return { volume, imageIdIndex };\n }\n }\n }\n\n /**\n * Returns the cached image from the imageCache for the requested imageId.\n * It first strips the imageId to remove the data loading scheme.\n *\n * @param imageId - Image ID\n * @returns cached image\n */\n public getCachedImageBasedOnImageURI(\n imageId: string\n ): ICachedImage | undefined {\n const imageURIToUse = imageIdToURI(imageId);\n\n const cachedImageIds = Array.from(this._imageCache.keys());\n const foundImageId = cachedImageIds.find((imageId) => {\n return imageIdToURI(imageId) === imageURIToUse;\n });\n\n if (!foundImageId) {\n return;\n }\n\n return this._imageCache.get(foundImageId);\n }\n /**\n * Puts a new image load object into the cache\n *\n * First, it creates a CachedVolume object and put it inside the volumeCache for\n * the volumeId. After the volumeLoadObject promise resolves to a volume,\n * it: 1) adds the volume into the correct CachedVolume object inside volumeCache\n * 2) increments the cache size, 3) triggers VOLUME_CACHE_VOLUME_ADDED 4) Purge\n * the cache if necessary -- if the cache size is greater than the maximum cache size, it\n * iterates over the imageCache (not volumeCache) and decache them one by one\n * until the cache size becomes less than the maximum allowed cache size\n *\n * @fires Events.VOLUME_CACHE_VOLUME_ADDED\n *\n * @param volumeId - volumeId of the volume\n * @param volumeLoadObject - The object that is loading or loaded the volume\n */\n public putVolumeLoadObject(\n volumeId: string,\n volumeLoadObject: IVolumeLoadObject\n ): Promise<any> {\n if (volumeId === undefined) {\n throw new Error('putVolumeLoadObject: volumeId must not be undefined');\n }\n if (volumeLoadObject.promise === undefined) {\n throw new Error(\n 'putVolumeLoadObject: volumeLoadObject.promise must not be undefined'\n );\n }\n if (this._volumeCache.has(volumeId)) {\n throw new Error(\n `putVolumeLoadObject: volumeId:${volumeId} already in cache`\n );\n }\n if (\n volumeLoadObject.cancelFn &&\n typeof volumeLoadObject.cancelFn !== 'function'\n ) {\n throw new Error(\n 'putVolumeLoadObject: volumeLoadObject.cancel must be a function'\n );\n }\n\n // todo: @Erik there are two loaded flags, one inside cachedVolume and the other\n // inside the volume.loadStatus.loaded, the actual all pixelData loaded is the\n // loadStatus one. This causes confusion\n const cachedVolume: ICachedVolume = {\n loaded: false,\n volumeId,\n volumeLoadObject,\n timeStamp: Date.now(),\n sizeInBytes: 0,\n };\n\n this._volumeCache.set(volumeId, cachedVolume);\n\n return volumeLoadObject.promise\n .then((volume: IImageVolume) => {\n if (!this._volumeCache.get(volumeId)) {\n // If the image has been purged before being loaded, we stop here.\n console.warn(\n 'The image was purged from the cache before it completed loading.'\n );\n return;\n }\n\n if (Number.isNaN(volume.sizeInBytes)) {\n throw new Error(\n 'putVolumeLoadObject: volume.sizeInBytes must not be undefined'\n );\n }\n if (volume.sizeInBytes.toFixed === undefined) {\n throw new Error(\n 'putVolumeLoadObject: volume.sizeInBytes is not a number'\n );\n }\n\n // this.isCacheable is called at the volume loader, before requesting\n // the images of the volume\n\n this.decacheIfNecessaryUntilBytesAvailable(\n volume.sizeInBytes,\n // @ts-ignore: // todo ImageVolume does not have imageIds\n volume.imageIds\n );\n\n // cachedVolume.loaded = true\n cachedVolume.volume = volume;\n cachedVolume.sizeInBytes = volume.sizeInBytes;\n this.incrementVolumeCacheSize(cachedVolume.sizeInBytes);\n\n const eventDetails: EventTypes.VolumeCacheVolumeAddedEventDetail = {\n volume: cachedVolume,\n };\n\n triggerEvent(\n eventTarget,\n Events.VOLUME_CACHE_VOLUME_ADDED,\n eventDetails\n );\n })\n .catch((error) => {\n this._volumeCache.delete(volumeId);\n throw error;\n });\n }\n\n /**\n * Returns the object that is loading a given volumeId\n *\n * @param volumeId - Volume ID\n * @returns IVolumeLoadObject\n */\n public getVolumeLoadObject = (volumeId: string): IVolumeLoadObject => {\n if (volumeId === undefined) {\n throw new Error('getVolumeLoadObject: volumeId must not be undefined');\n }\n const cachedVolume = this._volumeCache.get(volumeId);\n\n if (cachedVolume === undefined) {\n return;\n }\n\n // Bump time stamp for cached volume (not used for anything for now)\n cachedVolume.timeStamp = Date.now();\n\n return cachedVolume.volumeLoadObject;\n };\n\n public getGeometry = (geometryId: string): IGeometry => {\n if (geometryId == null) {\n throw new Error('getGeometry: geometryId must not be undefined');\n }\n\n const cachedGeometry = this._geometryCache.get(geometryId);\n\n if (cachedGeometry === undefined) {\n return;\n }\n\n // Bump time stamp for cached geometry (not used for anything for now)\n cachedGeometry.timeStamp = Date.now();\n\n return cachedGeometry.geometry;\n };\n\n /**\n * Returns the image associated with the imageId\n *\n * @param imageId - image ID\n * @returns Image\n */\n public getImage = (imageId: string): IImage => {\n if (imageId === undefined) {\n throw new Error('getImage: imageId must not be undefined');\n }\n const cachedImage = this._imageCache.get(imageId);\n\n if (cachedImage === undefined) {\n return;\n }\n\n // Bump time stamp for cached volume (not used for anything for now)\n cachedImage.timeStamp = Date.now();\n\n return cachedImage.image;\n };\n\n /**\n * Returns the volume associated with the volumeId\n *\n * @param volumeId - Volume ID\n * @returns Volume\n */\n public getVolume = (volumeId: string): IImageVolume => {\n if (volumeId === undefined) {\n throw new Error('getVolume: volumeId must not be undefined');\n }\n const cachedVolume = this._volumeCache.get(volumeId);\n\n if (cachedVolume === undefined) {\n return;\n }\n\n // Bump time stamp for cached volume (not used for anything for now)\n cachedVolume.timeStamp = Date.now();\n\n return cachedVolume.volume;\n };\n\n /**\n * Retrieves an array of image volumes from the cache.\n * @returns An array of image volumes.\n */\n public getVolumes = (): Array<IImageVolume> => {\n const cachedVolumes = Array.from(this._volumeCache.values());\n\n return cachedVolumes.map((cachedVolume) => cachedVolume.volume);\n };\n\n /**\n * Filters the cached volumes by the specified reference volume ID.\n * @param volumeId - The ID of the reference volume.\n * @returns An array of image volumes that have the specified reference volume ID.\n */\n public filterVolumesByReferenceId = (\n volumeId: string\n ): Array<IImageVolume> => {\n const cachedVolumes = this.getVolumes();\n\n return cachedVolumes.filter((volume) => {\n return volume.referencedVolumeId === volumeId;\n });\n };\n\n /**\n * Removes the image loader associated with a given Id from the cache\n *\n * It increases the cache size after removing the image.\n *\n * @fires Events.IMAGE_CACHE_IMAGE_REMOVED\n *\n * @param imageId - Image ID\n */\n public removeImageLoadObject = (imageId: string): void => {\n if (imageId === undefined) {\n throw new Error('removeImageLoadObject: imageId must not be undefined');\n }\n const cachedImage = this._imageCache.get(imageId);\n\n if (cachedImage === undefined) {\n throw new Error(\n 'removeImageLoadObject: imageId was not present in imageCache'\n );\n }\n\n this.incrementImageCacheSize(-cachedImage.sizeInBytes);\n\n const eventDetails = {\n image: cachedImage,\n imageId,\n };\n\n triggerEvent(eventTarget, Events.IMAGE_CACHE_IMAGE_REMOVED, eventDetails);\n this._decacheImage(imageId);\n };\n\n /**\n * Removes the volume loader associated with a given Id from the cache\n *\n * It increases the cache size after removing the image.\n *\n * @fires Events.VOLUME_CACHE_VOLUME_REMOVED\n *\n * @param imageId - ImageId\n */\n public removeVolumeLoadObject = (volumeId: string): void => {\n if (volumeId === undefined) {\n throw new Error('removeVolumeLoadObject: volumeId must not be undefined');\n }\n const cachedVolume = this._volumeCache.get(volumeId);\n\n if (cachedVolume === undefined) {\n throw new Error(\n 'removeVolumeLoadObject: volumeId was not present in volumeCache'\n );\n }\n\n this.incrementVolumeCacheSize(-cachedVolume.sizeInBytes);\n\n const eventDetails = {\n volume: cachedVolume,\n volumeId,\n };\n\n triggerEvent(eventTarget, Events.VOLUME_CACHE_VOLUME_REMOVED, eventDetails);\n this._decacheVolume(volumeId);\n };\n\n putGeometryLoadObject = (\n geometryId: string,\n geometryLoadObject: IGeometryLoadObject\n ): Promise<void> => {\n if (geometryId == undefined) {\n throw new Error(\n 'putGeometryLoadObject: geometryId must not be undefined'\n );\n }\n\n if (this._geometryCache.has(geometryId)) {\n throw new Error(\n 'putGeometryLoadObject: geometryId already present in geometryCache'\n );\n }\n\n const cachedGeometry: ICachedGeometry = {\n geometryId,\n geometryLoadObject,\n loaded: false,\n timeStamp: Date.now(),\n sizeInBytes: 0,\n };\n\n this._geometryCache.set(geometryId, cachedGeometry);\n\n return geometryLoadObject.promise\n .then((geometry: IGeometry) => {\n if (!this._geometryCache.has(geometryId)) {\n console.warn(\n 'putGeometryLoadObject: geometryId was removed from geometryCache'\n );\n return;\n }\n\n if (Number.isNaN(geometry.sizeInBytes)) {\n throw new Error(\n 'putGeometryLoadObject: geometry.sizeInBytes is not a number'\n );\n }\n\n // Todo: fix is cacheable\n\n cachedGeometry.loaded = true;\n cachedGeometry.geometry = geometry;\n cachedGeometry.sizeInBytes = geometry.sizeInBytes;\n\n // this._incrementGeometryCacheSize(geometry.sizeInBytes);\n\n const eventDetails = {\n geometry,\n geometryId,\n };\n\n triggerEvent(\n eventTarget,\n Events.GEOMETRY_CACHE_GEOMETRY_ADDED,\n eventDetails\n );\n\n return;\n })\n .catch((error) => {\n this._geometryCache.delete(geometryId);\n throw error;\n });\n };\n\n /**\n * Increases the image cache size with the provided increment\n *\n * @param increment - bytes length\n */\n public incrementImageCacheSize = (increment: number) => {\n this._imageCacheSize += increment;\n };\n\n /**\n * Increases the cache size with the provided increment\n *\n * @param increment - bytes length\n */\n public incrementVolumeCacheSize = (increment: number) => {\n this._volumeCacheSize += increment;\n };\n\n /**\n * Decreases the image cache size with the provided decrement\n *\n * @param decrement - bytes length\n */\n public decrementImageCacheSize = (decrement: number) => {\n this._imageCacheSize -= decrement;\n };\n\n /**\n * Decreases the cache size with the provided decrement\n *\n * @param decrement - bytes length\n */\n public decrementVolumeCacheSize = (decrement: number) => {\n this._volumeCacheSize -= decrement;\n };\n\n /**\n * This function will restore the images' pixel data from the shared array buffer\n * back to the individual images when the volume is purged from cache. It ensures\n * that each image retrieves its correct portion of data from the buffer based on\n * the previously stored offset and length information.\n *\n * @param volumeId - The volumeId whose images need to be restored.\n */\n private _restoreImagesFromBuffer(volume: IImageVolume) {\n if (!(volume instanceof ImageVolume)) {\n console.warn(\n 'Volume is not an ImageVolume. Cannot restore images from buffer.'\n );\n return;\n }\n\n // Retrieve the scalar data and the offset map from the volume\n const scalarData = volume.getScalarData();\n const imageCacheOffsetMap = volume.imageCacheOffsetMap;\n\n if (imageCacheOffsetMap.size === 0) {\n // This happens during testing and isn't an issue\n // console.warn('No cached images to restore for this volume.');\n return;\n }\n\n // Iterate over each image and restore its pixel data from the shared buffer\n for (const [imageId, { offset }] of imageCacheOffsetMap) {\n const image = this.getImage(imageId);\n\n if (!image) {\n console.warn(`Image with id ${imageId} not found in cache.`);\n continue;\n }\n\n const viewPixelData = image.getPixelData();\n const length = viewPixelData.length;\n\n // Create a new view of the buffer for this specific image\n // @ts-ignore\n const pixelData = new viewPixelData.constructor(\n scalarData.buffer,\n offset,\n length\n );\n\n // Restore the original getPixelData function and pixelData\n image.getPixelData = () => pixelData;\n\n if (image.imageFrame) {\n image.imageFrame.pixelData = pixelData;\n }\n\n delete image.bufferView;\n\n // Optionally, increment the image cache size again if needed\n this.incrementImageCacheSize(image.sizeInBytes);\n }\n\n console.log(`Images restored from buffer for volume ${volume.volumeId}.`);\n }\n}\n\n/**\n * This module deals with Caching of images and volumes\n * The cache has two main components: a volatile portion for images and a\n * non-volatile portion for volumes. Individual 2D images are volatile and\n * will be replaced by new images hitting the cache. When you allocate volumes,\n * these are non-volatile and reserve a block of memory from the cache.\n * Volumes must be released manually.\n * We will have a shared block of memory allocated for the entire cache, e.g. 1GB\n * which will be shared for images and volumes.\n *\n * **When a new image is added:**\n * We check if there is enough unallocated + volatile space for the single image\n *\n * if so\n * - We allocate the image in image cache, and if necessary oldest images\n * are decached to match the maximumCacheSize criteria\n * - If a volume contains that imageId, copy it over using TypedArray's set method.\n * If no volumes contain the imageId, the image is fetched by image loaders\n *\n * If not (cache is mostly/completely full with volumes)\n * - throw that the cache does not have enough working space to allocate the image\n *\n *\n * **When a new volume is added:**\n * Check if there is enough unallocated + volatile space to allocate the volume:\n *\n * If so:\n * - Decache oldest images which won't be included in this volume until\n * we have enough free space for the volume\n * - If not enough space from previous space, decache images that will be included\n * in the volume until we have enough free space (These will need to be re-fetched,\n * but we must do this not to straddle over the given memory limit, even for a\n * short time, as this may crash the app)\n * - At this point, if any of the frames (indexed by imageId) are present in the volatile\n * image cache, copy these over to the volume now\n *\n * If not (cache is mostly/completely full with volumes),\n * - throw that the cache does not have enough working space to allocate the volume.\n *\n */\nconst cache = new Cache();\nexport default cache;\nexport { Cache }; // for documentation\n","import vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';\nimport vtkDataArray from '@kitware/vtk.js/Common/Core/DataArray';\nimport isTypedArray from '../../utilities/isTypedArray';\nimport {\n genericMetadataProvider,\n getMinMax,\n imageIdToURI,\n} from '../../utilities';\nimport { vtkStreamingOpenGLTexture } from '../../RenderingEngine/vtkClasses';\nimport {\n Metadata,\n Point3,\n IImageVolume,\n Mat3,\n PixelDataTypedArray,\n ImageVolumeProps,\n IImage,\n IImageLoadObject,\n} from '../../types';\nimport cache from '../cache';\nimport * as metaData from '../../metaData';\n\n/** The base class for volume data. It includes the volume metadata\n * and the volume data along with the loading status.\n */\nexport class ImageVolume implements IImageVolume {\n private _imageIds: Array<string>;\n private _imageIdsIndexMap = new Map();\n private _imageURIsIndexMap = new Map();\n /** volume scalar data 3D or 4D */\n protected scalarData: PixelDataTypedArray | Array<PixelDataTypedArray>;\n protected numFrames: number;\n protected totalNumFrames: number;\n protected cornerstoneImageMetaData = null;\n\n /** Read-only unique identifier for the volume */\n readonly volumeId: string;\n\n imageCacheOffsetMap = new Map();\n\n isPreScaled = false;\n\n /** Dimensions of the volume */\n dimensions: Point3;\n /** volume direction in world space */\n direction: Mat3;\n /** volume metadata */\n metadata: Metadata;\n /** volume origin, Note this is an opinionated origin for the volume */\n origin: Point3;\n /** Whether preScaling has been performed on the volume */\n /** volume scaling parameters if it contains scaled data */\n scaling?: {\n PT?: {\n // @TODO: Do these values exist?\n SUVlbmFactor?: number;\n SUVbsaFactor?: number;\n // accessed in ProbeTool\n suvbwToSuvlbm?: number;\n suvbwToSuvbsa?: number;\n };\n };\n /** volume size in bytes */\n sizeInBytes?: number; // Seems weird to pass this in? Why not grab it from scalarData.byteLength\n /** volume spacing in 3d world space */\n spacing: Point3;\n /** volume number of voxels */\n numVoxels: number;\n /** volume image data */\n imageData?: vtkImageData;\n /** open gl texture for the volume */\n vtkOpenGLTexture: any; // No good way of referencing vtk classes as they aren't classes.\n /** load status object for the volume */\n loadStatus?: Record<string, any>;\n /** optional reference volume id if the volume is derived from another volume */\n referencedVolumeId?: string;\n /** optional reference image ids if the volume is derived from a set of images in the image cache */\n referencedImageIds?: Array<string>;\n /** whether the metadata for the pixel spacing is not undefined */\n hasPixelSpacing: boolean;\n /** Property to store additional information */\n additionalDetails?: Record<string, any>;\n\n constructor(props: ImageVolumeProps) {\n const {\n imageIds,\n scalarData,\n scaling,\n dimensions,\n spacing,\n origin,\n direction,\n volumeId,\n referencedVolumeId,\n sizeInBytes,\n imageData,\n metadata,\n referencedImageIds,\n additionalDetails,\n } = props;\n\n this.imageIds = imageIds;\n this.volumeId = volumeId;\n this.metadata = metadata;\n this.dimensions = dimensions;\n this.spacing = spacing;\n this.origin = origin;\n this.direction = direction;\n this.scalarData = scalarData;\n this.sizeInBytes = sizeInBytes;\n this.vtkOpenGLTexture = vtkStreamingOpenGLTexture.newInstance();\n this.numVoxels =\n this.dimensions[0] * this.dimensions[1] * this.dimensions[2];\n\n if (imageData) {\n this.imageData = imageData;\n } else {\n const imageData = vtkImageData.newInstance();\n\n const scalarArray = vtkDataArray.newInstance({\n name: 'Pixels',\n numberOfComponents: 1,\n values: scalarData,\n });\n\n imageData.setDimensions(dimensions);\n imageData.setSpacing(spacing);\n imageData.setDirection(direction);\n imageData.setOrigin(origin);\n imageData.getPointData().setScalars(scalarArray);\n\n this.imageData = imageData;\n }\n\n this.numFrames = this._getNumFrames();\n this._reprocessImageIds();\n this._createCornerstoneImageMetaData();\n\n if (scaling) {\n this.scaling = scaling;\n }\n\n if (referencedVolumeId) {\n this.referencedVolumeId = referencedVolumeId;\n }\n\n if (referencedImageIds) {\n this.referencedImageIds = referencedImageIds;\n }\n\n if (additionalDetails) {\n this.additionalDetails = additionalDetails;\n }\n }\n\n /** return the image ids for the volume if it is made of separated images */\n public get imageIds(): Array<string> {\n return this._imageIds;\n }\n\n /** updates the image ids */\n public set imageIds(newImageIds: Array<string>) {\n this._imageIds = newImageIds;\n this._reprocessImageIds();\n }\n\n private _reprocessImageIds() {\n this._imageIdsIndexMap.clear();\n this._imageURIsIndexMap.clear();\n\n this._imageIds.forEach((imageId, i) => {\n const imageURI = imageIdToURI(imageId);\n\n this._imageIdsIndexMap.set(imageId, i);\n this._imageURIsIndexMap.set(imageURI, i);\n });\n }\n\n cancelLoading: () => void;\n\n /** return true if it is a 4D volume or false if it is 3D volume */\n public isDynamicVolume(): boolean {\n return false;\n }\n\n /**\n * Return the scalar data for 3D volumes or the active scalar data\n * (current time point) for 4D volumes\n */\n public getScalarData(): PixelDataTypedArray {\n if (isTypedArray(this.scalarData)) {\n return <PixelDataTypedArray>this.scalarData;\n }\n\n throw new Error('Unknown scalar data type');\n }\n\n /**\n * return the index of a given imageId\n * @param imageId - imageId\n * @returns imageId index\n */\n public getImageIdIndex(imageId: string): number {\n return this._imageIdsIndexMap.get(imageId);\n }\n\n /**\n * return the index of a given imageURI\n * @param imageId - imageURI\n * @returns imageURI index\n */\n public getImageURIIndex(imageURI: string): number {\n return this._imageURIsIndexMap.get(imageURI);\n }\n\n /**\n * destroy the volume and make it unusable\n */\n destroy(): void {\n // TODO: GPU memory associated with volume is not cleared.\n this.imageData.delete();\n this.imageData = null;\n this.scalarData = null;\n\n this.vtkOpenGLTexture.releaseGraphicsResources();\n this.vtkOpenGLTexture.delete();\n }\n\n /**\n * Return all scalar data objects (buffers) which will be only one for\n * 3D volumes and one per time point for 4D volumes\n * images of each 3D volume is stored\n * @returns scalar data array\n */\n public getScalarDataArrays(): PixelDataTypedArray[] {\n return this.isDynamicVolume()\n ? <PixelDataTypedArray[]>this.scalarData\n : [<PixelDataTypedArray>this.scalarData];\n }\n\n /**\n * Updates the internals of the volume to reflect the changes in the\n * underlying scalar data. This should be called when the scalar data\n * is modified externally\n */\n public modified() {\n this.imageData.modified();\n\n if (this.isDynamicVolume()) {\n throw new Error('Not implemented');\n } else {\n this.scalarData = this.imageData\n .getPointData()\n .getScalars()\n .getData() as PixelDataTypedArray;\n }\n\n this.numFrames = this._getNumFrames();\n }\n\n /**\n * If completelyRemove is true, remove the volume completely from the cache. Otherwise,\n * convert the volume to cornerstone images (stack images) and store it in the cache\n * @param completelyRemove - If true, the image will be removed from the\n * cache completely.\n */\n public decache(completelyRemove = false): void | Array<string> {\n if (completelyRemove) {\n this.removeFromCache();\n } else {\n this.convertToImageSlicesAndCache();\n }\n }\n\n public removeFromCache() {\n cache.removeVolumeLoadObject(this.volumeId);\n }\n\n public getScalarDataLength(): number {\n const { scalarData } = this;\n return this.isDynamicVolume()\n ? (<PixelDataTypedArray[]>scalarData)[0].length\n : (<PixelDataTypedArray>scalarData).length;\n }\n\n /**\n * Returns the number of frames stored in a scalarData object. The number of\n * frames is equal to the number of images for 3D volumes or the number of\n * frames per time poins for 4D volumes.\n * @returns number of frames per volume\n */\n private _getNumFrames(): number {\n const { imageIds, scalarData } = this;\n const scalarDataCount = this.isDynamicVolume() ? scalarData.length : 1;\n\n return imageIds.length / scalarDataCount;\n }\n\n private _getScalarDataLength(): number {\n const { scalarData } = this;\n return this.isDynamicVolume()\n ? (<PixelDataTypedArray[]>scalarData)[0].length\n : (<PixelDataTypedArray>scalarData).length;\n }\n\n /**\n * Creates the metadata required for converting the volume to an cornerstoneImage\n */\n private _createCornerstoneImageMetaData() {\n const { numFrames } = this;\n\n if (numFrames === 0) {\n return;\n }\n\n const bytesPerImage = this.sizeInBytes / numFrames;\n const scalarDataLength = this._getScalarDataLength();\n const numComponents = scalarDataLength / this.numVoxels;\n const pixelsPerImage =\n this.dimensions[0] * this.dimensions[1] * numComponents;\n\n const { PhotometricInterpretation, voiLut, VOILUTFunction } = this.metadata;\n\n let windowCenter = [];\n let windowWidth = [];\n\n if (voiLut && voiLut.length) {\n windowCenter = voiLut.map((voi) => {\n return voi.windowCenter;\n });\n\n windowWidth = voiLut.map((voi) => {\n return voi.windowWidth;\n });\n }\n\n const color = numComponents > 1 ? true : false; //todo: fix this\n\n this.cornerstoneImageMetaData = {\n bytesPerImage,\n numComponents,\n pixelsPerImage,\n windowCenter,\n windowWidth,\n color,\n // we use rgb (3 components) for the color volumes (and not rgba), and not rgba (which is used\n // in some parts of the lib for stack viewing in CPU)\n rgba: false,\n spacing: this.spacing,\n dimensions: this.dimensions,\n photometricInterpretation: PhotometricInterpretation,\n voiLUTFunction: VOILUTFunction,\n invert: PhotometricInterpretation === 'MONOCHROME1',\n };\n }\n\n protected getScalarDataByImageIdIndex(\n imageIdIndex: number\n ): PixelDataTypedArray {\n if (imageIdIndex < 0 || imageIdIndex >= this.imageIds.length) {\n throw new Error('imageIdIndex out of range');\n }\n\n const scalarDataArrays = this.getScalarDataArrays();\n const scalarDataIndex = Math.floor(imageIdIndex / this.numFrames);\n\n return scalarDataArrays[scalarDataIndex];\n }\n\n /**\n * Converts the requested imageId inside the volume to a cornerstoneImage\n * object. It uses the typedArray set method to copy the pixelData from the\n * correct offset in the scalarData to a new array for the image\n *\n * @param imageId - the imageId of the image to be converted\n * @param imageIdIndex - the index of the imageId in the imageIds array\n * @returns image object containing the pixel data, metadata, and other information\n */\n public getCornerstoneImage(imageId: string, imageIdIndex: number): IImage {\n const { imageIds } = this;\n const frameIndex = this.imageIdIndexToFrameIndex(imageIdIndex);\n\n const {\n bytesPerImage,\n pixelsPerImage,\n windowCenter,\n windowWidth,\n numComponents,\n color,\n dimensions,\n spacing,\n invert,\n voiLUTFunction,\n photometricInterpretation,\n } = this.cornerstoneImageMetaData;\n\n // 1. Grab the buffer and it's type\n const scalarData = this.getScalarDataByImageIdIndex(imageIdIndex);\n const volumeBuffer = scalarData.buffer;\n // (not sure if this actually works, TypeScript keeps complaining)\n const TypedArray = scalarData.constructor;\n\n // 2. Given the index of the image and frame length in bytes,\n // create a view on the volume arraybuffer\n const bytePerPixel = bytesPerImage / pixelsPerImage;\n\n let byteOffset = bytesPerImage * frameIndex;\n\n // If there is a discrepancy between the volume typed array\n // and the bitsAllocated for the image. The reason is that VTK uses Float32\n // on the GPU and if the type is not Float32, it will convert it. So for not\n // having a performance issue, we convert all types initially to Float32 even\n // if they are not Float32.\n if (scalarData.BYTES_PER_ELEMENT !== bytePerPixel) {\n byteOffset *= scalarData.BYTES_PER_ELEMENT / bytePerPixel;\n }\n\n // 3. Create a new TypedArray of the same type for the new\n // Image that will be created\n // @ts-ignore\n const imageScalarData = new TypedArray(pixelsPerImage);\n // @ts-ignore\n const volumeBufferView = new TypedArray(\n volumeBuffer,\n byteOffset,\n pixelsPerImage\n );\n\n // 4. Use e.g. TypedArray.set() to copy the data from the larger\n // buffer's view into the smaller one\n imageScalarData.set(volumeBufferView);\n\n // 5. Create an Image Object from imageScalarData and put it into the Image cache\n const volumeImageId = imageIds[imageIdIndex];\n const modalityLutModule =\n metaData.get('modalityLutModule', volumeImageId) || {};\n const minMax = getMinMax(imageScalarData);\n const intercept = modalityLutModule.rescaleIntercept\n ? modalityLutModule.rescaleIntercept\n : 0;\n\n return {\n imageId,\n intercept,\n windowCenter,\n windowWidth,\n voiLUTFunction,\n color,\n rgba: false,\n numComps: numComponents,\n // Note the dimensions were defined as [Columns, Rows, Frames]\n rows: dimensions[1],\n columns: dimensions[0],\n sizeInBytes: imageScalarData.byteLength,\n getPixelData: () => imageScalarData,\n minPixelValue: minMax.min,\n maxPixelValue: minMax.max,\n slope: modalityLutModule.rescaleSlope\n ? modalityLutModule.rescaleSlope\n : 1,\n getCanvas: undefined, // todo: which canvas?\n height: dimensions[0],\n width: dimensions[1],\n columnPixelSpacing: spacing[0],\n rowPixelSpacing: spacing[1],\n invert,\n photometricInterpretation,\n };\n }\n\n /**\n * Converts imageIdIndex into frameIndex which will be the same\n * for 3D volumes but different for 4D volumes. The indices are 0 based.\n */\n protected imageIdIndexToFrameIndex(imageIdIndex: number): number {\n return imageIdIndex % this.numFrames;\n }\n\n /**\n * Converts the requested imageId inside the volume to a cornerstoneImage\n * object. It uses the typedArray set method to copy the pixelData from the\n * correct offset in the scalarData to a new array for the image\n * Duplicate of getCornerstoneImageLoadObject for legacy reasons\n *\n * @param imageId - the imageId of the image to be converted\n * @param imageIdIndex - the index of the imageId in the imageIds array\n * @returns imageLoadObject containing the promise that resolves\n * to the cornerstone image\n */\n public convertToCornerstoneImage(\n imageId: string,\n imageIdIndex: number\n ): IImageLoadObject {\n return this.getCornerstoneImageLoadObject(imageId, imageIdIndex);\n }\n\n /**\n * Converts the requested imageId inside the volume to a cornerstoneImage\n * object. It uses the typedArray set method to copy the pixelData from the\n * correct offset in the scalarData to a new array for the image\n *\n * @param imageId - the imageId of the image to be converted\n * @param imageIdIndex - the index of the imageId in the imageIds array\n * @returns imageLoadObject containing the promise that resolves\n * to the cornerstone image\n */\n public getCornerstoneImageLoadObject(\n imageId: string,\n imageIdIndex: number\n ): IImageLoadObject {\n const image = this.getCornerstoneImage(imageId, imageIdIndex);\n\n const imageLoadObject = {\n promise: Promise.resolve(image),\n };\n\n return imageLoadObject;\n }\n\n /**\n * Returns an array of all the volume's images as Cornerstone images.\n * It iterates over all the imageIds and converts them to Cornerstone images.\n *\n * @returns An array of Cornerstone images.\n */\n public getCornerstoneImages(): IImage[] {\n const { imageIds } = this;\n\n return imageIds.map((imageId, imageIdIndex) => {\n return this.getCornerstoneImage(imageId, imageIdIndex);\n });\n }\n\n /**\n * Converts all the volume images (imageIds) to cornerstoneImages and caches them.\n * It iterates over all the imageIds and convert them until there is no\n * enough space left inside the imageCache. Finally it will decache the Volume.\n *\n */\n public convertToImageSlicesAndCache() {\n // 1. Try to decache images in the volatile Image Cache to provide\n // enough space to store another entire copy of the volume (as Images).\n // If we do not have enough, we will store as many images in the cache\n // as possible, and the rest of the volume will be decached.\n const byteLength = this.sizeInBytes;\n\n if (!this.imageIds?.length) {\n // generate random imageIds\n // check if the referenced volume has imageIds to see how many\n // images we need to generate\n const referencedVolumeId = this.referencedVolumeId;\n\n let numSlices = this.dimensions[2];\n if (referencedVolumeId) {\n const referencedVolume = cache.getVolume(referencedVolumeId);\n numSlices = referencedVolume?.imageIds?.length ?? numSlices;\n }\n\n this.imageIds = Array.from({ length: numSlices }, (_, i) => {\n return `generated:${this.volumeId}:${i}`;\n });\n\n this._reprocessImageIds();\n this.numFrames = this._getNumFrames();\n this._createCornerstoneImageMetaData();\n }\n\n const numImages = this.imageIds.length;\n const { bytesPerImage } = this.cornerstoneImageMetaData;\n let bytesRemaining = cache.decacheIfNecessaryUntilBytesAvailable(\n byteLength,\n this.imageIds\n );\n\n for (let imageIdIndex = 0; imageIdIndex < numImages; imageIdIndex++) {\n const imageId = this.imageIds[imageIdIndex];\n\n bytesRemaining = bytesRemaining - bytesPerImage;\n\n // 2. Convert each imageId to a cornerstone Image object which is\n // resolved inside the promise of imageLoadObject\n const image = this.getCornerstoneImage(imageId, imageIdIndex);\n\n const imageLoadObject = {\n promise: Promise.resolve(image),\n };\n\n // 3. Caching the image\n if (!cache.getImageLoadObject(imageId)) {\n cache.putImageLoadObject(imageId, imageLoadObject).catch((err) => {\n console.error(err);\n });\n }\n\n // 4. If we know we won't be able to add another Image to the cache\n // without breaching the limit, stop here.\n if (bytesRemaining <= bytesPerImage) {\n break;\n }\n\n const imageOrientationPatient = [\n this.direction[0],\n this.direction[1],\n this.direction[2],\n this.direction[3],\n this.direction[4],\n this.direction[5],\n ];\n\n const precision = 6;\n const imagePositionPatient = [\n parseFloat(\n (\n this.origin[0] +\n imageIdIndex * this.direction[6] * this.spacing[0]\n ).toFixed(precision)\n ),\n parseFloat(\n (\n this.origin[1] +\n imageIdIndex * this.direction[7] * this.spacing[1]\n ).toFixed(precision)\n ),\n parseFloat(\n (\n this.origin[2] +\n imageIdIndex * this.direction[8] * this.spacing[2]\n ).toFixed(precision)\n ),\n ];\n\n const pixelData = image.getPixelData();\n const bitsAllocated = pixelData.BYTES_PER_ELEMENT * 8;\n\n const imagePixelModule = {\n // bitsStored: number;\n // samplesPerPixel: number;\n // highBit: number;\n // pixelRepresentation: string;\n // modality: string;\n bitsAllocated,\n photometricInterpretation: image.photometricInterpretation,\n windowWidth: image.windowWidth,\n windowCenter: image.windowCenter,\n voiLUTFunction: image.voiLUTFunction,\n };\n\n const imagePlaneModule = {\n rowCosines: [this.direction[0], this.direction[1], this.direction[2]],\n columnCosines: [\n this.direction[3],\n this.direction[4],\n this.direction[5],\n ],\n pixelSpacing: [this.spacing[0], this.spacing[1]],\n // sliceLocation?: number;\n // sliceThickness?: number;\n // frameOfReferenceUID: string;\n imageOrientationPatient: imageOrientationPatient,\n imagePositionPatient: imagePositionPatient,\n columnPixelSpacing: image.columnPixelSpacing,\n rowPixelSpacing: image.rowPixelSpacing,\n columns: image.columns,\n rows: image.rows,\n };\n\n const generalSeriesModule = {\n // modality: image.modality,\n // seriesInstanceUID: string;\n // seriesNumber: number;\n // studyInstanceUID: string;\n // seriesDate: DicomDateObject;\n // seriesTime: DicomTimeObject;\n };\n\n const metadata = {\n imagePixelModule,\n imagePlaneModule,\n generalSeriesModule,\n };\n\n ['imagePixelModule', 'imagePlaneModule', 'generalSeriesModule'].forEach(\n (type) => {\n genericMetadataProvider.add(imageId, {\n type,\n metadata: metadata[type],\n });\n }\n );\n }\n // 5. When as much of the Volume is processed into Images as possible\n // without breaching the cache limit, remove the Volume\n // but first check if the volume is referenced as a derived\n // volume by another volume, then we need to update their referencedVolumeId\n // to be now the referencedImageIds of this volume\n const otherVolumes = cache.filterVolumesByReferenceId(this.volumeId);\n\n if (otherVolumes.length) {\n otherVolumes.forEach((volume) => {\n volume.referencedImageIds = this.imageIds;\n });\n }\n\n this.removeFromCache();\n\n return this.imageIds;\n }\n}\n\nexport default ImageVolume;\n","/**\n * checks if an object is an instance of a TypedArray\n *\n * @param obj - Object to check\n *\n * @returns True if the object is a TypedArray.\n */\nexport default function isTypedArray(obj: any): boolean {\n return (\n obj instanceof Int8Array ||\n obj instanceof Uint8Array ||\n obj instanceof Uint8ClampedArray ||\n obj instanceof Int16Array ||\n obj instanceof Uint16Array ||\n obj instanceof Int32Array ||\n obj instanceof Uint32Array ||\n obj instanceof Float32Array ||\n obj instanceof Float64Array\n );\n}\n","import { getShouldUseSharedArrayBuffer } from '../init';\n\nconst SMALL_MEMORY_LIMIT = 2 * 1024 * 1024 * 1024 - 2;\nconst BIG_MEMORY_LIMIT = SMALL_MEMORY_LIMIT * 2;\n// Wasm page size\nconst PAGE_SIZE = 65536;\n\n/**\n * A helper function that creates a new Float32Array that utilized a shared\n * array buffer. This allows the array to be updated simultaneously in\n * workers or the main thread. Depending on the system (the CPU, the OS, the Browser)\n * it can take a while until the change is propagated to all contexts.\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer|MDN: SharedArrayBuffer}\n * @remarks\n * We use SharedArrayBuffers in our ImageCache class. It's what allows us to\n * stream data to build a volume. It's important to note that SharedArrayBuffer\n * does not work out of the box for all web browsers. In some, it is disabled\n * behind a flag; in others, it has been removed entirely.\n *\n * @example\n * Creating an array for a Volume with known dimensions:\n * ```\n * const dimensions = [512, 512, 25];\n * const scalarData = createFloat32SharedArray(dimensions[0] * dimensions[1] * dimensions[2]);\n * ```\n *\n * @param length - frame size * number of frames\n * @returns a Float32Array with an underlying SharedArrayBuffer\n * @public\n */\nfunction createFloat32SharedArray(length: number): Float32Array {\n if (!getShouldUseSharedArrayBuffer()) {\n throw new Error(\n 'Your page is NOT cross-origin isolated, see https://developer.mozilla.org/en-US/docs/Web/API/crossOriginIsolated'\n );\n }\n if (window.SharedArrayBuffer === undefined) {\n throw new Error(\n 'SharedArrayBuffer is NOT supported in your browser see https://developer.chrome.com/blog/enabling-shared-array-buffer/'\n );\n }\n\n const byteLength = length * 4;\n\n if (byteLength < SMALL_MEMORY_LIMIT) {\n const sharedArrayBuffer = new SharedArrayBuffer(byteLength);\n return new Float32Array(sharedArrayBuffer);\n } else if (byteLength < BIG_MEMORY_LIMIT) {\n const pages = Math.ceil(byteLength / PAGE_SIZE);\n const memory = new WebAssembly.Memory({\n initial: pages,\n maximum: pages,\n shared: true,\n });\n return new Float32Array(memory.buffer, 0, length);\n }\n}\n\nexport default createFloat32SharedArray;\n","import global from '../global';\n/**\n * A helper function that creates a new Int16 that utilized a shared\n * array buffer. This allows the array to be updated simultaneously in\n * workers or the main thread. Depending on the system (the CPU, the OS, the Browser)\n * it can take a while until the change is propagated to all contexts.\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer|MDN: SharedArrayBuffer}\n * @remarks\n * We use SharedArrayBuffers in our ImageCache class. It's what allows us to\n * stream data to build a volume. It's important to note that SharedArrayBuffer\n * does not work out of the box for all web browsers. In some, it is disabled\n * behind a flag; in others, it has been removed entirely.\n *\n * @example\n * Creating an array for a Volume with known dimensions:\n * ```\n * const dimensions = [512, 512, 25];\n * const scalarData = createInt16SharedArray(dimensions[0] * dimensions[1] * dimensions[2]);\n * ```\n *\n * @param length - frame size * number of frames\n * @returns a Int8Array with an underlying SharedArrayBuffer\n * @public\n */\nfunction createInt16SharedArray(length: number): Int16Array {\n if (!window.crossOriginIsolated) {\n throw new Error(\n 'Your page is NOT cross-origin isolated, see https://developer.mozilla.org/en-US/docs/Web/API/crossOriginIsolated'\n );\n }\n if (window.SharedArrayBuffer === undefined) {\n throw new Error(\n 'SharedArrayBuffer is NOT supported in your browser see https://developer.chrome.com/blog/enabling-shared-array-buffer/'\n );\n }\n\n const sharedArrayBuffer = new SharedArrayBuffer(length * 2);\n\n return new Int16Array(sharedArrayBuffer);\n}\n\nexport default createInt16SharedArray;\n","import global from '../global';\n/**\n * A helper function that creates a new Uint16 that utilized a shared\n * array buffer. This allows the array to be updated simultaneously in\n * workers or the main thread. Depending on the system (the CPU, the OS, the Browser)\n * it can take a while until the change is propagated to all contexts.\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer|MDN: SharedArrayBuffer}\n * @remarks\n * We use SharedArrayBuffers in our ImageCache class. It's what allows us to\n * stream data to build a volume. It's important to note that SharedArrayBuffer\n * does not work out of the box for all web browsers. In some, it is disabled\n * behind a flag; in others, it has been removed entirely.\n *\n * @example\n * Creating an array for a Volume with known dimensions:\n * ```\n * const dimensions = [512, 512, 25];\n * const scalarData = createUint16SharedArray(dimensions[0] * dimensions[1] * dimensions[2]);\n * ```\n *\n * @param length - frame size * number of frames\n * @returns a Uint8Array with an underlying SharedArrayBuffer\n * @public\n */\nfunction createUint16SharedArray(length: number): Uint16Array {\n if (!window.crossOriginIsolated) {\n throw new Error(\n 'Your page is NOT cross-origin isolated, see https://developer.mozilla.org/en-US/docs/Web/API/crossOriginIsolated'\n );\n }\n if (window.SharedArrayBuffer === undefined) {\n throw new Error(\n 'SharedArrayBuffer is NOT supported in your browser see https://developer.chrome.com/blog/enabling-shared-array-buffer/'\n );\n }\n\n const sharedArrayBuffer = new SharedArrayBuffer(length * 2);\n\n return new Uint16Array(sharedArrayBuffer);\n}\n\nexport default createUint16SharedArray;\n","import global from '../global';\nimport { getShouldUseSharedArrayBuffer } from '../init';\n\n/**\n * A helper function that creates a new Float32Array that utilized a shared\n * array buffer. This allows the array to be updated simultaneously in\n * workers or the main thread. Depending on the system (the CPU, the OS, the Browser)\n * it can take a while until the change is propagated to all contexts.\n *\n * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer|MDN: SharedArrayBuffer}\n * @remarks\n * We use SharedArrayBuffers in our ImageCache class. It's what allows us to\n * stream data to build a volume. It's important to note that SharedArrayBuffer\n * does not work out of the box for all web browsers. In some, it is disabled\n * behind a flag; in others, it has been removed entirely.\n *\n * @example\n * Creating an array for a Volume with known dimensions:\n * ```\n * const dimensions = [512, 512, 25];\n * const scalarData = createUint8SharedArray(dimensions[0] * dimensions[1] * dimensions[2]);\n * ```\n *\n * @param length - frame size * number of frames\n * @returns a Uint8Array with an underlying SharedArrayBuffer\n * @public\n */\nfunction createUint8SharedArray(length: number): Uint8Array {\n if (!getShouldUseSharedArrayBuffer()) {\n throw new Error(\n 'Your page is NOT cross-origin isolated, see https://developer.mozilla.org/en-US/docs/Web/API/crossOriginIsolated'\n );\n }\n if (window.SharedArrayBuffer === undefined) {\n throw new Error(\n 'SharedArrayBuffer is NOT supported in your browser see https://developer.chrome.com/blog/enabling-shared-array-buffer/'\n );\n }\n\n const sharedArrayBuffer = new SharedArrayBuffer(length);\n\n return new Uint8Array(sharedArrayBuffer);\n}\n\nexport default createUint8SharedArray;\n","import { get as metaDataGet } from '../metaData';\nimport { ScalingParameters } from '../types';\n\n/**\n * It returns the scaling parameters for the image with the given imageId. This can be\n * used to get passed (as an option) to the imageLoader in order to apply scaling to the image inside\n * the imageLoader.\n * @param imageId - The imageId of the image\n * @returns ScalingParameters\n */\nexport default function getScalingParameters(\n imageId: string\n): ScalingParameters {\n const modalityLutModule = metaDataGet('modalityLutModule', imageId) || {};\n const generalSeriesModule = metaDataGet('generalSeriesModule', imageId) || {};\n\n const { modality } = generalSeriesModule;\n\n const scalingParameters = {\n rescaleSlope: modalityLutModule.rescaleSlope || 1,\n rescaleIntercept: modalityLutModule.rescaleIntercept ?? 0,\n modality,\n };\n\n const suvFactor = metaDataGet('scalingModule', imageId) || {};\n\n return {\n ...scalingParameters,\n ...(modality === 'PT' && {\n suvbw: suvFactor.suvbw,\n suvbsa: suvFactor.suvbsa,\n suvlbm: suvFactor.suvlbm,\n }),\n };\n}\n","import { metaData } from '../';\nimport { Metadata } from '../types';\n\n/**\n * It creates a metadata object for a volume given the imageIds that compose it.\n * It uses the first imageId to get the metadata.\n *\n * @param imageIds - array of imageIds\n * @returns The volume metadata\n */\nexport default function makeVolumeMetadata(imageIds: Array<string>): Metadata {\n const imageId0 = imageIds[0];\n\n const {\n pixelRepresentation,\n bitsAllocated,\n bitsStored,\n highBit,\n photometricInterpretation,\n samplesPerPixel,\n } = metaData.get('imagePixelModule', imageId0);\n\n // Add list of VOIs stored on the DICOM.\n const voiLut = [];\n\n const voiLutModule = metaData.get('voiLutModule', imageId0);\n\n // voiLutModule is not always present\n let voiLUTFunction;\n if (voiLutModule) {\n const { windowWidth, windowCenter } = voiLutModule;\n voiLUTFunction = voiLutModule?.voiLUTFunction;\n\n if (Array.isArray(windowWidth)) {\n for (let i = 0; i < windowWidth.length; i++) {\n voiLut.push({\n windowWidth: windowWidth[i],\n windowCenter: windowCenter[i],\n });\n }\n } else {\n voiLut.push({\n windowWidth: windowWidth,\n windowCenter: windowCenter,\n });\n }\n } else {\n voiLut.push({\n windowWidth: undefined,\n windowCenter: undefined,\n });\n }\n\n const { modality, seriesInstanceUID } = metaData.get(\n 'generalSeriesModule',\n imageId0\n );\n\n const {\n imageOrientationPatient,\n pixelSpacing,\n frameOfReferenceUID,\n columns,\n rows,\n } = metaData.get('imagePlaneModule', imageId0);\n\n // Map to dcmjs-style keywords. This is becoming the standard and makes it\n // Easier to swap out cornerstoneDICOMImageLoader at a later date.\n return {\n BitsAllocated: bitsAllocated,\n BitsStored: bitsStored,\n SamplesPerPixel: samplesPerPixel,\n HighBit: highBit,\n PhotometricInterpretation: photometricInterpretation,\n PixelRepresentation: pixelRepresentation,\n Modality: modality,\n ImageOrientationPatient: imageOrientationPatient,\n PixelSpacing: pixelSpacing,\n FrameOfReferenceUID: frameOfReferenceUID,\n Columns: columns,\n Rows: rows,\n // This is a reshaped object and not a dicom tag:\n voiLut,\n VOILUTFunction: voiLUTFunction,\n SeriesInstanceUID: seriesInstanceUID,\n };\n}\n","import { vec3 } from 'gl-matrix';\nimport { metaData, getConfiguration } from '../';\nimport { Point3 } from '../types';\n\ntype SortedImageIdsItem = {\n zSpacing: number;\n origin: Point3;\n sortedImageIds: Array<string>;\n};\n/**\n * Given an array of imageIds, sort them based on their imagePositionPatient, and\n * also returns the spacing between images and the origin of the reference image\n *\n * @param imageIds - array of imageIds\n * @param scanAxisNormal - [x, y, z] array or gl-matrix vec3\n *\n * @returns The sortedImageIds, zSpacing, and origin of the first image in the series.\n */\nexport default function sortImageIdsAndGetSpacing(\n imageIds: Array<string>,\n scanAxisNormal?: vec3\n): SortedImageIdsItem {\n const {\n imagePositionPatient: referenceImagePositionPatient,\n imageOrientationPatient,\n } = metaData.get('imagePlaneModule', imageIds[0]);\n\n if (!scanAxisNormal) {\n const rowCosineVec = vec3.fromValues(\n imageOrientationPatient[0],\n imageOrientationPatient[1],\n imageOrientationPatient[2]\n );\n const colCosineVec = vec3.fromValues(\n imageOrientationPatient[3],\n imageOrientationPatient[4],\n imageOrientationPatient[5]\n );\n\n scanAxisNormal = vec3.create();\n vec3.cross(scanAxisNormal, rowCosineVec, colCosineVec);\n }\n\n const refIppVec = vec3.create();\n\n // Check if we are using wadouri scheme\n const usingWadoUri = imageIds[0].split(':')[0] === 'wadouri';\n\n vec3.set(\n refIppVec,\n referenceImagePositionPatient[0],\n referenceImagePositionPatient[1],\n referenceImagePositionPatient[2]\n );\n\n let sortedImageIds: string[];\n let zSpacing: number;\n\n function getDistance(imageId: string) {\n const { imagePositionPatient } = metaData.get('imagePlaneModule', imageId);\n\n const positionVector = vec3.create();\n\n vec3.sub(\n positionVector,\n referenceImagePositionPatient,\n imagePositionPatient\n );\n\n return vec3.dot(positionVector, scanAxisNormal);\n }\n\n /**\n * If we are using wadors and so have all image metadata cached ahead of time,\n * then sort by image position in 3D space, and calculate average slice\n * spacing from the entire volume. If not, then use the sampled images (1st\n * and middle) to calculate slice spacing, and use the provided imageId order.\n * Correct sorting must be done ahead of time.\n */\n if (!usingWadoUri) {\n const distanceImagePairs = imageIds.map((imageId) => {\n const distance = getDistance(imageId);\n\n return {\n distance,\n imageId,\n };\n });\n\n distanceImagePairs.sort((a, b) => b.distance - a.distance);\n\n sortedImageIds = distanceImagePairs.map((a) => a.imageId);\n const numImages = distanceImagePairs.length;\n\n // Calculated average spacing.\n // We would need to resample if these are not similar.\n // It should be up to the host app to do this if it needed to.\n zSpacing =\n Math.abs(\n distanceImagePairs[numImages - 1].distance -\n distanceImagePairs[0].distance\n ) /\n (numImages - 1);\n } else {\n // Using wadouri, so we have only prefetched the first, middle, and last\n // images for metadata. Assume initial imageId array order is pre-sorted,\n // but check orientation.\n const prefetchedImageIds = [\n imageIds[0],\n imageIds[Math.floor(imageIds.length / 2)],\n ];\n sortedImageIds = imageIds;\n const firstImageDistance = getDistance(prefetchedImageIds[0]);\n const middleImageDistance = getDistance(prefetchedImageIds[1]);\n if (firstImageDistance - middleImageDistance < 0) {\n sortedImageIds.reverse();\n }\n\n // Calculate average spacing between the first and middle prefetched images,\n // otherwise fall back to DICOM `spacingBetweenSlices`\n const metadataForMiddleImage = metaData.get(\n 'imagePlaneModule',\n prefetchedImageIds[1]\n );\n if (!metadataForMiddleImage) {\n throw new Error('Incomplete metadata required for volume construction.');\n }\n\n const positionVector = vec3.create();\n\n vec3.sub(\n positionVector,\n referenceImagePositionPatient,\n metadataForMiddleImage.imagePositionPatient\n );\n const distanceBetweenFirstAndMiddleImages = vec3.dot(\n positionVector,\n scanAxisNormal\n );\n zSpacing =\n Math.abs(distanceBetweenFirstAndMiddleImages) /\n Math.floor(imageIds.length / 2);\n }\n\n const {\n imagePositionPatient: origin,\n sliceThickness,\n spacingBetweenSlices,\n } = metaData.get('imagePlaneModule', sortedImageIds[0]);\n\n const { strictZSpacingForVolumeViewport } = getConfiguration().rendering;\n\n // We implemented these lines for multiframe dicom files that does not have\n // position for each frame, leading to incorrect calculation of zSpacing = 0\n // If possible, we use the sliceThickness, but we warn about this dicom file\n // weirdness. If sliceThickness is not available, we set to 1 just to render\n if (zSpacing === 0 && !strictZSpacingForVolumeViewport) {\n if (sliceThickness && spacingBetweenSlices) {\n console.log('Could not calculate zSpacing. Using spacingBetweenSlices');\n zSpacing = spacingBetweenSlices;\n } else if (sliceThickness) {\n console.log(\n 'Could not calculate zSpacing and no spacingBetweenSlices. Using sliceThickness'\n );\n zSpacing = sliceThickness;\n } else {\n console.log(\n 'Could not calculate zSpacing. The VolumeViewport visualization is compromised. Setting zSpacing to 1 to render'\n );\n zSpacing = 1;\n }\n }\n const result: SortedImageIdsItem = {\n zSpacing,\n origin,\n sortedImageIds,\n };\n\n return result;\n}\n","import { ScalingParameters } from '../types';\n\n/**\n * Checks if the scaling parameters contain a float rescale value.\n * @param scalingParameters - The scaling parameters to check.\n * @returns True if the scaling parameters contain a float rescale value, false otherwise.\n */\nexport const hasFloatScalingParameters = (\n scalingParameters: ScalingParameters\n): boolean => {\n const hasFloatRescale = Object.values(scalingParameters).some(\n (value) => typeof value === 'number' && !Number.isInteger(value)\n );\n return hasFloatRescale;\n};\n","import cache, { Cache } from './cache';\nimport ImageVolume from './classes/ImageVolume';\nimport { Surface } from './classes/Surface';\n\nexport { ImageVolume, Cache, Surface };\nexport default cache;\n","import { vec3 } from 'gl-matrix';\nimport {\n canRenderFloatTextures,\n getConfiguration,\n getShouldUseSharedArrayBuffer,\n} from '../init';\nimport createFloat32SharedArray from './createFloat32SharedArray';\nimport createInt16SharedArray from './createInt16SharedArray';\nimport createUint16SharedArray from './createUInt16SharedArray';\nimport createUint8SharedArray from './createUint8SharedArray';\nimport getScalingParameters from './getScalingParameters';\nimport makeVolumeMetadata from './makeVolumeMetadata';\nimport sortImageIdsAndGetSpacing from './sortImageIdsAndGetSpacing';\nimport { hasFloatScalingParameters } from './hasFloatScalingParameters';\nimport { ImageVolumeProps, Mat3, Point3 } from '../types';\nimport cache from '../cache';\nimport { Events } from '../enums';\n\nfunction generateVolumePropsFromImageIds(\n imageIds: string[],\n volumeId: string\n): ImageVolumeProps {\n const { useNorm16Texture, preferSizeOverAccuracy } =\n getConfiguration().rendering;\n\n const use16BitDataType = useNorm16Texture || preferSizeOverAccuracy;\n const volumeMetadata = makeVolumeMetadata(imageIds);\n\n // For a streaming volume, the data type cannot rely on CSWIL to load\n // the proper array buffer type. This is because the target buffer container\n // must be decided ahead of time.\n // TODO: move this logic into CSWIL to avoid logic duplication.\n // We check if scaling parameters are negative we choose Int16 instead of\n // Uint16 for cases where BitsAllocated is 16.\n const imageIdIndex = Math.floor(imageIds.length / 2);\n const imageId = imageIds[imageIdIndex];\n const scalingParameters = getScalingParameters(imageId);\n const hasNegativeRescale =\n scalingParameters.rescaleIntercept < 0 ||\n scalingParameters.rescaleSlope < 0;\n\n // The prescale is ALWAYS used with modality LUT, so we can assume that\n // if the rescale slope is not an integer, we need to use Float32\n const floatAfterScale = hasFloatScalingParameters(scalingParameters);\n const canRenderFloat = canRenderFloatTextures();\n\n const {\n BitsAllocated,\n PixelRepresentation,\n PhotometricInterpretation,\n ImageOrientationPatient,\n PixelSpacing,\n Columns,\n Rows,\n } = volumeMetadata;\n\n const rowCosineVec = vec3.fromValues(\n ImageOrientationPatient[0],\n ImageOrientationPatient[1],\n ImageOrientationPatient[2]\n );\n const colCosineVec = vec3.fromValues(\n ImageOrientationPatient[3],\n ImageOrientationPatient[4],\n ImageOrientationPatient[5]\n );\n\n const scanAxisNormal = vec3.create();\n\n vec3.cross(scanAxisNormal, rowCosineVec, colCosineVec);\n\n const { zSpacing, origin, sortedImageIds } = sortImageIdsAndGetSpacing(\n imageIds,\n scanAxisNormal\n );\n\n const numFrames = imageIds.length;\n\n // Spacing goes [1] then [0], as [1] is column spacing (x) and [0] is row spacing (y)\n const spacing = <Point3>[PixelSpacing[1], PixelSpacing[0], zSpacing];\n const dimensions = <Point3>[Columns, Rows, numFrames];\n const direction = [\n ...rowCosineVec,\n ...colCosineVec,\n ...scanAxisNormal,\n ] as Mat3;\n const signed = PixelRepresentation === 1;\n const numComponents = PhotometricInterpretation === 'RGB' ? 3 : 1;\n const useSharedArrayBuffer = getShouldUseSharedArrayBuffer();\n const length = dimensions[0] * dimensions[1] * dimensions[2];\n const handleCache = (sizeInBytes) => {\n if (!cache.isCacheable(sizeInBytes)) {\n throw new Error(Events.CACHE_SIZE_EXCEEDED);\n }\n cache.decacheIfNecessaryUntilBytesAvailable(sizeInBytes);\n };\n\n let scalarData, sizeInBytes;\n switch (BitsAllocated) {\n case 8:\n if (signed) {\n throw new Error(\n '8 Bit signed images are not yet supported by this plugin.'\n );\n }\n sizeInBytes = length * numComponents;\n handleCache(sizeInBytes);\n scalarData = useSharedArrayBuffer\n ? createUint8SharedArray(length * numComponents)\n : new Uint8Array(length * numComponents);\n break;\n\n case 16:\n // Temporary fix for 16 bit images to use Float32\n // until the new dicom image loader handler the conversion\n // correctly\n if (!use16BitDataType || (canRenderFloat && floatAfterScale)) {\n sizeInBytes = length * 4;\n scalarData = useSharedArrayBuffer\n ? createFloat32SharedArray(length)\n : new Float32Array(length);\n\n break;\n }\n\n sizeInBytes = length * 2;\n if (signed || hasNegativeRescale) {\n handleCache(sizeInBytes);\n scalarData = useSharedArrayBuffer\n ? createInt16SharedArray(length)\n : new Int16Array(length);\n break;\n }\n\n if (!signed && !hasNegativeRescale) {\n handleCache(sizeInBytes);\n scalarData = useSharedArrayBuffer\n ? createUint16SharedArray(length)\n : new Uint16Array(length);\n break;\n }\n\n // Default to Float32 again\n sizeInBytes = length * 4;\n handleCache(sizeInBytes);\n scalarData = useSharedArrayBuffer\n ? createFloat32SharedArray(length)\n : new Float32Array(length);\n break;\n\n case 24:\n sizeInBytes = length * numComponents;\n handleCache(sizeInBytes);\n\n // hacky because we don't support alpha channel in dicom\n scalarData = useSharedArrayBuffer\n ? createUint8SharedArray(length * numComponents)\n : new Uint8Array(length * numComponents);\n break;\n case 32:\n sizeInBytes = length * 4;\n handleCache(sizeInBytes);\n scalarData = useSharedArrayBuffer\n ? createFloat32SharedArray(length)\n : new Float32Array(length);\n break;\n default:\n throw new Error(\n `Bits allocated of ${BitsAllocated} is not defined to generate scalarData for the volume.`\n );\n }\n\n return {\n dimensions,\n spacing,\n origin,\n direction,\n scalarData,\n sizeInBytes,\n metadata: volumeMetadata,\n imageIds: sortedImageIds,\n volumeId,\n };\n}\n\nexport { generateVolumePropsFromImageIds };\n","import { PixelDataTypedArray, PixelDataTypedArrayString } from '../types';\n\n/**\n * Creates a target buffer based on the provided options.\n *\n * @param targetBufferType - The type of the target buffer.\n * @param length - The length of the target buffer.\n * @param options - Options for the target buffer. Currently supports\n * `use16BitTexture` and `isVolumeBuffer`.\n * @returns Returns an object containing the number of bytes and the type array\n * constructor of the target buffer, which you then use to create the target buffer\n * with new TypedArrayConstructor(length).\n */\nfunction getBufferConfiguration(\n targetBufferType: PixelDataTypedArrayString,\n length: number,\n options: { use16BitTexture?: boolean; isVolumeBuffer?: boolean } = {}\n): {\n numBytes: number;\n TypedArrayConstructor: new (\n length: number | SharedArrayBuffer\n ) => PixelDataTypedArray;\n} {\n const { use16BitTexture = false, isVolumeBuffer = false } = options;\n\n switch (targetBufferType) {\n case 'Float32Array':\n return { numBytes: length * 4, TypedArrayConstructor: Float32Array };\n case 'Uint8Array':\n return { numBytes: length, TypedArrayConstructor: Uint8Array };\n case 'Uint16Array':\n if (!isVolumeBuffer) {\n return { numBytes: length * 2, TypedArrayConstructor: Uint16Array };\n } else {\n if (use16BitTexture) {\n return { numBytes: length * 2, TypedArrayConstructor: Uint16Array };\n } else {\n console.warn(\n 'Uint16Array is not supported for volume rendering, switching back to Float32Array'\n );\n return { numBytes: length * 4, TypedArrayConstructor: Float32Array };\n }\n }\n case 'Int16Array':\n if (!isVolumeBuffer) {\n return { numBytes: length * 2, TypedArrayConstructor: Int16Array };\n } else {\n if (use16BitTexture) {\n return { numBytes: length * 2, TypedArrayConstructor: Int16Array };\n } else {\n console.warn(\n 'Int16Array is not supported for volume rendering, switching back to Float32Array'\n );\n return { numBytes: length * 4, TypedArrayConstructor: Float32Array };\n }\n }\n default:\n if (targetBufferType) {\n throw new Error(\n 'TargetBuffer should be Float32Array, Uint8Array, Uint16Array, or Int16Array'\n );\n } else {\n // Use Float32Array if no targetBuffer is provided\n return { numBytes: length * 4, TypedArrayConstructor: Float32Array };\n }\n }\n}\n\nexport { getBufferConfiguration };\n","import cache, { ImageVolume } from '../cache';\nimport { Events } from '../enums';\nimport eventTarget from '../eventTarget';\nimport { getConfiguration, getShouldUseSharedArrayBuffer } from '../init';\n\n/**\n * This function will check if the cache optimization is enabled and if it is\n * it will check if the created volume was derived from an already cached stack\n * of images, if so it will go back to the image cache and create a view at the\n * correct offset of the bigger volume array buffer, this will save memory.\n *\n * @param volumeId - The volumeId that will be checked for cache optimization\n */\nexport function setupCacheOptimizationEventListener(volumeId) {\n const { enableCacheOptimization } = getConfiguration();\n const shouldUseSAB = getShouldUseSharedArrayBuffer();\n\n const performOptimization = enableCacheOptimization && shouldUseSAB;\n if (!performOptimization) {\n return;\n }\n\n eventTarget.addEventListenerOnce(\n Events.IMAGE_VOLUME_LOADING_COMPLETED,\n (evt) => {\n if (evt.detail.volumeId !== volumeId) {\n return;\n }\n\n const volume = cache.getVolume(volumeId);\n\n performCacheOptimizationForVolume(volume);\n }\n );\n}\n\n/**\n * Performs cache optimization for a volume by replacing the pixel data of each image\n * in the image cache (if found) with a view of the volume's scalar data.\n * @param options - The options for cache optimization.\n * @param options.volumeId - The ID of the volume.\n */\nexport function performCacheOptimizationForVolume(volume) {\n if (!(volume instanceof ImageVolume)) {\n return;\n }\n\n const scalarData = volume.getScalarData();\n\n volume.imageCacheOffsetMap.size > 0\n ? _processImageCacheOffsetMap(volume, scalarData)\n : _processVolumeImages(volume, scalarData);\n}\n\n/**\n * This function will process the volume images and replace the pixel data of each\n * image in the image cache (if found) with a view of the volume's scalar data.\n * This function is used when the volume is derived from an already cached stack\n * of images.\n *\n * @param volume - The volume to process.\n * @param scalarData - The scalar data to use for the volume.\n */\nfunction _processImageCacheOffsetMap(volume, scalarData) {\n volume.imageCacheOffsetMap.forEach(({ offset }, imageId) => {\n const image = cache.getImage(imageId);\n if (!image) {\n return;\n }\n\n _updateImageWithScalarDataView(image, scalarData, offset);\n cache.decrementImageCacheSize(image.sizeInBytes);\n });\n}\n\n/**\n * This function will process the volume images and replace the pixel data of each\n * image in the image cache (if found) with a view of the volume's scalar data.\n * This function is used when the volume is not derived from an already cached stack\n * of images.\n *\n * @param volume - The volume to process.\n * @param scalarData - The scalar data to use for the volume.\n */\nfunction _processVolumeImages(volume, scalarData) {\n let compatibleScalarData = scalarData;\n\n const sampleImageIdWithImage = volume.imageIds.find((imageId) => {\n const image = cache.getImage(imageId);\n return image;\n });\n\n if (!sampleImageIdWithImage) {\n return;\n }\n\n const sampleImage = cache.getImage(sampleImageIdWithImage);\n const samplePixelData =\n sampleImage.imageFrame?.pixelData || sampleImage.getPixelData();\n\n // Check if the types of scalarData and pixelData are different.\n if (scalarData.constructor !== samplePixelData.constructor) {\n // If so, create a new typed array of the same type as pixelData and copy the values from scalarData.\n compatibleScalarData = new samplePixelData.constructor(scalarData.length);\n\n // Copy values from scalarData to compatibleScalarData.\n compatibleScalarData.set(scalarData);\n }\n\n volume.imageIds.forEach((imageId) => {\n const image = cache.getImage(imageId);\n if (!image) {\n return;\n }\n\n const index = volume.getImageIdIndex(imageId);\n const offset = index * image.getPixelData().byteLength;\n\n _updateImageWithScalarDataView(image, compatibleScalarData, offset);\n cache.decrementImageCacheSize(image.sizeInBytes);\n });\n}\n\nfunction _updateImageWithScalarDataView(image, scalarData, offset) {\n const pixelData = image.imageFrame\n ? image.imageFrame.pixelData\n : image.getPixelData();\n\n const view = new pixelData.constructor(\n scalarData.buffer,\n offset,\n pixelData.length\n );\n\n image.getPixelData = () => view;\n\n if (image.imageFrame) {\n image.imageFrame.pixelData = view;\n }\n\n image.bufferView = {\n buffer: scalarData.buffer,\n offset,\n };\n}\n","import '@kitware/vtk.js/Rendering/Profiles/Volume';\n\nimport vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';\nimport type { vtkImageData as vtkImageDataType } from '@kitware/vtk.js/Common/DataModel/ImageData';\nimport vtkDataArray from '@kitware/vtk.js/Common/Core/DataArray';\n\nimport { ImageVolume } from '../cache/classes/ImageVolume';\nimport cache from '../cache/cache';\nimport Events from '../enums/Events';\nimport eventTarget from '../eventTarget';\nimport triggerEvent from '../utilities/triggerEvent';\nimport cloneDeep from 'lodash.clonedeep';\n\nimport {\n createUint16SharedArray,\n createUint8SharedArray,\n createFloat32SharedArray,\n generateVolumePropsFromImageIds,\n getBufferConfiguration,\n uuidv4,\n} from '../utilities';\nimport {\n Point3,\n Metadata,\n EventTypes,\n Mat3,\n IImageVolume,\n VolumeLoaderFn,\n IDynamicImageVolume,\n PixelDataTypedArray,\n IVolumeLoadObject,\n PixelDataTypedArrayString,\n} from '../types';\nimport { getConfiguration, getShouldUseSharedArrayBuffer } from '../init';\nimport {\n performCacheOptimizationForVolume,\n setupCacheOptimizationEventListener,\n} from '../utilities/cacheUtils';\n\ninterface VolumeLoaderOptions {\n imageIds: Array<string>;\n}\n\ninterface DerivedVolumeOptions {\n volumeId: string;\n targetBuffer?: {\n type: PixelDataTypedArrayString;\n sharedArrayBuffer?: boolean;\n };\n}\ninterface LocalVolumeOptions {\n metadata: Metadata;\n dimensions: Point3;\n spacing: Point3;\n origin: Point3;\n direction: Mat3;\n scalarData?: PixelDataTypedArray;\n imageIds?: Array<string>;\n referencedImageIds?: Array<string>;\n referencedVolumeId?: string;\n targetBuffer?: {\n type: PixelDataTypedArrayString;\n sharedArrayBuffer?: boolean;\n };\n}\n\n/**\n * Adds a single scalar data to a 3D volume\n */\nfunction addScalarDataToImageData(\n imageData: vtkImageDataType,\n scalarData: PixelDataTypedArray,\n dataArrayAttrs\n) {\n const scalarArray = vtkDataArray.newInstance({\n name: `Pixels`,\n values: scalarData,\n ...dataArrayAttrs,\n });\n\n imageData.getPointData().setScalars(scalarArray);\n}\n\n/**\n * Adds multiple scalar data (time points) to a 4D volume\n */\nfunction addScalarDataArraysToImageData(\n imageData: vtkImageDataType,\n scalarDataArrays: PixelDataTypedArray[],\n dataArrayAttrs\n) {\n scalarDataArrays.forEach((scalarData, i) => {\n const vtkScalarArray = vtkDataArray.newInstance({\n name: `timePoint-${i}`,\n values: scalarData,\n ...dataArrayAttrs,\n });\n\n imageData.getPointData().addArray(vtkScalarArray);\n });\n\n // Set the first as active otherwise nothing is displayed on the screen\n imageData.getPointData().setActiveScalars('timePoint-0');\n}\n\nfunction createInternalVTKRepresentation(\n volume: IImageVolume\n): vtkImageDataType {\n const { dimensions, metadata, spacing, direction, origin } = volume;\n const { PhotometricInterpretation } = metadata;\n\n let numComponents = 1;\n if (PhotometricInterpretation === 'RGB') {\n numComponents = 3;\n }\n\n const imageData = vtkImageData.newInstance();\n const dataArrayAttrs = { numberOfComponents: numComponents };\n\n imageData.setDimensions(dimensions);\n imageData.setSpacing(spacing);\n imageData.setDirection(direction);\n imageData.setOrigin(origin);\n\n // Add scalar data to 3D or 4D volume\n if (volume.isDynamicVolume()) {\n const scalarDataArrays = (<IDynamicImageVolume>(\n volume\n )).getScalarDataArrays();\n\n addScalarDataArraysToImageData(imageData, scalarDataArrays, dataArrayAttrs);\n } else {\n const scalarData = volume.getScalarData();\n\n addScalarDataToImageData(imageData, scalarData, dataArrayAttrs);\n }\n\n return imageData;\n}\n\n/**\n * This module deals with VolumeLoaders and loading volumes\n */\n\nconst volumeLoaders = {};\n\nlet unknownVolumeLoader;\n\n/**\n * Load a volume using a registered Cornerstone Volume Loader.\n *\n * The volume loader that is used will be\n * determined by the volume loader scheme matching against the volumeId.\n *\n * @param volumeId - A Cornerstone Volume Object's volumeId\n * @param options - Options to be passed to the Volume Loader. Options\n * contain the ImageIds that is passed to the loader\n *\n * @returns An Object which can be used to act after a volume is loaded or loading fails\n *\n */\nfunction loadVolumeFromVolumeLoader(\n volumeId: string,\n options?: VolumeLoaderOptions\n): IVolumeLoadObject {\n const colonIndex = volumeId.indexOf(':');\n const scheme = volumeId.substring(0, colonIndex);\n let loader = volumeLoaders[scheme];\n\n if (loader === undefined || loader === null) {\n if (\n unknownVolumeLoader == null ||\n typeof unknownVolumeLoader !== 'function'\n ) {\n throw new Error(\n `No volume loader for scheme ${scheme} has been registered`\n );\n }\n\n loader = unknownVolumeLoader;\n }\n\n const volumeLoadObject = loader(volumeId, options);\n\n setupCacheOptimizationEventListener(volumeId);\n\n // Broadcast a volume loaded event once the image is loaded\n volumeLoadObject.promise.then(\n function (volume) {\n triggerEvent(eventTarget, Events.VOLUME_LOADED, { volume });\n },\n function (error) {\n const errorObject: EventTypes.VolumeLoadedFailedEventDetail = {\n volumeId,\n error,\n };\n\n triggerEvent(eventTarget, Events.VOLUME_LOADED_FAILED, errorObject);\n }\n );\n\n return volumeLoadObject;\n}\n\n/**\n * Loads a volume given a volumeId and optional priority and returns a promise which will resolve to\n * the loaded image object or fail if an error occurred. The loaded image is not stored in the cache.\n *\n * @param volumeId - A Cornerstone Image Object's volumeId\n * @param options - Options to be passed to the Volume Loader\n *\n * @returns An Object which can be used to act after an image is loaded or loading fails\n */\nexport function loadVolume(\n volumeId: string,\n options: VolumeLoaderOptions = { imageIds: [] }\n): Promise<IImageVolume> {\n if (volumeId === undefined) {\n throw new Error('loadVolume: parameter volumeId must not be undefined');\n }\n\n let volumeLoadObject = cache.getVolumeLoadObject(volumeId);\n\n if (volumeLoadObject !== undefined) {\n return volumeLoadObject.promise;\n }\n\n volumeLoadObject = loadVolumeFromVolumeLoader(volumeId, options);\n\n return volumeLoadObject.promise.then((volume: IImageVolume) => {\n volume.imageData = createInternalVTKRepresentation(volume);\n return volume;\n });\n}\n\n/**\n * Loads an image given an volumeId and optional priority and returns a promise which will resolve to\n * the loaded image object or fail if an error occurred. The image is stored in the cache.\n *\n * @param volumeId - A Cornerstone Image Object's volumeId\n * @param options - Options to be passed to the Volume Loader\n *\n * @returns Volume Loader Object\n */\nexport async function createAndCacheVolume(\n volumeId: string,\n options?: VolumeLoaderOptions\n): Promise<Record<string, any>> {\n if (volumeId === undefined) {\n throw new Error(\n 'createAndCacheVolume: parameter volumeId must not be undefined'\n );\n }\n\n let volumeLoadObject = cache.getVolumeLoadObject(volumeId);\n\n if (volumeLoadObject !== undefined) {\n return volumeLoadObject.promise;\n }\n\n volumeLoadObject = loadVolumeFromVolumeLoader(volumeId, options);\n\n volumeLoadObject.promise.then((volume: IImageVolume) => {\n volume.imageData = createInternalVTKRepresentation(volume);\n });\n\n cache.putVolumeLoadObject(volumeId, volumeLoadObject).catch((err) => {\n throw err;\n });\n\n return volumeLoadObject.promise;\n}\n\n/**\n * Based on a referencedVolumeId, it will build and cache a new volume. If\n * no scalarData is specified in the options, an empty derived volume will be\n * created that matches the image metadata of the referenceVolume. If scalarData\n * is given, it will be used to generate the intensity values for the derivedVolume.\n * Finally, it will save the volume in the cache.\n * @param referencedVolumeId - the volumeId from which the new volume will get its metadata\n * @param options - DerivedVolumeOptions {uid: derivedVolumeUID, targetBuffer: { type: Float32Array | Uint8Array |\n * Uint16Array | Uint32Array }, scalarData: if provided}\n *\n * @returns ImageVolume\n */\nexport async function createAndCacheDerivedVolume(\n referencedVolumeId: string,\n options: DerivedVolumeOptions\n): Promise<IImageVolume> {\n const referencedVolume = cache.getVolume(referencedVolumeId);\n if (!referencedVolume) {\n throw new Error(\n `Cannot created derived volume: Referenced volume with id ${referencedVolumeId} does not exist.`\n );\n }\n\n let { volumeId } = options;\n const { targetBuffer } = options;\n\n if (volumeId === undefined) {\n volumeId = uuidv4();\n }\n\n const { metadata, dimensions, spacing, origin, direction } = referencedVolume;\n const scalarData = referencedVolume.getScalarData();\n const scalarLength = scalarData.length;\n\n const { volumeScalarData, numBytes } = generateVolumeScalarData(\n targetBuffer,\n scalarLength\n );\n\n // Todo: handle more than one component for segmentation (RGB)\n const scalarArray = vtkDataArray.newInstance({\n name: 'Pixels',\n numberOfComponents: 1,\n values: volumeScalarData,\n });\n\n const derivedImageData = vtkImageData.newInstance();\n\n derivedImageData.setDimensions(dimensions);\n derivedImageData.setSpacing(spacing);\n derivedImageData.setDirection(direction);\n derivedImageData.setOrigin(origin);\n derivedImageData.getPointData().setScalars(scalarArray);\n\n const derivedVolume = new ImageVolume({\n volumeId,\n metadata: structuredClone(metadata),\n dimensions: [dimensions[0], dimensions[1], dimensions[2]],\n spacing,\n origin,\n direction,\n imageData: derivedImageData,\n scalarData: volumeScalarData,\n sizeInBytes: numBytes,\n imageIds: [],\n referencedVolumeId,\n });\n\n const volumeLoadObject = {\n promise: Promise.resolve(derivedVolume),\n };\n\n await cache.putVolumeLoadObject(volumeId, volumeLoadObject);\n\n return derivedVolume;\n}\n\n/**\n * Creates and cache a volume based on a set of provided properties including\n * dimensions, spacing, origin, direction, metadata, scalarData. It should be noted that\n * scalarData should be provided for this function to work. If a volume with the same\n * Id exists in the cache it returns it immediately.\n * @param options - { scalarData, metadata, dimensions, spacing, origin, direction }\n * @param volumeId - Id of the generated volume\n *\n * @returns ImageVolume\n */\nexport function createLocalVolume(\n options: LocalVolumeOptions,\n volumeId: string,\n preventCache = false\n): IImageVolume {\n const { metadata, dimensions, spacing, origin, direction, targetBuffer } =\n options;\n\n let { scalarData } = options;\n\n // Define the valid data types for scalarData\n const validDataTypes = [\n 'Uint8Array',\n 'Float32Array',\n 'Uint16Array',\n 'Int16Array',\n ];\n\n const scalarLength = dimensions[0] * dimensions[1] * dimensions[2];\n\n // Check if scalarData is provided and is of a valid type\n if (!scalarData || !validDataTypes.includes(scalarData.constructor.name)) {\n // Check if targetBuffer is provided and has a valid type\n if (!targetBuffer?.type || !validDataTypes.includes(targetBuffer.type)) {\n throw new Error(\n 'createLocalVolume: parameter scalarData must be provided and must be either Uint8Array, Float32Array, Uint16Array or Int16Array'\n );\n }\n\n // Generate volume scalar data if scalarData is not provided or invalid\n ({ volumeScalarData: scalarData } = generateVolumeScalarData(\n targetBuffer,\n scalarLength\n ));\n }\n\n // Todo: handle default values for spacing, origin, direction if not provided\n if (volumeId === undefined) {\n volumeId = uuidv4();\n }\n\n const cachedVolume = cache.getVolume(volumeId);\n\n if (cachedVolume) {\n return cachedVolume as IImageVolume;\n }\n\n const numBytes = scalarData ? scalarData.buffer.byteLength : scalarLength * 4;\n\n // check if there is enough space in unallocated + image Cache\n const isCacheable = cache.isCacheable(numBytes);\n if (!isCacheable) {\n throw new Error(Events.CACHE_SIZE_EXCEEDED);\n }\n\n const scalarArray = vtkDataArray.newInstance({\n name: 'Pixels',\n numberOfComponents: 1,\n values: scalarData,\n });\n\n const imageData = vtkImageData.newInstance();\n\n imageData.setDimensions(dimensions);\n imageData.setSpacing(spacing);\n imageData.setDirection(direction);\n imageData.setOrigin(origin);\n imageData.getPointData().setScalars(scalarArray);\n\n const derivedVolume = new ImageVolume({\n volumeId,\n metadata: structuredClone(metadata),\n dimensions: [dimensions[0], dimensions[1], dimensions[2]],\n spacing,\n origin,\n direction,\n imageData: imageData,\n scalarData,\n sizeInBytes: numBytes,\n referencedImageIds: options.referencedImageIds || [],\n referencedVolumeId: options.referencedVolumeId,\n imageIds: options.imageIds || [],\n });\n\n if (preventCache) {\n return derivedVolume;\n }\n\n const volumeLoadObject = {\n promise: Promise.resolve(derivedVolume),\n };\n cache.putVolumeLoadObject(volumeId, volumeLoadObject);\n\n return derivedVolume;\n}\n\nexport async function createAndCacheVolumeFromImages(\n volumeId: string,\n imageIds: string[],\n options: {\n preventCache?: boolean;\n additionalDetails?: Record<string, any>;\n } = {}\n): Promise<IImageVolume> {\n const { preventCache = false } = options;\n\n if (imageIds === undefined) {\n throw new Error(\n 'createAndCacheVolumeFromImages: parameter imageIds must not be undefined'\n );\n }\n\n if (volumeId === undefined) {\n throw new Error(\n 'createAndCacheVolumeFromImages: parameter volumeId must not be undefined'\n );\n }\n\n const cachedVolume = cache.getVolume(volumeId);\n\n if (cachedVolume) {\n return Promise.resolve(cachedVolume);\n }\n\n const volumeProps = generateVolumePropsFromImageIds(imageIds, volumeId);\n\n // volume is an empty volume, we need to load the data from the imageIds\n // into the volume scalarData\n\n // it is important to get the imageIds from the volumeProps\n // since they are sorted\n const imagePromises = volumeProps.imageIds.map((imageId, imageIdIndex) => {\n const imageLoadObject = cache.getImageLoadObject(imageId);\n\n return imageLoadObject.promise.then((image) => {\n const pixelData = image.getPixelData();\n const offset = imageIdIndex * image.rows * image.columns;\n\n (volumeProps.scalarData as PixelDataTypedArray).set(pixelData, offset);\n });\n });\n\n await Promise.all(imagePromises);\n\n const volume = new ImageVolume({\n ...volumeProps,\n referencedImageIds: imageIds,\n ...options,\n });\n\n // since we generated the volume from images, we can optimize the cache\n // by replacing the pixelData of the images with a view of the volume's\n // scalarData\n performCacheOptimizationForVolume(volume);\n\n const volumeLoadObject = {\n promise: Promise.resolve(volume),\n };\n\n if (preventCache) {\n return volumeLoadObject.promise;\n }\n\n cache.putVolumeLoadObject(volumeId, volumeLoadObject);\n\n return volumeLoadObject.promise;\n}\n\n/**\n * Registers an volumeLoader plugin with cornerstone for the specified scheme\n *\n * @param scheme - The scheme to use for this volume loader (e.g. 'dicomweb', 'wadouri', 'http')\n * @param volumeLoader - A Cornerstone Volume Loader function\n */\nexport function registerVolumeLoader(\n scheme: string,\n volumeLoader: VolumeLoaderFn\n): void {\n volumeLoaders[scheme] = volumeLoader;\n}\n\n/** Gets the array of volume loader schemes */\nexport function getVolumeLoaderSchemes(): string[] {\n return Object.keys(volumeLoaders);\n}\n\n/**\n * Registers a new unknownVolumeLoader and returns the previous one\n *\n * @param volumeLoader - A Cornerstone Volume Loader\n *\n * @returns The previous Unknown Volume Loader\n */\nexport function registerUnknownVolumeLoader(\n volumeLoader: VolumeLoaderFn\n): VolumeLoaderFn | undefined {\n const oldVolumeLoader = unknownVolumeLoader;\n\n unknownVolumeLoader = volumeLoader;\n\n return oldVolumeLoader;\n}\n\nexport function getUnknownVolumeLoaderSchema(): string {\n return unknownVolumeLoader.name;\n}\n\n/**\n * Creates and caches a derived segmentation volume based on a referenced volume.\n * This is basically a utility method since for the segmentations we have to specify\n * Uint8Array as the targetBuffer type for now until we support other types.\n *\n * @param referencedVolumeId - The ID of the referenced volume.\n * @param options - The options for creating the derived volume.\n * @returns A promise that resolves to the created derived segmentation volume.\n */\nexport async function createAndCacheDerivedSegmentationVolume(\n referencedVolumeId: string,\n options = {} as DerivedVolumeOptions\n): Promise<IImageVolume> {\n return createAndCacheDerivedVolume(referencedVolumeId, {\n ...options,\n targetBuffer: {\n type: 'Uint8Array',\n },\n });\n}\n\n/**\n * Creates a local segmentation volume.\n *\n * @param options - The options for creating the volume.\n * @param volumeId - The ID of the volume.\n * @param preventCache - Whether to prevent caching the volume.\n * @returns A promise that resolves to the created image volume.\n */\nexport async function createLocalSegmentationVolume(\n options: LocalVolumeOptions,\n volumeId: string,\n preventCache = false\n): Promise<IImageVolume> {\n if (!options.scalarData) {\n options.scalarData = new Uint8Array(\n options.dimensions[0] * options.dimensions[1] * options.dimensions[2]\n );\n }\n\n return createLocalVolume(options, volumeId, preventCache);\n}\n\n/**\n * This function generates volume scalar data based on the provided target buffer and scalar length.\n * It checks if the cache can accommodate the data size and throws an error if it exceeds the cache size.\n * If a shared array buffer is available in the target buffer, it uses that to create the typed array.\n * Otherwise, it creates a typed array based on the scalar length.\n *\n * @param targetBuffer - The target buffer object which may contain a type and a shared array buffer.\n * @param scalarLength - The scalar length for creating the typed array.\n * @param useNorm16Texture - A flag to specify whether to use a 16-bit texture or not.\n * @returns The volume scalar data as a typed array.\n */\nfunction generateVolumeScalarData(\n targetBuffer: {\n type: PixelDataTypedArrayString;\n sharedArrayBuffer?: boolean;\n },\n scalarLength: number\n) {\n const { useNorm16Texture } = getConfiguration().rendering;\n\n const { TypedArrayConstructor, numBytes } = getBufferConfiguration(\n targetBuffer?.type,\n scalarLength,\n {\n use16BitTexture: useNorm16Texture,\n isVolumeBuffer: true,\n }\n );\n\n const isCacheable = cache.isCacheable(numBytes);\n if (!isCacheable) {\n throw new Error(Events.CACHE_SIZE_EXCEEDED);\n }\n\n let volumeScalarData;\n if (targetBuffer?.sharedArrayBuffer ?? getShouldUseSharedArrayBuffer()) {\n switch (targetBuffer.type) {\n case 'Float32Array':\n volumeScalarData = createFloat32SharedArray(scalarLength);\n break;\n case 'Uint8Array':\n volumeScalarData = createUint8SharedArray(scalarLength);\n break;\n case 'Uint16Array':\n volumeScalarData = createUint16SharedArray(scalarLength);\n break;\n case 'Int16Array':\n volumeScalarData = createUint16SharedArray(scalarLength);\n break;\n default:\n throw new Error(\n 'generateVolumeScalarData: SharedArrayBuffer is not supported for the specified target buffer type'\n );\n }\n } else {\n volumeScalarData = new TypedArrayConstructor(scalarLength);\n }\n\n return { volumeScalarData, numBytes };\n}\n","import macro from '@kitware/vtk.js/macros';\nimport vtkVolumeMapper from '@kitware/vtk.js/Rendering/Core/VolumeMapper';\n\n/**\n * vtkSharedVolumeMapper - A derived class of the core vtkVolumeMapper class\n * the scalar texture in as an argument. This is so we can share the same texture\n * memory across different mappers/actors, so we don't duplicate memory usage.\n *\n *\n *\n * @param {*} publicAPI The public API to extend\n * @param {*} model The private model to extend.\n * @hidden\n */\nfunction vtkSharedVolumeMapper(publicAPI, model) {\n model.classHierarchy.push('vtkSharedVolumeMapper');\n\n const superDelete = publicAPI.delete;\n publicAPI.delete = () => {\n model.scalarTexture = null;\n superDelete();\n };\n}\n\n// ----------------------------------------------------------------------------\n// Object factory\n// ----------------------------------------------------------------------------\n\n// ----------------------------------------------------------------------------\n\nconst DEFAULT_VALUES = {\n scalarTexture: null,\n};\n\nexport function extend(publicAPI, model, initialValues = {}) {\n Object.assign(model, DEFAULT_VALUES, initialValues);\n\n vtkVolumeMapper.extend(publicAPI, model, initialValues);\n\n macro.setGet(publicAPI, model, ['scalarTexture']);\n\n // Object methods\n vtkSharedVolumeMapper(publicAPI, model);\n}\n\n// ----------------------------------------------------------------------------\n\nexport const newInstance = macro.newInstance(extend, 'vtkSharedVolumeMapper');\n\n// ----------------------------------------------------------------------------\n\nexport default { newInstance, extend };\n","import { vtkSharedVolumeMapper } from '../vtkClasses';\nimport { getConfiguration } from '../../init';\n/**\n * Given an imageData and a vtkOpenGLTexture, it creates a \"shared\" vtk volume mapper\n * from which various volume actors can be created.\n *\n * @param imageData - the vtkImageData object that contains the data to\n * render.\n * @param vtkOpenGLTexture - The vtkOpenGLTexture that will be used to render\n * the volume.\n * @returns The volume mapper.\n */\nexport default function createVolumeMapper(\n imageData: any,\n vtkOpenGLTexture: any\n): any {\n const volumeMapper = vtkSharedVolumeMapper.newInstance();\n\n if (getConfiguration().rendering.preferSizeOverAccuracy) {\n volumeMapper.setPreferSizeOverAccuracy(true);\n }\n\n volumeMapper.setInputData(imageData);\n\n const spacing = imageData.getSpacing();\n // Set the sample distance to half the mean length of one side. This is where the divide by 6 comes from.\n // https://github.com/Kitware/VTK/blob/6b559c65bb90614fb02eb6d1b9e3f0fca3fe4b0b/Rendering/VolumeOpenGL2/vtkSmartVolumeMapper.cxx#L344\n const sampleDistance = (spacing[0] + spacing[1] + spacing[2]) / 6;\n\n // This is to allow for good pixel level image quality.\n // Todo: why we are setting this to 4000? Is this a good number? it should be configurable\n volumeMapper.setMaximumSamplesPerRay(4000);\n volumeMapper.setSampleDistance(sampleDistance);\n volumeMapper.setScalarTexture(vtkOpenGLTexture);\n\n return volumeMapper;\n}\n","import { RequestPoolManager } from './requestPoolManager';\nimport RequestType from '../enums/RequestType';\n\n/**\n * You can use the imageLoadPoolManager to load images, by providing a `requestFn`\n * that returns a promise for the image. You can provide a `type` to specify the type of\n * request (interaction, thumbnail, prefetch), and you can provide additional details\n * that will be passed to the requestFn. Below is an example of a requestFn that loads\n * an image from an imageId:\n *\n * ```javascript\n *\n * const priority = -5\n * const requestType = RequestType.Interaction\n * const additionalDetails = { imageId }\n * const options = {\n * targetBuffer: {\n * type: 'Float32Array',\n * offset: null,\n * length: null,\n * },\n * preScale: {\n * enabled: true,\n * },\n * }\n *\n * imageLoadPoolManager.addRequest(\n * loadAndCacheImage(imageId, options).then(() => { // set on viewport}),\n * requestType,\n * additionalDetails,\n * priority\n * )\n * ```\n */\nconst imageLoadPoolManager = new RequestPoolManager('imageLoadPool');\n\nimageLoadPoolManager.grabDelay = 0;\n\nimageLoadPoolManager.setMaxSimultaneousRequests(RequestType.Interaction, 1000);\nimageLoadPoolManager.setMaxSimultaneousRequests(RequestType.Thumbnail, 1000);\nimageLoadPoolManager.setMaxSimultaneousRequests(RequestType.Prefetch, 1000);\n\nexport default imageLoadPoolManager;\n","import cache from '../cache/cache';\nimport { ImageVolume } from '../cache';\nimport Events from '../enums/Events';\nimport eventTarget from '../eventTarget';\nimport {\n genericMetadataProvider,\n getBufferConfiguration,\n triggerEvent,\n uuidv4,\n} from '../utilities';\nimport {\n IImage,\n ImageLoaderFn,\n IImageLoadObject,\n EventTypes,\n Point2,\n Point3,\n Mat3,\n PixelDataTypedArrayString,\n PixelDataTypedArray,\n} from '../types';\nimport imageLoadPoolManager from '../requestPool/imageLoadPoolManager';\nimport { metaData } from '../';\n\nexport interface ImageLoaderOptions {\n priority: number;\n requestType: string;\n additionalDetails?: Record<string, unknown>;\n ignoreCache?: boolean;\n}\n\ninterface DerivedImages {\n imageIds: Array<string>;\n promises: Array<Promise<IImage>>;\n}\n\ntype LocalImageOptions = {\n scalarData?: PixelDataTypedArray;\n targetBufferType?: PixelDataTypedArrayString;\n dimensions?: Point2;\n spacing?: Point3;\n origin?: Point3;\n direction?: Mat3;\n /**\n * Skip creation of the actual buffer object.\n * In fact, this creates a very short buffer, as there are lots of places\n * assuming a buffer exists.\n * This can be used when there are alternative representations of the image data.\n */\n skipCreateBuffer?: boolean;\n /**\n * A method to call to update the image object when it gets added to the cache.\n * This can be used to create alternative representations of the image data,\n * such as a VoxelManager.\n */\n onCacheAdd?: (image: IImage) => void;\n};\n\ntype DerivedImageOptions = LocalImageOptions & {\n imageId?: string;\n targetBufferType?: PixelDataTypedArrayString;\n};\n\n/**\n * This module deals with ImageLoaders, loading images and caching images\n */\nconst imageLoaders = {};\nlet unknownImageLoader;\n\n/**\n * Loads an image using a registered Cornerstone Image Loader.\n *\n * The image loader that is used will be\n * determined by the image loader scheme matching against the imageId.\n *\n * @param imageId - A Cornerstone Image Object's imageId\n * @param Options - to be passed to the Image Loader\n *\n * @returns - An Object which can be used to act after an image is loaded or loading fails\n */\nfunction loadImageFromImageLoader(\n imageId: string,\n options: ImageLoaderOptions\n): IImageLoadObject {\n // Extract the image loader scheme: wadors:https://image1 => wadors\n const colonIndex = imageId.indexOf(':');\n const scheme = imageId.substring(0, colonIndex);\n const loader = imageLoaders[scheme];\n if (loader === undefined || loader === null) {\n if (unknownImageLoader !== undefined) {\n return unknownImageLoader(imageId);\n }\n throw new Error('loadImageFromImageLoader: no image loader for imageId');\n }\n // Load using the registered loader\n const imageLoadObject = loader(imageId, options);\n // Broadcast an image loaded event once the image is loaded\n imageLoadObject.promise.then(\n function (image) {\n triggerEvent(eventTarget, Events.IMAGE_LOADED, { image });\n },\n function (error) {\n const errorObject: EventTypes.ImageLoadedFailedEventDetail = {\n imageId,\n error,\n };\n triggerEvent(eventTarget, Events.IMAGE_LOAD_FAILED, errorObject);\n }\n );\n return imageLoadObject;\n}\n\n/**\n * Gets the imageLoadObject by 1) Looking in to the cache to see if the\n * imageLoadObject has already been cached, 2) Checks inside the volume cache\n * to see if there is a volume that contains the same imageURI for the requested\n * imageID 3) Checks inside the imageCache for similar imageURI that might have\n * been stored as a result of decaching a volume 4) Finally if none were found\n * it request it from the registered imageLoaders.\n *\n * @param imageId - A Cornerstone Image Object's imageId\n * @param options - Options to be passed to the Image Loader\n *\n * @returns An Object which can be used to act after an image is loaded or loading fails\n */\nfunction loadImageFromCacheOrVolume(\n imageId: string,\n options: ImageLoaderOptions\n): IImageLoadObject {\n if (options.ignoreCache) {\n return loadImageFromImageLoader(imageId, options);\n }\n\n // 1. Check inside the image cache for imageId\n let imageLoadObject = cache.getImageLoadObject(imageId);\n if (imageLoadObject !== undefined) {\n return imageLoadObject;\n }\n // 2. Check if there exists a volume in the cache containing the imageId,\n // we copy the pixelData over.\n const cachedVolumeInfo = cache.getVolumeContainingImageId(imageId);\n if (cachedVolumeInfo?.volume?.loadStatus?.loaded) {\n // 2.1 Convert the volume at the specific slice to a cornerstoneImage object.\n // this will copy the pixel data over.\n const { volume, imageIdIndex } = cachedVolumeInfo;\n\n if (volume instanceof ImageVolume) {\n imageLoadObject = volume.convertToCornerstoneImage(imageId, imageIdIndex);\n }\n return imageLoadObject;\n }\n // 3. If no volume found, we search inside the imageCache for the imageId\n // that has the same URI which had been cached if the volume was converted\n // to an image\n const cachedImage = cache.getCachedImageBasedOnImageURI(imageId);\n if (cachedImage) {\n imageLoadObject = cachedImage.imageLoadObject;\n return imageLoadObject;\n }\n // 4. if not in image cache nor inside the volume cache, we request the\n // image loaders to load it\n imageLoadObject = loadImageFromImageLoader(imageId, options);\n\n return imageLoadObject;\n}\n\n/**\n * Loads an image given an imageId and optional priority and returns a promise\n * which will resolve to the loaded image object or fail if an error occurred.\n * The loaded image is not stored in the cache.\n *\n *\n * @param imageId - A Cornerstone Image Object's imageId\n * @param options - Options to be passed to the Image Loader\n *\n * @returns An Object which can be used to act after an image is loaded or loading fails\n */\nexport function loadImage(\n imageId: string,\n options: ImageLoaderOptions = { priority: 0, requestType: 'prefetch' }\n): Promise<IImage> {\n if (imageId === undefined) {\n throw new Error('loadImage: parameter imageId must not be undefined');\n }\n\n return loadImageFromCacheOrVolume(imageId, options).promise;\n}\n\n/**\n * Loads an image given an imageId and optional priority and returns a promise\n * which will resolve to the loaded image object or fail if an error occurred.\n * The image is stored in the cache.\n *\n * @param imageId - A Cornerstone Image Object's imageId\n * @param options - Options to be passed to the Image Loader\n *\n * @returns Image Loader Object\n */\nexport function loadAndCacheImage(\n imageId: string,\n options: ImageLoaderOptions = { priority: 0, requestType: 'prefetch' }\n): Promise<IImage> {\n if (imageId === undefined) {\n throw new Error(\n 'loadAndCacheImage: parameter imageId must not be undefined'\n );\n }\n const imageLoadObject = loadImageFromCacheOrVolume(imageId, options);\n\n // if not inside cache, store it\n if (!cache.getImageLoadObject(imageId)) {\n cache.putImageLoadObject(imageId, imageLoadObject).catch((err) => {\n console.warn(err);\n });\n }\n\n return imageLoadObject.promise;\n}\n\n/**\n * Load and cache a list of imageIds\n *\n * @param imageIds - list of imageIds\n * @param options - options for loader\n *\n */\nexport function loadAndCacheImages(\n imageIds: Array<string>,\n options: ImageLoaderOptions = { priority: 0, requestType: 'prefetch' }\n): Promise<IImage>[] {\n if (!imageIds || imageIds.length === 0) {\n throw new Error(\n 'loadAndCacheImages: parameter imageIds must be list of image Ids'\n );\n }\n\n const allPromises = imageIds.map((imageId) => {\n return loadAndCacheImage(imageId, options);\n });\n\n return allPromises;\n}\n\n/**\n * Loads an image given an imageId and optional priority and returns a promise\n * which will resolve to the loaded image object or fail if an error occurred.\n * The image is stored in the cache.\n *\n * @param referencedImageId - A Cornerstone Image Object's imageId\n * @param options - Options to be passed to the Image Loader\n *\n * @returns Image Loader Object\n */\nexport function createAndCacheDerivedImage(\n referencedImageId: string,\n options: DerivedImageOptions = {},\n preventCache = false\n): Promise<IImage> {\n if (referencedImageId === undefined) {\n throw new Error(\n 'createAndCacheDerivedImage: parameter imageId must not be undefined'\n );\n }\n\n if (options.imageId === undefined) {\n options.imageId = `derived:${uuidv4()}`;\n }\n\n const { imageId, skipCreateBuffer, onCacheAdd } = options;\n\n const imagePlaneModule = metaData.get('imagePlaneModule', referencedImageId);\n\n const length = imagePlaneModule.rows * imagePlaneModule.columns;\n\n const { TypedArrayConstructor } = getBufferConfiguration(\n options.targetBufferType,\n length\n );\n\n // Use a buffer of size 1 for no data\n const imageScalarData = new TypedArrayConstructor(\n skipCreateBuffer ? 1 : length\n );\n const derivedImageId = imageId;\n\n ['imagePlaneModule', 'generalSeriesModule'].forEach((type) => {\n genericMetadataProvider.add(derivedImageId, {\n type,\n metadata: metaData.get(type, referencedImageId),\n });\n });\n\n const imagePixelModule = metaData.get('imagePixelModule', referencedImageId);\n // TODO - add a general way to specify this\n genericMetadataProvider.add(derivedImageId, {\n type: 'imagePixelModule',\n metadata: {\n ...imagePixelModule,\n bitsAllocated: 8,\n bitsStored: 8,\n highBit: 7,\n samplesPerPixel: 1,\n pixelRepresentation: 0,\n },\n });\n\n const localImage = createAndCacheLocalImage(\n { scalarData: imageScalarData, onCacheAdd, skipCreateBuffer },\n imageId,\n true\n );\n\n const imageLoadObject = {\n promise: Promise.resolve(localImage),\n };\n\n if (!preventCache) {\n cache.putImageLoadObject(derivedImageId, imageLoadObject);\n }\n return imageLoadObject.promise;\n}\n\n/**\n * Load and cache a list of imageIds\n *\n * @param referencedImageIds - list of imageIds\n * @param options\n * @param options.getDerivedImageId - function to get the derived imageId\n * @param options.targetBufferType - target buffer type\n * @param options.skipBufferCreate - avoid creating the buffer\n */\nexport function createAndCacheDerivedImages(\n referencedImageIds: Array<string>,\n options: DerivedImageOptions & {\n getDerivedImageId?: (referencedImageId: string) => string;\n targetBufferType?: PixelDataTypedArrayString;\n } = {}\n): DerivedImages {\n if (referencedImageIds?.length === 0) {\n throw new Error(\n 'createAndCacheDerivedImages: parameter imageIds must be list of image Ids'\n );\n }\n\n const derivedImageIds = [];\n const allPromises = referencedImageIds.map((referencedImageId) => {\n const newOptions: DerivedImageOptions = {\n imageId:\n options.getDerivedImageId?.(referencedImageId) || `derived:${uuidv4()}`,\n ...options,\n };\n derivedImageIds.push(newOptions.imageId);\n return createAndCacheDerivedImage(referencedImageId, newOptions);\n });\n\n return { imageIds: derivedImageIds, promises: allPromises };\n}\n\nexport function createAndCacheLocalImage(\n options: LocalImageOptions,\n imageId: string,\n preventCache = false\n): IImage {\n const imagePlaneModule = metaData.get('imagePlaneModule', imageId);\n\n const length = imagePlaneModule.rows * imagePlaneModule.columns;\n\n const image = {\n imageId: imageId,\n intercept: 0,\n windowCenter: 0,\n windowWidth: 0,\n color: false,\n numComps: 1,\n slope: 1,\n minPixelValue: 0,\n maxPixelValue: 255,\n voiLUTFunction: undefined,\n rows: imagePlaneModule.rows,\n columns: imagePlaneModule.columns,\n getCanvas: undefined, // todo: which canvas?\n height: imagePlaneModule.rows,\n width: imagePlaneModule.columns,\n rgba: undefined, // todo: how\n columnPixelSpacing: imagePlaneModule.columnPixelSpacing,\n rowPixelSpacing: imagePlaneModule.rowPixelSpacing,\n invert: false,\n } as IImage;\n\n if (options.scalarData) {\n const imageScalarData = options.scalarData;\n\n if (\n !(\n imageScalarData instanceof Uint8Array ||\n imageScalarData instanceof Float32Array ||\n imageScalarData instanceof Uint16Array ||\n imageScalarData instanceof Int16Array\n )\n ) {\n throw new Error(\n 'To use createLocalVolume you should pass scalarData of type Uint8Array, Uint16Array, Int16Array or Float32Array'\n );\n }\n\n image.sizeInBytes = imageScalarData.byteLength;\n image.getPixelData = () => imageScalarData;\n } else if (options.skipCreateBuffer !== true) {\n const { numBytes, TypedArrayConstructor } = getBufferConfiguration(\n options.targetBufferType,\n length\n );\n\n const imageScalarData = new TypedArrayConstructor(length);\n\n image.sizeInBytes = numBytes;\n image.getPixelData = () => imageScalarData;\n }\n\n // The onCacheAdd may modify the size in bytes for this image, which is ok,\n // as this is used after resolution for cache storage. It may also do\n // thinks like adding alternative representations such as VoxelManager\n options.onCacheAdd?.(image);\n\n const imageLoadObject = {\n promise: Promise.resolve(image),\n };\n\n if (!preventCache) {\n cache.putImageLoadObject(image.imageId, imageLoadObject);\n }\n\n return image;\n}\n\n/**\n * Removes the imageId from the request pool manager and executes the `cancel`\n * function if it exists.\n *\n * @param imageId - A Cornerstone Image Object's imageId\n *\n */\nexport function cancelLoadImage(imageId: string): void {\n const filterFunction = ({ additionalDetails }) => {\n if (additionalDetails.imageId) {\n return additionalDetails.imageId !== imageId;\n }\n\n // for volumes\n return true;\n };\n\n // Instruct the request pool manager to filter queued\n // requests to ensure requests we no longer need are\n // no longer sent.\n imageLoadPoolManager.filterRequests(filterFunction);\n\n // TODO: Cancel decoding and retrieval as well (somehow?)\n\n // cancel image loading if in progress\n const imageLoadObject = cache.getImageLoadObject(imageId);\n\n if (imageLoadObject) {\n imageLoadObject.cancelFn();\n }\n}\n\n/**\n * Removes the imageIds from the request pool manager and calls the `cancel`\n * function if it exists.\n *\n * @param imageIds - Array of Cornerstone Image Object's imageIds\n *\n */\nexport function cancelLoadImages(imageIds: Array<string>): void {\n imageIds.forEach((imageId) => cancelLoadImage(imageId));\n}\n\n/**\n * Removes all the ongoing image loads by calling the `cancel` method on each\n * imageLoadObject. If no `cancel` method is available, it will be ignored.\n *\n */\nexport function cancelLoadAll(): void {\n const requestPool = imageLoadPoolManager.getRequestPool();\n\n Object.keys(requestPool).forEach((type: string) => {\n const requests = requestPool[type];\n\n Object.keys(requests).forEach((priority) => {\n const requestDetails = requests[priority].pop();\n const additionalDetails = requestDetails.additionalDetails as any;\n const { imageId, volumeId } = additionalDetails;\n\n let loadObject;\n\n if (imageId) {\n loadObject = cache.getImageLoadObject(imageId);\n } else if (volumeId) {\n loadObject = cache.getVolumeLoadObject(volumeId);\n }\n if (loadObject) {\n loadObject.cancel();\n }\n });\n // resetting the pool types to be empty\n imageLoadPoolManager.clearRequestStack(type);\n\n // TODO: Clear retrieval and decoding queues as well\n });\n}\n\n/**\n * Registers an imageLoader plugin with cornerstone for the specified scheme\n *\n * @param scheme - The scheme to use for this image loader (e.g. 'dicomweb', 'wadouri', 'http')\n * @param imageLoader - A Cornerstone Image Loader function\n */\nexport function registerImageLoader(\n scheme: string,\n imageLoader: ImageLoaderFn\n): void {\n imageLoaders[scheme] = imageLoader;\n}\n/**\n * Registers a new unknownImageLoader and returns the previous one\n *\n * @param imageLoader - A Cornerstone Image Loader\n *\n * @returns The previous Unknown Image Loader\n */\nexport function registerUnknownImageLoader(\n imageLoader: ImageLoaderFn\n): ImageLoaderFn {\n const oldImageLoader = unknownImageLoader;\n unknownImageLoader = imageLoader;\n return oldImageLoader;\n}\n/**\n * Removes all registered and unknown image loaders. This should be called\n * when the application is unmounted to prevent memory leaks.\n *\n */\nexport function unregisterAllImageLoaders(): void {\n Object.keys(imageLoaders).forEach(\n (imageLoader) => delete imageLoaders[imageLoader]\n );\n unknownImageLoader = undefined;\n}\n\n/**\n * Creates and caches derived segmentation images based on the referenced imageIds, this\n * is a helper function, we don't have segmentation concept in the cornerstone core; however,\n * this helper would make it clear that the segmentation images SHOULD be Uint8Array type\n * always until we have a better solution.\n *\n * @param referencedImageIds - An array of referenced image IDs.\n * @param options - The options for creating the derived images (default: { targetBufferType: 'Uint8Array' }).\n * @returns The derived images.\n */\nexport function createAndCacheDerivedSegmentationImages(\n referencedImageIds: Array<string>,\n options: DerivedImageOptions = {\n targetBufferType: 'Uint8Array',\n }\n): DerivedImages {\n return createAndCacheDerivedImages(referencedImageIds, options);\n}\n\n/**\n * Creates and caches a derived segmentation image based on the referenced image ID.\n * this is a helper function, we don't have segmentation concept in the cornerstone core; however,\n * this helper would make it clear that the segmentation images SHOULD be Uint8Array type\n * always until we have a better solution.\n *\n * @param referencedImageId The ID of the referenced image.\n * @param options The options for creating the derived image (default: { targetBufferType: 'Uint8Array' }).\n * @returns A promise that resolves to the created derived segmentation image.\n */\nexport function createAndCacheDerivedSegmentationImage(\n referencedImageId: string,\n options: DerivedImageOptions = {\n targetBufferType: 'Uint8Array',\n }\n): Promise<IImage> {\n return createAndCacheDerivedImage(referencedImageId, options);\n}\n","/**\n * Given a low and high window level, return the window width and window center\n * Formulas from note 4 in\n * https://dicom.nema.org/medical/dicom/current/output/html/part03.html#sect_C.11.2.1.2.1\n * extended to allow for low/high swapping\n * @param low - The low window level.\n * @param high - The high window level.\n * @returns a JavaScript object with two properties: windowWidth and windowCenter.\n */\nfunction toWindowLevel(\n low: number,\n high: number\n): {\n windowWidth: number;\n windowCenter: number;\n} {\n // Allow for swapping high/low\n const windowWidth = Math.abs(high - low) + 1;\n const windowCenter = (low + high + 1) / 2;\n\n return { windowWidth, windowCenter };\n}\n\n/**\n * Given a window width and center, return the lower and upper bounds of the window\n * The formulas for the calculation are specified in\n * https://dicom.nema.org/medical/dicom/current/output/html/part03.html#sect_C.11.2.1.2.1\n * if (x <= c - 0.5 - (w-1) /2), then y = ymin\n * else if (x > c - 0.5 + (w-1) /2), then y = ymax\n * else y = ((x - (c - 0.5)) / (w-1) + 0.5) * (ymax- ymin) + ymin\n * @param windowWidth - the width of the window in HU\n * @param windowCenter - The center of the window.\n * @returns a JavaScript object with two properties: lower and upper.\n */\nfunction toLowHighRange(\n windowWidth: number,\n windowCenter: number\n): {\n lower: number;\n upper: number;\n} {\n const lower = windowCenter - 0.5 - (windowWidth - 1) / 2;\n const upper = windowCenter - 0.5 + (windowWidth - 1) / 2;\n\n return { lower, upper };\n}\n\nexport { toWindowLevel, toLowHighRange };\n","import {\n VolumeActor,\n IImageVolume,\n VOIRange,\n ScalingParameters,\n} from '../../types';\nimport { loadAndCacheImage } from '../../loaders/imageLoader';\nimport * as metaData from '../../metaData';\nimport { getMinMax, windowLevel } from '../../utilities';\nimport { RequestType } from '../../enums';\nimport cache from '../../cache';\n\nconst PRIORITY = 0;\nconst REQUEST_TYPE = RequestType.Prefetch;\n\n/**\n * It sets the default window level of an image volume based on the VOI.\n * It first look for the VOI in the metadata and if it is not found, it\n * loads the middle slice image (middle imageId) and based on its min\n * and max pixel values, it calculates the VOI.\n * Finally it sets the VOI on the volumeActor transferFunction\n * @param volumeActor - The volume actor\n * @param imageVolume - The image volume that we want to set the VOI for.\n * @param useNativeDataType - The image data type is native or Float32Array\n */\nasync function setDefaultVolumeVOI(\n volumeActor: VolumeActor,\n imageVolume: IImageVolume,\n useNativeDataType: boolean\n): Promise<void> {\n let voi = getVOIFromMetadata(imageVolume);\n\n if (!voi && imageVolume?.imageIds?.length) {\n voi = await getVOIFromMinMax(imageVolume, useNativeDataType);\n voi = handlePreScaledVolume(imageVolume, voi);\n }\n // if (!voi || voi.lower === undefined || voi.upper === undefined) {\n // throw new Error(\n // 'Could not get VOI from metadata, nor from the min max of the image middle slice'\n // );\n // }\n if (\n (voi?.lower === 0 && voi?.upper === 0) ||\n voi?.lower === undefined ||\n voi?.upper === undefined\n ) {\n return;\n }\n\n volumeActor\n .getProperty()\n .getRGBTransferFunction(0)\n .setMappingRange(voi.lower, voi.upper);\n}\n\nfunction handlePreScaledVolume(imageVolume: IImageVolume, voi: VOIRange) {\n const imageIds = imageVolume.imageIds;\n const imageIdIndex = Math.floor(imageIds.length / 2);\n const imageId = imageIds[imageIdIndex];\n\n const generalSeriesModule =\n metaData.get('generalSeriesModule', imageId) || {};\n\n /**\n * If the volume is prescaled and the modality is PT Sometimes you get super high\n * values at the peak and it skews the min/max so nothing useful is displayed\n * Therefore, we follow the majority of other viewers and we set the min/max\n * for the scaled PT to be 0, 5\n */\n if (_isCurrentImagePTPrescaled(generalSeriesModule.modality, imageVolume)) {\n return {\n lower: 0,\n upper: 5,\n };\n }\n\n return voi;\n}\n\n/**\n * Get the VOI from the metadata of the middle slice of the image volume or the metadata of the image volume\n * It checks the metadata for the VOI and if it is not found, it returns null\n *\n * @param imageVolume - The image volume that we want to get the VOI from.\n * @returns VOIRange with lower and upper values\n */\nfunction getVOIFromMetadata(imageVolume: IImageVolume): VOIRange {\n const { imageIds, metadata } = imageVolume;\n let voi;\n if (imageIds.length) {\n const imageIdIndex = Math.floor(imageIds.length / 2);\n const imageId = imageIds[imageIdIndex];\n const voiLutModule = metaData.get('voiLutModule', imageId);\n if (voiLutModule && voiLutModule.windowWidth && voiLutModule.windowCenter) {\n const { windowWidth, windowCenter } = voiLutModule;\n voi = {\n windowWidth: Array.isArray(windowWidth) ? windowWidth[0] : windowWidth,\n windowCenter: Array.isArray(windowCenter)\n ? windowCenter[0]\n : windowCenter,\n };\n }\n } else {\n voi = metadata?.voiLut?.[0];\n }\n if (voi) {\n const { lower, upper } = windowLevel.toLowHighRange(\n Number(voi.windowWidth),\n Number(voi.windowCenter)\n );\n return {\n lower,\n upper,\n };\n }\n}\n\n/**\n * It loads the middle slice image (middle imageId) and based on its min\n * and max pixel values, it calculates the VOI.\n *\n * @param imageVolume - The image volume that we want to get the VOI from.\n * @param useNativeDataType - The image data type is native or Float32Array\n * @returns The VOIRange with lower and upper values\n */\nasync function getVOIFromMinMax(\n imageVolume: IImageVolume,\n useNativeDataType: boolean\n): Promise<VOIRange> {\n const { imageIds } = imageVolume;\n const scalarData = imageVolume.getScalarData();\n\n // Get the middle image from the list of imageIds\n const imageIdIndex = Math.floor(imageIds.length / 2);\n const imageId = imageVolume.imageIds[imageIdIndex];\n const generalSeriesModule =\n metaData.get('generalSeriesModule', imageId) || {};\n const { modality } = generalSeriesModule;\n const modalityLutModule = metaData.get('modalityLutModule', imageId) || {};\n\n const numImages = imageIds.length;\n const bytesPerImage = scalarData.byteLength / numImages;\n const voxelsPerImage = scalarData.length / numImages;\n const bytePerPixel = scalarData.BYTES_PER_ELEMENT;\n\n const scalingParameters: ScalingParameters = {\n rescaleSlope: modalityLutModule.rescaleSlope,\n rescaleIntercept: modalityLutModule.rescaleIntercept,\n modality,\n };\n\n let scalingParametersToUse;\n if (modality === 'PT') {\n const suvFactor = metaData.get('scalingModule', imageId);\n\n if (suvFactor) {\n scalingParametersToUse = {\n ...scalingParameters,\n suvbw: suvFactor.suvbw,\n };\n }\n }\n\n const byteOffset = imageIdIndex * bytesPerImage;\n\n const options = {\n targetBuffer: {\n type: useNativeDataType ? undefined : 'Float32Array',\n },\n priority: PRIORITY,\n requestType: REQUEST_TYPE,\n useNativeDataType,\n preScale: {\n enabled: true,\n scalingParameters: scalingParametersToUse,\n },\n };\n\n // Loading the middle slice image for a volume has two scenarios, the first one is that\n // uses the same volumeLoader which might not resolve to an image (since for performance\n // reasons volumes' pixelData is set via offset and length on the volume arrayBuffer\n // when each slice is loaded). The second scenario is that the image might not reach\n // to the volumeLoader, and an already cached image (with Image object) is used\n // instead. For the first scenario, we use the arrayBuffer of the volume to get the correct\n // slice for the imageScalarData, and for the second scenario we use the getPixelData\n // on the Cornerstone IImage object to get the pixel data.\n // Note: we don't want to use the derived or generated images for setting the\n // default VOI, because they are not the original. This is ugly but don't\n // know how to do it better.\n let image = cache.getImage(imageId);\n\n if (!imageVolume.referencedImageIds?.length) {\n // we should ignore the cache here,\n // since we want to load the image from with the most\n // recent prescale settings\n image = await loadAndCacheImage(imageId, { ...options, ignoreCache: true });\n }\n\n const imageScalarData = image\n ? image.getPixelData()\n : _getImageScalarDataFromImageVolume(\n imageVolume,\n byteOffset,\n bytePerPixel,\n voxelsPerImage\n );\n\n // Get the min and max pixel values of the middle slice\n const { min, max } = getMinMax(imageScalarData);\n\n return {\n lower: min,\n upper: max,\n };\n}\n\nfunction _getImageScalarDataFromImageVolume(\n imageVolume,\n byteOffset,\n bytePerPixel,\n voxelsPerImage\n) {\n const { scalarData } = imageVolume;\n const { buffer } = scalarData;\n if (scalarData.BYTES_PER_ELEMENT !== bytePerPixel) {\n byteOffset *= scalarData.BYTES_PER_ELEMENT / bytePerPixel;\n }\n\n const TypedArray = scalarData.constructor;\n const imageScalarData = new TypedArray(voxelsPerImage);\n\n const volumeBufferView = new TypedArray(buffer, byteOffset, voxelsPerImage);\n\n imageScalarData.set(volumeBufferView);\n\n return imageScalarData;\n}\n\nfunction _isCurrentImagePTPrescaled(modality, imageVolume) {\n if (modality !== 'PT' || !imageVolume.isPreScaled) {\n return false;\n }\n\n if (!imageVolume.scaling?.PT.suvbw) {\n return false;\n }\n\n return true;\n}\n\nexport default setDefaultVolumeVOI;\n","import vtkVolume from '@kitware/vtk.js/Rendering/Core/Volume';\n\nimport { VolumeActor } from './../../types/IActor';\nimport { VoiModifiedEventDetail } from './../../types/EventTypes';\nimport { loadVolume } from '../../loaders/volumeLoader';\nimport createVolumeMapper from './createVolumeMapper';\nimport BlendModes from '../../enums/BlendModes';\nimport { triggerEvent } from '../../utilities';\nimport { Events } from '../../enums';\nimport setDefaultVolumeVOI from './setDefaultVolumeVOI';\n\ninterface createVolumeActorInterface {\n volumeId: string;\n callback?: ({\n volumeActor,\n volumeId,\n }: {\n volumeActor: VolumeActor;\n volumeId: string;\n }) => void;\n blendMode?: BlendModes;\n}\n\n/**\n * Given a volumeId, it creates a vtk volume actor and returns it. If\n * callback is provided, it will be called with the volume actor and the\n * volumeId. If blendMode is provided, it will be set on the volume actor.\n *\n * @param props - createVolumeActorInterface\n * @returns A promise that resolves to a VolumeActor.\n */\nasync function createVolumeActor(\n props: createVolumeActorInterface,\n element: HTMLDivElement,\n viewportId: string,\n suppressEvents = false,\n useNativeDataType = false\n): Promise<VolumeActor> {\n const { volumeId, callback, blendMode } = props;\n\n const imageVolume = await loadVolume(volumeId);\n\n if (!imageVolume) {\n throw new Error(\n `imageVolume with id: ${imageVolume.volumeId} does not exist`\n );\n }\n\n const { imageData, vtkOpenGLTexture } = imageVolume;\n\n const volumeMapper = createVolumeMapper(imageData, vtkOpenGLTexture);\n\n if (blendMode) {\n volumeMapper.setBlendMode(blendMode);\n }\n\n const volumeActor = vtkVolume.newInstance();\n volumeActor.setMapper(volumeMapper);\n\n const numberOfComponents = imageData\n .getPointData()\n .getScalars()\n .getNumberOfComponents();\n\n if (numberOfComponents === 3) {\n volumeActor.getProperty().setIndependentComponents(false);\n }\n\n await setDefaultVolumeVOI(volumeActor, imageVolume, useNativeDataType);\n\n if (callback) {\n callback({ volumeActor, volumeId });\n }\n\n if (!suppressEvents) {\n triggerVOIModified(element, viewportId, volumeActor, volumeId);\n }\n\n return volumeActor;\n}\n\nfunction triggerVOIModified(\n element: HTMLDivElement,\n viewportId: string,\n volumeActor: VolumeActor,\n volumeId: string\n) {\n const voiRange = volumeActor\n .getProperty()\n .getRGBTransferFunction(0)\n .getRange();\n\n const voiModifiedEventDetail: VoiModifiedEventDetail = {\n viewportId,\n range: {\n lower: voiRange[0],\n upper: voiRange[1],\n },\n volumeId,\n };\n\n triggerEvent(element, Events.VOI_MODIFIED, voiModifiedEventDetail);\n}\n\nexport default createVolumeActor;\n","const VIEWPORT_ELEMENT = 'viewport-element';\nconst CANVAS_CSS_CLASS = 'cornerstone-canvas';\nexport const EPSILON = 1e-4;\n\n/**\n * Create a canvas and append it to the element\n *\n * @param element - An HTML Element\n * @returns canvas - A Canvas DOM element\n */\nfunction createCanvas(element: Element | HTMLDivElement): HTMLCanvasElement {\n const canvas = document.createElement('canvas');\n\n canvas.style.position = 'absolute';\n canvas.style.width = '100%';\n canvas.style.height = '100%';\n canvas.style.imageRendering = 'pixelated';\n canvas.classList.add(CANVAS_CSS_CLASS);\n element.appendChild(canvas);\n\n return canvas;\n}\n\n/**\n * Creates an internal div that will contain canvas and SVG layer as children\n * @param element - An HTML Element\n * @returns div Cornerstone internal div that will include the canvas and SVG\n * as its children\n */\nexport function createViewportElement(element: HTMLDivElement): HTMLDivElement {\n const div = document.createElement('div');\n div.style.position = 'relative';\n div.style.width = '100%';\n div.style.height = '100%';\n // Hide any canvas elements not viewable\n div.style.overflow = 'hidden';\n div.classList.add(VIEWPORT_ELEMENT);\n element.appendChild(div);\n\n return div;\n}\n\n/**\n * Create a canvas or returns the one that already exists for a given element.\n * It first checks if the element has a canvas, if not it creates one and returns it.\n * The canvas is updated for:\n * 1. width/height in screen pixels to completely cover the div element\n * 2. CSS width/height in CSS pixels to be the size of the physical screen pixels\n * width and height (from #1)\n * This allows drawing to the canvas and having pixel perfect/exact drawing to\n * the physical screen pixels.\n *\n * @param element - An HTML Element\n * @returns canvas a Canvas DOM element\n */\nexport default function getOrCreateCanvas(\n element: HTMLDivElement\n): HTMLCanvasElement {\n const canvasSelector = `canvas.${CANVAS_CSS_CLASS}`;\n const viewportElement = `div.${VIEWPORT_ELEMENT}`;\n\n // Internal div with `relative` positioning to enable absolute positioning\n // of the canvas and svg layer.\n const internalDiv =\n element.querySelector(viewportElement) || createViewportElement(element);\n\n const canvas = (internalDiv.querySelector(canvasSelector) ||\n createCanvas(internalDiv)) as HTMLCanvasElement;\n // Fit the canvas into the div\n const rect = internalDiv.getBoundingClientRect();\n const devicePixelRatio = window.devicePixelRatio || 1;\n\n // The width/height is the number of physical pixels which will completely\n // cover the div so that no pixels, fractional or full are left uncovered.\n // Thus, it is the ceiling of the CSS size times the physical pixels.\n // In theory, the physical pixels can be offset from CSS pixels, but in practice\n // this hasn't been observed.\n const width = Math.ceil(rect.width * devicePixelRatio);\n const height = Math.ceil(rect.height * devicePixelRatio);\n canvas.width = width;\n canvas.height = height;\n // Reset the size of the canvas to be the number of physical pixels,\n // expressed as CSS pixels, with a tiny extra amount to prevent clipping\n // to the next lower size in the physical display.\n canvas.style.width = (width + EPSILON) / devicePixelRatio + 'px';\n canvas.style.height = (height + EPSILON) / devicePixelRatio + 'px';\n\n return canvas;\n}\n","import macro from '@kitware/vtk.js/macros';\nimport vtkOpenGLVolumeMapper from '@kitware/vtk.js/Rendering/OpenGL/VolumeMapper';\nimport { Filter } from '@kitware/vtk.js/Rendering/OpenGL/Texture/Constants';\nimport { VtkDataTypes } from '@kitware/vtk.js/Common/Core/DataArray/Constants';\nimport vtkDataArray from '@kitware/vtk.js/Common/Core/DataArray';\nimport { Representation } from '@kitware/vtk.js/Rendering/Core/Property/Constants';\n\n/**\n * vtkStreamingOpenGLVolumeMapper - A derived class of the core vtkOpenGLVolumeMapper class.\n * This class replaces the buildBufferObjects function so that we progressively upload our textures\n * into GPU memory using the new methods on vtkStreamingOpenGLTexture.\n *\n *\n * @param {*} publicAPI The public API to extend\n * @param {*} model The private model to extend.\n */\nfunction vtkStreamingOpenGLVolumeMapper(publicAPI, model) {\n model.classHierarchy.push('vtkStreamingOpenGLVolumeMapper');\n\n /**\n * buildBufferObjects - A fork of vtkOpenGLVolumeMapper's buildBufferObjects method.\n * This fork performs most of the same actions, but builds the textures progressively using\n * vtkStreamingOpenGLTexture's methods, and also prevents recomputation of the texture for each\n * vtkStreamingOpenGLVolumeMapper using the texture.\n *\n *\n * @param {*} ren The renderer.\n * @param {*} actor The actor to build the buffer objects for.\n */\n publicAPI.buildBufferObjects = (ren, actor) => {\n const image = model.currentInput;\n if (!image) {\n return;\n }\n\n const scalars = image.getPointData() && image.getPointData().getScalars();\n if (!scalars) {\n return;\n }\n\n const vprop = actor.getProperty();\n\n if (!model.jitterTexture.getHandle()) {\n const oTable = new Uint8Array(32 * 32);\n for (let i = 0; i < 32 * 32; ++i) {\n oTable[i] = 255.0 * Math.random();\n }\n model.jitterTexture.setMinificationFilter(Filter.LINEAR);\n model.jitterTexture.setMagnificationFilter(Filter.LINEAR);\n model.jitterTexture.create2DFromRaw(\n 32,\n 32,\n 1,\n VtkDataTypes.UNSIGNED_CHAR,\n oTable\n );\n }\n\n const numComp = scalars.getNumberOfComponents();\n const iComps = vprop.getIndependentComponents();\n const numIComps = iComps ? numComp : 1;\n\n // rebuild opacity tfun?\n let toString = `${vprop.getMTime()}`;\n if (model.opacityTextureString !== toString) {\n const oWidth = 1024;\n const oSize = oWidth * 2 * numIComps;\n const ofTable = new Float32Array(oSize);\n const tmpTable = new Float32Array(oWidth);\n\n for (let c = 0; c < numIComps; ++c) {\n const ofun = vprop.getScalarOpacity(c);\n const opacityFactor =\n model.renderable.getSampleDistance() /\n vprop.getScalarOpacityUnitDistance(c);\n\n const oRange = ofun.getRange();\n ofun.getTable(oRange[0], oRange[1], oWidth, tmpTable, 1);\n // adjust for sample distance etc\n for (let i = 0; i < oWidth; ++i) {\n ofTable[c * oWidth * 2 + i] =\n 1.0 - (1.0 - tmpTable[i]) ** opacityFactor;\n ofTable[c * oWidth * 2 + i + oWidth] = ofTable[c * oWidth * 2 + i];\n }\n }\n\n model.opacityTexture.releaseGraphicsResources(model._openGLRenderWindow);\n model.opacityTexture.setMinificationFilter(Filter.LINEAR);\n model.opacityTexture.setMagnificationFilter(Filter.LINEAR);\n\n // use float texture where possible because we really need the resolution\n // for this table. Errors in low values of opacity accumulate to\n // visible artifacts. High values of opacity quickly terminate without\n // artifacts.\n if (\n model._openGLRenderWindow.getWebgl2() ||\n (model.context.getExtension('OES_texture_float') &&\n model.context.getExtension('OES_texture_float_linear'))\n ) {\n model.opacityTexture.create2DFromRaw(\n oWidth,\n 2 * numIComps,\n 1,\n VtkDataTypes.FLOAT,\n ofTable\n );\n } else {\n const oTable = new Uint8Array(oSize);\n for (let i = 0; i < oSize; ++i) {\n oTable[i] = 255.0 * ofTable[i];\n }\n model.opacityTexture.create2DFromRaw(\n oWidth,\n 2 * numIComps,\n 1,\n VtkDataTypes.UNSIGNED_CHAR,\n oTable\n );\n }\n model.opacityTextureString = toString;\n }\n\n // rebuild color tfun?\n toString = `${vprop.getMTime()}`;\n\n if (model.colorTextureString !== toString) {\n const cWidth = 1024;\n const cSize = cWidth * 2 * numIComps * 3;\n const cTable = new Uint8Array(cSize);\n const tmpTable = new Float32Array(cWidth * 3);\n\n for (let c = 0; c < numIComps; ++c) {\n const cfun = vprop.getRGBTransferFunction(c);\n const cRange = cfun.getRange();\n cfun.getTable(cRange[0], cRange[1], cWidth, tmpTable, 1);\n for (let i = 0; i < cWidth * 3; ++i) {\n cTable[c * cWidth * 6 + i] = 255.0 * tmpTable[i];\n cTable[c * cWidth * 6 + i + cWidth * 3] = 255.0 * tmpTable[i];\n }\n }\n\n model.colorTexture.releaseGraphicsResources(model._openGLRenderWindow);\n model.colorTexture.setMinificationFilter(Filter.LINEAR);\n model.colorTexture.setMagnificationFilter(Filter.LINEAR);\n\n model.colorTexture.create2DFromRaw(\n cWidth,\n 2 * numIComps,\n 3,\n VtkDataTypes.UNSIGNED_CHAR,\n cTable\n );\n model.colorTextureString = toString;\n }\n\n publicAPI.updateLabelOutlineThicknessTexture(actor);\n\n // rebuild the scalarTexture if the data has changed\n toString = `${image.getMTime()}`;\n\n if (model.scalarTextureString !== toString) {\n // Build the textures\n const dims = image.getDimensions();\n\n const previousTextureParameters =\n model.scalarTexture.getTextureParameters();\n\n const dataType = image.getPointData().getScalars().getDataType();\n const data = image.getPointData().getScalars().getData();\n\n let shouldReset = true;\n\n if (\n previousTextureParameters.dataType &&\n previousTextureParameters.dataType === dataType\n ) {\n const previousTextureSize =\n previousTextureParameters.width *\n previousTextureParameters.height *\n previousTextureParameters.depth *\n previousTextureParameters.numComps;\n if (data.length === previousTextureSize) {\n shouldReset = false;\n }\n }\n\n if (shouldReset) {\n model.scalarTexture.setOglNorm16Ext(\n model.context.getExtension('EXT_texture_norm16')\n );\n\n model.scalarTexture.releaseGraphicsResources(model._openGLRenderWindow);\n model.scalarTexture.resetFormatAndType();\n\n model.scalarTexture.create3DFilterableFromRaw(\n dims[0],\n dims[1],\n dims[2],\n numComp,\n scalars.getDataType(),\n scalars.getData(),\n model.renderable.getPreferSizeOverAccuracy()\n );\n } else {\n model.scalarTexture.deactivate();\n model.scalarTexture.update3DFromRaw(data);\n }\n\n model.scalarTextureString = toString;\n }\n\n if (!model.tris.getCABO().getElementCount()) {\n // build the CABO\n const ptsArray = new Float32Array(12);\n for (let i = 0; i < 4; i++) {\n ptsArray[i * 3] = (i % 2) * 2 - 1.0;\n ptsArray[i * 3 + 1] = i > 1 ? 1.0 : -1.0;\n ptsArray[i * 3 + 2] = -1.0;\n }\n\n const cellArray = new Uint16Array(8);\n cellArray[0] = 3;\n cellArray[1] = 0;\n cellArray[2] = 1;\n cellArray[3] = 3;\n cellArray[4] = 3;\n cellArray[5] = 0;\n cellArray[6] = 3;\n cellArray[7] = 2;\n\n const points = vtkDataArray.newInstance({\n numberOfComponents: 3,\n values: ptsArray,\n });\n points.setName('points');\n const cells = vtkDataArray.newInstance({\n numberOfComponents: 1,\n values: cellArray,\n });\n model.tris.getCABO().createVBO(cells, 'polys', Representation.SURFACE, {\n points,\n cellOffset: 0,\n });\n }\n\n model.VBOBuildTime.modified();\n };\n\n publicAPI.getRenderTargetSize = () => {\n if (model._useSmallViewport) {\n return [model._smallViewportWidth, model._smallViewportHeight];\n }\n\n const { usize, vsize } = model._openGLRenderer.getTiledSizeAndOrigin();\n\n return [usize, vsize];\n };\n\n publicAPI.getRenderTargetOffset = () => {\n const { lowerLeftU, lowerLeftV } =\n model._openGLRenderer.getTiledSizeAndOrigin();\n\n return [lowerLeftU, lowerLeftV];\n };\n\n // TODO: it seems like this may be needed to reset the GPU memory associated\n // with a volume\n // publicAPI.hardReset = () => {\n // model.opacityTexture.releaseGraphicsResources(model._openGLRenderWindow);\n // model.colorTexture.releaseGraphicsResources(model._openGLRenderWindow);\n // model.scalarTexture.setOglNorm16Ext(\n // model.context.getExtension('EXT_texture_norm16')\n // );\n // model.scalarTexture.releaseGraphicsResources(model._openGLRenderWindow);\n // model.scalarTexture.resetFormatAndType();\n // };\n}\n\n// ----------------------------------------------------------------------------\n// Object factory\n// ----------------------------------------------------------------------------\n\n// ----------------------------------------------------------------------------\n\nconst DEFAULT_VALUES = {};\n\nexport function extend(publicAPI, model, initialValues = {}) {\n Object.assign(model, DEFAULT_VALUES, initialValues);\n\n vtkOpenGLVolumeMapper.extend(publicAPI, model, initialValues);\n\n model.scalarTexture = initialValues.scalarTexture;\n model.previousState = {};\n\n // Object methods\n vtkStreamingOpenGLVolumeMapper(publicAPI, model);\n}\n\n// ----------------------------------------------------------------------------\n\nexport const newInstance = macro.newInstance(\n extend,\n 'vtkStreamingOpenGLVolumeMapper'\n);\n\n// ----------------------------------------------------------------------------\n\nexport default { newInstance, extend };\n","import macro from '@kitware/vtk.js/macros';\n// import vtkGenericWidgetRepresentation from '@kitware/vtk.js/Rendering/SceneGraph/GenericWidgetRepresentation'\nimport vtkOpenGLActor from '@kitware/vtk.js/Rendering/OpenGL/Actor';\nimport vtkOpenGLActor2D from '@kitware/vtk.js/Rendering/OpenGL/Actor2D';\nimport vtkOpenGLCamera from '@kitware/vtk.js/Rendering/OpenGL/Camera';\nimport vtkOpenGLGlyph3DMapper from '@kitware/vtk.js/Rendering/OpenGL/Glyph3DMapper';\nimport vtkOpenGLImageMapper from '@kitware/vtk.js/Rendering/OpenGL/ImageMapper';\nimport vtkOpenGLImageSlice from '@kitware/vtk.js/Rendering/OpenGL/ImageSlice';\nimport vtkOpenGLPixelSpaceCallbackMapper from '@kitware/vtk.js/Rendering/OpenGL/PixelSpaceCallbackMapper';\nimport vtkOpenGLPolyDataMapper from '@kitware/vtk.js/Rendering/OpenGL/PolyDataMapper';\nimport vtkOpenGLRenderer from '@kitware/vtk.js/Rendering/OpenGL/Renderer';\nimport vtkOpenGLSkybox from '@kitware/vtk.js/Rendering/OpenGL/Skybox';\nimport vtkOpenGLSphereMapper from '@kitware/vtk.js/Rendering/OpenGL/SphereMapper';\nimport vtkOpenGLStickMapper from '@kitware/vtk.js/Rendering/OpenGL/StickMapper';\nimport vtkOpenGLTexture from '@kitware/vtk.js/Rendering/OpenGL/Texture';\nimport vtkOpenGLVolume from '@kitware/vtk.js/Rendering/OpenGL/Volume';\nimport vtkOpenGLVolumeMapper from '@kitware/vtk.js/Rendering/OpenGL/VolumeMapper';\nimport vtkViewNodeFactory from '@kitware/vtk.js/Rendering/SceneGraph/ViewNodeFactory';\nimport vtkStreamingOpenGLVolumeMapper from './vtkStreamingOpenGLVolumeMapper';\n\nconst CLASS_MAPPING = Object.create(null);\n\nexport function registerOverride(className, fn) {\n CLASS_MAPPING[className] = fn;\n}\n\n/**\n * vtkStreamingOpenGLViewNodeFactory - A fork of the vtkOpenGLViewNodeFactory,\n * so that we can inject our custom derived \"Streaming\" classes.\n *\n * @param {*} publicAPI The public API to extend\n * @param {*} model The private model to extend.\n */\nfunction vtkStreamingOpenGLViewNodeFactory(publicAPI, model) {\n // Set our className\n model.classHierarchy.push('vtkStreamingOpenGLViewNodeFactory');\n\n /**\n * createNode - fork of createNode from vtkOpenGLViewNodeFactory.\n * This fork is required to inject the properties from model.getModelInitialValues.\n *\n * @param {object} dataObject An instance of a vtk.js class.\n */\n publicAPI.createNode = (dataObject) => {\n if (dataObject.isDeleted()) {\n return null;\n }\n\n let cpt = 0;\n let className = dataObject.getClassName(cpt++);\n let isObject = false;\n const keys = Object.keys(model.overrides);\n while (className && !isObject) {\n if (keys.indexOf(className) !== -1) {\n isObject = true;\n } else {\n className = dataObject.getClassName(cpt++);\n }\n }\n\n if (!isObject) {\n return null;\n }\n\n const initialValues = model.getModelInitialValues(dataObject);\n\n const vn = model.overrides[className](initialValues);\n vn.setMyFactory(publicAPI);\n return vn;\n };\n\n model.overrides = CLASS_MAPPING;\n\n /**\n * getModelInitialValues - This function allows us to pass textures down from our\n * vtkSharedVolumeMapper to new instances of vtkStreamingOpenGLVolumeMapper.\n * The prevents us from sharing memory.\n *\n * TODO: It would be beneficial to push similar, but generalized, functionality\n * back to vtk.js in the future.\n *\n * @param {object} dataObject An instance of a vtk.js class.\n */\n model.getModelInitialValues = (dataObject) => {\n const initialValues = {};\n\n const className = dataObject.getClassName();\n\n if (className === 'vtkSharedVolumeMapper') {\n initialValues.scalarTexture = dataObject.getScalarTexture();\n }\n\n return initialValues;\n };\n}\n\n// ----------------------------------------------------------------------------\n// Object factory\n// ----------------------------------------------------------------------------\n\nconst DEFAULT_VALUES = {};\n\n// ----------------------------------------------------------------------------\n\nexport function extend(publicAPI, model, initialValues = {}) {\n Object.assign(model, DEFAULT_VALUES, initialValues);\n\n // Inheritance\n vtkViewNodeFactory.extend(publicAPI, model, initialValues);\n\n // Object methods\n vtkStreamingOpenGLViewNodeFactory(publicAPI, model);\n\n // Initialization\n registerOverride('vtkActor', vtkOpenGLActor.newInstance);\n registerOverride('vtkActor2D', vtkOpenGLActor2D.newInstance);\n registerOverride('vtkCamera', vtkOpenGLCamera.newInstance);\n registerOverride('vtkGlyph3DMapper', vtkOpenGLGlyph3DMapper.newInstance);\n registerOverride('vtkImageMapper', vtkOpenGLImageMapper.newInstance);\n registerOverride('vtkImageSlice', vtkOpenGLImageSlice.newInstance);\n registerOverride('vtkMapper', vtkOpenGLPolyDataMapper.newInstance);\n registerOverride(\n 'vtkPixelSpaceCallbackMapper',\n vtkOpenGLPixelSpaceCallbackMapper.newInstance\n );\n registerOverride('vtkRenderer', vtkOpenGLRenderer.newInstance);\n registerOverride('vtkSkybox', vtkOpenGLSkybox.newInstance);\n registerOverride('vtkSphereMapper', vtkOpenGLSphereMapper.newInstance);\n registerOverride('vtkStickMapper', vtkOpenGLStickMapper.newInstance);\n registerOverride('vtkTexture', vtkOpenGLTexture.newInstance);\n registerOverride('vtkVolume', vtkOpenGLVolume.newInstance);\n registerOverride('vtkVolumeMapper', vtkOpenGLVolumeMapper.newInstance);\n registerOverride(\n 'vtkSharedVolumeMapper',\n vtkStreamingOpenGLVolumeMapper.newInstance\n );\n // registerOverride(\n // 'vtkWidgetRepresentation',\n // vtkGenericWidgetRepresentation.newInstance\n // )\n}\n\n// ----------------------------------------------------------------------------\n\nexport const newInstance = macro.newInstance(\n extend,\n 'vtkStreamingOpenGLViewNodeFactory'\n);\n\n// ----------------------------------------------------------------------------\n\nexport default { newInstance, extend };\n","import macro from '@kitware/vtk.js/macros';\nimport vtkOpenGLRenderWindow from '@kitware/vtk.js/Rendering/OpenGL/RenderWindow';\nimport vtkStreamingOpenGLViewNodeFactory, {\n registerOverride,\n} from './vtkStreamingOpenGLViewNodeFactory';\n\n/**\n * vtkStreamingOpenGLRenderWindow - A derived class of the core vtkOpenGLRenderWindow class.\n * The main purpose for this class extension is to add in our own node factory, so we can use\n * our extended \"streaming\" classes for progressive texture loading.\n *\n *\n * @param {*} publicAPI The public API to extend\n * @param {*} model The private model to extend.\n */\nfunction vtkStreamingOpenGLRenderWindow(publicAPI, model) {\n model.classHierarchy.push('vtkStreamingOpenGLRenderWindow');\n}\n\n// ----------------------------------------------------------------------------\n// Object factory\n// ----------------------------------------------------------------------------\n\n// ----------------------------------------------------------------------------\n\nexport function extend(publicAPI, model, initialValues = {}) {\n Object.assign(model, initialValues);\n\n vtkOpenGLRenderWindow.extend(publicAPI, model, initialValues);\n\n model.myFactory = vtkStreamingOpenGLViewNodeFactory.newInstance();\n\n registerOverride('vtkRenderWindow', newInstance);\n\n // Object methods\n vtkStreamingOpenGLRenderWindow(publicAPI, model);\n}\n\n// ----------------------------------------------------------------------------\n\nexport const newInstance = macro.newInstance(\n extend,\n 'vtkStreamingOpenGLRenderWindow'\n);\n\n// ----------------------------------------------------------------------------\n\nexport default { newInstance, extend };\n","import macro from '@kitware/vtk.js/macros';\nimport vtkStreamingOpenGLRenderWindow from './vtkStreamingOpenGLRenderWindow';\nimport vtkRenderer from '@kitware/vtk.js/Rendering/Core/Renderer';\nimport vtkRenderWindow from '@kitware/vtk.js/Rendering/Core/RenderWindow';\nimport vtkRenderWindowInteractor from '@kitware/vtk.js/Rendering/Core/RenderWindowInteractor';\n\n// Load basic classes for vtk() factory\nimport '@kitware/vtk.js/Common/Core/Points';\nimport '@kitware/vtk.js/Common/Core/DataArray';\nimport '@kitware/vtk.js/Common/DataModel/PolyData';\nimport '@kitware/vtk.js/Rendering/Core/Actor';\nimport '@kitware/vtk.js/Rendering/Core/Mapper';\n\n/**\n * vtkOffscreenMultiRenderWindow - A class to deal with offscreen rendering with multiple renderers.\n *\n * This class is based on the vtkGenericRenderWindow with two key differences:\n * - the vtkGenericRenderWindow had a renderer at the top level, with helpers to get it from the renderWindow.\n * although you could add more renderers, this gave special status to the first viewport. Which was confusing.\n * - When checking the size of the container element we no longer check the client size, as the canvas is offscreen.\n * - We aren't using interactor styles, so don't set one up.\n *\n * Additionally this class has some new helpers to easily add/associate renderers to different viewportIds.\n *\n *\n * @param {*} publicAPI The public API to extend\n * @param {*} model The private model to extend.\n */\nfunction vtkOffscreenMultiRenderWindow(publicAPI, model) {\n // Capture resize trigger method to remove from publicAPI\n const invokeResize = publicAPI.invokeResize;\n delete publicAPI.invokeResize;\n\n // VTK renderWindow. No renderers set by default\n model.renderWindow = vtkRenderWindow.newInstance();\n model.rendererMap = {};\n\n // OpenGLRenderWindow\n model.openGLRenderWindow = vtkStreamingOpenGLRenderWindow.newInstance();\n model.renderWindow.addView(model.openGLRenderWindow);\n\n // Interactor\n model.interactor = vtkRenderWindowInteractor.newInstance();\n model.interactor.setView(model.openGLRenderWindow);\n model.interactor.initialize();\n\n publicAPI.addRenderer = ({ viewport, id, background }) => {\n const renderer = vtkRenderer.newInstance({\n viewport,\n background: background || model.background,\n });\n\n model.renderWindow.addRenderer(renderer);\n model.rendererMap[id] = renderer;\n };\n\n publicAPI.destroy = () => {\n const rwi = model.renderWindow.getInteractor();\n rwi.delete();\n };\n\n publicAPI.removeRenderer = (id) => {\n const renderer = publicAPI.getRenderer(id);\n model.renderWindow.removeRenderer(renderer);\n renderer.delete();\n delete model.rendererMap[id];\n };\n\n publicAPI.getRenderer = (id) => {\n return model.rendererMap[id];\n };\n\n publicAPI.getRenderers = () => {\n const { rendererMap } = model;\n\n const renderers = Object.keys(rendererMap).map((id) => {\n return { id, renderer: rendererMap[id] };\n });\n\n return renderers;\n };\n\n // Handle window resize\n publicAPI.resize = () => {\n if (model.container) {\n // Don't use getBoundingClientRect() as in vtkGenericRenderWindow as is an offscreen canvas.\n const { width, height } = model.container;\n\n // Note: we do not scale by devicePixelRatio here because it has already\n // been done when adding the offscreenCanvas viewport representations\n model.openGLRenderWindow.setSize(Math.floor(width), Math.floor(height));\n invokeResize();\n model.renderWindow.render();\n }\n };\n\n // Handle DOM container relocation\n publicAPI.setContainer = (el) => {\n // Switch container\n model.container = el;\n model.openGLRenderWindow.setContainer(model.container);\n };\n\n // Properly release GL context\n publicAPI.delete = macro.chain(\n publicAPI.setContainer,\n publicAPI.destroy,\n model.openGLRenderWindow.delete,\n publicAPI.delete\n );\n\n publicAPI.resize();\n}\n\n// ----------------------------------------------------------------------------\n// Object factory\n// ----------------------------------------------------------------------------\n\nconst DEFAULT_VALUES = {\n background: [0.0, 0.0, 0.0],\n container: null,\n};\n\n// ----------------------------------------------------------------------------\n\nexport function extend(publicAPI, model, initialValues = {}) {\n Object.assign(model, DEFAULT_VALUES, initialValues);\n\n // Object methods\n macro.obj(publicAPI, model);\n macro.get(publicAPI, model, [\n 'renderWindow',\n 'openGLRenderWindow',\n 'interactor',\n 'container',\n ]);\n macro.event(publicAPI, model, 'resize');\n\n // Object specific methods\n vtkOffscreenMultiRenderWindow(publicAPI, model);\n}\n\n// ----------------------------------------------------------------------------\n\nexport const newInstance = macro.newInstance(extend);\n\n// ----------------------------------------------------------------------------\n\nexport default { newInstance, extend };\n","import { mat3, vec3 } from 'gl-matrix';\nimport { IImageVolume, Point3 } from '../types';\n\n/**\n * Given an `imageVolume` and a normal direction (`viewPlaneNormal`), calculates\n * the spacing between voxels in the normal direction. If (`viewPlaneNormal`) is\n * parallel to one of the directions you will obtain the spacing in that direction.\n * Otherwise each of the `imageVolume`'s directions are projected onto the volume,\n * so that you obtain a spacing of the order of \"seeing a new set of voxels if the camera where to dolly\".\n *\n * @param imageVolume - The image volume to calculate the spacing in the normal direction.\n * @param viewPlaneNormal - The normal direction of the view plane.\n * @returns\n */\nexport default function getSpacingInNormalDirection(\n imageVolume: IImageVolume | { direction: mat3; spacing: Point3 },\n viewPlaneNormal: Point3\n): number {\n const { direction, spacing } = imageVolume;\n\n // Calculate size of spacing vector in normal direction\n const iVector = direction.slice(0, 3) as Point3;\n const jVector = direction.slice(3, 6) as Point3;\n const kVector = direction.slice(6, 9) as Point3;\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 const projectedSpacing = vec3.create();\n\n vec3.set(\n projectedSpacing,\n dotProducts[0] * spacing[0],\n dotProducts[1] * spacing[1],\n dotProducts[2] * spacing[2]\n );\n\n const spacingInNormalDirection = vec3.length(projectedSpacing);\n\n return spacingInNormalDirection;\n}\n","import { Types } from '..';\n\ntype actorTypes = 'vtkActor' | 'vtkVolume' | 'vtkImageSlice';\n\n/**\n * Checks if a vtk Actor is an image actor (vtkVolume or vtkImageSlice) otherwise returns false.\n *\n * @param actor - actor\n * @returns A boolean value.\n */\nexport function isImageActor(actorEntry: Types.ActorEntry): boolean {\n return (\n actorIsA(actorEntry, 'vtkVolume') || actorIsA(actorEntry, 'vtkImageSlice')\n );\n}\n\nexport function actorIsA(\n actorEntry: Types.ActorEntry | Types.Actor,\n actorType: actorTypes\n): boolean {\n const actorToCheck = 'isA' in actorEntry ? actorEntry : actorEntry.actor;\n\n return !!actorToCheck.isA(actorType);\n}\n","import { vec3 } from 'gl-matrix';\nimport * as metaData from '../metaData';\nimport type { IImageVolume, Point3 } from '../types';\n\nimport getSpacingInNormalDirection from './getSpacingInNormalDirection';\nimport { EPSILON } from '../constants';\n\n/**\n * Given an image, a point in space and the viewPlaneNormal it returns the\n * closest imageId of the image volume that is within half voxel spacing\n * of the point in space.\n * @param imageVolume - The image volume\n * @param worldPos - The position in the world coordinate system (from mouse click)\n * @param viewPlaneNormal - The normal vector of the viewport\n *\n * @returns The imageId for the tool.\n */\nexport default function getClosestImageId(\n imageVolume: IImageVolume,\n worldPos: Point3,\n viewPlaneNormal: Point3\n): string {\n if (!imageVolume) {\n return;\n }\n\n const { direction, imageIds } = imageVolume;\n\n if (!imageIds || !imageIds.length) {\n return;\n }\n\n // 1. Get ScanAxis vector\n const kVector = direction.slice(6, 9);\n\n // 2. Check if scanAxis is not parallel to camera viewPlaneNormal\n const dotProducts = vec3.dot(kVector as Point3, <vec3>viewPlaneNormal);\n\n // 2.a if imagePlane is not parallel to the camera: tool is not drawn on an\n // imaging plane, return\n if (Math.abs(dotProducts) < 1 - EPSILON) {\n return;\n }\n\n // 3. Calculate Spacing the in the normal direction, this will get used to\n // check whether we are withing a slice\n const spacingInNormalDirection = getSpacingInNormalDirection(\n imageVolume,\n viewPlaneNormal\n );\n\n const halfSpacingInNormalDirection = spacingInNormalDirection / 2;\n\n // 4. Iterate over all imageIds and check if the tool point (worldPos) is\n // withing one of the slices defined by an imageId\n let imageIdForTool;\n for (let i = 0; i < imageIds.length; i++) {\n const imageId = imageIds[i];\n\n // 4.a Get metadata for the imageId\n const { imagePositionPatient } = metaData.get('imagePlaneModule', imageId);\n\n // 4.b Calculate the direction vector from annotation. point to the first voxel\n // of this image defined by imageId\n const dir = vec3.create();\n vec3.sub(dir, worldPos, imagePositionPatient);\n\n // 4.c Calculate the distance between the vector above and the viewplaneNormal\n // i.e., projected distance\n const dot = vec3.dot(dir, viewPlaneNormal);\n\n // 4.d If the distance is withing range, return the imageId\n if (Math.abs(dot) < halfSpacingInNormalDirection) {\n imageIdForTool = imageId;\n }\n }\n\n return imageIdForTool;\n}\n","import { Point3 } from '../types';\n\n/**\n * Converts `vtkVolumeActor` bounds to corners in world space.\n *\n * @param volumeActor - The `vtkVolumeActor`.\n *\n * @returns An array of the corners of the `volumeActor` in world space.\n */\nexport default function getVolumeActorCorners(volumeActor): Array<Point3> {\n const imageData = volumeActor.getMapper().getInputData();\n const bounds = imageData.extentToBounds(imageData.getExtent());\n\n return [\n [bounds[0], bounds[2], bounds[4]],\n [bounds[0], bounds[2], bounds[5]],\n [bounds[0], bounds[3], bounds[4]],\n [bounds[0], bounds[3], bounds[5]],\n [bounds[1], bounds[2], bounds[4]],\n [bounds[1], bounds[2], bounds[5]],\n [bounds[1], bounds[3], bounds[4]],\n [bounds[1], bounds[3], bounds[5]],\n ];\n}\n","import vtkMatrixBuilder from '@kitware/vtk.js/Common/Core/MatrixBuilder';\nimport getVolumeActorCorners from './getVolumeActorCorners';\nimport type { VolumeActor, Point3, ActorSliceRange } from '../types';\nimport { EPSILON } from '../constants';\n\nconst SMALL_EPSILON = EPSILON * EPSILON;\nconst isOne = (v) => Math.abs(Math.abs(v) - 1) < SMALL_EPSILON;\nconst isUnit = (v, off) =>\n isOne(v[off]) || isOne(v[off + 1]) || isOne(v[off + 2]);\n\nconst isOrthonormal = (v) => isUnit(v, 0) && isUnit(v, 3) && isUnit(v, 6);\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: VolumeActor,\n viewPlaneNormal: Point3,\n focalPoint: Point3\n): ActorSliceRange {\n const imageData = volumeActor.getMapper().getInputData();\n let corners;\n const direction = imageData.getDirection();\n\n if (isOrthonormal(direction)) {\n // This logic is only valid when the IJK vectors are unit vectors\n corners = getVolumeActorCorners(volumeActor);\n } else {\n // This logic works for both unit and non-unit vectors, but is slower\n const [dx, dy, dz] = imageData.getDimensions();\n const cornersIdx = [\n [0, 0, 0],\n [dx - 1, 0, 0],\n [0, dy - 1, 0],\n [dx - 1, dy - 1, 0],\n [0, 0, dz - 1],\n [dx - 1, 0, dz - 1],\n [0, dy - 1, dz - 1],\n [dx - 1, dy - 1, dz - 1],\n ];\n corners = cornersIdx.map((it) => imageData.indexToWorld(it));\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 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 {\n min: minX,\n max: maxX,\n current: currentSlice,\n actor: volumeActor,\n viewPlaneNormal,\n focalPoint,\n };\n}\n","import { vec3 } from 'gl-matrix';\nimport { ActorSliceRange, Point3 } from '../types';\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 sliceRange - 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: Point3,\n position: Point3,\n sliceRange: ActorSliceRange,\n viewPlaneNormal: Point3,\n spacingInNormalDirection: number,\n deltaFrames: number\n): { newFocalPoint: Point3; newPosition: Point3 } {\n const { min, max, current } = sliceRange;\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 = <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 = <Point3>[\n newFocalPoint[0] + viewPlaneNormal[0] * newSlicePosFromMin,\n newFocalPoint[1] + viewPlaneNormal[1] * newSlicePosFromMin,\n newFocalPoint[2] + viewPlaneNormal[2] * newSlicePosFromMin,\n ];\n\n const newPosition = <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 vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction';\n\nexport default function getVoiFromSigmoidRGBTransferFunction(\n cfun: vtkColorTransferFunction\n): [number, number] {\n let cfunRange = [];\n // @ts-ignore: vtk d ts problem\n const [lower, upper] = cfun.getRange();\n cfun.getTable(lower, upper, 1024, cfunRange);\n cfunRange = cfunRange.filter((v, k) => k % 3 === 0);\n const cfunDomain = [...Array(1024).keys()].map((v, k) => {\n return lower + ((upper - lower) / (1024 - 1)) * k;\n });\n const y1 = cfunRange[256];\n const logy1 = Math.log((1 - y1) / y1);\n const x1 = cfunDomain[256];\n const y2 = cfunRange[256 * 3];\n const logy2 = Math.log((1 - y2) / y2);\n const x2 = cfunDomain[256 * 3];\n const ww = Math.round((4 * (x2 - x1)) / (logy1 - logy2));\n const wc = Math.round(x1 + (ww * logy1) / 4);\n return [Math.round(wc - ww / 2), Math.round(wc + ww / 2)];\n}\n","function areNumbersEqualWithTolerance(\n num1: number,\n num2: number,\n tolerance: number\n): boolean {\n return Math.abs(num1 - num2) <= tolerance;\n}\n\nfunction areArraysEqual(\n arr1: ArrayLike<number>,\n arr2: ArrayLike<number>,\n tolerance = 1e-5\n): boolean {\n if (arr1.length !== arr2.length) {\n return false;\n }\n\n for (let i = 0; i < arr1.length; i++) {\n if (!areNumbersEqualWithTolerance(arr1[i], arr2[i], tolerance)) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction isNumberType(value: any): value is number {\n return typeof value === 'number';\n}\n\nfunction isNumberArrayLike(value: any): value is ArrayLike<number> {\n return 'length' in value && typeof value[0] === 'number';\n}\n\n/**\n * Returns whether two values are equal or not, based on epsilon comparison.\n * For array comparison, it does NOT strictly compare them but only compare its values.\n * It can compare array of numbers and also typed array. Otherwise it will just return false.\n *\n * @param v1 - The first value to compare\n * @param v2 - The second value to compare\n * @param tolerance - The acceptable tolerance, the default is 0.00001\n *\n * @returns True if the two values are within the tolerance levels.\n */\nexport default function isEqual<ValueType>(\n v1: ValueType,\n v2: ValueType,\n tolerance = 1e-5\n): boolean {\n // values must be the same type or not null\n if (typeof v1 !== typeof v2 || v1 === null || v2 === null) {\n return false;\n }\n\n if (isNumberType(v1) && isNumberType(v2)) {\n return areNumbersEqualWithTolerance(v1, v2, tolerance);\n }\n\n if (isNumberArrayLike(v1) && isNumberArrayLike(v2)) {\n return areArraysEqual(v1, v2, tolerance);\n }\n\n return false;\n}\n\nconst negative = (v) =>\n typeof v === 'number' ? -v : v?.map ? v.map(negative) : !v;\n\nconst abs = (v) =>\n typeof v === 'number' ? Math.abs(v) : v?.map ? v.map(abs) : v;\n\n/**\n * Compare negative values of both single numbers and vectors\n */\nconst isEqualNegative = <ValueType>(\n v1: ValueType,\n v2: ValueType,\n tolerance = undefined\n) => isEqual(v1, negative(v2) as unknown as ValueType, tolerance);\n\n/**\n * Compare absolute values for single numbers and vectors.\n * Not recommended for large vectors as this creates a copy\n */\nconst isEqualAbs = <ValueType>(\n v1: ValueType,\n v2: ValueType,\n tolerance = undefined\n) => isEqual(abs(v1), abs(v2) as unknown as ValueType, tolerance);\n\nexport { isEqualNegative, isEqual, isEqualAbs };\n","import vtkColorMaps from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction/ColorMaps';\n\nimport { ColormapPublic, ColormapRegistration } from '../types';\nimport isEqual from './isEqual';\nimport { actorIsA } from './actorCheck';\n\nconst _colormaps = new Map();\n\n/**\n * Register a colormap\n * @param name - name of the colormap\n * @param colormap - colormap object\n */\nfunction registerColormap(colormap: ColormapRegistration) {\n _colormaps.set(colormap.Name, colormap);\n}\n\n/**\n * Get a colormap by name\n * @param name - name of the colormap\n * @returns colormap object\n */\nfunction getColormap(name) {\n return _colormaps.get(name);\n}\n\n/**\n * Get all registered colormap names\n * @returns array of colormap names\n *\n */\nfunction getColormapNames() {\n return Array.from(_colormaps.keys());\n}\n\n/**\n * Finds a colormap that matches the given RGB points.\n *\n * @param rgbPoints - The RGB points to match against the colormaps.\n * @returns The matched colormap object or null if no match is found.\n */\nfunction findMatchingColormap(rgbPoints, actor): ColormapPublic | null {\n const colormapsVTK = vtkColorMaps.rgbPresetNames.map((presetName) =>\n vtkColorMaps.getPresetByName(presetName)\n );\n\n const colormapsCS3D = getColormapNames().map((colormapName) =>\n getColormap(colormapName)\n );\n\n const colormaps = colormapsVTK.concat(colormapsCS3D);\n\n // Find the colormap that matches the given RGB points\n const matchedColormap = colormaps.find((colormap) => {\n const { RGBPoints: presetRGBPoints } = colormap;\n\n if (presetRGBPoints.length !== rgbPoints.length) {\n return false;\n }\n\n for (let i = 0; i < presetRGBPoints.length; i += 4) {\n if (\n !isEqual(\n presetRGBPoints.slice(i + 1, i + 4),\n rgbPoints.slice(i + 1, i + 4)\n )\n ) {\n return false;\n }\n }\n\n return true;\n });\n\n if (!matchedColormap) {\n return null;\n }\n\n const opacity = [];\n if (actorIsA(actor, 'vtkVolume')) {\n const opacityPoints = actor\n .getProperty()\n .getScalarOpacity(0)\n .getDataPointer();\n\n if (!opacityPoints) {\n return {\n name: matchedColormap.Name,\n };\n }\n\n for (let i = 0; i < opacityPoints.length; i += 2) {\n opacity.push({\n value: opacityPoints[i],\n opacity: opacityPoints[i + 1],\n });\n }\n }\n\n return {\n name: matchedColormap.Name,\n opacity,\n };\n}\n\nexport {\n getColormap,\n getColormapNames,\n registerColormap,\n findMatchingColormap,\n};\n","/**\n * A utility that can be used to invert (in place) an RgbTransferFunction.\n *\n * @example\n * Grabbing a reference to the RGB Transfer function from the viewport:\n * ```\n * const rgbTransferFunction = viewport\n * .getActor()\n * .getProperty()\n * .getRGBTransferFunction(0);\n *\n * rgbTransferFunction.setRange(0, 5);\n *\n * invertRgbTransferFunction(rgbTransferFunction);\n * ```\n *\n * @see {@link https://kitware.github.io/vtk-js/api/Rendering_Core_ColorTransferFunction.html|VTK.js: ColorTransferFunction}\n * @param rgbTransferFunction\n */\nexport default function invertRgbTransferFunction(\n rgbTransferFunction: any\n): void {\n // cut in case there is no function at all\n if (!rgbTransferFunction) {\n return;\n }\n\n const size = rgbTransferFunction.getSize();\n\n for (let index = 0; index < size; index++) {\n const nodeValue1 = [];\n\n rgbTransferFunction.getNodeValue(index, nodeValue1);\n\n nodeValue1[1] = 1 - nodeValue1[1];\n nodeValue1[2] = 1 - nodeValue1[2];\n nodeValue1[3] = 1 - nodeValue1[3];\n\n rgbTransferFunction.setNodeValue(index, nodeValue1);\n }\n}\n","import vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction';\nimport vtkDataArray from '@kitware/vtk.js/Common/Core/DataArray';\nimport { VOIRange } from '../types';\nimport * as windowLevelUtil from './windowLevel';\n\n/**\n * A utility that can be used to generate an Sigmoid RgbTransferFunction.\n * Sigmoid transfer functions are used in the dicom specification:\n * https://dicom.nema.org/medical/dicom/2018b/output/chtml/part03/sect_C.11.2.html\n *\n * @example\n * Setting an RGB Transfer function from the viewport:\n * ```\n * const sigmoidRGBTransferFunction = createSigmoidRGBTransferFunction(0, 255, { lower: 0, upper: 255} );\n * viewport\n * .getActor()\n * .getProperty()\n * .setRGBTransferFunction(0, sigmoidRGBTransferFunction);\n * ```\n *\n * @see {@link https://kitware.github.io/vtk-js/api/Rendering_Core_ColorTransferFunction.html|VTK.js: ColorTransferFunction}\n * @param rgbTransferFunction\n */\nexport default function createSigmoidRGBTransferFunction(\n voiRange: VOIRange,\n approximationNodes = 1024 // humans can precieve no more than 900 shades of gray doi: 10.1007/s10278-006-1052-3\n): vtkColorTransferFunction {\n const { windowWidth, windowCenter } = windowLevelUtil.toWindowLevel(\n voiRange.lower,\n voiRange.upper\n );\n\n // Function is defined by dicom spec\n // https://dicom.nema.org/medical/dicom/2018b/output/chtml/part03/sect_C.11.2.html\n const sigmoid = (x: number, wc: number, ww: number) => {\n return 1 / (1 + Math.exp((-4 * (x - wc)) / ww));\n };\n\n // This function is the analytical inverse of the dicom spec sigmoid function\n // for values y = [0, 1] exclusive. We use this to perform better sampling of\n // points for the LUT as some images can have 2^16 unique values. This method\n // can be deprecated if vtk supports LUTFunctions rather than look up tables\n // or if vtk supports logistic scale. It currently only supports linear and\n // log10 scaling which can be set on the vtkColorTransferFunction\n const logit = (y: number, wc: number, ww: number) => {\n return wc - (ww / 4) * Math.log((1 - y) / y);\n };\n\n // we slice out the first and last value to avoid 0 and 1 Infinity values\n const range = [...Array(approximationNodes + 2).keys()]\n .map((v) => v / (approximationNodes + 2))\n .slice(1, -1);\n const table = range.reduce((res, y) => {\n const x = logit(y, windowCenter, windowWidth);\n return res.concat(x, y, y, y, 0.5, 0.0);\n }, []);\n\n const cfun = vtkColorTransferFunction.newInstance();\n cfun.buildFunctionFromArray(\n vtkDataArray.newInstance({ values: table, numberOfComponents: 6 })\n );\n return cfun;\n}\n","/**\n * Retrieves the volume ID from a target ID. Target Id is not only\n * volumeId but might include other information, but it starts with volumeId.\n *\n * @param targetId - The target ID from which to extract the volume ID.\n * @returns The volume ID extracted from the target ID.\n */\nexport const getVolumeId = (targetId: string) => {\n const prefix = 'volumeId:';\n const str = targetId.includes(prefix)\n ? targetId.substring(prefix.length)\n : targetId;\n\n const index = str.indexOf('?');\n return index === -1 ? str : str.substring(0, index);\n};\n","import cache from '../cache/cache';\nimport { EPSILON } from '../constants';\nimport { ICamera, IImageVolume, IVolumeViewport, Point3 } from '../types';\nimport getSpacingInNormalDirection from './getSpacingInNormalDirection';\nimport { getVolumeLoaderSchemes } from '../loaders/volumeLoader';\nimport { getVolumeId } from './getVolumeId';\n\n// One EPSILON part larger multiplier\nconst EPSILON_PART = 1 + EPSILON;\n\nconst startsWith = (str, starts) =>\n starts === str.substring(0, Math.min(str.length, starts.length));\n\n// Check if this is a primary volume\n// For now, that means it came from some sort of image loader, but\n// should be specifically designated.\nconst isPrimaryVolume = (volume): boolean =>\n !!getVolumeLoaderSchemes().find((scheme) =>\n startsWith(volume.volumeId, scheme)\n );\n\n/**\n * Given a volume viewport and camera, find the target volume.\n * The imageVolume is retrieved from cache for the specified targetId or\n * in case it is not provided, it chooses the volumeId on the viewport (there\n * might be more than one in case of fusion) that has the finest resolution in the\n * direction of view (normal).\n *\n * @param viewport - volume viewport\n * @param camera - current camera\n * @param targetId - If a targetId is forced to be used.\n * @param useSlabThickness - If true, the number of steps will be calculated\n * based on the slab thickness instead of the spacing in the normal direction\n * @returns An object containing the imageVolume and spacingInNormalDirection.\n *\n */\nexport default function getTargetVolumeAndSpacingInNormalDir(\n viewport: IVolumeViewport,\n camera: ICamera,\n targetId?: string,\n useSlabThickness = false\n): {\n imageVolume: IImageVolume;\n spacingInNormalDirection: number;\n actorUID: string;\n} {\n const { viewPlaneNormal } = camera;\n const volumeActors = viewport.getActors();\n\n if (!volumeActors || !volumeActors.length) {\n return {\n spacingInNormalDirection: null,\n imageVolume: null,\n actorUID: null,\n };\n }\n\n const imageVolumes = volumeActors\n .map((va) => {\n // prefer the referenceUID if it is set, since it can be a derived actor\n // and the uid does not necessarily match the volumeId\n const actorUID = va.referenceId ?? va.uid;\n return cache.getVolume(actorUID);\n })\n .filter((iv) => !!iv);\n\n // If a volumeId is defined, set that volume as the target\n if (targetId) {\n const targetVolumeId = getVolumeId(targetId);\n const imageVolumeIndex = imageVolumes.findIndex((iv) =>\n targetVolumeId.includes(iv.volumeId)\n );\n\n const imageVolume = imageVolumes[imageVolumeIndex];\n const { uid: actorUID } = volumeActors[imageVolumeIndex];\n\n const spacingInNormalDirection = getSpacingInNormal(\n imageVolume,\n viewPlaneNormal,\n viewport,\n useSlabThickness\n );\n\n return { imageVolume, spacingInNormalDirection, actorUID };\n }\n\n if (!imageVolumes.length) {\n return {\n spacingInNormalDirection: null,\n imageVolume: null,\n actorUID: null,\n };\n }\n\n // Fetch volume actor with finest resolution in direction of projection.\n const smallest = {\n spacingInNormalDirection: Infinity,\n imageVolume: null,\n actorUID: null,\n };\n\n const hasPrimaryVolume = imageVolumes.find(isPrimaryVolume);\n\n for (let i = 0; i < imageVolumes.length; i++) {\n const imageVolume = imageVolumes[i];\n\n if (hasPrimaryVolume && !isPrimaryVolume(imageVolume)) {\n // Secondary volumes like segmentation don't count towards spacing\n continue;\n }\n\n const spacingInNormalDirection = getSpacingInNormal(\n imageVolume,\n viewPlaneNormal,\n viewport\n );\n\n // Allow for EPSILON part larger requirement to prefer earlier volumes\n // when the spacing is within a factor of EPSILON. Use a factor because\n // that deals with very small or very large volumes effectively.\n if (\n spacingInNormalDirection * EPSILON_PART <\n smallest.spacingInNormalDirection\n ) {\n smallest.spacingInNormalDirection = spacingInNormalDirection;\n smallest.imageVolume = imageVolume;\n smallest.actorUID = volumeActors[i].uid;\n }\n }\n\n return smallest;\n}\n\nfunction getSpacingInNormal(\n imageVolume: IImageVolume,\n viewPlaneNormal: Point3,\n viewport: IVolumeViewport,\n useSlabThickness = false\n): number {\n const { slabThickness } = viewport.getProperties();\n let spacingInNormalDirection = slabThickness;\n if (!slabThickness || useSlabThickness === false) {\n spacingInNormalDirection = getSpacingInNormalDirection(\n imageVolume,\n viewPlaneNormal\n );\n }\n\n return spacingInNormalDirection;\n}\n","import getSliceRange from './getSliceRange';\nimport getTargetVolumeAndSpacingInNormalDir from './getTargetVolumeAndSpacingInNormalDir';\nimport {\n ActorSliceRange,\n IVolumeViewport,\n ICamera,\n VolumeActor,\n} from '../types';\n\n/**\n * Calculates the slice range for the given volume based on its orientation\n * @param viewport - Volume viewport\n * @param volumeId - Id of one of the volumes loaded on the given viewport\n * @param useSlabThickness - If true, the slice range will be calculated\n * based on the slab thickness instead of the spacing in the normal direction\n * @returns slice range information\n */\nfunction getVolumeSliceRangeInfo(\n viewport: IVolumeViewport,\n volumeId: string,\n useSlabThickness = false\n): {\n sliceRange: ActorSliceRange;\n spacingInNormalDirection: number;\n camera: ICamera;\n} {\n const camera = viewport.getCamera();\n const { focalPoint, viewPlaneNormal } = camera;\n const { spacingInNormalDirection, actorUID } =\n getTargetVolumeAndSpacingInNormalDir(\n viewport,\n camera,\n volumeId,\n useSlabThickness\n );\n\n if (!actorUID) {\n throw new Error(\n `Could not find image volume with id ${volumeId} in the viewport`\n );\n }\n\n const actorEntry = viewport.getActor(actorUID);\n\n if (!actorEntry) {\n console.warn('No actor found for with actorUID of', actorUID);\n return null;\n }\n\n const volumeActor = actorEntry.actor as VolumeActor;\n const sliceRange = getSliceRange(volumeActor, viewPlaneNormal, focalPoint);\n\n return {\n sliceRange,\n spacingInNormalDirection,\n camera,\n };\n}\n\nexport default getVolumeSliceRangeInfo;\n","import { IVolumeViewport } from '../types';\nimport getVolumeSliceRangeInfo from './getVolumeSliceRangeInfo';\n\n/**\n * Calculates the number os steps the volume can scroll based on its orientation\n * @param viewport - Volume viewport\n * @param volumeId - Id of one of the volumes loaded on the given viewport\n * @param useSlabThickness - If true, the number of steps will be calculated\n * based on the slab thickness instead of the spacing in the normal direction\n * @returns number of steps the volume can scroll and its current position\n */\nfunction getVolumeViewportScrollInfo(\n viewport: IVolumeViewport,\n volumeId: string,\n useSlabThickness = false\n) {\n const { sliceRange, spacingInNormalDirection, camera } =\n getVolumeSliceRangeInfo(viewport, volumeId, useSlabThickness);\n\n const { min, max, current } = sliceRange;\n\n // Now we can see how many steps there are in this direction\n const numScrollSteps = Math.round((max - min) / spacingInNormalDirection);\n\n // Find out current frameIndex\n const fraction = (current - min) / (max - min);\n const floatingStepNumber = fraction * numScrollSteps;\n const currentStepIndex = Math.round(floatingStepNumber);\n\n return {\n numScrollSteps,\n currentStepIndex,\n sliceRangeInfo: {\n sliceRange,\n spacingInNormalDirection,\n camera,\n },\n };\n}\n\nexport default getVolumeViewportScrollInfo;\n","import vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction';\nimport vtkPiecewiseFunction from '@kitware/vtk.js/Common/DataModel/PiecewiseFunction';\nimport { ViewportPreset } from '../types';\nimport { VolumeActor } from '../types/IActor';\n\n/**\n * Applies a preset to a volume actor.\n *\n * @param actor - The volume actor to apply the preset to.\n * @param preset - The preset to apply.\n */\nexport default function applyPreset(\n actor: VolumeActor,\n preset: ViewportPreset\n) {\n // Create color transfer function\n const colorTransferArray = preset.colorTransfer\n .split(' ')\n .splice(1)\n .map(parseFloat);\n\n const { shiftRange } = getShiftRange(colorTransferArray);\n const min = shiftRange[0];\n const width = shiftRange[1] - shiftRange[0];\n const cfun = vtkColorTransferFunction.newInstance();\n const normColorTransferValuePoints = [];\n for (let i = 0; i < colorTransferArray.length; i += 4) {\n let value = colorTransferArray[i];\n const r = colorTransferArray[i + 1];\n const g = colorTransferArray[i + 2];\n const b = colorTransferArray[i + 3];\n\n value = (value - min) / width;\n normColorTransferValuePoints.push([value, r, g, b]);\n }\n\n applyPointsToRGBFunction(normColorTransferValuePoints, shiftRange, cfun);\n\n actor.getProperty().setRGBTransferFunction(0, cfun);\n\n // Create scalar opacity function\n const scalarOpacityArray = preset.scalarOpacity\n .split(' ')\n .splice(1)\n .map(parseFloat);\n\n const ofun = vtkPiecewiseFunction.newInstance();\n const normPoints = [];\n for (let i = 0; i < scalarOpacityArray.length; i += 2) {\n let value = scalarOpacityArray[i];\n const opacity = scalarOpacityArray[i + 1];\n\n value = (value - min) / width;\n\n normPoints.push([value, opacity]);\n }\n\n applyPointsToPiecewiseFunction(normPoints, shiftRange, ofun);\n\n const property = actor.getProperty();\n\n property.setScalarOpacity(0, ofun);\n const [\n gradientMinValue,\n gradientMinOpacity,\n gradientMaxValue,\n gradientMaxOpacity,\n ] = preset.gradientOpacity.split(' ').splice(1).map(parseFloat);\n\n property.setUseGradientOpacity(0, true);\n property.setGradientOpacityMinimumValue(0, gradientMinValue);\n property.setGradientOpacityMinimumOpacity(0, gradientMinOpacity);\n property.setGradientOpacityMaximumValue(0, gradientMaxValue);\n property.setGradientOpacityMaximumOpacity(0, gradientMaxOpacity);\n\n if (preset.interpolation === '1') {\n property.setInterpolationTypeToFastLinear();\n //property.setInterpolationTypeToLinear()\n }\n\n property.setShade(preset.shade === '1');\n\n const ambient = parseFloat(preset.ambient);\n const diffuse = parseFloat(preset.diffuse);\n const specular = parseFloat(preset.specular);\n const specularPower = parseFloat(preset.specularPower);\n\n property.setAmbient(ambient);\n property.setDiffuse(diffuse);\n property.setSpecular(specular);\n property.setSpecularPower(specularPower);\n}\n\nfunction getShiftRange(colorTransferArray) {\n // Credit to paraview-glance\n // https://github.com/Kitware/paraview-glance/blob/3fec8eeff31e9c19ad5b6bff8e7159bd745e2ba9/src/components/controls/ColorBy/script.js#L133\n\n // shift range is original rgb/opacity range centered around 0\n let min = Infinity;\n let max = -Infinity;\n for (let i = 0; i < colorTransferArray.length; i += 4) {\n min = Math.min(min, colorTransferArray[i]);\n max = Math.max(max, colorTransferArray[i]);\n }\n\n const center = (max - min) / 2;\n\n return {\n shiftRange: [-center, center],\n min,\n max,\n };\n}\n\nfunction applyPointsToRGBFunction(points, range, cfun) {\n const width = range[1] - range[0];\n const rescaled = points.map(([x, r, g, b]) => [\n x * width + range[0],\n r,\n g,\n b,\n ]);\n\n cfun.removeAllPoints();\n rescaled.forEach(([x, r, g, b]) => cfun.addRGBPoint(x, r, g, b));\n\n return rescaled;\n}\n\nfunction applyPointsToPiecewiseFunction(points, range, pwf) {\n const width = range[1] - range[0];\n const rescaled = points.map(([x, y]) => [x * width + range[0], y]);\n\n pwf.removeAllPoints();\n rescaled.forEach(([x, y]) => pwf.addPoint(x, y));\n\n return rescaled;\n}\n","import { ImageSliceData, IVolumeViewport, VolumeActor } from '../types';\nimport getSliceRange from './getSliceRange';\nimport getTargetVolumeAndSpacingInNormalDir from './getTargetVolumeAndSpacingInNormalDir';\n\n/**\n * It calculates the number of slices and the current slice index for a given\n * Volume viewport\n * @param viewport - volume viewport\n * @returns An object with two properties: numberOfSlices and imageIndex.\n */\nfunction getImageSliceDataForVolumeViewport(\n viewport: IVolumeViewport\n): ImageSliceData {\n const camera = viewport.getCamera();\n\n const { spacingInNormalDirection, imageVolume } =\n getTargetVolumeAndSpacingInNormalDir(viewport, camera);\n\n if (!imageVolume) {\n return;\n }\n\n const { viewPlaneNormal, focalPoint } = camera;\n\n const actorEntry = viewport\n .getActors()\n .find(\n (a) =>\n a.referenceId === imageVolume.volumeId || a.uid === imageVolume.volumeId\n );\n\n if (!actorEntry) {\n console.warn('No actor found for with actorUID of', imageVolume.volumeId);\n }\n\n const volumeActor = actorEntry.actor as VolumeActor;\n const sliceRange = getSliceRange(volumeActor, viewPlaneNormal, focalPoint);\n\n const { min, max, current } = sliceRange;\n\n // calculate number of steps from min to max with current normal spacing in direction\n const numberOfSlices = Math.round((max - min) / spacingInNormalDirection) + 1;\n\n // calculate the imageIndex based on min, max, current\n let imageIndex = ((current - min) / (max - min)) * numberOfSlices;\n imageIndex = Math.floor(imageIndex);\n\n // Clamp imageIndex\n if (imageIndex > numberOfSlices - 1) {\n imageIndex = numberOfSlices - 1;\n } else if (imageIndex < 0) {\n imageIndex = 0;\n }\n\n return {\n numberOfSlices,\n imageIndex,\n };\n}\n\nexport default getImageSliceDataForVolumeViewport;\n","import {\n getImageSliceDataForVolumeViewport,\n triggerEvent,\n} from '../../utilities';\nimport { EventTypes } from '../../types';\nimport { Events } from '../../enums';\nimport { getRenderingEngine } from '../getRenderingEngine';\nimport BaseVolumeViewport from '../BaseVolumeViewport';\n\n// Keeping track of previous imageIndex for each viewportId\ntype VolumeImageState = Record<string, number>;\n\nconst state: VolumeImageState = {};\n\nexport function resetVolumeNewImageState(viewportId: string): void {\n if (state[viewportId] !== undefined) {\n delete state[viewportId];\n }\n}\n\n/**\n * It captures the camera modified event and with the camera focal point and viewPlaneNomad\n * it calculates the image index in the view direction. Finally it triggers\n * a VOLUME_NEW_IMAGE event with the image index.\n *\n * @internal\n *\n * @param cameraEvent - The camera modified event\n * @param viewportImageData - The image data of the viewport\n */\nfunction volumeNewImageEventDispatcher(\n cameraEvent: EventTypes.CameraModifiedEvent\n): void {\n const { renderingEngineId, viewportId } = cameraEvent.detail;\n const renderingEngine = getRenderingEngine(renderingEngineId);\n const viewport = renderingEngine.getViewport(viewportId);\n\n if (!(viewport instanceof BaseVolumeViewport)) {\n throw new Error(\n `volumeNewImageEventDispatcher: viewport is not a BaseVolumeViewport`\n );\n }\n\n if (state[viewport.id] === undefined) {\n state[viewport.id] = 0;\n }\n\n const sliceData = getImageSliceDataForVolumeViewport(viewport);\n\n if (!sliceData) {\n console.warn(\n `volumeNewImageEventDispatcher: sliceData is undefined for viewport ${viewport.id}`\n );\n return;\n }\n\n const { numberOfSlices, imageIndex } = sliceData;\n\n if (state[viewport.id] === imageIndex) {\n return;\n }\n\n state[viewport.id] = imageIndex;\n\n const eventDetail: EventTypes.VolumeNewImageEventDetail = {\n imageIndex,\n viewportId,\n renderingEngineId,\n numberOfSlices,\n };\n\n triggerEvent(viewport.element, Events.VOLUME_NEW_IMAGE, eventDetail);\n}\n\nexport default volumeNewImageEventDispatcher;\n","import { Point3, Plane } from '../types';\nimport { vec3, mat3 } from 'gl-matrix';\n\n/**\n * It calculates the intersection of a line and a plane.\n * Plane equation is Ax+By+Cz=D\n * @param p0 - [x,y,z] of the first point of the line\n * @param p1 - [x,y,z] of the second point of the line\n * @param plane - [A, B, C, D] Plane parameter: Ax+By+Cz=D\n * @returns - [X,Y,Z] coordinates of the intersection\n */\nfunction linePlaneIntersection(p0: Point3, p1: Point3, plane: Plane): Point3 {\n const [x0, y0, z0] = p0;\n const [x1, y1, z1] = p1;\n const [A, B, C, D] = plane;\n const a = x1 - x0;\n const b = y1 - y0;\n const c = z1 - z0;\n const t = (-1 * (A * x0 + B * y0 + C * z0 - D)) / (A * a + B * b + C * c);\n const X = a * t + x0;\n const Y = b * t + y0;\n const Z = c * t + z0;\n\n return [X, Y, Z];\n}\n\n/**\n * It returns the plane equation defined by a point and a normal vector.\n * @param normal - normal vector\n * @param point - a point on the plane\n * @param normalized - if true, the values of the plane equation will be normalized\n * @returns - [A, B,C, D] of plane equation A*X + B*Y + C*Z = D\n */\nfunction planeEquation(\n normal: Point3,\n point: Point3 | vec3,\n normalized = false\n): Plane {\n const [A, B, C] = normal;\n const D = A * point[0] + B * point[1] + C * point[2];\n\n if (normalized) {\n const length = Math.sqrt(A * A + B * B + C * C);\n return [A / length, B / length, C / length, D / length];\n }\n\n return [A, B, C, D];\n}\n\n/**\n * Computes the intersection of three planes in 3D space with equations:\n * A1*X + B1*Y + C1*Z = D1\n * A2*X + B2*Y + C2*Z = D2\n * A3*X + B3*Y + C3*Z = D3\n * @returns - [x, y, z] the intersection in the world coordinate\n */\nfunction threePlaneIntersection(\n firstPlane: Plane,\n secondPlane: Plane,\n thirdPlane: Plane\n): Point3 {\n const [A1, B1, C1, D1] = firstPlane;\n const [A2, B2, C2, D2] = secondPlane;\n const [A3, B3, C3, D3] = thirdPlane;\n const m0 = mat3.fromValues(A1, A2, A3, B1, B2, B3, C1, C2, C3);\n const m1 = mat3.fromValues(D1, D2, D3, B1, B2, B3, C1, C2, C3);\n const m2 = mat3.fromValues(A1, A2, A3, D1, D2, D3, C1, C2, C3);\n const m3 = mat3.fromValues(A1, A2, A3, B1, B2, B3, D1, D2, D3);\n\n // TODO: handle no intersection scenario\n const x = mat3.determinant(m1) / mat3.determinant(m0);\n const y = mat3.determinant(m2) / mat3.determinant(m0);\n const z = mat3.determinant(m3) / mat3.determinant(m0);\n return [x, y, z];\n}\n\n/**\n * Computes the distance of a point in 3D space to a plane\n * @param plane - [A, B, C, D] of plane equation A*X + B*Y + C*Z = D\n * @param point - [A, B, C] the plane in World coordinate\n * @param signed - if true, the distance is signed\n * @returns - the distance of the point to the plane\n * */\nfunction planeDistanceToPoint(\n plane: Plane,\n point: Point3,\n signed = false\n): number {\n const [A, B, C, D] = plane;\n const [x, y, z] = point;\n const numerator = A * x + B * y + C * z - D;\n const distance = Math.abs(numerator) / Math.sqrt(A * A + B * B + C * C);\n const sign = signed ? Math.sign(numerator) : 1;\n return sign * distance;\n}\n\nexport {\n linePlaneIntersection,\n planeEquation,\n threePlaneIntersection,\n planeDistanceToPoint,\n};\n","/**\n * A function that checks if there is a value in the array that is NaN.\n * or if the input is a number it just checks if it is NaN.\n * @param input - The input to check if it is NaN.\n * @returns - True if the input is NaN, false otherwise.\n */\nexport default function hasNaNValues(input: number[] | number): boolean {\n if (Array.isArray(input)) {\n return input.some((value) => Number.isNaN(value));\n }\n return Number.isNaN(input);\n}\n","import type { vtkCamera } from '@kitware/vtk.js/Rendering/Core/Camera';\nimport vtkMatrixBuilder from '@kitware/vtk.js/Common/Core/MatrixBuilder';\nimport vtkMath from '@kitware/vtk.js/Common/Core/Math';\nimport vtkPlane from '@kitware/vtk.js/Common/DataModel/Plane';\n\nimport { vec2, vec3 } from 'gl-matrix';\n\nimport Events from '../enums/Events';\nimport ViewportStatus from '../enums/ViewportStatus';\nimport ViewportType from '../enums/ViewportType';\nimport renderingEngineCache from './renderingEngineCache';\nimport {\n triggerEvent,\n planar,\n isImageActor,\n actorIsA,\n isEqual,\n} from '../utilities';\nimport hasNaNValues from '../utilities/hasNaNValues';\nimport { RENDERING_DEFAULTS } from '../constants';\nimport type {\n ICamera,\n ActorEntry,\n IRenderingEngine,\n ViewportInputOptions,\n Point2,\n Point3,\n FlipDirection,\n EventTypes,\n DisplayArea,\n ViewPresentation,\n ViewReference,\n ViewportProperties,\n} from '../types';\nimport type {\n ViewportInput,\n IViewport,\n ViewReferenceSpecifier,\n ReferenceCompatibleOptions,\n ViewPresentationSelector,\n} from '../types/IViewport';\nimport type { vtkSlabCamera } from './vtkClasses/vtkSlabCamera';\nimport { getConfiguration } from '../init';\nimport IImageCalibration from '../types/IImageCalibration';\nimport { InterpolationType } from '../enums';\n\n/**\n * An object representing a single viewport, which is a camera\n * looking into a viewport, and an associated target output `HTMLDivElement`.\n * Viewport is a base class that can be extended to create a specific\n * viewport type. Both VolumeViewport and StackViewport are subclasses\n * of Viewport. Common logic for all viewports is contained in Viewport class\n * which is camera properties/methods, vtk.js actors, and other common\n * logic.\n */\nclass Viewport implements IViewport {\n /**\n * CameraViewPresentation is a view preentation selector that has all the\n * camera related presentation selections, and would typically be used for\n * choosing presentation information between two viewports showing the same\n * type of orientation of a view, such as the CT, PT and fusion views in the\n * same orientation view.\n */\n public static readonly CameraViewPresentation: ViewPresentationSelector = {\n rotation: true,\n pan: true,\n zoom: true,\n displayArea: true,\n };\n\n /**\n * TransferViewPresentation is a view presentation selector that selects all\n * the transfer function related attributes. It would typically be used for\n * synchronizing different orientations of the same series, or for\n * synchronizing two views of the same type of series such as a CT.\n */\n public static readonly TransferViewPresentation: ViewPresentationSelector = {\n windowLevel: true,\n paletteLut: true,\n };\n\n /** unique identifier for the viewport */\n readonly id: string;\n /** HTML element in DOM that is used for rendering the viewport */\n readonly element: HTMLDivElement;\n /** an internal canvas that is created on the provided HTML element */\n readonly canvas: HTMLCanvasElement;\n /** RenderingEngine id that the viewport belongs to */\n readonly renderingEngineId: string;\n /** Type of viewport */\n readonly type: ViewportType;\n /**\n * The amount by which the images are inset in a viewport by default.\n */\n protected insetImageMultiplier = 1.1;\n\n protected flipHorizontal = false;\n protected flipVertical = false;\n public isDisabled: boolean;\n /** Record the rendering status, mostly for testing purposes, but can also\n * be useful for knowing things like whether the viewport is initialized\n */\n public viewportStatus: ViewportStatus = ViewportStatus.NO_DATA;\n\n /** sx of viewport on the offscreen canvas */\n sx: number;\n /** sy of viewport on the offscreen canvas */\n sy: number;\n /** sWidth of viewport on the offscreen canvas */\n sWidth: number;\n /** sHeight of viewport on the offscreen canvas */\n sHeight: number;\n /** a Map containing the actor uid and actors */\n _actors: Map<string, any>;\n /** Default options for the viewport which includes orientation, viewPlaneNormal and backgroundColor */\n readonly defaultOptions: Record<string, any>;\n /** options for the viewport which includes orientation axis, backgroundColor and displayArea */\n options: ViewportInputOptions;\n /** informs if a new actor was added before a resetCameraClippingRange phase */\n _suppressCameraModifiedEvents = false;\n /** A flag representing if viewport methods should fire events or not */\n readonly suppressEvents: boolean;\n protected hasPixelSpacing = true;\n protected calibration: IImageCalibration;\n /** The camera that is initially defined on the reset for\n * the relative pan/zoom\n */\n protected initialCamera: ICamera;\n /** The camera that is defined for resetting displayArea to ensure absolute displayArea\n * settings\n */\n protected fitToCanvasCamera: ICamera;\n\n constructor(props: ViewportInput) {\n this.id = props.id;\n this.renderingEngineId = props.renderingEngineId;\n this.type = props.type;\n this.element = props.element;\n this.canvas = props.canvas;\n this.sx = props.sx;\n this.sy = props.sy;\n this.sWidth = props.sWidth;\n this.sHeight = props.sHeight;\n this._actors = new Map();\n // Set data attributes for render events\n this.element.setAttribute('data-viewport-uid', this.id);\n this.element.setAttribute(\n 'data-rendering-engine-uid',\n this.renderingEngineId\n );\n\n this.defaultOptions = structuredClone(props.defaultOptions);\n this.suppressEvents = props.defaultOptions.suppressEvents\n ? props.defaultOptions.suppressEvents\n : false;\n this.options = structuredClone(props.defaultOptions);\n this.isDisabled = false;\n }\n\n getRotation: () => number;\n getFrameOfReferenceUID: () => string;\n canvasToWorld: (canvasPos: Point2) => Point3;\n worldToCanvas: (worldPos: Point3) => Point2;\n customRenderViewportToCanvas: () => unknown;\n resize: () => void;\n getProperties: () => ViewportProperties = () => ({});\n updateRenderingPipeline: () => void;\n getNumberOfSlices: () => number;\n protected setRotation = (_rotation: number) => {\n /*empty*/\n };\n\n static get useCustomRenderingPipeline(): boolean {\n return false;\n }\n\n private viewportWidgets = new Map() as Map<string, any>;\n\n public addWidget = (widgetId, widget) => {\n this.viewportWidgets.set(widgetId, widget);\n };\n\n public getWidget = (id) => {\n return this.viewportWidgets.get(id);\n };\n\n public getWidgets = () => {\n return Array.from(this.viewportWidgets.values());\n };\n\n public removeWidgets = () => {\n const widgets = this.getWidgets();\n widgets.forEach((widget) => {\n if (widget.getEnabled()) {\n widget.setEnabled(false);\n }\n if (widget.getActor && widget.getRenderer) {\n const actor = widget.getActor();\n const renderer = widget.getRenderer();\n if (renderer && actor) {\n renderer.removeActor(actor);\n }\n }\n });\n };\n\n /**\n * Indicate that the image has been rendered.\n * This will set the viewportStatus to RENDERED if there is image data\n * available to actually be rendered - otherwise, the rendering simply showed\n * the background image.\n */\n public setRendered() {\n if (\n this.viewportStatus === ViewportStatus.NO_DATA ||\n this.viewportStatus === ViewportStatus.LOADING\n ) {\n return;\n }\n this.viewportStatus = ViewportStatus.RENDERED;\n }\n\n /**\n * Returns the rendering engine driving the `Viewport`.\n *\n * @returns The RenderingEngine instance.\n */\n public getRenderingEngine(): IRenderingEngine {\n return renderingEngineCache.get(this.renderingEngineId);\n }\n\n /**\n * Returns the `vtkRenderer` responsible for rendering the `Viewport`.\n *\n * @returns The `vtkRenderer` for the `Viewport`.\n */\n public getRenderer(): any {\n const renderingEngine = this.getRenderingEngine();\n\n if (!renderingEngine || renderingEngine.hasBeenDestroyed) {\n throw new Error('Rendering engine has been destroyed');\n }\n\n return renderingEngine.offscreenMultiRenderWindow.getRenderer(this.id);\n }\n\n /**\n * Renders the `Viewport` using the `RenderingEngine`.\n */\n public render(): void {\n const renderingEngine = this.getRenderingEngine();\n\n renderingEngine.renderViewport(this.id);\n }\n\n /**\n * Sets new options and (TODO) applies them.\n *\n * @param options - The viewport options to set.\n * @param immediate - If `true`, renders the viewport after the options are set.\n */\n public setOptions(options: ViewportInputOptions, immediate = false): void {\n this.options = <ViewportInputOptions>structuredClone(options);\n\n // TODO When this is needed we need to move the camera position.\n // We can steal some logic from the tools we build to do this.\n if (this.options?.displayArea) {\n this.setDisplayArea(this.options?.displayArea);\n }\n if (immediate) {\n this.render();\n }\n }\n\n /**\n * Resets the options the `Viewport`'s `defaultOptions`\n *\n * @param immediate - If `true`, renders the viewport after the options are reset.\n */\n public reset(immediate = false) {\n this.options = structuredClone(this.defaultOptions);\n\n // TODO When this is needed we need to move the camera position.\n // We can steal some logic from the tools we build to do this.\n\n if (immediate) {\n this.render();\n }\n }\n\n /**\n * Flip the viewport on horizontal or vertical axis, this method\n * works with vtk-js backed rendering pipeline.\n *\n * @param flipOptions - Flip options specifying the axis of flip\n * * flipOptions.flipHorizontal - Flip the viewport on horizontal axis\n * * flipOptions.flipVertical - Flip the viewport on vertical axis\n */\n protected flip({ flipHorizontal, flipVertical }: FlipDirection): void {\n const imageData = this.getDefaultImageData();\n\n if (!imageData) {\n return;\n }\n\n const camera = this.getCamera();\n const { viewPlaneNormal, viewUp, focalPoint, position } = camera;\n\n const viewRight = vec3.cross(vec3.create(), viewPlaneNormal, viewUp);\n let viewUpToSet = vec3.copy(vec3.create(), viewUp);\n const viewPlaneNormalToSet = vec3.negate(vec3.create(), viewPlaneNormal);\n\n // for both flip horizontal and vertical we need to move the camera to the\n // other side of the image\n const distance = vec3.distance(position, focalPoint);\n\n // If the pan has been applied, we need to be able\n // apply the pan back\n const dimensions = imageData.getDimensions();\n const middleIJK = dimensions.map((d) => Math.floor(d / 2));\n\n const idx = [middleIJK[0], middleIJK[1], middleIJK[2]];\n const centeredFocalPoint = imageData.indexToWorld(idx, vec3.create());\n\n const resetFocalPoint = this._getFocalPointForResetCamera(\n centeredFocalPoint as Point3,\n camera,\n { resetPan: true, resetToCenter: false }\n );\n\n const panDir = vec3.subtract(vec3.create(), focalPoint, resetFocalPoint);\n const panValue = vec3.length(panDir);\n\n const getPanDir = (mirrorVec) => {\n const panDirMirror = vec3.scale(\n vec3.create(),\n mirrorVec,\n 2 * vec3.dot(panDir, mirrorVec)\n );\n vec3.subtract(panDirMirror, panDirMirror, panDir);\n vec3.normalize(panDirMirror, panDirMirror);\n\n return panDirMirror;\n };\n\n // Flipping horizontal mean that the camera should move\n // to the other side of the image but looking at the\n // same direction and same focal point\n if (flipHorizontal) {\n // we need to apply the pan value to the new focal point but in the direction\n // that is mirrored on the viewUp for the flip horizontal and\n // viewRight for the flip vertical\n\n // mirror the pan direction based on the viewUp\n const panDirMirror = getPanDir(viewUpToSet);\n\n // move focal point from the resetFocalPoint to the newFocalPoint\n // based on the panDirMirror and panValue\n const newFocalPoint = vec3.scaleAndAdd(\n vec3.create(),\n resetFocalPoint,\n panDirMirror,\n panValue\n );\n\n // move the camera position also the same way as the focal point\n const newPosition = vec3.scaleAndAdd(\n vec3.create(),\n newFocalPoint,\n viewPlaneNormalToSet,\n distance\n );\n\n this.setCamera({\n viewPlaneNormal: viewPlaneNormalToSet as Point3,\n position: newPosition as Point3,\n focalPoint: newFocalPoint as Point3,\n });\n\n this.flipHorizontal = !this.flipHorizontal;\n }\n\n // Flipping vertical mean that the camera should negate the view up\n // and also move to the other side of the image but looking at the\n if (flipVertical) {\n viewUpToSet = vec3.negate(viewUpToSet, viewUp);\n\n // we need to apply the pan value to the new focal point but in the direction\n const panDirMirror = getPanDir(viewRight);\n\n const newFocalPoint = vec3.scaleAndAdd(\n vec3.create(),\n resetFocalPoint,\n panDirMirror,\n panValue\n );\n\n const newPosition = vec3.scaleAndAdd(\n vec3.create(),\n newFocalPoint,\n viewPlaneNormalToSet,\n distance\n );\n\n this.setCamera({\n focalPoint: newFocalPoint as Point3,\n viewPlaneNormal: viewPlaneNormalToSet as Point3,\n viewUp: viewUpToSet as Point3,\n position: newPosition as Point3,\n });\n\n this.flipVertical = !this.flipVertical;\n }\n\n this.render();\n }\n\n private getDefaultImageData(): any {\n const actorEntry = this.getDefaultActor();\n\n if (actorEntry && isImageActor(actorEntry)) {\n return actorEntry.actor.getMapper().getInputData();\n }\n }\n\n /**\n * Get the default actor\n * @returns An actor entry.\n */\n public getDefaultActor(): ActorEntry {\n return this.getActors()[0];\n }\n\n /**\n * Get all the actors in the viewport\n * @returns An array of ActorEntry objects.\n */\n public getActors(): Array<ActorEntry> {\n return Array.from(this._actors.values());\n }\n\n /**\n * Returns an array of unique identifiers for all the actors in the viewport.\n * @returns An array of strings\n */\n public getActorUIDs(): Array<string> {\n return Array.from(this._actors.keys());\n }\n\n /**\n * Get an actor by its UID\n * @param actorUID - The unique ID of the actor.\n * @returns An ActorEntry object.\n */\n public getActor(actorUID: string): ActorEntry {\n return this._actors.get(actorUID);\n }\n\n /**\n * Get an actor UID by its index\n * @param index - array index.\n * @returns actorUID\n */\n public getActorUIDByIndex(index: number): string {\n const actor = this.getActors()[index];\n if (actor) {\n return actor.uid;\n }\n }\n\n /**\n * Get an actor by its index\n * @param index - array index.\n * @returns actorUID\n */\n public getActorByIndex(index: number): ActorEntry {\n return this.getActors()[index];\n }\n\n /**\n * It removes all actors from the viewport and then adds the actors from the array.\n * @param actors - An array of ActorEntry objects.\n */\n public setActors(actors: Array<ActorEntry>): void {\n this.removeAllActors();\n const resetCameraPanAndZoom = true;\n // when we set the actor we need to reset the camera to initialize the\n // camera focal point with the bounds of the actors.\n this.addActors(actors, resetCameraPanAndZoom);\n }\n\n /**\n * Remove the actor from the viewport\n * @param actorUID - The unique identifier for the actor.\n */\n _removeActor(actorUID: string): void {\n const actorEntry = this.getActor(actorUID);\n if (!actorEntry) {\n console.warn(`Actor ${actorUID} does not exist for this viewport`);\n return;\n }\n const renderer = this.getRenderer();\n renderer.removeViewProp(actorEntry.actor); // removeActor not implemented in vtk?\n this._actors.delete(actorUID);\n }\n\n /**\n * Remove the actors with the given UIDs from the viewport\n * @param actorUIDs - An array of actor UIDs to remove.\n */\n public removeActors(actorUIDs: Array<string>): void {\n actorUIDs.forEach((actorUID) => {\n this._removeActor(actorUID);\n });\n }\n\n /**\n * Add a list of actors (actor entries) to the viewport\n * @param resetCameraPanAndZoom - force reset pan and zoom of the camera,\n * default value is false.\n * @param actors - An array of ActorEntry objects.\n */\n public addActors(\n actors: Array<ActorEntry>,\n resetCameraPanAndZoom = false\n ): void {\n const renderingEngine = this.getRenderingEngine();\n if (!renderingEngine || renderingEngine.hasBeenDestroyed) {\n console.warn(\n 'Viewport::addActors::Rendering engine has not been initialized or has been destroyed'\n );\n return;\n }\n\n actors.forEach((actor) => this.addActor(actor));\n\n // set the clipping planes for the actors\n this.resetCamera(resetCameraPanAndZoom, resetCameraPanAndZoom);\n }\n\n /**\n * Add an actor to the viewport including its id, its actor and slabThickness\n * if defined\n * @param actorEntry - ActorEntry\n * * actorEntry.uid - The unique identifier for the actor.\n * * actorEntry.actor - The volume actor.\n * * actorEntry.slabThickness - The slab thickness.\n */\n public addActor(actorEntry: ActorEntry): void {\n const { uid: actorUID, actor } = actorEntry;\n const renderingEngine = this.getRenderingEngine();\n\n if (!renderingEngine || renderingEngine.hasBeenDestroyed) {\n console.warn(\n `Cannot add actor UID of ${actorUID} Rendering Engine has been destroyed`\n );\n return;\n }\n\n if (!actorUID || !actor) {\n throw new Error('Actors should have uid and vtk Actor properties');\n }\n\n if (this.getActor(actorUID)) {\n console.warn(`Actor ${actorUID} already exists for this viewport`);\n return;\n }\n\n const renderer = this.getRenderer();\n renderer?.addActor(actor);\n this._actors.set(actorUID, Object.assign({}, actorEntry));\n\n // when we add an actor we should update the camera clipping range and\n // clipping planes as well\n this.updateCameraClippingPlanesAndRange();\n }\n\n /**\n * Remove all actors from the renderer\n */\n public removeAllActors(): void {\n this.getRenderer()?.removeAllViewProps();\n this._actors = new Map();\n return;\n }\n\n /**\n * Reset the camera to the default viewport camera without firing events\n */\n protected resetCameraNoEvent(): void {\n this._suppressCameraModifiedEvents = true;\n this.resetCamera();\n this._suppressCameraModifiedEvents = false;\n }\n\n /**\n * Sets the camera to the default viewport camera without firing events\n * @param camera - The camera to use for the viewport.\n */\n protected setCameraNoEvent(camera: ICamera): void {\n this._suppressCameraModifiedEvents = true;\n this.setCamera(camera);\n this._suppressCameraModifiedEvents = false;\n }\n\n /**\n * Calculates the intersections between the volume's boundaries and the viewplane.\n * 1) Determine the viewplane using the camera's ViewplaneNormal and focalPoint.\n * 2) Using volumeBounds, calculate the line equation for the 3D volume's 12 edges.\n * 3) Intersect each edge to the viewPlane and see whether the intersection point is inside the volume bounds.\n * 4) Return list of intersection points\n * It should be noted that intersection points may range from 3 to 6 points.\n * Orthogonal views have four points of intersection.\n *\n * @param imageData - vtkImageData\n * @param focalPoint - camera focal point\n * @param normal - view plane normal\n * @returns intersections list\n */\n private _getViewImageDataIntersections(imageData, focalPoint, normal) {\n // Viewplane equation: Ax+By+Cz=D\n const A = normal[0];\n const B = normal[1];\n const C = normal[2];\n const D = A * focalPoint[0] + B * focalPoint[1] + C * focalPoint[2];\n\n // Computing the edges of the 3D cube\n const bounds = imageData.getBounds();\n const edges = this._getEdges(bounds);\n\n const intersections = [];\n\n for (const edge of edges) {\n // start point: [x0, y0, z0], end point: [x1, y1, z1]\n const [[x0, y0, z0], [x1, y1, z1]] = edge;\n // Check if the edge is parallel to plane\n if (A * (x1 - x0) + B * (y1 - y0) + C * (z1 - z0) === 0) {\n continue;\n }\n const intersectionPoint = planar.linePlaneIntersection(\n [x0, y0, z0],\n [x1, y1, z1],\n [A, B, C, D]\n );\n\n if (this._isInBounds(intersectionPoint, bounds)) {\n intersections.push(intersectionPoint);\n }\n }\n\n return intersections;\n }\n\n /**\n * Sets the interpolation type. No-op in the base.\n */\n protected setInterpolationType(_interpolationType: InterpolationType, _arg?) {\n // No-op - just done to allow setting on the base viewport\n }\n\n /**\n * Sets the camera to an initial bounds. If\n * resetPan and resetZoom are true it places the focal point at the center of\n * the volume (or slice); otherwise, only the camera zoom and camera Pan or Zoom\n * is reset for the current view.\n * @param displayArea - The display area of interest.\n * @param suppressEvents - If true, don't fire displayArea event.\n */\n public setDisplayArea(\n displayArea: DisplayArea,\n suppressEvents = false\n ): void {\n if (!displayArea) {\n return;\n }\n const { storeAsInitialCamera, type: areaType } = displayArea;\n\n // Instead of storing the camera itself, if initial camera is set,\n // then store the display area as the baseline display area.\n if (storeAsInitialCamera) {\n this.options.displayArea = displayArea;\n }\n\n // make calculations relative to the fitToCanvasCamera view\n const { _suppressCameraModifiedEvents } = this;\n this._suppressCameraModifiedEvents = true;\n\n // This should only apply for storeAsInitialCamera, but the calculations\n // currently don't quite work otherwise.\n // TODO - fix so that the store works for existing transforms\n this.setCamera(this.fitToCanvasCamera);\n\n if (areaType === 'SCALE') {\n this.setDisplayAreaScale(displayArea);\n } else {\n this.setInterpolationType(\n this.getProperties()?.interpolationType || InterpolationType.LINEAR\n );\n this.setDisplayAreaFit(displayArea);\n }\n\n // Set the initial camera if appropriate\n if (storeAsInitialCamera) {\n this.initialCamera = this.getCamera();\n }\n\n // Restore event firing\n this._suppressCameraModifiedEvents = _suppressCameraModifiedEvents;\n if (!suppressEvents && !_suppressCameraModifiedEvents) {\n const eventDetail: EventTypes.DisplayAreaModifiedEventDetail = {\n viewportId: this.id,\n displayArea: displayArea,\n storeAsInitialCamera: storeAsInitialCamera,\n };\n\n triggerEvent(this.element, Events.DISPLAY_AREA_MODIFIED, eventDetail);\n this.setCamera(this.getCamera());\n }\n }\n\n /**\n * Sets the viewport to pixel scaling mode. Pixel scaling displays\n * 1 image pixel as 1 (or scale) physical screen pixels. That is,\n * a 1024x512 image will be displayed with scale=2, as 2048x1024\n * physical image pixels.\n *\n * @param displayArea - display area to set\n * * displayArea.scale - the number of physical pixels to display\n * each image pixel in. Values `< 1` mean smaller than physical,\n * while values `> 1` mean more than one pixel. Default is 1\n * Suggest using whole numbers or integer fractions (eg `1/3`)\n */\n protected setDisplayAreaScale(displayArea: DisplayArea): void {\n const { scale = 1 } = displayArea;\n const canvas = this.canvas;\n const height = canvas.height;\n const width = canvas.width;\n if (height < 8 || width < 8) {\n return;\n }\n const imageData = this.getDefaultImageData();\n const spacingWorld = imageData.getSpacing();\n const spacing = spacingWorld[1];\n // Need nearest interpolation for scale\n this.setInterpolationType(InterpolationType.NEAREST);\n this.setCamera({ parallelScale: (height * spacing) / (2 * scale) });\n\n // If this is scale, then image area isn't allowed, so just delete it to be safe\n delete displayArea.imageArea;\n // Apply the pan values from the display area.\n this.setDisplayAreaFit(displayArea);\n\n // Need to ensure the focal point is aligned with the canvas size/position\n // so that we don't get half pixel rendering, which causes additional\n // moire patterns to be displayed.\n // This is based on the canvas size having the center pixel be at a fractional\n // position when the size is even, so matching a fractional position on the\n // focal point to the center of an image pixel.\n const { focalPoint, position, viewUp, viewPlaneNormal } = this.getCamera();\n const focalChange = vec3.create();\n if (canvas.height % 2) {\n vec3.scaleAndAdd(focalChange, focalChange, viewUp, scale * 0.5 * spacing);\n }\n if (canvas.width % 2) {\n const viewRight = vec3.cross(vec3.create(), viewUp, viewPlaneNormal);\n vec3.scaleAndAdd(\n focalChange,\n focalChange,\n viewRight,\n scale * 0.5 * spacing\n );\n }\n if (!focalChange[0] && !focalChange[1] && !focalChange[2]) {\n return;\n }\n this.setCamera({\n focalPoint: <Point3>vec3.add(vec3.create(), focalPoint, focalChange),\n position: <Point3>vec3.add(vec3.create(), position, focalChange),\n });\n }\n\n /**\n * This applies a display area with a fit of the provided area to the\n * available area.\n * The zoom level is controlled by the imageArea parameter, which is a pair\n * of percentage width in the horizontal and vertical dimension is scaled\n * to fit the displayable area. Both values are taken into account, and the\n * scaling is set so that both fractions of the image area are visible.\n *\n * The panning is controlled by the imageCanvasPoint, which has two\n * values, teh imagePoint and the canvasPoint. They are fractional\n * values of the image and canvas respectively, with the panning set to\n * display the image pixel at the given fraction on top of the canvas at the\n * given percentage. The default points are 0.5.\n *\n * For example, if the zoom level is [2,1], then the image is displayed\n * such that at least twice the width is visible, and the height is visible.\n * That will result in the image width being black, divided up on the left\n * and right according to the imageCanvasPoint\n *\n * Then, if the imagePoint is [1,0] and the canvas point is [1,0], then\n * the right most edge of the image, at the top of the image, will be\n * displayed at the right most edge of the canvas, at the top.\n *\n */\n protected setDisplayAreaFit(displayArea: DisplayArea) {\n const { imageArea, imageCanvasPoint } = displayArea;\n\n const devicePixelRatio = window?.devicePixelRatio || 1;\n const imageData = this.getDefaultImageData();\n if (!imageData) {\n return;\n }\n const canvasWidth = this.sWidth / devicePixelRatio;\n const canvasHeight = this.sHeight / devicePixelRatio;\n const dimensions = imageData.getDimensions();\n const canvasZero = this.worldToCanvas(imageData.indexToWorld([0, 0, 0]));\n const canvasEdge = this.worldToCanvas(\n imageData.indexToWorld([\n dimensions[0] - 1,\n dimensions[1] - 1,\n dimensions[2],\n ])\n );\n\n const canvasImage = [\n Math.abs(canvasEdge[0] - canvasZero[0]),\n Math.abs(canvasEdge[1] - canvasZero[1]),\n ];\n const [imgWidth, imgHeight] = canvasImage;\n\n if (imageArea) {\n const [areaX, areaY] = imageArea;\n const requireX = Math.abs((areaX * imgWidth) / canvasWidth);\n const requireY = Math.abs((areaY * imgHeight) / canvasHeight);\n\n const initZoom = this.getZoom();\n const fitZoom = this.getZoom(this.fitToCanvasCamera);\n const absZoom = Math.min(1 / requireX, 1 / requireY);\n const applyZoom = (absZoom * initZoom) / fitZoom;\n this.setZoom(applyZoom, false);\n }\n\n // getting the image info\n // getting the image info\n if (imageCanvasPoint) {\n const { imagePoint, canvasPoint = imagePoint || [0.5, 0.5] } =\n imageCanvasPoint;\n const [canvasX, canvasY] = canvasPoint;\n const canvasPanX = canvasWidth * (canvasX - 0.5);\n const canvasPanY = canvasHeight * (canvasY - 0.5);\n\n const [imageX, imageY] = imagePoint || canvasPoint;\n const useZoom = 1;\n const imagePanX = useZoom * imgWidth * (0.5 - imageX);\n const imagePanY = useZoom * imgHeight * (0.5 - imageY);\n\n const newPositionX = imagePanX + canvasPanX;\n const newPositionY = imagePanY + canvasPanY;\n\n const deltaPoint2: Point2 = [newPositionX, newPositionY];\n // Use getPan from current for the setting\n vec2.add(deltaPoint2, deltaPoint2, this.getPan());\n // The pan is part of the display area settings, not the initial camera, so\n // don't store as initial camera here - that breaks rotation and other changes.\n this.setPan(deltaPoint2, false);\n }\n }\n\n public getDisplayArea(): DisplayArea | undefined {\n return this.options?.displayArea;\n }\n\n /**\n * Resets the camera based on the rendering volume(s) bounds. If\n * resetPan and resetZoom are true it places the focal point at the center of\n * the volume (or slice); otherwise, only the camera zoom and camera Pan or Zoom\n * is reset for the current view.\n * @param resetPan - If true, the camera focal point is reset to the center of the volume (slice)\n * @param resetZoom - If true, the camera zoom is reset to the default zoom\n * @param storeAsInitialCamera - If true, reset camera is stored as the initial camera (to allow differences to\n * be detected for pan/zoom values)\n * @returns boolean\n */\n public resetCamera(\n resetPan = true,\n resetZoom = true,\n resetToCenter = true,\n storeAsInitialCamera = true\n ): boolean {\n const renderer = this.getRenderer();\n\n // fix the flip right away, since we rely on the viewPlaneNormal and\n // viewUp for later. Basically, we need to flip back if flipHorizontal\n // is true or flipVertical is true\n // we should use resetCamera no event here, since we don't want to fire\n // camera modified events yet since a proper one will be fired later down\n // below\n this.setCameraNoEvent({\n flipHorizontal: false,\n flipVertical: false,\n });\n\n const previousCamera = structuredClone(this.getCamera());\n const bounds = renderer.computeVisiblePropBounds();\n const focalPoint = <Point3>[0, 0, 0];\n const imageData = this.getDefaultImageData();\n\n // The bounds are used to set the clipping view, which is then used to\n // figure out the center point of each image. This needs to be the depth\n // center, so the bounds need to be extended by the spacing such that the\n // depth center is in the middle of each image.\n if (imageData) {\n const spc = imageData.getSpacing();\n\n bounds[0] = bounds[0] + spc[0] / 2;\n bounds[1] = bounds[1] - spc[0] / 2;\n bounds[2] = bounds[2] + spc[1] / 2;\n bounds[3] = bounds[3] - spc[1] / 2;\n bounds[4] = bounds[4] + spc[2] / 2;\n bounds[5] = bounds[5] - spc[2] / 2;\n }\n\n const activeCamera = this.getVtkActiveCamera();\n const viewPlaneNormal = <Point3>activeCamera.getViewPlaneNormal();\n const viewUp = <Point3>activeCamera.getViewUp();\n\n // Reset the perspective zoom factors, otherwise subsequent zooms will cause\n // the view angle to become very small and cause bad depth sorting.\n // todo: parallel projection only\n\n focalPoint[0] = (bounds[0] + bounds[1]) / 2.0;\n focalPoint[1] = (bounds[2] + bounds[3]) / 2.0;\n focalPoint[2] = (bounds[4] + bounds[5]) / 2.0;\n\n if (imageData) {\n const dimensions = imageData.getDimensions();\n // TODO: This should be the line below, but that causes issues with existing\n // tests. Not doing that adds significant fuzziness on rendering, so at\n // some point it should be fixed.\n // const middleIJK = dimensions.map((d) => Math.floor((d-1) / 2));\n const middleIJK = dimensions.map((d) => Math.floor(d / 2));\n\n const idx = [middleIJK[0], middleIJK[1], middleIJK[2]];\n // Modifies the focal point in place, as this hits the vtk indexToWorld function\n imageData.indexToWorld(idx, focalPoint);\n }\n\n const { widthWorld, heightWorld } =\n this._getWorldDistanceViewUpAndViewRight(bounds, viewUp, viewPlaneNormal);\n\n const canvasSize = [this.sWidth, this.sHeight];\n\n const boundsAspectRatio = widthWorld / heightWorld;\n const canvasAspectRatio = canvasSize[0] / canvasSize[1];\n\n const scaleFactor = boundsAspectRatio / canvasAspectRatio;\n\n const parallelScale =\n scaleFactor < 1 // can fit full height, so use it.\n ? (this.insetImageMultiplier * heightWorld) / 2\n : (this.insetImageMultiplier * heightWorld * scaleFactor) / 2;\n\n // If we have just a single point, pick a radius of 1.0\n // compute the radius of the enclosing sphere\n // For 3D viewport, we should increase the radius to make sure the whole\n // volume is visible and we don't get clipping artifacts.\n const radius =\n Viewport.boundsRadius(bounds) *\n (this.type === ViewportType.VOLUME_3D ? 10 : 1);\n\n const distance = this.insetImageMultiplier * radius;\n\n const viewUpToSet: Point3 =\n Math.abs(vtkMath.dot(viewUp, viewPlaneNormal)) > 0.999\n ? [-viewUp[2], viewUp[0], viewUp[1]]\n : viewUp;\n\n const focalPointToSet = this._getFocalPointForResetCamera(\n focalPoint,\n previousCamera,\n { resetPan, resetToCenter }\n );\n\n const positionToSet: Point3 = [\n focalPointToSet[0] + distance * viewPlaneNormal[0],\n focalPointToSet[1] + distance * viewPlaneNormal[1],\n focalPointToSet[2] + distance * viewPlaneNormal[2],\n ];\n\n renderer.resetCameraClippingRange(bounds);\n\n const clippingRangeToUse: Point2 = [\n -RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE,\n RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE,\n ];\n\n activeCamera.setPhysicalScale(radius);\n activeCamera.setPhysicalTranslation(\n -focalPointToSet[0],\n -focalPointToSet[1],\n -focalPointToSet[2]\n );\n\n this.setCamera({\n parallelScale: resetZoom ? parallelScale : previousCamera.parallelScale,\n focalPoint: focalPointToSet,\n position: positionToSet,\n viewAngle: 90,\n viewUp: viewUpToSet,\n clippingRange: clippingRangeToUse,\n });\n\n const modifiedCamera = structuredClone(this.getCamera());\n\n this.setFitToCanvasCamera(structuredClone(this.getCamera()));\n\n if (storeAsInitialCamera) {\n this.setInitialCamera(modifiedCamera);\n }\n\n if (resetZoom) {\n this.setZoom(1, storeAsInitialCamera);\n }\n\n const RESET_CAMERA_EVENT = {\n type: 'ResetCameraEvent',\n renderer,\n };\n\n // Here to let parallel/distributed compositing intercept\n // and do the right thing.\n renderer.invokeEvent(RESET_CAMERA_EVENT);\n\n this.triggerCameraModifiedEventIfNecessary(previousCamera, modifiedCamera);\n\n if (\n imageData &&\n this.options?.displayArea &&\n resetZoom &&\n resetPan &&\n resetToCenter\n ) {\n this.setDisplayArea(this.options?.displayArea);\n }\n\n return true;\n }\n\n /**\n * Sets the provided camera as the initial camera.\n * This allows computing differences applied later as compared to the initial\n * position, for things like zoom and pan.\n * @param camera - to store as the initial value.\n */\n protected setInitialCamera(camera: ICamera): void {\n this.initialCamera = camera;\n }\n\n /**\n * Sets the provided camera as the displayArea camera.\n * This allows computing differences applied later as compared to the initial\n * position, for things like zoom and pan.\n * @param camera - to store as the initial value.\n */\n protected setFitToCanvasCamera(camera: ICamera): void {\n this.fitToCanvasCamera = camera;\n }\n\n /**\n * Helper function to return the current canvas pan value.\n *\n * @returns a Point2 containing the current pan values\n * on the canvas,\n * computed from the current camera, where the initial pan\n * value is [0,0].\n */\n public getPan(initialCamera = this.initialCamera): Point2 {\n const activeCamera = this.getVtkActiveCamera();\n const focalPoint = activeCamera.getFocalPoint() as Point3;\n\n const zero3 = this.canvasToWorld([0, 0]);\n const initialCanvasFocal = this.worldToCanvas(\n <Point3>vec3.subtract([0, 0, 0], initialCamera.focalPoint, zero3)\n );\n const currentCanvasFocal = this.worldToCanvas(\n <Point3>vec3.subtract([0, 0, 0], focalPoint, zero3)\n );\n const result = <Point2>(\n vec2.subtract([0, 0], initialCanvasFocal, currentCanvasFocal)\n );\n return result;\n }\n\n public getCurrentImageIdIndex(): number {\n throw new Error('Not implemented');\n }\n\n public getSliceIndex(): number {\n throw new Error('Not implemented');\n }\n\n /**\n * Gets a referenced image url of some sort - could be a real image id, or\n * could be a URL with parameters. Regardless it refers to the currently displaying\n * image as a string value.\n */\n public getReferenceId(_specifier?: ViewReferenceSpecifier): string {\n return null;\n }\n\n /**\n * Sets the canvas pan value relative to the initial view position of 0,0\n * Modifies the camera to perform the pan.\n */\n public setPan(pan: Point2, storeAsInitialCamera = false): void {\n const previousCamera = this.getCamera();\n const { focalPoint, position } = previousCamera;\n const zero3 = this.canvasToWorld([0, 0]);\n const delta2 = vec2.subtract([0, 0], pan, this.getPan());\n if (\n Math.abs(delta2[0]) < 1 &&\n Math.abs(delta2[1]) < 1 &&\n !storeAsInitialCamera\n ) {\n return;\n }\n const delta = vec3.subtract(\n vec3.create(),\n this.canvasToWorld(<Point2>delta2),\n zero3\n );\n const newFocal = vec3.subtract(vec3.create(), focalPoint, delta);\n const newPosition = vec3.subtract(vec3.create(), position, delta);\n this.setCamera(\n {\n ...previousCamera,\n focalPoint: newFocal as Point3,\n position: newPosition as Point3,\n },\n storeAsInitialCamera\n );\n }\n\n /**\n * Returns a current zoom level relative to the initial parallel scale\n * originally applied to the image. That is, on initial display,\n * the zoom level is 1. Computed as a function of the camera.\n */\n public getZoom(compareCamera = this.initialCamera): number {\n if (!compareCamera) {\n return 1;\n }\n\n const activeCamera = this.getVtkActiveCamera();\n const { parallelScale: initialParallelScale } = compareCamera;\n return initialParallelScale / activeCamera.getParallelScale();\n }\n\n /** Zooms the image using parallel scale by updating the camera value.\n * @param value - The relative parallel scale to apply. It is relative\n * to the initial offsets value.\n * @param storeAsInitialCamera - can be set to true to reset the camera\n * after applying this zoom as the initial camera. A subsequent getZoom\n * call will return \"1\", but the zoom will have been applied.\n */\n public setZoom(value: number, storeAsInitialCamera = false): void {\n const camera = this.getCamera();\n const { parallelScale: initialParallelScale } = this.initialCamera;\n const parallelScale = initialParallelScale / value;\n if (camera.parallelScale === parallelScale && !storeAsInitialCamera) {\n return;\n }\n this.setCamera(\n {\n ...camera,\n parallelScale,\n },\n storeAsInitialCamera\n );\n }\n\n /**\n * Because the focalPoint is always in the centre of the viewport,\n * we must do planar computations if the frame (image \"slice\") is to be preserved.\n * 1. Calculate the intersection of the view plane with the imageData\n * which results in points of intersection (minimum of 3, maximum of 6)\n * 2. Calculate average of the intersection points to get newFocalPoint\n * 3. Set the new focalPoint\n * @param imageData - imageData\n * @returns focalPoint\n */\n private _getFocalPointForViewPlaneReset(imageData) {\n // Todo: move some where else\n const { focalPoint, viewPlaneNormal: normal } = this.getCamera();\n const intersections = this._getViewImageDataIntersections(\n imageData,\n focalPoint,\n normal\n );\n\n let x = 0;\n let y = 0;\n let z = 0;\n\n intersections.forEach(([point_x, point_y, point_z]) => {\n x += point_x;\n y += point_y;\n z += point_z;\n });\n\n const newFocalPoint = <Point3>[\n x / intersections.length,\n y / intersections.length,\n z / intersections.length,\n ];\n // Set the focal point on the average of the intersection points\n return newFocalPoint;\n }\n\n /**\n * Gets the target output canvas for the `Viewport`.\n *\n * @returns an HTMLCanvasElement.\n */\n public getCanvas(): HTMLCanvasElement {\n return <HTMLCanvasElement>this.canvas;\n }\n /**\n * Gets the active vtkCamera for the viewport.\n *\n * @returns vtk driven camera\n */\n protected getVtkActiveCamera(): vtkCamera | vtkSlabCamera {\n const renderer = this.getRenderer();\n\n return renderer.getActiveCamera();\n }\n\n /**\n * Get the camera's current state\n * @returns The camera object.\n */\n public getCamera(): ICamera {\n const vtkCamera = this.getVtkActiveCamera();\n\n return {\n viewUp: <Point3>vtkCamera.getViewUp(),\n viewPlaneNormal: <Point3>vtkCamera.getViewPlaneNormal(),\n position: <Point3>vtkCamera.getPosition(),\n focalPoint: <Point3>vtkCamera.getFocalPoint(),\n parallelProjection: vtkCamera.getParallelProjection(),\n parallelScale: vtkCamera.getParallelScale(),\n viewAngle: vtkCamera.getViewAngle(),\n flipHorizontal: this.flipHorizontal,\n flipVertical: this.flipVertical,\n };\n }\n\n /**\n * Set the camera parameters\n * @param cameraInterface - ICamera\n * @param storeAsInitialCamera - to set the provided camera as the initial one,\n * used to compute differences for things like pan and zoom.\n */\n public setCamera(\n cameraInterface: ICamera,\n storeAsInitialCamera = false\n ): void {\n const vtkCamera = this.getVtkActiveCamera();\n const previousCamera = structuredClone(this.getCamera());\n const updatedCamera = Object.assign({}, previousCamera, cameraInterface);\n const {\n viewUp,\n viewPlaneNormal,\n position,\n focalPoint,\n parallelScale,\n viewAngle,\n flipHorizontal,\n flipVertical,\n clippingRange,\n } = cameraInterface;\n\n // Note: Flip camera should be two separate calls since\n // for flip, we need to flip the viewportNormal, and if\n // flipHorizontal, and flipVertical are both true, that would\n // the logic would be incorrect. So instead, we handle flip Horizontal\n // and flipVertical separately.\n if (flipHorizontal !== undefined) {\n // flip if not flipped but requested to flip OR if flipped but requested to\n // not flip\n const flipH =\n (flipHorizontal && !this.flipHorizontal) ||\n (!flipHorizontal && this.flipHorizontal);\n\n if (flipH) {\n this.flip({ flipHorizontal: flipH });\n }\n }\n\n if (flipVertical !== undefined) {\n const flipV =\n (flipVertical && !this.flipVertical) ||\n (!flipVertical && this.flipVertical);\n\n if (flipV) {\n this.flip({ flipVertical: flipV });\n }\n }\n\n if (viewUp !== undefined) {\n vtkCamera.setViewUp(viewUp);\n }\n\n if (viewPlaneNormal !== undefined) {\n vtkCamera.setDirectionOfProjection(\n -viewPlaneNormal[0],\n -viewPlaneNormal[1],\n -viewPlaneNormal[2]\n );\n }\n\n if (position !== undefined) {\n vtkCamera.setPosition(...position);\n }\n\n if (focalPoint !== undefined) {\n vtkCamera.setFocalPoint(...focalPoint);\n }\n\n if (parallelScale !== undefined) {\n vtkCamera.setParallelScale(parallelScale);\n }\n\n if (viewAngle !== undefined) {\n vtkCamera.setViewAngle(viewAngle);\n }\n\n if (clippingRange !== undefined) {\n vtkCamera.setClippingRange(clippingRange);\n }\n\n // update clipping range only if focal point changed of a new actor is added\n const prevFocalPoint = previousCamera.focalPoint;\n const prevViewUp = previousCamera.viewUp;\n\n if ((prevFocalPoint && focalPoint) || (prevViewUp && viewUp)) {\n const currentViewPlaneNormal = <Point3>vtkCamera.getViewPlaneNormal();\n const currentViewUp = <Point3>vtkCamera.getViewUp();\n\n let cameraModifiedOutOfPlane = false;\n let viewUpHasChanged = false;\n\n if (focalPoint) {\n const deltaCamera = <Point3>[\n focalPoint[0] - prevFocalPoint[0],\n focalPoint[1] - prevFocalPoint[1],\n focalPoint[2] - prevFocalPoint[2],\n ];\n\n cameraModifiedOutOfPlane =\n Math.abs(vtkMath.dot(deltaCamera, currentViewPlaneNormal)) > 0;\n }\n\n if (viewUp) {\n viewUpHasChanged = !isEqual(currentViewUp, prevViewUp);\n }\n\n // only modify the clipping planes if the camera is modified out of plane\n // or a new actor is added and we need to update the clipping planes\n if (cameraModifiedOutOfPlane || viewUpHasChanged) {\n const actorEntry = this.getDefaultActor();\n if (!actorEntry?.actor) {\n return;\n }\n\n if (!actorIsA(actorEntry, 'vtkActor')) {\n this.updateClippingPlanesForActors(updatedCamera);\n }\n\n if (\n actorIsA(actorEntry, 'vtkImageSlice') ||\n this.type === ViewportType.VOLUME_3D\n ) {\n const renderer = this.getRenderer();\n renderer.resetCameraClippingRange();\n }\n }\n }\n\n if (storeAsInitialCamera) {\n this.setInitialCamera(updatedCamera);\n }\n\n this.triggerCameraModifiedEventIfNecessary(\n previousCamera,\n this.getCamera()\n );\n }\n\n /**\n * Trigger camera modified event\n * @param cameraInterface - ICamera\n * @param cameraInterface - ICamera\n */\n public triggerCameraModifiedEventIfNecessary(\n previousCamera: ICamera,\n updatedCamera: ICamera\n ): void {\n if (!this._suppressCameraModifiedEvents && !this.suppressEvents) {\n const eventDetail: EventTypes.CameraModifiedEventDetail = {\n previousCamera,\n camera: updatedCamera,\n element: this.element,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n rotation: this.getRotation(),\n };\n\n triggerEvent(this.element, Events.CAMERA_MODIFIED, eventDetail);\n }\n }\n\n /**\n * Updates the camera's clipping planes and range.\n */\n public updateCameraClippingPlanesAndRange(): void {\n const currentCamera = this.getCamera();\n this.updateClippingPlanesForActors(currentCamera);\n this.getRenderer().resetCameraClippingRange();\n }\n\n /**\n * Updates the actors clipping planes orientation from the camera properties\n * @param updatedCamera - ICamera\n */\n protected async updateClippingPlanesForActors(\n updatedCamera: ICamera\n ): Promise<void> {\n const actorEntries = this.getActors();\n // Todo: this was using an async and promise wait all because of the\n // new surface rendering use case, which broke the more important 3D\n // volume rendering, so reverting this back for now until I can figure\n // out a better way to handle this.\n actorEntries.map((actorEntry) => {\n // we assume that the first two clipping plane of the mapper are always\n // the 'camera' clipping. Update clipping planes only if the actor is\n // a vtkVolume\n if (!actorEntry.actor) {\n return;\n }\n\n const mapper = actorEntry.actor.getMapper();\n let vtkPlanes = actorEntry?.clippingFilter\n ? actorEntry.clippingFilter.getClippingPlanes()\n : mapper.getClippingPlanes();\n\n if (vtkPlanes.length === 0 && actorEntry?.clippingFilter) {\n vtkPlanes = [vtkPlane.newInstance(), vtkPlane.newInstance()];\n }\n\n let slabThickness = RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS;\n if (actorEntry.slabThickness) {\n slabThickness = actorEntry.slabThickness;\n }\n\n const { viewPlaneNormal, focalPoint } = updatedCamera;\n\n this.setOrientationOfClippingPlanes(\n vtkPlanes,\n slabThickness,\n viewPlaneNormal,\n focalPoint\n );\n triggerEvent(this.element, Events.CLIPPING_PLANES_UPDATED, {\n actorEntry,\n focalPoint,\n vtkPlanes,\n viewport: this,\n });\n });\n }\n\n public setOrientationOfClippingPlanes(\n vtkPlanes: Array<vtkPlane>,\n slabThickness: number,\n viewPlaneNormal: Point3,\n focalPoint: Point3\n ): void {\n if (vtkPlanes.length < 2) {\n return;\n }\n\n const scaledDistance = <Point3>[\n viewPlaneNormal[0],\n viewPlaneNormal[1],\n viewPlaneNormal[2],\n ];\n vtkMath.multiplyScalar(scaledDistance, slabThickness);\n\n vtkPlanes[0].setNormal(viewPlaneNormal);\n const newOrigin1 = <Point3>[0, 0, 0];\n vtkMath.subtract(focalPoint, scaledDistance, newOrigin1);\n vtkPlanes[0].setOrigin(newOrigin1);\n\n vtkPlanes[1].setNormal(\n -viewPlaneNormal[0],\n -viewPlaneNormal[1],\n -viewPlaneNormal[2]\n );\n const newOrigin2 = <Point3>[0, 0, 0];\n vtkMath.add(focalPoint, scaledDistance, newOrigin2);\n vtkPlanes[1].setOrigin(newOrigin2);\n }\n\n /**\n * Method to get the clipping planes of a given actor\n * @param actorEntry - The actor entry (a specific type you'll define dependent on your code)\n * @returns vtkPlanes - An array of vtkPlane objects associated with the given actor\n */\n public getClippingPlanesForActor(actorEntry?: ActorEntry): vtkPlane[] {\n if (!actorEntry) {\n actorEntry = this.getDefaultActor();\n }\n\n if (!actorEntry.actor) {\n throw new Error('Invalid actor entry: Actor is undefined');\n }\n\n const mapper = actorEntry.actor.getMapper();\n let vtkPlanes = actorEntry?.clippingFilter\n ? actorEntry.clippingFilter.getClippingPlanes()\n : mapper.getClippingPlanes();\n\n if (vtkPlanes.length === 0 && actorEntry?.clippingFilter) {\n vtkPlanes = [vtkPlane.newInstance(), vtkPlane.newInstance()];\n }\n\n return vtkPlanes;\n }\n\n private _getWorldDistanceViewUpAndViewRight(bounds, viewUp, viewPlaneNormal) {\n const viewUpCorners = this._getCorners(bounds);\n const viewRightCorners = this._getCorners(bounds);\n\n const viewRight = vec3.cross(vec3.create(), viewUp, viewPlaneNormal);\n\n let transform = vtkMatrixBuilder\n .buildFromDegree()\n .identity()\n .rotateFromDirections(viewUp, [1, 0, 0]);\n\n viewUpCorners.forEach((pt) => transform.apply(pt));\n\n // range is now maximum X distance\n let minY = Infinity;\n let maxY = -Infinity;\n for (let i = 0; i < 8; i++) {\n const y = viewUpCorners[i][0];\n if (y > maxY) {\n maxY = y;\n }\n if (y < minY) {\n minY = y;\n }\n }\n\n transform = vtkMatrixBuilder\n .buildFromDegree()\n .identity()\n .rotateFromDirections(\n [viewRight[0], viewRight[1], viewRight[2]],\n [1, 0, 0]\n );\n\n viewRightCorners.forEach((pt) => transform.apply(pt));\n\n // range is now maximum Y distance\n let minX = Infinity;\n let maxX = -Infinity;\n for (let i = 0; i < 8; i++) {\n const x = viewRightCorners[i][0];\n if (x > maxX) {\n maxX = x;\n }\n if (x < minX) {\n minX = x;\n }\n }\n\n return { widthWorld: maxX - minX, heightWorld: maxY - minY };\n }\n\n /**\n * Gets a view target specifying WHAT a view is displaying,\n * allowing for checking if a given image is displayed or could be displayed\n * in a given viewport.\n * See getViewPresentation for HOW a view is displayed.\n *\n * @param viewRefSpecifier - choose an alternate view to be specified, typically\n * a different slice index in the same set of images.\n */\n public getViewReference(\n viewRefSpecifier: ViewReferenceSpecifier = {}\n ): ViewReference {\n const {\n focalPoint: cameraFocalPoint,\n viewPlaneNormal,\n viewUp,\n } = this.getCamera();\n const target: ViewReference = {\n FrameOfReferenceUID: this.getFrameOfReferenceUID(),\n cameraFocalPoint,\n viewPlaneNormal,\n viewUp,\n sliceIndex: viewRefSpecifier.sliceIndex ?? this.getSliceIndex(),\n };\n return target;\n }\n\n /**\n * Find out if this viewport does or could show this view reference.\n *\n * @param options - allows specifying whether the view COULD display this with\n * some modification - either navigation or displaying as volume.\n * @returns true if the viewport could show this view reference\n */\n public isReferenceViewable(\n viewRef: ViewReference,\n options?: ReferenceCompatibleOptions\n ): boolean {\n if (\n viewRef.FrameOfReferenceUID &&\n viewRef.FrameOfReferenceUID !== this.getFrameOfReferenceUID()\n ) {\n return false;\n }\n\n const { viewPlaneNormal } = viewRef;\n const camera = this.getCamera();\n if (\n viewPlaneNormal &&\n !isEqual(viewPlaneNormal, camera.viewPlaneNormal) &&\n !isEqual(\n vec3.negate(camera.viewPlaneNormal, camera.viewPlaneNormal),\n viewPlaneNormal\n )\n ) {\n // Could navigate as a volume to the reference with an orientation change\n return options?.withOrientation === true;\n }\n return true;\n }\n\n /**\n * Gets a view presentation information specifying HOW a viewport displays\n * something, but not what is being displayed.\n * See getViewReference to get information on WHAT is being displayed.\n *\n * This is intended to have information on how an image is presented to the user, without\n * specifying what image s displayed. All of this information is available\n * externally, but this method combines the parts of this that are appropriate\n * for remember or applying to other views, without necessarily needing to know\n * what all the atributes are. That differs from methods like getCamera which\n * fetch exact view details that are not likely to be identical between viewports\n * as they change sizes or apply to different images.\n *\n * Note that the results of this can be used on different viewports, for example,\n * the pan values can be applied to a volume viewport showing a CT, and a\n * stack viewport showing an ultrasound.\n *\n * The selector allows choosing which view presentation attributes to return.\n * Some default values are available from `Viewport.CameraViewPresentation` and\n * `Viewport.TransferViewPresentation`\n *\n * @param viewPresSel - select which attributes to display.\n */\n public getViewPresentation(\n viewPresSel: ViewPresentationSelector = {\n rotation: true,\n displayArea: true,\n zoom: true,\n pan: true,\n }\n ): ViewPresentation {\n const target: ViewPresentation = {};\n\n const { rotation, displayArea, zoom, pan } = viewPresSel;\n if (rotation) {\n target.rotation = this.getRotation();\n }\n if (displayArea) {\n target.displayArea = this.getDisplayArea();\n }\n const initZoom = this.getZoom();\n\n if (zoom) {\n target.zoom = initZoom;\n }\n if (pan) {\n target.pan = this.getPan();\n vec2.scale(target.pan, target.pan, 1 / initZoom);\n }\n return target;\n }\n\n /**\n * Navigates to the image specified by the viewRef.\n */\n public setViewReference(viewRef: ViewReference) {\n // No-op\n }\n\n /**\n * Applies the display area, zoom, pan and rotation from the view presentation.\n * No-op is viewPres isn't defined.\n */\n public setViewPresentation(viewPres: ViewPresentation) {\n if (!viewPres) {\n return;\n }\n const { displayArea, zoom = this.getZoom(), pan, rotation } = viewPres;\n if (displayArea !== this.getDisplayArea()) {\n this.setDisplayArea(displayArea);\n }\n this.setZoom(zoom);\n if (pan) {\n this.setPan(vec2.scale([0, 0], pan, zoom) as Point2);\n }\n if (rotation >= 0) {\n this.setRotation(rotation);\n }\n }\n\n protected _shouldUseNativeDataType() {\n const { useNorm16Texture, preferSizeOverAccuracy } =\n getConfiguration().rendering;\n return useNorm16Texture || preferSizeOverAccuracy;\n }\n\n _getCorners(bounds: Array<number>): Array<number>[] {\n return [\n [bounds[0], bounds[2], bounds[4]],\n [bounds[0], bounds[2], bounds[5]],\n [bounds[0], bounds[3], bounds[4]],\n [bounds[0], bounds[3], bounds[5]],\n [bounds[1], bounds[2], bounds[4]],\n [bounds[1], bounds[2], bounds[5]],\n [bounds[1], bounds[3], bounds[4]],\n [bounds[1], bounds[3], bounds[5]],\n ];\n }\n\n _getFocalPointForResetCamera(\n centeredFocalPoint: Point3,\n previousCamera: ICamera,\n { resetPan = true, resetToCenter = true }\n ): Point3 {\n if (resetToCenter && resetPan) {\n return centeredFocalPoint;\n }\n\n if (resetToCenter && !resetPan) {\n return hasNaNValues(previousCamera.focalPoint)\n ? centeredFocalPoint\n : previousCamera.focalPoint;\n }\n\n if (!resetToCenter && resetPan) {\n // this is an interesting case that means the reset camera should not\n // change the slice (default behavior is to go to the center of the\n // image), and rather just reset the pan on the slice that is currently\n // being viewed\n const oldCamera = previousCamera;\n const oldFocalPoint = oldCamera.focalPoint;\n const oldViewPlaneNormal = oldCamera.viewPlaneNormal;\n\n const vectorFromOldFocalPointToCenteredFocalPoint = vec3.subtract(\n vec3.create(),\n centeredFocalPoint,\n oldFocalPoint\n );\n\n const distanceFromOldFocalPointToCenteredFocalPoint = vec3.dot(\n vectorFromOldFocalPointToCenteredFocalPoint,\n oldViewPlaneNormal\n );\n\n const newFocalPoint = vec3.scaleAndAdd(\n vec3.create(),\n centeredFocalPoint,\n oldViewPlaneNormal,\n -1 * distanceFromOldFocalPointToCenteredFocalPoint\n );\n\n return [newFocalPoint[0], newFocalPoint[1], newFocalPoint[2]];\n }\n\n if (!resetPan && !resetToCenter) {\n // this means the reset camera should not change the slice and should not\n // touch the pan either.\n return hasNaNValues(previousCamera.focalPoint)\n ? centeredFocalPoint\n : previousCamera.focalPoint;\n }\n }\n\n /**\n * Determines whether or not the 3D point position is inside the boundaries of the 3D imageData.\n * @param point - 3D coordinate\n * @param bounds - Bounds of the image\n * @returns boolean\n */\n _isInBounds(point: Point3, bounds: number[]): boolean {\n const [xMin, xMax, yMin, yMax, zMin, zMax] = bounds;\n const [x, y, z] = point;\n if (x < xMin || x > xMax || y < yMin || y > yMax || z < zMin || z > zMax) {\n return false;\n }\n return true;\n }\n\n /**\n * Returns a list of edges for the imageData bounds, which are\n * the cube edges in the case of volumeViewport edges.\n * p1: front, bottom, left\n * p2: front, top, left\n * p3: back, bottom, left\n * p4: back, top, left\n * p5: front, bottom, right\n * p6: front, top, right\n * p7: back, bottom, right\n * p8: back, top, right\n * @param bounds - Bounds of the renderer\n * @returns Edges of the containing bounds\n */\n _getEdges(bounds: Array<number>): Array<[number[], number[]]> {\n const [p1, p2, p3, p4, p5, p6, p7, p8] = this._getCorners(bounds);\n return [\n [p1, p2],\n [p1, p5],\n [p1, p3],\n [p2, p4],\n [p2, p6],\n [p3, p4],\n [p3, p7],\n [p4, p8],\n [p5, p7],\n [p5, p6],\n [p6, p8],\n [p7, p8],\n ];\n }\n\n /**\n * Computes the bounds radius value\n */\n static boundsRadius(bounds: number[]) {\n const w1 = (bounds[1] - bounds[0]) ** 2;\n const w2 = (bounds[3] - bounds[2]) ** 2;\n const w3 = (bounds[5] - bounds[4]) ** 2;\n\n // If we have just a single point, pick a radius of 1.0\n // compute the radius of the enclosing sphere\n // For 3D viewport, we should increase the radius to make sure the whole\n // volume is visible and we don't get clipping artifacts.\n const radius = Math.sqrt(w1 + w2 + w3 || 1) * 0.5;\n return radius;\n }\n}\n\nexport default Viewport;\n","import macro from '@kitware/vtk.js/macros';\nimport vtkCamera from '@kitware/vtk.js/Rendering/Core/Camera';\nimport vtkMath from '@kitware/vtk.js/Common/Core/Math';\nimport { vec3, mat4 } from 'gl-matrix';\nimport type { vtkObject } from '@kitware/vtk.js/interfaces';\n\n// Copied from VTKCamera\n\n/**\n *\n */\ninterface ICameraInitialValues {\n position?: number[];\n focalPoint?: number[];\n viewUp?: number[];\n directionOfProjection?: number[];\n parallelProjection?: boolean;\n useHorizontalViewAngle?: boolean;\n viewAngle?: number;\n parallelScale?: number;\n clippingRange?: number[];\n windowCenter?: number[];\n viewPlaneNormal?: number[];\n useOffAxisProjection?: boolean;\n screenBottomLeft?: number[];\n screenBottomRight?: number[];\n screenTopRight?: number[];\n freezeFocalPoint?: boolean;\n physicalTranslation?: number[];\n physicalScale?: number;\n physicalViewUp?: number[];\n physicalViewNorth?: number[];\n}\n\nexport interface vtkSlabCamera extends vtkObject {\n /**\n * Apply a transform to the camera.\n * The camera position, focal-point, and view-up are re-calculated\n * using the transform's matrix to multiply the old points by the new transform.\n * @param transformMat4 -\n */\n applyTransform(transformMat4: mat4): void;\n\n /**\n * Rotate the camera about the view up vector centered at the focal point.\n * @param angle -\n */\n azimuth(angle: number): void;\n\n /**\n *\n * @param bounds -\n */\n computeClippingRange(bounds: number[]): number[];\n\n /**\n * This method must be called when the focal point or camera position changes\n */\n computeDistance(): void;\n\n /**\n * the provided matrix should include\n * translation and orientation only\n * mat is physical to view\n * @param mat -\n */\n computeViewParametersFromPhysicalMatrix(mat: mat4): void;\n\n /**\n *\n * @param vmat -\n */\n computeViewParametersFromViewMatrix(vmat: mat4): void;\n\n /**\n * Not implemented yet\n * @param sourceCamera -\n */\n deepCopy(sourceCamera: vtkSlabCamera): void;\n\n /**\n * Move the position of the camera along the view plane normal. Moving\n * towards the focal point (e.g., greater than 1) is a dolly-in, moving away\n * from the focal point (e.g., less than 1) is a dolly-out.\n * @param amount -\n */\n dolly(amount: number): void;\n\n /**\n * Rotate the camera about the cross product of the negative of the direction of projection and the view up vector, using the focal point as the center of rotation.\n * @param angle -\n */\n elevation(angle: number): void;\n\n /**\n * Not implemented yet\n */\n getCameraLightTransformMatrix(): void;\n\n /**\n *\n * @defaultValue [0.01, 1000.01],\n */\n getClippingRange(): number[];\n\n /**\n *\n * @defaultValue [0.01, 1000.01],\n */\n getClippingRangeByReference(): number[];\n\n /**\n *\n * @param aspect - Camera frustum aspect ratio.\n * @param nearz - Camera frustum near plane.\n * @param farz - Camera frustum far plane.\n */\n getCompositeProjectionMatrix(\n aspect: number,\n nearz: number,\n farz: number\n ): mat4;\n\n /**\n * Get the vector in the direction from the camera position to the focal point.\n * @defaultValue [0, 0, -1],\n */\n getDirectionOfProjection(): number[];\n\n /**\n *\n * @defaultValue [0, 0, -1],\n */\n getDirectionOfProjectionByReference(): number[];\n\n /**\n * Get the distance from the camera position to the focal point.\n */\n getDistance(): number;\n\n /**\n *\n * @defaultValue [0, 0, 0]\n */\n getFocalPoint(): number[];\n\n /**\n *\n */\n getFocalPointByReference(): number[];\n\n /**\n *\n * @defaultValue false\n */\n getFreezeFocalPoint(): boolean;\n\n setFreezeFocalPoint(freeze: boolean): void;\n\n /**\n * Not implemented yet\n * @param aspect - Camera frustum aspect ratio.\n */\n getFrustumPlanes(aspect: number): void;\n\n /**\n * Not implemented yet\n */\n getOrientation(): void;\n\n /**\n * Not implemented yet\n */\n getOrientationWXYZ(): void;\n\n /**\n *\n * @defaultValue false\n */\n getParallelProjection(): boolean;\n\n /**\n *\n * @defaultValue 1\n */\n getParallelScale(): number;\n\n /**\n *\n * @defaultValue 1.0\n */\n getPhysicalScale(): number;\n\n /**\n *\n * @param result -\n */\n getPhysicalToWorldMatrix(result: mat4): void;\n\n /**\n *\n */\n getPhysicalTranslation(): number[];\n\n /**\n *\n */\n getPhysicalTranslationByReference(): number[];\n\n /**\n *\n * @defaultValue [0, 0, -1],\n */\n getPhysicalViewNorth(): number[];\n\n /**\n *\n */\n getPhysicalViewNorthByReference(): number[];\n\n /**\n *\n * @defaultValue [0, 1, 0]\n */\n getPhysicalViewUp(): number[];\n\n /**\n *\n */\n getPhysicalViewUpByReference(): number[];\n\n /**\n * Get the position of the camera in world coordinates.\n * @defaultValue [0, 0, 1]\n */\n getPosition(): number[];\n\n /**\n *\n */\n getPositionByReference(): number[];\n\n /**\n *\n * @param aspect - Camera frustum aspect ratio.\n * @param nearz - Camera frustum near plane.\n * @param farz - Camera frustum far plane.\n * @defaultValue null\n */\n getProjectionMatrix(aspect: number, nearz: number, farz: number): null | mat4;\n\n /**\n * Not implemented yet\n * Get the roll angle of the camera about the direction of projection.\n */\n getRoll(): void;\n\n /**\n * Get top left corner point of the screen.\n * @defaultValue [-0.5, -0.5, -0.5]\n */\n getScreenBottomLeft(): number[];\n\n /**\n *\n * @defaultValue [-0.5, -0.5, -0.5]\n */\n getScreenBottomLeftByReference(): number[];\n\n /**\n * Get bottom left corner point of the screen\n * @defaultValue [0.5, -0.5, -0.5]\n */\n getScreenBottomRight(): number[];\n\n /**\n *\n * @defaultValue [0.5, -0.5, -0.5]\n */\n getScreenBottomRightByReference(): number[];\n\n /**\n *\n * @defaultValue [0.5, 0.5, -0.5]\n */\n getScreenTopRight(): number[];\n\n /**\n *\n * @defaultValue [0.5, 0.5, -0.5]\n */\n getScreenTopRightByReference(): number[];\n\n /**\n * Get the center of the window in viewport coordinates.\n */\n getThickness(): number;\n\n /**\n * Get the value of the UseHorizontalViewAngle instance variable.\n * @defaultValue false\n */\n getUseHorizontalViewAngle(): boolean;\n\n /**\n * Get use offaxis frustum.\n * @defaultValue false\n */\n getUseOffAxisProjection(): boolean;\n\n /**\n * Get the camera view angle.\n * @defaultValue 30\n */\n getViewAngle(): number;\n\n /**\n *\n * @defaultValue null\n */\n getViewMatrix(): null | mat4;\n\n /**\n * Get the ViewPlaneNormal.\n * This vector will point opposite to the direction of projection,\n * unless you have created a sheared output view using SetViewShear/SetObliqueAngles.\n * @defaultValue [0, 0, 1]\n */\n getViewPlaneNormal(): number[];\n\n /**\n * Get the ViewPlaneNormal by reference.\n */\n getViewPlaneNormalByReference(): number[];\n\n /**\n * Get ViewUp vector.\n * @defaultValue [0, 1, 0]\n */\n getViewUp(): number[];\n\n /**\n * Get ViewUp vector by reference.\n * @defaultValue [0, 1, 0]\n */\n getViewUpByReference(): number[];\n\n /**\n * Get the center of the window in viewport coordinates.\n * The viewport coordinate range is ([-1,+1],[-1,+1]).\n * @defaultValue [0, 0]\n */\n getWindowCenter(): number[];\n\n /**\n *\n * @defaultValue [0, 0]\n */\n getWindowCenterByReference(): number[];\n\n /**\n *\n * @param result -\n */\n getWorldToPhysicalMatrix(result: mat4): void;\n\n /**\n *\n * @defaultValue false\n */\n getIsPerformingCoordinateTransformation(status: boolean): void;\n\n /**\n * Recompute the ViewUp vector to force it to be perpendicular to the camera's focalpoint vector.\n */\n orthogonalizeViewUp(): void;\n\n /**\n *\n * @param ori -\n */\n physicalOrientationToWorldDirection(ori: number[]): any;\n\n /**\n * Rotate the focal point about the cross product of the view up vector and the direction of projection, using the camera's position as the center of rotation.\n * @param angle -\n */\n pitch(angle: number): void;\n\n /**\n * Rotate the camera about the direction of projection.\n * @param angle -\n */\n roll(angle: number): void;\n\n /**\n * Set the location of the near and far clipping planes along the direction\n * of projection.\n * @param near -\n * @param far -\n */\n setClippingRange(near: number, far: number): boolean;\n\n /**\n * Set the location of the near and far clipping planes along the direction\n * of projection.\n * @param clippingRange -\n */\n setClippingRange(clippingRange: number[]): boolean;\n\n /**\n *\n * @param clippingRange -\n */\n setClippingRangeFrom(clippingRange: number[]): boolean;\n\n /**\n * used to handle convert js device orientation angles\n * when you use this method the camera will adjust to the\n * device orientation such that the physicalViewUp you set\n * in world coordinates looks up, and the physicalViewNorth\n * you set in world coorindates will (maybe) point north\n *\n * NOTE WARNING - much of the documentation out there on how\n * orientation works is seriously wrong. Even worse the Chrome\n * device orientation simulator is completely wrong and should\n * never be used. OMG it is so messed up.\n *\n * how it seems to work on iOS is that the device orientation\n * is specified in extrinsic angles with a alpha, beta, gamma\n * convention with axes of Z, X, Y (the code below substitutes\n * the physical coordinate system for these axes to get the right\n * modified coordinate system.\n * @param alpha -\n * @param beta -\n * @param gamma -\n * @param screen -\n */\n setDeviceAngles(\n alpha: number,\n beta: number,\n gamma: number,\n screen: number\n ): boolean;\n\n /**\n *\n * @param x - The x coordinate.\n * @param y - The y coordinate.\n * @param z - The z coordinate.\n */\n setDirectionOfProjection(x: number, y: number, z: number): boolean;\n\n /**\n *\n * @param distance -\n */\n setDistance(distance: number): boolean;\n\n /**\n *\n * @param x - The x coordinate.\n * @param y - The y coordinate.\n * @param z - The z coordinate.\n */\n setFocalPoint(x: number, y: number, z: number): boolean;\n\n /**\n *\n * @param focalPoint -\n */\n setFocalPointFrom(focalPoint: number[]): boolean;\n\n /**\n * Not implement yet\n * Set the oblique viewing angles.\n * The first angle, alpha, is the angle (measured from the horizontal) that rays along\n * the direction of projection will follow once projected onto the 2D screen.\n * The second angle, beta, is the angle between the view plane and the direction of projection.\n * This creates a shear transform x' = x + dz*cos(alpha)/tan(beta), y' = dz*sin(alpha)/tan(beta) where dz is the distance of the point from the focal plane.\n * The angles are (45,90) by default. Oblique projections commonly use (30,63.435).\n *\n * @param alpha -\n * @param beta -\n */\n setObliqueAngles(alpha: number, beta: number): boolean;\n\n /**\n *\n * @param degrees -\n * @param x - The x coordinate.\n * @param y - The y coordinate.\n * @param z - The z coordinate.\n */\n setOrientationWXYZ(degrees: number, x: number, y: number, z: number): boolean;\n\n /**\n *\n * @param parallelProjection -\n */\n setParallelProjection(parallelProjection: boolean): boolean;\n\n /**\n *\n * @param parallelScale -\n */\n setParallelScale(parallelScale: number): boolean;\n\n /**\n *\n * @param physicalScale -\n */\n setPhysicalScale(physicalScale: number): boolean;\n\n /**\n *\n * @param x - The x coordinate.\n * @param y - The y coordinate.\n * @param z - The z coordinate.\n */\n setPhysicalTranslation(x: number, y: number, z: number): boolean;\n\n /**\n *\n * @param physicalTranslation -\n */\n setPhysicalTranslationFrom(physicalTranslation: number[]): boolean;\n\n /**\n *\n * @param x - The x coordinate.\n * @param y - The y coordinate.\n * @param z - The z coordinate.\n */\n setPhysicalViewNorth(x: number, y: number, z: number): boolean;\n\n /**\n *\n * @param physicalViewNorth -\n */\n setPhysicalViewNorthFrom(physicalViewNorth: number[]): boolean;\n\n /**\n *\n * @param x - The x coordinate.\n * @param y - The y coordinate.\n * @param z - The z coordinate.\n */\n setPhysicalViewUp(x: number, y: number, z: number): boolean;\n\n /**\n *\n * @param physicalViewUp -\n */\n setPhysicalViewUpFrom(physicalViewUp: number[]): boolean;\n\n /**\n * Set the position of the camera in world coordinates.\n * @param x - The x coordinate.\n * @param y - The y coordinate.\n * @param z - The z coordinate.\n */\n setPosition(x: number, y: number, z: number): boolean;\n\n /**\n *\n * @param mat -\n */\n setProjectionMatrix(mat: mat4): boolean;\n\n /**\n * Set the roll angle of the camera about the direction of projection.\n * todo Not implemented yet\n * @param angle -\n */\n setRoll(angle: number): boolean;\n\n /**\n * Set top left corner point of the screen.\n *\n * This will be used only for offaxis frustum calculation.\n * @param x - The x coordinate.\n * @param y - The y coordinate.\n * @param z - The z coordinate.\n */\n setScreenBottomLeft(x: number, y: number, z: number): boolean;\n\n /**\n * Set top left corner point of the screen.\n *\n * This will be used only for offaxis frustum calculation.\n * @param screenBottomLeft -\n */\n setScreenBottomLeft(screenBottomLeft: number[]): boolean;\n\n /**\n *\n * @param screenBottomLeft -\n */\n setScreenBottomLeftFrom(screenBottomLeft: number[]): boolean;\n\n /**\n *\n * @param x - The x coordinate.\n * @param y - The y coordinate.\n * @param z - The z coordinate.\n */\n setScreenBottomRight(x: number, y: number, z: number): boolean;\n\n /**\n *\n * @param screenBottomRight -\n */\n setScreenBottomRight(screenBottomRight: number[]): boolean;\n\n /**\n *\n * @param screenBottomRight -\n */\n setScreenBottomRightFrom(screenBottomRight: number[]): boolean;\n\n /**\n * Set top right corner point of the screen.\n *\n * This will be used only for offaxis frustum calculation.\n * @param x - The x coordinate.\n * @param y - The y coordinate.\n * @param z - The z coordinate.\n */\n setScreenTopRight(x: number, y: number, z: number): boolean;\n\n /**\n * Set top right corner point of the screen.\n *\n * This will be used only for offaxis frustum calculation.\n * @param screenTopRight -\n */\n setScreenTopRight(screenTopRight: number[]): boolean;\n\n /**\n *\n * @param screenTopRight -\n */\n setScreenTopRightFrom(screenTopRight: number[]): boolean;\n\n /**\n * Set the distance between clipping planes.\n *\n * This method adjusts the far clipping plane to be set a distance 'thickness' beyond the near clipping plane.\n * @param thickness -\n */\n setThickness(thickness: number): boolean;\n\n /**\n *\n * @param thickness -\n */\n setThicknessFromFocalPoint(thickness: number): boolean;\n\n /**\n *\n * @param useHorizontalViewAngle -\n */\n setUseHorizontalViewAngle(useHorizontalViewAngle: boolean): boolean;\n\n /**\n * Set use offaxis frustum.\n *\n * OffAxis frustum is used for off-axis frustum calculations specifically for\n * stereo rendering. For reference see \"High Resolution Virtual Reality\", in\n * Proc. SIGGRAPH '92, Computer Graphics, pages 195-202, 1992.\n * @param useOffAxisProjection -\n */\n setUseOffAxisProjection(useOffAxisProjection: boolean): boolean;\n\n /**\n * Set the camera view angle, which is the angular height of the camera view measured in degrees.\n * @param viewAngle -\n */\n setViewAngle(viewAngle: number): boolean;\n\n /**\n *\n * @param mat -\n */\n setViewMatrix(mat: mat4): boolean;\n\n /**\n *\n * @param x - The x coordinate.\n * @param y - The y coordinate.\n * @param z - The z coordinate.\n */\n setViewUp(x: number, y: number, z: number): boolean;\n\n /**\n *\n * @param viewUp -\n */\n setViewUp(viewUp: number[]): boolean;\n\n /**\n *\n * @param viewUp -\n */\n setViewUpFrom(viewUp: number[]): boolean;\n\n /**\n * Set the center of the window in viewport coordinates.\n * The viewport coordinate range is ([-1,+1],[-1,+1]).\n * This method is for if you have one window which consists of several viewports, or if you have several screens which you want to act together as one large screen\n * @param x - The x coordinate.\n * @param y - The y coordinate.\n */\n setWindowCenter(x: number, y: number): boolean;\n\n /**\n * Set the center of the window in viewport coordinates from an array.\n * @param windowCenter -\n */\n setWindowCenterFrom(windowCenter: number[]): boolean;\n\n /**\n *\n * @param x - The x coordinate.\n * @param y - The y coordinate.\n * @param z - The z coordinate.\n */\n translate(x: number, y: number, z: number): void;\n\n /**\n * Rotate the focal point about the view up vector, using the camera's position as the center of rotation.\n * @param angle -\n */\n yaw(angle: number): void;\n\n /**\n * In perspective mode, decrease the view angle by the specified factor.\n * @param factor -\n */\n zoom(factor: number): void;\n\n /**\n * Activate camera clipping customization necessary when doing coordinate transformations\n * @param status -\n */\n setIsPerformingCoordinateTransformation(status: boolean): void;\n}\n\nconst DEFAULT_VALUES = {\n isPerformingCoordinateTransformation: false,\n};\n\n/**\n * Method use to decorate a given object (publicAPI+model) with vtkRenderer characteristics.\n *\n * @param publicAPI - object on which methods will be bounds (public)\n * @param model - object on which data structure will be bounds (protected)\n * @param initialValues -\n */\nfunction extend(\n publicAPI: any,\n model: any,\n initialValues: ICameraInitialValues = {}\n): void {\n Object.assign(model, DEFAULT_VALUES, initialValues);\n\n vtkCamera.extend(publicAPI, model, initialValues);\n\n macro.setGet(publicAPI, model, ['isPerformingCoordinateTransformation']);\n\n // Object methods\n vtkSlabCamera(publicAPI, model);\n}\n\n/**\n * Method use to create a new instance of vtkCamera with its focal point at the origin,\n * and position=(0,0,1). The view up is along the y-axis, view angle is 30 degrees,\n * and the clipping range is (.1,1000).\n * @param initialValues - for pre-setting some of its content\n */\nconst newInstance: (initialValues?: ICameraInitialValues) => vtkSlabCamera =\n macro.newInstance(extend, 'vtkSlabCamera');\n\n/**\n * vtkCamera is a virtual camera for 3D rendering. It provides methods\n * to position and orient the view point and focal point. Convenience\n * methods for moving about the focal point also are provided. More\n * complex methods allow the manipulation of the computer graphics model\n * including view up vector, clipping planes, and camera perspective.\n */\n\n/**\n * vtkSlabCamera - A derived class of the core vtkCamera class\n *\n * This customization is necesssary because when we do coordinate transformations\n * we need to set the cRange between [d, d + 0.1],\n * where d is distance between the camera position and the focal point.\n * While when we render we set to the clippingRange [0.01, d * 2],\n * where d is the calculated from the bounds of all the actors.\n *\n * @param {*} publicAPI The public API to extend\n * @param {*} model The private model to extend.\n */\nfunction vtkSlabCamera(publicAPI, model) {\n model.classHierarchy.push('vtkSlabCamera');\n\n // Set up private variables and methods\n const tmpMatrix = mat4.identity(new Float64Array(16) as unknown as mat4);\n const tmpvec1 = new Float64Array(3) as unknown as vec3;\n\n /**\n * getProjectionMatrix - A fork of vtkCamera's getProjectionMatrix method.\n * This fork performs most of the same actions, but define crange around\n * model.distance when doing coordinate transformations.\n */\n publicAPI.getProjectionMatrix = (aspect, nearz, farz) => {\n const result = mat4.create();\n\n if (model.projectionMatrix) {\n const scale = 1 / model.physicalScale;\n vec3.set(tmpvec1, scale, scale, scale);\n\n mat4.copy(result, model.projectionMatrix);\n mat4.scale(result, result, tmpvec1);\n mat4.transpose(result, result);\n return result;\n }\n\n mat4.identity(tmpMatrix);\n\n let cRange0 = model.clippingRange[0];\n let cRange1 = model.clippingRange[1];\n if (model.isPerformingCoordinateTransformation) {\n /**\n * NOTE: this is necessary because we want the coordinate transformation\n * respect to the view plane (plane orthogonal to the camera and passing to\n * the focal point).\n *\n * When vtk.js computes the coordinate transformations, it simply uses the\n * camera matrix (no ray casting).\n *\n * However for the volume viewport the clipping range is set to be\n * (-RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE, RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE).\n * The clipping range is used in the camera method getProjectionMatrix().\n * The projection matrix is used then for viewToWorld/worldToView methods of\n * the renderer. This means that vkt.js will not return the coordinates of\n * the point on the view plane (i.e. the depth coordinate will corresponded\n * to the focal point).\n *\n * Therefore the clipping range has to be set to (distance, distance + 0.01),\n * where now distance is the distance between the camera position and focal\n * point. This is done internally, in our camera customization when the flag\n * isPerformingCoordinateTransformation is set to true.\n */\n cRange0 = model.distance;\n cRange1 = model.distance + 0.1;\n }\n\n const cWidth = cRange1 - cRange0;\n const cRange = [\n cRange0 + ((nearz + 1) * cWidth) / 2.0,\n cRange0 + ((farz + 1) * cWidth) / 2.0,\n ];\n\n if (model.parallelProjection) {\n // set up a rectangular parallelipiped\n const width = model.parallelScale * aspect;\n const height = model.parallelScale;\n\n const xmin = (model.windowCenter[0] - 1.0) * width;\n const xmax = (model.windowCenter[0] + 1.0) * width;\n const ymin = (model.windowCenter[1] - 1.0) * height;\n const ymax = (model.windowCenter[1] + 1.0) * height;\n\n mat4.ortho(tmpMatrix, xmin, xmax, ymin, ymax, cRange[0], cRange[1]);\n mat4.transpose(tmpMatrix, tmpMatrix);\n } else if (model.useOffAxisProjection) {\n throw new Error('Off-Axis projection is not supported at this time');\n } else {\n const tmp = Math.tan(vtkMath.radiansFromDegrees(model.viewAngle) / 2.0);\n let width;\n let height;\n if (model.useHorizontalViewAngle === true) {\n width = cRange0 * tmp;\n height = (cRange0 * tmp) / aspect;\n } else {\n width = cRange0 * tmp * aspect;\n height = cRange0 * tmp;\n }\n\n const xmin = (model.windowCenter[0] - 1.0) * width;\n const xmax = (model.windowCenter[0] + 1.0) * width;\n const ymin = (model.windowCenter[1] - 1.0) * height;\n const ymax = (model.windowCenter[1] + 1.0) * height;\n const znear = cRange[0];\n const zfar = cRange[1];\n\n tmpMatrix[0] = (2.0 * znear) / (xmax - xmin);\n tmpMatrix[5] = (2.0 * znear) / (ymax - ymin);\n tmpMatrix[2] = (xmin + xmax) / (xmax - xmin);\n tmpMatrix[6] = (ymin + ymax) / (ymax - ymin);\n tmpMatrix[10] = -(znear + zfar) / (zfar - znear);\n tmpMatrix[14] = -1.0;\n tmpMatrix[11] = (-2.0 * znear * zfar) / (zfar - znear);\n tmpMatrix[15] = 0.0;\n }\n\n mat4.copy(result, tmpMatrix);\n\n return result;\n };\n}\n\n// ----------------------------------------------------------------------------\n// Object factory\n// ----------------------------------------------------------------------------\n\n// ----------------------------------------------------------------------------\n\nexport default { newInstance, extend };\nexport { newInstance, extend };\n","import type Point3 from '../types/Point3';\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 transformWorldToIndex(imageData, worldPos: Point3) {\n const continuousIndex = imageData.worldToIndex(worldPos);\n const index = continuousIndex.map(Math.round);\n\n return index;\n}\n","function getTransferFunctionNodes(transferFunction) {\n const size = transferFunction.getSize();\n const values = [];\n for (let index = 0; index < size; index++) {\n const nodeValue1 = [];\n\n transferFunction.getNodeValue(index, nodeValue1);\n\n values.push(nodeValue1);\n }\n\n return values;\n}\n\nfunction setTransferFunctionNodes(transferFunction, nodes) {\n if (!nodes?.length) {\n return;\n }\n\n transferFunction.removeAllPoints();\n\n nodes.forEach((node) => {\n transferFunction.addRGBPoint(...node);\n });\n}\n\nexport { getTransferFunctionNodes, setTransferFunctionNodes };\n","import vtkVolume from '@kitware/vtk.js/Rendering/Core/Volume';\nimport vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction';\nimport vtkColorMaps from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction/ColorMaps';\nimport vtkPiecewiseFunction from '@kitware/vtk.js/Common/DataModel/PiecewiseFunction';\n\nimport { vec2, vec3 } from 'gl-matrix';\n\nimport cache from '../cache';\nimport {\n MPR_CAMERA_VALUES,\n RENDERING_DEFAULTS,\n VIEWPORT_PRESETS,\n} from '../constants';\nimport {\n BlendModes,\n Events,\n InterpolationType,\n OrientationAxis,\n ViewportStatus,\n VOILUTFunctionType,\n} from '../enums';\nimport ViewportType from '../enums/ViewportType';\nimport eventTarget from '../eventTarget';\nimport { getShouldUseCPURendering } from '../init';\nimport { loadVolume } from '../loaders/volumeLoader';\nimport type {\n ActorEntry,\n ColormapPublic,\n FlipDirection,\n IImageData,\n IVolumeInput,\n OrientationVectors,\n Point2,\n Point3,\n VOIRange,\n EventTypes,\n VolumeViewportProperties,\n ViewReferenceSpecifier,\n ReferenceCompatibleOptions,\n ViewPresentation,\n ViewReference,\n IVolumeViewport,\n} from '../types';\nimport { VoiModifiedEventDetail } from '../types/EventTypes';\nimport type { ViewportInput } from '../types/IViewport';\nimport {\n actorIsA,\n applyPreset,\n createSigmoidRGBTransferFunction,\n getVoiFromSigmoidRGBTransferFunction,\n imageIdToURI,\n invertRgbTransferFunction,\n triggerEvent,\n colormap as colormapUtils,\n isEqualNegative,\n getVolumeViewportScrollInfo,\n snapFocalPointToSlice,\n isEqual,\n} from '../utilities';\nimport { createVolumeActor } from './helpers';\nimport volumeNewImageEventDispatcher, {\n resetVolumeNewImageState,\n} from './helpers/volumeNewImageEventDispatcher';\nimport Viewport from './Viewport';\nimport type { vtkSlabCamera as vtkSlabCameraType } from './vtkClasses/vtkSlabCamera';\nimport vtkSlabCamera from './vtkClasses/vtkSlabCamera';\nimport transformWorldToIndex from '../utilities/transformWorldToIndex';\nimport { findMatchingColormap } from '../utilities/colormap';\nimport { getTransferFunctionNodes } from '../utilities/transferFunctionUtils';\n/**\n * Abstract base class for volume viewports. VolumeViewports are used to render\n * 3D volumes from which various orientations can be viewed. Since VolumeViewports\n * use SharedVolumeMappers behind the scene, memory footprint of visualizations\n * of the same volume in different orientations is very small.\n *\n * For setting volumes on viewports you need to use {@link addVolumesToViewports}\n * which will add volumes to the specified viewports.\n */\nabstract class BaseVolumeViewport extends Viewport implements IVolumeViewport {\n useCPURendering = false;\n useNativeDataType = false;\n private _FrameOfReferenceUID: string;\n\n protected initialTransferFunctionNodes: any;\n // Viewport Properties\n private globalDefaultProperties: VolumeViewportProperties;\n private perVolumeIdDefaultProperties = new Map<\n string,\n VolumeViewportProperties\n >();\n // Camera properties\n protected initialViewUp: Point3;\n protected viewportProperties: VolumeViewportProperties = {};\n\n constructor(props: ViewportInput) {\n super(props);\n\n this.useCPURendering = getShouldUseCPURendering();\n this.useNativeDataType = this._shouldUseNativeDataType();\n\n if (this.useCPURendering) {\n throw new Error(\n 'VolumeViewports cannot be used whilst CPU Fallback Rendering is enabled.'\n );\n }\n\n const renderer = this.getRenderer();\n\n const camera = vtkSlabCamera.newInstance();\n renderer.setActiveCamera(camera);\n\n switch (this.type) {\n case ViewportType.ORTHOGRAPHIC:\n camera.setParallelProjection(true);\n break;\n case ViewportType.VOLUME_3D:\n camera.setParallelProjection(true);\n break;\n case ViewportType.PERSPECTIVE:\n camera.setParallelProjection(false);\n break;\n default:\n throw new Error(`Unrecognized viewport type: ${this.type}`);\n }\n\n this.initializeVolumeNewImageEventDispatcher();\n }\n\n static get useCustomRenderingPipeline(): boolean {\n return false;\n }\n\n protected applyViewOrientation(\n orientation: OrientationAxis | OrientationVectors,\n resetCamera = true\n ) {\n const { viewPlaneNormal, viewUp } =\n this._getOrientationVectors(orientation);\n const camera = this.getVtkActiveCamera();\n camera.setDirectionOfProjection(\n -viewPlaneNormal[0],\n -viewPlaneNormal[1],\n -viewPlaneNormal[2]\n );\n camera.setViewUpFrom(viewUp);\n this.initialViewUp = viewUp;\n\n if (resetCamera) {\n this.resetCamera();\n }\n }\n\n private initializeVolumeNewImageEventDispatcher(): void {\n const volumeNewImageHandlerBound = volumeNewImageHandler.bind(this);\n const volumeNewImageCleanUpBound = volumeNewImageCleanUp.bind(this);\n\n function volumeNewImageHandler(cameraEvent) {\n const { viewportId } = cameraEvent.detail;\n\n if (viewportId !== this.id || this.isDisabled) {\n return;\n }\n\n const viewportImageData = this.getImageData();\n\n if (!viewportImageData) {\n return;\n }\n\n volumeNewImageEventDispatcher(cameraEvent);\n }\n\n function volumeNewImageCleanUp(evt) {\n const { viewportId } = evt.detail;\n\n if (viewportId !== this.id) {\n return;\n }\n\n this.element.removeEventListener(\n Events.CAMERA_MODIFIED,\n volumeNewImageHandlerBound\n );\n\n eventTarget.removeEventListener(\n Events.ELEMENT_DISABLED,\n volumeNewImageCleanUpBound\n );\n\n resetVolumeNewImageState(viewportId);\n }\n\n this.element.removeEventListener(\n Events.CAMERA_MODIFIED,\n volumeNewImageHandlerBound\n );\n this.element.addEventListener(\n Events.CAMERA_MODIFIED,\n volumeNewImageHandlerBound\n );\n\n eventTarget.addEventListener(\n Events.ELEMENT_DISABLED,\n volumeNewImageCleanUpBound\n );\n }\n\n protected resetVolumeViewportClippingRange() {\n const activeCamera = this.getVtkActiveCamera();\n\n if (activeCamera.getParallelProjection()) {\n activeCamera.setClippingRange(\n -RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE,\n RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE\n );\n } else {\n activeCamera.setClippingRange(\n RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS,\n RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE\n );\n }\n }\n\n /**\n * Sets the properties for the volume viewport on the volume\n * Sets the VOILUTFunction property for the volume viewport on the volume\n *\n * @param VOILUTFunction - Sets the voi mode (LINEAR or SAMPLED_SIGMOID)\n * @param volumeId - The volume id to set the properties for (if undefined, the first volume)\n * @param suppressEvents - If true, the viewport will not emit events\n */\n private setVOILUTFunction(\n voiLUTFunction: VOILUTFunctionType,\n volumeId?: string,\n suppressEvents?: boolean\n ): void {\n // make sure the VOI LUT function is valid in the VOILUTFunctionType which is enum\n if (Object.values(VOILUTFunctionType).indexOf(voiLUTFunction) === -1) {\n voiLUTFunction = VOILUTFunctionType.LINEAR;\n }\n const { voiRange } = this.getProperties();\n this.setVOI(voiRange, volumeId, suppressEvents);\n this.viewportProperties.VOILUTFunction = voiLUTFunction;\n }\n\n /**\n * Sets the colormap for the volume with the given ID and optionally suppresses events.\n *\n * @param colormap - The colormap to apply (e.g., \"hsv\").\n * @param volumeId - The ID of the volume to set the colormap for.\n * @param suppressEvents - If `true`, events will not be emitted during the colormap a\n *\n * @returns void\n */\n private setColormap(\n colormap: ColormapPublic,\n volumeId: string,\n suppressEvents?: boolean\n ) {\n const applicableVolumeActorInfo = this._getApplicableVolumeActor(volumeId);\n if (!applicableVolumeActorInfo) {\n return;\n }\n\n const { volumeActor } = applicableVolumeActorInfo;\n\n const cfun = vtkColorTransferFunction.newInstance();\n let colormapObj = colormapUtils.getColormap(colormap.name);\n\n const { name } = colormap;\n\n if (!colormapObj) {\n colormapObj = vtkColorMaps.getPresetByName(name);\n }\n\n if (!colormapObj) {\n throw new Error(`Colormap ${colormap} not found`);\n }\n\n const range = volumeActor\n .getProperty()\n .getRGBTransferFunction(0)\n .getRange();\n\n cfun.applyColorMap(colormapObj);\n cfun.setMappingRange(range[0], range[1]);\n volumeActor.getProperty().setRGBTransferFunction(0, cfun);\n\n // This configures the viewport to use the most recently applied colormap.\n // However, this approach is not optimal when dealing with two volumes, as it prevents retrieval of the\n // colormap for Volume A if Volume B's colormap was the last one applied.\n this.viewportProperties.colormap = colormap;\n\n if (!suppressEvents) {\n const eventDetail = {\n viewportId: this.id,\n colormap,\n volumeId,\n };\n triggerEvent(this.element, Events.COLORMAP_MODIFIED, eventDetail);\n }\n }\n\n /**\n * Sets the opacity for the volume with the given ID.\n *\n * @param colormap - An object containing opacity that can be a number or an array of OpacityMapping\n * @param volumeId - The ID of the volume to set the opacity for.\n *\n * @returns void\n */\n private setOpacity(colormap: ColormapPublic, volumeId: string) {\n const applicableVolumeActorInfo = this._getApplicableVolumeActor(volumeId);\n if (!applicableVolumeActorInfo) {\n return;\n }\n const { volumeActor } = applicableVolumeActorInfo;\n\n const ofun = vtkPiecewiseFunction.newInstance();\n if (typeof colormap.opacity === 'number') {\n const range = volumeActor\n .getProperty()\n .getRGBTransferFunction(0)\n .getRange();\n\n ofun.addPoint(range[0], colormap.opacity);\n ofun.addPoint(range[1], colormap.opacity);\n } else {\n colormap.opacity.forEach(({ opacity, value }) => {\n ofun.addPoint(value, opacity);\n });\n }\n volumeActor.getProperty().setScalarOpacity(0, ofun);\n\n if (!this.viewportProperties.colormap) {\n this.viewportProperties.colormap = {};\n }\n\n this.viewportProperties.colormap.opacity = colormap.opacity;\n }\n\n /**\n * Sets the inversion for the volume transfer function\n *\n * @param inverted - Should the transfer function be inverted?\n * @param volumeId - volumeId\n * @param suppressEvents - If `true`, events will not be published\n *\n * @returns void\n */\n private setInvert(\n inverted: boolean,\n volumeId?: string,\n suppressEvents?: boolean\n ) {\n const applicableVolumeActorInfo = this._getApplicableVolumeActor(volumeId);\n\n if (!applicableVolumeActorInfo) {\n return;\n }\n\n const volumeIdToUse = applicableVolumeActorInfo.volumeId;\n\n const cfun = this._getOrCreateColorTransferFunction(volumeIdToUse);\n invertRgbTransferFunction(cfun);\n\n this.viewportProperties.invert = inverted;\n\n if (!suppressEvents) {\n const eventDetail: VoiModifiedEventDetail = {\n ...this.getVOIModifiedEventDetail(volumeIdToUse),\n invertStateChanged: true,\n };\n\n triggerEvent(this.element, Events.VOI_MODIFIED, eventDetail);\n }\n }\n\n protected getVOIModifiedEventDetail(\n volumeId: string\n ): VoiModifiedEventDetail {\n const applicableVolumeActorInfo = this._getApplicableVolumeActor(volumeId);\n\n if (!applicableVolumeActorInfo) {\n throw new Error(`No actor found for the given volumeId: ${volumeId}`);\n }\n\n const volumeActor = applicableVolumeActorInfo.volumeActor;\n\n const transferFunction = volumeActor\n .getProperty()\n .getRGBTransferFunction(0);\n\n const range = transferFunction.getMappingRange();\n\n const matchedColormap = this.getColormap(volumeId);\n const { VOILUTFunction, invert } = this.getProperties(volumeId);\n\n return {\n viewportId: this.id,\n range: {\n lower: range[0],\n upper: range[1],\n },\n volumeId: applicableVolumeActorInfo.volumeId,\n VOILUTFunction: VOILUTFunction,\n colormap: matchedColormap,\n invert,\n };\n }\n\n private _getOrCreateColorTransferFunction(\n volumeId: string\n ): vtkColorTransferFunction {\n const applicableVolumeActorInfo = this._getApplicableVolumeActor(volumeId);\n\n if (!applicableVolumeActorInfo) {\n return null;\n }\n\n const { volumeActor } = applicableVolumeActorInfo;\n\n const rgbTransferFunction = volumeActor\n .getProperty()\n .getRGBTransferFunction(0);\n\n if (rgbTransferFunction) {\n return rgbTransferFunction;\n }\n\n const newRGBTransferFunction = vtkColorTransferFunction.newInstance();\n volumeActor.getProperty().setRGBTransferFunction(0, newRGBTransferFunction);\n\n return newRGBTransferFunction;\n }\n\n protected setInterpolationType(\n interpolationType: InterpolationType,\n volumeId?: string\n ) {\n const applicableVolumeActorInfo = this._getApplicableVolumeActor(volumeId);\n\n if (!applicableVolumeActorInfo) {\n return;\n }\n\n const { volumeActor } = applicableVolumeActorInfo;\n const volumeProperty = volumeActor.getProperty();\n\n // @ts-ignore\n volumeProperty.setInterpolationType(interpolationType);\n this.viewportProperties.interpolationType = interpolationType;\n }\n\n /**\n * Sets the properties for the volume viewport on the volume\n * (if fusion, it sets it for the first volume in the fusion)\n *\n * @param voiRange - Sets the lower and upper voi\n * @param volumeId - The volume id to set the properties for (if undefined, the first volume)\n * @param suppressEvents - If true, the viewport will not emit events\n */\n private setVOI(\n voiRange: VOIRange,\n volumeId?: string,\n suppressEvents = false\n ): void {\n const applicableVolumeActorInfo = this._getApplicableVolumeActor(volumeId);\n\n if (!applicableVolumeActorInfo) {\n return;\n }\n\n const { volumeActor } = applicableVolumeActorInfo;\n const volumeIdToUse = applicableVolumeActorInfo.volumeId;\n\n let voiRangeToUse = voiRange;\n if (typeof voiRangeToUse === 'undefined') {\n const imageData = volumeActor.getMapper().getInputData();\n const range = imageData.getPointData().getScalars().getRange();\n const maxVoiRange = { lower: range[0], upper: range[1] };\n voiRangeToUse = maxVoiRange;\n }\n\n const { VOILUTFunction } = this.getProperties(volumeIdToUse);\n\n // scaling logic here\n // https://github.com/Kitware/vtk-js/blob/c6f2e12cddfe5c0386a73f0793eb6d9ab20d573e/Sources/Rendering/OpenGL/VolumeMapper/index.js#L957-L972\n if (VOILUTFunction === VOILUTFunctionType.SAMPLED_SIGMOID) {\n const cfun = createSigmoidRGBTransferFunction(voiRangeToUse);\n volumeActor.getProperty().setRGBTransferFunction(0, cfun);\n } else {\n // TODO: refactor and make it work for PET series (inverted/colormap)\n // const cfun = createLinearRGBTransferFunction(voiRangeToUse);\n // volumeActor.getProperty().setRGBTransferFunction(0, cfun);\n\n // Todo: Moving from LINEAR to SIGMOID and back to LINEAR will not\n // work until we implement it in a different way because the\n // LINEAR transfer function is not recreated.\n const { lower, upper } = voiRangeToUse;\n volumeActor\n .getProperty()\n .getRGBTransferFunction(0)\n .setRange(lower, upper);\n }\n\n if (!suppressEvents) {\n const eventDetail: VoiModifiedEventDetail = {\n ...this.getVOIModifiedEventDetail(volumeIdToUse),\n };\n\n triggerEvent(this.element, Events.VOI_MODIFIED, eventDetail);\n }\n\n this.viewportProperties.voiRange = voiRangeToUse;\n }\n\n protected setRotation = (rotation: number) => {\n const panFit = this.getPan(this.fitToCanvasCamera);\n const pan = this.getPan();\n const previousCamera = this.getCamera();\n const panSub = vec2.sub([0, 0], panFit, pan) as Point2;\n this.setPan(panSub, false);\n const { flipVertical } = this.getCamera();\n\n // Moving back to zero rotation, for new scrolled slice rotation is 0 after camera reset\n const initialViewUp = flipVertical\n ? vec3.negate([0, 0, 0], this.initialViewUp)\n : this.initialViewUp;\n\n this.setCameraNoEvent({\n viewUp: initialViewUp as Point3,\n });\n\n // rotating camera to the new value\n this.rotateCamera(rotation);\n const afterPan = this.getPan();\n const afterPanFit = this.getPan(this.fitToCanvasCamera);\n const newCenter = vec2.sub([0, 0], afterPan, afterPanFit);\n const newOffset = vec2.add([0, 0], panFit, newCenter) as Point2;\n this.setPan(newOffset, false);\n\n if (this._suppressCameraModifiedEvents) {\n return;\n }\n\n // New camera after rotation\n const camera = this.getCamera();\n\n const eventDetail: EventTypes.CameraModifiedEventDetail = {\n previousCamera,\n camera,\n element: this.element,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n rotation,\n };\n\n triggerEvent(this.element, Events.CAMERA_MODIFIED, eventDetail);\n this.viewportProperties.rotation = rotation;\n };\n\n private rotateCamera(rotation: number): void {\n const rotationToApply = rotation - this.getRotation();\n // rotating camera to the new value\n this.getVtkActiveCamera().roll(-rotationToApply);\n }\n\n /**\n * Update the default properties for the volume viewport on the volume\n * @param ViewportProperties - The properties to set\n * @param volumeId - The volume id to set the default properties for (if undefined, we set the global default viewport properties)\n */\n public setDefaultProperties(\n ViewportProperties: VolumeViewportProperties,\n volumeId?: string\n ): void {\n if (volumeId == null) {\n this.globalDefaultProperties = ViewportProperties;\n } else {\n this.perVolumeIdDefaultProperties.set(volumeId, ViewportProperties);\n }\n }\n\n /**\n * Remove the global default properties of the viewport or remove default properties for a volumeId if specified\n * @param volumeId If given, we remove the default properties only for this volumeId, if not\n * the global default properties will be removed\n */\n public clearDefaultProperties(volumeId?: string): void {\n if (volumeId == null) {\n this.globalDefaultProperties = {};\n this.resetProperties();\n } else {\n this.perVolumeIdDefaultProperties.delete(volumeId);\n this.resetToDefaultProperties(volumeId);\n }\n }\n\n /**\n * Gets a view target, allowing comparison between view positions as well\n * as restoring views later.\n */\n public getViewReference(\n viewRefSpecifier: ViewReferenceSpecifier = {}\n ): ViewReference {\n const target = super.getViewReference(viewRefSpecifier);\n const volumeId = this.getVolumeId(viewRefSpecifier);\n if (viewRefSpecifier?.forFrameOfReference !== false) {\n target.volumeId = volumeId;\n }\n if (typeof viewRefSpecifier?.sliceIndex !== 'number') {\n return target;\n }\n const { viewPlaneNormal } = target;\n const delta =\n (viewRefSpecifier.sliceIndex as number) - this.getSliceIndex();\n // Calculate a camera focal point and position\n const { sliceRangeInfo } = getVolumeViewportScrollInfo(\n this,\n volumeId,\n true\n );\n\n const { sliceRange, spacingInNormalDirection, camera } = sliceRangeInfo;\n const { focalPoint, position } = camera;\n const { newFocalPoint } = snapFocalPointToSlice(\n focalPoint,\n position,\n sliceRange,\n viewPlaneNormal,\n spacingInNormalDirection,\n delta\n );\n target.cameraFocalPoint = newFocalPoint;\n\n return target;\n }\n\n /**\n * Find out if this viewport would show this view\n *\n * @param options - allows specifying whether the view COULD display this with\n * some modification - either navigation or displaying as volume.\n * @returns true if the target is compatible with this view\n */\n public isReferenceViewable(\n viewRef: ViewReference,\n options?: ReferenceCompatibleOptions\n ): boolean {\n if (!viewRef.FrameOfReferenceUID) {\n return false;\n }\n if (!super.isReferenceViewable(viewRef, options)) {\n return false;\n }\n if (options?.withNavigation) {\n return true;\n }\n const currentSliceIndex = this.getSliceIndex();\n const { sliceIndex } = viewRef;\n if (Array.isArray(sliceIndex)) {\n return (\n sliceIndex[0] <= currentSliceIndex && currentSliceIndex <= sliceIndex[1]\n );\n }\n return sliceIndex === undefined || sliceIndex === currentSliceIndex;\n }\n\n /**\n * Scrolls the viewport in the given direction/amount\n */\n public scroll(delta = 1) {\n const volumeId = this.getVolumeId();\n const { sliceRangeInfo } = getVolumeViewportScrollInfo(\n this,\n volumeId,\n true\n );\n\n if (!sliceRangeInfo) {\n return;\n }\n\n const { sliceRange, spacingInNormalDirection, camera } = sliceRangeInfo;\n const { focalPoint, viewPlaneNormal, position } = camera;\n\n const { newFocalPoint, newPosition } = snapFocalPointToSlice(\n focalPoint,\n position,\n sliceRange,\n viewPlaneNormal,\n spacingInNormalDirection,\n delta\n );\n\n this.setCamera({\n focalPoint: newFocalPoint,\n position: newPosition,\n });\n }\n\n /**\n * Navigates to the specified view reference.\n */\n public setViewReference(viewRef: ViewReference): void {\n if (!viewRef) {\n return;\n }\n const volumeId = this.getVolumeId();\n const {\n viewPlaneNormal: refViewPlaneNormal,\n FrameOfReferenceUID: refFrameOfReference,\n cameraFocalPoint,\n viewUp,\n } = viewRef;\n let { sliceIndex } = viewRef;\n const { focalPoint, viewPlaneNormal, position } = this.getCamera();\n const isNegativeNormal = isEqualNegative(\n viewPlaneNormal,\n refViewPlaneNormal\n );\n const isSameNormal = isEqual(viewPlaneNormal, refViewPlaneNormal);\n\n // Handle slices\n if (\n typeof sliceIndex === 'number' &&\n viewRef.volumeId === volumeId &&\n (isNegativeNormal || isSameNormal)\n ) {\n const { currentStepIndex, sliceRangeInfo, numScrollSteps } =\n getVolumeViewportScrollInfo(this, volumeId, true);\n\n const { sliceRange, spacingInNormalDirection } = sliceRangeInfo;\n if (isNegativeNormal) {\n // Convert opposite orientation view refs to normal orientation\n sliceIndex = numScrollSteps - sliceIndex - 1;\n }\n const delta = sliceIndex - currentStepIndex;\n const { newFocalPoint, newPosition } = snapFocalPointToSlice(\n focalPoint,\n position,\n sliceRange,\n viewPlaneNormal,\n spacingInNormalDirection,\n delta\n );\n this.setCamera({ focalPoint: newFocalPoint, position: newPosition });\n } else if (refFrameOfReference === this.getFrameOfReferenceUID()) {\n // Handle same frame of reference navigation\n\n if (refViewPlaneNormal && !isNegativeNormal && !isSameNormal) {\n // Need to update the orientation vectors correctly for this case\n // this.setCameraNoEvent({ viewPlaneNormal: refViewPlaneNormal, viewUp });\n this.setOrientation({ viewPlaneNormal: refViewPlaneNormal, viewUp });\n return this.setViewReference(viewRef);\n }\n if (cameraFocalPoint) {\n const focalDelta = vec3.subtract(\n [0, 0, 0],\n cameraFocalPoint,\n focalPoint\n );\n const useNormal = refViewPlaneNormal ?? viewPlaneNormal;\n const normalDot = vec3.dot(focalDelta, useNormal);\n if (!isEqual(normalDot, 0)) {\n // Gets the portion of the focal point in the normal direction\n vec3.scale(focalDelta, useNormal, normalDot);\n }\n const newFocal = <Point3>vec3.add([0, 0, 0], focalPoint, focalDelta);\n const newPosition = <Point3>vec3.add([0, 0, 0], position, focalDelta);\n this.setCamera({ focalPoint: newFocal, position: newPosition });\n }\n } else {\n throw new Error(\n `Incompatible view refs: ${refFrameOfReference}!==${this.getFrameOfReferenceUID()}`\n );\n }\n }\n\n /**\n * Sets the properties for the volume viewport on the volume\n * and if setProperties is called for the first time, the properties will also become the default one.\n * (if fusion, it sets it for the first volume in the fusion)\n *\n * @param VolumeViewportProperties - The properties to set\n * @param [VolumeViewportProperties.voiRange] - Sets the lower and upper voi\n * @param [VolumeViewportProperties.VOILUTFunction] - Sets the voi mode (LINEAR, or SAMPLED_SIGMOID)\n * @param [VolumeViewportProperties.invert] - Inverts the color transfer function\n * @param [VolumeViewportProperties.colormap] - Sets the colormap\n * @param [VolumeViewportProperties.preset] - Sets the colormap preset\n * @param volumeId - The volume id to set the properties for (if undefined, the first volume)\n * @param suppressEvents - If true, the viewport will not emit events\n */\n public setProperties(\n {\n voiRange,\n VOILUTFunction,\n invert,\n colormap,\n preset,\n interpolationType,\n slabThickness,\n rotation,\n }: VolumeViewportProperties = {},\n volumeId?: string,\n suppressEvents = false\n ): void {\n //If the viewport hasn't been initialized, we need to set the default properties\n if (this.globalDefaultProperties == null) {\n this.setDefaultProperties({\n voiRange,\n VOILUTFunction,\n invert,\n colormap,\n preset,\n slabThickness,\n rotation,\n });\n }\n\n // Note: colormap should always be done first, since we can then\n // modify the voiRange\n\n if (colormap?.name) {\n this.setColormap(colormap, volumeId, suppressEvents);\n }\n if (colormap?.opacity != null) {\n this.setOpacity(colormap, volumeId);\n }\n\n if (voiRange !== undefined) {\n this.setVOI(voiRange, volumeId, suppressEvents);\n }\n\n if (typeof interpolationType !== 'undefined') {\n this.setInterpolationType(interpolationType);\n }\n\n if (VOILUTFunction !== undefined) {\n this.setVOILUTFunction(VOILUTFunction, volumeId, suppressEvents);\n }\n\n if (invert !== undefined && this.viewportProperties.invert !== invert) {\n this.setInvert(invert, volumeId, suppressEvents);\n }\n\n if (preset !== undefined) {\n this.setPreset(preset, volumeId, suppressEvents);\n }\n\n if (slabThickness !== undefined) {\n this.setSlabThickness(slabThickness);\n //We need to set the current slab thickness here since setSlabThickness is define in VolumeViewport\n this.viewportProperties.slabThickness = slabThickness;\n }\n\n if (rotation !== undefined) {\n this.setRotation(rotation);\n }\n }\n\n /**\n * Reset the viewport properties to the default values\n */\n public resetToDefaultProperties(volumeId: string): void {\n const properties = this.globalDefaultProperties;\n\n if (properties.colormap?.name) {\n this.setColormap(properties.colormap, volumeId);\n }\n if (properties.colormap?.opacity != null) {\n this.setOpacity(properties.colormap, volumeId);\n }\n\n if (properties.voiRange !== undefined) {\n this.setVOI(properties.voiRange, volumeId);\n }\n\n if (properties.VOILUTFunction !== undefined) {\n this.setVOILUTFunction(properties.VOILUTFunction, volumeId);\n }\n\n if (properties.invert !== undefined) {\n this.setInvert(properties.invert, volumeId);\n }\n\n if (properties.slabThickness !== undefined) {\n this.setSlabThickness(properties.slabThickness);\n //We need to set the current slabThickness here since setSlabThickness is define in VolumeViewport\n this.viewportProperties.slabThickness = properties.slabThickness;\n }\n\n if (properties.rotation !== undefined) {\n this.setRotation(properties.rotation);\n }\n\n this.render();\n }\n\n /**\n * Sets the specified preset for the volume with the given ID\n *\n * @param presetName - The name of the preset to apply (e.g., \"CT-Bone\").\n * @param volumeId - The ID of the volume to set the preset for.\n * @param suppressEvents - If `true`, events will not be emitted during the preset application.\n *\n * @returns void\n */\n private setPreset(presetNameOrObj, volumeId, suppressEvents) {\n const applicableVolumeActorInfo = this._getApplicableVolumeActor(volumeId);\n\n if (!applicableVolumeActorInfo) {\n return;\n }\n\n const { volumeActor } = applicableVolumeActorInfo;\n\n let preset = presetNameOrObj;\n\n if (typeof preset === 'string') {\n preset = VIEWPORT_PRESETS.find((preset) => {\n return preset.name === presetNameOrObj;\n });\n }\n\n if (!preset) {\n return;\n }\n\n applyPreset(volumeActor, preset);\n\n this.viewportProperties.preset = preset;\n this.render();\n\n if (!suppressEvents) {\n triggerEvent(this.element, Events.PRESET_MODIFIED, {\n viewportId: this.id,\n volumeId: applicableVolumeActorInfo.volumeId,\n actor: volumeActor,\n presetName: preset.name,\n });\n }\n }\n\n /**\n * Retrieve the viewport default properties\n * @param volumeId If given, we retrieve the default properties of a volumeId if it exists\n * If not given,we return the global properties of the viewport\n * @returns default viewport properties including voi, invert, interpolation type, colormap\n */\n public getDefaultProperties = (\n volumeId?: string\n ): VolumeViewportProperties => {\n let volumeProperties;\n if (volumeId !== undefined) {\n volumeProperties = this.perVolumeIdDefaultProperties.get(volumeId);\n }\n\n if (volumeProperties !== undefined) {\n return volumeProperties;\n }\n\n return {\n ...this.globalDefaultProperties,\n };\n };\n\n /**\n * Retrieve the viewport properties\n * @param volumeId - The volume id to get the properties for (if undefined, the first volume)\n * @returns viewport properties including voi, interpolation type: TODO: slabThickness, invert, rotation, flip\n */\n public getProperties = (volumeId?: string): VolumeViewportProperties => {\n const applicableVolumeActorInfo = this._getApplicableVolumeActor(volumeId);\n if (!applicableVolumeActorInfo) {\n return;\n }\n\n const {\n colormap: latestColormap,\n VOILUTFunction,\n interpolationType,\n invert,\n slabThickness,\n rotation,\n preset,\n } = this.viewportProperties;\n\n const voiRanges = this.getActors()\n .map((actorEntry) => {\n const volumeActor = actorEntry.actor as vtkVolume;\n const volumeId = actorEntry.uid;\n const volume = cache.getVolume(volumeId);\n if (!volume) {\n return null;\n }\n const cfun = volumeActor.getProperty().getRGBTransferFunction(0);\n const [lower, upper] =\n this.viewportProperties?.VOILUTFunction === 'SIGMOID'\n ? getVoiFromSigmoidRGBTransferFunction(cfun)\n : cfun.getRange();\n return { volumeId, voiRange: { lower, upper } };\n })\n .filter(Boolean);\n\n const voiRange = volumeId\n ? voiRanges.find((range) => range.volumeId === volumeId)?.voiRange\n : voiRanges[0]?.voiRange;\n\n const volumeColormap = this.getColormap(volumeId);\n\n const colormap =\n volumeId && volumeColormap ? volumeColormap : latestColormap;\n\n return {\n colormap: colormap,\n voiRange: voiRange,\n VOILUTFunction: VOILUTFunction,\n interpolationType: interpolationType,\n invert: invert,\n slabThickness: slabThickness,\n rotation: rotation,\n preset,\n };\n };\n\n /**\n * This function extracts the nodes from the RGB Transfer Function, transforming each node's x, r, g, b properties\n * into a unified array \"RGB Points.\" Then, it compares these RGB Points—specifically the r, g, b values—with\n * those in the predefined vtk colormap presets. Upon finding a matching set of r, g, b values, the function identifies and selects the\n * corresponding colormap.\n *\n * Next, the function extracts an array of opacity points, formatted as a sequence of [x,y] pairs, where 'x' represents a value and\n * 'y' represents its opacity. It iterates through this array to construct an opacity object that maps each value to its opacity.\n *\n * The function returns an object that includes the name of the identified colormap and the constructed opacity object.\n * @param applicableVolumeActorInfo - The volume actor information for the volume\n * @returns colormap information for the volume if identified\n */\n private getColormap = (volumeId) => {\n const applicableVolumeActorInfo = this._getApplicableVolumeActor(volumeId);\n\n if (!applicableVolumeActorInfo) {\n return;\n }\n\n const { volumeActor } = applicableVolumeActorInfo;\n const cfun = volumeActor.getProperty().getRGBTransferFunction(0);\n const { nodes } = cfun.getState();\n const RGBPoints = nodes.reduce((acc, node) => {\n acc.push(node.x, node.r, node.g, node.b);\n return acc;\n }, []);\n\n const matchedColormap = findMatchingColormap(RGBPoints, volumeActor);\n\n return matchedColormap;\n };\n\n /**\n * Creates volume actors for all volumes defined in the `volumeInputArray`.\n * For each entry, if a `callback` is supplied, it will be called with the new volume actor as input.\n * For each entry, if a `blendMode` and/or `slabThickness` is defined, this will be set on the actor's\n * `VolumeMapper`.\n *\n * @param volumeInputArray - The array of `VolumeInput`s which define the volumes to add.\n * @param immediate - Whether the `Viewport` should be rendered as soon as volumes are added.\n */\n public async setVolumes(\n volumeInputArray: Array<IVolumeInput>,\n immediate = false,\n suppressEvents = false\n ): Promise<void> {\n const firstImageVolume = cache.getVolume(volumeInputArray[0].volumeId);\n\n if (!firstImageVolume) {\n throw new Error(\n `imageVolume with id: ${firstImageVolume.volumeId} does not exist`\n );\n }\n\n const FrameOfReferenceUID = firstImageVolume.metadata.FrameOfReferenceUID;\n\n await this._isValidVolumeInputArray(volumeInputArray, FrameOfReferenceUID);\n\n this._FrameOfReferenceUID = FrameOfReferenceUID;\n\n const volumeActors = [];\n\n // One actor per volume\n for (let i = 0; i < volumeInputArray.length; i++) {\n const { volumeId, actorUID, slabThickness } = volumeInputArray[i];\n\n const actor = await createVolumeActor(\n volumeInputArray[i],\n this.element,\n this.id,\n suppressEvents,\n this.useNativeDataType\n );\n\n // We cannot use only volumeId since then we cannot have for instance more\n // than one representation of the same volume (since actors would have the\n // same name, and we don't allow that) AND We cannot use only any uid, since\n // we rely on the volume in the cache for mapper. So we prefer actorUID if\n // it is defined, otherwise we use volumeId for the actor name.\n const uid = actorUID || volumeId;\n volumeActors.push({\n uid,\n actor,\n slabThickness,\n referenceId: volumeId,\n });\n }\n\n this._setVolumeActors(volumeActors);\n this.viewportStatus = ViewportStatus.PRE_RENDER;\n\n this.initializeColorTransferFunction(volumeInputArray);\n\n triggerEvent(this.element, Events.VOLUME_VIEWPORT_NEW_VOLUME, {\n viewportId: this.id,\n volumeActors,\n });\n\n if (immediate) {\n this.render();\n }\n }\n\n /**\n * Creates and adds volume actors for all volumes defined in the `volumeInputArray`.\n * For each entry, if a `callback` is supplied, it will be called with the new volume actor as input.\n *\n * @param volumeInputArray - The array of `VolumeInput`s which define the volumes to add.\n * @param immediate - Whether the `Viewport` should be rendered as soon as volumes are added.\n */\n public async addVolumes(\n volumeInputArray: Array<IVolumeInput>,\n immediate = false,\n suppressEvents = false\n ): Promise<void> {\n const firstImageVolume = cache.getVolume(volumeInputArray[0].volumeId);\n\n if (!firstImageVolume) {\n throw new Error(\n `imageVolume with id: ${firstImageVolume.volumeId} does not exist`\n );\n }\n const volumeActors = [];\n\n await this._isValidVolumeInputArray(\n volumeInputArray,\n this._FrameOfReferenceUID\n );\n\n // One actor per volume\n for (let i = 0; i < volumeInputArray.length; i++) {\n const { volumeId, visibility, actorUID, slabThickness } =\n volumeInputArray[i];\n\n const actor = await createVolumeActor(\n volumeInputArray[i],\n this.element,\n this.id,\n suppressEvents,\n this.useNativeDataType\n );\n\n if (visibility === false) {\n actor.setVisibility(false);\n }\n\n // We cannot use only volumeId since then we cannot have for instance more\n // than one representation of the same volume (since actors would have the\n // same name, and we don't allow that) AND We cannot use only any uid, since\n // we rely on the volume in the cache for mapper. So we prefer actorUID if\n // it is defined, otherwise we use volumeId for the actor name.\n const uid = actorUID || volumeId;\n volumeActors.push({\n uid,\n actor,\n slabThickness,\n // although the actor UID is defined, we need to use the volumeId for the\n // referenceId, since the actor UID is used to reference the actor in the\n // viewport, however, the actor is created from its volumeId\n // and if later we need to grab the referenced volume from cache,\n // we can use the referenceId to get the volume from the cache\n referenceId: volumeId,\n });\n }\n\n this.addActors(volumeActors);\n\n this.initializeColorTransferFunction(volumeInputArray);\n\n if (immediate) {\n // render\n this.render();\n }\n }\n\n /**\n * It removes the volume actor from the Viewport. If the volume actor is not in\n * the viewport, it does nothing.\n * @param actorUIDs - Array of actor UIDs to remove. In case of simple volume it will\n * be the volume Id, but in case of Segmentation it will be `{volumeId}-{representationType}`\n * since the same volume can be rendered in multiple representations.\n * @param immediate - If true, the Viewport will be rendered immediately\n */\n public removeVolumeActors(actorUIDs: Array<string>, immediate = false): void {\n // Todo: This is actually removeActors\n this.removeActors(actorUIDs);\n\n if (immediate) {\n this.render();\n }\n }\n\n /**\n * It sets the orientation for the camera, the orientation can be one of the\n * following: axial, sagittal, coronal, default. Use the Enums.OrientationAxis\n * to set the orientation. The \"default\" orientation is the orientation that\n * the volume was acquired in (scan axis)\n *\n * @param orientation - The orientation to set the camera to.\n * @param immediate - Whether the `Viewport` should be rendered as soon as the camera is set.\n */\n public setOrientation(\n _orientation: OrientationAxis | OrientationVectors,\n _immediate = true\n ): void {\n console.warn('Method \"setOrientation\" needs implementation');\n }\n\n /**\n * Initializes the color transfer function nodes for a given volume.\n *\n * @param volumeInputArray - Array of volume inputs.\n * @param getTransferFunctionNodes - Function to get the transfer function nodes.\n * @returns void\n */\n private initializeColorTransferFunction(volumeInputArray) {\n const selectedVolumeId = volumeInputArray[0].volumeId;\n const colorTransferFunction =\n this._getOrCreateColorTransferFunction(selectedVolumeId);\n\n if (!this.initialTransferFunctionNodes) {\n this.initialTransferFunctionNodes = getTransferFunctionNodes(\n colorTransferFunction\n );\n }\n }\n\n private _getApplicableVolumeActor(volumeId?: string) {\n if (volumeId !== undefined && !this.getActor(volumeId)) {\n return;\n }\n\n const actorEntries = this.getActors();\n\n if (!actorEntries.length) {\n return;\n }\n\n let volumeActor;\n\n if (volumeId) {\n volumeActor = this.getActor(volumeId)?.actor as vtkVolume;\n }\n\n // // set it for the first volume (if there are more than one - fusion)\n if (!volumeActor) {\n volumeActor = actorEntries[0].actor as vtkVolume;\n volumeId = actorEntries[0].uid;\n }\n\n return { volumeActor, volumeId };\n }\n\n private async _isValidVolumeInputArray(\n volumeInputArray: Array<IVolumeInput>,\n FrameOfReferenceUID: string\n ): Promise<boolean> {\n const numVolumes = volumeInputArray.length;\n\n // Check all other volumes exist and have the same FrameOfReference\n for (let i = 1; i < numVolumes; i++) {\n const volumeInput = volumeInputArray[i];\n\n const imageVolume = await loadVolume(volumeInput.volumeId);\n\n if (!imageVolume) {\n throw new Error(\n `imageVolume with id: ${imageVolume.volumeId} does not exist`\n );\n }\n\n if (FrameOfReferenceUID !== imageVolume.metadata.FrameOfReferenceUID) {\n throw new Error(\n `Volumes being added to viewport ${this.id} do not share the same FrameOfReferenceUID. This is not yet supported`\n );\n }\n }\n\n return true;\n }\n\n /**\n * Gets the rotation resulting from the value set in setRotation AND taking into\n * account any flips that occurred subsequently from the camera provided or the viewport.\n *\n * @returns the rotation resulting from the value set in setRotation AND taking into\n * account any flips that occurred subsequently.\n */\n public getRotation = (): number => {\n const {\n viewUp: currentViewUp,\n viewPlaneNormal,\n flipVertical,\n } = this.getCamera();\n\n // The initial view up vector without any rotation, but incorporating vertical flip.\n const initialViewUp = flipVertical\n ? vec3.negate([0, 0, 0], this.initialViewUp)\n : this.initialViewUp;\n\n if (!initialViewUp) {\n return 0;\n }\n\n // The angle between the initial and current view up vectors.\n // TODO: check with VTK about rounding errors here.\n const initialToCurrentViewUpAngle =\n (vec3.angle(initialViewUp, currentViewUp) * 180) / Math.PI;\n\n // Now determine if initialToCurrentViewUpAngle is positive or negative by comparing\n // the direction of the initial/current view up cross product with the current\n // viewPlaneNormal.\n\n const initialToCurrentViewUpCross = vec3.cross(\n [0, 0, 0],\n initialViewUp,\n currentViewUp\n );\n\n // The sign of the dot product of the start/end view up cross product and\n // the viewPlaneNormal indicates a positive or negative rotation respectively.\n const normalDot = vec3.dot(initialToCurrentViewUpCross, viewPlaneNormal);\n\n const value =\n normalDot >= 0\n ? initialToCurrentViewUpAngle\n : (360 - initialToCurrentViewUpAngle) % 360;\n\n return value;\n };\n\n /**\n * gets the visible bounds of the viewport in the world coordinate system\n */\n public getBounds(): number[] {\n const renderer = this.getRenderer();\n const bounds = renderer.computeVisiblePropBounds();\n return bounds;\n }\n\n /**\n * Flip the viewport along the desired axis\n * @param flipDirection - FlipDirection\n */\n public flip(flipDirection: FlipDirection): void {\n super.flip(flipDirection);\n }\n\n public getFrameOfReferenceUID = (): string => {\n return this._FrameOfReferenceUID;\n };\n\n /**\n * Checks if the viewport has a volume actor with the given volumeId\n * @param volumeId - the volumeId to look for\n * @returns Boolean indicating if the volume is present in the viewport\n */\n public hasVolumeId(volumeId: string): boolean {\n // Note: this assumes that the uid of the volume is the same as the volumeId\n // which is not guaranteed to be the case for SEG.\n const actorEntries = this.getActors();\n return actorEntries.some((actorEntry) => {\n return actorEntry.uid === volumeId;\n });\n }\n\n /**\n * Returns the image and its properties that is being shown inside the\n * stack viewport. It returns, the image dimensions, image direction,\n * image scalar data, vtkImageData object, metadata, and scaling (e.g., PET suvbw)\n * Note: since the volume viewport supports fusion, to get the\n * image data for a specific volume, use the optional volumeId\n * argument.\n *\n * @param volumeId - The volumeId of the volume to get the image for.\n * @returns IImageData: {dimensions, direction, scalarData, vtkImageData, metadata, scaling}\n */\n public getImageData(volumeId?: string): IImageData | undefined {\n const defaultActor = this.getDefaultActor();\n if (!defaultActor) {\n return;\n }\n\n const { uid: defaultActorUID } = defaultActor;\n volumeId = volumeId ?? defaultActorUID;\n\n const actorEntry = this.getActor(volumeId);\n\n if (!actorIsA(actorEntry, 'vtkVolume')) {\n return;\n }\n\n const actor = actorEntry.actor;\n const volume = cache.getVolume(volumeId);\n\n const vtkImageData = actor.getMapper().getInputData();\n return {\n dimensions: vtkImageData.getDimensions(),\n spacing: vtkImageData.getSpacing(),\n origin: vtkImageData.getOrigin(),\n direction: vtkImageData.getDirection(),\n scalarData: vtkImageData.getPointData().getScalars().isDeleted()\n ? null\n : vtkImageData.getPointData().getScalars().getData(),\n imageData: actor.getMapper().getInputData(),\n metadata: {\n Modality: volume?.metadata?.Modality,\n },\n scaling: volume?.scaling,\n hasPixelSpacing: true,\n };\n }\n\n /**\n * Attaches the volume actors to the viewport.\n *\n * @param volumeActorEntries - The volume actors to add the viewport.\n *\n */\n private _setVolumeActors(volumeActorEntries: Array<ActorEntry>): void {\n // New volume actors implies resetting the inverted flag (i.e. like starting from scratch).\n\n for (let i = 0; i < volumeActorEntries.length; i++) {\n this.viewportProperties.invert = false;\n }\n this.setActors(volumeActorEntries);\n }\n\n /**\n * canvasToWorld Returns the world coordinates of the given `canvasPos`\n * projected onto the plane defined by the `Viewport`'s `vtkCamera`'s focal point\n * and the direction of projection.\n *\n * @param canvasPos - The position in canvas coordinates.\n * @returns The corresponding world coordinates.\n * @public\n */\n public canvasToWorld = (canvasPos: Point2): Point3 => {\n const vtkCamera = this.getVtkActiveCamera() as vtkSlabCameraType;\n\n /**\n * NOTE: this is necessary because we want the coordinate transformation\n * respect to the view plane (plane orthogonal to the camera and passing to\n * the focal point).\n *\n * When vtk.js computes the coordinate transformations, it simply uses the\n * camera matrix (no ray casting).\n *\n * However for the volume viewport the clipping range is set to be\n * (-RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE, RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE).\n * The clipping range is used in the camera method getProjectionMatrix().\n * The projection matrix is used then for viewToWorld/worldToView methods of\n * the renderer. This means that vkt.js will not return the coordinates of\n * the point on the view plane (i.e. the depth coordinate will correspond\n * to the focal point).\n *\n * Therefore the clipping range has to be set to (distance, distance + 0.01),\n * where now distance is the distance between the camera position and focal\n * point. This is done internally, in our camera customization when the flag\n * isPerformingCoordinateTransformation is set to true.\n */\n\n vtkCamera.setIsPerformingCoordinateTransformation?.(true);\n\n const renderer = this.getRenderer();\n const offscreenMultiRenderWindow =\n this.getRenderingEngine().offscreenMultiRenderWindow;\n const openGLRenderWindow =\n offscreenMultiRenderWindow.getOpenGLRenderWindow();\n const size = openGLRenderWindow.getSize();\n const devicePixelRatio = window.devicePixelRatio || 1;\n const canvasPosWithDPR = [\n canvasPos[0] * devicePixelRatio,\n canvasPos[1] * devicePixelRatio,\n ];\n const displayCoord = [\n canvasPosWithDPR[0] + this.sx,\n canvasPosWithDPR[1] + this.sy,\n ];\n\n // The y axis display coordinates are inverted with respect to canvas coords\n displayCoord[1] = size[1] - displayCoord[1];\n\n const worldCoord = openGLRenderWindow.displayToWorld(\n displayCoord[0],\n displayCoord[1],\n 0,\n renderer\n );\n\n vtkCamera.setIsPerformingCoordinateTransformation?.(false);\n\n return [worldCoord[0], worldCoord[1], worldCoord[2]];\n };\n\n /**\n * Returns the canvas coordinates of the given `worldPos`\n * projected onto the `Viewport`'s `canvas`.\n *\n * @param worldPos - The position in world coordinates.\n * @returns The corresponding canvas coordinates.\n * @public\n */\n public worldToCanvas = (worldPos: Point3): Point2 => {\n const vtkCamera = this.getVtkActiveCamera() as vtkSlabCameraType;\n\n /**\n * NOTE: this is necessary because we want the coordinate trasformation\n * respect to the view plane (plane orthogonal to the camera and passing to\n * the focal point).\n *\n * When vtk.js computes the coordinate transformations, it simply uses the\n * camera matrix (no ray casting).\n *\n * However for the volume viewport the clipping range is set to be\n * (-RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE, RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE).\n * The clipping range is used in the camera method getProjectionMatrix().\n * The projection matrix is used then for viewToWorld/worldToView methods of\n * the renderer. This means that vkt.js will not return the coordinates of\n * the point on the view plane (i.e. the depth coordinate will corresponded\n * to the focal point).\n *\n * Therefore the clipping range has to be set to (distance, distance + 0.01),\n * where now distance is the distance between the camera position and focal\n * point. This is done internally, in our camera customization when the flag\n * isPerformingCoordinateTransformation is set to true.\n */\n\n vtkCamera.setIsPerformingCoordinateTransformation?.(true);\n\n const renderer = this.getRenderer();\n const offscreenMultiRenderWindow =\n this.getRenderingEngine().offscreenMultiRenderWindow;\n const openGLRenderWindow =\n offscreenMultiRenderWindow.getOpenGLRenderWindow();\n const size = openGLRenderWindow.getSize();\n const displayCoord = openGLRenderWindow.worldToDisplay(\n ...worldPos,\n renderer\n );\n\n // The y axis display coordinates are inverted with respect to canvas coords\n displayCoord[1] = size[1] - displayCoord[1];\n\n const canvasCoord = <Point2>[\n displayCoord[0] - this.sx,\n displayCoord[1] - this.sy,\n ];\n\n const devicePixelRatio = window.devicePixelRatio || 1;\n const canvasCoordWithDPR = <Point2>[\n canvasCoord[0] / devicePixelRatio,\n canvasCoord[1] / devicePixelRatio,\n ];\n\n vtkCamera.setIsPerformingCoordinateTransformation?.(false);\n\n return canvasCoordWithDPR;\n };\n\n /*\n * Checking if the imageURI is in the volumes that are being\n * rendered by the viewport. imageURI is the imageId without the schema\n * for instance for the imageId of wadors:http://..., the http://... is the imageURI.\n * Why we don't check the imageId is because the same image can be shown in\n * another viewport (StackViewport) with a different schema\n *\n * @param imageURI - The imageURI to check\n * @returns True if the imageURI is in the volumes that are being rendered by the viewport\n */\n public hasImageURI = (imageURI: string): boolean => {\n const volumeActors = this.getActors().filter((actorEntry) =>\n actorIsA(actorEntry, 'vtkVolume')\n );\n\n return volumeActors.some(({ uid }) => {\n const volume = cache.getVolume(uid);\n\n if (!volume || !volume.imageIds) {\n return false;\n }\n\n const volumeImageURIs = volume.imageIds.map(imageIdToURI);\n\n return volumeImageURIs.includes(imageURI);\n });\n };\n\n protected _getOrientationVectors(\n orientation: OrientationAxis | OrientationVectors\n ): OrientationVectors {\n if (typeof orientation === 'object') {\n if (orientation.viewPlaneNormal && orientation.viewUp) {\n return orientation;\n } else {\n throw new Error(\n 'Invalid orientation object. It must contain viewPlaneNormal and viewUp'\n );\n }\n } else if (\n typeof orientation === 'string' &&\n MPR_CAMERA_VALUES[orientation]\n ) {\n this.viewportProperties.orientation = orientation;\n return MPR_CAMERA_VALUES[orientation];\n } else {\n throw new Error(\n `Invalid orientation: ${orientation}. Valid orientations are: ${Object.keys(\n MPR_CAMERA_VALUES\n ).join(', ')}`\n );\n }\n }\n /**\n * Gets the largest slab thickness from all actors in the viewport.\n *\n * @returns slabThickness - The slab thickness.\n */\n public getSlabThickness(): number {\n const actors = this.getActors();\n let slabThickness = RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS;\n actors.forEach((actor) => {\n if (actor.slabThickness > slabThickness) {\n slabThickness = actor.slabThickness;\n }\n });\n\n return slabThickness;\n }\n /**\n * Given a point in world coordinates, return the intensity at that point\n * @param point - The point in world coordinates to get the intensity\n * from.\n * @returns The intensity value of the voxel at the given point.\n */\n public getIntensityFromWorld(point: Point3): number {\n const actorEntry = this.getDefaultActor();\n if (!actorIsA(actorEntry, 'vtkVolume')) {\n return;\n }\n\n const { actor, uid } = actorEntry;\n const imageData = actor.getMapper().getInputData();\n\n const volume = cache.getVolume(uid);\n const { dimensions } = volume;\n\n const index = transformWorldToIndex(imageData, point);\n\n const voxelIndex =\n index[2] * dimensions[0] * dimensions[1] +\n index[1] * dimensions[0] +\n index[0];\n\n return volume.getScalarData()[voxelIndex];\n }\n\n /**\n * Returns the list of image Ids for the current viewport\n *\n * @param volumeId - volumeId\n * @returns list of strings for image Ids\n */\n public getImageIds = (volumeId?: string): Array<string> => {\n const applicableVolumeActorInfo = this._getApplicableVolumeActor(volumeId);\n\n if (!applicableVolumeActorInfo) {\n throw new Error(`No actor found for the given volumeId: ${volumeId}`);\n }\n\n const volumeIdToUse = applicableVolumeActorInfo.volumeId;\n\n const imageVolume = cache.getVolume(volumeIdToUse);\n if (!imageVolume) {\n throw new Error(\n `imageVolume with id: ${volumeIdToUse} does not exist in cache`\n );\n }\n\n return imageVolume.imageIds;\n };\n\n abstract getCurrentImageId(): string;\n\n /**\n * Gets the volumeId to use for references.\n * Returns undefined if the specified volume is NOT in this viewport.\n */\n protected getVolumeId(specifier?: ViewReferenceSpecifier) {\n const actorEntries = this.getActors();\n if (!actorEntries) {\n return;\n }\n if (!specifier?.volumeId) {\n // find the first image actor of instance type vtkVolume\n return actorEntries.find(\n (actorEntry) => actorEntry.actor.getClassName() === 'vtkVolume'\n )?.uid;\n }\n\n // See if this volumeId can be found in one of the actors for this\n // viewport. This check will cause undefined to be returned when the\n // volumeId isn't currently shown in this viewport.\n return actorEntries.find(\n (actorEntry) =>\n actorEntry.actor.getClassName() === 'vtkVolume' &&\n actorEntry.uid === specifier.volumeId\n )?.uid;\n }\n\n /**\n * For a volume viewport, the reference id will be a URN starting with\n * `volumeId:<volumeId>`, followed by additional arguments to specify\n * the view orientation. This will end up being a unique string that\n * identifies the view reference being shown. It is different from the\n * view reference in that the values are all incorporated into a string to\n * allow using it as a parameter key.\n */\n public getReferenceId(specifier: ViewReferenceSpecifier = {}): string {\n let { volumeId, sliceIndex: sliceIndex } = specifier;\n if (!volumeId) {\n const actorEntries = this.getActors();\n if (!actorEntries) {\n return;\n }\n // find the first image actor of instance type vtkVolume\n volumeId = actorEntries.find(\n (actorEntry) => actorEntry.actor.getClassName() === 'vtkVolume'\n )?.uid;\n }\n\n const currentIndex = this.getSliceIndex();\n sliceIndex ??= currentIndex;\n const { viewPlaneNormal, focalPoint } = this.getCamera();\n const querySeparator = volumeId.indexOf('?') > -1 ? '&' : '?';\n return `volumeId:${volumeId}${querySeparator}sliceIndex=${sliceIndex}&viewPlaneNormal=${viewPlaneNormal.join(\n ','\n )}&focalPoint=${focalPoint.join(',')}`;\n }\n\n abstract setBlendMode(\n blendMode: BlendModes,\n filterActorUIDs?: Array<string>,\n immediate?: boolean\n ): void;\n\n abstract setSlabThickness(\n slabThickness: number,\n filterActorUIDs?: Array<string>\n ): void;\n\n abstract resetSlabThickness(): void;\n\n abstract resetProperties(volumeId?: string): void;\n}\n\nexport default BaseVolumeViewport;\n","import vtkPlane from '@kitware/vtk.js/Common/DataModel/Plane';\nimport vtkVolume from '@kitware/vtk.js/Rendering/Core/Volume';\n\nimport cache from '../cache';\nimport { MPR_CAMERA_VALUES, RENDERING_DEFAULTS } from '../constants';\nimport { BlendModes, OrientationAxis, Events } from '../enums';\nimport type {\n ActorEntry,\n IImageVolume,\n IVolumeInput,\n OrientationVectors,\n Point3,\n EventTypes,\n ViewReference,\n ViewReferenceSpecifier,\n} from '../types';\nimport type { ViewportInput } from '../types/IViewport';\nimport {\n actorIsA,\n getClosestImageId,\n getSliceRange,\n getSpacingInNormalDirection,\n isImageActor,\n snapFocalPointToSlice,\n triggerEvent,\n} from '../utilities';\nimport BaseVolumeViewport from './BaseVolumeViewport';\nimport setDefaultVolumeVOI from './helpers/setDefaultVolumeVOI';\nimport { setTransferFunctionNodes } from '../utilities/transferFunctionUtils';\nimport { ImageActor } from '../types/IActor';\nimport getImageSliceDataForVolumeViewport from '../utilities/getImageSliceDataForVolumeViewport';\nimport { vec3 } from 'gl-matrix';\n\n/**\n * An object representing a VolumeViewport. VolumeViewports are used to render\n * 3D volumes from which various orientations can be viewed. Since VolumeViewports\n * use SharedVolumeMappers behind the scene, memory footprint of visualizations\n * of the same volume in different orientations is very small.\n *\n * For setting volumes on viewports you need to use {@link addVolumesToViewports}\n * which will add volumes to the specified viewports.\n */\nclass VolumeViewport extends BaseVolumeViewport {\n private _useAcquisitionPlaneForViewPlane = false;\n constructor(props: ViewportInput) {\n super(props);\n\n const { orientation } = this.options;\n // if the camera is set to be acquisition axis then we need to skip\n // it for now until the volume is set\n if (orientation && orientation !== OrientationAxis.ACQUISITION) {\n this.applyViewOrientation(orientation);\n return;\n }\n\n this._useAcquisitionPlaneForViewPlane = true;\n }\n\n /**\n * Creates volume actors for all volumes defined in the `volumeInputArray`.\n * For each entry, if a `callback` is supplied, it will be called with the new volume actor as input.\n * For each entry, if a `blendMode` and/or `slabThickness` is defined, this will be set on the actor's\n * `VolumeMapper`.\n *\n * @param volumeInputArray - The array of `VolumeInput`s which define the volumes to add.\n * @param immediate - Whether the `Viewport` should be rendered as soon as volumes are added.\n */\n public async setVolumes(\n volumeInputArray: Array<IVolumeInput>,\n immediate = false,\n suppressEvents = false\n ): Promise<void> {\n const firstImageVolume = cache.getVolume(volumeInputArray[0].volumeId);\n\n if (!firstImageVolume) {\n throw new Error(\n `imageVolume with id: ${firstImageVolume.volumeId} does not exist`\n );\n }\n\n if (this._useAcquisitionPlaneForViewPlane) {\n this._setViewPlaneToAcquisitionPlane(firstImageVolume);\n this._useAcquisitionPlaneForViewPlane = false;\n }\n\n return super.setVolumes(volumeInputArray, immediate, suppressEvents);\n }\n\n /** Gets the number of slices the volume is broken up into in the camera direction */\n public getNumberOfSlices = (): number => {\n const { numberOfSlices } = getImageSliceDataForVolumeViewport(this);\n return numberOfSlices;\n };\n\n /**\n * Creates and adds volume actors for all volumes defined in the `volumeInputArray`.\n * For each entry, if a `callback` is supplied, it will be called with the new volume actor as input.\n *\n * @param volumeInputArray - The array of `VolumeInput`s which define the volumes to add.\n * @param immediate - Whether the `Viewport` should be rendered as soon as volumes are added.\n */\n public async addVolumes(\n volumeInputArray: Array<IVolumeInput>,\n immediate = false,\n suppressEvents = false\n ): Promise<void> {\n const firstImageVolume = cache.getVolume(volumeInputArray[0].volumeId);\n\n if (!firstImageVolume) {\n throw new Error(\n `imageVolume with id: ${firstImageVolume.volumeId} does not exist`\n );\n }\n\n if (this._useAcquisitionPlaneForViewPlane) {\n this._setViewPlaneToAcquisitionPlane(firstImageVolume);\n this._useAcquisitionPlaneForViewPlane = false;\n }\n\n return super.addVolumes(volumeInputArray, immediate, suppressEvents);\n }\n\n /**\n * It sets the orientation for the camera, the orientation can be one of the\n * following: axial, sagittal, coronal, default. Use the Enums.OrientationAxis\n * to set the orientation. The \"default\" orientation is the orientation that\n * the volume was acquired in (scan axis)\n *\n * @param orientation - The orientation to set the camera to.\n * @param immediate - Whether the `Viewport` should be rendered as soon as the camera is set.\n */\n public setOrientation(\n orientation: OrientationAxis | OrientationVectors,\n immediate = true\n ): void {\n let viewPlaneNormal, viewUp;\n\n // check if the orientation is a string or an object\n if (typeof orientation === 'string') {\n if (MPR_CAMERA_VALUES[orientation]) {\n ({ viewPlaneNormal, viewUp } = MPR_CAMERA_VALUES[orientation]);\n } else if (orientation === 'acquisition') {\n ({ viewPlaneNormal, viewUp } = this._getAcquisitionPlaneOrientation());\n } else {\n throw new Error(\n `Invalid orientation: ${orientation}. Use Enums.OrientationAxis instead.`\n );\n }\n\n this.setCamera({\n viewPlaneNormal,\n viewUp,\n });\n\n this.viewportProperties.orientation = orientation;\n this.resetCamera();\n } else {\n ({ viewPlaneNormal, viewUp } = orientation);\n this.applyViewOrientation(orientation);\n }\n\n if (immediate) {\n this.render();\n }\n }\n\n private _getAcquisitionPlaneOrientation(): OrientationVectors {\n const actorEntry = this.getDefaultActor();\n\n if (!actorEntry) {\n return;\n }\n\n // Todo: fix this after we add the volumeId reference to actorEntry later\n // in the segmentation refactor\n const volumeId = actorEntry.uid;\n\n const imageVolume = cache.getVolume(volumeId);\n\n if (!imageVolume) {\n throw new Error(\n `imageVolume with id: ${volumeId} does not exist in cache`\n );\n }\n\n const { direction } = imageVolume;\n const viewPlaneNormal = direction.slice(6, 9).map((x) => -x) as Point3;\n const viewUp = (direction.slice(3, 6) as Point3).map((x) => -x) as Point3;\n\n return {\n viewPlaneNormal,\n viewUp,\n };\n }\n\n private _setViewPlaneToAcquisitionPlane(imageVolume: IImageVolume): void {\n let viewPlaneNormal, viewUp;\n\n if (imageVolume) {\n const { direction } = imageVolume;\n viewPlaneNormal = direction.slice(6, 9).map((x) => -x) as Point3;\n viewUp = (direction.slice(3, 6) as Point3).map((x) => -x) as Point3;\n } else {\n ({ viewPlaneNormal, viewUp } = this._getAcquisitionPlaneOrientation());\n }\n\n this.setCamera({\n viewPlaneNormal,\n viewUp,\n });\n\n this.initialViewUp = viewUp;\n this.resetCamera();\n }\n\n public setBlendMode(\n blendMode: BlendModes,\n filterActorUIDs = [],\n immediate = false\n ): void {\n let actorEntries = this.getActors();\n\n if (filterActorUIDs && filterActorUIDs.length > 0) {\n actorEntries = actorEntries.filter((actorEntry: ActorEntry) => {\n return filterActorUIDs.includes(actorEntry.uid);\n });\n }\n\n actorEntries.forEach((actorEntry) => {\n const { actor } = actorEntry;\n\n const mapper = actor.getMapper();\n // @ts-ignore vtk incorrect typing\n mapper.setBlendMode?.(blendMode);\n });\n\n if (immediate) {\n this.render();\n }\n }\n\n /**\n * Reset the camera for the volume viewport\n */\n public resetCamera(\n resetPan = true,\n resetZoom = true,\n resetToCenter = true,\n resetRotation = false,\n supressEvents = false\n ): boolean {\n const { orientation } = this.viewportProperties;\n if (orientation) {\n this.applyViewOrientation(orientation, false);\n }\n super.resetCamera(resetPan, resetZoom, resetToCenter);\n\n this.resetVolumeViewportClippingRange();\n\n const activeCamera = this.getVtkActiveCamera();\n const viewPlaneNormal = <Point3>activeCamera.getViewPlaneNormal();\n const focalPoint = <Point3>activeCamera.getFocalPoint();\n\n // always add clipping planes for the volume viewport. If a use case\n // arises where we don't want clipping planes, you should use the volume_3d\n // viewport instead.\n const actorEntries = this.getActors();\n actorEntries.forEach((actorEntry) => {\n if (!actorEntry.actor) {\n return;\n }\n const mapper = actorEntry.actor.getMapper();\n const vtkPlanes = mapper.getClippingPlanes();\n\n if (vtkPlanes.length === 0 && !actorEntry?.clippingFilter) {\n const clipPlane1 = vtkPlane.newInstance();\n const clipPlane2 = vtkPlane.newInstance();\n const newVtkPlanes = [clipPlane1, clipPlane2];\n\n let slabThickness = RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS;\n if (actorEntry.slabThickness) {\n slabThickness = actorEntry.slabThickness;\n }\n\n this.setOrientationOfClippingPlanes(\n newVtkPlanes,\n slabThickness,\n viewPlaneNormal,\n focalPoint\n );\n\n mapper.addClippingPlane(clipPlane1);\n mapper.addClippingPlane(clipPlane2);\n }\n });\n\n //Only reset the rotation of the camera if wanted (so we don't reset everytime resetCamera is called) and also verify that the viewport has an orientation that we know (sagittal, coronal, axial)\n if (\n resetRotation &&\n MPR_CAMERA_VALUES[this.viewportProperties.orientation] !== undefined\n ) {\n const viewToReset =\n MPR_CAMERA_VALUES[this.viewportProperties.orientation];\n this.setCameraNoEvent({\n viewUp: viewToReset.viewUp,\n viewPlaneNormal: viewToReset.viewPlaneNormal,\n });\n }\n\n if (!supressEvents) {\n const eventDetail: EventTypes.CameraResetEventDetail = {\n viewportId: this.id,\n camera: this.getCamera(),\n renderingEngineId: this.renderingEngineId,\n element: this.element,\n };\n\n triggerEvent(this.element, Events.CAMERA_RESET, eventDetail);\n }\n return true;\n }\n\n /**\n * It sets the slabThickness of the actors of the viewport. If filterActorUIDs are\n * provided, only the actors with the given UIDs will be affected. If no\n * filterActorUIDs are provided, all actors will be affected.\n *\n * @param slabThickness - The slab thickness to set.\n * @param filterActorUIDs - Optional argument to filter the actors to apply\n * the slab thickness to (if not provided, all actors will be affected).\n */\n public setSlabThickness(slabThickness: number, filterActorUIDs = []): void {\n if (slabThickness < 0.1) {\n // Cannot render zero thickness\n slabThickness = 0.1;\n }\n\n let actorEntries = this.getActors();\n\n if (filterActorUIDs && filterActorUIDs.length > 0) {\n actorEntries = actorEntries.filter((actorEntry) => {\n return filterActorUIDs.includes(actorEntry.uid);\n });\n }\n\n actorEntries.forEach((actorEntry) => {\n if (actorIsA(actorEntry, 'vtkVolume')) {\n actorEntry.slabThickness = slabThickness;\n }\n });\n\n const currentCamera = this.getCamera();\n this.updateClippingPlanesForActors(currentCamera);\n this.triggerCameraModifiedEventIfNecessary(currentCamera, currentCamera);\n this.viewportProperties.slabThickness = slabThickness;\n }\n\n /**\n * Uses the origin and focalPoint to calculate the slice index.\n\n\n\n * Resets the slab thickness of the actors of the viewport to the default value.\n */\n public resetSlabThickness(): void {\n const actorEntries = this.getActors();\n\n actorEntries.forEach((actorEntry) => {\n if (actorIsA(actorEntry, 'vtkVolume')) {\n actorEntry.slabThickness = RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS;\n }\n });\n\n const currentCamera = this.getCamera();\n this.updateClippingPlanesForActors(currentCamera);\n this.triggerCameraModifiedEventIfNecessary(currentCamera, currentCamera);\n this.viewportProperties.slabThickness = undefined;\n }\n\n /**\n * Returns the imageId index of the current slice in the volume viewport.\n * Note: this is not guaranteed to be the same as the slice index in the view\n * To get the slice index in the view (scroll position), use getSliceIndex()\n *\n * In future we will even delete this method as it should not be used\n * at all.\n *\n * @returns The slice index in the direction of the view\n */\n public getCurrentImageIdIndex = (volumeId?: string): number => {\n const { viewPlaneNormal, focalPoint } = this.getCamera();\n\n const imageData = this.getImageData(volumeId);\n\n if (!imageData) {\n return;\n }\n\n const { origin, direction, spacing } = imageData;\n\n const spacingInNormal = getSpacingInNormalDirection(\n { direction, spacing },\n viewPlaneNormal\n );\n const sub = vec3.create();\n vec3.sub(sub, focalPoint, origin);\n const distance = vec3.dot(sub, viewPlaneNormal);\n\n // divide by the spacing in the normal direction to get the\n // number of steps, and subtract 1 to get the index\n return Math.round(Math.abs(distance) / spacingInNormal);\n };\n\n /**\n * Returns the image index associated with the volume viewport in the current view, the difference\n * between this method and getCurrentImageIdIndex is that this method returns the index of the\n * slice in the volume in view direction so at the top (scrollbar top) of the viewport the index\n * will be 0 and at the bottom (scrollbar bottom) the index will be the number of slices - 1.\n * But the getCurrentImageIdIndex returns the index of current image in the imageIds\n * which is not guaranteed to be the same as the slice index in the view.\n *\n * @returns The image index.\n */\n public getSliceIndex = (): number => {\n const { imageIndex } = getImageSliceDataForVolumeViewport(this);\n return imageIndex;\n };\n\n /**\n * Uses viewport camera and volume actor to decide if the viewport\n * is looking at the volume in the direction of acquisition (imageIds).\n * If so, it uses the origin and focalPoint to find which imageId is\n * currently being viewed.\n *\n * @returns ImageId\n */\n public getCurrentImageId = (): string | undefined => {\n const actorEntry = this.getDefaultActor();\n\n if (!actorEntry || !actorIsA(actorEntry, 'vtkVolume')) {\n return;\n }\n\n const { uid } = actorEntry;\n const volume = cache.getVolume(uid);\n\n if (!volume) {\n return;\n }\n\n const { viewPlaneNormal, focalPoint } = this.getCamera();\n\n return getClosestImageId(volume, focalPoint, viewPlaneNormal);\n };\n\n /**\n * Gets a view target, allowing comparison between view positions as well\n * as restoring views later.\n * Add the referenced image id.\n */\n public getViewReference(\n viewRefSpecifier: ViewReferenceSpecifier = {}\n ): ViewReference {\n const viewRef = super.getViewReference(viewRefSpecifier);\n if (!viewRef?.volumeId) {\n return;\n }\n const volume = cache.getVolume(viewRef.volumeId);\n viewRef.referencedImageId = getClosestImageId(\n volume,\n viewRef.cameraFocalPoint,\n viewRef.viewPlaneNormal\n );\n return viewRef;\n }\n /**\n * Reset the viewport properties to the default values\n *\n\n * @param volumeId - Optional volume ID to specify which volume properties to reset.\n * If not provided, it will reset the properties of the default actor.\n *\n * @returns void\n */\n public resetProperties(volumeId?: string): void {\n this._resetProperties(volumeId);\n }\n\n private _resetProperties(volumeId?: string) {\n // Get the actor based on the volumeId if provided, otherwise use the default actor.\n const volumeActor = volumeId\n ? this.getActor(volumeId)\n : this.getDefaultActor();\n\n if (!volumeActor) {\n throw new Error(`No actor found for the given volumeId: ${volumeId}`);\n }\n\n // if a custom slabThickness was set, we need to reset it\n if (volumeActor.slabThickness) {\n volumeActor.slabThickness = RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS;\n this.viewportProperties.slabThickness = undefined;\n this.updateClippingPlanesForActors(this.getCamera());\n }\n\n const imageVolume = cache.getVolume(volumeActor.uid);\n if (!imageVolume) {\n throw new Error(\n `imageVolume with id: ${volumeActor.uid} does not exist in cache`\n );\n }\n setDefaultVolumeVOI(volumeActor.actor as vtkVolume, imageVolume, false);\n\n if (isImageActor(volumeActor)) {\n const transferFunction = (volumeActor.actor as ImageActor)\n .getProperty()\n .getRGBTransferFunction(0);\n\n setTransferFunctionNodes(\n transferFunction,\n this.initialTransferFunctionNodes\n );\n }\n\n const eventDetails = {\n ...super.getVOIModifiedEventDetail(volumeId),\n };\n\n const resetPan = true;\n const resetZoom = true;\n const resetToCenter = true;\n const resetCameraRotation = true;\n this.resetCamera(resetPan, resetZoom, resetToCenter, resetCameraRotation);\n\n triggerEvent(this.element, Events.VOI_MODIFIED, eventDetails);\n }\n\n /**\n * Retrieves the clipping planes for the slices in the volume viewport.\n * @returns An array of vtkPlane objects representing the clipping planes, or an array of objects with normal and origin properties if raw is true.\n */\n getSlicesClippingPlanes(): Array<{\n sliceIndex: number;\n planes: Array<{\n normal: Point3;\n origin: Point3;\n }>;\n }> {\n const focalPoints = this.getSlicePlaneCoordinates();\n const { viewPlaneNormal } = this.getCamera();\n const slabThickness = RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS;\n\n return focalPoints.map(({ point, sliceIndex }) => {\n const vtkPlanes = [vtkPlane.newInstance(), vtkPlane.newInstance()];\n\n this.setOrientationOfClippingPlanes(\n vtkPlanes,\n slabThickness,\n viewPlaneNormal,\n point\n );\n\n return {\n sliceIndex,\n planes: vtkPlanes.map((plane) => ({\n normal: plane.getNormal(),\n origin: plane.getOrigin(),\n })),\n };\n });\n }\n\n /**\n * Returns an array of 3D coordinates representing the slice plane positions.\n * It starts by the focal point as a reference point on the current slice that\n * the camera is looking at, and then it calculates the slice plane positions\n * by moving the focal point in the direction of the view plane normal back and\n * forward, and snaps them to the slice.\n *\n * @returns An array of Point3 representing the slice plane coordinates.\n */\n public getSlicePlaneCoordinates = (): Array<{\n sliceIndex: number;\n point: Point3;\n }> => {\n const actorEntry = this.getDefaultActor();\n\n if (!actorEntry?.actor) {\n console.warn('No image data found for calculating vtkPlanes.');\n return [];\n }\n\n const volumeId = actorEntry.uid;\n const imageVolume = cache.getVolume(volumeId);\n\n const camera = this.getCamera();\n const { focalPoint, position, viewPlaneNormal } = camera;\n const spacingInNormalDirection = getSpacingInNormalDirection(\n imageVolume,\n viewPlaneNormal\n );\n const sliceRange = getSliceRange(\n actorEntry.actor as vtkVolume,\n viewPlaneNormal,\n focalPoint\n );\n\n // calculate the number of slices that is possible to visit\n // in the direction of the view back and forward\n const numSlicesBackward = Math.round(\n (sliceRange.current - sliceRange.min) / spacingInNormalDirection\n );\n\n const numSlicesForward = Math.round(\n (sliceRange.max - sliceRange.current) / spacingInNormalDirection\n );\n\n const currentSliceIndex = this.getSliceIndex();\n const focalPoints = [];\n\n for (let i = -numSlicesBackward; i <= numSlicesForward; i++) {\n const { newFocalPoint: point } = snapFocalPointToSlice(\n focalPoint,\n position,\n sliceRange,\n viewPlaneNormal,\n spacingInNormalDirection,\n i\n );\n\n focalPoints.push({ sliceIndex: currentSliceIndex + i, point });\n }\n\n return focalPoints;\n };\n}\n\nexport default VolumeViewport;\n","import { addProvider } from '../metaData';\n\nconst retrieveConfigurationState = new Map<string, any>();\n\nconst IMAGE_RETRIEVE_CONFIGURATION = 'imageRetrieveConfiguration';\n\n/**\n * Simple metadataProvider object to store metadata for the image retrieval.\n */\nconst imageRetrieveMetadataProvider = {\n IMAGE_RETRIEVE_CONFIGURATION,\n\n /** Empty the metadata state */\n clear: () => {\n retrieveConfigurationState.clear();\n },\n\n /* Adding a new entry to the state object. */\n add: (key: string, payload): void => {\n retrieveConfigurationState.set(key, payload);\n },\n\n get: (type: string, ...queries: string[]) => {\n if (type === IMAGE_RETRIEVE_CONFIGURATION) {\n return queries\n .map((query) => retrieveConfigurationState.get(query))\n .find((it) => it !== undefined);\n }\n },\n};\n\naddProvider(\n imageRetrieveMetadataProvider.get.bind(imageRetrieveMetadataProvider)\n);\n\nexport default imageRetrieveMetadataProvider;\n","import vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';\nimport { IImage, PixelDataTypedArray } from '../types';\n\nfunction updateVTKImageDataWithCornerstoneImage(\n sourceImageData: vtkImageData,\n image: IImage\n) {\n const pixelData = image.getPixelData();\n if (!sourceImageData.getPointData) {\n // This happens for a CanvasActor, that doesn't have the getPointData\n return;\n }\n const scalarData = sourceImageData\n .getPointData()\n .getScalars()\n .getData() as PixelDataTypedArray;\n\n // if the color image is loaded with CPU previously, it loads it\n // with RGBA, and here we need to remove the A channel from the\n // pixel data.\n if (image.color && image.rgba) {\n const newPixelData = new Uint8Array(image.columns * image.rows * 3);\n for (let i = 0; i < image.columns * image.rows; i++) {\n newPixelData[i * 3] = pixelData[i * 4];\n newPixelData[i * 3 + 1] = pixelData[i * 4 + 1];\n newPixelData[i * 3 + 2] = pixelData[i * 4 + 2];\n }\n // modify the image object to have the correct pixel data for later\n // use.\n image.rgba = false;\n image.getPixelData = () => newPixelData;\n scalarData.set(newPixelData);\n } else {\n scalarData.set(pixelData);\n }\n\n // Trigger modified on the VTK Object so the texture is updated\n // TODO: evaluate directly changing things with texSubImage3D later\n sourceImageData.modified();\n}\n\nexport { updateVTKImageDataWithCornerstoneImage };\n","import { Point2, Point4, CPUFallbackLookupTable } from '../../../../types';\n\n// This code was created based on vtkLookupTable\n// http://www.vtk.org/doc/release/5.0/html/a01697.html\n// https://github.com/Kitware/VTK/blob/master/Common/Core/vtkLookupTable.cxx\nconst BELOW_RANGE_COLOR_INDEX = 0;\nconst ABOVE_RANGE_COLOR_INDEX = 1;\nconst NAN_COLOR_INDEX = 2;\n\n/**\n * Converts an HSV (Hue, Saturation, Value) color to RGB (Red, Green, Blue) color value\n * @param {Number} hue A number representing the hue color value\n * @param {any} sat A number representing the saturation color value\n * @param {any} val A number representing the value color value\n * @returns {Numberp[]} An RGB color array\n */\nfunction HSVToRGB(hue, sat, val) {\n if (hue > 1) {\n throw new Error('HSVToRGB expects hue < 1');\n }\n\n const rgb = [];\n\n if (sat === 0) {\n rgb[0] = val;\n rgb[1] = val;\n rgb[2] = val;\n\n return rgb;\n }\n\n const hueCase = Math.floor(hue * 6);\n const frac = 6 * hue - hueCase;\n const lx = val * (1 - sat);\n const ly = val * (1 - sat * frac);\n const lz = val * (1 - sat * (1 - frac));\n\n switch (hueCase) {\n /* 0<hue<1/6 */\n case 0:\n case 6:\n rgb[0] = val;\n rgb[1] = lz;\n rgb[2] = lx;\n break;\n\n /* 1/6<hue<2/6 */\n case 1:\n rgb[0] = ly;\n rgb[1] = val;\n rgb[2] = lx;\n break;\n\n /* 2/6<hue<3/6 */\n case 2:\n rgb[0] = lx;\n rgb[1] = val;\n rgb[2] = lz;\n break;\n\n /* 3/6<hue/4/6 */\n case 3:\n rgb[0] = lx;\n rgb[1] = ly;\n rgb[2] = val;\n break;\n\n /* 4/6<hue<5/6 */\n case 4:\n rgb[0] = lz;\n rgb[1] = lx;\n rgb[2] = val;\n break;\n\n /* 5/6<hue<1 */\n case 5:\n rgb[0] = val;\n rgb[1] = lx;\n rgb[2] = ly;\n break;\n }\n\n return rgb;\n}\n\n/**\n * Maps a value to an index in the table\n * @param {Number} v A double value which table index will be returned.\n * @param {any} p An object that contains the Table \"Range\", the table \"MaxIndex\",\n * A \"Shift\" from first value in the table and the table \"Scale\" value\n * @returns {Number} The mapped index in the table\n * @memberof Colors\n */\nfunction linearIndexLookupMain(v, p) {\n let dIndex;\n\n // NOTE: Added Math.floor since values were not integers? Check VTK source\n if (v < p.Range[0]) {\n dIndex = p.MaxIndex + BELOW_RANGE_COLOR_INDEX + 1.5;\n } else if (v > p.Range[1]) {\n dIndex = p.MaxIndex + ABOVE_RANGE_COLOR_INDEX + 1.5;\n } else {\n dIndex = (v + p.Shift) * p.Scale;\n }\n\n return Math.floor(dIndex);\n}\n\n/**\n * Maps scalar values into colors via a lookup table\n * LookupTable is an object that is used by mapper objects to map scalar values into rgba (red-green-blue-alpha transparency) color specification,\n * or rgba into scalar values. The color table can be created by direct insertion of color values, or by specifying hue, saturation, value, and alpha range and generating a table\n */\nclass LookupTable implements CPUFallbackLookupTable {\n NumberOfColors: number;\n Ramp: string;\n TableRange: Point2;\n HueRange: Point2;\n SaturationRange: Point2;\n ValueRange: Point2;\n AlphaRange: Point2;\n NaNColor: Point4;\n BelowRangeColor: Point4;\n UseBelowRangeColor: boolean;\n AboveRangeColor: Point4;\n UseAboveRangeColor: boolean;\n InputRange: Point2;\n Table: Point4[];\n\n /**\n * Creates a default linear LookupTable object with 256 colors.\n */\n constructor() {\n this.NumberOfColors = 256;\n this.Ramp = 'linear';\n this.TableRange = [0, 255];\n this.HueRange = [0, 0.66667];\n this.SaturationRange = [1, 1];\n this.ValueRange = [1, 1];\n this.AlphaRange = [1, 1];\n this.NaNColor = [128, 0, 0, 255];\n this.BelowRangeColor = [0, 0, 0, 255];\n this.UseBelowRangeColor = true;\n this.AboveRangeColor = [255, 255, 255, 255];\n this.UseAboveRangeColor = true;\n this.InputRange = [0, 255];\n this.Table = [];\n }\n\n /**\n * Specify the number of values (i.e., colors) in the lookup table.\n * @param {Number} number The number of colors in he LookupTable\n * @returns {void}\n * @memberof Colors\n */\n public setNumberOfTableValues(number) {\n this.NumberOfColors = number;\n }\n\n /**\n * Set the shape of the table ramp to either 'linear', 'scurve' or 'sqrt'\n * @param {String} ramp A string value representing the shape of the table. Allowed values are 'linear', 'scurve' or 'sqrt'\n * @returns {void}\n * @memberof Colors\n */\n public setRamp(ramp) {\n this.Ramp = ramp;\n }\n\n /**\n * Sets the minimum/maximum scalar values for scalar mapping.\n * Scalar values less than minimum range value are clamped to minimum range value.\n * Scalar values greater than maximum range value are clamped to maximum range value.\n * @param {Number} start A double representing the minimum scaler value of the LookupTable\n * @param {any} end A double representing the maximum scaler value of the LookupTable\n * @returns {void}\n * @memberof Colors\n */\n public setTableRange(start, end) {\n this.TableRange[0] = start;\n this.TableRange[1] = end;\n }\n\n /**\n * Set the range in hue (using automatic generation). Hue ranges between [0,1].\n * @param {Number} start A double representing the minimum hue value in a range. Min. is 0\n * @param {Number} end A double representing the maximum hue value in a range. Max. is 1\n * @returns {void}\n * @memberof Colors\n */\n public setHueRange(start, end) {\n this.HueRange[0] = start;\n this.HueRange[1] = end;\n }\n\n /**\n * Set the range in saturation (using automatic generation). Saturation ranges between [0,1].\n * @param {Number} start A double representing the minimum Saturation value in a range. Min. is 0\n * @param {Number} end A double representing the maximum Saturation value in a range. Max. is 1\n * @returns {void}\n * @memberof Colors\n */\n public setSaturationRange(start, end) {\n this.SaturationRange[0] = start;\n this.SaturationRange[1] = end;\n }\n\n /**\n * Set the range in value (using automatic generation). Value ranges between [0,1].\n * @param {Numeber } start A double representing the minimum value in a range. Min. is 0\n * @param {Numeber} end A double representing the maximum value in a range. Max. is 1\n * @returns {void}\n * @memberof Colors\n */\n public setValueRange(start, end) {\n // Set the range in value (using automatic generation). Value ranges between [0,1].\n this.ValueRange[0] = start;\n this.ValueRange[1] = end;\n }\n\n /**\n * (Not Used) Sets the range of scalars which will be mapped.\n * @param {Number} start the minimum scalar value in the range\n * @param {Number} end the maximum scalar value in the range\n * @returns {void}\n * @memberof Colors\n */\n public setRange(start, end) {\n this.InputRange[0] = start;\n this.InputRange[1] = end;\n }\n\n /**\n * Set the range in alpha (using automatic generation). Alpha ranges from [0,1].\n * @param {Number} start A double representing the minimum alpha value\n * @param {Number} end A double representing the maximum alpha value\n * @returns {void}\n * @memberof Colors\n */\n public setAlphaRange(start, end) {\n // Set the range in alpha (using automatic generation). Alpha ranges from [0,1].\n this.AlphaRange[0] = start;\n this.AlphaRange[1] = end;\n }\n\n /**\n * Map one value through the lookup table and return the color as an\n * RGBA array of doubles between 0 and 1.\n * @param {Number} scalar A double scalar value which will be mapped to a color in the LookupTable\n * @returns {Number[]} An RGBA array of doubles between 0 and 1\n * @memberof Colors\n */\n public getColor(scalar) {\n return this.mapValue(scalar);\n }\n\n /**\n * Generate lookup table from hue, saturation, value, alpha min/max values. Table is built from linear ramp of each value.\n * @param {Boolean} force true to force the build of the LookupTable. Otherwie, false. This is useful if a lookup table has been defined manually\n * (using SetTableValue) and then an application decides to rebuild the lookup table using the implicit process.\n * @returns {void}\n * @memberof Colors\n */\n public build(force) {\n if (this.Table.length > 1 && !force) {\n return;\n }\n\n // Clear the table\n this.Table = [];\n\n const maxIndex = this.NumberOfColors - 1;\n\n let hinc, sinc, vinc, ainc;\n\n if (maxIndex) {\n hinc = (this.HueRange[1] - this.HueRange[0]) / maxIndex;\n sinc = (this.SaturationRange[1] - this.SaturationRange[0]) / maxIndex;\n vinc = (this.ValueRange[1] - this.ValueRange[0]) / maxIndex;\n ainc = (this.AlphaRange[1] - this.AlphaRange[0]) / maxIndex;\n } else {\n hinc = sinc = vinc = ainc = 0.0;\n }\n\n for (let i = 0; i <= maxIndex; i++) {\n const hue = this.HueRange[0] + i * hinc;\n const sat = this.SaturationRange[0] + i * sinc;\n const val = this.ValueRange[0] + i * vinc;\n const alpha = this.AlphaRange[0] + i * ainc;\n\n const rgb = HSVToRGB(hue, sat, val);\n const c_rgba: Point4 = [0, 0, 0, 0];\n\n switch (this.Ramp) {\n case 'scurve':\n c_rgba[0] = Math.floor(\n 127.5 * (1.0 + Math.cos((1.0 - rgb[0]) * Math.PI))\n );\n c_rgba[1] = Math.floor(\n 127.5 * (1.0 + Math.cos((1.0 - rgb[1]) * Math.PI))\n );\n c_rgba[2] = Math.floor(\n 127.5 * (1.0 + Math.cos((1.0 - rgb[2]) * Math.PI))\n );\n c_rgba[3] = Math.floor(alpha * 255);\n break;\n case 'linear':\n c_rgba[0] = Math.floor(rgb[0] * 255 + 0.5);\n c_rgba[1] = Math.floor(rgb[1] * 255 + 0.5);\n c_rgba[2] = Math.floor(rgb[2] * 255 + 0.5);\n c_rgba[3] = Math.floor(alpha * 255 + 0.5);\n break;\n case 'sqrt':\n c_rgba[0] = Math.floor(Math.sqrt(rgb[0]) * 255 + 0.5);\n c_rgba[1] = Math.floor(Math.sqrt(rgb[1]) * 255 + 0.5);\n c_rgba[2] = Math.floor(Math.sqrt(rgb[2]) * 255 + 0.5);\n c_rgba[3] = Math.floor(Math.sqrt(alpha) * 255 + 0.5);\n break;\n default:\n throw new Error(`Invalid Ramp value (${this.Ramp})`);\n }\n\n this.Table.push(c_rgba);\n }\n\n this.buildSpecialColors();\n }\n\n /**\n * Ensures the out-of-range colors (Below range and Above range) are set correctly.\n * @returns {void}\n * @memberof Colors\n */\n private buildSpecialColors() {\n const numberOfColors = this.NumberOfColors;\n const belowRangeColorIndex = numberOfColors + BELOW_RANGE_COLOR_INDEX;\n const aboveRangeColorIndex = numberOfColors + ABOVE_RANGE_COLOR_INDEX;\n const nanColorIndex = numberOfColors + NAN_COLOR_INDEX;\n\n // Below range color\n if (this.UseBelowRangeColor || numberOfColors === 0) {\n this.Table[belowRangeColorIndex] = this.BelowRangeColor;\n } else {\n // Duplicate the first color in the table.\n this.Table[belowRangeColorIndex] = this.Table[0];\n }\n\n // Above range color\n if (this.UseAboveRangeColor || numberOfColors === 0) {\n this.Table[aboveRangeColorIndex] = this.AboveRangeColor;\n } else {\n // Duplicate the last color in the table.\n this.Table[aboveRangeColorIndex] = this.Table[numberOfColors - 1];\n }\n\n // Always use NanColor\n this.Table[nanColorIndex] = this.NaNColor;\n }\n\n /**\n * Similar to GetColor - Map one value through the lookup table and return the color as an\n * RGBA array of doubles between 0 and 1.\n * @param {Numeber} v A double scalar value which will be mapped to a color in the LookupTable\n * @returns {Number[]} An RGBA array of doubles between 0 and 1\n * @memberof Colors\n */\n private mapValue(v) {\n const index = this.getIndex(v);\n\n if (index < 0) {\n return this.NaNColor;\n } else if (index === 0) {\n if (this.UseBelowRangeColor && v < this.TableRange[0]) {\n return this.BelowRangeColor;\n }\n } else if (index === this.NumberOfColors - 1) {\n if (this.UseAboveRangeColor && v > this.TableRange[1]) {\n return this.AboveRangeColor;\n }\n }\n\n return this.Table[index];\n }\n\n /**\n * Return the table index associated with a particular value.\n * @param {Number} v A double value which table index will be returned.\n * @returns {Number} The index in the LookupTable\n * @memberof Colors\n */\n private getIndex(v) {\n const p = {\n Range: [],\n MaxIndex: this.NumberOfColors - 1,\n Shift: -this.TableRange[0],\n Scale: 1,\n };\n\n if (this.TableRange[1] <= this.TableRange[0]) {\n p.Scale = Number.MAX_VALUE;\n } else {\n p.Scale = p.MaxIndex / (this.TableRange[1] - this.TableRange[0]);\n }\n\n p.Range[0] = this.TableRange[0];\n p.Range[1] = this.TableRange[1];\n\n // First, check whether we have a number...\n if (isNaN(v)) {\n // For backwards compatibility\n return -1;\n }\n\n // Map to an index:\n let index = linearIndexLookupMain(v, p);\n\n // For backwards compatibility, if the index indicates an\n // Out-of-range value, truncate to index range for in-range colors.\n if (index === this.NumberOfColors + BELOW_RANGE_COLOR_INDEX) {\n index = 0;\n } else if (index === this.NumberOfColors + ABOVE_RANGE_COLOR_INDEX) {\n index = this.NumberOfColors - 1;\n }\n\n return index;\n }\n\n /**\n * Directly load color into lookup table. Use [0,1] double values for color component specification.\n * Make sure that you've either used the Build() method or used SetNumberOfTableValues() prior to using this method.\n * @param {Number} index The index in the LookupTable of where to insert the color value\n * @param {Number[]} rgba An array of [0,1] double values for an RGBA color component\n * @returns {void}\n * @memberof Colors\n */\n public setTableValue(index, rgba) {\n // Check if it index, red, green, blue and alpha were passed as parameter\n if (arguments.length === 5) {\n rgba = Array.prototype.slice.call(arguments, 1);\n }\n\n // Check the index to make sure it is valid\n if (index < 0) {\n throw new Error(\n `Can't set the table value for negative index (${index})`\n );\n }\n\n if (index >= this.NumberOfColors) {\n new Error(\n `Index ${index} is greater than the number of colors ${this.NumberOfColors}`\n );\n }\n\n this.Table[index] = rgba;\n\n if (index === 0 || index === this.NumberOfColors - 1) {\n // This is needed due to the way the special colors are stored in\n // The internal table. If Above/BelowRangeColors are not used and\n // The min/max colors are changed in the table with this member\n // Function, then the colors used for values outside the range may\n // Be incorrect. Calling this here ensures the out-of-range colors\n // Are set correctly.\n this.buildSpecialColors();\n }\n }\n}\n\nexport default LookupTable;\n","import LookupTable from './lookupTable';\nimport CPU_COLORMAPS from '../../../../constants/cpuColormaps';\nimport {\n CPUFallbackColormap,\n CPUFallbackColormapData,\n Point4,\n} from '../../../../types';\n\nconst COLOR_TRANSPARENT: Point4 = [0, 0, 0, 0];\n\n/**\n * Generate linearly spaced vectors\n * http://cens.ioc.ee/local/man/matlab/techdoc/ref/linspace.html\n * @param {Number} a A number representing the first vector\n * @param {Number} b A number representing the second vector\n * @param {Number} n The number of linear spaced vectors to generate\n * @returns {Array} An array of points representing linear spaced vectors.\n * @memberof Colors\n */\nfunction linspace(a: number, b: number, n: number): number[] {\n n = n === null ? 100 : n;\n\n const increment = (b - a) / (n - 1);\n const vector = [];\n\n while (n-- > 0) {\n vector.push(a);\n a += increment;\n }\n\n // Make sure the last item will always be \"b\" because most of the\n // Time we'll get numbers like 1.0000000000000002 instead of 1.\n vector[vector.length - 1] = b;\n\n return vector;\n}\n\n/**\n * Returns the \"rank/index\" of the element in a sorted array if found or the highest index if not. Uses (binary search)\n * @param {Array} array A sorted array to search in\n * @param {any} elem the element in the array to search for\n * @returns {number} The rank/index of the element in the given array\n * @memberof Colors\n */\nfunction getRank(array, elem) {\n let left = 0;\n let right = array.length - 1;\n\n while (left <= right) {\n const mid = left + Math.floor((right - left) / 2);\n const midElem = array[mid];\n\n if (midElem === elem) {\n return mid;\n } else if (elem < midElem) {\n right = mid - 1;\n } else {\n left = mid + 1;\n }\n }\n\n return left;\n}\n\n/**\n * Find the indices into a sorted array a such that, if the corresponding elements\n * In v were inserted before the indices, the order of a would be preserved.\n * http://lagrange.univ-lyon1.fr/docs/numpy/1.11.0/reference/generated/numpy.searchsorted.html\n * @param {Array} inputArray The array where the values will be inserted\n * @param {Array} values An array of the values to be inserted into the inputArray\n * @returns {Array} The indices where elements should be inserted to maintain order.\n * @memberof Colors\n */\nfunction searchSorted(inputArray, values) {\n let i;\n const indexes = [];\n const len = values.length;\n\n inputArray.sort(function (a, b) {\n return a - b;\n });\n\n for (i = 0; i < len; i++) {\n indexes[i] = getRank(inputArray, values[i]);\n }\n\n return indexes;\n}\n\n/**\n * Creates an *N* -element 1-d lookup table\n * @param {Number} N The number of elements in the result lookup table\n * @param {Array} data represented by a list of x,y0,y1 mapping correspondences. Each element in this\n * List represents how a value between 0 and 1 (inclusive) represented by x is mapped to\n * A corresponding value between 0 and 1 (inclusive). The two values of y are to allow for\n * Discontinuous mapping functions (say as might be found in a sawtooth) where y0 represents\n * The value of y for values of x <= to that given, and y1 is the value to be used for x >\n * Than that given). The list must start with x=0, end with x=1, and all values of x must be\n * In increasing order. Values between the given mapping points are determined by simple linear\n * Interpolation.\n * @param {any} gamma value denotes a \"gamma curve\" value which adjusts the brightness\n * at the bottom and top of the map.\n * @returns {any[]} an array \"result\" where result[x*(N-1)] gives the closest value for\n * Values of x between 0 and 1.\n * @memberof Colors\n */\nfunction makeMappingArray(N, data, gamma) {\n let i;\n const x = [];\n const y0 = [];\n const y1 = [];\n const lut = [];\n\n gamma = gamma === null ? 1 : gamma;\n\n for (i = 0; i < data.length; i++) {\n const element = data[i];\n\n x.push((N - 1) * element[0]);\n y0.push(element[1]);\n y1.push(element[1]);\n }\n\n const xLinSpace = linspace(0, 1, N);\n\n for (i = 0; i < N; i++) {\n xLinSpace[i] = (N - 1) * Math.pow(xLinSpace[i], gamma);\n }\n\n const xLinSpaceIndexes = searchSorted(x, xLinSpace);\n\n for (i = 1; i < N - 1; i++) {\n const index = xLinSpaceIndexes[i];\n const colorPercent =\n (xLinSpace[i] - x[index - 1]) / (x[index] - x[index - 1]);\n const colorDelta = y0[index] - y1[index - 1];\n\n lut[i] = colorPercent * colorDelta + y1[index - 1];\n }\n\n lut[0] = y1[0];\n lut[N - 1] = y0[data.length - 1];\n\n return lut;\n}\n\n/**\n * Creates a Colormap based on lookup tables using linear segments.\n * @param {{red:Array, green:Array, blue:Array}} segmentedData An object with a red, green and blue entries.\n * Each entry should be a list of x, y0, y1 tuples, forming rows in a table.\n * @param {Number} N The number of elements in the result Colormap\n * @param {any} gamma value denotes a \"gamma curve\" value which adjusts the brightness\n * at the bottom and top of the Colormap.\n * @returns {Array} The created Colormap object\n * @description The lookup table is generated using linear interpolation for each\n * Primary color, with the 0-1 domain divided into any number of\n * Segments.\n * https://github.com/stefanv/matplotlib/blob/3f1a23755e86fef97d51e30e106195f34425c9e3/lib/matplotlib/colors.py#L663\n * @memberof Colors\n */\nfunction createLinearSegmentedColormap(segmentedData, N, gamma) {\n let i;\n const lut = [];\n\n N = N === null ? 256 : N;\n gamma = gamma === null ? 1 : gamma;\n\n const redLut = makeMappingArray(N, segmentedData.red, gamma);\n const greenLut = makeMappingArray(N, segmentedData.green, gamma);\n const blueLut = makeMappingArray(N, segmentedData.blue, gamma);\n\n for (i = 0; i < N; i++) {\n const red = Math.round(redLut[i] * 255);\n const green = Math.round(greenLut[i] * 255);\n const blue = Math.round(blueLut[i] * 255);\n const rgba = [red, green, blue, 255];\n\n lut.push(rgba);\n }\n\n return lut;\n}\n\n/**\n * Return all available colormaps (id and name)\n * @returns {Array<{id,key}>} An array of colormaps with an object containing the \"id\" and display \"name\"\n * @memberof Colors\n */\nexport function getColormapsList() {\n const colormaps = [];\n const keys = Object.keys(CPU_COLORMAPS);\n\n keys.forEach(function (key) {\n if (CPU_COLORMAPS.hasOwnProperty(key)) {\n const colormap = CPU_COLORMAPS[key];\n\n colormaps.push({\n id: key,\n name: colormap.name,\n });\n }\n });\n\n colormaps.sort(function (a, b) {\n const aName = a.name.toLowerCase();\n const bName = b.name.toLowerCase();\n\n if (aName === bName) {\n return 0;\n }\n\n return aName < bName ? -1 : 1;\n });\n\n return colormaps;\n}\n\n/**\n * Return a colorMap object with the provided id and colormapData\n * if the Id matches existent colorMap objects (check colormapsData) the colormapData is ignored.\n * if the colormapData is not empty, the colorMap will be added to the colormapsData list. Otherwise, an empty colorMap object is returned.\n * @param {string} id The ID of the colormap\n * @param {Object} colormapData - An object that can contain a name, numColors, gama, segmentedData and/or colors\n * @returns {*} The Colormap Object\n * @memberof Colors\n */\nexport function getColormap(\n id: string,\n colormapData?: CPUFallbackColormapData\n): CPUFallbackColormap {\n let colormap = CPU_COLORMAPS[id];\n\n if (!colormap) {\n colormap = CPU_COLORMAPS[id] = colormapData || {\n name: '',\n colors: [],\n };\n }\n\n if (!colormap.colors && colormap.segmentedData) {\n colormap.colors = createLinearSegmentedColormap(\n colormap.segmentedData,\n colormap.numColors,\n colormap.gamma\n );\n }\n\n const cpuFallbackColormap: CPUFallbackColormap = {\n getId() {\n return id;\n },\n\n getColorSchemeName() {\n return colormap.name;\n },\n\n setColorSchemeName(name) {\n colormap.name = name;\n },\n\n getNumberOfColors() {\n return colormap.colors.length;\n },\n\n setNumberOfColors(numColors) {\n while (colormap.colors.length < numColors) {\n colormap.colors.push(COLOR_TRANSPARENT);\n }\n\n colormap.colors.length = numColors;\n },\n\n getColor(index) {\n if (this.isValidIndex(index)) {\n return colormap.colors[index];\n }\n\n return COLOR_TRANSPARENT;\n },\n\n getColorRepeating(index) {\n const numColors = colormap.colors.length;\n\n index = numColors ? index % numColors : 0;\n\n return this.getColor(index);\n },\n\n setColor(index, rgba) {\n if (this.isValidIndex(index)) {\n colormap.colors[index] = rgba;\n }\n },\n\n addColor(rgba) {\n colormap.colors.push(rgba);\n },\n\n insertColor(index, rgba) {\n if (this.isValidIndex(index)) {\n colormap.colors.splice(index, 1, rgba);\n }\n },\n\n removeColor(index) {\n if (this.isValidIndex(index)) {\n colormap.colors.splice(index, 1);\n }\n },\n\n clearColors() {\n colormap.colors = [];\n },\n\n buildLookupTable(lut) {\n if (!lut) {\n return;\n }\n\n const numColors = colormap.colors.length;\n\n lut.setNumberOfTableValues(numColors);\n\n for (let i = 0; i < numColors; i++) {\n lut.setTableValue(i, colormap.colors[i]);\n }\n },\n\n createLookupTable() {\n const lut = new LookupTable();\n\n this.buildLookupTable(lut);\n\n return lut;\n },\n\n isValidIndex(index) {\n return index >= 0 && index < colormap.colors.length;\n },\n };\n\n return cpuFallbackColormap;\n}\n","/**\n * Use the performance.now() method if possible, and if not, use Date.now()\n *\n * @return {number} Time elapsed since the time origin\n * @memberof Polyfills\n */\nexport default function (): number {\n if (window.performance) {\n return performance.now();\n }\n\n return Date.now();\n}\n","/* eslint no-bitwise: 0 */\n\n/**\n * Volume of Interest Lookup Table Function\n *\n * @typedef {Function} VOILUTFunction\n *\n * @param {Number} modalityLutValue\n * @returns {Number} transformed value\n * @memberof Objects\n */\n\n/**\n * @module: VOILUT\n */\n\n/**\n * Generates the linear VOI LUT function.\n * From the DICOM standard:\n * https://dicom.nema.org/medical/dicom/current/output/html/part03.html#sect_C.11.2.1.2.1\n * ((x - (c - 0.5)) / (w-1) + 0.5) * (ymax- ymin) + ymin\n * clipped to the ymin...ymax range\n *\n * @param {Number} windowWidth Window Width\n * @param {Number} windowCenter Window Center\n * @returns {VOILUTFunction} VOI LUT mapping function\n * @memberof VOILUT\n */\nfunction generateLinearVOILUT(windowWidth: number, windowCenter: number) {\n return function (modalityLutValue) {\n const value =\n ((modalityLutValue - (windowCenter - 0.5)) / (windowWidth - 1) + 0.5) *\n 255.0;\n return Math.min(Math.max(value, 0), 255);\n };\n}\n\n/**\n * Generate a non-linear volume of interest lookup table\n *\n * @param {LUT} voiLUT Volume of Interest Lookup Table Object\n *\n * @returns {VOILUTFunction} VOI LUT mapping function\n * @memberof VOILUT\n */\nfunction generateNonLinearVOILUT(voiLUT) {\n // We don't trust the voiLUT.numBitsPerEntry, mainly thanks to Agfa!\n const bitsPerEntry = Math.max(...voiLUT.lut).toString(2).length;\n const shift = bitsPerEntry - 8;\n const minValue = voiLUT.lut[0] >> shift;\n const maxValue = voiLUT.lut[voiLUT.lut.length - 1] >> shift;\n const maxValueMapped = voiLUT.firstValueMapped + voiLUT.lut.length - 1;\n\n return function (modalityLutValue) {\n if (modalityLutValue < voiLUT.firstValueMapped) {\n return minValue;\n } else if (modalityLutValue >= maxValueMapped) {\n return maxValue;\n }\n\n return voiLUT.lut[modalityLutValue - voiLUT.firstValueMapped] >> shift;\n };\n}\n\n/**\n * Retrieve a VOI LUT mapping function given the current windowing settings\n * and the VOI LUT for the image\n *\n * @param {Number} windowWidth Window Width\n * @param {Number} windowCenter Window Center\n * @param {LUT} [voiLUT] Volume of Interest Lookup Table Object\n *\n * @return {VOILUTFunction} VOI LUT mapping function\n * @memberof VOILUT\n */\nexport default function (windowWidth: number, windowCenter: number, voiLUT) {\n if (voiLUT) {\n return generateNonLinearVOILUT(voiLUT);\n }\n\n return generateLinearVOILUT(windowWidth, windowCenter);\n}\n","import {\n CPUFallbackTransform,\n Point2,\n TransformMatrix2D,\n} from '../../../../types';\n\n// By Simon Sarris\n// Www.simonsarris.com\n// Sarris@acm.org\n//\n// Free to use and distribute at will\n// So long as you are nice to people, etc\n\n// Simple class for keeping track of the current transformation matrix\n\n// For instance:\n// Var t = new Transform();\n// T.rotate(5);\n// Var m = t.m;\n// Ctx.setTransform(m[0], m[1], m[2], m[3], m[4], m[5]);\n\n// Is equivalent to:\n// Ctx.rotate(5);\n\n// But now you can retrieve it :)\n\n// Remember that this does not account for any CSS transforms applied to the canvas\nexport class Transform implements CPUFallbackTransform {\n private m: TransformMatrix2D;\n\n constructor() {\n this.reset();\n }\n\n getMatrix(): TransformMatrix2D {\n return this.m;\n }\n\n reset(): void {\n this.m = [1, 0, 0, 1, 0, 0];\n }\n\n clone(): CPUFallbackTransform {\n const transform = new Transform();\n\n transform.m[0] = this.m[0];\n transform.m[1] = this.m[1];\n transform.m[2] = this.m[2];\n transform.m[3] = this.m[3];\n transform.m[4] = this.m[4];\n transform.m[5] = this.m[5];\n\n return transform;\n }\n\n multiply(matrix: TransformMatrix2D): void {\n const m11 = this.m[0] * matrix[0] + this.m[2] * matrix[1];\n const m12 = this.m[1] * matrix[0] + this.m[3] * matrix[1];\n\n const m21 = this.m[0] * matrix[2] + this.m[2] * matrix[3];\n const m22 = this.m[1] * matrix[2] + this.m[3] * matrix[3];\n\n const dx = this.m[0] * matrix[4] + this.m[2] * matrix[5] + this.m[4];\n const dy = this.m[1] * matrix[4] + this.m[3] * matrix[5] + this.m[5];\n\n this.m[0] = m11;\n this.m[1] = m12;\n this.m[2] = m21;\n this.m[3] = m22;\n this.m[4] = dx;\n this.m[5] = dy;\n }\n\n invert(): void {\n const d = 1 / (this.m[0] * this.m[3] - this.m[1] * this.m[2]);\n const m0 = this.m[3] * d;\n const m1 = -this.m[1] * d;\n const m2 = -this.m[2] * d;\n const m3 = this.m[0] * d;\n const m4 = d * (this.m[2] * this.m[5] - this.m[3] * this.m[4]);\n const m5 = d * (this.m[1] * this.m[4] - this.m[0] * this.m[5]);\n\n this.m[0] = m0;\n this.m[1] = m1;\n this.m[2] = m2;\n this.m[3] = m3;\n this.m[4] = m4;\n this.m[5] = m5;\n }\n\n rotate(rad: number): void {\n const c = Math.cos(rad);\n const s = Math.sin(rad);\n const m11 = this.m[0] * c + this.m[2] * s;\n const m12 = this.m[1] * c + this.m[3] * s;\n const m21 = this.m[0] * -s + this.m[2] * c;\n const m22 = this.m[1] * -s + this.m[3] * c;\n\n this.m[0] = m11;\n this.m[1] = m12;\n this.m[2] = m21;\n this.m[3] = m22;\n }\n\n translate(x: number, y: number): void {\n this.m[4] += this.m[0] * x + this.m[2] * y;\n this.m[5] += this.m[1] * x + this.m[3] * y;\n }\n\n scale(sx: number, sy: number) {\n this.m[0] *= sx;\n this.m[1] *= sx;\n this.m[2] *= sy;\n this.m[3] *= sy;\n }\n\n transformPoint(point: Point2): Point2 {\n const x = point[0];\n const y = point[1];\n\n return [\n x * this.m[0] + y * this.m[2] + this.m[4],\n x * this.m[1] + y * this.m[3] + this.m[5],\n ];\n }\n}\n","import { Transform } from './transform';\nimport {\n CPUFallbackEnabledElement,\n CPUFallbackTransform,\n} from '../../../../types';\n\n/**\n * Calculate the transform for a Cornerstone enabled element\n *\n * @param enabledElement - The Cornerstone Enabled Element\n * @param scale - The viewport scale\n * @returns The current transform\n */\nexport default function (\n enabledElement: CPUFallbackEnabledElement,\n scale?: number\n): CPUFallbackTransform {\n const transform = new Transform();\n\n if (!enabledElement.viewport.displayedArea) {\n return transform;\n }\n\n // Move to center of canvas\n transform.translate(\n enabledElement.canvas.width / 2,\n enabledElement.canvas.height / 2\n );\n\n // Apply the rotation before scaling for non square pixels\n const angle = enabledElement.viewport.rotation;\n\n if (angle !== 0) {\n transform.rotate((angle * Math.PI) / 180);\n }\n\n // Apply the scale\n let widthScale = enabledElement.viewport.scale;\n let heightScale = enabledElement.viewport.scale;\n\n const width =\n enabledElement.viewport.displayedArea.brhc.x -\n (enabledElement.viewport.displayedArea.tlhc.x - 1);\n const height =\n enabledElement.viewport.displayedArea.brhc.y -\n (enabledElement.viewport.displayedArea.tlhc.y - 1);\n\n if (enabledElement.viewport.displayedArea.presentationSizeMode === 'NONE') {\n if (\n enabledElement.image.rowPixelSpacing <\n enabledElement.image.columnPixelSpacing\n ) {\n widthScale *=\n enabledElement.image.columnPixelSpacing /\n enabledElement.image.rowPixelSpacing;\n } else if (\n enabledElement.image.columnPixelSpacing <\n enabledElement.image.rowPixelSpacing\n ) {\n heightScale *=\n enabledElement.image.rowPixelSpacing /\n enabledElement.image.columnPixelSpacing;\n }\n } else {\n // These should be good for \"TRUE SIZE\" and \"MAGNIFY\"\n widthScale = enabledElement.viewport.displayedArea.columnPixelSpacing;\n heightScale = enabledElement.viewport.displayedArea.rowPixelSpacing;\n\n if (\n enabledElement.viewport.displayedArea.presentationSizeMode ===\n 'SCALE TO FIT'\n ) {\n // Fit TRUE IMAGE image (width/height) to window\n const verticalScale =\n enabledElement.canvas.height / (height * heightScale);\n const horizontalScale =\n enabledElement.canvas.width / (width * widthScale);\n\n // Apply new scale\n widthScale = heightScale = Math.min(horizontalScale, verticalScale);\n\n if (\n enabledElement.viewport.displayedArea.rowPixelSpacing <\n enabledElement.viewport.displayedArea.columnPixelSpacing\n ) {\n widthScale *=\n enabledElement.viewport.displayedArea.columnPixelSpacing /\n enabledElement.viewport.displayedArea.rowPixelSpacing;\n } else if (\n enabledElement.viewport.displayedArea.columnPixelSpacing <\n enabledElement.viewport.displayedArea.rowPixelSpacing\n ) {\n heightScale *=\n enabledElement.viewport.displayedArea.rowPixelSpacing /\n enabledElement.viewport.displayedArea.columnPixelSpacing;\n }\n }\n }\n\n transform.scale(widthScale, heightScale);\n\n // Unrotate to so we can translate unrotated\n if (angle !== 0) {\n transform.rotate((-angle * Math.PI) / 180);\n }\n\n // Apply the pan offset\n transform.translate(\n enabledElement.viewport.translation.x,\n enabledElement.viewport.translation.y\n );\n\n // Rotate again so we can apply general scale\n if (angle !== 0) {\n transform.rotate((angle * Math.PI) / 180);\n }\n\n if (scale !== undefined) {\n // Apply the font scale\n transform.scale(scale, scale);\n }\n\n // Apply Flip if required\n if (enabledElement.viewport.hflip) {\n transform.scale(-1, 1);\n }\n\n if (enabledElement.viewport.vflip) {\n transform.scale(1, -1);\n }\n\n // Move back from center of image\n transform.translate(-width / 2, -height / 2);\n\n return transform;\n}\n","import calculateTransform from './calculateTransform';\nimport { CPUFallbackEnabledElement } from '../../../../types';\n\n/**\n * Sets the canvas context transformation matrix to the pixel coordinate system. This allows\n * geometry to be driven using the canvas context using coordinates in the pixel coordinate system\n * @param {EnabledElement} enabledElement The\n * @param {CanvasRenderingContext2D} context The CanvasRenderingContext2D for the enabledElement's Canvas\n * @param {Number} [scale] Optional scale to apply\n * @returns {void}\n */\nexport default function (\n enabledElement: CPUFallbackEnabledElement,\n context: CanvasRenderingContext2D,\n scale?: number\n): void {\n if (enabledElement === undefined) {\n throw new Error(\n 'setToPixelCoordinateSystem: parameter enabledElement must not be undefined'\n );\n }\n if (context === undefined) {\n throw new Error(\n 'setToPixelCoordinateSystem: parameter context must not be undefined'\n );\n }\n\n const transform = calculateTransform(enabledElement, scale);\n const m = transform.getMatrix();\n\n context.setTransform(m[0], m[1], m[2], m[3], m[4], m[5]);\n}\n","import { CPUFallbackEnabledElement, IImage } from '../../../../types';\n\n/**\n * Determine whether or not an Enabled Element needs to be re-rendered.\n *\n * If the imageId has changed, or if any of the last rendered viewport\n * parameters have changed, this function will return true.\n *\n * @param enabledElement - An Enabled Element\n * @param image - An Image\n * @returns Whether - or not the Enabled Element needs to re-render its image\n */\nexport default function doesImageNeedToBeRendered(\n enabledElement: CPUFallbackEnabledElement,\n image: IImage\n): boolean {\n const lastRenderedImageId = enabledElement.renderingTools.lastRenderedImageId;\n const lastRenderedViewport =\n enabledElement.renderingTools.lastRenderedViewport;\n\n return (\n image.imageId !== lastRenderedImageId ||\n !lastRenderedViewport ||\n lastRenderedViewport.windowCenter !==\n enabledElement.viewport.voi.windowCenter ||\n lastRenderedViewport.windowWidth !==\n enabledElement.viewport.voi.windowWidth ||\n lastRenderedViewport.invert !== enabledElement.viewport.invert ||\n lastRenderedViewport.rotation !== enabledElement.viewport.rotation ||\n lastRenderedViewport.hflip !== enabledElement.viewport.hflip ||\n lastRenderedViewport.vflip !== enabledElement.viewport.vflip ||\n lastRenderedViewport.modalityLUT !== enabledElement.viewport.modalityLUT ||\n lastRenderedViewport.voiLUT !== enabledElement.viewport.voiLUT ||\n lastRenderedViewport.colormap !== enabledElement.viewport.colormap\n );\n}\n","import { CPUFallbackEnabledElement, IImage } from '../../../../types';\n\n/**\n * Sets size and clears canvas\n *\n * @param {Object} enabledElement Cornerstone Enabled Element\n * @param {Object} image Image to be rendered\n * @returns {void}\n * @memberof rendering\n */\nexport default function (\n enabledElement: CPUFallbackEnabledElement,\n image: IImage\n): void {\n const renderCanvas = enabledElement.renderingTools.renderCanvas;\n\n // Resize the canvas\n renderCanvas.width = image.width;\n renderCanvas.height = image.height;\n\n const canvasContext = renderCanvas.getContext('2d');\n\n // NOTE - we need to fill the render canvas with white pixels since we\n // control the luminance using the alpha channel to improve rendering performance.\n canvasContext.fillStyle = 'white';\n canvasContext.fillRect(0, 0, renderCanvas.width, renderCanvas.height);\n\n const renderCanvasData = canvasContext.getImageData(\n 0,\n 0,\n image.width,\n image.height\n );\n\n enabledElement.renderingTools.renderCanvasContext = canvasContext;\n enabledElement.renderingTools.renderCanvasData = renderCanvasData;\n}\n","import {\n CPUFallbackEnabledElement,\n CPUFallbackRenderingTools,\n} from '../../../../types';\n\n/**\n * Saves the parameters of the last render into renderingTools, used later to decide if data can be reused.\n *\n * @param {Object} enabledElement Cornerstone EnabledElement\n * @returns {Object} enabledElement.renderingTools\n * @memberof rendering\n */\n\nexport default function (\n enabledElement: CPUFallbackEnabledElement\n): CPUFallbackRenderingTools {\n const imageId = enabledElement.image.imageId;\n const viewport = enabledElement.viewport;\n const isColor = enabledElement.image.color;\n\n enabledElement.renderingTools.lastRenderedImageId = imageId;\n enabledElement.renderingTools.lastRenderedIsColor = isColor;\n enabledElement.renderingTools.lastRenderedViewport = {\n windowCenter: viewport.voi.windowCenter,\n windowWidth: viewport.voi.windowWidth,\n invert: viewport.invert,\n rotation: viewport.rotation,\n hflip: viewport.hflip,\n vflip: viewport.vflip,\n modalityLUT: viewport.modalityLUT,\n voiLUT: viewport.voiLUT,\n colormap: viewport.colormap,\n };\n\n return enabledElement.renderingTools;\n}\n","import now from './now';\nimport generateColorLUT from './generateColorLUT';\nimport storedColorPixelDataToCanvasImageData from './storedColorPixelDataToCanvasImageData';\nimport storedRGBAPixelDataToCanvasImageData from './storedRGBAPixelDataToCanvasImageData';\nimport setToPixelCoordinateSystem from './setToPixelCoordinateSystem';\nimport doesImageNeedToBeRendered from './doesImageNeedToBeRendered';\nimport initializeRenderCanvas from './initializeRenderCanvas';\nimport saveLastRendered from './saveLastRendered';\nimport {\n IImage,\n CPUFallbackViewport,\n CPUFallbackEnabledElement,\n} from '../../../../types';\n\n/**\n * Generates an appropriate Look Up Table to render the given image with the given window width and level (specified in the viewport)\n * Uses an internal cache for performance\n *\n * @param {Object} image The image to be rendered\n * @param {Object} viewport The viewport values used for rendering\n * @returns {Uint8ClampedArray} Look Up Table array.\n * @memberof rendering\n */\nfunction getLut(image: IImage, viewport: CPUFallbackViewport) {\n // If we have a cached lut and it has the right values, return it immediately\n if (\n image.cachedLut !== undefined &&\n image.cachedLut.windowCenter === viewport.voi.windowCenter &&\n image.cachedLut.windowWidth === viewport.voi.windowWidth &&\n image.cachedLut.invert === viewport.invert\n ) {\n return image.cachedLut.lutArray;\n }\n\n // Lut is invalid or not present, regenerate it and cache it\n generateColorLUT(\n image,\n viewport.voi.windowWidth,\n viewport.voi.windowCenter,\n viewport.invert\n );\n image.cachedLut.windowWidth = viewport.voi.windowWidth;\n image.cachedLut.windowCenter = viewport.voi.windowCenter;\n image.cachedLut.invert = viewport.invert;\n\n return image.cachedLut.lutArray;\n}\n\n/**\n * Returns an appropriate canvas to render the Image. If the canvas available in the cache is appropriate\n * it is returned, otherwise adjustments are made. It also sets the color transfer functions.\n *\n * @param enabledElement - The cornerstone enabled element\n * @param image - The image to be rendered\n * @param invalidated - Is pixel data valid\n * @returns An appropriate canvas for rendering the image\n * @memberof rendering\n */\nfunction getRenderCanvas(\n enabledElement: CPUFallbackEnabledElement,\n image: IImage,\n invalidated: boolean\n): HTMLCanvasElement {\n const canvasWasColor =\n enabledElement.renderingTools.lastRenderedIsColor === true;\n\n if (!enabledElement.renderingTools.renderCanvas || !canvasWasColor) {\n enabledElement.renderingTools.renderCanvas =\n document.createElement('canvas');\n }\n\n const renderCanvas = enabledElement.renderingTools.renderCanvas;\n\n // The ww/wc is identity and not inverted - get a canvas with the image rendered into it for\n // Fast drawing. Note that this is 256/128, and NOT 255/127, per the DICOM\n // standard, but allow either.\n const { windowWidth, windowCenter } = enabledElement.viewport.voi;\n if (\n (windowWidth === 256 || windowWidth === 255) &&\n (windowCenter === 128 || windowCenter === 127) &&\n enabledElement.viewport.invert === false &&\n image.getCanvas &&\n image.getCanvas()\n ) {\n return image.getCanvas();\n }\n\n // Apply the lut to the stored pixel data onto the render canvas\n if (\n doesImageNeedToBeRendered(enabledElement, image) === false &&\n invalidated !== true\n ) {\n return renderCanvas;\n }\n\n // If our render canvas does not match the size of this image reset it\n // NOTE: This might be inefficient if we are updating multiple images of different\n // Sizes frequently.\n if (\n renderCanvas.width !== image.width ||\n renderCanvas.height !== image.height\n ) {\n initializeRenderCanvas(enabledElement, image);\n }\n\n // Get the lut to use\n let start = now();\n const colorLUT = getLut(image, enabledElement.viewport);\n\n image.stats = image.stats || {};\n image.stats.lastLutGenerateTime = now() - start;\n\n const renderCanvasData = enabledElement.renderingTools.renderCanvasData;\n const renderCanvasContext = enabledElement.renderingTools.renderCanvasContext;\n\n // The color image voi/invert has been modified - apply the lut to the underlying\n // Pixel data and put it into the renderCanvas\n if (image.rgba) {\n storedRGBAPixelDataToCanvasImageData(\n image,\n colorLUT,\n renderCanvasData.data\n );\n } else {\n storedColorPixelDataToCanvasImageData(\n image,\n colorLUT,\n renderCanvasData.data\n );\n }\n\n start = now();\n renderCanvasContext.putImageData(renderCanvasData, 0, 0);\n image.stats.lastPutImageDataTime = now() - start;\n\n return renderCanvas;\n}\n\n/**\n * API function to render a color image to an enabled element\n *\n * @param {EnabledElement} enabledElement The Cornerstone Enabled Element to redraw\n * @param {Boolean} invalidated - true if pixel data has been invalidated and cached rendering should not be used\n * @returns {void}\n * @memberof rendering\n */\nexport function renderColorImage(\n enabledElement: CPUFallbackEnabledElement,\n invalidated: boolean\n): void {\n if (enabledElement === undefined) {\n throw new Error(\n 'renderColorImage: enabledElement parameter must not be undefined'\n );\n }\n\n const image = enabledElement.image;\n\n if (image === undefined) {\n throw new Error(\n 'renderColorImage: image must be loaded before it can be drawn'\n );\n }\n\n // Get the canvas context and reset the transform\n const context = enabledElement.canvas.getContext('2d');\n\n context.setTransform(1, 0, 0, 1, 0, 0);\n\n // Clear the canvas\n context.fillStyle = 'black';\n context.fillRect(\n 0,\n 0,\n enabledElement.canvas.width,\n enabledElement.canvas.height\n );\n\n // Turn off image smooth/interpolation if pixelReplication is set in the viewport\n context.imageSmoothingEnabled = !enabledElement.viewport.pixelReplication;\n\n // Save the canvas context state and apply the viewport properties\n setToPixelCoordinateSystem(enabledElement, context);\n\n const renderCanvas = getRenderCanvas(enabledElement, image, invalidated);\n\n const sx = enabledElement.viewport.displayedArea.tlhc.x - 1;\n const sy = enabledElement.viewport.displayedArea.tlhc.y - 1;\n const width = enabledElement.viewport.displayedArea.brhc.x - sx;\n const height = enabledElement.viewport.displayedArea.brhc.y - sy;\n\n context.drawImage(renderCanvas, sx, sy, width, height, 0, 0, width, height);\n\n enabledElement.renderingTools = saveLastRendered(enabledElement);\n}\n","import getVOILUT from './getVOILut';\nimport { IImage, CPUFallbackLUT } from '../../../../types';\n\n/**\n * Creates a LUT used while rendering to convert stored pixel values to\n * display pixels\n *\n * @param image - A Cornerstone Image Object\n * @param windowWidth - The Window Width\n * @param windowCenter - The Window Center\n * @param invert - A boolean describing whether or not the image has been inverted\n * @param voiLUT- A Volume of Interest Lookup Table\n *\n * @returns A lookup table to apply to the image\n */\nexport default function generateColorLUT(\n image: IImage,\n windowWidth: number | number[],\n windowCenter: number | number[],\n invert: boolean,\n voiLUT?: CPUFallbackLUT\n) {\n const maxPixelValue = image.maxPixelValue;\n const minPixelValue = image.minPixelValue;\n const offset = Math.min(minPixelValue, 0);\n\n if (image.cachedLut === undefined) {\n const length = maxPixelValue - offset + 1;\n\n image.cachedLut = {};\n image.cachedLut.lutArray = new Uint8ClampedArray(length);\n }\n\n const lut = image.cachedLut.lutArray;\n const vlutfn = getVOILUT(\n Array.isArray(windowWidth) ? windowWidth[0] : windowWidth,\n Array.isArray(windowCenter) ? windowCenter[0] : windowCenter,\n voiLUT\n );\n\n if (invert === true) {\n for (\n let storedValue = minPixelValue;\n storedValue <= maxPixelValue;\n storedValue++\n ) {\n lut[storedValue + -offset] = 255 - vlutfn(storedValue);\n }\n } else {\n for (\n let storedValue = minPixelValue;\n storedValue <= maxPixelValue;\n storedValue++\n ) {\n lut[storedValue + -offset] = vlutfn(storedValue);\n }\n }\n\n return lut;\n}\n","import now from './now';\nimport { IImage } from '../../../../types';\n\n/**\n * Converts stored RGBA color pixel values to display pixel values using a LUT.\n *\n * @param {Image} image A Cornerstone Image Object\n * @param {Array} lut Lookup table array\n * @param {Uint8ClampedArray} canvasImageDataData canvasImageData.data buffer filled with white pixels\n *\n * @returns {void}\n * @memberof Internal\n */\nexport default function (\n image: IImage,\n lut: Uint8ClampedArray,\n canvasImageDataData: Uint8ClampedArray\n): void {\n let start = now();\n const pixelData = image.getPixelData();\n\n image.stats.lastGetPixelDataTime = now() - start;\n\n const minPixelValue = image.minPixelValue;\n let canvasImageDataIndex = 0;\n let storedPixelDataIndex = 0;\n const numPixels = pixelData.length;\n\n // NOTE: As of Nov 2014, most javascript engines have lower performance when indexing negative indexes.\n // We have a special code path for this case that improves performance. Thanks to @jpambrun for this enhancement\n start = now();\n if (minPixelValue < 0) {\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Red\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Green\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Blue\n canvasImageDataData[canvasImageDataIndex++] =\n pixelData[storedPixelDataIndex++];\n }\n } else {\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++]]; // Red\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++]]; // Green\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++]]; // Blue\n canvasImageDataData[canvasImageDataIndex++] =\n pixelData[storedPixelDataIndex++];\n }\n }\n image.stats.lastStoredPixelDataToCanvasImageDataTime = now() - start;\n}\n","import now from './now';\nimport { IImage } from '../../../../types';\n\n/**\n * Converts stored color pixel values to display pixel values using a LUT.\n *\n * Note: Skips alpha value for any input image pixel data.\n *\n * @param {Image} image A Cornerstone Image Object\n * @param {Array} lut Lookup table array\n * @param {Uint8ClampedArray} canvasImageDataData canvasImageData.data buffer filled with white pixels\n *\n * @returns {void}\n * @memberof Internal\n */\nexport default function (\n image: IImage,\n lut: Uint8ClampedArray,\n canvasImageDataData: Uint8ClampedArray\n): void {\n let start = now();\n const pixelData = image.getPixelData();\n\n image.stats.lastGetPixelDataTime = now() - start;\n\n const minPixelValue = image.minPixelValue;\n let canvasImageDataIndex = 0;\n let storedPixelDataIndex = 0;\n const numPixels = pixelData.length;\n\n // NOTE: As of Nov 2014, most javascript engines have lower performance when indexing negative indexes.\n // We have a special code path for this case that improves performance. Thanks to @jpambrun for this enhancement\n start = now();\n if (minPixelValue < 0) {\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Red\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Green\n canvasImageDataData[canvasImageDataIndex] =\n lut[pixelData[storedPixelDataIndex] + -minPixelValue]; // Blue\n storedPixelDataIndex += 2;\n canvasImageDataIndex += 2;\n }\n } else {\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++]]; // Red\n canvasImageDataData[canvasImageDataIndex++] =\n lut[pixelData[storedPixelDataIndex++]]; // Green\n canvasImageDataData[canvasImageDataIndex] =\n lut[pixelData[storedPixelDataIndex]]; // Blue\n storedPixelDataIndex += 2;\n canvasImageDataIndex += 2;\n }\n }\n image.stats.lastStoredPixelDataToCanvasImageDataTime = now() - start;\n}\n","/**\n * Check if two lookup tables match\n *\n * @param {LUT} a A lookup table function\n * @param {LUT} b Another lookup table function\n * @return {boolean} Whether or not they match\n * @memberof rendering\n */\nexport default function (a: any, b: any) {\n // If undefined, they are equal\n if (!a && !b) {\n return true;\n }\n // If one is undefined, not equal\n if (!a || !b) {\n return false;\n }\n\n // Check the unique ids\n return a.id === b.id;\n}\n","import computeAutoVoi from './computeAutoVoi';\nimport lutMatches from './lutMatches';\nimport generateLut from './generateLut';\nimport { IImage, CPUFallbackViewport } from '../../../../types';\n\n/**\n * Retrieve or generate a LUT Array for an Image and Viewport\n *\n * @param {Image} image An Image Object\n * @param {Viewport} viewport An Viewport Object\n * @param {Boolean} invalidated Whether or not the LUT data has been invalidated\n * (e.g. by a change to the windowWidth, windowCenter, or invert viewport parameters).\n * @return {Uint8ClampedArray} LUT Array\n * @memberof rendering\n */\nexport default function (\n image: IImage,\n viewport: CPUFallbackViewport,\n invalidated: boolean\n): Uint8ClampedArray {\n // If we have a cached lut and it has the right values, return it immediately\n if (\n image.cachedLut !== undefined &&\n image.cachedLut.windowCenter === viewport.voi.windowCenter &&\n image.cachedLut.windowWidth === viewport.voi.windowWidth &&\n lutMatches(image.cachedLut.modalityLUT, viewport.modalityLUT) &&\n lutMatches(image.cachedLut.voiLUT, viewport.voiLUT) &&\n image.cachedLut.invert === viewport.invert &&\n invalidated !== true\n ) {\n return image.cachedLut.lutArray;\n }\n\n computeAutoVoi(viewport, image);\n\n // Lut is invalid or not present, regenerate it and cache it\n generateLut(\n image,\n viewport.voi.windowWidth,\n viewport.voi.windowCenter,\n viewport.invert,\n viewport.modalityLUT,\n viewport.voiLUT\n );\n\n image.cachedLut.windowWidth = viewport.voi.windowWidth;\n image.cachedLut.windowCenter = viewport.voi.windowCenter;\n image.cachedLut.invert = viewport.invert;\n image.cachedLut.voiLUT = viewport.voiLUT;\n image.cachedLut.modalityLUT = viewport.modalityLUT;\n\n return image.cachedLut.lutArray;\n}\n","import type { IImage, CPUFallbackViewport } from '../../../../types';\n\n/**\n * Computes the VOI to display all the pixels if no VOI LUT data (Window Width/Window Center or voiLUT) exists on the viewport object.\n *\n * @param viewport - Object containing the viewport properties\n * @param image - An Image loaded by a Cornerstone Image Loader\n */\nexport default function computeAutoVoi(\n viewport: CPUFallbackViewport,\n image: IImage\n): void {\n if (hasVoi(viewport)) {\n return;\n }\n\n const maxVoi = image.maxPixelValue * image.slope + image.intercept;\n const minVoi = image.minPixelValue * image.slope + image.intercept;\n const ww = maxVoi - minVoi;\n const wc = (maxVoi + minVoi) / 2;\n\n if (viewport.voi === undefined) {\n viewport.voi = {\n windowWidth: ww,\n windowCenter: wc,\n };\n } else {\n viewport.voi.windowWidth = ww;\n viewport.voi.windowCenter = wc;\n }\n}\n\n/**\n * Check if viewport has voi LUT data\n * @param viewport - The viewport to check for voi LUT data\n * @returns true viewport has LUT data (Window Width/Window Center or voiLUT). Otherwise, false.\n */\nfunction hasVoi(viewport: CPUFallbackViewport): boolean {\n const hasLut =\n viewport.voiLUT && viewport.voiLUT.lut && viewport.voiLUT.lut.length > 0;\n\n return (\n hasLut ||\n (viewport.voi.windowWidth !== undefined &&\n viewport.voi.windowCenter !== undefined)\n );\n}\n","import getModalityLut from './getModalityLut';\nimport getVOILUT from './getVOILut';\nimport { IImage, CPUFallbackLUT } from '../../../../types';\n\n/**\n * Creates a LUT used while rendering to convert stored pixel values to\n * display pixels\n *\n * @param image - A Cornerstone Image Object\n * @param windowWidth - The Window Width\n * @param windowCenter - The Window Center\n * @param invert - A boolean describing whether or not the image has been inverted\n * @param modalityLUT - A modality Lookup Table\n * @param voiLUT - A Volume of Interest Lookup Table\n *\n * @returns A lookup table to apply to the image\n */\nexport default function (\n image: IImage,\n windowWidth: number,\n windowCenter: number,\n invert: boolean,\n modalityLUT: CPUFallbackLUT,\n voiLUT: CPUFallbackLUT\n): Uint8ClampedArray {\n const maxPixelValue = image.maxPixelValue;\n const minPixelValue = image.minPixelValue;\n const offset = Math.min(minPixelValue, 0);\n\n if (image.cachedLut === undefined) {\n const length = maxPixelValue - offset + 1;\n\n image.cachedLut = {};\n image.cachedLut.lutArray = new Uint8ClampedArray(length);\n }\n\n const lut = image.cachedLut.lutArray;\n\n const mlutfn = getModalityLut(image.slope, image.intercept, modalityLUT);\n const vlutfn = getVOILUT(windowWidth, windowCenter, voiLUT);\n\n if (image.isPreScaled) {\n // if the image is already preScaled, it means that the slop and the intercept\n // are applied and there is no need for a modalityLut\n if (invert === true) {\n for (\n let storedValue = minPixelValue;\n storedValue <= maxPixelValue;\n storedValue++\n ) {\n lut[storedValue + -offset] = 255 - vlutfn(storedValue);\n }\n } else {\n for (\n let storedValue = minPixelValue;\n storedValue <= maxPixelValue;\n storedValue++\n ) {\n lut[storedValue + -offset] = vlutfn(storedValue);\n }\n }\n } else {\n if (invert === true) {\n for (\n let storedValue = minPixelValue;\n storedValue <= maxPixelValue;\n storedValue++\n ) {\n lut[storedValue + -offset] = 255 - vlutfn(mlutfn(storedValue));\n }\n } else {\n for (\n let storedValue = minPixelValue;\n storedValue <= maxPixelValue;\n storedValue++\n ) {\n lut[storedValue + -offset] = vlutfn(mlutfn(storedValue));\n }\n }\n }\n\n return lut;\n}\n","/**\n * Generates a linear modality transformation function\n *\n * See DICOM PS3.3 C.11.1 Modality LUT Module\n *\n * http://dicom.nema.org/medical/Dicom/current/output/chtml/part03/sect_C.11.html\n *\n * @param {Number} slope m in the equation specified by Rescale Intercept (0028,1052).\n * @param {Number} intercept The value b in relationship between stored values (SV) and the output units specified in Rescale Type (0028,1054).\n\n Output units = m*SV + b.\n * @return {function(*): *} A linear modality LUT function. Given a stored pixel it returns the modality pixel value\n * @memberof Internal\n */\nfunction generateLinearModalityLUT(slope, intercept) {\n return (storedPixelValue) => storedPixelValue * slope + intercept;\n}\n\nfunction generateNonLinearModalityLUT(modalityLUT) {\n const minValue = modalityLUT.lut[0];\n const maxValue = modalityLUT.lut[modalityLUT.lut.length - 1];\n const maxValueMapped = modalityLUT.firstValueMapped + modalityLUT.lut.length;\n\n return (storedPixelValue) => {\n if (storedPixelValue < modalityLUT.firstValueMapped) {\n return minValue;\n } else if (storedPixelValue >= maxValueMapped) {\n return maxValue;\n }\n\n return modalityLUT.lut[storedPixelValue];\n };\n}\n\n/**\n * Get the appropriate Modality LUT for the current situation.\n *\n * @param {Number} [slope] m in the equation specified by Rescale Intercept (0028,1052).\n * @param {Number} [intercept] The value b in relationship between stored values (SV) and the output units specified in Rescale Type (0028,1054).\n * @param {Function} [modalityLUT] A modality LUT function. Given a stored pixel it returns the modality pixel value.\n *\n * @return {function(*): *} A modality LUT function. Given a stored pixel it returns the modality pixel value.\n * @memberof Internal\n */\nexport default function (\n slope: number,\n intercept: number,\n modalityLUT: unknown\n) {\n if (modalityLUT) {\n return generateNonLinearModalityLUT(modalityLUT);\n }\n\n return generateLinearModalityLUT(slope, intercept);\n}\n","import storedPixelDataToCanvasImageData from './storedPixelDataToCanvasImageData';\nimport storedPixelDataToCanvasImageDataPET from './storedPixelDataToCanvasImageDataPET';\nimport storedPixelDataToCanvasImageDataRGBA from './storedPixelDataToCanvasImageDataRGBA';\nimport setToPixelCoordinateSystem from './setToPixelCoordinateSystem';\nimport now from './now';\nimport getLut from './getLut';\nimport doesImageNeedToBeRendered from './doesImageNeedToBeRendered';\nimport initializeRenderCanvas from './initializeRenderCanvas';\nimport saveLastRendered from './saveLastRendered';\nimport { IImage, CPUFallbackEnabledElement } from '../../../../types';\n\n/**\n * Returns an appropriate canvas to render the Image. If the canvas available in the cache is appropriate\n * it is returned, otherwise adjustments are made. It also sets the color transfer functions.\n *\n * @param {Object} enabledElement The cornerstone enabled element\n * @param {Object} image The image to be rendered\n * @param {Boolean} invalidated Is pixel data valid\n * @param {Boolean} [useAlphaChannel = true] Will an alpha channel be used\n * @returns {HTMLCanvasElement} An appropriate canvas for rendering the image\n * @memberof rendering\n */\nfunction getRenderCanvas(\n enabledElement: CPUFallbackEnabledElement,\n image: IImage,\n invalidated: boolean,\n useAlphaChannel = true\n): HTMLCanvasElement {\n const canvasWasColor =\n enabledElement.renderingTools.lastRenderedIsColor === true;\n\n if (!enabledElement.renderingTools.renderCanvas || canvasWasColor) {\n enabledElement.renderingTools.renderCanvas =\n document.createElement('canvas');\n initializeRenderCanvas(enabledElement, image);\n }\n\n const renderCanvas = enabledElement.renderingTools.renderCanvas;\n\n if (\n doesImageNeedToBeRendered(enabledElement, image) === false &&\n invalidated !== true\n ) {\n return renderCanvas;\n }\n\n // If our render canvas does not match the size of this image reset it\n // NOTE: This might be inefficient if we are updating multiple images of different\n // Sizes frequently.\n if (\n renderCanvas.width !== image.width ||\n renderCanvas.height !== image.height\n ) {\n initializeRenderCanvas(enabledElement, image);\n }\n\n image.stats = image.stats || {};\n\n const renderCanvasData = enabledElement.renderingTools.renderCanvasData;\n const renderCanvasContext = enabledElement.renderingTools.renderCanvasContext;\n\n let start = now();\n image.stats.lastLutGenerateTime = now() - start;\n\n const { viewport } = enabledElement;\n\n // If modality is 'PT' and the image is scaled then the results are floating points,\n // and we cannot create a lut for it (cannot have float indices). Therefore,\n // we use a mapping function to get the voiLUT from the values by applying\n // the windowLevel and windowWidth.\n if (viewport.modality === 'PT' && image.isPreScaled) {\n const { windowWidth, windowCenter } = viewport.voi;\n const minimum = windowCenter - windowWidth / 2;\n const maximum = windowCenter + windowWidth / 2;\n const range = maximum - minimum;\n const collectedMultiplierTerms = 255.0 / range;\n\n let petVOILutFunction;\n\n if (viewport.invert) {\n petVOILutFunction = (value) =>\n 255 - (value - minimum) * collectedMultiplierTerms;\n } else {\n // Note, don't need to math.floor, that is dealt with by setting the value in the Uint8Array.\n petVOILutFunction = (value) =>\n (value - minimum) * collectedMultiplierTerms;\n }\n\n storedPixelDataToCanvasImageDataPET(\n image,\n petVOILutFunction,\n renderCanvasData.data\n );\n } else {\n // Get the lut to use\n const lut = getLut(image, viewport, invalidated);\n\n if (useAlphaChannel) {\n storedPixelDataToCanvasImageData(image, lut, renderCanvasData.data);\n } else {\n storedPixelDataToCanvasImageDataRGBA(image, lut, renderCanvasData.data);\n }\n }\n\n start = now();\n renderCanvasContext.putImageData(renderCanvasData, 0, 0);\n image.stats.lastPutImageDataTime = now() - start;\n\n return renderCanvas;\n}\n\n/**\n * API function to draw a grayscale image to a given enabledElement\n *\n * @param {EnabledElement} enabledElement The Cornerstone Enabled Element to redraw\n * @param {Boolean} invalidated - true if pixel data has been invalidated and cached rendering should not be used\n * @returns {void}\n * @memberof rendering\n */\nexport function renderGrayscaleImage(\n enabledElement: CPUFallbackEnabledElement,\n invalidated: boolean\n): void {\n if (enabledElement === undefined) {\n throw new Error(\n 'drawImage: enabledElement parameter must not be undefined'\n );\n }\n\n const image = enabledElement.image;\n\n if (image === undefined) {\n throw new Error('drawImage: image must be loaded before it can be drawn');\n }\n\n // Get the canvas context and reset the transform\n const context = enabledElement.canvas.getContext('2d');\n\n context.setTransform(1, 0, 0, 1, 0, 0);\n\n // Clear the canvas\n context.fillStyle = 'black';\n context.fillRect(\n 0,\n 0,\n enabledElement.canvas.width,\n enabledElement.canvas.height\n );\n\n // Turn off image smooth/interpolation if pixelReplication is set in the viewport\n context.imageSmoothingEnabled = !enabledElement.viewport.pixelReplication;\n\n // Save the canvas context state and apply the viewport properties\n setToPixelCoordinateSystem(enabledElement, context);\n\n const renderCanvas = getRenderCanvas(enabledElement, image, invalidated);\n\n const sx = enabledElement.viewport.displayedArea.tlhc.x - 1;\n const sy = enabledElement.viewport.displayedArea.tlhc.y - 1;\n const width = enabledElement.viewport.displayedArea.brhc.x - sx;\n const height = enabledElement.viewport.displayedArea.brhc.y - sy;\n\n context.drawImage(renderCanvas, sx, sy, width, height, 0, 0, width, height);\n\n enabledElement.renderingTools = saveLastRendered(enabledElement);\n}\n","import now from './now';\nimport { IImage } from '../../../../types';\n\n/**\n * This function transforms stored pixel values into a canvas image data buffer\n * by using a LUT. This is the most performance sensitive code in cornerstone and\n * we use a special trick to make this go as fast as possible. Specifically we\n * use the alpha channel only to control the luminance rather than the red, green and\n * blue channels which makes it over 3x faster. The canvasImageDataData buffer needs\n * to be previously filled with white pixels.\n *\n * NOTE: Attribution would be appreciated if you use this technique!\n *\n * @param {Image} image A Cornerstone Image Object\n * @param {Array} lut Lookup table array\n * @param {Uint8ClampedArray} canvasImageDataData canvasImageData.data buffer filled with white pixels\n *\n * @returns {void}\n * @memberof Internal\n */\nexport default function (\n image: IImage,\n lutFunction: (value: number) => number,\n canvasImageDataData: Uint8ClampedArray\n): void {\n let start = now();\n const pixelData = image.getPixelData();\n\n image.stats.lastGetPixelDataTime = now() - start;\n\n const numPixels = pixelData.length;\n // const minPixelValue = image.minPixelValue;\n let canvasImageDataIndex = 3;\n let storedPixelDataIndex = 0;\n\n // NOTE: As of Nov 2014, most javascript engines have lower performance when indexing negative indexes.\n // We have a special code path for this case that improves performance. Thanks to @jpambrun for this enhancement\n\n // Added two paths (Int16Array, Uint16Array) to avoid polymorphic deoptimization in chrome.\n start = now();\n\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex] = lutFunction(\n pixelData[storedPixelDataIndex++]\n ); // Alpha\n canvasImageDataIndex += 4;\n }\n\n image.stats.lastStoredPixelDataToCanvasImageDataTime = now() - start;\n}\n","import now from './now';\nimport { IImage } from '../../../../types';\n\n/**\n * This function transforms stored pixel values into a canvas image data buffer\n * by using a LUT. This is the most performance sensitive code in cornerstone and\n * we use a special trick to make this go as fast as possible. Specifically we\n * use the alpha channel only to control the luminance rather than the red, green and\n * blue channels which makes it over 3x faster. The canvasImageDataData buffer needs\n * to be previously filled with white pixels.\n *\n * NOTE: Attribution would be appreciated if you use this technique!\n *\n * @param {Image} image A Cornerstone Image Object\n * @param {Array} lut Lookup table array\n * @param {Uint8ClampedArray} canvasImageDataData canvasImageData.data buffer filled with white pixels\n *\n * @returns {void}\n * @memberof Internal\n */\nexport default function (\n image: IImage,\n lut: Uint8ClampedArray,\n canvasImageDataData: Uint8ClampedArray\n): void {\n let start = now();\n const pixelData = image.getPixelData();\n\n image.stats.lastGetPixelDataTime = now() - start;\n\n const numPixels = pixelData.length;\n const minPixelValue = image.minPixelValue;\n let canvasImageDataIndex = 3;\n let storedPixelDataIndex = 0;\n\n // NOTE: As of Nov 2014, most javascript engines have lower performance when indexing negative indexes.\n // We have a special code path for this case that improves performance. Thanks to @jpambrun for this enhancement\n\n // Added two paths (Int16Array, Uint16Array) to avoid polymorphic deoptimization in chrome.\n start = now();\n if (pixelData instanceof Int16Array) {\n if (minPixelValue < 0) {\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex] =\n lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Alpha\n canvasImageDataIndex += 4;\n }\n } else {\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex] =\n lut[pixelData[storedPixelDataIndex++]]; // Alpha\n canvasImageDataIndex += 4;\n }\n }\n } else if (pixelData instanceof Uint16Array) {\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex] =\n lut[pixelData[storedPixelDataIndex++]]; // Alpha\n canvasImageDataIndex += 4;\n }\n } else if (minPixelValue < 0) {\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex] =\n lut[pixelData[storedPixelDataIndex++] + -minPixelValue]; // Alpha\n canvasImageDataIndex += 4;\n }\n } else {\n while (storedPixelDataIndex < numPixels) {\n canvasImageDataData[canvasImageDataIndex] =\n lut[pixelData[storedPixelDataIndex++]]; // Alpha\n canvasImageDataIndex += 4;\n }\n }\n\n image.stats.lastStoredPixelDataToCanvasImageDataTime = now() - start;\n}\n","import now from './now';\nimport { IImage } from '../../../../types';\n\n/**\n * This function transforms stored pixel values into a canvas image data buffer\n * by using a LUT.\n *\n * @param {Image} image A Cornerstone Image Object\n * @param {Array} lut Lookup table array\n * @param {Uint8ClampedArray} canvasImageDataData canvasImageData.data buffer filled with white pixels\n *\n * @returns {void}\n * @memberof Internal\n */\nexport default function (\n image: IImage,\n lut: Uint8ClampedArray,\n canvasImageDataData: Uint8ClampedArray\n): void {\n let start = now();\n const pixelData = image.getPixelData();\n\n image.stats.lastGetPixelDataTime = now() - start;\n\n const numPixels = pixelData.length;\n const minPixelValue = image.minPixelValue;\n let canvasImageDataIndex = 0;\n let storedPixelDataIndex = 0;\n let pixelValue;\n\n // NOTE: As of Nov 2014, most javascript engines have lower performance when indexing negative indexes.\n // We have a special code path for this case that improves performance. Thanks to @jpambrun for this enhancement\n\n // Added two paths (Int16Array, Uint16Array) to avoid polymorphic deoptimization in chrome.\n start = now();\n if (pixelData instanceof Int16Array) {\n if (minPixelValue < 0) {\n while (storedPixelDataIndex < numPixels) {\n pixelValue = lut[pixelData[storedPixelDataIndex++] + -minPixelValue];\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = 255; // Alpha\n }\n } else {\n while (storedPixelDataIndex < numPixels) {\n pixelValue = lut[pixelData[storedPixelDataIndex++]];\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = 255; // Alpha\n }\n }\n } else if (pixelData instanceof Uint16Array) {\n while (storedPixelDataIndex < numPixels) {\n pixelValue = lut[pixelData[storedPixelDataIndex++]];\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = 255; // Alpha\n }\n } else if (minPixelValue < 0) {\n while (storedPixelDataIndex < numPixels) {\n pixelValue = lut[pixelData[storedPixelDataIndex++] + -minPixelValue];\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = 255; // Alpha\n }\n } else {\n while (storedPixelDataIndex < numPixels) {\n pixelValue = lut[pixelData[storedPixelDataIndex++]];\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = pixelValue;\n canvasImageDataData[canvasImageDataIndex++] = 255; // Alpha\n }\n }\n\n image.stats.lastStoredPixelDataToCanvasImageDataTime = now() - start;\n}\n","import * as colors from '../colors/index';\nimport now from './now';\nimport type { IImage, CPUFallbackLookupTable } from '../../../../types';\n\n/**\n *\n * @param {Image} image A Cornerstone Image Object\n * @param {Array} grayscaleLut Lookup table array\n * @param {LookupTable|Array} colorLUT Lookup table array\n * @param {Uint8ClampedArray} canvasImageDataData canvasImageData.data buffer filled with white pixels\n *\n * @returns {void}\n * @memberof Internal\n */\nfunction storedPixelDataToCanvasImageDataPseudocolorLUT(\n image: IImage,\n grayscaleLut: Uint8ClampedArray,\n colorLUT: CPUFallbackLookupTable,\n canvasImageDataData: Uint8ClampedArray\n): void {\n let start = now();\n const pixelData = image.getPixelData();\n\n image.stats.lastGetPixelDataTime = now() - start;\n\n const numPixels = pixelData.length;\n const minPixelValue = image.minPixelValue;\n let canvasImageDataIndex = 0;\n let storedPixelDataIndex = 0;\n let grayscale;\n let rgba;\n let clut;\n\n start = now();\n\n if (colorLUT instanceof colors.LookupTable) {\n clut = colorLUT.Table;\n } else {\n clut = colorLUT;\n }\n\n if (minPixelValue < 0) {\n while (storedPixelDataIndex < numPixels) {\n grayscale =\n grayscaleLut[pixelData[storedPixelDataIndex++] + -minPixelValue];\n rgba = clut[grayscale];\n canvasImageDataData[canvasImageDataIndex++] = rgba[0];\n canvasImageDataData[canvasImageDataIndex++] = rgba[1];\n canvasImageDataData[canvasImageDataIndex++] = rgba[2];\n canvasImageDataData[canvasImageDataIndex++] = rgba[3];\n }\n } else {\n while (storedPixelDataIndex < numPixels) {\n grayscale = grayscaleLut[pixelData[storedPixelDataIndex++]];\n rgba = clut[grayscale];\n canvasImageDataData[canvasImageDataIndex++] = rgba[0];\n canvasImageDataData[canvasImageDataIndex++] = rgba[1];\n canvasImageDataData[canvasImageDataIndex++] = rgba[2];\n canvasImageDataData[canvasImageDataIndex++] = rgba[3];\n }\n }\n\n image.stats.lastStoredPixelDataToCanvasImageDataTime = now() - start;\n}\n\nexport default storedPixelDataToCanvasImageDataPseudocolorLUT;\n","import * as colors from '../colors/index';\nimport now from './now';\nimport type { IImage, CPUFallbackLookupTable } from '../../../../types';\n\n/**\n *\n * @param {Image} image A Cornerstone Image Object\n * @param {Array} grayscaleLut Lookup table array\n * @param {LookupTable|Array} colorLUT Lookup table array\n * @param {Uint8ClampedArray} canvasImageDataData canvasImageData.data buffer filled with white pixels\n *\n * @returns {void}\n * @memberof Internal\n */\nfunction storedPixelDataToCanvasImageDataPseudocolorLUTPET(\n image: IImage,\n lutFunction: (value: number) => number,\n colorLUT: CPUFallbackLookupTable,\n canvasImageDataData: Uint8ClampedArray\n): void {\n let start = now();\n const pixelData = image.getPixelData();\n\n image.stats.lastGetPixelDataTime = now() - start;\n\n const numPixels = pixelData.length;\n const minPixelValue = image.minPixelValue;\n let canvasImageDataIndex = 0;\n let storedPixelDataIndex = 0;\n let grayscale;\n let rgba;\n let clut;\n\n start = now();\n\n if (colorLUT instanceof colors.LookupTable) {\n clut = colorLUT.Table;\n } else {\n clut = colorLUT;\n }\n\n if (minPixelValue < 0) {\n while (storedPixelDataIndex < numPixels) {\n grayscale = lutFunction(\n pixelData[storedPixelDataIndex++] + -minPixelValue\n );\n\n rgba = clut[grayscale];\n canvasImageDataData[canvasImageDataIndex++] = rgba[0];\n canvasImageDataData[canvasImageDataIndex++] = rgba[1];\n canvasImageDataData[canvasImageDataIndex++] = rgba[2];\n canvasImageDataData[canvasImageDataIndex++] = rgba[3];\n }\n } else {\n while (storedPixelDataIndex < numPixels) {\n grayscale = lutFunction(pixelData[storedPixelDataIndex++]);\n rgba = clut[grayscale];\n canvasImageDataData[canvasImageDataIndex++] = rgba[0];\n canvasImageDataData[canvasImageDataIndex++] = rgba[1];\n canvasImageDataData[canvasImageDataIndex++] = rgba[2];\n canvasImageDataData[canvasImageDataIndex++] = rgba[3];\n }\n }\n\n image.stats.lastStoredPixelDataToCanvasImageDataTime = now() - start;\n}\n\nexport default storedPixelDataToCanvasImageDataPseudocolorLUTPET;\n","function clamp(value: number, min: number, max: number) {\n return Math.max(min, Math.min(max, value));\n}\n\nexport { clamp as default, clamp };\n","import setToPixelCoordinateSystem from './setToPixelCoordinateSystem';\nimport now from './now';\nimport initializeRenderCanvas from './initializeRenderCanvas';\nimport getLut from './getLut';\nimport saveLastRendered from './saveLastRendered';\nimport doesImageNeedToBeRendered from './doesImageNeedToBeRendered';\nimport storedPixelDataToCanvasImageDataPseudocolorLUT from './storedPixelDataToCanvasImageDataPseudocolorLUT';\nimport storedPixelDataToCanvasImageDataPseudocolorLUTPET from './storedPixelDataToCanvasImageDataPseudocolorLUTPET';\nimport * as colors from '../colors/index';\nimport type { IImage, CPUFallbackEnabledElement } from '../../../../types';\nimport { clamp } from '../../../../utilities';\n\n/**\n * Returns an appropriate canvas to render the Image. If the canvas available in the cache is appropriate\n * it is returned, otherwise adjustments are made. It also sets the color transfer functions.\n *\n * @param {Object} enabledElement The cornerstone enabled element\n * @param {Object} image The image to be rendered\n * @param {Boolean} invalidated Is pixel data valid\n * @returns {HTMLCanvasElement} An appropriate canvas for rendering the image\n * @memberof rendering\n */\nfunction getRenderCanvas(\n enabledElement: CPUFallbackEnabledElement,\n image: IImage,\n invalidated: boolean\n): HTMLCanvasElement {\n if (!enabledElement.renderingTools.renderCanvas) {\n enabledElement.renderingTools.renderCanvas =\n document.createElement('canvas');\n }\n\n const renderCanvas = enabledElement.renderingTools.renderCanvas;\n\n let colormap =\n enabledElement.viewport.colormap || enabledElement.options.colormap;\n\n if (enabledElement.options && enabledElement.options.colormap) {\n console.warn(\n 'enabledElement.options.colormap is deprecated. Use enabledElement.viewport.colormap instead'\n );\n }\n if (colormap && typeof colormap === 'string') {\n colormap = colors.getColormap(colormap);\n }\n\n if (!colormap) {\n throw new Error('renderPseudoColorImage: colormap not found.');\n }\n\n const colormapId = colormap.getId();\n\n if (\n doesImageNeedToBeRendered(enabledElement, image) === false &&\n invalidated !== true &&\n enabledElement.renderingTools.colormapId === colormapId\n ) {\n return renderCanvas;\n }\n\n // If our render canvas does not match the size of this image reset it\n // NOTE: This might be inefficient if we are updating multiple images of different\n // Sizes frequently.\n if (\n renderCanvas.width !== image.width ||\n renderCanvas.height !== image.height\n ) {\n initializeRenderCanvas(enabledElement, image);\n }\n\n // Get the lut to use\n let start = now();\n\n if (\n !enabledElement.renderingTools.colorLUT ||\n invalidated ||\n enabledElement.renderingTools.colormapId !== colormapId\n ) {\n colormap.setNumberOfColors(256);\n enabledElement.renderingTools.colorLUT = colormap.createLookupTable();\n enabledElement.renderingTools.colormapId = colormapId;\n }\n\n const renderCanvasData = enabledElement.renderingTools.renderCanvasData;\n const renderCanvasContext = enabledElement.renderingTools.renderCanvasContext;\n const { viewport } = enabledElement;\n const colorLUT = enabledElement.renderingTools.colorLUT;\n\n if (viewport.modality === 'PT') {\n const { windowWidth, windowCenter } = viewport.voi;\n const minimum = windowCenter - windowWidth / 2;\n const maximum = windowCenter + windowWidth / 2;\n const range = maximum - minimum;\n const collectedMultiplierTerms = 255.0 / range;\n\n let petVOILutFunction;\n\n if (viewport.invert) {\n petVOILutFunction = (value) => {\n return clamp(\n Math.floor(255 - (value - minimum) * collectedMultiplierTerms),\n 0,\n 255\n );\n };\n } else {\n petVOILutFunction = (value) => {\n return clamp(\n Math.floor((value - minimum) * collectedMultiplierTerms),\n 0,\n 255\n );\n };\n }\n\n storedPixelDataToCanvasImageDataPseudocolorLUTPET(\n image,\n petVOILutFunction,\n colorLUT,\n renderCanvasData.data\n );\n } else {\n const lut = getLut(image, enabledElement.viewport, invalidated);\n\n image.stats = image.stats || {};\n image.stats.lastLutGenerateTime = now() - start;\n\n storedPixelDataToCanvasImageDataPseudocolorLUT(\n image,\n lut,\n colorLUT,\n renderCanvasData.data\n );\n }\n\n start = now();\n renderCanvasContext.putImageData(renderCanvasData, 0, 0);\n image.stats.lastPutImageDataTime = now() - start;\n\n return renderCanvas;\n}\n\n/**\n * API function to draw a pseudo-color image to a given enabledElement\n *\n * @param {EnabledElement} enabledElement The Cornerstone Enabled Element to redraw\n * @param {Boolean} invalidated - true if pixel data has been invalidated and cached rendering should not be used\n * @returns {void}\n * @memberof rendering\n */\nexport function renderPseudoColorImage(\n enabledElement: CPUFallbackEnabledElement,\n invalidated: boolean\n): void {\n if (enabledElement === undefined) {\n throw new Error(\n 'drawImage: enabledElement parameter must not be undefined'\n );\n }\n\n const image = enabledElement.image;\n\n if (image === undefined) {\n throw new Error('drawImage: image must be loaded before it can be drawn');\n }\n\n // Get the canvas context and reset the transform\n const context = enabledElement.canvas.getContext('2d');\n\n context.setTransform(1, 0, 0, 1, 0, 0);\n\n // Clear the canvas\n context.fillStyle = 'black';\n context.fillRect(\n 0,\n 0,\n enabledElement.canvas.width,\n enabledElement.canvas.height\n );\n\n // Turn off image smooth/interpolation if pixelReplication is set in the viewport\n context.imageSmoothingEnabled = !enabledElement.viewport.pixelReplication;\n\n // Save the canvas context state and apply the viewport properties\n setToPixelCoordinateSystem(enabledElement, context);\n\n // If no options are set we will retrieve the renderCanvas through the\n // Normal Canvas rendering path\n // TODO: Add WebGL support for pseudocolor pipeline\n const renderCanvas = getRenderCanvas(enabledElement, image, invalidated);\n\n const sx = enabledElement.viewport.displayedArea.tlhc.x - 1;\n const sy = enabledElement.viewport.displayedArea.tlhc.y - 1;\n const width = enabledElement.viewport.displayedArea.brhc.x - sx;\n const height = enabledElement.viewport.displayedArea.brhc.y - sy;\n\n context.drawImage(renderCanvas, sx, sy, width, height, 0, 0, width, height);\n\n enabledElement.renderingTools = saveLastRendered(enabledElement);\n}\n","import now from './rendering/now';\nimport { renderColorImage } from './rendering/renderColorImage';\nimport { renderGrayscaleImage } from './rendering/renderGrayscaleImage';\nimport { renderPseudoColorImage } from './rendering/renderPseudoColorImage';\nimport { CPUFallbackEnabledElement } from '../../../types';\n\n/**\n * Draw an image to a given enabled element synchronously\n *\n * @param enabledElement - An enabled element to draw into\n * @param invalidated - true if pixel data has been invalidated and cached rendering should not be used\n */\nexport default function (\n enabledElement: CPUFallbackEnabledElement,\n invalidated: boolean\n): void {\n const image = enabledElement.image;\n\n // Check if enabledElement can be redrawn\n if (!enabledElement.canvas || !enabledElement.image) {\n return;\n }\n\n // Start measuring the time needed to draw the image.\n const start = now();\n\n image.stats = {\n lastGetPixelDataTime: -1.0,\n lastStoredPixelDataToCanvasImageDataTime: -1.0,\n lastPutImageDataTime: -1.0,\n lastRenderTime: -1.0,\n lastLutGenerateTime: -1.0,\n };\n\n if (image) {\n let render = image.render;\n\n if (!render) {\n if (enabledElement.viewport.colormap) {\n render = renderPseudoColorImage;\n } else if (image.color) {\n render = renderColorImage;\n } else {\n render = renderGrayscaleImage;\n }\n }\n\n render(enabledElement, invalidated);\n }\n\n // Calculate how long it took to draw the image/layers\n const renderTimeInMs = now() - start;\n\n image.stats.lastRenderTime = renderTimeInMs;\n\n enabledElement.invalid = false;\n enabledElement.needsRedraw = false;\n}\n","import calculateTransform from './calculateTransform';\nimport {\n CPUFallbackEnabledElement,\n CPUFallbackTransform,\n} from '../../../../types';\n\nexport default function (\n enabledElement: CPUFallbackEnabledElement\n): CPUFallbackTransform {\n // Todo: for some reason using the cached transfer after the first call\n // does not give correct transform.\n // if (enabledElement.transform) {\n // return enabledElement.transform;\n // }\n\n return calculateTransform(enabledElement);\n}\n","import getTransform from './getTransform';\n\nimport { Point2, CPUFallbackEnabledElement } from '../../../../types';\n\n/**\n * Converts a point in the canvas coordinate system to the pixel coordinate system\n * system. This can be used to reset tools' image coordinates after modifications\n * have been made in canvas space (e.g. moving a tool by a few cm, independent of\n * image resolution).\n *\n * @param element - The Cornerstone element within which the input point lies\n * @param pt - The input point in the canvas coordinate system\n *\n * @returns The transformed point in the pixel coordinate system\n */\nexport default function (\n enabledElement: CPUFallbackEnabledElement,\n pt: Point2\n): Point2 {\n const transform = getTransform(enabledElement);\n\n transform.invert();\n\n return transform.transformPoint(pt);\n}\n","import { CPUFallbackViewport } from '../../../../types';\n\nconst state = {\n viewport: {},\n};\n\n/**\n * Sets new default values for `getDefaultViewport`\n *\n * @param {Object} viewport - Object that sets new default values for getDefaultViewport\n * @returns {undefined}\n */\nexport default function (viewport: CPUFallbackViewport): void {\n state.viewport = viewport || {};\n}\n\nexport { state };\n","/**\n * Check if the supplied parameter is undefined and throws and error\n * @param {any} checkParam the parameter to validate for undefined\n * @param {any} errorMsg the error message to be thrown\n * @returns {void}\n * @memberof internal\n */\nexport function validateParameterUndefined(\n checkParam: any | undefined,\n errorMsg: string\n): void {\n if (checkParam === undefined) {\n throw new Error(errorMsg);\n }\n}\n\n/**\n * Check if the supplied parameter is undefined or null and throws and error\n * @param {any} checkParam the parameter to validate for undefined\n * @param {any} errorMsg the error message to be thrown\n * @returns {void}\n * @memberof internal\n */\nexport function validateParameterUndefinedOrNull(\n checkParam: any | null | undefined,\n errorMsg: string\n): void {\n if (checkParam === undefined || checkParam === null) {\n throw new Error(errorMsg);\n }\n}\n","import { validateParameterUndefinedOrNull } from './validator';\nimport { IImage } from '../../../../types';\n\n/**\n * Check if the angle is rotated\n * @param {Number} rotation the rotation angle\n * @returns {Boolean} true if the angle is rotated; Otherwise, false.\n * @memberof Internal\n */\nfunction isRotated(rotation?: number | null): boolean {\n return !(\n rotation === null ||\n rotation === undefined ||\n rotation === 0 ||\n rotation === 180\n );\n}\n\n/**\n * Retrieves the current image dimensions given an enabled element\n *\n * @param {any} image The Cornerstone image.\n * @param {Number} rotation Optional. The rotation angle of the image.\n * @return {{width:Number, height:Number}} The Image dimensions\n * @memberof Internal\n */\nexport default function (\n image: IImage,\n rotation = null\n): { height: number; width: number } {\n validateParameterUndefinedOrNull(\n image,\n 'getImageSize: parameter image must not be undefined'\n );\n validateParameterUndefinedOrNull(\n image.width,\n 'getImageSize: parameter image must have width'\n );\n validateParameterUndefinedOrNull(\n image.height,\n 'getImageSize: parameter image must have height'\n );\n\n if (isRotated(rotation)) {\n return {\n height: image.width,\n width: image.height,\n };\n }\n\n return {\n width: image.width,\n height: image.height,\n };\n}\n","import { validateParameterUndefinedOrNull } from './validator';\nimport getImageSize from './getImageSize';\nimport { IImage } from '../../../../types';\n\n/**\n * Calculates the horizontal, vertical and minimum scale factor for an image\n @param canvas - The window size where the image is displayed. This can be any HTML element or structure with a width, height fields (e.g. canvas).\n * @param image - The cornerstone image object\n * @param rotation - The rotation angle of the image.\n * @returns The calculated horizontal, vertical and minimum scale factor\n */\nexport default function (\n canvas: HTMLCanvasElement,\n image: IImage,\n rotation: number | null = null\n): {\n verticalScale: number;\n horizontalScale: number;\n scaleFactor: number;\n} {\n validateParameterUndefinedOrNull(\n canvas,\n 'getImageScale: parameter canvas must not be undefined'\n );\n validateParameterUndefinedOrNull(\n image,\n 'getImageScale: parameter image must not be undefined'\n );\n\n const imageSize = getImageSize(image, rotation);\n const rowPixelSpacing = image.rowPixelSpacing || 1;\n const columnPixelSpacing = image.columnPixelSpacing || 1;\n let verticalRatio = 1;\n let horizontalRatio = 1;\n\n if (rowPixelSpacing < columnPixelSpacing) {\n horizontalRatio = columnPixelSpacing / rowPixelSpacing;\n } else {\n // even if they are equal we want to calculate this ratio (the ration might be 0.5)\n verticalRatio = rowPixelSpacing / columnPixelSpacing;\n }\n\n const verticalScale = canvas.height / imageSize.height / verticalRatio;\n const horizontalScale = canvas.width / imageSize.width / horizontalRatio;\n\n // Fit image to window\n return {\n verticalScale,\n horizontalScale,\n scaleFactor: Math.min(horizontalScale, verticalScale),\n };\n}\n","import createViewport from './createViewport';\nimport getImageFitScale from './getImageFitScale';\nimport {\n IImage,\n CPUFallbackColormap,\n CPUFallbackViewport,\n} from '../../../../types';\n\n/**\n * Creates a new viewport object containing default values for the image and canvas\n *\n * @param canvas - A Canvas DOM element\n * @param image - A Cornerstone Image Object\n * @returns viewport - object\n */\nexport default function (\n canvas: HTMLCanvasElement,\n image: IImage,\n modality?: string,\n colormap?: CPUFallbackColormap\n): CPUFallbackViewport {\n if (canvas === undefined) {\n throw new Error(\n 'getDefaultViewport: parameter canvas must not be undefined'\n );\n }\n\n if (image === undefined) {\n return createViewport();\n }\n\n // Fit image to window\n const scale = getImageFitScale(canvas, image, 0).scaleFactor;\n\n let voi;\n\n if (modality === 'PT' && image.isPreScaled) {\n voi = {\n windowWidth: 5,\n windowCenter: 2.5,\n };\n } else if (\n image.windowWidth !== undefined &&\n image.windowCenter !== undefined\n ) {\n voi = {\n windowWidth: Array.isArray(image.windowWidth)\n ? image.windowWidth[0]\n : image.windowWidth,\n windowCenter: Array.isArray(image.windowCenter)\n ? image.windowCenter[0]\n : image.windowCenter,\n };\n }\n\n return {\n scale,\n translation: {\n x: 0,\n y: 0,\n },\n voi,\n invert: image.invert,\n pixelReplication: false,\n rotation: 0,\n hflip: false,\n vflip: false,\n modalityLUT: image.modalityLUT,\n modality,\n voiLUT: image.voiLUT,\n colormap: colormap !== undefined ? colormap : image.colormap,\n displayedArea: {\n tlhc: {\n x: 1,\n y: 1,\n },\n brhc: {\n x: image.columns,\n y: image.rows,\n },\n rowPixelSpacing:\n image.rowPixelSpacing === undefined ? 1 : image.rowPixelSpacing,\n columnPixelSpacing:\n image.columnPixelSpacing === undefined ? 1 : image.columnPixelSpacing,\n presentationSizeMode: 'NONE',\n },\n };\n}\n","import { state } from './setDefaultViewport';\nimport {\n CPUFallbackViewportDisplayedArea,\n CPUFallbackViewport,\n} from '../../../../types';\n\n// eslint-disable-next-line valid-jsdoc\n/**\n * Creates the default displayed area.\n * C.10.4 Displayed Area Module: This Module describes Attributes required to define a Specified Displayed Area space.\n *\n * @returns {tlhc: {x,y}, brhc: {x, y},rowPixelSpacing: Number, columnPixelSpacing: Number, presentationSizeMode: Number} displayedArea object\n * @memberof Internal\n */\nfunction createDefaultDisplayedArea(): CPUFallbackViewportDisplayedArea {\n return {\n // Top Left Hand Corner\n tlhc: {\n x: 1,\n y: 1,\n },\n // Bottom Right Hand Corner\n brhc: {\n x: 1,\n y: 1,\n },\n rowPixelSpacing: 1,\n columnPixelSpacing: 1,\n presentationSizeMode: 'NONE',\n };\n}\n\n/**\n * Creates a new viewport object containing default values\n *\n * @returns {Viewport} viewport object\n * @memberof Internal\n */\nexport default function createViewport(): CPUFallbackViewport {\n const displayedArea = createDefaultDisplayedArea();\n const initialDefaultViewport = {\n scale: 1,\n translation: {\n x: 0,\n y: 0,\n },\n voi: {\n windowWidth: undefined,\n windowCenter: undefined,\n },\n invert: false,\n pixelReplication: false,\n rotation: 0,\n hflip: false,\n vflip: false,\n modalityLUT: undefined,\n voiLUT: undefined,\n colormap: undefined,\n labelmap: false,\n displayedArea,\n };\n\n return Object.assign({}, initialDefaultViewport, state.viewport);\n}\n","import getTransform from './getTransform';\nimport { CPUFallbackEnabledElement, Point2 } from '../../../../types';\n\n/**\n * Converts a point in the pixel coordinate system to the canvas coordinate system\n * system. This can be used to render using canvas context without having the weird\n * side effects that come from scaling and non square pixels\n *\n * @param {HTMLDivElement} element An HTML Element enabled for Cornerstone\n * @param {{x: Number, y: Number}} pt The transformed point in the pixel coordinate system\n *\n * @returns {{x: Number, y: Number}} The input point in the canvas coordinate system\n * @memberof PixelCoordinateSystem\n */\nexport default function (\n enabledElement: CPUFallbackEnabledElement,\n pt: Point2\n): Point2 {\n const transform = getTransform(enabledElement);\n\n return transform.transformPoint(pt);\n}\n","import type { RetrieveStage } from '../../types';\n\n/**\n * This simply retrieves the images sequentially as provided.\n */\nconst singleRetrieveStages: RetrieveStage[] = [\n {\n id: 'initialImages',\n retrieveType: 'single',\n },\n // Shouldn't be necessary, but if the server returns an error for the above\n // configuration, this will ensure the image is still fetched.\n {\n id: 'errorRetrieve',\n },\n];\n\nexport default singleRetrieveStages;\n","import { RetrieveStage, NearbyFrames } from '../../types';\nimport { RequestType, ImageQualityStatus } from '../../enums';\n\n// Defines some nearby frames to replicate to\nconst nearbyFrames: NearbyFrames[] = [\n {\n offset: -1,\n imageQualityStatus: ImageQualityStatus.ADJACENT_REPLICATE,\n },\n {\n offset: +1,\n imageQualityStatus: ImageQualityStatus.ADJACENT_REPLICATE,\n },\n { offset: +2, imageQualityStatus: ImageQualityStatus.FAR_REPLICATE },\n];\n\n/**\n * This configuration is designed to interleave the data requests, using\n * lossy/thumbnail requests when available, but falling back to full retrieve\n * requests in an interleaved manner.\n * The basic ordering is:\n * 1. Retrieve middle image, first, last\n * 2. Retrieve every 4th image, offset 1, lossy if available\n * 3. Retrieve every 4th image, offset 3, lossy if available\n * 4. Retrieve every 4th image, offset 0, full images\n * 5. Retrieve every 4th image, offset 2, full images\n * 6. Retrieve every 4th image, offsets 1 and 3, full images if not already done\n */\nconst interleavedRetrieveConfiguration: RetrieveStage[] = [\n {\n id: 'initialImages',\n // Values between -1 and 1 are relative to size, so 0.5 is middle image\n // and 0 is first image, -1 is last image\n positions: [0.5, 0, -1],\n retrieveType: 'default',\n requestType: RequestType.Thumbnail,\n priority: 5,\n nearbyFrames,\n },\n {\n id: 'quarterThumb',\n decimate: 4,\n offset: 3,\n requestType: RequestType.Thumbnail,\n retrieveType: 'multipleFast',\n priority: 6,\n nearbyFrames,\n },\n {\n id: 'halfThumb',\n decimate: 4,\n offset: 1,\n priority: 7,\n requestType: RequestType.Thumbnail,\n retrieveType: 'multipleFast',\n nearbyFrames,\n },\n {\n id: 'quarterFull',\n decimate: 4,\n offset: 2,\n priority: 8,\n requestType: RequestType.Thumbnail,\n retrieveType: 'multipleFinal',\n },\n {\n id: 'halfFull',\n decimate: 4,\n offset: 0,\n priority: 9,\n requestType: RequestType.Thumbnail,\n retrieveType: 'multipleFinal',\n },\n {\n id: 'threeQuarterFull',\n decimate: 4,\n offset: 1,\n priority: 10,\n requestType: RequestType.Thumbnail,\n retrieveType: 'multipleFinal',\n },\n {\n id: 'finalFull',\n decimate: 4,\n offset: 3,\n priority: 11,\n requestType: RequestType.Thumbnail,\n retrieveType: 'multipleFinal',\n },\n {\n // This goes back to basic retrieve to recover from retrieving against\n // servers returning errors for any of the above requests.\n id: 'errorRetrieve',\n },\n];\nexport default interleavedRetrieveConfiguration;\n","export class PromiseIterator<T> extends Promise<T> {\n iterator?: ProgressiveIterator<T>;\n}\n\nexport type ErrorCallback = (message: string | Error) => void;\n\n/**\n * A progressive iterator is an async iterator that can have data delivered\n * to it, with newer ones replacing older iterations which have not yet been\n * consume. That allows iterating over sets of values and delivering updates,\n * but always getting the most recent instance.\n */\nexport default class ProgressiveIterator<T> {\n public done;\n public name?: string;\n\n private nextValue;\n private waiting;\n private rejectReason;\n\n constructor(name?) {\n this.name = name || 'unknown';\n }\n\n /** Casts a promise, progressive iterator or promise iterator to a\n * progressive iterator, creating one if needed to resolve it.\n */\n public static as(promise) {\n if (promise.iterator) {\n return promise.iterator;\n }\n const iterator = new ProgressiveIterator('as iterator');\n promise.then(\n (v) => {\n try {\n iterator.add(v, true);\n } catch (e) {\n iterator.reject(e as Error);\n }\n },\n (reason) => iterator.reject(reason)\n );\n return iterator;\n }\n\n /** Add a most recent result, indicating if the result is the final one */\n public add(x: T, done = false) {\n this.nextValue = x;\n this.done ||= done;\n if (this.waiting) {\n this.waiting.resolve(x);\n this.waiting = undefined;\n }\n }\n\n public resolve() {\n this.done = true;\n if (this.waiting) {\n this.waiting.resolve(this.nextValue);\n this.waiting = undefined;\n }\n }\n\n /** Reject the fetch. This will prevent further iteration. */\n public reject(reason: Error): void {\n this.rejectReason = reason;\n this.waiting?.reject(reason);\n }\n\n /** Gets the most recent value, without waiting */\n public getRecent(): T {\n if (this.rejectReason) {\n throw this.rejectReason;\n }\n return this.nextValue;\n }\n\n /**\n * Async iteration where the delivered values are the most recently available\n * ones, so not necessarily all values are ever seen.\n */\n public async *[Symbol.asyncIterator]() {\n while (!this.done) {\n if (this.rejectReason) {\n throw this.rejectReason;\n }\n if (this.nextValue !== undefined) {\n // console.log('Yielding on', this.name, this.nextValue);\n yield this.nextValue;\n if (this.done) {\n break;\n }\n }\n if (!this.waiting) {\n this.waiting = {};\n this.waiting.promise = new Promise((resolve, reject) => {\n this.waiting.resolve = resolve;\n this.waiting.reject = reject;\n });\n }\n // console.log('Awaiting on', this.name);\n await this.waiting.promise;\n }\n // console.log('Final yield on', this.name);\n yield this.nextValue;\n }\n\n /** Runs the forEach method on this filter */\n public async forEach(callback, errorCallback) {\n let index = 0;\n // Need to catch basic iteration errors first\n try {\n for await (const value of this) {\n const { done } = this;\n // Separately catch errors in the callback function\n try {\n await callback(value, done, index);\n index++;\n } catch (e) {\n if (!done) {\n console.warn('Caught exception in intermediate value', e);\n continue;\n }\n if (errorCallback) {\n errorCallback(e, done);\n } else {\n throw e;\n }\n }\n }\n } catch (e) {\n if (errorCallback) {\n errorCallback(e, true);\n } else {\n throw e;\n }\n }\n }\n\n /** Calls an async function to generate the results on the iterator */\n public generate(\n processFunction,\n errorCallback?: ErrorCallback\n ): Promise<any> {\n return processFunction(this, this.reject.bind(this)).then(\n () => {\n if (!this.done) {\n // Set it to done\n this.resolve();\n }\n },\n (reason) => {\n this.reject(reason);\n if (errorCallback) {\n errorCallback(reason);\n } else {\n console.warn(\"Couldn't process because\", reason);\n }\n }\n );\n }\n\n async nextPromise(): Promise<T> {\n for await (const i of this) {\n if (i) {\n return i;\n }\n }\n return this.nextValue;\n }\n\n async donePromise(): Promise<T> {\n for await (const i of this) {\n // No-op\n }\n return this.nextValue;\n }\n\n public getNextPromise() {\n const promise = this.nextPromise() as PromiseIterator<T>;\n promise.iterator = this;\n return promise;\n }\n\n public getDonePromise() {\n const promise = this.donePromise() as PromiseIterator<T>;\n promise.iterator = this;\n return promise;\n }\n}\n","/**\n * Return the decimated indices for the given list.\n * @param list - to decimate the indices for\n * @param interleave - the interleave interval for decimation\n * @param offset - where to start the interleave from\n */\nexport default function decimate(\n list: Array<unknown>,\n interleave: number,\n offset = 0\n): number[] {\n const interleaveIndices = [];\n for (let i = offset; i < list.length; i += interleave) {\n interleaveIndices.push(i);\n }\n return interleaveIndices;\n}\n","import {\n IRetrieveConfiguration,\n IImagesLoader,\n IImage,\n RetrieveStage,\n EventTypes,\n ImageLoadListener,\n RetrieveOptions,\n} from '../types';\nimport singleRetrieveStages from './configuration/singleRetrieve';\nimport sequentialRetrieveStages from './configuration/sequentialRetrieve';\nimport interleavedRetrieveStages from './configuration/interleavedRetrieve';\nimport { loadAndCacheImage } from './imageLoader';\nimport { triggerEvent, ProgressiveIterator, decimate } from '../utilities';\nimport imageLoadPoolManager from '../requestPool/imageLoadPoolManager';\nimport { ImageQualityStatus, RequestType, Events } from '../enums';\nimport cache from '../cache';\nimport eventTarget from '../eventTarget';\nimport { fillNearbyFrames } from './fillNearbyFrames';\n\nexport {\n sequentialRetrieveStages,\n interleavedRetrieveStages,\n singleRetrieveStages,\n};\n\ntype StageStatus = {\n stageId: string;\n // startTime is the overall start of loading a given image id\n startTime?: number;\n // stageStartTime is the time to start loading this stage item\n stageStartTime?: number;\n totalImageCount: number;\n imageLoadFailedCount: number;\n imageLoadPendingCount: number;\n};\n\n/**\n * A nearby request is a request that can be fulfilled by copying another image\n */\nexport type NearbyRequest = {\n // The item id to fill\n itemId: string;\n linearId?: string;\n // The new status of the filled image (will only fill if the existing status\n // is less than this one)\n imageQualityStatus: ImageQualityStatus;\n};\n\nexport type ProgressiveRequest = {\n imageId: string;\n stage: RetrieveStage;\n next?: ProgressiveRequest;\n /**\n * Nearby requests are a set of requests for filling nearby images which\n * could be filled by using this image as a copied image to generate the\n * nearby data as a low-resolution alternative image.\n */\n nearbyRequests?: NearbyRequest[];\n};\n\n/**\n * A progressive loader is given some number of images to load,\n * and calls a success or failure callback some number of times in some\n * ordering, possibly calling back multiple times.\n * This allows the progressive loader to be configured for different setups\n * and to return render results for various images.\n *\n * When used by the a stack viewport, the progressive loader can return multiple\n * representations to the viewport, replacing earlier/more lossy versions with better ones.\n *\n * When used by a streaming loader, the progressive loader can change the ordering\n * of the rendering to retrieve high priority images first, and the lower priority\n * images later to provide a complete final rendering.\n *\n * Requests are held in a queue, such that subsequent requests for a given\n * image can be cancelled or ensured to be not initiated until the higher\n * priority image sets have been completed.\n *\n * This loader is also used for the base streamimg image volume, configured with\n * a minimal interleaved load order, combined with filling nearby volume slices\n * on load, resulting in much faster initial apparent display.\n *\n * The loader will load images from existing cached images, cached volumes, and\n * from other nearby images or one or more calls to back end services.\n *\n * @param imageIds - the set of images to load. For a volume, these should be\n * ordered from top to bottom.\n * @param listener - has success and failure callbacks to listen for image deliver events, and may\n * have a getTargetOptions to get information on the retrieve\n * @param retrieveOptions - is a set of retrieve options to use\n */\nexport class ProgressiveRetrieveImages\n implements IImagesLoader, IRetrieveConfiguration\n{\n public static createProgressive = createProgressive;\n\n public static interleavedRetrieveStages = {\n stages: interleavedRetrieveStages,\n };\n\n public static singleRetrieveStages = {\n stages: singleRetrieveStages,\n };\n\n public static sequentialRetrieveStages = {\n stages: sequentialRetrieveStages,\n };\n\n stages: RetrieveStage[];\n retrieveOptions: Record<string, RetrieveOptions>;\n\n constructor(imageRetrieveConfiguration: IRetrieveConfiguration) {\n this.stages = imageRetrieveConfiguration.stages || singleRetrieveStages;\n this.retrieveOptions = imageRetrieveConfiguration.retrieveOptions || {};\n }\n\n public loadImages(imageIds: string[], listener: ImageLoadListener) {\n const instance = new ProgressiveRetrieveImagesInstance(\n this,\n imageIds,\n listener\n );\n return instance.loadImages();\n }\n}\n\nclass ProgressiveRetrieveImagesInstance {\n imageIds: string[];\n listener: ImageLoadListener;\n stages: RetrieveStage[];\n retrieveOptions: Record<string, RetrieveOptions>;\n outstandingRequests = 0;\n\n stageStatusMap = new Map<string, StageStatus>();\n imageQualityStatusMap = new Map<string, ImageQualityStatus>();\n displayedIterator = new ProgressiveIterator<void | IImage>('displayed');\n\n constructor(configuration: IRetrieveConfiguration, imageIds, listener) {\n this.stages = configuration.stages;\n this.retrieveOptions = configuration.retrieveOptions;\n this.imageIds = imageIds;\n this.listener = listener;\n }\n\n public async loadImages() {\n // The actual function is to just setup the interleave and add the\n // requests, with all the actual work being handled by the nested functions\n const interleaved = this.createStageRequests();\n this.outstandingRequests = interleaved.length;\n for (const request of interleaved) {\n this.addRequest(request);\n }\n if (this.outstandingRequests === 0) {\n return Promise.resolve(null);\n }\n\n return this.displayedIterator.getDonePromise();\n }\n\n protected sendRequest(request, options) {\n const { imageId, next } = request;\n const errorCallback = (reason, done) => {\n this.listener.errorCallback(imageId, complete || !next, reason);\n if (done) {\n this.updateStageStatus(request.stage, reason);\n }\n };\n const loadedPromise = (options.loader || loadAndCacheImage)(\n imageId,\n options\n );\n const uncompressedIterator = ProgressiveIterator.as(loadedPromise);\n let complete = false;\n\n uncompressedIterator\n .forEach(async (image, done) => {\n const oldStatus = this.imageQualityStatusMap.get(imageId);\n if (!image) {\n console.warn('No image retrieved', imageId);\n return;\n }\n const { imageQualityStatus } = image;\n complete ||= imageQualityStatus === ImageQualityStatus.FULL_RESOLUTION;\n if (oldStatus !== undefined && oldStatus > imageQualityStatus) {\n // We already have a better status, so don't update it\n this.updateStageStatus(request.stage, null, true);\n return;\n }\n\n this.listener.successCallback(imageId, image);\n this.imageQualityStatusMap.set(imageId, imageQualityStatus);\n this.displayedIterator.add(image);\n if (done) {\n this.updateStageStatus(request.stage);\n }\n fillNearbyFrames(\n this.listener,\n this.imageQualityStatusMap,\n request,\n image,\n options\n );\n }, errorCallback)\n .finally(() => {\n if (!complete && next) {\n if (cache.getImageLoadObject(imageId)) {\n cache.removeImageLoadObject(imageId);\n }\n this.addRequest(next, options.streamingData);\n } else {\n if (!complete) {\n this.listener.errorCallback(imageId, true, \"Couldn't decode\");\n }\n this.outstandingRequests--;\n for (let skip = next; skip; skip = skip.next) {\n this.updateStageStatus(skip.stage, null, true);\n }\n }\n if (this.outstandingRequests <= 0) {\n this.displayedIterator.resolve();\n }\n });\n const doneLoad = uncompressedIterator.getDonePromise();\n // Errors already handled above in the callback\n return doneLoad.catch((e) => null);\n }\n\n /** Adds a rquest to the image load pool manager */\n protected addRequest(request, streamingData = {}) {\n const { imageId, stage } = request;\n const baseOptions = this.listener.getLoaderImageOptions(imageId);\n if (!baseOptions) {\n // Image no longer of interest\n return;\n }\n const { retrieveType = 'default' } = stage;\n const { retrieveOptions: keyedRetrieveOptions } = this;\n const retrieveOptions =\n keyedRetrieveOptions[retrieveType] || keyedRetrieveOptions.default;\n const options = {\n ...baseOptions,\n retrieveType,\n retrieveOptions,\n streamingData,\n };\n const priority = stage.priority ?? -5;\n const requestType = stage.requestType || RequestType.Interaction;\n const additionalDetails = { imageId };\n\n imageLoadPoolManager.addRequest(\n this.sendRequest.bind(this, request, options),\n requestType,\n additionalDetails,\n priority\n );\n }\n\n protected updateStageStatus(stage, failure?, skipped = false) {\n const { id } = stage;\n const stageStatus = this.stageStatusMap.get(id);\n if (!stageStatus) {\n return;\n }\n stageStatus.imageLoadPendingCount--;\n if (failure) {\n stageStatus.imageLoadFailedCount++;\n } else if (!skipped) {\n stageStatus.totalImageCount++;\n }\n if (!skipped && !stageStatus.stageStartTime) {\n stageStatus.stageStartTime = Date.now();\n }\n if (!stageStatus.imageLoadPendingCount) {\n const {\n imageLoadFailedCount: numberOfFailures,\n totalImageCount: numberOfImages,\n stageStartTime = Date.now(),\n startTime,\n } = stageStatus;\n const detail: EventTypes.ImageLoadStageEventDetail = {\n stageId: id,\n numberOfFailures,\n numberOfImages,\n stageDurationInMS: stageStartTime ? Date.now() - stageStartTime : null,\n startDurationInMS: Date.now() - startTime,\n };\n triggerEvent(eventTarget, Events.IMAGE_RETRIEVAL_STAGE, detail);\n this.stageStatusMap.delete(id);\n }\n }\n\n /** Interleaves the values according to the stages definition */\n protected createStageRequests() {\n const interleaved = new Array<ProgressiveRequest>();\n // Maps image id to the LAST progressive request - to allow tail append\n const imageRequests = new Map<string, ProgressiveRequest>();\n\n const addStageInstance = (stage, position) => {\n const index =\n position < 0\n ? this.imageIds.length + position\n : position < 1\n ? Math.floor((this.imageIds.length - 1) * position)\n : position;\n const imageId = this.imageIds[index];\n if (!imageId) {\n throw new Error(`No value found to add to requests at ${position}`);\n }\n const request: ProgressiveRequest = {\n imageId,\n stage,\n nearbyRequests: this.findNearbyRequests(index, stage),\n };\n this.addStageStatus(stage);\n const existingRequest = imageRequests.get(imageId);\n if (existingRequest) {\n existingRequest.next = request;\n } else {\n interleaved.push(request);\n }\n imageRequests.set(imageId, request);\n };\n\n for (const stage of this.stages) {\n const indices =\n stage.positions ||\n decimate(this.imageIds, stage.decimate || 1, stage.offset ?? 0);\n indices.forEach((index) => addStageInstance(stage, index));\n }\n return interleaved;\n }\n\n /**\n * Finds nearby requests to fulfill to show the merge information earlier.\n * @param index - to use as the base value\n * @param imageIds - set of image ids to request\n * @param stage - to find information from\n * @returns Array of nearby frames to fill when the main stage is done\n */\n protected findNearbyRequests(index: number, stage): NearbyRequest[] {\n const nearby = new Array<NearbyRequest>();\n if (!stage.nearbyFrames) {\n return nearby;\n }\n for (const nearbyItem of stage.nearbyFrames) {\n const nearbyIndex = index + nearbyItem.offset;\n if (nearbyIndex < 0 || nearbyIndex >= this.imageIds.length) {\n continue;\n }\n nearby.push({\n itemId: this.imageIds[nearbyIndex],\n imageQualityStatus: nearbyItem.imageQualityStatus,\n });\n }\n\n return nearby;\n }\n\n protected addStageStatus(stage) {\n const { id } = stage;\n const stageStatus = this.stageStatusMap.get(id) || {\n stageId: id,\n startTime: Date.now(),\n stageStartTime: null,\n totalImageCount: 0,\n imageLoadFailedCount: 0,\n imageLoadPendingCount: 0,\n };\n stageStatus.imageLoadPendingCount++;\n this.stageStatusMap.set(id, stageStatus);\n return stageStatus;\n }\n}\n\nexport function createProgressive(configuration: IRetrieveConfiguration) {\n return new ProgressiveRetrieveImages(configuration);\n}\n\nexport default ProgressiveRetrieveImages;\n","import type { RetrieveStage } from '../../types';\n\n/**\n * This simply retrieves the images sequentially as provided.\n */\nconst sequentialRetrieveStages: RetrieveStage[] = [\n {\n id: 'lossySequential',\n retrieveType: 'singleFast',\n },\n {\n id: 'finalSequential',\n retrieveType: 'singleFinal',\n },\n];\n\nexport default sequentialRetrieveStages;\n","import { ImageLoadListener } from '../types';\nimport { ImageQualityStatus } from '../enums';\n\n/** Actually fills the nearby frames from the given frame */\nexport function fillNearbyFrames(\n listener: ImageLoadListener,\n imageQualityStatusMap: Map<string, ImageQualityStatus>,\n request,\n image,\n options\n) {\n if (!request?.nearbyRequests?.length) {\n return;\n }\n\n const {\n arrayBuffer,\n offset: srcOffset,\n type,\n length: frameLength,\n } = options.targetBuffer;\n if (!arrayBuffer || srcOffset === undefined || !type) {\n return;\n }\n const scalarData = new Float32Array(arrayBuffer);\n const bytesPerPixel = scalarData.byteLength / scalarData.length;\n const offset = options.targetBuffer.offset / bytesPerPixel; // in bytes\n\n // since set is based on the underlying type,\n // we need to divide the offset bytes by the byte type\n const src = scalarData.slice(offset, offset + frameLength);\n\n for (const nearbyItem of request.nearbyRequests) {\n try {\n const { itemId: targetId, imageQualityStatus } = nearbyItem;\n const targetStatus = imageQualityStatusMap.get(targetId);\n if (targetStatus !== undefined && targetStatus >= imageQualityStatus) {\n continue;\n }\n const targetOptions = listener.getLoaderImageOptions(targetId);\n const { offset: targetOffset } = targetOptions.targetBuffer as any;\n scalarData.set(src, targetOffset / bytesPerPixel);\n const nearbyImage = {\n ...image,\n imageQualityStatus,\n };\n listener.successCallback(targetId, nearbyImage);\n imageQualityStatusMap.set(targetId, imageQualityStatus);\n } catch (e) {\n console.log(\"Couldn't fill nearby item \", nearbyItem.itemId, e);\n }\n }\n}\n","import vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction';\nimport { VOIRange } from '../types';\n\nexport default function createLinearRGBTransferFunction(\n voiRange: VOIRange\n): vtkColorTransferFunction {\n const cfun = vtkColorTransferFunction.newInstance();\n let lower = 0;\n let upper = 1024;\n if (\n voiRange &&\n voiRange.lower !== undefined &&\n voiRange.upper !== undefined\n ) {\n lower = voiRange.lower;\n upper = voiRange.upper;\n }\n cfun.addRGBPoint(lower, 0.0, 0.0, 0.0);\n cfun.addRGBPoint(upper, 1.0, 1.0, 1.0);\n\n return cfun;\n}\n","import vtkDataArray from '@kitware/vtk.js/Common/Core/DataArray';\nimport type { vtkImageData as vtkImageDataType } from '@kitware/vtk.js/Common/DataModel/ImageData';\nimport vtkImageData from '@kitware/vtk.js/Common/DataModel/ImageData';\nimport vtkCamera from '@kitware/vtk.js/Rendering/Core/Camera';\nimport vtkColorTransferFunction from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction';\nimport vtkColorMaps from '@kitware/vtk.js/Rendering/Core/ColorTransferFunction/ColorMaps';\nimport vtkImageMapper from '@kitware/vtk.js/Rendering/Core/ImageMapper';\nimport vtkImageSlice from '@kitware/vtk.js/Rendering/Core/ImageSlice';\nimport { mat4, vec2, vec3 } from 'gl-matrix';\nimport eventTarget from '../eventTarget';\nimport * as metaData from '../metaData';\nimport cloneDeep from 'lodash.clonedeep';\nimport type {\n ActorEntry,\n CPUFallbackColormapData,\n CPUFallbackEnabledElement,\n CPUIImageData,\n ColormapPublic,\n EventTypes,\n FlipDirection,\n ICamera,\n IImage,\n IImageCalibration,\n IImageData,\n IImagesLoader,\n IStackInput,\n IStackViewport,\n ImageLoadListener,\n Mat3,\n PTScaling,\n Point2,\n Point3,\n Scaling,\n StackViewportProperties,\n VOIRange,\n ViewReference,\n ViewPresentation,\n VolumeActor,\n} from '../types';\nimport {\n ViewReferenceSpecifier,\n ReferenceCompatibleOptions,\n ViewportInput,\n} from '../types/IViewport';\nimport {\n actorIsA,\n colormap as colormapUtils,\n createSigmoidRGBTransferFunction,\n imageIdToURI,\n imageRetrieveMetadataProvider,\n invertRgbTransferFunction,\n isEqual,\n isImageActor,\n triggerEvent,\n updateVTKImageDataWithCornerstoneImage,\n windowLevel as windowLevelUtil,\n} from '../utilities';\nimport Viewport from './Viewport';\nimport { getColormap } from './helpers/cpuFallback/colors/index';\nimport drawImageSync from './helpers/cpuFallback/drawImageSync';\n\nimport {\n Events,\n InterpolationType,\n MetadataModules,\n RequestType,\n VOILUTFunctionType,\n ViewportStatus,\n} from '../enums';\nimport { ImageLoaderOptions, loadAndCacheImage } from '../loaders/imageLoader';\nimport imageLoadPoolManager from '../requestPool/imageLoadPoolManager';\nimport calculateTransform from './helpers/cpuFallback/rendering/calculateTransform';\nimport canvasToPixel from './helpers/cpuFallback/rendering/canvasToPixel';\nimport getDefaultViewport from './helpers/cpuFallback/rendering/getDefaultViewport';\nimport pixelToCanvas from './helpers/cpuFallback/rendering/pixelToCanvas';\nimport resize from './helpers/cpuFallback/rendering/resize';\n\nimport cache from '../cache';\nimport { getConfiguration, getShouldUseCPURendering } from '../init';\nimport { createProgressive } from '../loaders/ProgressiveRetrieveImages';\nimport {\n ImagePixelModule,\n ImagePlaneModule,\n PixelDataTypedArray,\n} from '../types';\nimport {\n StackViewportNewStackEventDetail,\n StackViewportScrollEventDetail,\n VoiModifiedEventDetail,\n} from '../types/EventTypes';\nimport { ImageActor } from '../types/IActor';\nimport createLinearRGBTransferFunction from '../utilities/createLinearRGBTransferFunction';\nimport {\n getTransferFunctionNodes,\n setTransferFunctionNodes,\n} from '../utilities/transferFunctionUtils';\nimport correctShift from './helpers/cpuFallback/rendering/correctShift';\nimport resetCamera from './helpers/cpuFallback/rendering/resetCamera';\nimport { Transform } from './helpers/cpuFallback/rendering/transform';\nimport { findMatchingColormap } from '../utilities/colormap';\n\nconst EPSILON = 1; // Slice Thickness\n\ninterface ImageDataMetaData {\n bitsAllocated: number;\n numComps: number;\n origin: Point3;\n direction: Mat3;\n dimensions: Point3;\n spacing: Point3;\n numVoxels: number;\n imagePlaneModule: ImagePlaneModule;\n imagePixelModule: ImagePixelModule;\n}\n// TODO This needs to be exposed as its published to consumers.\ntype CalibrationEvent = {\n rowScale?: number;\n columnScale?: number;\n scale: number;\n calibration: IImageCalibration;\n};\n\ntype SetVOIOptions = {\n suppressEvents?: boolean;\n forceRecreateLUTFunction?: boolean;\n voiUpdatedWithSetProperties?: boolean;\n};\n\n/**\n * An object representing a single stack viewport, which is a camera\n * looking into an internal viewport, and an associated target output `canvas`.\n *\n * StackViewports can be rendered using both GPU and a fallback CPU is the GPU\n * is not available (or low performance). Read more about StackViewports in\n * the documentation section of this website.\n */\nclass StackViewport extends Viewport implements IStackViewport, IImagesLoader {\n private imageIds: Array<string>;\n // current imageIdIndex that is rendered in the viewport\n private currentImageIdIndex: number;\n // the imageIdIndex that is targeted to be loaded with scrolling but has not initiated loading yet\n private targetImageIdIndex: number;\n // setTimeout if the image is debounced to be loaded\n private debouncedTimeout: number;\n /**\n * The progressive retrieval configuration used for this viewport.\n */\n protected imagesLoader: IImagesLoader = this;\n\n // Viewport Properties\n private globalDefaultProperties: StackViewportProperties;\n private perImageIdDefaultProperties = new Map<\n string,\n StackViewportProperties\n >();\n\n private colormap: ColormapPublic | CPUFallbackColormapData;\n private voiRange: VOIRange;\n private voiUpdatedWithSetProperties = false;\n private VOILUTFunction: VOILUTFunctionType;\n //\n private invert = false;\n // The initial invert of the image loaded as opposed to the invert status of the viewport itself (see above).\n private initialInvert = false;\n private initialTransferFunctionNodes = null;\n private interpolationType: InterpolationType;\n\n // Helpers\n private _imageData: vtkImageDataType;\n private cameraFocalPointOnRender: Point3; // we use focalPoint since flip manipulates the position and makes it useless to track\n private stackInvalidated = false; // if true -> new actor is forced to be created for the stack\n private _publishCalibratedEvent = false;\n private _calibrationEvent: CalibrationEvent;\n private _cpuFallbackEnabledElement?: CPUFallbackEnabledElement;\n // CPU fallback\n private useCPURendering: boolean;\n // Since WebGL natively supports 8 bit int and Float32, we should check if\n // extra configuration flags has been set to use native data type\n // which would save a lot of memory and speed up rendering but it is not\n // yet widely supported in all hardwares. This feature can be turned on\n // by setting useNorm16Texture or preferSizeOverAccuracy in the configuration\n private useNativeDataType = false;\n private cpuImagePixelData: PixelDataTypedArray;\n private cpuRenderingInvalidated: boolean;\n private csImage: IImage;\n\n // TODO: These should not be here and will be nuked\n public modality: string; // this is needed for tools\n public scaling: Scaling;\n\n // Camera properties\n private initialViewUp: Point3;\n\n // this flag is used to check\n // if the viewport used the same actor/mapper to render the image\n // or because of the new image inconsistency, a new actor/mapper was created\n public stackActorReInitialized: boolean;\n\n /**\n * Constructor for the StackViewport class\n * @param props - ViewportInput\n */\n constructor(props: ViewportInput) {\n super(props);\n this.scaling = {};\n this.modality = null;\n this.useCPURendering = getShouldUseCPURendering();\n this.useNativeDataType = this._shouldUseNativeDataType();\n this._configureRenderingPipeline();\n\n this.useCPURendering\n ? this._resetCPUFallbackElement()\n : this._resetGPUViewport();\n\n this.imageIds = [];\n this.currentImageIdIndex = 0;\n this.targetImageIdIndex = 0;\n this.cameraFocalPointOnRender = [0, 0, 0];\n this.resetCamera();\n\n this.initializeElementDisabledHandler();\n }\n\n public setUseCPURendering(value: boolean) {\n this.useCPURendering = value;\n this._configureRenderingPipeline(value);\n }\n\n static get useCustomRenderingPipeline(): boolean {\n return getShouldUseCPURendering();\n }\n\n public updateRenderingPipeline = () => {\n this._configureRenderingPipeline();\n };\n\n private _configureRenderingPipeline(value?: boolean) {\n this.useNativeDataType = this._shouldUseNativeDataType();\n this.useCPURendering = value ?? getShouldUseCPURendering();\n\n for (const [funcName, functions] of Object.entries(\n this.renderingPipelineFunctions\n )) {\n this[funcName] = this.useCPURendering ? functions.cpu : functions.gpu;\n }\n\n this.useCPURendering\n ? this._resetCPUFallbackElement()\n : this._resetGPUViewport();\n }\n\n private _resetCPUFallbackElement() {\n this._cpuFallbackEnabledElement = {\n canvas: this.canvas,\n renderingTools: {},\n transform: new Transform(),\n viewport: { rotation: 0 },\n };\n }\n\n private _resetGPUViewport() {\n const renderer = this.getRenderer();\n const camera = vtkCamera.newInstance();\n renderer.setActiveCamera(camera);\n\n const viewPlaneNormal = <Point3>[0, 0, -1];\n this.initialViewUp = <Point3>[0, -1, 0];\n\n camera.setDirectionOfProjection(\n -viewPlaneNormal[0],\n -viewPlaneNormal[1],\n -viewPlaneNormal[2]\n );\n camera.setViewUp(...this.initialViewUp);\n camera.setParallelProjection(true);\n camera.setThicknessFromFocalPoint(0.1);\n camera.setFreezeFocalPoint(true);\n }\n\n /**\n * Returns the image and its properties that is being shown inside the\n * stack viewport. It returns, the image dimensions, image direction,\n * image scalar data, vtkImageData object, metadata, and scaling (e.g., PET suvbw)\n *\n * @returns IImageData: dimensions, direction, scalarData, vtkImageData, metadata, scaling\n */\n public getImageData: () => IImageData | CPUIImageData;\n\n /**\n * If the user has selected CPU rendering, return the CPU camera, otherwise\n * return the default camera\n * @returns The camera object.\n */\n public getCamera: () => ICamera;\n\n /**\n * Set the camera based on the provided camera object.\n * @param cameraInterface - The camera interface that will be used to\n * render the scene.\n */\n public setCamera: (\n cameraInterface: ICamera,\n storeAsInitialCamera?: boolean\n ) => void;\n\n public getRotation: () => number;\n\n /**\n * It sets the colormap to the default colormap.\n */\n public unsetColormap: () => void;\n\n /**\n * Centers Pan and resets the zoom for stack viewport.\n */\n public resetCamera: (resetPan?: boolean, resetZoom?: boolean) => boolean;\n\n /**\n * canvasToWorld Returns the world coordinates of the given `canvasPos`\n * projected onto the plane defined by the `Viewport`'s camera.\n *\n * @param canvasPos - The position in canvas coordinates.\n * @returns The corresponding world coordinates.\n * @public\n */\n public canvasToWorld: (canvasPos: Point2) => Point3;\n\n /**\n * Returns the canvas coordinates of the given `worldPos`\n * projected onto the `Viewport`'s `canvas`.\n *\n * @param worldPos - The position in world coordinates.\n * @returns The corresponding canvas coordinates.\n * @public\n */\n public worldToCanvas: (worldPos: Point3) => Point2;\n\n /**\n * If the renderer is CPU based, throw an error. Otherwise, returns the `vtkRenderer` responsible for rendering the `Viewport`.\n *\n * @returns The `vtkRenderer` for the `Viewport`.\n */\n public getRenderer: () => any;\n\n /**\n * If the renderer is CPU based, throw an error. Otherwise, return the default\n * actor which is the first actor in the renderer.\n * @returns An actor entry.\n */\n public getDefaultActor: () => ActorEntry;\n\n /**\n * If the renderer is CPU based, throw an error. Otherwise, return the actors in the viewport\n * @returns An array of ActorEntry objects.\n */\n public getActors: () => Array<ActorEntry>;\n /**\n * If the renderer is CPU based, throw an error. Otherwise, it returns the actor entry for the given actor UID.\n * @param actorUID - The unique ID of the actor you want to get.\n * @returns An ActorEntry object.\n */\n public getActor: (actorUID: string) => ActorEntry;\n\n /**\n * If the renderer is CPU-based, throw an error; otherwise, set the\n * actors in the viewport.\n * @param actors - An array of ActorEntry objects.\n */\n public setActors: (actors: Array<ActorEntry>) => void;\n\n /**\n * If the renderer is CPU based, throw an error. Otherwise, add a list of actors to the viewport\n * @param actors - An array of ActorEntry objects.\n */\n public addActors: (actors: Array<ActorEntry>) => void;\n\n /**\n * If the renderer is CPU based, throw an error. Otherwise, add the\n * actor to the viewport\n * @param actorEntry - The ActorEntry object that was created by the\n * user.\n */\n public addActor: (actorEntry: ActorEntry) => void;\n\n /**\n * It throws an error if the renderer is CPU based. Otherwise, it removes the actors from the viewport.\n */\n public removeAllActors: () => void;\n\n private setVOI: (voiRange: VOIRange, options?: SetVOIOptions) => void;\n\n protected setInterpolationType: (\n interpolationType: InterpolationType\n ) => void;\n\n private setInvertColor: (invert: boolean) => void;\n\n /**\n * Sets the colormap for the current viewport.\n * @param colormap - The colormap data to use.\n */\n private setColormap: (\n colormap: CPUFallbackColormapData | ColormapPublic\n ) => void;\n\n private initializeElementDisabledHandler() {\n eventTarget.addEventListener(\n Events.ELEMENT_DISABLED,\n function elementDisabledHandler() {\n clearTimeout(this.debouncedTimeout);\n\n eventTarget.removeEventListener(\n Events.ELEMENT_DISABLED,\n elementDisabledHandler\n );\n }\n );\n }\n\n /**\n * Resizes the viewport - only used in CPU fallback for StackViewport. The\n * GPU resizing happens inside the RenderingEngine.\n */\n public resize = (): void => {\n // GPU viewport resize is handled inside the RenderingEngine\n if (this.useCPURendering) {\n this._resizeCPU();\n }\n };\n\n private _resizeCPU = (): void => {\n if (this._cpuFallbackEnabledElement.viewport) {\n resize(this._cpuFallbackEnabledElement);\n }\n };\n\n private getImageDataGPU(): IImageData | undefined {\n const defaultActor = this.getDefaultActor();\n\n if (!defaultActor) {\n return;\n }\n\n if (!isImageActor(defaultActor)) {\n return;\n }\n\n const { actor } = defaultActor;\n const vtkImageData = actor.getMapper().getInputData();\n return {\n dimensions: vtkImageData.getDimensions(),\n spacing: vtkImageData.getSpacing(),\n origin: vtkImageData.getOrigin(),\n direction: vtkImageData.getDirection(),\n scalarData: vtkImageData.getPointData().getScalars().getData(),\n imageData: actor.getMapper().getInputData(),\n metadata: { Modality: this.modality },\n scaling: this.scaling,\n hasPixelSpacing: this.hasPixelSpacing,\n calibration: { ...this.csImage.calibration, ...this.calibration },\n preScale: {\n ...this.csImage.preScale,\n },\n };\n }\n\n private getImageDataCPU(): CPUIImageData | undefined {\n const { metadata } = this._cpuFallbackEnabledElement;\n\n const spacing = metadata.spacing;\n\n return {\n dimensions: metadata.dimensions,\n spacing,\n origin: metadata.origin,\n direction: metadata.direction,\n metadata: { Modality: this.modality },\n scaling: this.scaling,\n imageData: {\n getDirection: () => metadata.direction,\n getDimensions: () => metadata.dimensions,\n getScalarData: () => this.cpuImagePixelData,\n getSpacing: () => spacing,\n worldToIndex: (point: Point3) => {\n const canvasPoint = this.worldToCanvasCPU(point);\n const pixelCoord = canvasToPixel(\n this._cpuFallbackEnabledElement,\n canvasPoint\n );\n return [pixelCoord[0], pixelCoord[1], 0];\n },\n indexToWorld: (point: Point3, destPoint?: Point3) => {\n const canvasPoint = pixelToCanvas(this._cpuFallbackEnabledElement, [\n point[0],\n point[1],\n ]);\n return this.canvasToWorldCPU(canvasPoint, destPoint);\n },\n },\n scalarData: this.cpuImagePixelData,\n hasPixelSpacing: this.hasPixelSpacing,\n calibration: { ...this.csImage.calibration, ...this.calibration },\n preScale: {\n ...this.csImage.preScale,\n },\n };\n }\n\n /**\n * Returns the frame of reference UID, if the image doesn't have imagePlaneModule\n * metadata, it returns undefined, otherwise, frameOfReferenceUID is returned.\n * @returns frameOfReferenceUID : string representing frame of reference id\n */\n public getFrameOfReferenceUID = (sliceIndex?: number): string =>\n this.getImagePlaneReferenceData(sliceIndex)?.FrameOfReferenceUID;\n\n /**\n * Returns the raw/loaded image being shown inside the stack viewport.\n */\n public getCornerstoneImage = (): IImage => this.csImage;\n\n /**\n * Creates imageMapper based on the provided vtkImageData and also creates\n * the imageSliceActor and connects it to the imageMapper.\n * For color stack images, it sets the independent components to be false which\n * is required in vtk.\n *\n * @param imageData - vtkImageData for the viewport\n * @returns actor vtkActor\n */\n private createActorMapper = (imageData) => {\n const mapper = vtkImageMapper.newInstance();\n mapper.setInputData(imageData);\n\n const actor = vtkImageSlice.newInstance();\n\n actor.setMapper(mapper);\n\n const { preferSizeOverAccuracy } = getConfiguration().rendering;\n\n if (preferSizeOverAccuracy) {\n mapper.setPreferSizeOverAccuracy(true);\n }\n\n if (imageData.getPointData().getNumberOfComponents() > 1) {\n actor.getProperty().setIndependentComponents(false);\n }\n\n return actor;\n };\n\n /** Gets the number of slices */\n public getNumberOfSlices = (): number => {\n return this.imageIds.length;\n };\n\n /**\n * Retrieves the metadata from the metadata provider, and optionally adds the\n * scaling to the viewport if modality is PET and scaling metadata is provided.\n *\n * @param imageId - a string representing the imageId for the image\n * @returns imagePlaneModule and imagePixelModule containing the metadata for the image\n */\n private buildMetadata(image: IImage) {\n const imageId = image.imageId;\n\n const {\n pixelRepresentation,\n bitsAllocated,\n bitsStored,\n highBit,\n photometricInterpretation,\n samplesPerPixel,\n } = metaData.get('imagePixelModule', imageId);\n\n // we can grab the window center and width from the image object\n // since it the loader already has used the metadata provider\n // to get the values\n const { windowWidth, windowCenter, voiLUTFunction } = image;\n\n const { modality } = metaData.get('generalSeriesModule', imageId);\n const imageIdScalingFactor = metaData.get('scalingModule', imageId);\n const calibration = metaData.get(MetadataModules.CALIBRATION, imageId);\n\n if (modality === 'PT' && imageIdScalingFactor) {\n this._addScalingToViewport(imageIdScalingFactor);\n }\n\n this.modality = modality;\n const voiLUTFunctionEnum = this._getValidVOILUTFunction(voiLUTFunction);\n this.VOILUTFunction = voiLUTFunctionEnum;\n\n this.calibration = calibration;\n let imagePlaneModule = this._getImagePlaneModule(imageId);\n\n if (!this.useCPURendering) {\n imagePlaneModule = this.calibrateIfNecessary(imageId, imagePlaneModule);\n }\n\n return {\n imagePlaneModule,\n imagePixelModule: {\n bitsAllocated,\n bitsStored,\n samplesPerPixel,\n highBit,\n photometricInterpretation,\n pixelRepresentation,\n windowWidth,\n windowCenter,\n modality,\n voiLUTFunction: voiLUTFunctionEnum,\n },\n };\n }\n\n /**\n * Checks the metadataProviders to see if a calibratedPixelSpacing is\n * given. If so, checks the actor to see if it needs to be modified, and\n * set the flags for imageCalibration if a new actor needs to be created\n *\n * @param imageId - imageId\n * @param imagePlaneModule - imagePlaneModule\n * @returns modified imagePlaneModule with the calibrated spacings\n */\n private calibrateIfNecessary(imageId, imagePlaneModule) {\n const calibration = metaData.get('calibratedPixelSpacing', imageId);\n const isUpdated = this.calibration !== calibration;\n const { scale } = calibration || {};\n this.hasPixelSpacing = scale > 0 || imagePlaneModule.rowPixelSpacing > 0;\n imagePlaneModule.calibration = calibration;\n\n if (!isUpdated) {\n return imagePlaneModule;\n }\n\n this.calibration = calibration;\n this._publishCalibratedEvent = true;\n this._calibrationEvent = <CalibrationEvent>{\n scale,\n calibration,\n };\n\n return imagePlaneModule;\n }\n\n /**\n * Update the default properties of the viewport and add properties by imageId if specified\n * @param ViewportProperties - The properties to set\n * @param imageId If given, we set the default properties only for this image index, if not\n * the default properties will be set for all imageIds\n */\n public setDefaultProperties(\n ViewportProperties: StackViewportProperties,\n imageId?: string\n ): void {\n if (imageId == null) {\n this.globalDefaultProperties = ViewportProperties;\n } else {\n this.perImageIdDefaultProperties.set(imageId, ViewportProperties);\n\n //If the viewport is the same imageIdI, we need to update the viewport\n if (this.getCurrentImageId() === imageId) {\n this.setProperties(ViewportProperties);\n }\n }\n }\n\n /**\n * Remove the global default properties of the viewport or remove default properties for an imageId if specified\n * @param imageId If given, we remove the default properties only for this imageID, if not\n * the global default properties will be removed\n */\n public clearDefaultProperties(imageId?: string): void {\n if (imageId == null) {\n this.globalDefaultProperties = {};\n this.resetProperties();\n } else {\n this.perImageIdDefaultProperties.delete(imageId);\n this.resetToDefaultProperties();\n }\n }\n\n /**\n Configures the properties of the viewport.\n This method allows customization of the viewport by setting attributes like\n VOI (Value of Interest), color inversion, interpolation type, and image rotation.\n If setProperties is called for the first time, the provided properties will\n become the default settings for all images in the stack in case the resetPropertiese need to be called\n @param properties - An object containing the properties to be set.\n @param properties.colormap - Specifies the colormap for the viewport.\n @param properties.voiRange - Defines the lower and upper Value of Interest (VOI) to be applied.\n @param properties.VOILUTFunction - Function to handle the application of a lookup table (LUT) to the VOI.\n @param properties.invert - A boolean value to toggle color inversion (true: inverted, false: not inverted).\n @param properties.interpolationType - Determines the interpolation method to be used (1: linear, 0: nearest-neighbor).\n @param properties.rotation - Specifies the image rotation angle in degrees.\n @param suppressEvents - A boolean value to control event suppression. If true, the related events will not be triggered. Default is false.\n */\n public setProperties(\n {\n colormap,\n voiRange,\n VOILUTFunction,\n invert,\n interpolationType,\n rotation,\n }: StackViewportProperties = {},\n suppressEvents = false\n ): void {\n this.viewportStatus = this.csImage\n ? ViewportStatus.PRE_RENDER\n : ViewportStatus.LOADING;\n\n if (this.globalDefaultProperties == null) {\n this.setDefaultProperties({\n colormap,\n voiRange,\n VOILUTFunction,\n invert,\n interpolationType,\n rotation,\n });\n }\n\n if (typeof colormap !== 'undefined') {\n this.setColormap(colormap);\n }\n // if voi is not applied for the first time, run the setVOI function\n // which will apply the default voi based on the range\n if (typeof voiRange !== 'undefined') {\n const voiUpdatedWithSetProperties = true;\n this.setVOI(voiRange, { suppressEvents, voiUpdatedWithSetProperties });\n }\n\n if (typeof VOILUTFunction !== 'undefined') {\n this.setVOILUTFunction(VOILUTFunction, suppressEvents);\n }\n\n if (typeof invert !== 'undefined') {\n this.setInvertColor(invert);\n }\n\n if (typeof interpolationType !== 'undefined') {\n this.setInterpolationType(interpolationType);\n }\n\n if (typeof rotation !== 'undefined') {\n // TODO: check with VTK about rounding errors here.\n if (this.getRotation() !== rotation) {\n this.setRotation(rotation);\n }\n }\n }\n\n /**\n * Retrieve the viewport default properties\n * @param imageId If given, we retrieve the default properties of an image index if it exists\n * If not given,we return the global properties of the viewport\n * @returns viewport properties including voi, invert, interpolation type, rotation, flip\n */\n public getDefaultProperties = (imageId?: string): StackViewportProperties => {\n let imageProperties;\n if (imageId !== undefined) {\n imageProperties = this.perImageIdDefaultProperties.get(imageId);\n }\n\n if (imageProperties !== undefined) {\n return imageProperties;\n }\n\n return {\n ...this.globalDefaultProperties,\n rotation: this.getRotation(),\n };\n };\n\n /**\n * Retrieve the viewport properties\n * @returns viewport properties including voi, invert, interpolation type, rotation, flip\n */\n public getProperties = (): StackViewportProperties => {\n const {\n colormap,\n voiRange,\n VOILUTFunction,\n interpolationType,\n invert,\n voiUpdatedWithSetProperties,\n } = this;\n const rotation = this.getRotation();\n\n return {\n colormap,\n voiRange,\n VOILUTFunction,\n interpolationType,\n invert,\n rotation,\n isComputedVOI: !voiUpdatedWithSetProperties,\n };\n };\n\n /**\n * Reset the viewport properties to the default values\n */\n public resetProperties(): void {\n this.cpuRenderingInvalidated = true;\n this.voiUpdatedWithSetProperties = false;\n this.viewportStatus = ViewportStatus.PRE_RENDER;\n\n this.fillWithBackgroundColor();\n\n if (this.useCPURendering) {\n this._cpuFallbackEnabledElement.renderingTools = {};\n }\n\n this._resetProperties();\n\n this.render();\n }\n\n private _resetProperties() {\n let voiRange;\n if (this._isCurrentImagePTPrescaled()) {\n // if not set via setProperties; if it is a PT image and is already prescaled,\n // use the default range for PT\n voiRange = this._getDefaultPTPrescaledVOIRange();\n } else {\n // if not set via setProperties; if it is not a PT image or is not prescaled,\n // use the voiRange for the current image from its metadata if found\n // otherwise, use the cached voiRange\n voiRange = this._getVOIRangeForCurrentImage();\n }\n\n this.setVOI(voiRange);\n\n this.setInvertColor(this.initialInvert);\n\n this.setInterpolationType(InterpolationType.LINEAR);\n\n if (this.getRotation() !== 0) {\n this.setRotation(0);\n }\n\n const transferFunction = this.getTransferFunction();\n setTransferFunctionNodes(\n transferFunction,\n this.initialTransferFunctionNodes\n );\n\n const nodes = getTransferFunctionNodes(transferFunction);\n\n const RGBPoints = nodes.reduce((acc, node) => {\n acc.push(node[0], node[1], node[2], node[3]);\n return acc;\n }, []);\n\n const defaultActor = this.getDefaultActor();\n const matchedColormap = findMatchingColormap(RGBPoints, defaultActor.actor);\n\n this.setColormap(matchedColormap);\n }\n\n public resetToDefaultProperties(): void {\n this.cpuRenderingInvalidated = true;\n this.viewportStatus = ViewportStatus.PRE_RENDER;\n\n this.fillWithBackgroundColor();\n\n if (this.useCPURendering) {\n this._cpuFallbackEnabledElement.renderingTools = {};\n }\n\n const currentImageId = this.getCurrentImageId();\n const properties =\n this.perImageIdDefaultProperties.get(currentImageId) ||\n this.globalDefaultProperties;\n\n if (properties.colormap?.name) {\n this.setColormap(properties.colormap);\n }\n\n let voiRange;\n if (properties.voiRange == undefined) {\n // if not set via setProperties; if it is not a PT image or is not prescaled,\n // use the voiRange for the current image from its metadata if found\n // otherwise, use the cached voiRange\n voiRange = this._getVOIRangeForCurrentImage();\n } else {\n voiRange = properties.voiRange;\n }\n\n this.setVOI(voiRange);\n\n if (this.getRotation() !== 0) {\n this.setRotation(0);\n }\n this.setInterpolationType(InterpolationType.LINEAR);\n this.setInvertColor(false);\n\n this.render();\n }\n\n private _setPropertiesFromCache(): void {\n const { interpolationType, invert } = this;\n\n let voiRange;\n if (this.voiUpdatedWithSetProperties) {\n // use the cached voiRange if the voiRange is locked (if the user has\n // manually set the voi with tools or setProperties api)\n voiRange = this.voiRange;\n } else if (this._isCurrentImagePTPrescaled()) {\n // if not set via setProperties; if it is a PT image and is already prescaled,\n // use the default range for PT\n voiRange = this._getDefaultPTPrescaledVOIRange();\n } else {\n // if not set via setProperties; if it is not a PT image or is not prescaled,\n // use the voiRange for the current image from its metadata if found\n // otherwise, use the cached voiRange\n voiRange = this._getVOIRangeForCurrentImage() ?? this.voiRange;\n }\n\n this.setVOI(voiRange);\n this.setInterpolationType(interpolationType);\n this.setInvertColor(invert);\n }\n\n private getCameraCPU(): Partial<ICamera> {\n const { metadata, viewport } = this._cpuFallbackEnabledElement;\n const { direction } = metadata;\n\n // focalPoint and position of CPU camera is just a placeholder since\n // tools need focalPoint to be defined\n const viewPlaneNormal = direction.slice(6, 9).map((x) => -x) as Point3;\n let viewUp = direction.slice(3, 6).map((x) => -x) as Point3;\n\n // If camera is rotated, we need the correct rotated viewUp along the\n // viewPlaneNormal vector\n if (viewport.rotation) {\n const rotationMatrix = mat4.fromRotation(\n mat4.create(),\n (viewport.rotation * Math.PI) / 180,\n viewPlaneNormal\n );\n viewUp = vec3.transformMat4(\n vec3.create(),\n viewUp,\n rotationMatrix\n ) as Point3;\n }\n\n const canvasCenter: Point2 = [\n this.element.clientWidth / 2,\n this.element.clientHeight / 2,\n ];\n\n // Focal point is the center of the canvas in world coordinate by construction\n const canvasCenterWorld = this.canvasToWorld(canvasCenter);\n\n // parallel scale is half of the viewport height in the world units (mm)\n\n const topLeftWorld = this.canvasToWorld([0, 0]);\n const bottomLeftWorld = this.canvasToWorld([0, this.element.clientHeight]);\n\n const parallelScale = vec3.distance(topLeftWorld, bottomLeftWorld) / 2;\n\n return {\n parallelProjection: true,\n focalPoint: canvasCenterWorld,\n position: [0, 0, 0],\n parallelScale,\n scale: viewport.scale,\n viewPlaneNormal: [\n viewPlaneNormal[0],\n viewPlaneNormal[1],\n viewPlaneNormal[2],\n ],\n viewUp: [viewUp[0], viewUp[1], viewUp[2]],\n flipHorizontal: this.flipHorizontal,\n flipVertical: this.flipVertical,\n };\n }\n\n private setCameraCPU(cameraInterface: ICamera): void {\n const { viewport, image } = this._cpuFallbackEnabledElement;\n const previousCamera = this.getCameraCPU();\n\n const { focalPoint, parallelScale, scale, flipHorizontal, flipVertical } =\n cameraInterface;\n\n const { clientHeight } = this.element;\n\n if (focalPoint) {\n const focalPointCanvas = this.worldToCanvasCPU(focalPoint);\n const focalPointPixel = canvasToPixel(\n this._cpuFallbackEnabledElement,\n focalPointCanvas\n );\n\n const prevFocalPointCanvas = this.worldToCanvasCPU(\n previousCamera.focalPoint\n );\n const prevFocalPointPixel = canvasToPixel(\n this._cpuFallbackEnabledElement,\n prevFocalPointCanvas\n );\n\n const deltaPixel = vec2.create();\n vec2.subtract(\n deltaPixel,\n vec2.fromValues(focalPointPixel[0], focalPointPixel[1]),\n vec2.fromValues(prevFocalPointPixel[0], prevFocalPointPixel[1])\n );\n\n const shift = correctShift(\n { x: deltaPixel[0], y: deltaPixel[1] },\n viewport\n );\n\n viewport.translation.x -= shift.x;\n viewport.translation.y -= shift.y;\n }\n\n if (parallelScale) {\n // We need to convert he parallelScale which has a physical meaning to\n // camera scale factor (since CPU works with scale). Since parallelScale represents\n // half of the height of the viewport in the world unit (mm), we can use that\n // to compute the scale factor which is the ratio of the viewport height in pixels\n // to the current rendered image height.\n const { rowPixelSpacing } = image;\n const scale = (clientHeight * rowPixelSpacing * 0.5) / parallelScale;\n\n viewport.scale = scale;\n viewport.parallelScale = parallelScale;\n }\n\n if (scale) {\n const { rowPixelSpacing } = image;\n viewport.scale = scale;\n viewport.parallelScale = (clientHeight * rowPixelSpacing * 0.5) / scale;\n }\n\n if (flipHorizontal !== undefined || flipVertical !== undefined) {\n this.setFlipCPU({ flipHorizontal, flipVertical });\n }\n\n // re-calculate the transforms\n this._cpuFallbackEnabledElement.transform = calculateTransform(\n this._cpuFallbackEnabledElement\n );\n\n const eventDetail: EventTypes.CameraModifiedEventDetail = {\n previousCamera,\n camera: this.getCamera(),\n element: this.element,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n rotation: this.getRotation(),\n };\n\n triggerEvent(this.element, Events.CAMERA_MODIFIED, eventDetail);\n }\n\n private getPanCPU(): Point2 {\n const { viewport } = this._cpuFallbackEnabledElement;\n\n return [viewport.translation.x, viewport.translation.y];\n }\n\n private setPanCPU(pan: Point2): void {\n const camera = this.getCameraCPU();\n\n this.setCameraCPU({\n ...camera,\n focalPoint: [...pan.map((p) => -p), 0] as Point3,\n });\n }\n\n private getZoomCPU(): number {\n const { viewport } = this._cpuFallbackEnabledElement;\n\n return viewport.scale;\n }\n\n private setZoomCPU(zoom: number): void {\n const camera = this.getCameraCPU();\n\n this.setCameraCPU({ ...camera, scale: zoom });\n }\n\n private setFlipCPU({ flipHorizontal, flipVertical }: FlipDirection): void {\n const { viewport } = this._cpuFallbackEnabledElement;\n\n if (flipHorizontal !== undefined) {\n viewport.hflip = flipHorizontal;\n this.flipHorizontal = viewport.hflip;\n }\n\n if (flipVertical !== undefined) {\n viewport.vflip = flipVertical;\n this.flipVertical = viewport.vflip;\n }\n }\n\n private getRotationCPU = (): number => {\n const { viewport } = this._cpuFallbackEnabledElement;\n return viewport.rotation;\n };\n\n /**\n * Gets the rotation resulting from the value set in setRotation AND taking into\n * account any flips that occurred subsequently.\n *\n * @returns the rotation resulting from the value set in setRotation AND taking into\n * account any flips that occurred subsequently.\n */\n private getRotationGPU = (): number => {\n const {\n viewUp: currentViewUp,\n viewPlaneNormal,\n flipVertical,\n } = this.getCamera();\n\n // The initial view up vector without any rotation, but incorporating vertical flip.\n const initialViewUp = flipVertical\n ? vec3.negate(vec3.create(), this.initialViewUp)\n : this.initialViewUp;\n\n // The angle between the initial and current view up vectors.\n // TODO: check with VTK about rounding errors here.\n const initialToCurrentViewUpAngle =\n (vec3.angle(initialViewUp, currentViewUp) * 180) / Math.PI;\n\n // Now determine if initialToCurrentViewUpAngle is positive or negative by comparing\n // the direction of the initial/current view up cross product with the current\n // viewPlaneNormal.\n\n const initialToCurrentViewUpCross = vec3.cross(\n vec3.create(),\n initialViewUp,\n currentViewUp\n );\n\n // The sign of the dot product of the start/end view up cross product and\n // the viewPlaneNormal indicates a positive or negative rotation respectively.\n const normalDot = vec3.dot(initialToCurrentViewUpCross, viewPlaneNormal);\n\n return normalDot >= 0\n ? initialToCurrentViewUpAngle\n : (360 - initialToCurrentViewUpAngle) % 360;\n };\n\n protected setRotation = (rotation: number) => {\n const previousCamera = this.getCamera();\n\n this.useCPURendering\n ? this.setRotationCPU(rotation)\n : this.setRotationGPU(rotation);\n\n if (this._suppressCameraModifiedEvents) {\n return;\n }\n\n // New camera after rotation\n const camera = this.getCamera();\n\n const eventDetail: EventTypes.CameraModifiedEventDetail = {\n previousCamera,\n camera,\n element: this.element,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n rotation,\n };\n\n triggerEvent(this.element, Events.CAMERA_MODIFIED, eventDetail);\n };\n\n private setVOILUTFunction(\n voiLUTFunction: VOILUTFunctionType,\n suppressEvents?: boolean\n ): void {\n if (this.useCPURendering) {\n throw new Error('VOI LUT function is not supported in CPU rendering');\n }\n\n // make sure the VOI LUT function is valid in the VOILUTFunctionType which is enum\n const newVOILUTFunction = this._getValidVOILUTFunction(voiLUTFunction);\n\n let forceRecreateLUTFunction = false;\n if (this.VOILUTFunction !== newVOILUTFunction) {\n forceRecreateLUTFunction = true;\n }\n\n this.VOILUTFunction = newVOILUTFunction;\n\n const { voiRange } = this.getProperties();\n this.setVOI(voiRange, { suppressEvents, forceRecreateLUTFunction });\n }\n\n private setRotationCPU(rotation: number): void {\n const { viewport } = this._cpuFallbackEnabledElement;\n viewport.rotation = rotation;\n }\n\n /**\n * The rotation that is being set is intended to be around the currently\n * display center of the image. However, the roll operation does it around\n * another point which can result in the image disappearing. The set/get\n * pan values move the center of rotation to the center of the image as\n * currently actually displayed.\n */\n private setRotationGPU(rotation: number): void {\n const panFit = this.getPan(this.fitToCanvasCamera);\n const pan = this.getPan();\n const panSub = vec2.sub([0, 0], panFit, pan) as Point2;\n this.setPan(panSub, false);\n const { flipVertical } = this.getCamera();\n\n // Moving back to zero rotation, for new scrolled slice rotation is 0 after camera reset\n const initialViewUp = flipVertical\n ? vec3.negate(vec3.create(), this.initialViewUp)\n : this.initialViewUp;\n\n this.setCameraNoEvent({\n viewUp: initialViewUp as Point3,\n });\n\n // rotating camera to the new value\n this.getVtkActiveCamera().roll(-rotation);\n const afterPan = this.getPan();\n const afterPanFit = this.getPan(this.fitToCanvasCamera);\n const newCenter = vec2.sub([0, 0], afterPan, afterPanFit);\n const newOffset = vec2.add([0, 0], panFit, newCenter) as Point2;\n this.setPan(newOffset, false);\n }\n\n private setInterpolationTypeGPU(interpolationType: InterpolationType): void {\n const defaultActor = this.getDefaultActor();\n\n if (!defaultActor) {\n return;\n }\n\n if (!isImageActor(defaultActor)) {\n return;\n }\n const { actor } = defaultActor;\n const volumeProperty = actor.getProperty();\n\n // @ts-ignore\n volumeProperty.setInterpolationType(interpolationType);\n\n this.interpolationType = interpolationType;\n }\n\n private setInterpolationTypeCPU(interpolationType: InterpolationType): void {\n const { viewport } = this._cpuFallbackEnabledElement;\n\n viewport.pixelReplication =\n interpolationType === InterpolationType.LINEAR ? false : true;\n\n this.interpolationType = interpolationType;\n }\n\n private setInvertColorCPU(invert: boolean): void {\n const { viewport } = this._cpuFallbackEnabledElement;\n\n if (!viewport) {\n return;\n }\n\n viewport.invert = invert;\n this.invert = invert;\n }\n\n private setInvertColorGPU(invert: boolean): void {\n const defaultActor = this.getDefaultActor();\n\n if (!defaultActor) {\n return;\n }\n\n if (!isImageActor(defaultActor)) {\n return;\n }\n\n // Duplicated logic to make sure typescript stops complaining\n // about vtkActor not having the correct property\n if (actorIsA(defaultActor, 'vtkVolume')) {\n const volumeActor = defaultActor.actor as VolumeActor;\n const tfunc = volumeActor.getProperty().getRGBTransferFunction(0);\n\n if ((!this.invert && invert) || (this.invert && !invert)) {\n invertRgbTransferFunction(tfunc);\n }\n this.invert = invert;\n } else if (actorIsA(defaultActor, 'vtkImageSlice')) {\n const imageSliceActor = defaultActor.actor as vtkImageSlice;\n const tfunc = imageSliceActor.getProperty().getRGBTransferFunction(0);\n\n if ((!this.invert && invert) || (this.invert && !invert)) {\n invertRgbTransferFunction(tfunc);\n }\n\n this.invert = invert;\n }\n }\n\n private setVOICPU(voiRange: VOIRange, options: SetVOIOptions = {}): void {\n const { suppressEvents = false } = options;\n // TODO: Account for VOILUTFunction\n const { viewport, image } = this._cpuFallbackEnabledElement;\n\n if (!viewport || !image) {\n return;\n }\n\n if (typeof voiRange === 'undefined') {\n const { windowWidth: ww, windowCenter: wc } = image;\n\n const wwToUse = Array.isArray(ww) ? ww[0] : ww;\n const wcToUse = Array.isArray(wc) ? wc[0] : wc;\n viewport.voi = {\n windowWidth: wwToUse,\n windowCenter: wcToUse,\n };\n\n const { lower, upper } = windowLevelUtil.toLowHighRange(wwToUse, wcToUse);\n voiRange = { lower, upper };\n } else {\n const { lower, upper } = voiRange;\n const { windowCenter, windowWidth } = windowLevelUtil.toWindowLevel(\n lower,\n upper\n );\n\n if (!viewport.voi) {\n viewport.voi = {\n windowWidth: 0,\n windowCenter: 0,\n };\n }\n\n viewport.voi.windowWidth = windowWidth;\n viewport.voi.windowCenter = windowCenter;\n }\n\n this.voiRange = voiRange;\n const eventDetail: VoiModifiedEventDetail = {\n viewportId: this.id,\n range: voiRange,\n };\n\n if (!suppressEvents) {\n triggerEvent(this.element, Events.VOI_MODIFIED, eventDetail);\n }\n }\n\n private getTransferFunction() {\n const defaultActor = this.getDefaultActor();\n\n if (!defaultActor) {\n return;\n }\n\n if (!isImageActor(defaultActor)) {\n return;\n }\n const imageActor = defaultActor.actor as ImageActor;\n\n return imageActor.getProperty().getRGBTransferFunction(0);\n }\n\n private setVOIGPU(voiRange: VOIRange, options: SetVOIOptions = {}): void {\n const {\n suppressEvents = false,\n forceRecreateLUTFunction = false,\n voiUpdatedWithSetProperties = false,\n } = options;\n\n if (\n voiRange &&\n this.voiRange &&\n this.voiRange.lower === voiRange.lower &&\n this.voiRange.upper === voiRange.upper &&\n !forceRecreateLUTFunction &&\n !this.stackInvalidated\n ) {\n return;\n }\n\n const defaultActor = this.getDefaultActor();\n if (!defaultActor) {\n return;\n }\n\n if (!isImageActor(defaultActor)) {\n return;\n }\n const imageActor = defaultActor.actor as ImageActor;\n\n let voiRangeToUse = voiRange;\n\n if (typeof voiRangeToUse === 'undefined') {\n const imageData = imageActor.getMapper().getInputData();\n const range = imageData.getPointData().getScalars().getRange();\n const maxVoiRange = { lower: range[0], upper: range[1] };\n voiRangeToUse = maxVoiRange;\n }\n\n // scaling logic here\n // https://github.com/Kitware/vtk-js/blob/master/Sources/Rendering/OpenGL/ImageMapper/index.js#L540-L549\n imageActor.getProperty().setUseLookupTableScalarRange(true);\n\n let transferFunction = imageActor.getProperty().getRGBTransferFunction(0);\n\n const isSigmoidTFun =\n this.VOILUTFunction === VOILUTFunctionType.SAMPLED_SIGMOID;\n\n // use the old cfun if it exists for linear case\n if (isSigmoidTFun || !transferFunction || forceRecreateLUTFunction) {\n const transferFunctionCreator = isSigmoidTFun\n ? createSigmoidRGBTransferFunction\n : createLinearRGBTransferFunction;\n\n transferFunction = transferFunctionCreator(voiRangeToUse);\n\n if (this.invert) {\n invertRgbTransferFunction(transferFunction);\n }\n\n imageActor.getProperty().setRGBTransferFunction(0, transferFunction);\n this.initialTransferFunctionNodes =\n getTransferFunctionNodes(transferFunction);\n }\n\n if (!isSigmoidTFun) {\n // @ts-ignore vtk type error\n transferFunction.setRange(voiRangeToUse.lower, voiRangeToUse.upper);\n }\n\n this.voiRange = voiRangeToUse;\n\n // if voiRange is set by setProperties we need to lock it if it is not locked already\n if (!this.voiUpdatedWithSetProperties) {\n this.voiUpdatedWithSetProperties = voiUpdatedWithSetProperties;\n }\n\n if (suppressEvents) {\n return;\n }\n\n const eventDetail: VoiModifiedEventDetail = {\n viewportId: this.id,\n range: voiRangeToUse,\n VOILUTFunction: this.VOILUTFunction,\n };\n\n triggerEvent(this.element, Events.VOI_MODIFIED, eventDetail);\n }\n\n /**\n * Adds scaling parameters to the viewport to be used along all slices\n *\n * @param imageIdScalingFactor - suvbw, suvlbm, suvbsa\n */\n private _addScalingToViewport(imageIdScalingFactor) {\n if (this.scaling.PT) {\n return;\n }\n\n // if don't exist\n // These ratios are constant across all frames, so only need one.\n const { suvbw, suvlbm, suvbsa } = imageIdScalingFactor;\n\n const ptScaling = <PTScaling>{};\n\n if (suvlbm) {\n ptScaling.suvbwToSuvlbm = suvlbm / suvbw;\n }\n\n if (suvbsa) {\n ptScaling.suvbwToSuvbsa = suvbsa / suvbw;\n }\n\n this.scaling.PT = ptScaling;\n }\n\n /**\n * Calculates number of components based on the dicom metadata\n *\n * @param photometricInterpretation - string dicom tag\n * @returns number representing number of components\n */\n private _getNumCompsFromPhotometricInterpretation(\n photometricInterpretation: string\n ): number {\n // TODO: this function will need to have more logic later\n // see http://dicom.nema.org/medical/Dicom/current/output/chtml/part03/sect_C.7.6.3.html#sect_C.7.6.3.1.2\n let numberOfComponents = 1;\n if (\n photometricInterpretation === 'RGB' ||\n photometricInterpretation.indexOf('YBR') !== -1 ||\n photometricInterpretation === 'PALETTE COLOR'\n ) {\n numberOfComponents = 3;\n }\n\n return numberOfComponents;\n }\n\n /**\n * Calculates image metadata based on the image object. It calculates normal\n * axis for the images, and output image metadata\n *\n * @param image - stack image containing cornerstone image\n * @returns image metadata: bitsAllocated, number of components, origin,\n * direction, dimensions, spacing, number of voxels.\n */\n public getImageDataMetadata(image: IImage): ImageDataMetaData {\n // TODO: Creating a single image should probably not require a metadata provider.\n // We should define the minimum we need to display an image and it should live on\n // the Image object itself. Additional stuff (e.g. pixel spacing, direction, origin, etc)\n // should be optional and used if provided through a metadata provider.\n\n const { imagePlaneModule, imagePixelModule } = this.buildMetadata(image);\n\n let rowCosines, columnCosines;\n\n rowCosines = <Point3>imagePlaneModule.rowCosines;\n columnCosines = <Point3>imagePlaneModule.columnCosines;\n\n // if null or undefined\n if (rowCosines == null || columnCosines == null) {\n rowCosines = <Point3>[1, 0, 0];\n columnCosines = <Point3>[0, 1, 0];\n }\n\n const rowCosineVec = vec3.fromValues(\n rowCosines[0],\n rowCosines[1],\n rowCosines[2]\n );\n const colCosineVec = vec3.fromValues(\n columnCosines[0],\n columnCosines[1],\n columnCosines[2]\n );\n const scanAxisNormal = vec3.create();\n vec3.cross(scanAxisNormal, rowCosineVec, colCosineVec);\n\n let origin = imagePlaneModule.imagePositionPatient;\n // if null or undefined\n if (origin == null) {\n origin = [0, 0, 0];\n }\n\n const xSpacing =\n imagePlaneModule.columnPixelSpacing || image.columnPixelSpacing;\n const ySpacing = imagePlaneModule.rowPixelSpacing || image.rowPixelSpacing;\n const xVoxels = image.columns;\n const yVoxels = image.rows;\n\n // Note: For rendering purposes, we use the EPSILON as the z spacing.\n // This is purely for internal implementation logic since we are still\n // technically rendering 3D objects with vtk.js, but the abstracted intention\n // of the stack viewport is to render 2D images\n const zSpacing = EPSILON;\n const zVoxels = 1;\n\n const numComps =\n image.numComps ||\n this._getNumCompsFromPhotometricInterpretation(\n imagePixelModule.photometricInterpretation\n );\n\n return {\n bitsAllocated: imagePixelModule.bitsAllocated,\n numComps,\n origin,\n direction: [...rowCosineVec, ...colCosineVec, ...scanAxisNormal] as Mat3,\n dimensions: [xVoxels, yVoxels, zVoxels],\n spacing: [xSpacing, ySpacing, zSpacing],\n numVoxels: xVoxels * yVoxels * zVoxels,\n imagePlaneModule,\n imagePixelModule,\n };\n }\n\n /**\n * Gets the view reference data for a given image slice. This uses the\n * image plane module to read a default focal point/normal, and also returns\n * the referenced image id and the frame of reference uid.\n */\n public getImagePlaneReferenceData(\n sliceIndex = this.getCurrentImageIdIndex()\n ): ViewReference {\n const imageId = this.imageIds[sliceIndex];\n if (!imageId) {\n return;\n }\n const imagePlaneModule = metaData.get(MetadataModules.IMAGE_PLANE, imageId);\n if (!imagePlaneModule) {\n return;\n }\n const { imagePositionPatient, frameOfReferenceUID: FrameOfReferenceUID } =\n imagePlaneModule;\n let { rowCosines, columnCosines } = imagePlaneModule;\n // Values are null, not undefined, so need to assign instead of defaulting\n rowCosines ||= [1, 0, 0];\n columnCosines ||= [0, 1, 0];\n const viewPlaneNormal = <Point3>(\n vec3.cross([0, 0, 0], columnCosines, rowCosines)\n );\n return {\n FrameOfReferenceUID,\n viewPlaneNormal,\n cameraFocalPoint: <Point3>imagePositionPatient,\n referencedImageId: imageId,\n sliceIndex,\n };\n }\n\n /**\n * Converts the image direction to camera viewUp and viewplaneNormal\n *\n * @param imageDataDirection - vtkImageData direction\n * @returns viewplane normal and viewUp of the camera\n */\n private _getCameraOrientation(imageDataDirection: Mat3): {\n viewPlaneNormal: Point3;\n viewUp: Point3;\n } {\n const viewPlaneNormal = imageDataDirection.slice(6, 9).map((x) => -x);\n\n const viewUp = imageDataDirection.slice(3, 6).map((x) => -x);\n return {\n viewPlaneNormal: [\n viewPlaneNormal[0],\n viewPlaneNormal[1],\n viewPlaneNormal[2],\n ],\n viewUp: [viewUp[0], viewUp[1], viewUp[2]],\n };\n }\n\n createVTKImageData({\n origin,\n direction,\n dimensions,\n spacing,\n numComps,\n pixelArray,\n }) {\n const values = new pixelArray.constructor(pixelArray.length);\n\n // Todo: I guess nothing should be done for use16bit?\n const scalarArray = vtkDataArray.newInstance({\n name: 'Pixels',\n numberOfComponents: numComps,\n values: values,\n });\n\n const imageData = vtkImageData.newInstance();\n\n imageData.setDimensions(dimensions);\n imageData.setSpacing(spacing);\n imageData.setDirection(direction);\n imageData.setOrigin(origin);\n imageData.getPointData().setScalars(scalarArray);\n\n return imageData;\n }\n /**\n * Creates vtkImagedata based on the image object, it creates\n * empty scalar data for the image based on the metadata\n * tags (e.g., bitsAllocated)\n *\n * @param image - cornerstone Image object\n */\n private _createVTKImageData({\n origin,\n direction,\n dimensions,\n spacing,\n numComps,\n pixelArray,\n }): void {\n this._imageData = this.createVTKImageData({\n origin,\n direction,\n dimensions,\n spacing,\n numComps,\n pixelArray,\n });\n }\n\n /**\n * Sets the imageIds to be visualized inside the stack viewport. It accepts\n * list of imageIds, the index of the first imageId to be viewed. It is a\n * asynchronous function that returns a promise resolving to imageId being\n * displayed in the stack viewport.\n *\n *\n * @param imageIds - list of strings, that represents list of image Ids\n * @param currentImageIdIndex - number representing the index of the initial image to be displayed\n */\n public async setStack(\n imageIds: Array<string>,\n currentImageIdIndex = 0\n ): Promise<string> {\n this._throwIfDestroyed();\n\n this.imageIds = imageIds;\n this.currentImageIdIndex = currentImageIdIndex;\n this.targetImageIdIndex = currentImageIdIndex;\n const imageRetrieveConfiguration = metaData.get(\n imageRetrieveMetadataProvider.IMAGE_RETRIEVE_CONFIGURATION,\n imageIds[currentImageIdIndex],\n 'stack'\n );\n\n this.imagesLoader = imageRetrieveConfiguration\n ? (imageRetrieveConfiguration.create || createProgressive)(\n imageRetrieveConfiguration\n )\n : this;\n\n // reset the stack\n this.stackInvalidated = true;\n this.flipVertical = false;\n this.flipHorizontal = false;\n this.voiRange = null;\n this.interpolationType = InterpolationType.LINEAR;\n this.invert = false;\n this.viewportStatus = ViewportStatus.LOADING;\n\n this.fillWithBackgroundColor();\n\n if (this.useCPURendering) {\n this._cpuFallbackEnabledElement.renderingTools = {};\n delete this._cpuFallbackEnabledElement.viewport.colormap;\n }\n\n const imageId = await this._setImageIdIndex(currentImageIdIndex);\n\n const eventDetail: StackViewportNewStackEventDetail = {\n imageIds,\n viewportId: this.id,\n element: this.element,\n currentImageIdIndex: currentImageIdIndex,\n };\n\n triggerEvent(eventTarget, Events.STACK_VIEWPORT_NEW_STACK, eventDetail);\n\n return imageId;\n }\n\n /**\n * Throws an error if you are using a destroyed instance of the stack viewport\n */\n private _throwIfDestroyed() {\n if (this.isDisabled) {\n throw new Error(\n 'The stack viewport has been destroyed and is no longer usable. Renderings will not be performed. If you ' +\n 'are using the same viewportId and have re-enabled the viewport, you need to grab the new viewport instance ' +\n 'using renderingEngine.getViewport(viewportId), instead of using your lexical scoped reference to the viewport instance.'\n );\n }\n }\n\n /**\n * It checks if the new image object matches the dimensions, spacing,\n * and direction of the previously displayed image in the viewport or not.\n * It returns a boolean\n *\n * @param image - Cornerstone Image object\n * @param imageData - vtkImageData\n * @returns boolean\n */\n private _checkVTKImageDataMatchesCornerstoneImage(\n image: IImage,\n imageData: vtkImageDataType\n ): boolean {\n if (!imageData) {\n return false;\n }\n const [xSpacing, ySpacing] = imageData.getSpacing();\n const [xVoxels, yVoxels] = imageData.getDimensions();\n const imagePlaneModule = this._getImagePlaneModule(image.imageId);\n const direction = imageData.getDirection();\n const rowCosines = direction.slice(0, 3);\n const columnCosines = direction.slice(3, 6);\n const dataType = imageData.getPointData().getScalars().getDataType();\n\n // using epsilon comparison for float numbers comparison.\n const isSameXSpacing = isEqual(xSpacing, image.columnPixelSpacing);\n const isSameYSpacing = isEqual(ySpacing, image.rowPixelSpacing);\n\n // using spacing, size, and direction only for now\n return (\n (isSameXSpacing ||\n (image.columnPixelSpacing === null && xSpacing === 1.0)) &&\n (isSameYSpacing ||\n (image.rowPixelSpacing === null && ySpacing === 1.0)) &&\n xVoxels === image.columns &&\n yVoxels === image.rows &&\n isEqual(imagePlaneModule.rowCosines, <Point3>rowCosines) &&\n isEqual(imagePlaneModule.columnCosines, <Point3>columnCosines) &&\n (!this.useNativeDataType ||\n dataType === image.getPixelData().constructor.name)\n );\n }\n\n /**\n * It Updates the vtkImageData of the viewport with the new pixel data\n * from the provided image object.\n *\n * @param image - Cornerstone Image object\n */\n private _updateVTKImageDataFromCornerstoneImage(image: IImage): void {\n const imagePlaneModule = this._getImagePlaneModule(image.imageId);\n let origin = imagePlaneModule.imagePositionPatient;\n\n if (origin == null) {\n origin = [0, 0, 0];\n }\n\n this._imageData.setOrigin(origin);\n\n // Update the pixel data in the vtkImageData object with the pixelData\n // from the loaded Cornerstone image\n updateVTKImageDataWithCornerstoneImage(this._imageData, image);\n }\n\n /**\n * It uses imageLoadPoolManager to add request for the imageId. It loadsAndCache\n * the image and triggers the STACK_NEW_IMAGE when the request successfully retrieves\n * the image. Next, the volume actor gets updated with the new new retrieved image.\n *\n * @param imageId - string representing the imageId\n * @param imageIdIndex - index of the imageId in the imageId list\n */\n private _loadAndDisplayImage(\n imageId: string,\n imageIdIndex: number\n ): Promise<string> {\n return this.useCPURendering\n ? this._loadAndDisplayImageCPU(imageId, imageIdIndex)\n : this._loadAndDisplayImageGPU(imageId, imageIdIndex);\n }\n\n private _loadAndDisplayImageCPU(\n imageId: string,\n imageIdIndex: number\n ): Promise<string> {\n return new Promise((resolve, reject) => {\n // 1. Load the image using the Image Loader\n function successCallback(\n image: IImage,\n imageIdIndex: number,\n imageId: string\n ) {\n // Perform this check after the image has finished loading\n // in case the user has already scrolled away to another image.\n // In that case, do not render this image.\n if (this.currentImageIdIndex !== imageIdIndex) {\n return;\n }\n\n const pixelData = image.getPixelData();\n\n // handle the case where the pixelData is a Float32Array\n // CPU path cannot handle it, it should be converted to Uint16Array\n // and via the Modality LUT we can display it properly\n const preScale = image.preScale;\n const scalingParams = preScale?.scalingParameters;\n\n const scaledWithNonIntegers =\n (preScale?.scaled && scalingParams?.rescaleIntercept % 1 !== 0) ||\n scalingParams?.rescaleSlope % 1 !== 0;\n\n if (pixelData instanceof Float32Array && scaledWithNonIntegers) {\n const floatMinMax = {\n min: image.maxPixelValue,\n max: image.minPixelValue,\n };\n const floatRange = Math.abs(floatMinMax.max - floatMinMax.min);\n const intRange = 65535;\n const slope = floatRange / intRange;\n const intercept = floatMinMax.min;\n const numPixels = pixelData.length;\n const intPixelData = new Uint16Array(numPixels);\n\n let min = 65535;\n\n let max = 0;\n\n for (let i = 0; i < numPixels; i++) {\n const rescaledPixel = Math.floor(\n (pixelData[i] - intercept) / slope\n );\n\n intPixelData[i] = rescaledPixel;\n min = Math.min(min, rescaledPixel);\n max = Math.max(max, rescaledPixel);\n }\n\n // reset the properties since basically the image has changed\n image.minPixelValue = min;\n image.maxPixelValue = max;\n image.slope = slope;\n image.intercept = intercept;\n image.getPixelData = () => intPixelData;\n\n image.preScale = {\n ...image.preScale,\n scaled: false,\n };\n }\n\n this._setCSImage(image);\n this.viewportStatus = ViewportStatus.PRE_RENDER;\n\n const eventDetail: EventTypes.StackNewImageEventDetail = {\n image,\n imageId,\n imageIdIndex,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n };\n\n triggerEvent(this.element, Events.STACK_NEW_IMAGE, eventDetail);\n\n this._updateToDisplayImageCPU(image);\n\n // Todo: trigger an event to allow applications to hook into END of loading state\n // Currently we use loadHandlerManagers for this\n\n // Trigger the image to be drawn on the next animation frame\n this.render();\n\n // Update the viewport's currentImageIdIndex to reflect the newly\n // rendered image\n this.currentImageIdIndex = imageIdIndex;\n resolve(imageId);\n }\n\n function errorCallback(\n error: Error,\n imageIdIndex: number,\n imageId: string\n ) {\n const eventDetail = {\n error,\n imageIdIndex,\n imageId,\n };\n\n if (!this.suppressEvents) {\n triggerEvent(eventTarget, Events.IMAGE_LOAD_ERROR, eventDetail);\n }\n\n reject(error);\n }\n\n function sendRequest(imageId, imageIdIndex, options) {\n return loadAndCacheImage(imageId, options).then(\n (image) => {\n successCallback.call(this, image, imageIdIndex, imageId);\n },\n (error) => {\n errorCallback.call(this, error, imageIdIndex, imageId);\n }\n );\n }\n\n const priority = -5;\n const requestType = RequestType.Interaction;\n const additionalDetails = { imageId, imageIdIndex };\n const options = {\n preScale: {\n enabled: true,\n },\n useRGBA: true,\n requestType,\n };\n\n const eventDetail: EventTypes.PreStackNewImageEventDetail = {\n imageId,\n imageIdIndex,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n };\n triggerEvent(this.element, Events.PRE_STACK_NEW_IMAGE, eventDetail);\n\n imageLoadPoolManager.addRequest(\n sendRequest.bind(this, imageId, imageIdIndex, options),\n requestType,\n additionalDetails,\n priority\n );\n });\n }\n\n public successCallback(imageId, image) {\n const imageIdIndex = this.imageIds.indexOf(imageId);\n // Todo: trigger an event to allow applications to hook into END of loading state\n // Currently we use loadHandlerManagers for this\n // Perform this check after the image has finished loading\n // in case the user has already scrolled away to another image.\n // In that case, do not render this image.\n if (this.currentImageIdIndex !== imageIdIndex) {\n return;\n }\n\n // If Photometric Interpretation is not the same for the next image we are trying to load\n // invalidate the stack to recreate the VTK imageData. Get the PMI from\n // the base csImage if imageFrame isn't defined, which happens when the images\n // come from the volume\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const csImgFrame = (<any>this.csImage)?.imageFrame;\n const imgFrame = image?.imageFrame;\n const photometricInterpretation =\n csImgFrame?.photometricInterpretation ||\n this.csImage?.photometricInterpretation;\n const newPhotometricInterpretation =\n imgFrame?.photometricInterpretation || image?.photometricInterpretation;\n\n if (photometricInterpretation !== newPhotometricInterpretation) {\n this.stackInvalidated = true;\n }\n\n this._setCSImage(image);\n\n const eventDetail: EventTypes.StackNewImageEventDetail = {\n image,\n imageId,\n imageIdIndex,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n };\n\n this._updateActorToDisplayImageId(image);\n triggerEvent(this.element, Events.STACK_NEW_IMAGE, eventDetail);\n\n // Trigger the image to be drawn on the next animation frame\n this.render();\n\n // Update the viewport's currentImageIdIndex to reflect the newly\n // rendered image\n this.currentImageIdIndex = imageIdIndex;\n }\n\n public errorCallback(imageId, permanent, error) {\n if (!permanent) {\n return;\n }\n const imageIdIndex = this.imageIds.indexOf(imageId);\n const eventDetail = {\n error,\n imageIdIndex,\n imageId,\n };\n\n triggerEvent(eventTarget, Events.IMAGE_LOAD_ERROR, eventDetail);\n }\n\n public getLoaderImageOptions(imageId: string) {\n const imageIdIndex = this.imageIds.indexOf(imageId);\n const { transferSyntaxUID } = metaData.get('transferSyntax', imageId) || {};\n\n /**\n * If use16bittexture is specified, the CSWIL will automatically choose the\n * array type when no targetBuffer is provided. When CSWIL is initialized,\n * the use16bit should match the settings of cornerstone3D (either preferSizeOverAccuracy\n * or norm16 textures need to be enabled)\n *\n * If use16bittexture is not specified, we force the Float32Array for now\n */\n const additionalDetails = { imageId, imageIdIndex };\n const options = {\n targetBuffer: {\n type: this.useNativeDataType ? undefined : 'Float32Array',\n },\n preScale: {\n enabled: true,\n },\n useRGBA: false,\n transferSyntaxUID,\n useNativeDataType: this.useNativeDataType,\n priority: 5,\n requestType: RequestType.Interaction,\n additionalDetails,\n };\n return options;\n }\n\n public async loadImages(\n imageIds: string[],\n listener: ImageLoadListener\n ): Promise<unknown> {\n const resultList = await Promise.allSettled(\n imageIds.map((imageId) => {\n const options = this.getLoaderImageOptions(\n imageId\n ) as ImageLoaderOptions;\n\n return loadAndCacheImage(imageId, options).then(\n (image) => {\n listener.successCallback(imageId, image);\n return imageId;\n },\n (error) => {\n listener.errorCallback(imageId, true, error);\n return imageId;\n }\n );\n })\n );\n const errorList = resultList.filter((item) => item.status === 'rejected');\n if (errorList && errorList.length) {\n const event = new CustomEvent(Events.IMAGE_LOAD_ERROR, {\n detail: errorList,\n cancelable: true,\n });\n eventTarget.dispatchEvent(event);\n }\n return resultList;\n }\n\n private _loadAndDisplayImageGPU(imageId: string, imageIdIndex: number) {\n const eventDetail: EventTypes.PreStackNewImageEventDetail = {\n imageId,\n imageIdIndex,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n };\n triggerEvent(this.element, Events.PRE_STACK_NEW_IMAGE, eventDetail);\n\n return this.imagesLoader.loadImages([imageId], this).then((v) => {\n return imageId;\n });\n }\n\n /**\n * Renders the given Cornerstone image object in the viewport.\n * This method is intended to be used by utilities to render\n * an individual image, rather than by applications that want to display\n * a complete image stack. If you want to load and display a complete\n * image stack, use the setStack method instead of this one.\n *\n * The rendered image will appear in the viewport's element.\n * Use this method if you have other means of loading and the\n * cornerstone image object is already available.\n *\n * If you don't understand the difference between this method and\n * setStack, you probably want to use setStack.\n *\n * @param image - The Cornerstone image object to render.\n */\n public renderImageObject = (image) => {\n this._setCSImage(image);\n\n const renderFn = this.useCPURendering\n ? this._updateToDisplayImageCPU\n : this._updateActorToDisplayImageId;\n\n renderFn.call(this, image);\n };\n\n private _setCSImage = (image) => {\n image.isPreScaled = image.preScale?.scaled;\n this.csImage = image;\n };\n\n private _updateToDisplayImageCPU(image: IImage) {\n const metadata = this.getImageDataMetadata(image) as ImageDataMetaData;\n\n const viewport = getDefaultViewport(\n this.canvas,\n image,\n this.modality,\n this._cpuFallbackEnabledElement.viewport.colormap\n );\n\n const { windowCenter, windowWidth } = viewport.voi;\n this.voiRange = windowLevelUtil.toLowHighRange(windowWidth, windowCenter);\n\n this._cpuFallbackEnabledElement.image = image;\n this._cpuFallbackEnabledElement.metadata = {\n ...metadata,\n };\n this.cpuImagePixelData = image.getPixelData();\n\n const viewportSettingToUse = Object.assign(\n {},\n viewport,\n this._cpuFallbackEnabledElement.viewport\n );\n\n // Important: this.stackInvalidated is different than cpuRenderingInvalidated. The\n // former is being used to maintain the previous state of the viewport\n // in the same stack, the latter is used to trigger drawImageSync\n this._cpuFallbackEnabledElement.viewport = this.stackInvalidated\n ? viewport\n : viewportSettingToUse;\n\n // used the previous state of the viewport, then stackInvalidated is set to false\n this.stackInvalidated = false;\n\n // new viewport is set to the current viewport, then cpuRenderingInvalidated is set to true\n this.cpuRenderingInvalidated = true;\n\n this._cpuFallbackEnabledElement.transform = calculateTransform(\n this._cpuFallbackEnabledElement\n );\n }\n\n /**\n * This method is used to add images to the stack viewport.\n * It takes an array of stack inputs, each containing an imageId and an actor UID.\n * For each stack input, it retrieves the image from the cache and creates a VTK image data object.\n * It then creates an actor mapper for the image data and adds it to the list of actors.\n * Finally, it sets the actors for the stack viewport.\n *\n * @param stackInputs - An array of stack inputs, each containing an image ID and an actor UID.\n */\n public addImages(stackInputs: Array<IStackInput>) {\n const actors = this.getActors();\n stackInputs.forEach((stackInput) => {\n const image = cache.getImage(stackInput.imageId);\n\n const { origin, dimensions, direction, spacing, numComps } =\n this.getImageDataMetadata(image);\n\n const imagedata = this.createVTKImageData({\n origin,\n dimensions,\n direction,\n spacing,\n numComps,\n pixelArray: image.getPixelData(),\n });\n\n const imageActor = this.createActorMapper(imagedata);\n if (imageActor) {\n actors.push({ uid: stackInput.actorUID, actor: imageActor });\n if (stackInput.callback) {\n stackInput.callback({ imageActor, imageId: stackInput.imageId });\n }\n }\n });\n this.setActors(actors);\n }\n\n /**\n * It updates the volume actor with the retrieved cornerstone image.\n * It first checks if the new image has the same dimensions, spacings, and\n * dimensions of the previous one: 1) If yes, it updates the pixel data 2) if not,\n * it creates a whole new volume actor for the image.\n * Note: Camera gets reset for both situations. Therefore, each image renders at\n * its exact 3D location in the space, and both image and camera moves while scrolling.\n *\n * @param image - Cornerstone image\n * @returns\n */\n private _updateActorToDisplayImageId(image) {\n // This function should do the following:\n // - Get the existing actor's vtkImageData that is being used to render the current image and check if we can reuse the vtkImageData that is in place (i.e. do the image dimensions and data type match?)\n // - If we can reuse it, replace the scalar data under the hood\n // - If we cannot reuse it, create a new actor, remove the old one, and reset the camera\n\n // 2. Check if we can reuse the existing vtkImageData object, if one is present.\n const sameImageData = this._checkVTKImageDataMatchesCornerstoneImage(\n image,\n this._imageData\n );\n\n const activeCamera = this.getRenderer().getActiveCamera();\n\n // Cache camera props so we can trigger one camera changed event after\n // The full transition.\n const previousCameraProps = structuredClone(this.getCamera());\n if (sameImageData && !this.stackInvalidated) {\n // 3a. If we can reuse it, replace the scalar data under the hood\n this._updateVTKImageDataFromCornerstoneImage(image);\n\n // Since the 3D location of the imageData is changing as we scroll, we need\n // to modify the camera position to render this properly. However, resetting\n // causes problem related to zoom and pan tools: upon rendering of a new slice\n // the pan and zoom will get reset. To solve this, 1) we store the camera\n // properties related to pan and zoom 2) reset the camera to correctly place\n // it in the space 3) restore the pan, zoom props.\n const cameraProps = this.getCamera();\n\n const panCache = vec3.subtract(\n vec3.create(),\n this.cameraFocalPointOnRender,\n cameraProps.focalPoint\n );\n\n // Reset the camera to point to the new slice location, reset camera doesn't\n // modify the direction of projection and viewUp\n this.resetCameraNoEvent();\n\n // set the flip and view up back to the previous value since the restore camera props\n // rely on the correct flip value\n this.setCameraNoEvent({\n flipHorizontal: previousCameraProps.flipHorizontal,\n flipVertical: previousCameraProps.flipVertical,\n viewUp: previousCameraProps.viewUp,\n });\n\n const { focalPoint } = this.getCamera();\n this.cameraFocalPointOnRender = focalPoint;\n\n // This is necessary to initialize the clipping range and it is not related\n // to our custom slabThickness.\n // @ts-ignore: vtkjs incorrect typing\n activeCamera.setFreezeFocalPoint(true);\n\n // We shouldn't restore the focalPoint, position and parallelScale after reset\n // if it is the first render or we have completely re-created the vtkImageData\n this._restoreCameraProps(\n cameraProps,\n previousCameraProps,\n panCache as Point3\n );\n\n this._setPropertiesFromCache();\n this.stackActorReInitialized = false;\n\n return;\n }\n\n const {\n origin,\n direction,\n dimensions,\n spacing,\n numComps,\n imagePixelModule,\n } = this.getImageDataMetadata(image);\n\n // 3b. If we cannot reuse the vtkImageData object (either the first render\n // or the size has changed), create a new one\n\n const pixelArray = image.getPixelData();\n this._createVTKImageData({\n origin,\n direction,\n dimensions,\n spacing,\n numComps,\n pixelArray,\n });\n\n // Set the scalar data of the vtkImageData object from the Cornerstone\n // Image's pixel data\n this._updateVTKImageDataFromCornerstoneImage(image);\n\n // Create a VTK Image Slice actor to display the vtkImageData object\n const actor = this.createActorMapper(this._imageData);\n const oldActors = this.getActors();\n if (oldActors.length && oldActors[0].uid === this.id) {\n oldActors[0].actor = actor;\n } else {\n oldActors.unshift({ uid: this.id, actor });\n }\n this.setActors(oldActors);\n\n // Adjusting the camera based on slice axis. this is required if stack\n // contains various image orientations (axial ct, sagittal xray)\n const { viewPlaneNormal, viewUp } = this._getCameraOrientation(direction);\n\n this.setCameraNoEvent({ viewUp, viewPlaneNormal });\n\n // Setting this makes the following comment about resetCameraNoEvent not modifying viewUp true.\n this.initialViewUp = viewUp;\n\n // Reset the camera to point to the new slice location, reset camera doesn't\n // modify the direction of projection and viewUp\n this.resetCameraNoEvent();\n\n this.triggerCameraEvent(this.getCamera(), previousCameraProps);\n\n // This is necessary to initialize the clipping range and it is not related\n // to our custom slabThickness.\n // @ts-ignore: vtkjs incorrect typing\n activeCamera.setFreezeFocalPoint(true);\n\n const monochrome1 =\n imagePixelModule.photometricInterpretation === 'MONOCHROME1';\n\n // invalidate the stack so that we can set the voi range\n this.stackInvalidated = true;\n\n this.setVOI(this._getInitialVOIRange(image), {\n forceRecreateLUTFunction: !!monochrome1,\n });\n\n this.initialInvert = !!monochrome1;\n\n // should carry over the invert color from the previous image if has been applied\n this.setInvertColor(this.invert || this.initialInvert);\n\n // Saving position of camera on render, to cache the panning\n this.cameraFocalPointOnRender = this.getCamera().focalPoint;\n this.stackInvalidated = false;\n\n this.stackActorReInitialized = true;\n\n if (this._publishCalibratedEvent) {\n this.triggerCalibrationEvent();\n }\n }\n\n private _getInitialVOIRange(image: IImage) {\n if (this.voiRange && this.voiUpdatedWithSetProperties) {\n return this.globalDefaultProperties.voiRange;\n }\n const { windowCenter, windowWidth } = image;\n\n let voiRange = this._getVOIRangeFromWindowLevel(windowWidth, windowCenter);\n\n // Get the range for the PT since if it is prescaled\n // we set a default range of 0-5\n voiRange = this._getPTPreScaledRange() || voiRange;\n\n return voiRange;\n }\n\n private _getPTPreScaledRange() {\n if (!this._isCurrentImagePTPrescaled()) {\n return undefined;\n }\n\n return this._getDefaultPTPrescaledVOIRange();\n }\n\n private _isCurrentImagePTPrescaled() {\n if (this.modality !== 'PT' || !this.csImage.isPreScaled) {\n return false;\n }\n\n if (!this.csImage.preScale?.scalingParameters?.suvbw) {\n return false;\n }\n\n return true;\n }\n\n private _getDefaultPTPrescaledVOIRange() {\n return { lower: 0, upper: 5 };\n }\n\n private _getVOIRangeFromWindowLevel(\n windowWidth: number | number[],\n windowCenter: number | number[]\n ): { lower: number; upper: number } | undefined {\n let center, width;\n\n if (typeof windowCenter === 'number' && typeof windowWidth === 'number') {\n center = windowCenter;\n width = windowWidth;\n } else if (Array.isArray(windowCenter) && Array.isArray(windowWidth)) {\n center = windowCenter[0];\n width = windowWidth[0];\n }\n\n // If center and width are defined, convert them to low-high range\n if (center !== undefined && width !== undefined) {\n return windowLevelUtil.toLowHighRange(width, center);\n }\n }\n\n /**\n * Loads the image based on the provided imageIdIndex\n * @param imageIdIndex - number represents imageId index\n */\n private async _setImageIdIndex(imageIdIndex: number): Promise<string> {\n if (imageIdIndex >= this.imageIds.length) {\n throw new Error(\n `ImageIdIndex provided ${imageIdIndex} is invalid, the stack only has ${this.imageIds.length} elements`\n );\n }\n\n // Update the state of the viewport to the new imageIdIndex;\n this.currentImageIdIndex = imageIdIndex;\n this.hasPixelSpacing = true;\n this.viewportStatus = ViewportStatus.PRE_RENDER;\n\n // Todo: trigger an event to allow applications to hook into START of loading state\n // Currently we use loadHandlerManagers for this\n const imageId = await this._loadAndDisplayImage(\n this.imageIds[imageIdIndex],\n imageIdIndex\n );\n\n //Check if there is any existing specific options for images if not we don't\n //want to re-render the viewport to its default properties\n if (this.perImageIdDefaultProperties.size >= 1) {\n const defaultProperties = this.perImageIdDefaultProperties.get(imageId);\n if (defaultProperties !== undefined) {\n this.setProperties(defaultProperties);\n } else if (this.globalDefaultProperties !== undefined) {\n this.setProperties(this.globalDefaultProperties);\n }\n }\n\n return imageId;\n }\n\n private resetCameraCPU(resetPan, resetZoom) {\n const { image } = this._cpuFallbackEnabledElement;\n\n if (!image) {\n return;\n }\n\n resetCamera(this._cpuFallbackEnabledElement, resetPan, resetZoom);\n\n const { scale } = this._cpuFallbackEnabledElement.viewport;\n\n // canvas center is the focal point\n const { clientWidth, clientHeight } = this.element;\n const center: Point2 = [clientWidth / 2, clientHeight / 2];\n\n const centerWorld = this.canvasToWorldCPU(center);\n\n this.setCameraCPU({\n focalPoint: centerWorld,\n scale,\n });\n }\n\n private resetCameraGPU(resetPan, resetZoom): boolean {\n // Todo: we need to make the rotation a camera properties so that\n // we can reset it there, right now it is not possible to reset the rotation\n // without this\n\n // We do not know the ordering of various flips and rotations that have been applied,\n // so the rotation and flip must be reset together.\n this.setCamera({\n flipHorizontal: false,\n flipVertical: false,\n viewUp: this.initialViewUp,\n });\n\n // For stack Viewport we since we have only one slice\n // it should be enough to reset the camera to the center of the image\n const resetToCenter = true;\n return super.resetCamera(resetPan, resetZoom, resetToCenter);\n }\n\n /**\n * It scrolls the stack of imageIds by the delta amount provided. If the debounce\n * flag is set, it will only scroll the stack if the delta is greater than the\n * debounceThreshold which is 40 milliseconds by default.\n * @param delta - number of indices to scroll, it can be positive or negative\n * @param debounce - whether to debounce the scroll event\n * @param loop - whether to loop the stack\n */\n public scroll(delta: number, debounce = true, loop = false): void {\n const imageIds = this.imageIds;\n\n const currentTargetImageIdIndex = this.targetImageIdIndex;\n const numberOfFrames = imageIds.length;\n\n let newTargetImageIdIndex = currentTargetImageIdIndex + delta;\n newTargetImageIdIndex = Math.max(0, newTargetImageIdIndex);\n\n if (loop) {\n newTargetImageIdIndex = newTargetImageIdIndex % numberOfFrames;\n } else {\n newTargetImageIdIndex = Math.min(\n numberOfFrames - 1,\n newTargetImageIdIndex\n );\n }\n\n this.targetImageIdIndex = newTargetImageIdIndex;\n\n const targetImageId = imageIds[newTargetImageIdIndex];\n\n const imageAlreadyLoaded = cache.isLoaded(targetImageId);\n\n // If image is already cached we want to scroll right away; however, if it is\n // not cached, we can debounce the scroll event to avoid firing multiple scroll\n // events for the images that might happen to be passing by (as a result of infinite\n // scrolling).\n if (imageAlreadyLoaded || !debounce) {\n this.setImageIdIndex(newTargetImageIdIndex);\n } else {\n clearTimeout(this.debouncedTimeout);\n this.debouncedTimeout = window.setTimeout(() => {\n this.setImageIdIndex(newTargetImageIdIndex);\n }, 40);\n }\n\n const eventData: StackViewportScrollEventDetail = {\n newImageIdIndex: newTargetImageIdIndex,\n imageId: targetImageId,\n direction: delta,\n };\n\n if (newTargetImageIdIndex !== currentTargetImageIdIndex) {\n triggerEvent(this.element, Events.STACK_VIEWPORT_SCROLL, eventData);\n }\n }\n\n /**\n * Loads the image based on the provided imageIdIndex. It is an Async function which\n * returns a promise that resolves to the imageId.\n *\n * @param imageIdIndex - number represents imageId index in the list of\n * provided imageIds in setStack\n */\n public setImageIdIndex(imageIdIndex: number): Promise<string> {\n this._throwIfDestroyed();\n\n // If we are already on this imageId index, stop here\n if (this.currentImageIdIndex === imageIdIndex) {\n return Promise.resolve(this.getCurrentImageId());\n }\n\n // Otherwise, get the imageId and attempt to display it\n const imageIdPromise = this._setImageIdIndex(imageIdIndex);\n\n return imageIdPromise;\n }\n\n /**\n * Calibrates the image with new metadata that has been added for imageId. To calibrate\n * a viewport, you should add your calibration data manually to\n * calibratedPixelSpacingMetadataProvider and call viewport.calibrateSpacing\n * for it get applied.\n *\n * @param imageId - imageId to be calibrated\n */\n public calibrateSpacing(imageId: string): void {\n const imageIdIndex = this.getImageIds().indexOf(imageId);\n this.stackInvalidated = true;\n this._loadAndDisplayImage(imageId, imageIdIndex);\n }\n\n /**\n * Restores the camera props such zooming and panning after an image is\n * changed, if needed (after scroll)\n *\n * @param parallelScale - camera parallel scale\n */\n private _restoreCameraProps(\n { parallelScale: prevScale }: ICamera,\n previousCamera: ICamera,\n panCache: Point3\n ): void {\n const renderer = this.getRenderer();\n\n // get the focalPoint and position after the reset\n const { position, focalPoint } = this.getCamera();\n\n const newPosition = vec3.subtract(vec3.create(), position, panCache);\n const newFocal = vec3.subtract(vec3.create(), focalPoint, panCache);\n\n // Restoring previous state x,y and scale, keeping the new z\n // we need to break the flip operations since they also work on the\n // camera position and focal point\n this.setCameraNoEvent({\n parallelScale: prevScale,\n position: newPosition as Point3,\n focalPoint: newFocal as Point3,\n });\n\n const camera = this.getCamera();\n\n this.triggerCameraEvent(camera, previousCamera);\n\n // Invoking render\n const RESET_CAMERA_EVENT = {\n type: 'ResetCameraEvent',\n renderer,\n };\n\n renderer.invokeEvent(RESET_CAMERA_EVENT);\n }\n\n private triggerCameraEvent(camera: ICamera, previousCamera: ICamera) {\n // Finally emit event for the full camera change cause during load image.\n const eventDetail: EventTypes.CameraModifiedEventDetail = {\n previousCamera,\n camera,\n element: this.element,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n };\n\n if (!this.suppressEvents) {\n // For crosshairs to adapt to new viewport size\n triggerEvent(this.element, Events.CAMERA_MODIFIED, eventDetail);\n }\n }\n\n private triggerCalibrationEvent() {\n // Update the indexToWorld and WorldToIndex for viewport\n const { imageData } = this.getImageData();\n // Finally emit event for the full camera change cause during load image.\n const eventDetail: EventTypes.ImageSpacingCalibratedEventDetail = {\n element: this.element,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n imageId: this.getCurrentImageId(),\n // Todo: why do we need to pass imageData? isn't' indexToWorld and worldToIndex enough?\n imageData: imageData as vtkImageData,\n worldToIndex: imageData.getWorldToIndex() as mat4,\n ...this._calibrationEvent,\n };\n\n if (!this.suppressEvents) {\n // Let the tools know the image spacing has been calibrated\n triggerEvent(this.element, Events.IMAGE_SPACING_CALIBRATED, eventDetail);\n }\n\n this._publishCalibratedEvent = false;\n }\n\n private canvasToWorldCPU = (\n canvasPos: Point2,\n worldPos: Point3 = [0, 0, 0]\n ): Point3 => {\n if (!this._cpuFallbackEnabledElement.image) {\n return;\n }\n // compute the pixel coordinate in the image\n const [px, py] = canvasToPixel(this._cpuFallbackEnabledElement, canvasPos);\n\n // convert pixel coordinate to world coordinate\n const { origin, spacing, direction } = this.getImageData();\n\n // Calculate size of spacing vector in normal direction\n const iVector = direction.slice(0, 3) as Point3;\n const jVector = direction.slice(3, 6) as Point3;\n\n // Calculate the world coordinate of the pixel\n vec3.scaleAndAdd(worldPos, origin, iVector, px * spacing[0]);\n vec3.scaleAndAdd(worldPos, worldPos, jVector, py * spacing[1]);\n\n return worldPos;\n };\n\n private worldToCanvasCPU = (worldPos: Point3): Point2 => {\n // world to pixel\n const { spacing, direction, origin } = this.getImageData();\n\n const iVector = direction.slice(0, 3) as Point3;\n const jVector = direction.slice(3, 6) as Point3;\n\n const diff = vec3.subtract(vec3.create(), worldPos, origin);\n\n const worldPoint: Point2 = [\n vec3.dot(diff, iVector) / spacing[0],\n vec3.dot(diff, jVector) / spacing[1],\n ];\n\n // pixel to canvas\n const canvasPoint = pixelToCanvas(\n this._cpuFallbackEnabledElement,\n worldPoint\n );\n return canvasPoint;\n };\n\n private canvasToWorldGPU = (canvasPos: Point2): Point3 => {\n const renderer = this.getRenderer();\n\n // Temporary setting the clipping range to the distance and distance + 0.1\n // in order to calculate the transformations correctly.\n // This is similar to the vtkSlabCamera isPerformingCoordinateTransformations\n // You can read more about it here there.\n const vtkCamera = this.getVtkActiveCamera();\n const crange = vtkCamera.getClippingRange();\n const distance = vtkCamera.getDistance();\n\n vtkCamera.setClippingRange(distance, distance + 0.1);\n\n const offscreenMultiRenderWindow =\n this.getRenderingEngine().offscreenMultiRenderWindow;\n const openGLRenderWindow =\n offscreenMultiRenderWindow.getOpenGLRenderWindow();\n const size = openGLRenderWindow.getSize();\n\n const devicePixelRatio = window.devicePixelRatio || 1;\n const canvasPosWithDPR = [\n canvasPos[0] * devicePixelRatio,\n canvasPos[1] * devicePixelRatio,\n ];\n const displayCoord = [\n canvasPosWithDPR[0] + this.sx,\n canvasPosWithDPR[1] + this.sy,\n ];\n\n // The y axis display coordinates are inverted with respect to canvas coords\n displayCoord[1] = size[1] - displayCoord[1];\n\n const worldCoord = openGLRenderWindow.displayToWorld(\n displayCoord[0],\n displayCoord[1],\n 0,\n renderer\n );\n\n // set clipping range back to original to be able\n vtkCamera.setClippingRange(crange[0], crange[1]);\n\n return [worldCoord[0], worldCoord[1], worldCoord[2]];\n };\n\n private worldToCanvasGPU = (worldPos: Point3): Point2 => {\n const renderer = this.getRenderer();\n\n // Temporary setting the clipping range to the distance and distance + 0.1\n // in order to calculate the transformations correctly.\n // This is similar to the vtkSlabCamera isPerformingCoordinateTransformations\n // You can read more about it here there.\n const vtkCamera = this.getVtkActiveCamera();\n const crange = vtkCamera.getClippingRange();\n const distance = vtkCamera.getDistance();\n\n vtkCamera.setClippingRange(distance, distance + 0.1);\n\n const offscreenMultiRenderWindow =\n this.getRenderingEngine().offscreenMultiRenderWindow;\n const openGLRenderWindow =\n offscreenMultiRenderWindow.getOpenGLRenderWindow();\n const size = openGLRenderWindow.getSize();\n const displayCoord = openGLRenderWindow.worldToDisplay(\n ...worldPos,\n renderer\n );\n\n // The y axis display coordinates are inverted with respect to canvas coords\n displayCoord[1] = size[1] - displayCoord[1];\n\n const canvasCoord = <Point2>[\n displayCoord[0] - this.sx,\n displayCoord[1] - this.sy,\n ];\n\n // set clipping range back to original to be able\n vtkCamera.setClippingRange(crange[0], crange[1]);\n\n const devicePixelRatio = window.devicePixelRatio || 1;\n const canvasCoordWithDPR = <Point2>[\n canvasCoord[0] / devicePixelRatio,\n canvasCoord[1] / devicePixelRatio,\n ];\n\n return canvasCoordWithDPR;\n };\n\n private _getVOIRangeForCurrentImage() {\n const { windowCenter, windowWidth } = this.csImage;\n\n return this._getVOIRangeFromWindowLevel(windowWidth, windowCenter);\n }\n\n private _getValidVOILUTFunction(voiLUTFunction: any) {\n if (Object.values(VOILUTFunctionType).indexOf(voiLUTFunction) === -1) {\n voiLUTFunction = VOILUTFunctionType.LINEAR;\n }\n return voiLUTFunction;\n }\n\n /**\n * Returns the index of the imageId being renderer\n *\n * @returns currently shown imageId index\n */\n public getCurrentImageIdIndex = (): number => {\n return this.currentImageIdIndex;\n };\n\n /**\n * returns the slice index of the view\n * @returns slice index\n */\n public getSliceIndex = (): number => {\n return this.currentImageIdIndex;\n };\n\n /**\n * Checks to see if this target is or could be shown in this viewport\n */\n public isReferenceViewable(\n viewRef: ViewReference,\n options: ReferenceCompatibleOptions = {}\n ): boolean {\n if (!super.isReferenceViewable(viewRef, options)) {\n return false;\n }\n\n let { imageURI } = options;\n const { referencedImageId, sliceIndex } = viewRef;\n\n if (viewRef.volumeId && !referencedImageId) {\n return options.asVolume === true;\n }\n\n let testIndex = this.getCurrentImageIdIndex();\n if (options.withNavigation && typeof sliceIndex === 'number') {\n testIndex = sliceIndex;\n }\n const imageId = this.imageIds[testIndex];\n if (!imageId) {\n return false;\n }\n if (!imageURI) {\n // Remove the dataLoader scheme since that can change\n const colonIndex = imageId.indexOf(':');\n imageURI = imageId.substring(colonIndex + 1);\n }\n return referencedImageId?.endsWith(imageURI);\n }\n\n /**\n * Gets a standard target to show this image instance.\n * Returns undefined if the requested slice index is not available.\n *\n * <b>Warning<b>If using sliceIndex for requeseting a specific reference, the slice index MUST come\n * from the stack of image ids. Using slice index from a volume or from a different\n * stack of images ids, EVEN if they contain the same set of images will result in\n * random images being chosen.\n */\n public getViewReference(\n viewRefSpecifier: ViewReferenceSpecifier = {}\n ): ViewReference {\n const { sliceIndex = this.getCurrentImageIdIndex() } = viewRefSpecifier;\n const reference = super.getViewReference(viewRefSpecifier);\n const referencedImageId = this.imageIds[sliceIndex as number];\n if (!referencedImageId) {\n return;\n }\n reference.referencedImageId = referencedImageId;\n if (this.getCurrentImageIdIndex() !== sliceIndex) {\n const referenceData = this.getImagePlaneReferenceData(\n sliceIndex as number\n );\n if (!referenceData) {\n return;\n }\n Object.assign(reference, referenceData);\n }\n return reference;\n }\n\n /**\n * Applies the view reference, which may navigate the slice index and apply\n * other camera modifications.\n * Assumes that the slice index is correct for this viewport\n */\n public setViewReference(viewRef: ViewReference): void {\n if (!viewRef) {\n return;\n }\n const { referencedImageId, sliceIndex, volumeId } = viewRef;\n if (\n typeof sliceIndex === 'number' &&\n referencedImageId &&\n referencedImageId === this.imageIds[sliceIndex]\n ) {\n this.setImageIdIndex(sliceIndex);\n } else {\n const foundIndex = this.imageIds.indexOf(referencedImageId);\n if (foundIndex !== -1) {\n this.setImageIdIndex(foundIndex);\n } else {\n throw new Error('Unsupported - referenced image id not found');\n }\n }\n }\n\n /**\n * Returns the imageId string for the specified view, using the\n * `imageId:<imageId>` URN format.\n */\n public getReferenceId(specifier: ViewReferenceSpecifier = {}): string {\n const { sliceIndex: sliceIndex = this.currentImageIdIndex } = specifier;\n if (Array.isArray(sliceIndex)) {\n throw new Error('Use of slice ranges for stacks not supported');\n }\n return `imageId:${this.imageIds[sliceIndex]}`;\n }\n\n /**\n *\n * Returns the imageIdIndex that is targeted to be loaded, in case of debounced\n * loading (with scroll), the targetImageIdIndex is the latest imageId\n * index that is requested to be loaded but debounced.\n */\n public getTargetImageIdIndex = (): number => {\n return this.targetImageIdIndex;\n };\n\n /**\n * Returns the list of image Ids for the current viewport\n * @returns list of strings for image Ids\n */\n public getImageIds = (): Array<string> => {\n return this.imageIds;\n };\n\n /**\n * Returns the currently rendered imageId\n * @returns string for imageId\n */\n public getCurrentImageId = (): string => {\n return this.imageIds[this.currentImageIdIndex];\n };\n\n /**\n * Returns true if the viewport contains the given imageId\n * @param imageId - imageId\n * @returns boolean if imageId is in viewport\n */\n public hasImageId = (imageId: string): boolean => {\n return this.imageIds.includes(imageId);\n };\n\n /**\n * Returns true if the viewport contains the given imageURI (no data loader scheme)\n * @param imageURI - imageURI\n * @returns boolean if imageURI is in viewport\n */\n public hasImageURI = (imageURI: string): boolean => {\n const imageIds = this.imageIds;\n for (let i = 0; i < imageIds.length; i++) {\n if (imageIdToURI(imageIds[i]) === imageURI) {\n return true;\n }\n }\n\n return false;\n };\n\n private getCPUFallbackError(method: string): Error {\n return new Error(\n `method ${method} cannot be used during CPU Fallback mode`\n );\n }\n\n private fillWithBackgroundColor() {\n const renderingEngine = this.getRenderingEngine();\n\n if (renderingEngine) {\n renderingEngine.fillCanvasWithBackgroundColor(\n this.canvas,\n this.options.background\n );\n }\n }\n\n public customRenderViewportToCanvas = () => {\n if (!this.useCPURendering) {\n throw new Error(\n 'Custom cpu rendering pipeline should only be hit in CPU rendering mode'\n );\n }\n\n if (this._cpuFallbackEnabledElement.image) {\n drawImageSync(\n this._cpuFallbackEnabledElement,\n this.cpuRenderingInvalidated\n );\n // reset flags\n this.cpuRenderingInvalidated = false;\n } else {\n this.fillWithBackgroundColor();\n }\n\n return {\n canvas: this.canvas,\n element: this.element,\n viewportId: this.id,\n renderingEngineId: this.renderingEngineId,\n viewportStatus: this.viewportStatus,\n };\n };\n\n private unsetColormapCPU() {\n delete this._cpuFallbackEnabledElement.viewport.colormap;\n this._cpuFallbackEnabledElement.renderingTools = {};\n\n this.cpuRenderingInvalidated = true;\n\n this.fillWithBackgroundColor();\n\n this.render();\n }\n\n private setColormapCPU(colormapData: CPUFallbackColormapData) {\n this.colormap = colormapData;\n const colormap = getColormap(colormapData.name, colormapData);\n\n this._cpuFallbackEnabledElement.viewport.colormap = colormap;\n this._cpuFallbackEnabledElement.renderingTools = {};\n\n this.fillWithBackgroundColor();\n this.cpuRenderingInvalidated = true;\n\n this.render();\n\n const eventDetail = {\n viewportId: this.id,\n colormap: colormapData,\n };\n triggerEvent(this.element, Events.COLORMAP_MODIFIED, eventDetail);\n }\n\n private setColormapGPU(colormap: ColormapPublic) {\n const ActorEntry = this.getDefaultActor();\n const actor = ActorEntry.actor as ImageActor;\n const actorProp = actor.getProperty();\n const rgbTransferFunction = actorProp.getRGBTransferFunction();\n\n const colormapObj =\n colormapUtils.getColormap(colormap.name) ||\n vtkColorMaps.getPresetByName(colormap.name);\n\n if (!rgbTransferFunction) {\n const cfun = vtkColorTransferFunction.newInstance();\n cfun.applyColorMap(colormapObj);\n cfun.setMappingRange(this.voiRange.lower, this.voiRange.upper);\n actorProp.setRGBTransferFunction(0, cfun);\n } else {\n rgbTransferFunction.applyColorMap(colormapObj);\n rgbTransferFunction.setMappingRange(\n this.voiRange.lower,\n this.voiRange.upper\n );\n actorProp.setRGBTransferFunction(0, rgbTransferFunction);\n }\n\n this.colormap = colormap;\n this.render();\n\n const eventDetail = {\n viewportId: this.id,\n colormap,\n };\n\n triggerEvent(this.element, Events.COLORMAP_MODIFIED, eventDetail);\n }\n\n private unsetColormapGPU() {\n // TODO -> vtk has full colormaps which are piecewise and frankly better?\n // Do we really want a pre defined 256 color map just for the sake of harmonization?\n throw new Error('unsetColormapGPU not implemented.');\n }\n\n // create default values for imagePlaneModule if values are undefined\n private _getImagePlaneModule(imageId: string): ImagePlaneModule {\n const imagePlaneModule = metaData.get(MetadataModules.IMAGE_PLANE, imageId);\n\n this.calibration ||= imagePlaneModule.calibration;\n const newImagePlaneModule: ImagePlaneModule = {\n ...imagePlaneModule,\n };\n\n if (!newImagePlaneModule.columnPixelSpacing) {\n newImagePlaneModule.columnPixelSpacing = 1;\n this.hasPixelSpacing = this.calibration?.scale > 0;\n }\n\n if (!newImagePlaneModule.rowPixelSpacing) {\n newImagePlaneModule.rowPixelSpacing = 1;\n this.hasPixelSpacing = this.calibration?.scale > 0;\n }\n\n if (!newImagePlaneModule.columnCosines) {\n newImagePlaneModule.columnCosines = [0, 1, 0];\n }\n\n if (!newImagePlaneModule.rowCosines) {\n newImagePlaneModule.rowCosines = [1, 0, 0];\n }\n\n if (!newImagePlaneModule.imagePositionPatient) {\n newImagePlaneModule.imagePositionPatient = [0, 0, 0];\n }\n\n if (!newImagePlaneModule.imageOrientationPatient) {\n newImagePlaneModule.imageOrientationPatient = new Float32Array([\n 1, 0, 0, 0, 1, 0,\n ]);\n }\n\n return newImagePlaneModule;\n }\n\n private renderingPipelineFunctions = {\n getImageData: {\n cpu: this.getImageDataCPU,\n gpu: this.getImageDataGPU,\n },\n setColormap: {\n cpu: this.setColormapCPU,\n gpu: this.setColormapGPU,\n },\n getCamera: {\n cpu: this.getCameraCPU,\n gpu: super.getCamera,\n },\n setCamera: {\n cpu: this.setCameraCPU,\n gpu: super.setCamera,\n },\n getPan: {\n cpu: this.getPanCPU,\n gpu: super.getPan,\n },\n setPan: {\n cpu: this.setPanCPU,\n gpu: super.setPan,\n },\n getZoom: {\n cpu: this.getZoomCPU,\n gpu: super.getZoom,\n },\n setZoom: {\n cpu: this.setZoomCPU,\n gpu: super.setZoom,\n },\n setVOI: {\n cpu: this.setVOICPU,\n gpu: this.setVOIGPU,\n },\n getRotation: {\n cpu: this.getRotationCPU,\n gpu: this.getRotationGPU,\n },\n setInterpolationType: {\n cpu: this.setInterpolationTypeCPU,\n gpu: this.setInterpolationTypeGPU,\n },\n setInvertColor: {\n cpu: this.setInvertColorCPU,\n gpu: this.setInvertColorGPU,\n },\n resetCamera: {\n cpu: (resetPan = true, resetZoom = true): boolean => {\n this.resetCameraCPU(resetPan, resetZoom);\n return true;\n },\n gpu: (resetPan = true, resetZoom = true): boolean => {\n this.resetCameraGPU(resetPan, resetZoom);\n return true;\n },\n },\n canvasToWorld: {\n cpu: this.canvasToWorldCPU,\n gpu: this.canvasToWorldGPU,\n },\n worldToCanvas: {\n cpu: this.worldToCanvasCPU,\n gpu: this.worldToCanvasGPU,\n },\n getRenderer: {\n cpu: () => this.getCPUFallbackError('getRenderer'),\n gpu: super.getRenderer,\n },\n getDefaultActor: {\n cpu: () => this.getCPUFallbackError('getDefaultActor'),\n gpu: super.getDefaultActor,\n },\n getActors: {\n cpu: () => this.getCPUFallbackError('getActors'),\n gpu: super.getActors,\n },\n getActor: {\n cpu: () => this.getCPUFallbackError('getActor'),\n gpu: super.getActor,\n },\n setActors: {\n cpu: () => this.getCPUFallbackError('setActors'),\n gpu: super.setActors,\n },\n addActors: {\n cpu: () => this.getCPUFallbackError('addActors'),\n gpu: super.addActors,\n },\n addActor: {\n cpu: () => this.getCPUFallbackError('addActor'),\n gpu: super.addActor,\n },\n removeAllActors: {\n cpu: () => this.getCPUFallbackError('removeAllActors'),\n gpu: super.removeAllActors,\n },\n unsetColormap: {\n cpu: this.unsetColormapCPU,\n gpu: this.unsetColormapGPU,\n },\n };\n}\n\nexport default StackViewport;\n","import fitToWindow from './fitToWindow';\nimport getImageSize from './getImageSize';\nimport { CPUFallbackEnabledElement } from '../../../../types';\n\n/**\n * This module is responsible for enabling an element to display images with cornerstone\n *\n * @param {HTMLDivElement} element The DOM element enabled for Cornerstone\n * @param {HTMLDivElement} canvas The Canvas DOM element within the DOM element enabled for Cornerstone\n * @returns {void}\n */\nfunction setCanvasSize(enabledElement: CPUFallbackEnabledElement) {\n const { canvas } = enabledElement;\n const { clientWidth, clientHeight } = canvas;\n\n // Set the canvas to be same resolution as the client.\n if (canvas.width !== clientWidth || canvas.height !== clientHeight) {\n canvas.width = clientWidth;\n canvas.height = clientHeight;\n }\n}\n\n/**\n * Checks if the image of a given enabled element fitted the window\n * before the resize\n *\n * @param {EnabledElement} enabledElement The Cornerstone Enabled Element\n * @param {number} oldCanvasWidth The width of the canvas before the resize\n * @param {number} oldCanvasHeight The height of the canvas before the resize\n * @return {Boolean} true if it fitted the windows, false otherwise\n */\nfunction wasFitToWindow(\n enabledElement: CPUFallbackEnabledElement,\n oldCanvasWidth: number,\n oldCanvasHeight: number\n): boolean {\n const scale = enabledElement.viewport.scale;\n const imageSize = getImageSize(\n enabledElement.image,\n enabledElement.viewport.rotation\n );\n const imageWidth = Math.round(imageSize.width * scale);\n const imageHeight = Math.round(imageSize.height * scale);\n const x = enabledElement.viewport.translation.x;\n const y = enabledElement.viewport.translation.y;\n\n return (\n (imageWidth === oldCanvasWidth && imageHeight <= oldCanvasHeight) ||\n (imageWidth <= oldCanvasWidth &&\n imageHeight === oldCanvasHeight &&\n x === 0 &&\n y === 0)\n );\n}\n\n/**\n * Rescale the image relative to the changed size of the canvas\n *\n * @param {EnabledElement} enabledElement The Cornerstone Enabled Element\n * @param {number} oldCanvasWidth The width of the canvas before the resize\n * @param {number} oldCanvasHeight The height of the canvas before the resize\n * @return {void}\n */\nfunction relativeRescale(\n enabledElement: CPUFallbackEnabledElement,\n oldCanvasWidth: number,\n oldCanvasHeight: number\n): void {\n const scale = enabledElement.viewport.scale;\n const canvasWidth = enabledElement.canvas.width;\n const canvasHeight = enabledElement.canvas.height;\n const relWidthChange = canvasWidth / oldCanvasWidth;\n const relHeightChange = canvasHeight / oldCanvasHeight;\n const relChange = Math.sqrt(relWidthChange * relHeightChange);\n\n enabledElement.viewport.scale = relChange * scale;\n}\n\n/**\n * Resizes an enabled element and optionally fits the image to window\n *\n * @param {HTMLDivElement} element The DOM element enabled for Cornerstone\n * @param {Boolean} forceFitToWindow true to to force a refit, false to rescale accordingly\n * @returns {void}\n */\nexport default function (\n enabledElement: CPUFallbackEnabledElement,\n forceFitToWindow = false\n): void {\n const oldCanvasWidth = enabledElement.canvas.width;\n const oldCanvasHeight = enabledElement.canvas.height;\n\n setCanvasSize(enabledElement);\n\n if (enabledElement.image === undefined) {\n return;\n }\n\n if (\n forceFitToWindow ||\n wasFitToWindow(enabledElement, oldCanvasWidth, oldCanvasHeight)\n ) {\n // Fit the image to the window again if it fitted before the resize\n fitToWindow(enabledElement);\n } else {\n // Adapt the scale of a zoomed or panned image relative to the size change\n relativeRescale(enabledElement, oldCanvasWidth, oldCanvasHeight);\n }\n}\n","import getImageFitScale from './getImageFitScale';\nimport { CPUFallbackEnabledElement } from '../../../../types';\n\n/**\n * Adjusts an image's scale and translation so the image is centered and all pixels\n * in the image are viewable.\n *\n * @param element - The Cornerstone element to update\n */\nexport default function (enabledElement: CPUFallbackEnabledElement): void {\n const { image } = enabledElement;\n\n // The new scale is the minimum of the horizontal and vertical scale values\n enabledElement.viewport.scale = getImageFitScale(\n enabledElement.canvas,\n image,\n enabledElement.viewport.rotation\n ).scaleFactor;\n\n enabledElement.viewport.translation.x = 0;\n enabledElement.viewport.translation.y = 0;\n}\n","import { CPUFallbackViewport, Point2 } from '../../../../types';\n\ntype Shift = {\n x: number;\n y: number;\n};\n/**\n * Corrects the shift by accounting for viewport rotation and flips.\n *\n * @param shift - The shift to correct.\n * @param viewportOrientation - Object containing information on the viewport orientation.\n */\nexport default function (\n shift: Shift,\n viewportOrientation: CPUFallbackViewport\n): Shift {\n const { hflip, vflip, rotation } = viewportOrientation;\n\n // Apply Flips\n shift.x *= hflip ? -1 : 1;\n shift.y *= vflip ? -1 : 1;\n\n // Apply rotations\n if (rotation !== 0) {\n const angle = (rotation * Math.PI) / 180;\n\n const cosA = Math.cos(angle);\n const sinA = Math.sin(angle);\n\n const newX = shift.x * cosA - shift.y * sinA;\n const newY = shift.x * sinA + shift.y * cosA;\n\n shift.x = newX;\n shift.y = newY;\n }\n\n return shift;\n}\n","import getImageFitScale from './getImageFitScale';\nimport { CPUFallbackEnabledElement } from '../../../../types';\n\n/**\n * Resets the camera to the default position. which would be the center of the image.\n * with no translation, no flipping, no zoom and proper scale.\n */\nexport default function (\n enabledElement: CPUFallbackEnabledElement,\n resetPan = true,\n resetZoom = true\n): void {\n const { canvas, image, viewport } = enabledElement;\n const scale = getImageFitScale(canvas, image, 0).scaleFactor;\n\n viewport.vflip = false;\n viewport.hflip = false;\n\n if (resetPan) {\n viewport.translation.x = 0;\n viewport.translation.y = 0;\n }\n\n if (resetZoom) {\n viewport.displayedArea.tlhc.x = 1;\n viewport.displayedArea.tlhc.y = 1;\n viewport.displayedArea.brhc.x = image.columns;\n viewport.displayedArea.brhc.y = image.rows;\n\n viewport.scale = scale;\n }\n}\n","import { BlendModes, OrientationAxis } from '../enums';\nimport type { ViewportInput } from '../types/IViewport';\nimport BaseVolumeViewport from './BaseVolumeViewport';\n\n/**\n * An object representing a 3-dimensional volume viewport. VolumeViewport3Ds are used to render\n * 3D volumes in their entirety, and not just load a single slice at a time.\n *\n * For setting volumes on viewports you need to use {@link addVolumesToViewports}\n * which will add volumes to the specified viewports.\n */\nclass VolumeViewport3D extends BaseVolumeViewport {\n constructor(props: ViewportInput) {\n super(props);\n\n const { parallelProjection, orientation } = this.options;\n\n const activeCamera = this.getVtkActiveCamera();\n\n if (parallelProjection != null) {\n activeCamera.setParallelProjection(parallelProjection);\n }\n\n if (orientation && orientation !== OrientationAxis.ACQUISITION) {\n this.applyViewOrientation(orientation);\n }\n }\n\n public resetCamera(\n resetPan = true,\n resetZoom = true,\n resetToCenter = true\n ): boolean {\n super.resetCamera(resetPan, resetZoom, resetToCenter);\n this.resetVolumeViewportClippingRange();\n return;\n }\n\n getRotation = (): number => 0;\n\n getCurrentImageIdIndex = (): number | undefined => {\n return undefined;\n };\n\n getCurrentImageId = (): string => {\n return null;\n };\n\n setSlabThickness(\n slabThickness: number,\n filterActorUIDs?: Array<string>\n ): void {\n return null;\n }\n\n setBlendMode(\n blendMode: BlendModes,\n filterActorUIDs?: string[],\n immediate?: boolean\n ): void {\n return null;\n }\n\n resetProperties(volumeId?: string): void {\n return null;\n }\n\n resetSlabThickness(): void {\n return null;\n }\n}\n\nexport default VolumeViewport3D;\n","import CanvasActor from '.';\n\n/**\n * Properties for rendering on a labelmap canvas actor.\n * Mostly a no-op right now, but the transfer function settings are live.\n */\nexport default class CanvasProperties {\n private actor: CanvasActor;\n private opacity = 0.4;\n private outlineOpacity = 0.4;\n private transferFunction = [];\n\n constructor(actor: CanvasActor) {\n this.actor = actor;\n }\n\n public setRGBTransferFunction(index, cfun) {\n this.transferFunction[index] = cfun;\n }\n\n public setScalarOpacity(opacity: number) {\n // No-op until this gets set correctly\n // this.opacity = opacity;\n }\n\n public setInterpolationTypeToNearest() {\n // No-op\n }\n\n public setUseLabelOutline() {\n // No-op - not implemented\n }\n\n public setLabelOutlineOpacity(opacity) {\n this.outlineOpacity = opacity;\n }\n\n public setLabelOutlineThickness() {\n // No-op - requires outline to be implemented first\n }\n\n public getColor(index: number) {\n const cfun = this.transferFunction[0];\n const r = cfun.getRedValue(index);\n const g = cfun.getGreenValue(index);\n const b = cfun.getBlueValue(index);\n return [r, g, b, this.opacity];\n }\n}\n","import CanvasActor from '.';\n\n/**\n * Mimics the VTK mapper functionality, but for non-vtk canvas based rendering\n * classes.\n */\nexport default class CanvasMapper {\n private actor: CanvasActor;\n\n constructor(actor: CanvasActor) {\n this.actor = actor;\n }\n\n getInputData() {\n return this.actor.getImage();\n }\n}\n","import type { IViewport } from '../../types/IViewport';\nimport type { ICanvasActor } from '../../types/IActor';\nimport CanvasProperties from './CanvasProperties';\nimport CanvasMapper from './CanvasMapper';\n\n/**\n * Handles canvas rendering of derived image data, typically label maps.\n * This class will update the canvas from the given viewport with a\n * derived image. The derived image can be a standard Cornerstone labelmap\n * or be an RLE based one. The RLE based ones are significantly faster to\n * render as they only render the area actually relevant.\n */\nexport default class CanvasActor implements ICanvasActor {\n private image;\n private derivedImage;\n private canvasProperties = new CanvasProperties(this);\n private visibility = false;\n private mapper = new CanvasMapper(this);\n private viewport;\n protected className = 'CanvasActor';\n protected canvas;\n\n constructor(viewport: IViewport, derivedImage) {\n this.derivedImage = derivedImage;\n this.viewport = viewport;\n }\n\n /**\n * Renders an RLE representation of the viewport data. This is optimized to\n * avoid iterating over any data not actually containing data.\n */\n protected renderRLE(viewport, context, voxelManager) {\n const { width, height } = this.image;\n let { canvas } = this;\n if (!canvas || canvas.width !== width || canvas.height !== height) {\n this.canvas = canvas = new window.OffscreenCanvas(width, height);\n }\n const localContext = canvas.getContext('2d');\n const imageData = localContext.createImageData(width, height);\n const { data: imageArray } = imageData;\n imageArray.fill(0);\n const { map } = voxelManager;\n let dirtyX = Infinity;\n let dirtyY = Infinity;\n let dirtyX2 = -Infinity;\n let dirtyY2 = -Infinity;\n for (let y = 0; y < height; y++) {\n const row = map.getRun(y, 0);\n if (!row) {\n continue;\n }\n dirtyY = Math.min(dirtyY, y);\n dirtyY2 = Math.max(dirtyY2, y);\n const baseOffset = (y * width) << 2;\n let indicesToDelete;\n for (const run of row) {\n const { start, end, value: segmentIndex } = run;\n if (segmentIndex === 0) {\n indicesToDelete ||= [];\n indicesToDelete.push(row.indexOf(run));\n continue;\n }\n dirtyX = Math.min(dirtyX, start);\n dirtyX2 = Math.max(dirtyX2, end);\n const rgb = this.canvasProperties\n .getColor(segmentIndex)\n .map((v) => v * 255);\n let startOffset = baseOffset + (start << 2);\n\n for (let i = start; i < end; i++) {\n imageArray[startOffset++] = rgb[0];\n imageArray[startOffset++] = rgb[1];\n imageArray[startOffset++] = rgb[2];\n imageArray[startOffset++] = rgb[3];\n }\n }\n }\n\n if (dirtyX > width) {\n return;\n }\n const dirtyWidth = dirtyX2 - dirtyX;\n const dirtyHeight = dirtyY2 - dirtyY;\n localContext.putImageData(\n imageData,\n 0,\n 0,\n dirtyX - 1,\n dirtyY - 1,\n dirtyWidth + 2,\n dirtyHeight + 2\n );\n context.drawImage(\n canvas,\n dirtyX,\n dirtyY,\n dirtyWidth,\n dirtyHeight,\n dirtyX,\n dirtyY,\n dirtyWidth,\n dirtyHeight\n );\n }\n\n public render(viewport: IViewport, context: CanvasRenderingContext2D): void {\n if (!this.visibility) {\n return;\n }\n const image = this.image || this.getImage();\n\n const { width, height } = image;\n\n const data = image.getScalarData();\n if (!data) {\n return;\n }\n const { voxelManager } = image;\n if (voxelManager) {\n if (voxelManager.map.getRun) {\n return this.renderRLE(viewport, context, voxelManager);\n }\n }\n let { canvas } = this;\n if (!canvas || canvas.width !== width || canvas.height !== height) {\n this.canvas = canvas = new window.OffscreenCanvas(width, height);\n }\n const localContext = canvas.getContext('2d');\n const imageData = localContext.createImageData(width, height);\n const { data: imageArray } = imageData;\n let offset = 0;\n let destOffset = 0;\n let dirtyX = Infinity;\n let dirtyY = Infinity;\n let dirtyX2 = -Infinity;\n let dirtyY2 = -Infinity;\n for (let y = 0; y < height; y++) {\n for (let x = 0; x < width; x++) {\n // const destOffset = (x + y * width) * 4;\n const segmentIndex = data[offset++];\n if (segmentIndex) {\n dirtyX = Math.min(x, dirtyX);\n dirtyY = Math.min(y, dirtyY);\n dirtyX2 = Math.max(x, dirtyX2);\n dirtyY2 = Math.max(y, dirtyY2);\n const rgb = this.canvasProperties.getColor(segmentIndex);\n imageArray[destOffset] = rgb[0] * 255;\n imageArray[destOffset + 1] = rgb[1] * 255;\n imageArray[destOffset + 2] = rgb[2] * 255;\n imageArray[destOffset + 3] = 127;\n // imageArray.fill(55, offset, offset + 4);\n }\n destOffset += 4;\n }\n }\n\n if (dirtyX > width) {\n return;\n }\n const dirtyWidth = dirtyX2 - dirtyX + 1;\n const dirtyHeight = dirtyY2 - dirtyY + 1;\n localContext.putImageData(\n imageData,\n 0,\n 0,\n dirtyX,\n dirtyY,\n dirtyWidth,\n dirtyHeight\n );\n context.drawImage(\n canvas,\n dirtyX,\n dirtyY,\n dirtyWidth,\n dirtyHeight,\n dirtyX,\n dirtyY,\n dirtyWidth,\n dirtyHeight\n );\n }\n\n public getClassName() {\n return this.className;\n }\n\n public getProperty() {\n return this.canvasProperties;\n }\n\n public setVisibility(visibility: boolean) {\n this.visibility = visibility;\n }\n\n public getMapper() {\n return this.mapper;\n }\n\n public isA(actorType) {\n return actorType === this.className;\n }\n\n public getImage() {\n if (this.image) {\n return this.image;\n }\n this.image = { ...this.derivedImage };\n const imageData = this.viewport.getImageData();\n Object.assign(this.image, {\n worldToIndex: (worldPos) => imageData.imageData.worldToIndex(worldPos),\n indexToWorld: (index, destPoint) =>\n imageData.imageData.indexToWorld(index, destPoint),\n getDimensions: () => imageData.dimensions,\n getScalarData: () => this.derivedImage?.getPixelData(),\n getDirection: () => imageData.direction,\n getSpacing: () => imageData.spacing,\n setOrigin: () => null,\n /**\n * Stores the new image cache data to update the image object, and sets\n * the image instance (this object) to null so that the next getImage\n * refreshes the display.\n */\n setDerivedImage: (image) => {\n this.derivedImage = image;\n this.image = null;\n },\n modified: () => null,\n });\n return this.image;\n }\n}\n","import { vec3 } from 'gl-matrix';\nimport {\n Events as EVENTS,\n VideoEnums as VideoViewportEnum,\n MetadataModules,\n} from '../enums';\nimport type {\n IVideoViewport,\n VideoViewportProperties,\n Point3,\n Point2,\n ICamera,\n InternalVideoCamera,\n VideoViewportInput,\n VOIRange,\n ICanvasActor,\n IImage,\n ViewReferenceSpecifier,\n ViewReference,\n ReferenceCompatibleOptions,\n} from '../types';\nimport * as metaData from '../metaData';\nimport { Transform } from './helpers/cpuFallback/rendering/transform';\nimport { triggerEvent } from '../utilities';\nimport Viewport from './Viewport';\nimport { getOrCreateCanvas } from './helpers';\nimport CanvasActor from './CanvasActor';\nimport cache from '../cache';\n\n/**\n * A data type for the scalar data for video data.\n */\nexport type CanvasScalarData = Uint8ClampedArray & {\n frameNumber?: number;\n getRange?: () => [number, number];\n};\n\n/**\n * An object representing a single stack viewport, which is a camera\n * looking into an internal scene, and an associated target output `canvas`.\n */\nclass VideoViewport extends Viewport implements IVideoViewport {\n public static frameRangeExtractor = /(\\/frames\\/|[&?]frameNumber=)([^/&?]*)/i;\n\n public modality;\n // Viewport Data\n protected imageId: string;\n readonly uid;\n readonly renderingEngineId: string;\n readonly canvasContext: CanvasRenderingContext2D;\n private videoElement?: HTMLVideoElement;\n private videoWidth = 0;\n private videoHeight = 0;\n\n private loop = true;\n private mute = true;\n private isPlaying = false;\n private scrollSpeed = 1;\n private playbackRate = 1;\n private scalarData: CanvasScalarData;\n\n /**\n * This is used to pause initially so that we get at least one render to allow\n * navigating frames. Otherwise the viewport is blank initially until the user\n * hits play manually.\n */\n private initialRender: () => void;\n\n /**\n * The range is the set of frames to play\n */\n private frameRange: [number, number] = [0, 0];\n\n protected metadata;\n\n /**\n * The fps, frames per second is used to calculate time/frame mapping values.\n * It is provided by the CINE Module in the metadata, defaulting to 30 if not\n * provided.\n */\n private fps = 30;\n\n /** The number of frames in the video */\n private numberOfFrames = 0;\n\n private videoCamera: InternalVideoCamera = {\n panWorld: [0, 0],\n parallelScale: 1,\n };\n\n /**\n * feFilter is an inline string value for the CSS filter on the video\n * CSS filters can reference SVG filters, so for the typical use case here\n * the CSS filter is actually an link link to a SVG filter.\n */\n private feFilter: string;\n\n /**\n * An average white point value, used to color balance the image so that\n * the given white is mapped to [255,255,255] via multiplication per channel.\n */\n private averageWhite: [number, number, number];\n\n /**\n * The VOI Range is used to apply contrast/brightness adjustments to the image.\n */\n private voiRange: VOIRange = {\n lower: 0,\n upper: 255,\n };\n\n constructor(props: VideoViewportInput) {\n super({\n ...props,\n canvas: props.canvas || getOrCreateCanvas(props.element),\n });\n this.canvasContext = this.canvas.getContext('2d');\n this.renderingEngineId = props.renderingEngineId;\n\n this.element.setAttribute('data-viewport-uid', this.id);\n this.element.setAttribute(\n 'data-rendering-engine-uid',\n this.renderingEngineId\n );\n\n this.videoElement = document.createElement('video');\n this.videoElement.muted = this.mute;\n this.videoElement.loop = this.loop;\n this.videoElement.autoplay = true;\n this.videoElement.crossOrigin = 'anonymous';\n\n this.addEventListeners();\n this.resize();\n }\n\n public static get useCustomRenderingPipeline() {\n return true;\n }\n\n private addEventListeners() {\n this.canvas.addEventListener(\n EVENTS.ELEMENT_DISABLED,\n this.elementDisabledHandler\n );\n }\n\n private removeEventListeners() {\n this.canvas.removeEventListener(\n EVENTS.ELEMENT_DISABLED,\n this.elementDisabledHandler\n );\n }\n\n private elementDisabledHandler() {\n this.removeEventListeners();\n this.videoElement.remove();\n }\n\n public getImageDataMetadata(image: IImage | string) {\n const imageId = typeof image === 'string' ? image : image.imageId;\n const imagePlaneModule = metaData.get(MetadataModules.IMAGE_PLANE, imageId);\n\n let rowCosines = <Point3>imagePlaneModule.rowCosines;\n let columnCosines = <Point3>imagePlaneModule.columnCosines;\n\n // if null or undefined\n if (rowCosines == null || columnCosines == null) {\n rowCosines = <Point3>[1, 0, 0];\n columnCosines = <Point3>[0, 1, 0];\n }\n\n const rowCosineVec = vec3.fromValues(\n rowCosines[0],\n rowCosines[1],\n rowCosines[2]\n );\n const colCosineVec = vec3.fromValues(\n columnCosines[0],\n columnCosines[1],\n columnCosines[2]\n );\n\n const { rows, columns } = imagePlaneModule;\n const scanAxisNormal = vec3.create();\n vec3.cross(scanAxisNormal, rowCosineVec, colCosineVec);\n\n let origin = imagePlaneModule.imagePositionPatient;\n // if null or undefined\n if (origin == null) {\n origin = [0, 0, 0];\n }\n\n const xSpacing = imagePlaneModule.columnPixelSpacing || 1;\n const ySpacing = imagePlaneModule.rowPixelSpacing || 1;\n const xVoxels = imagePlaneModule.columns;\n const yVoxels = imagePlaneModule.rows;\n\n const zSpacing = 1;\n const zVoxels = 1;\n\n this.hasPixelSpacing = !!imagePlaneModule.columnPixelSpacing;\n return {\n bitsAllocated: 8,\n numComps: 3,\n origin,\n rows,\n columns,\n direction: [...rowCosineVec, ...colCosineVec, ...scanAxisNormal],\n dimensions: [xVoxels, yVoxels, zVoxels],\n spacing: [xSpacing, ySpacing, zSpacing],\n hasPixelSpacing: this.hasPixelSpacing,\n numVoxels: xVoxels * yVoxels * zVoxels,\n imagePlaneModule,\n };\n }\n\n /**\n * Sets the video image id to show and hte frame number.\n * Requirements are to have the imageUrlModule in the metadata\n * with the rendered endpoint being the raw video in video/mp4 format.\n */\n public setVideo(imageId: string, frameNumber?: number): Promise<unknown> {\n this.imageId = Array.isArray(imageId) ? imageId[0] : imageId;\n const { rendered } = metaData.get(MetadataModules.IMAGE_URL, imageId);\n const generalSeries = metaData.get(MetadataModules.GENERAL_SERIES, imageId);\n this.modality = generalSeries?.Modality;\n this.metadata = this.getImageDataMetadata(imageId);\n\n return this.setVideoURL(rendered).then(() => {\n let { cineRate, numberOfFrames } = metaData.get(\n MetadataModules.CINE,\n imageId\n );\n if (!numberOfFrames) {\n numberOfFrames = Math.round(\n this.videoElement.duration * (cineRate || 30)\n );\n }\n if (!cineRate) {\n cineRate = Math.round(numberOfFrames / this.videoElement.duration);\n }\n this.fps = cineRate;\n this.numberOfFrames = numberOfFrames;\n // 1 based range setting\n this.setFrameRange([1, numberOfFrames]);\n // The initial render allows us to set the frame position - rendering needs\n // to start already playing\n this.initialRender = () => {\n this.initialRender = null;\n this.pause();\n this.setFrameNumber(frameNumber || 1);\n };\n\n // This is ugly, but without it, the video often fails to render initially\n // so having a play, followed by a pause fixes things.\n // 25 ms is a tested value that seems to work to prevent exceptions\n return new Promise((resolve) => {\n window.setTimeout(() => {\n this.setFrameNumber(frameNumber || 1);\n resolve(this);\n }, 25);\n });\n });\n }\n\n public async setVideoURL(videoURL: string) {\n return new Promise((resolve) => {\n this.videoElement.src = videoURL;\n this.videoElement.preload = 'auto';\n\n const loadedMetadataEventHandler = () => {\n this.videoWidth = this.videoElement.videoWidth;\n this.videoHeight = this.videoElement.videoHeight;\n this.videoElement.removeEventListener(\n 'loadedmetadata',\n loadedMetadataEventHandler\n );\n\n this.refreshRenderValues();\n\n resolve(true);\n };\n\n this.videoElement.addEventListener(\n 'loadedmetadata',\n loadedMetadataEventHandler\n );\n });\n }\n\n /**\n * Gets all the image ids associated with this video element. This will\n * have # of frames elements.\n */\n public getImageIds(): string[] {\n const imageIds = new Array<string>(this.numberOfFrames);\n const baseImageId = this.imageId.replace(/[0-9]+$/, '');\n for (let i = 0; i < this.numberOfFrames; i++) {\n imageIds[i] = `${baseImageId}${i + 1}`;\n }\n return imageIds;\n }\n\n public togglePlayPause(): boolean {\n if (this.isPlaying) {\n this.pause();\n return false;\n } else {\n this.play();\n return true;\n }\n }\n\n public async play() {\n try {\n if (!this.isPlaying) {\n // Play returns a promise that is true when playing completes.\n await this.videoElement.play();\n this.isPlaying = true;\n this.renderWhilstPlaying();\n }\n } catch (e) {\n // No-op, an exception sometimes gets thrown on the initial play, not\n // quite sure why. Catching it prevents displaying an error\n }\n }\n\n public async pause() {\n try {\n await this.videoElement.pause();\n this.isPlaying = false;\n } catch (e) {\n // No-op - sometimes this happens on startup\n }\n }\n\n public async scroll(delta = 1) {\n await this.pause();\n\n const videoElement = this.videoElement;\n const renderFrame = this.renderFrame;\n\n const currentTime = videoElement.currentTime;\n const newTime = currentTime + (delta * this.scrollSpeed) / this.fps;\n\n videoElement.currentTime = newTime;\n\n // Need to wait for seek update\n const seekEventListener = (evt) => {\n renderFrame();\n\n videoElement.removeEventListener('seeked', seekEventListener);\n };\n\n videoElement.addEventListener('seeked', seekEventListener);\n }\n\n public async start() {\n const videoElement = this.videoElement;\n const renderFrame = this.renderFrame;\n\n videoElement.currentTime = 0;\n\n if (videoElement.paused) {\n // Need to wait for seek update\n const seekEventListener = (evt) => {\n renderFrame();\n\n videoElement.removeEventListener('seeked', seekEventListener);\n };\n\n videoElement.addEventListener('seeked', seekEventListener);\n }\n }\n\n public async end() {\n const videoElement = this.videoElement;\n const renderFrame = this.renderFrame;\n\n videoElement.currentTime = videoElement.duration;\n\n if (videoElement.paused) {\n // Need to wait for seek update\n const seekEventListener = (evt) => {\n renderFrame();\n\n videoElement.removeEventListener('seeked', seekEventListener);\n };\n\n videoElement.addEventListener('seeked', seekEventListener);\n }\n }\n\n public async setTime(timeInSeconds: number) {\n const videoElement = this.videoElement;\n const renderFrame = this.renderFrame;\n\n videoElement.currentTime = timeInSeconds;\n\n if (videoElement.paused) {\n // Need to wait for seek update\n const seekEventListener = (evt) => {\n renderFrame();\n\n videoElement.removeEventListener('seeked', seekEventListener);\n };\n\n videoElement.addEventListener('seeked', seekEventListener);\n }\n }\n\n // Sets the frame number - note according to DICOM, this is 1 based\n public async setFrameNumber(frame: number) {\n this.setTime((frame - 1) / this.fps);\n }\n\n /**\n * Sets the playback frame range. The video will play over the given set\n * of frames (assuming it is playing).\n * @param frameRange - the minimum to maximum (inclusive) frames to play over\n * @returns\n */\n public setFrameRange(frameRange: number[]) {\n if (!frameRange) {\n this.frameRange = [1, this.numberOfFrames];\n return;\n }\n if (frameRange.length !== 2 || frameRange[0] === frameRange[1]) {\n return;\n }\n this.frameRange = [frameRange[0], frameRange[1]];\n }\n\n public getFrameRange(): [number, number] {\n return this.frameRange;\n }\n\n public setProperties(props: VideoViewportProperties) {\n if (props.loop !== undefined) {\n this.videoElement.loop = props.loop;\n }\n\n if (props.muted !== undefined) {\n this.videoElement.muted = props.muted;\n }\n\n if (props.playbackRate !== undefined) {\n this.setPlaybackRate(props.playbackRate);\n }\n\n if (props.scrollSpeed !== undefined) {\n this.setScrollSpeed(props.scrollSpeed);\n }\n\n if (props.voiRange) {\n this.setVOI(props.voiRange);\n }\n }\n\n public setPlaybackRate(rate = 1) {\n this.playbackRate = rate;\n // Minimum playback speed in chrome is 0.0625 compared to normal\n if (rate < 0.0625) {\n this.pause();\n return;\n }\n if (!this.videoElement) {\n return;\n }\n this.videoElement.playbackRate = rate;\n this.play();\n }\n\n public setScrollSpeed(\n scrollSpeed = 1,\n unit = VideoViewportEnum.SpeedUnit.FRAME\n ) {\n this.scrollSpeed =\n unit === VideoViewportEnum.SpeedUnit.SECOND\n ? scrollSpeed * this.fps\n : scrollSpeed;\n }\n\n public getProperties = (): VideoViewportProperties => {\n return {\n loop: this.videoElement.loop,\n muted: this.videoElement.muted,\n playbackRate: this.playbackRate,\n scrollSpeed: this.scrollSpeed,\n voiRange: { ...this.voiRange },\n };\n };\n\n public resetProperties() {\n this.setProperties({\n loop: false,\n muted: true,\n });\n }\n\n protected getScalarData(): CanvasScalarData {\n if (this.scalarData?.frameNumber === this.getFrameNumber()) {\n return this.scalarData;\n }\n const canvas = document.createElement('canvas');\n canvas.width = this.videoWidth;\n canvas.height = this.videoHeight;\n const context = canvas.getContext('2d');\n context.drawImage(this.videoElement, 0, 0);\n const canvasData = context.getImageData(\n 0,\n 0,\n this.videoWidth,\n this.videoHeight\n );\n const scalarData = canvasData.data as CanvasScalarData;\n scalarData.getRange = () => [0, 255];\n scalarData.frameNumber = this.getFrameNumber();\n this.scalarData = scalarData;\n return scalarData;\n }\n\n public getImageData() {\n const { metadata } = this;\n\n const spacing = metadata.spacing;\n\n const imageData = {\n dimensions: metadata.dimensions,\n spacing,\n origin: metadata.origin,\n direction: metadata.direction,\n metadata: { Modality: this.modality },\n getScalarData: () => this.getScalarData(),\n imageData: {\n getDirection: () => metadata.direction,\n getDimensions: () => metadata.dimensions,\n getRange: () => [0, 255],\n getScalarData: () => this.getScalarData(),\n getSpacing: () => metadata.spacing,\n worldToIndex: (point: Point3) => {\n const canvasPoint = this.worldToCanvas(point);\n const pixelCoord = this.canvasToIndex(canvasPoint);\n return [pixelCoord[0], pixelCoord[1], 0];\n },\n indexToWorld: (point: Point2, destPoint?: Point3) => {\n const canvasPoint = this.indexToCanvas([point[0], point[1]]);\n return this.canvasToWorld(canvasPoint, destPoint);\n },\n },\n hasPixelSpacing: this.hasPixelSpacing,\n calibration: this.calibration,\n preScale: {\n scaled: false,\n },\n };\n Object.defineProperty(imageData, 'scalarData', {\n get: () => this.getScalarData(),\n enumerable: true,\n });\n return imageData;\n }\n\n /**\n * Checks to see if the imageURI is currently being displayed. The imageURI\n * may contain frame numbers according to the DICOM standard format, which\n * will be stripped to compare the base image URI, and then the values used\n * to check if that frame is currently being displayed.\n *\n * The DICOM standard allows for comma separated values as well, however,\n * this is not supported here, with only a single range or single value\n * being tested.\n *\n * For a single value, the time range +/- 5 frames is permitted to allow\n * the detection to actually succeed when nearby without requiring an exact\n * time frame to be matched.\n *\n * @param imageURI - containing frame number or range.\n * @returns\n */\n public hasImageURI(imageURI: string) {\n // TODO - move annotationFrameRange into core so it can be used here.\n const framesMatch = imageURI.match(VideoViewport.frameRangeExtractor);\n const testURI = framesMatch\n ? imageURI.substring(0, framesMatch.index)\n : imageURI;\n return this.imageId.indexOf(testURI) !== -1;\n }\n\n public setVOI(voiRange: VOIRange): void {\n this.voiRange = voiRange;\n this.setColorTransform();\n }\n\n public setWindowLevel(windowWidth = 256, windowCenter = 128) {\n const lower = windowCenter - windowWidth / 2;\n const upper = windowCenter + windowWidth / 2 - 1;\n this.setVOI({ lower, upper });\n this.setColorTransform();\n }\n\n public setAverageWhite(averageWhite: [number, number, number]) {\n this.averageWhite = averageWhite;\n this.setColorTransform();\n }\n\n protected setColorTransform() {\n if (!this.voiRange && !this.averageWhite) {\n this.feFilter = null;\n return;\n }\n const white = this.averageWhite || [255, 255, 255];\n const maxWhite = Math.max(...white);\n const scaleWhite = white.map((c) => maxWhite / c);\n const { lower = 0, upper = 255 } = this.voiRange || {};\n const wlScale = (upper - lower + 1) / 255;\n const wlDelta = lower / 255;\n this.feFilter = `url('data:image/svg+xml,\\\n <svg xmlns=\"http://www.w3.org/2000/svg\">\\\n <filter id=\"colour\" color-interpolation-filters=\"linearRGB\">\\\n <feColorMatrix type=\"matrix\" \\\n values=\"\\\n ${scaleWhite[0] * wlScale} 0 0 0 ${wlDelta} \\\n 0 ${scaleWhite[1] * wlScale} 0 0 ${wlDelta} \\\n 0 0 ${scaleWhite[2] * wlScale} 0 ${wlDelta} \\\n 0 0 0 1 0\" />\\\n </filter>\\\n </svg>#colour')`;\n\n this.canvas.style.filter = this.feFilter;\n }\n\n public setCamera(camera: ICamera): void {\n const { parallelScale, focalPoint } = camera;\n\n // NOTE: the parallel scale should be done first\n // because it affects the focal point later\n if (parallelScale) {\n this.videoCamera.parallelScale =\n this.element.clientHeight / 2 / parallelScale;\n }\n\n if (focalPoint !== undefined) {\n const focalPointCanvas = this.worldToCanvas(focalPoint);\n const canvasCenter: Point2 = [\n this.element.clientWidth / 2,\n this.element.clientHeight / 2,\n ];\n\n const panWorldDelta: Point2 = [\n (focalPointCanvas[0] - canvasCenter[0]) /\n this.videoCamera.parallelScale,\n (focalPointCanvas[1] - canvasCenter[1]) /\n this.videoCamera.parallelScale,\n ];\n\n this.videoCamera.panWorld = [\n this.videoCamera.panWorld[0] - panWorldDelta[0],\n this.videoCamera.panWorld[1] - panWorldDelta[1],\n ];\n }\n\n this.canvasContext.fillStyle = 'rgba(0,0,0,1)';\n this.canvasContext.fillRect(0, 0, this.canvas.width, this.canvas.height);\n\n if (this.isPlaying === false) {\n this.renderFrame();\n }\n }\n\n /**\n * This function returns the imageID associated with either the current\n * frame being displayed, or the range of frames being played. This may not\n * correspond to any particular imageId that has imageId metadata, as the\n * format is one of:\n * `<DICOMweb URI>/frames/<Start Frame>(-<End Frame>)?`\n * or\n * `<Other URI>[?&]frameNumber=<Start Frame>(-<EndFrame>)?`\n * for a URL parameter.\n *\n * @returns an imageID for video\n */\n public getCurrentImageId() {\n const current = this.imageId.replace(\n '/frames/1',\n this.isPlaying\n ? `/frames/${this.frameRange[0]}-${this.frameRange[1]}`\n : `/frames/${this.getFrameNumber()}`\n );\n return current;\n }\n\n /**\n * Gets a target id that can be used to specify how to show this\n */\n public getReferenceId(specifier: ViewReferenceSpecifier = {}): string {\n const { sliceIndex: sliceIndex } = specifier;\n if (sliceIndex === undefined) {\n return `videoId:${this.getCurrentImageId()}`;\n }\n if (Array.isArray(sliceIndex)) {\n // Just remove the 1 from the end of the base URL - TODO, handle other types\n return `videoId:${this.imageId.substring(0, this.imageId.length - 1)}${\n sliceIndex[0] + 1\n }-${sliceIndex[1] + 1}`;\n }\n const baseTarget = this.imageId.replace(\n '/frames/1',\n `/frames/${1 + sliceIndex}`\n );\n return `videoId:${baseTarget}`;\n }\n\n /**\n * Figure out if a given view can be shown in the current viewport.\n */\n public isReferenceViewable(\n viewRef: ViewReference,\n options: ReferenceCompatibleOptions = {}\n ): boolean {\n let { imageURI } = options;\n const { referencedImageId, sliceIndex: sliceIndex } = viewRef;\n if (!super.isReferenceViewable(viewRef)) {\n return false;\n }\n\n const imageId = this.getCurrentImageId();\n if (!imageURI) {\n // Remove the dataLoader scheme and frame number\n // TODO - handle more imageURI types.\n const colonIndex = imageId.indexOf(':');\n imageURI = imageId.substring(colonIndex + 1, imageId.length - 1);\n }\n\n if (options.withNavigation) {\n return true;\n }\n const currentIndex = this.getSliceIndex();\n if (Array.isArray(sliceIndex)) {\n return currentIndex >= sliceIndex[0] && currentIndex <= sliceIndex[1];\n }\n if (sliceIndex !== undefined) {\n return currentIndex === sliceIndex;\n }\n if (!referencedImageId) {\n return false;\n }\n const match = referencedImageId.match(VideoViewport.frameRangeExtractor);\n if (!match || !match[2]) {\n return true;\n }\n const range = match[2].split('-').map((it) => Number(it));\n const frame = currentIndex + 1;\n return range[0] <= frame && frame <= (range[1] ?? range[0]);\n }\n\n /**\n * Gets a view target that species what type of view is required to show\n * the current view, or the one specified in the forTarget modifiers.\n */\n public getViewReference(\n viewRefSpecifier?: ViewReferenceSpecifier\n ): ViewReference {\n let sliceIndex = viewRefSpecifier?.sliceIndex;\n if (!sliceIndex) {\n sliceIndex = this.isPlaying\n ? [this.frameRange[0] - 1, this.frameRange[1] - 1]\n : this.getCurrentImageIdIndex();\n }\n return {\n ...super.getViewReference(viewRefSpecifier),\n referencedImageId: this.getReferenceId(viewRefSpecifier),\n sliceIndex: sliceIndex,\n };\n }\n\n /**\n * Gets the 1 based frame number (ala DICOM value), eg `1+ currentImageIdIndex`\n */\n public getFrameNumber() {\n // Need to round this as the fps/time isn't exact\n return 1 + this.getCurrentImageIdIndex();\n }\n\n public getCurrentImageIdIndex() {\n return Math.round(this.videoElement.currentTime * this.fps);\n }\n\n public getSliceIndex() {\n return this.getCurrentImageIdIndex();\n }\n\n public getCamera(): ICamera {\n const { parallelScale } = this.videoCamera;\n\n const canvasCenter: Point2 = [\n this.element.clientWidth / 2,\n this.element.clientHeight / 2,\n ];\n\n // All other viewports have the focal point in canvas coordinates in the center\n // of the canvas, so to make tools work the same, we need to do the same here\n // and convert to the world coordinate system since focal point is in world coordinates.\n const canvasCenterWorld = this.canvasToWorld(canvasCenter);\n\n return {\n parallelProjection: true,\n focalPoint: canvasCenterWorld,\n position: [0, 0, 0],\n viewUp: [0, -1, 0],\n parallelScale: this.element.clientHeight / 2 / parallelScale, // Reverse zoom direction back\n viewPlaneNormal: [0, 0, 1],\n };\n }\n\n public resetCamera = (): boolean => {\n this.refreshRenderValues();\n\n this.canvasContext.fillRect(0, 0, this.canvas.width, this.canvas.height);\n\n if (this.isPlaying === false) {\n // If its not replaying, just re-render the frame on move.\n this.renderFrame();\n }\n return true;\n };\n\n public getNumberOfSlices = (): number => {\n return Math.round(\n (this.videoElement.duration * this.fps) / this.scrollSpeed\n );\n };\n\n public getFrameOfReferenceUID = (): string => {\n // The video itself is the frame of reference.\n return this.videoElement.src;\n };\n\n public resize = (): void => {\n const canvas = this.canvas;\n const { clientWidth, clientHeight } = canvas;\n\n // Set the canvas to be same resolution as the client.\n if (canvas.width !== clientWidth || canvas.height !== clientHeight) {\n canvas.width = clientWidth;\n canvas.height = clientHeight;\n }\n\n this.refreshRenderValues();\n\n if (this.isPlaying === false) {\n // If its not playing, just re-render on resize.\n this.renderFrame();\n }\n };\n\n /**\n * Converts a VideoViewport canvas coordinate to a video coordinate.\n *\n * @param canvasPos - to convert to world\n * @returns World position\n */\n public canvasToWorld = (\n canvasPos: Point2,\n destPos: Point3 = [0, 0, 0]\n ): Point3 => {\n const pan: Point2 = this.videoCamera.panWorld; // In world coordinates\n const worldToCanvasRatio: number = this.getWorldToCanvasRatio();\n\n const panOffsetCanvas: Point2 = [\n pan[0] * worldToCanvasRatio,\n pan[1] * worldToCanvasRatio,\n ];\n\n const subCanvasPos: Point2 = [\n canvasPos[0] - panOffsetCanvas[0],\n canvasPos[1] - panOffsetCanvas[1],\n ];\n\n // Replace the x,y values only in place in the world position\n // as the z is unchanging for video display\n destPos.splice(\n 0,\n 2,\n subCanvasPos[0] / worldToCanvasRatio,\n subCanvasPos[1] / worldToCanvasRatio\n );\n return destPos;\n };\n\n /**\n * Converts `[x, y, 0]` world video coordinate to canvas CSS coordinates.\n *\n * @param worldPos - world coord to convert to canvas\n * @returns Canvas position\n */\n public worldToCanvas = (worldPos: Point3): Point2 => {\n const pan: Point2 = this.videoCamera.panWorld;\n const worldToCanvasRatio: number = this.getWorldToCanvasRatio();\n\n const canvasPos: Point2 = [\n (worldPos[0] + pan[0]) * worldToCanvasRatio,\n (worldPos[1] + pan[1]) * worldToCanvasRatio,\n ];\n\n return canvasPos;\n };\n\n public getPan(): Point2 {\n const panWorld = this.videoCamera.panWorld;\n return [panWorld[0], panWorld[1]];\n }\n\n public getRotation = () => 0;\n\n /**\n * Uses the transform to convert canvas coordinates into index coordinates.\n */\n protected canvasToIndex = (canvasPos: Point2): Point2 => {\n const transform = this.getTransform();\n transform.invert();\n\n return transform.transformPoint(\n <Point2>canvasPos.map((it) => it * devicePixelRatio)\n );\n };\n\n protected indexToCanvas = (indexPos: Point2): Point2 => {\n const transform = this.getTransform();\n return <Point2>(\n transform.transformPoint(indexPos).map((it) => it / devicePixelRatio)\n );\n };\n\n /**\n * Sets initial video camera to center the image area. The values\n * are set in canvas CSS pixel units and NOT in canvas index units.\n */\n private refreshRenderValues() {\n // this means that each unit (pixel) in the world (video) would be\n // represented by n pixels in the canvas, measured in css pixels\n let worldToCanvasRatio = this.canvas.offsetWidth / this.videoWidth;\n\n if (this.videoHeight * worldToCanvasRatio > this.canvas.height) {\n // If by fitting the width, we exceed the height of the viewport, then we need to decrease the\n // size of the viewport further by considering its verticality.\n worldToCanvasRatio = this.canvas.offsetHeight / this.videoHeight;\n }\n\n // Set the width as big as possible, this is the portion of the canvas\n // that the video will occupy.\n const drawWidth = Math.floor(this.videoWidth * worldToCanvasRatio);\n const drawHeight = Math.floor(this.videoHeight * worldToCanvasRatio);\n\n // calculate x and y offset in order to center the image\n const xOffsetCanvas = (this.canvas.offsetWidth - drawWidth) / 2;\n const yOffsetCanvas = (this.canvas.offsetHeight - drawHeight) / 2;\n\n const xOffsetWorld = xOffsetCanvas / worldToCanvasRatio;\n const yOffsetWorld = yOffsetCanvas / worldToCanvasRatio;\n\n this.videoCamera.panWorld = [xOffsetWorld, yOffsetWorld];\n this.videoCamera.parallelScale = worldToCanvasRatio;\n }\n\n private getWorldToCanvasRatio() {\n return this.videoCamera.parallelScale;\n }\n\n private getCanvasToWorldRatio() {\n return 1.0 / this.videoCamera.parallelScale;\n }\n\n public customRenderViewportToCanvas = () => {\n this.renderFrame();\n };\n\n /**\n * Creates a transform from video index coordinates to canvas coordinates.\n */\n protected getTransform() {\n const panWorld: Point2 = this.videoCamera.panWorld;\n const devicePixelRatio = window.devicePixelRatio || 1;\n const worldToCanvasRatio: number = this.getWorldToCanvasRatio();\n const canvasToWorldRatio: number = this.getCanvasToWorldRatio();\n const halfCanvas = [\n this.canvas.offsetWidth / 2,\n this.canvas.offsetHeight / 2,\n ];\n const halfCanvasWorldCoordinates = [\n halfCanvas[0] * canvasToWorldRatio,\n halfCanvas[1] * canvasToWorldRatio,\n ];\n const transform = new Transform();\n\n // Start by converting into canvas index coordinates FROM canvas css pixel coordinates\n transform.scale(devicePixelRatio, devicePixelRatio);\n\n // Translate to the center of the canvas (move origin of the transform\n // to the center of the canvas)\n transform.translate(halfCanvas[0], halfCanvas[1]);\n\n // Scale\n transform.scale(worldToCanvasRatio, worldToCanvasRatio);\n\n // Apply the translation\n transform.translate(panWorld[0], panWorld[1]);\n\n // Translate back\n transform.translate(\n -halfCanvasWorldCoordinates[0],\n -halfCanvasWorldCoordinates[1]\n );\n return transform;\n }\n\n /**\n * Nothing to do for the clipping planes for video as they don't exist.\n */\n public updateCameraClippingPlanesAndRange() {\n // No-op\n }\n\n public addImages(stackInputs: Array<any>) {\n const actors = this.getActors();\n stackInputs.forEach((stackInput) => {\n const image = cache.getImage(stackInput.imageId);\n\n const imageActor = this.createActorMapper(image);\n if (imageActor) {\n actors.push({ uid: stackInput.actorUID, actor: imageActor });\n if (stackInput.callback) {\n stackInput.callback({ imageActor, imageId: stackInput.imageId });\n }\n }\n });\n this.setActors(actors);\n }\n\n protected createActorMapper(image) {\n return new CanvasActor(this, image);\n }\n\n /**\n * Renders the video frame to the viewport.\n */\n private renderFrame = () => {\n const transform = this.getTransform();\n const transformationMatrix: number[] = transform.getMatrix();\n\n const ctx = this.canvasContext;\n\n ctx.resetTransform();\n\n // Need to correct the transform for device pixel ratio scaling.\n ctx.transform(\n transformationMatrix[0],\n transformationMatrix[1],\n transformationMatrix[2],\n transformationMatrix[3],\n transformationMatrix[4],\n transformationMatrix[5]\n );\n\n ctx.drawImage(this.videoElement, 0, 0, this.videoWidth, this.videoHeight);\n\n for (const actor of this.getActors()) {\n (actor.actor as ICanvasActor).render(this, this.canvasContext);\n }\n this.canvasContext.resetTransform();\n\n // This is stack new image to agree with stack/non-volume viewports\n triggerEvent(this.element, EVENTS.STACK_NEW_IMAGE, {\n element: this.element,\n viewportId: this.id,\n viewport: this,\n renderingEngineId: this.renderingEngineId,\n time: this.videoElement.currentTime,\n duration: this.videoElement.duration,\n });\n triggerEvent(this.element, EVENTS.IMAGE_RENDERED, {\n element: this.element,\n viewportId: this.id,\n viewport: this,\n renderingEngineId: this.renderingEngineId,\n time: this.videoElement.currentTime,\n duration: this.videoElement.duration,\n });\n\n this.initialRender?.();\n\n const frame = this.getFrameNumber();\n if (this.isPlaying) {\n if (frame < this.frameRange[0]) {\n this.setFrameNumber(this.frameRange[0]);\n } else if (frame > this.frameRange[1]) {\n if (this.loop) {\n this.setFrameNumber(this.frameRange[0]);\n } else {\n this.pause();\n }\n }\n }\n };\n\n private renderWhilstPlaying = () => {\n this.renderFrame();\n\n //wait approximately 16ms and run again\n if (this.isPlaying) {\n requestAnimationFrame(this.renderWhilstPlaying);\n }\n };\n}\n\nexport default VideoViewport;\n","// TODO -> Eventually we'll need to register to this list\nimport StackViewport from '../StackViewport';\nimport VolumeViewport from '../VolumeViewport';\nimport ViewportType from '../../enums/ViewportType';\nimport VolumeViewport3D from '../VolumeViewport3D';\nimport VideoViewport from '../VideoViewport';\n\nconst viewportTypeToViewportClass = {\n [ViewportType.ORTHOGRAPHIC]: VolumeViewport,\n [ViewportType.PERSPECTIVE]: VolumeViewport,\n [ViewportType.STACK]: StackViewport,\n [ViewportType.VOLUME_3D]: VolumeViewport3D,\n [ViewportType.VIDEO]: VideoViewport,\n};\n\nexport default viewportTypeToViewportClass;\n","import viewportTypeToViewportClass from './viewportTypeToViewportClass';\n\nexport default function viewportTypeUsesCustomRenderingPipeline(\n viewportType: string\n) {\n return viewportTypeToViewportClass[viewportType].useCustomRenderingPipeline;\n}\n","import RenderingEngine from './RenderingEngine';\nimport getRenderingEngine from './getRenderingEngine';\nimport VolumeViewport from './VolumeViewport';\nimport StackViewport from './StackViewport';\nimport VolumeViewport3D from './VolumeViewport3D';\nimport {\n createVolumeActor,\n createVolumeMapper,\n getOrCreateCanvas,\n} from './helpers';\n\nexport {\n getRenderingEngine,\n RenderingEngine,\n VolumeViewport,\n VolumeViewport3D,\n createVolumeActor,\n createVolumeMapper,\n getOrCreateCanvas,\n StackViewport,\n};\n\nexport default RenderingEngine;\n","import Events from '../enums/Events';\nimport renderingEngineCache from './renderingEngineCache';\nimport eventTarget from '../eventTarget';\nimport { triggerEvent, uuidv4 } from '../utilities';\nimport { vtkOffscreenMultiRenderWindow } from './vtkClasses';\nimport ViewportType from '../enums/ViewportType';\nimport VolumeViewport from './VolumeViewport';\nimport BaseVolumeViewport from './BaseVolumeViewport';\nimport StackViewport from './StackViewport';\nimport viewportTypeUsesCustomRenderingPipeline from './helpers/viewportTypeUsesCustomRenderingPipeline';\nimport getOrCreateCanvas from './helpers/getOrCreateCanvas';\nimport { getShouldUseCPURendering, isCornerstoneInitialized } from '../init';\nimport type IStackViewport from '../types/IStackViewport';\nimport type IVideoViewport from '../types/IVideoViewport';\nimport type IRenderingEngine from '../types/IRenderingEngine';\nimport type IVolumeViewport from '../types/IVolumeViewport';\nimport type { IViewport } from '../types/IViewport';\nimport VideoViewport from './VideoViewport';\nimport viewportTypeToViewportClass from './helpers/viewportTypeToViewportClass';\n\nimport type * as EventTypes from '../types/EventTypes';\nimport type {\n ViewportInput,\n PublicViewportInput,\n InternalViewportInput,\n NormalizedViewportInput,\n} from '../types/IViewport';\nimport { OrientationAxis } from '../enums';\nimport VolumeViewport3D from './VolumeViewport3D';\n\ntype ViewportDisplayCoords = {\n sxStartDisplayCoords: number;\n syStartDisplayCoords: number;\n sxEndDisplayCoords: number;\n syEndDisplayCoords: number;\n sx: number;\n sy: number;\n sWidth: number;\n sHeight: number;\n};\n\n// Rendering engines seem to not like rendering things less than 2 pixels per side\nconst VIEWPORT_MIN_SIZE = 2;\n\n/**\n * A RenderingEngine takes care of the full pipeline of creating viewports and rendering\n * them on a large offscreen canvas and transmitting this data back to the screen. This allows us\n * to leverage the power of vtk.js whilst only using one WebGL context for the processing, and allowing\n * us to share texture memory across on-screen viewports that show the same data.\n *\n *\n * Instantiating a rendering engine:\n * ```js\n * const renderingEngine = new RenderingEngine('pet-ct-rendering-engine');\n * ```\n *\n * There are various ways you can trigger a render on viewports. The simplest is to call `render()`\n * on the rendering engine; however, it will trigger a render on all viewports. A more efficient\n * way to do this is to call `renderViewports([viewportId])` on the rendering engine to\n * trigger a render on a specific viewport(s). Each viewport also has a `.render` method which can be used to trigger a render on that\n * viewport.\n *\n *\n * Rendering engine uses `detect-gpu` external library to detect if GPU is available and\n * it has minimum requirement to be able to render a volume with vtk.js. If GPU is not available\n * RenderingEngine will throw an error if you try to render a volume; however, for StackViewports\n * it is capable of falling back to CPU rendering for Stack images.\n *\n * By default RenderingEngine will use vtk.js enabled pipeline for rendering viewports,\n * however, if a custom rendering pipeline is specified by a custom viewport, it will be used instead.\n * We use this custom pipeline to render a StackViewport on CPU using Cornerstone-legacy cpu rendering pipeline.\n *\n * @public\n */\nclass RenderingEngine implements IRenderingEngine {\n /** Unique identifier for renderingEngine */\n readonly id: string;\n /** A flag which tells if the renderingEngine has been destroyed or not */\n public hasBeenDestroyed: boolean;\n public offscreenMultiRenderWindow: any;\n readonly offScreenCanvasContainer: any; // WebGL\n private _viewports: Map<string, IViewport>;\n private _needsRender: Set<string> = new Set();\n private _animationFrameSet = false;\n private _animationFrameHandle: number | null = null;\n private useCPURendering: boolean;\n\n /**\n * @param uid - Unique identifier for RenderingEngine\n */\n constructor(id?: string) {\n this.id = id ? id : uuidv4();\n this.useCPURendering = getShouldUseCPURendering();\n\n renderingEngineCache.set(this);\n\n if (!isCornerstoneInitialized()) {\n throw new Error(\n '@cornerstonejs/core is not initialized, run init() first'\n );\n }\n\n if (!this.useCPURendering) {\n this.offscreenMultiRenderWindow =\n vtkOffscreenMultiRenderWindow.newInstance();\n this.offScreenCanvasContainer = document.createElement('div');\n this.offscreenMultiRenderWindow.setContainer(\n this.offScreenCanvasContainer\n );\n }\n\n this._viewports = new Map();\n this.hasBeenDestroyed = false;\n }\n\n /**\n * Enables the requested viewport and add it to the viewports. It will\n * properly create the Stack viewport or Volume viewport:\n *\n * 1) Checks if the viewport is defined already, if yes, remove it first\n * 2) Checks if the viewport is using a custom rendering pipeline, if no,\n * it calculates a new offscreen canvas with the new requested viewport\n * 3) Adds the viewport\n *\n *\n * ```\n * renderingEngine.enableElement({\n * viewportId: viewportId,\n * type: ViewportType.ORTHOGRAPHIC,\n * element,\n * defaultOptions: {\n * orientation: Enums.OrientationAxis.AXIAL,\n * background: [1, 0, 1],\n * },\n * })\n * ```\n *\n * @fires Events.ELEMENT_ENABLED\n *\n * @param viewportInputEntry - viewport specifications\n */\n public enableElement(viewportInputEntry: PublicViewportInput): void {\n const viewportInput = this._normalizeViewportInputEntry(viewportInputEntry);\n\n this._throwIfDestroyed();\n const { element, viewportId } = viewportInput;\n\n // Throw error if no canvas\n if (!element) {\n throw new Error('No element provided');\n }\n\n // 1. Get the viewport from the list of available viewports.\n const viewport = this.getViewport(viewportId);\n\n // 1.a) If there is a found viewport, we remove the viewport and create a new viewport\n if (viewport) {\n this.disableElement(viewportId);\n }\n\n // 2.a) See if viewport uses a custom rendering pipeline.\n const { type } = viewportInput;\n\n const viewportUsesCustomRenderingPipeline =\n viewportTypeUsesCustomRenderingPipeline(type);\n\n // 2.b) Retrieving the list of viewports for calculation of the new size for\n // offScreen canvas.\n\n // If the viewport being added uses a custom pipeline, or we aren't using\n // GPU rendering, we don't need to resize the offscreen canvas.\n if (!this.useCPURendering && !viewportUsesCustomRenderingPipeline) {\n this.enableVTKjsDrivenViewport(viewportInput);\n } else {\n // 3 Add the requested viewport to rendering Engine\n this.addCustomViewport(viewportInput);\n }\n\n // 5. Set the background color for the canvas\n const canvas = getOrCreateCanvas(element);\n const { background } = viewportInput.defaultOptions;\n this.fillCanvasWithBackgroundColor(canvas, background);\n }\n\n /**\n * Disables the requested viewportId from the rendering engine:\n *\n * 1) It removes the viewport from the the list of viewports\n * 2) remove the renderer from the offScreen render window if using vtk.js driven\n * rendering pipeline\n * 3) resetting the viewport to remove the canvas attributes and canvas data\n * 4) resize the offScreen appropriately (if using vtk.js driven rendering pipeline)\n *\n * @fires Events.ELEMENT_ENABLED\n *\n * @param viewportId - viewport Id\n *\n */\n public disableElement(viewportId: string): void {\n this._throwIfDestroyed();\n // 1. Getting the viewport to remove it\n const viewport = this.getViewport(viewportId);\n\n // 2 To throw if there is no viewport stored in rendering engine\n if (!viewport) {\n console.warn(`viewport ${viewportId} does not exist`);\n return;\n }\n\n // 3. Reset the viewport to remove attributes, and reset the canvas\n this._resetViewport(viewport);\n\n // 4. Remove the related renderer from the offScreenMultiRenderWindow\n if (\n !viewportTypeUsesCustomRenderingPipeline(viewport.type) &&\n !this.useCPURendering\n ) {\n this.offscreenMultiRenderWindow.removeRenderer(viewportId);\n }\n\n // 5. Remove the requested viewport from the rendering engine\n this._removeViewport(viewportId);\n viewport.isDisabled = true;\n\n // 6. Avoid rendering for the disabled viewport\n this._needsRender.delete(viewportId);\n\n // 7. Clear RAF if no viewport is left\n const viewports = this.getViewports();\n if (!viewports.length) {\n this._clearAnimationFrame();\n }\n\n // Note: we should not call resize at the end of here, the reason is that\n // in batch rendering, we might disable a viewport and enable others at the same\n // time which would interfere with each other. So we just let the enable\n // to call resize, and also resize getting called by applications on the\n // DOM resize event.\n }\n\n /**\n * It takes an array of viewport input objects including element, viewportId, type\n * and defaultOptions. It will add the viewport to the rendering engine and enables them.\n *\n *\n * ```typescript\n *renderingEngine.setViewports([\n * {\n * viewportId: axialViewportId,\n * type: ViewportType.ORTHOGRAPHIC,\n * element: document.getElementById('axialDiv'),\n * defaultOptions: {\n * orientation: Enums.OrientationAxis.AXIAL,\n * },\n * },\n * {\n * viewportId: sagittalViewportId,\n * type: ViewportType.ORTHOGRAPHIC,\n * element: document.getElementById('sagittalDiv'),\n * defaultOptions: {\n * orientation: Enums.OrientationAxis.SAGITTAL,\n * },\n * },\n * {\n * viewportId: customOrientationViewportId,\n * type: ViewportType.ORTHOGRAPHIC,\n * element: document.getElementById('customOrientationDiv'),\n * defaultOptions: {\n * orientation: { viewPlaneNormal: [0, 0, 1], viewUp: [0, 1, 0] },\n * },\n * },\n * ])\n * ```\n *\n * @fires Events.ELEMENT_ENABLED\n *\n * @param viewportInputEntries - Array<PublicViewportInput>\n */\n\n public setViewports(\n publicViewportInputEntries: Array<PublicViewportInput>\n ): void {\n const viewportInputEntries = this._normalizeViewportInputEntries(\n publicViewportInputEntries\n );\n this._throwIfDestroyed();\n this._reset();\n\n // 1. Split viewports based on whether they use vtk.js or a custom pipeline.\n\n const vtkDrivenViewportInputEntries: NormalizedViewportInput[] = [];\n const customRenderingViewportInputEntries: NormalizedViewportInput[] = [];\n\n viewportInputEntries.forEach((vpie) => {\n if (\n !this.useCPURendering &&\n !viewportTypeUsesCustomRenderingPipeline(vpie.type)\n ) {\n vtkDrivenViewportInputEntries.push(vpie);\n } else {\n customRenderingViewportInputEntries.push(vpie);\n }\n });\n\n this.setVtkjsDrivenViewports(vtkDrivenViewportInputEntries);\n this.setCustomViewports(customRenderingViewportInputEntries);\n\n // Making sure the setViewports api also can fill the canvas\n // properly\n viewportInputEntries.forEach((vp) => {\n const canvas = getOrCreateCanvas(vp.element);\n const { background } = vp.defaultOptions;\n this.fillCanvasWithBackgroundColor(canvas, background);\n });\n }\n\n /**\n * Resizes the offscreen viewport and recalculates translations to on screen canvases.\n * It is up to the parent app to call the resize of the on-screen canvas changes.\n * This is left as an app level concern as one might want to debounce the changes, or the like.\n *\n * @param immediate - Whether all of the viewports should be rendered immediately.\n * @param keepCamera - Whether to keep the camera for other viewports while resizing the offscreen canvas\n */\n public resize(immediate = true, keepCamera = true): void {\n this._throwIfDestroyed();\n // 1. Get the viewports' canvases\n const viewports = this._getViewportsAsArray();\n\n const vtkDrivenViewports = [];\n const customRenderingViewports = [];\n\n viewports.forEach((vpie) => {\n if (!viewportTypeUsesCustomRenderingPipeline(vpie.type)) {\n vtkDrivenViewports.push(vpie);\n } else {\n customRenderingViewports.push(vpie);\n }\n });\n\n if (vtkDrivenViewports.length) {\n this._resizeVTKViewports(vtkDrivenViewports, keepCamera, immediate);\n }\n\n if (customRenderingViewports.length) {\n this._resizeUsingCustomResizeHandler(\n customRenderingViewports,\n keepCamera,\n immediate\n );\n }\n }\n\n /**\n * Returns the viewport by Id\n *\n * @returns viewport\n */\n public getViewport(viewportId: string): IViewport {\n return this._viewports.get(viewportId);\n }\n\n /**\n * getViewports Returns an array of all `Viewport`s on the `RenderingEngine` instance.\n *\n * @returns Array of viewports\n */\n public getViewports(): Array<IViewport> {\n this._throwIfDestroyed();\n\n return this._getViewportsAsArray();\n }\n\n /**\n * Filters all the available viewports and return the stack viewports\n * @returns stack viewports registered on the rendering Engine\n */\n public getStackViewports(): Array<IStackViewport> {\n this._throwIfDestroyed();\n\n const viewports = this.getViewports();\n\n const isStackViewport = (\n viewport: IViewport\n ): viewport is StackViewport => {\n return viewport instanceof StackViewport;\n };\n\n return viewports.filter(isStackViewport) as Array<IStackViewport>;\n }\n\n /**\n * Filters all the available viewports and return the stack viewports\n * @returns stack viewports registered on the rendering Engine\n */\n public getVideoViewports(): Array<IVideoViewport> {\n this._throwIfDestroyed();\n\n const viewports = this.getViewports();\n\n const isVideoViewport = (\n viewport: IViewport\n ): viewport is VideoViewport => {\n return viewport instanceof VideoViewport;\n };\n\n return viewports.filter(isVideoViewport) as Array<IVideoViewport>;\n }\n\n /**\n * Return all the viewports that are volume viewports\n * @returns An array of VolumeViewport objects.\n */\n public getVolumeViewports(): Array<IVolumeViewport> {\n this._throwIfDestroyed();\n\n const viewports = this.getViewports();\n\n const isVolumeViewport = (\n viewport: IViewport\n ): viewport is BaseVolumeViewport => {\n return viewport instanceof BaseVolumeViewport;\n };\n\n return viewports.filter(isVolumeViewport);\n }\n\n /**\n * Renders all viewports on the next animation frame.\n *\n * @fires Events.IMAGE_RENDERED\n */\n public render(): void {\n const viewports = this.getViewports();\n const viewportIds = viewports.map((vp) => vp.id);\n\n this._setViewportsToBeRenderedNextFrame(viewportIds);\n }\n\n /**\n * Renders any viewports viewing the given Frame Of Reference.\n *\n * @param FrameOfReferenceUID - The unique identifier of the\n * Frame Of Reference.\n */\n public renderFrameOfReference = (FrameOfReferenceUID: string): void => {\n const viewports = this._getViewportsAsArray();\n const viewportIdsWithSameFrameOfReferenceUID = viewports.map((vp) => {\n if (vp.getFrameOfReferenceUID() === FrameOfReferenceUID) {\n return vp.id;\n }\n });\n\n return this.renderViewports(viewportIdsWithSameFrameOfReferenceUID);\n };\n\n /**\n * Renders the provided Viewport IDs.\n *\n */\n public renderViewports(viewportIds: Array<string>): void {\n this._setViewportsToBeRenderedNextFrame(viewportIds);\n }\n\n /**\n * Renders only a specific `Viewport` on the next animation frame.\n *\n * @param viewportId - The Id of the viewport.\n */\n public renderViewport(viewportId: string): void {\n this._setViewportsToBeRenderedNextFrame([viewportId]);\n }\n\n /**\n * destroy the rendering engine. It will remove all the viewports and,\n * if the rendering engine is using the GPU, it will also destroy the GPU\n * resources.\n */\n public destroy(): void {\n if (this.hasBeenDestroyed) {\n return;\n }\n\n // remove vtk rendered first before resetting the viewport\n if (!this.useCPURendering) {\n const viewports = this._getViewportsAsArray();\n viewports.forEach((vp) => {\n this.offscreenMultiRenderWindow.removeRenderer(vp.id);\n });\n\n // Free up WebGL resources\n this.offscreenMultiRenderWindow.delete();\n\n // Make sure all references go stale and are garbage collected.\n delete this.offscreenMultiRenderWindow;\n }\n\n this._reset();\n renderingEngineCache.delete(this.id);\n\n this.hasBeenDestroyed = true;\n }\n\n /**\n * Fill the canvas with the background color\n * @param canvas - The canvas element to draw on.\n * @param backgroundColor - An array of three numbers between 0 and 1 that\n * specify the red, green, and blue values of the background color.\n */\n public fillCanvasWithBackgroundColor(\n canvas: HTMLCanvasElement,\n backgroundColor: [number, number, number]\n ): void {\n const ctx = canvas.getContext('2d');\n\n // Default to black if no background color is set\n let fillStyle;\n if (backgroundColor) {\n const rgb = backgroundColor.map((f) => Math.floor(255 * f));\n fillStyle = `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`;\n } else {\n fillStyle = 'black';\n }\n\n // We draw over the previous stack with the background color while we\n // wait for the next stack to load\n ctx.fillStyle = fillStyle;\n ctx.fillRect(0, 0, canvas.width, canvas.height);\n }\n\n private _normalizeViewportInputEntry(\n viewportInputEntry: PublicViewportInput\n ) {\n const { type, defaultOptions } = viewportInputEntry;\n let options = defaultOptions;\n\n if (!options || Object.keys(options).length === 0) {\n options = {\n background: [0, 0, 0],\n orientation: null,\n displayArea: null,\n };\n\n if (type === ViewportType.ORTHOGRAPHIC) {\n options = {\n ...options,\n orientation: OrientationAxis.AXIAL,\n };\n }\n }\n\n return {\n ...viewportInputEntry,\n defaultOptions: options,\n };\n }\n\n private _normalizeViewportInputEntries(\n viewportInputEntries: Array<PublicViewportInput>\n ): Array<NormalizedViewportInput> {\n const normalizedViewportInputs = [];\n\n viewportInputEntries.forEach((viewportInput) => {\n normalizedViewportInputs.push(\n this._normalizeViewportInputEntry(viewportInput)\n );\n });\n\n return normalizedViewportInputs;\n }\n\n private _resizeUsingCustomResizeHandler(\n customRenderingViewports: StackViewport[],\n keepCamera = true,\n immediate = true\n ) {\n // 1. If viewport has a custom resize method, call it here.\n customRenderingViewports.forEach((vp) => {\n if (typeof vp.resize === 'function') {\n vp.resize();\n }\n });\n\n // 3. Reset viewport cameras\n customRenderingViewports.forEach((vp) => {\n const prevCamera = vp.getCamera();\n vp.resetCamera();\n\n if (keepCamera) {\n vp.setCamera(prevCamera);\n }\n });\n\n // 2. If render is immediate: Render all\n if (immediate === true) {\n this.render();\n }\n }\n\n private _resizeVTKViewports(\n vtkDrivenViewports: Array<IStackViewport | IVolumeViewport>,\n keepCamera = true,\n immediate = true\n ) {\n // Ensure all the canvases are ready for rendering\n vtkDrivenViewports.forEach((vp: IStackViewport | IVolumeViewport) => {\n getOrCreateCanvas(vp.element);\n });\n const canvasesDrivenByVtkJs = vtkDrivenViewports.map((vp) => vp.canvas);\n\n if (canvasesDrivenByVtkJs.length) {\n // 1. Recalculate and resize the offscreen canvas size\n const { offScreenCanvasWidth, offScreenCanvasHeight } =\n this._resizeOffScreenCanvas(canvasesDrivenByVtkJs);\n\n // 2. Recalculate the viewports location on the off screen canvas\n this._resize(\n vtkDrivenViewports,\n offScreenCanvasWidth,\n offScreenCanvasHeight\n );\n }\n\n // 3. Reset viewport cameras\n vtkDrivenViewports.forEach((vp: IStackViewport | IVolumeViewport) => {\n const prevCamera = vp.getCamera();\n const rotation = vp.getRotation();\n const { flipHorizontal } = prevCamera;\n const resetPan = true;\n const resetZoom = true;\n const resetToCenter = true;\n const resetRotation = false;\n const supressEvents = true;\n vp.resetCamera(\n resetPan,\n resetZoom,\n resetToCenter,\n resetRotation,\n supressEvents\n );\n\n const displayArea = vp.getDisplayArea();\n\n // TODO - make this use get/set Presentation or in some way preserve the\n // basic presentation info on this viewport, rather than preserving camera\n if (keepCamera) {\n if (displayArea) {\n if (flipHorizontal) {\n vp.setCamera({ flipHorizontal });\n }\n if (rotation) {\n vp.setProperties({ rotation });\n }\n } else {\n vp.setCamera(prevCamera);\n }\n }\n });\n\n // 4. If render is immediate: Render all\n if (immediate === true) {\n this.render();\n }\n }\n\n /**\n * Enables a viewport to be driven by the offscreen vtk.js rendering engine.\n *\n * @param viewportInputEntry - Information object used to\n * construct and enable the viewport.\n */\n private enableVTKjsDrivenViewport(\n viewportInputEntry: NormalizedViewportInput\n ) {\n const viewports = this._getViewportsAsArray();\n const viewportsDrivenByVtkJs = viewports.filter(\n (vp) => viewportTypeUsesCustomRenderingPipeline(vp.type) === false\n );\n\n const canvasesDrivenByVtkJs = viewportsDrivenByVtkJs.map((vp) => vp.canvas);\n\n const canvas = getOrCreateCanvas(viewportInputEntry.element);\n canvasesDrivenByVtkJs.push(canvas);\n\n // 2.c Calculating the new size for offScreen Canvas\n const { offScreenCanvasWidth, offScreenCanvasHeight } =\n this._resizeOffScreenCanvas(canvasesDrivenByVtkJs);\n\n // 2.d Re-position previous viewports on the offScreen Canvas based on the new\n // offScreen canvas size\n const xOffset = this._resize(\n viewportsDrivenByVtkJs,\n offScreenCanvasWidth,\n offScreenCanvasHeight\n );\n\n const internalViewportEntry = { ...viewportInputEntry, canvas };\n\n // 3 Add the requested viewport to rendering Engine\n this.addVtkjsDrivenViewport(internalViewportEntry, {\n offScreenCanvasWidth,\n offScreenCanvasHeight,\n xOffset,\n });\n }\n\n /**\n * Disables the requested viewportId from the rendering engine:\n * 1) It removes the viewport from the the list of viewports\n * 2) remove the renderer from the offScreen render window\n * 3) resetting the viewport to remove the canvas attributes and canvas data\n * 4) resize the offScreen appropriately\n *\n * @param viewportId - viewport Id\n *\n */\n private _removeViewport(viewportId: string): void {\n // 1. Get the viewport\n const viewport = this.getViewport(viewportId);\n if (!viewport) {\n console.warn(`viewport ${viewportId} does not exist`);\n return;\n }\n\n // 2. Delete the viewports from the the viewports\n this._viewports.delete(viewportId);\n }\n\n /**\n * Adds a viewport driven by vtk.js to the `RenderingEngine`.\n *\n * @param viewportInputEntry - Information object used to construct and enable the viewport.\n * @param options - Options object used to configure the viewport.\n * @param options.offScreenCanvasWidth - The width of the offscreen canvas.\n * @param options.offScreenCanvasHeight - The height of the offscreen canvas.\n * @param options.xOffset - The x offset of the viewport on the offscreen canvas.\n */\n private addVtkjsDrivenViewport(\n viewportInputEntry: InternalViewportInput,\n offscreenCanvasProperties?: {\n offScreenCanvasWidth: number;\n offScreenCanvasHeight: number;\n xOffset: number;\n }\n ): void {\n const { element, canvas, viewportId, type, defaultOptions } =\n viewportInputEntry;\n\n // Make the element not focusable, we use this for modifier keys to work\n element.tabIndex = -1;\n\n const { offScreenCanvasWidth, offScreenCanvasHeight, xOffset } =\n offscreenCanvasProperties;\n\n // 1. Calculate the size of location of the viewport on the offScreen canvas\n const {\n sxStartDisplayCoords,\n syStartDisplayCoords,\n sxEndDisplayCoords,\n syEndDisplayCoords,\n sx,\n sy,\n sWidth,\n sHeight,\n } = this._getViewportCoordsOnOffScreenCanvas(\n viewportInputEntry,\n offScreenCanvasWidth,\n offScreenCanvasHeight,\n xOffset\n );\n // 2. Add a renderer to the offScreenMultiRenderWindow\n this.offscreenMultiRenderWindow.addRenderer({\n viewport: [\n sxStartDisplayCoords,\n syStartDisplayCoords,\n sxEndDisplayCoords,\n syEndDisplayCoords,\n ],\n id: viewportId,\n background: defaultOptions.background\n ? defaultOptions.background\n : [0, 0, 0],\n });\n\n // 3. ViewportInput to be passed to a stack/volume viewport\n const viewportInput = <ViewportInput>{\n id: viewportId,\n element, // div\n renderingEngineId: this.id,\n type,\n canvas,\n sx,\n sy,\n sWidth,\n sHeight,\n defaultOptions: defaultOptions || {},\n };\n\n // 4. Create a proper viewport based on the type of the viewport\n let viewport;\n if (type === ViewportType.STACK) {\n // 4.a Create stack viewport\n viewport = new StackViewport(viewportInput);\n } else if (\n type === ViewportType.ORTHOGRAPHIC ||\n type === ViewportType.PERSPECTIVE\n ) {\n // 4.b Create a volume viewport\n viewport = new VolumeViewport(viewportInput);\n } else if (type === ViewportType.VOLUME_3D) {\n viewport = new VolumeViewport3D(viewportInput);\n } else {\n throw new Error(`Viewport Type ${type} is not supported`);\n }\n\n // 5. Storing the viewports\n this._viewports.set(viewportId, viewport);\n\n const eventDetail: EventTypes.ElementEnabledEventDetail = {\n element,\n viewportId,\n renderingEngineId: this.id,\n };\n\n if (!viewport.suppressEvents) {\n triggerEvent(eventTarget, Events.ELEMENT_ENABLED, eventDetail);\n }\n }\n\n /**\n * Adds a viewport using a custom rendering pipeline to the `RenderingEngine`.\n *\n * @param viewportInputEntry - Information object used to\n * construct and enable the viewport.\n */\n private addCustomViewport(viewportInputEntry: PublicViewportInput): void {\n const { element, viewportId, type, defaultOptions } = viewportInputEntry;\n\n // Make the element not focusable, we use this for modifier keys to work\n element.tabIndex = -1;\n\n const canvas = getOrCreateCanvas(element);\n\n // Add a viewport with no offset\n const { clientWidth, clientHeight } = canvas;\n\n // Set the canvas to be same resolution as the client.\n // Note: This ignores devicePixelRatio for now. We may want to change it in the\n // future but it has no benefit for the Cornerstone CPU rendering pathway at the\n // moment anyway.\n if (canvas.width !== clientWidth || canvas.height !== clientHeight) {\n canvas.width = clientWidth;\n canvas.height = clientHeight;\n }\n\n const viewportInput = <ViewportInput>{\n id: viewportId,\n renderingEngineId: this.id,\n element, // div\n type,\n canvas,\n sx: 0, // No offset, uses own renderer\n sy: 0,\n sWidth: clientWidth,\n sHeight: clientHeight,\n defaultOptions: defaultOptions || {},\n };\n\n // 4. Create a proper viewport based on the type of the viewport\n const ViewportType = viewportTypeToViewportClass[type];\n\n const viewport = new ViewportType(viewportInput);\n\n // 5. Storing the viewports\n this._viewports.set(viewportId, viewport);\n\n const eventDetail: EventTypes.ElementEnabledEventDetail = {\n element,\n viewportId,\n renderingEngineId: this.id,\n };\n\n triggerEvent(eventTarget, Events.ELEMENT_ENABLED, eventDetail);\n }\n\n /**\n * Sets multiple viewports using custom rendering\n * pipelines to the `RenderingEngine`.\n *\n * @param viewportInputEntries - An array of information\n * objects used to construct and enable the viewports.\n */\n private setCustomViewports(viewportInputEntries: PublicViewportInput[]) {\n viewportInputEntries.forEach((vpie) => this.addCustomViewport(vpie));\n }\n\n /**\n * Sets multiple vtk.js driven viewports to\n * the `RenderingEngine`.\n *\n * @param viewportInputEntries - An array of information\n * objects used to construct and enable the viewports.\n */\n private setVtkjsDrivenViewports(\n viewportInputEntries: NormalizedViewportInput[]\n ) {\n // Deal with vtkjs driven viewports\n if (viewportInputEntries.length) {\n // 1. Getting all the canvases from viewports calculation of the new offScreen size\n const vtkDrivenCanvases = viewportInputEntries.map((vp) =>\n getOrCreateCanvas(vp.element)\n );\n\n // Ensure the canvas size includes any scaling due to device pixel ratio\n vtkDrivenCanvases.forEach((canvas) => {\n const devicePixelRatio = window.devicePixelRatio || 1;\n\n const rect = canvas.getBoundingClientRect();\n canvas.width = rect.width * devicePixelRatio;\n canvas.height = rect.height * devicePixelRatio;\n });\n\n // 2. Set canvas size based on height and sum of widths\n const { offScreenCanvasWidth, offScreenCanvasHeight } =\n this._resizeOffScreenCanvas(vtkDrivenCanvases);\n\n /*\n TODO: Commenting this out until we can mock the Canvas usage in the tests (or use jsdom?)\n if (!offScreenCanvasWidth || !offScreenCanvasHeight) {\n throw new Error('Invalid offscreen canvas width or height')\n }*/\n\n // 3. Adding the viewports based on the viewportInputEntry definition to the\n // rendering engine.\n let xOffset = 0;\n for (let i = 0; i < viewportInputEntries.length; i++) {\n const vtkDrivenViewportInputEntry = viewportInputEntries[i];\n const canvas = vtkDrivenCanvases[i];\n const internalViewportEntry = {\n ...vtkDrivenViewportInputEntry,\n canvas,\n };\n\n this.addVtkjsDrivenViewport(internalViewportEntry, {\n offScreenCanvasWidth,\n offScreenCanvasHeight,\n xOffset,\n });\n\n // Incrementing the xOffset which provides the horizontal location of each\n // viewport on the offScreen canvas\n xOffset += canvas.width;\n }\n }\n }\n\n /**\n * Resizes the offscreen canvas based on the provided vtk.js driven canvases.\n *\n * @param canvases - An array of HTML Canvas\n */\n private _resizeOffScreenCanvas(\n canvasesDrivenByVtkJs: Array<HTMLCanvasElement>\n ): { offScreenCanvasWidth: number; offScreenCanvasHeight: number } {\n const { offScreenCanvasContainer, offscreenMultiRenderWindow } = this;\n\n // 1. Calculated the height of the offScreen canvas to be the maximum height\n // between canvases\n const offScreenCanvasHeight = Math.max(\n ...canvasesDrivenByVtkJs.map((canvas) => canvas.height)\n );\n\n // 2. Calculating the width of the offScreen canvas to be the sum of all\n let offScreenCanvasWidth = 0;\n\n canvasesDrivenByVtkJs.forEach((canvas) => {\n offScreenCanvasWidth += canvas.width;\n });\n\n offScreenCanvasContainer.width = offScreenCanvasWidth;\n offScreenCanvasContainer.height = offScreenCanvasHeight;\n\n // 3. Resize command\n offscreenMultiRenderWindow.resize();\n\n return { offScreenCanvasWidth, offScreenCanvasHeight };\n }\n\n /**\n * Recalculates and updates the viewports location on the offScreen canvas upon its resize\n *\n * @param viewports - An array of viewports\n * @param offScreenCanvasWidth - new offScreen canvas width\n * @param offScreenCanvasHeight - new offScreen canvas height\n *\n * @returns _xOffset the final offset which will be used for the next viewport\n */\n private _resize(\n viewportsDrivenByVtkJs: Array<IViewport>,\n offScreenCanvasWidth: number,\n offScreenCanvasHeight: number\n ): number {\n // Redefine viewport properties\n let _xOffset = 0;\n\n for (let i = 0; i < viewportsDrivenByVtkJs.length; i++) {\n const viewport = viewportsDrivenByVtkJs[i];\n const {\n sxStartDisplayCoords,\n syStartDisplayCoords,\n sxEndDisplayCoords,\n syEndDisplayCoords,\n sx,\n sy,\n sWidth,\n sHeight,\n } = this._getViewportCoordsOnOffScreenCanvas(\n viewport,\n offScreenCanvasWidth,\n offScreenCanvasHeight,\n _xOffset\n );\n\n _xOffset += viewport.canvas.width;\n\n viewport.sx = sx;\n viewport.sy = sy;\n viewport.sWidth = sWidth;\n viewport.sHeight = sHeight;\n\n // Updating the renderer for the viewport\n const renderer = this.offscreenMultiRenderWindow.getRenderer(viewport.id);\n renderer.setViewport([\n sxStartDisplayCoords,\n syStartDisplayCoords,\n sxEndDisplayCoords,\n syEndDisplayCoords,\n ]);\n }\n\n // Returns the final xOffset\n return _xOffset;\n }\n\n /**\n * Calculates the location of the provided viewport on the offScreenCanvas\n *\n * @param viewports - An array of viewports\n * @param offScreenCanvasWidth - new offScreen canvas width\n * @param offScreenCanvasHeight - new offScreen canvas height\n * @param _xOffset - xOffSet to draw\n */\n private _getViewportCoordsOnOffScreenCanvas(\n viewport: InternalViewportInput | IViewport,\n offScreenCanvasWidth: number,\n offScreenCanvasHeight: number,\n _xOffset: number\n ): ViewportDisplayCoords {\n const { canvas } = viewport;\n const { width: sWidth, height: sHeight } = canvas;\n\n // Update the canvas drawImage offsets.\n const sx = _xOffset;\n const sy = 0;\n\n const sxStartDisplayCoords = sx / offScreenCanvasWidth;\n\n // Need to offset y if it not max height\n const syStartDisplayCoords =\n sy + (offScreenCanvasHeight - sHeight) / offScreenCanvasHeight;\n\n const sWidthDisplayCoords = sWidth / offScreenCanvasWidth;\n const sHeightDisplayCoords = sHeight / offScreenCanvasHeight;\n\n return {\n sxStartDisplayCoords,\n syStartDisplayCoords,\n sxEndDisplayCoords: sxStartDisplayCoords + sWidthDisplayCoords,\n syEndDisplayCoords: syStartDisplayCoords + sHeightDisplayCoords,\n sx,\n sy,\n sWidth,\n sHeight,\n };\n }\n\n /**\n * @method _getViewportsAsArray Returns an array of all viewports\n *\n * @returns {Array} Array of viewports.\n */\n private _getViewportsAsArray() {\n return Array.from(this._viewports.values());\n }\n\n private _setViewportsToBeRenderedNextFrame(viewportIds: string[]) {\n // Add the viewports to the set of flagged viewports\n viewportIds.forEach((viewportId) => {\n this._needsRender.add(viewportId);\n });\n\n // Render any flagged viewports\n this._render();\n }\n\n /**\n * 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 /**\n * Renders all viewports.\n */\n private _renderFlaggedViewports = () => {\n this._throwIfDestroyed();\n\n if (!this.useCPURendering) {\n this.performVtkDrawCall();\n }\n\n const viewports = this._getViewportsAsArray();\n const eventDetailArray = [];\n\n for (let i = 0; i < viewports.length; i++) {\n const viewport = viewports[i];\n if (this._needsRender.has(viewport.id)) {\n const eventDetail =\n this.renderViewportUsingCustomOrVtkPipeline(viewport);\n eventDetailArray.push(eventDetail);\n viewport.setRendered();\n\n // This viewport has been rendered, we can remove it from the set\n this._needsRender.delete(viewport.id);\n\n // If there is nothing left that is flagged for rendering, stop the loop\n if (this._needsRender.size === 0) {\n break;\n }\n }\n }\n\n // allow RAF to be called again\n this._animationFrameSet = false;\n this._animationFrameHandle = null;\n\n eventDetailArray.forEach((eventDetail) => {\n // Very small viewports won't have an element\n if (!eventDetail?.element) {\n return;\n }\n triggerEvent(eventDetail.element, Events.IMAGE_RENDERED, eventDetail);\n });\n };\n\n /**\n * Performs the single `vtk.js` draw call which is used to render the offscreen\n * canvas for vtk.js. This is a bulk rendering step for all Volume and Stack\n * viewports when GPU rendering is available.\n */\n private performVtkDrawCall() {\n // Render all viewports under vtk.js' control.\n const { offscreenMultiRenderWindow } = this;\n const renderWindow = offscreenMultiRenderWindow.getRenderWindow();\n\n const renderers = offscreenMultiRenderWindow.getRenderers();\n\n if (!renderers.length) {\n return;\n }\n\n for (let i = 0; i < renderers.length; i++) {\n const { renderer, id } = renderers[i];\n\n // Requesting viewports that need rendering to be rendered only\n if (this._needsRender.has(id)) {\n renderer.setDraw(true);\n } else {\n renderer.setDraw(false);\n }\n }\n\n renderWindow.render();\n\n // After redraw we set all renderers to not render until necessary\n for (let i = 0; i < renderers.length; i++) {\n renderers[i].renderer.setDraw(false);\n }\n }\n\n /**\n * Renders the given viewport\n * using its proffered method.\n *\n * @param viewport - The viewport to render\n */\n private renderViewportUsingCustomOrVtkPipeline(\n viewport: IViewport\n ): EventTypes.ImageRenderedEventDetail[] {\n let eventDetail;\n\n // Rendering engines start having issues without at least two pixels\n // in each direction\n if (\n viewport.sWidth < VIEWPORT_MIN_SIZE ||\n viewport.sHeight < VIEWPORT_MIN_SIZE\n ) {\n console.warn('Viewport is too small', viewport.sWidth, viewport.sHeight);\n return;\n }\n if (viewportTypeUsesCustomRenderingPipeline(viewport.type) === true) {\n eventDetail =\n viewport.customRenderViewportToCanvas() as EventTypes.ImageRenderedEventDetail;\n } else {\n if (this.useCPURendering) {\n throw new Error(\n 'GPU not available, and using a viewport with no custom render pipeline.'\n );\n }\n\n const { offscreenMultiRenderWindow } = this;\n const openGLRenderWindow =\n offscreenMultiRenderWindow.getOpenGLRenderWindow();\n const context = openGLRenderWindow.get3DContext();\n const offScreenCanvas = context.canvas;\n\n eventDetail = this._renderViewportFromVtkCanvasToOnscreenCanvas(\n viewport,\n offScreenCanvas\n );\n }\n\n return eventDetail;\n }\n\n /**\n * Renders a particular `Viewport`'s on screen canvas.\n * @param viewport - The `Viewport` to render.\n * @param offScreenCanvas - The offscreen canvas to render from.\n */\n private _renderViewportFromVtkCanvasToOnscreenCanvas(\n viewport: IViewport,\n offScreenCanvas\n ): EventTypes.ImageRenderedEventDetail {\n const {\n element,\n canvas,\n sx,\n sy,\n sWidth,\n sHeight,\n id: viewportId,\n renderingEngineId,\n suppressEvents,\n } = viewport;\n\n const { width: dWidth, height: dHeight } = canvas;\n\n const onScreenContext = canvas.getContext('2d');\n\n onScreenContext.drawImage(\n offScreenCanvas,\n sx,\n sy,\n sWidth,\n sHeight,\n 0, //dx\n 0, // dy\n dWidth,\n dHeight\n );\n\n return {\n element,\n suppressEvents,\n viewportId,\n renderingEngineId,\n viewportStatus: viewport.viewportStatus,\n };\n }\n\n /**\n * Reset the viewport by removing the data attributes\n * and clearing the context of draw. It also emits an element disabled event\n *\n * @param viewport - The `Viewport` to render.\n */\n private _resetViewport(viewport: IViewport) {\n const renderingEngineId = this.id;\n\n const { element, canvas, id: viewportId } = viewport;\n\n const eventDetail: EventTypes.ElementDisabledEventDetail = {\n element,\n viewportId,\n renderingEngineId,\n };\n\n viewport.removeWidgets();\n\n // Trigger first before removing the data attributes, as we need the enabled\n // element to remove tools associated with the viewport\n triggerEvent(eventTarget, Events.ELEMENT_DISABLED, eventDetail);\n\n element.removeAttribute('data-viewport-uid');\n element.removeAttribute('data-rendering-engine-uid');\n\n // clear drawing\n const context = canvas.getContext('2d');\n context.clearRect(0, 0, canvas.width, canvas.height);\n }\n\n private _clearAnimationFrame() {\n window.cancelAnimationFrame(this._animationFrameHandle);\n\n this._needsRender.clear();\n this._animationFrameSet = false;\n this._animationFrameHandle = null;\n }\n\n /**\n * Resets the `RenderingEngine`\n */\n private _reset() {\n const viewports = this._getViewportsAsArray();\n\n viewports.forEach((viewport) => {\n this._resetViewport(viewport);\n });\n\n this._clearAnimationFrame();\n\n this._viewports = new Map();\n }\n\n /**\n * 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 // debugging utils for offScreen canvas\n _downloadOffScreenCanvas() {\n const dataURL = this._debugRender();\n _TEMPDownloadURI(dataURL);\n }\n\n // debugging utils for offScreen canvas\n _debugRender(): void {\n const { offscreenMultiRenderWindow } = this;\n const renderWindow = offscreenMultiRenderWindow.getRenderWindow();\n\n const renderers = offscreenMultiRenderWindow.getRenderers();\n\n for (let i = 0; i < renderers.length; i++) {\n renderers[i].renderer.setDraw(true);\n }\n\n renderWindow.render();\n const openGLRenderWindow =\n offscreenMultiRenderWindow.getOpenGLRenderWindow();\n const context = openGLRenderWindow.get3DContext();\n\n const offScreenCanvas = context.canvas;\n const dataURL = offScreenCanvas.toDataURL();\n\n this._getViewportsAsArray().forEach((viewport) => {\n const { sx, sy, sWidth, sHeight } = viewport;\n\n const canvas = <HTMLCanvasElement>viewport.canvas;\n const { width: dWidth, height: dHeight } = canvas;\n\n const onScreenContext = canvas.getContext('2d');\n\n //sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight\n onScreenContext.drawImage(\n offScreenCanvas,\n sx,\n sy,\n sWidth,\n sHeight,\n 0, //dx\n 0, // dy\n dWidth,\n dHeight\n );\n });\n\n return dataURL;\n }\n}\n\nexport default RenderingEngine;\n\n// debugging utils for offScreen canvas\nfunction _TEMPDownloadURI(uri) {\n const link = document.createElement('a');\n\n link.download = 'viewport.png';\n link.href = uri;\n document.body.appendChild(link);\n link.click();\n document.body.removeChild(link);\n}\n","import { SurfaceData, Point3, ISurface, Color, RGB } from '../../types';\n\ntype SurfaceProps = {\n id: string;\n data: SurfaceData;\n frameOfReferenceUID: string;\n color?: Point3;\n};\n\n/**\n * Surface class for storing surface data\n */\nexport class Surface implements ISurface {\n readonly id: string;\n readonly sizeInBytes: number;\n readonly frameOfReferenceUID: string;\n private color: RGB = [200, 0, 0]; // default color\n private points: number[];\n private polys: number[];\n\n constructor(props: SurfaceProps) {\n this.id = props.id;\n this.points = props.data.points;\n this.polys = props.data.polys;\n this.color = props.color ?? this.color;\n this.frameOfReferenceUID = props.frameOfReferenceUID;\n this.sizeInBytes = this._getSizeInBytes();\n }\n\n _getSizeInBytes(): number {\n return this.points.length * 4 + this.polys.length * 4;\n }\n\n public getColor(): RGB {\n return this.color;\n }\n\n public getPoints(): number[] {\n return this.points;\n }\n\n public getPolys(): number[] {\n return this.polys;\n }\n\n public setColor(color: RGB): void {\n this.color = color;\n }\n\n public setPoints(points: number[]): void {\n this.points = points;\n }\n\n public setPolys(polys: number[]): void {\n this.polys = polys;\n }\n\n public getSizeInBytes(): number {\n return this.sizeInBytes;\n }\n}\n","import { RequestPoolManager } from './requestPoolManager';\nimport RequestType from '../enums/RequestType';\n\n/**\n * ImageRetrievalPoolManager\n * You don't need to directly use the imageRetrievalPoolManager to load images\n * since the imageLoadPoolManager will automatically use it for retrieval. However,\n * maximum number of concurrent requests can be set by calling `setMaxConcurrentRequests`.\n *\n * Retrieval (usually) === XHR requests\n */\nconst imageRetrievalPoolManager = new RequestPoolManager('imageRetrievalPool');\n\nimageRetrievalPoolManager.setMaxSimultaneousRequests(\n RequestType.Interaction,\n 200\n);\nimageRetrievalPoolManager.setMaxSimultaneousRequests(\n RequestType.Thumbnail,\n 200\n);\nimageRetrievalPoolManager.setMaxSimultaneousRequests(RequestType.Prefetch, 200);\nimageRetrievalPoolManager.grabDelay = 0;\n\nexport default imageRetrievalPoolManager;\n","import getRenderingEngine, {\n getRenderingEngines,\n} from './RenderingEngine/getRenderingEngine';\nimport { IEnabledElement, IStackViewport, IVolumeViewport } from './types';\n\n/**\n * A convenience method to find an EnabledElement given a reference to its\n * associated element. Commonly used in code that's handling a custom\n * event emitted by this library.\n *\n * @example\n * Using the renderingEngine to find the enabled element:\n * ```javascript\n * const element = getRenderingEngine(renderingEngineId)\n * .getViewport(viewportId)\n * .element\n *\n * const enabledElement = getEnabledElement(element)\n * ```\n *\n * @example\n * Using a cornerstone event's \"element\"\n * ```javascript\n * // Our \"cornerstone events\" contain the source element, which is\n * // raised on the viewport's div element\n * const { element } = evt.detail\n * const enabledElement = getEnabledElement(element)\n * ```\n *\n * @param element - a reference to an EnabledElement/Viewport's div element\n * @returns the associated EnabledElement, or undefined if no matching EnabledElement\n * can be found\n */\nexport default function getEnabledElement(\n element: HTMLDivElement | undefined\n): IEnabledElement | undefined {\n if (!element) {\n return;\n }\n\n const { viewportUid, renderingEngineUid } = element.dataset;\n\n return getEnabledElementByIds(viewportUid, renderingEngineUid);\n}\n\n/**\n * Similar to {@link getEnabledElement}, but takes the IDs of the\n * renderingEngine and viewport as parameters to return the associated\n * EnabledElement.\n *\n * @param viewportId - The Id of the viewport\n * @param renderingEngineId - The Id of the rendering engine.\n * @returns The enabled element which is an object that contains the viewport, rendering\n * engine, viewport Id, rendering engine Id, and the Frame of Reference UID.\n */\nexport function getEnabledElementByIds(\n viewportId: string,\n renderingEngineId: string\n): IEnabledElement {\n if (!renderingEngineId || !viewportId) {\n return;\n }\n\n const renderingEngine = getRenderingEngine(renderingEngineId);\n\n if (!renderingEngine || renderingEngine.hasBeenDestroyed) {\n return;\n }\n\n const viewport = renderingEngine.getViewport(viewportId) as\n | IStackViewport\n | IVolumeViewport;\n\n if (!viewport) {\n return;\n }\n\n const FrameOfReferenceUID = viewport.getFrameOfReferenceUID();\n\n return {\n viewport,\n renderingEngine,\n viewportId,\n renderingEngineId,\n FrameOfReferenceUID,\n };\n}\n\n/**\n * Retrieves the enabled element by the specified viewport ID. it searches\n * through all the rendering engines to find the viewport with the specified\n *\n * @param viewportId - The ID of the viewport.\n * @returns The enabled element associated with the specified viewport ID.\n */\nexport function getEnabledElementByViewportId(viewportId: string) {\n const renderingEngines = getRenderingEngines();\n\n for (let i = 0; i < renderingEngines.length; i++) {\n const renderingEngine = renderingEngines[i];\n const viewport = renderingEngine.getViewport(viewportId);\n\n if (viewport) {\n return getEnabledElementByIds(viewportId, renderingEngine.id);\n }\n }\n}\n\n/**\n * Get all the enabled elements from all the rendering engines\n * @returns An array of enabled elements.\n */\nexport function getEnabledElements(): IEnabledElement[] {\n const enabledElements = [];\n\n const renderingEngines = getRenderingEngines();\n\n renderingEngines.forEach((renderingEngine) => {\n const viewports = renderingEngine.getViewports();\n\n viewports.forEach(({ element }) => {\n enabledElements.push(getEnabledElement(element));\n });\n });\n\n return enabledElements;\n}\n","/*\n * Constants\n */\n\nconst DEFAULT_SETTINGS = Symbol('DefaultSettings');\nconst RUNTIME_SETTINGS = Symbol('RuntimeSettings');\nconst OBJECT_SETTINGS_MAP = Symbol('ObjectSettingsMap');\nconst DICTIONARY = Symbol('Dictionary');\n\n/**\n * Settings\n */\nexport default class Settings {\n constructor(base?: Settings) {\n const dictionary = Object.create(\n (base instanceof Settings && DICTIONARY in base\n ? base[DICTIONARY]\n : null) as object\n );\n Object.seal(\n Object.defineProperty(this, DICTIONARY, {\n value: dictionary,\n })\n );\n }\n\n set(key: string, value: unknown): boolean {\n return set(this[DICTIONARY], key, value, null);\n }\n\n get(key: string): unknown {\n return get(this[DICTIONARY], key);\n }\n\n /**\n * Unset a specific key or a set of keys within a namespace when the key ends with a dot (ASCII #46).\n * If the key is \".\", all keys will be removed and this command works as a reset.\n * @param key - name The key to be unset or a namespace.\n * @returns boolean\n */\n unset(key: string): boolean {\n return unset(this[DICTIONARY], key + '');\n }\n\n forEach(callback: (key: string, value: unknown) => void): void {\n iterate(this[DICTIONARY], callback);\n }\n\n extend(): Settings {\n return new Settings(this);\n }\n\n /**\n * Recursively import all properties from the given plain JavaScript object.\n * This method has the opposite effect of the `dump` method.\n * @param root - The root object whose properties will\n * be imported.\n */\n import(root: Record<string, unknown>): void {\n if (isPlainObject(root)) {\n Object.keys(root).forEach((key) => {\n set(this[DICTIONARY], key, root[key], null);\n });\n }\n }\n\n /**\n * Build a JSON representation of the current internal state of this settings\n * object. The returned object can be safely passed to `JSON.stringify`\n * function.\n * @returns The JSON representation of the current\n * state of this settings instance\n */\n dump(): Record<string, unknown> {\n const context = {};\n iterate(this[DICTIONARY], (key, value) => {\n if (typeof value !== 'undefined') {\n deepSet(context, key, value);\n }\n });\n return context;\n }\n\n static assert(subject: Settings): Settings {\n return subject instanceof Settings\n ? subject\n : Settings.getRuntimeSettings();\n }\n\n static getDefaultSettings(subfield = null): Settings | any {\n let defaultSettings = Settings[DEFAULT_SETTINGS];\n if (!(defaultSettings instanceof Settings)) {\n defaultSettings = new Settings();\n Settings[DEFAULT_SETTINGS] = defaultSettings;\n }\n\n // Given subfield of 'segmentation' it will return all settings\n // that starts with segmentation.*\n if (subfield) {\n const settingObj = {};\n defaultSettings.forEach((name: string) => {\n if (name.startsWith(subfield)) {\n const setting = name.split(`${subfield}.`)[1];\n settingObj[setting] = defaultSettings.get(name);\n }\n });\n return settingObj;\n }\n\n return defaultSettings;\n }\n\n static getRuntimeSettings(): Settings {\n let runtimeSettings = Settings[RUNTIME_SETTINGS];\n if (!(runtimeSettings instanceof Settings)) {\n runtimeSettings = new Settings(Settings.getDefaultSettings());\n Settings[RUNTIME_SETTINGS] = runtimeSettings;\n }\n return runtimeSettings;\n }\n\n static getObjectSettings(subject: unknown, from?: unknown): Settings {\n let settings = null;\n if (subject instanceof Settings) {\n settings = subject;\n } else if (typeof subject === 'object' && subject !== null) {\n let objectSettingsMap = Settings[OBJECT_SETTINGS_MAP];\n if (!(objectSettingsMap instanceof WeakMap)) {\n objectSettingsMap = new WeakMap();\n Settings[OBJECT_SETTINGS_MAP] = objectSettingsMap;\n }\n settings = objectSettingsMap.get(subject);\n if (!(settings instanceof Settings)) {\n settings = new Settings(\n Settings.assert(Settings.getObjectSettings(from))\n );\n objectSettingsMap.set(subject, settings);\n }\n }\n return settings;\n }\n\n static extendRuntimeSettings(): Settings {\n return Settings.getRuntimeSettings().extend();\n }\n}\n\n/*\n * Local Helpers\n */\n\nfunction unset(dictionary: Record<string, unknown>, name: string): boolean {\n if (name.endsWith('.')) {\n let deleteCount = 0;\n const namespace = name;\n const base = namespace.slice(0, -1);\n const deleteAll = base.length === 0;\n for (const key in dictionary) {\n if (\n Object.prototype.hasOwnProperty.call(dictionary, key) &&\n (deleteAll || key.startsWith(namespace) || key === base)\n ) {\n delete dictionary[key];\n ++deleteCount;\n }\n }\n return deleteCount > 0;\n }\n return delete dictionary[name];\n}\n\nfunction iterate(\n dictionary: Record<string, unknown>,\n callback: (key: string, value: unknown) => void\n): void {\n for (const key in dictionary) {\n callback(key, dictionary[key]);\n }\n}\n\nfunction setAll(\n dictionary: Record<string, unknown>,\n prefix: string,\n record: Record<string, unknown>,\n references: WeakSet<Record<string, unknown>>\n): boolean {\n let failCount: number;\n if (references.has(record)) {\n return set(dictionary, prefix, null, references);\n }\n references.add(record);\n failCount = 0;\n for (const field in record) {\n if (Object.prototype.hasOwnProperty.call(record, field)) {\n const key = field.length === 0 ? prefix : `${prefix}.${field}`;\n if (!set(dictionary, key, record[field], references)) {\n ++failCount;\n }\n }\n }\n references.delete(record);\n return failCount === 0;\n}\n\n/**\n * Set the key-value pair on a given dictionary. If the given value is a\n * plain javascript object, every property of that object will also be set.\n * @param dictionary {Record<string, unknown>} The target dictionary\n * @param key {string} The given key\n * @param value {unknown} The given value\n * @param references {WeakSet<Record<string, unknown>>} references is a WeakSet\n * instance used to keep track of which objects have already been iterated\n * through preventing thus possible stack overflows caused by cyclic references\n * @returns {boolean} Returns true if every given key-value pair has been\n * successfully set\n */\nfunction set(\n dictionary: Record<string, unknown>,\n key: string,\n value: unknown,\n references: WeakSet<Record<string, unknown>>\n): boolean {\n if (isValidKey(key)) {\n if (isPlainObject(value)) {\n return setAll(\n dictionary,\n key,\n value as Record<string, unknown>,\n references instanceof WeakSet ? references : new WeakSet()\n );\n }\n dictionary[key] = value;\n return true;\n }\n return false;\n}\n\nfunction get(dictionary: Record<string, unknown>, key: string): unknown {\n return dictionary[key];\n}\n\n/**\n * Make sure the -provided key correctly formatted.\n * e.g.:\n * \"my.cool.property\" (valid)\n * \"my.cool.property.\" (invalid)\n * \".my.cool.property\" (invalid)\n * \"my.cool..property\" (invalid)\n * @param key {string} The property name to be used as key within the internal\n * dictionary\n * @returns {boolean} True on success, false otherwise\n */\nfunction isValidKey(key: string): boolean {\n let last: number, current: number, previous: number;\n if (typeof key !== 'string' || (last = key.length - 1) < 0) {\n return false;\n }\n previous = -1;\n while ((current = key.indexOf('.', previous + 1)) >= 0) {\n if (current - previous < 2 || current === last) {\n return false;\n }\n previous = current;\n }\n return true;\n}\n\nfunction isPlainObject(subject: unknown) {\n if (typeof subject === 'object' && subject !== null) {\n const prototype = Object.getPrototypeOf(subject);\n if (prototype === Object.prototype || prototype === null) {\n return true;\n }\n }\n return false;\n}\n\nfunction deepSet(context, key, value) {\n const separator = key.indexOf('.');\n if (separator >= 0) {\n const subKey = key.slice(0, separator);\n let subContext = context[subKey];\n if (typeof subContext !== 'object' || subContext === null) {\n const subContextValue = subContext;\n subContext = {};\n if (typeof subContextValue !== 'undefined') {\n subContext[''] = subContextValue;\n }\n context[subKey] = subContext;\n }\n deepSet(subContext, key.slice(separator + 1, key.length), value);\n } else {\n context[key] = value;\n }\n}\n\n/**\n * Initial Settings for the repository\n */\nSettings.getDefaultSettings().set('useCursors', true);\n","import { Point3, ContourData, IContour } from '../../types';\nimport { ContourType } from '../../enums';\n\ntype ContourProps = {\n id: string;\n data: ContourData;\n color: Point3;\n segmentIndex: number;\n};\n\n/**\n * The `Contour` class implements the `IContour` interface and represents a contour in 3D space.\n * It holds information about the contour's id, size in bytes, points, color, and type.\n * The class also provides methods to retrieve the points, color, and type of the contour.\n * Each Contour is part of a ContourSet, and each ContourSet is part of a Geometry.\n */\nexport class Contour implements IContour {\n readonly id: string;\n readonly sizeInBytes: number;\n points: Point3[];\n color: Point3;\n type: ContourType;\n segmentIndex: number;\n\n constructor(props: ContourProps) {\n const { points, type } = props.data;\n this.id = props.id;\n this.points = points;\n this.type = type;\n this.color = props.color;\n this.segmentIndex = props.segmentIndex;\n\n this.sizeInBytes = this._getSizeInBytes();\n }\n\n _getSizeInBytes(): number {\n let sizeInBytes = 0;\n\n // Assuming each point is 1 byte\n sizeInBytes += this.points.length * 3;\n return sizeInBytes;\n }\n\n /**\n * It returns the value of the points property of the data object\n * @returns The points property of the data object.\n */\n public getPoints(): Point3[] {\n return this.points;\n }\n\n public getFlatPointsArray(): number[] {\n return this.points.map((point) => [...point]).flat();\n }\n\n /**\n * This function returns the color of the contour\n * @returns The color of the contour\n */\n public getColor(): Point3 {\n return this.color;\n }\n\n /**\n * It returns the type of the contour, closed or open\n * @returns The type of the contour.\n */\n public getType(): ContourType {\n return this.type;\n }\n}\n\nexport default Contour;\n","import vtkPolyData from '@kitware/vtk.js/Common/DataModel/PolyData';\nimport { Point3, IContourSet, IContour, ContourData } from '../../types';\nimport Contour from './Contour';\n\ntype ContourSetProps = {\n id: string;\n data: ContourData[];\n frameOfReferenceUID: string;\n segmentIndex: number;\n color?: Point3;\n};\n\n/**\n * This class represents a set of contours in 3d space.\n * Usually contours are grouped together in a contour set to represent a meaningful shape.\n */\nexport class ContourSet implements IContourSet {\n readonly id: string;\n readonly sizeInBytes: number;\n readonly frameOfReferenceUID: string;\n private color: Point3 = [200, 0, 0]; // default color\n private segmentIndex: number;\n private polyData: vtkPolyData;\n private centroid: Point3;\n contours: IContour[];\n\n constructor(props: ContourSetProps) {\n this.id = props.id;\n this.contours = [];\n this.color = props.color ?? this.color;\n this.frameOfReferenceUID = props.frameOfReferenceUID;\n this.segmentIndex = props.segmentIndex;\n this._createEachContour(props.data);\n this.sizeInBytes = this._getSizeInBytes();\n }\n\n _createEachContour(contourDataArray: ContourData[]): void {\n contourDataArray.forEach((contourData) => {\n const { points, type, color } = contourData;\n\n const contour = new Contour({\n id: `${this.id}-segment-${this.segmentIndex}`,\n data: {\n points,\n type,\n segmentIndex: this.segmentIndex,\n color: color ?? this.color,\n },\n segmentIndex: this.segmentIndex,\n color: color ?? this.color,\n });\n\n this.contours.push(contour);\n });\n\n this._updateContourSetCentroid();\n }\n\n // Todo: this centroid calculation has limitation in which\n // it will not work for MPR, the reason is that we are finding\n // the centroid of all points but at the end we are picking the\n // closest point to the centroid, which will not work for MPR\n // The reason for picking the closest is a rendering issue since\n // the centroid can be not exactly in the middle of the slice\n // and it might cause the contour to be rendered in the wrong slice\n // or not rendered at all\n _updateContourSetCentroid(): void {\n const numberOfPoints = this.getTotalNumberOfPoints();\n const flatPointsArray = this.getFlatPointsArray();\n\n const sumOfPoints = flatPointsArray.reduce(\n (acc, point) => {\n return [acc[0] + point[0], acc[1] + point[1], acc[2] + point[2]];\n },\n [0, 0, 0]\n );\n\n const centroid = [\n sumOfPoints[0] / numberOfPoints,\n sumOfPoints[1] / numberOfPoints,\n sumOfPoints[2] / numberOfPoints,\n ];\n\n const closestPoint = flatPointsArray.reduce((closestPoint, point) => {\n const distanceToPoint = this._getDistance(centroid, point);\n const distanceToClosestPoint = this._getDistance(centroid, closestPoint);\n\n if (distanceToPoint < distanceToClosestPoint) {\n return point;\n } else {\n return closestPoint;\n }\n }, flatPointsArray[0]);\n\n this.centroid = closestPoint;\n }\n\n _getSizeInBytes(): number {\n return this.contours.reduce((sizeInBytes, contour) => {\n return sizeInBytes + contour.sizeInBytes;\n }, 0);\n }\n\n public getCentroid(): Point3 {\n return this.centroid;\n }\n\n public getSegmentIndex(): number {\n return this.segmentIndex;\n }\n\n public getColor(): Point3 {\n // Currently, all contours in a contour set have the same color.\n // This may change in the future.\n return this.color;\n }\n\n /**\n * This function returns the contours of the image\n * @returns The contours of the image.\n */\n public getContours(): IContour[] {\n return this.contours;\n }\n\n public getSizeInBytes(): number {\n return this.sizeInBytes;\n }\n\n /**\n * It returns an array of all the points in the glyph\n * @returns An array of points.\n */\n public getFlatPointsArray(): Point3[] {\n return this.contours.map((contour) => contour.getPoints()).flat();\n }\n\n /**\n * This function returns the number of contours in the current shape.\n * @returns The number of contours in the glyph.\n */\n public getNumberOfContours(): number {\n return this.contours.length;\n }\n\n /**\n * It loops through each contour in the `contours` array, and adds the number of\n * points in each contour to the `numberOfPoints` variable\n * @returns The number of points in the contours.\n */\n public getTotalNumberOfPoints(): number {\n return this.contours.reduce((numberOfPoints, contour) => {\n return numberOfPoints + contour.getPoints().length;\n }, 0);\n }\n\n /**\n * It returns an array of the number of points in each contour.\n * @returns An array of numbers.\n */\n public getNumberOfPointsArray(): number[] {\n return this.contours.reduce((acc, _, i) => {\n acc[i] = this.getNumberOfPointsInAContour(i);\n return acc;\n }, []);\n }\n\n /**\n * It returns the points in a contour.\n * @param contourIndex - The index of the contour you want to get the\n * points from.\n * @returns An array of Point3 objects.\n */\n public getPointsInContour(contourIndex: number): Point3[] {\n return this.contours[contourIndex].getPoints();\n }\n /**\n * \"This function returns the number of points in a contour.\"\n *\n * @param contourIndex - The index of the contour you want to get the\n * number of points from.\n * @returns The number of points in the contour.\n */\n public getNumberOfPointsInAContour(contourIndex: number): number {\n return this.getPointsInContour(contourIndex).length;\n }\n\n private _getDistance(pointA, pointB) {\n return Math.sqrt(\n (pointA[0] - pointB[0]) ** 2 +\n (pointA[1] - pointB[1]) ** 2 +\n (pointA[2] - pointB[2]) ** 2\n );\n }\n /**\n public convertToClosedSurface(): ClosedSurface {\n const flatPointsArray = this.getFlatPointsArray();\n const numPointsArray = this.getNumberOfPointsArray();\n\n const closedSurfaceData = polySeg.convertToClosedSurface(\n flatPointsArray,\n numPointsArray\n );\n\n const closedSurface = new ClosedSurface({\n id: this.id,\n data: closedSurfaceData,\n color: this.color,\n });\n\n // cache the closed surface\n return closedSurface;\n }\n */\n}\n\nexport default Contour;\n","import '@kitware/vtk.js/Rendering/Profiles/Geometry';\n\nimport cache from '../cache';\nimport { GeometryType } from '../enums';\nimport { IGeometry, PublicContourSetData, PublicSurfaceData } from '../types';\nimport { createContourSet } from './utils/contourSet/createContourSet';\nimport { createSurface } from './utils/surface/createSurface';\n\ntype GeometryOptions = {\n type: GeometryType;\n geometryData: PublicContourSetData | PublicSurfaceData;\n};\n\n/**\n * Todo: currently we are not targeting loading geometry from a file.\n * This is a placeholder for future work. For instance, separate loaders\n * for .vti, .vtk, .obj, .dat etc. can be created and registered here.\n */\n\n/**\n * It creates a geometry object and caches it\n * @param geometryId - A unique identifier for the geometry.\n * @param options - GeometryOptions\n * @returns A promise that resolves to a geometry object.\n */\nasync function createAndCacheGeometry(\n geometryId: string,\n options: GeometryOptions\n): Promise<IGeometry> {\n let geometry = cache.getGeometry(geometryId);\n\n if (geometry) {\n return geometry;\n }\n\n if (options.type === GeometryType.CONTOUR) {\n geometry = createContourSet(\n geometryId,\n options.geometryData as PublicContourSetData\n );\n } else if (options.type === GeometryType.SURFACE) {\n geometry = createSurface(\n geometryId,\n options.geometryData as PublicSurfaceData\n );\n } else {\n throw new Error('Unknown geometry type, Only CONTOUR is supported');\n }\n\n const geometryLoadObject = {\n promise: Promise.resolve(geometry),\n };\n\n await cache.putGeometryLoadObject(geometryId, geometryLoadObject);\n\n return geometry;\n}\n\nexport { createAndCacheGeometry };\n","import { IGeometry, PublicContourSetData } from '../../../types';\nimport { GeometryType } from '../../../enums';\nimport { validateContourSet } from './validateContourSet';\nimport { ContourSet } from '../../../cache/classes/ContourSet';\n\nexport function createContourSet(\n geometryId: string,\n contourSetData: PublicContourSetData\n) {\n // validate the data to make sure it is a valid contour set\n validateContourSet(contourSetData);\n\n const contourSet = new ContourSet({\n id: contourSetData.id,\n data: contourSetData.data,\n color: contourSetData.color,\n frameOfReferenceUID: contourSetData.frameOfReferenceUID,\n segmentIndex: contourSetData.segmentIndex ?? 1,\n });\n\n const geometry: IGeometry = {\n id: geometryId,\n type: GeometryType.CONTOUR,\n data: contourSet,\n sizeInBytes: contourSet.getSizeInBytes(),\n };\n\n return geometry;\n}\n","import { PublicContourSetData } from '../../../types';\n\nexport function validateContourSet(contourSetData: PublicContourSetData) {\n if (!contourSetData || contourSetData.data.length === 0) {\n throw new Error(\n 'Invalid contour set data, see publicContourSetData type for more info'\n );\n }\n\n // make sure it each has id, and each has data of type Point3[]\n if (!contourSetData.id) {\n throw new Error(\n 'Invalid contour set data, each contour set must have an id'\n );\n }\n\n if (!contourSetData.data || !Array.isArray(contourSetData.data)) {\n throw new Error(\n 'Invalid contour set data, each contour set must have an array of contours'\n );\n }\n\n contourSetData.data.forEach((contourData) => {\n if (!contourData.points || !Array.isArray(contourData.points)) {\n throw new Error(\n 'Invalid contour set data, each contour must have an array of points'\n );\n }\n\n contourData.points.forEach((point) => {\n if (!point || !Array.isArray(point) || point.length !== 3) {\n throw new Error(\n 'Invalid contour set data, each point must be an array of length 3'\n );\n }\n });\n });\n}\n","import { IGeometry, PublicSurfaceData } from '../../../types';\nimport { GeometryType } from '../../../enums';\nimport { validateSurface } from './validateSurface';\nimport { Surface } from '../../../cache/classes/Surface';\n\nexport function createSurface(\n geometryId: string,\n SurfaceData: PublicSurfaceData\n) {\n // validate the data to make sure it is a valid contour set\n validateSurface(SurfaceData);\n\n const surface = new Surface({\n id: SurfaceData.id,\n color: SurfaceData.color,\n frameOfReferenceUID: SurfaceData.frameOfReferenceUID,\n data: {\n points: SurfaceData.data.points,\n polys: SurfaceData.data.polys,\n },\n });\n\n const geometry: IGeometry = {\n id: geometryId,\n type: GeometryType.SURFACE,\n data: surface,\n sizeInBytes: surface.getSizeInBytes(),\n };\n\n return geometry;\n}\n","import { PublicSurfaceData } from '../../../types';\n\nexport function validateSurface(contourSetData: PublicSurfaceData) {\n const { data } = contourSetData;\n\n if (!data.points || !data.polys) {\n throw new Error('Invalid surface data');\n }\n}\n","enum EventListenerPhases {\n None = 0,\n Capture = 1,\n Bubble = 2,\n}\n\ntype ListenersMap = Map<EventListener, EventListenerPhases>;\n\n/**\n * TargetEventListeners adds support for event types with namespace, allow\n * removing events without having to pass a callback and makes it possible to\n * remove all event listeners in a much simpler way avoiding leaving listeners\n * behind which would result in memory leaks.\n *\n * @example\n * Creating a new TargetEventListeners instance\n * ```javascript\n * const element = document.getElementById('foo');\n * const targetEventListeners = new TargetEventListeners(element)\n * ```\n *\n * @example\n * Adding and removing event listeners\n * ```javascript\n * const dragCallback = () => { };\n *\n * targetEventListeners.addEventListener('voi.mousemove', dragCallback);\n * targetEventListeners.addEventListener('voi.drag', dragCallback);\n * targetEventListeners.addEventListener('voi.mouseup', () => {\n * // do not need to store a reference of this function\n * }));\n *\n * // Removes a specific event listener\n * targetEventListeners.removeEventListener('voi.mousemove', dragCallback)\n *\n * // Removes all \"mouseup\" event listeners added to \"colorbar.voi\" namespace\n * targetEventListeners.removeEventListener('voi.mouseup')\n *\n * // Removes all event listeners added to the element using this targetEventListeners\n * // instance. A TargetEventListeners instance does not removes the event listeners\n * // added by another one.\n * targetEventListeners.reset();\n * ```\n *\n * @example\n * Adding and removing event listeners for capture and bubble phases. Each\n * listener must be removed indenpendently\n * ```javascript\n * const clickCaptureCallback = () => { };\n * const clickBubbleCallback = () => { };\n *\n * targetEventListeners.addEventListener('click', clickCaptureCallback, { capture: true });\n * targetEventListeners.addEventListener('click', clickBubbleCallback);\n *\n * // Removes the event listener added to the capture phase\n * targetEventListeners.removeEventListener('click', clickCaptureCallback, { capture: true });\n *\n * // Removes the event listener added to the bubble phase\n * targetEventListeners.removeEventListener('click', clickBubbleCallback);\n *\n * // Removes all event listeners added to the HTML element\n * targetEventListeners.reset();\n * ```\n\n */\nclass TargetEventListeners {\n private _target: EventTarget;\n private _eventListeners = new Map<string, ListenersMap>();\n private _children = new Map<string, TargetEventListeners>();\n\n constructor(target: EventTarget) {\n this._target = target;\n }\n\n public get isEmpty() {\n return this._eventListeners.size === 0 && this._children.size === 0;\n }\n\n public addEventListener(\n type: string,\n callback: EventListener,\n options?: AddEventListenerOptions\n ) {\n const dotIndex = type.indexOf('.');\n const isNamespace = dotIndex !== -1;\n\n if (isNamespace) {\n const namespaceToken = type.substring(0, dotIndex);\n let childElementEventListener = this._children.get(namespaceToken);\n\n if (!childElementEventListener) {\n childElementEventListener = new TargetEventListeners(this._target);\n this._children.set(namespaceToken, childElementEventListener);\n }\n\n type = type.substring(dotIndex + 1);\n childElementEventListener.addEventListener(type, callback, options);\n } else {\n this._addEventListener(type, callback, options);\n }\n }\n\n /**\n * Remove an event listener with support for namespaces and optional callback\n * which makes it remove all listeners of a given type\n * @param type - Event type\n * @param callback - Event listener\n * @param options - Event options\n */\n public removeEventListener(\n type: string,\n callback?: EventListener,\n options?: EventListenerOptions\n ): void {\n const dotIndex = type.indexOf('.');\n const isNamespace = dotIndex !== -1;\n\n if (isNamespace) {\n const namespaceToken = type.substring(0, dotIndex);\n const childElementEventListener = this._children.get(namespaceToken);\n\n if (!childElementEventListener) {\n return;\n }\n\n type = type.substring(dotIndex + 1);\n childElementEventListener.removeEventListener(type, callback, options);\n\n // remove empty child objects\n if (childElementEventListener.isEmpty) {\n this._children.delete(namespaceToken);\n }\n } else {\n this._removeEventListener(type, callback, options);\n }\n }\n\n /**\n * Loop through all types, listeners and phases and removing all of them\n */\n public reset() {\n // Destroy all children (DFS - depth first search)\n Array.from(this._children.entries()).forEach(([namespace, child]) => {\n child.reset();\n\n if (child.isEmpty) {\n this._children.delete(namespace);\n } else {\n // This scenario must never happen (safety only)\n throw new Error('Child is not empty and cannot be removed');\n }\n });\n\n this._unregisterAllEvents();\n }\n\n private _addEventListener(\n type: string,\n callback: EventListener,\n options?: AddEventListenerOptions\n ) {\n let listenersMap = this._eventListeners.get(type);\n\n if (!listenersMap) {\n listenersMap = new Map<EventListener, EventListenerPhases>();\n this._eventListeners.set(type, listenersMap);\n }\n\n const useCapture = options?.capture ?? false;\n const listenerPhase = useCapture\n ? EventListenerPhases.Capture\n : EventListenerPhases.Bubble;\n const registeredPhases =\n listenersMap.get(callback) ?? EventListenerPhases.None;\n\n // Bitwise operator to see if the current phase is already registered\n // because the same listener may be register twice (capturing and bubbling\n // phases)\n if (registeredPhases & listenerPhase) {\n console.warn('A listener is already registered for this phase');\n return;\n }\n\n // Add a new event listener or updates the existing one for the phase requested\n listenersMap.set(callback, registeredPhases | listenerPhase);\n\n // Add the event listener to the target\n this._target.addEventListener(type, callback, options);\n }\n\n private _removeEventListener(\n type: string,\n callback?: EventListener,\n options?: EventListenerOptions\n ): void {\n const useCapture = options?.capture ?? false;\n const listenerPhase = useCapture\n ? EventListenerPhases.Capture\n : EventListenerPhases.Bubble;\n\n const listenersMap = this._eventListeners.get(type);\n\n if (!listenersMap) {\n return;\n }\n\n // It can remove a single or all callbacks for a given namespace\n const callbacks = callback ? [callback] : Array.from(listenersMap.keys());\n\n callbacks.forEach((callbackItem) => {\n const registeredPhases =\n listenersMap.get(callbackItem) ?? EventListenerPhases.None;\n\n // Bitwise operation to see if the phase is registered\n const phaseRegistered = !!(registeredPhases & listenerPhase);\n\n if (!phaseRegistered) {\n return;\n }\n\n // Remove the event listener from the target\n this._target.removeEventListener(type, callbackItem, options);\n\n // Since it is enabled we can XOR it to zero the bit in that position\n // 00000011 (capture & buble) ^ 00000010 (buble) = 00000001 (capture)\n const newListenerPhase = registeredPhases ^ listenerPhase;\n\n // Deletes the listener if it is no more used in capturing or bubbling\n // phases or updates it otherwise\n if (newListenerPhase === EventListenerPhases.None) {\n listenersMap.delete(callbackItem);\n } else {\n listenersMap.set(callbackItem, newListenerPhase);\n }\n });\n\n // Deletes the event from the main map if there are no listeners anymore\n if (!listenersMap.size) {\n this._eventListeners.delete(type);\n }\n }\n\n private _unregisterAllListeners(type: string, listenersMap: ListenersMap) {\n // Creates a copy with Array.from() because the map mutates every\n // time an event listener is removed\n Array.from(listenersMap.entries()).forEach(([listener, eventPhases]) => {\n const startPhase = EventListenerPhases.Capture;\n\n // currentPhase start at 1 and shifts 1 bit to the left because\n // EventListenerPhases is a power of 2\n for (let currentPhase = startPhase; eventPhases; currentPhase <<= 1) {\n // Check if the current phase is registered\n if (!(eventPhases & currentPhase)) {\n continue;\n }\n\n const useCapture =\n currentPhase === EventListenerPhases.Capture ? true : false;\n\n // Remove the event listener for this given phase\n this.removeEventListener(type, listener, { capture: useCapture });\n\n // Switch the bit from the \"currentPhase\" from 1 to 0\n eventPhases ^= currentPhase;\n }\n });\n }\n\n private _unregisterAllEvents() {\n // Creates a copy with Array.from() because the map mutates every\n // time an event listener is removed\n Array.from(this._eventListeners.entries()).forEach(([type, listenersMap]) =>\n this._unregisterAllListeners(type, listenersMap)\n );\n }\n}\n\nexport { TargetEventListeners as default, TargetEventListeners };\n","import TargetEventListeners from './TargetEventListeners';\n\n/**\n * MultiTargetEventListenerManager allows you to add event listeners to multiple\n * HTML elements (targets) with support for event types with namespace,\n * allow removing events without having to pass a callback and makes it possible\n * to remove all event lsiteners from all HTML elements in a much simpler avoiding\n * leaving listeners behind which would result in memory leaks.\n *\n * @example\n * Adding and removing event listeners\n * ```javascript\n * const eventListenerManager = new MultiTargetEventListenerManager()\n * const element1 = document.getElementById('foo');\n * const element2 = document.getElementById('bar');\n * const mouseoverCallback = () => { };\n * const mouseoutCallback = () => { };\n * const dragCallback = () => { };\n *\n * eventListenerManager.addEventListener(element1, 'mouseover', mouseoverCallback);\n * eventListenerManager.addEventListener(element1, 'mouseout', mouseoutCallback);\n *\n * eventListenerManager.addEventListener(element2, 'voi.mousemove', dragCallback);\n * eventListenerManager.addEventListener(element2, 'voi.drag', dragCallback);\n * eventListenerManager.addEventListener(element2, 'voi.mouseup', () => {\n * // do not need to store a reference of this function\n * }));\n *\n * // Removes a specific event listener from element2\n * eventListenerManager.removeEventListener(element2, 'voi.mousemove', dragCallback)\n *\n * // Removes all \"mouseup\" event listeners added to \"voi\" namespace on element2\n * eventListenerManager.removeEventListener(element2, 'voi.mouseup')\n *\n * // Removes all event listeners added to element1 and element2\n * eventListenerManager.reset();\n * ```\n */\nclass MultiTargetEventListenerManager {\n private _targetsEventListeners = new Map<EventTarget, TargetEventListeners>();\n\n public addEventListener(\n target: EventTarget,\n type: string,\n callback: EventListener,\n options?: AddEventListenerOptions\n ) {\n let eventListeners = this._targetsEventListeners.get(target);\n\n if (!eventListeners) {\n eventListeners = new TargetEventListeners(target);\n this._targetsEventListeners.set(target, eventListeners);\n }\n\n eventListeners.addEventListener(type, callback, options);\n }\n\n public removeEventListener(\n target: EventTarget,\n type: string,\n callback?: EventListener,\n options?: EventListenerOptions\n ) {\n const eventListeners = this._targetsEventListeners.get(target);\n\n if (!eventListeners) {\n return;\n }\n\n eventListeners.removeEventListener(type, callback, options);\n\n if (eventListeners.isEmpty) {\n this._targetsEventListeners.delete(target);\n }\n }\n\n public reset() {\n Array.from(this._targetsEventListeners.entries()).forEach(\n ([target, targetEventListeners]) => {\n targetEventListeners.reset();\n this._targetsEventListeners.delete(target);\n }\n );\n }\n}\n\nexport {\n MultiTargetEventListenerManager as default,\n MultiTargetEventListenerManager,\n};\n","/**\n * A utility that can be used to scale (in place) an RgbTransferFunction. We\n * often use this to scale the transfer function based on a PET calculation.\n *\n * @example\n * Grabbing a reference to the RGB Transfer function from the viewport:\n * ```\n * const rgbTransferFunction = viewport\n * .getActor()\n * .getProperty()\n * .getRGBTransferFunction(0);\n *\n * scaleRgbTransferFunction(rgbTransferFunction, 2);\n * ```\n *\n * @see {@link https://kitware.github.io/vtk-js/api/Rendering_Core_ColorTransferFunction.html|VTK.js: ColorTransferFunction}\n * @param rgbTransferFunction\n * @param scalingFactor\n */\nexport default function scaleRGBTransferFunction(\n rgbTransferFunction: any,\n scalingFactor: number\n): void {\n const size = rgbTransferFunction.getSize();\n\n for (let index = 0; index < size; index++) {\n const nodeValue1 = [];\n\n rgbTransferFunction.getNodeValue(index, nodeValue1);\n\n nodeValue1[1] = nodeValue1[1] * scalingFactor;\n nodeValue1[2] = nodeValue1[2] * scalingFactor;\n nodeValue1[3] = nodeValue1[3] * scalingFactor;\n\n rgbTransferFunction.setNodeValue(index, nodeValue1);\n }\n}\n","const LAST_RUNTIME_ID = Symbol('LastRuntimeId');\nconst GLOBAL_CONTEXT = {};\nconst DEFAULT_MAX = 0xffffffff; // Max 32-bit integer\nconst DEFAULT_SEPARATOR = '-';\n\n/**\n * Generate a unique numeric ID string valid during a single runtime session;\n *\n * @param context - An optional object to be used as context.\n * Defaults to a global context;\n * @param separator - The component separator. Defaults to \"-\";\n * @param max - The maximum component value. Defaults to 4294967295;\n * @returns The string representation of the the unique ID;\n */\nexport default function getRuntimeId(\n context?: unknown,\n separator?: string,\n max?: number\n): string {\n return getNextRuntimeId(\n // @ts-ignore\n context !== null && typeof context === 'object' ? context : GLOBAL_CONTEXT,\n LAST_RUNTIME_ID,\n (typeof max === 'number' && max > 0 ? max : DEFAULT_MAX) >>> 0\n ).join(typeof separator === 'string' ? separator : DEFAULT_SEPARATOR);\n}\n\n/*\n * Helpers\n */\n\nfunction getNextRuntimeId(\n context: Record<symbol, Array<number>>,\n symbol: symbol,\n max: number\n): Array<number> {\n let idComponents = context[symbol];\n if (!(idComponents instanceof Array)) {\n idComponents = [0];\n Object.defineProperty(context, symbol, { value: idComponents });\n }\n for (let carry = true, i = 0; carry && i < idComponents.length; ++i) {\n let n = idComponents[i] | 0;\n if (n < max) {\n carry = false;\n n = n + 1;\n } else {\n n = 0;\n if (i + 1 === idComponents.length) {\n idComponents.push(0);\n }\n }\n idComponents[i] = n;\n }\n return idComponents;\n}\n","import imageIdToURI from './imageIdToURI';\nimport { IImageCalibration } from '../types';\n\nconst state: Record<string, IImageCalibration> = {}; // Calibrated pixel spacing per imageId\n\n/**\n * Simple metadataProvider object to store metadata for calibrated spacings.\n * This can be added via cornerstone.metaData.addProvider(...) in order to store\n * and return calibrated pixel spacings when metaData type is \"calibratedPixelSpacing\".\n */\nconst metadataProvider = {\n /**\n * Adds metadata for an imageId.\n * @param imageId - the imageId for the metadata to store\n * @param payload - the payload composed of new calibrated pixel spacings\n */\n add: (imageId: string, payload: IImageCalibration): void => {\n const imageURI = imageIdToURI(imageId);\n state[imageURI] = payload;\n },\n\n /**\n * Returns the metadata for an imageId if it exists.\n * @param type - the type of metadata to enquire about\n * @param imageId - the imageId to enquire about\n * @returns the calibrated pixel spacings for the imageId if it exists, otherwise undefined\n */\n get: (type: string, imageId: string): IImageCalibration => {\n if (type === 'calibratedPixelSpacing') {\n const imageURI = imageIdToURI(imageId);\n return state[imageURI];\n }\n },\n};\n\nexport default metadataProvider;\n","import type Point3 from '../types/Point3';\n\n/**\n * returns equal if the two vec3s are opposite within the\n * given tolerance in each dimension.\n *\n * @param v1 - The first 3 vector\n * @param v2 - The second 3 vector.\n * @param tolerance - The acceptable tolerance.\n *\n * @returns True if the two values are within the tolerance levels.\n */\nexport default function isOpposite(\n v1: Point3,\n v2: Point3,\n tolerance = 1e-5\n): boolean {\n return (\n Math.abs(v1[0] + v2[0]) < tolerance &&\n Math.abs(v1[1] + v2[1]) < tolerance &&\n Math.abs(v1[2] + v2[2]) < tolerance\n );\n}\n","import type { IViewport, IStackViewport, IVolumeViewport } from '../types';\nimport cache from '../cache';\n\nfunction getViewportModality(viewport: IViewport, volumeId?: string): string {\n if ((viewport as IStackViewport).modality) {\n return (viewport as IStackViewport).modality;\n }\n\n if ((viewport as IVolumeViewport).setVolumes) {\n volumeId = volumeId ?? viewport.getDefaultActor()?.uid;\n\n if (!volumeId) {\n return;\n }\n\n return cache.getVolume(volumeId)?.metadata.Modality;\n }\n\n throw new Error('Invalid viewport type');\n}\n\nexport { getViewportModality as default, getViewportModality };\n","import { Point3 } from '../types';\n\n/**\n * Returns true if the specified index is within the given dimensions.\n *\n * @param index - The index to check.\n * @param dimensions - The dimensions to check against.\n *\n * @returns True if the index is in-bounds.\n */\nexport default function indexWithinDimensions(\n index: Point3,\n dimensions: Point3\n): boolean {\n if (\n index[0] < 0 ||\n index[0] >= dimensions[0] ||\n index[1] < 0 ||\n index[1] >= dimensions[1] ||\n index[2] < 0 ||\n index[2] >= dimensions[2]\n ) {\n return false;\n }\n\n return true;\n}\n","import { IVolumeViewport } from '../types';\nimport {\n getRenderingEngines,\n getRenderingEngine,\n} from '../RenderingEngine/getRenderingEngine';\n\n/**\n * Returns the viewports containing the same volume actors (all actors) the same\n * as the target viewport. If renderingEngineId is provided, it will only return\n * viewports that are associated with the renderingEngineId; otherwise, it will\n * return search in all rendering engines.\n *\n * This method is useful for finding viewports that are associated with the same\n * volume (e.g., for tools that share state between viewports).\n *\n * @param viewport - target viewport\n * @returns array of viewports that have the same volume actor as the target viewport\n */\nfunction getVolumeViewportsContainingSameVolumes(\n targetViewport: IVolumeViewport,\n renderingEngineId?: string\n): Array<IVolumeViewport> {\n // If rendering engine is not provided, use all rendering engines\n let renderingEngines;\n if (renderingEngineId) {\n renderingEngines = [getRenderingEngine(renderingEngineId)];\n } else {\n renderingEngines = getRenderingEngines();\n }\n\n const sameVolumesViewports = [];\n\n renderingEngines.forEach((renderingEngine) => {\n const targetActors = targetViewport.getActors();\n const viewports = renderingEngine.getVolumeViewports();\n\n for (const vp of viewports) {\n const vpActors = vp.getActors();\n\n if (vpActors.length !== targetActors.length) {\n continue;\n }\n\n // every targetActors should be in the vpActors\n const sameVolumes = targetActors.every(({ uid }) =>\n vpActors.find((vpActor) => uid === vpActor.uid)\n );\n\n if (sameVolumes) {\n sameVolumesViewports.push(vp);\n }\n }\n });\n\n return sameVolumesViewports;\n}\n\nexport default getVolumeViewportsContainingSameVolumes;\n","import { IVolumeViewport } from '../types';\nimport {\n getRenderingEngines,\n getRenderingEngine,\n} from '../RenderingEngine/getRenderingEngine';\n\n/**\n * Similar to {@link getVolumeViewportsContainingSameVolumes}, but uses the volumeId\n * to filter viewports that contain the same volume.\n *\n * @returns VolumeViewport viewports array\n */\nfunction getViewportsWithVolumeId(\n volumeId: string,\n renderingEngineId?: string\n): Array<IVolumeViewport> {\n // If rendering engine is not provided, use all rendering engines\n let renderingEngines;\n if (renderingEngineId) {\n renderingEngines = [getRenderingEngine(renderingEngineId)];\n } else {\n renderingEngines = getRenderingEngines();\n }\n\n const targetViewports = [];\n\n renderingEngines.forEach((renderingEngine) => {\n const viewports = renderingEngine.getVolumeViewports();\n const filteredViewports = viewports.filter((vp) =>\n vp.hasVolumeId(volumeId)\n );\n targetViewports.push(...filteredViewports);\n });\n\n return targetViewports;\n}\n\nexport default getViewportsWithVolumeId;\n","import type Point3 from '../types/Point3';\n\n/**\n * Given an imageData object and a position in voxel space, return a point\n * in world space.\n *\n * @param imageData - The image data object.\n * @param voxelPos - Point in voxel space\n * index space.\n * @returns A point in world space.\n */\nexport default function transformIndexToWorld(imageData, voxelPos: Point3) {\n return imageData.indexToWorld(voxelPos);\n}\n","import { IImage } from '../types';\n\nconst isPTPrescaledWithSUV = (image: IImage) => {\n return image.preScale?.scaled && image.preScale.scalingParameters?.suvbw;\n};\n\nexport default isPTPrescaledWithSUV;\n","import getOrCreateCanvas, {\n EPSILON,\n} from '../RenderingEngine/helpers/getOrCreateCanvas';\nimport { ViewportType, Events } from '../enums';\nimport {\n IImage,\n IStackViewport,\n IVolume,\n ViewportInputOptions,\n IVolumeViewport,\n ViewReference,\n} from '../types';\nimport { getRenderingEngine } from '../RenderingEngine/getRenderingEngine';\nimport RenderingEngine from '../RenderingEngine';\nimport isPTPrescaledWithSUV from './isPTPrescaledWithSUV';\nimport { CanvasLoadPosition } from './loadImageToCanvas';\n\n/**\n * Renders an cornerstone image to a Canvas. This method will handle creation\n * of a temporary enabledElement, setting the imageId, and rendering the image via\n * a StackViewport, copying the canvas drawing to the given canvas Element, and\n * disabling the created temporary element. SuppressEvents argument is used to\n * prevent events from firing during the render process (e.g. during a series\n * of renders to a thumbnail image).\n *\n * @example\n * ```\n * const canvas = document.getElementById('myCanvas')\n *\n * renderToCanvasGPU(canvas, image)\n * ```\n * @param canvas - Canvas element to render to\n * @param imageOrVolume - The image to render\n * @param modality - [Default = undefined] The modality of the image\n * @returns - A promise that resolves when the image has been rendered with the imageId\n */\nexport default function renderToCanvasGPU(\n canvas: HTMLCanvasElement,\n imageOrVolume: IImage | IVolume,\n modality = undefined,\n renderingEngineId = '_thumbnails',\n viewportOptions: ViewportInputOptions & { viewReference?: ViewReference } = {\n displayArea: { imageArea: [1, 1] },\n }\n): Promise<CanvasLoadPosition> {\n if (!canvas || !(canvas instanceof HTMLCanvasElement)) {\n throw new Error('canvas element is required');\n }\n\n const isVolume = !(imageOrVolume as IImage).imageId;\n const image = !isVolume && (imageOrVolume as IImage);\n const volume = isVolume && (imageOrVolume as IVolume);\n const imageIdToPrint = image?.imageId || volume?.volumeId;\n const viewportId = `renderGPUViewport-${imageIdToPrint}`;\n const element = document.createElement('div');\n const devicePixelRatio = window.devicePixelRatio || 1;\n if (!viewportOptions.displayArea) {\n viewportOptions.displayArea = { imageArea: [1, 1] };\n }\n const originalWidth = canvas.width;\n const originalHeight = canvas.height;\n // The canvas width/height are set by flooring the CSS size converted\n // into physical pixels, but because these are float values, the conversion\n // isn't exact, and using the exact value sometimes leads to an off by 1\n // in the actual size, so adding EPSILON to the size resolves\n // the problem.\n // Don't touch the canvas size here as what we get out is a canvas at the right size\n element.style.width = `${originalWidth / devicePixelRatio + EPSILON}px`;\n element.style.height = `${originalHeight / devicePixelRatio + EPSILON}px`;\n element.style.visibility = 'hidden';\n element.style.position = 'absolute';\n\n document.body.appendChild(element);\n\n // add id to the element so we can find it later, and fix the : which is not allowed in css\n const uniqueId = viewportId.split(':').join('-');\n element.setAttribute('viewport-id-for-remove', uniqueId);\n\n // get the canvas element that is the child of the div\n const temporaryCanvas = getOrCreateCanvas(element);\n const renderingEngine =\n (getRenderingEngine(renderingEngineId) as RenderingEngine) ||\n new RenderingEngine(renderingEngineId);\n\n let viewport = renderingEngine.getViewport(viewportId);\n\n if (!viewport) {\n const viewportInput = {\n viewportId,\n type: isVolume ? ViewportType.ORTHOGRAPHIC : ViewportType.STACK,\n element,\n defaultOptions: {\n ...viewportOptions,\n suppressEvents: true,\n },\n };\n renderingEngine.enableElement(viewportInput);\n viewport = renderingEngine.getViewport(viewportId);\n }\n\n return new Promise((resolve) => {\n // Creating a temporary HTML element so that we can\n // enable it and later disable it without losing the canvas context\n let elementRendered = false;\n\n let { viewReference } = viewportOptions;\n\n // Create a named function to handle the event\n const onImageRendered = (eventDetail) => {\n if (elementRendered) {\n return;\n }\n if (viewReference) {\n const useViewRef = viewReference;\n viewReference = null;\n viewport.setViewReference(useViewRef);\n viewport.render();\n return;\n }\n\n // Copy the temporary canvas to the given canvas\n const context = canvas.getContext('2d');\n context.drawImage(\n temporaryCanvas,\n 0,\n 0,\n temporaryCanvas.width,\n temporaryCanvas.height, // source dimensions\n 0,\n 0,\n canvas.width,\n canvas.height // destination dimensions\n );\n\n const origin = viewport.canvasToWorld([0, 0]);\n const topRight = viewport.canvasToWorld([\n temporaryCanvas.width / devicePixelRatio,\n 0,\n ]);\n const bottomLeft = viewport.canvasToWorld([\n 0,\n temporaryCanvas.height / devicePixelRatio,\n ]);\n const thicknessMm = 1;\n elementRendered = true;\n\n // remove based on id\n element.removeEventListener(Events.IMAGE_RENDERED, onImageRendered);\n\n // Ensure pending previous resize calls are done which might have been\n // triggered by the same disableElement call. This is to avoid potential\n // grab of the wrong canvas coordinate from the offscreen renderer since\n // disable might have not finished resizing yet and it will cause weird\n // copy to on screen from an incorrect location in the offscreen renderer.\n setTimeout(() => {\n renderingEngine.disableElement(viewportId);\n\n // remove all the elements that has the same id\n const elements = document.querySelectorAll(\n `[viewport-id-for-remove=\"${uniqueId}\"]`\n );\n elements.forEach((element) => {\n element.remove();\n });\n }, 0);\n resolve({\n origin,\n bottomLeft,\n topRight,\n thicknessMm,\n });\n };\n\n element.addEventListener(Events.IMAGE_RENDERED, onImageRendered);\n if (isVolume) {\n (viewport as IVolumeViewport).setVolumes([volume], false, true);\n } else {\n (viewport as IStackViewport).renderImageObject(imageOrVolume);\n }\n\n // force a reset camera to center the image and undo the small scaling\n viewport.resetCamera();\n\n if (modality === 'PT' && !isPTPrescaledWithSUV(image)) {\n (viewport as IStackViewport).setProperties({\n voiRange: {\n lower: image.minPixelValue,\n upper: image.maxPixelValue,\n },\n });\n }\n\n viewport.render();\n });\n}\n","import {\n IImage,\n CPUFallbackEnabledElement,\n ViewportInputOptions,\n IVolume,\n} from '../types';\n\nimport getDefaultViewport from '../RenderingEngine/helpers/cpuFallback/rendering/getDefaultViewport';\nimport calculateTransform from '../RenderingEngine/helpers/cpuFallback/rendering/calculateTransform';\nimport drawImageSync from '../RenderingEngine/helpers/cpuFallback/drawImageSync';\nimport type { CanvasLoadPosition } from './loadImageToCanvas';\n\n/**\n * Renders a cornerstone image object to a canvas.\n * Note: this does not load the image but only takes care of the rendering pipeline\n *\n * @param image - Cornerstone image object\n * @param canvas - Canvas element to render to\n */\nexport default function renderToCanvasCPU(\n canvas: HTMLCanvasElement,\n imageOrVolume: IImage | IVolume,\n modality?: string,\n _renderingEngineId?: string,\n _viewportOptions?: ViewportInputOptions\n): Promise<CanvasLoadPosition> {\n const volume = imageOrVolume as IVolume;\n if (volume.volumeId) {\n throw new Error('Unsupported volume rendering for CPU');\n }\n const image = imageOrVolume as IImage;\n const viewport = getDefaultViewport(canvas, image, modality);\n\n const enabledElement: CPUFallbackEnabledElement = {\n canvas,\n viewport,\n image,\n renderingTools: {},\n };\n\n enabledElement.transform = calculateTransform(enabledElement);\n\n const invalidated = true;\n return new Promise((resolve, reject) => {\n drawImageSync(enabledElement, invalidated);\n resolve(null);\n });\n}\n","import type {\n IImage,\n ViewPresentation,\n ViewReference,\n ViewportInputOptions,\n Point3,\n IVolume,\n} from '../types';\n\nimport { loadAndCacheImage } from '../loaders/imageLoader';\nimport * as metaData from '../metaData';\nimport { RequestType } from '../enums';\nimport imageLoadPoolManager from '../requestPool/imageLoadPoolManager';\nimport renderToCanvasGPU from './renderToCanvasGPU';\nimport renderToCanvasCPU from './renderToCanvasCPU';\nimport { getConfiguration } from '../init';\nimport cache from '../cache';\n\n/**\n * The original load image options specified just an image id, which is optimal\n * for things like thumbnails rendering a single image.\n */\nexport type StackLoadImageOptions = {\n imageId: string;\n};\n\n/**\n * The full image load options allows specifying more parameters for both the\n * presentation and the view so that a specific view can be referenced/displayed.\n */\nexport type FullImageLoadOptions = {\n viewReference: ViewReference;\n viewPresentation: ViewPresentation;\n imageId: undefined;\n};\n\n/**\n * The canvas load position allows for determining the rendered position of\n * image data within the canvas, and can be used to map loaded canvas points\n * to and from other viewport positions for things like external computations\n * on the load image to canvas view and the viewport view (which may contain\n * extraneous data such as segmentation and thus not be usable for external\n * computations.)\n */\nexport type CanvasLoadPosition = {\n origin: Point3;\n topRight: Point3;\n bottomLeft: Point3;\n thicknessMm: number;\n};\n\n/**\n * The image canvas can be loaded/set with various view conditions to specify the initial\n * view as well as how and where ot render the image.\n */\nexport type LoadImageOptions = {\n canvas: HTMLCanvasElement;\n // Define the view specification as optional here, and then incorporate specific\n // requirements in mix in types.\n imageId?: string;\n viewReference?: ViewReference;\n viewPresentation?: ViewPresentation;\n requestType?: RequestType;\n priority?: number;\n renderingEngineId?: string;\n useCPURendering?: boolean;\n // Render a thumbnail in a 256x256 viewport\n // Also set imageAspect to render thumbnail in an aspect ratio width viewport\n thumbnail?: boolean;\n // Sets the CSS width to the image aspect ratio\n imageAspect?: boolean;\n // Sets the canvas pixel size to the physical pixel size of the image area\n physicalPixels?: boolean;\n // Sets the viewport input options Defaults to scale to fit 110%\n viewportOptions?: ViewportInputOptions;\n} & (StackLoadImageOptions | FullImageLoadOptions);\n\n/**\n * Loads and renders an imageId to a Canvas. It will use the GPU rendering pipeline\n * for image by default but you can force the CPU rendering pipeline by setting the\n * useCPURendering parameter to true.\n *\n * @example\n * ```\n * const canvas = document.getElementById('myCanvas')\n * const imageId = 'myImageId'\n *\n * loadImageToCanvas(canvas, imageId)\n * ```\n * @param canvas - Canvas element to render to\n * @param imageId - The imageId to render\n * @param requestType - The type of request (default to interaction), can be 'interaction' or 'prefetch' or 'thumbnail'\n * the order of loading for the pool manager is interaction, thumbnail, prefetch\n * @param priority - The priority of the request within the request type (lower is higher priority)\n * @param useCPURendering - Force the use of the CPU rendering pipeline (default to false)\n * @param thumbnail - Render a thumbnail image\n * @param imageAspect - assign the width based on the aspect ratio of the image\n * @returns - A promise that resolves when the image has been rendered with the imageId\n */\nexport default function loadImageToCanvas(\n options: LoadImageOptions\n): Promise<CanvasLoadPosition> {\n const {\n canvas,\n imageId,\n viewReference,\n requestType = RequestType.Thumbnail,\n priority = -5,\n renderingEngineId = '_thumbnails',\n useCPURendering = false,\n thumbnail = false,\n imageAspect = false,\n viewportOptions: baseViewportOptions,\n } = options;\n const volumeId = viewReference?.volumeId;\n const isVolume = volumeId && !imageId;\n const viewportOptions =\n viewReference && baseViewportOptions\n ? { ...baseViewportOptions, viewReference }\n : baseViewportOptions;\n\n const renderFn = useCPURendering ? renderToCanvasCPU : renderToCanvasGPU;\n\n return new Promise((resolve, reject) => {\n function successCallback(imageOrVolume: IImage | IVolume, imageId: string) {\n const { modality } = metaData.get('generalSeriesModule', imageId) || {};\n\n const image = !isVolume && (imageOrVolume as IImage);\n const volume = isVolume && (imageOrVolume as IVolume);\n if (image) {\n image.isPreScaled = image.isPreScaled || image.preScale?.scaled;\n }\n\n if (thumbnail) {\n canvas.height = 256;\n canvas.width = 256;\n }\n if (imageAspect && image) {\n canvas.width = image && (canvas.height * image.width) / image.height;\n }\n canvas.style.width = `${canvas.width / devicePixelRatio}px`;\n canvas.style.height = `${canvas.height / devicePixelRatio}px`;\n if (volume && useCPURendering) {\n reject(new Error('CPU rendering of volume not supported'));\n }\n renderFn(\n canvas,\n imageOrVolume,\n modality,\n renderingEngineId,\n viewportOptions\n ).then(resolve);\n }\n\n function errorCallback(error: Error, imageId: string) {\n console.error(error, imageId);\n reject(error);\n }\n\n function sendRequest(imageId, imageIdIndex, options) {\n return loadAndCacheImage(imageId, options).then(\n (image) => {\n successCallback.call(this, image, imageId);\n },\n (error) => {\n errorCallback.call(this, error, imageId);\n }\n );\n }\n\n const { useNorm16Texture } = getConfiguration().rendering;\n\n // IMPORTANT: Request type should be passed if not the 'interaction'\n // highest priority will be used for the request type in the imageRetrievalPool\n const options = {\n targetBuffer: {\n type: useNorm16Texture ? undefined : 'Float32Array',\n },\n preScale: {\n enabled: true,\n },\n useRGBA: !!useCPURendering,\n requestType,\n };\n\n if (volumeId) {\n const volume = cache.getVolume(volumeId) as unknown as IVolume;\n if (!volume) {\n reject(new Error(`Volume id ${volumeId} not found in cache`));\n }\n const useImageId = volume.imageIds[0];\n successCallback(volume, useImageId);\n } else {\n imageLoadPoolManager.addRequest(\n sendRequest.bind(null, imageId, null, options),\n requestType,\n { imageId },\n priority\n );\n }\n });\n}\n","import { vec3 } from 'gl-matrix';\nimport { metaData } from '..';\nimport { Point2, Point3 } from '../types';\n\n/**\n * Given the imageId, and 3d coordinates on the world space, it returns the continuos\n * image coordinates (IJ) on the image space. The image space is\n * defined with [0,0] being on the top left corner of the top left pixel,\n * the [1,1] being on the bottom right corner of the top left pixel.\n * @param imageId - The image id\n * @param worldCoords - The 3d coordinates on the world.\n * @returns The 2d coordinates on the image.\n *\n */\nfunction worldToImageCoords(\n imageId: string,\n worldCoords: Point3\n): Point2 | undefined {\n const imagePlaneModule = metaData.get('imagePlaneModule', imageId);\n\n if (!imagePlaneModule) {\n throw new Error(`No imagePlaneModule found for imageId: ${imageId}`);\n }\n\n // For the image coordinates we need to calculate the transformation matrix\n // from the world coordinates to the image coordinates.\n\n const {\n columnCosines,\n rowCosines,\n imagePositionPatient: origin,\n } = imagePlaneModule;\n\n let { columnPixelSpacing, rowPixelSpacing } = imagePlaneModule;\n // Use ||= to convert null and 0 as well as undefined to 1\n columnPixelSpacing ||= 1;\n rowPixelSpacing ||= 1;\n\n // The origin is the image position patient, but since image coordinates start\n // from [0,0] for the top left hand of the first pixel, and the origin is at the\n // center of the first pixel, we need to account for this.\n const newOrigin = vec3.create();\n\n vec3.scaleAndAdd(newOrigin, origin, columnCosines, -columnPixelSpacing / 2);\n vec3.scaleAndAdd(newOrigin, newOrigin, rowCosines, -rowPixelSpacing / 2);\n\n // Get the subtraction vector from the origin to the world coordinates\n const sub = vec3.create();\n vec3.sub(sub, worldCoords, newOrigin);\n\n // Projected distance of the sub vector onto the rowCosines\n const rowDistance = vec3.dot(sub, rowCosines);\n\n // Projected distance of the sub vector onto the columnCosines\n const columnDistance = vec3.dot(sub, columnCosines);\n\n const imageCoords = [\n rowDistance / rowPixelSpacing,\n columnDistance / columnPixelSpacing,\n ];\n\n return imageCoords as Point2;\n}\n\nexport default worldToImageCoords;\n","import { vec3 } from 'gl-matrix';\nimport { metaData } from '..';\nimport { Point2, Point3 } from '../types';\n\n/**\n * Given the imageId and a 2d coordinates on the image space with [0,0] being the top left corner\n * of the top left pixel, and options which includes the imageId, it returns the\n * 3d coordinates on the world space.\n * @param imageId - The image id\n * @param imageCoords - The 2d coordinates on the image\n * @returns The 3d coordinates on the world.\n *\n */\nexport default function imageToWorldCoords(\n imageId: string,\n imageCoords: Point2\n): Point3 | undefined {\n const imagePlaneModule = metaData.get('imagePlaneModule', imageId);\n\n if (!imagePlaneModule) {\n throw new Error(`No imagePlaneModule found for imageId: ${imageId}`);\n }\n\n const {\n columnCosines,\n rowCosines,\n imagePositionPatient: origin,\n } = imagePlaneModule;\n\n let { columnPixelSpacing, rowPixelSpacing } = imagePlaneModule;\n // Use ||= to convert null and 0 as well as undefined to 1\n columnPixelSpacing ||= 1;\n rowPixelSpacing ||= 1;\n\n // calculate the image coordinates in the world space\n const imageCoordsInWorld = vec3.create();\n\n // move from origin in the direction of the row cosines with the amount of\n // row pixel spacing times the first element of the image coordinates vector\n vec3.scaleAndAdd(\n imageCoordsInWorld,\n origin,\n rowCosines,\n // to accommodate the [0,0] being on the top left corner of the top left pixel\n // but the origin is at the center of the top left pixel\n rowPixelSpacing * (imageCoords[0] - 0.5)\n );\n\n vec3.scaleAndAdd(\n imageCoordsInWorld,\n imageCoordsInWorld,\n columnCosines,\n columnPixelSpacing * (imageCoords[1] - 0.5)\n );\n\n return Array.from(imageCoordsInWorld) as Point3;\n}\n","import { getRenderingEngine } from '../RenderingEngine';\nimport { getRenderingEngines } from '../RenderingEngine/getRenderingEngine';\nimport { IStackViewport, IVolumeViewport } from '../types';\n\ntype Viewport = IStackViewport | IVolumeViewport;\n\n/**\n * Get the viewport that is rendering the image with the given imageURI (imageId without\n * the loader schema), this can be a stackViewport or a volumeViewport.\n *\n * @param renderingEngine - The rendering engine that is rendering the viewports\n * @param imageURI - The imageURI of the image that is requested\n * @returns A Viewport\n */\nexport default function getViewportsWithImageURI(\n imageURI: string,\n renderingEngineId?: string\n): Array<Viewport> {\n // If rendering engine is not provided, use all rendering engines\n let renderingEngines;\n if (renderingEngineId) {\n renderingEngines = [getRenderingEngine(renderingEngineId)];\n } else {\n renderingEngines = getRenderingEngines();\n }\n\n const viewports = [];\n renderingEngines.forEach((renderingEngine) => {\n const viewportsForRenderingEngine = renderingEngine.getViewports();\n\n viewportsForRenderingEngine.forEach((viewport) => {\n if (viewport.hasImageURI(imageURI)) {\n viewports.push(viewport);\n }\n });\n });\n\n return viewports;\n}\n","import { vec3 } from 'gl-matrix';\nimport { planar } from '.';\nimport { metaData } from '..';\nimport { IStackViewport, Point3 } from '../types';\n\n/**\n * Given a point in 3D space and a viewport it returns the index of the closest imageId, it assumes that stack images are sorted according to their sliceLocation\n * @param point - [A, B, C] coordinates of the point in 3D space\n * @param viewport - The StackViewport to search for the closest imageId\n *\n * @returns The imageId index of the closest imageId or null if no imageId is found\n */\nexport default function getClosestStackImageIndexForPoint(\n point: Point3,\n viewport: IStackViewport\n): number | null {\n const minimalDistance = calculateMinimalDistanceForStackViewport(\n point,\n viewport\n );\n return minimalDistance ? minimalDistance.index : null;\n}\n\n//assumes that imageIds are sorted by slice location\nexport function calculateMinimalDistanceForStackViewport(\n point: Point3,\n viewport: IStackViewport\n): { distance: number; index: number } | null {\n const imageIds = viewport.getImageIds();\n const currentImageIdIndex = viewport.getCurrentImageIdIndex();\n\n if (imageIds.length === 0) {\n return null;\n }\n\n const getDistance = (imageId: string): null | number => {\n const planeMetadata = getPlaneMetadata(imageId);\n if (!planeMetadata) {\n return null;\n }\n const plane = planar.planeEquation(\n planeMetadata.planeNormal,\n planeMetadata.imagePositionPatient\n );\n const distance = planar.planeDistanceToPoint(plane, point);\n return distance;\n };\n\n const closestStack = {\n distance: getDistance(imageIds[currentImageIdIndex]) ?? Infinity,\n index: currentImageIdIndex,\n };\n\n //check higher indices\n const higherImageIds = imageIds.slice(currentImageIdIndex + 1);\n\n for (let i = 0; i < higherImageIds.length; i++) {\n const id = higherImageIds[i];\n const distance = getDistance(id);\n if (distance === null) {\n continue;\n }\n if (distance <= closestStack.distance) {\n closestStack.distance = distance;\n closestStack.index = i + currentImageIdIndex + 1;\n } else {\n break;\n }\n }\n //check lower indices\n const lowerImageIds = imageIds.slice(0, currentImageIdIndex);\n for (let i = lowerImageIds.length - 1; i >= 0; i--) {\n const id = lowerImageIds[i];\n const distance = getDistance(id);\n if (distance === null || distance === closestStack.distance) {\n continue;\n }\n if (distance < closestStack.distance) {\n closestStack.distance = distance;\n closestStack.index = i;\n } else {\n break;\n }\n }\n return closestStack.distance === Infinity ? null : closestStack;\n}\n\nfunction getPlaneMetadata(imageId: string): null | {\n rowCosines: Point3;\n columnCosines: Point3;\n imagePositionPatient: Point3;\n planeNormal: Point3;\n} {\n const targetImagePlane = metaData.get('imagePlaneModule', imageId);\n\n if (\n !targetImagePlane ||\n !(\n targetImagePlane.rowCosines instanceof Array &&\n targetImagePlane.rowCosines.length === 3\n ) ||\n !(\n targetImagePlane.columnCosines instanceof Array &&\n targetImagePlane.columnCosines.length === 3\n ) ||\n !(\n targetImagePlane.imagePositionPatient instanceof Array &&\n targetImagePlane.imagePositionPatient.length === 3\n )\n ) {\n return null;\n }\n const {\n rowCosines,\n columnCosines,\n imagePositionPatient,\n }: {\n rowCosines: Point3;\n columnCosines: Point3;\n imagePositionPatient: Point3;\n } = targetImagePlane;\n\n const rowVec = vec3.set(vec3.create(), ...rowCosines);\n const colVec = vec3.set(vec3.create(), ...columnCosines);\n const planeNormal = vec3.cross(vec3.create(), rowVec, colVec) as Point3;\n\n return { rowCosines, columnCosines, imagePositionPatient, planeNormal };\n}\n","import { IStackViewport, IVolumeViewport, Point2 } from '../types';\nimport transformWorldToIndex from './transformWorldToIndex';\n\n/**\n * Convert coordinates from canvas to index (volume) space\n * @param viewport - Stack or Volume viewport\n * @param ijkPoint - 2D point in canvas space\n * @returns 3D point in index (volume) space\n */\nexport function transformCanvasToIJK(\n viewport: IVolumeViewport | IStackViewport,\n canvasPoint: Point2\n) {\n const { imageData: vtkImageData } = viewport.getImageData();\n const worldPoint = viewport.canvasToWorld(canvasPoint);\n\n return transformWorldToIndex(vtkImageData, worldPoint);\n}\n","import { glMatrix, mat4, vec3 } from 'gl-matrix';\nimport { IVolumeViewport, Point3 } from '../types';\nimport { transformIJKToCanvas } from './transformIJKToCanvas';\nimport { transformCanvasToIJK } from './transformCanvasToIJK';\n\n/**\n * Get the image data for the current slice rendered on the viewport. The image\n * data returned is the full slice and not only the region that is visible on\n * the viewport. It does not work for oblique views.\n * @param viewport - Volume viewport\n * @returns Slice image dataand matrices to convert from volume\n * to slice and vice-versa\n */\nfunction getCurrentVolumeViewportSlice(viewport: IVolumeViewport) {\n const { dimensions, scalarData } = viewport.getImageData();\n const { width: canvasWidth, height: canvasHeight } = viewport.getCanvas();\n\n // Get three points from the canvas to help us identify the orientation of\n // the slice. Using canvas width/height to get point far away for each other\n // because points such as (0,0), (1,0) and (0,1) may be converted to the same\n // ijk index when the image is zoomed in.\n const ijkOriginPoint = transformCanvasToIJK(viewport, [0, 0]);\n const ijkRowPoint = transformCanvasToIJK(viewport, [canvasWidth - 1, 0]);\n const ijkColPoint = transformCanvasToIJK(viewport, [0, canvasHeight - 1]);\n\n // Subtract the points to get the row and column vectors in index space\n const ijkRowVec = vec3.sub(vec3.create(), ijkRowPoint, ijkOriginPoint);\n const ijkColVec = vec3.sub(vec3.create(), ijkColPoint, ijkOriginPoint);\n const ijkSliceVec = vec3.cross(vec3.create(), ijkRowVec, ijkColVec);\n\n vec3.normalize(ijkRowVec, ijkRowVec);\n vec3.normalize(ijkColVec, ijkColVec);\n vec3.normalize(ijkSliceVec, ijkSliceVec);\n\n // Any unit vector parallel to IJK have one component equal to 1 and\n // the other two components equal to 0. If two of them are parallel\n // the third one is also parallel\n const maxIJKRowVec = Math.max(\n Math.abs(ijkRowVec[0]),\n Math.abs(ijkRowVec[1]),\n Math.abs(ijkRowVec[2])\n );\n const maxIJKColVec = Math.max(\n Math.abs(ijkColVec[0]),\n Math.abs(ijkColVec[1]),\n Math.abs(ijkColVec[2])\n );\n\n // Using glMatrix.equals() because the number may be not exactly equal to\n // 1 due to rounding issues\n if (!glMatrix.equals(1, maxIJKRowVec) || !glMatrix.equals(1, maxIJKColVec)) {\n throw new Error('Livewire is not available for rotate/oblique viewports');\n }\n\n const [sx, sy, sz] = dimensions;\n\n // All eight volume corners in index space\n // prettier-ignore\n const ijkCorners: Point3[] = [\n [ 0, 0, 0], // top-left-front\n [sx - 1, 0, 0], // top-right-front\n [ 0, sy - 1, 0], // bottom-left-front\n [sx - 1, sy - 1, 0], // bottom-right-front\n [ 0, 0, sz - 1], // top-left-back\n [sx - 1, 0, sz - 1], // top-right-back\n [ 0, sy - 1, sz - 1], // bottom-left-back\n [sx - 1, sy - 1, sz - 1], // bottom-right-back\n ];\n\n // Project the volume corners onto the canvas\n const canvasCorners = ijkCorners.map((ijkCorner) =>\n transformIJKToCanvas(viewport, ijkCorner)\n );\n\n // Calculate the AABB from the corners project onto the canvas\n const canvasAABB = canvasCorners.reduce(\n (aabb, canvasPoint) => {\n aabb.minX = Math.min(aabb.minX, canvasPoint[0]);\n aabb.minY = Math.min(aabb.minY, canvasPoint[1]);\n aabb.maxX = Math.max(aabb.maxX, canvasPoint[0]);\n aabb.maxY = Math.max(aabb.maxY, canvasPoint[1]);\n\n return aabb;\n },\n { minX: Infinity, minY: Infinity, maxX: -Infinity, maxY: -Infinity }\n );\n\n // Get the top-left, bottom-right and the diagonal vector of\n // the slice in index space\n const ijkTopLeft = transformCanvasToIJK(viewport, [\n canvasAABB.minX,\n canvasAABB.minY,\n ]);\n const ijkBottomRight = transformCanvasToIJK(viewport, [\n canvasAABB.maxX,\n canvasAABB.maxY,\n ]);\n const ijkDiagonal = vec3.sub(vec3.create(), ijkBottomRight, ijkTopLeft);\n\n // prettier-ignore\n const sliceToIndexMatrix = mat4.fromValues(\n ijkRowVec[0], ijkRowVec[1], ijkRowVec[2], 0,\n ijkColVec[0], ijkColVec[1], ijkColVec[2], 0,\n ijkSliceVec[0], ijkSliceVec[1], ijkSliceVec[2], 0,\n ijkTopLeft[0], ijkTopLeft[1], ijkTopLeft[2], 1\n );\n\n const indexToSliceMatrix = mat4.invert(mat4.create(), sliceToIndexMatrix);\n\n // Dot the diagonal with row/column to find the image width/height\n const sliceWidth = vec3.dot(ijkRowVec, ijkDiagonal) + 1;\n const sliceHeight = vec3.dot(ijkColVec, ijkDiagonal) + 1;\n\n // Create a TypedArray with same type from the original scalarData\n const TypedArray = (scalarData as any).constructor;\n const sliceData = new TypedArray(sliceWidth * sliceHeight);\n\n // We need to know how many pixels to jump for every change in Z direction\n const pixelsPerSlice = dimensions[0] * dimensions[1];\n\n // Create two vectors to keep track of each row/column it is, reducing\n // the amount of vec3 instances created and simplifying the math.\n const ijkPixelRow = vec3.clone(ijkTopLeft);\n const ijkPixelCol = vec3.create();\n\n // Use an independent index to avoid multiple (x,y) to index conversions\n let slicePixelIndex = 0;\n\n for (let y = 0; y < sliceHeight; y++) {\n vec3.copy(ijkPixelCol, ijkPixelRow);\n\n for (let x = 0; x < sliceWidth; x++) {\n const volumePixelIndex =\n ijkPixelCol[2] * pixelsPerSlice +\n ijkPixelCol[1] * dimensions[0] +\n ijkPixelCol[0];\n\n // It may never throw any \"out of bounds\" error but just to be safe\n if (volumePixelIndex < scalarData.length) {\n sliceData[slicePixelIndex] = scalarData[volumePixelIndex];\n }\n\n // Move to next slice pixel\n slicePixelIndex++;\n\n // Move to the next voxel\n vec3.add(ijkPixelCol, ijkPixelCol, ijkRowVec);\n }\n\n // Move to the next row\n vec3.add(ijkPixelRow, ijkPixelRow, ijkColVec);\n }\n\n return {\n width: sliceWidth,\n height: sliceHeight,\n scalarData: sliceData,\n sliceToIndexMatrix,\n indexToSliceMatrix,\n };\n}\n\nexport {\n getCurrentVolumeViewportSlice as default,\n getCurrentVolumeViewportSlice,\n};\n","import { IStackViewport, IVolumeViewport, Point3 } from '../types';\nimport transformIndexToWorld from './transformIndexToWorld';\n\n/**\n * Convert coordinates from index (volume) to canvas space\n * @param viewport - Stack or Volume viewport\n * @param ijkPoint - 3D point in index (volume) space\n * @returns 2D point in canvas space\n */\nexport function transformIJKToCanvas(\n viewport: IVolumeViewport | IStackViewport,\n ijkPoint: Point3\n) {\n const { imageData: vtkImageData } = viewport.getImageData();\n const worldPoint = transformIndexToWorld(vtkImageData, ijkPoint);\n\n return viewport.worldToCanvas(worldPoint);\n}\n","import { mat4 } from 'gl-matrix';\nimport { addProvider } from '../metaData';\n\nconst state = {};\n\n/**\n * Simple metadataProvider object to store metadata for spatial registration module.\n */\nconst spatialRegistrationMetadataProvider = {\n /* Adding a new entry to the state object. */\n add: (query: string[], payload: mat4): void => {\n const [viewportId1, viewportId2] = query;\n const entryId = `${viewportId1}_${viewportId2}`;\n\n if (!state[entryId]) {\n state[entryId] = {};\n }\n\n state[entryId] = payload;\n },\n\n get: (type: string, viewportId1: string, viewportId2: string): mat4 => {\n if (type !== 'spatialRegistrationModule') {\n return;\n }\n\n // check both ways\n const entryId = `${viewportId1}_${viewportId2}`;\n\n if (state[entryId]) {\n return state[entryId];\n }\n\n const entryIdReverse = `${viewportId2}_${viewportId1}`;\n\n if (state[entryIdReverse]) {\n return mat4.invert(mat4.create(), state[entryIdReverse]);\n }\n },\n};\n\naddProvider(\n spatialRegistrationMetadataProvider.get.bind(\n spatialRegistrationMetadataProvider\n )\n);\n\nexport default spatialRegistrationMetadataProvider;\n","import { vec3, mat4 } from 'gl-matrix';\nimport { IStackViewport, IVolumeViewport } from '../types';\nimport spatialRegistrationMetadataProvider from './spatialRegistrationMetadataProvider';\nimport { metaData } from '..';\n\n/**\n * Defines the allowed difference as a percent between the unit normals before\n * two planes are considered not coplanar. Since this value is small compared\n * to the unit lenght, this value is approximately the angular difference, measured\n * in radians. That is, allow about a 3 degrees variation.\n */\nconst ALLOWED_DELTA = 0.05;\n\n/**\n * It calculates the registration matrix between two viewports (currently only\n * translation is supported)\n * If the viewports are in the same frame of reference, it will return early,\n * but otherwise it will use the current image's metadata to calculate the\n * translation between the two viewports and adds it to the spatialRegistrationModule\n * metadata provider\n *\n *\n * @param viewport1 - The first stack viewport\n * @param viewport2 - The second stack viewport\n */\nfunction calculateViewportsSpatialRegistration(\n viewport1: IStackViewport | IVolumeViewport,\n viewport2: IStackViewport | IVolumeViewport\n): void {\n const imageId1 = viewport1.getCurrentImageId();\n const imageId2 = viewport2.getCurrentImageId();\n\n const imagePlaneModule1 = metaData.get('imagePlaneModule', imageId1);\n const imagePlaneModule2 = metaData.get('imagePlaneModule', imageId2);\n\n if (!imagePlaneModule1 || !imagePlaneModule2) {\n console.log('Viewport spatial registration requires image plane module');\n return;\n }\n const { imageOrientationPatient: iop2 } = imagePlaneModule2;\n const isSameImagePlane = imagePlaneModule1.imageOrientationPatient.every(\n (v, i) => Math.abs(v - iop2[i]) < ALLOWED_DELTA\n );\n\n if (!isSameImagePlane) {\n console.log(\n 'Viewport spatial registration only supported for same orientation (hence translation only) for now',\n imagePlaneModule1?.imageOrientationPatient,\n imagePlaneModule2?.imageOrientationPatient\n );\n return;\n }\n\n const imagePositionPatient1 = imagePlaneModule1.imagePositionPatient;\n const imagePositionPatient2 = imagePlaneModule2.imagePositionPatient;\n\n const translation = vec3.subtract(\n vec3.create(),\n imagePositionPatient1,\n imagePositionPatient2\n );\n\n const mat = mat4.fromTranslation(mat4.create(), translation);\n spatialRegistrationMetadataProvider.add([viewport1.id, viewport2.id], mat);\n}\n\nexport default calculateViewportsSpatialRegistration;\n","import {\n IImageData,\n IStackViewport,\n IVolumeViewport,\n Point2,\n Point3,\n} from '../types';\n\n/**\n * Given a viewport, return the corners of the image in the viewport in world coordinates.\n * Note that this is different than the corners of the canvas in world coordinates since\n * an image can be zoomed out and the canvas can be larger than the image; hence, the\n * corners of the canvas in world coordinates will be outside the image.\n *\n * @param viewport - The viewport to get the corners of.\n * @returns The corners of the image in the viewport in world coordinates.\n */\nexport default function getViewportImageCornersInWorld(\n viewport: IStackViewport | IVolumeViewport\n): Point3[] {\n const { imageData, dimensions } = viewport.getImageData() as IImageData;\n const { canvas } = viewport;\n\n // we should consider the device pixel ratio since we are\n // working with canvas coordinates\n const ratio = window.devicePixelRatio;\n\n const topLeftCanvas: Point2 = [0, 0];\n const topRightCanvas: Point2 = [canvas.width / ratio, 0];\n const bottomRightCanvas: Point2 = [\n canvas.width / ratio,\n canvas.height / ratio,\n ];\n const bottomLeftCanvas: Point2 = [0, canvas.height / ratio];\n\n const topLeftWorld = viewport.canvasToWorld(topLeftCanvas);\n const topRightWorld = viewport.canvasToWorld(topRightCanvas);\n const bottomRightWorld = viewport.canvasToWorld(bottomRightCanvas);\n const bottomLeftWorld = viewport.canvasToWorld(bottomLeftCanvas);\n\n const topLeftImage = imageData.worldToIndex(topLeftWorld);\n const topRightImage = imageData.worldToIndex(topRightWorld);\n const bottomRightImage = imageData.worldToIndex(bottomRightWorld);\n const bottomLeftImage = imageData.worldToIndex(bottomLeftWorld);\n\n return _getStackViewportImageCorners({\n dimensions,\n imageData,\n topLeftImage,\n topRightImage,\n bottomRightImage,\n bottomLeftImage,\n topLeftWorld,\n topRightWorld,\n bottomRightWorld,\n bottomLeftWorld,\n });\n}\n\nfunction _getStackViewportImageCorners({\n dimensions,\n imageData,\n topLeftImage,\n topRightImage,\n bottomRightImage,\n bottomLeftImage,\n topLeftWorld,\n topRightWorld,\n bottomRightWorld,\n bottomLeftWorld,\n}) {\n const topLeftImageWorld = _isInBounds(topLeftImage, dimensions)\n ? topLeftWorld\n : (imageData.indexToWorld([0, 0, 0]) as Point3);\n\n const topRightImageWorld = _isInBounds(topRightImage, dimensions)\n ? topRightWorld\n : (imageData.indexToWorld([dimensions[0] - 1, 0, 0]) as Point3);\n\n const bottomRightImageWorld = _isInBounds(bottomRightImage, dimensions)\n ? bottomRightWorld\n : (imageData.indexToWorld([\n dimensions[0] - 1,\n dimensions[1] - 1,\n 0,\n ]) as Point3);\n\n const bottomLeftImageWorld = _isInBounds(bottomLeftImage, dimensions)\n ? bottomLeftWorld\n : (imageData.indexToWorld([0, dimensions[1] - 1, 0]) as Point3);\n\n return [\n topLeftImageWorld,\n topRightImageWorld,\n bottomLeftImageWorld,\n bottomRightImageWorld,\n ];\n}\n\nfunction _isInBounds(imageCoord, dimensions) {\n return (\n imageCoord[0] > 0 ||\n imageCoord[0] < dimensions[0] - 1 ||\n imageCoord[1] > 0 ||\n imageCoord[1] < dimensions[1] - 1 ||\n imageCoord[2] > 0 ||\n imageCoord[2] < dimensions[2] - 1\n );\n}\n","import type { Point2, Point3, PointsXYZ } from '../types';\n\nexport type PolyDataPointConfiguration = {\n /** The dimensionality of the points */\n dimensions?: number;\n /** The initial size of the backing array, not containing any data initially */\n initialSize?: number;\n /** The incremental size to grow by when required */\n growSize?: number;\n};\n\n/**\n * PointsManager handles Point type data contained in a TypedArray representation\n * where all the point data is consecutive from start to end. That is, the\n * organization is `x0,y0,z0,x1,y1,z1,...,xn,yn,zn`. This optimizes the storage\n * costs for large arrays of data, while still providing access to the point\n * data as though it were a simple array of objects.\n *\n * This representation is efficient for storing large numbers of points and for\n * transferring them amongst systems and is planned to have more methods added\n * for generic manipulation of data.\n */\nexport default class PointsManager<T> {\n /**\n * Allow storage for an index value to indicate where this array is\n * contained in terms of the index location.\n */\n public kIndex: number;\n\n /**\n * Sources data for this array. Just used for external access, not updated\n * here.\n */\n public sources: PointsManager<T>[];\n\n data: Float32Array;\n _dimensions = 3;\n _length = 0;\n _byteSize = 4;\n growSize = 128;\n array: ArrayBuffer;\n\n constructor(configuration: PolyDataPointConfiguration = {}) {\n const {\n initialSize = 1024,\n dimensions = 3,\n growSize = 128,\n } = configuration;\n const itemLength = initialSize * dimensions;\n this.growSize = growSize;\n // TODO - use resizeable arrays when they become available in all browsers\n this.array = new ArrayBuffer(itemLength * this._byteSize);\n this.data = new Float32Array(this.array);\n this._dimensions = dimensions;\n }\n\n public forEach(func: (value: T, index: number) => void) {\n for (let i = 0; i < this._length; i++) {\n func(this.getPoint(i), i);\n }\n }\n\n public get length() {\n return this._length;\n }\n\n public get dimensions() {\n return this._dimensions;\n }\n\n public get dimensionLength() {\n return this._length * this._dimensions;\n }\n\n /**\n * Returns a Float32Array view of the given point.\n * Changes to the data in this point will affect the underlying data.\n *\n * @param index - positive index from start, or negative from end\n * @returns Float32Array view onto the point at the given index\n */\n public getPoint(index: number): T {\n if (index < 0) {\n index += this._length;\n }\n if (index < 0 || index >= this._length) {\n return;\n }\n const offset = this._dimensions * index;\n return this.data.subarray(\n offset,\n offset + this._dimensions\n ) as unknown as T;\n }\n\n /**\n * Returns a `number[]` version of the given point.\n * Changes to the array will NOT affect the underlying data.\n *\n * @param index - positive index from start, or negative from end\n * @returns A new number[] instance of the given point.\n */\n public getPointArray(index: number): T {\n const array = [];\n if (index < 0) {\n index += this._length;\n }\n if (index < 0 || index >= this._length) {\n return;\n }\n const offset = this._dimensions * index;\n for (let i = 0; i < this._dimensions; i++) {\n array.push(this.data[i + offset]);\n }\n return array as unknown as T;\n }\n\n /**\n * Updates the array size as needed to allow for at least the given\n * additional number of elements.\n */\n protected grow(additionalSize = 1, growSize = this.growSize) {\n if (\n this.dimensionLength + additionalSize * this._dimensions <=\n this.data.length\n ) {\n return;\n }\n const newSize = this.data.length + growSize;\n const newArray = new ArrayBuffer(\n newSize * this._dimensions * this._byteSize\n );\n const newData = new Float32Array(newArray);\n newData.set(this.data);\n this.data = newData;\n this.array = newArray;\n }\n\n /**\n * Reverse the points in place.\n */\n public reverse() {\n const midLength = Math.floor(this._length / 2);\n\n for (let i = 0; i < midLength; i++) {\n const indexStart = i * this._dimensions;\n const indexEnd = (this._length - 1 - i) * this._dimensions;\n for (let dimension = 0; dimension < this._dimensions; dimension++) {\n const valueStart = this.data[indexStart + dimension];\n this.data[indexStart + dimension] = this.data[indexEnd + dimension];\n this.data[indexEnd + dimension] = valueStart;\n }\n }\n }\n\n /**\n * Push a new point onto this arrays object\n */\n public push(point: T) {\n this.grow(1);\n const offset = this.length * this._dimensions;\n for (let i = 0; i < this._dimensions; i++) {\n this.data[i + offset] = point[i];\n }\n this._length++;\n }\n\n /**\n * Maps the array onto another type.\n */\n public map<R>(f: (value, index: number) => R): R[] {\n const mapData = [];\n for (let i = 0; i < this._length; i++) {\n mapData.push(f(this.getPoint(i), i));\n }\n return mapData;\n }\n\n /**\n * A points object containing Float32Array instances referring to the underlying\n * data, contained in a FloatArray32[] instance.\n * Note - changes to the data store will directly affect the points value\n * returned here, even if stored separately.\n */\n public get points(): T[] {\n return this.map((p) => p);\n }\n\n /**\n * The XYZ representation of a points array is an object with three separate\n * arrays, one for each of x,y and z, containing the point data, eg\n * `x: {x0, x1, x2, ...., xn }`\n * Will create just x,y for Point2 arrays.\n *\n * @returns An XYZ array\n */\n public toXYZ(): PointsXYZ {\n const xyz = { x: [], y: [] } as PointsXYZ;\n if (this._dimensions >= 3) {\n xyz.z = [];\n }\n const { x, y, z } = xyz;\n\n this.forEach((p) => {\n x.push(p[0]);\n y.push(p[1]);\n if (z) {\n z.push(p[2]);\n }\n });\n return xyz;\n }\n\n /**\n * Create an PointsArray3 from the x,y,z individual arrays (see toXYZ)\n * Will create a Point3 array even if z is missing, with 0 as the value.\n */\n public static fromXYZ({ x, y, z }: PointsXYZ): PointsManager<Point3> {\n const array = PointsManager.create3(x.length);\n let offset = 0;\n for (let i = 0; i < x.length; i++) {\n array.data[offset++] = x[i];\n array.data[offset++] = y[i];\n array.data[offset++] = z ? z[i] : 0;\n }\n array._length = x.length;\n return array;\n }\n\n /**\n * Select the given number of points from the array, evenly spaced at the\n * given offset (which must be between `(-count,count)`)\n */\n public subselect(count = 10, offset = 0): PointsManager<T> {\n const selected = new PointsManager<T>({\n initialSize: count,\n dimensions: this._dimensions,\n });\n for (let i = 0; i < count; i++) {\n const index =\n (offset + Math.floor((this.length * i) / count)) % this.length;\n selected.push(this.getPoint(index));\n }\n return selected;\n }\n\n /**\n * Create a PointsManager<Point3> instance with available capacity of initialSize\n */\n public static create3(initialSize = 128) {\n return new PointsManager<Point3>({ initialSize, dimensions: 3 });\n }\n\n /**\n * Create a PointsManager<Point2> instance with available capacity of initialSize\n */\n public static create2(initialSize = 128) {\n return new PointsManager<Point2>({ initialSize, dimensions: 2 });\n }\n}\n","import { ScalingParameters } from '../types';\n\n/**\n * If the scalar data is a Uint8Array, return 'Uint8Array'. If the scalar data is a\n * Float32Array, return 'Float32Array'. If the scalar data is a Int16Array, return\n * 'Int16Array'. If the scalar data is a Uint16Array, return 'Uint16Array'. If the\n * scalar data is none of the above, throw an error.\n * @param {ScalingParameters} scalingParameters - {\n * @param {any} [scalarData] - The data to be converted.\n * @returns The data type of the scalar data.\n */\nexport default function getScalarDataType(\n scalingParameters: ScalingParameters,\n scalarData?: any\n): string {\n let type;\n\n if (scalarData && scalarData instanceof Uint8Array) {\n type = 'Uint8Array';\n } else if (scalarData instanceof Float32Array) {\n type = 'Float32Array';\n } else if (scalarData instanceof Int16Array) {\n type = 'Int16Array';\n } else if (scalarData instanceof Uint16Array) {\n type = 'Uint16Array';\n } else {\n throw new Error('Unsupported array type');\n }\n\n return type;\n}\n","import { StackViewport, Types } from '..';\nimport getEnabledElement from '../getEnabledElement';\n\n/**\n * Gets the IImage rendered by the given element. This is provided as a\n * convenience for the legacy cornerstone getImage function. However it is\n * encouraged for IStackViewport.getImage to be used instead.\n * @param element - the element rendering/containing the image\n * @returns the image\n */\nfunction getImageLegacy(element: HTMLDivElement): Types.IImage | undefined {\n const enabledElement = getEnabledElement(element);\n\n if (!enabledElement) {\n return;\n }\n\n const { viewport } = enabledElement;\n\n if (!(viewport instanceof StackViewport)) {\n throw new Error(\n `An image can only be fetched for a stack viewport and not for a viewport of type: ${viewport.type}`\n );\n }\n\n return viewport.getCornerstoneImage();\n}\n\nexport default getImageLegacy;\n","import { metaData } from '..';\nimport isEqual from './isEqual';\n\n/**\n * Checks if the given imageIds form a valid volume. A volume is considered valid if all imageIds\n * have the same series instance UID, modality, columns, rows, image orientation patient, and pixel\n * spacing.\n *\n * @param imageIds - The imageIds to check.\n * @returns true if the imageIds form a valid volume, false otherwise.\n */\nfunction isValidVolume(imageIds: string[]): boolean {\n const imageId0 = imageIds[0];\n\n const { modality, seriesInstanceUID } = metaData.get(\n 'generalSeriesModule',\n imageId0\n );\n\n const {\n imageOrientationPatient,\n pixelSpacing,\n frameOfReferenceUID,\n columns,\n rows,\n } = metaData.get('imagePlaneModule', imageId0);\n\n const baseMetadata = {\n modality,\n imageOrientationPatient,\n pixelSpacing,\n frameOfReferenceUID,\n columns,\n rows,\n seriesInstanceUID,\n };\n\n const validVolume = imageIds.every((imageId) => {\n const { modality, seriesInstanceUID } = metaData.get(\n 'generalSeriesModule',\n imageId\n );\n const { imageOrientationPatient, pixelSpacing, columns, rows } =\n metaData.get('imagePlaneModule', imageId);\n\n return (\n seriesInstanceUID === baseMetadata.seriesInstanceUID &&\n modality === baseMetadata.modality &&\n columns === baseMetadata.columns &&\n rows === baseMetadata.rows &&\n isEqual(imageOrientationPatient, baseMetadata.imageOrientationPatient) &&\n isEqual(pixelSpacing, baseMetadata.pixelSpacing)\n );\n });\n\n return validVolume;\n}\n\nexport { isValidVolume };\n","export const videoUIDs = new Set<string>([\n '1.2.840.10008.1.2.4.100',\n '1.2.840.10008.1.2.4.100.1',\n '1.2.840.10008.1.2.4.101',\n '1.2.840.10008.1.2.4.101.1',\n '1.2.840.10008.1.2.4.102',\n '1.2.840.10008.1.2.4.102.1',\n '1.2.840.10008.1.2.4.103',\n '1.2.840.10008.1.2.4.103.1',\n '1.2.840.10008.1.2.4.104',\n '1.2.840.10008.1.2.4.104.1',\n '1.2.840.10008.1.2.4.105',\n '1.2.840.10008.1.2.4.105.1',\n '1.2.840.10008.1.2.4.106',\n '1.2.840.10008.1.2.4.106.1',\n '1.2.840.10008.1.2.4.107',\n '1.2.840.10008.1.2.4.108',\n]);\n\nexport default function isVideoTransferSyntax(uidOrUids: string | string[]) {\n if (!uidOrUids) {\n return false;\n }\n const uids = Array.isArray(uidOrUids) ? uidOrUids : [uidOrUids];\n return uids.find((uid) => videoUIDs.has(uid));\n}\n","import BaseVolumeViewport from '../BaseVolumeViewport';\nimport type {\n IVolumeInput,\n IRenderingEngine,\n IVolumeViewport,\n} from '../../types';\n\n/**\n * Similar to {@link addVolumesToViewports} it adds volumes to viewports; however,\n * this method will Set the volumes on the viewports which means that the previous\n * volumes will be removed.\n *\n * @param renderingEngine - The rendering engine to use to get viewports from\n * @param volumeInputs - Array of volume inputs including volumeId. Other properties\n * such as visibility, callback, blendMode, slabThickness are optional\n * @param viewportIds - Array of viewport IDs to add the volume to\n * @param immediateRender - If true, the volumes will be rendered immediately\n * @returns A promise that resolves when all volumes have been added\n */\nasync function setVolumesForViewports(\n renderingEngine: IRenderingEngine,\n volumeInputs: Array<IVolumeInput>,\n viewportIds: Array<string>,\n immediateRender = false,\n suppressEvents = false\n): Promise<void> {\n // Check if all viewports are volumeViewports\n viewportIds.forEach((viewportId) => {\n const viewport = renderingEngine.getViewport(viewportId);\n\n if (!viewport) {\n throw new Error(`Viewport with Id ${viewportId} does not exist`);\n }\n\n // if not instance of BaseVolumeViewport, throw\n if (!(viewport instanceof BaseVolumeViewport)) {\n throw new Error(\n 'setVolumesForViewports only supports VolumeViewport and VolumeViewport3D'\n );\n }\n });\n\n const setVolumePromises = viewportIds.map(async (viewportId) => {\n const viewport = renderingEngine.getViewport(viewportId) as IVolumeViewport;\n\n await viewport.setVolumes(volumeInputs, immediateRender, suppressEvents);\n });\n\n await Promise.all(setVolumePromises);\n\n return;\n}\n\nexport default setVolumesForViewports;\n","import { IStackViewport, IVolumeViewport, Point3 } from '../types';\nimport { setVolumesForViewports } from '../RenderingEngine/helpers';\nimport {\n createAndCacheVolume,\n getUnknownVolumeLoaderSchema,\n} from '../loaders/volumeLoader';\nimport { Events, OrientationAxis, ViewportType } from '../enums';\n\n/**\n * Converts a stack viewport to a volume viewport.\n *\n * @param params - The parameters for the conversion.\n * @param params.viewport - The stack viewport to convert.\n * @param params.options - The options for the conversion.\n * @param [params.options.volumeId] - The volumeId that will get generated, it should have the volume loader schema defined if not we will use the default one.\n * @param [params.options.viewportId] - The viewportId that will get used for new viewport. If not provided, the stack viewport id will be used.\n * @param [params.options.background] - The background color of the volume viewport.\n * @returns The converted volume viewport.\n */\nasync function convertStackToVolumeViewport({\n viewport,\n options,\n}: {\n viewport: IStackViewport;\n options: {\n volumeId: string;\n viewportId?: string;\n background?: Point3;\n orientation?: OrientationAxis;\n };\n}): Promise<IVolumeViewport> {\n const renderingEngine = viewport.getRenderingEngine();\n\n let { volumeId } = options;\n\n // if there is no loader schema for the volume Id, we will use the default one\n // which we can get from the volume loader\n if (volumeId.split(':').length === 1) {\n const schema = getUnknownVolumeLoaderSchema();\n volumeId = `${schema}:${volumeId}`;\n }\n\n const { id, element } = viewport;\n const viewportId = options.viewportId || id;\n\n const imageIds = viewport.getImageIds();\n\n // It is important to keep the camera before enabling the viewport\n const prevCamera = viewport.getCamera();\n\n // this will disable the stack viewport and remove it from the toolGroup\n renderingEngine.enableElement({\n viewportId,\n type: ViewportType.ORTHOGRAPHIC,\n element,\n defaultOptions: {\n background: options.background,\n orientation: options.orientation,\n },\n });\n\n // Ideally here we should be able to just create a local volume and not use the\n // volume louder but we don't know if the stack is already pre-cached for all its\n // imageIds or not so we just let the loader handle it and we have cache\n // optimizations in place to avoid fetching the same imageId if it is already\n // cached\n const volume = await createAndCacheVolume(volumeId, {\n imageIds,\n });\n\n volume.load();\n\n // we should get the new viewport from the renderingEngine since the stack viewport\n // was disabled and replaced with a volume viewport of the same id\n const volumeViewport = <IVolumeViewport>(\n renderingEngine.getViewport(viewportId)\n );\n\n setVolumesForViewports(\n renderingEngine,\n [\n {\n volumeId,\n },\n ],\n [viewportId]\n );\n\n const volumeViewportNewVolumeHandler = () => {\n if (!options.orientation) {\n volumeViewport.setCamera({\n ...prevCamera,\n });\n }\n volumeViewport.render();\n\n element.removeEventListener(\n Events.VOLUME_VIEWPORT_NEW_VOLUME,\n volumeViewportNewVolumeHandler\n );\n };\n\n const addVolumeViewportNewVolumeListener = () => {\n element.addEventListener(\n Events.VOLUME_VIEWPORT_NEW_VOLUME,\n volumeViewportNewVolumeHandler\n );\n };\n\n addVolumeViewportNewVolumeListener();\n\n volumeViewport.render();\n\n return volumeViewport;\n}\n\nexport { convertStackToVolumeViewport };\n","import * as Types from '../types';\nimport cache, { ImageVolume } from '../cache';\nimport { ViewportType } from '../enums';\n\n/**\n * Converts a volume viewport to a stack viewport.\n *\n * @param params - The parameters for the conversion.\n * @param params.viewport - The volume viewport to convert.\n * @param params.options - The conversion options.\n * @param [params.options.viewportId] - The new stackViewportId, If not provided, the volume viewport id will be used.\n * @param [params.options.background] - The background color of the stack viewport.\n * @param [params.options.decache] - Whether to decache the volume. Defaults to false.\n *\n * @returns The converted stack viewport.\n */\nasync function convertVolumeToStackViewport({\n viewport,\n options,\n}: {\n viewport: Types.IVolumeViewport;\n options: {\n viewportId?: string;\n background?: Types.Point3;\n };\n}): Promise<Types.IStackViewport> {\n const volumeViewport = viewport;\n const { id, element } = volumeViewport;\n const renderingEngine = viewport.getRenderingEngine();\n const imageIdIndex = viewport.getCurrentImageIdIndex();\n\n const { background } = options;\n const viewportId = options.viewportId || id;\n\n const actorEntry = volumeViewport.getDefaultActor();\n const { uid: volumeId } = actorEntry;\n const volume = cache.getVolume(volumeId) as Types.IImageVolume;\n\n if (!(volume instanceof ImageVolume)) {\n throw new Error(\n 'Currently, you cannot decache a volume that is not an ImageVolume. So, unfortunately, volumes such as nifti (which are basic Volume, without imageIds) cannot be decached.'\n );\n }\n\n const viewportInput = {\n viewportId,\n type: ViewportType.STACK,\n element,\n defaultOptions: {\n background,\n },\n };\n\n renderingEngine.enableElement(viewportInput);\n\n // Get the stack viewport that was created\n const stackViewport = <Types.IStackViewport>(\n renderingEngine.getViewport(viewportId)\n );\n\n // So here we have two scenarios that we need to handle:\n // 1. the volume was derived from a stack and we need to decache it, this is easy\n // since we just need purge the volume from the cache and those images will get\n // their copy of the image back\n // 2. It was actually a native volume and we need to decache it, this is a bit more\n // complicated since then we need to decide on the imageIds for it to get\n // decached to\n const hasCachedImages = volume.imageCacheOffsetMap.size > 0;\n // Initialize the variable to hold the final result\n let isAllImagesCached = false;\n\n if (hasCachedImages) {\n // Check if every imageId in the volume is in the _imageCache\n isAllImagesCached = volume.imageIds.every((imageId) =>\n cache.getImage(imageId)\n );\n }\n\n const volumeUsedInOtherViewports = renderingEngine\n .getVolumeViewports()\n .find((vp) => vp.hasVolumeId(volumeId));\n\n volume.decache(!volumeUsedInOtherViewports && isAllImagesCached);\n\n const stack = [...volume.imageIds].reverse();\n\n let imageIdIndexToJump = Math.max(\n volume.imageIds.length - imageIdIndex - 1,\n 0\n );\n\n // Check to see if the image is already cached or not. If it's not, we will use another\n // nearby imageId for the first image to jump to. There seem to be a lot of side effects\n // if we jump to an image that is not cached in stack viewport while we convert\n // from a volume viewport. For example, if we switch back and forth between stack and volume,\n // and then try to jump to an image that is not cached, the image will not render at\n // all when the full volume is filled. I'm not sure why yet.\n const imageToJump = cache.getImage(stack[imageIdIndexToJump]);\n if (!imageToJump) {\n let minDistance = Infinity;\n let minDistanceIndex = null;\n\n stack.forEach((imageId, index) => {\n const image = cache.getImage(imageId);\n if (image) {\n const distance = Math.abs(imageIdIndexToJump - index);\n if (distance < minDistance) {\n minDistance = distance;\n minDistanceIndex = index;\n }\n }\n });\n\n imageIdIndexToJump = minDistanceIndex;\n }\n\n await stackViewport.setStack(stack, imageIdIndexToJump ?? 0);\n\n // Render the image\n stackViewport.render();\n\n return stackViewport;\n}\n\nexport { convertVolumeToStackViewport };\n","import { PixelDataTypedArray } from '../types';\n\n/**\n * The RLERun specifies a contigous run of values for a row,\n * where all indices (i only) from `[start,end)` have the specified\n * value.\n */\nexport type RLERun<T> = {\n value: T;\n start: number;\n end: number;\n};\n\n/**\n * RLE based implementation of a voxel map.\n * This can be used as single or multi-plane, as the underlying indexes are\n * mapped to rows and hte rows are indexed started at 0 and continuing\n * incrementing for all rows in the multi-plane voxel.\n */\nexport default class RLEVoxelMap<T> {\n /**\n * The rows for the voxel map is a map from the j index location (or for\n * volumes, `j + k*height`) to a list of RLE runs. That is, each entry in\n * the rows specifies the voxel data for a given row in the image.\n * Then, the RLE runs themselves specify the pixel values for given rows as\n * a pair of start/end indices, plus the value to apply.\n */\n protected rows = new Map<number, RLERun<T>[]>();\n /** The height of the images stored in the voxel map (eg the height of each plane) */\n protected height = 1;\n /** The width of the image planes */\n protected width = 1;\n /**\n * The number of image planes stored (the depth of the indices), with the k\n * index going from 0...depth.\n */\n protected depth = 1;\n /**\n * A multiplier value to go from j values to overall index values.\n */\n protected jMultiple = 1;\n /**\n * A multiplier value to go from k values to overall index values.\n */\n protected kMultiple = 1;\n /** Number of components in the value */\n protected numComps = 1;\n\n /**\n * The default value returned for get.\n * This allows treting the voxel map more like scalar data, returning the right\n * default value for unset values.\n * Set to 0 by default, but any maps where 0 not in T should update this value.\n */\n public defaultValue: T = 0 as unknown as T;\n\n /**\n * The constructor for creating pixel data.\n */\n public pixelDataConstructor = Uint8Array;\n\n constructor(width: number, height: number, depth = 1) {\n this.width = width;\n this.height = height;\n this.depth = depth;\n this.jMultiple = width;\n this.kMultiple = this.jMultiple * height;\n }\n\n /**\n * Gets the value encoded in the map at the given index, which is\n * an integer `[i,j,k]` voxel index, equal to `index=i+(j+k*height)*width`\n * value (eg a standard ScalarData index for stack/volume single component\n * indices.)\n *\n * Returns defaultValue if the RLE value is not found.\n */\n public get = (index: number): T => {\n const i = index % this.jMultiple;\n const j = (index - i) / this.jMultiple;\n const rle = this.getRLE(i, j);\n return rle?.value || this.defaultValue;\n };\n\n /**\n * Gets a list of RLERun values which specify the data on the row j\n * This allows applying or modifying the run directly. See CanvasActor\n * for an example in the RLE rendering.\n */\n protected getRLE(i: number, j: number, k = 0): RLERun<T> {\n const row = this.rows.get(j + k * this.height);\n if (!row) {\n return;\n }\n const index = this.findIndex(row, i);\n const rle = row[index];\n return i >= rle?.start ? rle : undefined;\n }\n\n /**\n * Finds the index in the row that i is contained in, OR that i would be\n * before. That is, the rle value for the returned index in that row\n * has `i ε [start,end)` if a direct RLE is found, or `i ε [end_-1,start)` if\n * in the prefix. If no RLE is found with that index, then\n * `i ε [end_final,length)`\n */\n protected findIndex(row: RLERun<T>[], i: number) {\n for (let index = 0; index < row.length; index++) {\n const { end: iEnd } = row[index];\n if (i < iEnd) {\n return index;\n }\n }\n return row.length;\n }\n\n /**\n * Gets the run for the given j,k indices. This is used to allow fast access\n * to runs for data for things like rendering entire rows of data.\n */\n public getRun = (j: number, k: number) => {\n const runIndex = j + k * this.height;\n return this.rows.get(runIndex);\n };\n\n /**\n * Adds to the RLE at the given position. This is unfortunately fairly\n * complex since it is desirable to minimize the number of runs, but to still\n * allow it to be efficient.\n */\n public set = (index: number, value: T) => {\n if (value === undefined) {\n throw new Error(`Can't set undefined at ${index % this.width}`);\n }\n const i = index % this.width;\n const j = (index - i) / this.width;\n const row = this.rows.get(j);\n if (!row) {\n this.rows.set(j, [{ start: i, end: i + 1, value }]);\n return;\n }\n const rleIndex = this.findIndex(row, i);\n const rle1 = row[rleIndex];\n const rle0 = row[rleIndex - 1];\n\n // Adding to the end of the row\n if (!rle1) {\n // We are at the end, check if the previous rle can be extended\n if (!rle0 || rle0.value !== value || rle0.end !== i) {\n row[rleIndex] = { start: i, end: i + 1, value };\n // validateRow(row, i, rleIndex, value);\n return;\n }\n // Just add it to the previous element.\n rle0.end++;\n return;\n }\n\n const { start, end, value: oldValue } = rle1;\n\n // Handle the already in place case\n if (value === oldValue && i >= start) {\n // validateRow(row, i, rleIndex, value, start);\n return;\n }\n\n const rleInsert = { start: i, end: i + 1, value };\n const isAfter = i > start;\n const insertIndex = isAfter ? rleIndex + 1 : rleIndex;\n const rlePrev = isAfter ? rle1 : rle0;\n let rleNext = isAfter ? row[rleIndex + 1] : rle1;\n\n // Can merge with previous value, so no insert\n if (rlePrev?.value === value && rlePrev?.end === i) {\n rlePrev.end++;\n if (rleNext?.value === value && rleNext.start === i + 1) {\n rlePrev.end = rleNext.end;\n row.splice(rleIndex, 1);\n // validateRow(row, i, rleIndex, value);\n } else if (rleNext?.start === i) {\n rleNext.start++;\n if (rleNext.start === rleNext.end) {\n row.splice(rleIndex, 1);\n rleNext = row[rleIndex];\n // Check if we can merge twice\n if (rleNext?.start === i + 1 && rleNext.value === value) {\n rlePrev.end = rleNext.end;\n row.splice(rleIndex, 1);\n }\n }\n // validateRow(row, i, rleIndex, value);\n }\n return;\n }\n\n // Can merge with next, so no insert\n if (rleNext?.value === value && rleNext.start === i + 1) {\n rleNext.start--;\n if (rlePrev?.end > i) {\n rlePrev.end = i;\n if (rlePrev.end === rlePrev.start) {\n row.splice(rleIndex, 1);\n }\n }\n // validateRow(row, i, rleIndex, value);\n return;\n }\n\n // Can't merge, need to see if we can replace\n if (rleNext?.start === i && rleNext.end === i + 1) {\n rleNext.value = value;\n const nextnext = row[rleIndex + 1];\n if (nextnext?.start == i + 1 && nextnext.value === value) {\n row.splice(rleIndex + 1, 1);\n rleNext.end = nextnext.end;\n }\n // validateRow(row, i, rleIndex, value);\n return;\n }\n\n // Need to fix the next start value\n if (i === rleNext?.start) {\n rleNext.start++;\n }\n if (isAfter && end > i + 1) {\n // Insert two items, to split the existing into three\n row.splice(insertIndex, 0, rleInsert, {\n start: i + 1,\n end: rlePrev.end,\n value: rlePrev.value,\n });\n } else {\n row.splice(insertIndex, 0, rleInsert);\n }\n if (rlePrev?.end > i) {\n rlePrev.end = i;\n }\n // validateRow(row, i, rleIndex, value, insertIndex);\n };\n\n /**\n * Clears all entries.\n */\n public clear() {\n this.rows.clear();\n }\n\n /**\n * Gets the set of key entries - that is j values. This may include\n * `j>=height`, where `j = key % height`, and `k = Math.floor(j / height)`\n */\n public keys(): number[] {\n return [...this.rows.keys()];\n }\n\n /**\n * Gets the pixel data into the provided pixel data array, or creates one\n * according to the assigned type.\n */\n public getPixelData(\n k = 0,\n pixelData?: PixelDataTypedArray\n ): PixelDataTypedArray {\n if (!pixelData) {\n pixelData = new this.pixelDataConstructor(\n this.width * this.height * this.numComps\n );\n } else {\n pixelData.fill(0);\n }\n const { width, height, numComps } = this;\n\n for (let j = 0; j < height; j++) {\n const row = this.getRun(j, k);\n if (!row) {\n continue;\n }\n if (numComps === 1) {\n for (const rle of row) {\n const rowOffset = j * width;\n const { start, end, value } = rle;\n for (let i = start; i < end; i++) {\n pixelData[rowOffset + i] = value as unknown as number;\n }\n }\n } else {\n for (const rle of row) {\n const rowOffset = j * width * numComps;\n const { start, end, value } = rle;\n for (let i = start; i < end; i += numComps) {\n for (let comp = 0; comp < numComps; comp++) {\n pixelData[rowOffset + i + comp] = value[comp];\n }\n }\n }\n }\n }\n return pixelData;\n }\n}\n\n// This is some code to allow debugging RLE maps\n// To be deleted along with references once RLE is better tested.\n// Might move to testing code at that point\n// function validateRow(row, ...inputs) {\n// if (!row) {\n// return;\n// }\n// let lastRle;\n// for (const rle of row) {\n// const { start, end, value } = rle;\n// if (start < 0 || end > 1920 || start >= end) {\n// console.log('Wrong order', ...inputs);\n// debugger;\n// }\n// if (!lastRle) {\n// lastRle = rle;\n// continue;\n// }\n// const { start: lastStart, end: lastEnd, value: lastValue } = lastRle;\n// lastRle = rle;\n// if (start < lastEnd) {\n// console.log('inputs for wrong overlap', ...inputs);\n// debugger;\n// }\n// if (start === lastEnd && value === lastValue) {\n// console.log('inputs for two in a row same', ...inputs);\n// debugger;\n// }\n// }\n// }\n","import type {\n BoundsIJK,\n Point3,\n PixelDataTypedArray,\n IImage,\n RGB,\n} from '../types';\nimport RLEVoxelMap from './RLEVoxelMap';\nimport isEqual from './isEqual';\n\n/**\n * Have a default size for cached RLE encoded images. This is hard to guess\n * up front because the RLE is usually used to store new/updated data, but this\n * is a first guess.\n */\nconst DEFAULT_RLE_SIZE = 5 * 1024;\n\n/**\n * This is a simple, standard interface to values associated with a voxel.\n */\nexport default class VoxelManager<T> {\n public modifiedSlices = new Set<number>();\n public boundsIJK = [\n [Infinity, -Infinity],\n [Infinity, -Infinity],\n [Infinity, -Infinity],\n ] as BoundsIJK;\n\n // Provide direct access to the underlying data, if any\n public scalarData: PixelDataTypedArray;\n public map: Map<number, T> | RLEVoxelMap<T>;\n public sourceVoxelManager: VoxelManager<T>;\n public isInObject: (pointIPS, pointIJK) => boolean;\n public readonly dimensions: Point3;\n public numComps = 1;\n\n points: Set<number>;\n width: number;\n frameSize: number;\n _get: (index: number) => T;\n _set: (index: number, v: T) => boolean | void;\n\n /**\n * Creates a generic voxel value accessor, with access to the values\n * provided by the _get and optionally _set values.\n * @param dimensions - for the voxel volume\n * @param _get - called to get a value by index\n * @param _set - called when setting a value\n */\n constructor(\n dimensions,\n _get: (index: number) => T,\n _set?: (index: number, v: T) => boolean | void\n ) {\n this.dimensions = dimensions;\n this.width = dimensions[0];\n this.frameSize = this.width * dimensions[1];\n this._get = _get;\n this._set = _set;\n }\n\n /**\n * Gets the voxel value at position i,j,k.\n */\n public getAtIJK = (i, j, k) => {\n const index = i + j * this.width + k * this.frameSize;\n return this._get(index);\n };\n\n /**\n * Sets the voxel value at position i,j,k and records the slice\n * that was modified.\n */\n public setAtIJK = (i: number, j: number, k: number, v) => {\n const index = i + j * this.width + k * this.frameSize;\n if (this._set(index, v) !== false) {\n this.modifiedSlices.add(k);\n VoxelManager.addBounds(this.boundsIJK, [i, j, k]);\n }\n };\n\n /**\n * Adds a point as an array or an index value to the set of points\n * associated with this voxel value.\n * Can be used for tracking clicked points or other modified values.\n */\n public addPoint(point: Point3 | number) {\n const index = Array.isArray(point)\n ? point[0] + this.width * point[1] + this.frameSize * point[2]\n : point;\n if (!this.points) {\n this.points = new Set<number>();\n }\n this.points.add(index);\n }\n\n /**\n * Gets the list of added points as an array of Point3 values\n */\n public getPoints(): Point3[] {\n return this.points\n ? [...this.points].map((index) => this.toIJK(index))\n : [];\n }\n\n /**\n * Gets the points added using addPoint as an array of indices.\n */\n public getPointIndices(): number[] {\n return this.points ? [...this.points] : [];\n }\n\n /**\n * Gets the voxel value at the given Point3 location.\n */\n public getAtIJKPoint = ([i, j, k]) => this.getAtIJK(i, j, k);\n\n /**\n * Sets the voxel value at the given point3 location to the specified value.\n * Records the z index modified.\n * Will record the index value if the VoxelManager is backed by a map.\n */\n public setAtIJKPoint = ([i, j, k]: Point3, v) => this.setAtIJK(i, j, k, v);\n\n /**\n * Gets the value at the given index.\n */\n public getAtIndex = (index) => this._get(index);\n\n /**\n * Sets the value at the given index\n */\n public setAtIndex = (index, v) => {\n if (this._set(index, v) !== false) {\n const pointIJK = this.toIJK(index);\n this.modifiedSlices.add(pointIJK[2]);\n VoxelManager.addBounds(this.boundsIJK, pointIJK);\n }\n };\n\n /**\n * Converts an index value to a Point3 IJK value\n */\n public toIJK(index: number): Point3 {\n return [\n index % this.width,\n Math.floor((index % this.frameSize) / this.width),\n Math.floor(index / this.frameSize),\n ];\n }\n\n /**\n * Converts an IJK Point3 value to an index value\n */\n public toIndex(ijk: Point3) {\n return ijk[0] + ijk[1] * this.width + ijk[2] * this.frameSize;\n }\n\n /**\n * Gets the bounds for the modified set of values.\n */\n public getBoundsIJK(): BoundsIJK {\n if (this.boundsIJK[0][0] < this.dimensions[0]) {\n return this.boundsIJK;\n }\n return this.dimensions.map((dimension) => [0, dimension - 1]) as BoundsIJK;\n }\n\n /**\n * Iterate over the points within the bounds, or the modified points if recorded.\n */\n public forEach = (callback, options?) => {\n const boundsIJK = options?.boundsIJK || this.getBoundsIJK();\n const { isWithinObject } = options || {};\n if (this.map) {\n // Optimize this for only values in the map\n for (const index of this.map.keys()) {\n const pointIJK = this.toIJK(index);\n const value = this._get(index);\n const callbackArguments = { value, index, pointIJK };\n if (isWithinObject?.(callbackArguments) === false) {\n continue;\n }\n callback(callbackArguments);\n }\n } else {\n for (let k = boundsIJK[2][0]; k <= boundsIJK[2][1]; k++) {\n const kIndex = k * this.frameSize;\n for (let j = boundsIJK[1][0]; j <= boundsIJK[1][1]; j++) {\n const jIndex = kIndex + j * this.width;\n for (\n let i = boundsIJK[0][0], index = jIndex + i;\n i <= boundsIJK[0][1];\n i++, index++\n ) {\n const value = this.getAtIndex(index);\n const callbackArguments = { value, index, pointIJK: [i, j, k] };\n if (isWithinObject?.(callbackArguments) === false) {\n continue;\n }\n callback(callbackArguments);\n }\n }\n }\n }\n };\n\n /**\n * Clears any map specific data, as wellas the modified slices, points and\n * bounds.\n */\n public clear() {\n if (this.map) {\n this.map.clear();\n }\n this.boundsIJK.map((bound) => {\n bound[0] = Infinity;\n bound[1] = -Infinity;\n });\n this.modifiedSlices.clear();\n this.points?.clear();\n }\n\n /**\n * @returns The array of modified k indices\n */\n public getArrayOfSlices(): number[] {\n return Array.from(this.modifiedSlices);\n }\n\n /**\n * Extends the bounds of this object to include the specified point\n */\n public static addBounds(bounds: BoundsIJK, point: Point3) {\n if (!bounds) {\n bounds = [\n [Infinity, -Infinity],\n [Infinity, -Infinity],\n [Infinity, -Infinity],\n ];\n }\n\n // Directly update the bounds for each axis\n bounds[0][0] = Math.min(point[0], bounds[0][0]);\n bounds[0][1] = Math.max(point[0], bounds[0][1]);\n bounds[1][0] = Math.min(point[1], bounds[1][0]);\n bounds[1][1] = Math.max(point[1], bounds[1][1]);\n bounds[2][0] = Math.min(point[2], bounds[2][0]);\n bounds[2][1] = Math.max(point[2], bounds[2][1]);\n }\n\n /**\n * Gets the pixel data for the given array.\n */\n public getPixelData: (\n sliceIndex?: number,\n pixelData?: PixelDataTypedArray\n ) => PixelDataTypedArray;\n\n /**\n * Creates a voxel manager backed by an array of scalar data having the\n * given number of components.\n * Note that the number of components can be larger than three, in case data\n * is stored in additional pixels. However, the return type is still RGB.\n */\n public static createRGBVolumeVoxelManager(\n dimensions: Point3,\n scalarData,\n numComponents\n ): VoxelManager<RGB> {\n const voxels = new VoxelManager<RGB>(\n dimensions,\n (index) => {\n index *= numComponents;\n return [scalarData[index++], scalarData[index++], scalarData[index++]];\n },\n (index, v) => {\n index *= 3;\n const isChanged = !isEqual(scalarData[index], v);\n scalarData[index++] = v[0];\n scalarData[index++] = v[1];\n scalarData[index++] = v[2];\n return isChanged;\n }\n );\n voxels.numComps = numComponents;\n voxels.scalarData = scalarData;\n return voxels;\n }\n\n /**\n * Creates a volume value accessor, based on a volume scalar data instance.\n * This also works for image value accessors for single plane (k=0) accessors.\n */\n public static createVolumeVoxelManager(\n dimensions: Point3,\n scalarData,\n numComponents = 0\n ): VoxelManager<number> | VoxelManager<RGB> {\n if (dimensions.length !== 3) {\n throw new Error(\n 'Dimensions must be provided as [number, number, number] for [width, height, depth]'\n );\n }\n if (!numComponents) {\n numComponents =\n scalarData.length / dimensions[0] / dimensions[1] / dimensions[2];\n // We only support 1,3,4 component data, and sometimes the scalar data\n // doesn't match for some reason, so throw an exception\n if (numComponents > 4 || numComponents < 1 || numComponents === 2) {\n throw new Error(\n `Number of components ${numComponents} must be 1, 3 or 4`\n );\n }\n }\n if (numComponents > 1) {\n return VoxelManager.createRGBVolumeVoxelManager(\n dimensions,\n scalarData,\n numComponents\n );\n }\n return VoxelManager.createNumberVolumeVoxelManager(dimensions, scalarData);\n }\n\n /**\n * Creates a volume voxel manager that works on single numeric values stored\n * in an array like structure of numbers.\n */\n public static createNumberVolumeVoxelManager(\n dimensions: Point3,\n scalarData\n ): VoxelManager<number> {\n const voxels = new VoxelManager<number>(\n dimensions,\n (index) => scalarData[index],\n (index, v) => {\n const isChanged = scalarData[index] !== v;\n scalarData[index] = v;\n return isChanged;\n }\n );\n voxels.scalarData = scalarData;\n return voxels;\n }\n\n /**\n * Creates a volume map value accessor. This is initially empty and\n * the map stores the index to value instances.\n * This is useful for sparse matrices containing pixel data.\n */\n public static createMapVoxelManager<T>(dimension: Point3): VoxelManager<T> {\n const map = new Map<number, T>();\n const voxelManager = new VoxelManager(\n dimension,\n map.get.bind(map),\n (index, v) => map.set(index, v) && true\n );\n voxelManager.map = map;\n return voxelManager;\n }\n\n /**\n * Creates a history remembering voxel manager.\n * This will remember the original values in the voxels, and will apply the\n * update to the underlying source voxel manager.\n */\n public static createHistoryVoxelManager<T>(\n sourceVoxelManager: VoxelManager<T>\n ): VoxelManager<T> {\n const map = new Map<number, T>();\n const { dimensions } = sourceVoxelManager;\n const voxelManager = new VoxelManager(\n dimensions,\n (index) => map.get(index),\n function (index, v) {\n if (!map.has(index)) {\n const oldV = this.sourceVoxelManager.getAtIndex(index);\n if (oldV === v) {\n // No-op\n return false;\n }\n map.set(index, oldV);\n } else if (v === map.get(index)) {\n map.delete(index);\n }\n this.sourceVoxelManager.setAtIndex(index, v);\n }\n );\n voxelManager.map = map;\n voxelManager.scalarData = sourceVoxelManager.scalarData;\n voxelManager.sourceVoxelManager = sourceVoxelManager;\n return voxelManager;\n }\n\n /**\n * Creates a lazy voxel manager that will create an image plane as required\n * for each slice of a volume as it gets changed. This can be used to\n * store image data that gets created as required.\n */\n public static createLazyVoxelManager<T>(\n dimensions: Point3,\n planeFactory: (width: number, height: number) => T\n ): VoxelManager<T> {\n const map = new Map<number, T>();\n const [width, height, depth] = dimensions;\n const planeSize = width * height;\n\n const voxelManager = new VoxelManager(\n dimensions,\n (index) => map.get(Math.floor(index / planeSize))?.[index % planeSize],\n (index, v) => {\n const k = Math.floor(index / planeSize);\n let layer = map.get(k);\n if (!layer) {\n layer = planeFactory(width, height);\n map.set(k, layer);\n }\n layer[index % planeSize] = v;\n }\n );\n voxelManager.map = map;\n return voxelManager;\n }\n\n /**\n * Creates a RLE based voxel manager. This is effective for storing\n * segmentation maps or already RLE encoded data such as ultrasounds.\n */\n public static createRLEVoxelManager<T>(dimensions: Point3): VoxelManager<T> {\n const [width, height, depth] = dimensions;\n const map = new RLEVoxelMap<T>(width, height, depth);\n\n const voxelManager = new VoxelManager<T>(\n dimensions,\n (index) => map.get(index),\n (index, v) => map.set(index, v)\n );\n voxelManager.map = map;\n voxelManager.getPixelData = map.getPixelData.bind(map);\n return voxelManager;\n }\n\n /**\n * This method adds a voxelManager instance to the image object\n * where the object added is of type:\n * 1. RLE map if the scalar data is missing or too small (dummy data)\n * 2. Volume VoxelManager scalar data representations\n */\n public static addInstanceToImage(image: IImage) {\n const { width, height } = image;\n const scalarData = image.getPixelData();\n // This test works for single images, or single representations of images\n // from a volume representation, for grayscale, indexed and RGB or RGBA images.\n if (scalarData?.length >= width * height) {\n // This case means there is enough scalar data for at least one image,\n // with 1 or more components, and creates a volume voxel manager\n // that can lookup the data\n image.voxelManager = VoxelManager.createVolumeVoxelManager(\n [width, height, 1],\n scalarData\n );\n return;\n }\n // This case occurs when the image data is a dummy image data set\n // created just to prevent exceptions in the caching logic. Then, the\n // RLE voxel manager can be created to store the data instead.\n image.voxelManager = VoxelManager.createRLEVoxelManager<number>([\n width,\n height,\n 1,\n ]);\n // The RLE voxel manager knows how to get scalar data pixel data representations.\n // That allows using the RLE representation as a normal pixel data representation\n // for VIEWING purposes.\n image.getPixelData = image.voxelManager.getPixelData;\n // Assign a different size to the cached data because this is actually\n // storing an RLE representation, which doesn't have an up front size.\n image.sizeInBytes = DEFAULT_RLE_SIZE;\n }\n}\n\nexport type { VoxelManager };\n","import { EPSILON } from '../constants';\n\n/**\n * Truncates decimal points to that there is at least 1+precision significant\n * digits.\n *\n * For example, with the default precision 2 (3 significant digits)\n * * Values larger than 100 show no information after the decimal point\n * * Values between 10 and 99 show 1 decimal point\n * * Values between 1 and 9 show 2 decimal points\n *\n * @param value - to return a fixed measurement value from\n * @param precision - defining how many digits after 1..9 are desired\n */\nfunction roundNumber(\n value: string | number | (string | number)[],\n precision = 2\n): string {\n if (Array.isArray(value)) {\n return value.map((v) => roundNumber(v, precision)).join(', ');\n }\n if (value === undefined || value === null || value === '') {\n return 'NaN';\n }\n value = Number(value);\n const absValue = Math.abs(value);\n if (absValue < 0.0001) {\n return `${value}`;\n }\n const fixedPrecision =\n absValue >= 100\n ? precision - 2\n : absValue >= 10\n ? precision - 1\n : absValue >= 1\n ? precision\n : absValue >= 0.1\n ? precision + 1\n : absValue >= 0.01\n ? precision + 2\n : absValue >= 0.001\n ? precision + 3\n : precision + 4;\n return value.toFixed(fixedPrecision);\n}\n\n/**\n * Rounds a number to the nearest multiple of EPSILON.\n * @param value - The number to round.\n * @returns The rounded number.\n */\nfunction roundToPrecision(value) {\n return Math.round(value / EPSILON) * EPSILON;\n}\n\nexport { roundToPrecision };\nexport default roundNumber;\n","export default function convertToGrayscale(\n scalarData,\n width: number,\n height: number\n) {\n const isRGBA = scalarData.length === width * height * 4;\n const isRGB = scalarData.length === width * height * 3;\n if (isRGBA || isRGB) {\n const newScalarData = new Float32Array(width * height);\n let offset = 0;\n let destOffset = 0;\n const increment = isRGBA ? 4 : 3;\n for (let x = 0; x < width; x++) {\n for (let y = 0; y < height; y++) {\n const r = scalarData[offset];\n const g = scalarData[offset + 1];\n const b = scalarData[offset + 2];\n newScalarData[destOffset] = (r + g + b) / 3;\n offset += increment;\n destOffset++;\n }\n }\n return newScalarData;\n } else {\n return scalarData;\n }\n}\n","import { VolumeViewport } from '../RenderingEngine';\nimport cache from '../cache';\nimport { IViewport, IStackViewport } from '../types';\n\n/**\n * Retrieves the image IDs from the given viewport.\n *\n * @param viewport - The viewport to retrieve the image IDs from.\n * @returns An array of image IDs.\n */\nfunction getViewportImageIds(viewport: IViewport) {\n if (viewport instanceof VolumeViewport) {\n const defaultActor = viewport.getDefaultActor();\n const volumeId = defaultActor.uid;\n const volume = cache.getVolume(volumeId);\n return volume.imageIds;\n } else if ((viewport as IStackViewport).getImageIds) {\n return (viewport as IStackViewport).getImageIds();\n }\n}\n\nexport default getViewportImageIds;\n","/**\n * Gets a random sample of specified size from the array.\n * If the requested size is greater than the array length, returns a shuffled clone of the original array.\n * @param array - The source array from which to sample.\n * @param size - The number of elements to sample from the array.\n * @returns A new array containing the random sample.\n */\nexport function getRandomSampleFromArray<T>(array: T[], size: number): T[] {\n const clonedArray = [...array]; // Copy the original array\n\n // If requested size is greater than array length, shuffle and return clone of the original array\n if (size >= clonedArray.length) {\n shuffleArray(clonedArray);\n return clonedArray;\n }\n\n shuffleArray(clonedArray);\n return clonedArray.slice(0, size);\n}\n\n/**\n * Shuffles an array\n * @param array - The array to shuffle.\n */\nfunction shuffleArray<T>(array: T[]): void {\n for (let i = array.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [array[i], array[j]] = [array[j], array[i]]; // Swap elements\n }\n}\n","function componentToHex(c) {\n const hex = c.toString(16);\n return hex.length == 1 ? '0' + hex : hex;\n}\n\n/**\n * Converts RGB color values to a hexadecimal color string.\n * @param r - The red component value (0-255).\n * @param g - The green component value (0-255).\n * @param b - The blue component value (0-255).\n * @returns The hexadecimal color string representation.\n */\nfunction rgbToHex(r, g, b) {\n return '#' + componentToHex(r) + componentToHex(g) + componentToHex(b);\n}\n\n/**\n * Converts a hexadecimal color code to an RGB object.\n * @param hex - The hexadecimal color code to convert.\n * @returns An object representing the RGB values of the color, or null if the input is invalid.\n */\nfunction hexToRgb(hex) {\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\n return result\n ? {\n r: parseInt(result[1], 16),\n g: parseInt(result[2], 16),\n b: parseInt(result[3], 16),\n }\n : null;\n}\n\nexport { hexToRgb, rgbToHex };\n","import BaseVolumeViewport from '../BaseVolumeViewport';\nimport type {\n IVolumeViewport,\n IVolumeInput,\n IRenderingEngine,\n} from '../../types';\n\n/**\n * For each provided viewport it adds a volume to the viewport using the\n * provided renderingEngine\n *\n *\n * @param renderingEngine - The rendering engine to use to get viewports from\n * @param volumeInputs - Array of volume inputs including volumeId. Other properties\n * such as visibility, callback, blendMode, slabThickness are optional\n * @param viewportIds - Array of viewport IDs to add the volume to\n * @param immediateRender - If true, the volumes will be rendered immediately\n * @returns A promise that resolves when all volumes have been added\n */\nasync function addVolumesToViewports(\n renderingEngine: IRenderingEngine,\n volumeInputs: Array<IVolumeInput>,\n viewportIds: Array<string>,\n immediateRender = false,\n suppressEvents = false\n): Promise<void> {\n // Check if all viewports are volumeViewports\n for (const viewportId of viewportIds) {\n const viewport = renderingEngine.getViewport(viewportId);\n\n if (!viewport) {\n throw new Error(`Viewport with Id ${viewportId} does not exist`);\n }\n\n // if not instance of BaseVolumeViewport, throw\n if (!(viewport instanceof BaseVolumeViewport)) {\n console.warn(\n `Viewport with Id ${viewportId} is not a BaseVolumeViewport. Cannot add volume to this viewport.`\n );\n\n return;\n }\n }\n\n const addVolumePromises = viewportIds.map(async (viewportId) => {\n const viewport = renderingEngine.getViewport(viewportId) as IVolumeViewport;\n\n await viewport.addVolumes(volumeInputs, immediateRender, suppressEvents);\n });\n\n await Promise.all(addVolumePromises);\n return;\n}\n\nexport default addVolumesToViewports;\n","import type {\n IStackViewport,\n IStackInput,\n IRenderingEngine,\n} from '../../types';\n\n/**\n * For each provided viewport it adds a volume to the viewport using the\n * provided renderingEngine\n *\n *\n * @param renderingEngine - The rendering engine to use to get viewports from\n * @param volumeInputs - Array of volume inputs including volumeId. Other properties\n * such as visibility, callback, blendMode, slabThickness are optional\n * @param viewportIds - Array of viewport IDs to add the volume to\n * @param immediateRender - If true, the volumes will be rendered immediately\n * @returns A promise that resolves when all volumes have been added\n */\nasync function addImageSlicesToViewports(\n renderingEngine: IRenderingEngine,\n stackInputs: Array<IStackInput>,\n viewportIds: Array<string>\n): Promise<void> {\n // Check if all viewports are volumeViewports\n for (const viewportId of viewportIds) {\n const viewport = renderingEngine.getViewport(viewportId);\n\n if (!viewport) {\n throw new Error(`Viewport with Id ${viewportId} does not exist`);\n }\n\n // if not instance of BaseVolumeViewport, throw\n if (!(viewport as IStackViewport).addImages) {\n console.warn(\n `Viewport with Id ${viewportId} does not have addImages. Cannot add image segmentation to this viewport.`\n );\n\n return;\n }\n }\n\n const addStackPromises = viewportIds.map(async (viewportId) => {\n const viewport = renderingEngine.getViewport(viewportId) as IStackViewport;\n\n return viewport.addImages(stackInputs);\n });\n\n await Promise.all(addStackPromises);\n}\n\nexport default addImageSlicesToViewports;\n"],"names":["root","factory","exports","module","require","define","amd","self","__WEBPACK_EXTERNAL_MODULE__199__","__WEBPACK_EXTERNAL_MODULE__468__","__WEBPACK_EXTERNAL_MODULE__795__","__WEBPACK_EXTERNAL_MODULE__38__","__WEBPACK_EXTERNAL_MODULE__441__","__WEBPACK_EXTERNAL_MODULE__976__","__WEBPACK_EXTERNAL_MODULE__847__","__WEBPACK_EXTERNAL_MODULE__807__","__WEBPACK_EXTERNAL_MODULE__864__","__WEBPACK_EXTERNAL_MODULE__283__","__WEBPACK_EXTERNAL_MODULE__785__","__WEBPACK_EXTERNAL_MODULE__197__","__WEBPACK_EXTERNAL_MODULE__953__","__WEBPACK_EXTERNAL_MODULE__903__","__WEBPACK_EXTERNAL_MODULE__821__","__WEBPACK_EXTERNAL_MODULE__215__","__WEBPACK_EXTERNAL_MODULE__739__","__WEBPACK_EXTERNAL_MODULE__9__","__WEBPACK_EXTERNAL_MODULE__896__","__WEBPACK_EXTERNAL_MODULE__861__","__WEBPACK_EXTERNAL_MODULE__281__","__WEBPACK_EXTERNAL_MODULE__329__","__WEBPACK_EXTERNAL_MODULE__673__","__WEBPACK_EXTERNAL_MODULE__348__","__WEBPACK_EXTERNAL_MODULE__70__","__WEBPACK_EXTERNAL_MODULE__474__","__WEBPACK_EXTERNAL_MODULE__610__","__WEBPACK_EXTERNAL_MODULE__21__","__WEBPACK_EXTERNAL_MODULE__643__","__WEBPACK_EXTERNAL_MODULE__128__","__WEBPACK_EXTERNAL_MODULE__664__","__WEBPACK_EXTERNAL_MODULE__973__","__WEBPACK_EXTERNAL_MODULE__394__","__WEBPACK_EXTERNAL_MODULE__582__","__WEBPACK_EXTERNAL_MODULE__482__","__WEBPACK_EXTERNAL_MODULE__343__","__WEBPACK_EXTERNAL_MODULE__363__","__WEBPACK_EXTERNAL_MODULE__982__","__WEBPACK_EXTERNAL_MODULE__130__","__WEBPACK_EXTERNAL_MODULE__298__","__WEBPACK_EXTERNAL_MODULE__398__","__WEBPACK_EXTERNAL_MODULE__388__","__WEBPACK_EXTERNAL_MODULE__120__","__WEBPACK_EXTERNAL_MODULE__395__","__WEBPACK_EXTERNAL_MODULE__948__","__WEBPACK_EXTERNAL_MODULE__478__","__WEBPACK_EXTERNAL_MODULE__914__","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","__webpack_modules__","n","getter","__esModule","d","a","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","r","Symbol","toStringTag","value","Events","RequestType","ViewportType","InterpolationType","BlendMode","vtkConstants","BlendModes","COMPOSITE_BLEND","MAXIMUM_INTENSITY_BLEND","MINIMUM_INTENSITY_BLEND","AVERAGE_INTENSITY_BLEND","OrientationAxis","SharedArrayBufferModes","GeometryType","ContourType","VOILUTFunctionType","DynamicOperatorType","CalibrationTypes","ViewportStatus","ImageQualityStatus","SpeedUnit","MetadataModules","hotIron","name","numOfColors","colors","pet","numColors","hotMetalBlue","pet20Step","gray","gamma","segmentedData","red","green","blue","jet","hsv","hot","cool","spring","summer","autumn","winter","bone","copper","spectral","coolwarm","blues","RENDERING_DEFAULTS","MINIMUM_SLAB_THICKNESS","MAXIMUM_RAY_DISTANCE","freeze","deepFreeze","object","propNames","getOwnPropertyNames","axial","viewPlaneNormal","viewUp","sagittal","coronal","gradientOpacity","specularPower","scalarOpacity","specular","shade","ambient","colorTransfer","diffuse","interpolation","slicer3D","_typeof","iterator","constructor","arg","input","hint","prim","toPrimitive","res","TypeError","String","configurable","writable","imageIdToURI","imageId","colonIndex","indexOf","substring","getMinMax","storedPixelData","storedPixel","min","max","numPixels","length","index","Math","providers","addProvider","provider","i","priority","arguments","splice","removeProvider","removeAllProviders","pop","getMetaData","type","_len","queries","Array","_key","result","state","metadataProvider","add","payload","JSON","parse","stringify","metadata","_state$imageId","clear","cache","id","set","re","renderingEngineId","delete","getAll","renderingEngines","keys","map","sort","b","getRenderingEngine","renderingEngineCache","getRenderingEngines","isMergeableObject","val","toString","cloneIfNecessary","optionsArgument","clone","deepMerge","isArray","defaultArrayMerge","target","source","destination","slice","forEach","e","array","arrayMerge","mergeObject","proxyMarker","createEndpoint","releaseProxy","finalizer","throwMarker","isObject","transferHandlers","Map","canHandle","serialize","port1","port2","MessageChannel","expose","deserialize","port","start","wrap","serialized","Error","isError","message","stack","assign","ep","globalThis","allowedOrigins","addEventListener","callback","ev","data","origin","allowedOrigin","RegExp","test","isAllowedOrigin","console","warn","path","argumentList","fromWireValue","returnValue","parent","reduce","rawValue","apply","proxy","transfers","transferCache","transfer","Promise","resolve","catch","then","wireValue","transferables","toWireValue","postMessage","removeEventListener","closeEndPoint","error","endpoint","isMessagePort","close","createProxy","throwIfProxyReleased","isReleased","releaseEndpoint","requestResponseMessage","proxyCounter","WeakMap","proxyFinalizers","FinalizationRegistry","newCount","isProxyReleased","Proxy","_target","unregister","unregisterProxy","p","bind","_thisArg","rawArgumentList","last","processArguments","construct","register","registerProxy","processed","v","arr","concat","handler","serializedValue","msg","fill","floor","random","Number","MAX_SAFE_INTEGER","join","l","uuidv4","replace","c","crypto","getRandomValues","Uint8Array","RequestPoolManager","_defineProperty","interaction","thumbnail","prefetch","compute","this","requestPool","grabDelay","awake","numRequests","maxNumRequests","setMaxSimultaneousRequests","getMaxSimultaneousRequests","destroy","timeoutHandle","window","clearTimeout","addRequest","requestFn","additionalDetails","requestDetails","push","startGrabbing","filterRequests","filterFunction","requestType","filter","clearRequestStack","sendRequests","requestsToSend","syncImageCount","getNextRequest","_requestResult","requestResult","finally","startAgain","interactionPriorities","getSortedPriorityGroups","shift","hasRemainingInteractionRequests","hasRemainingThumbnailRequests","hasRemainingPrefetchRequests","hasRemainingComputeRequests","setTimeout","getRequestPool","workerRegistry","workerPoolManager","registerWorker","workerName","workerFn","_this$workerRegistry$","options","maxWorkerInstances","overwrite","autoTerminateOnIdle","enabled","idleTimeThreshold","idleCheckIntervalId","clearInterval","workerProperties","instances","loadCounters","lastActiveTime","nativeWorkers","worker","Comlink","getNextWorkerAPI","workerInstances","instance","minLoadIndex","minLoadValue","currentLoadValue","api","executeTask","methodName","args","callbacks","reject","async","finalCallbacks","cb","processing","results","Date","now","setInterval","terminateIdleWorkers","err","_","terminateWorkerInstance","terminate","workerInstance","csRenderInitialized","useSharedArrayBuffer","sharedArrayBufferMode","defaultConfig","gpuTier","detectGPUConfig","isMobile","rendering","useCPURendering","preferSizeOverAccuracy","useNorm16Texture","strictZSpacingForVolumeViewport","enableCacheOptimization","config","webWorkerManager","_getGLContext","canvas","document","createElement","getContext","_hasActiveWebGLContext","gl","WebGLRenderingContext","WebGL2RenderingContext","isIOS","navigator","platform","maxTouchPoints","init","configuration","getExtension","_hasNorm16TextureSupport","_configuration$render","log","getGPUTier","_config$gpuTier","tier","setUseSharedArrayBuffer","CentralizedWebWorkerManager","setUseCPURendering","status","_updateRenderingPipelinesForAllViewports","setPreferSizeOverAccuracy","canRenderFloatTextures","resetUseCPURendering","getShouldUseCPURendering","mode","SharedArrayBuffer","hasSharedArrayBuffer","resetUseSharedArrayBuffer","getShouldUseSharedArrayBuffer","isCornerstoneInitialized","getConfiguration","setConfiguration","engine","getViewports","viewport","_viewport$updateRende","updateRenderingPipeline","getWebWorkerManager","DEFAULT_VALUES","updatedFrames","extend","publicAPI","model","initialValues","vtkOpenGLTexture","classHierarchy","superCreate3DFilterableFromRaw","create3DFilterableFromRaw","width","height","depth","numComps","dataType","inputDataType","inputNumComps","update3DFromRaw","bytesPerVoxel","TypedArrayConstructor","_openGLRenderWindow","activateTexture","createTexture","Int16Array","Uint16Array","Float32Array","fillSubImage3D","generateMipmap","context","deactivate","frameIndex","buffer","zOffset","components","rowLength","MAX_TEXTURE_SIZE","getParameter","blockHeight","multiRowBlockLength","multiRowBlockLengthInBytes","normalBlocks","lastBlockHeight","multiRowLastBlockLength","block","yOffset","dataView","useHalfFloat","idx","HalfFloat","texSubImage3D","format","openGLDataType","getTextureParameters","setUpdatedFrame","vtkStreamingOpenGLTexture","newInstance","macro","listeners","debouncedListeners","reset","addEventListenerOnce","onceWrapper","event","addEventListenerDebounced","delay","debouncedCallbacks","handle","timeoutId","original","removeEventListenerDebounced","debounced","stackLength","dispatchEvent","defaultPrevented","triggerEvent","el","eventTarget","detail","CustomEvent","cancelable","newMaxCacheSize","errorMessage","_maxCacheSize","byteLength","_maxInstanceSize","getBytesAvailable","_imageCacheSize","_volumeCacheSize","imageLoadObject","_imageCache","cancelFn","decache","volumeId","cachedVolume","_volumeCache","volumeLoadObject","volume","cancelLoading","imageData","_restoreImagesFromBuffer","imageIterator","done","next","removeImageLoadObject","purgeVolumeCache","volumeIterator","removeVolumeLoadObject","timeStamp","geometryId","cachedGeometry","_geometryCache","geometry","cachedImage","image","from","values","getVolumes","referencedVolumeId","incrementImageCacheSize","sizeInBytes","eventDetails","_decacheImage","incrementVolumeCacheSize","_decacheVolume","geometryLoadObject","has","loaded","promise","isNaN","increment","decrement","getMaxCacheSize","getCacheSize","decacheIfNecessaryUntilBytesAvailable","numBytes","volumeImageIds","bytesAvailable","cachedImages","cachedImageIds","im","imageIdsToPurge","includes","putImageLoadObject","sharedCacheKey","toFixed","isCacheable","getImageLoadObject","isLoaded","getVolumeContainingImageId","volumeIds","imageIdToUse","_volume$imageIds","imageIds","imageIdIndex","getImageURIIndex","getCachedImageBasedOnImageURI","imageURIToUse","foundImageId","find","putVolumeLoadObject","ImageVolume","scalarData","getScalarData","imageCacheOffsetMap","size","offset","getImage","viewPixelData","getPixelData","pixelData","imageFrame","bufferView","props","scaling","dimensions","spacing","direction","referencedImageIds","numVoxels","vtkImageData","scalarArray","vtkDataArray","numberOfComponents","setDimensions","setSpacing","setDirection","setOrigin","getPointData","setScalars","numFrames","_getNumFrames","_reprocessImageIds","_createCornerstoneImageMetaData","_imageIds","newImageIds","_imageIdsIndexMap","_imageURIsIndexMap","imageURI","isDynamicVolume","Int8Array","Uint8ClampedArray","Int32Array","Uint32Array","Float64Array","getImageIdIndex","releaseGraphicsResources","getScalarDataArrays","modified","getScalars","getData","removeFromCache","convertToImageSlicesAndCache","getScalarDataLength","scalarDataCount","_getScalarDataLength","bytesPerImage","numComponents","pixelsPerImage","PhotometricInterpretation","voiLut","VOILUTFunction","windowCenter","windowWidth","voi","color","cornerstoneImageMetaData","rgba","photometricInterpretation","voiLUTFunction","invert","getScalarDataByImageIdIndex","getCornerstoneImage","imageIdIndexToFrameIndex","volumeBuffer","TypedArray","bytePerPixel","byteOffset","BYTES_PER_ELEMENT","imageScalarData","volumeBufferView","modalityLutModule","metaData","minMax","intercept","rescaleIntercept","rows","columns","minPixelValue","maxPixelValue","slope","rescaleSlope","getCanvas","columnPixelSpacing","rowPixelSpacing","convertToCornerstoneImage","getCornerstoneImageLoadObject","getCornerstoneImages","_this$imageIds","numSlices","_referencedVolume$ima","_referencedVolume$ima2","referencedVolume","numImages","bytesRemaining","imageOrientationPatient","precision","imagePositionPatient","parseFloat","imagePixelModule","bitsAllocated","imagePlaneModule","rowCosines","columnCosines","pixelSpacing","generalSeriesModule","genericMetadataProvider","otherVolumes","sharedArrayBuffer","SMALL_MEMORY_LIMIT","pages","ceil","memory","WebAssembly","Memory","initial","maximum","shared","crossOriginIsolated","getScalingParameters","_modalityLutModule$re","metaDataGet","modality","scalingParameters","suvFactor","suvbw","suvbsa","suvlbm","makeVolumeMetadata","imageId0","pixelRepresentation","bitsStored","highBit","samplesPerPixel","voiLutModule","seriesInstanceUID","frameOfReferenceUID","BitsAllocated","BitsStored","SamplesPerPixel","HighBit","PixelRepresentation","Modality","ImageOrientationPatient","PixelSpacing","FrameOfReferenceUID","Columns","Rows","SeriesInstanceUID","sortImageIdsAndGetSpacing","scanAxisNormal","referenceImagePositionPatient","rowCosineVec","vec3","colCosineVec","refIppVec","usingWadoUri","split","sortedImageIds","zSpacing","getDistance","positionVector","prefetchedImageIds","reverse","metadataForMiddleImage","distanceBetweenFirstAndMiddleImages","abs","distanceImagePairs","distance","sliceThickness","spacingBetweenSlices","hasFloatScalingParameters","some","isInteger","generateVolumePropsFromImageIds","use16BitDataType","volumeMetadata","hasNegativeRescale","floatAfterScale","canRenderFloat","signed","handleCache","createUint8SharedArray","createFloat32SharedArray","createInt16SharedArray","createUint16SharedArray","getBufferConfiguration","targetBufferType","use16BitTexture","isVolumeBuffer","setupCacheOptimizationEventListener","shouldUseSAB","evt","performCacheOptimizationForVolume","_ref","_updateImageWithScalarDataView","_processImageCacheOffsetMap","_sampleImage$imageFra","compatibleScalarData","sampleImageIdWithImage","sampleImage","samplePixelData","_processVolumeImages","view","createInternalVTKRepresentation","dataArrayAttrs","scalarDataArrays","vtkScalarArray","addArray","setActiveScalars","addScalarDataArraysToImageData","addScalarDataToImageData","volumeLoaders","unknownVolumeLoader","loadVolumeFromVolumeLoader","scheme","loader","errorObject","loadVolume","createAndCacheVolume","createAndCacheDerivedVolume","targetBuffer","scalarLength","volumeScalarData","generateVolumeScalarData","derivedImageData","derivedVolume","structuredClone","createLocalVolume","preventCache","validDataTypes","createAndCacheVolumeFromImages","volumeProps","imagePromises","all","registerVolumeLoader","volumeLoader","getVolumeLoaderSchemes","registerUnknownVolumeLoader","oldVolumeLoader","getUnknownVolumeLoaderSchema","createAndCacheDerivedSegmentationVolume","createLocalSegmentationVolume","_targetBuffer$sharedA","scalarTexture","vtkVolumeMapper","superDelete","vtkSharedVolumeMapper","createVolumeMapper","volumeMapper","setInputData","getSpacing","sampleDistance","setMaximumSamplesPerRay","setSampleDistance","setScalarTexture","imageLoadPoolManager","imageLoaders","unknownImageLoader","loadImageFromImageLoader","loadImageFromCacheOrVolume","_cachedVolumeInfo$vol","ignoreCache","cachedVolumeInfo","loadStatus","loadImage","loadAndCacheImage","loadAndCacheImages","createAndCacheDerivedImage","referencedImageId","skipCreateBuffer","onCacheAdd","derivedImageId","localImage","createAndCacheLocalImage","createAndCacheDerivedImages","derivedImageIds","allPromises","_options$getDerivedIm","newOptions","getDerivedImageId","promises","_options$onCacheAdd","cancelLoadImage","cancelLoadImages","cancelLoadAll","requests","loadObject","cancel","registerImageLoader","imageLoader","registerUnknownImageLoader","oldImageLoader","unregisterAllImageLoaders","createAndCacheDerivedSegmentationImages","createAndCacheDerivedSegmentationImage","toWindowLevel","low","high","toLowHighRange","lower","upper","REQUEST_TYPE","volumeActor","imageVolume","useNativeDataType","_imageVolume$imageIds","_voi","_voi2","_voi3","_voi4","_metadata$voiLut","windowLevel","getVOIFromMetadata","_imageVolume$referenc","voxelsPerImage","scalingParametersToUse","preScale","_getImageScalarDataFromImageVolume","getVOIFromMinMax","_imageVolume$scaling","isPreScaled","PT","_isCurrentImagePTPrescaled","handlePreScaledVolume","getProperty","getRGBTransferFunction","setMappingRange","element","viewportId","suppressEvents","blendMode","setBlendMode","vtkVolume","setMapper","getNumberOfComponents","setIndependentComponents","setDefaultVolumeVOI","voiRange","getRange","voiModifiedEventDetail","range","triggerVOIModified","VIEWPORT_ELEMENT","CANVAS_CSS_CLASS","EPSILON","getOrCreateCanvas","canvasSelector","viewportElement","internalDiv","querySelector","div","style","position","overflow","classList","appendChild","createViewportElement","imageRendering","createCanvas","rect","getBoundingClientRect","devicePixelRatio","vtkOpenGLVolumeMapper","previousState","buildBufferObjects","ren","actor","currentInput","scalars","vprop","jitterTexture","getHandle","oTable","setMinificationFilter","Filter","setMagnificationFilter","create2DFromRaw","VtkDataTypes","numComp","numIComps","getIndependentComponents","getMTime","opacityTextureString","oWidth","oSize","ofTable","tmpTable","ofun","getScalarOpacity","opacityFactor","renderable","getSampleDistance","getScalarOpacityUnitDistance","oRange","getTable","opacityTexture","getWebgl2","colorTextureString","cWidth","cTable","cfun","cRange","colorTexture","updateLabelOutlineThicknessTexture","scalarTextureString","dims","getDimensions","previousTextureParameters","getDataType","shouldReset","previousTextureSize","setOglNorm16Ext","resetFormatAndType","getPreferSizeOverAccuracy","tris","getCABO","getElementCount","ptsArray","cellArray","points","setName","cells","createVBO","Representation","cellOffset","VBOBuildTime","getRenderTargetSize","_useSmallViewport","_smallViewportWidth","_smallViewportHeight","usize","vsize","_openGLRenderer","getTiledSizeAndOrigin","getRenderTargetOffset","lowerLeftU","lowerLeftV","vtkStreamingOpenGLVolumeMapper","CLASS_MAPPING","create","registerOverride","className","fn","vtkViewNodeFactory","createNode","dataObject","isDeleted","cpt","getClassName","overrides","getModelInitialValues","vn","setMyFactory","getScalarTexture","vtkStreamingOpenGLViewNodeFactory","vtkOpenGLActor","vtkOpenGLActor2D","vtkOpenGLCamera","vtkOpenGLGlyph3DMapper","vtkOpenGLImageMapper","vtkOpenGLImageSlice","vtkOpenGLPolyDataMapper","vtkOpenGLPixelSpaceCallbackMapper","vtkOpenGLRenderer","vtkOpenGLSkybox","vtkOpenGLSphereMapper","vtkOpenGLStickMapper","vtkOpenGLVolume","vtkOpenGLRenderWindow","myFactory","vtkStreamingOpenGLRenderWindow","background","container","invokeResize","renderWindow","vtkRenderWindow","rendererMap","openGLRenderWindow","addView","interactor","vtkRenderWindowInteractor","setView","initialize","addRenderer","renderer","vtkRenderer","getInteractor","removeRenderer","getRenderer","getRenderers","resize","setSize","render","setContainer","vtkOffscreenMultiRenderWindow","getSpacingInNormalDirection","iVector","jVector","kVector","dotProducts","projectedSpacing","isImageActor","actorEntry","actorIsA","actorType","isA","getClosestImageId","worldPos","halfSpacingInNormalDirection","imageIdForTool","dir","dot","getVolumeActorCorners","getMapper","getInputData","bounds","extentToBounds","getExtent","SMALL_EPSILON","isOne","isUnit","off","isOrthonormal","getSliceRange","focalPoint","corners","getDirection","dx","dy","dz","it","indexToWorld","transform","vtkMatrixBuilder","identity","rotateFromDirections","pt","transformedFocalPoint","currentSlice","minX","Infinity","maxX","x","current","snapFocalPointToSlice","sliceRange","spacingInNormalDirection","deltaFrames","posDiffFromFocalPoint","steps","round","floatingStepNumber","newFocalPoint","newSlicePosFromMin","newPosition","getVoiFromSigmoidRGBTransferFunction","cfunRange","k","cfunDomain","y1","logy1","x1","y2","logy2","x2","ww","wc","areNumbersEqualWithTolerance","num1","num2","tolerance","isNumberType","isNumberArrayLike","isEqual","v1","v2","arr1","arr2","areArraysEqual","negative","isEqualNegative","isEqualAbs","_colormaps","registerColormap","colormap","Name","getColormap","getColormapNames","findMatchingColormap","rgbPoints","colormapsVTK","vtkColorMaps","presetName","colormapsCS3D","colormapName","matchedColormap","RGBPoints","presetRGBPoints","opacity","opacityPoints","getDataPointer","invertRgbTransferFunction","rgbTransferFunction","getSize","nodeValue1","getNodeValue","setNodeValue","createSigmoidRGBTransferFunction","approximationNodes","windowLevelUtil","table","y","logit","vtkColorTransferFunction","buildFunctionFromArray","getVolumeId","targetId","str","prefix","EPSILON_PART","isPrimaryVolume","startsWith","starts","getTargetVolumeAndSpacingInNormalDir","camera","useSlabThickness","volumeActors","getActors","actorUID","imageVolumes","va","_va$referenceId","referenceId","uid","iv","targetVolumeId","imageVolumeIndex","findIndex","getSpacingInNormal","smallest","hasPrimaryVolume","slabThickness","getProperties","getCamera","getActor","getVolumeSliceRangeInfo","numScrollSteps","currentStepIndex","sliceRangeInfo","applyPreset","preset","colorTransferArray","shiftRange","center","getShiftRange","normColorTransferValuePoints","g","rescaled","removeAllPoints","_ref2","addRGBPoint","applyPointsToRGBFunction","setRGBTransferFunction","scalarOpacityArray","vtkPiecewiseFunction","normPoints","pwf","_ref3","_ref4","addPoint","applyPointsToPiecewiseFunction","property","setScalarOpacity","gradientMinValue","gradientMinOpacity","gradientMaxValue","gradientMaxOpacity","setUseGradientOpacity","setGradientOpacityMinimumValue","setGradientOpacityMinimumOpacity","setGradientOpacityMaximumValue","setGradientOpacityMaximumOpacity","setInterpolationTypeToFastLinear","setShade","setAmbient","setDiffuse","setSpecular","setSpecularPower","numberOfSlices","imageIndex","linePlaneIntersection","p0","p1","plane","x0","y0","z0","z1","A","B","C","D","t","planeEquation","normal","point","normalized","sqrt","threePlaneIntersection","firstPlane","secondPlane","thirdPlane","A1","B1","C1","D1","A2","B2","C2","D2","A3","B3","C3","D3","m0","mat3","m1","m2","m3","planeDistanceToPoint","z","numerator","sign","hasNaNValues","Viewport","_rotation","widgetId","widget","viewportWidgets","getWidgets","getEnabled","setEnabled","removeActor","sx","sy","sWidth","sHeight","_actors","setAttribute","defaultOptions","isDisabled","useCustomRenderingPipeline","setRendered","viewportStatus","renderingEngine","hasBeenDestroyed","offscreenMultiRenderWindow","renderViewport","setOptions","_this$options","immediate","_this$options2","displayArea","setDisplayArea","flip","flipHorizontal","flipVertical","getDefaultImageData","viewRight","viewUpToSet","viewPlaneNormalToSet","middleIJK","centeredFocalPoint","resetFocalPoint","_getFocalPointForResetCamera","resetPan","resetToCenter","panDir","panValue","getPanDir","mirrorVec","panDirMirror","setCamera","getDefaultActor","getActorUIDs","getActorUIDByIndex","getActorByIndex","setActors","actors","removeAllActors","addActors","_removeActor","removeViewProp","removeActors","actorUIDs","resetCameraPanAndZoom","addActor","resetCamera","updateCameraClippingPlanesAndRange","_this$getRenderer","removeAllViewProps","resetCameraNoEvent","_suppressCameraModifiedEvents","setCameraNoEvent","_getViewImageDataIntersections","getBounds","edges","_getEdges","intersections","edge","intersectionPoint","planar","_isInBounds","setInterpolationType","_interpolationType","_arg","storeAsInitialCamera","areaType","_this$getProperties","fitToCanvasCamera","setDisplayAreaScale","interpolationType","setDisplayAreaFit","initialCamera","eventDetail","scale","parallelScale","imageArea","focalChange","_window","imageCanvasPoint","canvasWidth","canvasHeight","canvasZero","worldToCanvas","canvasEdge","canvasImage","imgWidth","imgHeight","areaX","areaY","requireX","requireY","initZoom","getZoom","fitZoom","applyZoom","setZoom","imagePoint","canvasPoint","canvasX","canvasY","canvasPanX","canvasPanY","imageX","imageY","useZoom","deltaPoint2","vec2","getPan","setPan","getDisplayArea","_this$options3","_this$options4","resetZoom","previousCamera","computeVisiblePropBounds","spc","activeCamera","getVtkActiveCamera","getViewPlaneNormal","getViewUp","widthWorld","heightWorld","_getWorldDistanceViewUpAndViewRight","canvasSize","scaleFactor","insetImageMultiplier","radius","boundsRadius","vtkMath","focalPointToSet","positionToSet","resetCameraClippingRange","clippingRangeToUse","setPhysicalScale","setPhysicalTranslation","viewAngle","clippingRange","modifiedCamera","setFitToCanvasCamera","setInitialCamera","RESET_CAMERA_EVENT","_this$options5","invokeEvent","triggerCameraModifiedEventIfNecessary","getFocalPoint","zero3","canvasToWorld","initialCanvasFocal","currentCanvasFocal","getCurrentImageIdIndex","getSliceIndex","getReferenceId","_specifier","pan","delta2","delta","newFocal","compareCamera","initialParallelScale","getParallelScale","_getFocalPointForViewPlaneReset","point_x","point_y","point_z","getActiveCamera","vtkCamera","getPosition","parallelProjection","getParallelProjection","getViewAngle","cameraInterface","updatedCamera","flipH","flipV","setViewUp","setDirectionOfProjection","setPosition","setFocalPoint","setParallelScale","setViewAngle","setClippingRange","prevFocalPoint","prevViewUp","currentViewPlaneNormal","currentViewUp","cameraModifiedOutOfPlane","viewUpHasChanged","deltaCamera","updateClippingPlanesForActors","rotation","getRotation","currentCamera","mapper","vtkPlanes","clippingFilter","getClippingPlanes","vtkPlane","setOrientationOfClippingPlanes","scaledDistance","setNormal","newOrigin1","newOrigin2","getClippingPlanesForActor","_actorEntry","_actorEntry2","viewUpCorners","_getCorners","viewRightCorners","minY","maxY","getViewReference","_viewRefSpecifier$sli","viewRefSpecifier","cameraFocalPoint","getFrameOfReferenceUID","sliceIndex","isReferenceViewable","viewRef","withOrientation","getViewPresentation","viewPresSel","zoom","setViewReference","setViewPresentation","viewPres","setRotation","_shouldUseNativeDataType","oldCamera","oldFocalPoint","oldViewPlaneNormal","vectorFromOldFocalPointToCenteredFocalPoint","distanceFromOldFocalPointToCenteredFocalPoint","xMin","xMax","yMin","yMax","zMin","zMax","p2","p3","p4","p5","p6","p7","p8","w1","w2","w3","paletteLut","isPerformingCoordinateTransformation","tmpMatrix","mat4","tmpvec1","getProjectionMatrix","aspect","nearz","farz","projectionMatrix","physicalScale","cRange0","cRange1","xmin","xmax","ymin","ymax","useOffAxisProjection","tmp","tan","useHorizontalViewAngle","znear","zfar","vtkSlabCamera","transformWorldToIndex","worldToIndex","getTransferFunctionNodes","transferFunction","setTransferFunctionNodes","nodes","node","super","panFit","panSub","initialViewUp","rotateCamera","afterPan","afterPanFit","newCenter","newOffset","viewportProperties","volumeProperties","perVolumeIdDefaultProperties","globalDefaultProperties","_voiRanges$find","_voiRanges$","_getApplicableVolumeActor","latestColormap","voiRanges","_this$viewportPropert","Boolean","volumeColormap","applicableVolumeActorInfo","getState","acc","initialToCurrentViewUpAngle","PI","initialToCurrentViewUpCross","_FrameOfReferenceUID","canvasPos","_vtkCamera$setIsPerfo","_vtkCamera$setIsPerfo2","setIsPerformingCoordinateTransformation","getOpenGLRenderWindow","canvasPosWithDPR","displayCoord","worldCoord","displayToWorld","_vtkCamera$setIsPerfo3","_vtkCamera$setIsPerfo4","worldToDisplay","canvasCoord","canvasCoordWithDPR","volumeIdToUse","setActiveCamera","setParallelProjection","initializeVolumeNewImageEventDispatcher","applyViewOrientation","orientation","_getOrientationVectors","setViewUpFrom","volumeNewImageHandlerBound","cameraEvent","getImageData","getViewport","BaseVolumeViewport","sliceData","getImageSliceDataForVolumeViewport","volumeNewImageEventDispatcher","volumeNewImageCleanUpBound","resetVolumeNewImageState","resetVolumeViewportClippingRange","setVOILUTFunction","setVOI","setColormap","colormapObj","colormapUtils","applyColorMap","setOpacity","setInvert","inverted","_getOrCreateColorTransferFunction","getVOIModifiedEventDetail","invertStateChanged","getMappingRange","newRGBTransferFunction","voiRangeToUse","setRange","rotationToApply","roll","setDefaultProperties","ViewportProperties","clearDefaultProperties","resetProperties","resetToDefaultProperties","forFrameOfReference","getVolumeViewportScrollInfo","withNavigation","currentSliceIndex","scroll","refViewPlaneNormal","refFrameOfReference","isNegativeNormal","isSameNormal","setOrientation","focalDelta","useNormal","normalDot","setProperties","setPreset","setSlabThickness","_properties$colormap","_properties$colormap2","properties","presetNameOrObj","VIEWPORT_PRESETS","setVolumes","volumeInputArray","firstImageVolume","_isValidVolumeInputArray","createVolumeActor","_setVolumeActors","initializeColorTransferFunction","addVolumes","visibility","setVisibility","removeVolumeActors","_orientation","selectedVolumeId","colorTransferFunction","initialTransferFunctionNodes","actorEntries","_this$getActor","numVolumes","volumeInput","flipDirection","hasVolumeId","_volumeId","_volume$metadata","defaultActor","defaultActorUID","getOrigin","hasPixelSpacing","volumeActorEntries","MPR_CAMERA_VALUES","getSlabThickness","getIntensityFromWorld","voxelIndex","specifier","_actorEntries$find2","_actorEntries$find","_sliceIndex","_actorEntries$find3","currentIndex","querySeparator","spacingInNormal","sub","numSlicesBackward","numSlicesForward","focalPoints","_useAcquisitionPlaneForViewPlane","_setViewPlaneToAcquisitionPlane","_getAcquisitionPlaneOrientation","filterActorUIDs","_mapper$setBlendMode","resetRotation","supressEvents","clipPlane1","clipPlane2","newVtkPlanes","addClippingPlane","viewToReset","resetSlabThickness","_resetProperties","getSlicesClippingPlanes","getSlicePlaneCoordinates","planes","getNormal","retrieveConfigurationState","IMAGE_RETRIEVE_CONFIGURATION","imageRetrieveMetadataProvider","query","updateVTKImageDataWithCornerstoneImage","sourceImageData","newPixelData","HSVToRGB","hue","sat","rgb","hueCase","frac","lx","ly","lz","NumberOfColors","Ramp","TableRange","HueRange","SaturationRange","ValueRange","AlphaRange","NaNColor","BelowRangeColor","UseBelowRangeColor","AboveRangeColor","UseAboveRangeColor","InputRange","Table","setNumberOfTableValues","number","setRamp","ramp","setTableRange","end","setHueRange","setSaturationRange","setValueRange","setAlphaRange","getColor","scalar","mapValue","build","force","maxIndex","hinc","sinc","vinc","ainc","alpha","c_rgba","cos","buildSpecialColors","numberOfColors","belowRangeColorIndex","aboveRangeColorIndex","nanColorIndex","getIndex","Range","MaxIndex","Shift","Scale","MAX_VALUE","dIndex","linearIndexLookupMain","setTableValue","COLOR_TRANSPARENT","getRank","elem","left","right","mid","midElem","makeMappingArray","N","lut","xLinSpace","vector","linspace","pow","xLinSpaceIndexes","inputArray","indexes","len","searchSorted","colorPercent","colorDelta","colormapData","CPU_COLORMAPS","redLut","greenLut","blueLut","createLinearSegmentedColormap","getId","getColorSchemeName","setColorSchemeName","getNumberOfColors","setNumberOfColors","isValidIndex","getColorRepeating","setColor","addColor","insertColor","removeColor","clearColors","buildLookupTable","createLookupTable","LookupTable","performance","voiLUT","minValue","maxValue","maxValueMapped","firstValueMapped","modalityLutValue","generateNonLinearVOILUT","generateLinearVOILUT","Transform","getMatrix","m","multiply","matrix","m11","m12","m21","m22","m4","m5","rotate","rad","s","sin","translate","transformPoint","enabledElement","displayedArea","angle","widthScale","heightScale","brhc","tlhc","presentationSizeMode","verticalScale","horizontalScale","translation","hflip","vflip","calculateTransform","setTransform","doesImageNeedToBeRendered","lastRenderedImageId","renderingTools","lastRenderedViewport","modalityLUT","renderCanvas","canvasContext","fillStyle","fillRect","renderCanvasData","renderCanvasContext","isColor","lastRenderedIsColor","getRenderCanvas","invalidated","canvasWasColor","initializeRenderCanvas","colorLUT","cachedLut","lutArray","vlutfn","getVOILUT","generateColorLUT","storedValue","getLut","stats","lastLutGenerateTime","canvasImageDataData","lastGetPixelDataTime","canvasImageDataIndex","storedPixelDataIndex","lastStoredPixelDataToCanvasImageDataTime","storedRGBAPixelDataToCanvasImageData","storedColorPixelDataToCanvasImageData","putImageData","lastPutImageDataTime","renderColorImage","imageSmoothingEnabled","pixelReplication","setToPixelCoordinateSystem","drawImage","saveLastRendered","lutMatches","hasVoi","maxVoi","minVoi","computeAutoVoi","mlutfn","storedPixelValue","generateNonLinearModalityLUT","generateLinearModalityLUT","getModalityLut","generateLut","renderGrayscaleImage","useAlphaChannel","minimum","collectedMultiplierTerms","petVOILutFunction","lutFunction","storedPixelDataToCanvasImageDataPET","storedPixelDataToCanvasImageData","pixelValue","storedPixelDataToCanvasImageDataRGBA","grayscaleLut","grayscale","clut","clamp","renderPseudoColorImage","colormapId","storedPixelDataToCanvasImageDataPseudocolorLUTPET","storedPixelDataToCanvasImageDataPseudocolorLUT","lastRenderTime","renderTimeInMs","invalid","needsRedraw","getTransform","validateParameterUndefinedOrNull","checkParam","errorMsg","isRotated","imageSize","getImageSize","verticalRatio","horizontalRatio","labelmap","getImageFitScale","retrieveType","nearbyFrames","imageQualityStatus","positions","decimate","ProgressiveIterator","as","reason","nextValue","waiting","_this$waiting","rejectReason","getRecent","asyncIterator","errorCallback","generate","processFunction","nextPromise","donePromise","getNextPromise","getDonePromise","list","interleave","interleaveIndices","ProgressiveRetrieveImages","imageRetrieveConfiguration","stages","singleRetrieveStages","retrieveOptions","loadImages","listener","ProgressiveRetrieveImagesInstance","createProgressive","interleavedRetrieveStages","interleaved","createStageRequests","outstandingRequests","request","displayedIterator","sendRequest","loadedPromise","uncompressedIterator","complete","oldStatus","imageQualityStatusMap","updateStageStatus","stage","successCallback","_request$nearbyReques","nearbyRequests","arrayBuffer","srcOffset","frameLength","bytesPerPixel","src","nearbyItem","itemId","targetStatus","targetOptions","getLoaderImageOptions","targetOffset","nearbyImage","fillNearbyFrames","streamingData","skip","_stage$priority","baseOptions","keyedRetrieveOptions","default","failure","skipped","stageStatus","stageStatusMap","imageLoadPendingCount","imageLoadFailedCount","totalImageCount","stageStartTime","numberOfFailures","numberOfImages","startTime","stageId","stageDurationInMS","startDurationInMS","imageRequests","addStageInstance","findNearbyRequests","addStageStatus","existingRequest","_stage$offset","nearby","nearbyIndex","createLinearRGBTransferFunction","_this","_configureRenderingPipeline","_resizeCPU","_cpuFallbackEnabledElement","forceFitToWindow","oldCanvasWidth","oldCanvasHeight","clientWidth","clientHeight","setCanvasSize","imageWidth","imageHeight","wasFitToWindow","fitToWindow","relWidthChange","relHeightChange","relChange","relativeRescale","_this$getImagePlaneRe","getImagePlaneReferenceData","csImage","vtkImageMapper","vtkImageSlice","imageProperties","perImageIdDefaultProperties","voiUpdatedWithSetProperties","isComputedVOI","setRotationCPU","setRotationGPU","_setCSImage","_updateToDisplayImageCPU","_updateActorToDisplayImageId","_image$preScale","scaled","px","py","canvasToPixel","diff","worldPoint","pixelToCanvas","crange","getClippingRange","currentImageIdIndex","targetImageIdIndex","drawImageSync","cpuRenderingInvalidated","fillWithBackgroundColor","cpu","getImageDataCPU","gpu","getImageDataGPU","setColormapCPU","setColormapGPU","getCameraCPU","setCameraCPU","getPanCPU","setPanCPU","getZoomCPU","setZoomCPU","setVOICPU","setVOIGPU","getRotationCPU","getRotationGPU","setInterpolationTypeCPU","setInterpolationTypeGPU","setInvertColor","setInvertColorCPU","setInvertColorGPU","resetCameraCPU","resetCameraGPU","canvasToWorldCPU","canvasToWorldGPU","worldToCanvasCPU","worldToCanvasGPU","getCPUFallbackError","unsetColormap","unsetColormapCPU","unsetColormapGPU","_resetCPUFallbackElement","_resetGPUViewport","cameraFocalPointOnRender","initializeElementDisabledHandler","funcName","functions","entries","renderingPipelineFunctions","setThicknessFromFocalPoint","setFreezeFocalPoint","elementDisabledHandler","debouncedTimeout","calibration","cpuImagePixelData","pixelCoord","destPoint","buildMetadata","imageIdScalingFactor","_addScalingToViewport","voiLUTFunctionEnum","_getValidVOILUTFunction","_getImagePlaneModule","calibrateIfNecessary","isUpdated","_publishCalibratedEvent","_calibrationEvent","getCurrentImageId","_getDefaultPTPrescaledVOIRange","_getVOIRangeForCurrentImage","initialInvert","getTransferFunction","currentImageId","_setPropertiesFromCache","_this$_getVOIRangeFor","rotationMatrix","canvasCenter","canvasCenterWorld","topLeftWorld","bottomLeftWorld","focalPointCanvas","focalPointPixel","prevFocalPointCanvas","prevFocalPointPixel","deltaPixel","viewportOrientation","cosA","sinA","newX","newY","correctShift","setFlipCPU","newVOILUTFunction","forceRecreateLUTFunction","tfunc","wwToUse","wcToUse","stackInvalidated","imageActor","setUseLookupTableScalarRange","isSigmoidTFun","ptScaling","suvbwToSuvlbm","suvbwToSuvbsa","_getNumCompsFromPhotometricInterpretation","getImageDataMetadata","xSpacing","ySpacing","xVoxels","yVoxels","_getCameraOrientation","imageDataDirection","createVTKImageData","pixelArray","_createVTKImageData","_imageData","setStack","_throwIfDestroyed","imagesLoader","_setImageIdIndex","_checkVTKImageDataMatchesCornerstoneImage","isSameXSpacing","isSameYSpacing","_updateVTKImageDataFromCornerstoneImage","_loadAndDisplayImage","_loadAndDisplayImageCPU","_loadAndDisplayImageGPU","scalingParams","scaledWithNonIntegers","floatMinMax","intPixelData","rescaledPixel","useRGBA","_this$csImage","_this$csImage2","csImgFrame","imgFrame","permanent","transferSyntaxUID","resultList","allSettled","errorList","item","getDefaultViewport","viewportSettingToUse","addImages","stackInputs","stackInput","imagedata","createActorMapper","sameImageData","previousCameraProps","cameraProps","panCache","_restoreCameraProps","stackActorReInitialized","oldActors","unshift","triggerCameraEvent","monochrome1","_getInitialVOIRange","triggerCalibrationEvent","_getVOIRangeFromWindowLevel","_getPTPreScaledRange","_this$csImage$preScal","defaultProperties","centerWorld","debounce","loop","currentTargetImageIdIndex","numberOfFrames","newTargetImageIdIndex","targetImageId","setImageIdIndex","eventData","newImageIdIndex","calibrateSpacing","getImageIds","prevScale","getWorldToIndex","asVolume","testIndex","endsWith","reference","referenceData","foundIndex","method","fillCanvasWithBackgroundColor","actorProp","newImagePlaneModule","_this$calibration","_this$calibration2","CanvasProperties","setInterpolationTypeToNearest","setUseLabelOutline","setLabelOutlineOpacity","outlineOpacity","setLabelOutlineThickness","getRedValue","getGreenValue","getBlueValue","CanvasMapper","CanvasActor","derivedImage","renderRLE","voxelManager","OffscreenCanvas","localContext","createImageData","imageArray","dirtyX","dirtyY","dirtyX2","dirtyY2","row","getRun","baseOffset","indicesToDelete","run","segmentIndex","canvasProperties","startOffset","dirtyWidth","dirtyHeight","destOffset","_this$derivedImage","setDerivedImage","VideoViewport","panWorld","videoElement","muted","playbackRate","scrollSpeed","refreshRenderValues","isPlaying","renderFrame","duration","fps","destPos","videoCamera","worldToCanvasRatio","getWorldToCanvasRatio","panOffsetCanvas","subCanvasPos","indexPos","_this$initialRender","transformationMatrix","ctx","resetTransform","videoWidth","videoHeight","EVENTS","time","currentTime","initialRender","frame","getFrameNumber","frameRange","setFrameNumber","pause","requestAnimationFrame","renderWhilstPlaying","mute","autoplay","crossOrigin","addEventListeners","removeEventListeners","remove","setVideo","frameNumber","rendered","generalSeries","setVideoURL","cineRate","setFrameRange","videoURL","preload","loadedMetadataEventHandler","baseImageId","togglePlayPause","play","newTime","seekEventListener","paused","setTime","timeInSeconds","getFrameRange","setPlaybackRate","setScrollSpeed","rate","unit","VideoViewportEnum","_this$scalarData","canvasToIndex","indexToCanvas","hasImageURI","framesMatch","match","frameRangeExtractor","testURI","setColorTransform","setWindowLevel","setAverageWhite","averageWhite","feFilter","white","maxWhite","scaleWhite","wlScale","wlDelta","panWorldDelta","baseTarget","_range$","offsetWidth","offsetHeight","drawWidth","drawHeight","xOffsetWorld","yOffsetWorld","getCanvasToWorldRatio","canvasToWorldRatio","halfCanvas","halfCanvasWorldCoordinates","VolumeViewport","StackViewport","VolumeViewport3D","viewportTypeUsesCustomRenderingPipeline","viewportType","viewportTypeToViewportClass","Set","viewportIdsWithSameFrameOfReferenceUID","_getViewportsAsArray","vp","renderViewports","performVtkDrawCall","viewports","eventDetailArray","_needsRender","renderViewportUsingCustomOrVtkPipeline","_animationFrameSet","_animationFrameHandle","offScreenCanvasContainer","_viewports","enableElement","viewportInputEntry","viewportInput","_normalizeViewportInputEntry","disableElement","viewportUsesCustomRenderingPipeline","addCustomViewport","enableVTKjsDrivenViewport","_resetViewport","_removeViewport","_clearAnimationFrame","setViewports","publicViewportInputEntries","viewportInputEntries","_normalizeViewportInputEntries","_reset","vtkDrivenViewportInputEntries","customRenderingViewportInputEntries","vpie","setVtkjsDrivenViewports","setCustomViewports","keepCamera","vtkDrivenViewports","customRenderingViewports","_resizeVTKViewports","_resizeUsingCustomResizeHandler","getStackViewports","getVideoViewports","getVolumeViewports","viewportIds","_setViewportsToBeRenderedNextFrame","backgroundColor","f","normalizedViewportInputs","prevCamera","canvasesDrivenByVtkJs","offScreenCanvasWidth","offScreenCanvasHeight","_resizeOffScreenCanvas","_resize","viewportsDrivenByVtkJs","xOffset","internalViewportEntry","addVtkjsDrivenViewport","offscreenCanvasProperties","tabIndex","sxStartDisplayCoords","syStartDisplayCoords","sxEndDisplayCoords","syEndDisplayCoords","_getViewportCoordsOnOffScreenCanvas","vtkDrivenCanvases","vtkDrivenViewportInputEntry","_xOffset","setViewport","_render","_renderFlaggedViewports","getRenderWindow","renderers","setDraw","customRenderViewportToCanvas","offScreenCanvas","get3DContext","_renderViewportFromVtkCanvasToOnscreenCanvas","dWidth","dHeight","removeWidgets","removeAttribute","clearRect","cancelAnimationFrame","_downloadOffScreenCanvas","uri","link","download","href","body","click","removeChild","_TEMPDownloadURI","_debugRender","dataURL","toDataURL","Surface","_props$color","polys","_getSizeInBytes","getPoints","getPolys","setPoints","setPolys","getSizeInBytes","imageRetrievalPoolManager","getEnabledElement","viewportUid","renderingEngineUid","dataset","getEnabledElementByIds","getEnabledElementByViewportId","getEnabledElements","enabledElements","DEFAULT_SETTINGS","RUNTIME_SETTINGS","OBJECT_SETTINGS_MAP","DICTIONARY","Settings","base","dictionary","seal","unset","deleteCount","namespace","deleteAll","iterate","import","isPlainObject","dump","deepSet","assert","subject","getRuntimeSettings","getDefaultSettings","subfield","defaultSettings","settingObj","setting","runtimeSettings","getObjectSettings","settings","objectSettingsMap","extendRuntimeSettings","references","previous","isValidKey","record","failCount","field","setAll","WeakSet","getPrototypeOf","separator","subKey","subContext","subContextValue","getFlatPointsArray","flat","getType","ContourSet","contours","_createEachContour","contourDataArray","contourData","contour","Contour","_updateContourSetCentroid","numberOfPoints","getTotalNumberOfPoints","flatPointsArray","sumOfPoints","centroid","closestPoint","_getDistance","getCentroid","getSegmentIndex","getContours","getNumberOfContours","getNumberOfPointsArray","getNumberOfPointsInAContour","getPointsInContour","contourIndex","pointA","pointB","createAndCacheGeometry","contourSetData","_contourSetData$segme","validateContourSet","contourSet","createContourSet","geometryData","SurfaceData","validateSurface","surface","createSurface","EventListenerPhases","TargetEventListeners","isEmpty","_eventListeners","_children","dotIndex","namespaceToken","childElementEventListener","_addEventListener","_removeEventListener","child","_unregisterAllEvents","_options$capture","_listenersMap$get","listenersMap","listenerPhase","capture","Capture","Bubble","registeredPhases","None","_options$capture2","callbackItem","_listenersMap$get2","newListenerPhase","_unregisterAllListeners","eventPhases","currentPhase","useCapture","MultiTargetEventListenerManager","eventListeners","_targetsEventListeners","targetEventListeners","scaleRGBTransferFunction","scalingFactor","LAST_RUNTIME_ID","GLOBAL_CONTEXT","DEFAULT_MAX","DEFAULT_SEPARATOR","getRuntimeId","symbol","idComponents","carry","getNextRuntimeId","isOpposite","getViewportModality","_viewport$getDefaultA","_cache$getVolume","indexWithinDimensions","targetViewport","sameVolumesViewports","targetActors","vpActors","every","vpActor","targetViewports","filteredViewports","transformIndexToWorld","voxelPos","_image$preScale$scali","renderToCanvasGPU","imageOrVolume","viewportOptions","HTMLCanvasElement","isVolume","imageIdToPrint","originalWidth","originalHeight","uniqueId","temporaryCanvas","RenderingEngine","elementRendered","viewReference","onImageRendered","useViewRef","topRight","bottomLeft","querySelectorAll","thicknessMm","renderImageObject","isPTPrescaledWithSUV","renderToCanvasCPU","_renderingEngineId","_viewportOptions","loadImageToCanvas","imageAspect","baseViewportOptions","renderFn","worldCoords","newOrigin","imageToWorldCoords","imageCoords","imageCoordsInWorld","getViewportsWithImageURI","getClosestStackImageIndexForPoint","minimalDistance","planeMetadata","targetImagePlane","rowVec","colVec","planeNormal","getPlaneMetadata","closestStack","higherImageIds","lowerImageIds","calculateMinimalDistanceForStackViewport","transformCanvasToIJK","getCurrentVolumeViewportSlice","ijkOriginPoint","ijkRowPoint","ijkColPoint","ijkRowVec","ijkColVec","ijkSliceVec","maxIJKRowVec","maxIJKColVec","glMatrix","sz","canvasCorners","ijkCorner","ijkPoint","transformIJKToCanvas","canvasAABB","aabb","ijkTopLeft","ijkBottomRight","ijkDiagonal","sliceToIndexMatrix","indexToSliceMatrix","sliceWidth","sliceHeight","pixelsPerSlice","ijkPixelRow","ijkPixelCol","slicePixelIndex","volumePixelIndex","spatialRegistrationMetadataProvider","viewportId1","viewportId2","entryId","entryIdReverse","viewport1","viewport2","imageId1","imageId2","imagePlaneModule1","imagePlaneModule2","iop2","imagePositionPatient1","imagePositionPatient2","mat","getViewportImageCornersInWorld","ratio","topRightCanvas","bottomRightCanvas","bottomLeftCanvas","topRightWorld","bottomRightWorld","topLeftImage","topRightImage","bottomRightImage","bottomLeftImage","topLeftImageWorld","topRightImageWorld","bottomRightImageWorld","_getStackViewportImageCorners","imageCoord","PointsManager","initialSize","growSize","itemLength","ArrayBuffer","_byteSize","_dimensions","func","_length","getPoint","dimensionLength","subarray","getPointArray","grow","additionalSize","newSize","newArray","newData","midLength","indexStart","indexEnd","dimension","valueStart","mapData","toXYZ","xyz","fromXYZ","create3","subselect","count","selected","create2","getScalarDataType","isValidVolume","baseMetadata","validVolume","videoUIDs","isVideoTransferSyntax","uidOrUids","volumeInputs","immediateRender","setVolumePromises","convertStackToVolumeViewport","schema","load","volumeViewport","setVolumesForViewports","volumeViewportNewVolumeHandler","convertVolumeToStackViewport","_imageIdIndexToJump","stackViewport","isAllImagesCached","volumeUsedInOtherViewports","imageIdIndexToJump","minDistance","minDistanceIndex","RLEVoxelMap","jMultiple","j","rle","getRLE","defaultValue","runIndex","_rleNext4","_rleNext5","_rleNext6","rleIndex","rle1","rle0","oldValue","rleInsert","isAfter","insertIndex","rlePrev","rleNext","nextnext","_rleNext","_rleNext2","_rleNext3","kMultiple","iEnd","pixelDataConstructor","rowOffset","comp","VoxelManager","_get","_set","frameSize","modifiedSlices","addBounds","boundsIJK","getAtIJK","setAtIJK","pointIJK","toIJK","getBoundsIJK","isWithinObject","callbackArguments","kIndex","jIndex","getAtIndex","getPointIndices","toIndex","ijk","_this$points","bound","getArrayOfSlices","createRGBVolumeVoxelManager","voxels","isChanged","createVolumeVoxelManager","createNumberVolumeVoxelManager","createMapVoxelManager","createHistoryVoxelManager","sourceVoxelManager","oldV","setAtIndex","createLazyVoxelManager","planeFactory","planeSize","_map$get","layer","createRLEVoxelManager","addInstanceToImage","roundToPrecision","roundNumber","absValue","fixedPrecision","convertToGrayscale","isRGBA","isRGB","newScalarData","getRandomSampleFromArray","clonedArray","shuffleArray","componentToHex","hex","rgbToHex","hexToRgb","exec","parseInt","addVolumePromises","addStackPromises"],"sourceRoot":""}