@ohif/app 3.12.0-beta.99 → 3.12.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/{1403.bundle.94a178e2572f1f0b2a2c.js → 1403.bundle.1c9ce804d1e88033e276.js} +4 -2
- package/dist/{147.bundle.205350dc3d21478277b1.js → 147.bundle.37d627289453cb6c3937.js} +6 -15
- package/dist/{1608.bundle.f855c4bdb7f00eb66fca.js → 1608.bundle.0687c661f1c9edfb3b8a.js} +4 -4
- package/dist/{1730.bundle.37c569ae3ed057b69840.js → 1730.bundle.66a5e554ab20dab97b11.js} +7 -5
- package/dist/{1927.bundle.019331c266d306772371.js → 1927.bundle.3050588e95f43cf57cdd.js} +1 -1
- package/dist/{1933.bundle.ab5e8036f6e1c854c965.js → 1933.bundle.682f142e3217d4c7fbf7.js} +7 -3
- package/dist/{2018.bundle.469f9ad42597b6b29ff1.js → 2018.bundle.c06693143228cc034cb9.js} +47 -47
- package/dist/{213.bundle.398730bb3ceb1af54413.js → 213.bundle.c2d4d7370c26b0823880.js} +2 -2
- package/dist/{2424.bundle.be90e7bcf0fd8db68b2f.js → 2424.bundle.c1e287e752f352b76543.js} +2 -2
- package/dist/{2701.bundle.aca0d4f24a6f2094c3c3.js → 2701.bundle.12bd01a80a9f8ea4cd94.js} +4 -4
- package/dist/{2842.bundle.7852a204d3510fca8b27.js → 2842.bundle.860b9f10fcdd9656947a.js} +330 -123
- package/dist/{1903.bundle.dc5248f7cb6ba1dc1072.js → 3081.bundle.41838985e0472851eadb.js} +644 -322
- package/dist/{3343.bundle.f8fe9316b0ff68d087f7.js → 3343.bundle.d7578ce8f75d158c0bab.js} +2 -0
- package/dist/{3461.bundle.50c752c623f39cf6c457.js → 3461.bundle.a8fcefd1c6e389d905fc.js} +21 -17
- package/dist/{3584.bundle.839a16d349815b3f7c97.js → 3584.bundle.8cc0750425513433e9cc.js} +15 -17
- package/dist/{4019.bundle.01f63d5dd5b96ded0c00.js → 4019.bundle.83a604779f7da0101ced.js} +196 -366
- package/dist/{4202.bundle.790706560c6edb303476.js → 4202.bundle.5a0f8e4004c5d8a68548.js} +2 -2
- package/dist/{5448.bundle.9a36e001169ea3bfeb6c.js → 4410.bundle.c5224cd7d6238a7d4660.js} +313 -57
- package/dist/{4775.bundle.d7f0645419f1df8e00b8.js → 4775.bundle.70bc407db26afaa4331a.js} +24 -16
- package/dist/{4819.bundle.ef1151f023b3784bc1be.js → 4819.bundle.47e7aa44747ddab3a39a.js} +8 -6
- package/dist/{5028.bundle.b3611b7c7422a5c2e723.js → 5028.bundle.274945a9ae69c6b6ad51.js} +6 -6
- package/dist/{5462.bundle.a81a691eeef782ab95b9.js → 5462.bundle.21beddaca145b7465c72.js} +2 -0
- package/dist/{5485.bundle.71041ca4bc9e6ab57d92.js → 5485.bundle.4e0ec03c61ec5cadd9bb.js} +3 -3
- package/dist/{5802.bundle.28ab859d9b48a5b2c31c.js → 5802.bundle.3bf5e6b3ab330a594a47.js} +6 -12
- package/dist/{6163.bundle.1f096bdbe3a341c1710d.js → 6163.bundle.ca93a4e6501880901f94.js} +4 -2
- package/dist/{3353.bundle.a0f1654c642395bbbbbc.js → 6347.bundle.784c48912700f281de1d.js} +323 -179
- package/dist/{5400.bundle.de97508611da1c00d58a.js → 6409.bundle.b36048896cb11c8571fb.js} +450 -79
- package/dist/{7412.bundle.aec4834a71fc27c4ce06.js → 7412.bundle.fab1742191b7fe937330.js} +251 -197
- package/dist/{7431.bundle.999b2b65d4973bc56218.js → 7431.bundle.b01791d10e6cf9f503b0.js} +10 -4
- package/dist/{7639.bundle.e004d734044049fe8fe9.js → 7639.bundle.32152cacb059089ed7d7.js} +24 -20
- package/dist/{8305.bundle.ba43ed23edea2bf394b3.js → 8305.bundle.2ede68ba3c075928c9f4.js} +47 -29
- package/dist/{8558.bundle.463ddb34a619cf47493e.js → 8558.bundle.3e84c4ba2c7ec6fce52c.js} +33 -3
- package/dist/{8583.bundle.59c239cf891c2e10bf10.js → 8583.bundle.2908eee785e7e4595d14.js} +28 -23
- package/dist/{9195.bundle.e2fd5c6b5830c0ee25a8.js → 9195.bundle.606ca286a0fed8a43f58.js} +146 -73
- package/dist/{9845.bundle.31aec3fe7a5cdc247f4e.js → 9845.bundle.255e7c7f7a88193b4e47.js} +16 -8
- package/dist/{9862.bundle.3ca0ad5f54db87ccf91e.js → 9862.bundle.3a8958a82c572015d25d.js} +2 -2
- package/dist/{9927.bundle.f421cd167be94a7109f6.js → 9927.bundle.e798a347dfe1f241578f.js} +16 -16
- package/dist/{5549.bundle.d5def6a3124a3a481b7c.js → 997.bundle.822b33e561263084e18c.js} +961 -290
- package/dist/{app.bundle.7df5bc1cd812bd602686.js → app.bundle.26b7eafdf05b5445414b.js} +5893 -2247
- package/dist/app.bundle.css +1 -1
- package/dist/{compute.bundle.fdee4a0f193ee2e1b6da.js → compute.bundle.64280c7af19ff567465f.js} +3 -3
- package/dist/dicom-microscopy-viewer/dicomMicroscopyViewer.min.js +3254 -1792
- package/dist/dicom-microscopy-viewer/dicomMicroscopyViewer.min.js.map +1 -1
- package/dist/index.html +1 -1
- package/dist/{polySeg.bundle.11f9746cd60c9811a412.js → polySeg.bundle.a5aa9130b4191253c410.js} +3 -3
- package/dist/sw.js +1 -1
- package/package.json +24 -24
- /package/dist/{1459.bundle.3785cdd0abf449adebf1.js → 1459.bundle.e8802999a4d7f7edf628.js} +0 -0
- /package/dist/{5457.bundle.9f2eb65ad85fcbb75e27.js → 5457.bundle.f7de73bcfe1012a73b9f.js} +0 -0
- /package/dist/{5858.bundle.d5f4bf849aaeebf5025c.js → 5858.bundle.ff6b340cf7457db76a1a.js} +0 -0
- /package/dist/{6027.bundle.160bd47ea03784276275.js → 6027.bundle.2b12862684b0cb3af4b4.js} +0 -0
- /package/dist/{85.bundle.a16e254910c60223df19.js → 85.bundle.05591d5a14d74a502dfe.js} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
(globalThis["webpackChunk"] = globalThis["webpackChunk"] || []).push([[
|
|
2
|
+
(globalThis["webpackChunk"] = globalThis["webpackChunk"] || []).push([[3081],{
|
|
3
3
|
|
|
4
4
|
/***/ 38007:
|
|
5
5
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
@@ -25,8 +25,8 @@ var useSegmentations = __webpack_require__(73421);
|
|
|
25
25
|
var useViewportSegmentations = __webpack_require__(79063);
|
|
26
26
|
// EXTERNAL MODULE: ../../../node_modules/react/index.js
|
|
27
27
|
var react = __webpack_require__(86326);
|
|
28
|
-
// EXTERNAL MODULE: ../../ui-next/src/index.ts +
|
|
29
|
-
var src = __webpack_require__(
|
|
28
|
+
// EXTERNAL MODULE: ../../ui-next/src/index.ts + 3075 modules
|
|
29
|
+
var src = __webpack_require__(12517);
|
|
30
30
|
;// ../../../extensions/cornerstone/src/hooks/useViewportHover.ts
|
|
31
31
|
|
|
32
32
|
|
|
@@ -117,7 +117,7 @@ var useViewportRendering = __webpack_require__(47488);
|
|
|
117
117
|
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
|
|
118
118
|
/* harmony export */ c: () => (/* binding */ useActiveViewportSegmentationRepresentations)
|
|
119
119
|
/* harmony export */ });
|
|
120
|
-
/* harmony import */ var _ohif_ui_next__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(
|
|
120
|
+
/* harmony import */ var _ohif_ui_next__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12517);
|
|
121
121
|
/* harmony import */ var _useViewportSegmentations__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(79063);
|
|
122
122
|
|
|
123
123
|
|
|
@@ -250,6 +250,8 @@ function useMeasurementTracking({
|
|
|
250
250
|
/* harmony import */ var lodash_debounce__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(62051);
|
|
251
251
|
/* harmony import */ var lodash_debounce__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(lodash_debounce__WEBPACK_IMPORTED_MODULE_1__);
|
|
252
252
|
/* harmony import */ var _ohif_core__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(42356);
|
|
253
|
+
/* harmony import */ var _ohif_i18n__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(89010);
|
|
254
|
+
|
|
253
255
|
|
|
254
256
|
|
|
255
257
|
|
|
@@ -268,7 +270,7 @@ function mapMeasurementToDisplay(measurement, displaySetService) {
|
|
|
268
270
|
displayText: baseDisplayText
|
|
269
271
|
} = measurement;
|
|
270
272
|
const firstSite = findingSites?.[0];
|
|
271
|
-
const label = baseLabel || finding?.text || firstSite?.text || '
|
|
273
|
+
const label = baseLabel || finding?.text || firstSite?.text || _ohif_i18n__WEBPACK_IMPORTED_MODULE_3__/* ["default"] */ .A.t('MeasurementTable:empty');
|
|
272
274
|
|
|
273
275
|
// Initialize displayText with the structure used in Length.ts and CobbAngle.ts
|
|
274
276
|
const displayText = {
|
|
@@ -496,8 +498,8 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
496
498
|
var react = __webpack_require__(86326);
|
|
497
499
|
// EXTERNAL MODULE: ../../core/src/index.ts + 69 modules
|
|
498
500
|
var src = __webpack_require__(42356);
|
|
499
|
-
// EXTERNAL MODULE: ../../ui-next/src/index.ts +
|
|
500
|
-
var ui_next_src = __webpack_require__(
|
|
501
|
+
// EXTERNAL MODULE: ../../ui-next/src/index.ts + 3075 modules
|
|
502
|
+
var ui_next_src = __webpack_require__(12517);
|
|
501
503
|
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/index.js + 1 modules
|
|
502
504
|
var esm = __webpack_require__(15327);
|
|
503
505
|
;// ../../../extensions/cornerstone/src/components/ViewportDataOverlaySettingMenu/utils.ts
|
|
@@ -1657,7 +1659,7 @@ function useViewportSegmentations({
|
|
|
1657
1659
|
|
|
1658
1660
|
/***/ }),
|
|
1659
1661
|
|
|
1660
|
-
/***/
|
|
1662
|
+
/***/ 63081:
|
|
1661
1663
|
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
|
|
1662
1664
|
|
|
1663
1665
|
// ESM COMPAT FLAG
|
|
@@ -6985,8 +6987,8 @@ var useLutPresentationStore = __webpack_require__(10182);
|
|
|
6985
6987
|
var usePositionPresentationStore = __webpack_require__(44646);
|
|
6986
6988
|
// EXTERNAL MODULE: ../../../extensions/cornerstone/src/stores/useSegmentationPresentationStore.ts + 1 modules
|
|
6987
6989
|
var useSegmentationPresentationStore = __webpack_require__(2847);
|
|
6988
|
-
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/utilities/index.js +
|
|
6989
|
-
var esm_utilities = __webpack_require__(
|
|
6990
|
+
// EXTERNAL MODULE: ../../../node_modules/@cornerstonejs/core/dist/esm/utilities/index.js + 47 modules
|
|
6991
|
+
var esm_utilities = __webpack_require__(85343);
|
|
6990
6992
|
;// ../../../extensions/cornerstone/src/utils/initWebWorkerProgressHandler.ts
|
|
6991
6993
|
|
|
6992
6994
|
|
|
@@ -7471,8 +7473,8 @@ function _showCPURenderingModal(uiModalService, hangingProtocolService) {
|
|
|
7471
7473
|
inheritsFrom: 'ohif.overlayItem.instanceNumber'
|
|
7472
7474
|
}]
|
|
7473
7475
|
});
|
|
7474
|
-
// EXTERNAL MODULE: ../../ui-next/src/index.ts +
|
|
7475
|
-
var ui_next_src = __webpack_require__(
|
|
7476
|
+
// EXTERNAL MODULE: ../../ui-next/src/index.ts + 3075 modules
|
|
7477
|
+
var ui_next_src = __webpack_require__(12517);
|
|
7476
7478
|
// EXTERNAL MODULE: ../../../node_modules/react-i18next/dist/es/index.js + 15 modules
|
|
7477
7479
|
var es = __webpack_require__(99993);
|
|
7478
7480
|
;// ../../../extensions/cornerstone/src/components/ExportSegmentationSubMenuItem.tsx
|
|
@@ -7488,7 +7490,7 @@ const ExportSegmentationSubMenuItem = ({
|
|
|
7488
7490
|
}) => {
|
|
7489
7491
|
const {
|
|
7490
7492
|
t
|
|
7491
|
-
} = (0,es/* useTranslation */.Bd)('
|
|
7493
|
+
} = (0,es/* useTranslation */.Bd)('SegmentationPanel');
|
|
7492
7494
|
return /*#__PURE__*/react.createElement(ui_next_src/* DropdownMenuSub */.lvB, null, /*#__PURE__*/react.createElement(ui_next_src/* DropdownMenuSubTrigger */.nVd, {
|
|
7493
7495
|
className: "pl-1"
|
|
7494
7496
|
}, /*#__PURE__*/react.createElement(ui_next_src/* Icons */.FI1.Export, {
|
|
@@ -7555,7 +7557,7 @@ const CustomDropdownMenuContent = () => {
|
|
|
7555
7557
|
} = (0,src/* useSystem */.Jg)();
|
|
7556
7558
|
const {
|
|
7557
7559
|
t
|
|
7558
|
-
} = (0,es/* useTranslation */.Bd)('
|
|
7560
|
+
} = (0,es/* useTranslation */.Bd)('SegmentationPanel');
|
|
7559
7561
|
const {
|
|
7560
7562
|
onSegmentationAdd,
|
|
7561
7563
|
onSegmentationRemoveFromViewport,
|
|
@@ -7564,7 +7566,7 @@ const CustomDropdownMenuContent = () => {
|
|
|
7564
7566
|
exportOptions,
|
|
7565
7567
|
activeSegmentation,
|
|
7566
7568
|
activeSegmentationId,
|
|
7567
|
-
|
|
7569
|
+
segmentationRepresentationTypes,
|
|
7568
7570
|
disableEditing
|
|
7569
7571
|
} = (0,ui_next_src/* useSegmentationTableContext */.dQ$)('CustomDropdownMenu');
|
|
7570
7572
|
|
|
@@ -7623,7 +7625,7 @@ const CustomDropdownMenuContent = () => {
|
|
|
7623
7625
|
}, !disableEditing && /*#__PURE__*/react.createElement(ui_next_src/* DropdownMenuItem */._26, {
|
|
7624
7626
|
onClick: () => onSegmentationAdd({
|
|
7625
7627
|
segmentationId,
|
|
7626
|
-
segmentationRepresentationType
|
|
7628
|
+
segmentationRepresentationType: segmentationRepresentationTypes?.[0]
|
|
7627
7629
|
})
|
|
7628
7630
|
}, /*#__PURE__*/react.createElement(ui_next_src/* Icons */.FI1.Add, {
|
|
7629
7631
|
className: "text-foreground"
|
|
@@ -7643,7 +7645,7 @@ const CustomDropdownMenuContent = () => {
|
|
|
7643
7645
|
className: "pl-2"
|
|
7644
7646
|
}, t('Rename'))), /*#__PURE__*/react.createElement(ExportSegmentationSubMenuItem, {
|
|
7645
7647
|
segmentationId: segmentationId,
|
|
7646
|
-
segmentationRepresentationType:
|
|
7648
|
+
segmentationRepresentationType: segmentationRepresentationTypes?.[0],
|
|
7647
7649
|
allowExport: allowExport,
|
|
7648
7650
|
actions: actions
|
|
7649
7651
|
}), /*#__PURE__*/react.createElement(ui_next_src/* DropdownMenuSeparator */.mBJ, null), /*#__PURE__*/react.createElement(ui_next_src/* DropdownMenuItem */._26, {
|
|
@@ -7677,7 +7679,7 @@ const CustomSegmentStatisticsHeader = ({
|
|
|
7677
7679
|
} = servicesManager.services;
|
|
7678
7680
|
const {
|
|
7679
7681
|
t
|
|
7680
|
-
} = (0,es/* useTranslation */.Bd)('
|
|
7682
|
+
} = (0,es/* useTranslation */.Bd)('SegmentationPanel');
|
|
7681
7683
|
const segmentation = segmentationService.getSegmentation(segmentationId);
|
|
7682
7684
|
const segment = segmentation.segments[segmentIndex];
|
|
7683
7685
|
const cachedStats = segment.cachedStats;
|
|
@@ -7770,10 +7772,14 @@ const CustomSegmentStatisticsHeader = ({
|
|
|
7770
7772
|
|
|
7771
7773
|
|
|
7772
7774
|
|
|
7775
|
+
|
|
7773
7776
|
function SegmentationToolConfig() {
|
|
7774
7777
|
const {
|
|
7775
7778
|
commandsManager
|
|
7776
7779
|
} = (0,src/* useSystem */.Jg)();
|
|
7780
|
+
const {
|
|
7781
|
+
t
|
|
7782
|
+
} = (0,es/* useTranslation */.Bd)('SegmentationPanel');
|
|
7777
7783
|
|
|
7778
7784
|
// Get initial states based on current configuration
|
|
7779
7785
|
const [previewEdits, setPreviewEdits] = (0,react.useState)(false);
|
|
@@ -7813,28 +7819,28 @@ function SegmentationToolConfig() {
|
|
|
7813
7819
|
onCheckedChange: handlePreviewEditsChange
|
|
7814
7820
|
}), /*#__PURE__*/react.createElement("span", {
|
|
7815
7821
|
className: "text-foreground text-base"
|
|
7816
|
-
},
|
|
7822
|
+
}, t('Preview edits before creating'))), /*#__PURE__*/react.createElement("div", {
|
|
7817
7823
|
className: "flex items-center gap-2"
|
|
7818
7824
|
}, /*#__PURE__*/react.createElement(ui_next_src/* Switch */.dOG, {
|
|
7819
7825
|
checked: useCenterAsSegmentIndex,
|
|
7820
7826
|
onCheckedChange: handleUseCenterAsSegmentIndexChange
|
|
7821
7827
|
}), /*#__PURE__*/react.createElement("span", {
|
|
7822
7828
|
className: "text-foreground text-base"
|
|
7823
|
-
},
|
|
7829
|
+
}, t('Use center as segment index'))), /*#__PURE__*/react.createElement("div", {
|
|
7824
7830
|
className: "flex items-center gap-2"
|
|
7825
7831
|
}, /*#__PURE__*/react.createElement(ui_next_src/* Switch */.dOG, {
|
|
7826
7832
|
checked: toggleSegmentEnabled,
|
|
7827
7833
|
onCheckedChange: handleToggleSegmentEnabledChange
|
|
7828
7834
|
}), /*#__PURE__*/react.createElement("span", {
|
|
7829
7835
|
className: "text-foreground text-base"
|
|
7830
|
-
},
|
|
7836
|
+
}, t('Hover on segment border to activate'))), /*#__PURE__*/react.createElement("div", {
|
|
7831
7837
|
className: "flex items-center gap-2"
|
|
7832
7838
|
}, /*#__PURE__*/react.createElement(ui_next_src/* Switch */.dOG, {
|
|
7833
7839
|
checked: segmentLabelEnabled,
|
|
7834
7840
|
onCheckedChange: handleSegmentLabelEnabledChange
|
|
7835
7841
|
}), /*#__PURE__*/react.createElement("span", {
|
|
7836
7842
|
className: "text-foreground text-base"
|
|
7837
|
-
},
|
|
7843
|
+
}, t('Show segment name on hover'))));
|
|
7838
7844
|
}
|
|
7839
7845
|
;// ../../../extensions/cornerstone/src/customizations/segmentationPanelCustomization.tsx
|
|
7840
7846
|
|
|
@@ -9100,6 +9106,10 @@ function ViewportDownloadFormNew({
|
|
|
9100
9106
|
})), /*#__PURE__*/react.createElement(ui_next_src/* ImageModal */.jiK.ImageSize, {
|
|
9101
9107
|
width: dimensions.width.toString(),
|
|
9102
9108
|
height: dimensions.height.toString(),
|
|
9109
|
+
widthLabel: t('Width'),
|
|
9110
|
+
heightLabel: t('Height'),
|
|
9111
|
+
widthPlaceholder: t('Width'),
|
|
9112
|
+
heightPlaceholder: t('Height'),
|
|
9103
9113
|
onWidthChange: e => {
|
|
9104
9114
|
onDimensionsChange({
|
|
9105
9115
|
...dimensions,
|
|
@@ -9114,9 +9124,7 @@ function ViewportDownloadFormNew({
|
|
|
9114
9124
|
},
|
|
9115
9125
|
maxWidth: MAX_TEXTURE_SIZE.toString(),
|
|
9116
9126
|
maxHeight: MAX_TEXTURE_SIZE.toString()
|
|
9117
|
-
}, t('Image size'),
|
|
9118
|
-
className: "text-muted-foreground"
|
|
9119
|
-
}, "px")), /*#__PURE__*/react.createElement(ui_next_src/* ImageModal */.jiK.SwitchOption, {
|
|
9127
|
+
}, t('Image size in pixels')), /*#__PURE__*/react.createElement(ui_next_src/* ImageModal */.jiK.SwitchOption, {
|
|
9120
9128
|
defaultChecked: showAnnotations,
|
|
9121
9129
|
checked: showAnnotations,
|
|
9122
9130
|
onCheckedChange: onAnnotationsChange
|
|
@@ -9505,9 +9513,14 @@ const CornerstoneViewportDownloadForm = ({
|
|
|
9505
9513
|
mode,
|
|
9506
9514
|
bindings
|
|
9507
9515
|
} = toolModeAndBindings[toolName];
|
|
9508
|
-
|
|
9509
|
-
|
|
9510
|
-
|
|
9516
|
+
try {
|
|
9517
|
+
toolGroup.setToolMode(toolName, mode, {
|
|
9518
|
+
bindings
|
|
9519
|
+
});
|
|
9520
|
+
} catch (error) {
|
|
9521
|
+
// Handle errors when restoring tool mode during cleanup (e.g., when tool state is undefined)
|
|
9522
|
+
console.debug('Error restoring tool mode during cleanup:', toolName, error);
|
|
9523
|
+
}
|
|
9511
9524
|
});
|
|
9512
9525
|
};
|
|
9513
9526
|
}, []);
|
|
@@ -9557,7 +9570,7 @@ const CornerstoneViewportDownloadForm = ({
|
|
|
9557
9570
|
volumeId: volumeIds[0]
|
|
9558
9571
|
}]);
|
|
9559
9572
|
}
|
|
9560
|
-
if (segmentationRepresentations
|
|
9573
|
+
if (segmentationRepresentations?.length) {
|
|
9561
9574
|
segmentationRepresentations.forEach(segRepresentation => {
|
|
9562
9575
|
const {
|
|
9563
9576
|
segmentationId,
|
|
@@ -9638,14 +9651,17 @@ const CornerstoneViewportDownloadForm = ({
|
|
|
9638
9651
|
}, 100);
|
|
9639
9652
|
}
|
|
9640
9653
|
}, [viewportDimensions, showAnnotations]);
|
|
9641
|
-
const handleDownload = async (
|
|
9654
|
+
const handleDownload = async (baseFilename, fileType) => {
|
|
9642
9655
|
const divForDownloadViewport = document.querySelector(`div[data-viewport-uid="${VIEWPORT_ID}"]`);
|
|
9643
9656
|
if (!divForDownloadViewport) {
|
|
9644
9657
|
console.debug('No viewport found for download');
|
|
9645
9658
|
return;
|
|
9646
9659
|
}
|
|
9660
|
+
const filename = `${baseFilename}.${fileType}`;
|
|
9647
9661
|
const canvas = await (0,html2canvas_esm/* default */.A)(divForDownloadViewport);
|
|
9648
|
-
downloadUrl(canvas.toDataURL(`image/${fileType}`, 1.0)
|
|
9662
|
+
downloadUrl(canvas.toDataURL(`image/${fileType}`, 1.0), {
|
|
9663
|
+
filename
|
|
9664
|
+
});
|
|
9649
9665
|
};
|
|
9650
9666
|
const ViewportDownloadFormNew = customizationService.getCustomization('ohif.captureViewportModal');
|
|
9651
9667
|
return /*#__PURE__*/react.createElement(ViewportDownloadFormNew, {
|
|
@@ -9707,6 +9723,11 @@ async function updateSegmentationStats({
|
|
|
9707
9723
|
// Loop through each segment's stats
|
|
9708
9724
|
Object.entries(stats).forEach(([segmentIndex, segmentStats]) => {
|
|
9709
9725
|
const index = parseInt(segmentIndex);
|
|
9726
|
+
if (!updatedSegmentation.segments[index]) {
|
|
9727
|
+
// This happens when a segment is being restored
|
|
9728
|
+
console.warn('Segment not found to update cached stats:', index);
|
|
9729
|
+
return;
|
|
9730
|
+
}
|
|
9710
9731
|
if (!updatedSegmentation.segments[index].cachedStats) {
|
|
9711
9732
|
updatedSegmentation.segments[index].cachedStats = {};
|
|
9712
9733
|
hasUpdates = true;
|
|
@@ -10317,8 +10338,8 @@ let EasingFunctionEnum = /*#__PURE__*/function (EasingFunctionEnum) {
|
|
|
10317
10338
|
return EasingFunctionEnum;
|
|
10318
10339
|
}({});
|
|
10319
10340
|
const EasingFunctionMap = new Map([[EasingFunctionEnum.EASE, ease], [EasingFunctionEnum.EASE_IN, easeIn], [EasingFunctionEnum.EASE_OUT, easeOut], [EasingFunctionEnum.EASE_IN_OUT, easeInOut], [EasingFunctionEnum.LINEAR, linear]]);
|
|
10320
|
-
// EXTERNAL MODULE: ../../i18n/src/index.js +
|
|
10321
|
-
var i18n_src = __webpack_require__(
|
|
10341
|
+
// EXTERNAL MODULE: ../../i18n/src/index.js + 286 modules
|
|
10342
|
+
var i18n_src = __webpack_require__(89010);
|
|
10322
10343
|
;// ../../../extensions/cornerstone/src/utils/createSegmentationForViewport.ts
|
|
10323
10344
|
|
|
10324
10345
|
|
|
@@ -10523,6 +10544,42 @@ function commandsModule({
|
|
|
10523
10544
|
}
|
|
10524
10545
|
}
|
|
10525
10546
|
}
|
|
10547
|
+
|
|
10548
|
+
/**
|
|
10549
|
+
* Creates a command function that sets a style property for segmentation types.
|
|
10550
|
+
* If type is provided, sets the property for that type only.
|
|
10551
|
+
* If type is not provided, sets the property for both Labelmap and Contour types.
|
|
10552
|
+
* @param propertyName - The name of the style property to set
|
|
10553
|
+
* @returns A command function that takes { type, value }
|
|
10554
|
+
*/
|
|
10555
|
+
const createSetStyleCommand = propertyName => {
|
|
10556
|
+
return ({
|
|
10557
|
+
type,
|
|
10558
|
+
value
|
|
10559
|
+
}) => {
|
|
10560
|
+
const {
|
|
10561
|
+
segmentationService
|
|
10562
|
+
} = servicesManager.services;
|
|
10563
|
+
if (type) {
|
|
10564
|
+
segmentationService.setStyle({
|
|
10565
|
+
type
|
|
10566
|
+
}, {
|
|
10567
|
+
[propertyName]: value
|
|
10568
|
+
});
|
|
10569
|
+
} else {
|
|
10570
|
+
segmentationService.setStyle({
|
|
10571
|
+
type: esm_enums.SegmentationRepresentations.Labelmap
|
|
10572
|
+
}, {
|
|
10573
|
+
[propertyName]: value
|
|
10574
|
+
});
|
|
10575
|
+
segmentationService.setStyle({
|
|
10576
|
+
type: esm_enums.SegmentationRepresentations.Contour
|
|
10577
|
+
}, {
|
|
10578
|
+
[propertyName]: value
|
|
10579
|
+
});
|
|
10580
|
+
}
|
|
10581
|
+
};
|
|
10582
|
+
};
|
|
10526
10583
|
const actions = {
|
|
10527
10584
|
jumpToMeasurementViewport: ({
|
|
10528
10585
|
annotationUID,
|
|
@@ -11965,7 +12022,7 @@ function commandsModule({
|
|
|
11965
12022
|
animationFunctionType
|
|
11966
12023
|
} = customizationService.getCustomization('panelSegmentation.jumpToSegmentHighlightAnimationConfig') ?? {};
|
|
11967
12024
|
const validAnimationFunctionType = Object.values(EasingFunctionEnum).includes(animationFunctionType) ? animationFunctionType : undefined;
|
|
11968
|
-
segmentationService.
|
|
12025
|
+
segmentationService.jumpToSegmentNext(segmentationId, segmentIndex, undefined, highlightAlpha, highlightSegment, animationLength, undefined, validAnimationFunctionType);
|
|
11969
12026
|
},
|
|
11970
12027
|
/**
|
|
11971
12028
|
* Toggles the visibility of a segment
|
|
@@ -12139,146 +12196,6 @@ function commandsModule({
|
|
|
12139
12196
|
const renderInactive = segmentationService.getRenderInactiveSegmentations(viewportId);
|
|
12140
12197
|
segmentationService.setRenderInactiveSegmentations(viewportId, !renderInactive);
|
|
12141
12198
|
},
|
|
12142
|
-
/**
|
|
12143
|
-
* Sets the fill alpha value for a segmentation type
|
|
12144
|
-
* @param props.type - The type of segmentation
|
|
12145
|
-
* @param props.value - The alpha value to set
|
|
12146
|
-
*/
|
|
12147
|
-
setFillAlphaCommand: ({
|
|
12148
|
-
type,
|
|
12149
|
-
value
|
|
12150
|
-
}) => {
|
|
12151
|
-
const {
|
|
12152
|
-
segmentationService
|
|
12153
|
-
} = servicesManager.services;
|
|
12154
|
-
segmentationService.setStyle({
|
|
12155
|
-
type
|
|
12156
|
-
}, {
|
|
12157
|
-
fillAlpha: value
|
|
12158
|
-
});
|
|
12159
|
-
},
|
|
12160
|
-
/**
|
|
12161
|
-
* Sets the outline width for a segmentation type
|
|
12162
|
-
* @param props.type - The type of segmentation
|
|
12163
|
-
* @param props.value - The width value to set
|
|
12164
|
-
*/
|
|
12165
|
-
setOutlineWidthCommand: ({
|
|
12166
|
-
type,
|
|
12167
|
-
value
|
|
12168
|
-
}) => {
|
|
12169
|
-
const {
|
|
12170
|
-
segmentationService
|
|
12171
|
-
} = servicesManager.services;
|
|
12172
|
-
segmentationService.setStyle({
|
|
12173
|
-
type
|
|
12174
|
-
}, {
|
|
12175
|
-
outlineWidth: value
|
|
12176
|
-
});
|
|
12177
|
-
},
|
|
12178
|
-
/**
|
|
12179
|
-
* Sets whether to render fill for a segmentation type
|
|
12180
|
-
* @param props.type - The type of segmentation
|
|
12181
|
-
* @param props.value - Whether to render fill
|
|
12182
|
-
*/
|
|
12183
|
-
setRenderFillCommand: ({
|
|
12184
|
-
type,
|
|
12185
|
-
value
|
|
12186
|
-
}) => {
|
|
12187
|
-
const {
|
|
12188
|
-
segmentationService
|
|
12189
|
-
} = servicesManager.services;
|
|
12190
|
-
segmentationService.setStyle({
|
|
12191
|
-
type
|
|
12192
|
-
}, {
|
|
12193
|
-
renderFill: value
|
|
12194
|
-
});
|
|
12195
|
-
},
|
|
12196
|
-
/**
|
|
12197
|
-
* Sets whether to render fill for inactive segmentations of a segmentation type
|
|
12198
|
-
* @param props.type - The type of segmentation
|
|
12199
|
-
* @param props.value - Whether to render fill for inactive segmentations
|
|
12200
|
-
*/
|
|
12201
|
-
setRenderFillInactiveCommand: ({
|
|
12202
|
-
type,
|
|
12203
|
-
value
|
|
12204
|
-
}) => {
|
|
12205
|
-
const {
|
|
12206
|
-
segmentationService
|
|
12207
|
-
} = servicesManager.services;
|
|
12208
|
-
segmentationService.setStyle({
|
|
12209
|
-
type
|
|
12210
|
-
}, {
|
|
12211
|
-
renderFillInactive: value
|
|
12212
|
-
});
|
|
12213
|
-
},
|
|
12214
|
-
/**
|
|
12215
|
-
* Sets whether to render outline for a segmentation type
|
|
12216
|
-
* @param props.type - The type of segmentation
|
|
12217
|
-
* @param props.value - Whether to render outline
|
|
12218
|
-
*/
|
|
12219
|
-
setRenderOutlineCommand: ({
|
|
12220
|
-
type,
|
|
12221
|
-
value
|
|
12222
|
-
}) => {
|
|
12223
|
-
const {
|
|
12224
|
-
segmentationService
|
|
12225
|
-
} = servicesManager.services;
|
|
12226
|
-
segmentationService.setStyle({
|
|
12227
|
-
type
|
|
12228
|
-
}, {
|
|
12229
|
-
renderOutline: value
|
|
12230
|
-
});
|
|
12231
|
-
},
|
|
12232
|
-
/**
|
|
12233
|
-
* Sets whether to render outline for inactive segmentations of a segmentation type
|
|
12234
|
-
* @param props.type - The type of segmentation
|
|
12235
|
-
* @param props.value - Whether to render outline for inactive segmentations
|
|
12236
|
-
*/
|
|
12237
|
-
setRenderOutlineInactiveCommand: ({
|
|
12238
|
-
type,
|
|
12239
|
-
value
|
|
12240
|
-
}) => {
|
|
12241
|
-
const {
|
|
12242
|
-
segmentationService
|
|
12243
|
-
} = servicesManager.services;
|
|
12244
|
-
segmentationService.setStyle({
|
|
12245
|
-
type
|
|
12246
|
-
}, {
|
|
12247
|
-
renderOutlineInactive: value
|
|
12248
|
-
});
|
|
12249
|
-
},
|
|
12250
|
-
/**
|
|
12251
|
-
* Sets the fill alpha for inactive segmentations.
|
|
12252
|
-
* If no type is provided, the fill alpha for all types will be set.
|
|
12253
|
-
* @param props.type - The type of segmentation
|
|
12254
|
-
* @param props.value - The alpha value to set
|
|
12255
|
-
*/
|
|
12256
|
-
setFillAlphaInactiveCommand: ({
|
|
12257
|
-
type,
|
|
12258
|
-
value
|
|
12259
|
-
}) => {
|
|
12260
|
-
const {
|
|
12261
|
-
segmentationService
|
|
12262
|
-
} = servicesManager.services;
|
|
12263
|
-
if (type) {
|
|
12264
|
-
segmentationService.setStyle({
|
|
12265
|
-
type
|
|
12266
|
-
}, {
|
|
12267
|
-
fillAlphaInactive: value
|
|
12268
|
-
});
|
|
12269
|
-
} else {
|
|
12270
|
-
segmentationService.setStyle({
|
|
12271
|
-
type: esm_enums.SegmentationRepresentations.Labelmap
|
|
12272
|
-
}, {
|
|
12273
|
-
fillAlphaInactive: value
|
|
12274
|
-
});
|
|
12275
|
-
segmentationService.setStyle({
|
|
12276
|
-
type: esm_enums.SegmentationRepresentations.Contour
|
|
12277
|
-
}, {
|
|
12278
|
-
fillAlphaInactive: value
|
|
12279
|
-
});
|
|
12280
|
-
}
|
|
12281
|
-
},
|
|
12282
12199
|
editSegmentLabel: async ({
|
|
12283
12200
|
segmentationId,
|
|
12284
12201
|
segmentIndex
|
|
@@ -13230,25 +13147,25 @@ function commandsModule({
|
|
|
13230
13147
|
commandFn: actions.toggleRenderInactiveSegmentationsCommand
|
|
13231
13148
|
},
|
|
13232
13149
|
setFillAlpha: {
|
|
13233
|
-
commandFn:
|
|
13150
|
+
commandFn: createSetStyleCommand('fillAlpha')
|
|
13234
13151
|
},
|
|
13235
13152
|
setOutlineWidth: {
|
|
13236
|
-
commandFn:
|
|
13153
|
+
commandFn: createSetStyleCommand('outlineWidth')
|
|
13237
13154
|
},
|
|
13238
13155
|
setRenderFill: {
|
|
13239
|
-
commandFn:
|
|
13156
|
+
commandFn: createSetStyleCommand('renderFill')
|
|
13240
13157
|
},
|
|
13241
13158
|
setRenderFillInactive: {
|
|
13242
|
-
commandFn:
|
|
13159
|
+
commandFn: createSetStyleCommand('renderFillInactive')
|
|
13243
13160
|
},
|
|
13244
13161
|
setRenderOutline: {
|
|
13245
|
-
commandFn:
|
|
13162
|
+
commandFn: createSetStyleCommand('renderOutline')
|
|
13246
13163
|
},
|
|
13247
13164
|
setRenderOutlineInactive: {
|
|
13248
|
-
commandFn:
|
|
13165
|
+
commandFn: createSetStyleCommand('renderOutlineInactive')
|
|
13249
13166
|
},
|
|
13250
13167
|
setFillAlphaInactive: {
|
|
13251
|
-
commandFn:
|
|
13168
|
+
commandFn: createSetStyleCommand('fillAlphaInactive')
|
|
13252
13169
|
},
|
|
13253
13170
|
editSegmentLabel: {
|
|
13254
13171
|
commandFn: actions.editSegmentLabel
|
|
@@ -15391,6 +15308,7 @@ var hooks = __webpack_require__(38007);
|
|
|
15391
15308
|
|
|
15392
15309
|
|
|
15393
15310
|
|
|
15311
|
+
|
|
15394
15312
|
function ViewportDataOverlayMenu({
|
|
15395
15313
|
viewportId
|
|
15396
15314
|
}) {
|
|
@@ -15398,6 +15316,9 @@ function ViewportDataOverlayMenu({
|
|
|
15398
15316
|
commandsManager,
|
|
15399
15317
|
servicesManager
|
|
15400
15318
|
} = (0,src/* useSystem */.Jg)();
|
|
15319
|
+
const {
|
|
15320
|
+
t
|
|
15321
|
+
} = (0,es/* useTranslation */.Bd)();
|
|
15401
15322
|
const [pendingForegrounds, setPendingForegrounds] = (0,react.useState)([]);
|
|
15402
15323
|
const [pendingSegmentations, setPendingSegmentations] = (0,react.useState)([]);
|
|
15403
15324
|
const {
|
|
@@ -15555,7 +15476,7 @@ function ViewportDataOverlayMenu({
|
|
|
15555
15476
|
disabled: potentialForegroundDisplaySets.length === 0
|
|
15556
15477
|
}, /*#__PURE__*/react.createElement(ui_next_src/* Icons */.FI1.Plus, {
|
|
15557
15478
|
className: "h-4 w-4"
|
|
15558
|
-
}),
|
|
15479
|
+
}), t('Common:Foreground')), /*#__PURE__*/react.createElement(ui_next_src/* Button */.$nd, {
|
|
15559
15480
|
variant: "ghost",
|
|
15560
15481
|
className: "text-primary ml-2 flex items-center",
|
|
15561
15482
|
disabled: potentialOverlayDisplaySets.length === 0,
|
|
@@ -15565,7 +15486,7 @@ function ViewportDataOverlayMenu({
|
|
|
15565
15486
|
dataCY: `AddSegmentationDataOverlay-${viewportId}`
|
|
15566
15487
|
}, /*#__PURE__*/react.createElement(ui_next_src/* Icons */.FI1.Plus, {
|
|
15567
15488
|
className: "h-4 w-4"
|
|
15568
|
-
}),
|
|
15489
|
+
}), t('Tools:Segmentation'))), /*#__PURE__*/react.createElement("div", {
|
|
15569
15490
|
className: ""
|
|
15570
15491
|
}, /*#__PURE__*/react.createElement("div", {
|
|
15571
15492
|
className: "my-2 ml-1"
|
|
@@ -15618,7 +15539,7 @@ function ViewportDataOverlayMenu({
|
|
|
15618
15539
|
}, /*#__PURE__*/react.createElement(ui_next_src/* SelectTrigger */.bqE, {
|
|
15619
15540
|
className: "flex-1"
|
|
15620
15541
|
}, /*#__PURE__*/react.createElement(ui_next_src/* SelectValue */.yvm, {
|
|
15621
|
-
placeholder:
|
|
15542
|
+
placeholder: t('Common:SELECT A SEGMENTATION')
|
|
15622
15543
|
})), /*#__PURE__*/react.createElement(ui_next_src/* SelectContent */.gCo, null, potentialOverlayDisplaySets.map(item => /*#__PURE__*/react.createElement(ui_next_src/* SelectItem */.ebT, {
|
|
15623
15544
|
key: item.displaySetInstanceUID,
|
|
15624
15545
|
value: item.displaySetInstanceUID,
|
|
@@ -15688,7 +15609,7 @@ function ViewportDataOverlayMenu({
|
|
|
15688
15609
|
}, /*#__PURE__*/react.createElement(ui_next_src/* SelectTrigger */.bqE, {
|
|
15689
15610
|
className: "flex-1"
|
|
15690
15611
|
}, /*#__PURE__*/react.createElement(ui_next_src/* SelectValue */.yvm, {
|
|
15691
|
-
placeholder:
|
|
15612
|
+
placeholder: t('Common:SELECT A FOREGROUND')
|
|
15692
15613
|
})), /*#__PURE__*/react.createElement(ui_next_src/* SelectContent */.gCo, null, potentialForegroundDisplaySets.map(item => /*#__PURE__*/react.createElement(ui_next_src/* SelectItem */.ebT, {
|
|
15693
15614
|
key: item.displaySetInstanceUID,
|
|
15694
15615
|
value: item.displaySetInstanceUID,
|
|
@@ -16131,7 +16052,9 @@ function Colormap({
|
|
|
16131
16052
|
className: "p-1"
|
|
16132
16053
|
}, colormaps.map((colormap, index) => /*#__PURE__*/react.createElement(ui_next_src/* AllInOneMenu */.se.Item, {
|
|
16133
16054
|
key: index,
|
|
16134
|
-
label: colormap.
|
|
16055
|
+
label: t(`Colormaps:${colormap.Name}`, {
|
|
16056
|
+
defaultValue: colormap.Name
|
|
16057
|
+
}),
|
|
16135
16058
|
useIconSpace: false,
|
|
16136
16059
|
onClick: () => {
|
|
16137
16060
|
setCurrentColormap(colormap);
|
|
@@ -16188,9 +16111,13 @@ function Colorbar({
|
|
|
16188
16111
|
|
|
16189
16112
|
|
|
16190
16113
|
|
|
16114
|
+
|
|
16191
16115
|
function WindowLevel({
|
|
16192
16116
|
viewportId
|
|
16193
16117
|
} = {}) {
|
|
16118
|
+
const {
|
|
16119
|
+
t
|
|
16120
|
+
} = (0,es/* useTranslation */.Bd)('WindowLevelActionMenu');
|
|
16194
16121
|
const {
|
|
16195
16122
|
viewportDisplaySets
|
|
16196
16123
|
} = (0,useViewportRendering/* useViewportRendering */.e)(viewportId);
|
|
@@ -16242,7 +16169,7 @@ function WindowLevel({
|
|
|
16242
16169
|
onClick: () => setShowPreview(!showPreview)
|
|
16243
16170
|
}, /*#__PURE__*/react.createElement("span", {
|
|
16244
16171
|
className: "flex-shrink-0"
|
|
16245
|
-
},
|
|
16172
|
+
}, t('Preview in viewport')), /*#__PURE__*/react.createElement(ui_next_src/* Switch */.dOG, {
|
|
16246
16173
|
className: "ml-auto flex-shrink-0",
|
|
16247
16174
|
checked: showPreview,
|
|
16248
16175
|
onCheckedChange: checked => {
|
|
@@ -16261,7 +16188,7 @@ function WindowLevel({
|
|
|
16261
16188
|
className: "p-1"
|
|
16262
16189
|
}, windowLevelPresets.map((preset, index) => /*#__PURE__*/react.createElement(ui_next_src/* AllInOneMenu */.se.Item, {
|
|
16263
16190
|
key: index,
|
|
16264
|
-
label: preset.description,
|
|
16191
|
+
label: t(preset.description),
|
|
16265
16192
|
secondaryLabel: `${preset.window} / ${preset.level}`,
|
|
16266
16193
|
useIconSpace: false,
|
|
16267
16194
|
onClick: () => {
|
|
@@ -16289,6 +16216,7 @@ function WindowLevel({
|
|
|
16289
16216
|
|
|
16290
16217
|
|
|
16291
16218
|
|
|
16219
|
+
|
|
16292
16220
|
function VolumeRenderingPresetsContent({
|
|
16293
16221
|
presets,
|
|
16294
16222
|
viewportId,
|
|
@@ -16299,6 +16227,9 @@ function VolumeRenderingPresetsContent({
|
|
|
16299
16227
|
} = (0,src/* useSystem */.Jg)();
|
|
16300
16228
|
const [searchValue, setSearchValue] = (0,react.useState)('');
|
|
16301
16229
|
const [selectedPreset, setSelectedPreset] = (0,react.useState)(null);
|
|
16230
|
+
const {
|
|
16231
|
+
t
|
|
16232
|
+
} = (0,es/* useTranslation */.Bd)('WindowLevelActionMenu');
|
|
16302
16233
|
const handleSearchChange = (0,react.useCallback)(event => {
|
|
16303
16234
|
setSearchValue(event.target.value);
|
|
16304
16235
|
}, []);
|
|
@@ -16316,7 +16247,7 @@ function VolumeRenderingPresetsContent({
|
|
|
16316
16247
|
}, /*#__PURE__*/react.createElement(ui_next_src/* PresetDialog */.MUF.PresetBody, null, /*#__PURE__*/react.createElement(ui_next_src/* PresetDialog */.MUF.PresetFilter, null, /*#__PURE__*/react.createElement(ui_next_src/* PresetDialog */.MUF.PresetSearch, {
|
|
16317
16248
|
value: searchValue,
|
|
16318
16249
|
onChange: handleSearchChange,
|
|
16319
|
-
placeholder:
|
|
16250
|
+
placeholder: t('Search all', 'Search all')
|
|
16320
16251
|
})), /*#__PURE__*/react.createElement(ui_next_src/* PresetDialog */.MUF.PresetGrid, null, filteredPresets.map((preset, index) => /*#__PURE__*/react.createElement("div", {
|
|
16321
16252
|
key: index,
|
|
16322
16253
|
className: "flex cursor-pointer flex-col items-start",
|
|
@@ -16336,7 +16267,7 @@ function VolumeRenderingPresetsContent({
|
|
|
16336
16267
|
className: "mt-4 flex-shrink-0"
|
|
16337
16268
|
}, /*#__PURE__*/react.createElement(ui_next_src/* FooterAction */.esu.Right, null, /*#__PURE__*/react.createElement(ui_next_src/* FooterAction */.esu.Secondary, {
|
|
16338
16269
|
onClick: hide
|
|
16339
|
-
},
|
|
16270
|
+
}, t('Common:Cancel')))));
|
|
16340
16271
|
}
|
|
16341
16272
|
;// ../../../extensions/cornerstone/src/components/WindowLevelActionMenu/VolumeRenderingPresets.tsx
|
|
16342
16273
|
|
|
@@ -16345,6 +16276,7 @@ function VolumeRenderingPresetsContent({
|
|
|
16345
16276
|
|
|
16346
16277
|
|
|
16347
16278
|
|
|
16279
|
+
|
|
16348
16280
|
function VolumeRenderingPresets({
|
|
16349
16281
|
viewportId
|
|
16350
16282
|
} = {}) {
|
|
@@ -16357,11 +16289,14 @@ function VolumeRenderingPresets({
|
|
|
16357
16289
|
const {
|
|
16358
16290
|
uiDialogService
|
|
16359
16291
|
} = servicesManager.services;
|
|
16292
|
+
const {
|
|
16293
|
+
t
|
|
16294
|
+
} = (0,es/* useTranslation */.Bd)('WindowLevelActionMenu');
|
|
16360
16295
|
const onClickPresets = () => {
|
|
16361
16296
|
uiDialogService.show({
|
|
16362
16297
|
id: 'volume-rendering-presets',
|
|
16363
16298
|
content: VolumeRenderingPresetsContent,
|
|
16364
|
-
title: 'Rendering Presets',
|
|
16299
|
+
title: t('Rendering Presets'),
|
|
16365
16300
|
isDraggable: true,
|
|
16366
16301
|
contentProps: {
|
|
16367
16302
|
presets: volumeRenderingPresets,
|
|
@@ -16370,7 +16305,7 @@ function VolumeRenderingPresets({
|
|
|
16370
16305
|
});
|
|
16371
16306
|
};
|
|
16372
16307
|
return /*#__PURE__*/react.createElement(ui_next_src/* AllInOneMenu */.se.Item, {
|
|
16373
|
-
label:
|
|
16308
|
+
label: t('Rendering Presets'),
|
|
16374
16309
|
icon: /*#__PURE__*/react.createElement(ui_next_src/* Icons */.FI1.VolumeRendering, null),
|
|
16375
16310
|
rightIcon: /*#__PURE__*/react.createElement(ui_next_src/* Icons */.FI1.ByName, {
|
|
16376
16311
|
name: "action-new-dialog"
|
|
@@ -16382,6 +16317,7 @@ function VolumeRenderingPresets({
|
|
|
16382
16317
|
|
|
16383
16318
|
|
|
16384
16319
|
|
|
16320
|
+
|
|
16385
16321
|
function VolumeRenderingQuality({
|
|
16386
16322
|
volumeRenderingQualityRange,
|
|
16387
16323
|
viewportId
|
|
@@ -16399,6 +16335,9 @@ function VolumeRenderingQuality({
|
|
|
16399
16335
|
step
|
|
16400
16336
|
} = volumeRenderingQualityRange;
|
|
16401
16337
|
const [quality, setQuality] = (0,react.useState)(null);
|
|
16338
|
+
const {
|
|
16339
|
+
t
|
|
16340
|
+
} = (0,es/* useTranslation */.Bd)('WindowLevelActionMenu');
|
|
16402
16341
|
const onChange = (0,react.useCallback)(value => {
|
|
16403
16342
|
commandsManager.runCommand('setVolumeRenderingQulaity', {
|
|
16404
16343
|
viewportId,
|
|
@@ -16437,7 +16376,7 @@ function VolumeRenderingQuality({
|
|
|
16437
16376
|
className: "flex flex-row items-center"
|
|
16438
16377
|
}, /*#__PURE__*/react.createElement(ui_next_src/* Numeric */.ewR.Label, {
|
|
16439
16378
|
className: "w-16"
|
|
16440
|
-
},
|
|
16379
|
+
}, t('Quality')), /*#__PURE__*/react.createElement(ui_next_src/* Numeric */.ewR.SingleRange, {
|
|
16441
16380
|
sliderClassName: "mx-2 flex-grow"
|
|
16442
16381
|
})))));
|
|
16443
16382
|
}
|
|
@@ -16445,6 +16384,7 @@ function VolumeRenderingQuality({
|
|
|
16445
16384
|
|
|
16446
16385
|
|
|
16447
16386
|
|
|
16387
|
+
|
|
16448
16388
|
function VolumeShift({
|
|
16449
16389
|
viewportId
|
|
16450
16390
|
}) {
|
|
@@ -16466,6 +16406,9 @@ function VolumeShift({
|
|
|
16466
16406
|
actor
|
|
16467
16407
|
} = viewport.getActors()[0];
|
|
16468
16408
|
const ofun = actor.getProperty().getScalarOpacity(0);
|
|
16409
|
+
const {
|
|
16410
|
+
t
|
|
16411
|
+
} = (0,es/* useTranslation */.Bd)('WindowLevelActionMenu');
|
|
16469
16412
|
(0,react.useEffect)(() => {
|
|
16470
16413
|
if (isBlocking) {
|
|
16471
16414
|
return;
|
|
@@ -16505,7 +16448,7 @@ function VolumeShift({
|
|
|
16505
16448
|
className: "flex flex-row items-center"
|
|
16506
16449
|
}, /*#__PURE__*/react.createElement(ui_next_src/* Numeric */.ewR.Label, {
|
|
16507
16450
|
className: "w-16"
|
|
16508
|
-
},
|
|
16451
|
+
}, t('Shift')), /*#__PURE__*/react.createElement(ui_next_src/* Numeric */.ewR.SingleRange, {
|
|
16509
16452
|
sliderClassName: "mx-2 flex-grow"
|
|
16510
16453
|
})))));
|
|
16511
16454
|
}
|
|
@@ -16513,6 +16456,7 @@ function VolumeShift({
|
|
|
16513
16456
|
|
|
16514
16457
|
|
|
16515
16458
|
|
|
16459
|
+
|
|
16516
16460
|
function VolumeLighting({
|
|
16517
16461
|
viewportId,
|
|
16518
16462
|
hasShade
|
|
@@ -16529,6 +16473,9 @@ function VolumeLighting({
|
|
|
16529
16473
|
diffuse: null,
|
|
16530
16474
|
specular: null
|
|
16531
16475
|
});
|
|
16476
|
+
const {
|
|
16477
|
+
t
|
|
16478
|
+
} = (0,es/* useTranslation */.Bd)('WindowLevelActionMenu');
|
|
16532
16479
|
|
|
16533
16480
|
// Single callback to handle all lighting property changes
|
|
16534
16481
|
const onLightingChange = (0,react.useCallback)((property, value) => {
|
|
@@ -16561,13 +16508,13 @@ function VolumeLighting({
|
|
|
16561
16508
|
// Configuration for our lighting properties
|
|
16562
16509
|
const lightingProperties = [{
|
|
16563
16510
|
key: 'ambient',
|
|
16564
|
-
label: 'Ambient'
|
|
16511
|
+
label: t('Ambient')
|
|
16565
16512
|
}, {
|
|
16566
16513
|
key: 'diffuse',
|
|
16567
|
-
label: 'Diffuse'
|
|
16514
|
+
label: t('Diffuse')
|
|
16568
16515
|
}, {
|
|
16569
16516
|
key: 'specular',
|
|
16570
|
-
label: 'Specular'
|
|
16517
|
+
label: t('Specular')
|
|
16571
16518
|
}];
|
|
16572
16519
|
return /*#__PURE__*/react.createElement("div", {
|
|
16573
16520
|
className: "my-1 mt-2 flex flex-col space-y-2"
|
|
@@ -16596,10 +16543,14 @@ function VolumeLighting({
|
|
|
16596
16543
|
|
|
16597
16544
|
|
|
16598
16545
|
|
|
16546
|
+
|
|
16599
16547
|
function VolumeShade({
|
|
16600
16548
|
viewportId,
|
|
16601
16549
|
onClickShade = bool => {}
|
|
16602
16550
|
}) {
|
|
16551
|
+
const {
|
|
16552
|
+
t
|
|
16553
|
+
} = (0,es/* useTranslation */.Bd)('WindowLevelActionMenu');
|
|
16603
16554
|
const {
|
|
16604
16555
|
servicesManager,
|
|
16605
16556
|
commandsManager
|
|
@@ -16629,7 +16580,7 @@ function VolumeShade({
|
|
|
16629
16580
|
}, [viewportId, cornerstoneViewportService]);
|
|
16630
16581
|
return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement("span", {
|
|
16631
16582
|
className: "flex-grow"
|
|
16632
|
-
},
|
|
16583
|
+
}, t('Shade')), /*#__PURE__*/react.createElement(ui_next_src/* Switch */.dOG, {
|
|
16633
16584
|
className: "ml-2 flex-shrink-0",
|
|
16634
16585
|
key: key,
|
|
16635
16586
|
checked: shade,
|
|
@@ -16648,6 +16599,7 @@ function VolumeShade({
|
|
|
16648
16599
|
|
|
16649
16600
|
|
|
16650
16601
|
|
|
16602
|
+
|
|
16651
16603
|
function VolumeRenderingOptions({
|
|
16652
16604
|
viewportId
|
|
16653
16605
|
} = {}) {
|
|
@@ -16655,6 +16607,9 @@ function VolumeRenderingOptions({
|
|
|
16655
16607
|
volumeRenderingQualityRange
|
|
16656
16608
|
} = (0,useViewportRendering/* useViewportRendering */.e)(viewportId);
|
|
16657
16609
|
const [hasShade, setShade] = (0,react.useState)(false);
|
|
16610
|
+
const {
|
|
16611
|
+
t
|
|
16612
|
+
} = (0,es/* useTranslation */.Bd)('WindowLevelActionMenu');
|
|
16658
16613
|
return /*#__PURE__*/react.createElement(ui_next_src/* AllInOneMenu */.se.ItemPanel, null, /*#__PURE__*/react.createElement(VolumeRenderingQuality, {
|
|
16659
16614
|
viewportId: viewportId,
|
|
16660
16615
|
volumeRenderingQualityRange: volumeRenderingQualityRange
|
|
@@ -16664,7 +16619,7 @@ function VolumeRenderingOptions({
|
|
|
16664
16619
|
className: "mt-2 flex h-8 !h-[20px] w-full flex-shrink-0 items-center justify-start px-2 text-base"
|
|
16665
16620
|
}, /*#__PURE__*/react.createElement("div", {
|
|
16666
16621
|
className: "text-muted-foreground text-sm"
|
|
16667
|
-
},
|
|
16622
|
+
}, t('Lighting'))), /*#__PURE__*/react.createElement("div", {
|
|
16668
16623
|
className: "bg-background mt-1 mb-1 h-px w-full"
|
|
16669
16624
|
}), /*#__PURE__*/react.createElement("div", {
|
|
16670
16625
|
className: "hover:bg-accent flex h-8 w-full flex-shrink-0 items-center px-2 text-base hover:rounded"
|
|
@@ -16689,20 +16644,22 @@ function VolumeRenderingOptions({
|
|
|
16689
16644
|
|
|
16690
16645
|
function WindowLevelActionMenu({
|
|
16691
16646
|
viewportId,
|
|
16692
|
-
element,
|
|
16693
16647
|
align,
|
|
16694
|
-
side
|
|
16648
|
+
side,
|
|
16649
|
+
onVisibilityChange
|
|
16695
16650
|
}) {
|
|
16696
16651
|
return /*#__PURE__*/react.createElement(WindowLevelActionMenuContent, {
|
|
16697
16652
|
viewportId: viewportId,
|
|
16698
16653
|
align: align,
|
|
16699
|
-
side: side
|
|
16654
|
+
side: side,
|
|
16655
|
+
onVisibilityChange: onVisibilityChange
|
|
16700
16656
|
});
|
|
16701
16657
|
}
|
|
16702
16658
|
function WindowLevelActionMenuContent({
|
|
16703
16659
|
viewportId,
|
|
16704
16660
|
align,
|
|
16705
|
-
side
|
|
16661
|
+
side,
|
|
16662
|
+
onVisibilityChange
|
|
16706
16663
|
}) {
|
|
16707
16664
|
const {
|
|
16708
16665
|
t
|
|
@@ -16723,7 +16680,8 @@ function WindowLevelActionMenuContent({
|
|
|
16723
16680
|
isVisible: true,
|
|
16724
16681
|
align: align,
|
|
16725
16682
|
side: side,
|
|
16726
|
-
backLabel: i18next/* default */.A.t('WindowLevelActionMenu:Back to Display Options')
|
|
16683
|
+
backLabel: i18next/* default */.A.t('WindowLevelActionMenu:Back to Display Options'),
|
|
16684
|
+
onVisibilityChange: onVisibilityChange
|
|
16727
16685
|
}, /*#__PURE__*/react.createElement(ui_next_src/* AllInOneMenu */.se.ItemPanel, null, !is3DVolume && /*#__PURE__*/react.createElement(Colorbar, {
|
|
16728
16686
|
viewportId: viewportId
|
|
16729
16687
|
}), colorbarProperties?.colormaps && !is3DVolume && /*#__PURE__*/react.createElement(ui_next_src/* AllInOneMenu */.se.SubMenu, {
|
|
@@ -16758,7 +16716,6 @@ function WindowLevelActionMenuWrapper_extends() { return WindowLevelActionMenuWr
|
|
|
16758
16716
|
function WindowLevelActionMenuWrapper(props) {
|
|
16759
16717
|
const {
|
|
16760
16718
|
viewportId,
|
|
16761
|
-
element,
|
|
16762
16719
|
location,
|
|
16763
16720
|
isOpen = false,
|
|
16764
16721
|
onOpen,
|
|
@@ -16839,9 +16796,9 @@ function WindowLevelActionMenuWrapper(props) {
|
|
|
16839
16796
|
sideOffset: 5
|
|
16840
16797
|
}, /*#__PURE__*/react.createElement(WindowLevelActionMenu, {
|
|
16841
16798
|
viewportId: viewportIdToUse,
|
|
16842
|
-
element: element,
|
|
16843
16799
|
align: align,
|
|
16844
|
-
side: side
|
|
16800
|
+
side: side,
|
|
16801
|
+
onVisibilityChange: handleOpenChange
|
|
16845
16802
|
})));
|
|
16846
16803
|
}
|
|
16847
16804
|
;// ../../../extensions/cornerstone/src/components/VOIManualControlMenu/VOIManualControlMenu.tsx
|
|
@@ -17481,6 +17438,7 @@ function ModalityLoadBadge({
|
|
|
17481
17438
|
|
|
17482
17439
|
|
|
17483
17440
|
|
|
17441
|
+
|
|
17484
17442
|
/**
|
|
17485
17443
|
* NavigationComponent provides navigation controls for viewports containing
|
|
17486
17444
|
* special displaySets (SR, SEG, RTSTRUCT) to navigate between segments or measurements
|
|
@@ -17517,7 +17475,7 @@ function NavigationComponent({
|
|
|
17517
17475
|
} = (0,hooks/* useViewportSegmentations */.Lt)({
|
|
17518
17476
|
viewportId
|
|
17519
17477
|
});
|
|
17520
|
-
const hasSegmentations = segmentationsWithRepresentations.length > 0;
|
|
17478
|
+
const hasSegmentations = segmentationsWithRepresentations.length > 0 && segmentationsWithRepresentations.some(segmentation => segmentation?.representation?.type !== esm_enums.SegmentationRepresentations.Surface);
|
|
17521
17479
|
|
|
17522
17480
|
// prefer segment navigation if available
|
|
17523
17481
|
const navigationMode = hasSegmentations ? 'segment' : isSRDisplaySet ? 'measurement' : isTracked ? 'measurement' : null;
|
|
@@ -17546,7 +17504,8 @@ function NavigationComponent({
|
|
|
17546
17504
|
if (!segmentationsWithRepresentations.length) {
|
|
17547
17505
|
return;
|
|
17548
17506
|
}
|
|
17549
|
-
const
|
|
17507
|
+
const activeSegmentationWithRepresentation = segmentationsWithRepresentations.find(segmentation => segmentation?.representation?.active);
|
|
17508
|
+
const segmentationId = activeSegmentationWithRepresentation.segmentation.segmentationId;
|
|
17550
17509
|
src_utils.handleSegmentChange({
|
|
17551
17510
|
direction,
|
|
17552
17511
|
segmentationId,
|
|
@@ -18014,9 +17973,10 @@ function AdvancedRenderingControls({
|
|
|
18014
17973
|
|
|
18015
17974
|
|
|
18016
17975
|
|
|
17976
|
+
|
|
18017
17977
|
const getDisabledState = disabledText => ({
|
|
18018
17978
|
disabled: true,
|
|
18019
|
-
disabledText: disabledText ?? 'Not available on the current viewport'
|
|
17979
|
+
disabledText: disabledText ?? i18n_src/* default */.A.t('Buttons:Not available on the current viewport')
|
|
18020
17980
|
});
|
|
18021
17981
|
function getToolbarModule({
|
|
18022
17982
|
servicesManager,
|
|
@@ -18349,7 +18309,7 @@ function getToolbarModule({
|
|
|
18349
18309
|
if (supportedModalities?.length) {
|
|
18350
18310
|
const hasAnySupportedModality = displaySets.some(displaySet => supportedModalities.includes(displaySet?.Modality));
|
|
18351
18311
|
if (!hasAnySupportedModality) {
|
|
18352
|
-
return getDisabledState(disabledText || 'Tool not available for this modality');
|
|
18312
|
+
return getDisabledState(disabledText || i18n_src/* default */.A.t('Buttons:Tool not available for this modality'));
|
|
18353
18313
|
}
|
|
18354
18314
|
}
|
|
18355
18315
|
}
|
|
@@ -18792,9 +18752,26 @@ ToolGroupService.REGISTRATION = {
|
|
|
18792
18752
|
;// ../../../extensions/cornerstone/src/services/ToolGroupService/index.js
|
|
18793
18753
|
|
|
18794
18754
|
/* harmony default export */ const services_ToolGroupService = (ToolGroupService);
|
|
18755
|
+
;// ../../../extensions/cornerstone/src/utils/isAnyDisplaySetCommon.ts
|
|
18756
|
+
/**
|
|
18757
|
+
* Checks whether two viewports share at least one common display set.
|
|
18758
|
+
*
|
|
18759
|
+
* This method checks to see if the source and target share a display set.
|
|
18760
|
+
* It performs an O(n * m) comparison between the display sets of each viewport.
|
|
18761
|
+
* Since each viewport typically contains only a small number of display sets (≤ 5),
|
|
18762
|
+
* the computational cost is negligible.
|
|
18763
|
+
*
|
|
18764
|
+
* @param sourceDisplaySetUIDs - Array of displaySetInstanceUID from the source viewport.
|
|
18765
|
+
* @param targetDisplaySetUIDs - Array of displaySetInstanceUID from the target viewport.
|
|
18766
|
+
* @returns true if at least one display set is common; false otherwise.
|
|
18767
|
+
*/
|
|
18768
|
+
function isAnyDisplaySetCommon(sourceDisplaySetUIDs, targetDisplaySetUIDs) {
|
|
18769
|
+
return sourceDisplaySetUIDs.some(uid => targetDisplaySetUIDs.includes(uid));
|
|
18770
|
+
}
|
|
18795
18771
|
;// ../../../extensions/cornerstone/src/services/SyncGroupService/createHydrateSegmentationSynchronizer.ts
|
|
18796
18772
|
|
|
18797
18773
|
|
|
18774
|
+
|
|
18798
18775
|
const {
|
|
18799
18776
|
createSynchronizer
|
|
18800
18777
|
} = dist_esm.SynchronizerManager;
|
|
@@ -18818,6 +18795,13 @@ function createHydrateSegmentationSynchronizer(synchronizerName, {
|
|
|
18818
18795
|
});
|
|
18819
18796
|
return stackImageSynchronizer;
|
|
18820
18797
|
}
|
|
18798
|
+
|
|
18799
|
+
/**
|
|
18800
|
+
* This method will add the segmentation representation to any target viewports having:
|
|
18801
|
+
*
|
|
18802
|
+
* 1. the same FrameOfReferenceUID (FOR) as the segmentation representation, or
|
|
18803
|
+
* 2. a shared DisplaySet with the source viewport when no FOR is present.
|
|
18804
|
+
*/
|
|
18821
18805
|
const segmentationRepresentationModifiedCallback = async (synchronizerInstance, sourceViewport, targetViewport, sourceEvent, {
|
|
18822
18806
|
servicesManager,
|
|
18823
18807
|
options
|
|
@@ -18828,14 +18812,20 @@ const segmentationRepresentationModifiedCallback = async (synchronizerInstance,
|
|
|
18828
18812
|
type: segmentationRepresentationType
|
|
18829
18813
|
} = event.detail;
|
|
18830
18814
|
const {
|
|
18831
|
-
segmentationService
|
|
18815
|
+
segmentationService,
|
|
18816
|
+
cornerstoneViewportService
|
|
18832
18817
|
} = servicesManager.services;
|
|
18833
18818
|
const targetViewportId = targetViewport.viewportId;
|
|
18819
|
+
const sourceViewportId = sourceViewport.viewportId;
|
|
18834
18820
|
const {
|
|
18835
18821
|
viewport
|
|
18836
18822
|
} = (0,esm.getEnabledElementByViewportId)(targetViewportId);
|
|
18837
|
-
const
|
|
18838
|
-
|
|
18823
|
+
const sourceViewportInfo = cornerstoneViewportService.getViewportInfo(sourceViewportId);
|
|
18824
|
+
const targetViewportInfo = cornerstoneViewportService.getViewportInfo(targetViewportId);
|
|
18825
|
+
const sourceDisplaySetUIDs = extractDisplaySetUIDs(sourceViewportInfo);
|
|
18826
|
+
const targetDisplaySetUIDs = extractDisplaySetUIDs(targetViewportInfo);
|
|
18827
|
+
const sharedDisplaySetExists = isAnyDisplaySetCommon(sourceDisplaySetUIDs, targetDisplaySetUIDs);
|
|
18828
|
+
if (!sharedDisplaySetExists && !viewport.getFrameOfReferenceUID()) {
|
|
18839
18829
|
return;
|
|
18840
18830
|
}
|
|
18841
18831
|
const targetViewportRepresentation = segmentationService.getSegmentationRepresentations(targetViewportId, {
|
|
@@ -18851,10 +18841,17 @@ const segmentationRepresentationModifiedCallback = async (synchronizerInstance,
|
|
|
18851
18841
|
segmentationId,
|
|
18852
18842
|
type,
|
|
18853
18843
|
config: {
|
|
18854
|
-
blendMode: viewport
|
|
18844
|
+
blendMode: viewport?.getBlendMode?.() === 1 ? BlendModes.LABELMAP_EDGE_PROJECTION_BLEND : undefined
|
|
18855
18845
|
}
|
|
18856
18846
|
});
|
|
18857
18847
|
};
|
|
18848
|
+
|
|
18849
|
+
/**
|
|
18850
|
+
* Extracts the displaySetInstanceUIDs from a viewportInfo.
|
|
18851
|
+
*/
|
|
18852
|
+
function extractDisplaySetUIDs(viewportInfo) {
|
|
18853
|
+
return viewportInfo.getViewportData().data.map(ds => ds.displaySetInstanceUID);
|
|
18854
|
+
}
|
|
18858
18855
|
;// ../../../extensions/cornerstone/src/services/SyncGroupService/SyncGroupService.ts
|
|
18859
18856
|
var _SyncGroupService;
|
|
18860
18857
|
|
|
@@ -19138,6 +19135,9 @@ var _SegmentationService;
|
|
|
19138
19135
|
|
|
19139
19136
|
|
|
19140
19137
|
|
|
19138
|
+
const {
|
|
19139
|
+
DefaultHistoryMemo: SegmentationService_DefaultHistoryMemo
|
|
19140
|
+
} = esm.utilities.HistoryMemo;
|
|
19141
19141
|
const {
|
|
19142
19142
|
Labelmap: LABELMAP,
|
|
19143
19143
|
Contour: CONTOUR,
|
|
@@ -19898,11 +19898,69 @@ class SegmentationService extends src/* PubSubService */.Rc {
|
|
|
19898
19898
|
});
|
|
19899
19899
|
}
|
|
19900
19900
|
|
|
19901
|
+
/**
|
|
19902
|
+
* Creates a memo that records the current state of a segment (segmentationId/segmentIndex)
|
|
19903
|
+
* so that undo can restore it via addSegment and redo can call removeSegment again
|
|
19904
|
+
* without recording history.
|
|
19905
|
+
*
|
|
19906
|
+
* @param segmentationId - The ID of the segmentation.
|
|
19907
|
+
* @param segmentIndex - The index of the segment (must still exist when called).
|
|
19908
|
+
* @param _options - Reserved (e.g. deleting) for future use.
|
|
19909
|
+
* @returns A Memo with restoreMemo(undo): undo => addSegment, redo => removeSegment (skipRecordingHistory).
|
|
19910
|
+
*/
|
|
19911
|
+
createSegmentIndexMemo(segmentationId, segmentIndex, _options) {
|
|
19912
|
+
const csSegmentation = this.getCornerstoneSegmentation(segmentationId);
|
|
19913
|
+
const segment = csSegmentation?.segments?.[segmentIndex];
|
|
19914
|
+
if (!segment) {
|
|
19915
|
+
return null;
|
|
19916
|
+
}
|
|
19917
|
+
let color;
|
|
19918
|
+
let visibility;
|
|
19919
|
+
const viewportIds = this.getViewportIdsWithSegmentation(segmentationId);
|
|
19920
|
+
if (viewportIds.length > 0) {
|
|
19921
|
+
const firstViewportId = viewportIds[0];
|
|
19922
|
+
const representations = this.getSegmentationRepresentations(firstViewportId, {
|
|
19923
|
+
segmentationId
|
|
19924
|
+
});
|
|
19925
|
+
const repType = representations[0]?.type ?? LABELMAP;
|
|
19926
|
+
color = this.getSegmentColor(firstViewportId, segmentationId, segmentIndex);
|
|
19927
|
+
visibility = dist_esm.segmentation.config.visibility.getSegmentIndexVisibility(firstViewportId, {
|
|
19928
|
+
segmentationId,
|
|
19929
|
+
type: repType
|
|
19930
|
+
}, segmentIndex);
|
|
19931
|
+
}
|
|
19932
|
+
const segmentState = {
|
|
19933
|
+
segmentIndex,
|
|
19934
|
+
label: segment.label,
|
|
19935
|
+
isLocked: segment.locked,
|
|
19936
|
+
active: segment.active,
|
|
19937
|
+
color,
|
|
19938
|
+
visibility
|
|
19939
|
+
};
|
|
19940
|
+
const service = this;
|
|
19941
|
+
const memo = {
|
|
19942
|
+
id: esm.utilities.uuidv4(),
|
|
19943
|
+
operationType: 'segmentIndex',
|
|
19944
|
+
restoreMemo(undo) {
|
|
19945
|
+
if (undo === true) {
|
|
19946
|
+
service.addSegment(segmentationId, segmentState);
|
|
19947
|
+
} else {
|
|
19948
|
+
// Redo: remove the segment via cornerstone without recording history
|
|
19949
|
+
dist_esm.segmentation.removeSegment(segmentationId, segmentIndex, {
|
|
19950
|
+
recordHistory: false
|
|
19951
|
+
});
|
|
19952
|
+
}
|
|
19953
|
+
}
|
|
19954
|
+
};
|
|
19955
|
+
return memo;
|
|
19956
|
+
}
|
|
19957
|
+
|
|
19901
19958
|
/**
|
|
19902
19959
|
* Removes a segment from a segmentation and updates the active segment index if necessary.
|
|
19903
19960
|
*
|
|
19904
19961
|
* @param segmentationId - The ID of the segmentation containing the segment to remove.
|
|
19905
19962
|
* @param segmentIndex - The index of the segment to remove.
|
|
19963
|
+
* @param options - Optional. skipRecordingHistory: if true, do not push undo memo (used when redoing).
|
|
19906
19964
|
*
|
|
19907
19965
|
* @remarks
|
|
19908
19966
|
* This method performs the following actions:
|
|
@@ -19911,8 +19969,23 @@ class SegmentationService extends src/* PubSubService */.Rc {
|
|
|
19911
19969
|
* 3. If the removed segment was the active segment, it updates the active segment index.
|
|
19912
19970
|
*
|
|
19913
19971
|
*/
|
|
19914
|
-
removeSegment(segmentationId, segmentIndex) {
|
|
19915
|
-
|
|
19972
|
+
removeSegment(segmentationId, segmentIndex, options) {
|
|
19973
|
+
let memo;
|
|
19974
|
+
if (!options?.skipRecordingHistory) {
|
|
19975
|
+
memo = this.createSegmentIndexMemo(segmentationId, segmentIndex, {
|
|
19976
|
+
deleting: true
|
|
19977
|
+
});
|
|
19978
|
+
SegmentationService_DefaultHistoryMemo.startGroupRecording();
|
|
19979
|
+
dist_esm.segmentation.removeSegment(segmentationId, segmentIndex, {
|
|
19980
|
+
recordHistory: true
|
|
19981
|
+
});
|
|
19982
|
+
SegmentationService_DefaultHistoryMemo.push(memo);
|
|
19983
|
+
SegmentationService_DefaultHistoryMemo.endGroupRecording();
|
|
19984
|
+
} else {
|
|
19985
|
+
dist_esm.segmentation.removeSegment(segmentationId, segmentIndex, {
|
|
19986
|
+
recordHistory: false
|
|
19987
|
+
});
|
|
19988
|
+
}
|
|
19916
19989
|
}
|
|
19917
19990
|
setSegmentVisibility(viewportId, segmentationId, segmentIndex, isVisible, type) {
|
|
19918
19991
|
this._setSegmentVisibility(viewportId, segmentationId, segmentIndex, isVisible, type);
|
|
@@ -20128,15 +20201,111 @@ class SegmentationService extends src/* PubSubService */.Rc {
|
|
|
20128
20201
|
removeSegmentationRepresentations(viewportId, specifier = {}) {
|
|
20129
20202
|
dist_esm.segmentation.removeSegmentationRepresentations(viewportId, specifier);
|
|
20130
20203
|
}
|
|
20131
|
-
|
|
20132
|
-
|
|
20133
|
-
|
|
20204
|
+
|
|
20205
|
+
/**
|
|
20206
|
+
* Jumps to the next slice that contains the specified segment in the viewport.
|
|
20207
|
+
* For labelmaps, it jumps to the segment center. For contours, it cycles through
|
|
20208
|
+
* all slices that contain contour data for the segment.
|
|
20209
|
+
*
|
|
20210
|
+
* @param segmentationId - The ID of the segmentation
|
|
20211
|
+
* @param segmentIndex - The index of the segment to jump to
|
|
20212
|
+
* @param viewportId - Optional viewport ID. If not provided, applies to all viewports with this segmentation
|
|
20213
|
+
* @param highlightAlpha - Alpha value for highlighting (0-1)
|
|
20214
|
+
* @param highlightSegment - Whether to highlight the segment after jumping
|
|
20215
|
+
* @param animationLength - Length of highlight animation in milliseconds
|
|
20216
|
+
* @param highlightHideOthers - Whether to hide other segments during highlight
|
|
20217
|
+
* @param animationFunctionType - The easing function to use for animation
|
|
20218
|
+
*/
|
|
20219
|
+
jumpToSegmentNext(segmentationId, segmentIndex, forViewportId, direction = 1, highlightAlpha = 0.9, highlightSegment = true, animationLength = 750, highlightHideOthers = false, animationFunctionType = EasingFunctionEnum.EASE_IN_OUT) {
|
|
20220
|
+
const viewportIds = forViewportId ? [forViewportId] : this.getViewportIdsWithSegmentation(segmentationId);
|
|
20221
|
+
viewportIds.forEach(viewportId => {
|
|
20222
|
+
const representations = this.getSegmentationRepresentations(viewportId, {
|
|
20223
|
+
segmentationId
|
|
20224
|
+
});
|
|
20225
|
+
if (!representations || representations.length === 0) {
|
|
20226
|
+
return;
|
|
20227
|
+
}
|
|
20228
|
+
const representation = representations[0];
|
|
20229
|
+
const {
|
|
20230
|
+
type
|
|
20231
|
+
} = representation;
|
|
20232
|
+
|
|
20233
|
+
// For contours, check if we have a segment center.
|
|
20234
|
+
const center = type === CONTOUR ? this._getSegmentCenter(segmentationId, segmentIndex) : undefined;
|
|
20235
|
+
const canUseSegmentCenter = type !== CONTOUR || !!center;
|
|
20236
|
+
if (canUseSegmentCenter) {
|
|
20237
|
+
this.jumpToSegmentCenter(segmentationId, segmentIndex, viewportId, highlightAlpha, highlightSegment, animationLength, highlightHideOthers, animationFunctionType, center);
|
|
20238
|
+
return;
|
|
20239
|
+
}
|
|
20240
|
+
const {
|
|
20241
|
+
viewport
|
|
20242
|
+
} = (0,esm.getEnabledElementByViewportId)(viewportId);
|
|
20243
|
+
if (!viewport) {
|
|
20244
|
+
return;
|
|
20245
|
+
}
|
|
20246
|
+
const viewRefs = this._getContourViewReferences(segmentationId, viewport, segmentIndex);
|
|
20247
|
+
if (!viewRefs) {
|
|
20248
|
+
return;
|
|
20249
|
+
}
|
|
20250
|
+
|
|
20251
|
+
// Get the current slice index
|
|
20252
|
+
const currentSliceIndex = viewport.getCurrentImageIdIndex();
|
|
20253
|
+
let nearestSliceIndex = null;
|
|
20254
|
+
let loopSliceIndex = null;
|
|
20255
|
+
for (const [sliceIndex] of viewRefs.entries()) {
|
|
20256
|
+
// Track loop index for wraparound (smallest for forward, largest for backward)
|
|
20257
|
+
if (direction > 0) {
|
|
20258
|
+
if (loopSliceIndex === null || sliceIndex < loopSliceIndex) {
|
|
20259
|
+
loopSliceIndex = sliceIndex;
|
|
20260
|
+
}
|
|
20261
|
+
} else {
|
|
20262
|
+
if (loopSliceIndex === null || sliceIndex > loopSliceIndex) {
|
|
20263
|
+
loopSliceIndex = sliceIndex;
|
|
20264
|
+
}
|
|
20265
|
+
}
|
|
20266
|
+
if (direction > 0) {
|
|
20267
|
+
// Forward direction: find nearest slice after current
|
|
20268
|
+
if (sliceIndex <= currentSliceIndex) {
|
|
20269
|
+
continue;
|
|
20270
|
+
}
|
|
20271
|
+
if (nearestSliceIndex === null || sliceIndex < nearestSliceIndex) {
|
|
20272
|
+
nearestSliceIndex = sliceIndex;
|
|
20273
|
+
}
|
|
20274
|
+
} else {
|
|
20275
|
+
// Backward direction: find nearest slice before current
|
|
20276
|
+
if (sliceIndex >= currentSliceIndex) {
|
|
20277
|
+
continue;
|
|
20278
|
+
}
|
|
20279
|
+
if (nearestSliceIndex === null || sliceIndex > nearestSliceIndex) {
|
|
20280
|
+
nearestSliceIndex = sliceIndex;
|
|
20281
|
+
}
|
|
20282
|
+
}
|
|
20283
|
+
}
|
|
20284
|
+
|
|
20285
|
+
// Wraparound: if no slice found in direction, use loop index
|
|
20286
|
+
nearestSliceIndex = nearestSliceIndex ?? loopSliceIndex;
|
|
20287
|
+
if (nearestSliceIndex === null) {
|
|
20288
|
+
return;
|
|
20289
|
+
}
|
|
20290
|
+
const viewRef = viewRefs.get(nearestSliceIndex);
|
|
20291
|
+
viewport.setViewReference(viewRef);
|
|
20292
|
+
viewport.render();
|
|
20293
|
+
});
|
|
20294
|
+
}
|
|
20295
|
+
|
|
20296
|
+
/**
|
|
20297
|
+
* Jumps the viewport to the center of hte given segment.
|
|
20298
|
+
* Only works for labelmaps, and may result in not showing any contours.
|
|
20299
|
+
*/
|
|
20300
|
+
jumpToSegmentCenter(segmentationId, segmentIndex, viewportId, highlightAlpha = 0.9, highlightSegment = true, animationLength = 750, highlightHideOthers = false, animationFunctionType = EasingFunctionEnum.EASE_IN_OUT, center) {
|
|
20301
|
+
const resolvedCenter = center ?? this._getSegmentCenter(segmentationId, segmentIndex);
|
|
20302
|
+
if (!resolvedCenter) {
|
|
20134
20303
|
console.warn('No center found for segmentation', segmentationId, segmentIndex);
|
|
20135
20304
|
return;
|
|
20136
20305
|
}
|
|
20137
20306
|
const {
|
|
20138
20307
|
world
|
|
20139
|
-
} =
|
|
20308
|
+
} = resolvedCenter;
|
|
20140
20309
|
|
|
20141
20310
|
// need to find which viewports are displaying the segmentation
|
|
20142
20311
|
const viewportIds = viewportId ? [viewportId] : this.getViewportIdsWithSegmentation(segmentationId);
|
|
@@ -20144,6 +20313,9 @@ class SegmentationService extends src/* PubSubService */.Rc {
|
|
|
20144
20313
|
const {
|
|
20145
20314
|
viewport
|
|
20146
20315
|
} = (0,esm.getEnabledElementByViewportId)(viewportId);
|
|
20316
|
+
if (!viewport?.jumpToWorld) {
|
|
20317
|
+
return;
|
|
20318
|
+
}
|
|
20147
20319
|
viewport.jumpToWorld(world);
|
|
20148
20320
|
highlightSegment && this.highlightSegment(segmentationId, segmentIndex, viewportId, highlightAlpha, animationLength, highlightHideOthers, animationFunctionType);
|
|
20149
20321
|
});
|
|
@@ -20530,6 +20702,54 @@ class SegmentationService extends src/* PubSubService */.Rc {
|
|
|
20530
20702
|
}
|
|
20531
20703
|
}]);
|
|
20532
20704
|
}
|
|
20705
|
+
/**
|
|
20706
|
+
* Gets slice indices for contour segmentations by checking view references from annotation metadata
|
|
20707
|
+
* @private
|
|
20708
|
+
*/
|
|
20709
|
+
_getContourViewReferences(segmentationId, viewport, segmentIndex) {
|
|
20710
|
+
const segmentation = dist_esm.segmentation.state.getSegmentation(segmentationId);
|
|
20711
|
+
const contourData = segmentation.representationData[CONTOUR];
|
|
20712
|
+
if (!contourData || !contourData.annotationUIDsMap) {
|
|
20713
|
+
return;
|
|
20714
|
+
}
|
|
20715
|
+
const viewReferences = new Map();
|
|
20716
|
+
// Iterate through the annotationUIDsMap
|
|
20717
|
+
contourData.annotationUIDsMap.forEach((annotationUIDs, currentSegmentIndex) => {
|
|
20718
|
+
// Filter by segment index if specified
|
|
20719
|
+
if (segmentIndex !== undefined && currentSegmentIndex !== segmentIndex) {
|
|
20720
|
+
return;
|
|
20721
|
+
}
|
|
20722
|
+
// Process each annotation UID
|
|
20723
|
+
annotationUIDs.forEach(annotationUID => {
|
|
20724
|
+
const annotation = dist_esm.annotation.state.getAnnotation(annotationUID);
|
|
20725
|
+
if (!annotation?.metadata) {
|
|
20726
|
+
return;
|
|
20727
|
+
}
|
|
20728
|
+
const {
|
|
20729
|
+
metadata
|
|
20730
|
+
} = annotation;
|
|
20731
|
+
// Check if the viewport can view this annotation's view reference with navigation
|
|
20732
|
+
const isViewable = viewport.isReferenceViewable(metadata, {
|
|
20733
|
+
withNavigation: true
|
|
20734
|
+
});
|
|
20735
|
+
if (!isViewable) {
|
|
20736
|
+
return;
|
|
20737
|
+
}
|
|
20738
|
+
const {
|
|
20739
|
+
sliceIndex
|
|
20740
|
+
} = metadata;
|
|
20741
|
+
if (sliceIndex === undefined) {
|
|
20742
|
+
console.warn("Can't find slice index:", metadata);
|
|
20743
|
+
return;
|
|
20744
|
+
}
|
|
20745
|
+
viewReferences.set(sliceIndex, metadata);
|
|
20746
|
+
});
|
|
20747
|
+
});
|
|
20748
|
+
if (viewReferences.size === 0) {
|
|
20749
|
+
return;
|
|
20750
|
+
}
|
|
20751
|
+
return viewReferences;
|
|
20752
|
+
}
|
|
20533
20753
|
}
|
|
20534
20754
|
_SegmentationService = SegmentationService;
|
|
20535
20755
|
SegmentationService.REGISTRATION = {
|
|
@@ -21153,6 +21373,8 @@ var _CornerstoneViewportService;
|
|
|
21153
21373
|
|
|
21154
21374
|
|
|
21155
21375
|
|
|
21376
|
+
|
|
21377
|
+
|
|
21156
21378
|
const CornerstoneViewportService_EVENTS = {
|
|
21157
21379
|
VIEWPORT_DATA_CHANGED: 'event::cornerstoneViewportService:viewportDataChanged',
|
|
21158
21380
|
VIEWPORT_VOLUMES_CHANGED: 'event::cornerstoneViewportService:viewportVolumesChanged'
|
|
@@ -21596,8 +21818,7 @@ class CornerstoneViewportService extends src/* PubSubService */.Rc {
|
|
|
21596
21818
|
* viewport to display the image in where it matches, in order:
|
|
21597
21819
|
* * Active viewport that can be navigated to the given image without orientation change
|
|
21598
21820
|
* * Other viewport that can be navigated to the given image without orientation change
|
|
21599
|
-
* *
|
|
21600
|
-
* * Other viewport that can change orientation to display the image
|
|
21821
|
+
* * Best-aligned viewport that can display the image with an orientation change
|
|
21601
21822
|
*
|
|
21602
21823
|
* It returns `null` otherwise, indicating that a viewport needs display set/type
|
|
21603
21824
|
* changes in order to display the image.
|
|
@@ -21620,9 +21841,7 @@ class CornerstoneViewportService extends src/* PubSubService */.Rc {
|
|
|
21620
21841
|
if (!activeViewport) {
|
|
21621
21842
|
console.warn('No active viewport found for', activeViewportId);
|
|
21622
21843
|
}
|
|
21623
|
-
if (activeViewport?.isReferenceViewable(metadata, {
|
|
21624
|
-
withNavigation: true
|
|
21625
|
-
})) {
|
|
21844
|
+
if (activeViewport?.isReferenceViewable(metadata, WITH_NAVIGATION)) {
|
|
21626
21845
|
return activeViewportId;
|
|
21627
21846
|
}
|
|
21628
21847
|
|
|
@@ -21630,29 +21849,21 @@ class CornerstoneViewportService extends src/* PubSubService */.Rc {
|
|
|
21630
21849
|
// without considering orientation changes.
|
|
21631
21850
|
for (const id of this.viewportsById.keys()) {
|
|
21632
21851
|
const viewport = this.getCornerstoneViewport(id);
|
|
21633
|
-
if (viewport?.isReferenceViewable(metadata, {
|
|
21634
|
-
withNavigation: true
|
|
21635
|
-
})) {
|
|
21852
|
+
if (viewport?.isReferenceViewable(metadata, WITH_NAVIGATION)) {
|
|
21636
21853
|
return id;
|
|
21637
21854
|
}
|
|
21638
21855
|
}
|
|
21639
21856
|
|
|
21640
|
-
//
|
|
21641
|
-
// the
|
|
21642
|
-
|
|
21643
|
-
withNavigation: true,
|
|
21644
|
-
withOrientation: true
|
|
21645
|
-
})) {
|
|
21646
|
-
return activeViewportId;
|
|
21647
|
-
}
|
|
21857
|
+
// Compute view-plane alignment scores for all viewports to prefer the one
|
|
21858
|
+
// requiring the least orientation change when navigation-only is not possible.
|
|
21859
|
+
const viewportAlignmentData = this.getViewportAlignmentData(metadata);
|
|
21648
21860
|
|
|
21649
21861
|
// See if any viewport could show this with an orientation change
|
|
21650
|
-
for (const
|
|
21862
|
+
for (const {
|
|
21863
|
+
viewportId: id
|
|
21864
|
+
} of viewportAlignmentData) {
|
|
21651
21865
|
const viewport = this.getCornerstoneViewport(id);
|
|
21652
|
-
if (viewport?.isReferenceViewable(metadata, {
|
|
21653
|
-
withNavigation: true,
|
|
21654
|
-
withOrientation: true
|
|
21655
|
-
})) {
|
|
21866
|
+
if (viewport?.isReferenceViewable(metadata, WITH_ORIENTATION)) {
|
|
21656
21867
|
return id;
|
|
21657
21868
|
}
|
|
21658
21869
|
}
|
|
@@ -21662,24 +21873,51 @@ class CornerstoneViewportService extends src/* PubSubService */.Rc {
|
|
|
21662
21873
|
}
|
|
21663
21874
|
|
|
21664
21875
|
/**
|
|
21665
|
-
*
|
|
21666
|
-
*
|
|
21667
|
-
* the display set, but in the wrong orientation.
|
|
21668
|
-
*
|
|
21669
|
-
* The viewport will need to update the viewport type and/or display set to
|
|
21670
|
-
* display the resulting data.
|
|
21671
|
-
*
|
|
21672
|
-
* The first choice will be a viewport already showing the correct display set,
|
|
21673
|
-
* but showing it as a stack.
|
|
21876
|
+
* Given a metadata instance containing a planeRestriction, returns the
|
|
21877
|
+
* ordered list of best orientation match viewport ids.
|
|
21674
21878
|
*
|
|
21675
|
-
*
|
|
21676
|
-
*
|
|
21677
|
-
*
|
|
21678
|
-
|
|
21679
|
-
|
|
21680
|
-
|
|
21681
|
-
|
|
21682
|
-
|
|
21879
|
+
* This uses the planeRestriction preferentially as that one is more reliably
|
|
21880
|
+
* filled than the viewport normal since it is created from data points on
|
|
21881
|
+
* rehydration.
|
|
21882
|
+
*/
|
|
21883
|
+
getViewportAlignmentData(metadata) {
|
|
21884
|
+
const viewportAlignmentData = [];
|
|
21885
|
+
const {
|
|
21886
|
+
viewPlaneNormal: refViewPlaneNormal,
|
|
21887
|
+
planeRestriction
|
|
21888
|
+
} = metadata;
|
|
21889
|
+
const inPlaneVector1 = planeRestriction?.inPlaneVector1;
|
|
21890
|
+
const inPlaneVector2 = planeRestriction?.inPlaneVector2;
|
|
21891
|
+
for (const id of this.viewportsById.keys()) {
|
|
21892
|
+
const viewport = this.getCornerstoneViewport(id);
|
|
21893
|
+
const {
|
|
21894
|
+
viewPlaneNormal
|
|
21895
|
+
} = viewport.getCamera();
|
|
21896
|
+
if (!viewPlaneNormal) {
|
|
21897
|
+
continue;
|
|
21898
|
+
}
|
|
21899
|
+
let alignmentScore = 0;
|
|
21900
|
+
if (inPlaneVector1 || inPlaneVector2) {
|
|
21901
|
+
const inPlane1Score = inPlaneVector1 ? -Math.abs(gl_matrix_esm/* vec3.dot */.eR.dot(viewPlaneNormal, inPlaneVector1)) : 0;
|
|
21902
|
+
const inPlane2Score = inPlaneVector2 ? -Math.abs(gl_matrix_esm/* vec3.dot */.eR.dot(viewPlaneNormal, inPlaneVector2)) : 0;
|
|
21903
|
+
alignmentScore = inPlane1Score + inPlane2Score;
|
|
21904
|
+
} else if (refViewPlaneNormal) {
|
|
21905
|
+
alignmentScore = Math.abs(gl_matrix_esm/* vec3.dot */.eR.dot(viewPlaneNormal, refViewPlaneNormal));
|
|
21906
|
+
}
|
|
21907
|
+
viewportAlignmentData.push({
|
|
21908
|
+
viewportId: id,
|
|
21909
|
+
alignmentScore
|
|
21910
|
+
});
|
|
21911
|
+
}
|
|
21912
|
+
|
|
21913
|
+
// Try best-aligned viewports first
|
|
21914
|
+
viewportAlignmentData.sort((a, b) => b.alignmentScore - a.alignmentScore);
|
|
21915
|
+
return viewportAlignmentData;
|
|
21916
|
+
}
|
|
21917
|
+
|
|
21918
|
+
/**
|
|
21919
|
+
* Figures out which viewport to update when the viewport type needs to change.
|
|
21920
|
+
* Orchestrates the search strategies in order of preference.
|
|
21683
21921
|
*/
|
|
21684
21922
|
findUpdateableViewportConfiguration(activeViewportId, measurement) {
|
|
21685
21923
|
const {
|
|
@@ -21687,47 +21925,98 @@ class CornerstoneViewportService extends src/* PubSubService */.Rc {
|
|
|
21687
21925
|
displaySetInstanceUID
|
|
21688
21926
|
} = measurement;
|
|
21689
21927
|
const {
|
|
21690
|
-
|
|
21691
|
-
referencedImageId
|
|
21692
|
-
} = metadata;
|
|
21693
|
-
const {
|
|
21694
|
-
displaySetService,
|
|
21695
|
-
viewportGridService
|
|
21928
|
+
displaySetService
|
|
21696
21929
|
} = this.servicesManager.services;
|
|
21697
21930
|
const displaySet = displaySetService.getDisplaySetByUID(displaySetInstanceUID);
|
|
21931
|
+
|
|
21932
|
+
// 1. Determine the target Viewport Type (Stack vs Volume)
|
|
21933
|
+
const viewportType = this.determineTargetViewportType(displaySet, metadata);
|
|
21934
|
+
|
|
21935
|
+
// 2. Strategy: Find viewport already showing this volume
|
|
21936
|
+
const volumeMatch = this.findViewportShowingVolume(metadata, displaySetInstanceUID, viewportType);
|
|
21937
|
+
if (volumeMatch) {
|
|
21938
|
+
return volumeMatch;
|
|
21939
|
+
}
|
|
21940
|
+
|
|
21941
|
+
// 3. Strategy: Find viewport with compatible orientation (even if different display set)
|
|
21942
|
+
const compatibleMatch = this.findViewportConvertibleToVolume(metadata, displaySetInstanceUID, viewportType);
|
|
21943
|
+
if (compatibleMatch) {
|
|
21944
|
+
return compatibleMatch;
|
|
21945
|
+
}
|
|
21946
|
+
|
|
21947
|
+
// 4. Strategy: Find viewport with matching orientation via IOP
|
|
21948
|
+
const orientationMatch = this.findViewportWithMatchingOrientation(metadata, displaySetInstanceUID, viewportType);
|
|
21949
|
+
if (orientationMatch) {
|
|
21950
|
+
return orientationMatch;
|
|
21951
|
+
}
|
|
21952
|
+
|
|
21953
|
+
// 5. Fallback: Use the active viewport
|
|
21954
|
+
return {
|
|
21955
|
+
viewportId: activeViewportId,
|
|
21956
|
+
displaySetInstanceUID,
|
|
21957
|
+
viewportOptions: {
|
|
21958
|
+
viewportType
|
|
21959
|
+
}
|
|
21960
|
+
};
|
|
21961
|
+
}
|
|
21962
|
+
|
|
21963
|
+
/**
|
|
21964
|
+
* Determines if the viewport should be what is specified in
|
|
21965
|
+
* the viewportType of the display set, or stack if the display
|
|
21966
|
+
* set isn't reconstructable and there is a referenced image id, otherwise
|
|
21967
|
+
* volume.
|
|
21968
|
+
*
|
|
21969
|
+
* Expect there to be more rules in the future for different types of annotations/settings
|
|
21970
|
+
* such as 3d annotations.
|
|
21971
|
+
*/
|
|
21972
|
+
determineTargetViewportType(displaySet, metadata) {
|
|
21698
21973
|
let {
|
|
21699
21974
|
viewportType
|
|
21700
21975
|
} = displaySet;
|
|
21701
21976
|
if (!viewportType) {
|
|
21702
|
-
if (referencedImageId && !displaySet.isReconstructable) {
|
|
21977
|
+
if (metadata.referencedImageId && !displaySet.isReconstructable) {
|
|
21703
21978
|
viewportType = esm.Enums.ViewportType.STACK;
|
|
21704
|
-
} else if (volumeId) {
|
|
21979
|
+
} else if (metadata.volumeId) {
|
|
21705
21980
|
viewportType = 'volume';
|
|
21706
21981
|
}
|
|
21707
21982
|
}
|
|
21983
|
+
return viewportType;
|
|
21984
|
+
}
|
|
21708
21985
|
|
|
21709
|
-
|
|
21710
|
-
|
|
21711
|
-
|
|
21712
|
-
|
|
21713
|
-
|
|
21714
|
-
|
|
21715
|
-
|
|
21716
|
-
|
|
21717
|
-
|
|
21718
|
-
|
|
21719
|
-
|
|
21720
|
-
|
|
21721
|
-
|
|
21722
|
-
|
|
21723
|
-
|
|
21724
|
-
|
|
21725
|
-
|
|
21986
|
+
/**
|
|
21987
|
+
* Find viewports that could be updated to be volumes to show this view.
|
|
21988
|
+
* Prefers a viewport already showing the right display set.
|
|
21989
|
+
*/
|
|
21990
|
+
findViewportShowingVolume(metadata, displaySetInstanceUID, viewportType) {
|
|
21991
|
+
if (!metadata.volumeId) {
|
|
21992
|
+
return null;
|
|
21993
|
+
}
|
|
21994
|
+
for (const id of this.viewportsById.keys()) {
|
|
21995
|
+
const viewport = this.getCornerstoneViewport(id);
|
|
21996
|
+
if (viewport?.isReferenceViewable(metadata, {
|
|
21997
|
+
asVolume: true,
|
|
21998
|
+
withNavigation: true
|
|
21999
|
+
})) {
|
|
22000
|
+
return {
|
|
22001
|
+
viewportId: id,
|
|
22002
|
+
displaySetInstanceUID,
|
|
22003
|
+
viewportOptions: {
|
|
22004
|
+
viewportType
|
|
22005
|
+
}
|
|
22006
|
+
};
|
|
21726
22007
|
}
|
|
21727
22008
|
}
|
|
22009
|
+
return null;
|
|
22010
|
+
}
|
|
21728
22011
|
|
|
21729
|
-
|
|
21730
|
-
|
|
22012
|
+
/**
|
|
22013
|
+
* Find a viewport that could be converted to a volume to show this annotation,
|
|
22014
|
+
* already showing the right display set.
|
|
22015
|
+
*/
|
|
22016
|
+
findViewportConvertibleToVolume(metadata, displaySetInstanceUID, viewportType) {
|
|
22017
|
+
const {
|
|
22018
|
+
viewportGridService
|
|
22019
|
+
} = this.servicesManager.services;
|
|
21731
22020
|
const altMetadata = {
|
|
21732
22021
|
...metadata,
|
|
21733
22022
|
volumeId: null,
|
|
@@ -21739,7 +22028,7 @@ class CornerstoneViewportService extends src/* PubSubService */.Rc {
|
|
|
21739
22028
|
if (!viewportDisplaySetUID || !viewport) {
|
|
21740
22029
|
continue;
|
|
21741
22030
|
}
|
|
21742
|
-
if (volumeId) {
|
|
22031
|
+
if (metadata.volumeId) {
|
|
21743
22032
|
altMetadata.volumeId = viewportDisplaySetUID;
|
|
21744
22033
|
}
|
|
21745
22034
|
altMetadata.FrameOfReferenceUID = this._getFrameOfReferenceUID(viewportDisplaySetUID);
|
|
@@ -21756,15 +22045,24 @@ class CornerstoneViewportService extends src/* PubSubService */.Rc {
|
|
|
21756
22045
|
};
|
|
21757
22046
|
}
|
|
21758
22047
|
}
|
|
22048
|
+
return null;
|
|
22049
|
+
}
|
|
21759
22050
|
|
|
21760
|
-
|
|
21761
|
-
|
|
21762
|
-
|
|
21763
|
-
|
|
21764
|
-
|
|
21765
|
-
|
|
21766
|
-
|
|
21767
|
-
|
|
22051
|
+
/**
|
|
22052
|
+
* Find a viewport with the closest orientation but on a different display set.
|
|
22053
|
+
*/
|
|
22054
|
+
findViewportWithMatchingOrientation(metadata, displaySetInstanceUID, viewportType) {
|
|
22055
|
+
const viewportAlignmentData = this.getViewportAlignmentData(metadata);
|
|
22056
|
+
if (viewportAlignmentData?.length) {
|
|
22057
|
+
return {
|
|
22058
|
+
...viewportAlignmentData[0],
|
|
22059
|
+
displaySetInstanceUID,
|
|
22060
|
+
viewportOptions: {
|
|
22061
|
+
viewportType
|
|
22062
|
+
}
|
|
22063
|
+
};
|
|
22064
|
+
}
|
|
22065
|
+
return null;
|
|
21768
22066
|
}
|
|
21769
22067
|
|
|
21770
22068
|
/**
|
|
@@ -22161,7 +22459,10 @@ class CornerstoneViewportService extends src/* PubSubService */.Rc {
|
|
|
22161
22459
|
segmentationService.addSegmentationRepresentation(viewport.id, {
|
|
22162
22460
|
segmentationId,
|
|
22163
22461
|
predecessorImageId,
|
|
22164
|
-
type: representationType
|
|
22462
|
+
type: representationType,
|
|
22463
|
+
config: {
|
|
22464
|
+
blendMode: viewport?.getBlendMode?.() === 1 ? dist_esm_enums.BlendModes.LABELMAP_EDGE_PROJECTION_BLEND : undefined
|
|
22465
|
+
}
|
|
22165
22466
|
});
|
|
22166
22467
|
|
|
22167
22468
|
// store the segmentation presentation id in the viewport info
|
|
@@ -22390,7 +22691,10 @@ class CornerstoneViewportService extends src/* PubSubService */.Rc {
|
|
|
22390
22691
|
if (hydrated) {
|
|
22391
22692
|
segmentationService.addSegmentationRepresentation(viewport.id, {
|
|
22392
22693
|
segmentationId,
|
|
22393
|
-
type: representationType
|
|
22694
|
+
type: representationType,
|
|
22695
|
+
config: {
|
|
22696
|
+
blendMode: viewport?.getBlendMode?.() === 1 ? dist_esm_enums.BlendModes.LABELMAP_EDGE_PROJECTION_BLEND : undefined
|
|
22697
|
+
}
|
|
22394
22698
|
});
|
|
22395
22699
|
}
|
|
22396
22700
|
});
|
|
@@ -23215,7 +23519,7 @@ const hasExportableContourData = contour => {
|
|
|
23215
23519
|
|
|
23216
23520
|
function PanelSegmentation({
|
|
23217
23521
|
children,
|
|
23218
|
-
|
|
23522
|
+
segmentationRepresentationTypes
|
|
23219
23523
|
}) {
|
|
23220
23524
|
const {
|
|
23221
23525
|
commandsManager,
|
|
@@ -23236,8 +23540,8 @@ function PanelSegmentation({
|
|
|
23236
23540
|
[esm_enums.SegmentationRepresentations.Contour]: toolbarService.sections.contourSegmentationUtilities
|
|
23237
23541
|
};
|
|
23238
23542
|
const selectedSegmentationsForViewportMap = useSelectedSegmentationsForViewportStore(store => store.selectedSegmentationsForViewport[activeViewportId]);
|
|
23239
|
-
const selectedSegmentationIdForType =
|
|
23240
|
-
const buttonSection = utilitiesSectionMap[
|
|
23543
|
+
const selectedSegmentationIdForType = segmentationRepresentationTypes ? segmentationRepresentationTypes.reduce((selectedSegmentation, type) => selectedSegmentation || (selectedSegmentationsForViewportMap?.has(type) ? selectedSegmentationsForViewportMap?.get(type) : undefined), undefined) : segmentationService?.getActiveSegmentation(activeViewportId)?.segmentationId;
|
|
23544
|
+
const buttonSection = segmentationRepresentationTypes?.[0] ? utilitiesSectionMap[segmentationRepresentationTypes[0]] : undefined;
|
|
23241
23545
|
const {
|
|
23242
23546
|
activeToolOptions: activeUtilityOptions
|
|
23243
23547
|
} = (0,src/* useActiveToolOptions */.KP)({
|
|
@@ -23326,7 +23630,7 @@ function PanelSegmentation({
|
|
|
23326
23630
|
segmentIndex
|
|
23327
23631
|
});
|
|
23328
23632
|
},
|
|
23329
|
-
onSegmentCopy:
|
|
23633
|
+
onSegmentCopy: segmentationRepresentationTypes?.[0] === esm_enums.SegmentationRepresentations.Contour ? (segmentationId, segmentIndex) => {
|
|
23330
23634
|
commandsManager.run('copyContourSegment', {
|
|
23331
23635
|
sourceSegmentInfo: {
|
|
23332
23636
|
segmentationId,
|
|
@@ -23489,13 +23793,13 @@ function PanelSegmentation({
|
|
|
23489
23793
|
disabled,
|
|
23490
23794
|
data: segmentationsWithRepresentations,
|
|
23491
23795
|
mode: segmentationTableMode,
|
|
23492
|
-
title: `${
|
|
23796
|
+
title: `${segmentationRepresentationTypes?.[0] ? `${segmentationRepresentationTypes[0]} ` : ''}Segmentations`,
|
|
23493
23797
|
exportOptions,
|
|
23494
23798
|
disableEditing,
|
|
23495
23799
|
onSegmentationAdd,
|
|
23496
23800
|
showAddSegment,
|
|
23497
23801
|
renderInactiveSegmentations: handlers.getRenderInactiveSegmentations(),
|
|
23498
|
-
|
|
23802
|
+
segmentationRepresentationTypes,
|
|
23499
23803
|
selectedSegmentationIdForType,
|
|
23500
23804
|
...handlers
|
|
23501
23805
|
};
|
|
@@ -23556,16 +23860,17 @@ const workerFn = () => {
|
|
|
23556
23860
|
name: 'histogram-worker' // name used by the browser to name the worker
|
|
23557
23861
|
});
|
|
23558
23862
|
};
|
|
23863
|
+
|
|
23864
|
+
// Register worker once at module load time
|
|
23865
|
+
workerManager.registerWorker('histogram-worker', workerFn, WorkerOptions);
|
|
23559
23866
|
const getViewportVolumeHistogram = async (viewport, volume, options) => {
|
|
23560
|
-
workerManager.registerWorker('histogram-worker', workerFn, WorkerOptions);
|
|
23561
23867
|
const volumeImageData = viewport.getImageData(volume.volumeId);
|
|
23562
23868
|
if (!volumeImageData) {
|
|
23563
23869
|
return undefined;
|
|
23564
23870
|
}
|
|
23565
23871
|
let scalarData = volume.scalarData;
|
|
23566
23872
|
if (volume.numTimePoints > 1) {
|
|
23567
|
-
|
|
23568
|
-
scalarData = volume.voxelManager.getTimePointScalarData(targetTimePoint);
|
|
23873
|
+
scalarData = volume.voxelManager.getDimensionGroupScalarData(volume.numTimePoints);
|
|
23569
23874
|
} else {
|
|
23570
23875
|
scalarData = volume.voxelManager.getCompleteScalarDataArray();
|
|
23571
23876
|
}
|
|
@@ -23614,6 +23919,9 @@ const getViewportVolumeHistogram = async (viewport, volume, options) => {
|
|
|
23614
23919
|
* Gets node opacity from volume actor
|
|
23615
23920
|
*/
|
|
23616
23921
|
const getNodeOpacity = (volumeActor, nodeIndex) => {
|
|
23922
|
+
if (!volumeActor) {
|
|
23923
|
+
return undefined;
|
|
23924
|
+
}
|
|
23617
23925
|
const volumeOpacity = volumeActor.getProperty().getScalarOpacity(0);
|
|
23618
23926
|
const nodeValue = [];
|
|
23619
23927
|
volumeOpacity.getNodeValue(nodeIndex, nodeValue);
|
|
@@ -23624,6 +23932,9 @@ const getNodeOpacity = (volumeActor, nodeIndex) => {
|
|
|
23624
23932
|
* Checks if the opacity applied to the PET volume follows a specific pattern
|
|
23625
23933
|
*/
|
|
23626
23934
|
const isPetVolumeWithDefaultOpacity = (volumeId, volumeActor) => {
|
|
23935
|
+
if (!volumeActor) {
|
|
23936
|
+
return false;
|
|
23937
|
+
}
|
|
23627
23938
|
const volume = esm.cache.getVolume(volumeId);
|
|
23628
23939
|
if (!volume || volume.metadata.Modality !== 'PT') {
|
|
23629
23940
|
return false;
|
|
@@ -23655,6 +23966,9 @@ const isPetVolumeWithDefaultOpacity = (volumeId, volumeActor) => {
|
|
|
23655
23966
|
* Checks if volume has constant opacity
|
|
23656
23967
|
*/
|
|
23657
23968
|
const isVolumeWithConstantOpacity = volumeActor => {
|
|
23969
|
+
if (!volumeActor) {
|
|
23970
|
+
return false;
|
|
23971
|
+
}
|
|
23658
23972
|
const volumeOpacity = volumeActor.getProperty().getScalarOpacity(0);
|
|
23659
23973
|
const opacitySize = volumeOpacity.getSize();
|
|
23660
23974
|
const firstNodeValue = [];
|
|
@@ -23681,7 +23995,7 @@ const getWindowLevelsData = async (viewport, viewportInfo, getVolumeOpacity) =>
|
|
|
23681
23995
|
const viewportProperties = viewport.getProperties();
|
|
23682
23996
|
const {
|
|
23683
23997
|
voiRange
|
|
23684
|
-
} = viewportProperties;
|
|
23998
|
+
} = viewportProperties || {};
|
|
23685
23999
|
const viewportVoi = voiRange ? {
|
|
23686
24000
|
windowWidth: voiRange.upper - voiRange.lower,
|
|
23687
24001
|
windowCenter: voiRange.lower + (voiRange.upper - voiRange.lower) / 2
|
|
@@ -24280,6 +24594,7 @@ function StudySummaryFromMetadata(props) {
|
|
|
24280
24594
|
|
|
24281
24595
|
|
|
24282
24596
|
|
|
24597
|
+
|
|
24283
24598
|
function StudyMeasurementsActions({
|
|
24284
24599
|
items,
|
|
24285
24600
|
StudyInstanceUID,
|
|
@@ -24289,6 +24604,9 @@ function StudyMeasurementsActions({
|
|
|
24289
24604
|
const {
|
|
24290
24605
|
commandsManager
|
|
24291
24606
|
} = (0,src/* useSystem */.Jg)();
|
|
24607
|
+
const {
|
|
24608
|
+
t
|
|
24609
|
+
} = (0,es/* useTranslation */.Bd)('MeasurementTable');
|
|
24292
24610
|
const disabled = !items?.length;
|
|
24293
24611
|
if (disabled) {
|
|
24294
24612
|
return null;
|
|
@@ -24329,7 +24647,7 @@ function StudyMeasurementsActions({
|
|
|
24329
24647
|
measurementFilter
|
|
24330
24648
|
});
|
|
24331
24649
|
}
|
|
24332
|
-
}, /*#__PURE__*/react.createElement(ui_next_src/* Icons */.FI1.Add, null),
|
|
24650
|
+
}, /*#__PURE__*/react.createElement(ui_next_src/* Icons */.FI1.Add, null), t('Create SR')), /*#__PURE__*/react.createElement(ui_next_src/* Button */.$nd, {
|
|
24333
24651
|
size: "sm",
|
|
24334
24652
|
variant: "ghost",
|
|
24335
24653
|
className: "pl-0.5",
|
|
@@ -24343,7 +24661,7 @@ function StudyMeasurementsActions({
|
|
|
24343
24661
|
measurementFilter
|
|
24344
24662
|
});
|
|
24345
24663
|
}
|
|
24346
|
-
}, /*#__PURE__*/react.createElement(ui_next_src/* Icons */.FI1.Delete, null),
|
|
24664
|
+
}, /*#__PURE__*/react.createElement(ui_next_src/* Icons */.FI1.Delete, null), t('Delete'))));
|
|
24347
24665
|
}
|
|
24348
24666
|
/* harmony default export */ const components_StudyMeasurementsActions = (StudyMeasurementsActions);
|
|
24349
24667
|
;// ../../../extensions/cornerstone/src/components/StudySummaryWithActions.tsx
|
|
@@ -24549,7 +24867,7 @@ const getPanelModule = ({
|
|
|
24549
24867
|
configuration: {
|
|
24550
24868
|
...props?.configuration
|
|
24551
24869
|
},
|
|
24552
|
-
|
|
24870
|
+
segmentationRepresentationTypes: props?.segmentationRepresentationTypes
|
|
24553
24871
|
});
|
|
24554
24872
|
};
|
|
24555
24873
|
const wrappedPanelSegmentationNoHeader = props => {
|
|
@@ -24560,17 +24878,17 @@ const getPanelModule = ({
|
|
|
24560
24878
|
configuration: {
|
|
24561
24879
|
...props?.configuration
|
|
24562
24880
|
},
|
|
24563
|
-
|
|
24881
|
+
segmentationRepresentationTypes: props?.segmentationRepresentationTypes
|
|
24564
24882
|
});
|
|
24565
24883
|
};
|
|
24566
24884
|
const wrappedPanelSegmentationWithTools = props => {
|
|
24567
24885
|
const {
|
|
24568
24886
|
t
|
|
24569
|
-
} = (0,es/* useTranslation */.Bd)('
|
|
24570
|
-
const tKey = `${props.
|
|
24887
|
+
} = (0,es/* useTranslation */.Bd)('SegmentationPanel');
|
|
24888
|
+
const tKey = `${props.segmentationRepresentationTypes?.[0] ?? 'Segmentation'} tools`;
|
|
24571
24889
|
const tValue = t(tKey);
|
|
24572
24890
|
return /*#__PURE__*/react.createElement(react.Fragment, null, /*#__PURE__*/react.createElement(default_src.Toolbox, {
|
|
24573
|
-
buttonSectionId: toolSectionMap[props.
|
|
24891
|
+
buttonSectionId: toolSectionMap[props.segmentationRepresentationTypes?.[0]],
|
|
24574
24892
|
title: tValue
|
|
24575
24893
|
}), /*#__PURE__*/react.createElement(PanelSegmentation, {
|
|
24576
24894
|
commandsManager: commandsManager,
|
|
@@ -24579,7 +24897,7 @@ const getPanelModule = ({
|
|
|
24579
24897
|
configuration: {
|
|
24580
24898
|
...props?.configuration
|
|
24581
24899
|
},
|
|
24582
|
-
|
|
24900
|
+
segmentationRepresentationTypes: props?.segmentationRepresentationTypes
|
|
24583
24901
|
}));
|
|
24584
24902
|
};
|
|
24585
24903
|
return [{
|
|
@@ -24611,19 +24929,19 @@ const getPanelModule = ({
|
|
|
24611
24929
|
name: 'panelSegmentationWithToolsLabelMap',
|
|
24612
24930
|
iconName: 'tab-segmentation',
|
|
24613
24931
|
iconLabel: 'Segmentation',
|
|
24614
|
-
label: i18n_src/* default */.A.t('
|
|
24932
|
+
label: i18n_src/* default */.A.t('SegmentationPanel:Labelmap'),
|
|
24615
24933
|
component: props => wrappedPanelSegmentationWithTools({
|
|
24616
24934
|
...props,
|
|
24617
|
-
|
|
24935
|
+
segmentationRepresentationTypes: [esm_enums.SegmentationRepresentations.Labelmap, esm_enums.SegmentationRepresentations.Surface]
|
|
24618
24936
|
})
|
|
24619
24937
|
}, {
|
|
24620
24938
|
name: 'panelSegmentationWithToolsContour',
|
|
24621
24939
|
iconName: 'tab-contours',
|
|
24622
24940
|
iconLabel: 'Segmentation',
|
|
24623
|
-
label: i18n_src/* default */.A.t('
|
|
24941
|
+
label: i18n_src/* default */.A.t('SegmentationPanel:Contour'),
|
|
24624
24942
|
component: props => wrappedPanelSegmentationWithTools({
|
|
24625
24943
|
...props,
|
|
24626
|
-
|
|
24944
|
+
segmentationRepresentationTypes: [esm_enums.SegmentationRepresentations.Contour]
|
|
24627
24945
|
})
|
|
24628
24946
|
}];
|
|
24629
24947
|
};
|
|
@@ -24663,7 +24981,7 @@ const handleSegmentChange = ({
|
|
|
24663
24981
|
// Functions below use the segmentIndex object attribute so we have to do the conversion
|
|
24664
24982
|
const segmentIndex = Object.values(segments)[newSelectedSegmentIndex]?.segmentIndex;
|
|
24665
24983
|
segmentationService.setActiveSegment(segmentationId, segmentIndex);
|
|
24666
|
-
segmentationService.
|
|
24984
|
+
segmentationService.jumpToSegmentNext(segmentationId, segmentIndex, undefined, direction);
|
|
24667
24985
|
selectedSegmentObjectIndex = newSelectedSegmentIndex;
|
|
24668
24986
|
};
|
|
24669
24987
|
;// ../../../extensions/cornerstone/src/utils/isReferenceViewable.ts
|
|
@@ -25124,11 +25442,15 @@ const setUpAnnotationEventHandlers = () => {
|
|
|
25124
25442
|
|
|
25125
25443
|
|
|
25126
25444
|
|
|
25445
|
+
|
|
25127
25446
|
function MeasumentsMenu(props) {
|
|
25128
25447
|
const {
|
|
25129
25448
|
group,
|
|
25130
25449
|
classNames
|
|
25131
25450
|
} = props;
|
|
25451
|
+
const {
|
|
25452
|
+
t
|
|
25453
|
+
} = (0,es/* useTranslation */.Bd)('MeasurementTable');
|
|
25132
25454
|
if (!group.items?.length) {
|
|
25133
25455
|
console.log('No items to iterate', group.items);
|
|
25134
25456
|
return null;
|
|
@@ -25160,7 +25482,7 @@ function MeasumentsMenu(props) {
|
|
|
25160
25482
|
size: "icon",
|
|
25161
25483
|
variant: "ghost",
|
|
25162
25484
|
className: `h-6 w-6 transition-opacity ${isSelected || !isVisible ? 'opacity-100' : 'opacity-50 group-hover:opacity-100'}`,
|
|
25163
|
-
"aria-label": isVisible ? 'Hide' : 'Show',
|
|
25485
|
+
"aria-label": isVisible ? t('Hide') : t('Show'),
|
|
25164
25486
|
onClick: e => {
|
|
25165
25487
|
e.stopPropagation();
|
|
25166
25488
|
onAction(e, ['jumpToMeasurement', 'toggleVisibilityMeasurement']);
|
|
@@ -25189,7 +25511,7 @@ function MeasumentsMenu(props) {
|
|
|
25189
25511
|
className: "text-foreground"
|
|
25190
25512
|
}), /*#__PURE__*/react.createElement("span", {
|
|
25191
25513
|
className: "pl-2"
|
|
25192
|
-
},
|
|
25514
|
+
}, t('Delete'))))));
|
|
25193
25515
|
}
|
|
25194
25516
|
/* harmony default export */ const MeasurementsMenu = (MeasumentsMenu);
|
|
25195
25517
|
;// ../../../extensions/cornerstone/src/components/PanelAccordionTrigger.tsx
|