@ohif/app 3.7.0-beta.1 → 3.7.0-beta.100

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 (66) hide show
  1. package/dist/{917.bundle.06cb87cf1c42b9f20bd2.js → 12.bundle.34050abb042540a90a3a.js} +6 -6
  2. package/dist/{295.bundle.957b1159fec14b9199a1.js → 125.bundle.253395f320b72180da63.js} +6 -6
  3. package/dist/{351.bundle.2d4bc19d8b493879dbbe.js → 181.bundle.169383e9b1a0358b44e8.js} +227 -205
  4. package/dist/{351.css → 181.css} +1 -1
  5. package/dist/{744.bundle.392a124e4ee20ad6a657.js → 19.bundle.eef637102334f1832ba9.js} +246 -385
  6. package/dist/{606.bundle.5d876f5f3dd8287f0a28.js → 202.bundle.96bbb4547a346fe3921f.js} +1420 -750
  7. package/dist/{926.bundle.dbc9d0e591cb9217fda2.js → 220.bundle.f7e1c96c94245e70f2be.js} +990 -400
  8. package/dist/221.bundle.0b9f7401294213262852.js +1723 -0
  9. package/dist/221.css +2 -0
  10. package/dist/{664.bundle.09abae984223969d1bde.js → 23.bundle.e008ad788170f2ed5569.js} +5 -6
  11. package/dist/{976.bundle.2305e2f8244de8ccbaee.js → 236.bundle.7768b3e29b1fd618b9ec.js} +89 -105
  12. package/dist/{55.bundle.5f5e5ef9087b0beee35c.js → 250.bundle.8084960e3318cda37317.js} +52 -36
  13. package/dist/{973.bundle.a51bb5b329263c9e75e2.js → 281.bundle.39cb630582cf8114fd5e.js} +18 -14
  14. package/dist/{82.bundle.da0c036b2e572719dbc5.js → 342.bundle.6edc7ac022b4218ec99f.js} +1776 -482
  15. package/dist/{404.bundle.902c664e3e581335a5d2.js → 359.bundle.a8f6cf2f90fe05fc346d.js} +46 -131
  16. package/dist/{192.bundle.4fee0d418ae32bb7ab30.js → 370.bundle.4e1276530ba7757347f5.js} +113 -99
  17. package/dist/{790.bundle.aa7a8bebec3483d90f3f.js → 410.bundle.5a330214c0c31cbf2551.js} +11 -9
  18. package/dist/{151.bundle.31ea35044218837bf73f.js → 417.bundle.af0a207c29b109f84159.js} +49 -17
  19. package/dist/{569.bundle.0ed8d8178ffd43fe1c34.js → 451.bundle.9fd36f52ff69594f0669.js} +98 -107
  20. package/dist/{581.bundle.360d26f97b37da8faec3.js → 471.bundle.b3d77b83b1593c09a504.js} +78 -98
  21. package/dist/{199.bundle.290ef76d4ab8358e29bb.js → 506.bundle.ac385e382f79bbf4f306.js} +11 -14
  22. package/dist/{531.bundle.2a82fb1d69e5b57cc72b.js → 530.bundle.a03b6f942ace3e1baa1e.js} +726 -447
  23. package/dist/579.css +1 -0
  24. package/dist/{935.bundle.deeffff0e4f7b528e3c3.js → 604.bundle.a51f83e64004bca5f497.js} +2 -3
  25. package/dist/613.bundle.f75fd669ddfe4ecf9c1b.js +532 -0
  26. package/dist/{984.bundle.4e002ef9b3468bddb68b.js → 663.bundle.3863ac49f85320c8ca96.js} +68 -38
  27. package/dist/{205.bundle.b5a473c200dcf2bbcdb4.js → 686.bundle.dccef1f36e4bc79bcc48.js} +6 -6
  28. package/dist/{50.bundle.03f455d441f2138ce49e.js → 687.bundle.ebd1260565c31ab9ad08.js} +218 -9
  29. package/dist/{331.bundle.bd0c13931a21d53086c9.js → 743.bundle.4bfe6e562ffb2c22708f.js} +26281 -21326
  30. package/dist/{728.bundle.d13856835357400fef82.js → 774.bundle.7528cba56a1407357144.js} +95 -64
  31. package/dist/{381.bundle.0905e683605fcbc0895f.js → 775.bundle.2285e7e0e67878948c0d.js} +16 -16
  32. package/dist/{283.bundle.7cf0fabc69d49a8a2c5d.js → 782.bundle.8c17030f76b75035564c.js} +123 -80
  33. package/dist/{642.bundle.89f15ef57fbad2a1019b.js → 814.bundle.cc0ed4fc75cb16e34f02.js} +6 -6
  34. package/dist/{707.bundle.832f50366089fd23e93b.js → 82.bundle.7a89cd8b81eb7e1e5c66.js} +1187 -808
  35. package/dist/{799.bundle.ca18bdf4abe4d9abea26.js → 822.bundle.0545d6dbb49515aa04ee.js} +81 -34
  36. package/dist/831.bundle.83658f62fcc769043605.js +16700 -0
  37. package/dist/{953.bundle.9e3a7225f07336bfcb41.js → 886.bundle.4b3a7f2079d085fdbcb3.js} +34 -29
  38. package/dist/945.min.worker.js +1 -1
  39. package/dist/945.min.worker.js.map +1 -1
  40. package/dist/{270.bundle.4564621556b0f963a004.js → 957.bundle.71558794566041f37a92.js} +7110 -997
  41. package/dist/{208.bundle.29fe1842c33000edc75d.js → 99.bundle.c6876aaaa3ff2f1b08a1.js} +86 -105
  42. package/dist/_redirects +1 -1
  43. package/dist/app-config.js +35 -17
  44. package/dist/app.bundle.css +13 -12
  45. package/dist/{app.bundle.3ad961046deb5f47678a.js → app.bundle.dc0e89948c4f4568fe20.js} +73720 -68191
  46. package/dist/assets/yandex-browser-manifest.json +1 -1
  47. package/dist/cornerstoneDICOMImageLoader.min.js +1 -1
  48. package/dist/cornerstoneDICOMImageLoader.min.js.map +1 -1
  49. package/dist/{dicom-microscopy-viewer.bundle.aa60bdf008c32c39cfd7.js → dicom-microscopy-viewer.bundle.2c146384eb9466d02ff8.js} +5 -4
  50. package/dist/es6-shim.min.js +3569 -2
  51. package/dist/google.js +8 -7
  52. package/dist/index.html +2 -1
  53. package/dist/{index.worker.1c69152d710fa7b84bce.worker.js → index.worker.e62ecca63f1a2e124230.worker.js} +2 -2
  54. package/dist/index.worker.e62ecca63f1a2e124230.worker.js.map +1 -0
  55. package/dist/init-service-worker.js +3 -5
  56. package/dist/oidc-client.min.js +10857 -39
  57. package/dist/polyfill.min.js +184 -1
  58. package/dist/silent-refresh.html +18 -9
  59. package/dist/sw.js +1 -1
  60. package/package.json +20 -22
  61. package/dist/616.bundle.b76c70aeeed8b142593c.js +0 -685
  62. package/dist/780.bundle.fd0f13dc92e9caa0581e.js +0 -4769
  63. package/dist/index.worker.1c69152d710fa7b84bce.worker.js.map +0 -1
  64. /package/dist/{806.css → 19.css} +0 -0
  65. /package/dist/{55.css → 250.css} +0 -0
  66. /package/dist/{707.css → 82.css} +0 -0
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
- (globalThis["webpackChunk"] = globalThis["webpackChunk"] || []).push([[151],{
2
+ (self["webpackChunk"] = self["webpackChunk"] || []).push([[417],{
3
3
 
4
- /***/ 71251:
4
+ /***/ 15747:
5
5
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
6
6
 
7
7
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
@@ -355,13 +355,40 @@ function calculateSUVlbmScalingFactor(inputs) {
355
355
  PatientSize
356
356
  } = inputs;
357
357
  let LBM;
358
- const bodyMassIndex = PatientWeight * PatientWeight / (PatientSize * PatientSize * 10000); // convert size in cm
359
- // reference: https://www.medicalconnections.co.uk/kb/calculating-suv-from-pet-images/
358
+ const weightSizeFactor = Math.pow(PatientWeight / (PatientSize * 100), 2); // reference: https://www.medicalconnections.co.uk/kb/calculating-suv-from-pet-images/
360
359
 
361
360
  if (PatientSex === 'F') {
362
- LBM = 1.07 * PatientWeight - 148 * bodyMassIndex;
361
+ LBM = 1.07 * PatientWeight - 148 * weightSizeFactor;
363
362
  } else if (PatientSex === 'M') {
364
- LBM = 1.1 * PatientWeight - 120 * bodyMassIndex;
363
+ LBM = 1.1 * PatientWeight - 120 * weightSizeFactor;
364
+ } else {
365
+ throw new Error(`PatientSex is an invalid value: ${PatientSex}`);
366
+ }
367
+
368
+ return LBM * 1000; // convert in gr
369
+ }
370
+ /**
371
+ * From https://link.springer.com/article/10.1007/s00259-014-2961-x
372
+ * and https://link.springer.com/article/10.2165/00003088-200544100-00004
373
+ * and
374
+ * @param inputs
375
+ * @returns
376
+ */
377
+
378
+
379
+ function calculateSUVlbmJanmahasatianScalingFactor(inputs) {
380
+ const {
381
+ PatientSex,
382
+ PatientWeight,
383
+ PatientSize
384
+ } = inputs;
385
+ let LBM;
386
+ const bodyMassIndex = PatientWeight / Math.pow(PatientSize, 2);
387
+
388
+ if (PatientSex === 'F') {
389
+ LBM = 9270 * PatientWeight / (8780 + 244 * bodyMassIndex);
390
+ } else if (PatientSex === 'M') {
391
+ LBM = 9270 * PatientWeight / (6680 + 216 * bodyMassIndex);
365
392
  } else {
366
393
  throw new Error(`PatientSex is an invalid value: ${PatientSex}`);
367
394
  }
@@ -502,9 +529,10 @@ function calculateSUVScalingFactors(instances) {
502
529
 
503
530
  if (!isSingleSeries) {
504
531
  throw new Error('The set of instances does not appear to come from one Series. Every instance must have identical values for series-level metadata properties');
505
- }
532
+ } // Treat null, undefined and zero as a missing PatientWeight.
533
+
506
534
 
507
- if (PatientWeight === null || PatientWeight === undefined) {
535
+ if (!PatientWeight) {
508
536
  throw new Error('PatientWeight value is missing. It is not possible to calculate the SUV factors');
509
537
  }
510
538
 
@@ -567,6 +595,7 @@ function calculateSUVScalingFactors(instances) {
567
595
 
568
596
 
569
597
  let suvlbmFactor;
598
+ let suvlbmJenmaFactor;
570
599
 
571
600
  if (PatientSize === null || PatientSize === undefined) {
572
601
  console.warn('PatientSize value is missing. It is not possible to calculate the SUV lbm factors');
@@ -579,6 +608,7 @@ function calculateSUVScalingFactors(instances) {
579
608
  PatientSize
580
609
  };
581
610
  suvlbmFactor = calculateSUVlbmScalingFactor(suvlbmInputs);
611
+ suvlbmJenmaFactor = calculateSUVlbmJanmahasatianScalingFactor(suvlbmInputs);
582
612
  }
583
613
 
584
614
  return results.map(function (result, index) {
@@ -594,6 +624,10 @@ function calculateSUVScalingFactors(instances) {
594
624
  if (suvlbmFactor) {
595
625
  // multiply for LBM
596
626
  factors.suvlbm = decayCorrectionArray[index] * suvlbmFactor;
627
+ }
628
+
629
+ if (suvlbmJenmaFactor) {
630
+ factors.suvlbmJanma = decayCorrectionArray[index] * suvlbmJenmaFactor;
597
631
  } // factor formulaes taken from:
598
632
  // https://www.medicalconnections.co.uk/kb/calculating-suv-from-pet-images/
599
633
 
@@ -603,24 +637,23 @@ function calculateSUVScalingFactors(instances) {
603
637
  }
604
638
 
605
639
 
606
- //# sourceMappingURL=calculate-suv.esm.js.map
607
640
 
608
641
 
609
642
  /***/ }),
610
643
 
611
- /***/ 21767:
644
+ /***/ 94614:
612
645
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
613
646
 
614
647
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
615
648
  /* harmony export */ S_: () => (/* binding */ VariableSizeList)
616
649
  /* harmony export */ });
617
650
  /* unused harmony exports FixedSizeGrid, FixedSizeList, VariableSizeGrid, areEqual, shouldComponentUpdate */
618
- /* harmony import */ var _babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(20011);
619
- /* harmony import */ var _babel_runtime_helpers_esm_assertThisInitialized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(93173);
620
- /* harmony import */ var _babel_runtime_helpers_esm_inheritsLoose__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(23788);
621
- /* harmony import */ var memoize_one__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(89454);
622
- /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(32735);
623
- /* harmony import */ var _babel_runtime_helpers_esm_objectWithoutPropertiesLoose__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(66017);
651
+ /* harmony import */ var _babel_runtime_helpers_esm_extends__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(76805);
652
+ /* harmony import */ var _babel_runtime_helpers_esm_assertThisInitialized__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(80107);
653
+ /* harmony import */ var _babel_runtime_helpers_esm_inheritsLoose__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(84067);
654
+ /* harmony import */ var memoize_one__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(25539);
655
+ /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(43001);
656
+ /* harmony import */ var _babel_runtime_helpers_esm_objectWithoutPropertiesLoose__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(8339);
624
657
 
625
658
 
626
659
 
@@ -2571,7 +2604,6 @@ function shouldComponentUpdate(nextProps, nextState) {
2571
2604
  }
2572
2605
 
2573
2606
 
2574
- //# sourceMappingURL=index.esm.js.map
2575
2607
 
2576
2608
 
2577
2609
  /***/ })
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
- (globalThis["webpackChunk"] = globalThis["webpackChunk"] || []).push([[569],{
2
+ (self["webpackChunk"] = self["webpackChunk"] || []).push([[451],{
3
3
 
4
- /***/ 33569:
4
+ /***/ 4451:
5
5
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
6
6
 
7
7
  // ESM COMPAT FLAG
@@ -13,77 +13,24 @@ __webpack_require__.d(__webpack_exports__, {
13
13
  });
14
14
 
15
15
  // EXTERNAL MODULE: ../../../node_modules/prop-types/index.js
16
- var prop_types = __webpack_require__(60216);
16
+ var prop_types = __webpack_require__(3827);
17
17
  var prop_types_default = /*#__PURE__*/__webpack_require__.n(prop_types);
18
18
  // EXTERNAL MODULE: ../../../node_modules/react/index.js
19
- var react = __webpack_require__(32735);
19
+ var react = __webpack_require__(43001);
20
20
  // EXTERNAL MODULE: ../../../node_modules/react-i18next/dist/es/index.js + 15 modules
21
- var es = __webpack_require__(21572);
22
- // EXTERNAL MODULE: ../../core/src/index.ts + 101 modules
23
- var src = __webpack_require__(48501);
24
- // EXTERNAL MODULE: ../../ui/src/index.js + 449 modules
25
- var ui_src = __webpack_require__(43803);
21
+ var es = __webpack_require__(69190);
22
+ // EXTERNAL MODULE: ../../core/src/index.ts + 65 modules
23
+ var src = __webpack_require__(71771);
24
+ // EXTERNAL MODULE: ../../ui/src/index.js + 485 modules
25
+ var ui_src = __webpack_require__(71783);
26
26
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone-dicom-seg/src/utils/initSEGToolGroup.ts
27
27
  function createSEGToolGroupAndAddTools(ToolGroupService, customizationService, toolGroupId) {
28
28
  const {
29
29
  tools
30
30
  } = customizationService.get('cornerstone.overlayViewportTools') ?? {};
31
- return ToolGroupService.createToolGroupAndAddTools(toolGroupId, tools, {});
31
+ return ToolGroupService.createToolGroupAndAddTools(toolGroupId, tools);
32
32
  }
33
33
  /* harmony default export */ const initSEGToolGroup = (createSEGToolGroupAndAddTools);
34
- ;// CONCATENATED MODULE: ../../../extensions/cornerstone-dicom-seg/src/utils/_hydrateSEG.ts
35
- async function _hydrateSEGDisplaySet(_ref) {
36
- let {
37
- segDisplaySet,
38
- viewportIndex,
39
- servicesManager
40
- } = _ref;
41
- const {
42
- segmentationService,
43
- hangingProtocolService,
44
- viewportGridService
45
- } = servicesManager.services;
46
- const displaySetInstanceUID = segDisplaySet.referencedDisplaySetInstanceUID;
47
- let segmentationId = null;
48
-
49
- // We need the hydration to notify panels about the new segmentation added
50
- const suppressEvents = false;
51
- segmentationId = await segmentationService.createSegmentationForSEGDisplaySet(segDisplaySet, segmentationId, suppressEvents);
52
- segmentationService.hydrateSegmentation(segDisplaySet.displaySetInstanceUID);
53
- const {
54
- viewports
55
- } = viewportGridService.getState();
56
- const updatedViewports = hangingProtocolService.getViewportsRequireUpdate(viewportIndex, displaySetInstanceUID);
57
-
58
- // Todo: fix this after we have a better way for stack viewport segmentations
59
-
60
- // check every viewport in the viewports to see if the displaySetInstanceUID
61
- // is being displayed, if so we need to update the viewport to use volume viewport
62
- // (if already is not using it) since Cornerstone3D currently only supports
63
- // volume viewport for segmentation
64
- viewports.forEach((viewport, index) => {
65
- if (index === viewportIndex) {
66
- return;
67
- }
68
- const shouldDisplaySeg = segmentationService.shouldRenderSegmentation(viewport.displaySetInstanceUIDs, segDisplaySet.displaySetInstanceUID);
69
- if (shouldDisplaySeg) {
70
- updatedViewports.push({
71
- viewportIndex: index,
72
- displaySetInstanceUIDs: viewport.displaySetInstanceUIDs,
73
- viewportOptions: {
74
- initialImageOptions: {
75
- preset: 'middle'
76
- }
77
- }
78
- });
79
- }
80
- });
81
-
82
- // Do the entire update at once
83
- viewportGridService.setDisplaySetsForViewports(updatedViewports);
84
- return true;
85
- }
86
- /* harmony default export */ const _hydrateSEG = (_hydrateSEGDisplaySet);
87
34
  ;// CONCATENATED MODULE: ../../../extensions/cornerstone-dicom-seg/src/utils/promptHydrateSEG.ts
88
35
 
89
36
  const RESPONSE = {
@@ -95,32 +42,36 @@ function promptHydrateSEG(_ref) {
95
42
  let {
96
43
  servicesManager,
97
44
  segDisplaySet,
98
- viewportIndex
45
+ viewportId,
46
+ preHydrateCallbacks,
47
+ hydrateSEGDisplaySet
99
48
  } = _ref;
100
49
  const {
101
50
  uiViewportDialogService
102
51
  } = servicesManager.services;
103
52
  return new Promise(async function (resolve, reject) {
104
- const promptResult = await _askHydrate(uiViewportDialogService, viewportIndex);
53
+ const promptResult = await _askHydrate(uiViewportDialogService, viewportId);
105
54
  if (promptResult === RESPONSE.HYDRATE_SEG) {
106
- const isHydrated = await _hydrateSEG({
55
+ preHydrateCallbacks?.forEach(callback => {
56
+ callback();
57
+ });
58
+ const isHydrated = await hydrateSEGDisplaySet({
107
59
  segDisplaySet,
108
- viewportIndex,
109
- servicesManager
60
+ viewportId
110
61
  });
111
62
  resolve(isHydrated);
112
63
  }
113
64
  });
114
65
  }
115
- function _askHydrate(uiViewportDialogService, viewportIndex) {
66
+ function _askHydrate(uiViewportDialogService, viewportId) {
116
67
  return new Promise(function (resolve, reject) {
117
68
  const message = 'Do you want to open this Segmentation?';
118
69
  const actions = [{
119
- type: 'secondary',
70
+ type: ui_src/* ButtonEnums.type */.LZ.dt.secondary,
120
71
  text: 'No',
121
72
  value: RESPONSE.CANCEL
122
73
  }, {
123
- type: 'primary',
74
+ type: ui_src/* ButtonEnums.type */.LZ.dt.primary,
124
75
  text: 'Yes',
125
76
  value: RESPONSE.HYDRATE_SEG
126
77
  }];
@@ -129,7 +80,7 @@ function _askHydrate(uiViewportDialogService, viewportIndex) {
129
80
  resolve(result);
130
81
  };
131
82
  uiViewportDialogService.show({
132
- viewportIndex,
83
+ viewportId,
133
84
  type: 'info',
134
85
  message,
135
86
  actions,
@@ -155,8 +106,8 @@ function _getStatusComponent(_ref) {
155
106
  let StatusIcon = null;
156
107
  const {
157
108
  t
158
- } = (0,es/* useTranslation */.$G)("Common");
159
- const loadStr = t("LOAD");
109
+ } = (0,es/* useTranslation */.$G)('Common');
110
+ const loadStr = t('LOAD');
160
111
  switch (isHydrated) {
161
112
  case true:
162
113
  StatusIcon = () => /*#__PURE__*/react.createElement(ui_src/* Icon */.JO, {
@@ -166,18 +117,19 @@ function _getStatusComponent(_ref) {
166
117
  break;
167
118
  case false:
168
119
  StatusIcon = () => /*#__PURE__*/react.createElement(ui_src/* Icon */.JO, {
120
+ className: "text-aqua-pale",
169
121
  name: "status-untracked"
170
122
  });
171
123
  ToolTipMessage = () => /*#__PURE__*/react.createElement("div", null, "Click LOAD to load segmentation.");
172
124
  }
173
125
  const StatusArea = () => /*#__PURE__*/react.createElement("div", {
174
- className: "flex h-6 leading-6 cursor-default text-sm text-white"
126
+ className: "flex h-6 cursor-default text-sm leading-6 text-white"
175
127
  }, /*#__PURE__*/react.createElement("div", {
176
- className: "min-w-[45px] flex items-center p-1 rounded-l-xl rounded-r bg-customgray-100"
128
+ className: "bg-customgray-100 flex min-w-[45px] items-center rounded-l-xl rounded-r p-1"
177
129
  }, /*#__PURE__*/react.createElement(StatusIcon, null), /*#__PURE__*/react.createElement("span", {
178
130
  className: "ml-1"
179
131
  }, "SEG")), !isHydrated && /*#__PURE__*/react.createElement("div", {
180
- className: "ml-1 px-1.5 rounded cursor-pointer hover:text-black bg-primary-main hover:bg-primary-light"
132
+ className: "bg-primary-main hover:bg-primary-light ml-1 cursor-pointer rounded px-1.5 hover:text-black"
181
133
  // Using onMouseUp here because onClick is not working when the viewport is not active and is styled with pointer-events:none
182
134
  ,
183
135
  onMouseUp: onStatusClick
@@ -197,7 +149,6 @@ function _extends() { _extends = Object.assign ? Object.assign.bind() : function
197
149
 
198
150
 
199
151
 
200
-
201
152
  const {
202
153
  formatDate
203
154
  } = src.utils;
@@ -207,14 +158,15 @@ function OHIFCornerstoneSEGViewport(props) {
207
158
  children,
208
159
  displaySets,
209
160
  viewportOptions,
210
- viewportIndex,
211
161
  viewportLabel,
212
162
  servicesManager,
213
- extensionManager
163
+ extensionManager,
164
+ commandsManager
214
165
  } = props;
215
166
  const {
216
167
  t
217
168
  } = (0,es/* useTranslation */.$G)('SEGViewport');
169
+ const viewportId = viewportOptions.viewportId;
218
170
  const {
219
171
  displaySetService,
220
172
  toolGroupService,
@@ -222,7 +174,7 @@ function OHIFCornerstoneSEGViewport(props) {
222
174
  uiNotificationService,
223
175
  customizationService
224
176
  } = servicesManager.services;
225
- const toolGroupId = `${SEG_TOOLGROUP_BASE_NAME}-${viewportIndex}`;
177
+ const toolGroupId = `${SEG_TOOLGROUP_BASE_NAME}-${viewportId}`;
226
178
 
227
179
  // SEG viewport will always have a single display set
228
180
  if (displaySets.length > 1) {
@@ -232,7 +184,6 @@ function OHIFCornerstoneSEGViewport(props) {
232
184
  const [viewportGrid, viewportGridService] = (0,ui_src/* useViewportGrid */.O_)();
233
185
 
234
186
  // States
235
- const [isToolGroupCreated, setToolGroupCreated] = (0,react.useState)(false);
236
187
  const [selectedSegment, setSelectedSegment] = (0,react.useState)(1);
237
188
 
238
189
  // Hydration means that the SEG is opened and segments are loaded into the
@@ -252,10 +203,10 @@ function OHIFCornerstoneSEGViewport(props) {
252
203
  const referencedDisplaySetRef = (0,react.useRef)(null);
253
204
  const {
254
205
  viewports,
255
- activeViewportIndex
206
+ activeViewportId
256
207
  } = viewportGrid;
257
208
  const referencedDisplaySet = segDisplaySet.getReferenceDisplaySet();
258
- const referencedDisplaySetMetadata = _getReferencedDisplaySetMetadata(referencedDisplaySet);
209
+ const referencedDisplaySetMetadata = _getReferencedDisplaySetMetadata(referencedDisplaySet, segDisplaySet);
259
210
  referencedDisplaySetRef.current = {
260
211
  displaySet: referencedDisplaySet,
261
212
  metadata: referencedDisplaySetMetadata
@@ -272,6 +223,16 @@ function OHIFCornerstoneSEGViewport(props) {
272
223
  const onElementDisabled = () => {
273
224
  setElement(null);
274
225
  };
226
+ const storePresentationState = (0,react.useCallback)(() => {
227
+ viewportGrid?.viewports.forEach(_ref => {
228
+ let {
229
+ viewportId
230
+ } = _ref;
231
+ commandsManager.runCommand('storePresentation', {
232
+ viewportId
233
+ });
234
+ });
235
+ }, [viewportGrid]);
275
236
  const getCornerstoneViewport = (0,react.useCallback)(() => {
276
237
  const {
277
238
  component: Component
@@ -293,7 +254,7 @@ function OHIFCornerstoneSEGViewport(props) {
293
254
  onElementDisabled: onElementDisabled
294
255
  // initialImageIndex={initialImageIndex}
295
256
  }));
296
- }, [viewportIndex, segDisplaySet, toolGroupId]);
257
+ }, [viewportId, segDisplaySet, toolGroupId]);
297
258
  const onSegmentChange = (0,react.useCallback)(direction => {
298
259
  direction = direction === 'left' ? -1 : 1;
299
260
  const segmentationId = segDisplaySet.displaySetInstanceUID;
@@ -320,14 +281,16 @@ function OHIFCornerstoneSEGViewport(props) {
320
281
  }
321
282
  utils_promptHydrateSEG({
322
283
  servicesManager,
323
- viewportIndex,
324
- segDisplaySet
284
+ viewportId,
285
+ segDisplaySet,
286
+ preHydrateCallbacks: [storePresentationState],
287
+ hydrateSEGDisplaySet
325
288
  }).then(isHydrated => {
326
289
  if (isHydrated) {
327
290
  setIsHydrated(true);
328
291
  }
329
292
  });
330
- }, [servicesManager, viewportIndex, segDisplaySet, segIsLoading]);
293
+ }, [servicesManager, viewportId, segDisplaySet, segIsLoading]);
331
294
  (0,react.useEffect)(() => {
332
295
  const {
333
296
  unsubscribe
@@ -350,11 +313,11 @@ function OHIFCornerstoneSEGViewport(props) {
350
313
  (0,react.useEffect)(() => {
351
314
  const {
352
315
  unsubscribe
353
- } = segmentationService.subscribe(segmentationService.EVENTS.SEGMENT_LOADING_COMPLETE, _ref => {
316
+ } = segmentationService.subscribe(segmentationService.EVENTS.SEGMENT_LOADING_COMPLETE, _ref2 => {
354
317
  let {
355
318
  percentComplete,
356
319
  numSegments
357
- } = _ref;
320
+ } = _ref2;
358
321
  setProcessingProgress({
359
322
  percentComplete,
360
323
  totalSegments: numSegments
@@ -369,14 +332,14 @@ function OHIFCornerstoneSEGViewport(props) {
369
332
  Cleanup the SEG viewport when the viewport is destroyed
370
333
  */
371
334
  (0,react.useEffect)(() => {
372
- const onDisplaySetsRemovedSubscription = displaySetService.subscribe(displaySetService.EVENTS.DISPLAY_SETS_REMOVED, _ref2 => {
335
+ const onDisplaySetsRemovedSubscription = displaySetService.subscribe(displaySetService.EVENTS.DISPLAY_SETS_REMOVED, _ref3 => {
373
336
  let {
374
337
  displaySetInstanceUIDs
375
- } = _ref2;
376
- const activeViewport = viewports[activeViewportIndex];
338
+ } = _ref3;
339
+ const activeViewport = viewports.get(activeViewportId);
377
340
  if (displaySetInstanceUIDs.includes(activeViewport.displaySetInstanceUID)) {
378
341
  viewportGridService.setDisplaySetsForViewport({
379
- viewportIndex: activeViewportIndex,
342
+ viewportId: activeViewportId,
380
343
  displaySetInstanceUIDs: []
381
344
  });
382
345
  }
@@ -394,7 +357,6 @@ function OHIFCornerstoneSEGViewport(props) {
394
357
  // This creates a custom tool group which has the lifetime of this view
395
358
  // only, and does NOT interfere with currently displayed segmentations.
396
359
  toolGroup = initSEGToolGroup(toolGroupService, customizationService, toolGroupId);
397
- setToolGroupCreated(true);
398
360
  return () => {
399
361
  // remove the segmentation representations if seg displayset changed
400
362
  segmentationService.removeSegmentationRepresentationFromToolGroup(toolGroupId);
@@ -420,7 +382,7 @@ function OHIFCornerstoneSEGViewport(props) {
420
382
  if (children && children.length) {
421
383
  childrenWithProps = children.map((child, index) => {
422
384
  return child && /*#__PURE__*/react.cloneElement(child, {
423
- viewportIndex,
385
+ viewportId,
424
386
  key: index
425
387
  });
426
388
  });
@@ -436,11 +398,27 @@ function OHIFCornerstoneSEGViewport(props) {
436
398
  SeriesDescription,
437
399
  SpacingBetweenSlices
438
400
  } = referencedDisplaySetRef.current.metadata;
401
+ const hydrateSEGDisplaySet = _ref4 => {
402
+ let {
403
+ segDisplaySet,
404
+ viewportId
405
+ } = _ref4;
406
+ commandsManager.runCommand('loadSegmentationDisplaySetsForViewport', {
407
+ displaySets: [segDisplaySet],
408
+ viewportId
409
+ });
410
+ };
439
411
  const onStatusClick = async () => {
440
- const isHydrated = await _hydrateSEG({
412
+ // Before hydrating a SEG and make it added to all viewports in the grid
413
+ // that share the same frameOfReferenceUID, we need to store the viewport grid
414
+ // presentation state, so that we can restore it after hydrating the SEG. This is
415
+ // required if the user has changed the viewport (other viewport than SEG viewport)
416
+ // presentation state (w/l and invert) and then opens the SEG. If we don't store
417
+ // the presentation state, the viewport will be reset to the default presentation
418
+ storePresentationState();
419
+ const isHydrated = await hydrateSEGDisplaySet({
441
420
  segDisplaySet,
442
- viewportIndex,
443
- servicesManager
421
+ viewportId
444
422
  });
445
423
  setIsHydrated(isHydrated);
446
424
  };
@@ -466,15 +444,16 @@ function OHIFCornerstoneSEGViewport(props) {
466
444
  patientSex: PatientSex || '',
467
445
  patientAge: PatientAge || '',
468
446
  MRN: PatientID || '',
469
- thickness: SliceThickness ? `${SliceThickness.toFixed(2)}mm` : '',
470
- spacing: SpacingBetweenSlices !== undefined ? `${SpacingBetweenSlices.toFixed(2)}mm` : '',
447
+ thickness: SliceThickness ? src.utils.roundNumber(SliceThickness, 2) : '',
448
+ thicknessUnits: SliceThickness !== undefined ? 'mm' : '',
449
+ spacing: SpacingBetweenSlices !== undefined ? src.utils.roundNumber(SpacingBetweenSlices, 2) : '',
471
450
  scanner: ManufacturerModelName || ''
472
451
  }
473
452
  }
474
453
  }), /*#__PURE__*/react.createElement("div", {
475
- className: "relative flex flex-row w-full h-full overflow-hidden"
454
+ className: "relative flex h-full w-full flex-row overflow-hidden"
476
455
  }, segIsLoading && /*#__PURE__*/react.createElement(ui_src/* LoadingIndicatorTotalPercent */.bk, {
477
- className: "w-full h-full",
456
+ className: "h-full w-full",
478
457
  totalNumbers: processingProgress.totalSegments,
479
458
  percentComplete: processingProgress.percentComplete,
480
459
  loadingText: "Loading SEG..."
@@ -482,7 +461,7 @@ function OHIFCornerstoneSEGViewport(props) {
482
461
  }
483
462
  OHIFCornerstoneSEGViewport.propTypes = {
484
463
  displaySets: prop_types_default().arrayOf((prop_types_default()).object),
485
- viewportIndex: (prop_types_default()).number.isRequired,
464
+ viewportId: (prop_types_default()).string.isRequired,
486
465
  dataSource: (prop_types_default()).object,
487
466
  children: (prop_types_default()).node,
488
467
  customProps: (prop_types_default()).object
@@ -490,20 +469,32 @@ OHIFCornerstoneSEGViewport.propTypes = {
490
469
  OHIFCornerstoneSEGViewport.defaultProps = {
491
470
  customProps: {}
492
471
  };
493
- function _getReferencedDisplaySetMetadata(referencedDisplaySet) {
472
+ function _getReferencedDisplaySetMetadata(referencedDisplaySet, segDisplaySet) {
473
+ const {
474
+ SharedFunctionalGroupsSequence
475
+ } = segDisplaySet.instance;
476
+ const SharedFunctionalGroup = Array.isArray(SharedFunctionalGroupsSequence) ? SharedFunctionalGroupsSequence[0] : SharedFunctionalGroupsSequence;
477
+ const {
478
+ PixelMeasuresSequence
479
+ } = SharedFunctionalGroup;
480
+ const PixelMeasures = Array.isArray(PixelMeasuresSequence) ? PixelMeasuresSequence[0] : PixelMeasuresSequence;
481
+ const {
482
+ SpacingBetweenSlices,
483
+ SliceThickness
484
+ } = PixelMeasures;
494
485
  const image0 = referencedDisplaySet.images[0];
495
486
  const referencedDisplaySetMetadata = {
496
487
  PatientID: image0.PatientID,
497
488
  PatientName: image0.PatientName,
498
489
  PatientSex: image0.PatientSex,
499
490
  PatientAge: image0.PatientAge,
500
- SliceThickness: image0.SliceThickness,
491
+ SliceThickness: image0.SliceThickness || SliceThickness,
501
492
  StudyDate: image0.StudyDate,
502
493
  SeriesDescription: image0.SeriesDescription,
503
494
  SeriesInstanceUID: image0.SeriesInstanceUID,
504
495
  SeriesNumber: image0.SeriesNumber,
505
496
  ManufacturerModelName: image0.ManufacturerModelName,
506
- SpacingBetweenSlices: image0.SpacingBetweenSlices
497
+ SpacingBetweenSlices: image0.SpacingBetweenSlices || SpacingBetweenSlices
507
498
  };
508
499
  return referencedDisplaySetMetadata;
509
500
  }