@ohif/app 3.12.0-beta.90 → 3.12.0-beta.92

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 (45) hide show
  1. package/dist/{1037.bundle.87a5adb8c92bd5bf53f5.js → 1037.bundle.dd9098a9a640f0d0ef0f.js} +129 -96
  2. package/dist/{1608.bundle.3d904bc76f5d5f78ff21.js → 1608.bundle.f855c4bdb7f00eb66fca.js} +1 -1
  3. package/dist/{1903.bundle.f0505c6e927d0bef5589.js → 1903.bundle.9a291597f23ebaa3371c.js} +49 -47
  4. package/dist/{1604.bundle.4f01a6b0b8d5b1cbc294.js → 1933.bundle.a5d41c04da5425d06694.js} +13 -26
  5. package/dist/{2018.bundle.59c7c4cb3f79f63bab68.js → 2018.bundle.4527f2b0c1c8ff75f568.js} +18 -43
  6. package/dist/{306.bundle.f9faa2b3cdd7e86b5869.js → 306.bundle.a0af0889477845729c6a.js} +23 -1
  7. package/dist/{3461.bundle.458597198f24359ec78f.js → 3461.bundle.3cac685ef19f883a0f9d.js} +27 -8
  8. package/dist/{4019.bundle.1be1cdd0805ad2c59d65.js → 4019.bundle.03029c488a02493cb7f3.js} +17 -1
  9. package/dist/{2518.bundle.644302643ac0790e7374.js → 4033.bundle.1609f8751de2a6aff280.js} +457 -303
  10. package/dist/{4819.bundle.f187a4c0517c85e37ab0.js → 4819.bundle.14344bf9acf5c5f6d123.js} +3 -3
  11. package/dist/{5028.bundle.6003ab9178779929462f.js → 5028.bundle.c61b7cd88172e2d589d5.js} +2 -2
  12. package/dist/{5400.bundle.c3a3fe8867efa2edfa94.js → 5400.bundle.428fdd2dc347a7fda9e6.js} +96 -92
  13. package/dist/5457.bundle.af893cd38fdaeafd5c2a.js +89 -0
  14. package/dist/{5485.bundle.2ee096f57ff7e51d4c23.js → 5485.bundle.929d9add8bdf90a4f3c7.js} +8 -0
  15. package/dist/{5802.bundle.8922caf16c088b10cdb0.js → 5802.bundle.756d2ed511c06ee8b461.js} +2 -2
  16. package/dist/{6991.bundle.46bc04720d99fbb06785.js → 6991.bundle.7d091de815571097b96e.js} +8 -10
  17. package/dist/{7412.bundle.34fe5e72833e857edc0a.js → 7412.bundle.dfe01ae3e53107abe53d.js} +80 -57
  18. package/dist/{8305.bundle.8ea926425cdffaf84fe3.js → 8305.bundle.08ba73235df90e099838.js} +75 -55
  19. package/dist/{8558.bundle.c9ffb4f942dbbbff1849.js → 8558.bundle.705446f4883e84021bf4.js} +29 -11
  20. package/dist/{8583.bundle.7715397a42e8f00a9e3e.js → 8583.bundle.0288cadf5cf8401446b1.js} +12 -13
  21. package/dist/{874.bundle.92ddc54408fef9debee7.js → 874.bundle.7e543ec9343c9a718e3d.js} +35 -42
  22. package/dist/{3613.bundle.6157004e0592003c0800.js → 8802.bundle.4958d8ba1d0d521a002a.js} +131 -76
  23. package/dist/{9548.bundle.7be4f24aeadd0ad4f16c.js → 9195.bundle.70afccd0f802b78c279a.js} +75 -104
  24. package/dist/{9845.bundle.7e4db5e31b28d73fdac2.js → 9845.bundle.0d22f2210c1d5ac18882.js} +1 -1
  25. package/dist/{app.bundle.bdd8a45996ed4ca28560.js → app.bundle.2b7e40349f89ffdfd96c.js} +1055 -219
  26. package/dist/{compute.bundle.f3ca9fb0e7ce9e885b9c.js → compute.bundle.4c0ef8b919cbe5eef44d.js} +3 -3
  27. package/dist/index.html +1 -1
  28. package/dist/{polySeg.bundle.7b8d1bb21d442a48da1d.js → polySeg.bundle.75f37f2780c5375e161e.js} +3 -3
  29. package/dist/sw.js +1 -1
  30. package/package.json +22 -22
  31. package/dist/5457.bundle.535bae0c872c1ca0c2cb.js +0 -1358
  32. /package/dist/{1459.bundle.0481573ae1bde12b24ee.js → 1459.bundle.c4acfc6df383fc187e9e.js} +0 -0
  33. /package/dist/{147.bundle.6fc65a239d1ae1c6a918.js → 147.bundle.c191ca0b67633f707aff.js} +0 -0
  34. /package/dist/{1515.bundle.73d415797a677ae5261e.js → 1515.bundle.3f81b326242dd945ecdb.js} +0 -0
  35. /package/dist/{1604.css → 1933.css} +0 -0
  36. /package/dist/{213.bundle.9b152cd4d202cae43af2.js → 213.bundle.33092c23ffe1d81ae242.js} +0 -0
  37. /package/dist/{2243.bundle.25ca9faa6d0776355adf.js → 2243.bundle.e37c80996a222167dc14.js} +0 -0
  38. /package/dist/{2424.bundle.57b7484a3b1b1e5a1722.js → 2424.bundle.45583fc64208a2821aa3.js} +0 -0
  39. /package/dist/{319.bundle.4ea0dbcfeb553c900206.js → 319.bundle.febb2a63634488c11db6.js} +0 -0
  40. /package/dist/{6027.bundle.06ab1f1cd27f93f826e5.js → 6027.bundle.b2942a0dd2c583374d7b.js} +0 -0
  41. /package/dist/{7431.bundle.55dd86000e66bee467e2.js → 7431.bundle.b80819b8eb28d2ee897d.js} +0 -0
  42. /package/dist/{7639.bundle.a89f4a8c6e8b2593d7a4.js → 7639.bundle.2ad4b6cd132d87439fa6.js} +0 -0
  43. /package/dist/{85.bundle.f3a9149485e3fcf652f0.js → 85.bundle.a772983604a0f9514e33.js} +0 -0
  44. /package/dist/{9862.bundle.0456a2d473895bf2916e.js → 9862.bundle.eca4ea8821bb040a44c1.js} +0 -0
  45. /package/dist/{9927.bundle.d7051dac659d827d62d3.js → 9927.bundle.775cb41458de4c28a9ba.js} +0 -0
@@ -6809,7 +6809,7 @@ function updateLabelmapSegmentationImageReferences(viewportId, segmentationId) {
6809
6809
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
6810
6810
  /* harmony export */ A: () => (/* binding */ convertContourHoles)
6811
6811
  /* harmony export */ });
6812
- /* harmony import */ var _utilities_contours__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6936);
6812
+ /* harmony import */ var _utilities_contours__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(19111);
6813
6813
  /* harmony import */ var _annotation_annotationState__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(82056);
6814
6814
  /* harmony import */ var _getSegmentation__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(33283);
6815
6815
  /* harmony import */ var _extractSegmentPolylines__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(96629);
@@ -7250,7 +7250,7 @@ function removeCompleteContourAnnotation(annotation) {
7250
7250
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
7251
7251
  /* harmony export */ A: () => (/* binding */ removeContourHoles)
7252
7252
  /* harmony export */ });
7253
- /* harmony import */ var _utilities_contours__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6936);
7253
+ /* harmony import */ var _utilities_contours__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(19111);
7254
7254
  /* harmony import */ var _annotation_annotationState__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(82056);
7255
7255
  /* harmony import */ var _getSegmentation__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(33283);
7256
7256
  /* harmony import */ var _extractSegmentPolylines__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(96629);
@@ -23579,6 +23579,8 @@ function defaultGetTextLines(data, targetId) {
23579
23579
  /* harmony import */ var _stateManagement_annotation_helpers_state__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(44049);
23580
23580
  /* harmony import */ var _enums__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(99737);
23581
23581
  /* harmony import */ var _drawingSvg__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(74347);
23582
+ /* harmony import */ var _utilities_contours_AnnotationToPointData__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(29632);
23583
+
23582
23584
 
23583
23585
 
23584
23586
 
@@ -23666,6 +23668,9 @@ class LivewireContourSegmentationTool extends _LivewireContourTool__WEBPACK_IMPO
23666
23668
  isContourSegmentationTool() {
23667
23669
  return true;
23668
23670
  }
23671
+ static {
23672
+ _utilities_contours_AnnotationToPointData__WEBPACK_IMPORTED_MODULE_6__/* ["default"] */ .A.register(this);
23673
+ }
23669
23674
  }
23670
23675
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (LivewireContourSegmentationTool);
23671
23676
 
@@ -29680,14 +29685,20 @@ function _checkContourGeometryMatchViewport(geometryIds, viewportNormal) {
29680
29685
  return false;
29681
29686
  }
29682
29687
  const contours = geometryData.contours;
29683
- const points = contours[0].points;
29684
- const point1 = points[0];
29685
- const point2 = points[1];
29686
- const point3 = points[2];
29687
- let normal = gl_matrix__WEBPACK_IMPORTED_MODULE_9__/* .vec3.cross */ .eR.cross(gl_matrix__WEBPACK_IMPORTED_MODULE_9__/* .vec3.create */ .eR.create(), gl_matrix__WEBPACK_IMPORTED_MODULE_9__/* .vec3.sub */ .eR.sub(gl_matrix__WEBPACK_IMPORTED_MODULE_9__/* .vec3.create */ .eR.create(), point2, point1), gl_matrix__WEBPACK_IMPORTED_MODULE_9__/* .vec3.sub */ .eR.sub(gl_matrix__WEBPACK_IMPORTED_MODULE_9__/* .vec3.create */ .eR.create(), point3, point1));
29688
- normal = gl_matrix__WEBPACK_IMPORTED_MODULE_9__/* .vec3.normalize */ .eR.normalize(gl_matrix__WEBPACK_IMPORTED_MODULE_9__/* .vec3.create */ .eR.create(), normal);
29689
- const dotProduct = gl_matrix__WEBPACK_IMPORTED_MODULE_9__/* .vec3.dot */ .eR.dot(normal, viewportNormal);
29690
- return Math.abs(dotProduct) > 0.9;
29688
+ const { points } = contours[0];
29689
+ const [point] = points;
29690
+ const delta = gl_matrix__WEBPACK_IMPORTED_MODULE_9__/* .vec3.create */ .eR.create();
29691
+ const { length } = points;
29692
+ const increment = Math.ceil(length / 25);
29693
+ for (let i = 1; i < length; i += increment) {
29694
+ const point2 = points[i];
29695
+ gl_matrix__WEBPACK_IMPORTED_MODULE_9__/* .vec3.sub */ .eR.sub(delta, point, point2);
29696
+ gl_matrix__WEBPACK_IMPORTED_MODULE_9__/* .vec3.normalize */ .eR.normalize(delta, delta);
29697
+ if (gl_matrix__WEBPACK_IMPORTED_MODULE_9__/* .vec3.dot */ .eR.dot(viewportNormal, delta) > 0.1) {
29698
+ return false;
29699
+ }
29700
+ }
29701
+ return true;
29691
29702
  }
29692
29703
  function _checkContourNormalsMatchViewport(annotationUIDsMap, viewportNormal) {
29693
29704
  const annotationUIDs = Array.from(annotationUIDsMap.values())
@@ -36563,6 +36574,58 @@ function cleanupPolylines(polylines) {
36563
36574
  }
36564
36575
 
36565
36576
 
36577
+ /***/ }),
36578
+
36579
+ /***/ 29632:
36580
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
36581
+
36582
+ "use strict";
36583
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
36584
+ /* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)
36585
+ /* harmony export */ });
36586
+ /* harmony import */ var _RectangleROIStartEndThreshold__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(109);
36587
+
36588
+ function validateAnnotation(annotation) {
36589
+ if (!annotation?.data) {
36590
+ throw new Error('Tool data is empty');
36591
+ }
36592
+ if (!annotation.metadata || !annotation.metadata.referencedImageId) {
36593
+ throw new Error('Tool data is not associated with any imageId');
36594
+ }
36595
+ }
36596
+ class AnnotationToPointData {
36597
+ static { this.TOOL_NAMES = {}; }
36598
+ constructor() {
36599
+ }
36600
+ static convert(annotation, segment, metadataProvider) {
36601
+ validateAnnotation(annotation);
36602
+ const { toolName } = annotation.metadata;
36603
+ const toolClass = AnnotationToPointData.TOOL_NAMES[toolName];
36604
+ if (!toolClass) {
36605
+ throw new Error(`Unknown tool type: ${toolName}, cannot convert to RTSSReport`);
36606
+ }
36607
+ const contourSequence = toolClass.getContourSequence(annotation, metadataProvider);
36608
+ const color = segment.color?.slice(0, 3) || [
36609
+ Math.floor(Math.random() * 255),
36610
+ Math.floor(Math.random() * 255),
36611
+ Math.floor(Math.random() * 255),
36612
+ ];
36613
+ return {
36614
+ ReferencedROINumber: segment.segmentIndex,
36615
+ ROIDisplayColor: color,
36616
+ ContourSequence: Array.isArray(contourSequence)
36617
+ ? contourSequence
36618
+ : [contourSequence],
36619
+ };
36620
+ }
36621
+ static register(toolClass) {
36622
+ AnnotationToPointData.TOOL_NAMES[toolClass.toolName] = toolClass;
36623
+ }
36624
+ }
36625
+ AnnotationToPointData.register(_RectangleROIStartEndThreshold__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A);
36626
+ /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (AnnotationToPointData);
36627
+
36628
+
36566
36629
  /***/ }),
36567
36630
 
36568
36631
  /***/ 93843:
@@ -36849,7 +36912,7 @@ function getDeduplicatedVTKPolyDataPoints(polyData, bypass = false) {
36849
36912
 
36850
36913
  /***/ }),
36851
36914
 
36852
- /***/ 6936:
36915
+ /***/ 19111:
36853
36916
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
36854
36917
 
36855
36918
  "use strict";
@@ -36858,7 +36921,7 @@ __webpack_require__.r(__webpack_exports__);
36858
36921
 
36859
36922
  // EXPORTS
36860
36923
  __webpack_require__.d(__webpack_exports__, {
36861
- AnnotationToPointData: () => (/* reexport */ contours_AnnotationToPointData),
36924
+ AnnotationToPointData: () => (/* reexport */ AnnotationToPointData/* default */.A),
36862
36925
  acceptAutogeneratedInterpolations: () => (/* reexport */ acceptAutogeneratedInterpolations),
36863
36926
  areCoplanarContours: () => (/* reexport */ areCoplanarContours),
36864
36927
  calculatePerimeter: () => (/* reexport */ calculatePerimeter/* default */.A),
@@ -37124,48 +37187,8 @@ async function generateContourSetsFromLabelmap({ segmentations }) {
37124
37187
  }
37125
37188
 
37126
37189
 
37127
- // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/contours/RectangleROIStartEndThreshold.js
37128
- var RectangleROIStartEndThreshold = __webpack_require__(109);
37129
- ;// ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/contours/AnnotationToPointData.js
37130
-
37131
- function validateAnnotation(annotation) {
37132
- if (!annotation?.data) {
37133
- throw new Error('Tool data is empty');
37134
- }
37135
- if (!annotation.metadata || annotation.metadata.referencedImageId) {
37136
- throw new Error('Tool data is not associated with any imageId');
37137
- }
37138
- }
37139
- class AnnotationToPointData {
37140
- static { this.TOOL_NAMES = {}; }
37141
- constructor() {
37142
- }
37143
- static convert(annotation, index, metadataProvider) {
37144
- validateAnnotation(annotation);
37145
- const { toolName } = annotation.metadata;
37146
- const toolClass = AnnotationToPointData.TOOL_NAMES[toolName];
37147
- if (!toolClass) {
37148
- throw new Error(`Unknown tool type: ${toolName}, cannot convert to RTSSReport`);
37149
- }
37150
- const ContourSequence = toolClass.getContourSequence(annotation, metadataProvider);
37151
- const color = [
37152
- Math.floor(Math.random() * 255),
37153
- Math.floor(Math.random() * 255),
37154
- Math.floor(Math.random() * 255),
37155
- ];
37156
- return {
37157
- ReferencedROINumber: index + 1,
37158
- ROIDisplayColor: color,
37159
- ContourSequence,
37160
- };
37161
- }
37162
- static register(toolClass) {
37163
- AnnotationToPointData.TOOL_NAMES[toolClass.toolName] = toolClass;
37164
- }
37165
- }
37166
- AnnotationToPointData.register(RectangleROIStartEndThreshold/* default */.A);
37167
- /* harmony default export */ const contours_AnnotationToPointData = (AnnotationToPointData);
37168
-
37190
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/contours/AnnotationToPointData.js
37191
+ var AnnotationToPointData = __webpack_require__(29632);
37169
37192
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/contours/getContourHolesDataWorld.js
37170
37193
  var getContourHolesDataWorld = __webpack_require__(55659);
37171
37194
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/contours/getContourHolesDataCanvas.js
@@ -38006,7 +38029,7 @@ __webpack_require__.r(__webpack_exports__);
38006
38029
  /* harmony import */ var _AnnotationMultiSlice__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(16678);
38007
38030
  /* harmony import */ var _getViewportForAnnotation__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(40133);
38008
38031
  /* harmony import */ var _annotationHydration__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(64485);
38009
- /* harmony import */ var _contours__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(6936);
38032
+ /* harmony import */ var _contours__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(19111);
38010
38033
  /* harmony import */ var _segmentation__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(93759);
38011
38034
  /* harmony import */ var _drawing__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(473);
38012
38035
  /* harmony import */ var _math__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(95527);
@@ -39658,7 +39681,7 @@ async function calculateForVolume({ segmentationIds, segmentIndex }) {
39658
39681
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
39659
39682
  /* harmony export */ A: () => (/* binding */ contourAndFindLargestBidirectional)
39660
39683
  /* harmony export */ });
39661
- /* harmony import */ var _contours__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(6936);
39684
+ /* harmony import */ var _contours__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(19111);
39662
39685
  /* harmony import */ var _findLargestBidirectional__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(60199);
39663
39686
  /* harmony import */ var _getOrCreateSegmentationVolume__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(30722);
39664
39687
 
@@ -44472,7 +44495,7 @@ __webpack_require__.r(__webpack_exports__);
44472
44495
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
44473
44496
  /* harmony export */ r: () => (/* binding */ version)
44474
44497
  /* harmony export */ });
44475
- const version = '4.11.2';
44498
+ const version = '4.11.3';
44476
44499
 
44477
44500
 
44478
44501
  /***/ }),
@@ -30,8 +30,8 @@ var i18n_src = __webpack_require__(68523);
30
30
  var esm = __webpack_require__(15327);
31
31
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/index.js
32
32
  var dist_esm = __webpack_require__(4667);
33
- // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/adapters/dist/esm/index.js + 69 modules
34
- var adapters_dist_esm = __webpack_require__(53434);
33
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/adapters/dist/esm/index.js + 70 modules
34
+ var adapters_dist_esm = __webpack_require__(14041);
35
35
  // EXTERNAL MODULE: ../../../node_modules/dcmjs/build/dcmjs.es.js
36
36
  var dcmjs_es = __webpack_require__(5842);
37
37
  ;// ../../../extensions/cornerstone-dicom-seg/src/utils/dicomlabToRGB.ts
@@ -58,18 +58,23 @@ function dicomlabToRGB(cielab) {
58
58
  const sopClassUids = ['1.2.840.10008.5.1.4.1.1.66.4', '1.2.840.10008.5.1.4.1.1.66.7'];
59
59
  const loadPromises = {};
60
60
  function _getDisplaySetsFromSeries(instances, servicesManager, extensionManager) {
61
- const instance = instances[0];
61
+ src/* utils */.Wp.sortStudyInstances(instances);
62
+
63
+ // Choose the LAST instance in the list as the most recently created one.
64
+ const instance = instances[instances.length - 1];
62
65
  const {
63
66
  StudyInstanceUID,
64
67
  SeriesInstanceUID,
65
68
  SOPInstanceUID,
66
- SeriesDescription,
69
+ SeriesDescription = '',
67
70
  SeriesNumber,
68
71
  SeriesDate,
72
+ StructureSetDate,
69
73
  SOPClassUID,
70
74
  wadoRoot,
71
75
  wadoUri,
72
- wadoUriRoot
76
+ wadoUriRoot,
77
+ imageId: predecessorImageId
73
78
  } = instance;
74
79
  const displaySet = {
75
80
  Modality: 'SEG',
@@ -78,7 +83,7 @@ function _getDisplaySetsFromSeries(instances, servicesManager, extensionManager)
78
83
  displaySetInstanceUID: src/* utils */.Wp.guid(),
79
84
  SeriesDescription,
80
85
  SeriesNumber,
81
- SeriesDate,
86
+ SeriesDate: SeriesDate || StructureSetDate || '',
82
87
  SOPInstanceUID,
83
88
  SeriesInstanceUID,
84
89
  StudyInstanceUID,
@@ -93,6 +98,7 @@ function _getDisplaySetsFromSeries(instances, servicesManager, extensionManager)
93
98
  segments: {},
94
99
  sopClassUids,
95
100
  instance,
101
+ predecessorImageId,
96
102
  instances: [instance],
97
103
  wadoRoot,
98
104
  wadoUriRoot,
@@ -111,7 +117,10 @@ function _getDisplaySetsFromSeries(instances, servicesManager, extensionManager)
111
117
  const {
112
118
  displaySetService
113
119
  } = servicesManager.services;
114
- const referencedDisplaySets = displaySetService.getDisplaySetsForSeries(displaySet.referencedSeriesInstanceUID);
120
+ const referencedDisplaySets = displaySetService.getDisplaySetsForReferences(instance.ReferencedSeriesSequence);
121
+ if (referencedDisplaySets?.length > 1) {
122
+ console.warn('Segmentation does not currently handle references to multiple series, defaulting to first series');
123
+ }
115
124
  const referencedDisplaySet = referencedDisplaySets[0];
116
125
  if (!referencedDisplaySet) {
117
126
  // subscribe to display sets added which means at some point it will be available
@@ -345,8 +354,8 @@ function getHangingProtocolModule() {
345
354
  }
346
355
  /* harmony default export */ const src_getHangingProtocolModule = (getHangingProtocolModule);
347
356
 
348
- // EXTERNAL MODULE: ../../../extensions/default/src/index.ts + 141 modules
349
- var default_src = __webpack_require__(39548);
357
+ // EXTERNAL MODULE: ../../../extensions/default/src/index.ts + 139 modules
358
+ var default_src = __webpack_require__(39195);
350
359
  // EXTERNAL MODULE: ../../../extensions/default/src/utils/_shared/PROMPT_RESPONSES.ts
351
360
  var PROMPT_RESPONSES = __webpack_require__(96357);
352
361
  ;// ../../../extensions/cornerstone-dicom-seg/src/commandsModule.ts
@@ -357,10 +366,6 @@ var PROMPT_RESPONSES = __webpack_require__(96357);
357
366
 
358
367
 
359
368
 
360
-
361
- const {
362
- datasetToBlob
363
- } = dcmjs_es/* default.data */.Ay.data;
364
369
  const getTargetViewport = ({
365
370
  viewportId,
366
371
  viewportGridService
@@ -383,7 +388,7 @@ const {
383
388
  const {
384
389
  Cornerstone3D: {
385
390
  RTSS: {
386
- generateRTSSFromSegmentations
391
+ generateRTSSFromRepresentation
387
392
  }
388
393
  }
389
394
  } = adapters_dist_esm/* adaptersRT */.f_;
@@ -454,6 +459,7 @@ const commandsModule = ({
454
459
  options = {}
455
460
  }) => {
456
461
  const segmentation = dist_esm.segmentation.state.getSegmentation(segmentationId);
462
+ const predecessorImageId = options.predecessorImageId ?? segmentation.predecessorImageId;
457
463
  const {
458
464
  imageIds
459
465
  } = segmentation.representationData.Labelmap;
@@ -521,7 +527,10 @@ const commandsModule = ({
521
527
  };
522
528
  labelmap3D.metadata[segmentIndex] = segmentMetadata;
523
529
  });
524
- const generatedSegmentation = generateSegmentation(referencedImages, labelmap3D, esm.metaData, options);
530
+ const generatedSegmentation = generateSegmentation(referencedImages, labelmap3D, esm.metaData, {
531
+ predecessorImageId,
532
+ ...options
533
+ });
525
534
  return generatedSegmentation;
526
535
  },
527
536
  /**
@@ -557,34 +566,44 @@ const commandsModule = ({
557
566
  */
558
567
  storeSegmentation: async ({
559
568
  segmentationId,
560
- dataSource
569
+ dataSource,
570
+ modality = 'SEG'
561
571
  }) => {
562
572
  const segmentation = segmentationService.getSegmentation(segmentationId);
563
573
  if (!segmentation) {
564
574
  throw new Error('No segmentation found');
565
575
  }
566
576
  const {
567
- label
577
+ label,
578
+ predecessorImageId
568
579
  } = segmentation;
569
580
  const defaultDataSource = dataSource ?? extensionManager.getActiveDataSource()[0];
570
581
  const {
571
582
  value: reportName,
572
583
  dataSourceName: selectedDataSource,
584
+ series,
585
+ priorSeriesNumber,
573
586
  action
574
587
  } = await (0,default_src.createReportDialogPrompt)({
575
588
  servicesManager,
576
589
  extensionManager,
577
- title: 'Store Segmentation'
590
+ predecessorImageId,
591
+ title: 'Store Segmentation',
592
+ modality
578
593
  });
579
594
  if (action === PROMPT_RESPONSES/* default */.A.CREATE_REPORT) {
580
595
  try {
581
596
  const selectedDataSourceConfig = selectedDataSource ? extensionManager.getDataSources(selectedDataSource)[0] : defaultDataSource;
582
- const generatedData = actions.generateSegmentation({
597
+ const args = {
583
598
  segmentationId,
584
599
  options: {
585
- SeriesDescription: reportName || label || 'Research Derived Series'
600
+ SeriesDescription: series ? undefined : reportName || label || 'Contour Series',
601
+ SeriesNumber: series ? undefined : 1 + priorSeriesNumber,
602
+ predecessorImageId: series
586
603
  }
587
- });
604
+ };
605
+ const generatedDataAsync = modality === 'SEG' && actions.generateSegmentation(args) || modality === 'RTSTRUCT' && actions.generateContour(args);
606
+ const generatedData = await generatedDataAsync;
588
607
  if (!generatedData || !generatedData.dataset) {
589
608
  throw new Error('Error during segmentation generation');
590
609
  }
@@ -608,30 +627,43 @@ const commandsModule = ({
608
627
  }
609
628
  }
610
629
  },
611
- /**
612
- * Converts segmentations into RTSS for download.
613
- * This sample function retrieves all segentations and passes to
614
- * cornerstone tool adapter to convert to DICOM RTSS format. It then
615
- * converts dataset to downloadable blob.
616
- *
617
- */
618
- downloadRTSS: async ({
619
- segmentationId
620
- }) => {
630
+ generateContour: async args => {
631
+ const {
632
+ segmentationId,
633
+ options
634
+ } = args;
621
635
  const segmentations = segmentationService.getSegmentation(segmentationId);
622
636
 
623
637
  // inject colors to the segmentIndex
624
638
  const firstRepresentation = segmentationService.getRepresentationsForSegmentation(segmentationId)[0];
625
639
  Object.entries(segmentations.segments).forEach(([segmentIndex, segment]) => {
626
- segment.color = segmentationService.getSegmentColor(firstRepresentation.viewportId, segmentationId, segmentIndex);
640
+ segment.color = segmentationService.getSegmentColor(firstRepresentation.viewportId, segmentationId, Number(segmentIndex));
627
641
  });
628
- const RTSS = await generateRTSSFromSegmentations(segmentations, src/* classes */.Ly.MetadataProvider, src/* DicomMetadataStore */.H8);
642
+ const predecessorImageId = options?.predecessorImageId ?? segmentations.predecessorImageId;
643
+ const dataset = await generateRTSSFromRepresentation(segmentations, {
644
+ predecessorImageId,
645
+ ...options
646
+ });
647
+ return {
648
+ dataset
649
+ };
650
+ },
651
+ /**
652
+ * Downloads an RTSS instance from a segmentation or contour
653
+ * representation.
654
+ */
655
+ downloadRTSS: async args => {
656
+ const {
657
+ dataset
658
+ } = await actions.generateContour(args);
659
+ const {
660
+ InstanceNumber: instanceNumber = 1,
661
+ SeriesInstanceUID: seriesUID
662
+ } = dataset;
629
663
  try {
630
- const reportBlob = datasetToBlob(RTSS);
631
-
632
664
  //Create a URL for the binary.
633
- const objectUrl = URL.createObjectURL(reportBlob);
634
- window.location.assign(objectUrl);
665
+ const filename = `rtss-${seriesUID}-${instanceNumber}.dcm`;
666
+ downloadDICOMData(dataset, filename);
635
667
  } catch (e) {
636
668
  console.warn(e);
637
669
  }
@@ -654,24 +686,12 @@ const commandsModule = ({
654
686
  }
655
687
  };
656
688
  const definitions = {
657
- loadSegmentationsForViewport: {
658
- commandFn: actions.loadSegmentationsForViewport
659
- },
660
- generateSegmentation: {
661
- commandFn: actions.generateSegmentation
662
- },
663
- downloadSegmentation: {
664
- commandFn: actions.downloadSegmentation
665
- },
666
- storeSegmentation: {
667
- commandFn: actions.storeSegmentation
668
- },
669
- downloadRTSS: {
670
- commandFn: actions.downloadRTSS
671
- },
672
- toggleActiveSegmentationUtility: {
673
- commandFn: actions.toggleActiveSegmentationUtility
674
- }
689
+ loadSegmentationsForViewport: actions.loadSegmentationsForViewport,
690
+ generateSegmentation: actions.generateSegmentation,
691
+ downloadSegmentation: actions.downloadSegmentation,
692
+ storeSegmentation: actions.storeSegmentation,
693
+ downloadRTSS: actions.downloadRTSS,
694
+ toggleActiveSegmentationUtility: actions.toggleActiveSegmentationUtility
675
695
  };
676
696
  return {
677
697
  actions,
@@ -392,9 +392,9 @@ async function checkAndLoadContourData({
392
392
  ROIContour.ContourSequence.forEach((Contour, index) => {
393
393
  const promise = resolvedPromises[index];
394
394
  if (promise.status === 'fulfilled') {
395
- if (Array.isArray(promise.value) && promise.value.every(Number.isFinite)) {
395
+ if (Array.isArray(promise.value) && promise.value.every(it => Number.isFinite(Number(it)))) {
396
396
  // If promise.value is already an array of numbers, use it directly
397
- Contour.ContourData = promise.value;
397
+ Contour.ContourData = promise.value.map(Number);
398
398
  } else {
399
399
  // If the resolved promise value is a byte array (Blob), it needs to be decoded
400
400
  const uint8Array = new Uint8Array(promise.value);
@@ -647,18 +647,24 @@ const sopClassUids = [sopClassDictionary.RTStructureSetStorage];
647
647
  const cachedRTStructsSEG = new Set();
648
648
  const loadPromises = {};
649
649
  function _getDisplaySetsFromSeries(instances, servicesManager, extensionManager) {
650
- const instance = instances[0];
650
+ src/* utils */.Wp.sortStudyInstances(instances);
651
+ // Choose the LAST instance in the list as the most recently created one.
652
+ const instance = instances[instances.length - 1];
651
653
  const {
652
654
  StudyInstanceUID,
653
655
  SeriesInstanceUID,
654
656
  SOPInstanceUID,
655
- SeriesDescription,
657
+ SeriesDescription = '',
656
658
  SeriesNumber,
657
659
  SeriesDate,
660
+ SeriesTime,
661
+ StructureSetDate,
662
+ StructureSetTime,
658
663
  SOPClassUID,
659
664
  wadoRoot,
660
665
  wadoUri,
661
- wadoUriRoot
666
+ wadoUriRoot,
667
+ imageId: predecessorImageId
662
668
  } = instance;
663
669
  const displaySet = {
664
670
  Modality: 'RTSTRUCT',
@@ -667,7 +673,13 @@ function _getDisplaySetsFromSeries(instances, servicesManager, extensionManager)
667
673
  displaySetInstanceUID: src/* utils */.Wp.guid(),
668
674
  SeriesDescription,
669
675
  SeriesNumber,
670
- SeriesDate,
676
+ /**
677
+ * The "SeriesDate" for a display set is really the display set date, which
678
+ * should be the date of the instance being used, which will be the structure
679
+ * set date in this case.
680
+ */
681
+ SeriesDate: StructureSetDate || SeriesDate,
682
+ SeriesTime: StructureSetTime || SeriesTime,
671
683
  SOPInstanceUID,
672
684
  SeriesInstanceUID,
673
685
  StudyInstanceUID,
@@ -682,6 +694,8 @@ function _getDisplaySetsFromSeries(instances, servicesManager, extensionManager)
682
694
  structureSet: null,
683
695
  sopClassUids,
684
696
  instance,
697
+ instances,
698
+ predecessorImageId,
685
699
  wadoRoot,
686
700
  wadoUriRoot,
687
701
  wadoUri,
@@ -689,12 +703,13 @@ function _getDisplaySetsFromSeries(instances, servicesManager, extensionManager)
689
703
  label: SeriesDescription || `${i18n_src/* default */.A.t('Series')} ${SeriesNumber} - ${i18n_src/* default */.A.t('RTSTRUCT')}`
690
704
  };
691
705
  let referencedSeriesSequence = instance.ReferencedSeriesSequence;
692
- if (instance.ReferencedFrameOfReferenceSequence && !instance.ReferencedSeriesSequence) {
706
+ if (instance.ReferencedFrameOfReferenceSequence?.RTReferencedStudySequence && !instance.ReferencedSeriesSequence) {
693
707
  instance.ReferencedSeriesSequence = _deriveReferencedSeriesSequenceFromFrameOfReferenceSequence(instance.ReferencedFrameOfReferenceSequence);
694
708
  referencedSeriesSequence = instance.ReferencedSeriesSequence;
695
709
  }
696
710
  if (!referencedSeriesSequence) {
697
- throw new Error('ReferencedSeriesSequence is missing for the RTSTRUCT');
711
+ console.error('ReferencedSeriesSequence is missing for the RTSTRUCT');
712
+ return;
698
713
  }
699
714
  const referencedSeries = referencedSeriesSequence[0];
700
715
  displaySet.referencedImages = instance.ReferencedSeriesSequence.ReferencedInstanceSequence;
@@ -702,7 +717,10 @@ function _getDisplaySetsFromSeries(instances, servicesManager, extensionManager)
702
717
  const {
703
718
  displaySetService
704
719
  } = servicesManager.services;
705
- const referencedDisplaySets = displaySetService.getDisplaySetsForSeries(displaySet.referencedSeriesInstanceUID);
720
+ const referencedDisplaySets = displaySetService.getDisplaySetsForReferences(referencedSeriesSequence);
721
+ if (referencedDisplaySets?.length > 1) {
722
+ console.warn('Reference applies to more than 1 display set for Contours, applying only to first display set');
723
+ }
706
724
  if (!referencedDisplaySets || referencedDisplaySets.length === 0) {
707
725
  // Instead of throwing error, subscribe to display sets added
708
726
  const {
@@ -718,7 +736,7 @@ function _getDisplaySetsFromSeries(instances, servicesManager, extensionManager)
718
736
  }
719
737
  });
720
738
  } else {
721
- const referencedDisplaySet = referencedDisplaySets[0];
739
+ const [referencedDisplaySet] = referencedDisplaySets;
722
740
  displaySet.referencedDisplaySetInstanceUID = referencedDisplaySet.displaySetInstanceUID;
723
741
  displaySet.isReconstructable = referencedDisplaySet.isReconstructable;
724
742
  }
@@ -879,7 +897,7 @@ function _extends() { return _extends = Object.assign ? Object.assign.bind() : f
879
897
 
880
898
 
881
899
  const Component = /*#__PURE__*/react.lazy(() => {
882
- return Promise.all(/* import() */[__webpack_require__.e(4019), __webpack_require__.e(319), __webpack_require__.e(5400), __webpack_require__.e(7412), __webpack_require__.e(2108), __webpack_require__.e(7431), __webpack_require__.e(9548), __webpack_require__.e(1903), __webpack_require__.e(1608)]).then(__webpack_require__.bind(__webpack_require__, 88414));
900
+ return Promise.all(/* import() */[__webpack_require__.e(4019), __webpack_require__.e(319), __webpack_require__.e(5400), __webpack_require__.e(7412), __webpack_require__.e(2108), __webpack_require__.e(7431), __webpack_require__.e(9195), __webpack_require__.e(1903), __webpack_require__.e(1608)]).then(__webpack_require__.bind(__webpack_require__, 88414));
883
901
  });
884
902
  const OHIFCornerstoneRTViewport = props => {
885
903
  return /*#__PURE__*/react.createElement(react.Suspense, {
@@ -998,8 +998,8 @@ const handleROIThresholding = async ({
998
998
  segmentationService.addOrUpdateSegmentation(segmentation);
999
999
  });
1000
1000
  };
1001
- // EXTERNAL MODULE: ../../core/src/utils/index.ts + 31 modules
1002
- var utils = __webpack_require__(12505);
1001
+ // EXTERNAL MODULE: ../../core/src/utils/index.ts + 33 modules
1002
+ var utils = __webpack_require__(37447);
1003
1003
  ;// ../../../extensions/tmtv/src/Panels/PanelROIThresholdSegmentation/PanelROIThresholdExport.tsx
1004
1004
 
1005
1005
 
@@ -1096,8 +1096,8 @@ function PanelRoiThresholdSegmentation() {
1096
1096
 
1097
1097
 
1098
1098
 
1099
- // EXTERNAL MODULE: ../../../extensions/default/src/index.ts + 141 modules
1100
- var default_src = __webpack_require__(39548);
1099
+ // EXTERNAL MODULE: ../../../extensions/default/src/index.ts + 139 modules
1100
+ var default_src = __webpack_require__(39195);
1101
1101
  ;// ../../../extensions/tmtv/src/Panels/PanelTMTV.tsx
1102
1102
 
1103
1103
 
@@ -1433,6 +1433,10 @@ function _getStrategyFn(statistic) {
1433
1433
  }
1434
1434
  /* harmony default export */ const getThresholdValue = (getThresholdValues);
1435
1435
  ;// ../../../extensions/tmtv/src/utils/createAndDownloadTMTVReport.js
1436
+
1437
+ const {
1438
+ downloadCsv
1439
+ } = src/* utils */.Wp;
1436
1440
  function createAndDownloadTMTVReport(segReport, additionalReportRows, options = {}) {
1437
1441
  const firstReport = segReport[Object.keys(segReport)[0]];
1438
1442
  const columns = Object.keys(firstReport);
@@ -1463,19 +1467,14 @@ function createAndDownloadTMTVReport(segReport, additionalReportRows, options =
1463
1467
  });
1464
1468
  csv.push(temp.join(','));
1465
1469
  });
1466
- const blob = new Blob([csv.join('\n')], {
1467
- type: 'text/csv;charset=utf-8'
1470
+ downloadCsv(csv.join('\n'), {
1471
+ filename: options.filename ?? `${firstReport.PatientID}_tmtv.csv`
1468
1472
  });
1469
- const url = URL.createObjectURL(blob);
1470
- const a = document.createElement('a');
1471
- a.href = url;
1472
- a.download = options.filename ?? `${firstReport.PatientID}_tmtv.csv`;
1473
- a.click();
1474
1473
  }
1475
1474
  // EXTERNAL MODULE: ../../../node_modules/dcmjs/build/dcmjs.es.js
1476
1475
  var dcmjs_es = __webpack_require__(5842);
1477
- // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/adapters/dist/esm/index.js + 69 modules
1478
- var adapters_dist_esm = __webpack_require__(53434);
1476
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/adapters/dist/esm/index.js + 70 modules
1477
+ var adapters_dist_esm = __webpack_require__(14041);
1479
1478
  ;// ../../../extensions/tmtv/src/utils/dicomRTAnnotationExport/RTStructureSet/dicomRTAnnotationExport.js
1480
1479
 
1481
1480