Compare commits
30
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eaa423c64e | ||
|
|
f7db74a843 | ||
|
|
7aba01f534 | ||
|
|
c5ebeaa127 | ||
|
|
d7e1d2c975 | ||
|
|
eb7eb56d7e | ||
|
|
c5ee092bf2 | ||
|
|
e2f4f95222 | ||
|
|
4546ede9bb | ||
|
|
e0fb439e98 | ||
|
|
ebbc9e0d6d | ||
|
|
47a6130fd5 | ||
|
|
80dfdcc37c | ||
|
|
d74ad370e0 | ||
|
|
ddfde9279e | ||
|
|
aaab6d2622 | ||
|
|
d2921083e7 | ||
|
|
a6338ea266 | ||
|
|
fe9551b9b1 | ||
|
|
ef60156a47 | ||
|
|
850de2903a | ||
|
|
f26ed5539b | ||
|
|
21aeaa63c7 | ||
|
|
2ac0d3f017 | ||
|
|
efdbe8e7b4 | ||
|
|
67b70eaa98 | ||
|
|
5150ed9427 | ||
|
|
1bcb0acf9f | ||
|
|
5d6cf2a609 | ||
|
|
9f813e0ea0 |
No files matched your search
@@ -3,6 +3,38 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [2.12.15](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.12.14...@ohif/extension-cornerstone@2.12.15) (2022-09-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.12.14](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.12.13...@ohif/extension-cornerstone@2.12.14) (2022-09-01)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.12.13](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.12.12...@ohif/extension-cornerstone@2.12.13) (2022-06-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.12.12](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.12.11...@ohif/extension-cornerstone@2.12.12) (2022-06-29)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [2.12.11](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.12.10...@ohif/extension-cornerstone@2.12.11) (2022-06-14)
|
## [2.12.11](https://github.com/OHIF/Viewers/compare/@ohif/extension-cornerstone@2.12.10...@ohif/extension-cornerstone@2.12.11) (2022-06-14)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ohif/extension-cornerstone
|
**Note:** Version bump only for package @ohif/extension-cornerstone
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ohif/extension-cornerstone",
|
"name": "@ohif/extension-cornerstone",
|
||||||
"version": "2.12.11",
|
"version": "2.12.15",
|
||||||
"description": "OHIF extension for Cornerstone",
|
"description": "OHIF extension for Cornerstone",
|
||||||
"author": "OHIF",
|
"author": "OHIF",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -35,8 +35,8 @@
|
|||||||
"cornerstone-core": "^2.6.1",
|
"cornerstone-core": "^2.6.1",
|
||||||
"cornerstone-math": "^0.1.9",
|
"cornerstone-math": "^0.1.9",
|
||||||
"cornerstone-tools": "^6.0.6",
|
"cornerstone-tools": "^6.0.6",
|
||||||
"cornerstone-wado-image-loader": "^4.1.0",
|
"cornerstone-wado-image-loader": "^4.2.1",
|
||||||
"dcmjs": "0.19.9",
|
"dcmjs": "0.24.10",
|
||||||
"dicom-parser": "^1.8.11",
|
"dicom-parser": "^1.8.11",
|
||||||
"hammerjs": "^2.0.8",
|
"hammerjs": "^2.0.8",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
|
|||||||
@@ -237,7 +237,7 @@ class OHIFCornerstoneViewport extends Component {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const warningsOverlay = props => {
|
const overlay = props => {
|
||||||
const displaySet = this.props.viewportData.displaySet;
|
const displaySet = this.props.viewportData.displaySet;
|
||||||
let filteredSRLabels;
|
let filteredSRLabels;
|
||||||
if (displaySet.SRLabels && displaySet.SRLabels.length !== 0) {
|
if (displaySet.SRLabels && displaySet.SRLabels.length !== 0) {
|
||||||
@@ -264,7 +264,7 @@ class OHIFCornerstoneViewport extends Component {
|
|||||||
imageIdIndex={currentImageIdIndex}
|
imageIdIndex={currentImageIdIndex}
|
||||||
onNewImageDebounced={newImageHandler}
|
onNewImageDebounced={newImageHandler}
|
||||||
onNewImageDebounceTime={300}
|
onNewImageDebounceTime={300}
|
||||||
viewportOverlayComponent={warningsOverlay}
|
viewportOverlayComponent={overlay}
|
||||||
stackPrefetch={this.props.stackPrefetch}
|
stackPrefetch={this.props.stackPrefetch}
|
||||||
isStackPrefetchEnabled={this.props.isStackPrefetchEnabled}
|
isStackPrefetchEnabled={this.props.isStackPrefetchEnabled}
|
||||||
// ~~ Connected (From REDUX)
|
// ~~ Connected (From REDUX)
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
}
|
}
|
||||||
.OHIFCornerstoneViewportOverlay .bottom-left3 {
|
.OHIFCornerstoneViewportOverlay .bottom-left3 {
|
||||||
bottom: 110px;
|
bottom: 110px;
|
||||||
left: 100px;
|
left: -20px;
|
||||||
}
|
}
|
||||||
.OHIFCornerstoneViewportOverlay .bottom-right {
|
.OHIFCornerstoneViewportOverlay .bottom-right {
|
||||||
bottom: 20px;
|
bottom: 20px;
|
||||||
|
|||||||
@@ -18,19 +18,13 @@ import { Tooltip } from '@ohif/ui/src/components/tooltip';
|
|||||||
import { OverlayTrigger } from '@ohif/ui/src/components/overlayTrigger';
|
import { OverlayTrigger } from '@ohif/ui/src/components/overlayTrigger';
|
||||||
|
|
||||||
const Button = styled.button`
|
const Button = styled.button`
|
||||||
background-color: #3f51b5;
|
|
||||||
color: white;
|
color: white;
|
||||||
padding: 5px 15px;
|
padding: 2px 7px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
outline: 0;
|
outline: 0;
|
||||||
text-transform: lowercase;
|
text-transform: none;
|
||||||
margin: 5px 5px;
|
margin: 2px 2px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
box-shadow: 0px 2px 2px lightgray;
|
|
||||||
transition: ease background-color 250ms;
|
|
||||||
&:hover {
|
|
||||||
background-color: #283593;
|
|
||||||
}
|
|
||||||
&:disabled {
|
&:disabled {
|
||||||
cursor: default;
|
cursor: default;
|
||||||
opacity: 0.9;
|
opacity: 0.9;
|
||||||
@@ -51,7 +45,7 @@ class OHIFCornerstoneViewportOverlay extends PureComponent {
|
|||||||
imageId: PropTypes.string.isRequired,
|
imageId: PropTypes.string.isRequired,
|
||||||
imageIndex: PropTypes.number.isRequired,
|
imageIndex: PropTypes.number.isRequired,
|
||||||
stackSize: PropTypes.number.isRequired,
|
stackSize: PropTypes.number.isRequired,
|
||||||
inconsistencyWarnings: PropTypes.array.isRequired,
|
inconsistencyWarnings: PropTypes.array,
|
||||||
SRLabels: PropTypes.array,
|
SRLabels: PropTypes.array,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -152,34 +146,48 @@ class OHIFCornerstoneViewportOverlay extends PureComponent {
|
|||||||
|
|
||||||
const SRLabelsOn = SRLabels && SRLabels.length !== 0 ? true : false;
|
const SRLabelsOn = SRLabels && SRLabels.length !== 0 ? true : false;
|
||||||
|
|
||||||
|
/**/
|
||||||
|
|
||||||
const getSRLabelsContent = SRLabels => {
|
const getSRLabelsContent = SRLabels => {
|
||||||
if (Array.isArray(SRLabels)) {
|
if (Array.isArray(SRLabels)) {
|
||||||
const listedSRLabels = SRLabels.map((SRLabel, index) => {
|
const listedSRLabels = SRLabels.map((SRLabel, index) => {
|
||||||
|
const color = SRLabel.labels.color;
|
||||||
return (
|
return (
|
||||||
<OverlayTrigger
|
SRLabel.labels.visible && (
|
||||||
key={index}
|
<OverlayTrigger
|
||||||
placement="top"
|
key={index}
|
||||||
overlay={
|
placement="top"
|
||||||
<Tooltip
|
overlay={
|
||||||
placement="top"
|
<Tooltip
|
||||||
className="in tooltip-warning"
|
placement="top"
|
||||||
id="tooltip-top"
|
className="in tooltip-warning"
|
||||||
>
|
id="tooltip-top"
|
||||||
<div className="warningTitle"> Designators </div>
|
>
|
||||||
<div className="warningContent">
|
<div className="warningTitle">
|
||||||
{SRLabel.labels.labelCodingSchemeDesignator +
|
{' '}
|
||||||
' : ' +
|
Coding scheme designators{' '}
|
||||||
SRLabel.labels.valueCodingSchemeDesignator}
|
</div>
|
||||||
</div>
|
<div className="warningContent">
|
||||||
</Tooltip>
|
{SRLabel.labels.labelCodingSchemeDesignator +
|
||||||
}
|
' : ' +
|
||||||
>
|
SRLabel.labels.valueCodingSchemeDesignator}
|
||||||
<div style={{ display: 'inline-block' }}>
|
</div>
|
||||||
<Button disabled={true} key={index}>
|
</Tooltip>
|
||||||
{SRLabel.labels.label + ' : ' + SRLabel.labels.value}
|
}
|
||||||
</Button>
|
>
|
||||||
</div>
|
<div style={{ display: 'inline-block' }}>
|
||||||
</OverlayTrigger>
|
<Button
|
||||||
|
style={{
|
||||||
|
backgroundColor: color,
|
||||||
|
}}
|
||||||
|
disabled={true}
|
||||||
|
key={index}
|
||||||
|
>
|
||||||
|
{SRLabel.labels.label + ' : ' + SRLabel.labels.value}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</OverlayTrigger>
|
||||||
|
)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,14 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [0.3.3](https://github.com/OHIF/Viewers/compare/@ohif/extension-debugging@0.3.2...@ohif/extension-debugging@0.3.3) (2022-06-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-debugging
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [0.3.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-debugging@0.3.1...@ohif/extension-debugging@0.3.2) (2022-03-10)
|
## [0.3.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-debugging@0.3.1...@ohif/extension-debugging@0.3.2) (2022-03-10)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ohif/extension-debugging
|
**Note:** Version bump only for package @ohif/extension-debugging
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ohif/extension-debugging",
|
"name": "@ohif/extension-debugging",
|
||||||
"version": "0.3.2",
|
"version": "0.3.3",
|
||||||
"description": "OHIF extension for debugging.",
|
"description": "OHIF extension for debugging.",
|
||||||
"author": "OHIF",
|
"author": "OHIF",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@@ -89,10 +89,10 @@ const DubugReportModal = ({
|
|||||||
|
|
||||||
Object.keys(viewportSpecificData).forEach(viewportIndex => {
|
Object.keys(viewportSpecificData).forEach(viewportIndex => {
|
||||||
const displaySet = viewportSpecificData[viewportIndex];
|
const displaySet = viewportSpecificData[viewportIndex];
|
||||||
const [
|
const [referencedDisplaySetsRef] = _getReferencedSeriesInstanceUIDsString(
|
||||||
referencedDisplaySetsRef,
|
displaySet,
|
||||||
referencedDisplaySetsCount,
|
'SEG'
|
||||||
] = _getReferencedSeriesInstanceUIDsString(displaySet, 'SEG');
|
);
|
||||||
|
|
||||||
const [row, column] = _viewportIndexToViewportPosition(
|
const [row, column] = _viewportIndexToViewportPosition(
|
||||||
viewportIndex,
|
viewportIndex,
|
||||||
@@ -106,10 +106,27 @@ const DubugReportModal = ({
|
|||||||
|
|
||||||
Object.keys(viewportSpecificData).forEach(viewportIndex => {
|
Object.keys(viewportSpecificData).forEach(viewportIndex => {
|
||||||
const displaySet = viewportSpecificData[viewportIndex];
|
const displaySet = viewportSpecificData[viewportIndex];
|
||||||
const [
|
const [referencedDisplaySetsRef] = _getReferencedSeriesInstanceUIDsString(
|
||||||
referencedDisplaySetsRef,
|
displaySet,
|
||||||
referencedDisplaySetsCount,
|
'RTSTRUCT'
|
||||||
] = _getReferencedSeriesInstanceUIDsString(displaySet, 'RTSTRUCT');
|
);
|
||||||
|
|
||||||
|
const [row, column] = _viewportIndexToViewportPosition(
|
||||||
|
viewportIndex,
|
||||||
|
numColumns
|
||||||
|
);
|
||||||
|
|
||||||
|
body += `[${row},${column}]\t${referencedDisplaySetsRef}\n`;
|
||||||
|
});
|
||||||
|
|
||||||
|
body += '== ReferencedSRSeriesInstanceUIDs ==\n';
|
||||||
|
|
||||||
|
Object.keys(viewportSpecificData).forEach(viewportIndex => {
|
||||||
|
const displaySet = viewportSpecificData[viewportIndex];
|
||||||
|
const [referencedDisplaySetsRef] = _getReferencedSeriesInstanceUIDsString(
|
||||||
|
displaySet,
|
||||||
|
'SR'
|
||||||
|
);
|
||||||
|
|
||||||
const [row, column] = _viewportIndexToViewportPosition(
|
const [row, column] = _viewportIndexToViewportPosition(
|
||||||
viewportIndex,
|
viewportIndex,
|
||||||
@@ -261,11 +278,15 @@ const getLayout = viewports => {
|
|||||||
<tr>
|
<tr>
|
||||||
<th>ReferencedSEGSeriesInstanceUIDs</th>
|
<th>ReferencedSEGSeriesInstanceUIDs</th>
|
||||||
</tr>
|
</tr>
|
||||||
{getReferencedSEGSeriesInstanceUIDsPerRow(viewports)}
|
{getReferencedSeriesInstanceUIDsPerRow(viewports, 'SEG')}
|
||||||
<tr>
|
<tr>
|
||||||
<th>ReferencedRTSTRUCTSeriesInstanceUIDs</th>
|
<th>ReferencedRTSTRUCTSeriesInstanceUIDs</th>
|
||||||
</tr>
|
</tr>
|
||||||
{getReferencedRTSTRUCTSeriesInstanceUIDsPerRow(viewports)}
|
{getReferencedSeriesInstanceUIDsPerRow(viewports, 'RTSTRUCT')}
|
||||||
|
<tr>
|
||||||
|
<th>ReferencedSRSeriesInstanceUIDs</th>
|
||||||
|
</tr>
|
||||||
|
{getReferencedSeriesInstanceUIDsPerRow(viewports, 'SR')}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -351,7 +372,7 @@ const _getReferencedSeriesInstanceUIDsString = (displaySet, Modality) => {
|
|||||||
return [referencedDisplaySetsRef, referencedDisplaySetsCount];
|
return [referencedDisplaySetsRef, referencedDisplaySetsCount];
|
||||||
};
|
};
|
||||||
|
|
||||||
const getReferencedSEGSeriesInstanceUIDsPerRow = viewports => {
|
const getReferencedSeriesInstanceUIDsPerRow = (viewports, Modality) => {
|
||||||
const { viewportSpecificData, numColumns } = viewports;
|
const { viewportSpecificData, numColumns } = viewports;
|
||||||
|
|
||||||
// NOTE viewportSpecificData is actually an object with numerical keys.
|
// NOTE viewportSpecificData is actually an object with numerical keys.
|
||||||
@@ -360,43 +381,7 @@ const getReferencedSEGSeriesInstanceUIDsPerRow = viewports => {
|
|||||||
const [
|
const [
|
||||||
referencedDisplaySetsRef,
|
referencedDisplaySetsRef,
|
||||||
referencedDisplaySetsCount,
|
referencedDisplaySetsCount,
|
||||||
] = _getReferencedSeriesInstanceUIDsString(displaySet, 'SEG');
|
] = _getReferencedSeriesInstanceUIDsString(displaySet, Modality);
|
||||||
|
|
||||||
const [row, column] = _viewportIndexToViewportPosition(
|
|
||||||
viewportIndex,
|
|
||||||
numColumns
|
|
||||||
);
|
|
||||||
|
|
||||||
if (referencedDisplaySetsCount > 1) {
|
|
||||||
return (
|
|
||||||
<tr>
|
|
||||||
<td>{`[${row},${column}]`}</td>
|
|
||||||
<td className="debug-overflowText-border">
|
|
||||||
{referencedDisplaySetsRef}
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return (
|
|
||||||
<tr>
|
|
||||||
<td>{`[${row},${column}]`}</td>
|
|
||||||
<td className="debug-overflowText">{referencedDisplaySetsRef}</td>
|
|
||||||
</tr>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const getReferencedRTSTRUCTSeriesInstanceUIDsPerRow = viewports => {
|
|
||||||
const { viewportSpecificData, numColumns } = viewports;
|
|
||||||
|
|
||||||
// NOTE viewportSpecificData is actually an object with numerical keys.
|
|
||||||
return Object.keys(viewportSpecificData).map(viewportIndex => {
|
|
||||||
const displaySet = viewportSpecificData[viewportIndex];
|
|
||||||
const [
|
|
||||||
referencedDisplaySetsRef,
|
|
||||||
referencedDisplaySetsCount,
|
|
||||||
] = _getReferencedSeriesInstanceUIDsString(displaySet, 'RTSTRUCT');
|
|
||||||
|
|
||||||
const [row, column] = _viewportIndexToViewportPosition(
|
const [row, column] = _viewportIndexToViewportPosition(
|
||||||
viewportIndex,
|
viewportIndex,
|
||||||
|
|||||||
@@ -3,6 +3,22 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.3.23](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.22...@ohif/extension-dicom-html@1.3.23) (2022-09-01)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-html
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.3.22](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.21...@ohif/extension-dicom-html@1.3.22) (2022-06-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-html
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [1.3.21](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.20...@ohif/extension-dicom-html@1.3.21) (2022-04-05)
|
## [1.3.21](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-html@1.3.20...@ohif/extension-dicom-html@1.3.21) (2022-04-05)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ohif/extension-dicom-html
|
**Note:** Version bump only for package @ohif/extension-dicom-html
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ohif/extension-dicom-html",
|
"name": "@ohif/extension-dicom-html",
|
||||||
"version": "1.3.21",
|
"version": "1.3.23",
|
||||||
"description": "OHIF extension for rendering structured reports to HTML",
|
"description": "OHIF extension for rendering structured reports to HTML",
|
||||||
"author": "OHIF",
|
"author": "OHIF",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@ohif/core": "^0.50.0",
|
"@ohif/core": "^0.50.0",
|
||||||
"dcmjs": "0.19.9",
|
"dcmjs": "0.24.10",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
"react": "^16.8.6",
|
"react": "^16.8.6",
|
||||||
"react-dom": "^16.8.6"
|
"react-dom": "^16.8.6"
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { MODULE_TYPES, utils } from '@ohif/core';
|
import { MODULE_TYPES, utils, metadata } from '@ohif/core';
|
||||||
|
|
||||||
// TODO: Should probably use dcmjs for this
|
// TODO: Should probably use dcmjs for this
|
||||||
const SOP_CLASS_UIDS = {
|
const SOP_CLASS_UIDS = {
|
||||||
@@ -10,7 +10,7 @@ const SOP_CLASS_UIDS = {
|
|||||||
MAMMOGRAPHY_CAD_SR: '1.2.840.10008.5.1.4.1.1.88.50',
|
MAMMOGRAPHY_CAD_SR: '1.2.840.10008.5.1.4.1.1.88.50',
|
||||||
CHEST_CAD_SR: '1.2.840.10008.5.1.4.1.1.88.65',
|
CHEST_CAD_SR: '1.2.840.10008.5.1.4.1.1.88.65',
|
||||||
X_RAY_RADIATION_DOSE_SR: '1.2.840.10008.5.1.4.1.1.88.67',
|
X_RAY_RADIATION_DOSE_SR: '1.2.840.10008.5.1.4.1.1.88.67',
|
||||||
ACQUISITION_CONTEXT_SR_STORAGE: '1.2.840.10008.5.1.4.1.1.88.71'
|
ACQUISITION_CONTEXT_SR_STORAGE: '1.2.840.10008.5.1.4.1.1.88.71',
|
||||||
};
|
};
|
||||||
|
|
||||||
const sopClassUIDs = Object.values(SOP_CLASS_UIDS);
|
const sopClassUIDs = Object.values(SOP_CLASS_UIDS);
|
||||||
@@ -32,7 +32,7 @@ const OHIFDicomHtmlSopClassHandler = {
|
|||||||
SeriesTime,
|
SeriesTime,
|
||||||
} = metadata;
|
} = metadata;
|
||||||
|
|
||||||
return {
|
const srDisplaySet = {
|
||||||
plugin: 'html',
|
plugin: 'html',
|
||||||
Modality: 'SR',
|
Modality: 'SR',
|
||||||
displaySetInstanceUID: utils.guid(),
|
displaySetInstanceUID: utils.guid(),
|
||||||
@@ -49,7 +49,15 @@ const OHIFDicomHtmlSopClassHandler = {
|
|||||||
authorizationHeaders,
|
authorizationHeaders,
|
||||||
sopClassUids: sopClassUIDs,
|
sopClassUids: sopClassUIDs,
|
||||||
images: series._instances,
|
images: series._instances,
|
||||||
|
isDerived: true,
|
||||||
|
referencedDisplaySets: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
srDisplaySet.getSourceDisplaySet = function() {
|
||||||
|
return srDisplaySet.referencedDisplaySets;
|
||||||
|
};
|
||||||
|
|
||||||
|
return srDisplaySet;
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,22 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [0.7.13](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.7.12...@ohif/extension-dicom-rt@0.7.13) (2022-09-01)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-rt
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [0.7.12](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.7.11...@ohif/extension-dicom-rt@0.7.12) (2022-08-31)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-rt
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [0.7.11](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.7.10...@ohif/extension-dicom-rt@0.7.11) (2022-04-05)
|
## [0.7.11](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-rt@0.7.10...@ohif/extension-dicom-rt@0.7.11) (2022-04-05)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ohif/extension-dicom-rt
|
**Note:** Version bump only for package @ohif/extension-dicom-rt
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ohif/extension-dicom-rt",
|
"name": "@ohif/extension-dicom-rt",
|
||||||
"version": "0.7.11",
|
"version": "0.7.13",
|
||||||
"description": "OHIF extension for rendering DICOM RTSTRUCTs on top of cornerstone images.",
|
"description": "OHIF extension for rendering DICOM RTSTRUCTs on top of cornerstone images.",
|
||||||
"author": "OHIF",
|
"author": "OHIF",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
"@ohif/core": "^0.50.0",
|
"@ohif/core": "^0.50.0",
|
||||||
"cornerstone-core": "^2.6.1",
|
"cornerstone-core": "^2.6.1",
|
||||||
"cornerstone-tools": "^6.0.6",
|
"cornerstone-tools": "^6.0.6",
|
||||||
"dcmjs": "0.19.9",
|
"dcmjs": "0.24.10",
|
||||||
"gl-matrix": "^3.3.0",
|
"gl-matrix": "^3.3.0",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
"react": "^16.8.6",
|
"react": "^16.8.6",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect, useCallback } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import cornerstoneTools from 'cornerstone-tools';
|
import cornerstoneTools from 'cornerstone-tools';
|
||||||
import cornerstone from 'cornerstone-core';
|
import cornerstone from 'cornerstone-core';
|
||||||
|
|||||||
@@ -3,6 +3,38 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [0.7.15](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.7.14...@ohif/extension-dicom-segmentation@0.7.15) (2022-09-19)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [0.7.14](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.7.13...@ohif/extension-dicom-segmentation@0.7.14) (2022-09-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [0.7.13](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.7.12...@ohif/extension-dicom-segmentation@0.7.13) (2022-09-01)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [0.7.12](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.7.11...@ohif/extension-dicom-segmentation@0.7.12) (2022-08-31)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [0.7.11](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.7.10...@ohif/extension-dicom-segmentation@0.7.11) (2022-04-05)
|
## [0.7.11](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-segmentation@0.7.10...@ohif/extension-dicom-segmentation@0.7.11) (2022-04-05)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
|
**Note:** Version bump only for package @ohif/extension-dicom-segmentation
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ohif/extension-dicom-segmentation",
|
"name": "@ohif/extension-dicom-segmentation",
|
||||||
"version": "0.7.11",
|
"version": "0.7.15",
|
||||||
"description": "OHIF extension for viewing segmentations in the 2D MPR view",
|
"description": "OHIF extension for viewing segmentations in the 2D MPR view",
|
||||||
"author": "OHIF",
|
"author": "OHIF",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
"@ohif/core": "^0.50.0",
|
"@ohif/core": "^0.50.0",
|
||||||
"cornerstone-core": "^2.6.1",
|
"cornerstone-core": "^2.6.1",
|
||||||
"cornerstone-tools": "^6.0.6",
|
"cornerstone-tools": "^6.0.6",
|
||||||
"dcmjs": "0.19.9",
|
"dcmjs": "0.24.10",
|
||||||
"prop-types": "^15.6.2",
|
"prop-types": "^15.6.2",
|
||||||
"react": "^16.8.6",
|
"react": "^16.8.6",
|
||||||
"react-dom": "^16.8.6"
|
"react-dom": "^16.8.6"
|
||||||
|
|||||||
+30
-6
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect, useCallback } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import cornerstoneTools from 'cornerstone-tools';
|
import cornerstoneTools from 'cornerstone-tools';
|
||||||
import cornerstone from 'cornerstone-core';
|
import cornerstone from 'cornerstone-core';
|
||||||
@@ -36,6 +36,7 @@ const { studyMetadataManager } = utils;
|
|||||||
* @param {Function} props.onConfigurationChange - Configuration change handler
|
* @param {Function} props.onConfigurationChange - Configuration change handler
|
||||||
* @param {Function} props.activeContexts - List of active application contexts
|
* @param {Function} props.activeContexts - List of active application contexts
|
||||||
* @param {Function} props.contexts - List of available application contexts
|
* @param {Function} props.contexts - List of available application contexts
|
||||||
|
* @param {Function} props.servicesManager - Services manager
|
||||||
* @returns component
|
* @returns component
|
||||||
*/
|
*/
|
||||||
const SegmentationPanel = ({
|
const SegmentationPanel = ({
|
||||||
@@ -50,6 +51,7 @@ const SegmentationPanel = ({
|
|||||||
onSelectedSegmentationChange,
|
onSelectedSegmentationChange,
|
||||||
activeContexts = [],
|
activeContexts = [],
|
||||||
contexts = {},
|
contexts = {},
|
||||||
|
servicesManager,
|
||||||
}) => {
|
}) => {
|
||||||
const isVTK = () => activeContexts.includes(contexts.VTK);
|
const isVTK = () => activeContexts.includes(contexts.VTK);
|
||||||
const isCornerstone = () => activeContexts.includes(contexts.CORNERSTONE);
|
const isCornerstone = () => activeContexts.includes(contexts.CORNERSTONE);
|
||||||
@@ -59,6 +61,9 @@ const SegmentationPanel = ({
|
|||||||
* store with context to make these kind of things less blurry.
|
* store with context to make these kind of things less blurry.
|
||||||
*/
|
*/
|
||||||
const { configuration } = cornerstoneTools.getModule('segmentation');
|
const { configuration } = cornerstoneTools.getModule('segmentation');
|
||||||
|
if (configuration.segsTolerance === undefined) {
|
||||||
|
configuration.segsTolerance = 1e-2;
|
||||||
|
}
|
||||||
const DEFAULT_BRUSH_RADIUS = configuration.radius || 10;
|
const DEFAULT_BRUSH_RADIUS = configuration.radius || 10;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -87,6 +92,25 @@ const SegmentationPanel = ({
|
|||||||
return studyMetadata.getFirstImageId(displaySetInstanceUID);
|
return studyMetadata.getFirstImageId(displaySetInstanceUID);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getAllSegDisplaySets = () => {
|
||||||
|
const { StudyInstanceUID } = getActiveViewport();
|
||||||
|
const studyMetadata = studyMetadataManager.get(StudyInstanceUID);
|
||||||
|
return studyMetadata.getDerivedDatasets({
|
||||||
|
Modality: 'SEG',
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const updateSegDisplaySetsTolerance = tolerance => {
|
||||||
|
const segDisplaySets = getAllSegDisplaySets();
|
||||||
|
segDisplaySets.forEach(segDisplaySet => {
|
||||||
|
// update tol value
|
||||||
|
segDisplaySet.tolerance = tolerance;
|
||||||
|
// reset load flags for allowing retry for seg parsing.
|
||||||
|
segDisplaySet.isLoaded = false;
|
||||||
|
segDisplaySet.loadError = false;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const getActiveLabelMaps3D = () => {
|
const getActiveLabelMaps3D = () => {
|
||||||
const { labelmaps3D, activeLabelmapIndex } = getBrushStackState();
|
const { labelmaps3D, activeLabelmapIndex } = getBrushStackState();
|
||||||
return labelmaps3D[activeLabelmapIndex];
|
return labelmaps3D[activeLabelmapIndex];
|
||||||
@@ -224,10 +248,7 @@ const SegmentationPanel = ({
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}, [
|
}, [activeIndex, viewports]);
|
||||||
activeIndex,
|
|
||||||
viewports,
|
|
||||||
]);
|
|
||||||
|
|
||||||
const updateSegmentationComboBox = e => {
|
const updateSegmentationComboBox = e => {
|
||||||
const index = e.detail.activatedLabelmapIndex;
|
const index = e.detail.activatedLabelmapIndex;
|
||||||
@@ -601,7 +622,9 @@ const SegmentationPanel = ({
|
|||||||
configuration.outlineWidth = newConfiguration.outlineWidth;
|
configuration.outlineWidth = newConfiguration.outlineWidth;
|
||||||
configuration.fillAlphaInactive = newConfiguration.fillAlphaInactive;
|
configuration.fillAlphaInactive = newConfiguration.fillAlphaInactive;
|
||||||
configuration.outlineAlphaInactive = newConfiguration.outlineAlphaInactive;
|
configuration.outlineAlphaInactive = newConfiguration.outlineAlphaInactive;
|
||||||
|
configuration.segsTolerance = newConfiguration.segsTolerance;
|
||||||
onConfigurationChange(newConfiguration);
|
onConfigurationChange(newConfiguration);
|
||||||
|
updateSegDisplaySetsTolerance(configuration.segsTolerance);
|
||||||
refreshViewports();
|
refreshViewports();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -650,6 +673,7 @@ const SegmentationPanel = ({
|
|||||||
configuration={configuration}
|
configuration={configuration}
|
||||||
onBack={() => setState(state => ({ ...state, showSettings: false }))}
|
onBack={() => setState(state => ({ ...state, showSettings: false }))}
|
||||||
onChange={updateConfiguration}
|
onChange={updateConfiguration}
|
||||||
|
servicesManager={servicesManager}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
@@ -694,7 +718,7 @@ const SegmentationPanel = ({
|
|||||||
count={state.segmentList.length}
|
count={state.segmentList.length}
|
||||||
isVisible={
|
isVisible={
|
||||||
state.segmentsHidden.filter(isHidden => isHidden === true).length <
|
state.segmentsHidden.filter(isHidden => isHidden === true).length <
|
||||||
state.segmentNumbers.length && state.segmentNumbers.length > 0
|
state.segmentNumbers.length && state.segmentNumbers.length > 0
|
||||||
}
|
}
|
||||||
onVisibilityChange={onVisibilityChangeHandler}
|
onVisibilityChange={onVisibilityChangeHandler}
|
||||||
>
|
>
|
||||||
|
|||||||
+42
-6
@@ -4,7 +4,7 @@ import { Range } from '@ohif/ui';
|
|||||||
|
|
||||||
import './SegmentationSettings.css';
|
import './SegmentationSettings.css';
|
||||||
|
|
||||||
const SegmentationSettings = ({ configuration, onBack, onChange, disabledFields = [] }) => {
|
const SegmentationSettings = ({ configuration, onBack, onChange, servicesManager, disabledFields = [] }) => {
|
||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
renderFill: configuration.renderFill,
|
renderFill: configuration.renderFill,
|
||||||
renderOutline: configuration.renderOutline,
|
renderOutline: configuration.renderOutline,
|
||||||
@@ -13,7 +13,8 @@ const SegmentationSettings = ({ configuration, onBack, onChange, disabledFields
|
|||||||
outlineAlpha: configuration.outlineAlpha,
|
outlineAlpha: configuration.outlineAlpha,
|
||||||
outlineWidth: configuration.outlineWidth,
|
outlineWidth: configuration.outlineWidth,
|
||||||
fillAlphaInactive: configuration.fillAlphaInactive,
|
fillAlphaInactive: configuration.fillAlphaInactive,
|
||||||
outlineAlphaInactive: configuration.outlineAlphaInactive
|
outlineAlphaInactive: configuration.outlineAlphaInactive,
|
||||||
|
segsTolerance: configuration.segsTolerance,
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -133,6 +134,40 @@ const SegmentationSettings = ({ configuration, onBack, onChange, disabledFields
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
<div className="settings-group" style={{ marginBottom: 15 }}>
|
||||||
|
<label style={{ margin: '0 15px' }}>
|
||||||
|
Tolerance:
|
||||||
|
<input
|
||||||
|
style={{ margin: '0 15px' }}
|
||||||
|
label="Tolerance"
|
||||||
|
onKeyPress={event => {
|
||||||
|
const validate = string => {
|
||||||
|
let rgx = /[^-.e0-9]+/g;
|
||||||
|
return string.match(rgx);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (validate(event.key)) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onChange={event => {
|
||||||
|
save('segsTolerance', event.target.value);
|
||||||
|
|
||||||
|
const { UINotificationService, LoggerService } = servicesManager.services;
|
||||||
|
const error = new Error('Segmentation loader tolerance changed. This operation can potentially generate errors in the Segmentation parsing.');
|
||||||
|
LoggerService.error({ error, message: error.message });
|
||||||
|
UINotificationService.show({
|
||||||
|
title: 'Segmentation panel',
|
||||||
|
message: error.message,
|
||||||
|
type: 'warning',
|
||||||
|
autoClose: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
value={state.segsTolerance}
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@@ -169,11 +204,12 @@ SegmentationSettings.propTypes = {
|
|||||||
renderFill: PropTypes.bool.isRequired,
|
renderFill: PropTypes.bool.isRequired,
|
||||||
renderOutline: PropTypes.bool.isRequired,
|
renderOutline: PropTypes.bool.isRequired,
|
||||||
shouldRenderInactiveLabelmaps: PropTypes.bool.isRequired,
|
shouldRenderInactiveLabelmaps: PropTypes.bool.isRequired,
|
||||||
fillAlpha: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, /* TODO: why fillAlpha is string? */
|
fillAlpha: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
|
||||||
outlineAlpha: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, /* TODO: why fillAlpha is string? */
|
outlineAlpha: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
|
||||||
outlineWidth: PropTypes.number.isRequired,
|
outlineWidth: PropTypes.number.isRequired,
|
||||||
fillAlphaInactive: PropTypes.number.isRequired,
|
fillAlphaInactive: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
|
||||||
outlineAlphaInactive: PropTypes.number.isRequired,
|
outlineAlphaInactive: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
|
||||||
|
segsTolerance: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
onBack: PropTypes.func.isRequired,
|
onBack: PropTypes.func.isRequired,
|
||||||
onChange: PropTypes.func.isRequired,
|
onChange: PropTypes.func.isRequired,
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ export default function getSopClassHandlerModule({ servicesManager }) {
|
|||||||
SeriesNumber,
|
SeriesNumber,
|
||||||
SeriesDescription,
|
SeriesDescription,
|
||||||
metadata,
|
metadata,
|
||||||
|
tolerance: 1e-2,
|
||||||
};
|
};
|
||||||
|
|
||||||
segDisplaySet.getSourceDisplaySet = function(
|
segDisplaySet.getSourceDisplaySet = function(
|
||||||
@@ -93,7 +94,7 @@ export default function getSopClassHandlerModule({ servicesManager }) {
|
|||||||
referencedDisplaySet.SeriesInstanceUID
|
referencedDisplaySet.SeriesInstanceUID
|
||||||
);
|
);
|
||||||
|
|
||||||
const results = await _parseSeg(segArrayBuffer, imageIds);
|
const results = await _parseSeg(segArrayBuffer, imageIds, segDisplaySet.tolerance);
|
||||||
if (results === undefined) {
|
if (results === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -149,10 +150,13 @@ export default function getSopClassHandlerModule({ servicesManager }) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function _parseSeg(arrayBuffer, imageIds) {
|
function _parseSeg(
|
||||||
const skipOverlapping = false;
|
arrayBuffer,
|
||||||
const tolerance = 1e-2;
|
imageIds,
|
||||||
const cornerstoneToolsVersion = 4;
|
tolerance = 1e-2,
|
||||||
|
skipOverlapping = false,
|
||||||
|
cornerstoneToolsVersion = 4
|
||||||
|
) {
|
||||||
return dcmjs.adapters.Cornerstone.Segmentation.generateToolState(
|
return dcmjs.adapters.Cornerstone.Segmentation.generateToolState(
|
||||||
imageIds,
|
imageIds,
|
||||||
arrayBuffer,
|
arrayBuffer,
|
||||||
|
|||||||
@@ -32,7 +32,6 @@ export default {
|
|||||||
|
|
||||||
const ExtendedSegmentationPanel = props => {
|
const ExtendedSegmentationPanel = props => {
|
||||||
const { activeContexts } = api.hooks.useAppContext();
|
const { activeContexts } = api.hooks.useAppContext();
|
||||||
|
|
||||||
const onDisplaySetLoadFailureHandler = error => {
|
const onDisplaySetLoadFailureHandler = error => {
|
||||||
LoggerService.error({ error, message: error.message });
|
LoggerService.error({ error, message: error.message });
|
||||||
UINotificationService.show({
|
UINotificationService.show({
|
||||||
@@ -78,6 +77,7 @@ export default {
|
|||||||
onConfigurationChange={onConfigurationChangeHandler}
|
onConfigurationChange={onConfigurationChangeHandler}
|
||||||
onSelectedSegmentationChange={onSelectedSegmentationChangeHandler}
|
onSelectedSegmentationChange={onSelectedSegmentationChangeHandler}
|
||||||
onDisplaySetLoadFailure={onDisplaySetLoadFailureHandler}
|
onDisplaySetLoadFailure={onDisplaySetLoadFailureHandler}
|
||||||
|
servicesManager={servicesManager}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,6 +3,14 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [0.2.24](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.23...@ohif/extension-dicom-tag-browser@0.2.24) (2022-09-01)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [0.2.23](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.22...@ohif/extension-dicom-tag-browser@0.2.23) (2022-04-06)
|
## [0.2.23](https://github.com/OHIF/Viewers/compare/@ohif/extension-dicom-tag-browser@0.2.22...@ohif/extension-dicom-tag-browser@0.2.23) (2022-04-06)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
|
**Note:** Version bump only for package @ohif/extension-dicom-tag-browser
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ohif/extension-dicom-tag-browser",
|
"name": "@ohif/extension-dicom-tag-browser",
|
||||||
"version": "0.2.23",
|
"version": "0.2.24",
|
||||||
"description": "OHIF extension for checking DICOM headers.",
|
"description": "OHIF extension for checking DICOM headers.",
|
||||||
"author": "OHIF",
|
"author": "OHIF",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@ohif/core": "^2.6.0",
|
"@ohif/core": "^2.6.0",
|
||||||
"dcmjs": "0.19.9",
|
"dcmjs": "0.24.10",
|
||||||
"react": "^16.8.6"
|
"react": "^16.8.6"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -3,6 +3,14 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [0.2.2](https://github.com/OHIF/Viewers/compare/@ohif/extension-lesion-tracker@0.2.1...@ohif/extension-lesion-tracker@0.2.2) (2022-06-29)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-lesion-tracker
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [0.2.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-lesion-tracker@0.2.0...@ohif/extension-lesion-tracker@0.2.1) (2020-09-03)
|
## [0.2.1](https://github.com/OHIF/Viewers/compare/@ohif/extension-lesion-tracker@0.2.0...@ohif/extension-lesion-tracker@0.2.1) (2020-09-03)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ohif/extension-lesion-tracker
|
**Note:** Version bump only for package @ohif/extension-lesion-tracker
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ohif/extension-lesion-tracker",
|
"name": "@ohif/extension-lesion-tracker",
|
||||||
"version": "0.2.1",
|
"version": "0.2.2",
|
||||||
"description": "OHIF extension for Lesion Tracker",
|
"description": "OHIF extension for Lesion Tracker",
|
||||||
"author": "OHIF",
|
"author": "OHIF",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@@ -76,13 +76,13 @@ const additionalFindings = [
|
|||||||
|
|
||||||
const currentCollections = [
|
const currentCollections = [
|
||||||
{
|
{
|
||||||
selectorAction: () => { },
|
selectorAction: () => {},
|
||||||
maxMeasurements: 3,
|
maxMeasurements: 3,
|
||||||
groupName: 'Measurements',
|
groupName: 'Measurements',
|
||||||
measurements: measurements,
|
measurements: measurements,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
selectorAction: () => { },
|
selectorAction: () => {},
|
||||||
groupName: 'Additional Findings',
|
groupName: 'Additional Findings',
|
||||||
measurements: additionalFindings,
|
measurements: additionalFindings,
|
||||||
},
|
},
|
||||||
@@ -90,13 +90,13 @@ const currentCollections = [
|
|||||||
|
|
||||||
const comparisonColletions = [
|
const comparisonColletions = [
|
||||||
{
|
{
|
||||||
selectorAction: () => { },
|
selectorAction: () => {},
|
||||||
maxMeasurements: 3,
|
maxMeasurements: 3,
|
||||||
groupName: 'Measurements',
|
groupName: 'Measurements',
|
||||||
measurements: measurements,
|
measurements: measurements,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
selectorAction: () => { },
|
selectorAction: () => {},
|
||||||
groupName: 'Additional Findings',
|
groupName: 'Additional Findings',
|
||||||
measurements: additionalFindings,
|
measurements: additionalFindings,
|
||||||
},
|
},
|
||||||
@@ -128,7 +128,7 @@ const comparisonTimepoints = [
|
|||||||
{
|
{
|
||||||
key: 'Comparison',
|
key: 'Comparison',
|
||||||
date: '15-Jun-18',
|
date: '15-Jun-18',
|
||||||
}
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const MeasurementComparisonTable = () => {
|
const MeasurementComparisonTable = () => {
|
||||||
@@ -138,8 +138,8 @@ const MeasurementComparisonTable = () => {
|
|||||||
timepoints={comparisonTimepoints}
|
timepoints={comparisonTimepoints}
|
||||||
overallWarnings={overallWarnings}
|
overallWarnings={overallWarnings}
|
||||||
measurementCollection={comparisonCollections}
|
measurementCollection={comparisonCollections}
|
||||||
onRelabelClick={() => { }}
|
onRelabelClick={() => {}}
|
||||||
onEditDescriptionClick={() => { }}
|
onEditDescriptionClick={() => {}}
|
||||||
/>
|
/>
|
||||||
<div className="generate-report">
|
<div className="generate-report">
|
||||||
<button className="btn btn-primary">Generate Report</button>
|
<button className="btn btn-primary">Generate Report</button>
|
||||||
|
|||||||
@@ -3,6 +3,102 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.12.36](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.12.35...@ohif/extension-vtk@1.12.36) (2022-10-25)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-vtk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.12.35](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.12.34...@ohif/extension-vtk@1.12.35) (2022-09-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-vtk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.12.34](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.12.33...@ohif/extension-vtk@1.12.34) (2022-09-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-vtk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.12.33](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.12.32...@ohif/extension-vtk@1.12.33) (2022-09-19)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-vtk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.12.32](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.12.31...@ohif/extension-vtk@1.12.32) (2022-09-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-vtk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.12.31](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.12.30...@ohif/extension-vtk@1.12.31) (2022-09-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-vtk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.12.30](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.12.29...@ohif/extension-vtk@1.12.30) (2022-09-01)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-vtk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.12.29](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.12.28...@ohif/extension-vtk@1.12.29) (2022-08-31)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-vtk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.12.28](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.12.27...@ohif/extension-vtk@1.12.28) (2022-08-24)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-vtk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.12.27](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.12.26...@ohif/extension-vtk@1.12.27) (2022-06-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-vtk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.12.26](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.12.25...@ohif/extension-vtk@1.12.26) (2022-06-29)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-vtk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.12.25](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.12.24...@ohif/extension-vtk@1.12.25) (2022-06-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/extension-vtk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [1.12.24](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.12.23...@ohif/extension-vtk@1.12.24) (2022-06-14)
|
## [1.12.24](https://github.com/OHIF/Viewers/compare/@ohif/extension-vtk@1.12.23...@ohif/extension-vtk@1.12.24) (2022-06-14)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ohif/extension-vtk
|
**Note:** Version bump only for package @ohif/extension-vtk
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ohif/extension-vtk",
|
"name": "@ohif/extension-vtk",
|
||||||
"version": "1.12.24",
|
"version": "1.12.36",
|
||||||
"description": "OHIF extension for VTK.js",
|
"description": "OHIF extension for VTK.js",
|
||||||
"author": "OHIF",
|
"author": "OHIF",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -34,8 +34,8 @@
|
|||||||
"@ohif/ui": "^0.50.0",
|
"@ohif/ui": "^0.50.0",
|
||||||
"cornerstone-core": "^2.6.1",
|
"cornerstone-core": "^2.6.1",
|
||||||
"cornerstone-tools": "^6.0.6",
|
"cornerstone-tools": "^6.0.6",
|
||||||
"cornerstone-wado-image-loader": "^4.1.0",
|
"cornerstone-wado-image-loader": "^4.2.1",
|
||||||
"dcmjs": "0.19.9",
|
"dcmjs": "0.24.10",
|
||||||
"dicom-parser": "^1.8.11",
|
"dicom-parser": "^1.8.11",
|
||||||
"i18next": "^17.0.3",
|
"i18next": "^17.0.3",
|
||||||
"i18next-browser-languagedetector": "^3.0.1",
|
"i18next-browser-languagedetector": "^3.0.1",
|
||||||
@@ -50,13 +50,13 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.5.5",
|
"@babel/runtime": "^7.5.5",
|
||||||
"lodash.throttle": "^4.1.1",
|
"lodash.throttle": "^4.1.1",
|
||||||
"react-vtkjs-viewport": "^0.14.4"
|
"react-vtkjs-viewport": "^0.14.5"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@ohif/core": "^2.16.19",
|
"@ohif/core": "^2.16.30",
|
||||||
"@ohif/ui": "^1.10.8",
|
"@ohif/ui": "^1.10.10",
|
||||||
"cornerstone-tools": "^6.0.6",
|
"cornerstone-tools": "^6.0.6",
|
||||||
"cornerstone-wado-image-loader": "^4.1.0",
|
"cornerstone-wado-image-loader": "^4.2.1",
|
||||||
"dicom-parser": "^1.8.11",
|
"dicom-parser": "^1.8.11",
|
||||||
"gh-pages": "^2.0.1",
|
"gh-pages": "^2.0.1",
|
||||||
"i18next": "^17.0.3",
|
"i18next": "^17.0.3",
|
||||||
|
|||||||
@@ -3,6 +3,100 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [2.16.30](https://github.com/OHIF/Viewers/compare/@ohif/core@2.16.29...@ohif/core@2.16.30) (2022-10-25)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* 2965 Correct Parsing Logic for Qualitative Instance Level SR ([#2972](https://github.com/OHIF/Viewers/issues/2972)) ([f7db74a](https://github.com/OHIF/Viewers/commit/f7db74a84376598065b6fa2c00cd5735415ff651))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.16.29](https://github.com/OHIF/Viewers/compare/@ohif/core@2.16.28...@ohif/core@2.16.29) (2022-09-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/core
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.16.28](https://github.com/OHIF/Viewers/compare/@ohif/core@2.16.27...@ohif/core@2.16.28) (2022-09-19)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/core
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.16.27](https://github.com/OHIF/Viewers/compare/@ohif/core@2.16.26...@ohif/core@2.16.27) (2022-09-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/core
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.16.26](https://github.com/OHIF/Viewers/compare/@ohif/core@2.16.25...@ohif/core@2.16.26) (2022-09-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/core
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.16.25](https://github.com/OHIF/Viewers/compare/@ohif/core@2.16.24...@ohif/core@2.16.25) (2022-09-01)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/core
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.16.24](https://github.com/OHIF/Viewers/compare/@ohif/core@2.16.23...@ohif/core@2.16.24) (2022-08-31)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/core
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.16.23](https://github.com/OHIF/Viewers/compare/@ohif/core@2.16.22...@ohif/core@2.16.23) (2022-08-24)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/core
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.16.22](https://github.com/OHIF/Viewers/compare/@ohif/core@2.16.21...@ohif/core@2.16.22) (2022-06-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/core
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.16.21](https://github.com/OHIF/Viewers/compare/@ohif/core@2.16.20...@ohif/core@2.16.21) (2022-06-29)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/core
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [2.16.20](https://github.com/OHIF/Viewers/compare/@ohif/core@2.16.19...@ohif/core@2.16.20) (2022-06-28)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* Re IDC2797, fix double parsing of SR qualitative annotations ([#2830](https://github.com/OHIF/Viewers/issues/2830)) ([9f813e0](https://github.com/OHIF/Viewers/commit/9f813e0ea08f0aada8efab9ef6228ad90dd1758d))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [2.16.19](https://github.com/OHIF/Viewers/compare/@ohif/core@2.16.18...@ohif/core@2.16.19) (2022-06-14)
|
## [2.16.19](https://github.com/OHIF/Viewers/compare/@ohif/core@2.16.18...@ohif/core@2.16.19) (2022-06-14)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ohif/core
|
**Note:** Version bump only for package @ohif/core
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ohif/core",
|
"name": "@ohif/core",
|
||||||
"version": "2.16.19",
|
"version": "2.16.30",
|
||||||
"description": "Generic business logic for web-based medical imaging applications",
|
"description": "Generic business logic for web-based medical imaging applications",
|
||||||
"author": "OHIF Core Team",
|
"author": "OHIF Core Team",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -33,13 +33,13 @@
|
|||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"cornerstone-core": "^2.6.1",
|
"cornerstone-core": "^2.6.1",
|
||||||
"cornerstone-tools": "^6.0.6",
|
"cornerstone-tools": "^6.0.6",
|
||||||
"cornerstone-wado-image-loader": "^4.1.0",
|
"cornerstone-wado-image-loader": "^4.2.1",
|
||||||
"dicom-parser": "^1.8.11"
|
"dicom-parser": "^1.8.11"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.5.5",
|
"@babel/runtime": "^7.5.5",
|
||||||
"ajv": "^6.10.0",
|
"ajv": "^6.10.0",
|
||||||
"dcmjs": "0.19.9",
|
"dcmjs": "0.24.10",
|
||||||
"dicomweb-client": "^0.8.3",
|
"dicomweb-client": "^0.8.3",
|
||||||
"immer": "9.0.12",
|
"immer": "9.0.12",
|
||||||
"isomorphic-base64": "^1.0.2",
|
"isomorphic-base64": "^1.0.2",
|
||||||
|
|||||||
@@ -8,6 +8,16 @@ const parseSCOORD3D = ({ servicesManager, displaySets }) => {
|
|||||||
const { MeasurementService } = servicesManager.services;
|
const { MeasurementService } = servicesManager.services;
|
||||||
|
|
||||||
const srDisplaySets = displaySets.filter(ds => ds.Modality === 'SR');
|
const srDisplaySets = displaySets.filter(ds => ds.Modality === 'SR');
|
||||||
|
const imageDisplaySets = displaySets.filter(
|
||||||
|
ds =>
|
||||||
|
ds.Modality !== 'SR' &&
|
||||||
|
ds.Modality !== 'SEG' &&
|
||||||
|
ds.Modality !== 'RTSTRUCT'
|
||||||
|
);
|
||||||
|
|
||||||
|
imageDisplaySets.forEach(imageDisplaySet => {
|
||||||
|
imageDisplaySet.SRLabels = [];
|
||||||
|
});
|
||||||
|
|
||||||
srDisplaySets.forEach(srDisplaySet => {
|
srDisplaySets.forEach(srDisplaySet => {
|
||||||
const firstInstance = srDisplaySet.metadata;
|
const firstInstance = srDisplaySet.metadata;
|
||||||
@@ -28,13 +38,6 @@ const parseSCOORD3D = ({ servicesManager, displaySets }) => {
|
|||||||
srDisplaySet.isRehydratable = isRehydratable(srDisplaySet, mappings);
|
srDisplaySet.isRehydratable = isRehydratable(srDisplaySet, mappings);
|
||||||
srDisplaySet.isLoaded = true;
|
srDisplaySet.isLoaded = true;
|
||||||
|
|
||||||
const imageDisplaySets = displaySets.filter(
|
|
||||||
ds =>
|
|
||||||
ds.Modality !== 'SR' &&
|
|
||||||
ds.Modality !== 'SEG' &&
|
|
||||||
ds.Modality !== 'RTSTRUCT' &&
|
|
||||||
ds.Modality !== 'RTDOSE'
|
|
||||||
);
|
|
||||||
imageDisplaySets.forEach(imageDisplaySet => {
|
imageDisplaySets.forEach(imageDisplaySet => {
|
||||||
// Check currently added displaySets and add measurements if the sources exist.
|
// Check currently added displaySets and add measurements if the sources exist.
|
||||||
checkIfCanAddMeasurementsToDisplaySet(srDisplaySet, imageDisplaySet);
|
checkIfCanAddMeasurementsToDisplaySet(srDisplaySet, imageDisplaySet);
|
||||||
@@ -127,11 +130,10 @@ const checkIfCanAddMeasurementsToDisplaySet = (
|
|||||||
|
|
||||||
const imageIds = images.map(i => i.getImageId());
|
const imageIds = images.map(i => i.getImageId());
|
||||||
const SOPInstanceUIDs = images.map(i => i.SOPInstanceUID);
|
const SOPInstanceUIDs = images.map(i => i.SOPInstanceUID);
|
||||||
imageDisplaySet.SRLabels = [];
|
const colors = new Map();
|
||||||
measurements.forEach(measurement => {
|
measurements.forEach(measurement => {
|
||||||
const { coords } = measurement;
|
const { coords } = measurement;
|
||||||
|
coords.forEach((coord, index) => {
|
||||||
coords.forEach(coord => {
|
|
||||||
if (coord.ReferencedSOPSequence !== undefined) {
|
if (coord.ReferencedSOPSequence !== undefined) {
|
||||||
const imageIndex = SOPInstanceUIDs.findIndex(
|
const imageIndex = SOPInstanceUIDs.findIndex(
|
||||||
SOPInstanceUID =>
|
SOPInstanceUID =>
|
||||||
@@ -139,29 +141,50 @@ const checkIfCanAddMeasurementsToDisplaySet = (
|
|||||||
coord.ReferencedSOPSequence.ReferencedSOPInstanceUID
|
coord.ReferencedSOPSequence.ReferencedSOPInstanceUID
|
||||||
);
|
);
|
||||||
if (imageIndex > -1) {
|
if (imageIndex > -1) {
|
||||||
|
if (!srDisplaySet.referencedDisplaySets.includes(imageDisplaySet)) {
|
||||||
|
srDisplaySet.referencedDisplaySets.push(imageDisplaySet);
|
||||||
|
}
|
||||||
|
|
||||||
const imageId = imageIds[imageIndex];
|
const imageId = imageIds[imageIndex];
|
||||||
const imageMetadata = images[imageIndex].getData().metadata;
|
const imageMetadata = images[imageIndex].getData().metadata;
|
||||||
|
|
||||||
const coords = measurement.coords;
|
if (coord.GraphicType === 'TEXT') {
|
||||||
for (let i = 0; i < coords.length; i++) {
|
const key =
|
||||||
const coord = coords[i];
|
measurement.labels[index].label + measurement.labels[index].value;
|
||||||
if (coord.GraphicType !== 'TEXT') {
|
let color = colors.get(key);
|
||||||
continue;
|
if (!color) {
|
||||||
|
// random dark color
|
||||||
|
color =
|
||||||
|
'hsla(' + Math.floor(Math.random() * 360) + ', 70%, 30%, 1)';
|
||||||
|
colors.set(key, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
measurement.labels[index].color = color;
|
||||||
|
measurement.isSRText = true;
|
||||||
|
measurement.labels[index].visible = true;
|
||||||
|
|
||||||
imageDisplaySet.SRLabels.push({
|
imageDisplaySet.SRLabels.push({
|
||||||
ReferencedSOPInstanceUID:
|
ReferencedSOPInstanceUID:
|
||||||
coord.ReferencedSOPSequence.ReferencedSOPInstanceUID,
|
coord.ReferencedSOPSequence.ReferencedSOPInstanceUID,
|
||||||
labels: measurement.labels[i],
|
labels: measurement.labels[index],
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
addMeasurement(
|
if (index === 0) {
|
||||||
measurement,
|
addMeasurement(
|
||||||
imageId,
|
measurement,
|
||||||
imageMetadata,
|
imageId,
|
||||||
imageDisplaySet.displaySetInstanceUID
|
imageMetadata,
|
||||||
);
|
imageDisplaySet.displaySetInstanceUID
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
addMeasurement(
|
||||||
|
measurement,
|
||||||
|
imageId,
|
||||||
|
imageMetadata,
|
||||||
|
imageDisplaySet.displaySetInstanceUID
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -26,8 +26,10 @@ export default function addMeasurement(
|
|||||||
|
|
||||||
const measurementData = {
|
const measurementData = {
|
||||||
TrackingUniqueIdentifier: measurement.TrackingUniqueIdentifier,
|
TrackingUniqueIdentifier: measurement.TrackingUniqueIdentifier,
|
||||||
|
TrackingIdentifier: measurement.TrackingIdentifier,
|
||||||
renderableData: {},
|
renderableData: {},
|
||||||
labels: measurement.labels,
|
labels: measurement.labels,
|
||||||
|
isSRText: measurement.isSRText,
|
||||||
};
|
};
|
||||||
|
|
||||||
measurement.coords.forEach(coord => {
|
measurement.coords.forEach(coord => {
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ const getReferencedImagesList = ImagingMeasurementReportContentSequence => {
|
|||||||
CodeNameCodeSequenceValues.ImageLibrary
|
CodeNameCodeSequenceValues.ImageLibrary
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!ImageLibrary.ContentSequence) {
|
if (!ImageLibrary || !ImageLibrary.ContentSequence) {
|
||||||
return referencedImages;
|
return referencedImages;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,6 +22,10 @@ const getReferencedImagesList = ImagingMeasurementReportContentSequence => {
|
|||||||
CodeNameCodeSequenceValues.ImageLibraryGroup
|
CodeNameCodeSequenceValues.ImageLibraryGroup
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (!ImageLibraryGroup || !ImageLibraryGroup.ContentSequence) {
|
||||||
|
return referencedImages;
|
||||||
|
}
|
||||||
|
|
||||||
getSequenceAsArray(ImageLibraryGroup.ContentSequence).forEach(item => {
|
getSequenceAsArray(ImageLibraryGroup.ContentSequence).forEach(item => {
|
||||||
const { ReferencedSOPSequence } = item;
|
const { ReferencedSOPSequence } = item;
|
||||||
if (ReferencedSOPSequence) {
|
if (ReferencedSOPSequence) {
|
||||||
|
|||||||
@@ -21,16 +21,32 @@ const parseDicomStructuredReport = (
|
|||||||
displaySets,
|
displaySets,
|
||||||
external
|
external
|
||||||
) => {
|
) => {
|
||||||
if (external && external.servicesManager) {
|
|
||||||
parseSCOORD3D({ servicesManager: external.servicesManager, displaySets });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the dicom data as an Object
|
// Get the dicom data as an Object
|
||||||
const dicomData = dcmjs.data.DicomMessage.readFile(part10SRArrayBuffer);
|
const dicomData = dcmjs.data.DicomMessage.readFile(part10SRArrayBuffer);
|
||||||
const dataset = dcmjs.data.DicomMetaDictionary.naturalizeDataset(
|
const dataset = dcmjs.data.DicomMetaDictionary.naturalizeDataset(
|
||||||
dicomData.dict
|
dicomData.dict
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const {
|
||||||
|
LoggerService,
|
||||||
|
UINotificationService,
|
||||||
|
} = external.servicesManager.services;
|
||||||
|
if (external && external.servicesManager) {
|
||||||
|
try {
|
||||||
|
parseSCOORD3D({ servicesManager: external.servicesManager, displaySets });
|
||||||
|
} catch (error) {
|
||||||
|
const seriesDescription = dataset.SeriesDescription || '';
|
||||||
|
LoggerService.error({ error, message: error.message });
|
||||||
|
UINotificationService.show({
|
||||||
|
title: `Failed to parse ${seriesDescription} SR display set`,
|
||||||
|
message: error.message,
|
||||||
|
type: 'error',
|
||||||
|
autoClose: false,
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const { MeasurementReport } = dcmjs.adapters.Cornerstone;
|
const { MeasurementReport } = dcmjs.adapters.Cornerstone;
|
||||||
|
|
||||||
let storedMeasurementByToolType;
|
let storedMeasurementByToolType;
|
||||||
@@ -38,11 +54,12 @@ const parseDicomStructuredReport = (
|
|||||||
storedMeasurementByToolType = MeasurementReport.generateToolState(dataset);
|
storedMeasurementByToolType = MeasurementReport.generateToolState(dataset);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const seriesDescription = dataset.SeriesDescription || '';
|
const seriesDescription = dataset.SeriesDescription || '';
|
||||||
LogManager.publish(LogManager.EVENTS.OnLog, {
|
LoggerService.error({ error, message: error.message });
|
||||||
|
UINotificationService.show({
|
||||||
title: `Failed to parse ${seriesDescription} measurement report`,
|
title: `Failed to parse ${seriesDescription} measurement report`,
|
||||||
type: 'warning',
|
message: error.message,
|
||||||
message: error.message || '',
|
type: 'error',
|
||||||
notify: true,
|
autoClose: false,
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,12 +67,13 @@ export class HotkeysManager {
|
|||||||
UINotificationService,
|
UINotificationService,
|
||||||
LoggerService,
|
LoggerService,
|
||||||
} = this._servicesManager.services;
|
} = this._servicesManager.services;
|
||||||
const message = 'Erro while setting hotkeys';
|
const message = 'Error while setting hotkeys';
|
||||||
LoggerService.error({ error, message });
|
LoggerService.error({ error, message });
|
||||||
UINotificationService.show({
|
UINotificationService.show({
|
||||||
title: 'Hotkeys Manager',
|
title: 'Hotkeys Manager',
|
||||||
message,
|
message,
|
||||||
type: 'error',
|
type: 'error',
|
||||||
|
autoClose: false,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -469,8 +469,8 @@ class StudyLoadingListener {
|
|||||||
|
|
||||||
// TODO: Make this work for plugins
|
// TODO: Make this work for plugins
|
||||||
if (!stack) {
|
if (!stack) {
|
||||||
console.warn('Skipping adding displaySet to StudyLoadingListener');
|
//console.warn('Skipping adding displaySet to StudyLoadingListener');
|
||||||
console.warn(displaySet);
|
//console.warn(displaySet);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -275,6 +275,8 @@ class StudyMetadata extends Metadata {
|
|||||||
|
|
||||||
const otherDisplaySets = allDisplaySets.filter(
|
const otherDisplaySets = allDisplaySets.filter(
|
||||||
ds =>
|
ds =>
|
||||||
|
ds &&
|
||||||
|
derivatedDisplaySet &&
|
||||||
ds.displaySetInstanceUID !== derivatedDisplaySet.displaySetInstanceUID
|
ds.displaySetInstanceUID !== derivatedDisplaySet.displaySetInstanceUID
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -350,6 +352,26 @@ class StudyMetadata extends Metadata {
|
|||||||
referencedSeriesInstanceUID
|
referencedSeriesInstanceUID
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
if (
|
||||||
|
!displaySet.referencedDisplaySets ||
|
||||||
|
displaySet.referencedDisplaySets.length === 0
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const filteredReferencedDisplaySets = displaySet.referencedDisplaySets.filter(
|
||||||
|
referencedDisplaySet =>
|
||||||
|
referencedDisplaySet.SeriesInstanceUID ===
|
||||||
|
referencedSeriesInstanceUID
|
||||||
|
);
|
||||||
|
|
||||||
|
if (
|
||||||
|
filteredReferencedDisplaySets &&
|
||||||
|
filteredReferencedDisplaySets.length !== 0
|
||||||
|
) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,8 @@ export const dicomSRDisplayTool = {
|
|||||||
options: {
|
options: {
|
||||||
measurementTable: {
|
measurementTable: {
|
||||||
displayFunction: data => {
|
displayFunction: data => {
|
||||||
return `(SR) ${data.lesionNamingNumber ||
|
return `(SR) ${data.TrackingIdentifier ||
|
||||||
|
data.lesionNamingNumber ||
|
||||||
data.measurementNumber ||
|
data.measurementNumber ||
|
||||||
data.text ||
|
data.text ||
|
||||||
''}`;
|
''}`;
|
||||||
|
|||||||
@@ -420,6 +420,10 @@ class MeasurementService {
|
|||||||
throw new Error('No source definition provided.');
|
throw new Error('No source definition provided.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (definition == 'stack' || definition == 'stackPrefetch') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const sourceInfo = this._getSourceInfo(source);
|
const sourceInfo = this._getSourceInfo(source);
|
||||||
|
|
||||||
if (!this._sourceHasMappings(source)) {
|
if (!this._sourceHasMappings(source)) {
|
||||||
|
|||||||
@@ -19,17 +19,4 @@ describe('retrieveStudyMetadata.js', () => {
|
|||||||
|
|
||||||
expect(callWithNoStudyInstanceUID).toThrow(Error);
|
expect(callWithNoStudyInstanceUID).toThrow(Error);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('caches and returns the same promise for identical studyInstanceUIDs', () => {
|
|
||||||
const firstPromise = retrieveStudyMetadata(
|
|
||||||
fakeDicomWebServer,
|
|
||||||
'fake-study-instance-uid'
|
|
||||||
);
|
|
||||||
const secondPromise = retrieveStudyMetadata(
|
|
||||||
fakeDicomWebServer,
|
|
||||||
'fake-study-instance-uid'
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(firstPromise).toBe(secondPromise);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
@@ -102,6 +102,35 @@ async function makeSOPInstance(server, study, instance) {
|
|||||||
SOPInstanceUID,
|
SOPInstanceUID,
|
||||||
} = naturalizedInstance;
|
} = naturalizedInstance;
|
||||||
|
|
||||||
|
const validate = string => {
|
||||||
|
let rgx = /[^.0-9]+/g;
|
||||||
|
return string.match(rgx);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (StudyInstanceUID === undefined || validate(StudyInstanceUID)) {
|
||||||
|
const error =
|
||||||
|
'makeSOPInstance: StudyInstanceUID is not conforming with the UID (DICOM UI VR) character repertoire, skipping SOPInstance.';
|
||||||
|
console.error(error);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SeriesInstanceUID === undefined || validate(SeriesInstanceUID)) {
|
||||||
|
const error =
|
||||||
|
'makeSOPInstance: SeriesInstanceUID is not conforming with the UID (DICOM UI VR) character repertoire, skipping SOPInstance.';
|
||||||
|
console.error(error);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SOPInstanceUID === undefined || validate(SOPInstanceUID)) {
|
||||||
|
const error =
|
||||||
|
'makeSOPInstance: SOPInstanceUID is not conforming with the UID (DICOM UI VR) character repertoire, skipping SOPInstance.';
|
||||||
|
console.error(error);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let series = study.seriesMap[SeriesInstanceUID];
|
let series = study.seriesMap[SeriesInstanceUID];
|
||||||
|
|
||||||
if (!series) {
|
if (!series) {
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ function createAndAddStack(stackMap, study, displaySet, stackUpdatedCallbacks) {
|
|||||||
const imageIds = [];
|
const imageIds = [];
|
||||||
let imageId;
|
let imageId;
|
||||||
|
|
||||||
displaySet.images.forEach((instance, imageIndex) => {
|
images.forEach((instance, imageIndex) => {
|
||||||
const image = instance.getData();
|
const image = instance.getData();
|
||||||
const metaData = {
|
const metaData = {
|
||||||
instance: image, // in this context, instance will be the data of the InstanceMetadata object...
|
instance: image, // in this context, instance will be the data of the InstanceMetadata object...
|
||||||
@@ -35,7 +35,7 @@ function createAndAddStack(stackMap, study, displaySet, stackUpdatedCallbacks) {
|
|||||||
imageIndex: imageIndex + 1,
|
imageIndex: imageIndex + 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
const naturalizedInstance = instance.getData().metadata;
|
const naturalizedInstance = image.metadata;
|
||||||
const NumberOfFrames = naturalizedInstance.NumberOfFrames;
|
const NumberOfFrames = naturalizedInstance.NumberOfFrames;
|
||||||
|
|
||||||
if (NumberOfFrames > 1) {
|
if (NumberOfFrames > 1) {
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ async function loadAndCacheDerivedDisplaySets(
|
|||||||
title: 'DICOM Segmentation Loader',
|
title: 'DICOM Segmentation Loader',
|
||||||
message: error.message,
|
message: error.message,
|
||||||
type: 'error',
|
type: 'error',
|
||||||
autoClose: true,
|
autoClose: false,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,22 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [1.10.10](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.10.9...@ohif/ui@1.10.10) (2022-08-24)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/ui
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [1.10.9](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.10.8...@ohif/ui@1.10.9) (2022-06-29)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/ui
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [1.10.8](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.10.7...@ohif/ui@1.10.8) (2022-04-06)
|
## [1.10.8](https://github.com/OHIF/Viewers/compare/@ohif/ui@1.10.7...@ohif/ui@1.10.8) (2022-04-06)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ohif/ui
|
**Note:** Version bump only for package @ohif/ui
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ohif/ui",
|
"name": "@ohif/ui",
|
||||||
"version": "1.10.8",
|
"version": "1.10.10",
|
||||||
"description": "A set of React components for Medical Imaging Viewers",
|
"description": "A set of React components for Medical Imaging Viewers",
|
||||||
"author": "OHIF Contributors",
|
"author": "OHIF Contributors",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
|||||||
@@ -9,6 +9,14 @@ import { TableListItem } from './../tableList/TableListItem.js';
|
|||||||
|
|
||||||
import './MeasurementTableItem.styl';
|
import './MeasurementTableItem.styl';
|
||||||
|
|
||||||
|
const ColoredCircle = ({ color }) => {
|
||||||
|
return <div className="item-color" style={{ backgroundColor: color }}></div>;
|
||||||
|
};
|
||||||
|
|
||||||
|
ColoredCircle.propTypes = {
|
||||||
|
color: PropTypes.string.isRequired,
|
||||||
|
};
|
||||||
|
|
||||||
class MeasurementTableItem extends Component {
|
class MeasurementTableItem extends Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
measurementData: PropTypes.object.isRequired,
|
measurementData: PropTypes.object.isRequired,
|
||||||
@@ -21,6 +29,14 @@ class MeasurementTableItem extends Component {
|
|||||||
t: PropTypes.func,
|
t: PropTypes.func,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
collapsed: true,
|
||||||
|
visible: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const {
|
const {
|
||||||
warningTitle = '',
|
warningTitle = '',
|
||||||
@@ -93,27 +109,115 @@ class MeasurementTableItem extends Component {
|
|||||||
actionButtons.push(deleteButton);
|
actionButtons.push(deleteButton);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
if (
|
||||||
<TableListItem
|
this.props.measurementData.isSRText === true &&
|
||||||
itemKey={this.props.measurementData.measurementNumber}
|
this.props.measurementData.labels &&
|
||||||
itemClass={`measurementItem ${this.props.itemClass} ${hasWarningClass}`}
|
this.props.measurementData.labels.length > 0
|
||||||
itemIndex={this.props.itemIndex}
|
) {
|
||||||
onItemClick={this.onItemClick}
|
return (
|
||||||
>
|
<React.Fragment>
|
||||||
<div>
|
<TableListItem
|
||||||
<div className="measurementLocation">
|
key={this.props.measurementData.measurementNumber}
|
||||||
{this.props.t(this.props.measurementData.label, {
|
itemKey={this.props.measurementData.measurementNumber}
|
||||||
keySeparator: '>',
|
itemClass={`measurementItem ${this.props.itemClass} ${hasWarningClass}`}
|
||||||
nsSeparator: '|',
|
itemIndex={this.props.itemIndex}
|
||||||
|
onItemClick={this.onItemClick}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div className="measurementLocation">
|
||||||
|
{this.props.t(this.props.measurementData.label, {
|
||||||
|
keySeparator: '>',
|
||||||
|
nsSeparator: '|',
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="icons">
|
||||||
|
<div className="displayTexts">{this.getDataDisplayText()}</div>
|
||||||
|
<Icon
|
||||||
|
className={`eye-icon`}
|
||||||
|
name={this.state.visible ? 'eye' : 'eye-closed'}
|
||||||
|
width="20px"
|
||||||
|
height="20px"
|
||||||
|
onClick={() => {
|
||||||
|
this.props.measurementData.labels.forEach(label => {
|
||||||
|
label.visible = !this.state.visible;
|
||||||
|
});
|
||||||
|
|
||||||
|
this.setState({
|
||||||
|
visible: !this.state.visible,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Icon
|
||||||
|
className={`angle-double-${
|
||||||
|
this.state.collapsed ? 'down' : 'up'
|
||||||
|
}`}
|
||||||
|
name={`angle-double-${this.state.collapsed ? 'down' : 'up'}`}
|
||||||
|
width="20px"
|
||||||
|
height="20px"
|
||||||
|
onClick={() => {
|
||||||
|
this.setState({
|
||||||
|
collapsed: !this.state.collapsed,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</TableListItem>
|
||||||
|
{this.state.collapsed &&
|
||||||
|
this.props.measurementData.labels.map((SRLabel, index) => {
|
||||||
|
return (
|
||||||
|
<TableListItem
|
||||||
|
key={index}
|
||||||
|
itemKey={index}
|
||||||
|
itemMeta={<ColoredCircle color={SRLabel.color} />}
|
||||||
|
itemMetaClass="item-color-section"
|
||||||
|
onItemClick={this.onItemClick}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div className="icons">
|
||||||
|
<span style={{ width: '90px' }}>
|
||||||
|
{SRLabel.label + ' : ' + SRLabel.value}
|
||||||
|
</span>
|
||||||
|
<Icon
|
||||||
|
className={`eye-icon`}
|
||||||
|
name={SRLabel.visible ? 'eye' : 'eye-closed'}
|
||||||
|
width="20px"
|
||||||
|
height="20px"
|
||||||
|
onClick={() => {
|
||||||
|
SRLabel.visible = !SRLabel.visible;
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</TableListItem>
|
||||||
|
);
|
||||||
})}
|
})}
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<TableListItem
|
||||||
|
key={this.props.measurementData.measurementNumber}
|
||||||
|
itemKey={this.props.measurementData.measurementNumber}
|
||||||
|
itemClass={`measurementItem ${this.props.itemClass} ${hasWarningClass}`}
|
||||||
|
itemIndex={this.props.itemIndex}
|
||||||
|
onItemClick={this.onItemClick}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<div className="measurementLocation">
|
||||||
|
{this.props.t(this.props.measurementData.label, {
|
||||||
|
keySeparator: '>',
|
||||||
|
nsSeparator: '|',
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
<div className="displayTexts">{this.getDataDisplayText()}</div>
|
||||||
|
{!this.props.measurementData.isReadOnly && (
|
||||||
|
<div className="rowActions">{actionButtons}</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="displayTexts">{this.getDataDisplayText()}</div>
|
</TableListItem>
|
||||||
{!this.props.measurementData.isReadOnly && (
|
);
|
||||||
<div className="rowActions">{actionButtons}</div>
|
}
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</TableListItem>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
onItemClick = event => {
|
onItemClick = event => {
|
||||||
|
|||||||
@@ -1,4 +1,16 @@
|
|||||||
.measurementItem
|
.measurementItem
|
||||||
|
.item-color-section
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.item-color
|
||||||
|
margin-top: 8px;
|
||||||
|
border-radius: 100%;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
|
||||||
.rowActions
|
.rowActions
|
||||||
margin-left: -1px;
|
margin-left: -1px;
|
||||||
background-color: var(--ui-gray-darker)
|
background-color: var(--ui-gray-darker)
|
||||||
@@ -63,3 +75,16 @@
|
|||||||
width: 22px;
|
width: 22px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
pointer-events: inherit;
|
pointer-events: inherit;
|
||||||
|
|
||||||
|
.icons
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border-radius: 5px;
|
||||||
|
|
||||||
|
.icons .eye-icon
|
||||||
|
margin-left: 100px;
|
||||||
|
margin-right: -5px;
|
||||||
|
.icons .angle-double-down
|
||||||
|
.icons .angle-double-up
|
||||||
|
margin-left: 15px;
|
||||||
|
margin-right: -5px;
|
||||||
@@ -18,6 +18,7 @@ $headerRowHeight = 63px
|
|||||||
|
|
||||||
.tableListHeaderTitle
|
.tableListHeaderTitle
|
||||||
color: var(--text-secondary-color)
|
color: var(--text-secondary-color)
|
||||||
|
max-width: 230px
|
||||||
font-size: 22px
|
font-size: 22px
|
||||||
font-weight: 300
|
font-weight: 300
|
||||||
line-height: $headerRowHeight
|
line-height: $headerRowHeight
|
||||||
|
|||||||
@@ -12,16 +12,13 @@ export class TableListItem extends Component {
|
|||||||
itemIndex: PropTypes.number,
|
itemIndex: PropTypes.number,
|
||||||
itemMeta: PropTypes.node,
|
itemMeta: PropTypes.node,
|
||||||
itemMetaClass: PropTypes.string,
|
itemMetaClass: PropTypes.string,
|
||||||
itemKey: PropTypes.oneOfType([
|
itemKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||||
PropTypes.string,
|
|
||||||
PropTypes.number,
|
|
||||||
]),
|
|
||||||
onItemClick: PropTypes.func.isRequired,
|
onItemClick: PropTypes.func.isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
itemMeta: null,
|
itemMeta: null,
|
||||||
itemMetaClass: ''
|
itemMetaClass: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|||||||
@@ -3,6 +3,129 @@
|
|||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
||||||
|
|
||||||
|
## [4.12.42](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.41...@ohif/viewer@4.12.42) (2022-10-25)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.12.41](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.40...@ohif/viewer@4.12.41) (2022-09-26)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.12.40](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.39...@ohif/viewer@4.12.40) (2022-09-20)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.12.39](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.38...@ohif/viewer@4.12.39) (2022-09-19)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.12.38](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.37...@ohif/viewer@4.12.38) (2022-09-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.12.37](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.36...@ohif/viewer@4.12.37) (2022-09-12)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.12.36](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.35...@ohif/viewer@4.12.36) (2022-09-08)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* hotkey page up/down did not work ([#2910](https://github.com/OHIF/Viewers/issues/2910)) ([d74ad37](https://github.com/OHIF/Viewers/commit/d74ad370e091c8af2d93ec35f688c4ef902bab2b))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.12.35](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.34...@ohif/viewer@4.12.35) (2022-09-02)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.12.34](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.33...@ohif/viewer@4.12.34) (2022-09-01)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.12.33](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.32...@ohif/viewer@4.12.33) (2022-08-31)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.12.32](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.31...@ohif/viewer@4.12.32) (2022-08-25)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.12.31](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.30...@ohif/viewer@4.12.31) (2022-08-24)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.12.30](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.29...@ohif/viewer@4.12.30) (2022-06-30)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.12.29](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.28...@ohif/viewer@4.12.29) (2022-06-29)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## [4.12.28](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.27...@ohif/viewer@4.12.28) (2022-06-28)
|
||||||
|
|
||||||
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## [4.12.27](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.26...@ohif/viewer@4.12.27) (2022-06-14)
|
## [4.12.27](https://github.com/OHIF/Viewers/compare/@ohif/viewer@4.12.26...@ohif/viewer@4.12.27) (2022-06-14)
|
||||||
|
|
||||||
**Note:** Version bump only for package @ohif/viewer
|
**Note:** Version bump only for package @ohif/viewer
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@ohif/viewer",
|
"name": "@ohif/viewer",
|
||||||
"version": "4.12.27",
|
"version": "4.12.42",
|
||||||
"description": "OHIF Viewer",
|
"description": "OHIF Viewer",
|
||||||
"author": "OHIF Contributors",
|
"author": "OHIF Contributors",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
@@ -47,26 +47,26 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.5.5",
|
"@babel/runtime": "^7.5.5",
|
||||||
"@ohif/core": "^2.16.19",
|
"@ohif/core": "^2.16.30",
|
||||||
"@ohif/extension-cornerstone": "^2.12.11",
|
"@ohif/extension-cornerstone": "^2.12.15",
|
||||||
"@ohif/extension-debugging": "^0.3.2",
|
"@ohif/extension-debugging": "^0.3.3",
|
||||||
"@ohif/extension-dicom-html": "^1.3.21",
|
"@ohif/extension-dicom-html": "^1.3.23",
|
||||||
"@ohif/extension-dicom-microscopy": "^0.52.0",
|
"@ohif/extension-dicom-microscopy": "^0.52.0",
|
||||||
"@ohif/extension-dicom-pdf": "^1.1.2",
|
"@ohif/extension-dicom-pdf": "^1.1.2",
|
||||||
"@ohif/extension-dicom-rt": "^0.7.11",
|
"@ohif/extension-dicom-rt": "^0.7.13",
|
||||||
"@ohif/extension-dicom-segmentation": "^0.7.11",
|
"@ohif/extension-dicom-segmentation": "^0.7.15",
|
||||||
"@ohif/extension-lesion-tracker": "^0.2.1",
|
"@ohif/extension-lesion-tracker": "^0.2.2",
|
||||||
"@ohif/extension-vtk": "^1.12.24",
|
"@ohif/extension-vtk": "^1.12.36",
|
||||||
"@ohif/i18n": "^0.53.0",
|
"@ohif/i18n": "^0.53.0",
|
||||||
"@ohif/ui": "^1.10.8",
|
"@ohif/ui": "^1.10.10",
|
||||||
"@tanem/react-nprogress": "^1.1.25",
|
"@tanem/react-nprogress": "^1.1.25",
|
||||||
"classnames": "^2.2.6",
|
"classnames": "^2.2.6",
|
||||||
"core-js": "^3.2.1",
|
"core-js": "^3.2.1",
|
||||||
"cornerstone-core": "^2.6.1",
|
"cornerstone-core": "^2.6.1",
|
||||||
"cornerstone-math": "^0.1.9",
|
"cornerstone-math": "^0.1.9",
|
||||||
"cornerstone-tools": "^6.0.6",
|
"cornerstone-tools": "^6.0.6",
|
||||||
"cornerstone-wado-image-loader": "^4.1.0",
|
"cornerstone-wado-image-loader": "^4.2.1",
|
||||||
"dcmjs": "0.19.9",
|
"dcmjs": "0.24.10",
|
||||||
"dicom-parser": "^1.8.11",
|
"dicom-parser": "^1.8.11",
|
||||||
"dicomweb-client": "^0.8.3",
|
"dicomweb-client": "^0.8.3",
|
||||||
"hammerjs": "^2.0.8",
|
"hammerjs": "^2.0.8",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { redux } from '@ohif/core';
|
import { redux, utils } from '@ohif/core';
|
||||||
import store from './../../store';
|
import store from './../../store';
|
||||||
|
|
||||||
const commandsModule = ({ commandsManager }) => {
|
const commandsModule = ({ commandsManager }) => {
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ function convertMeasurementsToTableData(toolCollections, timepoints) {
|
|||||||
|
|
||||||
Object.keys(toolCollections).forEach(toolId => {
|
Object.keys(toolCollections).forEach(toolId => {
|
||||||
const toolMeasurements = toolCollections[toolId];
|
const toolMeasurements = toolCollections[toolId];
|
||||||
|
|
||||||
const tool = tools.find(tool => tool.id === toolId);
|
const tool = tools.find(tool => tool.id === toolId);
|
||||||
const { displayFunction } = tool.options.measurementTable;
|
const { displayFunction } = tool.options.measurementTable;
|
||||||
|
|
||||||
@@ -131,12 +132,13 @@ function convertMeasurementsToTableData(toolCollections, timepoints) {
|
|||||||
Object.keys(groupedMeasurements).forEach(groupedMeasurementsIndex => {
|
Object.keys(groupedMeasurements).forEach(groupedMeasurementsIndex => {
|
||||||
const measurementNumberList =
|
const measurementNumberList =
|
||||||
groupedMeasurements[groupedMeasurementsIndex];
|
groupedMeasurements[groupedMeasurementsIndex];
|
||||||
|
|
||||||
const measurementData = measurementNumberList[0];
|
const measurementData = measurementNumberList[0];
|
||||||
const {
|
const {
|
||||||
measurementNumber,
|
measurementNumber,
|
||||||
lesionNamingNumber,
|
lesionNamingNumber,
|
||||||
toolType,
|
toolType,
|
||||||
isReadOnly
|
isReadOnly,
|
||||||
} = measurementData;
|
} = measurementData;
|
||||||
const measurementId = measurementData._id;
|
const measurementId = measurementData._id;
|
||||||
|
|
||||||
@@ -150,6 +152,8 @@ function convertMeasurementsToTableData(toolCollections, timepoints) {
|
|||||||
const tableMeasurement = {
|
const tableMeasurement = {
|
||||||
itemNumber: lesionNamingNumber,
|
itemNumber: lesionNamingNumber,
|
||||||
label: getMeasurementText(measurementData),
|
label: getMeasurementText(measurementData),
|
||||||
|
labels: measurementData.labels,
|
||||||
|
isSRText: measurementData.isSRText,
|
||||||
measurementId,
|
measurementId,
|
||||||
measurementNumber,
|
measurementNumber,
|
||||||
lesionNamingNumber,
|
lesionNamingNumber,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { measurements, utils } from '@ohif/core';
|
import { measurements, utils } from '@ohif/core';
|
||||||
|
import { servicesManager } from './../../App.js';
|
||||||
const { MeasurementApi } = measurements;
|
const { MeasurementApi } = measurements;
|
||||||
const { studyMetadataManager } = utils;
|
const { studyMetadataManager } = utils;
|
||||||
|
|
||||||
@@ -19,6 +19,25 @@ export default function jumpToRowItem(
|
|||||||
timepointManagerState,
|
timepointManagerState,
|
||||||
options = { invertViewportTimepointsOrder: false, childToolKey: null }
|
options = { invertViewportTimepointsOrder: false, childToolKey: null }
|
||||||
) {
|
) {
|
||||||
|
const viewports = viewportsState.layout.viewports;
|
||||||
|
const activeViewportIndex = viewportsState.activeViewportIndex;
|
||||||
|
const activeViewport = viewports[activeViewportIndex];
|
||||||
|
if (activeViewport.vtk) {
|
||||||
|
const error = new Error('Measurements are not supported by the MPR mode.');
|
||||||
|
const { UINotificationService, LoggerService } = servicesManager.services;
|
||||||
|
LoggerService.error({ error, message: error.message });
|
||||||
|
UINotificationService.show({
|
||||||
|
title: 'Measurements panel',
|
||||||
|
message: error.message,
|
||||||
|
type: 'warning',
|
||||||
|
autoClose: true,
|
||||||
|
});
|
||||||
|
return {
|
||||||
|
viewportSpecificData: [],
|
||||||
|
layout: [], // TODO: if we need to change layout, we should return this here
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const numViewports = viewportsState.layout.viewports.length;
|
const numViewports = viewportsState.layout.viewports.length;
|
||||||
const numTimepoints = timepointManagerState.timepoints.length;
|
const numTimepoints = timepointManagerState.timepoints.length;
|
||||||
const { measurements, timepoints } = timepointManagerState;
|
const { measurements, timepoints } = timepointManagerState;
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ const mapDispatchToProps = (dispatch, ownProps) => {
|
|||||||
title: 'DICOM Segmentation Loader',
|
title: 'DICOM Segmentation Loader',
|
||||||
message: error.message,
|
message: error.message,
|
||||||
type: 'error',
|
type: 'error',
|
||||||
autoClose: true,
|
autoClose: false,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ const mapDispatchToProps = (dispatch, ownProps) => {
|
|||||||
);
|
);
|
||||||
document.dispatchEvent(selectionFired);
|
document.dispatchEvent(selectionFired);
|
||||||
});
|
});
|
||||||
} else {
|
} else if (Modality !== 'SR') {
|
||||||
displaySet = displaySet.getSourceDisplaySet(ownProps.studyMetadata);
|
displaySet = displaySet.getSourceDisplaySet(ownProps.studyMetadata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -262,7 +262,11 @@ class Viewer extends Component {
|
|||||||
const { currentTimepointId } = this;
|
const { currentTimepointId } = this;
|
||||||
|
|
||||||
this.timepointApi.retrieveTimepoints({ PatientID });
|
this.timepointApi.retrieveTimepoints({ PatientID });
|
||||||
this.measurementApi.retrieveMeasurements(PatientID, [currentTimepointId]);
|
this.measurementApi
|
||||||
|
.retrieveMeasurements(PatientID, [currentTimepointId])
|
||||||
|
.then(() => {
|
||||||
|
this._updateThumbnails();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -469,7 +473,7 @@ const _checkForDerivedDisplaySets = async function(displaySet, study) {
|
|||||||
let derivedDisplaySetsNumber = 0;
|
let derivedDisplaySetsNumber = 0;
|
||||||
if (
|
if (
|
||||||
displaySet.Modality &&
|
displaySet.Modality &&
|
||||||
!['SEG', 'SR', 'RTSTRUCT', 'RTDOSE'].includes(displaySet.Modality)
|
!['SEG', 'SR', 'RTSTRUCT'].includes(displaySet.Modality)
|
||||||
) {
|
) {
|
||||||
const studyMetadata = studyMetadataManager.get(study.StudyInstanceUID);
|
const studyMetadata = studyMetadataManager.get(study.StudyInstanceUID);
|
||||||
|
|
||||||
@@ -608,9 +612,29 @@ const _isDisplaySetActive = function(
|
|||||||
if (
|
if (
|
||||||
displaySet.Modality !== 'SEG' &&
|
displaySet.Modality !== 'SEG' &&
|
||||||
displaySet.Modality !== 'RTSTRUCT' &&
|
displaySet.Modality !== 'RTSTRUCT' &&
|
||||||
displaySet.Modality !== 'RTDOSE'
|
displaySet.Modality !== 'SR'
|
||||||
) {
|
) {
|
||||||
active = activeDisplaySetInstanceUID === displaySetInstanceUID;
|
active = activeDisplaySetInstanceUID === displaySetInstanceUID;
|
||||||
|
} else if (displaySet.Modality === 'SR') {
|
||||||
|
active = activeDisplaySetInstanceUID === displaySetInstanceUID;
|
||||||
|
|
||||||
|
if (!active && displaySet.getSourceDisplaySet) {
|
||||||
|
const referencedDisplaySet = displaySet.getSourceDisplaySet(
|
||||||
|
studies,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
if (referencedDisplaySet && referencedDisplaySet.length !== 0) {
|
||||||
|
for (let i = 0; i < referencedDisplaySet.length; i++) {
|
||||||
|
if (
|
||||||
|
referencedDisplaySet[i].displaySetInstanceUID ===
|
||||||
|
activeDisplaySetInstanceUID
|
||||||
|
) {
|
||||||
|
active = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else if (displaySet.getSourceDisplaySet) {
|
} else if (displaySet.getSourceDisplaySet) {
|
||||||
if (displaySet.Modality === 'SEG') {
|
if (displaySet.Modality === 'SEG') {
|
||||||
const { referencedDisplaySet } = displaySet.getSourceDisplaySet(
|
const { referencedDisplaySet } = displaySet.getSourceDisplaySet(
|
||||||
@@ -661,10 +685,9 @@ const _mapStudiesToThumbnails = function(studies, activeDisplaySetInstanceUID) {
|
|||||||
let altImageText;
|
let altImageText;
|
||||||
|
|
||||||
if (displaySet.Modality && displaySet.Modality === 'SEG') {
|
if (displaySet.Modality && displaySet.Modality === 'SEG') {
|
||||||
// TODO: We want to replace this with a thumbnail showing
|
|
||||||
// the segmentation map on the image, but this is easier
|
|
||||||
// and better than what we have right now.
|
|
||||||
altImageText = 'SEG';
|
altImageText = 'SEG';
|
||||||
|
} else if (displaySet.Modality && displaySet.Modality === 'SR') {
|
||||||
|
altImageText = 'SR';
|
||||||
} else if (displaySet.images && displaySet.images.length) {
|
} else if (displaySet.images && displaySet.images.length) {
|
||||||
const imageIndex = Math.floor(displaySet.images.length / 2);
|
const imageIndex = Math.floor(displaySet.images.length / 2);
|
||||||
imageId = displaySet.images[imageIndex].getImageId();
|
imageId = displaySet.images[imageIndex].getImageId();
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ class ViewerMain extends Component {
|
|||||||
title: 'DICOM Segmentation Loader',
|
title: 'DICOM Segmentation Loader',
|
||||||
message: error.message,
|
message: error.message,
|
||||||
type: 'error',
|
type: 'error',
|
||||||
autoClose: true,
|
autoClose: false,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -173,7 +173,7 @@ class ViewerMain extends Component {
|
|||||||
);
|
);
|
||||||
document.dispatchEvent(selectionFired);
|
document.dispatchEvent(selectionFired);
|
||||||
});
|
});
|
||||||
} else {
|
} else if (Modality !== 'SR') {
|
||||||
displaySet = displaySet.getSourceDisplaySet(this.props.studies);
|
displaySet = displaySet.getSourceDisplaySet(this.props.studies);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -721,14 +721,6 @@
|
|||||||
"@babel/helper-regex" "^7.4.4"
|
"@babel/helper-regex" "^7.4.4"
|
||||||
regexpu-core "^4.6.0"
|
regexpu-core "^4.6.0"
|
||||||
|
|
||||||
"@babel/polyfill@^7.8.3":
|
|
||||||
version "7.8.7"
|
|
||||||
resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.8.7.tgz#151ec24c7135481336168c3bd8b8bf0cf91c032f"
|
|
||||||
integrity sha512-LeSfP9bNZH2UOZgcGcZ0PIHUt1ZuHub1L3CVmEyqLxCeDLm4C5Gi8jRH8ZX2PNpDhQCo0z6y/+DIs2JlliXW8w==
|
|
||||||
dependencies:
|
|
||||||
core-js "^2.6.5"
|
|
||||||
regenerator-runtime "^0.13.4"
|
|
||||||
|
|
||||||
"@babel/preset-env@^7.5.0", "@babel/preset-env@^7.5.5":
|
"@babel/preset-env@^7.5.0", "@babel/preset-env@^7.5.5":
|
||||||
version "7.6.3"
|
version "7.6.3"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.6.3.tgz#9e1bf05a2e2d687036d24c40e4639dc46cef2271"
|
resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.6.3.tgz#9e1bf05a2e2d687036d24c40e4639dc46cef2271"
|
||||||
@@ -796,7 +788,15 @@
|
|||||||
"@babel/plugin-transform-react-jsx-self" "^7.0.0"
|
"@babel/plugin-transform-react-jsx-self" "^7.0.0"
|
||||||
"@babel/plugin-transform-react-jsx-source" "^7.0.0"
|
"@babel/plugin-transform-react-jsx-source" "^7.0.0"
|
||||||
|
|
||||||
"@babel/runtime@7.1.2", "@babel/runtime@7.5.5", "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.16.5", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.6":
|
"@babel/runtime-corejs2@^7.17.8":
|
||||||
|
version "7.18.9"
|
||||||
|
resolved "https://registry.yarnpkg.com/@babel/runtime-corejs2/-/runtime-corejs2-7.18.9.tgz#d88c327736ecc4b9db13ddef5a33a004b9aeac74"
|
||||||
|
integrity sha512-l057ZarpDX2QnXM89ViR2BgRFgTy2l5UFGDt0SbInhim1N/ljBgPeTJV0kRG1/Bo7CkHfYfrNNwTeQ2CPph9xQ==
|
||||||
|
dependencies:
|
||||||
|
core-js "^2.6.12"
|
||||||
|
regenerator-runtime "^0.13.4"
|
||||||
|
|
||||||
|
"@babel/runtime@7.1.2", "@babel/runtime@7.5.5", "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.16.5", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.6":
|
||||||
version "7.5.5"
|
version "7.5.5"
|
||||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132"
|
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132"
|
||||||
integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ==
|
integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ==
|
||||||
@@ -4242,13 +4242,13 @@ capture-exit@^2.0.0:
|
|||||||
rsvp "^4.8.4"
|
rsvp "^4.8.4"
|
||||||
|
|
||||||
cardboard-vr-display@^1.0.15:
|
cardboard-vr-display@^1.0.15:
|
||||||
version "1.0.16"
|
version "1.0.19"
|
||||||
resolved "https://registry.yarnpkg.com/cardboard-vr-display/-/cardboard-vr-display-1.0.16.tgz#f91e2798e8fb70a348599638c6742c72dfeadabc"
|
resolved "https://registry.yarnpkg.com/cardboard-vr-display/-/cardboard-vr-display-1.0.19.tgz#81dcde1804b329b8228b757ac00e1fd2afa9d748"
|
||||||
integrity sha512-GFBWPMH/ixy4Ji014BAO1ryddGHphtJlA8gUR6UdKsOpPjUQukCKpgsx2XIJ5oBlqXnDQOcLVRqBWyuvTI32jQ==
|
integrity sha512-+MjcnWKAkb95p68elqZLDPzoiF/dGncQilLGvPBM5ZorABp/ao3lCs7nnRcYBckmuNkg1V/5rdGDKoUaCVsHzQ==
|
||||||
dependencies:
|
dependencies:
|
||||||
gl-preserve-state "^1.0.0"
|
gl-preserve-state "^1.0.0"
|
||||||
nosleep.js "^0.7.0"
|
nosleep.js "^0.7.0"
|
||||||
webvr-polyfill-dpdb "^1.0.11"
|
webvr-polyfill-dpdb "^1.0.17"
|
||||||
|
|
||||||
cardinal@^2.1.1:
|
cardinal@^2.1.1:
|
||||||
version "2.1.1"
|
version "2.1.1"
|
||||||
@@ -5079,11 +5079,16 @@ core-js-compat@^3.1.1:
|
|||||||
browserslist "^4.7.2"
|
browserslist "^4.7.2"
|
||||||
semver "^6.3.0"
|
semver "^6.3.0"
|
||||||
|
|
||||||
core-js@^2.4.0, core-js@^2.5.0, core-js@^2.5.7, core-js@^2.6.5:
|
core-js@^2.4.0, core-js@^2.5.0, core-js@^2.5.7:
|
||||||
version "2.6.10"
|
version "2.6.10"
|
||||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.10.tgz#8a5b8391f8cc7013da703411ce5b585706300d7f"
|
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.10.tgz#8a5b8391f8cc7013da703411ce5b585706300d7f"
|
||||||
integrity sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==
|
integrity sha512-I39t74+4t+zau64EN1fE5v2W31Adtc/REhzWN+gWRRXg6WH5qAsZm62DHpQ1+Yhe4047T55jvzz7MUqF/dBBlA==
|
||||||
|
|
||||||
|
core-js@^2.6.12:
|
||||||
|
version "2.6.12"
|
||||||
|
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
|
||||||
|
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
|
||||||
|
|
||||||
core-js@^3.2.1:
|
core-js@^3.2.1:
|
||||||
version "3.3.4"
|
version "3.3.4"
|
||||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.3.4.tgz#6b0a23392958317bfb46e40b090529a923add669"
|
resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.3.4.tgz#6b0a23392958317bfb46e40b090529a923add669"
|
||||||
@@ -5112,10 +5117,10 @@ cornerstone-tools@^6.0.6:
|
|||||||
"@babel/runtime" "7.1.2"
|
"@babel/runtime" "7.1.2"
|
||||||
cornerstone-math "0.1.9"
|
cornerstone-math "0.1.9"
|
||||||
|
|
||||||
cornerstone-wado-image-loader@^4.1.0:
|
cornerstone-wado-image-loader@^4.2.1:
|
||||||
version "4.1.0"
|
version "4.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/cornerstone-wado-image-loader/-/cornerstone-wado-image-loader-4.1.0.tgz#a85c206eb23e188181ed3f1dcf3ec715e65efcb4"
|
resolved "https://registry.yarnpkg.com/cornerstone-wado-image-loader/-/cornerstone-wado-image-loader-4.2.1.tgz#ee37797fe8970dcb7e438a6d87b710e817066100"
|
||||||
integrity sha512-QRoMqBE5xEc1Jttg3eH6RB4jFY2aIEjd9rcbvJszefl0isow+JwcLv2kh1xkSvqGfHGozcz+F4mrORyTNNLuFQ==
|
integrity sha512-nRu+6GfHFERpZLytH/SCfymODCz1SC1NKRv/xn02pr3PEkzU6fvKI76sSxSFOozxDsYljupTRNi/qGMprfdBHA==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@cornerstonejs/codec-charls" "^0.1.1"
|
"@cornerstonejs/codec-charls" "^0.1.1"
|
||||||
"@cornerstonejs/codec-libjpeg-turbo-8bit" "^0.0.7"
|
"@cornerstonejs/codec-libjpeg-turbo-8bit" "^0.0.7"
|
||||||
@@ -5632,13 +5637,12 @@ dateformat@^3.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae"
|
resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae"
|
||||||
integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==
|
integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==
|
||||||
|
|
||||||
dcmjs@0.19.9:
|
dcmjs@0.24.10:
|
||||||
version "0.19.9"
|
version "0.24.10"
|
||||||
resolved "https://registry.yarnpkg.com/dcmjs/-/dcmjs-0.19.9.tgz#be500101b1f75a28ea9eb7ef845a8ed197355e76"
|
resolved "https://registry.yarnpkg.com/dcmjs/-/dcmjs-0.24.10.tgz#048a12a1905175763274545c17bb38b506cdfd00"
|
||||||
integrity sha512-V+0tND+SPX5e7WFeLzeoooaTsZbiKmEP2i3AyERsojaXXfaDV5E+pta5IqId4Ok1yfRT5qfTFwLGstGT6nLplA==
|
integrity sha512-kugEdBqwwTx7lqUxm4jdklkMJiQ8pZ0aqMw9WkszkDU5lDWHyq2kbRccACtcwqygC7j1d36w8uG/vNLMejeMBg==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/polyfill" "^7.8.3"
|
"@babel/runtime-corejs2" "^7.17.8"
|
||||||
"@babel/runtime" "^7.8.4"
|
|
||||||
gl-matrix "^3.1.0"
|
gl-matrix "^3.1.0"
|
||||||
lodash.clonedeep "^4.5.0"
|
lodash.clonedeep "^4.5.0"
|
||||||
loglevelnext "^3.0.1"
|
loglevelnext "^3.0.1"
|
||||||
@@ -11204,7 +11208,7 @@ normalize-url@^3.0.0, normalize-url@^3.3.0:
|
|||||||
nosleep.js@^0.7.0:
|
nosleep.js@^0.7.0:
|
||||||
version "0.7.0"
|
version "0.7.0"
|
||||||
resolved "https://registry.yarnpkg.com/nosleep.js/-/nosleep.js-0.7.0.tgz#cfd919c25523ca0d0f4a69fb3305c083adaee289"
|
resolved "https://registry.yarnpkg.com/nosleep.js/-/nosleep.js-0.7.0.tgz#cfd919c25523ca0d0f4a69fb3305c083adaee289"
|
||||||
integrity sha1-z9kZwlUjyg0PSmn7MwXAg62u4ok=
|
integrity sha512-Z4B1HgvzR+en62ghwZf6BwAR6x4/pjezsiMcbF9KMLh7xoscpoYhaSXfY3lLkqC68AtW+/qLJ1lzvBIj0FGaTA==
|
||||||
|
|
||||||
npm-bundled@^1.0.1:
|
npm-bundled@^1.0.1:
|
||||||
version "1.0.6"
|
version "1.0.6"
|
||||||
@@ -13515,10 +13519,10 @@ react-transition-group@^4.1.1:
|
|||||||
loose-envify "^1.4.0"
|
loose-envify "^1.4.0"
|
||||||
prop-types "^15.6.2"
|
prop-types "^15.6.2"
|
||||||
|
|
||||||
react-vtkjs-viewport@^0.14.4:
|
react-vtkjs-viewport@^0.14.5:
|
||||||
version "0.14.4"
|
version "0.14.5"
|
||||||
resolved "https://registry.yarnpkg.com/react-vtkjs-viewport/-/react-vtkjs-viewport-0.14.4.tgz#8cc5a49738fff3fee75ead61c98307bc24710151"
|
resolved "https://registry.yarnpkg.com/react-vtkjs-viewport/-/react-vtkjs-viewport-0.14.5.tgz#95cda594370e557d43aa966392ed92926e6c53c1"
|
||||||
integrity sha512-WKU87iqH6AQ1R8zp1hUXU4hsGwfbkkoUhzSCjbBGZ9Di0ELYNx/xY9DtdmgsKOU5Y5Arp5+VQW/ziFsq2KTcTA==
|
integrity sha512-DE+Ytub6veya3DTvItJdZhkTR8MppoLkrq57qhN9vd2meykeS1fZp9cDyWmq92dJ7IHSuS5FPof8ucsae9ci5w==
|
||||||
dependencies:
|
dependencies:
|
||||||
date-fns "^2.2.1"
|
date-fns "^2.2.1"
|
||||||
gl-matrix "^3.1.0"
|
gl-matrix "^3.1.0"
|
||||||
@@ -14495,7 +14499,7 @@ scriptjs@^2.5.9:
|
|||||||
seedrandom@2.4.3:
|
seedrandom@2.4.3:
|
||||||
version "2.4.3"
|
version "2.4.3"
|
||||||
resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-2.4.3.tgz#2438504dad33917314bff18ac4d794f16d6aaecc"
|
resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-2.4.3.tgz#2438504dad33917314bff18ac4d794f16d6aaecc"
|
||||||
integrity sha1-JDhQTa0zkXMUv/GKxNeU8W1qrsw=
|
integrity sha512-2CkZ9Wn2dS4mMUWQaXLsOAfGD+irMlLEeSP3cMxpGbgyOOzJGFa+MWCOMTOCMyZinHRPxyOj/S/C57li/1to6Q==
|
||||||
|
|
||||||
seedrandom@^3.0.5:
|
seedrandom@^3.0.5:
|
||||||
version "3.0.5"
|
version "3.0.5"
|
||||||
@@ -14711,7 +14715,7 @@ shebang-regex@^3.0.0:
|
|||||||
shelljs@0.7.8:
|
shelljs@0.7.8:
|
||||||
version "0.7.8"
|
version "0.7.8"
|
||||||
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3"
|
resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.7.8.tgz#decbcf874b0d1e5fb72e14b164a9683048e9acb3"
|
||||||
integrity sha1-3svPh0sNHl+3LhSxZKloMEjprLM=
|
integrity sha512-/YF5Uk8hcwi7ima04ppkbA4RaRMdPMBfwAvAf8sufYOxsJRtbdoBsT8vGvlb+799BrlGdYrd+oczIA2eN2JdWA==
|
||||||
dependencies:
|
dependencies:
|
||||||
glob "^7.0.0"
|
glob "^7.0.0"
|
||||||
interpret "^1.0.0"
|
interpret "^1.0.0"
|
||||||
@@ -16658,10 +16662,10 @@ websocket-extensions@>=0.1.1:
|
|||||||
resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29"
|
resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29"
|
||||||
integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==
|
integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==
|
||||||
|
|
||||||
webvr-polyfill-dpdb@^1.0.11:
|
webvr-polyfill-dpdb@^1.0.17:
|
||||||
version "1.0.16"
|
version "1.0.18"
|
||||||
resolved "https://registry.yarnpkg.com/webvr-polyfill-dpdb/-/webvr-polyfill-dpdb-1.0.16.tgz#7f2cf88460c002a5f10ff69b2bf3a5663e0ad9dd"
|
resolved "https://registry.yarnpkg.com/webvr-polyfill-dpdb/-/webvr-polyfill-dpdb-1.0.18.tgz#258484ce06b057bf18898acc911bd173847bce11"
|
||||||
integrity sha512-FCciTtPhwkYYHGL0K67G8k7ZnNVqnEx3u4NVHLJ0+Ya6f2VTZUl/GJpaEo1Id2pBP/2l0RYZ3IGZE4Pe8fRalg==
|
integrity sha512-O0S1ZGEWyPvyZEkS2VbyV7mtir/NM9MNK3EuhbHPoJ8EHTky2pTXehjIl+IiDPr+Lldgx129QGt3NGly7rwRPw==
|
||||||
|
|
||||||
webvr-polyfill@0.10.8:
|
webvr-polyfill@0.10.8:
|
||||||
version "0.10.8"
|
version "0.10.8"
|
||||||
|
|||||||
Reference in new issue
Block a user