@ohif/app 3.7.0-beta.7 → 3.7.0-beta.71

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 (60) hide show
  1. package/dist/{270.bundle.4564621556b0f963a004.js → 116.bundle.422d1a76d8daccfed61d.js} +1037 -823
  2. package/dist/{917.bundle.37f76105d2e1a70d94cf.js → 12.bundle.078c14f666c71663ae8e.js} +6 -6
  3. package/dist/{295.bundle.957b1159fec14b9199a1.js → 125.bundle.aeaad798561853bf6939.js} +6 -6
  4. package/dist/{208.bundle.21c449bf9b00123e1db3.js → 128.bundle.fdb6d1d5391b79de4936.js} +6 -6
  5. package/dist/{616.bundle.be469f44809e9b2485b2.js → 150.bundle.c99cc2e1df7cd4085265.js} +163 -106
  6. package/dist/{351.bundle.0742237651aef9694a65.js → 181.bundle.73dd6f63fe0ddc52b7eb.js} +225 -203
  7. package/dist/{351.css → 181.css} +1 -1
  8. package/dist/{606.bundle.5d876f5f3dd8287f0a28.js → 202.bundle.591726b6144882ba0ee0.js} +1459 -811
  9. package/dist/{926.bundle.dbc9d0e591cb9217fda2.js → 220.bundle.f7e1c96c94245e70f2be.js} +990 -400
  10. package/dist/{664.bundle.09abae984223969d1bde.js → 23.bundle.e008ad788170f2ed5569.js} +5 -6
  11. package/dist/{976.bundle.c1df3878a015cdf0e51f.js → 236.bundle.226efc38e453a4aeb7dd.js} +72 -83
  12. package/dist/{55.bundle.550a823e75eb608e8d5e.js → 250.bundle.8bc4553ee5c56bf7cf32.js} +51 -35
  13. package/dist/{973.bundle.f4b8ccf7ad2ff9f6041c.js → 281.bundle.e9554f25a9eeac2f43e6.js} +18 -14
  14. package/dist/{744.bundle.d07b9ad7b31de0ba4956.js → 30.bundle.c8dfb82c70ae9ff67f14.js} +185 -174
  15. package/dist/{192.bundle.1efc10937535a37a17f0.js → 348.bundle.e5082a6425f719eb6658.js} +43 -19
  16. package/dist/{404.bundle.d980e423e9670737ef12.js → 359.bundle.8da7f102410ca9c0c999.js} +13 -19
  17. package/dist/{790.bundle.ed28f0930111217b742a.js → 410.bundle.5d03eeef5b705198bf5e.js} +10 -7
  18. package/dist/{151.bundle.31ea35044218837bf73f.js → 417.bundle.6cadc61b8a455776de31.js} +49 -17
  19. package/dist/{569.bundle.21f8ad57c06a210448b5.js → 451.bundle.e59fcdb1f1d3fbe71cd4.js} +83 -101
  20. package/dist/{581.bundle.dc6197189f7c88c27d4c.js → 471.bundle.b598d406ddfc2666851b.js} +65 -93
  21. package/dist/{199.bundle.7cec631fcf4b8475abda.js → 506.bundle.869288177e788d808aaa.js} +86 -10
  22. package/dist/{935.bundle.deeffff0e4f7b528e3c3.js → 604.bundle.a51f83e64004bca5f497.js} +2 -3
  23. package/dist/{984.bundle.b33e9e702a96c5ae9fb7.js → 663.bundle.6a389399e5196510e0de.js} +67 -37
  24. package/dist/{531.bundle.2a82fb1d69e5b57cc72b.js → 677.bundle.ec5f2b4707db33bd4d8e.js} +731 -447
  25. package/dist/{205.bundle.b5a473c200dcf2bbcdb4.js → 686.bundle.b3dbf84eefbef768843f.js} +6 -6
  26. package/dist/{50.bundle.9b5c9aaaf1188ab0794a.js → 687.bundle.67d721785216e064fc52.js} +218 -9
  27. package/dist/{331.bundle.bd0c13931a21d53086c9.js → 754.bundle.a5c9246c77659eab2739.js} +12413 -7539
  28. package/dist/{728.bundle.d13856835357400fef82.js → 774.bundle.8ba82ee206266eb2da5e.js} +90 -63
  29. package/dist/{381.bundle.0905e683605fcbc0895f.js → 775.bundle.2285e7e0e67878948c0d.js} +16 -16
  30. package/dist/{283.bundle.8ffad59b5844a24b2a62.js → 782.bundle.6d57b35a056506c94352.js} +112 -62
  31. package/dist/{642.bundle.88a563313292ae2cdd2e.js → 814.bundle.ad8ebe6cffa96a5cfc1f.js} +6 -6
  32. package/dist/{799.bundle.758558e64147e5aad612.js → 822.bundle.5cdd9439a62e5c7e902f.js} +81 -34
  33. package/dist/{953.bundle.3b0189ebc11cf0946f18.js → 886.bundle.9e526affbd17b0ed96a6.js} +34 -29
  34. package/dist/{82.bundle.b824c7d8ff72de0fc149.js → 90.bundle.d7a1e818bbbd3bce5419.js} +1397 -366
  35. package/dist/945.min.worker.js +1 -1
  36. package/dist/945.min.worker.js.map +1 -1
  37. package/dist/{707.bundle.0b18a871c9eb8df9e992.js → 967.bundle.8b4adf9b5a7392b51d0c.js} +584 -435
  38. package/dist/app-config.js +7 -7
  39. package/dist/{app.bundle.f0885cb776ab9ae8974b.js → app.bundle.1905c07065c4b93afa5a.js} +69865 -67829
  40. package/dist/app.bundle.css +9 -9
  41. package/dist/assets/yandex-browser-manifest.json +1 -1
  42. package/dist/cornerstoneDICOMImageLoader.min.js +1 -1
  43. package/dist/cornerstoneDICOMImageLoader.min.js.map +1 -1
  44. package/dist/{dicom-microscopy-viewer.bundle.aa60bdf008c32c39cfd7.js → dicom-microscopy-viewer.bundle.2c146384eb9466d02ff8.js} +5 -4
  45. package/dist/es6-shim.min.js +3569 -2
  46. package/dist/google.js +8 -7
  47. package/dist/index.html +1 -1
  48. package/dist/{index.worker.1c69152d710fa7b84bce.worker.js → index.worker.e62ecca63f1a2e124230.worker.js} +2 -2
  49. package/dist/index.worker.e62ecca63f1a2e124230.worker.js.map +1 -0
  50. package/dist/init-service-worker.js +3 -5
  51. package/dist/oidc-client.min.js +10857 -39
  52. package/dist/polyfill.min.js +184 -1
  53. package/dist/silent-refresh.html +18 -9
  54. package/dist/sw.js +1 -1
  55. package/package.json +19 -20
  56. package/dist/780.bundle.fd0f13dc92e9caa0581e.js +0 -4769
  57. package/dist/index.worker.1c69152d710fa7b84bce.worker.js.map +0 -1
  58. /package/dist/{55.css → 250.css} +0 -0
  59. /package/dist/{806.css → 579.css} +0 -0
  60. /package/dist/{707.css → 967.css} +0 -0
@@ -1,6 +1,6 @@
1
- (globalThis["webpackChunk"] = globalThis["webpackChunk"] || []).push([[707],{
1
+ (self["webpackChunk"] = self["webpackChunk"] || []).push([[967],{
2
2
 
3
- /***/ 31197:
3
+ /***/ 94004:
4
4
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
5
5
 
6
6
  "use strict";
@@ -26,27 +26,26 @@ __webpack_require__.r(utils_namespaceObject);
26
26
  __webpack_require__.d(utils_namespaceObject, {
27
27
  getFirstAnnotationSelected: () => (getFirstAnnotationSelected),
28
28
  getHandlesFromPoints: () => (getHandlesFromPoints),
29
- getModalityUnit: () => (utils_getModalityUnit),
30
29
  getSOPInstanceAttributes: () => (getSOPInstanceAttributes/* default */.Z),
31
30
  isAnnotationSelected: () => (isAnnotationSelected),
32
31
  setAnnotationSelected: () => (setAnnotationSelected)
33
32
  });
34
33
 
35
34
  // EXTERNAL MODULE: ../../../node_modules/react/index.js
36
- var react = __webpack_require__(32735);
37
- // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/index.js + 335 modules
38
- var esm = __webpack_require__(77331);
39
- // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/index.js + 321 modules
40
- var dist_esm = __webpack_require__(57270);
41
- // EXTERNAL MODULE: ../../core/src/index.ts + 101 modules
42
- var src = __webpack_require__(48501);
35
+ var react = __webpack_require__(43001);
36
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/index.js + 337 modules
37
+ var esm = __webpack_require__(45754);
38
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/index.js + 326 modules
39
+ var dist_esm = __webpack_require__(99116);
40
+ // EXTERNAL MODULE: ../../core/src/index.ts + 75 modules
41
+ var src = __webpack_require__(78695);
43
42
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/streaming-image-volume-loader/dist/esm/index.js + 13 modules
44
- var streaming_image_volume_loader_dist_esm = __webpack_require__(28909);
43
+ var streaming_image_volume_loader_dist_esm = __webpack_require__(7087);
45
44
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/dicom-image-loader/dist/dynamic-import/cornerstoneDICOMImageLoader.min.js
46
- var cornerstoneDICOMImageLoader_min = __webpack_require__(99605);
45
+ var cornerstoneDICOMImageLoader_min = __webpack_require__(61539);
47
46
  var cornerstoneDICOMImageLoader_min_default = /*#__PURE__*/__webpack_require__.n(cornerstoneDICOMImageLoader_min);
48
47
  // EXTERNAL MODULE: ../../../node_modules/dicom-parser/dist/dicomParser.min.js
49
- var dicomParser_min = __webpack_require__(43264);
48
+ var dicomParser_min = __webpack_require__(56660);
50
49
  var dicomParser_min_default = /*#__PURE__*/__webpack_require__.n(dicomParser_min);
51
50
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/initWADOImageLoader.js
52
51
 
@@ -76,7 +75,7 @@ function initWebWorkers(appConfig) {
76
75
  initialized = true;
77
76
  }
78
77
  }
79
- function initWADOImageLoader(userAuthenticationService, appConfig) {
78
+ function initWADOImageLoader(userAuthenticationService, appConfig, extensionManager) {
80
79
  (cornerstoneDICOMImageLoader_min_default()).external.cornerstone = esm;
81
80
  (cornerstoneDICOMImageLoader_min_default()).external.dicomParser = (dicomParser_min_default());
82
81
  registerVolumeLoader('cornerstoneStreamingImageVolume', streaming_image_volume_loader_dist_esm/* cornerstoneStreamingImageVolumeLoader */.IU);
@@ -90,18 +89,13 @@ function initWADOImageLoader(userAuthenticationService, appConfig) {
90
89
  convertFloatPixelDataToInt: false
91
90
  },
92
91
  beforeSend: function (xhr) {
92
+ //TODO should be removed in the future and request emitted by DicomWebDataSource
93
+ const sourceConfig = extensionManager.getActiveDataSource()?.[0].getConfig() ?? {};
93
94
  const headers = userAuthenticationService.getAuthorizationHeader();
94
-
95
- // Request:
96
- // JPEG-LS Lossless (1.2.840.10008.1.2.4.80) if available, otherwise accept
97
- // whatever transfer-syntax the origin server provides.
98
- // For now we use image/jls and image/x-jls because some servers still use the old type
99
- // http://dicom.nema.org/medical/dicom/current/output/html/part18.html
95
+ const acceptHeader = src.utils.generateAcceptHeader(sourceConfig.acceptHeader, sourceConfig.requestTransferSyntaxUID, sourceConfig.omitQuotationForMultipartRequest);
100
96
  const xhrRequestHeaders = {
101
- Accept: appConfig.omitQuotationForMultipartRequest ? 'multipart/related; type=application/octet-stream' : 'multipart/related; type="application/octet-stream"'
102
- // 'multipart/related; type="image/x-jls", multipart/related; type="image/jls"; transfer-syntax="1.2.840.10008.1.2.4.80", multipart/related; type="image/x-jls", multipart/related; type="application/octet-stream"; transfer-syntax=*',
97
+ Accept: acceptHeader
103
98
  };
104
-
105
99
  if (headers) {
106
100
  Object.assign(xhrRequestHeaders, headers);
107
101
  }
@@ -116,14 +110,14 @@ function initWADOImageLoader(userAuthenticationService, appConfig) {
116
110
  function destroy() {
117
111
  // Note: we don't want to call .terminate on the webWorkerManager since
118
112
  // that resets the config
119
- const webWorkers = cornerstoneDICOMImageLoader_min.webWorkerManager.webWorkers;
113
+ const webWorkers = webWorkerManager.webWorkers;
120
114
  for (let i = 0; i < webWorkers.length; i++) {
121
115
  webWorkers[i].worker.terminate();
122
116
  }
123
117
  webWorkers.length = 0;
124
118
  }
125
- // EXTERNAL MODULE: ../../ui/src/index.js + 452 modules
126
- var ui_src = __webpack_require__(28619);
119
+ // EXTERNAL MODULE: ../../ui/src/index.js + 458 modules
120
+ var ui_src = __webpack_require__(88344);
127
121
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/callInputDialog.tsx
128
122
 
129
123
 
@@ -157,7 +151,9 @@ function callInputDialog(uiDialogService, data, callback) {
157
151
  } = _ref;
158
152
  switch (action.id) {
159
153
  case 'save':
160
- if (typeof validateFunc === 'function' && !validateFunc(value.label)) return;
154
+ if (typeof validateFunc === 'function' && !validateFunc(value.label)) {
155
+ return;
156
+ }
161
157
  callback(value.label, action.id);
162
158
  break;
163
159
  case 'cancel':
@@ -201,7 +197,7 @@ function callInputDialog(uiDialogService, data, callback) {
201
197
  } = _ref2;
202
198
  return /*#__PURE__*/react.createElement(ui_src/* Input */.II, {
203
199
  autoFocus: true,
204
- className: "bg-black border-primary-main",
200
+ className: "border-primary-main bg-black",
205
201
  type: "text",
206
202
  id: "annotation",
207
203
  label: inputLabel,
@@ -232,17 +228,17 @@ function callInputDialog(uiDialogService, data, callback) {
232
228
  }
233
229
  /* harmony default export */ const utils_callInputDialog = (callInputDialog);
234
230
  // EXTERNAL MODULE: ../../../extensions/cornerstone/src/state.ts
235
- var state = __webpack_require__(21922);
231
+ var state = __webpack_require__(73704);
236
232
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/getActiveViewportEnabledElement.ts
237
233
 
238
234
 
239
235
  function getActiveViewportEnabledElement(viewportGridService) {
240
236
  const {
241
- activeViewportIndex
237
+ activeViewportId
242
238
  } = viewportGridService.getState();
243
239
  const {
244
240
  element
245
- } = (0,state/* getEnabledElement */.K8)(activeViewportIndex) || {};
241
+ } = (0,state/* getEnabledElement */.K8)(activeViewportId) || {};
246
242
  const enabledElement = (0,esm.getEnabledElement)(element);
247
243
  return enabledElement;
248
244
  }
@@ -358,9 +354,214 @@ function onCompletedCalibrationLine(servicesManager, csToolsEvent) {
358
354
  });
359
355
  });
360
356
  }
357
+ // EXTERNAL MODULE: ../../core/src/utils/index.js + 25 modules
358
+ var utils = __webpack_require__(77250);
359
+ ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/tools/ImageOverlayViewerTool.tsx
360
+
361
+
362
+
363
+
364
+ /**
365
+ * Image Overlay Viewer tool is not a traditional tool that requires user interactin.
366
+ * But it is used to display Pixel Overlays. And it will provide toggling capability.
367
+ *
368
+ * The documentation for Overlay Plane Module of DICOM can be found in [C.9.2 of
369
+ * Part-3 of DICOM standard](https://dicom.nema.org/medical/dicom/2018b/output/chtml/part03/sect_C.9.2.html)
370
+ *
371
+ * Image Overlay rendered by this tool can be toggled on and off using
372
+ * toolGroup.setToolEnabled() and toolGroup.setToolDisabled()
373
+ */
374
+ class ImageOverlayViewerTool extends dist_esm.AnnotationDisplayTool {
375
+ constructor() {
376
+ let toolProps = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
377
+ let defaultToolProps = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
378
+ supportedInteractionTypes: [],
379
+ configuration: {
380
+ fillColor: [255, 127, 127, 255]
381
+ }
382
+ };
383
+ super(toolProps, defaultToolProps);
384
+ this._cachedOverlayMetadata = new Map();
385
+ this._cachedStats = {};
386
+ this.onSetToolDisabled = () => {
387
+ this._cachedStats = {};
388
+ this._cachedOverlayMetadata = new Map();
389
+ };
390
+ this.renderAnnotation = (enabledElement, svgDrawingHelper) => {
391
+ const {
392
+ viewport
393
+ } = enabledElement;
394
+ const imageId = this.getReferencedImageId(viewport);
395
+ if (!imageId) {
396
+ return;
397
+ }
398
+ const overlays = this._cachedOverlayMetadata.get(imageId) ?? esm.metaData.get('overlayPlaneModule', imageId)?.overlays;
399
+
400
+ // no overlays
401
+ if (!overlays?.length) {
402
+ return;
403
+ }
404
+ this._cachedOverlayMetadata.set(imageId, overlays);
405
+ this._getCachedStat(imageId, overlays, this.configuration.fillColor).then(cachedStat => {
406
+ cachedStat.overlays.forEach(overlay => {
407
+ this._renderOverlay(enabledElement, svgDrawingHelper, overlay);
408
+ });
409
+ });
410
+ return true;
411
+ };
412
+ }
413
+ /**
414
+ * Render to DOM
415
+ *
416
+ * @param enabledElement
417
+ * @param svgDrawingHelper
418
+ * @param overlayData
419
+ * @returns
420
+ */
421
+ _renderOverlay(enabledElement, svgDrawingHelper, overlayData) {
422
+ const {
423
+ viewport
424
+ } = enabledElement;
425
+ const imageId = this.getReferencedImageId(viewport);
426
+ if (!imageId) {
427
+ return;
428
+ }
429
+
430
+ // Decide the rendering position of the overlay image on the current canvas
431
+ const {
432
+ _id,
433
+ columns: width,
434
+ rows: height,
435
+ x,
436
+ y
437
+ } = overlayData;
438
+ const overlayTopLeftWorldPos = esm.utilities.imageToWorldCoords(imageId, [x - 1,
439
+ // Remind that top-left corner's (x, y) is be (1, 1)
440
+ y - 1]);
441
+ const overlayTopLeftOnCanvas = viewport.worldToCanvas(overlayTopLeftWorldPos);
442
+ const overlayBottomRightWorldPos = esm.utilities.imageToWorldCoords(imageId, [width, height]);
443
+ const overlayBottomRightOnCanvas = viewport.worldToCanvas(overlayBottomRightWorldPos);
444
+
445
+ // add image to the annotations svg layer
446
+ const svgns = 'http://www.w3.org/2000/svg';
447
+ const svgNodeHash = `image-overlay-${_id}`;
448
+ const existingImageElement = svgDrawingHelper.getSvgNode(svgNodeHash);
449
+ const attributes = {
450
+ 'data-id': svgNodeHash,
451
+ width: overlayBottomRightOnCanvas[0] - overlayTopLeftOnCanvas[0],
452
+ height: overlayBottomRightOnCanvas[1] - overlayTopLeftOnCanvas[1],
453
+ x: overlayTopLeftOnCanvas[0],
454
+ y: overlayTopLeftOnCanvas[1],
455
+ href: overlayData.dataUrl
456
+ };
457
+ if (isNaN(attributes.x) || isNaN(attributes.y) || isNaN(attributes.width) || isNaN(attributes.height)) {
458
+ console.warn('Invalid rendering attribute for image overlay', attributes['data-id']);
459
+ return false;
460
+ }
461
+ if (existingImageElement) {
462
+ dist_esm.drawing.setAttributesIfNecessary(attributes, existingImageElement);
463
+ svgDrawingHelper.setNodeTouched(svgNodeHash);
464
+ } else {
465
+ const newImageElement = document.createElementNS(svgns, 'image');
466
+ dist_esm.drawing.setNewAttributesIfValid(attributes, newImageElement);
467
+ svgDrawingHelper.appendNode(newImageElement, svgNodeHash);
468
+ }
469
+ return true;
470
+ }
471
+ async _getCachedStat(imageId, overlayMetadata, color) {
472
+ if (this._cachedStats[imageId] && this._isSameColor(this._cachedStats[imageId].color, color)) {
473
+ return this._cachedStats[imageId];
474
+ }
475
+ const overlays = await Promise.all(overlayMetadata.filter(overlay => overlay.pixelData).map(async (overlay, idx) => {
476
+ let pixelData = null;
477
+ if (overlay.pixelData.Value) {
478
+ pixelData = overlay.pixelData.Value;
479
+ } else if (overlay.pixelData.retrieveBulkData) {
480
+ pixelData = await overlay.pixelData.retrieveBulkData();
481
+ }
482
+ if (!pixelData) {
483
+ return;
484
+ }
485
+ const dataUrl = this._renderOverlayToDataUrl({
486
+ width: overlay.columns,
487
+ height: overlay.rows
488
+ }, color, pixelData);
489
+ return {
490
+ ...overlay,
491
+ _id: (0,utils/* guid */.M8)(),
492
+ dataUrl,
493
+ // this will be a data url expression of the rendered image
494
+ color
495
+ };
496
+ }));
497
+ this._cachedStats[imageId] = {
498
+ color: color,
499
+ overlays: overlays.filter(overlay => overlay)
500
+ };
501
+ return this._cachedStats[imageId];
502
+ }
503
+
504
+ /**
505
+ * compare two RGBA expression of colors.
506
+ *
507
+ * @param color1
508
+ * @param color2
509
+ * @returns
510
+ */
511
+ _isSameColor(color1, color2) {
512
+ return color1 && color2 && color1[0] === color2[0] && color1[1] === color2[1] && color1[2] === color2[2] && color1[3] === color2[3];
513
+ }
514
+
515
+ /**
516
+ * pixelData of overlayPlane module is an array of bits corresponding
517
+ * to each of the underlying pixels of the image.
518
+ * Let's create pixel data from bit array of overlay data
519
+ *
520
+ * @param pixelDataRaw
521
+ * @param color
522
+ * @returns
523
+ */
524
+ _renderOverlayToDataUrl(_ref, color, pixelDataRaw) {
525
+ let {
526
+ width,
527
+ height
528
+ } = _ref;
529
+ const pixelDataView = new DataView(pixelDataRaw);
530
+ const totalBits = width * height;
531
+ const canvas = document.createElement('canvas');
532
+ canvas.width = width;
533
+ canvas.height = height;
534
+ const ctx = canvas.getContext('2d');
535
+ ctx.clearRect(0, 0, width, height); // make it transparent
536
+ ctx.globalCompositeOperation = 'copy';
537
+ const imageData = ctx.getImageData(0, 0, width, height);
538
+ const data = imageData.data;
539
+ for (let i = 0, bitIdx = 0, byteIdx = 0; i < totalBits; i++) {
540
+ if (pixelDataView.getUint8(byteIdx) & 1 << bitIdx) {
541
+ data[i * 4] = color[0];
542
+ data[i * 4 + 1] = color[1];
543
+ data[i * 4 + 2] = color[2];
544
+ data[i * 4 + 3] = color[3];
545
+ }
546
+
547
+ // next bit, byte
548
+ if (bitIdx >= 7) {
549
+ bitIdx = 0;
550
+ byteIdx++;
551
+ } else {
552
+ bitIdx++;
553
+ }
554
+ }
555
+ ctx.putImageData(imageData, 0, 0);
556
+ return canvas.toDataURL();
557
+ }
558
+ }
559
+ ImageOverlayViewerTool.toolName = 'ImageOverlayViewer';
560
+ /* harmony default export */ const tools_ImageOverlayViewerTool = (ImageOverlayViewerTool);
361
561
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/initCornerstoneTools.js
362
562
 
363
563
 
564
+
364
565
  function initCornerstoneTools() {
365
566
  let configuration = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
366
567
  dist_esm.CrosshairsTool.isAnnotation = false;
@@ -390,6 +591,7 @@ function initCornerstoneTools() {
390
591
  (0,dist_esm.addTool)(dist_esm.ReferenceLinesTool);
391
592
  (0,dist_esm.addTool)(tools_CalibrationLineTool);
392
593
  (0,dist_esm.addTool)(dist_esm.TrackballRotateTool);
594
+ (0,dist_esm.addTool)(tools_ImageOverlayViewerTool);
393
595
 
394
596
  // Modify annotation tools to use dashed lines on SR
395
597
  const annotationStyle = {
@@ -428,13 +630,14 @@ const toolNames = {
428
630
  SegmentationDisplay: dist_esm.SegmentationDisplayTool.toolName,
429
631
  ReferenceLines: dist_esm.ReferenceLinesTool.toolName,
430
632
  CalibrationLine: tools_CalibrationLineTool.toolName,
431
- TrackballRotateTool: dist_esm.TrackballRotateTool.toolName
633
+ TrackballRotateTool: dist_esm.TrackballRotateTool.toolName,
634
+ ImageOverlayViewer: tools_ImageOverlayViewerTool.toolName
432
635
  };
433
636
 
434
637
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/constants/supportedTools.js
435
638
  /* harmony default export */ const supportedTools = (['Length', 'EllipticalROI', 'CircleROI', 'Bidirectional', 'ArrowAnnotate', 'Angle', 'CobbAngle', 'Probe', 'RectangleROI', 'PlanarFreehandROI']);
436
639
  // EXTERNAL MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/utils/getSOPInstanceAttributes.js
437
- var getSOPInstanceAttributes = __webpack_require__(63130);
640
+ var getSOPInstanceAttributes = __webpack_require__(87172);
438
641
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/Length.ts
439
642
 
440
643
 
@@ -607,7 +810,9 @@ function getDisplayText(mappedAnnotations, displaySet) {
607
810
  }
608
811
  const instanceText = InstanceNumber ? ` I: ${InstanceNumber}` : '';
609
812
  const frameText = displaySet.isMultiFrame ? ` F: ${frameNumber}` : '';
610
- if (length === null || length === undefined) return displayText;
813
+ if (length === null || length === undefined) {
814
+ return displayText;
815
+ }
611
816
  const roundedLength = src.utils.roundNumber(length, 2);
612
817
  displayText.push(`${roundedLength} mm (S: ${SeriesNumber}${instanceText}${frameText})`);
613
818
  return displayText;
@@ -791,22 +996,10 @@ function Bidirectional_getDisplayText(mappedAnnotations, displaySet) {
791
996
  return displayText;
792
997
  }
793
998
  /* harmony default export */ const measurementServiceMappings_Bidirectional = (Bidirectional);
794
- ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/utils/getModalityUnit.js
795
- function getModalityUnit(modality) {
796
- if (modality === 'CT') {
797
- return 'HU';
798
- } else if (modality === 'PT') {
799
- return 'SUV';
800
- } else {
801
- return '';
802
- }
803
- }
804
- /* harmony default export */ const utils_getModalityUnit = (getModalityUnit);
805
999
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/EllipticalROI.ts
806
1000
 
807
1001
 
808
1002
 
809
-
810
1003
  const EllipticalROI = {
811
1004
  toAnnotation: measurement => {},
812
1005
  toMeasurement: (csToolsEventDetail, displaySetService, cornerstoneViewportService, getValueTypeFromToolType) => {
@@ -904,16 +1097,16 @@ function EllipticalROI_getMappedAnnotations(annotation, displaySetService) {
904
1097
  stdDev,
905
1098
  max,
906
1099
  area,
907
- Modality
1100
+ Modality,
1101
+ modalityUnit
908
1102
  } = targetStats;
909
- const unit = utils_getModalityUnit(Modality);
910
1103
  annotations.push({
911
1104
  SeriesInstanceUID,
912
1105
  SOPInstanceUID,
913
1106
  SeriesNumber,
914
1107
  frameNumber,
915
1108
  Modality,
916
- unit,
1109
+ unit: modalityUnit,
917
1110
  mean,
918
1111
  stdDev,
919
1112
  max,
@@ -1013,7 +1206,6 @@ function EllipticalROI_getDisplayText(mappedAnnotations, displaySet) {
1013
1206
 
1014
1207
 
1015
1208
 
1016
-
1017
1209
  const CircleROI = {
1018
1210
  toAnnotation: measurement => {},
1019
1211
  toMeasurement: (csToolsEventDetail, DisplaySetService, CornerstoneViewportService, getValueTypeFromToolType) => {
@@ -1111,16 +1303,16 @@ function CircleROI_getMappedAnnotations(annotation, DisplaySetService) {
1111
1303
  stdDev,
1112
1304
  max,
1113
1305
  area,
1114
- Modality
1306
+ Modality,
1307
+ modalityUnit
1115
1308
  } = targetStats;
1116
- const unit = utils_getModalityUnit(Modality);
1117
1309
  annotations.push({
1118
1310
  SeriesInstanceUID,
1119
1311
  SOPInstanceUID,
1120
1312
  SeriesNumber,
1121
1313
  frameNumber,
1122
1314
  Modality,
1123
- unit,
1315
+ unit: modalityUnit,
1124
1316
  mean,
1125
1317
  stdDev,
1126
1318
  max,
@@ -1515,7 +1707,9 @@ function CobbAngle_getDisplayText(mappedAnnotations, displaySet) {
1515
1707
  }
1516
1708
  const instanceText = InstanceNumber ? ` I: ${InstanceNumber}` : '';
1517
1709
  const frameText = displaySet.isMultiFrame ? ` F: ${frameNumber}` : '';
1518
- if (angle === undefined) return displayText;
1710
+ if (angle === undefined) {
1711
+ return displayText;
1712
+ }
1519
1713
  const roundedAngle = src.utils.roundNumber(angle, 2);
1520
1714
  displayText.push(`${roundedAngle} ${unit} (S: ${SeriesNumber}${instanceText}${frameText})`);
1521
1715
  return displayText;
@@ -1695,7 +1889,9 @@ function Angle_getDisplayText(mappedAnnotations, displaySet) {
1695
1889
  }
1696
1890
  const instanceText = InstanceNumber ? ` I: ${InstanceNumber}` : '';
1697
1891
  const frameText = displaySet.isMultiFrame ? ` F: ${frameNumber}` : '';
1698
- if (angle === undefined) return displayText;
1892
+ if (angle === undefined) {
1893
+ return displayText;
1894
+ }
1699
1895
  const roundedAngle = src.utils.roundNumber(angle, 2);
1700
1896
  displayText.push(`${roundedAngle} ${unit} (S: ${SeriesNumber}${instanceText}${frameText})`);
1701
1897
  return displayText;
@@ -1839,7 +2035,6 @@ function PlanarFreehandROI_getDisplayText(mappedAnnotations) {
1839
2035
 
1840
2036
 
1841
2037
 
1842
-
1843
2038
  const RectangleROI = {
1844
2039
  toAnnotation: measurement => {},
1845
2040
  toMeasurement: (csToolsEventDetail, DisplaySetService, CornerstoneViewportService, getValueTypeFromToolType) => {
@@ -1937,16 +2132,16 @@ function RectangleROI_getMappedAnnotations(annotation, DisplaySetService) {
1937
2132
  stdDev,
1938
2133
  max,
1939
2134
  area,
1940
- Modality
2135
+ Modality,
2136
+ modalityUnit
1941
2137
  } = targetStats;
1942
- const unit = utils_getModalityUnit(Modality);
1943
2138
  annotations.push({
1944
2139
  SeriesInstanceUID,
1945
2140
  SOPInstanceUID,
1946
2141
  SeriesNumber,
1947
2142
  frameNumber,
1948
2143
  Modality,
1949
- unit,
2144
+ unit: modalityUnit,
1950
2145
  mean,
1951
2146
  stdDev,
1952
2147
  max,
@@ -2540,7 +2735,7 @@ function getInterleavedFrames(imageIds) {
2540
2735
  return imageIdsToPrefetch;
2541
2736
  }
2542
2737
  // EXTERNAL MODULE: ../../../node_modules/lodash/lodash.js
2543
- var lodash = __webpack_require__(92891);
2738
+ var lodash = __webpack_require__(44379);
2544
2739
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/interleaveCenterLoader.ts
2545
2740
 
2546
2741
 
@@ -2730,8 +2925,12 @@ function getNthFrames(imageIds) {
2730
2925
  * @returns [] reordered to be breadth first traversal of lists
2731
2926
  */
2732
2927
  function interleave(lists) {
2733
- if (!lists || !lists.length) return [];
2734
- if (lists.length === 1) return lists[0];
2928
+ if (!lists || !lists.length) {
2929
+ return [];
2930
+ }
2931
+ if (lists.length === 1) {
2932
+ return lists[0];
2933
+ }
2735
2934
  console.time('interleave');
2736
2935
  const useLists = [...lists];
2737
2936
  const ret = [];
@@ -3020,9 +3219,15 @@ const DEFAULT_CONTEXT_MENU_CLICKS = {
3020
3219
  function getEventName(evt) {
3021
3220
  const button = evt.detail.event.which;
3022
3221
  const nameArr = [];
3023
- if (evt.detail.event.altKey) nameArr.push('alt');
3024
- if (evt.detail.event.ctrlKey) nameArr.push('ctrl');
3025
- if (evt.detail.event.shiftKey) nameArr.push('shift');
3222
+ if (evt.detail.event.altKey) {
3223
+ nameArr.push('alt');
3224
+ }
3225
+ if (evt.detail.event.ctrlKey) {
3226
+ nameArr.push('ctrl');
3227
+ }
3228
+ if (evt.detail.event.shiftKey) {
3229
+ nameArr.push('shift');
3230
+ }
3026
3231
  nameArr.push('button');
3027
3232
  nameArr.push(button);
3028
3233
  return nameArr.join('');
@@ -3040,7 +3245,6 @@ function initContextMenu(_ref) {
3040
3245
  const cornerstoneViewportHandleEvent = (name, evt) => {
3041
3246
  const customizations = customizationService.get('cornerstoneViewportClickCommands') || DEFAULT_CONTEXT_MENU_CLICKS;
3042
3247
  const toRun = customizations[name];
3043
- console.log('initContextMenu::cornerstoneViewportHandleEvent', name, toRun);
3044
3248
  const options = {
3045
3249
  nearbyToolData: findNearbyToolData(commandsManager, evt),
3046
3250
  event: evt
@@ -3057,10 +3261,11 @@ function initContextMenu(_ref) {
3057
3261
  element
3058
3262
  } = evt.detail;
3059
3263
  const viewportInfo = cornerstoneViewportService.getViewportInfo(viewportId);
3060
- if (!viewportInfo) return;
3061
- const viewportIndex = viewportInfo.getViewportIndex();
3264
+ if (!viewportInfo) {
3265
+ return;
3266
+ }
3062
3267
  // TODO check update upstream
3063
- (0,state/* setEnabledElement */.Yc)(viewportIndex, element);
3268
+ (0,state/* setEnabledElement */.Yc)(viewportId, element);
3064
3269
  element.addEventListener(cs3DToolsEvents.MOUSE_CLICK, cornerstoneViewportHandleClick);
3065
3270
  }
3066
3271
  function elementDisabledHandler(evt) {
@@ -3094,9 +3299,15 @@ const DEFAULT_DOUBLE_CLICK = {
3094
3299
  */
3095
3300
  function getDoubleClickEventName(evt) {
3096
3301
  const nameArr = [];
3097
- if (evt.detail.event.altKey) nameArr.push('alt');
3098
- if (evt.detail.event.ctrlKey) nameArr.push('ctrl');
3099
- if (evt.detail.event.shiftKey) nameArr.push('shift');
3302
+ if (evt.detail.event.altKey) {
3303
+ nameArr.push('alt');
3304
+ }
3305
+ if (evt.detail.event.ctrlKey) {
3306
+ nameArr.push('ctrl');
3307
+ }
3308
+ if (evt.detail.event.shiftKey) {
3309
+ nameArr.push('shift');
3310
+ }
3100
3311
  nameArr.push('doubleClick');
3101
3312
  return nameArr.join('');
3102
3313
  }
@@ -3154,7 +3365,6 @@ function initDoubleClick(_ref) {
3154
3365
 
3155
3366
 
3156
3367
 
3157
-
3158
3368
  // TODO: Cypress tests are currently grabbing this from the window?
3159
3369
  window.cornerstone = esm;
3160
3370
  window.cornerstoneTools = dist_esm;
@@ -3181,18 +3391,18 @@ async function init(_ref) {
3181
3391
  }
3182
3392
  });
3183
3393
 
3184
- // For debugging large datasets
3185
- const MAX_CACHE_SIZE_1GB = 1073741824;
3186
- const maxCacheSize = appConfig.maxCacheSize;
3187
- esm.cache.setMaxCacheSize(maxCacheSize ? maxCacheSize : MAX_CACHE_SIZE_1GB);
3394
+ // For debugging large datasets, otherwise prefer the defaults
3395
+ const {
3396
+ maxCacheSize
3397
+ } = appConfig;
3398
+ if (maxCacheSize) {
3399
+ esm.cache.setMaxCacheSize(maxCacheSize);
3400
+ }
3188
3401
  initCornerstoneTools();
3189
3402
  esm.Settings.getRuntimeSettings().set('useCursors', Boolean(appConfig.useCursors));
3190
3403
  const {
3191
3404
  userAuthenticationService,
3192
- measurementService,
3193
3405
  customizationService,
3194
- displaySetService,
3195
- uiDialogService,
3196
3406
  uiModalService,
3197
3407
  uiNotificationService,
3198
3408
  cineService,
@@ -3254,7 +3464,7 @@ async function init(_ref) {
3254
3464
  thumbnail: appConfig?.maxNumRequests?.thumbnail || 75,
3255
3465
  prefetch: appConfig?.maxNumRequests?.prefetch || 10
3256
3466
  };
3257
- initWADOImageLoader(userAuthenticationService, appConfig);
3467
+ initWADOImageLoader(userAuthenticationService, appConfig, extensionManager);
3258
3468
 
3259
3469
  /* Measurement Service */
3260
3470
  this.measurementServiceSource = connectToolsToMeasurementService(servicesManager);
@@ -3338,12 +3548,10 @@ async function init(_ref) {
3338
3548
 
3339
3549
  esm.eventTarget.addEventListener(esm.EVENTS.ELEMENT_ENABLED, elementEnabledHandler.bind(null));
3340
3550
  esm.eventTarget.addEventListener(esm.EVENTS.ELEMENT_DISABLED, elementDisabledHandler.bind(null));
3341
- viewportGridService.subscribe(viewportGridService.EVENTS.ACTIVE_VIEWPORT_INDEX_CHANGED, _ref2 => {
3551
+ viewportGridService.subscribe(viewportGridService.EVENTS.ACTIVE_VIEWPORT_ID_CHANGED, _ref2 => {
3342
3552
  let {
3343
- viewportIndex,
3344
3553
  viewportId
3345
3554
  } = _ref2;
3346
- viewportId = viewportId || `viewport-${viewportIndex}`;
3347
3555
  const toolGroup = toolGroupService.getToolGroupForViewport(viewportId);
3348
3556
  if (!toolGroup || !toolGroup._toolInstances?.['ReferenceLines']) {
3349
3557
  return;
@@ -3387,12 +3595,12 @@ function _showCPURenderingModal(uiModalService, hangingProtocolService) {
3387
3595
  });
3388
3596
  }
3389
3597
  // EXTERNAL MODULE: ../../../node_modules/react-dropzone/dist/es/index.js + 5 modules
3390
- var es = __webpack_require__(58591);
3598
+ var es = __webpack_require__(74834);
3391
3599
  // EXTERNAL MODULE: ../../../node_modules/prop-types/index.js
3392
- var prop_types = __webpack_require__(60216);
3600
+ var prop_types = __webpack_require__(3827);
3393
3601
  var prop_types_default = /*#__PURE__*/__webpack_require__.n(prop_types);
3394
3602
  // EXTERNAL MODULE: ../../../node_modules/classnames/index.js
3395
- var classnames = __webpack_require__(40841);
3603
+ var classnames = __webpack_require__(44921);
3396
3604
  var classnames_default = /*#__PURE__*/__webpack_require__.n(classnames);
3397
3605
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/DicomFileUploader.ts
3398
3606
 
@@ -3541,7 +3749,9 @@ class DicomFileUploader extends src/* PubSubService */.hC {
3541
3749
  request.addEventListener('loadend', cleanUpCallback);
3542
3750
  }
3543
3751
  _checkDicomFile(arrayBuffer) {
3544
- if (arrayBuffer.length <= 132) return false;
3752
+ if (arrayBuffer.length <= 132) {
3753
+ return false;
3754
+ }
3545
3755
  const arr = new Uint8Array(arrayBuffer.slice(128, 132));
3546
3756
  // bytes from 128 to 132 must be "DICM"
3547
3757
  return Array.from('DICM').every((char, i) => char.charCodeAt(0) === arr[i]);
@@ -3560,7 +3770,6 @@ const DicomUploadProgressItem = /*#__PURE__*/(0,react.memo)(_ref => {
3560
3770
  const [percentComplete, setPercentComplete] = (0,react.useState)(dicomFileUploader.getPercentComplete());
3561
3771
  const [failedReason, setFailedReason] = (0,react.useState)('');
3562
3772
  const [status, setStatus] = (0,react.useState)(dicomFileUploader.getStatus());
3563
- console.info(`${dicomFileUploader.getFileId()}`);
3564
3773
  const isComplete = (0,react.useCallback)(() => {
3565
3774
  return status === UploadStatus.Failed || status === UploadStatus.Cancelled || status === UploadStatus.Success;
3566
3775
  }, [status]);
@@ -3601,25 +3810,25 @@ const DicomUploadProgressItem = /*#__PURE__*/(0,react.memo)(_ref => {
3601
3810
  }
3602
3811
  };
3603
3812
  return /*#__PURE__*/react.createElement("div", {
3604
- className: "flex w-full p-2.5 text-lg min-h-14 items-center border-b border-secondary-light overflow-hidden"
3813
+ className: "min-h-14 border-secondary-light flex w-full items-center overflow-hidden border-b p-2.5 text-lg"
3605
3814
  }, /*#__PURE__*/react.createElement("div", {
3606
- className: "flex flex-col gap-1 self-top w-0 grow shrink"
3815
+ className: "self-top flex w-0 shrink grow flex-col gap-1"
3607
3816
  }, /*#__PURE__*/react.createElement("div", {
3608
3817
  className: "flex gap-4"
3609
3818
  }, /*#__PURE__*/react.createElement("div", {
3610
- className: "flex w-6 justify-center items-center shrink-0"
3819
+ className: "flex w-6 shrink-0 items-center justify-center"
3611
3820
  }, getStatusIcon()), /*#__PURE__*/react.createElement("div", {
3612
- className: "text-ellipsis whitespace-nowrap overflow-hidden"
3821
+ className: "overflow-hidden text-ellipsis whitespace-nowrap"
3613
3822
  }, dicomFileUploader.getFileName())), failedReason && /*#__PURE__*/react.createElement("div", {
3614
3823
  className: "pl-10"
3615
3824
  }, failedReason)), /*#__PURE__*/react.createElement("div", {
3616
- className: "w-24 flex items-center"
3825
+ className: "flex w-24 items-center"
3617
3826
  }, !isComplete() && /*#__PURE__*/react.createElement(react.Fragment, null, dicomFileUploader.getStatus() === UploadStatus.InProgress && /*#__PURE__*/react.createElement("div", {
3618
3827
  className: "w-10 text-right"
3619
3828
  }, percentComplete, "%"), /*#__PURE__*/react.createElement("div", {
3620
- className: "flex cursor-pointer ml-auto"
3829
+ className: "ml-auto flex cursor-pointer"
3621
3830
  }, /*#__PURE__*/react.createElement(ui_src/* Icon */.JO, {
3622
- className: "self-center text-primary-active",
3831
+ className: "text-primary-active self-center",
3623
3832
  name: "close",
3624
3833
  onClick: cancelUpload
3625
3834
  })))));
@@ -3846,7 +4055,7 @@ function DicomUploadProgress(_ref) {
3846
4055
  }, []);
3847
4056
  const getNumCompletedAndTimeRemainingComponent = () => {
3848
4057
  return /*#__PURE__*/react.createElement("div", {
3849
- className: "text-lg px-1 pb-4 h-14 flex bg-primary-dark items-center"
4058
+ className: "bg-primary-dark flex h-14 items-center px-1 pb-4 text-lg"
3850
4059
  }, numFilesCompleted === dicomFileUploaderArr.length ? /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("span", {
3851
4060
  className: NO_WRAP_ELLIPSIS_CLASS_NAMES
3852
4061
  }, `${dicomFileUploaderArr.length} ${dicomFileUploaderArr.length > 1 ? 'files' : 'file'} completed.`), /*#__PURE__*/react.createElement(ui_src/* Button */.zx, {
@@ -3861,13 +4070,13 @@ function DicomUploadProgress(_ref) {
3861
4070
  }, ' files completed.', "\xA0"), /*#__PURE__*/react.createElement("span", {
3862
4071
  className: NO_WRAP_ELLIPSIS_CLASS_NAMES
3863
4072
  }, timeRemaining ? `Less than ${getFormattedTimeRemaining()} remaining. ` : ''), /*#__PURE__*/react.createElement("span", {
3864
- className: classnames_default()(NO_WRAP_ELLIPSIS_CLASS_NAMES, 'cursor-pointer text-primary-active hover:text-primary-light active:text-aqua-pale ml-auto'),
4073
+ className: classnames_default()(NO_WRAP_ELLIPSIS_CLASS_NAMES, 'text-primary-active hover:text-primary-light active:text-aqua-pale ml-auto cursor-pointer'),
3865
4074
  onClick: cancelAllUploads
3866
4075
  }, "Cancel All Uploads")));
3867
4076
  };
3868
4077
  const getShowFailedOnlyIconComponent = () => {
3869
4078
  return /*#__PURE__*/react.createElement("div", {
3870
- className: "ml-auto flex justify-center w-6"
4079
+ className: "ml-auto flex w-6 justify-center"
3871
4080
  }, numFails > 0 && /*#__PURE__*/react.createElement("div", {
3872
4081
  onClick: () => setShowFailedOnly(currentShowFailedOnly => !currentShowFailedOnly)
3873
4082
  }, /*#__PURE__*/react.createElement(ui_src/* Icon */.JO, {
@@ -3877,28 +4086,28 @@ function DicomUploadProgress(_ref) {
3877
4086
  };
3878
4087
  const getPercentCompleteComponent = () => {
3879
4088
  return /*#__PURE__*/react.createElement("div", {
3880
- className: "overflow-y-scroll ohif-scrollbar px-2 border-b border-secondary-light"
4089
+ className: "ohif-scrollbar border-secondary-light overflow-y-scroll border-b px-2"
3881
4090
  }, /*#__PURE__*/react.createElement("div", {
3882
- className: "flex w-full p-2.5 items-center min-h-14"
4091
+ className: "min-h-14 flex w-full items-center p-2.5"
3883
4092
  }, numFilesCompleted === dicomFileUploaderArr.length ? /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("div", {
3884
- className: "text-xl text-primary-light"
4093
+ className: "text-primary-light text-xl"
3885
4094
  }, numFails > 0 ? `Completed with ${numFails} ${numFails > 1 ? 'errors' : 'error'}!` : 'Completed!'), getShowFailedOnlyIconComponent()) : /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("div", {
3886
4095
  ref: progressBarContainerRef,
3887
4096
  className: "flex-grow"
3888
4097
  }, /*#__PURE__*/react.createElement(ui_src/* ProgressLoadingBar */.YE, {
3889
4098
  progress: showInfiniteProgressBar() ? undefined : Math.min(100, percentComplete)
3890
4099
  })), /*#__PURE__*/react.createElement("div", {
3891
- className: "w-24 ml-1 flex items-center"
4100
+ className: "ml-1 flex w-24 items-center"
3892
4101
  }, /*#__PURE__*/react.createElement("div", {
3893
4102
  className: "w-10 text-right"
3894
4103
  }, `${getPercentCompleteRounded()}%`), getShowFailedOnlyIconComponent()))));
3895
4104
  };
3896
4105
  return /*#__PURE__*/react.createElement("div", {
3897
- className: "flex flex-col grow"
4106
+ className: "flex grow flex-col"
3898
4107
  }, getNumCompletedAndTimeRemainingComponent(), /*#__PURE__*/react.createElement("div", {
3899
- className: "flex flex-col bg-black text-lg overflow-hidden grow"
4108
+ className: "flex grow flex-col overflow-hidden bg-black text-lg"
3900
4109
  }, getPercentCompleteComponent(), /*#__PURE__*/react.createElement("div", {
3901
- className: "overflow-y-scroll ohif-scrollbar px-2 grow h-1"
4110
+ className: "ohif-scrollbar h-1 grow overflow-y-scroll px-2"
3902
4111
  }, dicomFileUploaderArr.filter(dicomFileUploader => !showFailedOnly || dicomFileUploader.getStatus() === UploadStatus.Failed).map(dicomFileUploader => /*#__PURE__*/react.createElement(DicomUpload_DicomUploadProgressItem, {
3903
4112
  key: dicomFileUploader.getFileId(),
3904
4113
  dicomFileUploader: dicomFileUploader
@@ -3945,7 +4154,7 @@ function DicomUpload(_ref) {
3945
4154
  getRootProps
3946
4155
  } = _ref2;
3947
4156
  return /*#__PURE__*/react.createElement("div", _extends({}, getRootProps(), {
3948
- className: "m-5 dicom-upload-drop-area-border-dash flex flex-col items-center justify-center h-full"
4157
+ className: "dicom-upload-drop-area-border-dash m-5 flex h-full flex-col items-center justify-center"
3949
4158
  }), /*#__PURE__*/react.createElement("div", {
3950
4159
  className: "flex gap-3"
3951
4160
  }, /*#__PURE__*/react.createElement(es/* default */.Z, {
@@ -3979,7 +4188,7 @@ function DicomUpload(_ref) {
3979
4188
  })), /*#__PURE__*/react.createElement("div", {
3980
4189
  className: "pt-5"
3981
4190
  }, "or drag images or folders here"), /*#__PURE__*/react.createElement("div", {
3982
- className: "pt-3 text-aqua-pale text-lg"
4191
+ className: "text-aqua-pale pt-3 text-lg"
3983
4192
  }, "(DICOM files supported)"));
3984
4193
  });
3985
4194
  };
@@ -4043,7 +4252,7 @@ function getCustomizationModule() {
4043
4252
  }
4044
4253
  /* harmony default export */ const src_getCustomizationModule = (getCustomizationModule);
4045
4254
  // EXTERNAL MODULE: ../../../node_modules/html2canvas/dist/html2canvas.esm.js
4046
- var html2canvas_esm = __webpack_require__(63691);
4255
+ var html2canvas_esm = __webpack_require__(76010);
4047
4256
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/CornerstoneViewportDownloadForm.tsx
4048
4257
 
4049
4258
 
@@ -4059,10 +4268,10 @@ const VIEWPORT_ID = 'cornerstone-viewport-download-form';
4059
4268
  const CornerstoneViewportDownloadForm = _ref => {
4060
4269
  let {
4061
4270
  onClose,
4062
- activeViewportIndex,
4271
+ activeViewportId: activeViewportIdProp,
4063
4272
  cornerstoneViewportService
4064
4273
  } = _ref;
4065
- const enabledElement = (0,state/* getEnabledElement */.K8)(activeViewportIndex);
4274
+ const enabledElement = (0,state/* getEnabledElement */.K8)(activeViewportIdProp);
4066
4275
  const activeViewportElement = enabledElement?.element;
4067
4276
  const activeViewportEnabledElement = (0,esm.getEnabledElement)(activeViewportElement);
4068
4277
  const {
@@ -4264,7 +4473,7 @@ const CornerstoneViewportDownloadForm = _ref => {
4264
4473
  };
4265
4474
  CornerstoneViewportDownloadForm.propTypes = {
4266
4475
  onClose: (prop_types_default()).func,
4267
- activeViewportIndex: (prop_types_default()).number.isRequired
4476
+ activeViewportId: (prop_types_default()).string.isRequired
4268
4477
  };
4269
4478
  /* harmony default export */ const utils_CornerstoneViewportDownloadForm = (CornerstoneViewportDownloadForm);
4270
4479
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/stackSync/calculateViewportRegistrations.ts
@@ -4294,7 +4503,7 @@ const _getViewportPairs = viewports => {
4294
4503
 
4295
4504
  // [ {
4296
4505
  // synchronizerId: string,
4297
- // viewports: [ { viewportId: number, renderingEngineId: string, index: number } , ...]
4506
+ // viewports: [ { viewportId: string, renderingEngineId: string, index: number } , ...]
4298
4507
  // ]}
4299
4508
  let STACK_IMAGE_SYNC_GROUPS_INFO = [];
4300
4509
  function toggleStackImageSync(_ref) {
@@ -4328,27 +4537,23 @@ function toggleStackImageSync(_ref) {
4328
4537
  STACK_IMAGE_SYNC_GROUPS_INFO = [];
4329
4538
 
4330
4539
  // create synchronization groups and add viewports
4331
- let {
4540
+ const {
4332
4541
  viewports
4333
4542
  } = viewportGridService.getState();
4334
4543
 
4335
4544
  // filter empty viewports
4336
- viewports = viewports.filter(viewport => viewport.displaySetInstanceUIDs && viewport.displaySetInstanceUIDs.length);
4337
-
4545
+ const viewportsArray = Array.from(viewports.values()).filter(viewport => viewport.displaySetInstanceUIDs?.length)
4338
4546
  // filter reconstructable viewports
4339
- viewports = viewports.filter(viewport => {
4547
+ .filter(viewport => {
4340
4548
  const {
4341
4549
  displaySetInstanceUIDs
4342
4550
  } = viewport;
4343
4551
  for (const displaySetInstanceUID of displaySetInstanceUIDs) {
4344
4552
  const displaySet = displaySetService.getDisplaySetByUID(displaySetInstanceUID);
4345
- if (displaySet && displaySet.isReconstructable) {
4346
- return true;
4347
- }
4348
- return false;
4553
+ return !!displaySet?.isReconstructable;
4349
4554
  }
4350
4555
  });
4351
- const viewportsByOrientation = viewports.reduce((acc, viewport) => {
4556
+ const viewportsByOrientation = viewportsArray.reduce((acc, viewport) => {
4352
4557
  const {
4353
4558
  viewportId,
4354
4559
  viewportType
@@ -4457,6 +4662,7 @@ function commandsModule(_ref) {
4457
4662
  toolGroupService,
4458
4663
  cineService,
4459
4664
  toolbarService,
4665
+ stateSyncService,
4460
4666
  uiDialogService,
4461
4667
  cornerstoneViewportService,
4462
4668
  uiNotificationService,
@@ -4650,8 +4856,7 @@ function commandsModule(_ref) {
4650
4856
  console.warn('No viewport found for viewportId:', viewportId);
4651
4857
  return;
4652
4858
  }
4653
- const viewportIndex = viewportInfo.getViewportIndex();
4654
- viewportGridService.setActiveViewportIndex(viewportIndex);
4859
+ viewportGridService.setActiveViewportId(viewportId);
4655
4860
  },
4656
4861
  arrowTextCallback: _ref7 => {
4657
4862
  let {
@@ -4719,7 +4924,8 @@ function commandsModule(_ref) {
4719
4924
  setToolActive: _ref9 => {
4720
4925
  let {
4721
4926
  toolName,
4722
- toolGroupId = null
4927
+ toolGroupId = null,
4928
+ toggledState
4723
4929
  } = _ref9;
4724
4930
  if (toolName === 'Crosshairs') {
4725
4931
  const activeViewportToolGroup = toolGroupService.getToolGroup(null);
@@ -4735,9 +4941,10 @@ function commandsModule(_ref) {
4735
4941
  }
4736
4942
  const {
4737
4943
  viewports
4738
- } = viewportGridService.getState() || {
4739
- viewports: []
4740
- };
4944
+ } = viewportGridService.getState();
4945
+ if (!viewports.size) {
4946
+ return;
4947
+ }
4741
4948
  const toolGroup = toolGroupService.getToolGroup(toolGroupId);
4742
4949
  const toolGroupViewportIds = toolGroup?.getViewportIds?.();
4743
4950
 
@@ -4745,11 +4952,8 @@ function commandsModule(_ref) {
4745
4952
  if (!toolGroupViewportIds || !toolGroupViewportIds.length) {
4746
4953
  return;
4747
4954
  }
4748
- const filteredViewports = viewports.filter(viewport => {
4749
- if (!viewport.viewportOptions) {
4750
- return false;
4751
- }
4752
- return toolGroupViewportIds.includes(viewport.viewportOptions.viewportId);
4955
+ const filteredViewports = Array.from(viewports.values()).filter(viewport => {
4956
+ return toolGroupViewportIds.includes(viewport.viewportId);
4753
4957
  });
4754
4958
  if (!filteredViewports.length) {
4755
4959
  return;
@@ -4773,6 +4977,14 @@ function commandsModule(_ref) {
4773
4977
  toolGroup.setToolPassive(activeToolName);
4774
4978
  }
4775
4979
  }
4980
+
4981
+ // If there is a toggle state, then simply set the enabled/disabled state without
4982
+ // setting the tool active.
4983
+ if (toggledState != null) {
4984
+ toggledState ? toolGroup.setToolEnabled(toolName) : toolGroup.setToolDisabled(toolName);
4985
+ return;
4986
+ }
4987
+
4776
4988
  // Set the new toolName to be active
4777
4989
  toolGroup.setToolActive(toolName, {
4778
4990
  bindings: [{
@@ -4782,9 +4994,9 @@ function commandsModule(_ref) {
4782
4994
  },
4783
4995
  showDownloadViewportModal: () => {
4784
4996
  const {
4785
- activeViewportIndex
4997
+ activeViewportId
4786
4998
  } = viewportGridService.getState();
4787
- if (!cornerstoneViewportService.getCornerstoneViewportByIndex(activeViewportIndex)) {
4999
+ if (!cornerstoneViewportService.getCornerstoneViewport(activeViewportId)) {
4788
5000
  // Cannot download a non-cornerstone viewport (image).
4789
5001
  uiNotificationService.show({
4790
5002
  title: 'Download Image',
@@ -4801,7 +5013,7 @@ function commandsModule(_ref) {
4801
5013
  content: utils_CornerstoneViewportDownloadForm,
4802
5014
  title: 'Download High Quality Image',
4803
5015
  contentProps: {
4804
- activeViewportIndex,
5016
+ activeViewportId,
4805
5017
  onClose: uiModalService.hide,
4806
5018
  cornerstoneViewportService
4807
5019
  }
@@ -4882,15 +5094,13 @@ function commandsModule(_ref) {
4882
5094
  const {
4883
5095
  viewport
4884
5096
  } = enabledElement;
4885
- if (viewport instanceof esm.StackViewport) {
4886
- const {
4887
- invert
4888
- } = viewport.getProperties();
4889
- viewport.setProperties({
4890
- invert: !invert
4891
- });
4892
- viewport.render();
4893
- }
5097
+ const {
5098
+ invert
5099
+ } = viewport.getProperties();
5100
+ viewport.setProperties({
5101
+ invert: !invert
5102
+ });
5103
+ viewport.render();
4894
5104
  },
4895
5105
  resetViewport: () => {
4896
5106
  const enabledElement = _getActiveViewportEnabledElement();
@@ -4993,12 +5203,12 @@ function commandsModule(_ref) {
4993
5203
  },
4994
5204
  setViewportColormap: _ref15 => {
4995
5205
  let {
4996
- viewportIndex,
5206
+ viewportId,
4997
5207
  displaySetInstanceUID,
4998
5208
  colormap,
4999
5209
  immediate = false
5000
5210
  } = _ref15;
5001
- const viewport = cornerstoneViewportService.getCornerstoneViewportByIndex(viewportIndex);
5211
+ const viewport = cornerstoneViewportService.getCornerstoneViewport(viewportId);
5002
5212
  const actorEntries = viewport.getActors();
5003
5213
  const actorEntry = actorEntries.find(actorEntry => {
5004
5214
  return actorEntry.uid.includes(displaySetInstanceUID);
@@ -5015,51 +5225,52 @@ function commandsModule(_ref) {
5015
5225
  viewport.render();
5016
5226
  }
5017
5227
  },
5018
- incrementActiveViewport: () => {
5019
- const {
5020
- activeViewportIndex,
5021
- viewports
5022
- } = viewportGridService.getState();
5023
- const nextViewportIndex = (activeViewportIndex + 1) % viewports.length;
5024
- viewportGridService.setActiveViewportIndex(nextViewportIndex);
5025
- },
5026
- decrementActiveViewport: () => {
5228
+ changeActiveViewport: _ref16 => {
5229
+ let {
5230
+ direction = 1
5231
+ } = _ref16;
5027
5232
  const {
5028
- activeViewportIndex,
5233
+ activeViewportId,
5029
5234
  viewports
5030
5235
  } = viewportGridService.getState();
5031
- const nextViewportIndex = (activeViewportIndex - 1 + viewports.length) % viewports.length;
5032
- viewportGridService.setActiveViewportIndex(nextViewportIndex);
5236
+ const viewportIds = Array.from(viewports.keys());
5237
+ const currentIndex = viewportIds.indexOf(activeViewportId);
5238
+ const nextViewportIndex = (currentIndex + direction + viewportIds.length) % viewportIds.length;
5239
+ viewportGridService.setActiveViewportId(viewportIds[nextViewportIndex]);
5033
5240
  },
5034
- toggleStackImageSync: _ref16 => {
5241
+ toggleStackImageSync: _ref17 => {
5035
5242
  let {
5036
5243
  toggledState
5037
- } = _ref16;
5244
+ } = _ref17;
5038
5245
  toggleStackImageSync({
5039
5246
  getEnabledElement: esm.getEnabledElement,
5040
5247
  servicesManager,
5041
5248
  toggledState
5042
5249
  });
5043
5250
  },
5044
- toggleReferenceLines: _ref17 => {
5251
+ setSourceViewportForReferenceLinesTool: _ref18 => {
5045
5252
  let {
5046
5253
  toggledState
5047
- } = _ref17;
5254
+ } = _ref18;
5048
5255
  const {
5049
- activeViewportIndex
5256
+ activeViewportId
5050
5257
  } = viewportGridService.getState();
5051
- const viewportInfo = cornerstoneViewportService.getViewportInfoByIndex(activeViewportIndex);
5258
+ const viewportInfo = cornerstoneViewportService.getViewportInfo(activeViewportId);
5052
5259
  const viewportId = viewportInfo.getViewportId();
5053
5260
  const toolGroup = toolGroupService.getToolGroupForViewport(viewportId);
5054
- if (!toggledState) {
5055
- toolGroup.setToolDisabled(dist_esm.ReferenceLinesTool.toolName);
5056
- }
5057
5261
  toolGroup.setToolConfiguration(dist_esm.ReferenceLinesTool.toolName, {
5058
5262
  sourceViewportId: viewportId
5059
5263
  }, true // overwrite
5060
5264
  );
5265
+ },
5061
5266
 
5062
- toolGroup.setToolEnabled(dist_esm.ReferenceLinesTool.toolName);
5267
+ storePresentation: _ref19 => {
5268
+ let {
5269
+ viewportId
5270
+ } = _ref19;
5271
+ cornerstoneViewportService.storePresentation({
5272
+ viewportId
5273
+ });
5063
5274
  }
5064
5275
  };
5065
5276
  const definitions = {
@@ -5114,10 +5325,13 @@ function commandsModule(_ref) {
5114
5325
  }
5115
5326
  },
5116
5327
  incrementActiveViewport: {
5117
- commandFn: actions.incrementActiveViewport
5328
+ commandFn: actions.changeActiveViewport
5118
5329
  },
5119
5330
  decrementActiveViewport: {
5120
- commandFn: actions.decrementActiveViewport
5331
+ commandFn: actions.changeActiveViewport,
5332
+ options: {
5333
+ direction: -1
5334
+ }
5121
5335
  },
5122
5336
  flipViewportHorizontal: {
5123
5337
  commandFn: actions.flipViewportHorizontal
@@ -5194,8 +5408,13 @@ function commandsModule(_ref) {
5194
5408
  toggleStackImageSync: {
5195
5409
  commandFn: actions.toggleStackImageSync
5196
5410
  },
5197
- toggleReferenceLines: {
5198
- commandFn: actions.toggleReferenceLines
5411
+ setSourceViewportForReferenceLinesTool: {
5412
+ commandFn: actions.setSourceViewportForReferenceLinesTool
5413
+ },
5414
+ storePresentation: {
5415
+ commandFn: actions.storePresentation,
5416
+ storeContexts: [],
5417
+ options: {}
5199
5418
  }
5200
5419
  };
5201
5420
  return {
@@ -5210,9 +5429,8 @@ const mpr = {
5210
5429
  id: 'mpr',
5211
5430
  name: 'Multi-Planar Reconstruction',
5212
5431
  locked: true,
5213
- hasUpdatedPriorsInformation: false,
5214
5432
  createdDate: '2021-02-23',
5215
- modifiedDate: '2023-04-03',
5433
+ modifiedDate: '2023-08-15',
5216
5434
  availableTo: {},
5217
5435
  editableBy: {},
5218
5436
  // Unknown number of priors referenced - so just match any study
@@ -5283,6 +5501,7 @@ const mpr = {
5283
5501
  },
5284
5502
  viewports: [{
5285
5503
  viewportOptions: {
5504
+ viewportId: 'mpr-axial',
5286
5505
  toolGroupId: 'mpr',
5287
5506
  viewportType: 'volume',
5288
5507
  orientation: 'axial',
@@ -5301,6 +5520,7 @@ const mpr = {
5301
5520
  }]
5302
5521
  }, {
5303
5522
  viewportOptions: {
5523
+ viewportId: 'mpr-sagittal',
5304
5524
  toolGroupId: 'mpr',
5305
5525
  viewportType: 'volume',
5306
5526
  orientation: 'sagittal',
@@ -5319,6 +5539,7 @@ const mpr = {
5319
5539
  }]
5320
5540
  }, {
5321
5541
  viewportOptions: {
5542
+ viewportId: 'mpr-coronal',
5322
5543
  toolGroupId: 'mpr',
5323
5544
  viewportType: 'volume',
5324
5545
  orientation: 'coronal',
@@ -5341,7 +5562,6 @@ const mpr = {
5341
5562
  const mprAnd3DVolumeViewport = {
5342
5563
  id: 'mprAnd3DVolumeViewport',
5343
5564
  locked: true,
5344
- hasUpdatedPriorsInformation: false,
5345
5565
  name: 'mpr',
5346
5566
  createdDate: '2023-03-15T10:29:44.894Z',
5347
5567
  modifiedDate: '2023-03-15T10:29:44.894Z',
@@ -5789,7 +6009,7 @@ class SyncGroupService {
5789
6009
  * @param type is the type of the synchronizer to create
5790
6010
  * @param creator
5791
6011
  */
5792
- setSynchronizer(type, creator) {
6012
+ addSynchronizerType(type, creator) {
5793
6013
  this.synchronizerCreators[type.toLowerCase()] = creator;
5794
6014
  }
5795
6015
  _getOrCreateSynchronizer(type, id, options) {
@@ -5867,10 +6087,10 @@ SyncGroupService.REGISTRATION = {
5867
6087
 
5868
6088
  /* harmony default export */ const services_SyncGroupService = (SyncGroupService);
5869
6089
  // EXTERNAL MODULE: ../../../node_modules/lodash.clonedeep/index.js
5870
- var lodash_clonedeep = __webpack_require__(71975);
6090
+ var lodash_clonedeep = __webpack_require__(11677);
5871
6091
  var lodash_clonedeep_default = /*#__PURE__*/__webpack_require__.n(lodash_clonedeep);
5872
6092
  // EXTERNAL MODULE: ../../../node_modules/lodash.isequal/index.js
5873
- var lodash_isequal = __webpack_require__(68652);
6093
+ var lodash_isequal = __webpack_require__(10311);
5874
6094
  var lodash_isequal_default = /*#__PURE__*/__webpack_require__.n(lodash_isequal);
5875
6095
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/transitions.ts
5876
6096
  /**
@@ -6152,6 +6372,7 @@ class SegmentationService extends src/* PubSubService */.hC {
6152
6372
  if (!segmentation) {
6153
6373
  throw new Error(`Segmentation with segmentationId ${segmentationId} not found.`);
6154
6374
  }
6375
+ _this._setDisplaySetIsHydrated(segmentationId, true);
6155
6376
  segmentation.hydrated = true;
6156
6377
  if (!suppressEvents) {
6157
6378
  _this._broadcastEvent(_this.EVENTS.SEGMENTATION_UPDATED, {
@@ -6715,6 +6936,7 @@ class SegmentationService extends src/* PubSubService */.hC {
6715
6936
  id: segmentationId,
6716
6937
  displaySetInstanceUID: segDisplaySet.displaySetInstanceUID,
6717
6938
  type: representationType,
6939
+ label: segDisplaySet.SeriesDescription,
6718
6940
  representationData: {
6719
6941
  [LABELMAP]: {
6720
6942
  volumeId: segmentationId,
@@ -6731,11 +6953,11 @@ class SegmentationService extends src/* PubSubService */.hC {
6731
6953
  return this.addOrUpdateSegmentation(Object.assign(segmentation, cachedSegmentation), suppressEvents);
6732
6954
  }
6733
6955
  const {
6734
- segments,
6956
+ labelmapBufferArray,
6735
6957
  referencedVolumeId
6736
6958
  } = segDisplaySet;
6737
- if (!segments || !referencedVolumeId) {
6738
- throw new Error('To create the segmentation from SEG displaySet, the displaySet should be loaded first, you can perform segDisplaySet.load() before calling this method.');
6959
+ if (!labelmapBufferArray || !referencedVolumeId) {
6960
+ throw new Error('No labelmapBufferArray or referencedVolumeId found for the SEG displaySet');
6739
6961
  }
6740
6962
 
6741
6963
  // if the labelmap doesn't exist, we need to create it first from the
@@ -6754,72 +6976,27 @@ class SegmentationService extends src/* PubSubService */.hC {
6754
6976
  sharedArrayBuffer: true
6755
6977
  }
6756
6978
  });
6757
- const [rows, columns] = derivedVolume.dimensions;
6758
6979
  const derivedVolumeScalarData = derivedVolume.getScalarData();
6759
- const {
6760
- imageIds
6761
- } = referencedVolume;
6762
- const sopUIDImageIdIndexMap = imageIds.reduce((acc, imageId, index) => {
6763
- const {
6764
- sopInstanceUid
6765
- } = esm.metaData.get('generalImageModule', imageId);
6766
- acc[sopInstanceUid] = index;
6767
- return acc;
6768
- }, {});
6769
- const numSegments = Object.keys(segments).length;
6770
- // Note: ideally we could use the TypedArray set method, but since each
6771
- // slice can have multiple segments, we need to loop over each slice and
6772
- // set the segment value for each segment.
6773
- let overlappingSegments = false;
6774
- const _segmentInfoUpdate = (segmentInfo, segmentIndex) => {
6980
+ const segmentsInfo = segDisplaySet.segMetadata.data;
6981
+ derivedVolumeScalarData.set(new Uint8Array(labelmapBufferArray[0]));
6982
+ segmentation.segments = segmentsInfo.map((segmentInfo, segmentIndex) => {
6983
+ if (segmentIndex === 0) {
6984
+ return;
6985
+ }
6775
6986
  const {
6776
- pixelData: segPixelData
6987
+ SegmentedPropertyCategoryCodeSequence,
6988
+ SegmentNumber,
6989
+ SegmentLabel,
6990
+ SegmentAlgorithmType,
6991
+ SegmentAlgorithmName,
6992
+ SegmentedPropertyTypeCodeSequence,
6993
+ rgba
6777
6994
  } = segmentInfo;
6778
- let segmentX = 0;
6779
- let segmentY = 0;
6780
- let segmentZ = 0;
6781
- let count = 0;
6782
- for (const [functionalGroupIndex, functionalGroup] of segmentInfo.functionalGroups.entries()) {
6783
- const {
6784
- ReferencedSOPInstanceUID
6785
- } = functionalGroup.DerivationImageSequence.SourceImageSequence;
6786
- const imageIdIndex = sopUIDImageIdIndexMap[ReferencedSOPInstanceUID];
6787
- if (imageIdIndex === -1) {
6788
- return;
6789
- }
6790
- const step = rows * columns;
6791
-
6792
- // we need a faster way to get the pixel data for the current
6793
- // functional group, which we use typed array view
6794
-
6795
- const functionGroupPixelData = new Uint8Array(segPixelData.buffer, functionalGroupIndex * step, step);
6796
- const functionalGroupStartIndex = imageIdIndex * step;
6797
- const functionalGroupEndIndex = (imageIdIndex + 1) * step;
6798
-
6799
- // Note: this for loop is not optimized, since DICOM SEG stores
6800
- // each segment as a separate labelmap so if there is a slice
6801
- // that has multiple segments, we will have to loop over each
6802
- // segment and we cannot use the TypedArray set method.
6803
- for (let i = functionalGroupStartIndex, j = 0; i < functionalGroupEndIndex; i++, j++) {
6804
- if (functionGroupPixelData[j] !== 0) {
6805
- if (derivedVolumeScalarData[i] !== 0) {
6806
- overlappingSegments = true;
6807
- }
6808
- derivedVolumeScalarData[i] = segmentIndex;
6809
-
6810
- // centroid calculations
6811
- segmentX += i % columns;
6812
- segmentY += Math.floor(i / columns) % rows;
6813
- segmentZ += Math.floor(i / (columns * rows));
6814
- count++;
6815
- }
6816
- }
6817
- }
6818
-
6819
- // centroid calculations
6820
- const x = Math.floor(segmentX / count);
6821
- const y = Math.floor(segmentY / count);
6822
- const z = Math.floor(segmentZ / count);
6995
+ const {
6996
+ x,
6997
+ y,
6998
+ z
6999
+ } = segDisplaySet.centroids.get(segmentIndex);
6823
7000
  const centerWorld = derivedVolume.imageData.indexToWorld([x, y, z]);
6824
7001
  segmentation.cachedStats = {
6825
7002
  ...segmentation.cachedStats,
@@ -6834,51 +7011,24 @@ class SegmentationService extends src/* PubSubService */.hC {
6834
7011
  }
6835
7012
  }
6836
7013
  };
6837
- const numInitialized = Object.keys(segmentation.cachedStats.segmentCenter).length;
6838
-
6839
- // Calculate percentage completed
6840
- const percentComplete = Math.round(numInitialized / numSegments * 100);
6841
- this._broadcastEvent(SegmentationService_EVENTS.SEGMENT_LOADING_COMPLETE, {
6842
- percentComplete,
6843
- numSegments: numSegments
6844
- });
6845
- };
6846
- const promiseArray = [];
6847
- for (const segmentIndex in segments) {
6848
- const segmentInfo = segments[segmentIndex];
6849
-
6850
- // Important: we need a non-blocking way to update the segmentation
6851
- // state, otherwise the UI will freeze and the user will not be able
6852
- // to interact with the app or progress bars will not be updated.
6853
- const promise = new Promise((resolve, reject) => {
6854
- setTimeout(() => {
6855
- _segmentInfoUpdate(segmentInfo, segmentIndex);
6856
- resolve();
6857
- }, 0);
6858
- });
6859
- promiseArray.push(promise);
6860
- }
6861
- await Promise.all(promiseArray);
6862
- segmentation.segmentCount = Object.keys(segments).length;
6863
- segmentation.segments = [null]; // segment 0
6864
-
6865
- Object.keys(segments).forEach(segmentIndex => {
6866
- const segmentInfo = segments[segmentIndex];
6867
- const segIndex = Number(segmentIndex);
6868
- segmentation.segments[segIndex] = {
6869
- label: segmentInfo.label || `Segment ${segIndex}`,
6870
- segmentIndex: Number(segmentIndex),
6871
- color: [segmentInfo.color[0], segmentInfo.color[1], segmentInfo.color[2]],
6872
- opacity: segmentInfo.color[3],
7014
+ return {
7015
+ label: SegmentLabel || `Segment ${SegmentNumber}`,
7016
+ segmentIndex: Number(SegmentNumber),
7017
+ category: SegmentedPropertyCategoryCodeSequence ? SegmentedPropertyCategoryCodeSequence.CodeMeaning : '',
7018
+ type: SegmentedPropertyTypeCodeSequence ? SegmentedPropertyTypeCodeSequence.CodeMeaning : '',
7019
+ algorithmType: SegmentAlgorithmType,
7020
+ algorithmName: SegmentAlgorithmName,
7021
+ color: rgba,
7022
+ opacity: 255,
6873
7023
  isVisible: true,
6874
7024
  isLocked: false
6875
7025
  };
6876
7026
  });
7027
+ segmentation.segmentCount = segmentsInfo.length - 1;
6877
7028
  segDisplaySet.isLoaded = true;
6878
7029
  this._broadcastEvent(SegmentationService_EVENTS.SEGMENTATION_LOADING_COMPLETE, {
6879
7030
  segmentationId,
6880
- segDisplaySet,
6881
- overlappingSegments
7031
+ segDisplaySet
6882
7032
  });
6883
7033
  return this.addOrUpdateSegmentation(segmentation, suppressEvents);
6884
7034
  }
@@ -6911,6 +7061,7 @@ class SegmentationService extends src/* PubSubService */.hC {
6911
7061
  id: segmentationId,
6912
7062
  displaySetInstanceUID: rtDisplaySetUID,
6913
7063
  type: representationType,
7064
+ label: rtDisplaySet.SeriesDescription,
6914
7065
  representationData: {
6915
7066
  [CONTOUR]: {
6916
7067
  geometryIds
@@ -7068,6 +7219,14 @@ class SegmentationService extends src/* PubSubService */.hC {
7068
7219
  const adjustedAlpha = type === LABELMAP ? alpha : 1 - alpha;
7069
7220
  highlightFn(segmentIndex, adjustedAlpha, hideOthers, segments, toolGroupId, animationLength, segmentationRepresentation);
7070
7221
  }
7222
+ _setDisplaySetIsHydrated(displaySetUID, isHydrated) {
7223
+ const {
7224
+ DisplaySetService: displaySetService
7225
+ } = this.servicesManager.services;
7226
+ const displaySet = displaySetService.getDisplaySetByUID(displaySetUID);
7227
+ displaySet.isHydrated = isHydrated;
7228
+ displaySetService.setDisplaySetMetadataInvalidated(displaySetUID, false);
7229
+ }
7071
7230
  _highlightLabelmap(segmentIndex, alpha, hideOthers, segments, toolGroupId, animationLength, segmentationRepresentation) {
7072
7231
  const newSegmentSpecificConfig = {
7073
7232
  [segmentIndex]: {
@@ -7177,6 +7336,7 @@ class SegmentationService extends src/* PubSubService */.hC {
7177
7336
  this._setActiveSegmentationForToolGroup(id, this._getFirstToolGroupId(), false);
7178
7337
  }
7179
7338
  }
7339
+ this._setDisplaySetIsHydrated(segmentationId, false);
7180
7340
  this._broadcastEvent(this.EVENTS.SEGMENTATION_REMOVED, {
7181
7341
  segmentationId
7182
7342
  });
@@ -7747,16 +7907,17 @@ const DEFAULT_TOOLGROUP_ID = 'default';
7747
7907
  // Return true if the data contains the given display set UID OR the imageId
7748
7908
  // if it is a composite object.
7749
7909
  const dataContains = (data, displaySetUID, imageId) => {
7750
- if (data.displaySetInstanceUID === displaySetUID) return true;
7910
+ if (data.displaySetInstanceUID === displaySetUID) {
7911
+ return true;
7912
+ }
7751
7913
  if (imageId && data.isCompositeStack && data.imageIds) {
7752
7914
  return !!data.imageIds.find(dataId => dataId === imageId);
7753
7915
  }
7754
7916
  return false;
7755
7917
  };
7756
7918
  class ViewportInfo {
7757
- constructor(viewportIndex, viewportId) {
7919
+ constructor(viewportId) {
7758
7920
  this.viewportId = '';
7759
- this.viewportIndex = void 0;
7760
7921
  this.element = void 0;
7761
7922
  this.viewportOptions = void 0;
7762
7923
  this.displaySetOptions = void 0;
@@ -7768,7 +7929,6 @@ class ViewportInfo {
7768
7929
  this.viewportOptions = null;
7769
7930
  this.displaySetOptions = null;
7770
7931
  };
7771
- this.viewportIndex = viewportIndex;
7772
7932
  this.viewportId = viewportId;
7773
7933
  this.setPublicViewportOptions({});
7774
7934
  this.setPublicDisplaySetOptions([{}]);
@@ -7779,7 +7939,9 @@ class ViewportInfo {
7779
7939
  * OR if it is a composite stack and contains the given imageId
7780
7940
  */
7781
7941
  contains(displaySetUID, imageId) {
7782
- if (!this.viewportData?.data) return false;
7942
+ if (!this.viewportData?.data) {
7943
+ return false;
7944
+ }
7783
7945
  if (this.viewportData.data.length) {
7784
7946
  return !!this.viewportData.data.find(data => dataContains(data, displaySetUID, imageId));
7785
7947
  }
@@ -7794,9 +7956,6 @@ class ViewportInfo {
7794
7956
  setViewportId(viewportId) {
7795
7957
  this.viewportId = viewportId;
7796
7958
  }
7797
- setViewportIndex(viewportIndex) {
7798
- this.viewportIndex = viewportIndex;
7799
- }
7800
7959
  setElement(element) {
7801
7960
  this.element = element;
7802
7961
  }
@@ -7806,9 +7965,6 @@ class ViewportInfo {
7806
7965
  getViewportData() {
7807
7966
  return this.viewportData;
7808
7967
  }
7809
- getViewportIndex() {
7810
- return this.viewportIndex;
7811
- }
7812
7968
  getElement() {
7813
7969
  return this.element;
7814
7970
  }
@@ -7819,13 +7975,14 @@ class ViewportInfo {
7819
7975
  // map the displaySetOptions and check if they are undefined then set them to default values
7820
7976
  const displaySetOptions = this.mapDisplaySetOptions(publicDisplaySetOptions);
7821
7977
  this.setDisplaySetOptions(displaySetOptions);
7978
+ return this.displaySetOptions;
7822
7979
  }
7823
7980
  hasDisplaySet(displaySetInstanceUID) {
7824
7981
  // Todo: currently this does not work for non image & referenceImage displaySets.
7825
7982
  // Since SEG and other derived displaySets are loaded in a different way, and not
7826
7983
  // via cornerstoneViewportService
7827
7984
  let viewportData = this.getViewportData();
7828
- if (viewportData.viewportType === esm.Enums.ViewportType.ORTHOGRAPHIC) {
7985
+ if (viewportData.viewportType === esm.Enums.ViewportType.ORTHOGRAPHIC || viewportData.viewportType === esm.Enums.ViewportType.VOLUME_3D) {
7829
7986
  viewportData = viewportData;
7830
7987
  return viewportData.data.some(_ref => {
7831
7988
  let {
@@ -7865,6 +8022,7 @@ class ViewportInfo {
7865
8022
  toolGroupId,
7866
8023
  presentationIds
7867
8024
  });
8025
+ return this.viewportOptions;
7868
8026
  }
7869
8027
  setViewportOptions(viewportOptions) {
7870
8028
  this.viewportOptions = viewportOptions;
@@ -7959,7 +8117,6 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
7959
8117
  constructor(servicesManager) {
7960
8118
  super(CornerstoneViewportService_EVENTS);
7961
8119
  this.renderingEngine = void 0;
7962
- this.viewportsInfo = new Map();
7963
8120
  this.viewportsById = new Map();
7964
8121
  this.viewportGridResizeObserver = void 0;
7965
8122
  this.viewportsDisplaySets = new Map();
@@ -7975,37 +8132,16 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
7975
8132
 
7976
8133
  /**
7977
8134
  * Adds the HTML element to the viewportService
7978
- * @param {*} viewportIndex
8135
+ * @param {*} viewportId
7979
8136
  * @param {*} elementRef
7980
8137
  */
7981
- enableViewport(viewportIndex, viewportOptions, elementRef) {
7982
- // Use the provided viewportId
7983
- // Not providing a viewportId is frowned upon because it does weird things
7984
- // on moving them around, but it does mostly work.
7985
- if (!viewportOptions.viewportId) {
7986
- console.warn('Should provide viewport id externally', viewportOptions);
7987
- viewportOptions.viewportId = this.getViewportId(viewportIndex) || `viewport-${viewportIndex}`;
7988
- }
7989
- const {
7990
- viewportId
7991
- } = viewportOptions;
7992
- const viewportInfo = new Viewport(viewportIndex, viewportId);
7993
- if (!viewportInfo.viewportId) {
7994
- throw new Error('Should have viewport ID afterwards');
7995
- }
8138
+ enableViewport(viewportId, elementRef) {
8139
+ const viewportInfo = new Viewport(viewportId);
7996
8140
  viewportInfo.setElement(elementRef);
7997
- this.viewportsInfo.set(viewportIndex, viewportInfo);
7998
8141
  this.viewportsById.set(viewportId, viewportInfo);
7999
8142
  }
8000
8143
  getViewportIds() {
8001
- const viewportIds = [];
8002
- this.viewportsInfo.forEach(viewportInfo => {
8003
- viewportIds.push(viewportInfo.getViewportId());
8004
- });
8005
- return viewportIds;
8006
- }
8007
- getViewportId(viewportIndex) {
8008
- return this.viewportsInfo[viewportIndex]?.viewportId;
8144
+ return Array.from(this.viewportsById.keys());
8009
8145
  }
8010
8146
 
8011
8147
  /**
@@ -8059,34 +8195,38 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
8059
8195
  * created for every new viewport, this will be called whenever the set of
8060
8196
  * viewports is changed, but NOT when the viewport position changes only.
8061
8197
  *
8062
- * @param viewportIndex
8198
+ * @param viewportId - The viewportId to disable
8063
8199
  */
8064
- disableElement(viewportIndex) {
8065
- const viewportInfo = this.viewportsInfo.get(viewportIndex);
8066
- if (!viewportInfo) {
8067
- return;
8068
- }
8069
- const viewportId = viewportInfo.getViewportId();
8070
- this.renderingEngine && this.renderingEngine.disableElement(viewportId);
8071
- this.viewportsInfo.get(viewportIndex).destroy();
8072
- this.viewportsInfo.delete(viewportIndex);
8200
+ disableElement(viewportId) {
8201
+ this.renderingEngine?.disableElement(viewportId);
8202
+
8203
+ // clean up
8073
8204
  this.viewportsById.delete(viewportId);
8205
+ this.viewportsDisplaySets.delete(viewportId);
8074
8206
  }
8075
8207
  setPresentations(viewport, presentations) {
8076
8208
  const properties = presentations?.lutPresentation?.properties;
8077
- if (properties) viewport.setProperties(properties);
8209
+ if (properties) {
8210
+ viewport.setProperties(properties);
8211
+ }
8078
8212
  const camera = presentations?.positionPresentation?.camera;
8079
- if (camera) viewport.setCamera(camera);
8213
+ if (camera) {
8214
+ viewport.setCamera(camera);
8215
+ }
8080
8216
  }
8081
- getPresentation(viewportIndex) {
8082
- const viewportInfo = this.viewportsInfo.get(viewportIndex);
8083
- if (!viewportInfo) return;
8217
+ getPresentation(viewportId) {
8218
+ const viewportInfo = this.viewportsById.get(viewportId);
8219
+ if (!viewportInfo) {
8220
+ return;
8221
+ }
8084
8222
  const {
8085
8223
  viewportType,
8086
8224
  presentationIds
8087
8225
  } = viewportInfo.getViewportOptions();
8088
- const csViewport = this.getCornerstoneViewportByIndex(viewportIndex);
8089
- if (!csViewport) return;
8226
+ const csViewport = this.getCornerstoneViewport(viewportId);
8227
+ if (!csViewport) {
8228
+ return;
8229
+ }
8090
8230
  const properties = csViewport.getProperties();
8091
8231
  if (properties.isComputedVOI) {
8092
8232
  delete properties.voiRange;
@@ -8102,40 +8242,78 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
8102
8242
  camera
8103
8243
  };
8104
8244
  }
8245
+ storePresentation(_ref) {
8246
+ let {
8247
+ viewportId
8248
+ } = _ref;
8249
+ const stateSyncService = this.servicesManager.services.stateSyncService;
8250
+ let presentation;
8251
+ try {
8252
+ presentation = this.getPresentation(viewportId);
8253
+ } catch (error) {
8254
+ console.warn(error);
8255
+ }
8256
+ if (!presentation || !presentation.presentationIds) {
8257
+ return;
8258
+ }
8259
+ const {
8260
+ lutPresentationStore,
8261
+ positionPresentationStore
8262
+ } = stateSyncService.getState();
8263
+ const {
8264
+ presentationIds
8265
+ } = presentation;
8266
+ const {
8267
+ lutPresentationId,
8268
+ positionPresentationId
8269
+ } = presentationIds || {};
8270
+ const storeState = {};
8271
+ if (lutPresentationId) {
8272
+ storeState.lutPresentationStore = {
8273
+ ...lutPresentationStore,
8274
+ [lutPresentationId]: presentation
8275
+ };
8276
+ }
8277
+ if (positionPresentationId) {
8278
+ storeState.positionPresentationStore = {
8279
+ ...positionPresentationStore,
8280
+ [positionPresentationId]: presentation
8281
+ };
8282
+ }
8283
+ stateSyncService.store(storeState);
8284
+ }
8105
8285
 
8106
8286
  /**
8107
- * Uses the renderingEngine to enable the element for the given viewport index
8108
- * and sets the displaySet data to the viewport
8109
- * @param {*} viewportIndex
8110
- * @param {*} displaySet
8111
- * @param {*} dataSource
8112
- * @returns
8287
+ * Sets the viewport data for a viewport.
8288
+ * @param viewportId - The ID of the viewport to set the data for.
8289
+ * @param viewportData - The viewport data to set.
8290
+ * @param publicViewportOptions - The public viewport options.
8291
+ * @param publicDisplaySetOptions - The public display set options.
8292
+ * @param presentations - The presentations to set.
8113
8293
  */
8114
- setViewportData(viewportIndex, viewportData, publicViewportOptions, publicDisplaySetOptions, presentations) {
8294
+ setViewportData(viewportId, viewportData, publicViewportOptions, publicDisplaySetOptions, presentations) {
8115
8295
  const renderingEngine = this.getRenderingEngine();
8116
- const viewportId = publicViewportOptions.viewportId || this.getViewportId(viewportIndex);
8117
- if (!viewportId) {
8118
- throw new Error('Must define viewportId externally');
8119
- }
8296
+
8297
+ // This is the old viewportInfo, which may have old options but we might be
8298
+ // using its viewport (same viewportId as the new viewportInfo)
8120
8299
  const viewportInfo = this.viewportsById.get(viewportId);
8300
+
8301
+ // We should store the presentation for the current viewport since we can't only
8302
+ // rely to store it WHEN the viewport is disabled since we might keep around the
8303
+ // same viewport/element and just change the viewportData for it (drag and drop etc.)
8304
+ // the disableElement storePresentation handle would not be called in this case
8305
+ // and we would lose the presentation.
8306
+ this.storePresentation({
8307
+ viewportId: viewportInfo.getViewportId()
8308
+ });
8121
8309
  if (!viewportInfo) {
8122
- throw new Error('Viewport info not defined');
8310
+ throw new Error('element is not enabled for the given viewportId');
8123
8311
  }
8124
8312
 
8125
- // If the viewport has moved index, then record the new index
8126
- if (viewportInfo.viewportIndex !== viewportIndex) {
8127
- this.viewportsInfo.delete(viewportInfo.viewportIndex);
8128
- this.viewportsInfo.set(viewportIndex, viewportInfo);
8129
- viewportInfo.viewportIndex = viewportIndex;
8130
- }
8131
- viewportInfo.setRenderingEngineId(renderingEngine.id);
8132
- const {
8133
- viewportOptions,
8134
- displaySetOptions
8135
- } = this._getViewportAndDisplaySetOptions(publicViewportOptions, publicDisplaySetOptions, viewportInfo);
8136
- viewportInfo.setViewportOptions(viewportOptions);
8137
- viewportInfo.setDisplaySetOptions(displaySetOptions);
8138
- viewportInfo.setViewportData(viewportData);
8313
+ // override the viewportOptions and displaySetOptions with the public ones
8314
+ // since those are the newly set ones, we set them here so that it handles defaults
8315
+ const displaySetOptions = viewportInfo.setPublicDisplaySetOptions(publicDisplaySetOptions);
8316
+ const viewportOptions = viewportInfo.setPublicViewportOptions(publicViewportOptions);
8139
8317
  const element = viewportInfo.getElement();
8140
8318
  const type = viewportInfo.getViewportType();
8141
8319
  const background = viewportInfo.getBackground();
@@ -8150,11 +8328,23 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
8150
8328
  }
8151
8329
  };
8152
8330
 
8331
+ // Rendering Engine Id set should happen before enabling the element
8332
+ // since there are callbacks that depend on the renderingEngine id
8333
+ // Todo: however, this is a limitation which means that we can't change
8334
+ // the rendering engine id for a given viewport which might be a super edge
8335
+ // case
8336
+ viewportInfo.setRenderingEngineId(renderingEngine.id);
8337
+
8153
8338
  // Todo: this is not optimal at all, we are re-enabling the already enabled
8154
8339
  // element which is not what we want. But enabledElement as part of the
8155
8340
  // renderingEngine is designed to be used like this. This will trigger
8156
8341
  // ENABLED_ELEMENT again and again, which will run onEnableElement callbacks
8157
8342
  renderingEngine.enableElement(viewportInput);
8343
+ viewportInfo.setViewportOptions(viewportOptions);
8344
+ viewportInfo.setDisplaySetOptions(displaySetOptions);
8345
+ viewportInfo.setViewportData(viewportData);
8346
+ viewportInfo.setViewportId(viewportId);
8347
+ this.viewportsById.set(viewportId, viewportInfo);
8158
8348
  const viewport = renderingEngine.getViewport(viewportId);
8159
8349
  this._setDisplaySets(viewport, viewportData, viewportInfo, presentations);
8160
8350
 
@@ -8163,7 +8353,6 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
8163
8353
  // invalid data.
8164
8354
  this._broadcastEvent(this.EVENTS.VIEWPORT_DATA_CHANGED, {
8165
8355
  viewportData,
8166
- viewportIndex,
8167
8356
  viewportId
8168
8357
  });
8169
8358
  }
@@ -8175,31 +8364,8 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
8175
8364
  const viewport = this.renderingEngine.getViewport(viewportId);
8176
8365
  return viewport;
8177
8366
  }
8178
- getCornerstoneViewportByIndex(viewportIndex) {
8179
- const viewportInfo = this.getViewportInfoByIndex(viewportIndex);
8180
- if (!viewportInfo || !this.renderingEngine || this.renderingEngine.hasBeenDestroyed) {
8181
- return null;
8182
- }
8183
- const viewport = this.renderingEngine.getViewport(viewportInfo.getViewportId());
8184
- return viewport;
8185
- }
8186
-
8187
- /**
8188
- * Returns the viewportIndex for the provided viewportId
8189
- * @param {string} viewportId - the viewportId
8190
- * @returns {number} - the viewportIndex
8191
- */
8192
- getViewportInfoByIndex(viewportIndex) {
8193
- return this.viewportsInfo.get(viewportIndex);
8194
- }
8195
8367
  getViewportInfo(viewportId) {
8196
- // @ts-ignore
8197
- for (const [index, viewport] of this.viewportsInfo.entries()) {
8198
- if (viewport.getViewportId() === viewportId) {
8199
- return viewport;
8200
- }
8201
- }
8202
- return null;
8368
+ return this.viewportsById.get(viewportId);
8203
8369
  }
8204
8370
  _setStackViewport(viewport, viewportData, viewportInfo, presentations) {
8205
8371
  const displaySetOptions = viewportInfo.getDisplaySetOptions();
@@ -8236,9 +8402,13 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
8236
8402
  }
8237
8403
  }
8238
8404
  viewport.setStack(imageIds, initialImageIndexToUse).then(() => {
8239
- viewport.setProperties(properties);
8405
+ viewport.setProperties({
8406
+ ...properties
8407
+ });
8240
8408
  const camera = presentations.positionPresentation?.camera;
8241
- if (camera) viewport.setCamera(camera);
8409
+ if (camera) {
8410
+ viewport.setCamera(camera);
8411
+ }
8242
8412
  });
8243
8413
  }
8244
8414
  _getInitialImageIndexForViewport(viewportInfo, imageIds) {
@@ -8333,7 +8503,7 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
8333
8503
  });
8334
8504
  }
8335
8505
  this.viewportsDisplaySets.set(viewport.id, displaySetInstanceUIDs);
8336
- if (hangingProtocolService.hasCustomImageLoadStrategy() && !hangingProtocolService.customImageLoadPerformed) {
8506
+ if (hangingProtocolService.getShouldPerformCustomImageLoad()) {
8337
8507
  // delegate the volume loading to the hanging protocol service if it has a custom image load strategy
8338
8508
  return hangingProtocolService.runImageLoadStrategy({
8339
8509
  viewportId: viewport.id,
@@ -8395,11 +8565,11 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
8395
8565
  };
8396
8566
  });
8397
8567
  await viewport.setVolumes(volumeInputArray);
8398
- volumesProperties.forEach(_ref => {
8568
+ volumesProperties.forEach(_ref2 => {
8399
8569
  let {
8400
8570
  properties,
8401
8571
  volumeId
8402
- } = _ref;
8572
+ } = _ref2;
8403
8573
  viewport.setProperties(properties, volumeId);
8404
8574
  });
8405
8575
  this.setPresentations(viewport, presentations);
@@ -8487,13 +8657,12 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
8487
8657
 
8488
8658
  // Todo: keepCamera is an interim solution until we have a better solution for
8489
8659
  // keeping the camera position when the viewport data is changed
8490
- updateViewport(viewportIndex, viewportData) {
8660
+ updateViewport(viewportId, viewportData) {
8491
8661
  let keepCamera = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
8492
- const viewportInfo = this.getViewportInfoByIndex(viewportIndex);
8493
- const viewportId = viewportInfo.getViewportId();
8662
+ const viewportInfo = this.getViewportInfo(viewportId);
8494
8663
  const viewport = this.getCornerstoneViewport(viewportId);
8495
8664
  const viewportCamera = viewport.getCamera();
8496
- if (viewport instanceof esm.VolumeViewport) {
8665
+ if (viewport instanceof esm.VolumeViewport || viewport instanceof esm.VolumeViewport3D) {
8497
8666
  this._setVolumeViewport(viewport, viewportData, viewportInfo).then(() => {
8498
8667
  if (keepCamera) {
8499
8668
  viewport.setCamera(viewportCamera);
@@ -8548,23 +8717,6 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
8548
8717
  return slabThickness;
8549
8718
  }
8550
8719
  }
8551
- _getViewportAndDisplaySetOptions(publicViewportOptions, publicDisplaySetOptions, viewportInfo) {
8552
- const viewportIndex = viewportInfo.getViewportIndex();
8553
-
8554
- // Creating a temporary viewportInfo to handle defaults
8555
- const newViewportInfo = new Viewport(viewportIndex, viewportInfo.getViewportId());
8556
-
8557
- // To handle setting the default values if missing for the viewportOptions and
8558
- // displaySetOptions
8559
- newViewportInfo.setPublicViewportOptions(publicViewportOptions);
8560
- newViewportInfo.setPublicDisplaySetOptions(publicDisplaySetOptions);
8561
- const newViewportOptions = newViewportInfo.getViewportOptions();
8562
- const newDisplaySetOptions = newViewportInfo.getDisplaySetOptions();
8563
- return {
8564
- viewportOptions: newViewportOptions,
8565
- displaySetOptions: newDisplaySetOptions
8566
- };
8567
- }
8568
8720
  _getFrameOfReferenceUID(displaySetInstanceUID) {
8569
8721
  const {
8570
8722
  displaySetService
@@ -8602,28 +8754,28 @@ class CornerstoneViewportService extends src/* PubSubService */.hC {
8602
8754
  *
8603
8755
  * @param measurement
8604
8756
  * The measurement that is desired to view.
8605
- * @param activeViewportIndex - the index that was active at the time the jump
8757
+ * @param activeViewportId - the index that was active at the time the jump
8606
8758
  * was initiated.
8607
- * @return the viewportIndex to display the given measurement
8759
+ * @return the viewportId that the measurement should be displayed in.
8608
8760
  */
8609
- getViewportIndexToJump(activeViewportIndex, displaySetInstanceUID, cameraProps) {
8610
- const viewportInfo = this.viewportsInfo.get(activeViewportIndex);
8761
+ getViewportIdToJump(activeViewportId, displaySetInstanceUID, cameraProps) {
8762
+ const viewportInfo = this.getViewportInfo(activeViewportId);
8611
8763
  const {
8612
8764
  referencedImageId
8613
8765
  } = cameraProps;
8614
8766
  if (viewportInfo?.contains(displaySetInstanceUID, referencedImageId)) {
8615
- return activeViewportIndex;
8767
+ return activeViewportId;
8616
8768
  }
8617
- return [...this.viewportsById.values()].find(viewportInfo => viewportInfo.contains(displaySetInstanceUID, referencedImageId))?.viewportIndex ?? -1;
8769
+ return [...this.viewportsById.values()].find(viewportInfo => viewportInfo.contains(displaySetInstanceUID, referencedImageId))?.viewportId ?? null;
8618
8770
  }
8619
8771
  }
8620
8772
  CornerstoneViewportService.REGISTRATION = {
8621
8773
  name: 'cornerstoneViewportService',
8622
8774
  altName: 'CornerstoneViewportService',
8623
- create: _ref2 => {
8775
+ create: _ref3 => {
8624
8776
  let {
8625
8777
  servicesManager
8626
- } = _ref2;
8778
+ } = _ref3;
8627
8779
  return new CornerstoneViewportService(servicesManager);
8628
8780
  }
8629
8781
  };
@@ -8632,7 +8784,7 @@ CornerstoneViewportService.REGISTRATION = {
8632
8784
 
8633
8785
 
8634
8786
  // EXTERNAL MODULE: ../../../node_modules/dicomweb-client/build/dicomweb-client.es.js
8635
- var dicomweb_client_es = __webpack_require__(75935);
8787
+ var dicomweb_client_es = __webpack_require__(97604);
8636
8788
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/dicomLoaderService.js
8637
8789
 
8638
8790
 
@@ -8824,7 +8976,6 @@ function getHandlesFromPoints(points) {
8824
8976
 
8825
8977
 
8826
8978
 
8827
-
8828
8979
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone/src/utils/measurementServiceMappings/index.ts
8829
8980
 
8830
8981
 
@@ -8849,11 +9000,10 @@ function src_extends() { src_extends = Object.assign ? Object.assign.bind() : fu
8849
9000
 
8850
9001
 
8851
9002
 
8852
-
8853
9003
 
8854
9004
 
8855
9005
  const Component = /*#__PURE__*/react.lazy(() => {
8856
- return Promise.all(/* import() */[__webpack_require__.e(664), __webpack_require__.e(351)]).then(__webpack_require__.bind(__webpack_require__, 30351));
9006
+ return Promise.all(/* import() */[__webpack_require__.e(23), __webpack_require__.e(181)]).then(__webpack_require__.bind(__webpack_require__, 86181));
8857
9007
  });
8858
9008
  const OHIFCornerstoneViewport = props => {
8859
9009
  return /*#__PURE__*/react.createElement(react.Suspense, {
@@ -8876,7 +9026,6 @@ const cornerstoneExtension = {
8876
9026
  esm.imageLoadPoolManager.clearRequestStack(type);
8877
9027
  esm.imageRetrievalPoolManager.clearRequestStack(type);
8878
9028
  });
8879
- destroy();
8880
9029
  (0,state/* reset */.mc)();
8881
9030
  },
8882
9031
  /**
@@ -8956,7 +9105,7 @@ const cornerstoneExtension = {
8956
9105
 
8957
9106
  /***/ }),
8958
9107
 
8959
- /***/ 21922:
9108
+ /***/ 73704:
8960
9109
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
8961
9110
 
8962
9111
  "use strict";
@@ -8976,9 +9125,9 @@ const state = {
8976
9125
  * @param {HTMLElement} dom Active viewport element.
8977
9126
  * @return void
8978
9127
  */
8979
- const setEnabledElement = (viewportIndex, element, context) => {
9128
+ const setEnabledElement = (viewportId, element, context) => {
8980
9129
  const targetContext = context || state.DEFAULT_CONTEXT;
8981
- state.enabledElements[viewportIndex] = {
9130
+ state.enabledElements[viewportId] = {
8982
9131
  element,
8983
9132
  context: targetContext
8984
9133
  };
@@ -8989,8 +9138,8 @@ const setEnabledElement = (viewportIndex, element, context) => {
8989
9138
  *
8990
9139
  * @return {HTMLElement} Active viewport element.
8991
9140
  */
8992
- const getEnabledElement = viewportIndex => {
8993
- return state.enabledElements[viewportIndex];
9141
+ const getEnabledElement = viewportId => {
9142
+ return state.enabledElements[viewportId];
8994
9143
  };
8995
9144
  const reset = () => {
8996
9145
  state.enabledElements = {};
@@ -8999,14 +9148,14 @@ const reset = () => {
8999
9148
 
9000
9149
  /***/ }),
9001
9150
 
9002
- /***/ 63130:
9151
+ /***/ 87172:
9003
9152
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
9004
9153
 
9005
9154
  "use strict";
9006
9155
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
9007
9156
  /* harmony export */ Z: () => (/* binding */ getSOPInstanceAttributes)
9008
9157
  /* harmony export */ });
9009
- /* harmony import */ var _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(77331);
9158
+ /* harmony import */ var _cornerstonejs_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(45754);
9010
9159
 
9011
9160
 
9012
9161
  /**