larvitar 2.0.15 → 2.1.0

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.
package/dist/larvitar.js CHANGED
@@ -1690,6 +1690,7 @@ class EditMaskTool extends BaseBrushTool {
1690
1690
  // });
1691
1691
  // }
1692
1692
  }
1693
+
1693
1694
  activeCallback(element, options) {
1694
1695
  switch (options.force) {
1695
1696
  case "delete":
@@ -1970,7 +1971,7 @@ const addDefaultTools = function (toolToActivate) {
1970
1971
  });
1971
1972
 
1972
1973
  // set wheel scroll active
1973
- setToolActive("StackScrollMouseWheel", {
1974
+ setToolActive("CustomMouseWheelScroll", {
1974
1975
  loop: false,
1975
1976
  // default false
1976
1977
  allowSkipping: false,
@@ -2969,7 +2970,7 @@ class BorderMagnifyTool extends MagnifyTool {
2969
2970
  * @returns {void}
2970
2971
  */
2971
2972
  handleKeyDown(event) {
2972
- if (event.key === 'B' || event.key === 'b') {
2973
+ if (event.key === 'M' || event.key === 'm') {
2973
2974
  // Toggle the visibility of borders
2974
2975
  this.configuration.showBorders = !this.configuration.showBorders;
2975
2976
 
@@ -3939,6 +3940,7 @@ class RectangleRoiOverlayTool extends BaseAnnotationTool {
3939
3940
  // showMinMax: false,
3940
3941
  // showHounsfieldUnits: true,
3941
3942
  },
3943
+
3942
3944
  svgCursor: rectangleRoiCursor
3943
3945
  };
3944
3946
  super(props, defaultProps);
@@ -80591,8 +80593,8 @@ const updateLoadedStack = function (seriesData, allSeriesStack, customId, sliceI
80591
80593
  if (!allSeriesStack[id]) {
80592
80594
  let series = {
80593
80595
  currentImageIdIndex: 0,
80594
- imageIds: [], // (ordered)
80595
- instanceUIDs: {}, // instanceUID: imageId (ordered)
80596
+ imageIds: [],
80597
+ instanceUIDs: {},
80596
80598
  instances: {},
80597
80599
  seriesDescription: seriesDescription,
80598
80600
  larvitarSeriesInstanceUID: lid,
@@ -81301,6 +81303,7 @@ const interaction_1 = __webpack_require__(1534);
81301
81303
  const imageStore_1 = __importStar(__webpack_require__(5278));
81302
81304
  const imageColormaps_1 = __webpack_require__(4540);
81303
81305
  const imageUtils_1 = __webpack_require__(8345);
81306
+ const default_1 = __webpack_require__(6694);
81304
81307
  /*
81305
81308
  * This module provides the following functions to be exported:
81306
81309
  * clearImageCache(seriesId)
@@ -81720,6 +81723,7 @@ const renderImage = function (seriesStack, elementId, defaultProps) {
81720
81723
  }
81721
81724
  (0, exports.storeViewportData)(image, element.id, storedViewport, data);
81722
81725
  (0, imageStore_1.set)(["ready", element.id, true]);
81726
+ (0, imageStore_1.set)(["seriesUID", element.id, data.seriesUID]);
81723
81727
  const t1 = performance.now();
81724
81728
  console.log(`Call to renderImage took ${t1 - t0} milliseconds.`);
81725
81729
  const uri = cornerstone_wado_image_loader_1.default.wadouri.parseImageId(data.imageId).url;
@@ -81889,55 +81893,57 @@ const updateViewportData = function (elementId, viewportData, activeTool) {
81889
81893
  console.error("invalid html element: " + elementId);
81890
81894
  return;
81891
81895
  }
81892
- // TODO: understand how to handle synchronized tools
81893
- switch (activeTool) {
81894
- case "Wwwc":
81895
- case "Wwwl":
81896
- case "WwwcRegion":
81897
- if (viewportData.voi) {
81898
- (0, imageStore_1.set)([
81899
- "contrast",
81900
- elementId,
81901
- viewportData.voi.windowWidth,
81902
- viewportData.voi.windowCenter
81903
- ]);
81904
- }
81905
- break;
81906
- case "Pan":
81907
- if (viewportData.translation) {
81908
- (0, imageStore_1.set)([
81909
- "translation",
81910
- elementId,
81911
- viewportData.translation.x,
81912
- viewportData.translation.y
81913
- ]);
81914
- }
81915
- break;
81916
- case "Zoom":
81917
- if (viewportData.scale) {
81918
- (0, imageStore_1.set)(["scale", elementId, viewportData.scale]);
81919
- }
81920
- break;
81921
- case "Rotate":
81922
- if (viewportData.rotation) {
81923
- (0, imageStore_1.set)(["rotation", elementId, viewportData.rotation]);
81924
- }
81925
- break;
81926
- case "mouseWheel":
81927
- case "stackscroll":
81928
- const viewport = imageStore_1.default.get(["viewports", elementId]);
81929
- const isTimeserie = viewport.isTimeserie;
81930
- if (isTimeserie) {
81931
- const index = viewportData.newImageIdIndex;
81932
- const timeId = viewport.timeIds[index];
81933
- const timestamp = viewport.timestamps[index];
81934
- (0, imageStore_1.set)(["timeId", elementId, timeId]);
81935
- (0, imageStore_1.set)(["timestamp", elementId, timestamp]);
81936
- }
81937
- break;
81938
- default:
81939
- console.warn("unknown tool: " + activeTool);
81940
- break;
81896
+ const toolsNames = Object.keys(default_1.DEFAULT_TOOLS);
81897
+ const isValidTool = toolsNames.includes(activeTool);
81898
+ if (isValidTool === true) {
81899
+ switch (activeTool) {
81900
+ case "WwwcRegion":
81901
+ if (viewportData.voi) {
81902
+ (0, imageStore_1.set)([
81903
+ "contrast",
81904
+ elementId,
81905
+ viewportData.voi.windowWidth,
81906
+ viewportData.voi.windowCenter
81907
+ ]);
81908
+ }
81909
+ break;
81910
+ case "Pan":
81911
+ if (viewportData.translation) {
81912
+ (0, imageStore_1.set)([
81913
+ "translation",
81914
+ elementId,
81915
+ viewportData.translation.x,
81916
+ viewportData.translation.y
81917
+ ]);
81918
+ }
81919
+ break;
81920
+ case "Zoom":
81921
+ if (viewportData.scale) {
81922
+ (0, imageStore_1.set)(["scale", elementId, viewportData.scale]);
81923
+ }
81924
+ break;
81925
+ case "Rotate":
81926
+ if (viewportData.rotation) {
81927
+ (0, imageStore_1.set)(["rotation", elementId, viewportData.rotation]);
81928
+ }
81929
+ break;
81930
+ case "CustomMouseWheelScroll":
81931
+ const viewport = imageStore_1.default.get(["viewports", elementId]);
81932
+ const isTimeserie = viewport.isTimeserie;
81933
+ if (isTimeserie) {
81934
+ const index = viewportData.newImageIdIndex;
81935
+ const timeId = viewport.timeIds[index];
81936
+ const timestamp = viewport.timestamps[index];
81937
+ (0, imageStore_1.set)(["timeId", elementId, timeId]);
81938
+ (0, imageStore_1.set)(["timestamp", elementId, timestamp]);
81939
+ }
81940
+ break;
81941
+ default:
81942
+ break;
81943
+ }
81944
+ }
81945
+ else {
81946
+ console.warn("unknown tool: " + activeTool);
81941
81947
  }
81942
81948
  };
81943
81949
  exports.updateViewportData = updateViewportData;
@@ -81970,6 +81976,11 @@ const storeViewportData = function (image, elementId, viewport, data) {
81970
81976
  (0, imageStore_1.set)(["maxSliceId", elementId, data.numberOfSlices - 1]);
81971
81977
  }
81972
81978
  if (data.isTimeserie) {
81979
+ (0, imageStore_1.set)([
81980
+ "numberOfTemporalPositions",
81981
+ elementId,
81982
+ data.numberOfTemporalPositions
81983
+ ]);
81973
81984
  (0, imageStore_1.set)(["minTimeId", elementId, 0]);
81974
81985
  (0, imageStore_1.set)(["timeId", elementId, data.timeIndex || 0]);
81975
81986
  if (data.numberOfSlices && data.numberOfTemporalPositions) {
@@ -82016,6 +82027,9 @@ const storeViewportData = function (image, elementId, viewport, data) {
82016
82027
  ]);
82017
82028
  (0, imageStore_1.set)(["isColor", elementId, data.isColor]);
82018
82029
  (0, imageStore_1.set)(["isMultiframe", elementId, data.isMultiframe]);
82030
+ if (data.isMultiframe) {
82031
+ (0, imageStore_1.set)(["numberOfFrames", elementId, data.numberOfFrames]);
82032
+ }
82019
82033
  (0, imageStore_1.set)(["isTimeserie", elementId, data.isTimeserie]);
82020
82034
  (0, imageStore_1.set)(["isPDF", elementId, false]);
82021
82035
  (0, imageStore_1.set)(["waveform", elementId, data.waveform]);
@@ -82142,12 +82156,14 @@ exports.rotateImageRight = rotateImageRight;
82142
82156
  */
82143
82157
  const getSeriesData = function (series, defaultProps) {
82144
82158
  const data = {};
82159
+ data.seriesUID = series.larvitarSeriesInstanceUID || series.seriesUID; //case of resliced series
82145
82160
  if (series.isMultiframe) {
82146
82161
  data.isMultiframe = true;
82147
82162
  data.numberOfSlices = series.imageIds.length;
82148
82163
  data.imageIndex = 0;
82149
82164
  data.imageId = series.imageIds[data.imageIndex];
82150
82165
  data.isTimeserie = false;
82166
+ data.numberOfFrames = series.numberOfFrames;
82151
82167
  }
82152
82168
  else if (series.is4D) {
82153
82169
  data.isMultiframe = false;
@@ -82333,8 +82349,8 @@ const INITIAL_STORE_DATA = {
82333
82349
  };
82334
82350
  // default viewport object
82335
82351
  const DEFAULT_VIEWPORT = {
82336
- loading: 0, // from 0 to 100 (%)
82337
- ready: false, // true when currentImageId is rendered
82352
+ loading: 0,
82353
+ ready: false,
82338
82354
  minSliceId: 0,
82339
82355
  maxSliceId: 0,
82340
82356
  sliceId: 0,
@@ -82420,6 +82436,13 @@ const setValue = (store, data) => {
82420
82436
  store.series[k][field] = v[0];
82421
82437
  triggerSeriesListener(k);
82422
82438
  break;
82439
+ case "seriesUID":
82440
+ if (!viewport) {
82441
+ return;
82442
+ }
82443
+ viewport[field] = v[0];
82444
+ triggerViewportListener(k);
82445
+ break;
82423
82446
  case "isColor":
82424
82447
  case "isMultiframe":
82425
82448
  case "isPDF":
@@ -82443,6 +82466,8 @@ const setValue = (store, data) => {
82443
82466
  case "pendingSliceId":
82444
82467
  case "timeId":
82445
82468
  case "timestamp":
82469
+ case "numberOfFrames":
82470
+ case "numberOfTemporalPositions":
82446
82471
  if (!viewport) {
82447
82472
  return;
82448
82473
  }
@@ -83563,8 +83588,8 @@ const getReslicedMetadata = function (reslicedSeriesId, fromOrientation, toOrien
83563
83588
  x00280100: sampleMetadata.x00280100,
83564
83589
  x00280103: sampleMetadata.x00280103,
83565
83590
  // resliced series sizes
83566
- x00280010: toSize[1], // rows
83567
- x00280011: toSize[0], // cols
83591
+ x00280010: toSize[1],
83592
+ x00280011: toSize[0],
83568
83593
  // resliced series spacing
83569
83594
  x00280030: [toSpacing[1], toSpacing[0]],
83570
83595
  x00180050: [toSpacing[2]],
@@ -83650,8 +83675,8 @@ const getCmprMetadata = function (reslicedSeriesId, imageLoaderName, header // T
83650
83675
  // Bits Allocated
83651
83676
  x00280103: header.repr,
83652
83677
  // resliced series sizes
83653
- x00280010: header.rows, // rows
83654
- x00280011: header.cols, // cols
83678
+ x00280010: header.rows,
83679
+ x00280011: header.cols,
83655
83680
  // resliced series spacing
83656
83681
  x00280030: [header.spacing[1], header.spacing[0]],
83657
83682
  x00180050: [header.distance_btw_slices],
@@ -83681,8 +83706,8 @@ const getCmprMetadata = function (reslicedSeriesId, imageLoaderName, header // T
83681
83706
  // x00020010: sampleMetadata.x00020010,
83682
83707
  // x00200052: sampleMetadata.x00200052,
83683
83708
  // data needed to obtain a good rendering
83684
- x00281050: [header.wwwl[1] / 2], // [wl]
83685
- x00281051: [header.wwwl[0]], // [ww]
83709
+ x00281050: [header.wwwl[1] / 2],
83710
+ x00281051: [header.wwwl[0]],
83686
83711
  x00281052: header.intercept,
83687
83712
  x00281053: header.slope,
83688
83713
  // new image orientation (IOP)
@@ -84388,7 +84413,7 @@ const getImageFrame = function (metadata, dataSet) {
84388
84413
  rows: imagePixelModule.rows,
84389
84414
  columns: imagePixelModule.columns,
84390
84415
  bitsAllocated: imagePixelModule.bitsAllocated,
84391
- pixelRepresentation: imagePixelModule.pixelRepresentation, // 0 = unsigned,
84416
+ pixelRepresentation: imagePixelModule.pixelRepresentation,
84392
84417
  smallestPixelValue: imagePixelModule.smallestPixelValue,
84393
84418
  largestPixelValue: imagePixelModule.largestPixelValue,
84394
84419
  redPaletteColorLookupTableDescriptor: imagePixelModule.redPaletteColorLookupTableDescriptor,
@@ -84397,7 +84422,7 @@ const getImageFrame = function (metadata, dataSet) {
84397
84422
  redPaletteColorLookupTableData: imagePixelModule.redPaletteColorLookupTableData,
84398
84423
  greenPaletteColorLookupTableData: imagePixelModule.greenPaletteColorLookupTableData,
84399
84424
  bluePaletteColorLookupTableData: imagePixelModule.bluePaletteColorLookupTableData,
84400
- pixelData: undefined, // populated later after decoding,
84425
+ pixelData: undefined,
84401
84426
  ImageData: undefined
84402
84427
  };
84403
84428
  };
@@ -84827,7 +84852,7 @@ let createCustomImage = function (id, imageId, frameIndex, metadata) {
84827
84852
  color: cornerstone_wado_image_loader_1.default.isColorImage(imageFrame.photometricInterpretation),
84828
84853
  columnPixelSpacing: pixelSpacing[1]
84829
84854
  ? pixelSpacing[1]
84830
- : pixelSpacing, // check for specific spacing value
84855
+ : pixelSpacing,
84831
84856
  columns: imageFrame.columns,
84832
84857
  data: dataSet ? dataSet : undefined,
84833
84858
  height: imageFrame.rows,
@@ -84838,17 +84863,17 @@ let createCustomImage = function (id, imageId, frameIndex, metadata) {
84838
84863
  invert: imageFrame.photometricInterpretation === "MONOCHROME1",
84839
84864
  minPixelValue: imageFrame.smallestPixelValue,
84840
84865
  maxPixelValue: imageFrame.largestPixelValue,
84841
- render: undefined, // set below
84866
+ render: undefined,
84842
84867
  rowPixelSpacing: pixelSpacing[0]
84843
84868
  ? pixelSpacing[0]
84844
- : pixelSpacing, // check for specific spacing value
84869
+ : pixelSpacing,
84845
84870
  rows: imageFrame.rows,
84846
84871
  sizeInBytes: getSizeInBytes(),
84847
84872
  slope: rescaleSlope ? rescaleSlope : 1,
84848
84873
  width: imageFrame.columns,
84849
84874
  windowCenter: windowCenter,
84850
84875
  windowWidth: windowWidth,
84851
- decodeTimeInMS: undefined, // TODO
84876
+ decodeTimeInMS: undefined,
84852
84877
  loadTimeInMS: undefined // TODO
84853
84878
  };
84854
84879
  // add function to return pixel data
@@ -85054,11 +85079,11 @@ const buildNrrdImage = function (volume, seriesId, custom_header) {
85054
85079
  let intercept = header.volume.intercept;
85055
85080
  let slope = header.volume.slope;
85056
85081
  let metadata = {
85057
- x00280010: rows, // Rows
85058
- x00280011: cols, // Columns
85059
- x00200037: iop, // ImageOrientationPatient
85060
- x00280030: ps, // PixelSpacing
85061
- x00180050: [thickness][0], // SliceThickness
85082
+ x00280010: rows,
85083
+ x00280011: cols,
85084
+ x00200037: iop,
85085
+ x00280030: ps,
85086
+ x00180050: [thickness][0],
85062
85087
  x00281052: intercept ? [intercept] : [0],
85063
85088
  x00281053: slope ? [slope] : [1],
85064
85089
  x00200052: header.volume.imageIds
@@ -85303,7 +85328,7 @@ let createCustomImage = function (imageId, metadata, pixelData, dataSet) {
85303
85328
  invert: imageFrame.photometricInterpretation === "MONOCHROME1",
85304
85329
  minPixelValue: imageFrame.smallestPixelValue,
85305
85330
  maxPixelValue: imageFrame.largestPixelValue,
85306
- render: undefined, // set below
85331
+ render: undefined,
85307
85332
  rowPixelSpacing: pixelSpacing ? pixelSpacing[0] : undefined,
85308
85333
  rows: imageFrame.rows,
85309
85334
  sizeInBytes: getSizeInBytes(),
@@ -85484,7 +85509,7 @@ let createCustomImage = function (imageId, metadata, pixelData, dataSet // depre
85484
85509
  invert: imageFrame.photometricInterpretation === "MONOCHROME1",
85485
85510
  minPixelValue: imageFrame.smallestPixelValue,
85486
85511
  maxPixelValue: imageFrame.largestPixelValue,
85487
- render: undefined, // set below
85512
+ render: undefined,
85488
85513
  rowPixelSpacing: pixelSpacing ? pixelSpacing[0] : undefined,
85489
85514
  rows: imageFrame.rows,
85490
85515
  sizeInBytes: getSizeInBytes(),
@@ -85817,6 +85842,243 @@ function parseECG(seriesId, dataSet, tag, nSampling = 2) {
85817
85842
  exports.parseECG = parseECG;
85818
85843
 
85819
85844
 
85845
+ /***/ }),
85846
+
85847
+ /***/ 4585:
85848
+ /***/ (function(__unused_webpack_module, exports, __webpack_require__) {
85849
+
85850
+ "use strict";
85851
+
85852
+ /** @module tools/custom/customMouseWheelScrollTool
85853
+ * @desc This file provides functionalities for
85854
+ * custom DICOM Loader
85855
+ */
85856
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
85857
+ if (k2 === undefined) k2 = k;
85858
+ var desc = Object.getOwnPropertyDescriptor(m, k);
85859
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
85860
+ desc = { enumerable: true, get: function() { return m[k]; } };
85861
+ }
85862
+ Object.defineProperty(o, k2, desc);
85863
+ }) : (function(o, m, k, k2) {
85864
+ if (k2 === undefined) k2 = k;
85865
+ o[k2] = m[k];
85866
+ }));
85867
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
85868
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
85869
+ }) : function(o, v) {
85870
+ o["default"] = v;
85871
+ });
85872
+ var __importStar = (this && this.__importStar) || function (mod) {
85873
+ if (mod && mod.__esModule) return mod;
85874
+ var result = {};
85875
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
85876
+ __setModuleDefault(result, mod);
85877
+ return result;
85878
+ };
85879
+ var __importDefault = (this && this.__importDefault) || function (mod) {
85880
+ return (mod && mod.__esModule) ? mod : { "default": mod };
85881
+ };
85882
+ Object.defineProperty(exports, "__esModule", ({ value: true }));
85883
+ const cornerstone_tools_1 = __importDefault(__webpack_require__(4030));
85884
+ const BaseTool = cornerstone_tools_1.default.importInternal("base/BaseTool");
85885
+ const scrollToIndex = cornerstone_tools_1.default.importInternal("util/scrollToIndex");
85886
+ const getToolState = cornerstone_tools_1.default.getToolState;
85887
+ // internal libraries
85888
+ const imageStore_1 = __importStar(__webpack_require__(5278));
85889
+ const default_1 = __webpack_require__(6694);
85890
+ /*
85891
+ * @class CustomMouseWheelScrollTool
85892
+ * @extends BaseTool
85893
+ * @memberof Tools
85894
+ *
85895
+ * @classdesc Tool for scrolling through images using the mouse wheel
85896
+ * @private
85897
+ */
85898
+ class CustomMouseWheelScrollTool extends BaseTool {
85899
+ /*
85900
+ * @constructs CustomMouseWheelScrollTool
85901
+ * @param {object} props - Any properties passed to the component
85902
+ */
85903
+ constructor(props = {}) {
85904
+ const defaultProps = {
85905
+ name: "CustomMouseWheelScroll",
85906
+ supportedInteractionTypes: ["MouseWheel"],
85907
+ configuration: {
85908
+ loop: false,
85909
+ allowSkipping: true,
85910
+ invert: false,
85911
+ fixedFrame: 1,
85912
+ fixedSlice: 0,
85913
+ currentMode: "stack",
85914
+ framesNumber: 1
85915
+ }
85916
+ };
85917
+ super(props, defaultProps);
85918
+ this.currentMode = "stack";
85919
+ this.framesNumber = this.configuration.framesNumber;
85920
+ this.slicesnumber = 0;
85921
+ this.is4D = false;
85922
+ this.isMultiframe = false;
85923
+ this.animation = false;
85924
+ this.animationId = null;
85925
+ }
85926
+ /*
85927
+ * @verify4D
85928
+ * @desc Verify if the image is 4D or not
85929
+ */
85930
+ verify4D() {
85931
+ const viewport = imageStore_1.default.get(["viewports", this.element.id]);
85932
+ // check is4D and multiframe
85933
+ this.is4D = viewport.isTimeserie;
85934
+ this.isMultiframe = viewport.isMultiframe;
85935
+ // extract frames number
85936
+ if (this.is4D === true) {
85937
+ this.configuration.framesNumber = viewport.numberOfTemporalPositions;
85938
+ }
85939
+ else if (this.isMultiframe === true) {
85940
+ this.configuration.framesNumber = viewport.numberOfFrames;
85941
+ this.currentMode = "slice";
85942
+ this.configuration.currentMode = "slice";
85943
+ }
85944
+ else {
85945
+ this.configuration.framesNumber = 1;
85946
+ }
85947
+ this.framesNumber = this.configuration.framesNumber;
85948
+ }
85949
+ handleToggle(newcurrentMode) {
85950
+ // Toggle mode between 'stack' and 'slice' on Tab key press or other events
85951
+ this.verify4D();
85952
+ if (this.is4D === false) {
85953
+ this.currentMode = this.isMultiframe ? "slice" : "stack";
85954
+ this.configuration.currentMode = this.isMultiframe ? "slice" : "stack";
85955
+ }
85956
+ else if (this.is4D === true) {
85957
+ if (this.currentMode != newcurrentMode) {
85958
+ this.toggleScrollMode(this.element);
85959
+ }
85960
+ }
85961
+ }
85962
+ /*
85963
+ * @method toggleScrollMode
85964
+ * @param {element} HTMLElement
85965
+ * @desc Handle the toggle between 'stack' and 'slice' modes
85966
+ * we enter in this function only if this.is4d===true so this.framesNumber!=0
85967
+ */
85968
+ toggleScrollMode(element) {
85969
+ if (!element) {
85970
+ console.error("Element is undefined");
85971
+ return;
85972
+ }
85973
+ const toolData = getToolState(element, "stack");
85974
+ if (!toolData || !toolData.data || !toolData.data.length) {
85975
+ console.error("No Tool Data");
85976
+ return;
85977
+ }
85978
+ const stackData = toolData.data[0];
85979
+ const currentIndex = stackData.currentImageIdIndex;
85980
+ switch (this.currentMode) {
85981
+ case "stack":
85982
+ // Switching from 'stack' to 'slice'
85983
+ this.configuration.fixedSlice = Math.floor((currentIndex + 1) / this.framesNumber); // slice = 0,1,2,3 and so on
85984
+ this.configuration.currentMode = "slice";
85985
+ this.currentMode = "slice";
85986
+ break;
85987
+ case "slice":
85988
+ // Switching from 'slice' to 'stack'
85989
+ this.configuration.fixedFrame =
85990
+ currentIndex + 1 - this.configuration.fixedSlice * this.framesNumber; // frame is related to the current slice
85991
+ this.configuration.currentMode = "stack";
85992
+ this.currentMode = "stack";
85993
+ break;
85994
+ default:
85995
+ break;
85996
+ }
85997
+ }
85998
+ mouseWheelCallback(evt) {
85999
+ const { direction: invert, element } = evt.detail;
86000
+ this.handleToggle(default_1.DEFAULT_TOOLS["CustomMouseWheelScroll"].currentMode);
86001
+ // configure scroll direction
86002
+ const direction = invert *
86003
+ (this.configuration.currentMode === "stack"
86004
+ ? this.configuration.framesNumber
86005
+ : 1);
86006
+ const toolData = getToolState(element, "stack");
86007
+ if (!toolData || !toolData.data || !toolData.data.length) {
86008
+ return;
86009
+ }
86010
+ const stackData = toolData.data[0];
86011
+ if (this.configuration.currentMode === "stack") {
86012
+ // Handle 'stack' mode
86013
+ // Calculate validIndex for 'stack' mode (no looping) between 0 and (N-1)*framesnumber where N=numberofslices=numberofimageids/numberofframes
86014
+ let lastIndex = imageStore_1.default.get(["viewports", element.id, "sliceId"]);
86015
+ let nextIndex = lastIndex + direction;
86016
+ if (lastIndex === -1) {
86017
+ nextIndex = 0 + direction;
86018
+ lastIndex = 0;
86019
+ }
86020
+ this.slicesnumber =
86021
+ Math.ceil(stackData.imageIds.length / this.framesNumber) - 1;
86022
+ // Ensure nextIndex is between 0 and upperBound
86023
+ const validIndex = nextIndex >= 0 &&
86024
+ nextIndex < stackData.imageIds.length - 1 &&
86025
+ this.slicesnumber > 0
86026
+ ? nextIndex
86027
+ : lastIndex;
86028
+ // Scroll to the calculated index
86029
+ scrollToIndex(element, validIndex);
86030
+ }
86031
+ else {
86032
+ // Handle 'slice' mode
86033
+ let lastIndex = this.isMultiframe === true || this.is4D === true
86034
+ ? imageStore_1.default.get(["viewports", element.id, "sliceId"])
86035
+ : stackData.currentImageIdIndex;
86036
+ this.slicesnumber =
86037
+ Math.ceil(stackData.imageIds.length / this.framesNumber) - 1;
86038
+ const startFrame = this.configuration.fixedSlice * this.configuration.framesNumber;
86039
+ const endFrame = (this.configuration.fixedSlice + 1) * this.configuration.framesNumber -
86040
+ 1;
86041
+ // Calculate the potential new index without considering looping
86042
+ let nextIndex = lastIndex + direction;
86043
+ // Check if the new index is within the valid range for the current slice
86044
+ if (nextIndex < startFrame ||
86045
+ nextIndex > endFrame ||
86046
+ nextIndex >= stackData.imageIds.length) {
86047
+ nextIndex = startFrame;
86048
+ }
86049
+ // Scroll to the calculated index
86050
+ scrollToIndex(element, nextIndex);
86051
+ if (this.is4D) {
86052
+ const viewport = imageStore_1.default.get(["viewports", element.id]);
86053
+ const timeId = viewport.timeIds[nextIndex];
86054
+ const timestamp = viewport.timestamps[nextIndex];
86055
+ (0, imageStore_1.set)(["timeId", element.id, timeId]);
86056
+ (0, imageStore_1.set)(["timestamp", element.id, timestamp]);
86057
+ }
86058
+ }
86059
+ }
86060
+ /*
86061
+ * @method scrollWithoutSkipping
86062
+ * @param {stackData} stackData
86063
+ * @param {pendingEvent} pendingEvent
86064
+ * @param {element} element
86065
+ * @desc Handles the event of the mouse wheel
86066
+ */
86067
+ scrollWithoutSkipping(stackData, pendingEvent, element) {
86068
+ const newImageHandler = (event) => {
86069
+ const index = stackData.imageIds.indexOf(event.detail.image.imageId);
86070
+ if (index === pendingEvent.index) {
86071
+ stackData.pending = [];
86072
+ element.removeEventListener("cornerstoneimagerendered", newImageHandler);
86073
+ }
86074
+ };
86075
+ element.addEventListener("cornerstoneimagerendered", newImageHandler);
86076
+ scrollToIndex(element, pendingEvent.index);
86077
+ }
86078
+ }
86079
+ exports["default"] = CustomMouseWheelScrollTool;
86080
+
86081
+
85820
86082
  /***/ }),
85821
86083
 
85822
86084
  /***/ 8737:
@@ -86060,6 +86322,7 @@ const polylineScissorsTool_1 = __importDefault(__webpack_require__(8990));
86060
86322
  const rectangleRoiOverlayTool_1 = __importDefault(__webpack_require__(1828));
86061
86323
  const ellipticalRoiOverlayTool_1 = __importDefault(__webpack_require__(3211));
86062
86324
  const BorderMagnifyTool_1 = __importDefault(__webpack_require__(7819));
86325
+ const customMouseWheelScrollTool_1 = __importDefault(__webpack_require__(4585));
86063
86326
  /**
86064
86327
  * These tools are added with `addDefaultTools()`
86065
86328
  */
@@ -86127,48 +86390,28 @@ const DEFAULT_TOOLS = {
86127
86390
  shortcut: "ctrl-m",
86128
86391
  type: "utils"
86129
86392
  },
86130
- StackScroll: {
86131
- name: "StackScroll",
86393
+ CustomMouseWheelScroll: {
86394
+ name: "CustomMouseWheelScroll",
86132
86395
  viewports: "all",
86133
86396
  configuration: {
86134
- loop: false, // default false
86135
- allowSkipping: true // default true
86397
+ loop: false,
86398
+ allowSkipping: true,
86399
+ invert: false,
86400
+ fixedFrame: 1,
86401
+ fixedSlice: 0,
86402
+ currentMode: "stack",
86403
+ framesNumber: 1
86136
86404
  },
86137
86405
  options: {
86138
- mouseButtonMask: 1,
86139
- deltaY: 0 // default 0
86140
- },
86141
- cleanable: false,
86142
- defaultActive: false,
86143
- class: "StackScrollTool"
86144
- },
86145
- StackScrollMouseWheel: {
86146
- name: "StackScrollMouseWheel",
86147
- viewports: "all",
86148
- configuration: {
86149
- loop: false, // default false
86150
- allowSkipping: true, // default true
86151
- invert: false
86406
+ mouseButtonMask: 0
86152
86407
  },
86153
- options: {},
86154
86408
  cleanable: false,
86155
86409
  defaultActive: true,
86156
- class: "StackScrollMouseWheelTool"
86410
+ class: "CustomMouseWheelScrollTool",
86411
+ description: "scroll images/frames",
86412
+ shortcut: "mouse wheel",
86413
+ type: "utils"
86157
86414
  },
86158
- // Slice4DScrollMouseWheel: {
86159
- // name: "Slice4DScrollMouseWheel",
86160
- // viewports: "all",
86161
- // configuration: {
86162
- // loop: false, // default false
86163
- // allowSkipping: false, // default true
86164
- // invert: false,
86165
- // framesNumber: 1
86166
- // },
86167
- // options: {},
86168
- // cleanable: false,
86169
- // defaultActive: true,
86170
- // class: "Slice4DScrollMouseWheelTool"
86171
- // },
86172
86415
  Pan: {
86173
86416
  name: "Pan",
86174
86417
  viewports: "all",
@@ -86178,6 +86421,7 @@ const DEFAULT_TOOLS = {
86178
86421
  supportedInteractionTypes: ["Mouse", "Touch"]
86179
86422
  },
86180
86423
  cleanable: false,
86424
+ defaultActive: false,
86181
86425
  class: "PanTool",
86182
86426
  description: "Move image xy",
86183
86427
  shortcut: "ctrl-p",
@@ -86193,13 +86437,13 @@ const DEFAULT_TOOLS = {
86193
86437
  maxScale: 25.0
86194
86438
  },
86195
86439
  options: {
86196
- mouseButtonMask: 1,
86440
+ mouseButtonMask: 2,
86197
86441
  supportedInteractionTypes: ["Mouse", "Touch"],
86198
86442
  defaultStrategy: "default" // can be 'default', 'translate' or 'zoomToCenter'
86199
86443
  },
86200
86444
  cleanable: false,
86201
86445
  class: "ZoomTool",
86202
- defaultActive: false,
86446
+ defaultActive: true,
86203
86447
  description: "Zoom image at mouse position",
86204
86448
  shortcut: "ctrl-z",
86205
86449
  type: "utils"
@@ -86381,7 +86625,7 @@ const DEFAULT_TOOLS = {
86381
86625
  },
86382
86626
  cleanable: false,
86383
86627
  class: "ZoomTouchPinchTool",
86384
- defaultActive: true
86628
+ defaultActive: false
86385
86629
  },
86386
86630
  PanMultiTouch: {
86387
86631
  name: "PanMultiTouch",
@@ -86395,7 +86639,7 @@ const DEFAULT_TOOLS = {
86395
86639
  },
86396
86640
  cleanable: false,
86397
86641
  class: "PanMultiTouchTool",
86398
- defaultActive: true
86642
+ defaultActive: false
86399
86643
  },
86400
86644
  Brush: {
86401
86645
  name: "Brush",
@@ -86485,7 +86729,8 @@ const dvTools = {
86485
86729
  // Slice4DScrollMouseWheelTool: Slice4DScrollMouseWheelTool,
86486
86730
  RectangleRoiOverlayTool: rectangleRoiOverlayTool_1.default,
86487
86731
  EllipticalRoiOverlayTool: ellipticalRoiOverlayTool_1.default,
86488
- BorderMagnifyTool: BorderMagnifyTool_1.default
86732
+ BorderMagnifyTool: BorderMagnifyTool_1.default,
86733
+ CustomMouseWheelScrollTool: customMouseWheelScrollTool_1.default
86489
86734
  };
86490
86735
  exports.dvTools = dvTools;
86491
86736
  /**
@@ -86521,7 +86766,7 @@ exports.DEFAULT_SETTINGS = DEFAULT_SETTINGS;
86521
86766
  * Shortcut and mouse bindings defaults
86522
86767
  */
86523
86768
  const DEFAULT_MOUSE_KEYS = {
86524
- debug: true, // log changes
86769
+ debug: true,
86525
86770
  mouse_button_left: {
86526
86771
  shift: "Zoom",
86527
86772
  ctrl: "Pan",
@@ -86801,7 +87046,7 @@ const toggleMouseToolsListeners = function (elementId, disable) {
86801
87046
  // TODO-ts fix type (should be a cornerstoneTools event type)
86802
87047
  // @mronzoni does cornerstoneTools have a type for this event?
86803
87048
  (0, imageStore_1.set)(["sliceId", evt.target.id, evt.detail.newImageIdIndex]);
86804
- (0, imageRendering_1.updateViewportData)(evt.srcElement.id, evt.detail, "mouseWheel");
87049
+ (0, imageRendering_1.updateViewportData)(evt.srcElement.id, evt.detail, "CustomMouseWheelScroll");
86805
87050
  }
86806
87051
  if (disable) {
86807
87052
  element.removeEventListener("cornerstonetoolsmousedrag", mouseMoveHandler);
@@ -87229,7 +87474,7 @@ function tryUpdateImage(element) {
87229
87474
  * @param {Boolean} doNotSetInStore - Flag to avoid setting in store (useful on tools initialization eg in addDefaultTools). NOTE: This is just a hack, we must rework tools/ui sync.
87230
87475
  */
87231
87476
  const setToolActive = function (toolName, options, viewports, doNotSetInStore) {
87232
- var _a;
87477
+ var _a, _b;
87233
87478
  let defaultOpt = Object.assign({}, (_a = default_1.DEFAULT_TOOLS[toolName]) === null || _a === void 0 ? void 0 : _a.options); // deep copy obj because otherwise cornerstone tools will modify it
87234
87479
  (0, lodash_1.extend)(defaultOpt, options);
87235
87480
  if (viewports && viewports.length > 0) {
@@ -87254,6 +87499,9 @@ const setToolActive = function (toolName, options, viewports, doNotSetInStore) {
87254
87499
  // mouseButtonMask is now an array, thanks to cs tools "setToolActiveForElement",
87255
87500
  // but only if it has a rendered image in the viewport (!)
87256
87501
  // so we must check the type anyway for type coherence
87502
+ if (((_b = default_1.DEFAULT_TOOLS[toolName]) === null || _b === void 0 ? void 0 : _b.defaultActive) === true) {
87503
+ doNotSetInStore = false;
87504
+ }
87257
87505
  if (!doNotSetInStore && defaultOpt.mouseButtonMask) {
87258
87506
  if (typeof defaultOpt.mouseButtonMask == "number") {
87259
87507
  defaultOpt.mouseButtonMask = [defaultOpt.mouseButtonMask];
@@ -88981,7 +89229,7 @@ module.exports = JSON.parse('{"x00000000":{"tag":"x00000000","vr":"UL","vm":"1",
88981
89229
  /***/ ((module) => {
88982
89230
 
88983
89231
  "use strict";
88984
- module.exports = JSON.parse('{"name":"larvitar","keywords":["DICOM","imaging","medical","cornerstone"],"version":"2.0.15","description":"typescript library for parsing, loading, rendering and interacting with DICOM images","repository":{"url":"https://github.com/dvisionlab/Larvitar.git","type":"git"},"main":"dist/larvitar.js","types":"dist/index.d.ts","files":["dist","imaging/**/*.d.ts"],"scripts":{"coverage":"typescript-coverage-report","generate-docs":"node_modules/.bin/jsdoc -c jsdoc.json","build":"webpack --config ./bundler/webpack.prod.js && cp ./dist/larvitar.js ./docs/examples/larvitar.js","dev":"webpack --progress --config ./bundler/webpack.dev.js && cp ./dist/larvitar.js ./docs/examples/larvitar.js","dev-wip":"webpack serve --config ./bundler/webpack.dev-wip.js"},"author":"Simone Manini <simone.manini@dvisionlab.com> (https://www.dvisionlab.com)","contributors":["Mattia Ronzoni <mattia.ronzoni@dvisionlab.com> (https://www.dvisionlab.com)","Sara Zanchi <sara.zanchi@dvisionlab.com> (https://www.dvisionlab.com)","Ale Re <ale.re@dvisionlab.com> (https://www.dvisionlab.com)","Laura Borghesi Re <laura.borghesi@dvisionlab.com> (https://www.dvisionlab.com)"],"license":"MIT","dependencies":{"@rollup/plugin-commonjs":"^17.1.0","cornerstone-core":"^2.6.1","cornerstone-file-image-loader":"^0.3.0","cornerstone-tools":"^6.0.7","cornerstone-wado-image-loader":"^4.13.2","cornerstone-web-image-loader":"^2.1.1","crypto-js":"^4.1.1","dicom-character-set":"^1.0.3","dicom-parser":"^1.8.13","docdash":"^1.2.0","hammerjs":"^2.0.8","jpeg-lossless-decoder-js":"^2.0.7","keycode-js":"^3.1.0","lodash":"^4.17.15","pako":"^1.0.10","papaparse":"^5.3.0","plotly.js-dist-min":"^2.27.1","uuid":"^8.3.2"},"devDependencies":{"@babel/core":"^7.21.8","@types/cornerstone-core":"^2.3.0","@types/crypto-js":"^4.1.1","@types/hammerjs":"^2.0.41","@types/lodash":"^4.14.192","@types/papaparse":"^5.3.7","@types/plotly.js":"^2.12.30","@types/plotly.js-dist-min":"^2.3.4","@types/uuid":"^9.0.1","babel-loader":"^9.1.2","clean-webpack-plugin":"^4.0.0","copy-webpack-plugin":"^11.0.0","fs":"^0.0.1-security","html-loader":"^4.2.0","html-webpack-plugin":"^5.5.0","ip":"^1.1.8","jsdoc":"^3.6.4","portfinder-sync":"^0.0.2","ts-loader":"^9.4.2","typescript":"^5.0.2","typescript-coverage-report":"^0.7.0","webpack":"^5.76.3","webpack-bundle-analyzer":"^4.8.0","webpack-cli":"^5.0.1","webpack-dev-server":"^4.13.1"}}');
89232
+ module.exports = JSON.parse('{"name":"larvitar","keywords":["DICOM","imaging","medical","cornerstone"],"version":"2.1.0","description":"typescript library for parsing, loading, rendering and interacting with DICOM images","repository":{"url":"https://github.com/dvisionlab/Larvitar.git","type":"git"},"main":"dist/larvitar.js","types":"dist/index.d.ts","files":["dist","imaging/**/*.d.ts"],"scripts":{"coverage":"typescript-coverage-report","generate-docs":"node_modules/.bin/jsdoc -c jsdoc.json","build":"webpack --config ./bundler/webpack.prod.js && cp ./dist/larvitar.js ./docs/examples/larvitar.js","dev":"webpack --progress --config ./bundler/webpack.dev.js && cp ./dist/larvitar.js ./docs/examples/larvitar.js","dev-wip":"webpack serve --config ./bundler/webpack.dev-wip.js"},"author":"Simone Manini <simone.manini@dvisionlab.com> (https://www.dvisionlab.com)","contributors":["Mattia Ronzoni <mattia.ronzoni@dvisionlab.com> (https://www.dvisionlab.com)","Sara Zanchi <sara.zanchi@dvisionlab.com> (https://www.dvisionlab.com)","Ale Re <ale.re@dvisionlab.com> (https://www.dvisionlab.com)","Laura Borghesi Re <laura.borghesi@dvisionlab.com> (https://www.dvisionlab.com)"],"license":"MIT","dependencies":{"@rollup/plugin-commonjs":"^17.1.0","cornerstone-core":"^2.6.1","cornerstone-file-image-loader":"^0.3.0","cornerstone-tools":"^6.0.7","cornerstone-wado-image-loader":"^4.13.2","cornerstone-web-image-loader":"^2.1.1","crypto-js":"^4.1.1","dicom-character-set":"^1.0.3","dicom-parser":"^1.8.13","docdash":"^1.2.0","hammerjs":"^2.0.8","jpeg-lossless-decoder-js":"^2.0.7","keycode-js":"^3.1.0","lodash":"^4.17.15","pako":"^1.0.10","papaparse":"^5.3.0","plotly.js-dist-min":"^2.27.1","uuid":"^8.3.2"},"devDependencies":{"@babel/core":"^7.21.8","@types/cornerstone-core":"^2.3.0","@types/crypto-js":"^4.1.1","@types/hammerjs":"^2.0.41","@types/lodash":"^4.14.192","@types/papaparse":"^5.3.7","@types/plotly.js":"^2.12.30","@types/plotly.js-dist-min":"^2.3.4","@types/uuid":"^9.0.1","babel-loader":"^9.1.2","clean-webpack-plugin":"^4.0.0","copy-webpack-plugin":"^11.0.0","fs":"^0.0.1-security","html-loader":"^4.2.0","html-webpack-plugin":"^5.5.0","ip":"^1.1.8","jsdoc":"^3.6.4","portfinder-sync":"^0.0.2","ts-loader":"^9.4.2","typescript":"^5.0.2","typescript-coverage-report":"^0.7.0","webpack":"^5.76.3","webpack-bundle-analyzer":"^4.8.0","webpack-cli":"^5.0.1","webpack-dev-server":"^4.13.1"}}');
88985
89233
 
88986
89234
  /***/ })
88987
89235