@ohif/app 3.10.1 → 3.10.2

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 (44) hide show
  1. package/dist/{1919.bundle.6f7de53921f3710a1d54.js → 1919.bundle.6cb4a1f5ea770e504398.js} +2 -2
  2. package/dist/{1927.bundle.83810560c4d3a90eb7cf.js → 1927.bundle.5c25b9084f704a3582d2.js} +1 -1
  3. package/dist/{3396.bundle.858cfdfc5ab560840958.js → 2482.bundle.0947bc67ad4429d5fda3.js} +289 -1353
  4. package/dist/{2701.bundle.f1f15df81406d04851c4.js → 2701.bundle.87301d8d94693b5d5fcc.js} +2 -2
  5. package/dist/{2860.bundle.5d93c30e2df60e382bda.js → 2860.bundle.130f5c83c90c83017101.js} +1368 -28
  6. package/dist/{2914.bundle.a0a5ddfebfc9d429063d.js → 2914.bundle.adefec5b51b4955af1f9.js} +2 -0
  7. package/dist/{2932.bundle.038f79dbbfdd9d1f387b.js → 2932.bundle.2757ab993a28dab49d56.js} +2 -2
  8. package/dist/{3075.bundle.0624f6bf3f676f30d1b5.js → 3075.bundle.5d83563c3791a0d884df.js} +16 -3
  9. package/dist/{3353.bundle.184ebb9668df2cbebd26.js → 3353.bundle.1b2d3da25de70f5f1042.js} +33 -4
  10. package/dist/{3984.bundle.592161af4b618c9dd56f.js → 3984.bundle.1248e382e82ee04eff72.js} +12 -7
  11. package/dist/{4113.bundle.7ec6da0eb1ab98e1b791.js → 4113.bundle.1a3202dd6a1b2e6b9d5d.js} +5 -5
  12. package/dist/{4526.bundle.fbdd617a934353019be3.js → 4526.bundle.54c0b8f753ed5c39f6c5.js} +2 -2
  13. package/dist/{6029.bundle.43e04238ac01880fa66c.js → 6029.bundle.a4206e2a2e75c7b1ad7b.js} +238 -40
  14. package/dist/{6066.bundle.345453ace06e86bc481c.js → 6066.bundle.89df990e4f257e8ac73b.js} +1466 -39
  15. package/dist/{6201.bundle.e0d8d1c967a9daed4662.js → 6201.bundle.b584d7554570344d9170.js} +4 -4
  16. package/dist/{7197.bundle.a9c6429f2859a8feeded.js → 7197.bundle.2032eea26c084877d172.js} +3 -3
  17. package/dist/{810.bundle.86ba4f6f1311ccc28d41.js → 810.bundle.8b29de53f9632f0f1bf9.js} +4 -4
  18. package/dist/{8185.bundle.b2252d9ff14ce760df9c.js → 8185.bundle.c7e0ab58fa8f7070de26.js} +22 -16
  19. package/dist/{8558.bundle.5b67110ba3e66f5525ae.js → 8558.bundle.24bb90c2d5a0857577c5.js} +1 -1
  20. package/dist/{7241.bundle.7097a0cd314605d766f5.js → 8572.bundle.bd98ac784dae1e224a52.js} +135 -47
  21. package/dist/{3166.bundle.40162f1d9f9f5fc16b16.js → 908.bundle.7f901ab4610793bb5ee3.js} +29 -5
  22. package/dist/{934.bundle.c446dfb396152899756f.js → 934.bundle.441c775536d8be5029af.js} +2 -2
  23. package/dist/{963.bundle.88152346007c0f5049a3.js → 963.bundle.4b88a54196fdd1976d6c.js} +2 -2
  24. package/dist/{9890.bundle.37d7ed265c0454337a57.js → 9890.bundle.b4c265e3609512785ae8.js} +2 -2
  25. package/dist/{9977.bundle.071821200c1921021d29.js → 9977.bundle.4f44190c1a5d6a69bc00.js} +3 -1
  26. package/dist/{app.bundle.d09601053966ecdcfe4b.js → app.bundle.223c009cd6f636320f76.js} +2148 -1758
  27. package/dist/app.bundle.css +2 -2
  28. package/dist/{compute.bundle.f0c30502c027d04e94f2.js → compute.bundle.83a75c96620eedca973e.js} +3 -3
  29. package/dist/index.html +1 -1
  30. package/dist/{polySeg.bundle.7445d00e1e9ef623d0f1.js → polySeg.bundle.30f6f13491f48e597605.js} +3 -3
  31. package/dist/sw.js +1 -1
  32. package/package.json +19 -19
  33. /package/dist/{1459.bundle.4b6682c8673e199edf64.js → 1459.bundle.ea2023918c1ef217d23a.js} +0 -0
  34. /package/dist/{1807.bundle.e8c6890ca68e62f46990.js → 1807.bundle.a04f3486b00cdcc6a305.js} +0 -0
  35. /package/dist/{213.bundle.d8495e69f1d1405d0356.js → 213.bundle.e861b773d4779d7d724a.js} +0 -0
  36. /package/dist/{2424.bundle.ef98022039ea6e87cfd9.js → 2424.bundle.425cb2260521f2a23f70.js} +0 -0
  37. /package/dist/{3658.bundle.04fdfe11b9d38cd5f3c6.js → 3658.bundle.a6a9c2e1b32d92e3b621.js} +0 -0
  38. /package/dist/{6027.bundle.155cbff7fa97c7ede627.js → 6027.bundle.8e1b6021f0d570eb85f5.js} +0 -0
  39. /package/dist/{7639.bundle.a659acbf2ab7f3f2e8f4.js → 7639.bundle.b622eafdc74d9bfc1280.js} +0 -0
  40. /package/dist/{8228.bundle.74c8ca5e66a44db80464.js → 8228.bundle.f520ecf3c0a8998e770a.js} +0 -0
  41. /package/dist/{85.bundle.e65ed829e1a136e33576.js → 85.bundle.a27a1466f85e01adf8e8.js} +0 -0
  42. /package/dist/{8815.bundle.c8a97b220635e9b15109.js → 8815.bundle.096958a5ae7253911a2e.js} +0 -0
  43. /package/dist/{9026.bundle.eb2ae9e2311a6a620751.js → 9026.bundle.019d8b4b70096b94302e.js} +0 -0
  44. /package/dist/{9862.bundle.87d8249a9cf1d8cf579d.js → 9862.bundle.b0ea941458506379f666.js} +0 -0
@@ -3686,7 +3686,7 @@ else {}
3686
3686
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
3687
3687
  /* harmony export */ A: () => (__WEBPACK_DEFAULT_EXPORT__)
3688
3688
  /* harmony export */ });
3689
- /* harmony import */ var _kitware_vtk_js_Rendering_Core_ColorTransferFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(33739);
3689
+ /* harmony import */ var _kitware_vtk_js_Rendering_Core_ColorTransferFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(642);
3690
3690
  /* harmony import */ var _kitware_vtk_js_Rendering_Core_ColorTransferFunction_ColorMaps__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(660);
3691
3691
  /* harmony import */ var _kitware_vtk_js_Common_DataModel_PiecewiseFunction__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(99341);
3692
3692
  /* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(3823);
@@ -4051,19 +4051,14 @@ class BaseVolumeViewport extends _Viewport__WEBPACK_IMPORTED_MODULE_18__/* ["def
4051
4051
  const { volumeActor } = applicableVolumeActorInfo;
4052
4052
  const ofun = _kitware_vtk_js_Common_DataModel_PiecewiseFunction__WEBPACK_IMPORTED_MODULE_2__/* ["default"].newInstance */ .Ay.newInstance();
4053
4053
  if (typeof colormap.opacity === 'number') {
4054
- const range = volumeActor
4055
- .getProperty()
4056
- .getRGBTransferFunction(0)
4057
- .getRange();
4058
- ofun.addPoint(range[0], colormap.opacity);
4059
- ofun.addPoint(range[1], colormap.opacity);
4054
+ (0,_utilities_colormap__WEBPACK_IMPORTED_MODULE_11__.updateOpacity)(volumeActor, colormap.opacity);
4060
4055
  }
4061
4056
  else {
4062
4057
  colormap.opacity.forEach(({ opacity, value }) => {
4063
4058
  ofun.addPoint(value, opacity);
4064
4059
  });
4060
+ volumeActor.getProperty().setScalarOpacity(0, ofun);
4065
4061
  }
4066
- volumeActor.getProperty().setScalarOpacity(0, ofun);
4067
4062
  if (!this.viewportProperties.colormap) {
4068
4063
  this.viewportProperties.colormap = {};
4069
4064
  }
@@ -4250,6 +4245,7 @@ class BaseVolumeViewport extends _Viewport__WEBPACK_IMPORTED_MODULE_18__/* ["def
4250
4245
  const isNegativeNormal = (0,_utilities_isEqual__WEBPACK_IMPORTED_MODULE_24__/* .isEqualNegative */ .WC)(viewPlaneNormal, refViewPlaneNormal);
4251
4246
  const isSameNormal = (0,_utilities_isEqual__WEBPACK_IMPORTED_MODULE_24__/* ["default"] */ .Ay)(viewPlaneNormal, refViewPlaneNormal);
4252
4247
  if (typeof sliceIndex === 'number' &&
4248
+ volumeId !== undefined &&
4253
4249
  viewRef.volumeId === volumeId &&
4254
4250
  (isNegativeNormal || isSameNormal)) {
4255
4251
  const { currentStepIndex, sliceRangeInfo, numScrollSteps } = (0,_utilities_getVolumeViewportScrollInfo__WEBPACK_IMPORTED_MODULE_20__/* ["default"] */ .A)(this, volumeId, true);
@@ -4267,17 +4263,6 @@ class BaseVolumeViewport extends _Viewport__WEBPACK_IMPORTED_MODULE_18__/* ["def
4267
4263
  this.setViewReference(viewRef);
4268
4264
  return;
4269
4265
  }
4270
- if (cameraFocalPoint) {
4271
- const focalDelta = gl_matrix__WEBPACK_IMPORTED_MODULE_3__/* .vec3.subtract */ .eR.subtract([0, 0, 0], cameraFocalPoint, focalPoint);
4272
- const useNormal = refViewPlaneNormal ?? viewPlaneNormal;
4273
- const normalDot = gl_matrix__WEBPACK_IMPORTED_MODULE_3__/* .vec3.dot */ .eR.dot(focalDelta, useNormal);
4274
- if (!(0,_utilities_isEqual__WEBPACK_IMPORTED_MODULE_24__/* ["default"] */ .Ay)(normalDot, 0)) {
4275
- gl_matrix__WEBPACK_IMPORTED_MODULE_3__/* .vec3.scale */ .eR.scale(focalDelta, useNormal, normalDot);
4276
- }
4277
- const newFocal = gl_matrix__WEBPACK_IMPORTED_MODULE_3__/* .vec3.add */ .eR.add([0, 0, 0], focalPoint, focalDelta);
4278
- const newPosition = gl_matrix__WEBPACK_IMPORTED_MODULE_3__/* .vec3.add */ .eR.add([0, 0, 0], position, focalDelta);
4279
- this.setCamera({ focalPoint: newFocal, position: newPosition });
4280
- }
4281
4266
  if (referencedImageId && this.isInAcquisitionPlane()) {
4282
4267
  const imagePlaneModule = _metaData__WEBPACK_IMPORTED_MODULE_28__.get(_enums__WEBPACK_IMPORTED_MODULE_6__.MetadataModules.IMAGE_PLANE, referencedImageId);
4283
4268
  const { imagePositionPatient } = imagePlaneModule;
@@ -4289,12 +4274,36 @@ class BaseVolumeViewport extends _Viewport__WEBPACK_IMPORTED_MODULE_18__/* ["def
4289
4274
  focalPoint: newImagePositionPatient,
4290
4275
  });
4291
4276
  this.render();
4277
+ return;
4278
+ }
4279
+ if (cameraFocalPoint) {
4280
+ const focalDelta = gl_matrix__WEBPACK_IMPORTED_MODULE_3__/* .vec3.subtract */ .eR.subtract([0, 0, 0], cameraFocalPoint, focalPoint);
4281
+ const useNormal = refViewPlaneNormal ?? viewPlaneNormal;
4282
+ const normalDot = gl_matrix__WEBPACK_IMPORTED_MODULE_3__/* .vec3.dot */ .eR.dot(focalDelta, useNormal);
4283
+ if (!(0,_utilities_isEqual__WEBPACK_IMPORTED_MODULE_24__/* ["default"] */ .Ay)(normalDot, 0)) {
4284
+ gl_matrix__WEBPACK_IMPORTED_MODULE_3__/* .vec3.scale */ .eR.scale(focalDelta, useNormal, normalDot);
4285
+ }
4286
+ const newFocal = gl_matrix__WEBPACK_IMPORTED_MODULE_3__/* .vec3.add */ .eR.add([0, 0, 0], focalPoint, focalDelta);
4287
+ const newPosition = gl_matrix__WEBPACK_IMPORTED_MODULE_3__/* .vec3.add */ .eR.add([0, 0, 0], position, focalDelta);
4288
+ this.setCamera({ focalPoint: newFocal, position: newPosition });
4292
4289
  }
4293
4290
  }
4294
4291
  else {
4295
4292
  throw new Error(`Incompatible view refs: ${refFrameOfReference}!==${this.getFrameOfReferenceUID()}`);
4296
4293
  }
4297
4294
  }
4295
+ setThreshold(colormap, volumeId) {
4296
+ const applicableVolumeActorInfo = this._getApplicableVolumeActor(volumeId);
4297
+ if (!applicableVolumeActorInfo) {
4298
+ return;
4299
+ }
4300
+ const { volumeActor } = applicableVolumeActorInfo;
4301
+ (0,_utilities_colormap__WEBPACK_IMPORTED_MODULE_11__.updateThreshold)(volumeActor, colormap.threshold);
4302
+ if (!this.viewportProperties.colormap) {
4303
+ this.viewportProperties.colormap = {};
4304
+ }
4305
+ this.viewportProperties.colormap.threshold = colormap.threshold;
4306
+ }
4298
4307
  setProperties({ voiRange, VOILUTFunction, invert, colormap, preset, interpolationType, slabThickness, } = {}, volumeId, suppressEvents = false) {
4299
4308
  if (this.globalDefaultProperties == null) {
4300
4309
  this.setDefaultProperties({
@@ -4315,6 +4324,9 @@ class BaseVolumeViewport extends _Viewport__WEBPACK_IMPORTED_MODULE_18__/* ["def
4315
4324
  if (colormap?.opacity != null) {
4316
4325
  this.setOpacity(colormap, volumeId);
4317
4326
  }
4327
+ if (colormap?.threshold != null) {
4328
+ this.setThreshold(colormap, volumeId);
4329
+ }
4318
4330
  if (voiRange !== undefined) {
4319
4331
  this.setVOI(voiRange, volumeId, suppressEvents);
4320
4332
  }
@@ -4577,14 +4589,34 @@ class BaseVolumeViewport extends _Viewport__WEBPACK_IMPORTED_MODULE_18__/* ["def
4577
4589
  throw new Error('Invalid orientation object. It must contain viewPlaneNormal and viewUp');
4578
4590
  }
4579
4591
  }
4580
- else if (typeof orientation === 'string' &&
4581
- _constants__WEBPACK_IMPORTED_MODULE_5__.MPR_CAMERA_VALUES[orientation]) {
4582
- this.viewportProperties.orientation = orientation;
4583
- return _constants__WEBPACK_IMPORTED_MODULE_5__.MPR_CAMERA_VALUES[orientation];
4592
+ else if (typeof orientation === 'string') {
4593
+ if (orientation === 'acquisition') {
4594
+ return this._getAcquisitionPlaneOrientation();
4595
+ }
4596
+ else if (_constants__WEBPACK_IMPORTED_MODULE_5__.MPR_CAMERA_VALUES[orientation]) {
4597
+ this.viewportProperties.orientation = orientation;
4598
+ return _constants__WEBPACK_IMPORTED_MODULE_5__.MPR_CAMERA_VALUES[orientation];
4599
+ }
4584
4600
  }
4585
- else {
4586
- throw new Error(`Invalid orientation: ${orientation}. Valid orientations are: ${Object.keys(_constants__WEBPACK_IMPORTED_MODULE_5__.MPR_CAMERA_VALUES).join(', ')}`);
4601
+ throw new Error(`Invalid orientation: ${orientation}. Valid orientations are: ${Object.keys(_constants__WEBPACK_IMPORTED_MODULE_5__.MPR_CAMERA_VALUES).join(', ')}`);
4602
+ }
4603
+ _getAcquisitionPlaneOrientation() {
4604
+ const actorEntry = this.getDefaultActor();
4605
+ if (!actorEntry) {
4606
+ return;
4607
+ }
4608
+ const volumeId = this.getVolumeId();
4609
+ const imageVolume = _cache_cache__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .Ay.getVolume(volumeId);
4610
+ if (!imageVolume) {
4611
+ throw new Error(`imageVolume with id: ${volumeId} does not exist in cache`);
4587
4612
  }
4613
+ const { direction } = imageVolume;
4614
+ const viewPlaneNormal = direction.slice(6, 9).map((x) => -x);
4615
+ const viewUp = direction.slice(3, 6).map((x) => -x);
4616
+ return {
4617
+ viewPlaneNormal,
4618
+ viewUp,
4619
+ };
4588
4620
  }
4589
4621
  getSlabThickness() {
4590
4622
  const actors = this.getActors();
@@ -4663,8 +4695,8 @@ var DataArray = __webpack_require__(42008);
4663
4695
  var ImageData = __webpack_require__(58498);
4664
4696
  // EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Rendering/Core/Camera.js
4665
4697
  var Camera = __webpack_require__(26719);
4666
- // EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Rendering/Core/ColorTransferFunction.js + 1 modules
4667
- var ColorTransferFunction = __webpack_require__(33739);
4698
+ // EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Rendering/Core/ColorTransferFunction.js
4699
+ var ColorTransferFunction = __webpack_require__(642);
4668
4700
  // EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Rendering/Core/ColorTransferFunction/ColorMaps.js + 1 modules
4669
4701
  var ColorMaps = __webpack_require__(660);
4670
4702
  // EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Rendering/Core/ImageMapper/Constants.js
@@ -6939,6 +6971,10 @@ class StackViewport extends Viewport/* default */.A {
6939
6971
  origin = [0, 0, 0];
6940
6972
  }
6941
6973
  this._imageData.setOrigin(origin);
6974
+ const actor = this.getActor(this.id);
6975
+ if (actor) {
6976
+ actor.referencedId = image.imageId;
6977
+ }
6942
6978
  (0,updateVTKImageDataWithCornerstoneImage/* updateVTKImageDataWithCornerstoneImage */.J)(this._imageData, image);
6943
6979
  }
6944
6980
  _loadAndDisplayImage(imageId, imageIdIndex) {
@@ -7206,7 +7242,7 @@ class StackViewport extends Viewport/* default */.A {
7206
7242
  oldActors[0].actor = actor;
7207
7243
  }
7208
7244
  else {
7209
- oldActors.unshift({ uid: this.id, actor });
7245
+ oldActors.unshift({ uid: this.id, actor, referencedId: image.imageId });
7210
7246
  }
7211
7247
  this.setActors(oldActors);
7212
7248
  const { viewPlaneNormal, viewUp } = this._getCameraOrientation(direction);
@@ -7356,6 +7392,7 @@ class StackViewport extends Viewport/* default */.A {
7356
7392
  return Promise.resolve(this.getCurrentImageId());
7357
7393
  }
7358
7394
  const imageIdPromise = this._setImageIdIndex(imageIdIndex);
7395
+ this.targetImageIdIndex = imageIdIndex;
7359
7396
  return imageIdPromise;
7360
7397
  }
7361
7398
  calibrateSpacing(imageId) {
@@ -8847,22 +8884,41 @@ class Viewport {
8847
8884
  return this.getActors()[index];
8848
8885
  }
8849
8886
  setActors(actors) {
8887
+ const currentActors = this.getActors();
8850
8888
  this.removeAllActors();
8851
8889
  this.addActors(actors, { resetCamera: true });
8890
+ (0,_utilities_triggerEvent__WEBPACK_IMPORTED_MODULE_9__/* ["default"] */ .A)(this.element, _enums_Events__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .A.ACTORS_CHANGED, {
8891
+ viewportId: this.id,
8892
+ removedActors: currentActors,
8893
+ addedActors: actors,
8894
+ currentActors: actors,
8895
+ });
8852
8896
  }
8853
8897
  _removeActor(actorUID) {
8854
8898
  const actorEntry = this.getActor(actorUID);
8855
8899
  if (!actorEntry) {
8856
- console.warn(`Actor ${actorUID} does not exist for this viewport`);
8900
+ console.warn(`Actor ${actorUID} does not exist in ${this.id}, can't remove`);
8857
8901
  return;
8858
8902
  }
8859
8903
  const renderer = this.getRenderer();
8860
- renderer.removeViewProp(actorEntry.actor);
8904
+ renderer.removeActor(actorEntry.actor);
8861
8905
  this._actors.delete(actorUID);
8906
+ return actorEntry;
8862
8907
  }
8863
8908
  removeActors(actorUIDs) {
8909
+ const removedActors = [];
8864
8910
  actorUIDs.forEach((actorUID) => {
8865
- this._removeActor(actorUID);
8911
+ const removedActor = this._removeActor(actorUID);
8912
+ if (removedActor) {
8913
+ removedActors.push(removedActor);
8914
+ }
8915
+ });
8916
+ const currentActors = this.getActors();
8917
+ (0,_utilities_triggerEvent__WEBPACK_IMPORTED_MODULE_9__/* ["default"] */ .A)(this.element, _enums_Events__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .A.ACTORS_CHANGED, {
8918
+ viewportId: this.id,
8919
+ removedActors,
8920
+ addedActors: [],
8921
+ currentActors,
8866
8922
  });
8867
8923
  }
8868
8924
  addActors(actors, options = {}) {
@@ -8882,6 +8938,12 @@ class Viewport {
8882
8938
  this.setViewReference(prevViewRef);
8883
8939
  this.setViewPresentation(prevViewPresentation);
8884
8940
  }
8941
+ (0,_utilities_triggerEvent__WEBPACK_IMPORTED_MODULE_9__/* ["default"] */ .A)(this.element, _enums_Events__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .A.ACTORS_CHANGED, {
8942
+ viewportId: this.id,
8943
+ removedActors: [],
8944
+ addedActors: actors,
8945
+ currentActors: this.getActors(),
8946
+ });
8885
8947
  }
8886
8948
  addActor(actorEntry) {
8887
8949
  const { uid: actorUID, actor } = actorEntry;
@@ -8901,10 +8963,23 @@ class Viewport {
8901
8963
  renderer?.addActor(actor);
8902
8964
  this._actors.set(actorUID, Object.assign({}, actorEntry));
8903
8965
  this.updateCameraClippingPlanesAndRange();
8966
+ (0,_utilities_triggerEvent__WEBPACK_IMPORTED_MODULE_9__/* ["default"] */ .A)(this.element, _enums_Events__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .A.ACTORS_CHANGED, {
8967
+ viewportId: this.id,
8968
+ removedActors: [],
8969
+ addedActors: [actorEntry],
8970
+ currentActors: this.getActors(),
8971
+ });
8904
8972
  }
8905
8973
  removeAllActors() {
8974
+ const currentActors = this.getActors();
8906
8975
  this.getRenderer()?.removeAllViewProps();
8907
8976
  this._actors = new Map();
8977
+ (0,_utilities_triggerEvent__WEBPACK_IMPORTED_MODULE_9__/* ["default"] */ .A)(this.element, _enums_Events__WEBPACK_IMPORTED_MODULE_4__/* ["default"] */ .A.ACTORS_CHANGED, {
8978
+ viewportId: this.id,
8979
+ removedActors: currentActors,
8980
+ addedActors: [],
8981
+ currentActors: [],
8982
+ });
8908
8983
  return;
8909
8984
  }
8910
8985
  resetCameraNoEvent() {
@@ -9064,7 +9139,15 @@ class Viewport {
9064
9139
  flipVertical: false,
9065
9140
  });
9066
9141
  const previousCamera = this.getCamera();
9067
- const bounds = renderer.computeVisiblePropBounds();
9142
+ let bounds;
9143
+ const defaultActor = this.getDefaultActor();
9144
+ if (defaultActor && (0,_utilities_actorCheck__WEBPACK_IMPORTED_MODULE_8__/* .isImageActor */ .e)(defaultActor)) {
9145
+ const imageData = defaultActor.actor.getMapper().getInputData();
9146
+ bounds = imageData.getBounds();
9147
+ }
9148
+ else {
9149
+ bounds = renderer.computeVisiblePropBounds();
9150
+ }
9068
9151
  const focalPoint = [0, 0, 0];
9069
9152
  const imageData = this.getDefaultImageData();
9070
9153
  if (imageData) {
@@ -9815,11 +9898,11 @@ class VolumeViewport extends BaseVolumeViewport/* default */.A {
9815
9898
  setOrientation(orientation, immediate = true) {
9816
9899
  let viewPlaneNormal, viewUp;
9817
9900
  if (typeof orientation === 'string') {
9818
- if (constants.MPR_CAMERA_VALUES[orientation]) {
9819
- ({ viewPlaneNormal, viewUp } = constants.MPR_CAMERA_VALUES[orientation]);
9901
+ if (orientation === enums.OrientationAxis.ACQUISITION) {
9902
+ ({ viewPlaneNormal, viewUp } = super._getAcquisitionPlaneOrientation());
9820
9903
  }
9821
- else if (orientation === 'acquisition') {
9822
- ({ viewPlaneNormal, viewUp } = this._getAcquisitionPlaneOrientation());
9904
+ else if (constants.MPR_CAMERA_VALUES[orientation]) {
9905
+ ({ viewPlaneNormal, viewUp } = constants.MPR_CAMERA_VALUES[orientation]);
9823
9906
  }
9824
9907
  else {
9825
9908
  throw new Error(`Invalid orientation: ${orientation}. Use Enums.OrientationAxis instead.`);
@@ -9852,24 +9935,6 @@ class VolumeViewport extends BaseVolumeViewport/* default */.A {
9852
9935
  activeCamera.setClippingRange(constants.RENDERING_DEFAULTS.MINIMUM_SLAB_THICKNESS, constants.RENDERING_DEFAULTS.MAXIMUM_RAY_DISTANCE);
9853
9936
  }
9854
9937
  }
9855
- _getAcquisitionPlaneOrientation() {
9856
- const actorEntry = this.getDefaultActor();
9857
- if (!actorEntry) {
9858
- return;
9859
- }
9860
- const volumeId = this.getVolumeId();
9861
- const imageVolume = cache/* default */.Ay.getVolume(volumeId);
9862
- if (!imageVolume) {
9863
- throw new Error(`imageVolume with id: ${volumeId} does not exist in cache`);
9864
- }
9865
- const { direction } = imageVolume;
9866
- const viewPlaneNormal = direction.slice(6, 9).map((x) => -x);
9867
- const viewUp = direction.slice(3, 6).map((x) => -x);
9868
- return {
9869
- viewPlaneNormal,
9870
- viewUp,
9871
- };
9872
- }
9873
9938
  _setViewPlaneToAcquisitionPlane(imageVolume) {
9874
9939
  let viewPlaneNormal, viewUp;
9875
9940
  if (imageVolume) {
@@ -13083,8 +13148,8 @@ var macros2 = __webpack_require__(28906);
13083
13148
  var BoundingBox = __webpack_require__(21734);
13084
13149
  // EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Rendering/Core/Prop3D.js
13085
13150
  var Prop3D = __webpack_require__(62502);
13086
- // EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Rendering/Core/ColorTransferFunction.js + 1 modules
13087
- var ColorTransferFunction = __webpack_require__(33739);
13151
+ // EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Rendering/Core/ColorTransferFunction.js
13152
+ var ColorTransferFunction = __webpack_require__(642);
13088
13153
  // EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Common/DataModel/PiecewiseFunction.js
13089
13154
  var PiecewiseFunction = __webpack_require__(99341);
13090
13155
  // EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Rendering/Core/VolumeProperty/Constants.js
@@ -21672,11 +21737,12 @@ class BaseStreamingImageVolume extends _ImageVolume__WEBPACK_IMPORTED_MODULE_9__
21672
21737
  rescaleIntercept: modalityLutModule.rescaleIntercept,
21673
21738
  modality: generalSeriesModule.modality,
21674
21739
  };
21675
- if (scalingParameters.modality === 'PT') {
21676
- const suvFactor = _metaData__WEBPACK_IMPORTED_MODULE_0__.get('scalingModule', imageId);
21677
- if (suvFactor) {
21678
- this._addScalingToVolume(suvFactor);
21679
- scalingParameters.suvbw = suvFactor.suvbw;
21740
+ const modality = scalingParameters.modality;
21741
+ if (modality === 'PT' || modality === 'RTDOSE') {
21742
+ const scalingFactor = _metaData__WEBPACK_IMPORTED_MODULE_0__.get('scalingModule', imageId);
21743
+ if (scalingFactor) {
21744
+ this._addScalingToVolume(scalingFactor);
21745
+ Object.assign(scalingParameters, scalingFactor);
21680
21746
  }
21681
21747
  }
21682
21748
  const floatAfterScale = (0,_utilities_hasFloatScalingParameters__WEBPACK_IMPORTED_MODULE_6__/* .hasFloatScalingParameters */ .a)(scalingParameters);
@@ -25953,6 +26019,7 @@ var Events;
25953
26019
  Events["GEOMETRY_LOADED"] = "GEOMETRY_LOADED";
25954
26020
  Events["GEOMETRY_LOAD_PROGRESS"] = "GEOMETRY_LOAD_PROGRESS";
25955
26021
  Events["GEOMETRY_LOADED_FAILED"] = "GEOMETRY_LOADED_FAILED";
26022
+ Events["ACTORS_CHANGED"] = "CORNERSTONE_ACTORS_CHANGED";
25956
26023
  })(Events || (Events = {}));
25957
26024
  /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Events);
25958
26025
 
@@ -38102,7 +38169,7 @@ function actorIsA(actorEntry, actorType) {
38102
38169
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
38103
38170
  /* harmony export */ A: () => (/* binding */ applyPreset)
38104
38171
  /* harmony export */ });
38105
- /* harmony import */ var _kitware_vtk_js_Rendering_Core_ColorTransferFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(33739);
38172
+ /* harmony import */ var _kitware_vtk_js_Rendering_Core_ColorTransferFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(642);
38106
38173
  /* harmony import */ var _kitware_vtk_js_Common_DataModel_PiecewiseFunction__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(99341);
38107
38174
 
38108
38175
 
@@ -38445,11 +38512,18 @@ __webpack_require__.r(__webpack_exports__);
38445
38512
  /* harmony export */ findMatchingColormap: () => (/* binding */ findMatchingColormap),
38446
38513
  /* harmony export */ getColormap: () => (/* binding */ getColormap),
38447
38514
  /* harmony export */ getColormapNames: () => (/* binding */ getColormapNames),
38448
- /* harmony export */ registerColormap: () => (/* binding */ registerColormap)
38515
+ /* harmony export */ registerColormap: () => (/* binding */ registerColormap),
38516
+ /* harmony export */ setColorMapTransferFunctionForVolumeActor: () => (/* binding */ setColorMapTransferFunctionForVolumeActor),
38517
+ /* harmony export */ updateOpacity: () => (/* binding */ updateOpacity),
38518
+ /* harmony export */ updateThreshold: () => (/* binding */ updateThreshold)
38449
38519
  /* harmony export */ });
38450
38520
  /* harmony import */ var _kitware_vtk_js_Rendering_Core_ColorTransferFunction_ColorMaps__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(660);
38451
- /* harmony import */ var _isEqual__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(74638);
38452
- /* harmony import */ var _actorCheck__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(98039);
38521
+ /* harmony import */ var _kitware_vtk_js_Rendering_Core_ColorTransferFunction__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(642);
38522
+ /* harmony import */ var _kitware_vtk_js_Common_DataModel_PiecewiseFunction__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(99341);
38523
+ /* harmony import */ var _isEqual__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(74638);
38524
+ /* harmony import */ var _actorCheck__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(98039);
38525
+
38526
+
38453
38527
 
38454
38528
 
38455
38529
 
@@ -38474,7 +38548,7 @@ function findMatchingColormap(rgbPoints, actor) {
38474
38548
  return false;
38475
38549
  }
38476
38550
  for (let i = 0; i < presetRGBPoints.length; i += 4) {
38477
- if (!(0,_isEqual__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Ay)(presetRGBPoints.slice(i + 1, i + 4), rgbPoints.slice(i + 1, i + 4))) {
38551
+ if (!(0,_isEqual__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Ay)(presetRGBPoints.slice(i + 1, i + 4), rgbPoints.slice(i + 1, i + 4))) {
38478
38552
  return false;
38479
38553
  }
38480
38554
  }
@@ -38484,7 +38558,7 @@ function findMatchingColormap(rgbPoints, actor) {
38484
38558
  return null;
38485
38559
  }
38486
38560
  const opacity = [];
38487
- if ((0,_actorCheck__WEBPACK_IMPORTED_MODULE_2__/* .actorIsA */ .N)(actor, 'vtkVolume')) {
38561
+ if ((0,_actorCheck__WEBPACK_IMPORTED_MODULE_4__/* .actorIsA */ .N)(actor, 'vtkVolume')) {
38488
38562
  const opacityPoints = actor
38489
38563
  .getProperty()
38490
38564
  .getScalarOpacity(0)
@@ -38506,6 +38580,80 @@ function findMatchingColormap(rgbPoints, actor) {
38506
38580
  opacity,
38507
38581
  };
38508
38582
  }
38583
+ function setColorMapTransferFunctionForVolumeActor(volumeInfo) {
38584
+ const { volumeActor, preset, opacity = 0.9, threshold = null, colorRange = [0, 5], } = volumeInfo;
38585
+ const mapper = volumeActor.getMapper();
38586
+ mapper.setSampleDistance(1.0);
38587
+ const cfun = _kitware_vtk_js_Rendering_Core_ColorTransferFunction__WEBPACK_IMPORTED_MODULE_1__/* ["default"].newInstance */ .Ay.newInstance();
38588
+ const presetToUse = preset || _kitware_vtk_js_Rendering_Core_ColorTransferFunction_ColorMaps__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .A.getPresetByName('hsv');
38589
+ cfun.applyColorMap(presetToUse);
38590
+ cfun.setMappingRange(colorRange[0], colorRange[1]);
38591
+ volumeActor.getProperty().setRGBTransferFunction(0, cfun);
38592
+ updateOpacityWithThreshold(volumeActor, opacity, threshold);
38593
+ }
38594
+ function updateOpacity(volumeActor, newOpacity) {
38595
+ const currentThreshold = getThresholdValue(volumeActor);
38596
+ updateOpacityWithThreshold(volumeActor, newOpacity, currentThreshold);
38597
+ }
38598
+ function updateThreshold(volumeActor, newThreshold) {
38599
+ const currentOpacity = getMaxOpacity(volumeActor);
38600
+ updateOpacityWithThreshold(volumeActor, currentOpacity, newThreshold);
38601
+ }
38602
+ function updateOpacityWithThreshold(volumeActor, opacity, threshold) {
38603
+ const transferFunction = volumeActor.getProperty().getRGBTransferFunction(0);
38604
+ const range = transferFunction.getRange();
38605
+ const ofun = _kitware_vtk_js_Common_DataModel_PiecewiseFunction__WEBPACK_IMPORTED_MODULE_2__/* ["default"].newInstance */ .Ay.newInstance();
38606
+ if (threshold !== null) {
38607
+ const delta = Math.abs(range[1] - range[0]) * 0.001;
38608
+ const thresholdValue = Math.max(range[0], Math.min(range[1], threshold));
38609
+ ofun.addPoint(range[0], 0);
38610
+ ofun.addPoint(thresholdValue - delta, 0);
38611
+ ofun.addPoint(thresholdValue, opacity);
38612
+ ofun.addPoint(range[1], opacity);
38613
+ }
38614
+ else {
38615
+ ofun.addPoint(range[0], opacity);
38616
+ ofun.addPoint(range[1], opacity);
38617
+ }
38618
+ volumeActor.getProperty().setScalarOpacity(0, ofun);
38619
+ }
38620
+ function getThresholdValue(volumeActor) {
38621
+ const opacityFunction = volumeActor.getProperty().getScalarOpacity(0);
38622
+ if (!opacityFunction) {
38623
+ return null;
38624
+ }
38625
+ const dataArray = opacityFunction.getDataPointer();
38626
+ if (!dataArray || dataArray.length <= 4) {
38627
+ return null;
38628
+ }
38629
+ for (let i = 0; i < dataArray.length - 2; i += 2) {
38630
+ const x1 = dataArray[i];
38631
+ const y1 = dataArray[i + 1];
38632
+ const x2 = dataArray[i + 2];
38633
+ const y2 = dataArray[i + 3];
38634
+ if (y1 === 0 && y2 > 0) {
38635
+ return x2;
38636
+ }
38637
+ }
38638
+ return null;
38639
+ }
38640
+ function getMaxOpacity(volumeActor) {
38641
+ const opacityFunction = volumeActor.getProperty().getScalarOpacity(0);
38642
+ if (!opacityFunction) {
38643
+ return 1.0;
38644
+ }
38645
+ const dataArray = opacityFunction.getDataPointer();
38646
+ if (!dataArray || dataArray.length === 0) {
38647
+ return 1.0;
38648
+ }
38649
+ let maxOpacity = 0;
38650
+ for (let i = 1; i < dataArray.length; i += 2) {
38651
+ if (dataArray[i] > maxOpacity) {
38652
+ maxOpacity = dataArray[i];
38653
+ }
38654
+ }
38655
+ return maxOpacity;
38656
+ }
38509
38657
 
38510
38658
 
38511
38659
 
@@ -38518,7 +38666,7 @@ function findMatchingColormap(rgbPoints, actor) {
38518
38666
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
38519
38667
  /* harmony export */ A: () => (/* binding */ createLinearRGBTransferFunction)
38520
38668
  /* harmony export */ });
38521
- /* harmony import */ var _kitware_vtk_js_Rendering_Core_ColorTransferFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(33739);
38669
+ /* harmony import */ var _kitware_vtk_js_Rendering_Core_ColorTransferFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(642);
38522
38670
 
38523
38671
  function createLinearRGBTransferFunction(voiRange) {
38524
38672
  const cfun = _kitware_vtk_js_Rendering_Core_ColorTransferFunction__WEBPACK_IMPORTED_MODULE_0__/* ["default"].newInstance */ .Ay.newInstance();
@@ -38598,7 +38746,7 @@ function createPositionCallback(imageData) {
38598
38746
  /* harmony export */ __webpack_require__.d(__webpack_exports__, {
38599
38747
  /* harmony export */ A: () => (/* binding */ createSigmoidRGBTransferFunction)
38600
38748
  /* harmony export */ });
38601
- /* harmony import */ var _kitware_vtk_js_Rendering_Core_ColorTransferFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(33739);
38749
+ /* harmony import */ var _kitware_vtk_js_Rendering_Core_ColorTransferFunction__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(642);
38602
38750
  /* harmony import */ var _kitware_vtk_js_Common_Core_DataArray__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(42008);
38603
38751
  /* harmony import */ var _windowLevel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(68136);
38604
38752
  /* harmony import */ var _logit__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(58977);
@@ -38930,6 +39078,8 @@ function getConstructorFromType(bufferType, isVolumeBuffer) {
38930
39078
  return Float32Array;
38931
39079
  case 'Uint8Array':
38932
39080
  return Uint8Array;
39081
+ case 'Uint32Array':
39082
+ return Uint32Array;
38933
39083
  case 'Uint16Array':
38934
39084
  case 'Int16Array':
38935
39085
  if (!isVolumeBuffer) {
@@ -38941,7 +39091,7 @@ function getConstructorFromType(bufferType, isVolumeBuffer) {
38941
39091
  }
38942
39092
  default:
38943
39093
  if (bufferType) {
38944
- throw new Error('TargetBuffer should be Float32Array, Uint8Array, Uint16Array, or Int16Array');
39094
+ throw new Error('TargetBuffer should be Float32Array, Uint8Array, Uint16Array, Int16Array, or Uint32Array');
38945
39095
  }
38946
39096
  else {
38947
39097
  return Float32Array;
@@ -38969,12 +39119,15 @@ function getBufferConfiguration(targetBufferType, length, options = {}) {
38969
39119
  /* harmony export */ });
38970
39120
  /* harmony import */ var gl_matrix__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(3823);
38971
39121
  /* harmony import */ var _metaData__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(74876);
38972
- /* harmony import */ var _getSpacingInNormalDirection__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(85008);
38973
- /* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(19325);
39122
+ /* harmony import */ var _logger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(7608);
39123
+ /* harmony import */ var _getSpacingInNormalDirection__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(85008);
39124
+ /* harmony import */ var _constants__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(19325);
38974
39125
 
38975
39126
 
38976
39127
 
38977
39128
 
39129
+
39130
+ const log = _logger__WEBPACK_IMPORTED_MODULE_2__.coreLog.getLogger('utilities', 'getClosestImageId');
38978
39131
  function getClosestImageId(imageVolume, worldPos, viewPlaneNormal, options) {
38979
39132
  const { direction, spacing, imageIds } = imageVolume;
38980
39133
  const { ignoreSpacing = false } = options || {};
@@ -38983,13 +39136,12 @@ function getClosestImageId(imageVolume, worldPos, viewPlaneNormal, options) {
38983
39136
  }
38984
39137
  const kVector = direction.slice(6, 9);
38985
39138
  const dotProduct = gl_matrix__WEBPACK_IMPORTED_MODULE_0__/* .vec3.dot */ .eR.dot(kVector, viewPlaneNormal);
38986
- if (Math.abs(dotProduct) < 1 - _constants__WEBPACK_IMPORTED_MODULE_3__.EPSILON) {
38987
- console.debug('View plane normal is not parallel to the image scan axis. Unable to find closest imageId.');
39139
+ if (Math.abs(dotProduct) < 1 - _constants__WEBPACK_IMPORTED_MODULE_4__.EPSILON) {
38988
39140
  return;
38989
39141
  }
38990
39142
  let halfSpacingInNormalDirection;
38991
39143
  if (!ignoreSpacing) {
38992
- const spacingInNormalDirection = (0,_getSpacingInNormalDirection__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .A)({ direction, spacing }, viewPlaneNormal);
39144
+ const spacingInNormalDirection = (0,_getSpacingInNormalDirection__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A)({ direction, spacing }, viewPlaneNormal);
38993
39145
  halfSpacingInNormalDirection = spacingInNormalDirection / 2;
38994
39146
  }
38995
39147
  let closestImageId;
@@ -38998,7 +39150,7 @@ function getClosestImageId(imageVolume, worldPos, viewPlaneNormal, options) {
38998
39150
  const imageId = imageIds[i];
38999
39151
  const imagePlaneModule = _metaData__WEBPACK_IMPORTED_MODULE_1__.get('imagePlaneModule', imageId);
39000
39152
  if (!imagePlaneModule?.imagePositionPatient) {
39001
- console.warn(`Missing imagePositionPatient for imageId: ${imageId}`);
39153
+ log.warn(`Missing imagePositionPatient for imageId: ${imageId}`);
39002
39154
  continue;
39003
39155
  }
39004
39156
  const { imagePositionPatient } = imagePlaneModule;
@@ -39019,7 +39171,7 @@ function getClosestImageId(imageVolume, worldPos, viewPlaneNormal, options) {
39019
39171
  }
39020
39172
  }
39021
39173
  if (closestImageId === undefined) {
39022
- console.debug('No imageId found within the specified criteria (half spacing or absolute closest).');
39174
+ log.warn('No imageId found within the specified criteria (half spacing or absolute closest).');
39023
39175
  }
39024
39176
  return closestImageId;
39025
39177
  }
@@ -39158,13 +39310,19 @@ function getScalingParameters(imageId) {
39158
39310
  rescaleIntercept: modalityLutModule.rescaleIntercept ?? 0,
39159
39311
  modality,
39160
39312
  };
39161
- const suvFactor = _metaData__WEBPACK_IMPORTED_MODULE_0__.get('scalingModule', imageId) || {};
39313
+ const scalingModules = _metaData__WEBPACK_IMPORTED_MODULE_0__.get('scalingModule', imageId) || {};
39162
39314
  return {
39163
39315
  ...scalingParameters,
39164
39316
  ...(modality === 'PT' && {
39165
- suvbw: suvFactor.suvbw,
39166
- suvbsa: suvFactor.suvbsa,
39167
- suvlbm: suvFactor.suvlbm,
39317
+ suvbw: scalingModules.suvbw,
39318
+ suvbsa: scalingModules.suvbsa,
39319
+ suvlbm: scalingModules.suvlbm,
39320
+ }),
39321
+ ...(modality === 'RTDOSE' && {
39322
+ doseGridScaling: scalingModules.DoseGridScaling,
39323
+ doseSummation: scalingModules.DoseSummation,
39324
+ doseType: scalingModules.DoseType,
39325
+ doseUnit: scalingModules.DoseUnit,
39168
39326
  }),
39169
39327
  };
39170
39328
  }
@@ -42571,7 +42729,18 @@ async function decodeLittleEndian(imageFrame, pixelData) {
42571
42729
  arrayBuffer = arrayBuffer.slice(offset);
42572
42730
  offset = 0;
42573
42731
  }
42574
- imageFrame.pixelData = new Float32Array(arrayBuffer, offset, length / 4);
42732
+ if (imageFrame.floatPixelData || imageFrame.doubleFloatPixelData) {
42733
+ throw new Error('Float pixel data is not supported for parsing into ImageFrame');
42734
+ }
42735
+ if (imageFrame.pixelRepresentation === 0) {
42736
+ imageFrame.pixelData = new Uint32Array(arrayBuffer, offset, length / 4);
42737
+ }
42738
+ else if (imageFrame.pixelRepresentation === 1) {
42739
+ imageFrame.pixelData = new Int32Array(arrayBuffer, offset, length / 4);
42740
+ }
42741
+ else {
42742
+ imageFrame.pixelData = new Float32Array(arrayBuffer, offset, length / 4);
42743
+ }
42575
42744
  }
42576
42745
  return imageFrame;
42577
42746
  }
@@ -43185,7 +43354,7 @@ function decodeHTJ2K_getPixelData(frameInfo, decodedBuffer) {
43185
43354
  ;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/dicom-image-loader/dist/esm/shared/scaling/scaleArray.js
43186
43355
  function scaleArray(array, scalingParameters) {
43187
43356
  const arrayLength = array.length;
43188
- const { rescaleSlope, rescaleIntercept, suvbw } = scalingParameters;
43357
+ const { rescaleSlope, rescaleIntercept, suvbw, doseGridScaling } = scalingParameters;
43189
43358
  if (scalingParameters.modality === 'PT' &&
43190
43359
  typeof suvbw === 'number' &&
43191
43360
  !isNaN(suvbw)) {
@@ -43193,6 +43362,13 @@ function scaleArray(array, scalingParameters) {
43193
43362
  array[i] = suvbw * (array[i] * rescaleSlope + rescaleIntercept);
43194
43363
  }
43195
43364
  }
43365
+ else if (scalingParameters.modality === 'RTDOSE' &&
43366
+ typeof doseGridScaling === 'number' &&
43367
+ !isNaN(doseGridScaling)) {
43368
+ for (let i = 0; i < arrayLength; i++) {
43369
+ array[i] = array[i] * doseGridScaling;
43370
+ }
43371
+ }
43196
43372
  else {
43197
43373
  for (let i = 0; i < arrayLength; i++) {
43198
43374
  array[i] = array[i] * rescaleSlope + rescaleIntercept;
@@ -43233,6 +43409,7 @@ const typedArrayConstructors = {
43233
43409
  Uint16Array,
43234
43410
  Int16Array,
43235
43411
  Float32Array,
43412
+ Uint32Array,
43236
43413
  };
43237
43414
  function postProcessDecodedPixels(imageFrame, options, start, decodeConfig) {
43238
43415
  const shouldShift = imageFrame.pixelRepresentation !== undefined &&
@@ -43279,8 +43456,8 @@ function postProcessDecodedPixels(imageFrame, options, start, decodeConfig) {
43279
43456
  const scalingParameters = options.preScale.scalingParameters;
43280
43457
  _validateScalingParameters(scalingParameters);
43281
43458
  const { rescaleSlope, rescaleIntercept } = scalingParameters;
43282
- const isSlopeAndInterceptNumbers = typeof rescaleSlope === 'number' && typeof rescaleIntercept === 'number';
43283
- if (isSlopeAndInterceptNumbers) {
43459
+ const isRequiredScaling = _isRequiredScaling(scalingParameters);
43460
+ if (isRequiredScaling) {
43284
43461
  scaleArray(pixelDataArray, scalingParameters);
43285
43462
  imageFrame.preScale = {
43286
43463
  ...options.preScale,
@@ -43310,6 +43487,13 @@ function postProcessDecodedPixels(imageFrame, options, start, decodeConfig) {
43310
43487
  imageFrame.decodeTimeInMS = end - start;
43311
43488
  return imageFrame;
43312
43489
  }
43490
+ function _isRequiredScaling(scalingParameters) {
43491
+ const { rescaleSlope, rescaleIntercept, modality, doseGridScaling, suvbw } = scalingParameters;
43492
+ const hasRescaleValues = typeof rescaleSlope === 'number' && typeof rescaleIntercept === 'number';
43493
+ const isRTDOSEWithScaling = modality === 'RTDOSE' && typeof doseGridScaling === 'number';
43494
+ const isPTWithSUV = modality === 'PT' && typeof suvbw === 'number';
43495
+ return hasRescaleValues || isRTDOSEWithScaling || isPTWithSUV;
43496
+ }
43313
43497
  function _handleTargetBuffer(options, imageFrame, typedArrayConstructors, pixelDataArray) {
43314
43498
  const { arrayBuffer, type, offset: rawOffset = 0, length: rawLength, rows, } = options.targetBuffer;
43315
43499
  const TypedArrayConstructor = typedArrayConstructors[type];
@@ -45500,10 +45684,16 @@ function getScalingParameters(metaData, imageId) {
45500
45684
  rescaleIntercept: modalityLutModule.rescaleIntercept,
45501
45685
  modality,
45502
45686
  };
45503
- const suvFactor = metaData.get('scalingModule', imageId) || {};
45687
+ const scalingModules = metaData.get('scalingModule', imageId) || {};
45504
45688
  return {
45505
45689
  ...scalingParameters,
45506
- ...(modality === 'PT' && { suvbw: suvFactor.suvbw }),
45690
+ ...(modality === 'PT' && { suvbw: scalingModules.suvbw }),
45691
+ ...(modality === 'RTDOSE' && {
45692
+ doseGridScaling: scalingModules.DoseGridScaling,
45693
+ doseSummation: scalingModules.DoseSummation,
45694
+ doseType: scalingModules.DoseType,
45695
+ doseUnit: scalingModules.DoseUnit,
45696
+ }),
45507
45697
  };
45508
45698
  }
45509
45699
 
@@ -45613,6 +45803,7 @@ function createImage(imageId, pixelData, transferSyntax, options = {}) {
45613
45803
  Uint16Array,
45614
45804
  Int16Array,
45615
45805
  Float32Array,
45806
+ Uint32Array,
45616
45807
  };
45617
45808
  if (length !== imageFrame.pixelDataLength) {
45618
45809
  throw new Error(`target array for image does not have the same length (${length}) as the decoded image length (${imageFrame.pixelDataLength}).`);
@@ -46050,12 +46241,12 @@ function combineFrameInstance_getFrameInformation(PerFrameFunctionalGroupsSequen
46050
46241
  const shared = (SharedFunctionalGroupsSequence
46051
46242
  ? Object.values(SharedFunctionalGroupsSequence[0])
46052
46243
  : [])
46053
- .map((it) => it[0])
46244
+ .map((it) => it['Value']?.[0])
46054
46245
  .filter((it) => it !== undefined && typeof it === 'object');
46055
46246
  const perFrame = (PerFrameFunctionalGroupsSequence
46056
46247
  ? Object.values(PerFrameFunctionalGroupsSequence[frameNumber - 1])
46057
46248
  : [])
46058
- .map((it) => it.Value[0])
46249
+ .map((it) => it['Value']?.[0])
46059
46250
  .filter((it) => it !== undefined && typeof it === 'object');
46060
46251
  return {
46061
46252
  shared,
@@ -47091,6 +47282,9 @@ function getPixelDataTypeFromMinMax(min, max) {
47091
47282
  else if (max <= 65535) {
47092
47283
  pixelDataType = Uint16Array;
47093
47284
  }
47285
+ else if (max <= 4294967295) {
47286
+ pixelDataType = Uint32Array;
47287
+ }
47094
47288
  }
47095
47289
  else {
47096
47290
  if (min >= -128 && max <= 127) {
@@ -61938,60 +62132,35 @@ var vtkCamera$1 = {
61938
62132
 
61939
62133
  /***/ }),
61940
62134
 
61941
- /***/ 33739:
62135
+ /***/ 642:
61942
62136
  /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
61943
62137
 
61944
62138
  "use strict";
61945
-
61946
- // EXPORTS
61947
- __webpack_require__.d(__webpack_exports__, {
61948
- Ay: () => (/* binding */ vtkColorTransferFunction$1)
61949
- });
61950
-
61951
- // UNUSED EXPORTS: extend, newInstance
61952
-
61953
- // EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/macros2.js
61954
- var macros2 = __webpack_require__(28906);
61955
- // EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Common/Core/Math/index.js
61956
- var Core_Math = __webpack_require__(16632);
61957
- // EXTERNAL MODULE: ../../../node_modules/@kitware/vtk.js/Common/Core/ScalarsToColors.js
61958
- var ScalarsToColors = __webpack_require__(80993);
61959
- ;// CONCATENATED MODULE: ../../../node_modules/@kitware/vtk.js/Rendering/Core/ColorTransferFunction/Constants.js
61960
- const ColorSpace = {
61961
- RGB: 0,
61962
- HSV: 1,
61963
- LAB: 2,
61964
- DIVERGING: 3
61965
- };
61966
- const Scale = {
61967
- LINEAR: 0,
61968
- LOG10: 1
61969
- };
61970
- var Constants = {
61971
- ColorSpace,
61972
- Scale
61973
- };
61974
-
61975
-
61976
-
61977
- ;// CONCATENATED MODULE: ../../../node_modules/@kitware/vtk.js/Rendering/Core/ColorTransferFunction.js
62139
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
62140
+ /* harmony export */ Ay: () => (/* binding */ vtkColorTransferFunction$1)
62141
+ /* harmony export */ });
62142
+ /* unused harmony exports extend, newInstance */
62143
+ /* harmony import */ var _macros2_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(28906);
62144
+ /* harmony import */ var _Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(16632);
62145
+ /* harmony import */ var _Common_Core_ScalarsToColors_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(80993);
62146
+ /* harmony import */ var _ColorTransferFunction_Constants_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(25128);
61978
62147
 
61979
62148
 
61980
62149
 
61981
62150
 
61982
62151
 
61983
62152
  const {
61984
- ColorSpace: ColorTransferFunction_ColorSpace,
61985
- Scale: ColorTransferFunction_Scale
61986
- } = Constants;
62153
+ ColorSpace,
62154
+ Scale
62155
+ } = _ColorTransferFunction_Constants_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Ay;
61987
62156
  const {
61988
62157
  ScalarMappingTarget
61989
- } = ScalarsToColors/* default */.Ay;
62158
+ } = _Common_Core_ScalarsToColors_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"] */ .Ay;
61990
62159
  const {
61991
62160
  vtkDebugMacro,
61992
62161
  vtkErrorMacro,
61993
62162
  vtkWarningMacro
61994
- } = macros2.m;
62163
+ } = _macros2_js__WEBPACK_IMPORTED_MODULE_0__.m;
61995
62164
 
61996
62165
  // ----------------------------------------------------------------------------
61997
62166
  // Global methods
@@ -62055,8 +62224,8 @@ function vtkColorTransferFunctionAngleDiff(a1, a2) {
62055
62224
  function vtkColorTransferFunctionInterpolateDiverging(s, rgb1, rgb2, result) {
62056
62225
  const lab1 = [];
62057
62226
  const lab2 = [];
62058
- (0,Core_Math.N)(rgb1, lab1);
62059
- (0,Core_Math.N)(rgb2, lab2);
62227
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.N)(rgb1, lab1);
62228
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.N)(rgb2, lab2);
62060
62229
  const msh1 = [];
62061
62230
  const msh2 = [];
62062
62231
  vtkColorTransferFunctionLabToMsh(lab1, msh1);
@@ -62099,7 +62268,7 @@ function vtkColorTransferFunctionInterpolateDiverging(s, rgb1, rgb2, result) {
62099
62268
  // Now convert back to RGB
62100
62269
  const labTmp = [];
62101
62270
  vtkColorTransferFunctionMshToLab(mshTmp, labTmp);
62102
- (0,Core_Math.O)(labTmp, result);
62271
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.O)(labTmp, result);
62103
62272
  }
62104
62273
 
62105
62274
  // ----------------------------------------------------------------------------
@@ -62179,7 +62348,7 @@ function vtkColorTransferFunction(publicAPI, model) {
62179
62348
  let sharpness = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0.0;
62180
62349
  const rgb = [];
62181
62350
  const hsv = [h, s, v];
62182
- (0,Core_Math.h)(hsv, rgb);
62351
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.h)(hsv, rgb);
62183
62352
  return publicAPI.addRGBPoint(x, rgb[0], rgb[1], rgb[2], midpoint, sharpness);
62184
62353
  };
62185
62354
 
@@ -62316,8 +62485,8 @@ function vtkColorTransferFunction(publicAPI, model) {
62316
62485
  const hsv2 = [h2, s2, v2];
62317
62486
  const rgb1 = [];
62318
62487
  const rgb2 = [];
62319
- (0,Core_Math.h)(hsv1, rgb1);
62320
- (0,Core_Math.h)(hsv2, rgb2);
62488
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.h)(hsv1, rgb1);
62489
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.h)(hsv2, rgb2);
62321
62490
  publicAPI.addRGBSegment(x1, rgb1[0], rgb1[1], rgb1[2], x2, rgb2[0], rgb2[1], rgb2[2]);
62322
62491
  };
62323
62492
 
@@ -62388,7 +62557,7 @@ function vtkColorTransferFunction(publicAPI, model) {
62388
62557
  // Special case: If either the start or end is a NaN, then all any
62389
62558
  // interpolation done on them is also a NaN. Therefore, fill the table with
62390
62559
  // the NaN color.
62391
- if ((0,Core_Math.i)(xStart) || (0,Core_Math.i)(xEnd)) {
62560
+ if ((0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.i)(xStart) || (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.i)(xEnd)) {
62392
62561
  for (let i = 0; i < size; i++) {
62393
62562
  table[i * 3 + 0] = model.nanColor[0];
62394
62563
  table[i * 3 + 1] = model.nanColor[1];
@@ -62420,7 +62589,7 @@ function vtkColorTransferFunction(publicAPI, model) {
62420
62589
  const tmpVec = [];
62421
62590
 
62422
62591
  // If the scale is logarithmic, make sure the range is valid.
62423
- let usingLogScale = model.scale === ColorTransferFunction_Scale.LOG10;
62592
+ let usingLogScale = model.scale === Scale.LOG10;
62424
62593
  if (usingLogScale) {
62425
62594
  // Note: This requires range[0] <= range[1].
62426
62595
  usingLogScale = model.mappingRange[0] > 0.0;
@@ -62469,7 +62638,7 @@ function vtkColorTransferFunction(publicAPI, model) {
62469
62638
  // normalize x
62470
62639
  const xn = (x - range[0]) / deltaRange;
62471
62640
  // discretize
62472
- const discretizeIndex = (0,Core_Math.K)(numberOfValues * xn);
62641
+ const discretizeIndex = (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.K)(numberOfValues * xn);
62473
62642
  // get discretized x
62474
62643
  x = range[0] + discretizeIndex / (numberOfValues - 1) * deltaRange;
62475
62644
  }
@@ -62529,7 +62698,7 @@ function vtkColorTransferFunction(publicAPI, model) {
62529
62698
  table[tidx + 2] = lastB;
62530
62699
  }
62531
62700
  }
62532
- } else if (x < model.mappingRange[0] || (0,Core_Math.L)(x) && x < 0) {
62701
+ } else if (x < model.mappingRange[0] || (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.L)(x) && x < 0) {
62533
62702
  // we are before the first node? If so, duplicate this node's values.
62534
62703
  // We have to deal with -inf here
62535
62704
  table[tidx] = 0.0;
@@ -62598,15 +62767,15 @@ function vtkColorTransferFunction(publicAPI, model) {
62598
62767
  // In this case we want piecewise linear
62599
62768
  if (sharpness < 0.01) {
62600
62769
  // Simple linear interpolation
62601
- if (model.colorSpace === ColorTransferFunction_ColorSpace.RGB) {
62770
+ if (model.colorSpace === ColorSpace.RGB) {
62602
62771
  table[tidx] = (1 - s) * rgb1[0] + s * rgb2[0];
62603
62772
  table[tidx + 1] = (1 - s) * rgb1[1] + s * rgb2[1];
62604
62773
  table[tidx + 2] = (1 - s) * rgb1[2] + s * rgb2[2];
62605
- } else if (model.colorSpace === ColorTransferFunction_ColorSpace.HSV) {
62774
+ } else if (model.colorSpace === ColorSpace.HSV) {
62606
62775
  const hsv1 = [];
62607
62776
  const hsv2 = [];
62608
- (0,Core_Math.M)(rgb1, hsv1);
62609
- (0,Core_Math.M)(rgb2, hsv2);
62777
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.M)(rgb1, hsv1);
62778
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.M)(rgb2, hsv2);
62610
62779
  if (model.hSVWrap && (hsv1[0] - hsv2[0] > 0.5 || hsv2[0] - hsv1[0] > 0.5)) {
62611
62780
  if (hsv1[0] > hsv2[0]) {
62612
62781
  hsv1[0] -= 1.0;
@@ -62623,26 +62792,26 @@ function vtkColorTransferFunction(publicAPI, model) {
62623
62792
  hsvTmp[2] = (1.0 - s) * hsv1[2] + s * hsv2[2];
62624
62793
 
62625
62794
  // Now convert this back to RGB
62626
- (0,Core_Math.h)(hsvTmp, tmpVec);
62795
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.h)(hsvTmp, tmpVec);
62627
62796
  table[tidx] = tmpVec[0];
62628
62797
  table[tidx + 1] = tmpVec[1];
62629
62798
  table[tidx + 2] = tmpVec[2];
62630
- } else if (model.colorSpace === ColorTransferFunction_ColorSpace.LAB) {
62799
+ } else if (model.colorSpace === ColorSpace.LAB) {
62631
62800
  const lab1 = [];
62632
62801
  const lab2 = [];
62633
- (0,Core_Math.N)(rgb1, lab1);
62634
- (0,Core_Math.N)(rgb2, lab2);
62802
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.N)(rgb1, lab1);
62803
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.N)(rgb2, lab2);
62635
62804
  const labTmp = [];
62636
62805
  labTmp[0] = (1 - s) * lab1[0] + s * lab2[0];
62637
62806
  labTmp[1] = (1 - s) * lab1[1] + s * lab2[1];
62638
62807
  labTmp[2] = (1 - s) * lab1[2] + s * lab2[2];
62639
62808
 
62640
62809
  // Now convert back to RGB
62641
- (0,Core_Math.O)(labTmp, tmpVec);
62810
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.O)(labTmp, tmpVec);
62642
62811
  table[tidx] = tmpVec[0];
62643
62812
  table[tidx + 1] = tmpVec[1];
62644
62813
  table[tidx + 2] = tmpVec[2];
62645
- } else if (model.colorSpace === ColorTransferFunction_ColorSpace.DIVERGING) {
62814
+ } else if (model.colorSpace === ColorSpace.DIVERGING) {
62646
62815
  vtkColorTransferFunctionInterpolateDiverging(s, rgb1, rgb2, tmpVec);
62647
62816
  table[tidx] = tmpVec[0];
62648
62817
  table[tidx + 1] = tmpVec[1];
@@ -62675,7 +62844,7 @@ function vtkColorTransferFunction(publicAPI, model) {
62675
62844
  const h4 = sss - ss;
62676
62845
  let slope;
62677
62846
  let t;
62678
- if (model.colorSpace === ColorTransferFunction_ColorSpace.RGB) {
62847
+ if (model.colorSpace === ColorSpace.RGB) {
62679
62848
  for (let j = 0; j < 3; j++) {
62680
62849
  // Use one slope for both end points
62681
62850
  slope = rgb2[j] - rgb1[j];
@@ -62684,11 +62853,11 @@ function vtkColorTransferFunction(publicAPI, model) {
62684
62853
  // Compute the value
62685
62854
  table[tidx + j] = h1 * rgb1[j] + h2 * rgb2[j] + h3 * t + h4 * t;
62686
62855
  }
62687
- } else if (model.colorSpace === ColorTransferFunction_ColorSpace.HSV) {
62856
+ } else if (model.colorSpace === ColorSpace.HSV) {
62688
62857
  const hsv1 = [];
62689
62858
  const hsv2 = [];
62690
- (0,Core_Math.M)(rgb1, hsv1);
62691
- (0,Core_Math.M)(rgb2, hsv2);
62859
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.M)(rgb1, hsv1);
62860
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.M)(rgb2, hsv2);
62692
62861
  if (model.hSVWrap && (hsv1[0] - hsv2[0] > 0.5 || hsv2[0] - hsv1[0] > 0.5)) {
62693
62862
  if (hsv1[0] > hsv2[0]) {
62694
62863
  hsv1[0] -= 1.0;
@@ -62709,15 +62878,15 @@ function vtkColorTransferFunction(publicAPI, model) {
62709
62878
  }
62710
62879
  }
62711
62880
  // Now convert this back to RGB
62712
- (0,Core_Math.h)(hsvTmp, tmpVec);
62881
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.h)(hsvTmp, tmpVec);
62713
62882
  table[tidx] = tmpVec[0];
62714
62883
  table[tidx + 1] = tmpVec[1];
62715
62884
  table[tidx + 2] = tmpVec[2];
62716
- } else if (model.colorSpace === ColorTransferFunction_ColorSpace.LAB) {
62885
+ } else if (model.colorSpace === ColorSpace.LAB) {
62717
62886
  const lab1 = [];
62718
62887
  const lab2 = [];
62719
- (0,Core_Math.N)(rgb1, lab1);
62720
- (0,Core_Math.N)(rgb2, lab2);
62888
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.N)(rgb1, lab1);
62889
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.N)(rgb2, lab2);
62721
62890
  const labTmp = [];
62722
62891
  for (let j = 0; j < 3; j++) {
62723
62892
  // Use one slope for both end points
@@ -62728,11 +62897,11 @@ function vtkColorTransferFunction(publicAPI, model) {
62728
62897
  labTmp[j] = h1 * lab1[j] + h2 * lab2[j] + h3 * t + h4 * t;
62729
62898
  }
62730
62899
  // Now convert this back to RGB
62731
- (0,Core_Math.O)(labTmp, tmpVec);
62900
+ (0,_Common_Core_Math_index_js__WEBPACK_IMPORTED_MODULE_1__.O)(labTmp, tmpVec);
62732
62901
  table[tidx] = tmpVec[0];
62733
62902
  table[tidx + 1] = tmpVec[1];
62734
62903
  table[tidx + 2] = tmpVec[2];
62735
- } else if (model.colorSpace === ColorTransferFunction_ColorSpace.DIVERGING) {
62904
+ } else if (model.colorSpace === ColorSpace.DIVERGING) {
62736
62905
  // I have not implemented proper interpolation by a hermite curve for
62737
62906
  // the diverging color map, but I cannot think of a good use case for
62738
62907
  // that anyway.
@@ -63087,10 +63256,10 @@ function vtkColorTransferFunction(publicAPI, model) {
63087
63256
  publicAPI.applyColorMap = colorMap => {
63088
63257
  const oldColorSpace = JSON.stringify(model.colorSpace);
63089
63258
  if (colorMap.ColorSpace) {
63090
- model.colorSpace = ColorTransferFunction_ColorSpace[colorMap.ColorSpace.toUpperCase()];
63259
+ model.colorSpace = ColorSpace[colorMap.ColorSpace.toUpperCase()];
63091
63260
  if (model.colorSpace === undefined) {
63092
63261
  vtkErrorMacro(`ColorSpace ${colorMap.ColorSpace} not supported, using RGB instead`);
63093
- model.colorSpace = ColorTransferFunction_ColorSpace.RGB;
63262
+ model.colorSpace = ColorSpace.RGB;
63094
63263
  }
63095
63264
  }
63096
63265
  let isModified = oldColorSpace !== JSON.stringify(model.colorSpace);
@@ -63132,9 +63301,9 @@ function vtkColorTransferFunction(publicAPI, model) {
63132
63301
 
63133
63302
  const DEFAULT_VALUES = {
63134
63303
  clamping: true,
63135
- colorSpace: ColorTransferFunction_ColorSpace.RGB,
63304
+ colorSpace: ColorSpace.RGB,
63136
63305
  hSVWrap: true,
63137
- scale: ColorTransferFunction_Scale.LINEAR,
63306
+ scale: Scale.LINEAR,
63138
63307
  nanColor: null,
63139
63308
  belowRangeColor: null,
63140
63309
  aboveRangeColor: null,
@@ -63156,7 +63325,7 @@ function extend(publicAPI, model) {
63156
63325
  Object.assign(model, DEFAULT_VALUES, initialValues);
63157
63326
 
63158
63327
  // Inheritance
63159
- ScalarsToColors/* default.extend */.Ay.extend(publicAPI, model, initialValues);
63328
+ _Common_Core_ScalarsToColors_js__WEBPACK_IMPORTED_MODULE_2__/* ["default"].extend */ .Ay.extend(publicAPI, model, initialValues);
63160
63329
 
63161
63330
  // Internal objects initialization
63162
63331
  model.table = [];
@@ -63165,25 +63334,25 @@ function extend(publicAPI, model) {
63165
63334
  model.belowRangeColor = [0.0, 0.0, 0.0, 1.0];
63166
63335
  model.aboveRangeColor = [1.0, 1.0, 1.0, 1.0];
63167
63336
  model.buildTime = {};
63168
- macros2.m.obj(model.buildTime);
63337
+ _macros2_js__WEBPACK_IMPORTED_MODULE_0__.m.obj(model.buildTime);
63169
63338
 
63170
63339
  // Create get-only macros
63171
- macros2.m.get(publicAPI, model, ['buildTime', 'mappingRange']);
63340
+ _macros2_js__WEBPACK_IMPORTED_MODULE_0__.m.get(publicAPI, model, ['buildTime', 'mappingRange']);
63172
63341
 
63173
63342
  // Create get-set macros
63174
- macros2.m.setGet(publicAPI, model, ['useAboveRangeColor', 'useBelowRangeColor', 'discretize', 'numberOfValues', {
63343
+ _macros2_js__WEBPACK_IMPORTED_MODULE_0__.m.setGet(publicAPI, model, ['useAboveRangeColor', 'useBelowRangeColor', 'discretize', 'numberOfValues', {
63175
63344
  type: 'enum',
63176
63345
  name: 'colorSpace',
63177
- enum: ColorTransferFunction_ColorSpace
63346
+ enum: ColorSpace
63178
63347
  }, {
63179
63348
  type: 'enum',
63180
63349
  name: 'scale',
63181
- enum: ColorTransferFunction_Scale
63350
+ enum: Scale
63182
63351
  }]);
63183
- macros2.m.setArray(publicAPI, model, ['nanColor', 'belowRangeColor', 'aboveRangeColor'], 4);
63352
+ _macros2_js__WEBPACK_IMPORTED_MODULE_0__.m.setArray(publicAPI, model, ['nanColor', 'belowRangeColor', 'aboveRangeColor'], 4);
63184
63353
 
63185
63354
  // Create get macros for array
63186
- macros2.m.getArray(publicAPI, model, ['nanColor', 'belowRangeColor', 'aboveRangeColor']);
63355
+ _macros2_js__WEBPACK_IMPORTED_MODULE_0__.m.getArray(publicAPI, model, ['nanColor', 'belowRangeColor', 'aboveRangeColor']);
63187
63356
 
63188
63357
  // For more macro methods, see "Sources/macros.js"
63189
63358
 
@@ -63193,14 +63362,14 @@ function extend(publicAPI, model) {
63193
63362
 
63194
63363
  // ----------------------------------------------------------------------------
63195
63364
 
63196
- const newInstance = macros2.m.newInstance(extend, 'vtkColorTransferFunction');
63365
+ const newInstance = _macros2_js__WEBPACK_IMPORTED_MODULE_0__.m.newInstance(extend, 'vtkColorTransferFunction');
63197
63366
 
63198
63367
  // ----------------------------------------------------------------------------
63199
63368
 
63200
63369
  var vtkColorTransferFunction$1 = {
63201
63370
  newInstance,
63202
63371
  extend,
63203
- ...Constants
63372
+ ..._ColorTransferFunction_Constants_js__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .Ay
63204
63373
  };
63205
63374
 
63206
63375
 
@@ -77746,6 +77915,34 @@ var ColorMaps_vtkColorMaps = {
77746
77915
 
77747
77916
 
77748
77917
 
77918
+ /***/ }),
77919
+
77920
+ /***/ 25128:
77921
+ /***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
77922
+
77923
+ "use strict";
77924
+ /* harmony export */ __webpack_require__.d(__webpack_exports__, {
77925
+ /* harmony export */ Ay: () => (/* binding */ Constants)
77926
+ /* harmony export */ });
77927
+ /* unused harmony exports ColorSpace, Scale */
77928
+ const ColorSpace = {
77929
+ RGB: 0,
77930
+ HSV: 1,
77931
+ LAB: 2,
77932
+ DIVERGING: 3
77933
+ };
77934
+ const Scale = {
77935
+ LINEAR: 0,
77936
+ LOG10: 1
77937
+ };
77938
+ var Constants = {
77939
+ ColorSpace,
77940
+ Scale
77941
+ };
77942
+
77943
+
77944
+
77945
+
77749
77946
  /***/ }),
77750
77947
 
77751
77948
  /***/ 94520:
@@ -119713,27 +119910,27 @@ async function loadModule(module) {
119713
119910
  return imported.default;
119714
119911
  }
119715
119912
  if (module === "@ohif/extension-cornerstone") {
119716
- const imported = await Promise.all(/* import() */[__webpack_require__.e(2914), __webpack_require__.e(3075), __webpack_require__.e(9977), __webpack_require__.e(6029), __webpack_require__.e(8185), __webpack_require__.e(3984), __webpack_require__.e(7241), __webpack_require__.e(5674)]).then(__webpack_require__.bind(__webpack_require__, 7241));
119913
+ const imported = await Promise.all(/* import() */[__webpack_require__.e(2914), __webpack_require__.e(3075), __webpack_require__.e(9977), __webpack_require__.e(6029), __webpack_require__.e(8185), __webpack_require__.e(3984), __webpack_require__.e(8572), __webpack_require__.e(5674)]).then(__webpack_require__.bind(__webpack_require__, 78572));
119717
119914
  return imported.default;
119718
119915
  }
119719
119916
  if (module === "@ohif/extension-measurement-tracking") {
119720
- const imported = await Promise.all(/* import() */[__webpack_require__.e(2914), __webpack_require__.e(3075), __webpack_require__.e(9977), __webpack_require__.e(6029), __webpack_require__.e(8185), __webpack_require__.e(3166), __webpack_require__.e(5261), __webpack_require__.e(3984), __webpack_require__.e(7241), __webpack_require__.e(4113), __webpack_require__.e(2932)]).then(__webpack_require__.bind(__webpack_require__, 3427));
119917
+ const imported = await Promise.all(/* import() */[__webpack_require__.e(2914), __webpack_require__.e(3075), __webpack_require__.e(9977), __webpack_require__.e(6029), __webpack_require__.e(8185), __webpack_require__.e(908), __webpack_require__.e(5261), __webpack_require__.e(3984), __webpack_require__.e(8572), __webpack_require__.e(4113), __webpack_require__.e(2932)]).then(__webpack_require__.bind(__webpack_require__, 3427));
119721
119918
  return imported.default;
119722
119919
  }
119723
119920
  if (module === "@ohif/extension-cornerstone-dicom-sr") {
119724
- const imported = await Promise.all(/* import() */[__webpack_require__.e(2914), __webpack_require__.e(3075), __webpack_require__.e(9977), __webpack_require__.e(6029), __webpack_require__.e(8185), __webpack_require__.e(3166), __webpack_require__.e(3984), __webpack_require__.e(7241), __webpack_require__.e(4113), __webpack_require__.e(8402)]).then(__webpack_require__.bind(__webpack_require__, 34113));
119921
+ const imported = await Promise.all(/* import() */[__webpack_require__.e(2914), __webpack_require__.e(3075), __webpack_require__.e(9977), __webpack_require__.e(6029), __webpack_require__.e(8185), __webpack_require__.e(908), __webpack_require__.e(3984), __webpack_require__.e(8572), __webpack_require__.e(4113), __webpack_require__.e(8402)]).then(__webpack_require__.bind(__webpack_require__, 34113));
119725
119922
  return imported.default;
119726
119923
  }
119727
119924
  if (module === "@ohif/extension-cornerstone-dicom-seg") {
119728
- const imported = await Promise.all(/* import() */[__webpack_require__.e(2914), __webpack_require__.e(3075), __webpack_require__.e(9977), __webpack_require__.e(6029), __webpack_require__.e(3166), __webpack_require__.e(3984), __webpack_require__.e(7197)]).then(__webpack_require__.bind(__webpack_require__, 96975));
119925
+ const imported = await Promise.all(/* import() */[__webpack_require__.e(2914), __webpack_require__.e(3075), __webpack_require__.e(9977), __webpack_require__.e(6029), __webpack_require__.e(908), __webpack_require__.e(3984), __webpack_require__.e(7197)]).then(__webpack_require__.bind(__webpack_require__, 96975));
119729
119926
  return imported.default;
119730
119927
  }
119731
119928
  if (module === "@ohif/extension-cornerstone-dicom-pmap") {
119732
- const imported = await Promise.all(/* import() */[__webpack_require__.e(2914), __webpack_require__.e(3075), __webpack_require__.e(9977), __webpack_require__.e(6029), __webpack_require__.e(8185), __webpack_require__.e(3166), __webpack_require__.e(3984), __webpack_require__.e(7241), __webpack_require__.e(6201)]).then(__webpack_require__.bind(__webpack_require__, 82098));
119929
+ const imported = await Promise.all(/* import() */[__webpack_require__.e(2914), __webpack_require__.e(3075), __webpack_require__.e(9977), __webpack_require__.e(6029), __webpack_require__.e(8185), __webpack_require__.e(908), __webpack_require__.e(3984), __webpack_require__.e(8572), __webpack_require__.e(6201)]).then(__webpack_require__.bind(__webpack_require__, 82098));
119733
119930
  return imported.default;
119734
119931
  }
119735
119932
  if (module === "@ohif/extension-cornerstone-dynamic-volume") {
119736
- const imported = await Promise.all(/* import() */[__webpack_require__.e(2914), __webpack_require__.e(3075), __webpack_require__.e(9977), __webpack_require__.e(6029), __webpack_require__.e(8185), __webpack_require__.e(3984), __webpack_require__.e(7241), __webpack_require__.e(1919)]).then(__webpack_require__.bind(__webpack_require__, 14696));
119933
+ const imported = await Promise.all(/* import() */[__webpack_require__.e(2914), __webpack_require__.e(3075), __webpack_require__.e(9977), __webpack_require__.e(6029), __webpack_require__.e(8185), __webpack_require__.e(3984), __webpack_require__.e(8572), __webpack_require__.e(1919)]).then(__webpack_require__.bind(__webpack_require__, 14696));
119737
119934
  return imported.default;
119738
119935
  }
119739
119936
  if (module === "@ohif/extension-dicom-microscopy") {
@@ -119749,11 +119946,11 @@ async function loadModule(module) {
119749
119946
  return imported.default;
119750
119947
  }
119751
119948
  if (module === "@ohif/extension-tmtv") {
119752
- const imported = await Promise.all(/* import() */[__webpack_require__.e(2914), __webpack_require__.e(3075), __webpack_require__.e(9977), __webpack_require__.e(6029), __webpack_require__.e(8185), __webpack_require__.e(3166), __webpack_require__.e(3984), __webpack_require__.e(7241), __webpack_require__.e(810)]).then(__webpack_require__.bind(__webpack_require__, 57289));
119949
+ const imported = await Promise.all(/* import() */[__webpack_require__.e(2914), __webpack_require__.e(3075), __webpack_require__.e(9977), __webpack_require__.e(6029), __webpack_require__.e(8185), __webpack_require__.e(908), __webpack_require__.e(3984), __webpack_require__.e(8572), __webpack_require__.e(810)]).then(__webpack_require__.bind(__webpack_require__, 57289));
119753
119950
  return imported.default;
119754
119951
  }
119755
119952
  if (module === "@ohif/extension-test") {
119756
- const imported = await Promise.all(/* import() */[__webpack_require__.e(2914), __webpack_require__.e(3075), __webpack_require__.e(9977), __webpack_require__.e(6029), __webpack_require__.e(8185), __webpack_require__.e(3984), __webpack_require__.e(7241), __webpack_require__.e(934)]).then(__webpack_require__.bind(__webpack_require__, 94285));
119953
+ const imported = await Promise.all(/* import() */[__webpack_require__.e(2914), __webpack_require__.e(3075), __webpack_require__.e(9977), __webpack_require__.e(6029), __webpack_require__.e(8185), __webpack_require__.e(3984), __webpack_require__.e(8572), __webpack_require__.e(934)]).then(__webpack_require__.bind(__webpack_require__, 94285));
119757
119954
  return imported.default;
119758
119955
  }
119759
119956
  if (module === "@ohif/extension-cornerstone-dicom-rt") {
@@ -119761,7 +119958,7 @@ async function loadModule(module) {
119761
119958
  return imported.default;
119762
119959
  }
119763
119960
  if (module === "@ohif/mode-longitudinal") {
119764
- const imported = await Promise.all(/* import() */[__webpack_require__.e(2914), __webpack_require__.e(3075), __webpack_require__.e(9977), __webpack_require__.e(6029), __webpack_require__.e(8185), __webpack_require__.e(3166), __webpack_require__.e(3984), __webpack_require__.e(7241), __webpack_require__.e(4113), __webpack_require__.e(963)]).then(__webpack_require__.bind(__webpack_require__, 6980));
119961
+ const imported = await Promise.all(/* import() */[__webpack_require__.e(2914), __webpack_require__.e(3075), __webpack_require__.e(9977), __webpack_require__.e(6029), __webpack_require__.e(8185), __webpack_require__.e(908), __webpack_require__.e(3984), __webpack_require__.e(8572), __webpack_require__.e(4113), __webpack_require__.e(963)]).then(__webpack_require__.bind(__webpack_require__, 6980));
119765
119962
  return imported.default;
119766
119963
  }
119767
119964
  if (module === "@ohif/mode-segmentation") {
@@ -125375,6 +125572,7 @@ const serviceImplementation = {
125375
125572
  console.warn('isEmpty() NOT IMPLEMENTED');
125376
125573
  return true;
125377
125574
  },
125575
+ _updatePosition: (id, position) => console.warn('updatePosition() NOT IMPLEMENTED'),
125378
125576
  _customComponent: null
125379
125577
  };
125380
125578
  class UIDialogService {
@@ -125416,6 +125614,16 @@ class UIDialogService {
125416
125614
  return serviceImplementation._isEmpty();
125417
125615
  }
125418
125616
 
125617
+ /**
125618
+ * Update the position of a specific dialog by id
125619
+ *
125620
+ * @param {string} id - The dialog id to update
125621
+ * @param {{ x: number; y: number }} position - The new position
125622
+ */
125623
+ updatePosition(id, position) {
125624
+ return serviceImplementation._updatePosition(id, position);
125625
+ }
125626
+
125419
125627
  /**
125420
125628
  * This provides flexibility in customizing the Modal's default component
125421
125629
  *
@@ -125433,6 +125641,7 @@ class UIDialogService {
125433
125641
  hide,
125434
125642
  hideAll,
125435
125643
  isEmpty,
125644
+ updatePosition,
125436
125645
  customComponent
125437
125646
  }) {
125438
125647
  if (show) {
@@ -125447,6 +125656,9 @@ class UIDialogService {
125447
125656
  if (isEmpty) {
125448
125657
  serviceImplementation._isEmpty = isEmpty;
125449
125658
  }
125659
+ if (updatePosition) {
125660
+ serviceImplementation._updatePosition = updatePosition;
125661
+ }
125450
125662
  if (customComponent) {
125451
125663
  serviceImplementation._customComponent = customComponent;
125452
125664
  }
@@ -125608,17 +125820,24 @@ class UINotificationService {
125608
125820
  * @param {string} [notification.promiseMessages.loading] - Message to show while promise is pending
125609
125821
  * @param {string | function} [notification.promiseMessages.success] - Message to show when promise resolves
125610
125822
  * @param {string | function} [notification.promiseMessages.error] - Message to show when promise rejects
125823
+ * @param {object} [notification.action] - Action button configuration
125824
+ * @param {string} notification.action.label - The label for the action button
125825
+ * @param {function} notification.action.onClick - The function to call when the action button is clicked
125611
125826
  * @returns {string} id - The ID of the created notification
125612
125827
  */
125613
125828
  show({
125614
125829
  title,
125615
125830
  message,
125616
- duration = 5000,
125831
+ duration = 2000,
125617
125832
  position = 'bottom-right',
125618
125833
  type = 'info',
125619
125834
  autoClose = true,
125620
125835
  promise,
125621
- promiseMessages
125836
+ promiseMessages,
125837
+ id,
125838
+ allowDuplicates = false,
125839
+ deduplicationInterval = 30000,
125840
+ action
125622
125841
  }) {
125623
125842
  if (promise && promiseMessages) {
125624
125843
  const loadingId = UINotificationService_serviceImplementation._show({
@@ -125626,7 +125845,10 @@ class UINotificationService {
125626
125845
  message: promiseMessages.loading || 'Loading...',
125627
125846
  type: 'loading',
125628
125847
  autoClose: false,
125629
- position
125848
+ position,
125849
+ id: id ? `${id}-loading` : undefined,
125850
+ allowDuplicates,
125851
+ deduplicationInterval
125630
125852
  });
125631
125853
  promise.then(data => {
125632
125854
  const successMessage = typeof promiseMessages.success === 'function' ? promiseMessages.success(data) : promiseMessages.success || 'Success';
@@ -125636,7 +125858,11 @@ class UINotificationService {
125636
125858
  type: 'success',
125637
125859
  duration,
125638
125860
  position,
125639
- autoClose
125861
+ autoClose,
125862
+ id: id ? `${id}-success` : undefined,
125863
+ allowDuplicates,
125864
+ deduplicationInterval,
125865
+ action
125640
125866
  });
125641
125867
  this.hide(loadingId);
125642
125868
  }, error => {
@@ -125647,7 +125873,11 @@ class UINotificationService {
125647
125873
  type: 'error',
125648
125874
  duration,
125649
125875
  position,
125650
- autoClose
125876
+ autoClose,
125877
+ id: id ? `${id}-error` : undefined,
125878
+ allowDuplicates,
125879
+ deduplicationInterval,
125880
+ action
125651
125881
  });
125652
125882
  this.hide(loadingId);
125653
125883
  });
@@ -125659,7 +125889,11 @@ class UINotificationService {
125659
125889
  duration,
125660
125890
  position,
125661
125891
  type,
125662
- autoClose
125892
+ autoClose,
125893
+ id,
125894
+ allowDuplicates,
125895
+ deduplicationInterval,
125896
+ action
125663
125897
  });
125664
125898
  }
125665
125899
  }
@@ -133073,7 +133307,10 @@ class MetadataProvider {
133073
133307
  RescaleIntercept,
133074
133308
  RescaleSlope
133075
133309
  } = instance;
133076
- if (RescaleIntercept === undefined || RescaleSlope === undefined) {
133310
+ // Early return if RescaleIntercept or RescaleSlope are not
133311
+ // present (undefined) or explicitly set to null. We use loose
133312
+ // equality in this case to check for *null* or *undefined*.
133313
+ if (RescaleIntercept == null || RescaleSlope == null) {
133077
133314
  return;
133078
133315
  }
133079
133316
  metadata = {
@@ -138924,7 +139161,7 @@ const detectionOptions = {
138924
139161
  }
138925
139162
  });
138926
139163
  ;// CONCATENATED MODULE: ../../i18n/package.json
138927
- const package_namespaceObject = {"rE":"3.10.0"};
139164
+ const package_namespaceObject = {"rE":"3.10.1"};
138928
139165
  ;// CONCATENATED MODULE: ../../i18n/src/utils.js
138929
139166
  const languagesMap = {
138930
139167
  ar: 'Arabic',
@@ -141336,8 +141573,8 @@ const PowerOff = props => /*#__PURE__*/react.createElement("svg", PowerOff_exten
141336
141573
  xmlns: "http://www.w3.org/2000/svg",
141337
141574
  viewBox: "0 0 24 28",
141338
141575
  "aria-labelledby": "title",
141339
- width: "1em",
141340
- height: "1em",
141576
+ width: "28px",
141577
+ height: "28px",
141341
141578
  fill: "currentColor"
141342
141579
  }, props), /*#__PURE__*/react.createElement("title", {
141343
141580
  id: "title"
@@ -145685,7 +145922,7 @@ const Clear = props => /*#__PURE__*/react.createElement("svg", Clear_extends({
145685
145922
  fill: "none",
145686
145923
  fillRule: "evenodd"
145687
145924
  }, /*#__PURE__*/react.createElement("circle", {
145688
- fill: "#0944B3",
145925
+ fill: "currentColor",
145689
145926
  cx: "9.5",
145690
145927
  cy: "9.5",
145691
145928
  r: "9.5"
@@ -226503,463 +226740,1729 @@ const StudySummary = ({
226503
226740
 
226504
226741
  // EXTERNAL MODULE: ../../../node_modules/react-error-boundary/dist/react-error-boundary.esm.js
226505
226742
  var react_error_boundary_esm = __webpack_require__(31523);
226506
- ;// CONCATENATED MODULE: ../../ui-next/src/components/Errorboundary/ErrorBoundary.tsx
226743
+ ;// CONCATENATED MODULE: ../../ui-next/src/contextProviders/NotificationProvider.tsx
226744
+ function NotificationProvider_extends() { return NotificationProvider_extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, NotificationProvider_extends.apply(null, arguments); }
226507
226745
 
226508
226746
 
226509
226747
 
226748
+ const NotificationContext = /*#__PURE__*/(0,react.createContext)(null);
226749
+ const useNotification = () => (0,react.useContext)(NotificationContext);
226510
226750
 
226751
+ // Notification deduplication cache
226511
226752
 
226753
+ const NotificationProvider = ({
226754
+ children,
226755
+ service,
226756
+ deduplicationInterval = 10000 // Default to 10 seconds
226757
+ }) => {
226758
+ const DEFAULT_OPTIONS = {
226759
+ title: '',
226760
+ message: '',
226761
+ duration: 5000,
226762
+ position: 'bottom-right',
226763
+ // Aligning to Sonner's positioning system
226764
+ type: 'info' // info, success, error
226765
+ };
226512
226766
 
226767
+ // Cache for recent notifications to prevent duplicates
226768
+ // Structure: { [title_message_type]: { timestamp, id } }
226769
+ const recentNotificationsRef = (0,react.useRef)({});
226513
226770
 
226514
- const isProduction = "production" === 'production';
226771
+ // Use the configurable deduplication interval from props
226515
226772
 
226516
- /**
226517
- * Parses an error stack trace to extract important information
226518
- * Extracts the first function name from the stack trace
226519
- */
226520
- const parseErrorStack = error => {
226521
- if (!error.stack) {
226522
- return {
226523
- filePath: null,
226524
- errorTitle: null,
226525
- code: null,
226526
- firstFilename: null
226773
+ const show = (0,react.useCallback)(options => {
226774
+ const {
226775
+ title,
226776
+ message,
226777
+ duration,
226778
+ position,
226779
+ type,
226780
+ promise,
226781
+ allowDuplicates = false,
226782
+ deduplicationInterval: optionsDeduplicationInterval,
226783
+ action
226784
+ } = {
226785
+ ...DEFAULT_OPTIONS,
226786
+ ...options
226527
226787
  };
226528
- }
226529
- const stack = error.stack;
226530
- const stackLines = stack.split('\n');
226531
-
226532
- // Extract error message from first line
226533
- const errorMessage = stackLines[0].trim();
226534
-
226535
- // Extract first function name from the stack trace
226536
- let firstFilename = null;
226537
226788
 
226538
- // Find the first stack line (starts with " at ")
226539
- for (let i = 1; i < stackLines.length; i++) {
226540
- const line = stackLines[i].trim();
226541
- if (line.startsWith('at ')) {
226542
- // Extract function name pattern
226543
- const match = line.match(/at\s+([^\s(]+)[\s(]/);
226544
- if (match && match[1]) {
226545
- firstFilename = match[1];
226546
- break;
226547
- }
226789
+ // Use the provider's deduplicationInterval by default, but allow it to be overridden per notification
226790
+ const notificationDeduplicationInterval = optionsDeduplicationInterval || deduplicationInterval;
226791
+ if (promise) {
226792
+ return dist_ue.promise(promise, {
226793
+ loading: title || 'Loading...',
226794
+ success: data => {
226795
+ const description = typeof message === 'function' ? message(data) : message;
226796
+ return {
226797
+ title: title || 'Success',
226798
+ description
226799
+ };
226800
+ },
226801
+ error: err => {
226802
+ const description = typeof message === 'function' ? message(err) : message;
226803
+ return {
226804
+ title: title || 'Error',
226805
+ description
226806
+ };
226807
+ }
226808
+ });
226548
226809
  }
226549
- }
226550
226810
 
226551
- // Sanitize stack trace for display - safer approach to avoid ReDoS
226552
- const sanitizedStack = stackLines.map(line => {
226553
- // Limit line length to prevent excessive processing
226554
- const limitedLine = line.substring(0, 2000);
226811
+ // Create a cache key from notification properties
226812
+ const messageStr = typeof message === 'function' ? 'function' : message;
226813
+ const cacheKey = `${title}_${messageStr}_${type}`;
226555
226814
 
226556
- // Process each part separately to avoid complex regex patterns
226557
- if (limitedLine.includes('(')) {
226558
- // Extract filename from paths in parentheses
226559
- const openParenIndex = limitedLine.indexOf('(');
226560
- const closeParenIndex = limitedLine.indexOf(')', openParenIndex);
226561
- if (openParenIndex >= 0 && closeParenIndex > openParenIndex) {
226562
- const pathInParens = limitedLine.substring(openParenIndex + 1, closeParenIndex);
226815
+ // Handle deduplication
226816
+ if (!allowDuplicates && type === 'error') {
226817
+ const now = Date.now();
226818
+ const cachedNotification = recentNotificationsRef.current[cacheKey];
226563
226819
 
226564
- // Find the last segment after slash or backslash
226565
- const lastSlashIndex = Math.max(pathInParens.lastIndexOf('/'), pathInParens.lastIndexOf('\\'));
226566
- if (lastSlashIndex >= 0) {
226567
- const filename = pathInParens.substring(lastSlashIndex + 1);
226568
- return limitedLine.substring(0, openParenIndex + 1) + filename + limitedLine.substring(closeParenIndex);
226820
+ // First check if we've shown this notification recently
226821
+ if (cachedNotification) {
226822
+ const timeSinceLastShown = now - cachedNotification.timestamp;
226823
+
226824
+ // If it's been shown recently and within the deduplication interval,
226825
+ // don't show it again
226826
+ if (timeSinceLastShown < notificationDeduplicationInterval) {
226827
+ console.debug(`Prevented duplicate notification: "${title}" (${timeSinceLastShown}ms < ${notificationDeduplicationInterval}ms)`);
226828
+ // Return the existing notification ID
226829
+ return cachedNotification.id;
226569
226830
  }
226831
+
226832
+ // If it's been shown before but outside the deduplication interval,
226833
+ // dismiss the old notification first and allow showing a new one
226834
+ console.debug(`Showing notification again after interval: "${title}" (${timeSinceLastShown}ms >= ${notificationDeduplicationInterval}ms)`);
226835
+ dist_ue.dismiss(cachedNotification.id);
226570
226836
  }
226571
226837
  }
226572
226838
 
226573
- // Handle the "at Function path:line:column" format
226574
- if (limitedLine.includes(' at ')) {
226575
- const atIndex = limitedLine.indexOf(' at ');
226576
- const afterAt = limitedLine.substring(atIndex + 4).trim();
226839
+ // Show the notification with action if provided
226840
+ const toastOptions = {
226841
+ duration,
226842
+ position,
226843
+ description: message,
226844
+ id: options.id // Use provided ID if available
226845
+ };
226577
226846
 
226578
- // Split by whitespace to separate function and path
226579
- const spaceAfterFunc = afterAt.indexOf(' ');
226580
- if (spaceAfterFunc > 0) {
226581
- const funcName = afterAt.substring(0, spaceAfterFunc);
226582
- const path = afterAt.substring(spaceAfterFunc + 1);
226847
+ // Add action button if provided
226848
+ if (action && action.label && typeof action.onClick === 'function') {
226849
+ toastOptions.action = {
226850
+ label: action.label,
226851
+ onClick: action.onClick
226852
+ };
226853
+ }
226854
+ const id = dist_ue[type](title, toastOptions);
226583
226855
 
226584
- // Check if this is a path with line/column numbers
226585
- if (path.includes(':') && /.*:[0-9]+:[0-9]+/.test(path)) {
226586
- // Find the last segment after slash or backslash
226587
- const lastSlashIndex = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\'));
226588
- if (lastSlashIndex >= 0) {
226589
- const filename = path.substring(lastSlashIndex + 1);
226590
- return limitedLine.substring(0, atIndex + 4) + funcName + ' ' + filename;
226591
- }
226592
- }
226593
- }
226856
+ // Cache this notification for deduplication if it's an error
226857
+ if (type === 'error') {
226858
+ const timestamp = Date.now();
226859
+ recentNotificationsRef.current[cacheKey] = {
226860
+ timestamp,
226861
+ id
226862
+ };
226863
+ console.debug(`Stored notification in cache: "${title}" (id: ${id}, timestamp: ${timestamp})`);
226864
+
226865
+ // We no longer auto-delete the cache entry after duration
226866
+ // Instead, we keep it to track when the notification was last shown
226867
+ // The entry will be checked against the deduplication interval
226594
226868
  }
226595
- return limitedLine;
226596
- }).join('\n');
226597
- return {
226598
- errorTitle: errorMessage,
226599
- code: sanitizedStack,
226600
- firstFilename: firstFilename
226601
- };
226602
- };
226603
- const DefaultFallback = ({
226604
- error,
226605
- context,
226606
- resetErrorBoundary = () => {}
226607
- }) => {
226608
- const {
226609
- t
226610
- } = (0,dist_es/* useTranslation */.Bd)('ErrorBoundary');
226611
- const [showDetails, setShowDetails] = (0,react.useState)(false);
226612
- const title = `${t('Something went wrong')}${!isProduction && ` ${t('in')} ${context}`}.`;
226613
- const subtitle = t('Sorry, something went wrong there. Try again.');
226614
- const {
226615
- errorTitle,
226616
- code,
226617
- firstFilename
226618
- } = parseErrorStack(error);
226619
- const copyErrorToClipboard = () => {
226620
- if (code) {
226621
- navigator.clipboard.writeText(code);
226622
- dist_ue.success(t('Error copied to clipboard'));
226869
+ return id;
226870
+ }, []);
226871
+ const hide = (0,react.useCallback)(id => {
226872
+ dist_ue.dismiss(id);
226873
+
226874
+ // Remove from cache if present
226875
+ const cacheEntries = Object.entries(recentNotificationsRef.current);
226876
+ for (const [key, entry] of cacheEntries) {
226877
+ if (entry.id === id) {
226878
+ delete recentNotificationsRef.current[key];
226879
+ break;
226880
+ }
226623
226881
  }
226624
- };
226625
- (0,react.useEffect)(() => {
226626
- dist_ue.error(title, {
226627
- description: subtitle,
226628
- action: {
226629
- label: t('Show Details'),
226630
- onClick: () => setShowDetails(true)
226631
- },
226632
- duration: 0
226633
- });
226634
- }, [error, subtitle, t, title]);
226635
- if (isProduction) {
226636
- return null;
226637
- }
226638
- return /*#__PURE__*/react.createElement(Dialog_Dialog, {
226639
- open: showDetails,
226640
- onOpenChange: setShowDetails
226641
- }, /*#__PURE__*/react.createElement(Dialog_DialogContent, {
226642
- className: "bg-muted max-w-3xl overflow-hidden border-0 p-0",
226643
- onInteractOutside: e => e.preventDefault()
226644
- }, /*#__PURE__*/react.createElement("div", {
226645
- className: "p-5 pb-4"
226646
- }, /*#__PURE__*/react.createElement("div", {
226647
- className: "flex items-center justify-between"
226648
- }, /*#__PURE__*/react.createElement("h2", {
226649
- className: "text-highlight text-xl font-normal"
226650
- }, errorTitle || error.message || title))), code && /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement(ScrollArea_ScrollArea, {
226651
- className: "bg-background text-foreground mx-6 h-[321px] rounded-b-md"
226652
- }, /*#__PURE__*/react.createElement("div", {
226653
- className: "bg-background border-input flex items-center justify-between rounded-t-md border-b px-4 py-2"
226654
- }, /*#__PURE__*/react.createElement("div", {
226655
- className: "text-muted-foreground text-base"
226656
- }, firstFilename || 'Error Stack'), /*#__PURE__*/react.createElement(Button_Button/* Button */.$, {
226657
- className: "w-20",
226658
- onClick: copyErrorToClipboard,
226659
- title: t('Copy error')
226660
- }, "Copy")), /*#__PURE__*/react.createElement("div", {
226661
- className: "p-4 font-mono text-sm"
226662
- }, code.split('\n').map((line, index) => /*#__PURE__*/react.createElement("div", {
226663
- key: index,
226664
- className: "flex"
226665
- }, /*#__PURE__*/react.createElement("span", {
226666
- className: "whitespace-pre"
226667
- }, line)))))), /*#__PURE__*/react.createElement("div", {
226668
- className: "flex items-center justify-end p-6 pt-2"
226669
- }, /*#__PURE__*/react.createElement(Button_Button/* Button */.$, {
226670
- variant: "link",
226671
- className: "text-primary p-0",
226672
- onClick: () => window.open('https://github.com/OHIF/Viewers/issues/new?template=bug-report.yml', '_blank')
226673
- }, "Report Issue"))));
226674
- };
226675
- const ErrorBoundary = ({
226676
- context = 'OHIF',
226677
- onReset = () => {},
226678
- onError = () => {},
226679
- fallbackComponent: FallbackComponent = DefaultFallback,
226680
- children,
226681
- fallbackRoute = null,
226682
- isPage
226683
- }) => {
226684
- const [error, setError] = (0,react.useState)(null);
226685
- const onResetHandler = () => {
226686
- setError(null);
226687
- onReset();
226688
- };
226882
+ }, []);
226883
+ const hideAll = (0,react.useCallback)(() => {
226884
+ dist_ue.dismiss();
226885
+ // Clear notification cache
226886
+ recentNotificationsRef.current = {};
226887
+ }, []);
226689
226888
 
226690
- // Add error event listener to window
226889
+ /**
226890
+ * Sets the implementation of a notification service that can be used by extensions.
226891
+ *
226892
+ * @returns void
226893
+ */
226691
226894
  (0,react.useEffect)(() => {
226692
- let errorTimeout;
226693
- const handleError = event => {
226694
- event.preventDefault();
226695
- clearTimeout(errorTimeout);
226696
- errorTimeout = setTimeout(() => {
226697
- setError(event.error);
226698
- onErrorHandler(event.error, null);
226699
- }, 100);
226700
- };
226701
- const handleRejection = event => {
226702
- event.preventDefault();
226703
- clearTimeout(errorTimeout);
226704
- errorTimeout = setTimeout(() => {
226705
- setError(event.reason);
226706
- onErrorHandler(event.reason, null);
226707
- }, 100);
226708
- };
226709
- window.addEventListener('error', handleError);
226710
- window.addEventListener('unhandledrejection', handleRejection);
226711
- return () => {
226712
- clearTimeout(errorTimeout);
226713
- window.removeEventListener('error', handleError);
226714
- window.removeEventListener('unhandledrejection', handleRejection);
226895
+ if (service) {
226896
+ service.setServiceImplementation({
226897
+ hide,
226898
+ show
226899
+ });
226900
+ }
226901
+ }, [service, hide, show]);
226902
+
226903
+ // Debug function to get the current cache (for development use)
226904
+ const getNotificationCache = (0,react.useCallback)(() => {
226905
+ const cache = {
226906
+ ...recentNotificationsRef.current
226715
226907
  };
226908
+
226909
+ // Add human-readable timestamps and time since showing
226910
+ const now = Date.now();
226911
+ const enhancedCache = Object.entries(cache).reduce((result, [key, entry]) => {
226912
+ const timeSince = now - entry.timestamp;
226913
+ result[key] = {
226914
+ ...entry,
226915
+ date: new Date(entry.timestamp).toISOString(),
226916
+ timeSinceMs: timeSince,
226917
+ timeSinceStr: `${Math.floor(timeSince / 1000)}s ago`
226918
+ };
226919
+ return result;
226920
+ }, {});
226921
+ return enhancedCache;
226716
226922
  }, []);
226717
- const onErrorHandler = (error, componentStack) => {
226718
- console.debug(`${context} Error Boundary`, error, componentStack, context);
226719
- onError(error, componentStack || '', context);
226923
+ return /*#__PURE__*/react.createElement(NotificationContext.Provider, {
226924
+ value: {
226925
+ show,
226926
+ hide,
226927
+ hideAll,
226928
+ getNotificationCache
226929
+ }
226930
+ }, /*#__PURE__*/react.createElement(Toaster, {
226931
+ position: "bottom-right"
226932
+ }), children);
226933
+ };
226934
+ NotificationProvider.propTypes = {
226935
+ children: (prop_types_default()).node.isRequired,
226936
+ service: (prop_types_default()).object,
226937
+ deduplicationInterval: (prop_types_default()).number
226938
+ };
226939
+ const withNotification = Component => {
226940
+ return function WrappedComponent(props) {
226941
+ const notificationContext = useNotification();
226942
+ return /*#__PURE__*/React.createElement(Component, NotificationProvider_extends({}, props, {
226943
+ notificationContext: notificationContext
226944
+ }));
226720
226945
  };
226721
- return /*#__PURE__*/react.createElement(react_error_boundary_esm/* ErrorBoundary */.tH, {
226722
- fallbackRender: props => /*#__PURE__*/react.createElement(FallbackComponent, {
226723
- error: props.error,
226724
- context: context,
226725
- resetErrorBoundary: props.resetErrorBoundary
226726
- }),
226727
- onReset: onResetHandler,
226728
- onError: (error, info) => onErrorHandler(error, info.componentStack)
226729
- }, /*#__PURE__*/react.createElement(react.Fragment, null, children, error && /*#__PURE__*/react.createElement(FallbackComponent, {
226730
- error: error,
226731
- context: context,
226732
- resetErrorBoundary: () => setError(null)
226733
- })));
226734
226946
  };
226947
+ /* harmony default export */ const contextProviders_NotificationProvider = (NotificationProvider);
226948
+ // EXTERNAL MODULE: ../../../node_modules/lodash.merge/index.js
226949
+ var lodash_merge = __webpack_require__(2816);
226950
+ var lodash_merge_default = /*#__PURE__*/__webpack_require__.n(lodash_merge);
226951
+ // EXTERNAL MODULE: ../../core/src/index.ts + 69 modules
226952
+ var src = __webpack_require__(62037);
226953
+ ;// CONCATENATED MODULE: ../../ui-next/src/contextProviders/ViewportGridProvider.tsx
226735
226954
 
226736
- ;// CONCATENATED MODULE: ../../ui-next/src/components/Errorboundary/index.tsx
226737
-
226738
-
226739
- ;// CONCATENATED MODULE: ../../ui-next/src/components/NavBar/NavBar.tsx
226740
226955
 
226741
226956
 
226742
226957
 
226743
- const stickyClasses = 'sticky top-0';
226744
- const notStickyClasses = 'relative';
226745
- const NavBar = ({
226746
- className,
226747
- children,
226748
- isSticky
226749
- }) => {
226750
- return /*#__PURE__*/react.createElement("div", {
226751
- className: classnames_default()('bg-secondary-dark z-20 border-black px-1', isSticky && stickyClasses, !isSticky && notStickyClasses, className)
226752
- }, children);
226753
- };
226754
- NavBar.propTypes = {
226755
- className: (prop_types_default()).string,
226756
- children: (prop_types_default()).node,
226757
- isSticky: (prop_types_default()).bool
226958
+ const DEFAULT_STATE = {
226959
+ activeViewportId: null,
226960
+ layout: {
226961
+ numRows: 0,
226962
+ numCols: 0,
226963
+ layoutType: 'grid'
226964
+ },
226965
+ // this flag is used to determine if the hanging protocol layout is active
226966
+ // so that we can inherit the viewport options from the previous state
226967
+ // otherwise we will not allow that. Basically the issue is that we need
226968
+ // to be able to come out of the hanging protocol layout and go back to the
226969
+ // regular layout e.g., if we are in the MPR hanging protocol, and someone use
226970
+ // 1x1 layout by custom layout selector, there is no way to drag and drop
226971
+ // a non-reconstructible series to the viewport since it will always
226972
+ // inherit the hanging protocol layout options (volume viewport),
226973
+ // so we need to be able to switch back to the regular layout.
226974
+ isHangingProtocolLayout: false,
226975
+ // Viewports structure has been changed to Map (previously it was
226976
+ // tied to the viewportIndex which caused multiple issues. Now we have
226977
+ // moved completely to viewportId which is unique for each viewport.
226978
+ viewports: new Map(Object.entries({
226979
+ default: {
226980
+ viewportId: 'default',
226981
+ displaySetInstanceUIDs: [],
226982
+ isReady: false,
226983
+ viewportOptions: {
226984
+ viewportId: 'default'
226985
+ },
226986
+ displaySetSelectors: [],
226987
+ displaySetOptions: [{}],
226988
+ x: 0,
226989
+ // left
226990
+ y: 0,
226991
+ // top
226992
+ width: 100,
226993
+ height: 100,
226994
+ viewportLabel: null
226995
+ }
226996
+ }))
226758
226997
  };
226759
- /* harmony default export */ const NavBar_NavBar = (NavBar);
226760
- ;// CONCATENATED MODULE: ../../ui-next/src/components/NavBar/index.js
226998
+ const determineActiveViewportId = (state, newViewports) => {
226999
+ const {
227000
+ activeViewportId
227001
+ } = state;
227002
+ const currentActiveViewport = state.viewports.get(activeViewportId);
227003
+ if (!currentActiveViewport) {
227004
+ // if there is no active viewport, we should just return the first viewport
227005
+ const firstViewport = newViewports.values().next().value;
227006
+ return firstViewport.viewportOptions.viewportId;
227007
+ }
226761
227008
 
226762
- /* harmony default export */ const components_NavBar = (NavBar_NavBar);
226763
- ;// CONCATENATED MODULE: ../../ui-next/src/components/Header/Header.tsx
226764
- function Header_extends() { return Header_extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, Header_extends.apply(null, arguments); }
227009
+ // for the new viewports, we should rank them by the displaySetInstanceUIDs
227010
+ // they are displaying and the orientation then we can find the active viewport
227011
+ const currentActiveDisplaySetInstanceUIDs = currentActiveViewport.displaySetInstanceUIDs;
226765
227012
 
227013
+ // This doesn't take into account where stack viewport is converting to volumeViewport
227014
+ // since in stack viewport we don't have a concept of "orientation" as a string
227015
+ // maybe we should calculate the orientation based on the active imageId
227016
+ // so that we can compare it with the new viewports (which might be volume viewports)
227017
+ // and find the best match
227018
+ const currentOrientation = currentActiveViewport.viewportOptions.orientation;
227019
+ const filteredNewViewports = Array.from(newViewports.values()).filter(viewport => viewport.displaySetInstanceUIDs?.length > 0);
227020
+ const sortedViewports = Array.from(filteredNewViewports.values()).sort((a, b) => {
227021
+ // Compare orientations
227022
+ const aOrientationMatch = a.viewportOptions.orientation === currentOrientation;
227023
+ const bOrientationMatch = b.viewportOptions.orientation === currentOrientation;
227024
+ if (aOrientationMatch !== bOrientationMatch) {
227025
+ return bOrientationMatch - aOrientationMatch;
227026
+ }
226766
227027
 
227028
+ // Compare displaySetInstanceUIDs
227029
+ const aMatch = a.displaySetInstanceUIDs.some(uid => currentActiveDisplaySetInstanceUIDs.includes(uid));
227030
+ const bMatch = b.displaySetInstanceUIDs.some(uid => currentActiveDisplaySetInstanceUIDs.includes(uid));
227031
+ if (aMatch !== bMatch) {
227032
+ return bMatch - aMatch;
227033
+ }
227034
+ return 0; // Return 0 if no differences found
227035
+ });
227036
+ if (!sortedViewports?.length) {
227037
+ return null;
227038
+ }
227039
+ return sortedViewports[0].viewportId;
227040
+ };
226767
227041
 
227042
+ // Define the API interface
226768
227043
 
227044
+ // Update the context type
227045
+ const ViewportGridContext = /*#__PURE__*/(0,react.createContext)([DEFAULT_STATE, {}]);
226769
227046
 
226770
- // Todo: we should move this component to composition and remove props base
227047
+ // Update the provider props type
226771
227048
 
226772
- function Header_Header({
227049
+ function ViewportGridProvider({
226773
227050
  children,
226774
- menuOptions,
226775
- isReturnEnabled = true,
226776
- onClickReturnButton,
226777
- isSticky = false,
226778
- WhiteLabeling,
226779
- PatientInfo,
226780
- UndoRedo,
226781
- Secondary,
226782
- ...props
227051
+ service
226783
227052
  }) {
226784
- const onClickReturn = () => {
226785
- if (isReturnEnabled && onClickReturnButton) {
226786
- onClickReturnButton();
226787
- }
226788
- };
226789
- return /*#__PURE__*/react.createElement(components_NavBar, Header_extends({
226790
- isSticky: isSticky
226791
- }, props), /*#__PURE__*/react.createElement("div", {
226792
- className: "relative h-[48px] items-center"
226793
- }, /*#__PURE__*/react.createElement("div", {
226794
- className: "absolute left-0 top-1/2 flex -translate-y-1/2 items-center"
226795
- }, /*#__PURE__*/react.createElement("div", {
226796
- className: classnames_default()('mr-3 inline-flex items-center', isReturnEnabled && 'cursor-pointer'),
226797
- onClick: onClickReturn,
226798
- "data-cy": "return-to-work-list"
226799
- }, isReturnEnabled && /*#__PURE__*/react.createElement(Icons/* Icons */.F.ArrowLeft, {
226800
- className: "text-primary ml-1 h-7 w-7"
226801
- }), /*#__PURE__*/react.createElement("div", {
226802
- className: "ml-1"
226803
- }, WhiteLabeling?.createLogoComponentFn?.(react, props) || /*#__PURE__*/react.createElement(Icons/* Icons */.F.OHIFLogo, null)))), /*#__PURE__*/react.createElement("div", {
226804
- className: "absolute top-1/2 left-[250px] h-8 -translate-y-1/2"
226805
- }, Secondary), /*#__PURE__*/react.createElement("div", {
226806
- className: "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 transform"
226807
- }, /*#__PURE__*/react.createElement("div", {
226808
- className: "flex items-center justify-center space-x-2"
226809
- }, children)), /*#__PURE__*/react.createElement("div", {
226810
- className: "absolute right-0 top-1/2 flex -translate-y-1/2 select-none items-center"
226811
- }, UndoRedo, /*#__PURE__*/react.createElement("div", {
226812
- className: "border-primary-dark mx-1.5 h-[25px] border-r"
226813
- }), PatientInfo, /*#__PURE__*/react.createElement("div", {
226814
- className: "border-primary-dark mx-1.5 h-[25px] border-r"
226815
- }), /*#__PURE__*/react.createElement("div", {
226816
- className: "flex-shrink-0"
226817
- }, /*#__PURE__*/react.createElement(DropdownMenu_DropdownMenu, null, /*#__PURE__*/react.createElement(DropdownMenu_DropdownMenuTrigger, {
226818
- asChild: true
226819
- }, /*#__PURE__*/react.createElement(components_Button/* Button */.$, {
226820
- variant: "ghost",
226821
- size: "icon",
226822
- className: "text-primary hover:bg-primary-dark mt-2 h-full w-full"
226823
- }, /*#__PURE__*/react.createElement(Icons/* Icons */.F.GearSettings, null))), /*#__PURE__*/react.createElement(DropdownMenu_DropdownMenuContent, {
226824
- align: "end"
226825
- }, menuOptions.map((option, index) => {
226826
- const IconComponent = option.icon ? Icons/* Icons */.F[option.icon] : null;
226827
- return /*#__PURE__*/react.createElement(DropdownMenu_DropdownMenuItem, {
226828
- key: index,
226829
- onSelect: option.onClick,
226830
- className: "flex items-center gap-2 py-2"
226831
- }, IconComponent && /*#__PURE__*/react.createElement("span", {
226832
- className: "flex h-4 w-4 items-center justify-center"
226833
- }, /*#__PURE__*/react.createElement(Icons/* Icons */.F.ByName, {
226834
- name: IconComponent.name
226835
- })), /*#__PURE__*/react.createElement("span", {
226836
- className: "flex-1"
226837
- }, option.title));
226838
- })))))));
226839
- }
226840
- /* harmony default export */ const components_Header_Header = (Header_Header);
226841
- ;// CONCATENATED MODULE: ../../ui-next/src/components/Header/index.js
226842
-
226843
-
226844
- ;// CONCATENATED MODULE: ../../ui-next/src/components/Card/Card.tsx
226845
- function Card_extends() { return Card_extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, Card_extends.apply(null, arguments); }
226846
-
227053
+ const viewportGridReducer = (state, action) => {
227054
+ switch (action.type) {
227055
+ case 'SET_IS_REFERENCE_VIEWABLE':
227056
+ {
227057
+ const {
227058
+ viewportId,
227059
+ isReferenceViewable
227060
+ } = action.payload;
227061
+ const viewports = new Map(state.viewports);
227062
+ const viewport = viewports.get(viewportId);
227063
+ if (!viewport) {
227064
+ return;
227065
+ }
227066
+ viewports.set(viewportId, {
227067
+ ...viewport,
227068
+ isReferenceViewable
227069
+ });
227070
+ return {
227071
+ ...state,
227072
+ viewports
227073
+ };
227074
+ }
227075
+ case 'SET_ACTIVE_VIEWPORT_ID':
227076
+ {
227077
+ return {
227078
+ ...state,
227079
+ ...{
227080
+ activeViewportId: action.payload
227081
+ }
227082
+ };
227083
+ }
226847
227084
 
226848
- const Card = /*#__PURE__*/react.forwardRef(({
226849
- className,
226850
- ...props
226851
- }, ref) => /*#__PURE__*/react.createElement("div", Card_extends({
226852
- ref: ref,
226853
- className: (0,utils.cn)('bg-card text-card-foreground border-input rounded-lg border shadow', className)
226854
- }, props)));
226855
- Card.displayName = 'Card';
226856
- const CardHeader = /*#__PURE__*/react.forwardRef(({
226857
- className,
226858
- ...props
226859
- }, ref) => /*#__PURE__*/react.createElement("div", Card_extends({
226860
- ref: ref,
226861
- className: (0,utils.cn)('flex flex-col space-y-1.5 p-6', className)
226862
- }, props)));
226863
- CardHeader.displayName = 'CardHeader';
226864
- const CardTitle = /*#__PURE__*/react.forwardRef(({
226865
- className,
226866
- ...props
226867
- }, ref) => /*#__PURE__*/react.createElement("h3", Card_extends({
226868
- ref: ref,
226869
- className: (0,utils.cn)('font-semibold leading-none tracking-tight', className)
226870
- }, props)));
226871
- CardTitle.displayName = 'CardTitle';
226872
- const CardDescription = /*#__PURE__*/react.forwardRef(({
226873
- className,
226874
- ...props
226875
- }, ref) => /*#__PURE__*/react.createElement("p", Card_extends({
226876
- ref: ref,
226877
- className: (0,utils.cn)('text-muted-foreground text-base', className)
226878
- }, props)));
226879
- CardDescription.displayName = 'CardDescription';
226880
- const CardContent = /*#__PURE__*/react.forwardRef(({
226881
- className,
226882
- ...props
226883
- }, ref) => /*#__PURE__*/react.createElement("div", Card_extends({
226884
- ref: ref,
226885
- className: (0,utils.cn)('p-6 pt-0', className)
226886
- }, props)));
226887
- CardContent.displayName = 'CardContent';
226888
- const CardFooter = /*#__PURE__*/react.forwardRef(({
226889
- className,
226890
- ...props
226891
- }, ref) => /*#__PURE__*/react.createElement("div", Card_extends({
226892
- ref: ref,
226893
- className: (0,utils.cn)('flex items-center p-6 pt-0', className)
226894
- }, props)));
226895
- CardFooter.displayName = 'CardFooter';
227085
+ /**
227086
+ * Sets the display sets for multiple viewports.
227087
+ * This is a replacement for the older set display set for viewport (single)
227088
+ * because the old one had race conditions wherein the viewports could
227089
+ * render partially in various ways causing exceptions.
227090
+ */
227091
+ case 'SET_DISPLAYSETS_FOR_VIEWPORTS':
227092
+ {
227093
+ const {
227094
+ payload
227095
+ } = action;
227096
+ const viewports = new Map(state.viewports);
227097
+ payload.forEach(updatedViewport => {
227098
+ const {
227099
+ viewportId,
227100
+ displaySetInstanceUIDs
227101
+ } = updatedViewport;
227102
+ if (!viewportId) {
227103
+ throw new Error('ViewportId is required to set display sets for viewport');
227104
+ }
227105
+ const previousViewport = viewports.get(viewportId);
226896
227106
 
226897
- ;// CONCATENATED MODULE: ../../ui-next/src/components/Card/index.ts
227107
+ // remove options that were meant for one time usage
227108
+ if (previousViewport?.viewportOptions?.initialImageOptions) {
227109
+ const {
227110
+ useOnce
227111
+ } = previousViewport.viewportOptions.initialImageOptions;
227112
+ if (useOnce) {
227113
+ previousViewport.viewportOptions.initialImageOptions = null;
227114
+ }
227115
+ }
226898
227116
 
227117
+ // Use the newly provide viewportOptions and display set options
227118
+ // when provided, and otherwise fall back to the previous ones.
227119
+ // That allows for easy updates of just the display set.
227120
+ let viewportOptions = lodash_merge_default()({}, previousViewport?.viewportOptions, updatedViewport?.viewportOptions);
227121
+ const displaySetOptions = updatedViewport?.displaySetOptions || [];
227122
+ if (!displaySetOptions.length) {
227123
+ // Copy all the display set options, assuming a full set of displaySet UID's is provided.
227124
+ if (state.isHangingProtocolLayout) {
227125
+ displaySetOptions.push(...(previousViewport.displaySetOptions || []));
227126
+ }
227127
+ if (!displaySetOptions.length) {
227128
+ displaySetOptions.push({});
227129
+ }
227130
+ }
226899
227131
 
226900
- ;// CONCATENATED MODULE: ../../ui-next/src/components/Viewport/ViewportActionButton.tsx
227132
+ // if it is not part of the hanging protocol layout, we should remove the toolGroupId
227133
+ // and viewportType from the viewportOptions so that it doesn't
227134
+ // inherit the hanging protocol layout options, only when
227135
+ // the viewport options is not provided (e.g., when drag and drop)
227136
+ // otherwise, programmatically set options should be preserved
227137
+ if (!updatedViewport.viewportOptions && !state.isHangingProtocolLayout) {
227138
+ viewportOptions = {
227139
+ viewportId: viewportOptions.viewportId
227140
+ };
227141
+ }
227142
+ const newViewport = {
227143
+ ...previousViewport,
227144
+ displaySetInstanceUIDs,
227145
+ viewportOptions,
227146
+ displaySetOptions
227147
+ // viewportLabel: getViewportLabel(viewports, viewportId),
227148
+ };
227149
+ viewportOptions.presentationIds = service.getPresentationIds({
227150
+ viewport: newViewport,
227151
+ viewports
227152
+ });
227153
+ viewports.set(viewportId, {
227154
+ ...viewports.get(viewportId),
227155
+ ...newViewport
227156
+ });
227157
+ });
227158
+ return {
227159
+ ...state,
227160
+ viewports
227161
+ };
227162
+ }
227163
+ case 'SET_LAYOUT':
227164
+ {
227165
+ const {
227166
+ numCols,
227167
+ numRows,
227168
+ layoutOptions,
227169
+ layoutType = 'grid',
227170
+ activeViewportId,
227171
+ findOrCreateViewport,
227172
+ isHangingProtocolLayout
227173
+ } = action.payload;
226901
227174
 
227175
+ // If empty viewportOptions, we use numRow and numCols to calculate number of viewports
227176
+ const hasOptions = layoutOptions?.length;
227177
+ const viewports = new Map();
227178
+ // Options is a temporary state store which can be used by the
227179
+ // findOrCreate to store state about already found viewports. Typically,
227180
+ // it will be used to store the display set UID's which are already
227181
+ // in view so that the find or create can decide which display sets
227182
+ // haven't been viewed yet, and add them in the appropriate order.
227183
+ const options = {};
227184
+ let activeViewportIdToSet = activeViewportId;
227185
+ for (let row = 0; row < numRows; row++) {
227186
+ for (let col = 0; col < numCols; col++) {
227187
+ const position = col + row * numCols;
227188
+ const layoutOption = layoutOptions[position];
227189
+ let xPos, yPos, w, h;
227190
+ if (layoutOptions && layoutOptions[position]) {
227191
+ ({
227192
+ x: xPos,
227193
+ y: yPos,
227194
+ width: w,
227195
+ height: h
227196
+ } = layoutOptions[position]);
227197
+ } else {
227198
+ w = 1 / numCols;
227199
+ h = 1 / numRows;
227200
+ xPos = col * w;
227201
+ yPos = row * h;
227202
+ }
227203
+ const colIndex = Math.round(xPos * numCols);
227204
+ const rowIndex = Math.round(yPos * numRows);
227205
+ const positionId = layoutOption?.positionId || `${colIndex}-${rowIndex}`;
227206
+ if (hasOptions && position >= layoutOptions.length) {
227207
+ continue;
227208
+ }
227209
+ const viewport = findOrCreateViewport(position, positionId, options);
227210
+ if (!viewport) {
227211
+ continue;
227212
+ }
227213
+ viewport.positionId = positionId;
226902
227214
 
227215
+ // If the viewport doesn't have a viewportId, we create one
227216
+ if (!viewport.viewportOptions?.viewportId) {
227217
+ const randomUID = src/* utils */.Wp.uuidv4().substring(0, 8);
227218
+ viewport.viewportOptions = viewport.viewportOptions || {};
227219
+ viewport.viewportOptions.viewportId = `viewport-${randomUID}`;
227220
+ }
227221
+ viewport.viewportId = viewport.viewportOptions.viewportId;
226903
227222
 
226904
- /**
226905
- * A button that can trigger commands when clicked.
226906
- */
226907
- function ViewportActionButton({
226908
- onInteraction,
226909
- commands,
226910
- id,
226911
- children
226912
- }) {
226913
- return /*#__PURE__*/react.createElement("div", {
226914
- className: "bg-primary-main hover:bg-primary-light ml-1 cursor-pointer rounded px-1.5 hover:text-black"
226915
- // Using onMouseUp because onClick wasn't firing if pointer-events are none.
226916
- ,
226917
- onMouseUp: () => {
226918
- onInteraction({
226919
- itemId: id,
226920
- commands
226921
- });
227223
+ // Create a new viewport object as it is getting updated here
227224
+ // and it is part of the read only state
227225
+ viewports.set(viewport.viewportId, viewport);
227226
+ Object.assign(viewport, {
227227
+ width: w,
227228
+ height: h,
227229
+ x: xPos,
227230
+ y: yPos
227231
+ });
227232
+ viewport.isReady = false;
227233
+ if (!viewport.viewportOptions.presentationIds) {
227234
+ const presentationIds = service.getPresentationIds({
227235
+ viewport,
227236
+ viewports
227237
+ });
227238
+ viewport.viewportOptions.presentationIds = presentationIds;
227239
+ }
227240
+ }
227241
+ }
227242
+ activeViewportIdToSet = activeViewportIdToSet ?? determineActiveViewportId(state, viewports);
227243
+ const ret = {
227244
+ ...state,
227245
+ activeViewportId: activeViewportIdToSet,
227246
+ layout: {
227247
+ ...state.layout,
227248
+ numCols,
227249
+ numRows,
227250
+ layoutType
227251
+ },
227252
+ viewports,
227253
+ isHangingProtocolLayout
227254
+ };
227255
+ return ret;
227256
+ }
227257
+ case 'RESET':
227258
+ {
227259
+ return DEFAULT_STATE;
227260
+ }
227261
+ case 'SET':
227262
+ {
227263
+ return {
227264
+ ...state,
227265
+ ...action.payload
227266
+ };
227267
+ }
227268
+ case 'VIEWPORT_IS_READY':
227269
+ {
227270
+ const {
227271
+ viewportId,
227272
+ isReady
227273
+ } = action.payload;
227274
+ const viewports = new Map(state.viewports);
227275
+ const viewport = viewports.get(viewportId);
227276
+ if (!viewport) {
227277
+ return;
227278
+ }
227279
+ viewports.set(viewportId, {
227280
+ ...viewport,
227281
+ isReady
227282
+ });
227283
+ return {
227284
+ ...state,
227285
+ viewports
227286
+ };
227287
+ }
227288
+ default:
227289
+ return action.payload;
226922
227290
  }
226923
- }, children);
226924
- }
226925
- ViewportActionButton.propTypes = {
226926
- id: (prop_types_default()).string,
226927
- onInteraction: (prop_types_default()).func.isRequired,
226928
- commands: (prop_types_default()).array,
226929
- children: (prop_types_default()).node
226930
- };
226931
-
226932
- ;// CONCATENATED MODULE: ../../ui-next/src/components/Viewport/PatientInfo.tsx
226933
-
226934
-
226935
-
226936
-
226937
-
226938
- const classes = {
226939
- infoHeader: 'text-base text-primary-light',
226940
- infoText: 'text-base text-white max-w-24 truncate',
226941
- firstRow: 'flex flex-col',
226942
- row: 'flex flex-col ml-4'
226943
- };
226944
-
226945
- /**
226946
- * A small info icon that, when clicked, can reveal additional patient details in a tooltip overlay.
226947
- */
226948
- function PatientInfo({
226949
- patientName,
226950
- patientSex,
226951
- patientAge,
226952
- MRN,
226953
- thickness,
226954
- thicknessUnits,
226955
- spacing,
226956
- scanner,
226957
- isOpen,
226958
- showPatientInfoRef
226959
- }) {
226960
- const {
226961
- t
226962
- } = (0,dist_es/* useTranslation */.Bd)('PatientInfo');
227291
+ };
227292
+ const [viewportGridState, dispatch] = (0,react.useReducer)(viewportGridReducer, DEFAULT_STATE);
227293
+ const getState = (0,react.useCallback)(() => {
227294
+ return viewportGridState;
227295
+ }, [viewportGridState]);
227296
+ const getActiveViewportOptionByKey = key => {
227297
+ const {
227298
+ viewports,
227299
+ activeViewportId
227300
+ } = viewportGridState;
227301
+ return viewports.get(activeViewportId)?.viewportOptions?.[key];
227302
+ };
227303
+ const setActiveViewportId = (0,react.useCallback)(index => dispatch({
227304
+ type: 'SET_ACTIVE_VIEWPORT_ID',
227305
+ payload: index
227306
+ }), [dispatch]);
227307
+ const setIsReferenceViewable = (0,react.useCallback)((viewportId, isReferenceViewable) => {
227308
+ dispatch({
227309
+ type: 'SET_IS_REFERENCE_VIEWABLE',
227310
+ payload: {
227311
+ viewportId,
227312
+ isReferenceViewable
227313
+ }
227314
+ });
227315
+ }, [dispatch]);
227316
+ const setDisplaySetsForViewports = (0,react.useCallback)(viewports => dispatch({
227317
+ type: 'SET_DISPLAYSETS_FOR_VIEWPORTS',
227318
+ payload: viewports
227319
+ }), [dispatch]);
227320
+ const setViewportIsReady = (0,react.useCallback)((viewportId, isReady) => {
227321
+ dispatch({
227322
+ type: 'VIEWPORT_IS_READY',
227323
+ payload: {
227324
+ viewportId,
227325
+ isReady
227326
+ }
227327
+ });
227328
+ }, [dispatch, viewportGridState]);
227329
+ const getGridViewportsReady = (0,react.useCallback)(() => {
227330
+ const {
227331
+ viewports
227332
+ } = viewportGridState;
227333
+ const readyViewports = Array.from(viewports.values()).filter(viewport => viewport.isReady);
227334
+ return readyViewports.length === viewports.size;
227335
+ }, [viewportGridState]);
227336
+ const setLayout = (0,react.useCallback)(({
227337
+ layoutType,
227338
+ numRows,
227339
+ numCols,
227340
+ layoutOptions = [],
227341
+ activeViewportId,
227342
+ findOrCreateViewport,
227343
+ isHangingProtocolLayout
227344
+ }) => dispatch({
227345
+ type: 'SET_LAYOUT',
227346
+ payload: {
227347
+ layoutType,
227348
+ numRows,
227349
+ numCols,
227350
+ layoutOptions,
227351
+ activeViewportId,
227352
+ findOrCreateViewport,
227353
+ isHangingProtocolLayout
227354
+ }
227355
+ }), [dispatch]);
227356
+ const reset = (0,react.useCallback)(() => dispatch({
227357
+ type: 'RESET',
227358
+ payload: {}
227359
+ }), [dispatch]);
227360
+ const set = (0,react.useCallback)(payload => dispatch({
227361
+ type: 'SET',
227362
+ payload
227363
+ }), [dispatch]);
227364
+ const getViewportState = (0,react.useCallback)(viewportId => {
227365
+ const {
227366
+ viewports
227367
+ } = viewportGridState;
227368
+ return viewports.get(viewportId);
227369
+ }, [viewportGridState]);
227370
+ const getNumViewportPanes = (0,react.useCallback)(() => {
227371
+ const {
227372
+ layout,
227373
+ viewports
227374
+ } = viewportGridState;
227375
+ const {
227376
+ numRows,
227377
+ numCols
227378
+ } = layout;
227379
+ return Math.min(viewports.size, numCols * numRows);
227380
+ }, [viewportGridState]);
227381
+
227382
+ /**
227383
+ * Sets the implementation of ViewportGridService that can be used by extensions.
227384
+ *
227385
+ * @returns void
227386
+ */
227387
+ (0,react.useEffect)(() => {
227388
+ if (service) {
227389
+ service.setServiceImplementation({
227390
+ getState,
227391
+ setActiveViewportId,
227392
+ setDisplaySetsForViewports,
227393
+ setIsReferenceViewable,
227394
+ setLayout,
227395
+ reset,
227396
+ onModeExit: reset,
227397
+ set,
227398
+ getNumViewportPanes,
227399
+ setViewportIsReady,
227400
+ getViewportState,
227401
+ getGridViewportsReady
227402
+ });
227403
+ }
227404
+ }, [getState, service, setActiveViewportId, setDisplaySetsForViewports, setIsReferenceViewable, setLayout, reset, set, getNumViewportPanes, setViewportIsReady, getGridViewportsReady, getViewportState]);
227405
+
227406
+ // run many of the calls through the service itself since we want to publish events
227407
+ const api = {
227408
+ getState,
227409
+ setActiveViewportId: index => service.setActiveViewportId(index),
227410
+ setDisplaySetsForViewport: props => service.setDisplaySetsForViewports([props]),
227411
+ setDisplaySetsForViewports: props => service.setDisplaySetsForViewports(props),
227412
+ setIsReferenceViewable: (viewportId, isReferenceViewable) => service.setIsReferenceViewable(viewportId, isReferenceViewable),
227413
+ setLayout: layout => service.setLayout(layout),
227414
+ getViewportState: viewportId => service.getViewportState(viewportId),
227415
+ reset: () => service.reset(),
227416
+ set: gridLayoutState => service.setState(gridLayoutState),
227417
+ // run it through the service itself since we want to publish events
227418
+ getNumViewportPanes,
227419
+ setViewportIsReady,
227420
+ getGridViewportsReady,
227421
+ getActiveViewportOptionByKey,
227422
+ setViewportGridSizeChanged: props => service.setViewportGridSizeChanged(props),
227423
+ publishViewportsReady: () => service.publishViewportsReady(),
227424
+ getLayoutOptionsFromState: state => service.getLayoutOptionsFromState(state)
227425
+ };
227426
+ return /*#__PURE__*/react.createElement(ViewportGridContext.Provider, {
227427
+ value: [viewportGridState, api]
227428
+ }, children);
227429
+ }
227430
+ ViewportGridProvider.propTypes = {
227431
+ children: (prop_types_default()).any,
227432
+ service: prop_types_default().instanceOf(src/* ViewportGridService */.sI).isRequired
227433
+ };
227434
+
227435
+ // Update the useViewportGrid hook
227436
+ const useViewportGrid = () => (0,react.useContext)(ViewportGridContext);
227437
+ ;// CONCATENATED MODULE: ../../ui-next/src/contextProviders/ModalProvider.tsx
227438
+ function ModalProvider_extends() { return ModalProvider_extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, ModalProvider_extends.apply(null, arguments); }
227439
+
227440
+
227441
+ const ModalContext = /*#__PURE__*/(0,react.createContext)(null);
227442
+ const useModal = () => {
227443
+ const ctx = (0,react.useContext)(ModalContext);
227444
+ if (!ctx) {
227445
+ throw new Error('useModal must be used within a ModalProvider');
227446
+ }
227447
+ return ctx;
227448
+ };
227449
+ const DEFAULT_OPTIONS = {
227450
+ title: '',
227451
+ shouldCloseOnEsc: true
227452
+ };
227453
+ const ModalProvider = ({
227454
+ children,
227455
+ modal: ModalComponent,
227456
+ service = null
227457
+ }) => {
227458
+ const {
227459
+ t
227460
+ } = (0,dist_es/* useTranslation */.Bd)('Modals');
227461
+ const [options, setOptions] = (0,react.useState)(DEFAULT_OPTIONS);
227462
+ const ModalContent = options.content;
227463
+ const show = (0,react.useCallback)(props => {
227464
+ setOptions(prev => ({
227465
+ ...prev,
227466
+ ...props
227467
+ }));
227468
+ }, []);
227469
+ const hide = (0,react.useCallback)(() => {
227470
+ setOptions(DEFAULT_OPTIONS);
227471
+ }, []);
227472
+ (0,react.useEffect)(() => {
227473
+ if (service) {
227474
+ service.setServiceImplementation({
227475
+ show,
227476
+ hide
227477
+ });
227478
+ }
227479
+ }, [hide, service, show]);
227480
+ const {
227481
+ title
227482
+ } = options;
227483
+ const CustomModal = service?.getCustomComponent();
227484
+ const RenderedModal = CustomModal || ModalComponent;
227485
+ return /*#__PURE__*/react.createElement(ModalContext.Provider, {
227486
+ value: {
227487
+ show,
227488
+ hide
227489
+ }
227490
+ }, ModalContent && /*#__PURE__*/react.createElement(RenderedModal, ModalProvider_extends({
227491
+ isOpen: true,
227492
+ onClose: hide,
227493
+ title: t(title)
227494
+ }, options), /*#__PURE__*/react.createElement(ModalContent, ModalProvider_extends({}, options.contentProps, {
227495
+ show: show,
227496
+ hide: hide
227497
+ }))), children);
227498
+ };
227499
+
227500
+ const ModalConsumer = ModalContext.Consumer;
227501
+ ;// CONCATENATED MODULE: ../../ui-next/src/contextProviders/ManagedDialog.tsx
227502
+ function ManagedDialog_extends() { return ManagedDialog_extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, ManagedDialog_extends.apply(null, arguments); }
227503
+
227504
+
227505
+
227506
+ const ManagedDialog = /*#__PURE__*/(0,react.forwardRef)(({
227507
+ id,
227508
+ isOpen,
227509
+ title,
227510
+ content: DialogContentComponent,
227511
+ contentProps,
227512
+ isDraggable,
227513
+ shouldCloseOnEsc = false,
227514
+ shouldCloseOnOverlayClick = false,
227515
+ showOverlay = true,
227516
+ defaultPosition,
227517
+ onClose,
227518
+ unstyled,
227519
+ containerClassName
227520
+ }, ref) => {
227521
+ const [currentPosition, setCurrentPosition] = (0,react.useState)(defaultPosition);
227522
+ (0,react.useImperativeHandle)(ref, () => ({
227523
+ updatePosition: position => {
227524
+ setCurrentPosition(position);
227525
+ }
227526
+ }), []);
227527
+ (0,react.useEffect)(() => {
227528
+ setCurrentPosition(defaultPosition);
227529
+ }, [defaultPosition]);
227530
+ return /*#__PURE__*/react.createElement(Dialog_Dialog, {
227531
+ open: isOpen,
227532
+ modal: false // keep modal behavior off for independent windows
227533
+ ,
227534
+ onOpenChange: open => {
227535
+ if (!open) {
227536
+ onClose(id);
227537
+ }
227538
+ },
227539
+ isDraggable: isDraggable,
227540
+ shouldCloseOnEsc: shouldCloseOnEsc,
227541
+ shouldCloseOnOverlayClick: shouldCloseOnOverlayClick,
227542
+ showOverlay: showOverlay
227543
+ }, /*#__PURE__*/react.createElement(Dialog_DialogContent, {
227544
+ className: (0,utils.cn)(unstyled ? 'p-0' : '', containerClassName),
227545
+ unstyled: unstyled,
227546
+ style: {
227547
+ ...(currentPosition ? {
227548
+ position: 'fixed',
227549
+ left: `${currentPosition.x}px`,
227550
+ top: `${currentPosition.y}px`,
227551
+ transform: 'translate(0, 0)',
227552
+ margin: 0,
227553
+ animation: 'none'
227554
+ } : {})
227555
+ }
227556
+ }, !unstyled && /*#__PURE__*/react.createElement(DialogHeader, null, title && /*#__PURE__*/react.createElement(Dialog_DialogTitle, null, title)), /*#__PURE__*/react.createElement(DialogContentComponent, ManagedDialog_extends({}, contentProps, {
227557
+ hide: () => onClose(id)
227558
+ }))));
227559
+ });
227560
+ ManagedDialog.displayName = 'ManagedDialog';
227561
+ /* harmony default export */ const contextProviders_ManagedDialog = (ManagedDialog);
227562
+ ;// CONCATENATED MODULE: ../../ui-next/src/contextProviders/DialogProvider.tsx
227563
+ function DialogProvider_extends() { return DialogProvider_extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, DialogProvider_extends.apply(null, arguments); }
227564
+
227565
+
227566
+ const DialogProvider_DialogContext = /*#__PURE__*/(0,react.createContext)(null);
227567
+ const useDialog = () => {
227568
+ const context = useContext(DialogProvider_DialogContext);
227569
+ if (!context) {
227570
+ throw new Error('useDialog must be used within a DialogProvider');
227571
+ }
227572
+ return context;
227573
+ };
227574
+ const DialogProvider_DialogProvider = ({
227575
+ children,
227576
+ dialog: DialogComponent = contextProviders_ManagedDialog,
227577
+ service = null
227578
+ }) => {
227579
+ const [dialogs, setDialogs] = (0,react.useState)([]);
227580
+ const dialogRefs = (0,react.useRef)(new Map());
227581
+ const show = (0,react.useCallback)(options => {
227582
+ const id = options.id;
227583
+ setDialogs(prev => [...prev, {
227584
+ ...options,
227585
+ id
227586
+ }]);
227587
+ return id;
227588
+ }, []);
227589
+ const hide = (0,react.useCallback)(id => {
227590
+ setDialogs(prev => prev.filter(dialog => dialog.id !== id));
227591
+ dialogRefs.current.delete(id);
227592
+ }, []);
227593
+ const hideAll = (0,react.useCallback)(() => {
227594
+ setDialogs([]);
227595
+ dialogRefs.current.clear();
227596
+ }, []);
227597
+ const isEmpty = (0,react.useCallback)(() => dialogs.length === 0, [dialogs]);
227598
+ const updatePosition = (0,react.useCallback)((id, position) => {
227599
+ const dialogRef = dialogRefs.current.get(id);
227600
+ if (dialogRef) {
227601
+ dialogRef.updatePosition(position);
227602
+ }
227603
+ }, []);
227604
+ const contextValue = (0,react.useMemo)(() => ({
227605
+ show,
227606
+ hide,
227607
+ hideAll,
227608
+ isEmpty,
227609
+ updatePosition
227610
+ }), [show, hide, hideAll, isEmpty, updatePosition]);
227611
+ (0,react.useEffect)(() => {
227612
+ if (service) {
227613
+ service.setServiceImplementation(contextValue);
227614
+ }
227615
+ }, [service, contextValue]);
227616
+ const CustomDialog = service?.getCustomComponent?.();
227617
+ const RenderedDialog = CustomDialog || DialogComponent;
227618
+ return /*#__PURE__*/react.createElement(DialogProvider_DialogContext.Provider, {
227619
+ value: contextValue
227620
+ }, dialogs.map(dialog => /*#__PURE__*/react.createElement(RenderedDialog, DialogProvider_extends({
227621
+ key: dialog.id,
227622
+ ref: ref => {
227623
+ if (ref) {
227624
+ dialogRefs.current.set(dialog.id, ref);
227625
+ }
227626
+ },
227627
+ onClose: hide,
227628
+ isOpen: true
227629
+ }, dialog))), children);
227630
+ };
227631
+
227632
+ ;// CONCATENATED MODULE: ../../ui-next/src/contextProviders/ViewportDialogProvider.tsx
227633
+
227634
+
227635
+ const ViewportDialogProvider_DEFAULT_STATE = {
227636
+ message: undefined,
227637
+ type: 'info',
227638
+ // "error" | "warning" | "info" | "success"
227639
+ actions: undefined,
227640
+ // array of { type, text, value }
227641
+ onSubmit: () => {
227642
+ console.log('btn value?');
227643
+ },
227644
+ onOutsideClick: () => {
227645
+ console.warn('default: onOutsideClick');
227646
+ },
227647
+ onDismiss: () => {
227648
+ console.log('dismiss? -1');
227649
+ },
227650
+ onKeyPress: () => {
227651
+ console.log('key pressed?');
227652
+ }
227653
+ };
227654
+ const ViewportDialogContext = /*#__PURE__*/(0,react.createContext)(null);
227655
+ const {
227656
+ Provider: ViewportDialogProvider_Provider
227657
+ } = ViewportDialogContext;
227658
+ const useViewportDialog = () => (0,react.useContext)(ViewportDialogContext);
227659
+ const ViewportDialogProvider = ({
227660
+ children,
227661
+ service
227662
+ }) => {
227663
+ const [viewportDialogState, setViewportDialogState] = (0,react.useState)(ViewportDialogProvider_DEFAULT_STATE);
227664
+ const show = (0,react.useCallback)(params => setViewportDialogState({
227665
+ ...viewportDialogState,
227666
+ ...params
227667
+ }), [viewportDialogState]);
227668
+ const hide = (0,react.useCallback)(() => setViewportDialogState(ViewportDialogProvider_DEFAULT_STATE), []);
227669
+ (0,react.useEffect)(() => {
227670
+ if (service) {
227671
+ service.setServiceImplementation({
227672
+ hide,
227673
+ show
227674
+ });
227675
+ }
227676
+ }, [hide, service, show]);
227677
+ return /*#__PURE__*/react.createElement(ViewportDialogProvider_Provider, {
227678
+ value: [viewportDialogState, {
227679
+ show,
227680
+ hide
227681
+ }]
227682
+ }, children);
227683
+ };
227684
+ ViewportDialogProvider.propTypes = {
227685
+ /** Children that will be wrapped with Modal Context */
227686
+ children: prop_types_default().oneOfType([prop_types_default().arrayOf((prop_types_default()).node), (prop_types_default()).node]).isRequired,
227687
+ service: prop_types_default().shape({
227688
+ setServiceImplementation: (prop_types_default()).func
227689
+ })
227690
+ };
227691
+ /* harmony default export */ const contextProviders_ViewportDialogProvider = (ViewportDialogProvider);
227692
+ ;// CONCATENATED MODULE: ../../ui-next/src/contextProviders/UserAuthenticationProvider.tsx
227693
+
227694
+
227695
+ const UserAuthenticationProvider_DEFAULT_STATE = {
227696
+ user: null,
227697
+ enabled: false
227698
+ };
227699
+ const UserAuthenticationContext = /*#__PURE__*/(0,react.createContext)(UserAuthenticationProvider_DEFAULT_STATE);
227700
+ function UserAuthenticationProvider({
227701
+ children,
227702
+ service
227703
+ }) {
227704
+ const userAuthenticationReducer = (state, action) => {
227705
+ switch (action.type) {
227706
+ case 'SET_USER':
227707
+ {
227708
+ return {
227709
+ ...state,
227710
+ ...{
227711
+ user: action.payload.user
227712
+ }
227713
+ };
227714
+ }
227715
+ case 'RESET':
227716
+ {
227717
+ return {
227718
+ user: null
227719
+ };
227720
+ }
227721
+ case 'SET':
227722
+ {
227723
+ return {
227724
+ ...state,
227725
+ ...action.payload
227726
+ };
227727
+ }
227728
+ default:
227729
+ return action.payload;
227730
+ }
227731
+ };
227732
+ const [userAuthenticationState, dispatch] = (0,react.useReducer)(userAuthenticationReducer, UserAuthenticationProvider_DEFAULT_STATE);
227733
+ const getState = (0,react.useCallback)(() => userAuthenticationState, [userAuthenticationState]);
227734
+ const setUser = (0,react.useCallback)(user => dispatch({
227735
+ type: 'SET_USER',
227736
+ payload: {
227737
+ user
227738
+ }
227739
+ }), [dispatch]);
227740
+ const getUser = (0,react.useCallback)(() => userAuthenticationState.user, [userAuthenticationState]);
227741
+ const reset = (0,react.useCallback)(() => dispatch({
227742
+ type: 'RESET',
227743
+ payload: {}
227744
+ }), [dispatch]);
227745
+ const set = (0,react.useCallback)(payload => dispatch({
227746
+ type: 'SET',
227747
+ payload
227748
+ }), [dispatch]);
227749
+
227750
+ /**
227751
+ * Sets the implementation of the UserAuthenticationService that can be used by extensions.
227752
+ *
227753
+ * @returns void
227754
+ */
227755
+ // TODO: should this be a useEffect or not?
227756
+ (0,react.useEffect)(() => {
227757
+ if (service) {
227758
+ service.setServiceImplementation({
227759
+ getState,
227760
+ setUser,
227761
+ getUser,
227762
+ reset,
227763
+ set
227764
+ });
227765
+ }
227766
+ }, [getState, service, setUser, getUser, reset, set]);
227767
+
227768
+ // TODO: This may not be correct, but I think we need to set the implementation for the service
227769
+ // immediately when this runs, since otherwise the authentication redirects will fail.
227770
+ // (useEffect only runs after the child components - in this case, routing logic - has failed)
227771
+ if (service) {
227772
+ service.setServiceImplementation({
227773
+ getState,
227774
+ setUser,
227775
+ getUser,
227776
+ reset,
227777
+ set
227778
+ });
227779
+ }
227780
+ const api = {
227781
+ getState,
227782
+ setUser,
227783
+ getUser,
227784
+ getAuthorizationHeader: service.getAuthorizationHeader,
227785
+ handleUnauthenticated: service.handleUnauthenticated,
227786
+ reset,
227787
+ set
227788
+ };
227789
+ return /*#__PURE__*/react.createElement(UserAuthenticationContext.Provider, {
227790
+ value: [userAuthenticationState, api]
227791
+ }, children);
227792
+ }
227793
+ /* harmony default export */ const contextProviders_UserAuthenticationProvider = ((/* unused pure expression or super */ null && (UserAuthenticationProvider)));
227794
+ const UserAuthenticationConsumer = UserAuthenticationContext.Consumer;
227795
+
227796
+ UserAuthenticationProvider.propTypes = {
227797
+ children: (prop_types_default()).any,
227798
+ service: prop_types_default().shape({
227799
+ setServiceImplementation: (prop_types_default()).func
227800
+ }).isRequired
227801
+ };
227802
+ const useUserAuthentication = () => (0,react.useContext)(UserAuthenticationContext);
227803
+ ;// CONCATENATED MODULE: ../../ui-next/src/contextProviders/ImageViewerProvider.tsx
227804
+
227805
+ const ImageViewerContext = /*#__PURE__*/(0,react.createContext)(null);
227806
+ const useImageViewer = () => (0,react.useContext)(ImageViewerContext);
227807
+ function ImageViewerProvider({
227808
+ StudyInstanceUIDs,
227809
+ children
227810
+ }) {
227811
+ const value = (0,react.useMemo)(() => {
227812
+ return {
227813
+ StudyInstanceUIDs
227814
+ };
227815
+ }, [StudyInstanceUIDs]);
227816
+ return /*#__PURE__*/react.createElement(ImageViewerContext.Provider, {
227817
+ value: value
227818
+ }, children);
227819
+ }
227820
+ // EXTERNAL MODULE: ../../../node_modules/react-dnd-html5-backend/dist/esm/index.js + 13 modules
227821
+ var dist_esm = __webpack_require__(87654);
227822
+ ;// CONCATENATED MODULE: ../../ui-next/src/contextProviders/DragAndDropProvider.tsx
227823
+
227824
+
227825
+
227826
+
227827
+
227828
+ // import TouchBackend from 'react-dnd-touch-backend';
227829
+
227830
+ // TODO: this is false when it should not be :thinking:
227831
+ const isTouchDevice = typeof window !== `undefined` && !!('ontouchstart' in window || navigator.maxTouchPoints);
227832
+
227833
+ /**
227834
+ * Relevant:
227835
+ * https://github.com/react-dnd/react-dnd/issues/186#issuecomment-335429067
227836
+ * https://github.com/react-dnd/react-dnd/issues/186#issuecomment-282789420
227837
+ *
227838
+ * Docs:
227839
+ * http://react-dnd.github.io/react-dnd/docs/api/drag-drop-context
227840
+ */
227841
+ function DragAndDropProvider({
227842
+ children
227843
+ }) {
227844
+ const backend = dist_esm/* HTML5Backend */.t2; // isTouchDevice ? TouchBackend : HTML5Backend;
227845
+ const opts = {}; // isTouchDevice ? { enableMouseEvents: true } : {};
227846
+
227847
+ console.log('using... touch backend?', isTouchDevice);
227848
+ return /*#__PURE__*/react.createElement(esm/* DndProvider */.QP, {
227849
+ backend: backend,
227850
+ opts: opts
227851
+ }, children);
227852
+ }
227853
+ DragAndDropProvider.propTypes = {
227854
+ children: (prop_types_default()).any
227855
+ };
227856
+ /* harmony default export */ const contextProviders_DragAndDropProvider = (DragAndDropProvider);
227857
+ ;// CONCATENATED MODULE: ../../ui-next/src/contextProviders/CineProvider.tsx
227858
+
227859
+ const CineProvider_DEFAULT_STATE = {
227860
+ isCineEnabled: false,
227861
+ cines: {
227862
+ /*
227863
+ * viewportId: { isPlaying: false, frameRate: 24 };
227864
+ */
227865
+ }
227866
+ };
227867
+ const DEFAULT_CINE = {
227868
+ isPlaying: false,
227869
+ frameRate: 24
227870
+ };
227871
+ const CineContext = /*#__PURE__*/(0,react.createContext)(null);
227872
+ function CineProvider({
227873
+ children,
227874
+ service
227875
+ }) {
227876
+ const reducer = (state, action) => {
227877
+ switch (action.type) {
227878
+ case 'SET_CINE':
227879
+ {
227880
+ const {
227881
+ id,
227882
+ frameRate,
227883
+ isPlaying = undefined
227884
+ } = action.payload;
227885
+ const cines = state.cines;
227886
+ const syncedCineIds = service.getSyncedViewports(id).map(({
227887
+ viewportId
227888
+ }) => viewportId);
227889
+ const cineIdsToUpdate = [id, ...syncedCineIds].filter(curId => {
227890
+ const currentCine = cines[curId] ?? {};
227891
+ const shouldUpdateFrameRate = currentCine.frameRate !== (frameRate ?? currentCine.frameRate);
227892
+ const shouldUpdateIsPlaying = currentCine.isPlaying !== (isPlaying ?? currentCine.isPlaying);
227893
+ return shouldUpdateFrameRate || shouldUpdateIsPlaying;
227894
+ });
227895
+ cineIdsToUpdate.forEach(currId => {
227896
+ let cine = cines[currId];
227897
+ if (!cine) {
227898
+ cine = {
227899
+ id,
227900
+ ...DEFAULT_CINE
227901
+ };
227902
+ cines[currId] = cine;
227903
+ }
227904
+ cine.frameRate = frameRate ?? cine.frameRate;
227905
+ cine.isPlaying = isPlaying ?? cine.isPlaying;
227906
+ });
227907
+ return {
227908
+ ...state,
227909
+ ...cines
227910
+ };
227911
+ }
227912
+ case 'SET_IS_CINE_ENABLED':
227913
+ {
227914
+ return {
227915
+ ...state,
227916
+ ...{
227917
+ isCineEnabled: action.payload
227918
+ }
227919
+ };
227920
+ }
227921
+ default:
227922
+ return action.payload;
227923
+ }
227924
+ };
227925
+ const [state, dispatch] = (0,react.useReducer)(reducer, CineProvider_DEFAULT_STATE);
227926
+ const getState = (0,react.useCallback)(() => state, [state]);
227927
+ const setIsCineEnabled = (0,react.useCallback)(isCineEnabled => dispatch({
227928
+ type: 'SET_IS_CINE_ENABLED',
227929
+ payload: isCineEnabled
227930
+ }), [dispatch]);
227931
+ const setCine = (0,react.useCallback)(({
227932
+ id,
227933
+ frameRate,
227934
+ isPlaying
227935
+ }) => dispatch({
227936
+ type: 'SET_CINE',
227937
+ payload: {
227938
+ id,
227939
+ frameRate,
227940
+ isPlaying
227941
+ }
227942
+ }), [dispatch]);
227943
+
227944
+ /**
227945
+ * Sets the implementation of a modal service that can be used by extensions.
227946
+ *
227947
+ * @returns void
227948
+ */
227949
+ (0,react.useEffect)(() => {
227950
+ if (service) {
227951
+ service.setServiceImplementation({
227952
+ getState,
227953
+ setIsCineEnabled,
227954
+ setCine
227955
+ });
227956
+ }
227957
+ }, [getState, service, setCine, setIsCineEnabled]);
227958
+ const api = {
227959
+ getState,
227960
+ setCine,
227961
+ setIsCineEnabled: isCineEnabled => service.setIsCineEnabled(isCineEnabled),
227962
+ playClip: (element, playClipOptions) => service.playClip(element, playClipOptions),
227963
+ stopClip: (element, stopClipOptions) => service.stopClip(element, stopClipOptions),
227964
+ setViewportCineClosed: viewportId => service.setViewportCineClosed(viewportId),
227965
+ clearViewportCineClosed: viewportId => service.clearViewportCineClosed(viewportId),
227966
+ isViewportCineClosed: viewportId => service.isViewportCineClosed(viewportId)
227967
+ };
227968
+ return /*#__PURE__*/react.createElement(CineContext.Provider, {
227969
+ value: [state, api]
227970
+ }, children);
227971
+ }
227972
+ const useCine = () => (0,react.useContext)(CineContext);
227973
+ ;// CONCATENATED MODULE: ../../ui-next/src/contextProviders/index.ts
227974
+
227975
+
227976
+
227977
+
227978
+
227979
+
227980
+
227981
+
227982
+
227983
+
227984
+
227985
+
227986
+
227987
+
227988
+
227989
+
227990
+
227991
+
227992
+
227993
+
227994
+
227995
+ ;// CONCATENATED MODULE: ../../ui-next/src/components/Errorboundary/ErrorBoundary.tsx
227996
+ function ErrorBoundary_extends() { return ErrorBoundary_extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, ErrorBoundary_extends.apply(null, arguments); }
227997
+
227998
+
227999
+
228000
+
228001
+
228002
+
228003
+
228004
+ const isProduction = "production" === 'production';
228005
+
228006
+ /**
228007
+ * Parses an error stack trace to extract important information
228008
+ * Extracts the first function name from the stack trace
228009
+ */
228010
+ const parseErrorStack = error => {
228011
+ if (!error.stack) {
228012
+ return {
228013
+ filePath: null,
228014
+ errorTitle: null,
228015
+ code: null,
228016
+ firstFilename: null
228017
+ };
228018
+ }
228019
+ const stack = error.stack;
228020
+ const stackLines = stack.split('\n');
228021
+
228022
+ // Extract error message from first line
228023
+ const errorMessage = stackLines[0].trim();
228024
+
228025
+ // Extract first function name from the stack trace
228026
+ let firstFilename = null;
228027
+
228028
+ // Find the first stack line (starts with " at ")
228029
+ for (let i = 1; i < stackLines.length; i++) {
228030
+ const line = stackLines[i].trim();
228031
+ if (line.startsWith('at ')) {
228032
+ // Extract function name pattern
228033
+ const match = line.match(/at\s+([^\s(]+)[\s(]/);
228034
+ if (match && match[1]) {
228035
+ firstFilename = match[1];
228036
+ break;
228037
+ }
228038
+ }
228039
+ }
228040
+
228041
+ // Sanitize stack trace for display - safer approach to avoid ReDoS
228042
+ const sanitizedStack = stackLines.map(line => {
228043
+ // Limit line length to prevent excessive processing
228044
+ const limitedLine = line.substring(0, 2000);
228045
+
228046
+ // Process each part separately to avoid complex regex patterns
228047
+ if (limitedLine.includes('(')) {
228048
+ // Extract filename from paths in parentheses
228049
+ const openParenIndex = limitedLine.indexOf('(');
228050
+ const closeParenIndex = limitedLine.indexOf(')', openParenIndex);
228051
+ if (openParenIndex >= 0 && closeParenIndex > openParenIndex) {
228052
+ const pathInParens = limitedLine.substring(openParenIndex + 1, closeParenIndex);
228053
+
228054
+ // Find the last segment after slash or backslash
228055
+ const lastSlashIndex = Math.max(pathInParens.lastIndexOf('/'), pathInParens.lastIndexOf('\\'));
228056
+ if (lastSlashIndex >= 0) {
228057
+ const filename = pathInParens.substring(lastSlashIndex + 1);
228058
+ return limitedLine.substring(0, openParenIndex + 1) + filename + limitedLine.substring(closeParenIndex);
228059
+ }
228060
+ }
228061
+ }
228062
+
228063
+ // Handle the "at Function path:line:column" format
228064
+ if (limitedLine.includes(' at ')) {
228065
+ const atIndex = limitedLine.indexOf(' at ');
228066
+ const afterAt = limitedLine.substring(atIndex + 4).trim();
228067
+
228068
+ // Split by whitespace to separate function and path
228069
+ const spaceAfterFunc = afterAt.indexOf(' ');
228070
+ if (spaceAfterFunc > 0) {
228071
+ const funcName = afterAt.substring(0, spaceAfterFunc);
228072
+ const path = afterAt.substring(spaceAfterFunc + 1);
228073
+
228074
+ // Check if this is a path with line/column numbers
228075
+ if (path.includes(':') && /.*:[0-9]+:[0-9]+/.test(path)) {
228076
+ // Find the last segment after slash or backslash
228077
+ const lastSlashIndex = Math.max(path.lastIndexOf('/'), path.lastIndexOf('\\'));
228078
+ if (lastSlashIndex >= 0) {
228079
+ const filename = path.substring(lastSlashIndex + 1);
228080
+ return limitedLine.substring(0, atIndex + 4) + funcName + ' ' + filename;
228081
+ }
228082
+ }
228083
+ }
228084
+ }
228085
+ return limitedLine;
228086
+ }).join('\n');
228087
+ return {
228088
+ errorTitle: errorMessage,
228089
+ code: sanitizedStack,
228090
+ firstFilename: firstFilename
228091
+ };
228092
+ };
228093
+ const DefaultFallback = ({
228094
+ error,
228095
+ context,
228096
+ resetErrorBoundary = () => {}
228097
+ }) => {
228098
+ const {
228099
+ t
228100
+ } = (0,dist_es/* useTranslation */.Bd)('ErrorBoundary');
228101
+ const [showDetails, setShowDetails] = (0,react.useState)(false);
228102
+ const {
228103
+ show
228104
+ } = useNotification();
228105
+ const title = `${t('Something went wrong')}${!isProduction && ` ${t('in')} ${context}`}.`;
228106
+ const subtitle = t('Sorry, something went wrong there. Try again.');
228107
+ const {
228108
+ errorTitle,
228109
+ code,
228110
+ firstFilename
228111
+ } = parseErrorStack(error);
228112
+ const copyErrorToClipboard = () => {
228113
+ if (code) {
228114
+ navigator.clipboard.writeText(code);
228115
+ show({
228116
+ title: t('Success'),
228117
+ message: t('Error copied to clipboard'),
228118
+ type: 'success',
228119
+ duration: 3000
228120
+ });
228121
+ }
228122
+ };
228123
+ (0,react.useEffect)(() => {
228124
+ // Use a stable ID based on error message to support deduplication
228125
+ const errorId = `error-${errorTitle || error.message}`;
228126
+
228127
+ // We don't need to track shown state - instead rely on the notification deduplication system
228128
+ show({
228129
+ title,
228130
+ message: subtitle,
228131
+ type: 'error',
228132
+ duration: 0,
228133
+ id: errorId,
228134
+ action: {
228135
+ label: t('Show Details'),
228136
+ onClick: () => setShowDetails(true)
228137
+ }
228138
+ });
228139
+ }, [error, errorTitle, subtitle, t, title, show]);
228140
+ if (isProduction) {
228141
+ return null;
228142
+ }
228143
+ return /*#__PURE__*/react.createElement(Dialog_Dialog, {
228144
+ open: showDetails,
228145
+ onOpenChange: setShowDetails
228146
+ }, /*#__PURE__*/react.createElement(Dialog_DialogContent, {
228147
+ className: "bg-muted max-w-3xl overflow-hidden border-0 p-0",
228148
+ onInteractOutside: e => e.preventDefault()
228149
+ }, /*#__PURE__*/react.createElement("div", {
228150
+ className: "p-5 pb-4"
228151
+ }, /*#__PURE__*/react.createElement("div", {
228152
+ className: "flex items-center justify-between"
228153
+ }, /*#__PURE__*/react.createElement("h2", {
228154
+ className: "text-highlight text-xl font-normal"
228155
+ }, errorTitle || error.message || title))), code && /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement(ScrollArea_ScrollArea, {
228156
+ className: "bg-background text-foreground mx-6 h-[321px] rounded-b-md"
228157
+ }, /*#__PURE__*/react.createElement("div", {
228158
+ className: "bg-background border-input flex items-center justify-between rounded-t-md border-b px-4 py-2"
228159
+ }, /*#__PURE__*/react.createElement("div", {
228160
+ className: "text-muted-foreground text-base"
228161
+ }, firstFilename || 'Error Stack'), /*#__PURE__*/react.createElement(Button_Button/* Button */.$, {
228162
+ className: "w-20",
228163
+ onClick: copyErrorToClipboard,
228164
+ title: t('Copy error')
228165
+ }, "Copy")), /*#__PURE__*/react.createElement("div", {
228166
+ className: "p-4 font-mono text-sm"
228167
+ }, code.split('\n').map((line, index) => /*#__PURE__*/react.createElement("div", {
228168
+ key: index,
228169
+ className: "flex"
228170
+ }, /*#__PURE__*/react.createElement("span", {
228171
+ className: "whitespace-pre"
228172
+ }, line)))))), /*#__PURE__*/react.createElement("div", {
228173
+ className: "flex items-center justify-end p-6 pt-2"
228174
+ }, /*#__PURE__*/react.createElement(Button_Button/* Button */.$, {
228175
+ variant: "link",
228176
+ className: "text-primary p-0",
228177
+ onClick: () => window.open('https://github.com/OHIF/Viewers/issues/new?template=bug-report.yml', '_blank')
228178
+ }, "Report Issue"))));
228179
+ };
228180
+ const ErrorBoundary = ({
228181
+ context = 'OHIF',
228182
+ onReset = () => {},
228183
+ onError = () => {},
228184
+ fallbackComponent: FallbackComponent = DefaultFallback,
228185
+ children,
228186
+ fallbackRoute = null,
228187
+ isPage
228188
+ }) => {
228189
+ const [error, setError] = (0,react.useState)(null);
228190
+ const onResetHandler = () => {
228191
+ setError(null);
228192
+ onReset();
228193
+ };
228194
+
228195
+ // Add error event listener to window
228196
+ (0,react.useEffect)(() => {
228197
+ let errorTimeout;
228198
+ const handleError = event => {
228199
+ event.preventDefault();
228200
+ clearTimeout(errorTimeout);
228201
+ errorTimeout = setTimeout(() => {
228202
+ setError(event.error);
228203
+ onErrorHandler(event.error, null);
228204
+ }, 100);
228205
+ };
228206
+ const handleRejection = event => {
228207
+ event.preventDefault();
228208
+ clearTimeout(errorTimeout);
228209
+ errorTimeout = setTimeout(() => {
228210
+ setError(event.reason);
228211
+ onErrorHandler(event.reason, null);
228212
+ }, 100);
228213
+ };
228214
+ window.addEventListener('error', handleError);
228215
+ window.addEventListener('unhandledrejection', handleRejection);
228216
+ return () => {
228217
+ clearTimeout(errorTimeout);
228218
+ window.removeEventListener('error', handleError);
228219
+ window.removeEventListener('unhandledrejection', handleRejection);
228220
+ };
228221
+ }, []);
228222
+ const onErrorHandler = (error, componentStack) => {
228223
+ console.debug(`${context} Error Boundary`, error, componentStack, context);
228224
+ onError(error, componentStack || '', context);
228225
+ };
228226
+ return /*#__PURE__*/react.createElement(react_error_boundary_esm/* ErrorBoundary */.tH, {
228227
+ fallbackRender: props => /*#__PURE__*/react.createElement(FallbackComponent, ErrorBoundary_extends({}, props, {
228228
+ context: context
228229
+ })),
228230
+ onReset: onResetHandler,
228231
+ onError: (error, info) => onErrorHandler(error, info.componentStack)
228232
+ }, /*#__PURE__*/react.createElement(react.Fragment, null, children, error && /*#__PURE__*/react.createElement(FallbackComponent, {
228233
+ error: error,
228234
+ context: context,
228235
+ resetErrorBoundary: () => setError(null)
228236
+ })));
228237
+ };
228238
+
228239
+ ;// CONCATENATED MODULE: ../../ui-next/src/components/Errorboundary/index.tsx
228240
+
228241
+
228242
+ ;// CONCATENATED MODULE: ../../ui-next/src/components/NavBar/NavBar.tsx
228243
+
228244
+
228245
+
228246
+ const stickyClasses = 'sticky top-0';
228247
+ const notStickyClasses = 'relative';
228248
+ const NavBar = ({
228249
+ className,
228250
+ children,
228251
+ isSticky
228252
+ }) => {
228253
+ return /*#__PURE__*/react.createElement("div", {
228254
+ className: classnames_default()('bg-secondary-dark z-20 border-black px-1', isSticky && stickyClasses, !isSticky && notStickyClasses, className)
228255
+ }, children);
228256
+ };
228257
+ NavBar.propTypes = {
228258
+ className: (prop_types_default()).string,
228259
+ children: (prop_types_default()).node,
228260
+ isSticky: (prop_types_default()).bool
228261
+ };
228262
+ /* harmony default export */ const NavBar_NavBar = (NavBar);
228263
+ ;// CONCATENATED MODULE: ../../ui-next/src/components/NavBar/index.js
228264
+
228265
+ /* harmony default export */ const components_NavBar = (NavBar_NavBar);
228266
+ ;// CONCATENATED MODULE: ../../ui-next/src/components/Header/Header.tsx
228267
+ function Header_extends() { return Header_extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, Header_extends.apply(null, arguments); }
228268
+
228269
+
228270
+
228271
+
228272
+
228273
+ // Todo: we should move this component to composition and remove props base
228274
+
228275
+ function Header_Header({
228276
+ children,
228277
+ menuOptions,
228278
+ isReturnEnabled = true,
228279
+ onClickReturnButton,
228280
+ isSticky = false,
228281
+ WhiteLabeling,
228282
+ PatientInfo,
228283
+ UndoRedo,
228284
+ Secondary,
228285
+ ...props
228286
+ }) {
228287
+ const onClickReturn = () => {
228288
+ if (isReturnEnabled && onClickReturnButton) {
228289
+ onClickReturnButton();
228290
+ }
228291
+ };
228292
+ return /*#__PURE__*/react.createElement(components_NavBar, Header_extends({
228293
+ isSticky: isSticky
228294
+ }, props), /*#__PURE__*/react.createElement("div", {
228295
+ className: "relative h-[48px] items-center"
228296
+ }, /*#__PURE__*/react.createElement("div", {
228297
+ className: "absolute left-0 top-1/2 flex -translate-y-1/2 items-center"
228298
+ }, /*#__PURE__*/react.createElement("div", {
228299
+ className: classnames_default()('mr-3 inline-flex items-center', isReturnEnabled && 'cursor-pointer'),
228300
+ onClick: onClickReturn,
228301
+ "data-cy": "return-to-work-list"
228302
+ }, isReturnEnabled && /*#__PURE__*/react.createElement(Icons/* Icons */.F.ArrowLeft, {
228303
+ className: "text-primary ml-1 h-7 w-7"
228304
+ }), /*#__PURE__*/react.createElement("div", {
228305
+ className: "ml-1"
228306
+ }, WhiteLabeling?.createLogoComponentFn?.(react, props) || /*#__PURE__*/react.createElement(Icons/* Icons */.F.OHIFLogo, null)))), /*#__PURE__*/react.createElement("div", {
228307
+ className: "absolute top-1/2 left-[250px] h-8 -translate-y-1/2"
228308
+ }, Secondary), /*#__PURE__*/react.createElement("div", {
228309
+ className: "absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 transform"
228310
+ }, /*#__PURE__*/react.createElement("div", {
228311
+ className: "flex items-center justify-center space-x-2"
228312
+ }, children)), /*#__PURE__*/react.createElement("div", {
228313
+ className: "absolute right-0 top-1/2 flex -translate-y-1/2 select-none items-center"
228314
+ }, UndoRedo, /*#__PURE__*/react.createElement("div", {
228315
+ className: "border-primary-dark mx-1.5 h-[25px] border-r"
228316
+ }), PatientInfo, /*#__PURE__*/react.createElement("div", {
228317
+ className: "border-primary-dark mx-1.5 h-[25px] border-r"
228318
+ }), /*#__PURE__*/react.createElement("div", {
228319
+ className: "flex-shrink-0"
228320
+ }, /*#__PURE__*/react.createElement(DropdownMenu_DropdownMenu, null, /*#__PURE__*/react.createElement(DropdownMenu_DropdownMenuTrigger, {
228321
+ asChild: true
228322
+ }, /*#__PURE__*/react.createElement(components_Button/* Button */.$, {
228323
+ variant: "ghost",
228324
+ size: "icon",
228325
+ className: "text-primary hover:bg-primary-dark mt-2 h-full w-full"
228326
+ }, /*#__PURE__*/react.createElement(Icons/* Icons */.F.GearSettings, null))), /*#__PURE__*/react.createElement(DropdownMenu_DropdownMenuContent, {
228327
+ align: "end"
228328
+ }, menuOptions.map((option, index) => {
228329
+ const IconComponent = option.icon ? Icons/* Icons */.F[option.icon] : null;
228330
+ return /*#__PURE__*/react.createElement(DropdownMenu_DropdownMenuItem, {
228331
+ key: index,
228332
+ onSelect: option.onClick,
228333
+ className: "flex items-center gap-2 py-2"
228334
+ }, IconComponent && /*#__PURE__*/react.createElement("span", {
228335
+ className: "flex h-4 w-4 items-center justify-center"
228336
+ }, /*#__PURE__*/react.createElement(Icons/* Icons */.F.ByName, {
228337
+ name: IconComponent.name
228338
+ })), /*#__PURE__*/react.createElement("span", {
228339
+ className: "flex-1"
228340
+ }, option.title));
228341
+ })))))));
228342
+ }
228343
+ /* harmony default export */ const components_Header_Header = (Header_Header);
228344
+ ;// CONCATENATED MODULE: ../../ui-next/src/components/Header/index.js
228345
+
228346
+
228347
+ ;// CONCATENATED MODULE: ../../ui-next/src/components/Card/Card.tsx
228348
+ function Card_extends() { return Card_extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, Card_extends.apply(null, arguments); }
228349
+
228350
+
228351
+ const Card = /*#__PURE__*/react.forwardRef(({
228352
+ className,
228353
+ ...props
228354
+ }, ref) => /*#__PURE__*/react.createElement("div", Card_extends({
228355
+ ref: ref,
228356
+ className: (0,utils.cn)('bg-card text-card-foreground border-input rounded-lg border shadow', className)
228357
+ }, props)));
228358
+ Card.displayName = 'Card';
228359
+ const CardHeader = /*#__PURE__*/react.forwardRef(({
228360
+ className,
228361
+ ...props
228362
+ }, ref) => /*#__PURE__*/react.createElement("div", Card_extends({
228363
+ ref: ref,
228364
+ className: (0,utils.cn)('flex flex-col space-y-1.5 p-6', className)
228365
+ }, props)));
228366
+ CardHeader.displayName = 'CardHeader';
228367
+ const CardTitle = /*#__PURE__*/react.forwardRef(({
228368
+ className,
228369
+ ...props
228370
+ }, ref) => /*#__PURE__*/react.createElement("h3", Card_extends({
228371
+ ref: ref,
228372
+ className: (0,utils.cn)('font-semibold leading-none tracking-tight', className)
228373
+ }, props)));
228374
+ CardTitle.displayName = 'CardTitle';
228375
+ const CardDescription = /*#__PURE__*/react.forwardRef(({
228376
+ className,
228377
+ ...props
228378
+ }, ref) => /*#__PURE__*/react.createElement("p", Card_extends({
228379
+ ref: ref,
228380
+ className: (0,utils.cn)('text-muted-foreground text-base', className)
228381
+ }, props)));
228382
+ CardDescription.displayName = 'CardDescription';
228383
+ const CardContent = /*#__PURE__*/react.forwardRef(({
228384
+ className,
228385
+ ...props
228386
+ }, ref) => /*#__PURE__*/react.createElement("div", Card_extends({
228387
+ ref: ref,
228388
+ className: (0,utils.cn)('p-6 pt-0', className)
228389
+ }, props)));
228390
+ CardContent.displayName = 'CardContent';
228391
+ const CardFooter = /*#__PURE__*/react.forwardRef(({
228392
+ className,
228393
+ ...props
228394
+ }, ref) => /*#__PURE__*/react.createElement("div", Card_extends({
228395
+ ref: ref,
228396
+ className: (0,utils.cn)('flex items-center p-6 pt-0', className)
228397
+ }, props)));
228398
+ CardFooter.displayName = 'CardFooter';
228399
+
228400
+ ;// CONCATENATED MODULE: ../../ui-next/src/components/Card/index.ts
228401
+
228402
+
228403
+ ;// CONCATENATED MODULE: ../../ui-next/src/components/Viewport/ViewportActionButton.tsx
228404
+
228405
+
228406
+
228407
+ /**
228408
+ * A button that can trigger commands when clicked.
228409
+ */
228410
+ function ViewportActionButton({
228411
+ onInteraction,
228412
+ commands,
228413
+ id,
228414
+ children
228415
+ }) {
228416
+ return /*#__PURE__*/react.createElement("div", {
228417
+ className: "bg-primary-main hover:bg-primary-light ml-1 cursor-pointer rounded px-1.5 hover:text-black"
228418
+ // Using onMouseUp because onClick wasn't firing if pointer-events are none.
228419
+ ,
228420
+ onMouseUp: () => {
228421
+ onInteraction({
228422
+ itemId: id,
228423
+ commands
228424
+ });
228425
+ }
228426
+ }, children);
228427
+ }
228428
+ ViewportActionButton.propTypes = {
228429
+ id: (prop_types_default()).string,
228430
+ onInteraction: (prop_types_default()).func.isRequired,
228431
+ commands: (prop_types_default()).array,
228432
+ children: (prop_types_default()).node
228433
+ };
228434
+
228435
+ ;// CONCATENATED MODULE: ../../ui-next/src/components/Viewport/PatientInfo.tsx
228436
+
228437
+
228438
+
228439
+
228440
+
228441
+ const classes = {
228442
+ infoHeader: 'text-base text-primary-light',
228443
+ infoText: 'text-base text-white max-w-24 truncate',
228444
+ firstRow: 'flex flex-col',
228445
+ row: 'flex flex-col ml-4'
228446
+ };
228447
+
228448
+ /**
228449
+ * A small info icon that, when clicked, can reveal additional patient details in a tooltip overlay.
228450
+ */
228451
+ function PatientInfo({
228452
+ patientName,
228453
+ patientSex,
228454
+ patientAge,
228455
+ MRN,
228456
+ thickness,
228457
+ thicknessUnits,
228458
+ spacing,
228459
+ scanner,
228460
+ isOpen,
228461
+ showPatientInfoRef
228462
+ }) {
228463
+ const {
228464
+ t
228465
+ } = (0,dist_es/* useTranslation */.Bd)('PatientInfo');
226963
228466
 
226964
228467
  // strip leading '0' from age if present
226965
228468
  while (patientAge.charAt(0) === '0') {
@@ -227249,9 +228752,10 @@ function ViewportPane({
227249
228752
  }, /*#__PURE__*/react.createElement("div", {
227250
228753
  className: classnames_default()('relative h-full w-full', className)
227251
228754
  }, children), /*#__PURE__*/react.createElement("div", {
227252
- className: classnames_default()('pointer-events-none absolute inset-0', {
227253
- 'border-highlight rounded-md border': isActive,
227254
- 'group-hover:border-highlight/50 rounded-md border border-transparent': !isActive
228755
+ className: classnames_default()('pointer-events-none absolute inset-0 rounded-md border', {
228756
+ 'border-highlight': isActive,
228757
+ 'group-hover/pane:border-highlight/50 border-transparent': !isActive,
228758
+ '!border-secondary-light border-dashed': isHighlighted
227255
228759
  })
227256
228760
  }));
227257
228761
  }
@@ -228093,7 +229597,7 @@ const DividerItem = () => {
228093
229597
  return /*#__PURE__*/react.createElement("div", {
228094
229598
  className: "flex h-3.5 shrink-0 items-center px-2"
228095
229599
  }, /*#__PURE__*/react.createElement("div", {
228096
- className: "bg-primary-dark h-[2px] w-full"
229600
+ className: "bg-background h-[2px] w-full"
228097
229601
  }));
228098
229602
  };
228099
229603
  /* harmony default export */ const AllInOneMenu_DividerItem = (DividerItem);
@@ -228459,7 +229963,7 @@ const AllInOneMenu = {
228459
229963
  };
228460
229964
  /* harmony default export */ const components_AllInOneMenu = (AllInOneMenu);
228461
229965
  // EXTERNAL MODULE: ../../../node_modules/d3-selection/src/index.js + 52 modules
228462
- var src = __webpack_require__(21423);
229966
+ var d3_selection_src = __webpack_require__(21423);
228463
229967
  // EXTERNAL MODULE: ../../../node_modules/d3-array/src/index.js + 58 modules
228464
229968
  var d3_array_src = __webpack_require__(20071);
228465
229969
  // EXTERNAL MODULE: ../../../node_modules/d3-axis/src/index.js + 2 modules
@@ -228887,7 +230391,7 @@ const _updateSeriesColors = series => {
228887
230391
  };
228888
230392
  const _textEllipses = (width, padding = 0) => {
228889
230393
  return function (...args) {
228890
- const self = src/* select */.Lt(this);
230394
+ const self = d3_selection_src/* select */.Lt(this);
228891
230395
  let textLength = self.node().getComputedTextLength();
228892
230396
  let text = self.text();
228893
230397
  while (textLength > width - 2 * padding && text.length > 0) {
@@ -229052,7 +230556,7 @@ const LineChart = ({
229052
230556
  const chartContainer = chartContainerRef.current;
229053
230557
  const containerWidth = chartContainer.offsetWidth;
229054
230558
  const containerHeight = chartContainer.offsetHeight;
229055
- const d3Container = src/* create */.vt('svg').attr('viewBox', [0, 0, containerWidth, containerHeight]).style('max-width', `${containerWidth}px`).style('overflow', 'visible');
230559
+ const d3Container = d3_selection_src/* create */.vt('svg').attr('viewBox', [0, 0, containerWidth, containerHeight]).style('max-width', `${containerWidth}px`).style('overflow', 'visible');
229056
230560
  chartContainer.append(d3Container.node());
229057
230561
  setD3SVGRef(d3Container);
229058
230562
  setWidth(containerWidth);
@@ -229229,1209 +230733,91 @@ const LabellingFlow = ({
229229
230733
  const [value, setValue] = (0,react.useState)(initialLabel);
229230
230734
  const [currentItems, setCurrentItems] = (0,react.useState)([]);
229231
230735
 
229232
- // Update items when labelData changes
229233
- (0,react.useEffect)(() => {
229234
- if (labelData) {
229235
- setCurrentItems(lodash_clonedeep_default()(labelData));
229236
- }
229237
- }, [labelData]);
229238
-
229239
- // Original component used measurementData?.label in constructor,
229240
- // let's try to initialize based on that if initialLabel is not provided.
229241
- (0,react.useEffect)(() => {
229242
- if (!initialLabel && measurementData?.label) {
229243
- setValue(measurementData.label);
229244
- }
229245
- }, [initialLabel, measurementData]);
229246
- return /*#__PURE__*/react.createElement(Command_Command, {
229247
- className: "border-input border"
229248
- }, /*#__PURE__*/react.createElement(Command_CommandInput, {
229249
- placeholder: placeholder
229250
- }), /*#__PURE__*/react.createElement(Command_CommandList, null, /*#__PURE__*/react.createElement(Command_CommandEmpty, null, emptyMessage), /*#__PURE__*/react.createElement(ScrollArea_ScrollArea, {
229251
- className: "h-[300px]"
229252
- }, /*#__PURE__*/react.createElement(Command_CommandGroup, null, currentItems.map(item => /*#__PURE__*/react.createElement(Command_CommandItem, {
229253
- key: item.value,
229254
- value: item.value,
229255
- onSelect: currentValue => {
229256
- const newValue = currentValue === value ? '' : currentValue;
229257
- setValue(newValue);
229258
- labellingDoneCallback(newValue);
229259
- hide();
229260
- }
229261
- }, /*#__PURE__*/react.createElement(react_icons_esm/* CheckIcon */.Srz, {
229262
- className: (0,utils.cn)('mr-2 h-4 w-4', value === item.value ? 'opacity-100' : 'opacity-0')
229263
- }), item.label))))));
229264
- };
229265
- /* harmony default export */ const Labelling_LabellingFlow = (LabellingFlow);
229266
- ;// CONCATENATED MODULE: ../../ui-next/src/components/Labelling/index.ts
229267
-
229268
- /* harmony default export */ const Labelling = (Labelling_LabellingFlow);
229269
- ;// CONCATENATED MODULE: ../../ui-next/src/components/index.ts
229270
-
229271
-
229272
-
229273
-
229274
-
229275
-
229276
-
229277
-
229278
-
229279
-
229280
-
229281
-
229282
-
229283
-
229284
-
229285
-
229286
-
229287
-
229288
-
229289
-
229290
-
229291
-
229292
-
229293
-
229294
-
229295
-
229296
-
229297
-
229298
-
229299
-
229300
-
229301
-
229302
-
229303
-
229304
-
229305
-
229306
-
229307
-
229308
-
229309
-
229310
-
229311
-
229312
-
229313
-
229314
-
229315
-
229316
-
229317
-
229318
-
229319
-
229320
-
229321
-
229322
-
229323
-
229324
-
229325
-
229326
-
229327
-
229328
-
229329
-
229330
-
229331
-
229332
-
229333
-
229334
-
229335
-
229336
-
229337
-
229338
-
229339
- // Segmentation Context Exports
229340
-
229341
-
229342
- ;// CONCATENATED MODULE: ../../ui-next/src/contextProviders/NotificationProvider.tsx
229343
- function NotificationProvider_extends() { return NotificationProvider_extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, NotificationProvider_extends.apply(null, arguments); }
229344
-
229345
-
229346
-
229347
- const NotificationContext = /*#__PURE__*/(0,react.createContext)(null);
229348
- const useNotification = () => useContext(NotificationContext);
229349
- const NotificationProvider = ({
229350
- children,
229351
- service
229352
- }) => {
229353
- const DEFAULT_OPTIONS = {
229354
- title: '',
229355
- message: '',
229356
- duration: 5000,
229357
- position: 'bottom-right',
229358
- // Aligning to Sonner's positioning system
229359
- type: 'info' // info, success, error
229360
- };
229361
- const show = (0,react.useCallback)(options => {
229362
- const {
229363
- title,
229364
- message,
229365
- duration,
229366
- position,
229367
- type,
229368
- promise
229369
- } = {
229370
- ...DEFAULT_OPTIONS,
229371
- ...options
229372
- };
229373
- if (promise) {
229374
- return dist_ue.promise(promise, {
229375
- loading: title || 'Loading...',
229376
- success: data => ({
229377
- title: title || 'Success',
229378
- description: typeof message === 'function' ? message(data) : message
229379
- }),
229380
- error: err => ({
229381
- title: title || 'Error',
229382
- description: typeof message === 'function' ? message(err) : message
229383
- })
229384
- });
230736
+ // Update items when labelData changes
230737
+ (0,react.useEffect)(() => {
230738
+ if (labelData) {
230739
+ setCurrentItems(lodash_clonedeep_default()(labelData));
229385
230740
  }
229386
- return dist_ue[type](title, {
229387
- duration,
229388
- position,
229389
- description: message
229390
- });
229391
- }, []);
229392
- const hide = (0,react.useCallback)(id => {
229393
- dist_ue.dismiss(id);
229394
- }, []);
229395
- const hideAll = (0,react.useCallback)(() => {
229396
- dist_ue.dismiss();
229397
- }, []);
230741
+ }, [labelData]);
229398
230742
 
229399
- /**
229400
- * Sets the implementation of a notification service that can be used by extensions.
229401
- *
229402
- * @returns void
229403
- */
230743
+ // Original component used measurementData?.label in constructor,
230744
+ // let's try to initialize based on that if initialLabel is not provided.
229404
230745
  (0,react.useEffect)(() => {
229405
- if (service) {
229406
- service.setServiceImplementation({
229407
- hide,
229408
- show
229409
- });
230746
+ if (!initialLabel && measurementData?.label) {
230747
+ setValue(measurementData.label);
229410
230748
  }
229411
- }, [service, hide, show]);
229412
- return /*#__PURE__*/react.createElement(NotificationContext.Provider, {
229413
- value: {
229414
- show,
229415
- hide,
229416
- hideAll
230749
+ }, [initialLabel, measurementData]);
230750
+ return /*#__PURE__*/react.createElement(Command_Command, {
230751
+ className: "border-input border"
230752
+ }, /*#__PURE__*/react.createElement(Command_CommandInput, {
230753
+ placeholder: placeholder
230754
+ }), /*#__PURE__*/react.createElement(Command_CommandList, null, /*#__PURE__*/react.createElement(Command_CommandEmpty, null, emptyMessage), /*#__PURE__*/react.createElement(ScrollArea_ScrollArea, {
230755
+ className: "h-[300px]"
230756
+ }, /*#__PURE__*/react.createElement(Command_CommandGroup, null, currentItems.map(item => /*#__PURE__*/react.createElement(Command_CommandItem, {
230757
+ key: item.value,
230758
+ value: item.value,
230759
+ onSelect: currentValue => {
230760
+ const newValue = currentValue === value ? '' : currentValue;
230761
+ setValue(newValue);
230762
+ labellingDoneCallback(newValue);
230763
+ hide();
229417
230764
  }
229418
- }, /*#__PURE__*/react.createElement(Toaster, {
229419
- position: "bottom-right"
229420
- }), children);
229421
- };
229422
- NotificationProvider.propTypes = {
229423
- children: (prop_types_default()).node.isRequired
229424
- };
229425
- const withNotification = Component => {
229426
- return function WrappedComponent(props) {
229427
- const notificationContext = useNotification();
229428
- return /*#__PURE__*/React.createElement(Component, NotificationProvider_extends({}, props, {
229429
- notificationContext: notificationContext
229430
- }));
229431
- };
230765
+ }, /*#__PURE__*/react.createElement(react_icons_esm/* CheckIcon */.Srz, {
230766
+ className: (0,utils.cn)('mr-2 h-4 w-4', value === item.value ? 'opacity-100' : 'opacity-0')
230767
+ }), item.label))))));
229432
230768
  };
229433
- /* harmony default export */ const contextProviders_NotificationProvider = (NotificationProvider);
229434
- // EXTERNAL MODULE: ../../../node_modules/lodash.merge/index.js
229435
- var lodash_merge = __webpack_require__(2816);
229436
- var lodash_merge_default = /*#__PURE__*/__webpack_require__.n(lodash_merge);
229437
- // EXTERNAL MODULE: ../../core/src/index.ts + 69 modules
229438
- var core_src = __webpack_require__(62037);
229439
- ;// CONCATENATED MODULE: ../../ui-next/src/contextProviders/ViewportGridProvider.tsx
230769
+ /* harmony default export */ const Labelling_LabellingFlow = (LabellingFlow);
230770
+ ;// CONCATENATED MODULE: ../../ui-next/src/components/Labelling/index.ts
229440
230771
 
230772
+ /* harmony default export */ const Labelling = (Labelling_LabellingFlow);
230773
+ ;// CONCATENATED MODULE: ../../ui-next/src/components/index.ts
229441
230774
 
229442
230775
 
229443
230776
 
229444
- const DEFAULT_STATE = {
229445
- activeViewportId: null,
229446
- layout: {
229447
- numRows: 0,
229448
- numCols: 0,
229449
- layoutType: 'grid'
229450
- },
229451
- // this flag is used to determine if the hanging protocol layout is active
229452
- // so that we can inherit the viewport options from the previous state
229453
- // otherwise we will not allow that. Basically the issue is that we need
229454
- // to be able to come out of the hanging protocol layout and go back to the
229455
- // regular layout e.g., if we are in the MPR hanging protocol, and someone use
229456
- // 1x1 layout by custom layout selector, there is no way to drag and drop
229457
- // a non-reconstructible series to the viewport since it will always
229458
- // inherit the hanging protocol layout options (volume viewport),
229459
- // so we need to be able to switch back to the regular layout.
229460
- isHangingProtocolLayout: false,
229461
- // Viewports structure has been changed to Map (previously it was
229462
- // tied to the viewportIndex which caused multiple issues. Now we have
229463
- // moved completely to viewportId which is unique for each viewport.
229464
- viewports: new Map(Object.entries({
229465
- default: {
229466
- viewportId: 'default',
229467
- displaySetInstanceUIDs: [],
229468
- isReady: false,
229469
- viewportOptions: {
229470
- viewportId: 'default'
229471
- },
229472
- displaySetSelectors: [],
229473
- displaySetOptions: [{}],
229474
- x: 0,
229475
- // left
229476
- y: 0,
229477
- // top
229478
- width: 100,
229479
- height: 100,
229480
- viewportLabel: null
229481
- }
229482
- }))
229483
- };
229484
- const determineActiveViewportId = (state, newViewports) => {
229485
- const {
229486
- activeViewportId
229487
- } = state;
229488
- const currentActiveViewport = state.viewports.get(activeViewportId);
229489
- if (!currentActiveViewport) {
229490
- // if there is no active viewport, we should just return the first viewport
229491
- const firstViewport = newViewports.values().next().value;
229492
- return firstViewport.viewportOptions.viewportId;
229493
- }
229494
230777
 
229495
- // for the new viewports, we should rank them by the displaySetInstanceUIDs
229496
- // they are displaying and the orientation then we can find the active viewport
229497
- const currentActiveDisplaySetInstanceUIDs = currentActiveViewport.displaySetInstanceUIDs;
229498
230778
 
229499
- // This doesn't take into account where stack viewport is converting to volumeViewport
229500
- // since in stack viewport we don't have a concept of "orientation" as a string
229501
- // maybe we should calculate the orientation based on the active imageId
229502
- // so that we can compare it with the new viewports (which might be volume viewports)
229503
- // and find the best match
229504
- const currentOrientation = currentActiveViewport.viewportOptions.orientation;
229505
- const filteredNewViewports = Array.from(newViewports.values()).filter(viewport => viewport.displaySetInstanceUIDs?.length > 0);
229506
- const sortedViewports = Array.from(filteredNewViewports.values()).sort((a, b) => {
229507
- // Compare orientations
229508
- const aOrientationMatch = a.viewportOptions.orientation === currentOrientation;
229509
- const bOrientationMatch = b.viewportOptions.orientation === currentOrientation;
229510
- if (aOrientationMatch !== bOrientationMatch) {
229511
- return bOrientationMatch - aOrientationMatch;
229512
- }
229513
230779
 
229514
- // Compare displaySetInstanceUIDs
229515
- const aMatch = a.displaySetInstanceUIDs.some(uid => currentActiveDisplaySetInstanceUIDs.includes(uid));
229516
- const bMatch = b.displaySetInstanceUIDs.some(uid => currentActiveDisplaySetInstanceUIDs.includes(uid));
229517
- if (aMatch !== bMatch) {
229518
- return bMatch - aMatch;
229519
- }
229520
- return 0; // Return 0 if no differences found
229521
- });
229522
- if (!sortedViewports?.length) {
229523
- return null;
229524
- }
229525
- return sortedViewports[0].viewportId;
229526
- };
229527
230780
 
229528
- // Define the API interface
229529
230781
 
229530
- // Update the context type
229531
- const ViewportGridContext = /*#__PURE__*/(0,react.createContext)([DEFAULT_STATE, {}]);
229532
230782
 
229533
- // Update the provider props type
229534
230783
 
229535
- function ViewportGridProvider({
229536
- children,
229537
- service
229538
- }) {
229539
- const viewportGridReducer = (state, action) => {
229540
- switch (action.type) {
229541
- case 'SET_IS_REFERENCE_VIEWABLE':
229542
- {
229543
- const {
229544
- viewportId,
229545
- isReferenceViewable
229546
- } = action.payload;
229547
- const viewports = new Map(state.viewports);
229548
- const viewport = viewports.get(viewportId);
229549
- if (!viewport) {
229550
- return;
229551
- }
229552
- viewports.set(viewportId, {
229553
- ...viewport,
229554
- isReferenceViewable
229555
- });
229556
- return {
229557
- ...state,
229558
- viewports
229559
- };
229560
- }
229561
- case 'SET_ACTIVE_VIEWPORT_ID':
229562
- {
229563
- return {
229564
- ...state,
229565
- ...{
229566
- activeViewportId: action.payload
229567
- }
229568
- };
229569
- }
229570
230784
 
229571
- /**
229572
- * Sets the display sets for multiple viewports.
229573
- * This is a replacement for the older set display set for viewport (single)
229574
- * because the old one had race conditions wherein the viewports could
229575
- * render partially in various ways causing exceptions.
229576
- */
229577
- case 'SET_DISPLAYSETS_FOR_VIEWPORTS':
229578
- {
229579
- const {
229580
- payload
229581
- } = action;
229582
- const viewports = new Map(state.viewports);
229583
- payload.forEach(updatedViewport => {
229584
- const {
229585
- viewportId,
229586
- displaySetInstanceUIDs
229587
- } = updatedViewport;
229588
- if (!viewportId) {
229589
- throw new Error('ViewportId is required to set display sets for viewport');
229590
- }
229591
- const previousViewport = viewports.get(viewportId);
229592
230785
 
229593
- // remove options that were meant for one time usage
229594
- if (previousViewport?.viewportOptions?.initialImageOptions) {
229595
- const {
229596
- useOnce
229597
- } = previousViewport.viewportOptions.initialImageOptions;
229598
- if (useOnce) {
229599
- previousViewport.viewportOptions.initialImageOptions = null;
229600
- }
229601
- }
229602
230786
 
229603
- // Use the newly provide viewportOptions and display set options
229604
- // when provided, and otherwise fall back to the previous ones.
229605
- // That allows for easy updates of just the display set.
229606
- let viewportOptions = lodash_merge_default()({}, previousViewport?.viewportOptions, updatedViewport?.viewportOptions);
229607
- const displaySetOptions = updatedViewport?.displaySetOptions || [];
229608
- if (!displaySetOptions.length) {
229609
- // Copy all the display set options, assuming a full set of displaySet UID's is provided.
229610
- if (state.isHangingProtocolLayout) {
229611
- displaySetOptions.push(...(previousViewport.displaySetOptions || []));
229612
- }
229613
- if (!displaySetOptions.length) {
229614
- displaySetOptions.push({});
229615
- }
229616
- }
229617
230787
 
229618
- // if it is not part of the hanging protocol layout, we should remove the toolGroupId
229619
- // and viewportType from the viewportOptions so that it doesn't
229620
- // inherit the hanging protocol layout options, only when
229621
- // the viewport options is not provided (e.g., when drag and drop)
229622
- // otherwise, programmatically set options should be preserved
229623
- if (!updatedViewport.viewportOptions && !state.isHangingProtocolLayout) {
229624
- viewportOptions = {
229625
- viewportId: viewportOptions.viewportId
229626
- };
229627
- }
229628
- const newViewport = {
229629
- ...previousViewport,
229630
- displaySetInstanceUIDs,
229631
- viewportOptions,
229632
- displaySetOptions
229633
- // viewportLabel: getViewportLabel(viewports, viewportId),
229634
- };
229635
- viewportOptions.presentationIds = service.getPresentationIds({
229636
- viewport: newViewport,
229637
- viewports
229638
- });
229639
- viewports.set(viewportId, {
229640
- ...viewports.get(viewportId),
229641
- ...newViewport
229642
- });
229643
- });
229644
- return {
229645
- ...state,
229646
- viewports
229647
- };
229648
- }
229649
- case 'SET_LAYOUT':
229650
- {
229651
- const {
229652
- numCols,
229653
- numRows,
229654
- layoutOptions,
229655
- layoutType = 'grid',
229656
- activeViewportId,
229657
- findOrCreateViewport,
229658
- isHangingProtocolLayout
229659
- } = action.payload;
229660
230788
 
229661
- // If empty viewportOptions, we use numRow and numCols to calculate number of viewports
229662
- const hasOptions = layoutOptions?.length;
229663
- const viewports = new Map();
229664
- // Options is a temporary state store which can be used by the
229665
- // findOrCreate to store state about already found viewports. Typically,
229666
- // it will be used to store the display set UID's which are already
229667
- // in view so that the find or create can decide which display sets
229668
- // haven't been viewed yet, and add them in the appropriate order.
229669
- const options = {};
229670
- let activeViewportIdToSet = activeViewportId;
229671
- for (let row = 0; row < numRows; row++) {
229672
- for (let col = 0; col < numCols; col++) {
229673
- const position = col + row * numCols;
229674
- const layoutOption = layoutOptions[position];
229675
- let xPos, yPos, w, h;
229676
- if (layoutOptions && layoutOptions[position]) {
229677
- ({
229678
- x: xPos,
229679
- y: yPos,
229680
- width: w,
229681
- height: h
229682
- } = layoutOptions[position]);
229683
- } else {
229684
- w = 1 / numCols;
229685
- h = 1 / numRows;
229686
- xPos = col * w;
229687
- yPos = row * h;
229688
- }
229689
- const colIndex = Math.round(xPos * numCols);
229690
- const rowIndex = Math.round(yPos * numRows);
229691
- const positionId = layoutOption?.positionId || `${colIndex}-${rowIndex}`;
229692
- if (hasOptions && position >= layoutOptions.length) {
229693
- continue;
229694
- }
229695
- const viewport = findOrCreateViewport(position, positionId, options);
229696
- if (!viewport) {
229697
- continue;
229698
- }
229699
- viewport.positionId = positionId;
229700
230789
 
229701
- // If the viewport doesn't have a viewportId, we create one
229702
- if (!viewport.viewportOptions?.viewportId) {
229703
- const randomUID = core_src/* utils */.Wp.uuidv4().substring(0, 8);
229704
- viewport.viewportOptions = viewport.viewportOptions || {};
229705
- viewport.viewportOptions.viewportId = `viewport-${randomUID}`;
229706
- }
229707
- viewport.viewportId = viewport.viewportOptions.viewportId;
229708
230790
 
229709
- // Create a new viewport object as it is getting updated here
229710
- // and it is part of the read only state
229711
- viewports.set(viewport.viewportId, viewport);
229712
- Object.assign(viewport, {
229713
- width: w,
229714
- height: h,
229715
- x: xPos,
229716
- y: yPos
229717
- });
229718
- viewport.isReady = false;
229719
- if (!viewport.viewportOptions.presentationIds) {
229720
- const presentationIds = service.getPresentationIds({
229721
- viewport,
229722
- viewports
229723
- });
229724
- viewport.viewportOptions.presentationIds = presentationIds;
229725
- }
229726
- }
229727
- }
229728
- activeViewportIdToSet = activeViewportIdToSet ?? determineActiveViewportId(state, viewports);
229729
- const ret = {
229730
- ...state,
229731
- activeViewportId: activeViewportIdToSet,
229732
- layout: {
229733
- ...state.layout,
229734
- numCols,
229735
- numRows,
229736
- layoutType
229737
- },
229738
- viewports,
229739
- isHangingProtocolLayout
229740
- };
229741
- return ret;
229742
- }
229743
- case 'RESET':
229744
- {
229745
- return DEFAULT_STATE;
229746
- }
229747
- case 'SET':
229748
- {
229749
- return {
229750
- ...state,
229751
- ...action.payload
229752
- };
229753
- }
229754
- case 'VIEWPORT_IS_READY':
229755
- {
229756
- const {
229757
- viewportId,
229758
- isReady
229759
- } = action.payload;
229760
- const viewports = new Map(state.viewports);
229761
- const viewport = viewports.get(viewportId);
229762
- if (!viewport) {
229763
- return;
229764
- }
229765
- viewports.set(viewportId, {
229766
- ...viewport,
229767
- isReady
229768
- });
229769
- return {
229770
- ...state,
229771
- viewports
229772
- };
229773
- }
229774
- default:
229775
- return action.payload;
229776
- }
229777
- };
229778
- const [viewportGridState, dispatch] = (0,react.useReducer)(viewportGridReducer, DEFAULT_STATE);
229779
- const getState = (0,react.useCallback)(() => {
229780
- return viewportGridState;
229781
- }, [viewportGridState]);
229782
- const getActiveViewportOptionByKey = key => {
229783
- const {
229784
- viewports,
229785
- activeViewportId
229786
- } = viewportGridState;
229787
- return viewports.get(activeViewportId)?.viewportOptions?.[key];
229788
- };
229789
- const setActiveViewportId = (0,react.useCallback)(index => dispatch({
229790
- type: 'SET_ACTIVE_VIEWPORT_ID',
229791
- payload: index
229792
- }), [dispatch]);
229793
- const setIsReferenceViewable = (0,react.useCallback)((viewportId, isReferenceViewable) => {
229794
- dispatch({
229795
- type: 'SET_IS_REFERENCE_VIEWABLE',
229796
- payload: {
229797
- viewportId,
229798
- isReferenceViewable
229799
- }
229800
- });
229801
- }, [dispatch]);
229802
- const setDisplaySetsForViewports = (0,react.useCallback)(viewports => dispatch({
229803
- type: 'SET_DISPLAYSETS_FOR_VIEWPORTS',
229804
- payload: viewports
229805
- }), [dispatch]);
229806
- const setViewportIsReady = (0,react.useCallback)((viewportId, isReady) => {
229807
- dispatch({
229808
- type: 'VIEWPORT_IS_READY',
229809
- payload: {
229810
- viewportId,
229811
- isReady
229812
- }
229813
- });
229814
- }, [dispatch, viewportGridState]);
229815
- const getGridViewportsReady = (0,react.useCallback)(() => {
229816
- const {
229817
- viewports
229818
- } = viewportGridState;
229819
- const readyViewports = Array.from(viewports.values()).filter(viewport => viewport.isReady);
229820
- return readyViewports.length === viewports.size;
229821
- }, [viewportGridState]);
229822
- const setLayout = (0,react.useCallback)(({
229823
- layoutType,
229824
- numRows,
229825
- numCols,
229826
- layoutOptions = [],
229827
- activeViewportId,
229828
- findOrCreateViewport,
229829
- isHangingProtocolLayout
229830
- }) => dispatch({
229831
- type: 'SET_LAYOUT',
229832
- payload: {
229833
- layoutType,
229834
- numRows,
229835
- numCols,
229836
- layoutOptions,
229837
- activeViewportId,
229838
- findOrCreateViewport,
229839
- isHangingProtocolLayout
229840
- }
229841
- }), [dispatch]);
229842
- const reset = (0,react.useCallback)(() => dispatch({
229843
- type: 'RESET',
229844
- payload: {}
229845
- }), [dispatch]);
229846
- const set = (0,react.useCallback)(payload => dispatch({
229847
- type: 'SET',
229848
- payload
229849
- }), [dispatch]);
229850
- const getViewportState = (0,react.useCallback)(viewportId => {
229851
- const {
229852
- viewports
229853
- } = viewportGridState;
229854
- return viewports.get(viewportId);
229855
- }, [viewportGridState]);
229856
- const getNumViewportPanes = (0,react.useCallback)(() => {
229857
- const {
229858
- layout,
229859
- viewports
229860
- } = viewportGridState;
229861
- const {
229862
- numRows,
229863
- numCols
229864
- } = layout;
229865
- return Math.min(viewports.size, numCols * numRows);
229866
- }, [viewportGridState]);
229867
230791
 
229868
- /**
229869
- * Sets the implementation of ViewportGridService that can be used by extensions.
229870
- *
229871
- * @returns void
229872
- */
229873
- (0,react.useEffect)(() => {
229874
- if (service) {
229875
- service.setServiceImplementation({
229876
- getState,
229877
- setActiveViewportId,
229878
- setDisplaySetsForViewports,
229879
- setIsReferenceViewable,
229880
- setLayout,
229881
- reset,
229882
- onModeExit: reset,
229883
- set,
229884
- getNumViewportPanes,
229885
- setViewportIsReady,
229886
- getViewportState,
229887
- getGridViewportsReady
229888
- });
229889
- }
229890
- }, [getState, service, setActiveViewportId, setDisplaySetsForViewports, setIsReferenceViewable, setLayout, reset, set, getNumViewportPanes, setViewportIsReady, getGridViewportsReady, getViewportState]);
229891
230792
 
229892
- // run many of the calls through the service itself since we want to publish events
229893
- const api = {
229894
- getState,
229895
- setActiveViewportId: index => service.setActiveViewportId(index),
229896
- setDisplaySetsForViewport: props => service.setDisplaySetsForViewports([props]),
229897
- setDisplaySetsForViewports: props => service.setDisplaySetsForViewports(props),
229898
- setIsReferenceViewable: (viewportId, isReferenceViewable) => service.setIsReferenceViewable(viewportId, isReferenceViewable),
229899
- setLayout: layout => service.setLayout(layout),
229900
- getViewportState: viewportId => service.getViewportState(viewportId),
229901
- reset: () => service.reset(),
229902
- set: gridLayoutState => service.setState(gridLayoutState),
229903
- // run it through the service itself since we want to publish events
229904
- getNumViewportPanes,
229905
- setViewportIsReady,
229906
- getGridViewportsReady,
229907
- getActiveViewportOptionByKey,
229908
- setViewportGridSizeChanged: props => service.setViewportGridSizeChanged(props),
229909
- publishViewportsReady: () => service.publishViewportsReady(),
229910
- getLayoutOptionsFromState: state => service.getLayoutOptionsFromState(state)
229911
- };
229912
- return /*#__PURE__*/react.createElement(ViewportGridContext.Provider, {
229913
- value: [viewportGridState, api]
229914
- }, children);
229915
- }
229916
- ViewportGridProvider.propTypes = {
229917
- children: (prop_types_default()).any,
229918
- service: prop_types_default().instanceOf(core_src/* ViewportGridService */.sI).isRequired
229919
- };
229920
230793
 
229921
- // Update the useViewportGrid hook
229922
- const useViewportGrid = () => (0,react.useContext)(ViewportGridContext);
229923
- ;// CONCATENATED MODULE: ../../ui-next/src/contextProviders/ModalProvider.tsx
229924
- function ModalProvider_extends() { return ModalProvider_extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, ModalProvider_extends.apply(null, arguments); }
229925
230794
 
229926
230795
 
229927
- const ModalContext = /*#__PURE__*/(0,react.createContext)(null);
229928
- const useModal = () => {
229929
- const ctx = (0,react.useContext)(ModalContext);
229930
- if (!ctx) {
229931
- throw new Error('useModal must be used within a ModalProvider');
229932
- }
229933
- return ctx;
229934
- };
229935
- const DEFAULT_OPTIONS = {
229936
- title: '',
229937
- shouldCloseOnEsc: true
229938
- };
229939
- const ModalProvider = ({
229940
- children,
229941
- modal: ModalComponent,
229942
- service = null
229943
- }) => {
229944
- const {
229945
- t
229946
- } = (0,dist_es/* useTranslation */.Bd)('Modals');
229947
- const [options, setOptions] = (0,react.useState)(DEFAULT_OPTIONS);
229948
- const ModalContent = options.content;
229949
- const show = (0,react.useCallback)(props => {
229950
- setOptions(prev => ({
229951
- ...prev,
229952
- ...props
229953
- }));
229954
- }, []);
229955
- const hide = (0,react.useCallback)(() => {
229956
- setOptions(DEFAULT_OPTIONS);
229957
- }, []);
229958
- (0,react.useEffect)(() => {
229959
- if (service) {
229960
- service.setServiceImplementation({
229961
- show,
229962
- hide
229963
- });
229964
- }
229965
- }, [hide, service, show]);
229966
- const {
229967
- title
229968
- } = options;
229969
- const CustomModal = service?.getCustomComponent();
229970
- const RenderedModal = CustomModal || ModalComponent;
229971
- return /*#__PURE__*/react.createElement(ModalContext.Provider, {
229972
- value: {
229973
- show,
229974
- hide
229975
- }
229976
- }, ModalContent && /*#__PURE__*/react.createElement(RenderedModal, ModalProvider_extends({
229977
- isOpen: true,
229978
- onClose: hide,
229979
- title: t(title)
229980
- }, options), /*#__PURE__*/react.createElement(ModalContent, ModalProvider_extends({}, options.contentProps, {
229981
- show: show,
229982
- hide: hide
229983
- }))), children);
229984
- };
229985
230796
 
229986
- const ModalConsumer = ModalContext.Consumer;
229987
- ;// CONCATENATED MODULE: ../../ui-next/src/contextProviders/ManagedDialog.tsx
229988
- function ManagedDialog_extends() { return ManagedDialog_extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, ManagedDialog_extends.apply(null, arguments); }
229989
230797
 
229990
230798
 
229991
230799
 
229992
- const ManagedDialog = ({
229993
- id,
229994
- isOpen,
229995
- title,
229996
- content: DialogContentComponent,
229997
- contentProps,
229998
- isDraggable,
229999
- shouldCloseOnEsc = false,
230000
- shouldCloseOnOverlayClick = false,
230001
- showOverlay = true,
230002
- defaultPosition,
230003
- onClose,
230004
- unstyled,
230005
- containerClassName
230006
- }) => {
230007
- return /*#__PURE__*/react.createElement(Dialog_Dialog, {
230008
- open: isOpen,
230009
- modal: false // keep modal behavior off for independent windows
230010
- ,
230011
- onOpenChange: open => {
230012
- if (!open) {
230013
- onClose(id);
230014
- }
230015
- },
230016
- isDraggable: isDraggable,
230017
- shouldCloseOnEsc: shouldCloseOnEsc,
230018
- shouldCloseOnOverlayClick: shouldCloseOnOverlayClick,
230019
- showOverlay: showOverlay
230020
- }, /*#__PURE__*/react.createElement(Dialog_DialogContent, {
230021
- className: (0,utils.cn)(unstyled ? 'p-0' : '', containerClassName),
230022
- unstyled: unstyled,
230023
- style: {
230024
- ...(defaultPosition ? {
230025
- position: 'fixed',
230026
- left: `${defaultPosition.x}px`,
230027
- top: `${defaultPosition.y}px`,
230028
- transform: 'translate(0, 0)',
230029
- margin: 0,
230030
- animation: 'none'
230031
- } : {})
230032
- }
230033
- }, !unstyled && /*#__PURE__*/react.createElement(DialogHeader, null, title && /*#__PURE__*/react.createElement(Dialog_DialogTitle, null, title)), /*#__PURE__*/react.createElement(DialogContentComponent, ManagedDialog_extends({}, contentProps, {
230034
- hide: () => onClose(id)
230035
- }))));
230036
- };
230037
- /* harmony default export */ const contextProviders_ManagedDialog = (ManagedDialog);
230038
- ;// CONCATENATED MODULE: ../../ui-next/src/contextProviders/DialogProvider.tsx
230039
- function DialogProvider_extends() { return DialogProvider_extends = Object.assign ? Object.assign.bind() : function (n) { for (var e = 1; e < arguments.length; e++) { var t = arguments[e]; for (var r in t) ({}).hasOwnProperty.call(t, r) && (n[r] = t[r]); } return n; }, DialogProvider_extends.apply(null, arguments); }
230040
230800
 
230041
230801
 
230042
- const DialogProvider_DialogContext = /*#__PURE__*/(0,react.createContext)(null);
230043
- const useDialog = () => {
230044
- const context = useContext(DialogProvider_DialogContext);
230045
- if (!context) {
230046
- throw new Error('useDialog must be used within a DialogProvider');
230047
- }
230048
- return context;
230049
- };
230050
- const DialogProvider_DialogProvider = ({
230051
- children,
230052
- dialog: DialogComponent = contextProviders_ManagedDialog,
230053
- service = null
230054
- }) => {
230055
- const [dialogs, setDialogs] = (0,react.useState)([]);
230056
- const show = (0,react.useCallback)(options => {
230057
- const id = options.id;
230058
- setDialogs(prev => [...prev, {
230059
- ...options,
230060
- id
230061
- }]);
230062
- return id;
230063
- }, []);
230064
- const hide = (0,react.useCallback)(id => {
230065
- setDialogs(prev => prev.filter(dialog => dialog.id !== id));
230066
- }, []);
230067
- const hideAll = (0,react.useCallback)(() => {
230068
- setDialogs([]);
230069
- }, []);
230070
- const isEmpty = (0,react.useCallback)(() => dialogs.length === 0, [dialogs]);
230071
- const contextValue = (0,react.useMemo)(() => ({
230072
- show,
230073
- hide,
230074
- hideAll,
230075
- isEmpty
230076
- }), [show, hide, hideAll, isEmpty]);
230077
- (0,react.useEffect)(() => {
230078
- if (service) {
230079
- service.setServiceImplementation(contextValue);
230080
- }
230081
- }, [service, contextValue]);
230082
- const CustomDialog = service?.getCustomComponent?.();
230083
- const RenderedDialog = CustomDialog || DialogComponent;
230084
- return /*#__PURE__*/react.createElement(DialogProvider_DialogContext.Provider, {
230085
- value: contextValue
230086
- }, dialogs.map(dialog => /*#__PURE__*/react.createElement(RenderedDialog, DialogProvider_extends({
230087
- key: dialog.id,
230088
- onClose: hide,
230089
- isOpen: true
230090
- }, dialog))), children);
230091
- };
230092
230802
 
230093
- ;// CONCATENATED MODULE: ../../ui-next/src/contextProviders/ViewportDialogProvider.tsx
230094
230803
 
230095
230804
 
230096
- const ViewportDialogProvider_DEFAULT_STATE = {
230097
- message: undefined,
230098
- type: 'info',
230099
- // "error" | "warning" | "info" | "success"
230100
- actions: undefined,
230101
- // array of { type, text, value }
230102
- onSubmit: () => {
230103
- console.log('btn value?');
230104
- },
230105
- onOutsideClick: () => {
230106
- console.warn('default: onOutsideClick');
230107
- },
230108
- onDismiss: () => {
230109
- console.log('dismiss? -1');
230110
- },
230111
- onKeyPress: () => {
230112
- console.log('key pressed?');
230113
- }
230114
- };
230115
- const ViewportDialogContext = /*#__PURE__*/(0,react.createContext)(null);
230116
- const {
230117
- Provider: ViewportDialogProvider_Provider
230118
- } = ViewportDialogContext;
230119
- const useViewportDialog = () => (0,react.useContext)(ViewportDialogContext);
230120
- const ViewportDialogProvider = ({
230121
- children,
230122
- service
230123
- }) => {
230124
- const [viewportDialogState, setViewportDialogState] = (0,react.useState)(ViewportDialogProvider_DEFAULT_STATE);
230125
- const show = (0,react.useCallback)(params => setViewportDialogState({
230126
- ...viewportDialogState,
230127
- ...params
230128
- }), [viewportDialogState]);
230129
- const hide = (0,react.useCallback)(() => setViewportDialogState(ViewportDialogProvider_DEFAULT_STATE), []);
230130
- (0,react.useEffect)(() => {
230131
- if (service) {
230132
- service.setServiceImplementation({
230133
- hide,
230134
- show
230135
- });
230136
- }
230137
- }, [hide, service, show]);
230138
- return /*#__PURE__*/react.createElement(ViewportDialogProvider_Provider, {
230139
- value: [viewportDialogState, {
230140
- show,
230141
- hide
230142
- }]
230143
- }, children);
230144
- };
230145
- ViewportDialogProvider.propTypes = {
230146
- /** Children that will be wrapped with Modal Context */
230147
- children: prop_types_default().oneOfType([prop_types_default().arrayOf((prop_types_default()).node), (prop_types_default()).node]).isRequired,
230148
- service: prop_types_default().shape({
230149
- setServiceImplementation: (prop_types_default()).func
230150
- })
230151
- };
230152
- /* harmony default export */ const contextProviders_ViewportDialogProvider = (ViewportDialogProvider);
230153
- ;// CONCATENATED MODULE: ../../ui-next/src/contextProviders/UserAuthenticationProvider.tsx
230154
230805
 
230155
230806
 
230156
- const UserAuthenticationProvider_DEFAULT_STATE = {
230157
- user: null,
230158
- enabled: false
230159
- };
230160
- const UserAuthenticationContext = /*#__PURE__*/(0,react.createContext)(UserAuthenticationProvider_DEFAULT_STATE);
230161
- function UserAuthenticationProvider({
230162
- children,
230163
- service
230164
- }) {
230165
- const userAuthenticationReducer = (state, action) => {
230166
- switch (action.type) {
230167
- case 'SET_USER':
230168
- {
230169
- return {
230170
- ...state,
230171
- ...{
230172
- user: action.payload.user
230173
- }
230174
- };
230175
- }
230176
- case 'RESET':
230177
- {
230178
- return {
230179
- user: null
230180
- };
230181
- }
230182
- case 'SET':
230183
- {
230184
- return {
230185
- ...state,
230186
- ...action.payload
230187
- };
230188
- }
230189
- default:
230190
- return action.payload;
230191
- }
230192
- };
230193
- const [userAuthenticationState, dispatch] = (0,react.useReducer)(userAuthenticationReducer, UserAuthenticationProvider_DEFAULT_STATE);
230194
- const getState = (0,react.useCallback)(() => userAuthenticationState, [userAuthenticationState]);
230195
- const setUser = (0,react.useCallback)(user => dispatch({
230196
- type: 'SET_USER',
230197
- payload: {
230198
- user
230199
- }
230200
- }), [dispatch]);
230201
- const getUser = (0,react.useCallback)(() => userAuthenticationState.user, [userAuthenticationState]);
230202
- const reset = (0,react.useCallback)(() => dispatch({
230203
- type: 'RESET',
230204
- payload: {}
230205
- }), [dispatch]);
230206
- const set = (0,react.useCallback)(payload => dispatch({
230207
- type: 'SET',
230208
- payload
230209
- }), [dispatch]);
230210
230807
 
230211
- /**
230212
- * Sets the implementation of the UserAuthenticationService that can be used by extensions.
230213
- *
230214
- * @returns void
230215
- */
230216
- // TODO: should this be a useEffect or not?
230217
- (0,react.useEffect)(() => {
230218
- if (service) {
230219
- service.setServiceImplementation({
230220
- getState,
230221
- setUser,
230222
- getUser,
230223
- reset,
230224
- set
230225
- });
230226
- }
230227
- }, [getState, service, setUser, getUser, reset, set]);
230228
230808
 
230229
- // TODO: This may not be correct, but I think we need to set the implementation for the service
230230
- // immediately when this runs, since otherwise the authentication redirects will fail.
230231
- // (useEffect only runs after the child components - in this case, routing logic - has failed)
230232
- if (service) {
230233
- service.setServiceImplementation({
230234
- getState,
230235
- setUser,
230236
- getUser,
230237
- reset,
230238
- set
230239
- });
230240
- }
230241
- const api = {
230242
- getState,
230243
- setUser,
230244
- getUser,
230245
- getAuthorizationHeader: service.getAuthorizationHeader,
230246
- handleUnauthenticated: service.handleUnauthenticated,
230247
- reset,
230248
- set
230249
- };
230250
- return /*#__PURE__*/react.createElement(UserAuthenticationContext.Provider, {
230251
- value: [userAuthenticationState, api]
230252
- }, children);
230253
- }
230254
- /* harmony default export */ const contextProviders_UserAuthenticationProvider = ((/* unused pure expression or super */ null && (UserAuthenticationProvider)));
230255
- const UserAuthenticationConsumer = UserAuthenticationContext.Consumer;
230256
230809
 
230257
- UserAuthenticationProvider.propTypes = {
230258
- children: (prop_types_default()).any,
230259
- service: prop_types_default().shape({
230260
- setServiceImplementation: (prop_types_default()).func
230261
- }).isRequired
230262
- };
230263
- const useUserAuthentication = () => (0,react.useContext)(UserAuthenticationContext);
230264
- ;// CONCATENATED MODULE: ../../ui-next/src/contextProviders/ImageViewerProvider.tsx
230265
230810
 
230266
- const ImageViewerContext = /*#__PURE__*/(0,react.createContext)(null);
230267
- const useImageViewer = () => (0,react.useContext)(ImageViewerContext);
230268
- function ImageViewerProvider({
230269
- StudyInstanceUIDs,
230270
- children
230271
- }) {
230272
- const value = (0,react.useMemo)(() => {
230273
- return {
230274
- StudyInstanceUIDs
230275
- };
230276
- }, [StudyInstanceUIDs]);
230277
- return /*#__PURE__*/react.createElement(ImageViewerContext.Provider, {
230278
- value: value
230279
- }, children);
230280
- }
230281
- // EXTERNAL MODULE: ../../../node_modules/react-dnd-html5-backend/dist/esm/index.js + 13 modules
230282
- var dist_esm = __webpack_require__(87654);
230283
- ;// CONCATENATED MODULE: ../../ui-next/src/contextProviders/DragAndDropProvider.tsx
230284
230811
 
230285
230812
 
230286
230813
 
230287
230814
 
230288
230815
 
230289
- // import TouchBackend from 'react-dnd-touch-backend';
230290
230816
 
230291
- // TODO: this is false when it should not be :thinking:
230292
- const isTouchDevice = typeof window !== `undefined` && !!('ontouchstart' in window || navigator.maxTouchPoints);
230293
230817
 
230294
- /**
230295
- * Relevant:
230296
- * https://github.com/react-dnd/react-dnd/issues/186#issuecomment-335429067
230297
- * https://github.com/react-dnd/react-dnd/issues/186#issuecomment-282789420
230298
- *
230299
- * Docs:
230300
- * http://react-dnd.github.io/react-dnd/docs/api/drag-drop-context
230301
- */
230302
- function DragAndDropProvider({
230303
- children
230304
- }) {
230305
- const backend = dist_esm/* HTML5Backend */.t2; // isTouchDevice ? TouchBackend : HTML5Backend;
230306
- const opts = {}; // isTouchDevice ? { enableMouseEvents: true } : {};
230307
230818
 
230308
- console.log('using... touch backend?', isTouchDevice);
230309
- return /*#__PURE__*/react.createElement(esm/* DndProvider */.QP, {
230310
- backend: backend,
230311
- opts: opts
230312
- }, children);
230313
- }
230314
- DragAndDropProvider.propTypes = {
230315
- children: (prop_types_default()).any
230316
- };
230317
- /* harmony default export */ const contextProviders_DragAndDropProvider = (DragAndDropProvider);
230318
- ;// CONCATENATED MODULE: ../../ui-next/src/contextProviders/CineProvider.tsx
230319
230819
 
230320
- const CineProvider_DEFAULT_STATE = {
230321
- isCineEnabled: false,
230322
- cines: {
230323
- /*
230324
- * viewportId: { isPlaying: false, frameRate: 24 };
230325
- */
230326
- }
230327
- };
230328
- const DEFAULT_CINE = {
230329
- isPlaying: false,
230330
- frameRate: 24
230331
- };
230332
- const CineContext = /*#__PURE__*/(0,react.createContext)(null);
230333
- function CineProvider({
230334
- children,
230335
- service
230336
- }) {
230337
- const reducer = (state, action) => {
230338
- switch (action.type) {
230339
- case 'SET_CINE':
230340
- {
230341
- const {
230342
- id,
230343
- frameRate,
230344
- isPlaying = undefined
230345
- } = action.payload;
230346
- const cines = state.cines;
230347
- const syncedCineIds = service.getSyncedViewports(id).map(({
230348
- viewportId
230349
- }) => viewportId);
230350
- const cineIdsToUpdate = [id, ...syncedCineIds].filter(curId => {
230351
- const currentCine = cines[curId] ?? {};
230352
- const shouldUpdateFrameRate = currentCine.frameRate !== (frameRate ?? currentCine.frameRate);
230353
- const shouldUpdateIsPlaying = currentCine.isPlaying !== (isPlaying ?? currentCine.isPlaying);
230354
- return shouldUpdateFrameRate || shouldUpdateIsPlaying;
230355
- });
230356
- cineIdsToUpdate.forEach(currId => {
230357
- let cine = cines[currId];
230358
- if (!cine) {
230359
- cine = {
230360
- id,
230361
- ...DEFAULT_CINE
230362
- };
230363
- cines[currId] = cine;
230364
- }
230365
- cine.frameRate = frameRate ?? cine.frameRate;
230366
- cine.isPlaying = isPlaying ?? cine.isPlaying;
230367
- });
230368
- return {
230369
- ...state,
230370
- ...cines
230371
- };
230372
- }
230373
- case 'SET_IS_CINE_ENABLED':
230374
- {
230375
- return {
230376
- ...state,
230377
- ...{
230378
- isCineEnabled: action.payload
230379
- }
230380
- };
230381
- }
230382
- default:
230383
- return action.payload;
230384
- }
230385
- };
230386
- const [state, dispatch] = (0,react.useReducer)(reducer, CineProvider_DEFAULT_STATE);
230387
- const getState = (0,react.useCallback)(() => state, [state]);
230388
- const setIsCineEnabled = (0,react.useCallback)(isCineEnabled => dispatch({
230389
- type: 'SET_IS_CINE_ENABLED',
230390
- payload: isCineEnabled
230391
- }), [dispatch]);
230392
- const setCine = (0,react.useCallback)(({
230393
- id,
230394
- frameRate,
230395
- isPlaying
230396
- }) => dispatch({
230397
- type: 'SET_CINE',
230398
- payload: {
230399
- id,
230400
- frameRate,
230401
- isPlaying
230402
- }
230403
- }), [dispatch]);
230404
230820
 
230405
- /**
230406
- * Sets the implementation of a modal service that can be used by extensions.
230407
- *
230408
- * @returns void
230409
- */
230410
- (0,react.useEffect)(() => {
230411
- if (service) {
230412
- service.setServiceImplementation({
230413
- getState,
230414
- setIsCineEnabled,
230415
- setCine
230416
- });
230417
- }
230418
- }, [getState, service, setCine, setIsCineEnabled]);
230419
- const api = {
230420
- getState,
230421
- setCine,
230422
- setIsCineEnabled: isCineEnabled => service.setIsCineEnabled(isCineEnabled),
230423
- playClip: (element, playClipOptions) => service.playClip(element, playClipOptions),
230424
- stopClip: (element, stopClipOptions) => service.stopClip(element, stopClipOptions),
230425
- setViewportCineClosed: viewportId => service.setViewportCineClosed(viewportId),
230426
- clearViewportCineClosed: viewportId => service.clearViewportCineClosed(viewportId),
230427
- isViewportCineClosed: viewportId => service.isViewportCineClosed(viewportId)
230428
- };
230429
- return /*#__PURE__*/react.createElement(CineContext.Provider, {
230430
- value: [state, api]
230431
- }, children);
230432
- }
230433
- const useCine = () => (0,react.useContext)(CineContext);
230434
- ;// CONCATENATED MODULE: ../../ui-next/src/contextProviders/index.ts
230435
230821
 
230436
230822
 
230437
230823
 
@@ -230451,6 +230837,10 @@ const useCine = () => (0,react.useContext)(CineContext);
230451
230837
 
230452
230838
 
230453
230839
 
230840
+
230841
+
230842
+
230843
+ // Segmentation Context Exports
230454
230844
 
230455
230845
 
230456
230846
  ;// CONCATENATED MODULE: ../../ui-next/src/types/Predicate.ts
@@ -427310,7 +427700,7 @@ function __rewriteRelativeImportExtension(path, preserveJsx) {
427310
427700
  /******/ // This function allow to reference async chunks
427311
427701
  /******/ __webpack_require__.u = (chunkId) => {
427312
427702
  /******/ // return url for filenames based on template
427313
- /******/ return "" + ({"572":"polySeg","2007":"interpolation","3054":"histogram-worker","3694":"compute"}[chunkId] || chunkId) + ".bundle." + {"85":"e65ed829e1a136e33576","213":"d8495e69f1d1405d0356","572":"7445d00e1e9ef623d0f1","732":"6978ac30a1e36abf06db","810":"86ba4f6f1311ccc28d41","934":"c446dfb396152899756f","963":"88152346007c0f5049a3","1459":"4b6682c8673e199edf64","1807":"e8c6890ca68e62f46990","1919":"6f7de53921f3710a1d54","1927":"83810560c4d3a90eb7cf","2007":"26c71e2b635b13e01127","2424":"ef98022039ea6e87cfd9","2701":"f1f15df81406d04851c4","2914":"a0a5ddfebfc9d429063d","2932":"038f79dbbfdd9d1f387b","3054":"b7bb02c6cd9273c422f5","3075":"0624f6bf3f676f30d1b5","3166":"40162f1d9f9f5fc16b16","3658":"04fdfe11b9d38cd5f3c6","3694":"f0c30502c027d04e94f2","3984":"592161af4b618c9dd56f","4113":"7ec6da0eb1ab98e1b791","4202":"89ae773b645db3b1c59c","4526":"fbdd617a934353019be3","4759":"d1fdc8e827d54c0f40c9","4991":"8578c7880edc0fbef374","5261":"6e1a017f8f1027557f5b","5674":"49f5a714f733cf20d560","6027":"155cbff7fa97c7ede627","6029":"43e04238ac01880fa66c","6201":"e0d8d1c967a9daed4662","6939":"45622b7920dac102b5a7","7159":"9c21bc29860ed1850c67","7197":"a9c6429f2859a8feeded","7241":"7097a0cd314605d766f5","7639":"a659acbf2ab7f3f2e8f4","8094":"5c44190a325ac23e3e5c","8185":"b2252d9ff14ce760df9c","8228":"74c8ca5e66a44db80464","8402":"edb924cd47cd168f621c","8558":"5b67110ba3e66f5525ae","8815":"c8a97b220635e9b15109","9026":"eb2ae9e2311a6a620751","9862":"87d8249a9cf1d8cf579d","9890":"37d7ed265c0454337a57","9977":"071821200c1921021d29"}[chunkId] + ".js";
427703
+ /******/ return "" + ({"572":"polySeg","2007":"interpolation","3054":"histogram-worker","3694":"compute"}[chunkId] || chunkId) + ".bundle." + {"85":"a27a1466f85e01adf8e8","213":"e861b773d4779d7d724a","572":"30f6f13491f48e597605","732":"6978ac30a1e36abf06db","810":"8b29de53f9632f0f1bf9","908":"7f901ab4610793bb5ee3","934":"441c775536d8be5029af","963":"4b88a54196fdd1976d6c","1459":"ea2023918c1ef217d23a","1807":"a04f3486b00cdcc6a305","1919":"6cb4a1f5ea770e504398","1927":"5c25b9084f704a3582d2","2007":"26c71e2b635b13e01127","2424":"425cb2260521f2a23f70","2701":"87301d8d94693b5d5fcc","2914":"adefec5b51b4955af1f9","2932":"2757ab993a28dab49d56","3054":"b7bb02c6cd9273c422f5","3075":"5d83563c3791a0d884df","3658":"a6a9c2e1b32d92e3b621","3694":"83a75c96620eedca973e","3984":"1248e382e82ee04eff72","4113":"1a3202dd6a1b2e6b9d5d","4202":"89ae773b645db3b1c59c","4526":"54c0b8f753ed5c39f6c5","4759":"d1fdc8e827d54c0f40c9","4991":"8578c7880edc0fbef374","5261":"6e1a017f8f1027557f5b","5674":"49f5a714f733cf20d560","6027":"8e1b6021f0d570eb85f5","6029":"a4206e2a2e75c7b1ad7b","6201":"b584d7554570344d9170","6939":"45622b7920dac102b5a7","7159":"9c21bc29860ed1850c67","7197":"2032eea26c084877d172","7639":"b622eafdc74d9bfc1280","8094":"5c44190a325ac23e3e5c","8185":"c7e0ab58fa8f7070de26","8228":"f520ecf3c0a8998e770a","8402":"edb924cd47cd168f621c","8558":"24bb90c2d5a0857577c5","8572":"bd98ac784dae1e224a52","8815":"096958a5ae7253911a2e","9026":"019d8b4b70096b94302e","9862":"b0ea941458506379f666","9890":"b4c265e3609512785ae8","9977":"4f44190c1a5d6a69bc00"}[chunkId] + ".js";
427314
427704
  /******/ };
427315
427705
  /******/ })();
427316
427706
  /******/
@@ -427669,7 +428059,7 @@ function __rewriteRelativeImportExtension(path, preserveJsx) {
427669
428059
  /******/ ],
427670
428060
  /******/ "7197": [
427671
428061
  /******/ 8185,
427672
- /******/ 7241,
428062
+ /******/ 8572,
427673
428063
  /******/ 4526
427674
428064
  /******/ ],
427675
428065
  /******/ "8402": [
@@ -427683,7 +428073,7 @@ function __rewriteRelativeImportExtension(path, preserveJsx) {
427683
428073
  /******/ 6029,
427684
428074
  /******/ 8185,
427685
428075
  /******/ 3984,
427686
- /******/ 7241,
428076
+ /******/ 8572,
427687
428077
  /******/ 9890
427688
428078
  /******/ ],
427689
428079
  /******/ "9890": [