@ohif/app 3.12.0-beta.99 → 3.12.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/{1403.bundle.94a178e2572f1f0b2a2c.js → 1403.bundle.761239eb886a88301851.js} +37 -37
  2. package/dist/{1459.bundle.3785cdd0abf449adebf1.js → 1459.bundle.fcdd0dec6286845179bf.js} +5 -6
  3. package/dist/{147.bundle.205350dc3d21478277b1.js → 147.bundle.47af018b91121924a12c.js} +10 -18
  4. package/dist/{1608.bundle.f855c4bdb7f00eb66fca.js → 1608.bundle.b9abbf4ed6cc2e491dc3.js} +10 -10
  5. package/dist/{1730.bundle.37c569ae3ed057b69840.js → 1730.bundle.51e69967a025226592cd.js} +41 -40
  6. package/dist/{1927.bundle.019331c266d306772371.js → 1927.bundle.be67b3aafe238ca9f191.js} +27 -38
  7. package/dist/{1933.bundle.ab5e8036f6e1c854c965.js → 1933.bundle.e3ba7d4dcbbd75701d8e.js} +19 -17
  8. package/dist/{2018.bundle.469f9ad42597b6b29ff1.js → 2018.bundle.45c44470b4b098aa343f.js} +65 -66
  9. package/dist/{2108.bundle.e84aa8d858d8c4f2413e.js → 2108.bundle.aea8d3b39486dd5ab39e.js} +569 -558
  10. package/dist/{213.bundle.398730bb3ceb1af54413.js → 213.bundle.863ab5d320fc06043a4e.js} +5 -7
  11. package/dist/{3584.bundle.839a16d349815b3f7c97.js → 2199.bundle.974037f21bfd12c4e8af.js} +256 -2236
  12. package/dist/{2424.bundle.be90e7bcf0fd8db68b2f.js → 2424.bundle.b070e83baf101dad2121.js} +5 -7
  13. package/dist/{2516.bundle.1ea0988d309a757bb6da.js → 2516.bundle.f62228e9a800de8d4b31.js} +6 -6
  14. package/dist/{2701.bundle.aca0d4f24a6f2094c3c3.js → 2701.bundle.58a6a580073edbb4cc04.js} +9 -9
  15. package/dist/{2842.bundle.7852a204d3510fca8b27.js → 2816.bundle.838fa4d72921c026083c.js} +1136 -2342
  16. package/dist/{9195.bundle.e2fd5c6b5830c0ee25a8.js → 2851.bundle.70227d013c1937e846be.js} +318 -150
  17. package/dist/{1903.bundle.dc5248f7cb6ba1dc1072.js → 3081.bundle.930757b1a5aa8549e112.js} +752 -466
  18. package/dist/{3343.bundle.f8fe9316b0ff68d087f7.js → 3343.bundle.a4424b8418b8c0c1a9e4.js} +27 -25
  19. package/dist/{3461.bundle.50c752c623f39cf6c457.js → 3461.bundle.ab31c31a5ddc4baa72f7.js} +40 -40
  20. package/dist/{4202.bundle.790706560c6edb303476.js → 4202.bundle.4f76d3a50d6cf819fba0.js} +6 -6
  21. package/dist/{4019.bundle.01f63d5dd5b96ded0c00.js → 4287.bundle.87e14e648f2bce5e4176.js} +372 -567
  22. package/dist/{4775.bundle.d7f0645419f1df8e00b8.js → 4775.bundle.768f00df706f506f3789.js} +57 -51
  23. package/dist/{4819.bundle.ef1151f023b3784bc1be.js → 4819.bundle.6377aba4cf194120e7d4.js} +35 -34
  24. package/dist/{5028.bundle.b3611b7c7422a5c2e723.js → 5028.bundle.3a086ff61ec8dc1da4b1.js} +13 -15
  25. package/dist/{5261.bundle.6e1a017f8f1027557f5b.js → 5261.bundle.2655560097e9250eac44.js} +412 -345
  26. package/dist/{5457.bundle.9f2eb65ad85fcbb75e27.js → 5457.bundle.0063531ed24c06fba48b.js} +16 -23
  27. package/dist/{5462.bundle.a81a691eeef782ab95b9.js → 5462.bundle.d5bb9b3ddc510fea141f.js} +1108 -1030
  28. package/dist/{5485.bundle.71041ca4bc9e6ab57d92.js → 5485.bundle.b523d7015979fc641f7e.js} +17 -32
  29. package/dist/{5491.bundle.2e01dd7ad29e4cc01bc1.js → 5491.bundle.4866d2ecb20dd089e071.js} +54 -51
  30. package/dist/5724.bundle.62ea5c07c7809ab4cd74.js +297 -0
  31. package/dist/5724.css +2 -0
  32. package/dist/{5802.bundle.28ab859d9b48a5b2c31c.js → 5802.bundle.ae4d88742c353de462c2.js} +13 -18
  33. package/dist/{5830.bundle.b073c265c4fcea1afff3.js → 5830.bundle.791019deddd536980a11.js} +3 -3
  34. package/dist/{5858.bundle.d5f4bf849aaeebf5025c.js → 5858.bundle.466e58128de344ab53f3.js} +90 -86
  35. package/dist/{6027.bundle.160bd47ea03784276275.js → 6027.bundle.3cf6c827b4ce9066b426.js} +3 -5
  36. package/dist/{6163.bundle.1f096bdbe3a341c1710d.js → 6163.bundle.ac77880c970e788c9a07.js} +33 -33
  37. package/dist/{5549.bundle.d5def6a3124a3a481b7c.js → 6280.bundle.f22f9955eb906e1d7da8.js} +2475 -1200
  38. package/dist/{3353.bundle.a0f1654c642395bbbbbc.js → 6347.bundle.f8393c20d5159ed41b64.js} +358 -214
  39. package/dist/{6354.bundle.c387737dc09c9cab4ff2.js → 6354.bundle.d8a592b03e9a5b7a66c2.js} +102 -96
  40. package/dist/{6376.bundle.272e755bdcbb5615a44e.js → 6376.bundle.527820a5cb1eece2a8d2.js} +6 -6
  41. package/dist/{5400.bundle.de97508611da1c00d58a.js → 6409.bundle.24edbaa283b7c521b8f7.js} +517 -146
  42. package/dist/6939.bundle.41fbdef87597b5172ec6.js +3 -3
  43. package/dist/7159.bundle.a5991a5d4f0dd8f1c95f.js +3 -3
  44. package/dist/{7190.bundle.d731ae6cf6e933a2c408.js → 7190.bundle.479332d662ffe08d1f92.js} +1462 -955
  45. package/dist/{732.bundle.6978ac30a1e36abf06db.js → 732.bundle.ea6f9d8504e37e01a208.js} +5 -13
  46. package/dist/{7431.bundle.999b2b65d4973bc56218.js → 7431.bundle.b31ebb4a2625e89d864e.js} +38 -32
  47. package/dist/{7639.bundle.e004d734044049fe8fe9.js → 7639.bundle.0147cdd1c23858221b62.js} +27 -25
  48. package/dist/7758.bundle.c8d106364298e7d288f0.js +3 -3
  49. package/dist/{8094.bundle.5c44190a325ac23e3e5c.js → 8094.bundle.148a66619607e37cbf19.js} +3 -4
  50. package/dist/{8305.bundle.ba43ed23edea2bf394b3.js → 8305.bundle.565339762503b9ae4f59.js} +57 -41
  51. package/dist/{85.bundle.a16e254910c60223df19.js → 85.bundle.b2365b2e4c3c6935f453.js} +3 -5
  52. package/dist/{8558.bundle.463ddb34a619cf47493e.js → 8558.bundle.9af6d13a22ddb44ea766.js} +60 -32
  53. package/dist/{8583.bundle.59c239cf891c2e10bf10.js → 8583.bundle.f51188077125da303398.js} +42 -39
  54. package/dist/{5448.bundle.9a36e001169ea3bfeb6c.js → 8665.bundle.dc56c125411422f9f686.js} +3753 -1424
  55. package/dist/{7412.bundle.aec4834a71fc27c4ce06.js → 9205.bundle.2a2f38a4ee23647f5fa4.js} +3413 -1271
  56. package/dist/{9845.bundle.31aec3fe7a5cdc247f4e.js → 9845.bundle.31f3e7e2d28fa6033ee5.js} +22 -14
  57. package/dist/{9862.bundle.3ca0ad5f54db87ccf91e.js → 9862.bundle.73ea2a7703bf1bb96275.js} +8 -6
  58. package/dist/{9927.bundle.f421cd167be94a7109f6.js → 9927.bundle.af31e6ce5cac195607fd.js} +19 -21
  59. package/dist/app-config.js +12 -0
  60. package/dist/{app.bundle.7df5bc1cd812bd602686.js → app.bundle.b2817894afde20b59bdb.js} +67903 -63389
  61. package/dist/app.bundle.css +1 -1
  62. package/dist/{compute.bundle.fdee4a0f193ee2e1b6da.js → compute.bundle.73440405025831e0e072.js} +10 -22
  63. package/dist/dicom-microscopy-viewer/dicomMicroscopyViewer.min.js +3254 -1792
  64. package/dist/dicom-microscopy-viewer/dicomMicroscopyViewer.min.js.map +1 -1
  65. package/dist/{histogram-worker.bundle.d4e40a8018d2698b072e.js → histogram-worker.bundle.5b679ce4142c803c80a4.js} +11 -23
  66. package/dist/index.html +1 -1
  67. package/dist/{interpolation.bundle.1938b79f9d6db363528a.js → interpolation.bundle.7554483d97f6119414f9.js} +14 -26
  68. package/dist/{polySeg.bundle.11f9746cd60c9811a412.js → polySeg.bundle.6373e24bd578ae0d41eb.js} +8 -20
  69. package/dist/sw.js +1 -1
  70. package/package.json +24 -24
@@ -1,7 +1,7 @@
1
- (globalThis["webpackChunk"] = globalThis["webpackChunk"] || []).push([[3353],{
1
+ (globalThis["webpackChunk"] = globalThis["webpackChunk"] || []).push([[6347],{
2
2
 
3
- /***/ 14041:
4
- /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
3
+ /***/ 22031
4
+ (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
5
5
 
6
6
  "use strict";
7
7
 
@@ -112,16 +112,16 @@ const {
112
112
  DicomMetaDictionary
113
113
  } = dcmjs_es/* data */.p;
114
114
  const FINDING = {
115
- CodingSchemeDesignator: "DCM",
116
- CodeValue: "121071"
115
+ CodingSchemeDesignator: 'DCM',
116
+ CodeValue: '121071'
117
117
  };
118
118
  const FINDING_SITE = {
119
- CodingSchemeDesignator: "SCT",
120
- CodeValue: "363698007"
119
+ CodingSchemeDesignator: 'SCT',
120
+ CodeValue: '363698007'
121
121
  };
122
122
  const FINDING_SITE_OLD = {
123
- CodingSchemeDesignator: "SRT",
124
- CodeValue: "G-C0E3"
123
+ CodingSchemeDesignator: 'SRT',
124
+ CodeValue: 'G-C0E3'
125
125
  };
126
126
  const codeValueMatch = (group, code, oldCode) => {
127
127
  const {
@@ -165,8 +165,8 @@ class MeasurementReport {
165
165
  const contentSequenceArr = toArray(ContentSequence);
166
166
  const findingGroup = contentSequenceArr.find(group => codeValueMatch(group, FINDING));
167
167
  const findingSiteGroups = contentSequenceArr.filter(group => codeValueMatch(group, FINDING_SITE, FINDING_SITE_OLD)) || [];
168
- const NUMGroup = contentSequenceArr.find(group => group.ValueType === "NUM");
169
- const SCOORDGroup = toArray(NUMGroup.ContentSequence).find(group => group.ValueType === "SCOORD");
168
+ const NUMGroup = contentSequenceArr.find(group => group.ValueType === 'NUM');
169
+ const SCOORDGroup = toArray(NUMGroup.ContentSequence).find(group => group.ValueType === 'SCOORD');
170
170
  const {
171
171
  ReferencedSOPSequence
172
172
  } = SCOORDGroup.ContentSequence;
@@ -208,16 +208,16 @@ class MeasurementReport {
208
208
  let allMeasurementGroups = [];
209
209
  const firstImageId = Object.keys(toolState)[0];
210
210
  if (!firstImageId) {
211
- throw new Error("No measurements provided.");
211
+ throw new Error('No measurements provided.');
212
212
  }
213
213
 
214
214
  /* Patient ID
215
- Warning - Missing attribute or value that would be needed to build DICOMDIR - Patient ID
216
- Warning - Missing attribute or value that would be needed to build DICOMDIR - Study Date
217
- Warning - Missing attribute or value that would be needed to build DICOMDIR - Study Time
218
- Warning - Missing attribute or value that would be needed to build DICOMDIR - Study ID
219
- */
220
- const generalSeriesModule = metadataProvider.get("generalSeriesModule", firstImageId);
215
+ Warning - Missing attribute or value that would be needed to build DICOMDIR - Patient ID
216
+ Warning - Missing attribute or value that would be needed to build DICOMDIR - Study Date
217
+ Warning - Missing attribute or value that would be needed to build DICOMDIR - Study Time
218
+ Warning - Missing attribute or value that would be needed to build DICOMDIR - Study ID
219
+ */
220
+ const generalSeriesModule = metadataProvider.get('generalSeriesModule', firstImageId);
221
221
 
222
222
  //const sopCommonModule = metadataProvider.get('sopCommonModule', firstImageId);
223
223
 
@@ -231,8 +231,8 @@ class MeasurementReport {
231
231
 
232
232
  // Loop through each image in the toolData
233
233
  Object.keys(toolState).forEach(imageId => {
234
- const sopCommonModule = metadataProvider.get("sopCommonModule", imageId);
235
- const frameNumber = metadataProvider.get("frameNumber", imageId);
234
+ const sopCommonModule = metadataProvider.get('sopCommonModule', imageId);
235
+ const frameNumber = metadataProvider.get('frameNumber', imageId);
236
236
  const toolData = toolState[imageId];
237
237
  const toolTypes = Object.keys(toolData);
238
238
  const ReferencedSOPSequence = {
@@ -271,26 +271,26 @@ class MeasurementReport {
271
271
  const _meta = {
272
272
  FileMetaInformationVersion: {
273
273
  Value: [fileMetaInformationVersionArray.buffer],
274
- vr: "OB"
274
+ vr: 'OB'
275
275
  },
276
276
  //MediaStorageSOPClassUID
277
277
  //MediaStorageSOPInstanceUID: sopCommonModule.sopInstanceUID,
278
278
  TransferSyntaxUID: {
279
- Value: ["1.2.840.10008.1.2.1"],
280
- vr: "UI"
279
+ Value: ['1.2.840.10008.1.2.1'],
280
+ vr: 'UI'
281
281
  },
282
282
  ImplementationClassUID: {
283
283
  Value: [DicomMetaDictionary.uid()],
284
284
  // TODO: could be git hash or other valid id
285
- vr: "UI"
285
+ vr: 'UI'
286
286
  },
287
287
  ImplementationVersionName: {
288
- Value: ["dcmjs"],
289
- vr: "SH"
288
+ Value: ['dcmjs'],
289
+ vr: 'SH'
290
290
  }
291
291
  };
292
292
  const _vrMap = {
293
- PixelData: "OW"
293
+ PixelData: 'OW'
294
294
  };
295
295
  derivationSourceDataset._meta = _meta;
296
296
  derivationSourceDataset._vrMap = _vrMap;
@@ -300,7 +300,7 @@ class MeasurementReport {
300
300
  // Merge the derived dataset with the content from the Measurement Report
301
301
  report.dataset = Object.assign(report.dataset, contentItem);
302
302
  report.dataset._meta = _meta;
303
- report.dataset.SpecificCharacterSet = "ISO_IR 192";
303
+ report.dataset.SpecificCharacterSet = 'ISO_IR 192';
304
304
  return report;
305
305
  }
306
306
 
@@ -314,12 +314,12 @@ class MeasurementReport {
314
314
  static generateToolState(dataset) {
315
315
  let hooks = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
316
316
  // For now, bail out if the dataset is not a TID1500 SR with length measurements
317
- if (dataset.ContentTemplateSequence.TemplateIdentifier !== "1500") {
318
- throw new Error("This package can currently only interpret DICOM SR TID 1500");
317
+ if (dataset.ContentTemplateSequence.TemplateIdentifier !== '1500') {
318
+ throw new Error('This package can currently only interpret DICOM SR TID 1500');
319
319
  }
320
- const REPORT = "Imaging Measurements";
321
- const GROUP = "Measurement Group";
322
- const TRACKING_IDENTIFIER = "Tracking Identifier";
320
+ const REPORT = 'Imaging Measurements';
321
+ const GROUP = 'Measurement Group';
322
+ const TRACKING_IDENTIFIER = 'Tracking Identifier';
323
323
 
324
324
  // Identify the Imaging Measurements
325
325
  const imagingMeasurementContent = toArray(dataset.ContentSequence).find(codeMeaningEquals(REPORT));
@@ -365,7 +365,7 @@ MeasurementReport.CORNERSTONE_TOOL_CLASSES_BY_TOOL_TYPE = {};
365
365
 
366
366
 
367
367
  ;// ../../../node_modules/@cornerstonejs/adapters/dist/esm/adapters/Cornerstone/cornerstone4Tag.js
368
- var CORNERSTONE_4_TAG = "cornerstoneTools@^4.0.0";
368
+ var CORNERSTONE_4_TAG = 'cornerstoneTools@^4.0.0';
369
369
 
370
370
 
371
371
 
@@ -377,7 +377,7 @@ var CORNERSTONE_4_TAG = "cornerstoneTools@^4.0.0";
377
377
  const {
378
378
  Length: TID300Length
379
379
  } = dcmjs_es/* utilities */.BF.TID300;
380
- const LENGTH = "Length";
380
+ const LENGTH = 'Length';
381
381
  class Length {
382
382
  // TODO: this function is required for all Cornerstone Tool Adapters, since it is called by MeasurementReport.
383
383
  static getMeasurementData(MeasurementGroup) {
@@ -414,7 +414,7 @@ class Length {
414
414
  const point1 = handles.start;
415
415
  const point2 = handles.end;
416
416
  const distance = tool.length;
417
- const trackingIdentifierTextValue = "cornerstoneTools@^4.0.0:Length";
417
+ const trackingIdentifierTextValue = 'cornerstoneTools@^4.0.0:Length';
418
418
  return {
419
419
  point1,
420
420
  point2,
@@ -429,10 +429,10 @@ Length.toolType = LENGTH;
429
429
  Length.utilityToolType = LENGTH;
430
430
  Length.TID300Representation = TID300Length;
431
431
  Length.isValidCornerstoneTrackingIdentifier = TrackingIdentifier => {
432
- if (!TrackingIdentifier.includes(":")) {
432
+ if (!TrackingIdentifier.includes(':')) {
433
433
  return false;
434
434
  }
435
- const [cornerstone4Tag, toolType] = TrackingIdentifier.split(":");
435
+ const [cornerstone4Tag, toolType] = TrackingIdentifier.split(':');
436
436
  if (cornerstone4Tag !== CORNERSTONE_4_TAG) {
437
437
  return false;
438
438
  }
@@ -502,7 +502,7 @@ class FreehandRoi {
502
502
  area = 0,
503
503
  perimeter = 0
504
504
  } = cachedStats;
505
- const trackingIdentifierTextValue = "cornerstoneTools@^4.0.0:FreehandRoi";
505
+ const trackingIdentifierTextValue = 'cornerstoneTools@^4.0.0:FreehandRoi';
506
506
  return {
507
507
  points,
508
508
  area,
@@ -513,14 +513,14 @@ class FreehandRoi {
513
513
  };
514
514
  }
515
515
  }
516
- FreehandRoi.toolType = "FreehandRoi";
517
- FreehandRoi.utilityToolType = "FreehandRoi";
516
+ FreehandRoi.toolType = 'FreehandRoi';
517
+ FreehandRoi.utilityToolType = 'FreehandRoi';
518
518
  FreehandRoi.TID300Representation = TID300Polyline;
519
519
  FreehandRoi.isValidCornerstoneTrackingIdentifier = TrackingIdentifier => {
520
- if (!TrackingIdentifier.includes(":")) {
520
+ if (!TrackingIdentifier.includes(':')) {
521
521
  return false;
522
522
  }
523
- const [cornerstone4Tag, toolType] = TrackingIdentifier.split(":");
523
+ const [cornerstone4Tag, toolType] = TrackingIdentifier.split(':');
524
524
  if (cornerstone4Tag !== CORNERSTONE_4_TAG) {
525
525
  return false;
526
526
  }
@@ -540,11 +540,11 @@ MeasurementReport.registerTool(FreehandRoi);
540
540
  const {
541
541
  Bidirectional: TID300Bidirectional
542
542
  } = dcmjs_es/* utilities */.BF.TID300;
543
- const BIDIRECTIONAL = "Bidirectional";
544
- const LONG_AXIS = "Long Axis";
545
- const SHORT_AXIS = "Short Axis";
546
- const Bidirectional_FINDING = "121071";
547
- const Bidirectional_FINDING_SITE = "G-C0E3";
543
+ const BIDIRECTIONAL = 'Bidirectional';
544
+ const LONG_AXIS = 'Long Axis';
545
+ const SHORT_AXIS = 'Short Axis';
546
+ const Bidirectional_FINDING = '121071';
547
+ const Bidirectional_FINDING_SITE = 'G-C0E3';
548
548
  class Bidirectional {
549
549
  // TODO: this function is required for all Cornerstone Tool Adapters, since it is called by MeasurementReport.
550
550
  static getMeasurementData(MeasurementGroup) {
@@ -554,9 +554,9 @@ class Bidirectional {
554
554
  const findingGroup = toArray(ContentSequence).find(group => group.ConceptNameCodeSequence.CodeValue === Bidirectional_FINDING);
555
555
  const findingSiteGroups = toArray(ContentSequence).filter(group => group.ConceptNameCodeSequence.CodeValue === Bidirectional_FINDING_SITE);
556
556
  const longAxisNUMGroup = toArray(ContentSequence).find(group => group.ConceptNameCodeSequence.CodeMeaning === LONG_AXIS);
557
- const longAxisSCOORDGroup = toArray(longAxisNUMGroup.ContentSequence).find(group => group.ValueType === "SCOORD");
557
+ const longAxisSCOORDGroup = toArray(longAxisNUMGroup.ContentSequence).find(group => group.ValueType === 'SCOORD');
558
558
  const shortAxisNUMGroup = toArray(ContentSequence).find(group => group.ConceptNameCodeSequence.CodeMeaning === SHORT_AXIS);
559
- const shortAxisSCOORDGroup = toArray(shortAxisNUMGroup.ContentSequence).find(group => group.ValueType === "SCOORD");
559
+ const shortAxisSCOORDGroup = toArray(shortAxisNUMGroup.ContentSequence).find(group => group.ValueType === 'SCOORD');
560
560
  const {
561
561
  ReferencedSOPSequence
562
562
  } = longAxisSCOORDGroup.ContentSequence;
@@ -631,7 +631,7 @@ class Bidirectional {
631
631
  isCreating: false,
632
632
  longestDiameter,
633
633
  shortestDiameter,
634
- toolName: "Bidirectional",
634
+ toolName: 'Bidirectional',
635
635
  visible: true,
636
636
  finding: findingGroup ? findingGroup.ConceptCodeSequence : undefined,
637
637
  findingSites: findingSiteGroups.map(fsg => fsg.ConceptCodeSequence)
@@ -651,7 +651,7 @@ class Bidirectional {
651
651
  finding,
652
652
  findingSites
653
653
  } = tool;
654
- const trackingIdentifierTextValue = "cornerstoneTools@^4.0.0:Bidirectional";
654
+ const trackingIdentifierTextValue = 'cornerstoneTools@^4.0.0:Bidirectional';
655
655
  return {
656
656
  longAxis: {
657
657
  point1: start,
@@ -673,10 +673,10 @@ Bidirectional.toolType = BIDIRECTIONAL;
673
673
  Bidirectional.utilityToolType = BIDIRECTIONAL;
674
674
  Bidirectional.TID300Representation = TID300Bidirectional;
675
675
  Bidirectional.isValidCornerstoneTrackingIdentifier = TrackingIdentifier => {
676
- if (!TrackingIdentifier.includes(":")) {
676
+ if (!TrackingIdentifier.includes(':')) {
677
677
  return false;
678
678
  }
679
- const [cornerstone4Tag, toolType] = TrackingIdentifier.split(":");
679
+ const [cornerstone4Tag, toolType] = TrackingIdentifier.split(':');
680
680
  if (cornerstone4Tag !== CORNERSTONE_4_TAG) {
681
681
  return false;
682
682
  }
@@ -694,7 +694,7 @@ MeasurementReport.registerTool(Bidirectional);
694
694
  const {
695
695
  Ellipse: TID300Ellipse
696
696
  } = dcmjs_es/* utilities */.BF.TID300;
697
- const ELLIPTICALROI = "EllipticalRoi";
697
+ const ELLIPTICALROI = 'EllipticalRoi';
698
698
  class EllipticalRoi {
699
699
  // TODO: this function is required for all Cornerstone Tool Adapters, since it is called by MeasurementReport.
700
700
  static getMeasurementData(MeasurementGroup) {
@@ -837,7 +837,7 @@ class EllipticalRoi {
837
837
  y: center.y
838
838
  });
839
839
  }
840
- const trackingIdentifierTextValue = "cornerstoneTools@^4.0.0:EllipticalRoi";
840
+ const trackingIdentifierTextValue = 'cornerstoneTools@^4.0.0:EllipticalRoi';
841
841
  return {
842
842
  area,
843
843
  points,
@@ -851,10 +851,10 @@ EllipticalRoi.toolType = ELLIPTICALROI;
851
851
  EllipticalRoi.utilityToolType = ELLIPTICALROI;
852
852
  EllipticalRoi.TID300Representation = TID300Ellipse;
853
853
  EllipticalRoi.isValidCornerstoneTrackingIdentifier = TrackingIdentifier => {
854
- if (!TrackingIdentifier.includes(":")) {
854
+ if (!TrackingIdentifier.includes(':')) {
855
855
  return false;
856
856
  }
857
- const [cornerstone4Tag, toolType] = TrackingIdentifier.split(":");
857
+ const [cornerstone4Tag, toolType] = TrackingIdentifier.split(':');
858
858
  if (cornerstone4Tag !== CORNERSTONE_4_TAG) {
859
859
  return false;
860
860
  }
@@ -872,7 +872,7 @@ MeasurementReport.registerTool(EllipticalRoi);
872
872
  const {
873
873
  Circle: TID300Circle
874
874
  } = dcmjs_es/* utilities */.BF.TID300;
875
- const CIRCLEROI = "CircleRoi";
875
+ const CIRCLEROI = 'CircleRoi';
876
876
  class CircleRoi {
877
877
  /** Gets the measurement data for cornerstone, given DICOM SR measurement data. */
878
878
  static getMeasurementData(MeasurementGroup) {
@@ -953,7 +953,7 @@ class CircleRoi {
953
953
  const points = [];
954
954
  points.push(center);
955
955
  points.push(end);
956
- const trackingIdentifierTextValue = "cornerstoneTools@^4.0.0:CircleRoi";
956
+ const trackingIdentifierTextValue = 'cornerstoneTools@^4.0.0:CircleRoi';
957
957
  return {
958
958
  area,
959
959
  perimeter,
@@ -969,10 +969,10 @@ CircleRoi.toolType = CIRCLEROI;
969
969
  CircleRoi.utilityToolType = CIRCLEROI;
970
970
  CircleRoi.TID300Representation = TID300Circle;
971
971
  CircleRoi.isValidCornerstoneTrackingIdentifier = TrackingIdentifier => {
972
- if (!TrackingIdentifier.includes(":")) {
972
+ if (!TrackingIdentifier.includes(':')) {
973
973
  return false;
974
974
  }
975
- const [cornerstone4Tag, toolType] = TrackingIdentifier.split(":");
975
+ const [cornerstone4Tag, toolType] = TrackingIdentifier.split(':');
976
976
  if (cornerstone4Tag !== CORNERSTONE_4_TAG) {
977
977
  return false;
978
978
  }
@@ -990,8 +990,8 @@ MeasurementReport.registerTool(CircleRoi);
990
990
  const {
991
991
  Point: TID300Point
992
992
  } = dcmjs_es/* utilities */.BF.TID300;
993
- const ARROW_ANNOTATE = "ArrowAnnotate";
994
- const CORNERSTONEFREETEXT = "CORNERSTONEFREETEXT";
993
+ const ARROW_ANNOTATE = 'ArrowAnnotate';
994
+ const CORNERSTONEFREETEXT = 'CORNERSTONEFREETEXT';
995
995
  class ArrowAnnotate {
996
996
  static getMeasurementData(MeasurementGroup) {
997
997
  const {
@@ -1052,7 +1052,7 @@ class ArrowAnnotate {
1052
1052
  if (!finding || finding.CodeValue !== CORNERSTONEFREETEXT) {
1053
1053
  finding = {
1054
1054
  CodeValue: CORNERSTONEFREETEXT,
1055
- CodingSchemeDesignator: "CST4",
1055
+ CodingSchemeDesignator: 'CST4',
1056
1056
  CodeMeaning: tool.label
1057
1057
  };
1058
1058
  }
@@ -1064,10 +1064,10 @@ ArrowAnnotate.toolType = ARROW_ANNOTATE;
1064
1064
  ArrowAnnotate.utilityToolType = ARROW_ANNOTATE;
1065
1065
  ArrowAnnotate.TID300Representation = TID300Point;
1066
1066
  ArrowAnnotate.isValidCornerstoneTrackingIdentifier = TrackingIdentifier => {
1067
- if (!TrackingIdentifier.includes(":")) {
1067
+ if (!TrackingIdentifier.includes(':')) {
1068
1068
  return false;
1069
1069
  }
1070
- const [cornerstone4Tag, toolType] = TrackingIdentifier.split(":");
1070
+ const [cornerstone4Tag, toolType] = TrackingIdentifier.split(':');
1071
1071
  if (cornerstone4Tag !== CORNERSTONE_4_TAG) {
1072
1072
  return false;
1073
1073
  }
@@ -1085,7 +1085,7 @@ MeasurementReport.registerTool(ArrowAnnotate);
1085
1085
  const {
1086
1086
  CobbAngle: TID300CobbAngle
1087
1087
  } = dcmjs_es/* utilities */.BF.TID300;
1088
- const COBB_ANGLE = "CobbAngle";
1088
+ const COBB_ANGLE = 'CobbAngle';
1089
1089
  class CobbAngle {
1090
1090
  // TODO: this function is required for all Cornerstone Tool Adapters, since it is called by MeasurementReport.
1091
1091
  static getMeasurementData(MeasurementGroup) {
@@ -1132,7 +1132,7 @@ class CobbAngle {
1132
1132
  const point3 = handles.start2;
1133
1133
  const point4 = handles.end2;
1134
1134
  const rAngle = tool.rAngle;
1135
- const trackingIdentifierTextValue = "cornerstoneTools@^4.0.0:CobbAngle";
1135
+ const trackingIdentifierTextValue = 'cornerstoneTools@^4.0.0:CobbAngle';
1136
1136
  return {
1137
1137
  point1,
1138
1138
  point2,
@@ -1149,10 +1149,10 @@ CobbAngle.toolType = COBB_ANGLE;
1149
1149
  CobbAngle.utilityToolType = COBB_ANGLE;
1150
1150
  CobbAngle.TID300Representation = TID300CobbAngle;
1151
1151
  CobbAngle.isValidCornerstoneTrackingIdentifier = TrackingIdentifier => {
1152
- if (!TrackingIdentifier.includes(":")) {
1152
+ if (!TrackingIdentifier.includes(':')) {
1153
1153
  return false;
1154
1154
  }
1155
- const [cornerstone4Tag, toolType] = TrackingIdentifier.split(":");
1155
+ const [cornerstone4Tag, toolType] = TrackingIdentifier.split(':');
1156
1156
  if (cornerstone4Tag !== CORNERSTONE_4_TAG) {
1157
1157
  return false;
1158
1158
  }
@@ -1170,7 +1170,7 @@ MeasurementReport.registerTool(CobbAngle);
1170
1170
  const {
1171
1171
  Angle: TID300Angle
1172
1172
  } = dcmjs_es/* utilities */.BF.TID300;
1173
- const ANGLE = "Angle";
1173
+ const ANGLE = 'Angle';
1174
1174
  class Angle {
1175
1175
  /**
1176
1176
  * Generate TID300 measurement data for a plane angle measurement - use a Angle, but label it as Angle
@@ -1212,7 +1212,7 @@ class Angle {
1212
1212
  const point3 = handles.middle;
1213
1213
  const point4 = handles.end;
1214
1214
  const rAngle = tool.rAngle;
1215
- const trackingIdentifierTextValue = "cornerstoneTools@^4.0.0:Angle";
1215
+ const trackingIdentifierTextValue = 'cornerstoneTools@^4.0.0:Angle';
1216
1216
  return {
1217
1217
  point1,
1218
1218
  point2,
@@ -1229,10 +1229,10 @@ Angle.toolType = ANGLE;
1229
1229
  Angle.utilityToolType = ANGLE;
1230
1230
  Angle.TID300Representation = TID300Angle;
1231
1231
  Angle.isValidCornerstoneTrackingIdentifier = TrackingIdentifier => {
1232
- if (!TrackingIdentifier.includes(":")) {
1232
+ if (!TrackingIdentifier.includes(':')) {
1233
1233
  return false;
1234
1234
  }
1235
- const [cornerstone4Tag, toolType] = TrackingIdentifier.split(":");
1235
+ const [cornerstone4Tag, toolType] = TrackingIdentifier.split(':');
1236
1236
  if (cornerstone4Tag !== CORNERSTONE_4_TAG) {
1237
1237
  return false;
1238
1238
  }
@@ -1305,7 +1305,7 @@ class RectangleRoi {
1305
1305
  area,
1306
1306
  perimeter
1307
1307
  } = cachedStats;
1308
- const trackingIdentifierTextValue = "cornerstoneTools@^4.0.0:RectangleRoi";
1308
+ const trackingIdentifierTextValue = 'cornerstoneTools@^4.0.0:RectangleRoi';
1309
1309
  return {
1310
1310
  points,
1311
1311
  area,
@@ -1316,14 +1316,14 @@ class RectangleRoi {
1316
1316
  };
1317
1317
  }
1318
1318
  }
1319
- RectangleRoi.toolType = "RectangleRoi";
1320
- RectangleRoi.utilityToolType = "RectangleRoi";
1319
+ RectangleRoi.toolType = 'RectangleRoi';
1320
+ RectangleRoi.utilityToolType = 'RectangleRoi';
1321
1321
  RectangleRoi.TID300Representation = RectangleRoi_TID300Polyline;
1322
1322
  RectangleRoi.isValidCornerstoneTrackingIdentifier = TrackingIdentifier => {
1323
- if (!TrackingIdentifier.includes(":")) {
1323
+ if (!TrackingIdentifier.includes(':')) {
1324
1324
  return false;
1325
1325
  }
1326
- const [cornerstone4Tag, toolType] = TrackingIdentifier.split(":");
1326
+ const [cornerstone4Tag, toolType] = TrackingIdentifier.split(':');
1327
1327
  if (cornerstone4Tag !== CORNERSTONE_4_TAG) {
1328
1328
  return false;
1329
1329
  }
@@ -1436,9 +1436,9 @@ function generateSegmentation(images, brushData) {
1436
1436
  dims.xy = dims.x * dims.y;
1437
1437
  const numSegments = _getSegCount(seg, segments);
1438
1438
  if (!numSegments) {
1439
- throw new Error("No segments to export!");
1439
+ throw new Error('No segments to export!');
1440
1440
  }
1441
- const isMultiframe = image0.imageId.includes("?frame");
1441
+ const isMultiframe = image0.imageId.includes('?frame');
1442
1442
  const seg = _createSegFromImages(images, isMultiframe, options);
1443
1443
  const {
1444
1444
  referencedFramesPerSegment,
@@ -1540,9 +1540,9 @@ function generateToolState(imageIds, arrayBuffer, metadataProvider) {
1540
1540
  const dataset = Segmentation_3X_DicomMetaDictionary.naturalizeDataset(dicomData.dict);
1541
1541
  dataset._meta = Segmentation_3X_DicomMetaDictionary.namifyDataset(dicomData.meta);
1542
1542
  const multiframe = Segmentation_3X_Normalizer.normalizeToDataset([dataset]);
1543
- const imagePlaneModule = metadataProvider.get("imagePlaneModule", imageIds[0]);
1543
+ const imagePlaneModule = metadataProvider.get('imagePlaneModule', imageIds[0]);
1544
1544
  if (!imagePlaneModule) {
1545
- console.warn("Insufficient metadata, imagePlaneModule missing.");
1545
+ console.warn('Insufficient metadata, imagePlaneModule missing.');
1546
1546
  }
1547
1547
  const ImageOrientationPatient = Array.isArray(imagePlaneModule.rowCosines) ? [...imagePlaneModule.rowCosines, ...imagePlaneModule.columnCosines] : [imagePlaneModule.rowCosines.x, imagePlaneModule.rowCosines.y, imagePlaneModule.rowCosines.z, imagePlaneModule.columnCosines.x, imagePlaneModule.columnCosines.y, imagePlaneModule.columnCosines.z];
1548
1548
 
@@ -1593,17 +1593,17 @@ function generateToolState(imageIds, arrayBuffer, metadataProvider) {
1593
1593
  */
1594
1594
  function unpackPixelData(multiframe) {
1595
1595
  const segType = multiframe.SegmentationType;
1596
- if (segType === "BINARY") {
1596
+ if (segType === 'BINARY') {
1597
1597
  return BitArray.unpack(multiframe.PixelData);
1598
1598
  }
1599
1599
  const pixelData = new Uint8Array(multiframe.PixelData);
1600
1600
  const max = multiframe.MaximumFractionalValue;
1601
1601
  const onlyMaxAndZero = pixelData.find(element => element !== 0 && element !== max) === undefined;
1602
1602
  if (!onlyMaxAndZero) {
1603
- dcmjs_es/* log */.Rm.warn("This is a fractional segmentation, which is not currently supported.");
1603
+ dcmjs_es/* log */.Rm.warn('This is a fractional segmentation, which is not currently supported.');
1604
1604
  return;
1605
1605
  }
1606
- dcmjs_es/* log */.Rm.warn("This segmentation object is actually binary... processing as such.");
1606
+ dcmjs_es/* log */.Rm.warn('This segmentation object is actually binary... processing as such.');
1607
1607
  return pixelData;
1608
1608
  }
1609
1609
 
@@ -1669,7 +1669,7 @@ function getImageIdOfSourceImage(SourceImageSequence, imageIds, metadataProvider
1669
1669
  */
1670
1670
  function getImageIdOfReferencedSingleFramedSOPInstance(sopInstanceUid, imageIds, metadataProvider) {
1671
1671
  return imageIds.find(imageId => {
1672
- const sopCommonModule = metadataProvider.get("sopCommonModule", imageId);
1672
+ const sopCommonModule = metadataProvider.get('sopCommonModule', imageId);
1673
1673
  if (!sopCommonModule) {
1674
1674
  return;
1675
1675
  }
@@ -1690,11 +1690,11 @@ function getImageIdOfReferencedSingleFramedSOPInstance(sopInstanceUid, imageIds,
1690
1690
  */
1691
1691
  function getImageIdOfReferencedFrame(sopInstanceUid, frameNumber, imageIds, metadataProvider) {
1692
1692
  const imageId = imageIds.find(imageId => {
1693
- const sopCommonModule = metadataProvider.get("sopCommonModule", imageId);
1693
+ const sopCommonModule = metadataProvider.get('sopCommonModule', imageId);
1694
1694
  if (!sopCommonModule) {
1695
1695
  return;
1696
1696
  }
1697
- const imageIdFrameNumber = Number(imageId.split("frame=")[1]);
1697
+ const imageIdFrameNumber = Number(imageId.split('frame=')[1]);
1698
1698
  return (
1699
1699
  //frameNumber is zero indexed for cornerstoneDICOMImageLoader image Ids.
1700
1700
  sopCommonModule.sopInstanceUID === sopInstanceUid && imageIdFrameNumber === frameNumber - 1
@@ -1967,19 +1967,19 @@ function fillSegmentation(segmentation, inputLabelmaps3D) {
1967
1967
  // to be 1 for BINARY. This is not ideal and there should be a better format for compression in this manner
1968
1968
  // added to the standard.
1969
1969
  segmentation.assignToDataset({
1970
- BitsAllocated: "8",
1971
- BitsStored: "8",
1972
- HighBit: "7",
1973
- SegmentationType: "FRACTIONAL",
1974
- SegmentationFractionalType: "PROBABILITY",
1975
- MaximumFractionalValue: "255"
1970
+ BitsAllocated: '8',
1971
+ BitsStored: '8',
1972
+ HighBit: '7',
1973
+ SegmentationType: 'FRACTIONAL',
1974
+ SegmentationFractionalType: 'PROBABILITY',
1975
+ MaximumFractionalValue: '255'
1976
1976
  });
1977
1977
  segmentation.dataset._meta.TransferSyntaxUID = {
1978
- Value: ["1.2.840.10008.1.2.5"],
1979
- vr: "UI"
1978
+ Value: ['1.2.840.10008.1.2.5'],
1979
+ vr: 'UI'
1980
1980
  };
1981
- segmentation.dataset.SpecificCharacterSet = "ISO_IR 192";
1982
- segmentation.dataset._vrMap.PixelData = "OB";
1981
+ segmentation.dataset.SpecificCharacterSet = 'ISO_IR 192';
1982
+ segmentation.dataset._vrMap.PixelData = 'OB';
1983
1983
  segmentation.dataset.PixelData = rleEncodedFrames;
1984
1984
  } else {
1985
1985
  // If no rleEncoding, at least bitpack the data.
@@ -2039,11 +2039,11 @@ async function Segmentation_4X_generateToolState(referencedImageIds, arrayBuffer
2039
2039
  const dataset = Segmentation_4X_DicomMetaDictionary.naturalizeDataset(dicomData.dict);
2040
2040
  dataset._meta = Segmentation_4X_DicomMetaDictionary.namifyDataset(dicomData.meta);
2041
2041
  const multiframe = Segmentation_4X_Normalizer.normalizeToDataset([dataset]);
2042
- const imagePlaneModule = metadataProvider.get("imagePlaneModule", referencedImageIds[0]);
2043
- const generalSeriesModule = metadataProvider.get("generalSeriesModule", referencedImageIds[0]);
2042
+ const imagePlaneModule = metadataProvider.get('imagePlaneModule', referencedImageIds[0]);
2043
+ const generalSeriesModule = metadataProvider.get('generalSeriesModule', referencedImageIds[0]);
2044
2044
  const SeriesInstanceUID = generalSeriesModule.seriesInstanceUID;
2045
2045
  if (!imagePlaneModule) {
2046
- console.warn("Insufficient metadata, imagePlaneModule missing.");
2046
+ console.warn('Insufficient metadata, imagePlaneModule missing.');
2047
2047
  }
2048
2048
  const ImageOrientationPatient = Array.isArray(imagePlaneModule.rowCosines) ? [...imagePlaneModule.rowCosines, ...imagePlaneModule.columnCosines] : [imagePlaneModule.rowCosines.x, imagePlaneModule.rowCosines.y, imagePlaneModule.rowCosines.z, imagePlaneModule.columnCosines.x, imagePlaneModule.columnCosines.y, imagePlaneModule.columnCosines.z];
2049
2049
 
@@ -2054,11 +2054,11 @@ async function Segmentation_4X_generateToolState(referencedImageIds, arrayBuffer
2054
2054
  const TransferSyntaxUID = multiframe._meta.TransferSyntaxUID.Value[0];
2055
2055
  let pixelData;
2056
2056
  let pixelDataChunks;
2057
- if (TransferSyntaxUID === "1.2.840.10008.1.2.5") {
2057
+ if (TransferSyntaxUID === '1.2.840.10008.1.2.5') {
2058
2058
  const rleEncodedFrames = Array.isArray(multiframe.PixelData) ? multiframe.PixelData : [multiframe.PixelData];
2059
2059
  pixelData = decode(rleEncodedFrames, multiframe.Rows, multiframe.Columns);
2060
2060
  if (multiframe.BitsStored === 1) {
2061
- console.warn("No implementation for rle + bitbacking.");
2061
+ console.warn('No implementation for rle + bitbacking.');
2062
2062
  return;
2063
2063
  }
2064
2064
 
@@ -2069,7 +2069,7 @@ async function Segmentation_4X_generateToolState(referencedImageIds, arrayBuffer
2069
2069
  maxBytesPerChunk
2070
2070
  });
2071
2071
  if (!pixelDataChunks) {
2072
- throw new Error("Fractional segmentations are not yet supported");
2072
+ throw new Error('Fractional segmentations are not yet supported');
2073
2073
  }
2074
2074
  }
2075
2075
  const orientation = checkOrientation(multiframe, validOrientations, [imagePlaneModule.rows, imagePlaneModule.columns, referencedImageIds.length], tolerance);
@@ -2080,7 +2080,7 @@ async function Segmentation_4X_generateToolState(referencedImageIds, arrayBuffer
2080
2080
  const sopUIDImageIdIndexMap = referencedImageIds.reduce((acc, imageId) => {
2081
2081
  const {
2082
2082
  sopInstanceUID
2083
- } = metadataProvider.get("generalImageModule", imageId);
2083
+ } = metadataProvider.get('generalImageModule', imageId);
2084
2084
  acc[sopInstanceUID] = imageId;
2085
2085
  return acc;
2086
2086
  }, {});
@@ -2090,25 +2090,25 @@ async function Segmentation_4X_generateToolState(referencedImageIds, arrayBuffer
2090
2090
  }
2091
2091
  let insertFunction;
2092
2092
  switch (orientation) {
2093
- case "Planar":
2093
+ case 'Planar':
2094
2094
  if (overlapping) {
2095
2095
  insertFunction = insertOverlappingPixelDataPlanar;
2096
2096
  } else {
2097
2097
  insertFunction = insertPixelDataPlanar;
2098
2098
  }
2099
2099
  break;
2100
- case "Perpendicular":
2100
+ case 'Perpendicular':
2101
2101
  //insertFunction = insertPixelDataPerpendicular;
2102
- throw new Error("Segmentations orthogonal to the acquisition plane of the source data are not yet supported.");
2103
- case "Oblique":
2104
- throw new Error("Segmentations oblique to the acquisition plane of the source data are not yet supported.");
2102
+ throw new Error('Segmentations orthogonal to the acquisition plane of the source data are not yet supported.');
2103
+ case 'Oblique':
2104
+ throw new Error('Segmentations oblique to the acquisition plane of the source data are not yet supported.');
2105
2105
  }
2106
2106
 
2107
2107
  /* if SEGs are overlapping:
2108
- 1) the labelmapBuffer will contain M volumes which have non-overlapping segments;
2109
- 2) segmentsOnFrame will have M * numberOfFrames values to track in which labelMap are the segments;
2110
- 3) insertFunction will return the number of LabelMaps
2111
- 4) generateToolState return is an array*/
2108
+ 1) the labelmapBuffer will contain M volumes which have non-overlapping segments;
2109
+ 2) segmentsOnFrame will have M * numberOfFrames values to track in which labelMap are the segments;
2110
+ 3) insertFunction will return the number of LabelMaps
2111
+ 4) generateToolState return is an array*/
2112
2112
 
2113
2113
  const segmentsOnFrameArray = [];
2114
2114
  segmentsOnFrameArray[0] = [];
@@ -2121,7 +2121,7 @@ async function Segmentation_4X_generateToolState(referencedImageIds, arrayBuffer
2121
2121
  // a function for each imageId in the for loop.
2122
2122
  const imageIdMaps = referencedImageIds.reduce((acc, curr, index) => {
2123
2123
  acc.indices[curr] = index;
2124
- acc.metadata[curr] = metadataProvider.get("instance", curr);
2124
+ acc.metadata[curr] = metadataProvider.get('instance', curr);
2125
2125
  return acc;
2126
2126
  }, {
2127
2127
  indices: {},
@@ -2372,7 +2372,7 @@ function findReferenceSourceImageId(multiframe, frameSegment, imageIds, metadata
2372
2372
  }
2373
2373
  }
2374
2374
  } else if (SourceImageSequence && SourceImageSequence.length !== 0) {
2375
- console.warn("DerivationImageSequence not present, using SourceImageSequence assuming SEG has the same geometry as the source image.");
2375
+ console.warn('DerivationImageSequence not present, using SourceImageSequence assuming SEG has the same geometry as the source image.');
2376
2376
  frameSourceImageSequence = SourceImageSequence[frameSegment];
2377
2377
  }
2378
2378
  if (frameSourceImageSequence) {
@@ -2417,12 +2417,12 @@ function checkSEGsOverlapping(pixelData, multiframe, imageIds, validOrientations
2417
2417
  for (let frameSegment = 0; frameSegment < groupsLen; ++frameSegment) {
2418
2418
  const segmentIndex = getSegmentIndex(multiframe, frameSegment);
2419
2419
  if (segmentIndex === undefined) {
2420
- console.warn("Could not retrieve the segment index for frame segment " + frameSegment + ", skipping this frame.");
2420
+ console.warn('Could not retrieve the segment index for frame segment ' + frameSegment + ', skipping this frame.');
2421
2421
  continue;
2422
2422
  }
2423
2423
  const imageId = findReferenceSourceImageId(multiframe, frameSegment, imageIds, metadataProvider, tolerance, sopUIDImageIdIndexMap);
2424
2424
  if (!imageId) {
2425
- console.warn("Image not present in stack, can't import frame : " + frameSegment + ".");
2425
+ console.warn("Image not present in stack, can't import frame : " + frameSegment + '.');
2426
2426
  continue;
2427
2427
  }
2428
2428
  const imageIdIndex = imageIds.findIndex(element => element === imageId);
@@ -2446,7 +2446,7 @@ function checkSEGsOverlapping(pixelData, multiframe, imageIds, validOrientations
2446
2446
  const pixelDataI2D = ndarray_default()(view, [Rows, Columns]);
2447
2447
  const alignedPixelDataI = Segmentation_4X_alignPixelDataWithSourceData(pixelDataI2D, ImageOrientationPatientI, validOrientations, tolerance);
2448
2448
  if (!alignedPixelDataI) {
2449
- console.warn("Individual SEG frames are out of plane with respect to the first SEG frame, this is not yet supported, skipping this frame.");
2449
+ console.warn('Individual SEG frames are out of plane with respect to the first SEG frame, this is not yet supported, skipping this frame.');
2450
2450
  continue;
2451
2451
  }
2452
2452
  const data = alignedPixelDataI.data;
@@ -2497,7 +2497,7 @@ function insertOverlappingPixelDataPlanar(segmentsOnFrame, segmentsOnFrameArray,
2497
2497
  const PerFrameFunctionalGroups = PerFrameFunctionalGroupsSequence[i];
2498
2498
  const segmentIndex = getSegmentIndex(multiframe, i);
2499
2499
  if (segmentIndex === undefined) {
2500
- throw new Error("Could not retrieve the segment index. Aborting segmentation loading.");
2500
+ throw new Error('Could not retrieve the segment index. Aborting segmentation loading.');
2501
2501
  }
2502
2502
  if (segmentIndex !== segmentIndexToProcess) {
2503
2503
  continue;
@@ -2511,16 +2511,16 @@ function insertOverlappingPixelDataPlanar(segmentsOnFrame, segmentsOnFrameArray,
2511
2511
  const pixelDataI2D = ndarray_default()(view, [Rows, Columns]);
2512
2512
  const alignedPixelDataI = Segmentation_4X_alignPixelDataWithSourceData(pixelDataI2D, ImageOrientationPatientI, validOrientations, tolerance);
2513
2513
  if (!alignedPixelDataI) {
2514
- throw new Error("Individual SEG frames are out of plane with respect to the first SEG frame. " + "This is not yet supported. Aborting segmentation loading.");
2514
+ throw new Error('Individual SEG frames are out of plane with respect to the first SEG frame. ' + 'This is not yet supported. Aborting segmentation loading.');
2515
2515
  }
2516
2516
  const imageId = findReferenceSourceImageId(multiframe, i, imageIds, metadataProvider, tolerance, sopUIDImageIdIndexMap);
2517
2517
  if (!imageId) {
2518
- console.warn("Image not present in stack, can't import frame : " + i + ".");
2518
+ console.warn("Image not present in stack, can't import frame : " + i + '.');
2519
2519
  continue;
2520
2520
  }
2521
- const sourceImageMetadata = metadataProvider.get("instance", imageId);
2521
+ const sourceImageMetadata = metadataProvider.get('instance', imageId);
2522
2522
  if (Rows !== sourceImageMetadata.Rows || Columns !== sourceImageMetadata.Columns) {
2523
- throw new Error("Individual SEG frames have different geometry dimensions (Rows and Columns) " + "respect to the source image reference frame. This is not yet supported. " + "Aborting segmentation loading. ");
2523
+ throw new Error('Individual SEG frames have different geometry dimensions (Rows and Columns) ' + 'respect to the source image reference frame. This is not yet supported. ' + 'Aborting segmentation loading. ');
2524
2524
  }
2525
2525
  const imageIdIndex = imageIds.findIndex(element => element === imageId);
2526
2526
  const byteOffset = sliceLength * imageIdIndex * TypedArrayConstructor.BYTES_PER_ELEMENT;
@@ -2602,23 +2602,23 @@ function insertPixelDataPlanar(segmentsOnFrame, segmentsOnFrameArray, labelmapBu
2602
2602
  const pixelDataI2D = ndarray_default()(view, [Rows, Columns]);
2603
2603
  const alignedPixelDataI = Segmentation_4X_alignPixelDataWithSourceData(pixelDataI2D, ImageOrientationPatientI, validOrientations, tolerance);
2604
2604
  if (!alignedPixelDataI) {
2605
- throw new Error("Individual SEG frames are out of plane with respect to the first SEG frame. " + "This is not yet supported. Aborting segmentation loading.");
2605
+ throw new Error('Individual SEG frames are out of plane with respect to the first SEG frame. ' + 'This is not yet supported. Aborting segmentation loading.');
2606
2606
  }
2607
2607
  const segmentIndex = getSegmentIndex(multiframe, i);
2608
2608
  if (segmentIndex === undefined) {
2609
- throw new Error("Could not retrieve the segment index. Aborting segmentation loading.");
2609
+ throw new Error('Could not retrieve the segment index. Aborting segmentation loading.');
2610
2610
  }
2611
2611
  if (!segmentsPixelIndices.has(segmentIndex)) {
2612
2612
  segmentsPixelIndices.set(segmentIndex, {});
2613
2613
  }
2614
2614
  const imageId = findReferenceSourceImageId(multiframe, i, imageIds, metadataProvider, tolerance, sopUIDImageIdIndexMap);
2615
2615
  if (!imageId) {
2616
- console.warn("Image not present in stack, can't import frame : " + i + ".");
2616
+ console.warn("Image not present in stack, can't import frame : " + i + '.');
2617
2617
  continue;
2618
2618
  }
2619
2619
  const sourceImageMetadata = imageIdMaps.metadata[imageId];
2620
2620
  if (Rows !== sourceImageMetadata.Rows || Columns !== sourceImageMetadata.Columns) {
2621
- throw new Error("Individual SEG frames have different geometry dimensions (Rows and Columns) " + "respect to the source image reference frame. This is not yet supported. " + "Aborting segmentation loading. ");
2621
+ throw new Error('Individual SEG frames have different geometry dimensions (Rows and Columns) ' + 'respect to the source image reference frame. This is not yet supported. ' + 'Aborting segmentation loading. ');
2622
2622
  }
2623
2623
  const imageIdIndex = imageIdMaps.indices[imageId];
2624
2624
  const byteOffset = sliceLength * imageIdIndex * TypedArrayConstructor.BYTES_PER_ELEMENT;
@@ -2684,15 +2684,15 @@ function Segmentation_4X_unpackPixelData(multiframe, options) {
2684
2684
  data = multiframe.PixelData;
2685
2685
  }
2686
2686
  if (data === undefined) {
2687
- dcmjs_es/* log */.Rm.error("This segmentation pixelData is undefined.");
2687
+ dcmjs_es/* log */.Rm.error('This segmentation pixelData is undefined.');
2688
2688
  }
2689
- if (segType === "BINARY") {
2689
+ if (segType === 'BINARY') {
2690
2690
  // For extreme big data, we can't unpack the data at once and we need to
2691
2691
  // chunk it and unpack each chunk separately.
2692
2692
  // MAX 2GB is the limit right now to allocate a buffer
2693
2693
  return getUnpackedChunks(data, options.maxBytesPerChunk);
2694
2694
  }
2695
- if (segType === "LABELMAP") {
2695
+ if (segType === 'LABELMAP') {
2696
2696
  // For LABELMAP, we can return the data as is, since it is already in a
2697
2697
  // format that Cornerstone can handle. Also here we are returning the
2698
2698
  // whole data at once, since the storage is more efficent than BINARY mode
@@ -2711,7 +2711,7 @@ function Segmentation_4X_unpackPixelData(multiframe, options) {
2711
2711
  // This is a fractional segmentation, which is not currently supported.
2712
2712
  return;
2713
2713
  }
2714
- dcmjs_es/* log */.Rm.warn("This segmentation object is actually binary... processing as such.");
2714
+ dcmjs_es/* log */.Rm.warn('This segmentation object is actually binary... processing as such.');
2715
2715
  return pixelData;
2716
2716
  }
2717
2717
  function getUnpackedChunks(data, maxBytesPerChunk) {
@@ -2750,15 +2750,15 @@ function getImageIdOfSourceImageBySourceImageSequence(SourceImageSequence, sopUI
2750
2750
  return undefined;
2751
2751
  }
2752
2752
  if (ReferencedFrameNumber !== undefined) {
2753
- if (baseImageId.includes("frames/")) {
2753
+ if (baseImageId.includes('frames/')) {
2754
2754
  return baseImageId.replace(/frames\/\d+/, `frames/${ReferencedFrameNumber}`);
2755
- } else if (baseImageId.includes("dicomfile:")) {
2755
+ } else if (baseImageId.includes('dicomfile:')) {
2756
2756
  // dicomfile base 1, despite having frame=
2757
2757
  return baseImageId.replace(/frame=\d+/, `frame=${ReferencedFrameNumber}`);
2758
- } else if (baseImageId.includes("frame=")) {
2758
+ } else if (baseImageId.includes('frame=')) {
2759
2759
  return baseImageId.replace(/frame=\d+/, `frame=${ReferencedFrameNumber - 1}`);
2760
2760
  } else {
2761
- if (baseImageId.includes("wadors:")) {
2761
+ if (baseImageId.includes('wadors:')) {
2762
2762
  return `${baseImageId}/frames/${ReferencedFrameNumber}`;
2763
2763
  } else {
2764
2764
  return `${baseImageId}?frame=${ReferencedFrameNumber - 1}`;
@@ -2797,7 +2797,7 @@ function getImageIdOfSourceImagebyGeometry(ReferencedSeriesInstanceUID, FrameOfR
2797
2797
  }
2798
2798
  const segFramePosition = PerFrameFunctionalGroup.PlanePositionSequence[0].ImagePositionPatient;
2799
2799
  for (let imageId of imageIds) {
2800
- const sourceImageMetadata = metadataProvider.get("instance", imageId);
2800
+ const sourceImageMetadata = metadataProvider.get('instance', imageId);
2801
2801
  if (!sourceImageMetadata) {
2802
2802
  continue;
2803
2803
  }
@@ -2808,7 +2808,7 @@ function getImageIdOfSourceImagebyGeometry(ReferencedSeriesInstanceUID, FrameOfR
2808
2808
 
2809
2809
  // For multiframe images, check each frame's position
2810
2810
  if (isMultiframe) {
2811
- const framePosition = metadataProvider.get("imagePlaneModule", imageId)?.imagePositionPatient;
2811
+ const framePosition = metadataProvider.get('imagePlaneModule', imageId)?.imagePositionPatient;
2812
2812
  if (framePosition && esm.utilities.isEqual(segFramePosition, framePosition, tolerance)) {
2813
2813
  return imageId;
2814
2814
  }
@@ -2938,7 +2938,7 @@ function readFromUnpackedChunks(chunks, offset, length) {
2938
2938
  function getUnpackedOffsetAndLength(chunks, offset, length) {
2939
2939
  var totalBytes = chunks.reduce((total, chunk) => total + chunk.length, 0);
2940
2940
  if (offset < 0 || offset + length > totalBytes) {
2941
- throw new Error("Offset and length out of bounds");
2941
+ throw new Error('Offset and length out of bounds');
2942
2942
  }
2943
2943
  var startChunkIndex = 0;
2944
2944
  var startOffsetInChunk = offset;
@@ -2979,9 +2979,9 @@ function calculateCentroid(imageIdIndexBufferIndex, multiframe, metadataProvider
2979
2979
 
2980
2980
  // Get metadata for this slice
2981
2981
  const imageId = imageIds[z];
2982
- const imagePlaneModule = metadataProvider.get("imagePlaneModule", imageId);
2982
+ const imagePlaneModule = metadataProvider.get('imagePlaneModule', imageId);
2983
2983
  if (!imagePlaneModule) {
2984
- console.debug("Missing imagePlaneModule metadata for centroid calculation");
2984
+ console.debug('Missing imagePlaneModule metadata for centroid calculation');
2985
2985
  continue;
2986
2986
  }
2987
2987
  const {
@@ -3333,7 +3333,7 @@ const CornerstonePMAP = {
3333
3333
 
3334
3334
 
3335
3335
  ;// ../../../node_modules/@cornerstonejs/adapters/dist/esm/adapters/Cornerstone3D/cornerstone3DTag.js
3336
- var CORNERSTONE_3D_TAG = "Cornerstone3DTools@^0.1.0";
3336
+ var CORNERSTONE_3D_TAG = 'Cornerstone3DTools@^0.1.0';
3337
3337
 
3338
3338
 
3339
3339
 
@@ -3432,10 +3432,10 @@ function toPoint3(flatPoints) {
3432
3432
  // This is a custom coding scheme defined to store some annotations from Cornerstone.
3433
3433
  // Note: CodeMeaning is VR type LO, which means we only actually support 64 characters
3434
3434
  // here this is fine for most labels, but may be problematic at some point.
3435
- const CodingScheme_CORNERSTONEFREETEXT = "CORNERSTONEFREETEXT";
3435
+ const CodingScheme_CORNERSTONEFREETEXT = 'CORNERSTONEFREETEXT';
3436
3436
 
3437
3437
  // Cornerstone specified coding scheme for storing findings
3438
- const CodingSchemeDesignator = "CORNERSTONEJS";
3438
+ const CodingSchemeDesignator = 'CORNERSTONEJS';
3439
3439
  const CodingScheme = {
3440
3440
  CodingSchemeDesignator,
3441
3441
  codeValues: {
@@ -3539,9 +3539,11 @@ const {
3539
3539
  sr: {
3540
3540
  valueTypes,
3541
3541
  coding
3542
+ },
3543
+ adapters: {
3544
+ Cornerstone3D
3542
3545
  }
3543
3546
  } = dcmjs_es/* default */.Ay;
3544
- const LabelData_CORNERSTONEFREETEXT = "CORNERSTONEFREETEXT";
3545
3547
  class LabelData {
3546
3548
  constructor(tid300Item, annotation) {
3547
3549
  this.tid300Item = tid300Item;
@@ -3564,12 +3566,16 @@ class LabelData {
3564
3566
  return contentEntries;
3565
3567
  }
3566
3568
  filterCornerstoneFreeText(contentEntries) {
3569
+ const {
3570
+ codeValues
3571
+ } = Cornerstone3D.CodeScheme;
3572
+ const freeTextCodes = [codeValues.FREE_TEXT_CODE_VALUE, codeValues.CORNERSTONEFREETEXT];
3567
3573
  for (let i = 0; i < contentEntries.length; i++) {
3568
3574
  const group = contentEntries[i];
3569
3575
  if (!group.ConceptCodeSequence) {
3570
3576
  continue;
3571
3577
  }
3572
- const csLabel = group.ConceptCodeSequence.find(item => item.CodeValue === LabelData_CORNERSTONEFREETEXT);
3578
+ const csLabel = group.ConceptCodeSequence.findIndex(item => freeTextCodes.includes(item.CodeValue));
3573
3579
  if (csLabel !== -1) {
3574
3580
  group.ConceptCodeSequence.splice(csLabel, 1);
3575
3581
  if (group.ConceptCodeSequence.length === 0) {
@@ -3596,9 +3602,6 @@ class LabelData {
3596
3602
  FrameOfReferenceUID: frameOfReferenceUID
3597
3603
  } = annotation.metadata;
3598
3604
  const is3DMeasurement = !referencedImageId;
3599
- const {
3600
- worldPosition
3601
- } = textBox;
3602
3605
  const {
3603
3606
  x,
3604
3607
  y,
@@ -3606,27 +3609,28 @@ class LabelData {
3606
3609
  } = toScoord({
3607
3610
  is3DMeasurement,
3608
3611
  referencedImageId
3609
- }, worldPosition);
3612
+ }, textBox.worldPosition);
3610
3613
  const graphicType = valueTypes.GraphicTypes.POINT;
3611
3614
  const relationshipType = valueTypes.RelationshipTypes.CONTAINS;
3612
3615
  const name = new coding.CodedConcept(TEXT_ANNOTATION_POSITION);
3613
- if (is3DMeasurement) {
3614
- const graphicData = [x, y, z];
3615
- return new valueTypes.Scoord3DContentItem({
3616
- name,
3617
- relationshipType,
3618
- graphicType,
3619
- frameOfReferenceUID,
3620
- graphicData
3621
- });
3622
- }
3623
- const graphicData = [x, y];
3624
- return new valueTypes.ScoordContentItem({
3616
+ const scoord = is3DMeasurement ? new valueTypes.Scoord3DContentItem({
3617
+ name,
3618
+ relationshipType,
3619
+ graphicType,
3620
+ graphicData: [x, y, z],
3621
+ frameOfReferenceUID
3622
+ }) : new valueTypes.ScoordContentItem({
3625
3623
  name,
3626
3624
  relationshipType,
3627
3625
  graphicType,
3628
- graphicData
3626
+ graphicData: [x, y]
3629
3627
  });
3628
+ scoord.ContentSequence = [{
3629
+ RelationshipType: valueTypes.RelationshipTypes.SELECTED_FROM,
3630
+ ValueType: valueTypes.ValueTypes.IMAGE,
3631
+ ReferencedSOPSequence: this.ReferencedSOPSequence
3632
+ }];
3633
+ return scoord;
3630
3634
  }
3631
3635
  }
3632
3636
 
@@ -4323,7 +4327,7 @@ class BaseAdapter3D {
4323
4327
 
4324
4328
  var _ArrowAnnotate;
4325
4329
  const {
4326
- Point: ArrowAnnotate_TID300Point
4330
+ ArrowAnnotate: TID300ArrowAnnotate
4327
4331
  } = dcmjs_es/* utilities */.BF.TID300;
4328
4332
  const {
4329
4333
  imageToWorldCoords: ArrowAnnotate_imageToWorldCoords
@@ -4406,7 +4410,7 @@ class ArrowAnnotate_ArrowAnnotate extends BaseAdapter3D {
4406
4410
  }
4407
4411
  _ArrowAnnotate = ArrowAnnotate_ArrowAnnotate;
4408
4412
  (() => {
4409
- _ArrowAnnotate.init("ArrowAnnotate", ArrowAnnotate_TID300Point);
4413
+ _ArrowAnnotate.init("ArrowAnnotate", TID300ArrowAnnotate);
4410
4414
  _ArrowAnnotate.registerLegacy();
4411
4415
  })();
4412
4416
 
@@ -4456,7 +4460,9 @@ class Bidirectional_Bidirectional extends BaseAdapter3D {
4456
4460
  state.annotation.data.cachedStats = {
4457
4461
  [`imageId:${referencedImageId}`]: {
4458
4462
  length: longAxisNUMGroup.MeasuredValueSequence.NumericValue,
4459
- width: shortAxisNUMGroup.MeasuredValueSequence.NumericValue
4463
+ width: shortAxisNUMGroup.MeasuredValueSequence.NumericValue,
4464
+ unit: longAxisNUMGroup.MeasuredValueSequence.MeasurementUnitsCodeSequence.CodeValue,
4465
+ widthUnit: shortAxisNUMGroup.MeasuredValueSequence.MeasurementUnitsCodeSequence.CodeValue
4460
4466
  }
4461
4467
  };
4462
4468
  }
@@ -4503,7 +4509,8 @@ class Bidirectional_Bidirectional extends BaseAdapter3D {
4503
4509
  const shortAxisEndImage = toScoord(scoordProps, longAxisPoints[1]);
4504
4510
  const {
4505
4511
  length,
4506
- width
4512
+ width,
4513
+ unit
4507
4514
  } = cachedStats[`imageId:${referencedImageId}`] || {};
4508
4515
  return {
4509
4516
  longAxis: {
@@ -4516,6 +4523,7 @@ class Bidirectional_Bidirectional extends BaseAdapter3D {
4516
4523
  },
4517
4524
  longAxisLength: length,
4518
4525
  shortAxisLength: width,
4526
+ unit,
4519
4527
  trackingIdentifierTextValue: this.trackingIdentifierTextValue,
4520
4528
  finding: finding,
4521
4529
  findingSites: findingSites || [],
@@ -4697,6 +4705,82 @@ _CobbAngle = CobbAngle_CobbAngle;
4697
4705
 
4698
4706
 
4699
4707
 
4708
+ ;// ../../../node_modules/@cornerstonejs/adapters/dist/esm/adapters/Cornerstone3D/metricHandler.js
4709
+ function extractAllNUMGroups(MeasurementGroup, referencedSOPInstanceUID) {
4710
+ const numGroupsBySOPInstanceUID = {};
4711
+ if (MeasurementGroup.ContentSequence) {
4712
+ MeasurementGroup.ContentSequence.forEach(item => {
4713
+ if (item.ValueType === "NUM" && item.ConceptNameCodeSequence) {
4714
+ const codeMeaning = item.ConceptNameCodeSequence.CodeMeaning;
4715
+ const numericValue = item.MeasuredValueSequence?.NumericValue;
4716
+ const unitCode = item.MeasuredValueSequence?.MeasurementUnitsCodeSequence?.CodeValue;
4717
+ if (numericValue !== undefined && referencedSOPInstanceUID) {
4718
+ if (!numGroupsBySOPInstanceUID[referencedSOPInstanceUID]) {
4719
+ numGroupsBySOPInstanceUID[referencedSOPInstanceUID] = {};
4720
+ }
4721
+ numGroupsBySOPInstanceUID[referencedSOPInstanceUID][codeMeaning] = {
4722
+ value: numericValue,
4723
+ unit: unitCode || ""
4724
+ };
4725
+ }
4726
+ }
4727
+ });
4728
+ }
4729
+ return numGroupsBySOPInstanceUID;
4730
+ }
4731
+ function restoreAdditionalMetrics(numGroups) {
4732
+ const additionalMetrics = {};
4733
+ let modalityUnit = "";
4734
+ const metricMapping = {
4735
+ Mean: "mean",
4736
+ "Standard Deviation": "stdDev",
4737
+ Maximum: "max",
4738
+ Minimum: "min",
4739
+ Area: "area",
4740
+ Radius: "radius",
4741
+ Perimeter: "perimeter",
4742
+ Length: "length",
4743
+ Width: "width"
4744
+ };
4745
+ const unitCategory = {
4746
+ area: "areaUnit",
4747
+ radius: "radiusUnit",
4748
+ width: "widthUnit"
4749
+ };
4750
+ for (const [codeMeaning, metricKey] of Object.entries(metricMapping)) {
4751
+ const group = numGroups[codeMeaning];
4752
+ if (!group) {
4753
+ continue;
4754
+ }
4755
+ const {
4756
+ value,
4757
+ unit
4758
+ } = group;
4759
+ if (value == null) {
4760
+ continue;
4761
+ }
4762
+ additionalMetrics[metricKey] = value;
4763
+ if (!unit) {
4764
+ continue;
4765
+ }
4766
+ if (!modalityUnit) {
4767
+ modalityUnit = unit;
4768
+ }
4769
+ const category = unitCategory[metricKey];
4770
+ if (category) {
4771
+ if (!additionalMetrics[category]) {
4772
+ additionalMetrics[category] = unit;
4773
+ }
4774
+ } else {
4775
+ additionalMetrics[`${metricKey}Unit`] = unit;
4776
+ }
4777
+ }
4778
+ additionalMetrics.modalityUnit = modalityUnit;
4779
+ return additionalMetrics;
4780
+ }
4781
+
4782
+
4783
+
4700
4784
  ;// ../../../node_modules/@cornerstonejs/adapters/dist/esm/adapters/Cornerstone3D/CircleROI.js
4701
4785
 
4702
4786
 
@@ -4704,6 +4788,7 @@ _CobbAngle = CobbAngle_CobbAngle;
4704
4788
 
4705
4789
 
4706
4790
 
4791
+
4707
4792
  var _CircleROI;
4708
4793
  const {
4709
4794
  Circle: CircleROI_TID300Circle
@@ -4717,6 +4802,9 @@ class CircleROI extends BaseAdapter3D {
4717
4802
  referencedImageId,
4718
4803
  ReferencedFrameNumber
4719
4804
  } = MeasurementReport_MeasurementReport.getSetupMeasurementData(MeasurementGroup, sopInstanceUIDToImageIdMap, metadata, this.toolType);
4805
+ const referencedSOPInstanceUID = state.sopInstanceUid;
4806
+ const allNUMGroups = extractAllNUMGroups(MeasurementGroup, referencedSOPInstanceUID);
4807
+ const measurementNUMGroups = allNUMGroups[referencedSOPInstanceUID] || {};
4720
4808
  state.annotation.data = {
4721
4809
  ...state.annotation.data,
4722
4810
  handles: {
@@ -4730,7 +4818,8 @@ class CircleROI extends BaseAdapter3D {
4730
4818
  [`imageId:${referencedImageId}`]: {
4731
4819
  area: NUMGroup ? NUMGroup.MeasuredValueSequence.NumericValue : 0,
4732
4820
  radius: 0,
4733
- perimeter: 0
4821
+ perimeter: 0,
4822
+ ...restoreAdditionalMetrics(measurementNUMGroups)
4734
4823
  }
4735
4824
  };
4736
4825
  }
@@ -4759,13 +4848,27 @@ class CircleROI extends BaseAdapter3D {
4759
4848
  const end = toScoord(scoordProps, handles.points[1]);
4760
4849
  const {
4761
4850
  area,
4762
- radius
4851
+ radius,
4852
+ max,
4853
+ min,
4854
+ stdDev,
4855
+ mean,
4856
+ modalityUnit,
4857
+ radiusUnit,
4858
+ areaUnit
4763
4859
  } = cachedStats[`imageId:${referencedImageId}`] || {};
4764
4860
  const perimeter = 2 * Math.PI * radius;
4765
4861
  return {
4766
4862
  area,
4863
+ areaUnit,
4767
4864
  perimeter,
4865
+ modalityUnit,
4866
+ radiusUnit,
4768
4867
  radius,
4868
+ max,
4869
+ min,
4870
+ stdDev,
4871
+ mean,
4769
4872
  points: [center, end],
4770
4873
  trackingIdentifierTextValue: this.trackingIdentifierTextValue,
4771
4874
  finding,
@@ -4790,6 +4893,7 @@ _CircleROI = CircleROI;
4790
4893
 
4791
4894
 
4792
4895
 
4896
+
4793
4897
  var _EllipticalROI;
4794
4898
  const {
4795
4899
  Ellipse: EllipticalROI_TID300Ellipse
@@ -4803,6 +4907,9 @@ class EllipticalROI extends BaseAdapter3D {
4803
4907
  referencedImageId,
4804
4908
  ReferencedFrameNumber
4805
4909
  } = MeasurementReport_MeasurementReport.getSetupMeasurementData(MeasurementGroup, sopInstanceUIDToImageIdMap, metadata, EllipticalROI.toolType);
4910
+ const referencedSOPInstanceUID = state.sopInstanceUid;
4911
+ const allNUMGroups = extractAllNUMGroups(MeasurementGroup, referencedSOPInstanceUID);
4912
+ const measurementNUMGroups = allNUMGroups[referencedSOPInstanceUID] || {};
4806
4913
  state.annotation.data = {
4807
4914
  ...state.annotation.data,
4808
4915
  handles: {
@@ -4813,7 +4920,8 @@ class EllipticalROI extends BaseAdapter3D {
4813
4920
  };
4814
4921
  state.annotation.data.cachedStats = referencedImageId ? {
4815
4922
  [`imageId:${referencedImageId}`]: {
4816
- area: NUMGroup ? NUMGroup.MeasuredValueSequence.NumericValue : 0
4923
+ area: NUMGroup ? NUMGroup.MeasuredValueSequence.NumericValue : 0,
4924
+ ...restoreAdditionalMetrics(measurementNUMGroups)
4817
4925
  }
4818
4926
  } : {};
4819
4927
  return state;
@@ -4859,11 +4967,23 @@ class EllipticalROI extends BaseAdapter3D {
4859
4967
  points.push(left, right, top, bottom);
4860
4968
  }
4861
4969
  const {
4862
- area
4970
+ area,
4971
+ max,
4972
+ min,
4973
+ mean,
4974
+ stdDev,
4975
+ modalityUnit,
4976
+ areaUnit
4863
4977
  } = cachedStats[`imageId:${referencedImageId}`] || {};
4864
4978
  const convertedPoints = points.map(point => toScoord(scoordProps, point));
4865
4979
  return {
4866
4980
  area,
4981
+ areaUnit,
4982
+ max,
4983
+ min,
4984
+ mean,
4985
+ stdDev,
4986
+ modalityUnit,
4867
4987
  points: convertedPoints,
4868
4988
  trackingIdentifierTextValue: this.trackingIdentifierTextValue,
4869
4989
  finding,
@@ -4885,6 +5005,7 @@ _EllipticalROI.init("EllipticalROI", EllipticalROI_TID300Ellipse);
4885
5005
 
4886
5006
 
4887
5007
 
5008
+
4888
5009
  var _RectangleROI;
4889
5010
  const {
4890
5011
  Polyline: RectangleROI_TID300Polyline
@@ -4904,10 +5025,14 @@ class RectangleROI extends BaseAdapter3D {
4904
5025
  } = MeasurementReport_MeasurementReport.getSetupMeasurementData(MeasurementGroup, sopInstanceUIDToImageIdMap, metadata, this.toolType);
4905
5026
  const points = worldCoords.length === 5 ? worldCoords.slice(0, 4) : worldCoords;
4906
5027
  const areaGroup = MeasurementGroup.ContentSequence.find(g => g.ValueType === "NUM" && g.ConceptNameCodeSequence[0].CodeMeaning === "Area");
5028
+ const referencedSOPInstanceUID = state.sopInstanceUid;
5029
+ const allNUMGroups = extractAllNUMGroups(MeasurementGroup, referencedSOPInstanceUID);
5030
+ const measurementNUMGroups = allNUMGroups[referencedSOPInstanceUID] || {};
4907
5031
  const cachedStats = referencedImageId ? {
4908
5032
  [`imageId:${referencedImageId}`]: {
4909
5033
  area: areaGroup?.MeasuredValueSequence?.[0]?.NumericValue || 0,
4910
- areaUnit: areaGroup?.MeasuredValueSequence?.[0]?.MeasurementUnitsCodeSequence?.CodeValue
5034
+ areaUnit: areaGroup?.MeasuredValueSequence?.[0]?.MeasurementUnitsCodeSequence?.CodeValue,
5035
+ ...restoreAdditionalMetrics(measurementNUMGroups)
4911
5036
  }
4912
5037
  } : {};
4913
5038
  state.annotation.data = {
@@ -4939,12 +5064,22 @@ class RectangleROI extends BaseAdapter3D {
4939
5064
  const corners = toScoords(scoordProps, data.handles.points);
4940
5065
  const {
4941
5066
  area,
4942
- perimeter
5067
+ perimeter,
5068
+ max,
5069
+ mean,
5070
+ stdDev,
5071
+ areaUnit,
5072
+ modalityUnit
4943
5073
  } = data.cachedStats[`imageId:${referencedImageId}`] || {};
4944
5074
  return {
4945
5075
  points: [corners[0], corners[1], corners[3], corners[2], corners[0]],
4946
5076
  area,
4947
5077
  perimeter,
5078
+ max,
5079
+ mean,
5080
+ stdDev,
5081
+ areaUnit,
5082
+ modalityUnit,
4948
5083
  trackingIdentifierTextValue: this.trackingIdentifierTextValue,
4949
5084
  finding,
4950
5085
  findingSites: findingSites || [],
@@ -4985,7 +5120,8 @@ class Length_Length extends BaseAdapter3D {
4985
5120
  } = MeasurementReport_MeasurementReport.getSetupMeasurementData(MeasurementGroup, sopInstanceUIDToImageIdMap, metadata, this.toolType);
4986
5121
  const cachedStats = referencedImageId ? {
4987
5122
  [`imageId:${referencedImageId}`]: {
4988
- length: NUMGroup ? NUMGroup.MeasuredValueSequence.NumericValue : 0
5123
+ length: NUMGroup ? NUMGroup.MeasuredValueSequence.NumericValue : 0,
5124
+ unit: NUMGroup.MeasuredValueSequence.MeasurementUnitsCodeSequence.CodeValue
4989
5125
  }
4990
5126
  } : {};
4991
5127
  state.annotation.data = {
@@ -5053,6 +5189,7 @@ var gl_matrix_esm = __webpack_require__(3823);
5053
5189
 
5054
5190
 
5055
5191
 
5192
+
5056
5193
  var _PlanarFreehandROI;
5057
5194
  const {
5058
5195
  Polyline: PlanarFreehandROI_TID300Polyline
@@ -5076,6 +5213,9 @@ class PlanarFreehandROI extends BaseAdapter3D {
5076
5213
  if (isOpenContour) {
5077
5214
  points.push(worldCoords[0], worldCoords[worldCoords.length - 1]);
5078
5215
  }
5216
+ const referencedSOPInstanceUID = state.sopInstanceUid;
5217
+ const allNUMGroups = extractAllNUMGroups(MeasurementGroup, referencedSOPInstanceUID);
5218
+ const measurementNUMGroups = allNUMGroups[referencedSOPInstanceUID] || {};
5079
5219
  state.annotation.data = {
5080
5220
  ...state.annotation.data,
5081
5221
  contour: {
@@ -5091,7 +5231,8 @@ class PlanarFreehandROI extends BaseAdapter3D {
5091
5231
  if (referencedImageId) {
5092
5232
  state.annotation.data.cachedStats = {
5093
5233
  [`imageId:${referencedImageId}`]: {
5094
- area: NUMGroup ? NUMGroup.MeasuredValueSequence.NumericValue : null
5234
+ area: NUMGroup ? NUMGroup.MeasuredValueSequence.NumericValue : null,
5235
+ ...restoreAdditionalMetrics(measurementNUMGroups)
5095
5236
  }
5096
5237
  };
5097
5238
  }
@@ -5129,13 +5270,14 @@ class PlanarFreehandROI extends BaseAdapter3D {
5129
5270
  perimeter,
5130
5271
  mean,
5131
5272
  max,
5132
- stdDev
5273
+ stdDev,
5274
+ length
5133
5275
  } = data.cachedStats[`imageId:${referencedImageId}`] || {};
5134
5276
  return {
5135
5277
  points,
5136
5278
  area,
5137
5279
  areaUnit,
5138
- perimeter,
5280
+ perimeter: perimeter ?? length,
5139
5281
  modalityUnit,
5140
5282
  mean,
5141
5283
  max,
@@ -6783,7 +6925,7 @@ class Segmentation_Segmentation {
6783
6925
  * @return {{}}
6784
6926
  */
6785
6927
  static generateSegments(dataset) {
6786
- if (dataset.SegmentSequence.constructor.name !== "Array") {
6928
+ if (dataset.SegmentSequence.constructor.name !== 'Array') {
6787
6929
  dataset.SegmentSequence = [dataset.SegmentSequence];
6788
6930
  }
6789
6931
  dataset.SegmentSequence.forEach(segment => {
@@ -6931,10 +7073,10 @@ function downloadDICOMData(bufferOrDataset, filename) {
6931
7073
 
6932
7074
 
6933
7075
 
6934
- /***/ }),
7076
+ /***/ },
6935
7077
 
6936
- /***/ 75183:
6937
- /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
7078
+ /***/ 75183
7079
+ (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
6938
7080
 
6939
7081
  "use strict";
6940
7082
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
@@ -6955,10 +7097,10 @@ var ChangeTypes;
6955
7097
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ChangeTypes);
6956
7098
 
6957
7099
 
6958
- /***/ }),
7100
+ /***/ },
6959
7101
 
6960
- /***/ 94021:
6961
- /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
7102
+ /***/ 94021
7103
+ (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
6962
7104
 
6963
7105
  "use strict";
6964
7106
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
@@ -7016,10 +7158,10 @@ var Events;
7016
7158
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Events);
7017
7159
 
7018
7160
 
7019
- /***/ }),
7161
+ /***/ },
7020
7162
 
7021
- /***/ 18682:
7022
- /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
7163
+ /***/ 18682
7164
+ (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
7023
7165
 
7024
7166
  "use strict";
7025
7167
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
@@ -7034,10 +7176,10 @@ var SegmentationRepresentations;
7034
7176
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (SegmentationRepresentations);
7035
7177
 
7036
7178
 
7037
- /***/ }),
7179
+ /***/ },
7038
7180
 
7039
- /***/ 84093:
7040
- /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
7181
+ /***/ 84093
7182
+ (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
7041
7183
 
7042
7184
  "use strict";
7043
7185
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
@@ -7045,6 +7187,8 @@ var SegmentationRepresentations;
7045
7187
  /* harmony export */ });
7046
7188
  var StrategyCallbacks;
7047
7189
  (function (StrategyCallbacks) {
7190
+ StrategyCallbacks["CalculateCursorGeometry"] = "calculateCursorGeometry";
7191
+ StrategyCallbacks["RenderCursor"] = "renderCursor";
7048
7192
  StrategyCallbacks["OnInteractionStart"] = "onInteractionStart";
7049
7193
  StrategyCallbacks["OnInteractionEnd"] = "onInteractionEnd";
7050
7194
  StrategyCallbacks["Preview"] = "preview";
@@ -7065,10 +7209,10 @@ var StrategyCallbacks;
7065
7209
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (StrategyCallbacks);
7066
7210
 
7067
7211
 
7068
- /***/ }),
7212
+ /***/ },
7069
7213
 
7070
- /***/ 66452:
7071
- /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
7214
+ /***/ 66452
7215
+ (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
7072
7216
 
7073
7217
  "use strict";
7074
7218
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
@@ -7105,10 +7249,10 @@ var KeyboardBindings;
7105
7249
 
7106
7250
 
7107
7251
 
7108
- /***/ }),
7252
+ /***/ },
7109
7253
 
7110
- /***/ 49892:
7111
- /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
7254
+ /***/ 49892
7255
+ (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
7112
7256
 
7113
7257
  "use strict";
7114
7258
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
@@ -7124,10 +7268,10 @@ var ToolModes;
7124
7268
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ToolModes);
7125
7269
 
7126
7270
 
7127
- /***/ }),
7271
+ /***/ },
7128
7272
 
7129
- /***/ 10401:
7130
- /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
7273
+ /***/ 10401
7274
+ (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
7131
7275
 
7132
7276
  "use strict";
7133
7277
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
@@ -7143,10 +7287,10 @@ var Swipe;
7143
7287
 
7144
7288
 
7145
7289
 
7146
- /***/ }),
7290
+ /***/ },
7147
7291
 
7148
- /***/ 29857:
7149
- /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
7292
+ /***/ 29857
7293
+ (__unused_webpack_module, __webpack_exports__, __webpack_require__) {
7150
7294
 
7151
7295
  "use strict";
7152
7296
  // ESM COMPAT FLAG
@@ -7230,10 +7374,10 @@ var MeasurementType;
7230
7374
 
7231
7375
 
7232
7376
 
7233
- /***/ }),
7377
+ /***/ },
7234
7378
 
7235
- /***/ 26337:
7236
- /***/ ((module) => {
7379
+ /***/ 26337
7380
+ (module) {
7237
7381
 
7238
7382
  "use strict";
7239
7383
 
@@ -7248,10 +7392,10 @@ function iota(n) {
7248
7392
 
7249
7393
  module.exports = iota
7250
7394
 
7251
- /***/ }),
7395
+ /***/ },
7252
7396
 
7253
- /***/ 11604:
7254
- /***/ ((module) => {
7397
+ /***/ 11604
7398
+ (module) {
7255
7399
 
7256
7400
  /*!
7257
7401
  * Determine if an object is a Buffer
@@ -7276,10 +7420,10 @@ function isSlowBuffer (obj) {
7276
7420
  }
7277
7421
 
7278
7422
 
7279
- /***/ }),
7423
+ /***/ },
7280
7424
 
7281
- /***/ 3293:
7282
- /***/ ((module, __unused_webpack_exports, __webpack_require__) => {
7425
+ /***/ 3293
7426
+ (module, __unused_webpack_exports, __webpack_require__) {
7283
7427
 
7284
7428
  var iota = __webpack_require__(26337)
7285
7429
  var isBuffer = __webpack_require__(11604)
@@ -7632,6 +7776,6 @@ function wrappedNDArrayCtor(data, shape, stride, offset) {
7632
7776
  module.exports = wrappedNDArrayCtor
7633
7777
 
7634
7778
 
7635
- /***/ })
7779
+ /***/ }
7636
7780
 
7637
7781
  }]);