@ohif/app 3.13.0-beta.119 → 3.13.0-beta.120

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 (39) hide show
  1. package/dist/{1483.bundle.e208a19dd0ff9a11.js → 1483.bundle.5e93c978bd32d7de.js} +1 -1
  2. package/dist/{2343.bundle.e50c08b2df863e1a.js → 2343.bundle.3445fda02a002697.js} +12 -8
  3. package/dist/{2036.bundle.1b6c0d890aa6bf4e.js → 2493.bundle.f3b6a64d158365da.js} +113 -35
  4. package/dist/{3215.bundle.1fca83719c1b786b.js → 3330.bundle.b1297ef8c94e5440.js} +796 -180
  5. package/dist/{2690.bundle.f5dc28ac498de122.js → 3568.bundle.45dc681ef6890166.js} +2112 -76
  6. package/dist/{6495.bundle.84b83aa091c338cd.js → 6495.bundle.a6764fdb8c0c252f.js} +846 -219
  7. package/dist/{8668.bundle.93c88419e37dc076.js → 8668.bundle.0e47f7231aa07da2.js} +227 -3
  8. package/dist/{9402.bundle.0dd1b538f0708077.js → 9402.bundle.928437e2e48c12dd.js} +2 -2
  9. package/dist/{9560.bundle.bb39f946ea79cf0e.js → 9560.bundle.517f0ef7ee3a20bf.js} +159 -196
  10. package/dist/{app.bundle.bdeb02edea129b2c.js → app.bundle.81a823d1149be346.js} +99 -25
  11. package/dist/{compute.bundle.77e80c1775429bd6.js → compute.bundle.9cc3697d07fbb082.js} +3 -3
  12. package/dist/index.html +1 -1
  13. package/dist/{polySeg.bundle.5e350e0723aa59b6.js → polySeg.bundle.a526954fc2fed311.js} +3 -3
  14. package/dist/sw.js +1 -1
  15. package/package.json +6 -6
  16. /package/dist/{100.bundle.bd6735a86c215595.js → 100.bundle.84a35e9d087b403c.js} +0 -0
  17. /package/dist/{1180.bundle.4c5146471b4d3497.js → 1180.bundle.7f790d9fd6fb031c.js} +0 -0
  18. /package/dist/{1602.bundle.163e3da3a27b860c.js → 1602.bundle.254a392a6b5d2b85.js} +0 -0
  19. /package/dist/{2779.bundle.664d9d0a704f7b94.js → 2779.bundle.c879d6af5dc0c274.js} +0 -0
  20. /package/dist/{3500.bundle.18412afd9ee5d6a7.js → 3500.bundle.d4aaab15c4461cc4.js} +0 -0
  21. /package/dist/{3760.bundle.f69046888fc2b881.js → 3760.bundle.c95abd6ab662bd3b.js} +0 -0
  22. /package/dist/{4556.bundle.128d2abaea69dce3.js → 4556.bundle.c3ac23e680d677b2.js} +0 -0
  23. /package/dist/{4683.bundle.b02523a9d66f4d19.js → 4683.bundle.ed3f14fcb89fbad1.js} +0 -0
  24. /package/dist/{5189.bundle.2a0f740738759e32.js → 5189.bundle.ea191ea99047fd6f.js} +0 -0
  25. /package/dist/{5642.bundle.1622d255af1102d8.js → 5642.bundle.98e17a4413db6ef1.js} +0 -0
  26. /package/dist/{5696.bundle.2f47cb5ab5a7f983.js → 5696.bundle.e77041f7e2b08236.js} +0 -0
  27. /package/dist/{6749.bundle.9f0550714a4d5f8b.js → 6749.bundle.9dcda33e49485da4.js} +0 -0
  28. /package/dist/{7231.bundle.46f843b74a964f89.js → 7231.bundle.1063d727ad99108a.js} +0 -0
  29. /package/dist/{7248.bundle.bffd4e60f806e25d.js → 7248.bundle.ab6f276adad059da.js} +0 -0
  30. /package/dist/{7499.bundle.bb240e8754167cb2.js → 7499.bundle.832916b9b820c33f.js} +0 -0
  31. /package/dist/{781.bundle.f7411dabe0628911.js → 781.bundle.f06b6ab92ef4d695.js} +0 -0
  32. /package/dist/{8423.bundle.071901427fd3cd9e.js → 8423.bundle.ebf8d7d638d9616b.js} +0 -0
  33. /package/dist/{8492.bundle.9c17dcbab24b07c3.js → 8492.bundle.1ceeb18471c1c06b.js} +0 -0
  34. /package/dist/{8832.bundle.e413f00216682f40.js → 8832.bundle.1eb46bfa451c792f.js} +0 -0
  35. /package/dist/{9116.bundle.1cb5c393e3a152cd.js → 9116.bundle.1d0c6c18a4db51cc.js} +0 -0
  36. /package/dist/{9290.bundle.77a274271ce884a3.js → 9290.bundle.82e8dfc0f73c41bb.js} +0 -0
  37. /package/dist/{9383.bundle.9b1d03c71cc52f4f.js → 9383.bundle.ec44c452ccc23e93.js} +0 -0
  38. /package/dist/{9415.bundle.d3532cc872787744.js → 9415.bundle.69d74a2b03d5d6e4.js} +0 -0
  39. /package/dist/{9437.bundle.a18085ed31658c82.js → 9437.bundle.ca5db89624e35827.js} +0 -0
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- (globalThis["rspackChunk"] = globalThis["rspackChunk"] || []).push([[3215], {
2
+ (globalThis["rspackChunk"] = globalThis["rspackChunk"] || []).push([[3330], {
3
3
  28910(__unused_rspack_module, __webpack_exports__, __webpack_require__) {
4
4
  __webpack_require__.r(__webpack_exports__);
5
5
  __webpack_require__.d(__webpack_exports__, {
@@ -6310,6 +6310,9 @@ __webpack_require__.d(__webpack_exports__, {
6310
6310
  loadImageToCanvas: () => (/* reexport */ loadImageToCanvas/* ["default"] */.A),
6311
6311
  logger: () => (/* reexport */ logger),
6312
6312
  makeVolumeMetadata: () => (/* reexport */ makeVolumeMetadata/* ["default"] */.A),
6313
+ mapMappedBandToRawRange: () => (/* reexport */ viewportVoiIntensityMapping/* .mapMappedBandToRawRange */.j_),
6314
+ mapScalarToViewportVoiIntensity: () => (/* reexport */ viewportVoiIntensityMapping/* .mapScalarToViewportVoiIntensity */.fT),
6315
+ mapViewportVoiIntensityToScalar: () => (/* reexport */ viewportVoiIntensityMapping/* .mapViewportVoiIntensityToScalar */.l2),
6313
6316
  planar: () => (/* reexport */ planar),
6314
6317
  pointInShapeCallback: () => (/* reexport */ pointInShapeCallback/* .pointInShapeCallback */.ii),
6315
6318
  renderToCanvasCPU: () => (/* reexport */ renderToCanvasCPU/* ["default"] */.A),
@@ -6576,6 +6579,8 @@ var calculateSpacingBetweenImageIds = __webpack_require__(66831);
6576
6579
  var logger = __webpack_require__(80977);
6577
6580
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/utilities/calculateNeighborhoodStats.js
6578
6581
  var calculateNeighborhoodStats = __webpack_require__(5830);
6582
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/utilities/viewportVoiIntensityMapping.js
6583
+ var viewportVoiIntensityMapping = __webpack_require__(28656);
6579
6584
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/utilities/getPixelSpacingInformation.js
6580
6585
  var getPixelSpacingInformation = __webpack_require__(41840);
6581
6586
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/utilities/getPlaneCubeIntersectionDimensions.js
@@ -6706,6 +6711,7 @@ var isEqual = __webpack_require__(77981);
6706
6711
 
6707
6712
 
6708
6713
 
6714
+
6709
6715
 
6710
6716
 
6711
6717
  const utilities_getViewportModality = (viewport, volumeId) => (0,getViewportModality/* ._getViewportModality */.p)(viewport, volumeId, cache/* ["default"].getVolume */.Ay.getVolume);
@@ -6714,6 +6720,29 @@ const utilities_getScalingDescriptor = (viewport, targetId) => (0,getScalingDesc
6714
6720
 
6715
6721
 
6716
6722
 
6723
+ },
6724
+ 80977(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
6725
+ __webpack_require__.r(__webpack_exports__);
6726
+ __webpack_require__.d(__webpack_exports__, {
6727
+ aiLog: () => (aiLog),
6728
+ coreLog: () => (coreLog),
6729
+ cs3dLog: () => (cs3dLog),
6730
+ dicomConsistencyLog: () => (dicomConsistencyLog),
6731
+ examplesLog: () => (examplesLog),
6732
+ getLogger: () => (getLogger),
6733
+ getRootLogger: () => (getRootLogger),
6734
+ growCutLog: () => (growCutLog),
6735
+ imageConsistencyLog: () => (imageConsistencyLog),
6736
+ loaderLog: () => (loaderLog),
6737
+ toolsLog: () => (toolsLog),
6738
+ workerLog: () => (workerLog)
6739
+ });
6740
+ /* import */ var _cornerstonejs_utils__rspack_import_0 = __webpack_require__(53103);
6741
+
6742
+ const { /* getRootLogger */pp: getRootLogger, /* getLogger */tZ: getLogger, /* cs3dLog */gE: cs3dLog, /* workerLog */bM: workerLog, /* coreLog */uu: coreLog, /* toolsLog */UA: toolsLog, /* loaderLog */_E: loaderLog, /* aiLog */RZ: aiLog, /* examplesLog */UX: examplesLog, /* dicomConsistencyLog */HL: dicomConsistencyLog, /* imageConsistencyLog */U5: imageConsistencyLog, } = _cornerstonejs_utils__rspack_import_0/* .logging */.m9;
6743
+ const growCutLog = toolsLog.getLogger('growCut');
6744
+
6745
+
6717
6746
  },
6718
6747
  25481(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
6719
6748
  __webpack_require__.r(__webpack_exports__);
@@ -6778,7 +6807,7 @@ function isPointOnPlane(point, plane, tolerance = _constants_index_js__rspack_im
6778
6807
 
6779
6808
 
6780
6809
  },
6781
- 48260(__unused_rspack___webpack_module__, __unused_rspack___webpack_exports__, __webpack_require__) {
6810
+ 63215(__unused_rspack___webpack_module__, __unused_rspack___webpack_exports__, __webpack_require__) {
6782
6811
  // NAMESPACE OBJECT: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/polyData/utils.js
6783
6812
  var utils_namespaceObject = {};
6784
6813
  __webpack_require__.r(utils_namespaceObject);
@@ -10188,7 +10217,7 @@ var COLOR_LUT = __webpack_require__(69501);
10188
10217
 
10189
10218
 
10190
10219
  ;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/version.js
10191
- const version = '5.4.12';
10220
+ const version = '5.4.13';
10192
10221
 
10193
10222
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/viewportPresentation.js
10194
10223
  var viewportPresentation = __webpack_require__(88299);
@@ -31010,6 +31039,769 @@ class RegionSegmentPlusTool extends GrowCutBaseTool/* ["default"] */.A {
31010
31039
  RegionSegmentPlusTool.toolName = 'RegionSegmentPlus';
31011
31040
  /* export default */ const annotation_RegionSegmentPlusTool = ((/* unused pure expression or super */ null && (RegionSegmentPlusTool)));
31012
31041
 
31042
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/segmentation/growCut/runFloodFillSegmentation.js + 4 modules
31043
+ var runFloodFillSegmentation = __webpack_require__(55600);
31044
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/segmentation/floodFillSliceLazy.js
31045
+ var floodFillSliceLazy = __webpack_require__(10621);
31046
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/segmentation/growCut/intensityRange/adaptiveRegionIntensityRange.js
31047
+ var adaptiveRegionIntensityRange = __webpack_require__(81537);
31048
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/segmentation/growCut/getViewportVoiMappingForVolume.js
31049
+ var getViewportVoiMappingForVolume = __webpack_require__(1967);
31050
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/segmentation/triggerSegmentationEvents.js + 4 modules
31051
+ var triggerSegmentationEvents = __webpack_require__(49256);
31052
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/segmentation/createLabelmapMemo.js
31053
+ var createLabelmapMemo = __webpack_require__(1732);
31054
+ // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/tools/annotation/regionSegmentHoverCursors.js
31055
+ var regionSegmentHoverCursors = __webpack_require__(58690);
31056
+ ;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/tools/annotation/ClickSegmentTool.js
31057
+
31058
+
31059
+
31060
+
31061
+
31062
+
31063
+
31064
+
31065
+
31066
+
31067
+
31068
+ const { growCutLog } = esm.utilities.logger;
31069
+ const HOVER_PROBE_THROTTLE_MS = 100;
31070
+ const PROBE_REUSE_DISTANCE_PX = 6;
31071
+ const PROBE_FRESH_MS = 1500;
31072
+ const EXPAND_STEP_FACTOR = 1.15;
31073
+ const SHRINK_STEP_FACTOR = 0.85;
31074
+ const MIN_COMPACTNESS = 0.08;
31075
+ const COMPACTNESS_CHECK_MIN_VOLUME_MM3 = 2000;
31076
+ const COMPUTE_BUDGET_MM3 = 2_000_000;
31077
+ const NOT_LESION_MESSAGE = 'The region here does not form a self-contained, lesion-like shape; nothing was segmented.';
31078
+ const DRY_RUN_YIELD_EVERY = 10_000;
31079
+ const CONSENSUS_MIN_NEIGHBOR_VOTES = 2;
31080
+ const VERDICT_CACHE_TTL_MS = 2500;
31081
+ const MAX_REJECTED_REGIONS = 8;
31082
+ class ClickSegmentTool extends GrowCutBaseTool/* ["default"] */.A {
31083
+ constructor(toolProps = {}, defaultToolProps = {
31084
+ supportedInteractionTypes: ['Mouse', 'Touch'],
31085
+ configuration: {
31086
+ maxDeltaK: 25,
31087
+ maxDeltaIJ: 512,
31088
+ actions: {
31089
+ cancelInProgress: {
31090
+ method: 'cancelInProgress',
31091
+ bindings: [
31092
+ {
31093
+ key: 'Escape',
31094
+ },
31095
+ ],
31096
+ },
31097
+ },
31098
+ },
31099
+ }) {
31100
+ super(toolProps, defaultToolProps);
31101
+ this.segmentationInProgress = false;
31102
+ this.hoverThrottleTimer = null;
31103
+ this.pendingHoverEvent = null;
31104
+ this.lastHoverElement = null;
31105
+ this.lastProbe = null;
31106
+ this.lastClick = null;
31107
+ this.clickAbortController = null;
31108
+ this.dryRunToken = null;
31109
+ this.confirmedRegion = null;
31110
+ this.rejectedRegions = [];
31111
+ }
31112
+ notifySegmentationError(message) {
31113
+ const event = new CustomEvent(esm.Enums.Events.ERROR_EVENT, {
31114
+ detail: {
31115
+ type: 'Segmentation',
31116
+ message,
31117
+ },
31118
+ cancelable: true,
31119
+ });
31120
+ esm.eventTarget.dispatchEvent(event);
31121
+ }
31122
+ cancelInProgress() {
31123
+ return this.cancelActiveOperation();
31124
+ }
31125
+ cancelActiveOperation() {
31126
+ if (!this.clickAbortController ||
31127
+ this.clickAbortController.signal.aborted) {
31128
+ return false;
31129
+ }
31130
+ this.clickAbortController.abort();
31131
+ return true;
31132
+ }
31133
+ clearHoverState() {
31134
+ if (this.hoverThrottleTimer !== null) {
31135
+ window.clearTimeout(this.hoverThrottleTimer);
31136
+ this.hoverThrottleTimer = null;
31137
+ }
31138
+ this.pendingHoverEvent = null;
31139
+ this.lastProbe = null;
31140
+ this.confirmedRegion = null;
31141
+ this.rejectedRegions = [];
31142
+ if (this.dryRunToken) {
31143
+ this.dryRunToken.cancelled = true;
31144
+ this.dryRunToken = null;
31145
+ }
31146
+ if (this.lastHoverElement) {
31147
+ this.lastHoverElement.style.cursor = '';
31148
+ this.lastHoverElement = null;
31149
+ }
31150
+ }
31151
+ pointerOnConfirmedRegion(refVolume, viewport, world) {
31152
+ const region = this.confirmedRegion;
31153
+ if (!region ||
31154
+ region.viewportId !== viewport.id ||
31155
+ Date.now() > region.expiresAt) {
31156
+ return false;
31157
+ }
31158
+ const ijk = esm.utilities.transformWorldToIndex(refVolume.imageData, world)
31159
+ .map(Math.round);
31160
+ for (let axis = 0; axis < 3; axis++) {
31161
+ if (ijk[axis] < region.bbox.min[axis] ||
31162
+ ijk[axis] > region.bbox.max[axis]) {
31163
+ return false;
31164
+ }
31165
+ }
31166
+ const [width, height] = refVolume.dimensions;
31167
+ const scalar = Number(refVolume.voxelManager.getAtIndex(ijk[2] * width * height + ijk[1] * width + ijk[0]));
31168
+ if (!Number.isFinite(scalar) ||
31169
+ scalar < region.bandMin ||
31170
+ scalar > region.bandMax) {
31171
+ return false;
31172
+ }
31173
+ region.expiresAt = Date.now() + VERDICT_CACHE_TTL_MS;
31174
+ return true;
31175
+ }
31176
+ static bandsAreSimilar(aMin, aMax, bMin, bMax) {
31177
+ const edgeMatches = (a, b) => {
31178
+ if (!Number.isFinite(a) || !Number.isFinite(b)) {
31179
+ return a === b;
31180
+ }
31181
+ const scale = Math.max(Math.abs(a), Math.abs(b), 1e-6);
31182
+ return Math.abs(a - b) <= 0.25 * scale;
31183
+ };
31184
+ return edgeMatches(aMin, bMin) && edgeMatches(aMax, bMax);
31185
+ }
31186
+ matchesRejectedRegion(viewportId, range) {
31187
+ const now = Date.now();
31188
+ this.rejectedRegions = this.rejectedRegions.filter((entry) => entry.expiresAt > now);
31189
+ const seed = range.ijkStart;
31190
+ const match = this.rejectedRegions.find((entry) => {
31191
+ if (entry.viewportId !== viewportId) {
31192
+ return false;
31193
+ }
31194
+ for (let axis = 0; axis < 3; axis++) {
31195
+ if (seed[axis] < entry.bbox.min[axis] ||
31196
+ seed[axis] > entry.bbox.max[axis]) {
31197
+ return false;
31198
+ }
31199
+ }
31200
+ return ClickSegmentTool.bandsAreSimilar(range.min, range.max, entry.bandMin, entry.bandMax);
31201
+ });
31202
+ if (match) {
31203
+ match.expiresAt = now + VERDICT_CACHE_TTL_MS;
31204
+ return true;
31205
+ }
31206
+ return false;
31207
+ }
31208
+ rememberRejectedRegion(viewportId, bbox, bandMin, bandMax) {
31209
+ if (!bbox) {
31210
+ return;
31211
+ }
31212
+ this.rejectedRegions.push({
31213
+ viewportId,
31214
+ bbox: {
31215
+ min: [...bbox.min],
31216
+ max: [...bbox.max],
31217
+ },
31218
+ bandMin,
31219
+ bandMax,
31220
+ expiresAt: Date.now() + VERDICT_CACHE_TTL_MS,
31221
+ });
31222
+ if (this.rejectedRegions.length > MAX_REJECTED_REGIONS) {
31223
+ this.rejectedRegions.splice(0, this.rejectedRegions.length - MAX_REJECTED_REGIONS);
31224
+ }
31225
+ }
31226
+ safeSpacing(volume) {
31227
+ const spacing = volume.spacing ?? [1, 1, 1];
31228
+ return [0, 1, 2].map((axis) => Number.isFinite(spacing[axis]) && spacing[axis] > 0 ? spacing[axis] : 1);
31229
+ }
31230
+ computeVoxelBudget(volume) {
31231
+ const [sx, sy, sz] = this.safeSpacing(volume);
31232
+ return Math.max(1000, Math.ceil(COMPUTE_BUDGET_MM3 / (sx * sy * sz)));
31233
+ }
31234
+ makeRegionShapeGate(volume) {
31235
+ const spacing = this.safeSpacing(volume);
31236
+ const voxelVolumeMm3 = spacing[0] * spacing[1] * spacing[2];
31237
+ const maxDeltaK = this.configuration.maxDeltaK;
31238
+ return ({ voxelCount, bbox }) => {
31239
+ if (typeof maxDeltaK === 'number' && maxDeltaK >= 0) {
31240
+ const kExtent = bbox.max[2] - bbox.min[2] + 1;
31241
+ if (kExtent >= 2 * maxDeltaK + 1) {
31242
+ return false;
31243
+ }
31244
+ }
31245
+ const volumeMm3 = voxelCount * voxelVolumeMm3;
31246
+ if (volumeMm3 < COMPACTNESS_CHECK_MIN_VOLUME_MM3) {
31247
+ return true;
31248
+ }
31249
+ let bboxMm3 = 1;
31250
+ for (let axis = 0; axis < 3; axis++) {
31251
+ bboxMm3 *= (bbox.max[axis] - bbox.min[axis] + 1) * spacing[axis];
31252
+ }
31253
+ return volumeMm3 / bboxMm3 >= MIN_COMPACTNESS;
31254
+ };
31255
+ }
31256
+ onSetToolPassive() {
31257
+ this.clearHoverState();
31258
+ }
31259
+ onSetToolDisabled() {
31260
+ this.clearHoverState();
31261
+ }
31262
+ buildProbeOptions(viewport, element, referencedVolumeId) {
31263
+ return {
31264
+ viewport,
31265
+ element,
31266
+ referencedVolumeId,
31267
+ voiMapping: (0,getViewportVoiMappingForVolume/* .getViewportVoiMappingForVolume */.K)(viewport, referencedVolumeId) ??
31268
+ undefined,
31269
+ };
31270
+ }
31271
+ mouseMoveCallback(evt) {
31272
+ if (this.mode !== enums.ToolModes.Active) {
31273
+ return;
31274
+ }
31275
+ const { element } = evt.detail;
31276
+ this.lastHoverElement = element;
31277
+ if (this.segmentationInProgress) {
31278
+ element.style.cursor = 'wait';
31279
+ return;
31280
+ }
31281
+ this.queueHoverProbe(evt);
31282
+ }
31283
+ queueHoverProbe(evt) {
31284
+ this.pendingHoverEvent = evt;
31285
+ if (this.hoverThrottleTimer !== null) {
31286
+ return;
31287
+ }
31288
+ this.flushHoverProbe();
31289
+ }
31290
+ flushHoverProbe() {
31291
+ const evt = this.pendingHoverEvent;
31292
+ this.pendingHoverEvent = null;
31293
+ if (!evt) {
31294
+ return;
31295
+ }
31296
+ void this.runHoverProbe(evt);
31297
+ this.hoverThrottleTimer = window.setTimeout(() => {
31298
+ this.hoverThrottleTimer = null;
31299
+ if (this.pendingHoverEvent) {
31300
+ this.flushHoverProbe();
31301
+ }
31302
+ }, HOVER_PROBE_THROTTLE_MS);
31303
+ }
31304
+ getViewportSliceIndex(viewport) {
31305
+ const getSliceIndex = viewport.getSliceIndex;
31306
+ if (typeof getSliceIndex !== 'function') {
31307
+ return null;
31308
+ }
31309
+ try {
31310
+ const sliceIndex = getSliceIndex.call(viewport);
31311
+ return Number.isFinite(sliceIndex) ? sliceIndex : null;
31312
+ }
31313
+ catch {
31314
+ return null;
31315
+ }
31316
+ }
31317
+ async runHoverProbe(evt) {
31318
+ if (this.mode !== enums.ToolModes.Active || this.segmentationInProgress) {
31319
+ return;
31320
+ }
31321
+ const { element, currentPoints } = evt.detail;
31322
+ const enabledElement = (0,esm.getEnabledElement)(element);
31323
+ const viewport = enabledElement?.viewport;
31324
+ if (!viewport) {
31325
+ return;
31326
+ }
31327
+ if (this.dryRunToken) {
31328
+ this.dryRunToken.cancelled = true;
31329
+ this.dryRunToken = null;
31330
+ }
31331
+ let state = 'unknown';
31332
+ let dryRunInput = null;
31333
+ try {
31334
+ if (stateManagement_segmentation.activeSegmentation.getActiveSegmentation(viewport.id)) {
31335
+ const labelmapData = await this.getLabelmapSegmentationData(viewport);
31336
+ if (labelmapData) {
31337
+ const { referencedVolumeId } = labelmapData;
31338
+ if (!this._isOrthogonalView(viewport, referencedVolumeId)) {
31339
+ state = 'blocked';
31340
+ }
31341
+ else {
31342
+ const refVolume = esm.cache.getVolume(referencedVolumeId);
31343
+ if (refVolume) {
31344
+ if (this.pointerOnConfirmedRegion(refVolume, viewport, currentPoints.world)) {
31345
+ state = 'plus';
31346
+ }
31347
+ else {
31348
+ const options = this.buildProbeOptions(viewport, element, referencedVolumeId);
31349
+ const probe = (0,adaptiveRegionIntensityRange/* .probeAdaptiveRegion */.Ti)(refVolume, currentPoints.world, options);
31350
+ if (!probe.viable || !probe.range) {
31351
+ state = 'blocked';
31352
+ }
31353
+ else if (this.matchesRejectedRegion(viewport.id, probe.range)) {
31354
+ state = 'blocked';
31355
+ }
31356
+ else if (!this.neighborsAgree(probe)) {
31357
+ state = 'blocked';
31358
+ }
31359
+ else {
31360
+ state = 'pending';
31361
+ dryRunInput = { refVolume, range: probe.range };
31362
+ }
31363
+ }
31364
+ }
31365
+ }
31366
+ }
31367
+ }
31368
+ }
31369
+ catch (err) {
31370
+ growCutLog.debug('hover probe: could not evaluate', {
31371
+ message: err instanceof Error ? err.message : String(err),
31372
+ });
31373
+ state = 'unknown';
31374
+ }
31375
+ const verdict = state === 'unknown'
31376
+ ? null
31377
+ : {
31378
+ viewportId: viewport.id,
31379
+ canvas: [...currentPoints.canvas],
31380
+ sliceIndex: this.getViewportSliceIndex(viewport),
31381
+ ok: state !== 'blocked',
31382
+ at: Date.now(),
31383
+ };
31384
+ this.lastProbe = verdict;
31385
+ element.style.cursor =
31386
+ state === 'plus'
31387
+ ? regionSegmentHoverCursors/* .PLUS_CURSOR */.ys
31388
+ : state === 'blocked'
31389
+ ? regionSegmentHoverCursors/* .BLOCKED_CURSOR */.kC
31390
+ : regionSegmentHoverCursors/* .PENDING_CURSOR */.t5;
31391
+ if (state === 'pending' && dryRunInput && verdict) {
31392
+ const token = { cancelled: false };
31393
+ this.dryRunToken = token;
31394
+ void this.runConfinementDryRun(dryRunInput.refVolume, dryRunInput.range, token, verdict, element);
31395
+ }
31396
+ }
31397
+ neighborsAgree(probe) {
31398
+ const joinLevels = probe.clickNeighborJoinLevels;
31399
+ const tolerance = probe.toleranceBytes;
31400
+ if (!joinLevels || typeof tolerance !== 'number') {
31401
+ return true;
31402
+ }
31403
+ let votes = 0;
31404
+ let evaluated = 0;
31405
+ for (const joinLevel of joinLevels) {
31406
+ if (joinLevel === null) {
31407
+ continue;
31408
+ }
31409
+ evaluated++;
31410
+ if (joinLevel >= 0 && joinLevel <= tolerance) {
31411
+ votes++;
31412
+ }
31413
+ }
31414
+ return evaluated < CONSENSUS_MIN_NEIGHBOR_VOTES
31415
+ ? votes === evaluated
31416
+ : votes >= CONSENSUS_MIN_NEIGHBOR_VOTES;
31417
+ }
31418
+ async runConfinementDryRun(refVolume, range, token, verdict, element) {
31419
+ const { dimensions } = refVolume;
31420
+ const [width, height, depth] = dimensions;
31421
+ const pixelsPerSlice = width * height;
31422
+ const voxelManager = refVolume.voxelManager;
31423
+ const { min, max } = range;
31424
+ const shapeGate = this.makeRegionShapeGate(refVolume);
31425
+ try {
31426
+ const { truncated, voxelCount, bbox } = await (0,floodFillSliceLazy/* .floodFill3dSliceLazy */.x)((x, y, z) => Number(voxelManager.getAtIndex(z * pixelsPerSlice + y * width + x)), [...range.ijkStart], {
31427
+ width,
31428
+ height,
31429
+ depth,
31430
+ equals: (val) => typeof val === 'number' &&
31431
+ Number.isFinite(val) &&
31432
+ val >= min &&
31433
+ val <= max,
31434
+ yieldEvery: DRY_RUN_YIELD_EVERY,
31435
+ maxDeltaK: this.configuration.maxDeltaK,
31436
+ maxDeltaIJ: this.configuration.maxDeltaIJ,
31437
+ isCancelled: () => token.cancelled,
31438
+ maxVoxels: this.computeVoxelBudget(refVolume),
31439
+ shouldContinue: shapeGate,
31440
+ });
31441
+ if (token.cancelled) {
31442
+ return;
31443
+ }
31444
+ const lesionLike = !truncated && bbox && shapeGate({ voxelCount, bbox });
31445
+ if (lesionLike) {
31446
+ this.confirmedRegion = {
31447
+ viewportId: verdict.viewportId,
31448
+ bbox,
31449
+ bandMin: min,
31450
+ bandMax: max,
31451
+ expiresAt: Date.now() + VERDICT_CACHE_TTL_MS,
31452
+ };
31453
+ if (this.lastProbe === verdict) {
31454
+ verdict.ok = true;
31455
+ element.style.cursor = regionSegmentHoverCursors/* .PLUS_CURSOR */.ys;
31456
+ }
31457
+ }
31458
+ else {
31459
+ this.rememberRejectedRegion(verdict.viewportId, bbox, min, max);
31460
+ if (this.lastProbe === verdict) {
31461
+ verdict.ok = false;
31462
+ element.style.cursor = regionSegmentHoverCursors/* .BLOCKED_CURSOR */.kC;
31463
+ }
31464
+ }
31465
+ }
31466
+ catch (err) {
31467
+ growCutLog.debug('hover dry-run: could not evaluate', {
31468
+ message: err instanceof Error ? err.message : String(err),
31469
+ });
31470
+ }
31471
+ finally {
31472
+ if (this.dryRunToken === token) {
31473
+ this.dryRunToken = null;
31474
+ }
31475
+ }
31476
+ }
31477
+ probeAppliesToClick(viewport, canvas) {
31478
+ const probe = this.lastProbe;
31479
+ if (!probe || probe.viewportId !== viewport.id) {
31480
+ return false;
31481
+ }
31482
+ if (Date.now() - probe.at > PROBE_FRESH_MS) {
31483
+ return false;
31484
+ }
31485
+ if (probe.sliceIndex !== this.getViewportSliceIndex(viewport)) {
31486
+ return false;
31487
+ }
31488
+ const dx = canvas[0] - probe.canvas[0];
31489
+ const dy = canvas[1] - probe.canvas[1];
31490
+ return Math.sqrt(dx * dx + dy * dy) <= PROBE_REUSE_DISTANCE_PX;
31491
+ }
31492
+ async preMouseDownCallback(evt) {
31493
+ if (this.segmentationInProgress) {
31494
+ return false;
31495
+ }
31496
+ const { currentPoints, element } = evt.detail;
31497
+ const { world: worldPoint, canvas: canvasPoint } = currentPoints;
31498
+ const enabledElement = element ? (0,esm.getEnabledElement)(element) : undefined;
31499
+ if (enabledElement?.viewport &&
31500
+ this.probeAppliesToClick(enabledElement.viewport, canvasPoint) &&
31501
+ this.lastProbe?.ok === false) {
31502
+ growCutLog.info('click ignored: hover probe reported no proper region', {
31503
+ canvasPoint,
31504
+ });
31505
+ return false;
31506
+ }
31507
+ let setupOk = false;
31508
+ try {
31509
+ setupOk = await super.preMouseDownCallback(evt);
31510
+ }
31511
+ catch (err) {
31512
+ const message = err instanceof Error ? err.message : 'Click segmentation failed.';
31513
+ growCutLog.info('ClickSegment: click setup rejected', { message });
31514
+ this.notifySegmentationError(message);
31515
+ return false;
31516
+ }
31517
+ if (!setupOk || !this.growCutData) {
31518
+ return false;
31519
+ }
31520
+ const clickData = this.growCutData;
31521
+ this.growCutData = null;
31522
+ void this.runClick(clickData, worldPoint, element).catch((err) => {
31523
+ const message = err instanceof Error ? err.message : 'Click segmentation failed.';
31524
+ this.notifySegmentationError(message);
31525
+ growCutLog.error('ClickSegment: segmentation failed', { message });
31526
+ });
31527
+ return true;
31528
+ }
31529
+ async runClick(clickData, worldPoint, element) {
31530
+ const { segmentation, viewportId, renderingEngineId } = clickData;
31531
+ const { referencedVolumeId, labelmapVolumeId, segmentIndex } = segmentation;
31532
+ const renderingEngine = (0,esm.getRenderingEngine)(renderingEngineId);
31533
+ const viewport = renderingEngine?.getViewport(viewportId);
31534
+ if (!viewport) {
31535
+ throw new Error('ClickSegment: viewport not found for click.');
31536
+ }
31537
+ const refVolume = esm.cache.getVolume(referencedVolumeId);
31538
+ const labelmapVolume = esm.cache.getVolume(labelmapVolumeId);
31539
+ if (!refVolume || !labelmapVolume) {
31540
+ throw new Error('ClickSegment: referenced or labelmap volume not in cache.');
31541
+ }
31542
+ const probe = (0,adaptiveRegionIntensityRange/* .probeAdaptiveRegion */.Ti)(refVolume, worldPoint, this.buildProbeOptions(viewport, viewport.element, referencedVolumeId));
31543
+ if (!probe.viable || !probe.range || !probe.expandContext) {
31544
+ growCutLog.info('ClickSegment: click found no meaningful region', {
31545
+ reason: probe.reason,
31546
+ regionAreaMm2: probe.regionAreaMm2,
31547
+ });
31548
+ this.notifySegmentationError('No meaningful region at the clicked location. Move the pointer until the plus cursor appears.');
31549
+ return;
31550
+ }
31551
+ growCutLog.info('ClickSegment: click', {
31552
+ worldPoint,
31553
+ toleranceBytes: probe.toleranceBytes,
31554
+ regionAreaMm2: probe.regionAreaMm2,
31555
+ band: { min: probe.range.min, max: probe.range.max },
31556
+ });
31557
+ const memo = this.beginLabelmapMemo(segmentation, labelmapVolume);
31558
+ let filledPoints;
31559
+ try {
31560
+ filledPoints = await this.fillWithRange(probe.range, {
31561
+ segmentation,
31562
+ viewportId,
31563
+ renderingEngineId,
31564
+ }, viewport, labelmapVolume, element, memo);
31565
+ }
31566
+ finally {
31567
+ this.doneEditMemo();
31568
+ }
31569
+ this.lastClick = {
31570
+ expandContext: probe.expandContext,
31571
+ toleranceBytes: probe.expandContext.chosenToleranceBytes,
31572
+ worldPoint: [...worldPoint],
31573
+ filledPoints,
31574
+ segmentation,
31575
+ viewportId,
31576
+ renderingEngineId,
31577
+ };
31578
+ growCutLog.info('ClickSegment: click complete', {
31579
+ filledVoxels: filledPoints.length,
31580
+ segmentIndex,
31581
+ });
31582
+ }
31583
+ async fillWithRange(range, target, viewport, labelmapVolume, element, memo) {
31584
+ const { segmentation } = target;
31585
+ const { referencedVolumeId, segmentIndex, segmentationId } = segmentation;
31586
+ this.segmentationInProgress = true;
31587
+ if (element) {
31588
+ element.style.cursor = 'wait';
31589
+ }
31590
+ const abortController = new AbortController();
31591
+ this.clickAbortController = abortController;
31592
+ let filledPoints = [];
31593
+ let notLesionLike = false;
31594
+ try {
31595
+ const referencedVolume = esm.cache.getVolume(referencedVolumeId);
31596
+ if (!referencedVolume) {
31597
+ throw new Error('ClickSegment: referenced volume is no longer cached; cannot fill.');
31598
+ }
31599
+ const result = await (0,runFloodFillSegmentation/* .runFloodFillSegmentation */.ZC)({
31600
+ referencedVolumeId,
31601
+ worldPosition: this.indexToWorld(referencedVolume, range.ijkStart),
31602
+ viewport,
31603
+ labelmapVolume,
31604
+ options: {
31605
+ segmentIndex,
31606
+ getIntensityRange: () => range,
31607
+ element: viewport.element,
31608
+ applyExternalIslandRemoval: true,
31609
+ applyInternalIslandRemoval: true,
31610
+ maxDeltaK: this.configuration.maxDeltaK,
31611
+ maxDeltaIJ: this.configuration.maxDeltaIJ,
31612
+ isCancelled: () => abortController.signal.aborted,
31613
+ maxVoxels: this.computeVoxelBudget(referencedVolume),
31614
+ shouldContinueRegion: this.makeRegionShapeGate(referencedVolume),
31615
+ historyVoxelManager: memo?.voxelManager,
31616
+ onRejected: ({ voxelCount, bbox }) => {
31617
+ notLesionLike = true;
31618
+ growCutLog.info('ClickSegment: fill rejected by shape gate', {
31619
+ voxelCount,
31620
+ bbox,
31621
+ });
31622
+ },
31623
+ onCommitted: (points) => {
31624
+ filledPoints = points;
31625
+ },
31626
+ },
31627
+ });
31628
+ if (!result) {
31629
+ if (abortController.signal.aborted) {
31630
+ throw new Error('ClickSegment: fill cancelled.');
31631
+ }
31632
+ throw new Error(notLesionLike
31633
+ ? NOT_LESION_MESSAGE
31634
+ : 'ClickSegment: fill produced no result (band rejected).');
31635
+ }
31636
+ (0,triggerSegmentationEvents.triggerSegmentationDataModified)(segmentationId);
31637
+ return filledPoints;
31638
+ }
31639
+ finally {
31640
+ if (this.clickAbortController === abortController) {
31641
+ this.clickAbortController = null;
31642
+ }
31643
+ this.segmentationInProgress = false;
31644
+ if (element) {
31645
+ element.style.cursor = regionSegmentHoverCursors/* .PENDING_CURSOR */.t5;
31646
+ }
31647
+ }
31648
+ }
31649
+ indexToWorld(volume, ijk) {
31650
+ return esm.utilities.transformIndexToWorld(volume.imageData, ijk);
31651
+ }
31652
+ beginLabelmapMemo(segmentation, labelmapVolume) {
31653
+ const memo = createLabelmapMemo.createLabelmapMemo(segmentation.segmentationId, labelmapVolume.voxelManager);
31654
+ this.memo = memo;
31655
+ return memo;
31656
+ }
31657
+ curveSizeAt(context, toleranceBytes) {
31658
+ let size = 0;
31659
+ for (const [level, levelSize] of context.growthCurve) {
31660
+ if (level > toleranceBytes) {
31661
+ break;
31662
+ }
31663
+ size = levelSize;
31664
+ }
31665
+ return size;
31666
+ }
31667
+ pickNextTolerance(direction) {
31668
+ const lastClick = this.lastClick;
31669
+ if (!lastClick) {
31670
+ return null;
31671
+ }
31672
+ const { expandContext, toleranceBytes } = lastClick;
31673
+ const currentSize = this.curveSizeAt(expandContext, toleranceBytes);
31674
+ if (direction > 0) {
31675
+ for (const [level, size] of expandContext.growthCurve) {
31676
+ if (level <= toleranceBytes) {
31677
+ continue;
31678
+ }
31679
+ if (size >= Math.max(currentSize + 1, currentSize * EXPAND_STEP_FACTOR)) {
31680
+ return level;
31681
+ }
31682
+ }
31683
+ return null;
31684
+ }
31685
+ for (let index = expandContext.growthCurve.length - 1; index >= 0; index--) {
31686
+ const [level, size] = expandContext.growthCurve[index];
31687
+ if (level >= toleranceBytes) {
31688
+ continue;
31689
+ }
31690
+ if (size <= Math.min(currentSize - 1, currentSize * SHRINK_STEP_FACTOR)) {
31691
+ return level;
31692
+ }
31693
+ }
31694
+ return null;
31695
+ }
31696
+ expand() {
31697
+ this.stepTolerance(1);
31698
+ }
31699
+ shrink() {
31700
+ this.stepTolerance(-1);
31701
+ }
31702
+ refresh() {
31703
+ const lastClick = this.lastClick;
31704
+ if (!lastClick || this.segmentationInProgress) {
31705
+ return;
31706
+ }
31707
+ void this.refillAtTolerance(lastClick.toleranceBytes).catch((err) => {
31708
+ growCutLog.error('ClickSegment: refresh failed', {
31709
+ message: err instanceof Error ? err.message : String(err),
31710
+ });
31711
+ });
31712
+ }
31713
+ stepTolerance(direction) {
31714
+ if (this.segmentationInProgress) {
31715
+ return;
31716
+ }
31717
+ const lastClick = this.lastClick;
31718
+ if (!lastClick) {
31719
+ growCutLog.info('ClickSegment: no click to expand/shrink yet');
31720
+ return;
31721
+ }
31722
+ const next = this.pickNextTolerance(direction);
31723
+ if (next === null) {
31724
+ growCutLog.info('ClickSegment: no further step available', {
31725
+ direction: direction > 0 ? 'expand' : 'shrink',
31726
+ toleranceBytes: lastClick.toleranceBytes,
31727
+ });
31728
+ return;
31729
+ }
31730
+ growCutLog.info('ClickSegment: stepping tolerance', {
31731
+ direction: direction > 0 ? 'expand' : 'shrink',
31732
+ fromToleranceBytes: lastClick.toleranceBytes,
31733
+ toToleranceBytes: next,
31734
+ predictedRegionPx: this.curveSizeAt(lastClick.expandContext, next),
31735
+ });
31736
+ const previousTolerance = lastClick.toleranceBytes;
31737
+ void this.refillAtTolerance(next).catch((err) => {
31738
+ const message = err instanceof Error ? err.message : String(err);
31739
+ if (message === NOT_LESION_MESSAGE && direction > 0) {
31740
+ growCutLog.info('ClickSegment: expand blocked by the lesion shape gate; previous result kept', { previousTolerance });
31741
+ this.notifySegmentationError('Expanding further would leak beyond a lesion-like shape; kept the previous result.');
31742
+ return;
31743
+ }
31744
+ growCutLog.error('ClickSegment: expand/shrink failed', { message });
31745
+ });
31746
+ }
31747
+ async refillAtTolerance(toleranceBytes) {
31748
+ const lastClick = this.lastClick;
31749
+ if (!lastClick) {
31750
+ return;
31751
+ }
31752
+ const { segmentation, viewportId, renderingEngineId } = lastClick;
31753
+ const labelmapVolume = esm.cache.getVolume(segmentation.labelmapVolumeId);
31754
+ const renderingEngine = (0,esm.getRenderingEngine)(renderingEngineId);
31755
+ const viewport = renderingEngine?.getViewport(viewportId);
31756
+ if (!labelmapVolume || !viewport) {
31757
+ growCutLog.warn('ClickSegment: labelmap or viewport gone; cannot expand/shrink');
31758
+ return;
31759
+ }
31760
+ const memo = this.beginLabelmapMemo(segmentation, labelmapVolume);
31761
+ try {
31762
+ const { voxelManager } = labelmapVolume;
31763
+ const historyVm = memo.voxelManager;
31764
+ const [width, height] = labelmapVolume.dimensions;
31765
+ const pixelsPerSlice = width * height;
31766
+ const { segmentIndex } = segmentation;
31767
+ const clearedIndices = [];
31768
+ for (const [x, y, z] of lastClick.filledPoints) {
31769
+ const index = z * pixelsPerSlice + y * width + x;
31770
+ if (voxelManager.getAtIndex(index) === segmentIndex) {
31771
+ historyVm.setAtIndex(index, 0);
31772
+ clearedIndices.push(index);
31773
+ }
31774
+ }
31775
+ const range = (0,adaptiveRegionIntensityRange/* .resolveAdaptiveBandAtTolerance */.CN)(lastClick.expandContext, toleranceBytes);
31776
+ try {
31777
+ const filledPoints = await this.fillWithRange(range, {
31778
+ segmentation,
31779
+ viewportId,
31780
+ renderingEngineId,
31781
+ }, viewport, labelmapVolume, this.lastHoverElement ?? undefined, memo);
31782
+ lastClick.toleranceBytes = toleranceBytes;
31783
+ lastClick.filledPoints = filledPoints;
31784
+ growCutLog.info('ClickSegment: refill complete', {
31785
+ toleranceBytes,
31786
+ filledVoxels: filledPoints.length,
31787
+ });
31788
+ }
31789
+ catch (err) {
31790
+ for (const index of clearedIndices) {
31791
+ historyVm.setAtIndex(index, segmentIndex);
31792
+ }
31793
+ (0,triggerSegmentationEvents.triggerSegmentationDataModified)(segmentation.segmentationId);
31794
+ throw err;
31795
+ }
31796
+ }
31797
+ finally {
31798
+ this.doneEditMemo();
31799
+ }
31800
+ }
31801
+ }
31802
+ ClickSegmentTool.toolName = 'ClickSegment';
31803
+ /* export default */ const annotation_ClickSegmentTool = ((/* unused pure expression or super */ null && (ClickSegmentTool)));
31804
+
31013
31805
  ;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/tools/annotation/WholeBodySegmentTool.js
31014
31806
 
31015
31807
 
@@ -32433,8 +33225,6 @@ CircleROIStartEndThresholdTool.toolName = 'CircleROIStartEndThreshold';
32433
33225
 
32434
33226
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/tools/segmentation/BrushTool.js
32435
33227
  var BrushTool = __webpack_require__(70947);
32436
- // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/stateManagement/segmentation/triggerSegmentationEvents.js + 4 modules
32437
- var triggerSegmentationEvents = __webpack_require__(49256);
32438
33228
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/segmentation/floodFill.js
32439
33229
  var floodFill = __webpack_require__(97637);
32440
33230
  ;// CONCATENATED MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/tools/segmentation/PaintFillTool.js
@@ -34126,6 +34916,7 @@ LabelMapEditWithContourTool.viewportIdsChecked = [];
34126
34916
 
34127
34917
 
34128
34918
 
34919
+
34129
34920
 
34130
34921
 
34131
34922
  // EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/tools/dist/esm/utilities/math/rectangle/index.js
@@ -36855,181 +37646,6 @@ __webpack_require__.d(__webpack_exports__, {
36855
37646
 
36856
37647
 
36857
37648
 
36858
- },
36859
- 88392(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
36860
- __webpack_require__.d(__webpack_exports__, {
36861
- AD: () => (registerLabelmap),
36862
- BS: () => (getLabelmapForVolumeId),
36863
- Hs: () => (getLabelmap),
36864
- M4: () => (getLabelmapForImageId),
36865
- kL: () => (getOrCreateLabelmapVolume),
36866
- m: () => (getLabelmaps)
36867
- });
36868
- /* import */ var _cornerstonejs_core__rspack_import_0 = __webpack_require__(88479);
36869
- /* import */ var _normalizeLabelmapSegmentationData_js__rspack_import_1 = __webpack_require__(209);
36870
- /* import */ var _labelmapImageIdMapping_js__rspack_import_2 = __webpack_require__(26372);
36871
-
36872
-
36873
-
36874
- function getLabelmap(segmentation, labelmapId) {
36875
- return (0,_normalizeLabelmapSegmentationData_js__rspack_import_1/* .ensureLabelmapState */.uk)(segmentation)?.labelmaps?.[labelmapId];
36876
- }
36877
- function getLabelmaps(segmentation) {
36878
- const labelmapState = (0,_normalizeLabelmapSegmentationData_js__rspack_import_1/* .ensureLabelmapState */.uk)(segmentation);
36879
- if (!labelmapState) {
36880
- return [];
36881
- }
36882
- return Object.values(labelmapState.labelmaps);
36883
- }
36884
- function registerLabelmap(segmentation, layer) {
36885
- const labelmapState = (0,_normalizeLabelmapSegmentationData_js__rspack_import_1/* .ensureLabelmapState */.uk)(segmentation);
36886
- if (!labelmapState) {
36887
- return;
36888
- }
36889
- labelmapState.labelmaps[layer.labelmapId] = layer;
36890
- }
36891
- function removeLabelmap(segmentation, labelmapId) {
36892
- const labelmapState = ensureLabelmapState(segmentation);
36893
- if (!labelmapState) {
36894
- return;
36895
- }
36896
- const layer = labelmapState.labelmaps[labelmapId];
36897
- if (layer?.geometryVolumeId && cache.getVolume(layer.geometryVolumeId)) {
36898
- cache.removeVolumeLoadObject(layer.geometryVolumeId);
36899
- }
36900
- delete labelmapState.labelmaps[labelmapId];
36901
- }
36902
- function getOrCreateLabelmapVolume(layer) {
36903
- const mergedVolume = getOrCreateMergedStackLabelmapVolume(layer);
36904
- if (mergedVolume) {
36905
- return mergedVolume;
36906
- }
36907
- const existingVolumeId = layer.volumeId ?? layer.geometryVolumeId;
36908
- if (existingVolumeId) {
36909
- const cachedVolume = _cornerstonejs_core__rspack_import_0.cache.getVolume(existingVolumeId);
36910
- if (cachedVolume) {
36911
- return cachedVolume;
36912
- }
36913
- }
36914
- const imageIds = layer.imageIds ?? [];
36915
- if (!imageIds.length) {
36916
- return;
36917
- }
36918
- const volumeId = layer.volumeId ?? layer.geometryVolumeId ?? `${layer.labelmapId}-geometry`;
36919
- if (!layer.volumeId) {
36920
- layer.geometryVolumeId = volumeId;
36921
- }
36922
- const cachedVolume = _cornerstonejs_core__rspack_import_0.cache.getVolume(volumeId);
36923
- if (cachedVolume) {
36924
- return cachedVolume;
36925
- }
36926
- return _cornerstonejs_core__rspack_import_0.volumeLoader.createAndCacheVolumeFromImagesSync(volumeId, imageIds);
36927
- }
36928
- function getOrCreateMergedStackLabelmapVolume(layer) {
36929
- if (layer.volumeId || !hasDuplicateReferencedImageIds(layer)) {
36930
- return;
36931
- }
36932
- const volumeId = layer.geometryVolumeId ?? `${layer.labelmapId}-geometry`;
36933
- const cachedVolume = _cornerstonejs_core__rspack_import_0.cache.getVolume(volumeId);
36934
- if (cachedVolume) {
36935
- return cachedVolume;
36936
- }
36937
- const imageIdsByReferencedImageId = new Map();
36938
- (0,_labelmapImageIdMapping_js__rspack_import_2/* .forEachLabelmapImageReference */.Zd)(layer, (referencedImageId, imageId) => {
36939
- const imageIdsForReference = imageIdsByReferencedImageId.get(referencedImageId) ?? [];
36940
- imageIdsForReference.push(imageId);
36941
- imageIdsByReferencedImageId.set(referencedImageId, imageIdsForReference);
36942
- });
36943
- const mergedReferencedImageIds = Array.from(imageIdsByReferencedImageId.keys());
36944
- if (!mergedReferencedImageIds.length) {
36945
- return;
36946
- }
36947
- let mergedImageIndex = 0;
36948
- const mergedImages = _cornerstonejs_core__rspack_import_0.imageLoader.createAndCacheDerivedImages(mergedReferencedImageIds, {
36949
- getDerivedImageId: () => `${volumeId}-image-${mergedImageIndex++}`,
36950
- targetBuffer: { type: 'Uint8Array' },
36951
- });
36952
- mergedImages.forEach((mergedImage) => {
36953
- const sourceImageIds = imageIdsByReferencedImageId.get(mergedImage.referencedImageId);
36954
- if (!sourceImageIds?.length) {
36955
- return;
36956
- }
36957
- const targetVoxelManager = mergedImage.voxelManager;
36958
- const scalarDataLength = targetVoxelManager.getScalarDataLength();
36959
- sourceImageIds.forEach((sourceImageId) => {
36960
- const sourceImage = _cornerstonejs_core__rspack_import_0.cache.getImage(sourceImageId);
36961
- const sourceVoxelManager = sourceImage?.voxelManager;
36962
- if (!sourceVoxelManager) {
36963
- return;
36964
- }
36965
- const sourceScalarDataLength = sourceVoxelManager.getScalarDataLength();
36966
- const length = Math.min(scalarDataLength, sourceScalarDataLength);
36967
- for (let index = 0; index < length; index++) {
36968
- const value = Number(sourceVoxelManager.getAtIndex(index));
36969
- if (value !== 0) {
36970
- targetVoxelManager.setAtIndex(index, value);
36971
- }
36972
- }
36973
- });
36974
- });
36975
- layer.geometryVolumeId = volumeId;
36976
- return _cornerstonejs_core__rspack_import_0.volumeLoader.createAndCacheVolumeFromImagesSync(volumeId, mergedImages.map((image) => image.imageId));
36977
- }
36978
- function hasDuplicateReferencedImageIds(layer) {
36979
- return (0,_labelmapImageIdMapping_js__rspack_import_2/* .hasMultipleLabelmapImagesPerReferencedImageId */.dm)(layer);
36980
- }
36981
- function getLabelmapIds(segmentation) {
36982
- return getLabelmaps(segmentation).map((layer) => layer.labelmapId);
36983
- }
36984
- function getLabelmapDataById(segmentation, labelmapId) {
36985
- const labelmapState = ensureLabelmapState(segmentation);
36986
- const layer = labelmapState?.labelmaps?.[labelmapId];
36987
- if (!labelmapState || !layer) {
36988
- return;
36989
- }
36990
- return {
36991
- volumeId: layer.volumeId,
36992
- referencedVolumeId: layer.referencedVolumeId,
36993
- imageIds: layer.imageIds,
36994
- referencedImageIds: layer.referencedImageIds,
36995
- sourceRepresentationName: labelmapState.sourceRepresentationName,
36996
- primaryLabelmapId: labelmapId,
36997
- labelmaps: {
36998
- [labelmapId]: layer,
36999
- },
37000
- segmentBindings: Object.fromEntries(Object.entries(labelmapState.segmentBindings).filter(([, binding]) => binding.labelmapId === labelmapId)),
37001
- };
37002
- }
37003
- function getScalarArrayLengthFromLabelmap(layer) {
37004
- if (layer.volumeId) {
37005
- return cache.getVolume(layer.volumeId)?.voxelManager?.getScalarDataLength();
37006
- }
37007
- const firstImageId = layer.imageIds?.[0];
37008
- const firstImage = firstImageId ? cache.getImage(firstImageId) : null;
37009
- if (!firstImage || !layer.imageIds?.length) {
37010
- return 0;
37011
- }
37012
- return firstImage.voxelManager.getScalarDataLength() * layer.imageIds.length;
37013
- }
37014
- function getConstructorNameForLabelmap(layer) {
37015
- if (layer.volumeId) {
37016
- return cache.getVolume(layer.volumeId)?.voxelManager?.getConstructor()
37017
- ?.name;
37018
- }
37019
- const imageId = layer.imageIds?.[0];
37020
- return imageId
37021
- ? cache.getImage(imageId)?.voxelManager?.getConstructor()?.name
37022
- : undefined;
37023
- }
37024
- function getLabelmapForImageId(segmentation, imageId) {
37025
- return getLabelmaps(segmentation).find((layer) => layer.imageIds?.includes(imageId));
37026
- }
37027
- function getLabelmapForVolumeId(segmentation, volumeId) {
37028
- return getLabelmaps(segmentation).find((layer) => layer.volumeId === volumeId || layer.geometryVolumeId === volumeId);
37029
- }
37030
-
37031
-
37032
-
37033
37649
  },
37034
37650
  85335(__unused_rspack___webpack_module__, __webpack_exports__, __webpack_require__) {
37035
37651
  __webpack_require__.d(__webpack_exports__, {