fix(jump): Jump to measurement wasn't jumping when presentation already existed (#3318)
* fix: Jump to measurement after presentation store * Fix initial load of DICOM SR * Fix measurement highlight issues * Clear measurements changed to array * Fix merge issues * PR comments * Removed unused formatting. Change to single event * Fix the unit test * PR review comments * refactor(viewport): simplify imports, align destructuring Simplify import statements by removing unused imports, organize existing imports, and align destructured imports consistently across the component. ---------
This commit is contained in:
parent
66f6e3eade
commit
b5b936b53e
@ -3,10 +3,8 @@ import { DisplaySetService, classes } from '@ohif/core';
|
||||
const ImageSet = classes.ImageSet;
|
||||
|
||||
const findInstance = (measurement, displaySetService: DisplaySetService) => {
|
||||
const {
|
||||
displaySetInstanceUID,
|
||||
ReferencedSOPInstanceUID: sopUid,
|
||||
} = measurement;
|
||||
const { displaySetInstanceUID, ReferencedSOPInstanceUID: sopUid } =
|
||||
measurement;
|
||||
const referencedDisplaySet = displaySetService.getDisplaySetByUID(
|
||||
displaySetInstanceUID
|
||||
);
|
||||
@ -52,7 +50,7 @@ const findReferencedInstances = (
|
||||
const createReferencedImageDisplaySet = (displaySetService, displaySet) => {
|
||||
const instances = findReferencedInstances(displaySetService, displaySet);
|
||||
// This will be a member function of the created image set
|
||||
const updateInstances = function() {
|
||||
const updateInstances = function () {
|
||||
this.images.splice(
|
||||
0,
|
||||
this.images.length,
|
||||
@ -77,6 +75,8 @@ const createReferencedImageDisplaySet = (displaySetService, displaySet) => {
|
||||
numImageFrames: instances.length,
|
||||
SOPClassHandlerId: `@ohif/extension-default.sopClassHandlerModule.stack`,
|
||||
isReconstructable: false,
|
||||
// This object is made of multiple instances from other series
|
||||
isCompositeStack: true,
|
||||
madeInClient: true,
|
||||
updateInstances,
|
||||
});
|
||||
|
||||
@ -2,18 +2,10 @@ import PropTypes from 'prop-types';
|
||||
import React, { useCallback, useContext, useEffect, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import OHIF, { utils, ServicesManager, ExtensionManager } from '@ohif/core';
|
||||
import { CornerstoneServices } from '@ohif/extension-cornerstone/types';
|
||||
|
||||
import { setTrackingUniqueIdentifiersForElement } from '../tools/modules/dicomSRModule';
|
||||
|
||||
import {
|
||||
Icon,
|
||||
Notification,
|
||||
Tooltip,
|
||||
useViewportDialog,
|
||||
useViewportGrid,
|
||||
ViewportActionBar,
|
||||
} from '@ohif/ui';
|
||||
import { Icon, Tooltip, useViewportGrid, ViewportActionBar } from '@ohif/ui';
|
||||
import hydrateStructuredReport from '../utils/hydrateStructuredReport';
|
||||
import createReferencedImageDisplaySet from '../utils/createReferencedImageDisplaySet';
|
||||
|
||||
@ -40,7 +32,7 @@ function OHIFCornerstoneSRViewport(props) {
|
||||
displaySetService,
|
||||
cornerstoneViewportService,
|
||||
measurementService,
|
||||
} = servicesManager.services as CornerstoneServices;
|
||||
} = servicesManager.services;
|
||||
|
||||
// SR viewport will always have a single display set
|
||||
if (displaySets.length > 1) {
|
||||
@ -50,7 +42,6 @@ function OHIFCornerstoneSRViewport(props) {
|
||||
const srDisplaySet = displaySets[0];
|
||||
|
||||
const [viewportGrid, viewportGridService] = useViewportGrid();
|
||||
const [viewportDialogState, viewportDialogApi] = useViewportDialog();
|
||||
const [measurementSelected, setMeasurementSelected] = useState(0);
|
||||
const [measurementCount, setMeasurementCount] = useState(1);
|
||||
const [activeImageDisplaySetData, setActiveImageDisplaySetData] = useState(
|
||||
|
||||
@ -9,6 +9,7 @@ import {
|
||||
StackViewport,
|
||||
utilities as csUtils,
|
||||
} from '@cornerstonejs/core';
|
||||
import { MeasurementService } from '@ohif/core';
|
||||
import {
|
||||
CinePlayer,
|
||||
useCine,
|
||||
@ -30,6 +31,12 @@ import CornerstoneServices from '../types/CornerstoneServices';
|
||||
|
||||
const STACK = 'stack';
|
||||
|
||||
/**
|
||||
* Caches the jump to measurement operation, so that if display set is shown,
|
||||
* it can jump to the measurement.
|
||||
*/
|
||||
let cacheJumpToMeasurementEvent;
|
||||
|
||||
function areEqual(prevProps, nextProps) {
|
||||
if (nextProps.needsRerendering) {
|
||||
return false;
|
||||
@ -412,6 +419,13 @@ const OHIFCornerstoneViewport = React.memo(props => {
|
||||
lutPresentation:
|
||||
lutPresentationStore[presentationIds?.lutPresentationId],
|
||||
};
|
||||
let measurement;
|
||||
if (cacheJumpToMeasurementEvent?.viewportIndex === viewportIndex) {
|
||||
measurement = cacheJumpToMeasurementEvent.measurement;
|
||||
// Delete the position presentation so that viewport navigates direct
|
||||
presentations.positionPresentation = null;
|
||||
cacheJumpToMeasurementEvent = null;
|
||||
}
|
||||
|
||||
cornerstoneViewportService.setViewportData(
|
||||
viewportIndex,
|
||||
@ -420,6 +434,10 @@ const OHIFCornerstoneViewport = React.memo(props => {
|
||||
displaySetOptions,
|
||||
presentations
|
||||
);
|
||||
|
||||
if (measurement) {
|
||||
cs3DTools.annotation.selection.setAnnotationSelected(measurement.uid);
|
||||
}
|
||||
};
|
||||
|
||||
loadViewportData();
|
||||
@ -536,22 +554,30 @@ function _subscribeToJumpToMeasurementEvents(
|
||||
displaySet => displaySet.displaySetInstanceUID
|
||||
);
|
||||
const { unsubscribe } = measurementService.subscribe(
|
||||
measurementService.EVENTS.JUMP_TO_MEASUREMENT,
|
||||
({ measurement }) => {
|
||||
if (!measurement) return;
|
||||
|
||||
// Jump the the measurement if the viewport contains the displaySetUID (fusion)
|
||||
if (displaysUIDs.includes(measurement.displaySetInstanceUID)) {
|
||||
_jumpToMeasurement(
|
||||
measurement,
|
||||
elementRef,
|
||||
viewportIndex,
|
||||
measurementService,
|
||||
displaySetService,
|
||||
viewportGridService,
|
||||
cornerstoneViewportService
|
||||
MeasurementService.EVENTS.JUMP_TO_MEASUREMENT_VIEWPORT,
|
||||
props => {
|
||||
cacheJumpToMeasurementEvent = props;
|
||||
const { viewportIndex: jumpIndex, measurement, isConsumed } = props;
|
||||
if (!measurement || isConsumed) return;
|
||||
if (cacheJumpToMeasurementEvent.cornerstoneViewport === undefined) {
|
||||
// Decide on which viewport should handle this
|
||||
cacheJumpToMeasurementEvent.cornerstoneViewport = cornerstoneViewportService.getViewportIndexToJump(
|
||||
jumpIndex,
|
||||
measurement.displaySetInstanceUID,
|
||||
{ referencedImageId: measurement.referencedImageId }
|
||||
);
|
||||
}
|
||||
if (cacheJumpToMeasurementEvent.cornerstoneViewport !== viewportIndex)
|
||||
return;
|
||||
_jumpToMeasurement(
|
||||
measurement,
|
||||
elementRef,
|
||||
viewportIndex,
|
||||
measurementService,
|
||||
displaySetService,
|
||||
viewportGridService,
|
||||
cornerstoneViewportService
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
@ -568,21 +594,19 @@ function _checkForCachedJumpToMeasurementEvents(
|
||||
viewportGridService,
|
||||
cornerstoneViewportService
|
||||
) {
|
||||
if (!cacheJumpToMeasurementEvent) return;
|
||||
if (cacheJumpToMeasurementEvent.isConsumed) {
|
||||
cacheJumpToMeasurementEvent = null;
|
||||
return;
|
||||
}
|
||||
const displaysUIDs = displaySets.map(
|
||||
displaySet => displaySet.displaySetInstanceUID
|
||||
);
|
||||
if (!displaysUIDs?.length) return;
|
||||
|
||||
const measurementIdToJumpTo = measurementService.getJumpToMeasurement(
|
||||
viewportIndex
|
||||
);
|
||||
|
||||
if (measurementIdToJumpTo && elementRef) {
|
||||
// Jump to measurement if the measurement exists
|
||||
const measurement = measurementService.getMeasurement(
|
||||
measurementIdToJumpTo
|
||||
);
|
||||
|
||||
// Jump to measurement if the measurement exists
|
||||
const { measurement } = cacheJumpToMeasurementEvent;
|
||||
if (measurement && elementRef) {
|
||||
if (displaysUIDs.includes(measurement?.displaySetInstanceUID)) {
|
||||
_jumpToMeasurement(
|
||||
measurement,
|
||||
@ -611,6 +635,7 @@ function _jumpToMeasurement(
|
||||
|
||||
if (!SOPInstanceUID) {
|
||||
console.warn('cannot jump in a non-acquisition plane measurements yet');
|
||||
return;
|
||||
}
|
||||
|
||||
const referencedDisplaySet = displaySetService.getDisplaySetByUID(
|
||||
@ -623,15 +648,17 @@ function _jumpToMeasurement(
|
||||
|
||||
viewportGridService.setActiveViewportIndex(viewportIndex);
|
||||
|
||||
const enableElement = getEnabledElement(targetElement);
|
||||
const enabledElement = getEnabledElement(targetElement);
|
||||
|
||||
const viewportInfo = cornerstoneViewportService.getViewportInfoByIndex(
|
||||
viewportIndex
|
||||
);
|
||||
|
||||
if (enableElement) {
|
||||
if (enabledElement) {
|
||||
// See how the jumpToSlice() of Cornerstone3D deals with imageIdx param.
|
||||
const viewport = enableElement.viewport as IStackViewport | IVolumeViewport;
|
||||
const viewport = enabledElement.viewport as
|
||||
| IStackViewport
|
||||
| IVolumeViewport;
|
||||
|
||||
let imageIdIndex = 0;
|
||||
let viewportCameraDirectionMatch = true;
|
||||
@ -680,7 +707,8 @@ function _jumpToMeasurement(
|
||||
|
||||
cs3DTools.annotation.selection.setAnnotationSelected(measurement.uid);
|
||||
// Jump to measurement consumed, remove.
|
||||
measurementService.removeJumpToMeasurement(viewportIndex);
|
||||
cacheJumpToMeasurementEvent?.consume?.();
|
||||
cacheJumpToMeasurementEvent = null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -10,6 +10,7 @@ import {
|
||||
utilities as cstUtils,
|
||||
ReferenceLinesTool,
|
||||
} from '@cornerstonejs/tools';
|
||||
import { Types as OhifTypes } from '@ohif/core';
|
||||
|
||||
import CornerstoneViewportDownloadForm from './utils/CornerstoneViewportDownloadForm';
|
||||
import callInputDialog from './utils/callInputDialog';
|
||||
@ -19,7 +20,10 @@ import { getFirstAnnotationSelected } from './utils/measurementServiceMappings/u
|
||||
import getActiveViewportEnabledElement from './utils/getActiveViewportEnabledElement';
|
||||
import { CornerstoneServices } from './types';
|
||||
|
||||
function commandsModule({ servicesManager, commandsManager }) {
|
||||
function commandsModule({
|
||||
servicesManager,
|
||||
commandsManager,
|
||||
}: OhifTypes.Extensions.ExtensionParams): OhifTypes.Extensions.CommandsModule {
|
||||
const {
|
||||
viewportGridService,
|
||||
toolGroupService,
|
||||
@ -484,33 +488,22 @@ function commandsModule({ servicesManager, commandsManager }) {
|
||||
}
|
||||
}
|
||||
},
|
||||
firstImage: () => {
|
||||
// Get current active viewport (return if none active)
|
||||
const enabledElement = _getActiveViewportEnabledElement();
|
||||
if (!enabledElement) {
|
||||
return;
|
||||
}
|
||||
const { viewport } = enabledElement;
|
||||
|
||||
// Check viewport is supported
|
||||
if (
|
||||
viewport! instanceof StackViewport &&
|
||||
viewport! instanceof VolumeViewport
|
||||
) {
|
||||
throw new Error('Unsupported viewport type');
|
||||
}
|
||||
|
||||
// Set slice to first slice
|
||||
const options = { imageIndex: 0 };
|
||||
cstUtils.jumpToSlice(viewport.element, options);
|
||||
},
|
||||
lastImage: () => {
|
||||
/** Jumps the active viewport or the specified one to the given slice index */
|
||||
jumpToImage: ({ imageIndex, viewport: gridViewport }): void => {
|
||||
// Get current active viewport (return if none active)
|
||||
const enabledElement = _getActiveViewportEnabledElement();
|
||||
if (!enabledElement) {
|
||||
return;
|
||||
let viewport;
|
||||
if (!gridViewport) {
|
||||
const enabledElement = _getActiveViewportEnabledElement();
|
||||
if (!enabledElement) {
|
||||
return;
|
||||
}
|
||||
viewport = enabledElement.viewport;
|
||||
} else {
|
||||
viewport = cornerstoneViewportService.getCornerstoneViewport(
|
||||
gridViewport.id
|
||||
);
|
||||
}
|
||||
const { viewport } = enabledElement;
|
||||
|
||||
// Get number of slices
|
||||
// -> Copied from cornerstone3D jumpToSlice\_getImageSliceData()
|
||||
@ -525,8 +518,14 @@ function commandsModule({ servicesManager, commandsManager }) {
|
||||
throw new Error('Unsupported viewport type');
|
||||
}
|
||||
|
||||
const jumpIndex =
|
||||
imageIndex < 0 ? numberOfSlices + imageIndex : imageIndex;
|
||||
if (jumpIndex >= numberOfSlices || jumpIndex < 0) {
|
||||
throw new Error(`Can't jump to ${imageIndex}`);
|
||||
}
|
||||
|
||||
// Set slice to last slice
|
||||
const options = { imageIndex: numberOfSlices - 1 };
|
||||
const options = { imageIndex: jumpIndex };
|
||||
cstUtils.jumpToSlice(viewport.element, options);
|
||||
},
|
||||
scroll: ({ direction }) => {
|
||||
@ -625,8 +624,6 @@ function commandsModule({ servicesManager, commandsManager }) {
|
||||
|
||||
getNearbyToolData: {
|
||||
commandFn: actions.getNearbyToolData,
|
||||
storeContexts: [],
|
||||
options: {},
|
||||
},
|
||||
getNearbyAnnotation: {
|
||||
commandFn: actions.getNearbyAnnotation,
|
||||
@ -636,142 +633,100 @@ function commandsModule({ servicesManager, commandsManager }) {
|
||||
|
||||
deleteMeasurement: {
|
||||
commandFn: actions.deleteMeasurement,
|
||||
storeContexts: [],
|
||||
options: {},
|
||||
},
|
||||
setMeasurementLabel: {
|
||||
commandFn: actions.setMeasurementLabel,
|
||||
storeContexts: [],
|
||||
options: {},
|
||||
},
|
||||
updateMeasurement: {
|
||||
commandFn: actions.updateMeasurement,
|
||||
storeContexts: [],
|
||||
options: {},
|
||||
},
|
||||
|
||||
setWindowLevel: {
|
||||
commandFn: actions.setWindowLevel,
|
||||
storeContexts: [],
|
||||
options: {},
|
||||
},
|
||||
toolbarServiceRecordInteraction: {
|
||||
commandFn: actions.toolbarServiceRecordInteraction,
|
||||
storeContexts: [],
|
||||
options: {},
|
||||
},
|
||||
setToolActive: {
|
||||
commandFn: actions.setToolActive,
|
||||
storeContexts: [],
|
||||
options: {},
|
||||
},
|
||||
rotateViewportCW: {
|
||||
commandFn: actions.rotateViewport,
|
||||
storeContexts: [],
|
||||
options: { rotation: 90 },
|
||||
},
|
||||
rotateViewportCCW: {
|
||||
commandFn: actions.rotateViewport,
|
||||
storeContexts: [],
|
||||
options: { rotation: -90 },
|
||||
},
|
||||
incrementActiveViewport: {
|
||||
commandFn: actions.incrementActiveViewport,
|
||||
storeContexts: [],
|
||||
},
|
||||
decrementActiveViewport: {
|
||||
commandFn: actions.decrementActiveViewport,
|
||||
storeContexts: [],
|
||||
},
|
||||
flipViewportHorizontal: {
|
||||
commandFn: actions.flipViewportHorizontal,
|
||||
storeContexts: [],
|
||||
options: {},
|
||||
},
|
||||
flipViewportVertical: {
|
||||
commandFn: actions.flipViewportVertical,
|
||||
storeContexts: [],
|
||||
options: {},
|
||||
},
|
||||
invertViewport: {
|
||||
commandFn: actions.invertViewport,
|
||||
storeContexts: [],
|
||||
options: {},
|
||||
},
|
||||
resetViewport: {
|
||||
commandFn: actions.resetViewport,
|
||||
storeContexts: [],
|
||||
options: {},
|
||||
},
|
||||
scaleUpViewport: {
|
||||
commandFn: actions.scaleViewport,
|
||||
storeContexts: [],
|
||||
options: { direction: 1 },
|
||||
},
|
||||
scaleDownViewport: {
|
||||
commandFn: actions.scaleViewport,
|
||||
storeContexts: [],
|
||||
options: { direction: -1 },
|
||||
},
|
||||
fitViewportToWindow: {
|
||||
commandFn: actions.scaleViewport,
|
||||
storeContexts: [],
|
||||
options: { direction: 0 },
|
||||
},
|
||||
nextImage: {
|
||||
commandFn: actions.scroll,
|
||||
storeContexts: [],
|
||||
options: { direction: 1 },
|
||||
},
|
||||
previousImage: {
|
||||
commandFn: actions.scroll,
|
||||
storeContexts: [],
|
||||
options: { direction: -1 },
|
||||
},
|
||||
firstImage: {
|
||||
commandFn: actions.firstImage,
|
||||
storeContexts: [],
|
||||
options: {},
|
||||
commandFn: actions.jumpToImage,
|
||||
options: { imageIndex: 0 },
|
||||
},
|
||||
lastImage: {
|
||||
commandFn: actions.lastImage,
|
||||
storeContexts: [],
|
||||
options: {},
|
||||
commandFn: actions.jumpToImage,
|
||||
options: { imageIndex: -1 },
|
||||
},
|
||||
jumpToImage: {
|
||||
commandFn: actions.jumpToImage,
|
||||
},
|
||||
showDownloadViewportModal: {
|
||||
commandFn: actions.showDownloadViewportModal,
|
||||
storeContexts: [],
|
||||
options: {},
|
||||
},
|
||||
toggleCine: {
|
||||
commandFn: actions.toggleCine,
|
||||
storeContexts: [],
|
||||
options: {},
|
||||
},
|
||||
arrowTextCallback: {
|
||||
commandFn: actions.arrowTextCallback,
|
||||
storeContexts: [],
|
||||
options: {},
|
||||
},
|
||||
setViewportActive: {
|
||||
commandFn: actions.setViewportActive,
|
||||
storeContexts: [],
|
||||
options: {},
|
||||
},
|
||||
setViewportColormap: {
|
||||
commandFn: actions.setViewportColormap,
|
||||
storeContexts: [],
|
||||
options: {},
|
||||
},
|
||||
toggleStackImageSync: {
|
||||
commandFn: actions.toggleStackImageSync,
|
||||
storeContexts: [],
|
||||
options: {},
|
||||
},
|
||||
toggleReferenceLines: {
|
||||
commandFn: actions.toggleReferenceLines,
|
||||
storeContexts: [],
|
||||
options: {},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@ -16,14 +16,14 @@ const VOLUME_LOADER_SCHEME = 'cornerstoneStreamingImageVolume';
|
||||
|
||||
class CornerstoneCacheService {
|
||||
static REGISTRATION = {
|
||||
name: 'cornerstoneCacheService',
|
||||
altName: 'CornerstoneCacheService',
|
||||
name: 'cornerstoneCacheService',
|
||||
altName: 'CornerstoneCacheService',
|
||||
create: ({
|
||||
servicesManager,
|
||||
}: Types.Extensions.ExtensionParams): CornerstoneCacheService => {
|
||||
return new CornerstoneCacheService(servicesManager);
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
stackImageIds: Map<string, string[]> = new Map();
|
||||
volumeImageIds: Map<string, string[]> = new Map();
|
||||
@ -143,13 +143,18 @@ class CornerstoneCacheService {
|
||||
this.stackImageIds.set(displaySet.displaySetInstanceUID, stackImageIds);
|
||||
}
|
||||
|
||||
const { displaySetInstanceUID, StudyInstanceUID } = displaySet;
|
||||
const {
|
||||
displaySetInstanceUID,
|
||||
StudyInstanceUID,
|
||||
isCompositeStack,
|
||||
} = displaySet;
|
||||
|
||||
const StackViewportData: StackViewportData = {
|
||||
viewportType,
|
||||
data: {
|
||||
StudyInstanceUID,
|
||||
displaySetInstanceUID,
|
||||
isCompositeStack,
|
||||
imageIds: stackImageIds,
|
||||
},
|
||||
};
|
||||
|
||||
@ -906,6 +906,34 @@ class CornerstoneViewportService extends PubSubService
|
||||
return images[0].FrameOfReferenceUID;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks through the viewports to see if the specified measurement can be
|
||||
* displayed in one of the viewports.
|
||||
*
|
||||
* @param measurement
|
||||
* The measurement that is desired to view.
|
||||
* @param activeViewportIndex - the index that was active at the time the jump
|
||||
* was initiated.
|
||||
* @return the viewportIndex to display the given measurement
|
||||
*/
|
||||
public getViewportIndexToJump(
|
||||
activeViewportIndex: number,
|
||||
displaySetInstanceUID: string,
|
||||
cameraProps: unknown
|
||||
): number {
|
||||
const viewportInfo = this.viewportsInfo.get(activeViewportIndex);
|
||||
const { referencedImageId } = cameraProps;
|
||||
if (viewportInfo?.contains(displaySetInstanceUID, referencedImageId)) {
|
||||
return activeViewportIndex;
|
||||
}
|
||||
|
||||
return (
|
||||
[...this.viewportsById.values()].find(viewportInfo =>
|
||||
viewportInfo.contains(displaySetInstanceUID, referencedImageId)
|
||||
)?.viewportIndex ?? -1
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default CornerstoneViewportService;
|
||||
|
||||
@ -88,6 +88,20 @@ export type DisplaySet = {
|
||||
const STACK = 'stack';
|
||||
const DEFAULT_TOOLGROUP_ID = 'default';
|
||||
|
||||
// Return true if the data contains the given display set UID OR the imageId
|
||||
// if it is a composite object.
|
||||
const dataContains = (
|
||||
data,
|
||||
displaySetUID: string,
|
||||
imageId?: string
|
||||
): boolean => {
|
||||
if (data.displaySetInstanceUID === displaySetUID) return true;
|
||||
if (imageId && data.isCompositeStack && data.imageIds) {
|
||||
return !!data.imageIds.find(dataId => dataId === imageId);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
class ViewportInfo {
|
||||
private viewportId = '';
|
||||
private viewportIndex: number;
|
||||
@ -104,6 +118,21 @@ class ViewportInfo {
|
||||
this.setPublicDisplaySetOptions([{}]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the viewport contains the given display set UID,
|
||||
* OR if it is a composite stack and contains the given imageId
|
||||
*/
|
||||
public contains(displaySetUID: string, imageId: string): boolean {
|
||||
if (!this.viewportData?.data) return false;
|
||||
|
||||
if (this.viewportData.data.length) {
|
||||
return !!this.viewportData.find(data =>
|
||||
dataContains(data, displaySetUID, imageId)
|
||||
);
|
||||
}
|
||||
return dataContains(this.viewportData.data, displaySetUID, imageId);
|
||||
}
|
||||
|
||||
public destroy = (): void => {
|
||||
this.element = null;
|
||||
this.viewportData = null;
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
import {
|
||||
Enums,
|
||||
Types,
|
||||
} from '@cornerstonejs/core';
|
||||
|
||||
import { Enums, Types } from '@cornerstonejs/core';
|
||||
|
||||
type StackData = {
|
||||
StudyInstanceUID: string;
|
||||
displaySetInstanceUID: string;
|
||||
// A composite stack is one created from other display sets - kind of like
|
||||
// madeInClient, but specific to indicating that the imageIds can come from
|
||||
// different series or even studies.
|
||||
isCompositeStack?: boolean;
|
||||
imageIds: string[];
|
||||
frameRate?: number;
|
||||
isClip?: boolean;
|
||||
@ -20,19 +20,14 @@ type VolumeData = {
|
||||
imageIds?: string[];
|
||||
};
|
||||
|
||||
type StackViewportData = {
|
||||
type StackViewportData = {
|
||||
viewportType: Enums.ViewportType;
|
||||
data: StackData;
|
||||
};
|
||||
|
||||
type VolumeViewportData = {
|
||||
type VolumeViewportData = {
|
||||
viewportType: Enums.ViewportType;
|
||||
data: VolumeData[];
|
||||
};
|
||||
|
||||
export type {
|
||||
StackViewportData,
|
||||
VolumeViewportData,
|
||||
StackData,
|
||||
VolumeData,
|
||||
};
|
||||
export type { StackViewportData, VolumeViewportData, StackData, VolumeData };
|
||||
|
||||
@ -188,6 +188,7 @@ function getDisplayText(mappedAnnotations, displaySet) {
|
||||
const instanceText = InstanceNumber ? ` I: ${InstanceNumber}` : '';
|
||||
const frameText = displaySet.isMultiFrame ? ` F: ${frameNumber}` : '';
|
||||
|
||||
if (length === null || length === undefined) return displayText;
|
||||
const roundedLength = utils.roundNumber(length, 2);
|
||||
displayText.push(
|
||||
`${roundedLength} mm (S: ${SeriesNumber}${instanceText}${frameText})`
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { ServicesManager, utils } from '@ohif/core';
|
||||
import { ServicesManager, utils, Types } from '@ohif/core';
|
||||
|
||||
import {
|
||||
ContextMenuController,
|
||||
@ -244,6 +244,12 @@ const commandsModule = ({
|
||||
}
|
||||
}
|
||||
// Do this after successfully applying the update
|
||||
// Note, don't store the active display set - it is only needed while
|
||||
// changing display sets. This causes jump to measurement to fail on
|
||||
// multi-study display.
|
||||
delete displaySetSelectorMap[
|
||||
`${activeStudyUID || hpInfo.activeStudyUID}:activeDisplaySet:0`
|
||||
];
|
||||
stateSyncService.store(stateSyncReduce);
|
||||
// This is a default action applied
|
||||
actions.toggleHpTools(hangingProtocolService.getActiveProtocol());
|
||||
|
||||
@ -47,6 +47,15 @@ function TrackedMeasurementsContextProvider(
|
||||
|
||||
const uid = trackedMeasurements[0].uid;
|
||||
|
||||
console.log(
|
||||
'jumping to measurement reset viewport',
|
||||
viewportGrid.activeViewportIndex,
|
||||
trackedMeasurements[0]
|
||||
);
|
||||
viewportGridService.setDisplaySetsForViewport({
|
||||
viewportIndex: viewportGrid.activeViewportIndex,
|
||||
displaySetInstanceUIDs: [trackedMeasurements[0].displaySetInstanceUID],
|
||||
});
|
||||
measurementService.jumpToMeasurement(
|
||||
viewportGrid.activeViewportIndex,
|
||||
uid
|
||||
|
||||
@ -67,7 +67,10 @@ const EVENTS = {
|
||||
RAW_MEASUREMENT_ADDED: 'event::raw_measurement_added',
|
||||
MEASUREMENT_REMOVED: 'event::measurement_removed',
|
||||
MEASUREMENTS_CLEARED: 'event::measurements_cleared',
|
||||
JUMP_TO_MEASUREMENT: 'event:jump_to_measurement',
|
||||
// Give the viewport a chance to jump to the measurement
|
||||
JUMP_TO_MEASUREMENT_VIEWPORT: 'event:jump_to_measurement_viewport',
|
||||
// Give the layout a chance to jump to the measurement
|
||||
JUMP_TO_MEASUREMENT_LAYOUT: 'event:jump_to_measurement_layout',
|
||||
};
|
||||
|
||||
const VALUE_TYPES = {
|
||||
@ -104,15 +107,16 @@ class MeasurementService extends PubSubService {
|
||||
},
|
||||
};
|
||||
|
||||
public static readonly EVENTS = EVENTS;
|
||||
public static VALUE_TYPES = VALUE_TYPES;
|
||||
public readonly VALUE_TYPES = VALUE_TYPES;
|
||||
|
||||
private measurements = new Map();
|
||||
|
||||
constructor() {
|
||||
super(EVENTS);
|
||||
this.sources = {};
|
||||
this.mappings = {};
|
||||
this.measurements = {};
|
||||
this._jumpToMeasurementCache = {};
|
||||
}
|
||||
|
||||
/**
|
||||
@ -120,7 +124,7 @@ class MeasurementService extends PubSubService {
|
||||
* This method should be used to add custom tool schema to the measurement service.
|
||||
* @param {Array} schema schema for validation
|
||||
*/
|
||||
addMeasurementSchemaKeys(schema) {
|
||||
public addMeasurementSchemaKeys(schema): void {
|
||||
if (!Array.isArray(schema)) {
|
||||
schema = [schema];
|
||||
}
|
||||
@ -160,11 +164,7 @@ class MeasurementService extends PubSubService {
|
||||
* @return {Measurement[]} Array of measurements
|
||||
*/
|
||||
getMeasurements() {
|
||||
const measurements = this._arrayOfObjects(this.measurements);
|
||||
return (
|
||||
measurements &&
|
||||
measurements.map(m => this.measurements[Object.keys(m)[0]])
|
||||
);
|
||||
return [...this.measurements.values()];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -173,18 +173,14 @@ class MeasurementService extends PubSubService {
|
||||
* @param {string} uid measurement uid
|
||||
* @return {Measurement} Measurement instance
|
||||
*/
|
||||
getMeasurement(measurementUID) {
|
||||
let measurement = null;
|
||||
const measurements = this.measurements[measurementUID];
|
||||
|
||||
if (measurements && Object.keys(measurements).length > 0) {
|
||||
measurement = this.measurements[measurementUID];
|
||||
}
|
||||
|
||||
return measurement;
|
||||
public getMeasurement(measurementUID: string) {
|
||||
return this.measurements.get(measurementUID);
|
||||
}
|
||||
|
||||
setMeasurementSelected(measurementUID, selected) {
|
||||
public setMeasurementSelected(
|
||||
measurementUID: string,
|
||||
selected: boolean
|
||||
): void {
|
||||
const measurement = this.getMeasurement(measurementUID);
|
||||
if (!measurement) {
|
||||
return;
|
||||
@ -373,8 +369,8 @@ class MeasurementService extends PubSubService {
|
||||
}
|
||||
}
|
||||
|
||||
update(measurementUID, measurement, notYetUpdatedAtSource = false) {
|
||||
if (!this.measurements[measurementUID]) {
|
||||
update(measurementUID: string, measurement, notYetUpdatedAtSource = false) {
|
||||
if (!this.measurements.has(measurementUID)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -388,7 +384,7 @@ class MeasurementService extends PubSubService {
|
||||
updatedMeasurement
|
||||
);
|
||||
|
||||
this.measurements[measurementUID] = updatedMeasurement;
|
||||
this.measurements.set(measurementUID, updatedMeasurement);
|
||||
|
||||
this._broadcastEvent(this.EVENTS.MEASUREMENT_UPDATED, {
|
||||
source: measurement.source,
|
||||
@ -470,15 +466,15 @@ class MeasurementService extends PubSubService {
|
||||
uid: internalUID,
|
||||
};
|
||||
|
||||
if (this.measurements[internalUID]) {
|
||||
this.measurements[internalUID] = newMeasurement;
|
||||
if (this.measurements.get(internalUID)) {
|
||||
this.measurements.set(internalUID, newMeasurement);
|
||||
this._broadcastEvent(this.EVENTS.MEASUREMENT_UPDATED, {
|
||||
source,
|
||||
measurement: newMeasurement,
|
||||
});
|
||||
} else {
|
||||
log.info('Measurement added', newMeasurement);
|
||||
this.measurements[internalUID] = newMeasurement;
|
||||
this.measurements.set(internalUID, newMeasurement);
|
||||
this._broadcastEvent(this.EVENTS.RAW_MEASUREMENT_ADDED, {
|
||||
source,
|
||||
measurement: newMeasurement,
|
||||
@ -557,7 +553,7 @@ class MeasurementService extends PubSubService {
|
||||
);
|
||||
}
|
||||
|
||||
const oldMeasurement = this.measurements[internalUID];
|
||||
const oldMeasurement = this.measurements.get(internalUID);
|
||||
|
||||
const newMeasurement = {
|
||||
...oldMeasurement,
|
||||
@ -569,7 +565,7 @@ class MeasurementService extends PubSubService {
|
||||
if (oldMeasurement) {
|
||||
// TODO: Ultimately, each annotation should have a selected flag right from the soure.
|
||||
// For now, it is just added in OHIF here and in setMeasurementSelected.
|
||||
this.measurements[internalUID] = newMeasurement;
|
||||
this.measurements.set(internalUID, newMeasurement);
|
||||
if (isUpdate) {
|
||||
this._broadcastEvent(this.EVENTS.MEASUREMENT_UPDATED, {
|
||||
source,
|
||||
@ -585,7 +581,7 @@ class MeasurementService extends PubSubService {
|
||||
}
|
||||
} else {
|
||||
log.info('Measurement started.', newMeasurement);
|
||||
this.measurements[internalUID] = newMeasurement;
|
||||
this.measurements.set(internalUID, newMeasurement);
|
||||
}
|
||||
|
||||
return newMeasurement.uid;
|
||||
@ -598,12 +594,12 @@ class MeasurementService extends PubSubService {
|
||||
* @param {MeasurementSource} source The measurement source instance
|
||||
*/
|
||||
remove(measurementUID, source, eventDetails) {
|
||||
if (!measurementUID || !this.measurements[measurementUID]) {
|
||||
if (!measurementUID || !this.measurements.has(measurementUID)) {
|
||||
log.warn(`No uid provided, or unable to find measurement by uid.`);
|
||||
return;
|
||||
}
|
||||
|
||||
delete this.measurements[measurementUID];
|
||||
this.measurements.delete(measurementUID);
|
||||
this._broadcastEvent(this.EVENTS.MEASUREMENT_REMOVED, {
|
||||
source,
|
||||
measurement: measurementUID,
|
||||
@ -613,9 +609,8 @@ class MeasurementService extends PubSubService {
|
||||
|
||||
clearMeasurements() {
|
||||
// Make a copy of the measurements
|
||||
const measurements = { ...this.measurements };
|
||||
this.measurements = {};
|
||||
this._jumpToMeasurementCache = {};
|
||||
const measurements = [...this.measurements.values()];
|
||||
this.measurements.clear();
|
||||
this._broadcastEvent(this.EVENTS.MEASUREMENTS_CLEARED, { measurements });
|
||||
}
|
||||
|
||||
@ -628,27 +623,39 @@ class MeasurementService extends PubSubService {
|
||||
this.clearMeasurements();
|
||||
}
|
||||
|
||||
jumpToMeasurement(viewportIndex, measurementUID) {
|
||||
const measurement = this.measurements[measurementUID];
|
||||
/**
|
||||
* This method calls the subscriptions for JUMP_TO_MEASUREMENT_VIEWPORT
|
||||
* and JUMP_TO_MEASUREMENT_LAYOUT. There are two events which are
|
||||
* fired because there are two different items which might want to handle
|
||||
* the event. First, there might already be a viewport which can handle
|
||||
* the event. If so, then the layout doesn't need to necessarily change.
|
||||
* This is communicated by the isConsumed value on the event itself.
|
||||
* Otherwise, the layout itself may need to be navigated to in order
|
||||
* to provide a viewport which can show the given measurement.
|
||||
*
|
||||
* When a viewport decides to apply the event, it should call the consume()
|
||||
* method on the event, so that other listeners know they do not need to
|
||||
* navigate. This does NOT affect whether the layout event is fired, and
|
||||
* merely causes it to fire the event with the isConsumed set to true.
|
||||
*/
|
||||
|
||||
public jumpToMeasurement(
|
||||
viewportIndex: number,
|
||||
measurementUID: string
|
||||
): void {
|
||||
const measurement = this.measurements.get(measurementUID);
|
||||
|
||||
if (!measurement) {
|
||||
log.warn(`No measurement uid, or unable to find by uid.`);
|
||||
return;
|
||||
}
|
||||
this._addJumpToMeasurement(viewportIndex, measurementUID);
|
||||
|
||||
this._broadcastEvent(this.EVENTS.JUMP_TO_MEASUREMENT, {
|
||||
const consumableEvent = this.createConsumableEvent({
|
||||
viewportIndex,
|
||||
measurement,
|
||||
});
|
||||
}
|
||||
|
||||
getJumpToMeasurement(viewportIndex) {
|
||||
return this._jumpToMeasurementCache[viewportIndex];
|
||||
}
|
||||
|
||||
removeJumpToMeasurement(viewportIndex) {
|
||||
delete this._jumpToMeasurementCache[viewportIndex];
|
||||
this._broadcastEvent(EVENTS.JUMP_TO_MEASUREMENT_VIEWPORT, consumableEvent);
|
||||
this._broadcastEvent(EVENTS.JUMP_TO_MEASUREMENT_LAYOUT, consumableEvent);
|
||||
}
|
||||
|
||||
_getSourceUID(name, version) {
|
||||
@ -663,10 +670,6 @@ class MeasurementService extends PubSubService {
|
||||
return sourceUID;
|
||||
}
|
||||
|
||||
_addJumpToMeasurement(viewportIndex, measurementUID) {
|
||||
this._jumpToMeasurementCache[viewportIndex] = measurementUID;
|
||||
}
|
||||
|
||||
_getMappingByMeasurementSource(measurement, annotationType) {
|
||||
if (this._isValidSource(measurement.source)) {
|
||||
return this.mappings[measurement.source.uid].find(
|
||||
|
||||
@ -1,12 +1,13 @@
|
||||
import { PubSubService } from '../_shared/pubSubServiceInterface';
|
||||
|
||||
const EVENTS = {
|
||||
ACTIVE_VIEWPORT_INDEX_CHANGED: 'event::activeviewportindexchanged',
|
||||
LAYOUT_CHANGED: 'event::layoutChanged',
|
||||
GRID_STATE_CHANGED: 'event::gridStateChanged',
|
||||
};
|
||||
import { getPresentationIds, PresentationIds } from './getPresentationIds';
|
||||
|
||||
class ViewportGridService extends PubSubService {
|
||||
public static readonly EVENTS = {
|
||||
ACTIVE_VIEWPORT_INDEX_CHANGED: 'event::activeviewportindexchanged',
|
||||
LAYOUT_CHANGED: 'event::layoutChanged',
|
||||
GRID_STATE_CHANGED: 'event::gridStateChanged',
|
||||
};
|
||||
|
||||
public static REGISTRATION = {
|
||||
name: 'viewportGridService',
|
||||
altName: 'ViewportGridService',
|
||||
@ -14,12 +15,13 @@ class ViewportGridService extends PubSubService {
|
||||
return new ViewportGridService();
|
||||
},
|
||||
};
|
||||
public static EVENTS = EVENTS;
|
||||
|
||||
public static getPresentationIds = getPresentationIds;
|
||||
|
||||
serviceImplementation = {};
|
||||
|
||||
constructor() {
|
||||
super(EVENTS);
|
||||
super(ViewportGridService.EVENTS);
|
||||
this.serviceImplementation = {};
|
||||
}
|
||||
|
||||
@ -37,10 +39,12 @@ class ViewportGridService extends PubSubService {
|
||||
this.serviceImplementation._getState = getStateImplementation;
|
||||
}
|
||||
if (setActiveViewportIndexImplementation) {
|
||||
this.serviceImplementation._setActiveViewportIndex = setActiveViewportIndexImplementation;
|
||||
this.serviceImplementation._setActiveViewportIndex =
|
||||
setActiveViewportIndexImplementation;
|
||||
}
|
||||
if (setDisplaySetsForViewportsImplementation) {
|
||||
this.serviceImplementation._setDisplaySetsForViewports = setDisplaySetsForViewportsImplementation;
|
||||
this.serviceImplementation._setDisplaySetsForViewports =
|
||||
setDisplaySetsForViewportsImplementation;
|
||||
}
|
||||
if (setLayoutImplementation) {
|
||||
this.serviceImplementation._setLayout = setLayoutImplementation;
|
||||
@ -55,7 +59,8 @@ class ViewportGridService extends PubSubService {
|
||||
this.serviceImplementation._set = setImplementation;
|
||||
}
|
||||
if (getNumViewportPanesImplementation) {
|
||||
this.serviceImplementation._getNumViewportPanes = getNumViewportPanesImplementation;
|
||||
this.serviceImplementation._getNumViewportPanes =
|
||||
getNumViewportPanesImplementation;
|
||||
}
|
||||
}
|
||||
|
||||
@ -75,11 +80,29 @@ class ViewportGridService extends PubSubService {
|
||||
|
||||
public setDisplaySetsForViewport(props) {
|
||||
// Just update a single viewport, but use the multi-viewport update for it.
|
||||
this.serviceImplementation._setDisplaySetsForViewports([props]);
|
||||
this.setDisplaySetsForViewports([props]);
|
||||
}
|
||||
|
||||
public setDisplaySetsForViewports(props) {
|
||||
this.serviceImplementation._setDisplaySetsForViewports(props);
|
||||
const state = this.getState();
|
||||
const viewports = [];
|
||||
|
||||
for (const viewport of props) {
|
||||
const updatedViewport = state.viewports[viewport.viewportIndex];
|
||||
if (updatedViewport) {
|
||||
viewports.push(updatedViewport);
|
||||
} else {
|
||||
console.warn(
|
||||
"ViewportGridService::Didn't find updated viewport",
|
||||
viewport
|
||||
);
|
||||
}
|
||||
}
|
||||
this._broadcastEvent(ViewportGridService.EVENTS.GRID_STATE_CHANGED, {
|
||||
state,
|
||||
viewports,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -150,3 +173,5 @@ class ViewportGridService extends PubSubService {
|
||||
}
|
||||
|
||||
export default ViewportGridService;
|
||||
|
||||
export type { PresentationIds };
|
||||
|
||||
@ -118,3 +118,4 @@ const getPresentationIds = (viewport, viewports): PresentationIds => {
|
||||
};
|
||||
|
||||
export default getPresentationIds;
|
||||
export { getPresentationIds };
|
||||
@ -103,4 +103,20 @@ export class PubSubService {
|
||||
this.unsubscriptions.forEach(unsub => unsub());
|
||||
this.unsubscriptions = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an event that records whether or not someone
|
||||
* has consumed it. Call eventData.consume() to consume the event.
|
||||
* Check eventData.isConsumed to see if it is consumed or not.
|
||||
* @param props - to include in the event
|
||||
*/
|
||||
protected createConsumableEvent(props) {
|
||||
return {
|
||||
...props,
|
||||
isConsumed: false,
|
||||
consume: function Consume() {
|
||||
this.isConsumed = true;
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,27 +24,22 @@ describe('absoluteUrl', () => {
|
||||
});
|
||||
|
||||
test('should return the original path when there path in the window.origin after the domain and port', () => {
|
||||
global.window = Object.create(window);
|
||||
delete global.window.location;
|
||||
const url = 'http://dummy.com';
|
||||
Object.defineProperty(window, 'location', {
|
||||
value: {
|
||||
origin: url,
|
||||
},
|
||||
writable: true,
|
||||
});
|
||||
global.window.location = {
|
||||
origin: url,
|
||||
};
|
||||
const absoluteUrlOutput = absoluteUrl('path_1/path_2/path_3');
|
||||
expect(absoluteUrlOutput).toEqual('/path_1/path_2/path_3');
|
||||
});
|
||||
|
||||
test('should be able to return the absolute path even when the path contains duplicates', () => {
|
||||
global.window = Object.create(window);
|
||||
global.window ||= Object.create(window);
|
||||
const url = 'http://dummy.com';
|
||||
Object.defineProperty(window, 'location', {
|
||||
value: {
|
||||
origin: url,
|
||||
},
|
||||
writable: true,
|
||||
});
|
||||
delete global.window.location;
|
||||
global.window.location = {
|
||||
origin: url,
|
||||
};
|
||||
const absoluteUrlOutput = absoluteUrl('path_1/path_1/path_1');
|
||||
expect(absoluteUrlOutput).toEqual('/path_1/path_1/path_1');
|
||||
});
|
||||
|
||||
@ -29,7 +29,8 @@ There are seven events that get publish in `MeasurementService`:
|
||||
| RAW_MEASUREMENT_ADDED | Fires when a raw measurement is added (e.g., dicom-sr) |
|
||||
| MEASUREMENT_REMOVED | Fires when a measurement is removed |
|
||||
| MEASUREMENTS_CLEARED | Fires when all measurements are deleted |
|
||||
| JUMP_TO_MEASUREMENT | Fires when a measurement is requested to be jump to |
|
||||
| JUMP_TO_MEASUREMENT_VIEWPORT | Fires when a measurement is requested to be jumped to, applying to individual viewports. |
|
||||
| JUMP_TO_MEASUREMENT_LAYOUT | Fires when a measurement is requested to be jumped to, applying to the overall layout. |
|
||||
|
||||
## API
|
||||
|
||||
|
||||
@ -7,8 +7,8 @@ import React, {
|
||||
} from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import isEqual from 'lodash.isequal';
|
||||
import { ViewportGridService } from '@ohif/core';
|
||||
import viewportLabels from '../utils/viewportLabels';
|
||||
import getPresentationIds from './getPresentationIds';
|
||||
|
||||
const DEFAULT_STATE = {
|
||||
activeViewportIndex: 0,
|
||||
@ -173,7 +173,7 @@ export function ViewportGridProvider({ children, service }) {
|
||||
displaySetOptions,
|
||||
viewportLabel: viewportLabels[viewportIndex],
|
||||
};
|
||||
viewportOptions.presentationIds = getPresentationIds(
|
||||
viewportOptions.presentationIds = ViewportGridService.getPresentationIds(
|
||||
newViewport,
|
||||
viewports
|
||||
);
|
||||
@ -265,7 +265,7 @@ export function ViewportGridProvider({ children, service }) {
|
||||
state.viewports
|
||||
);
|
||||
if (!viewport.viewportOptions.presentationIds) {
|
||||
viewport.viewportOptions.presentationIds = getPresentationIds(
|
||||
viewport.viewportOptions.presentationIds = ViewportGridService.getPresentationIds(
|
||||
viewport,
|
||||
viewports
|
||||
);
|
||||
@ -403,12 +403,16 @@ export function ViewportGridProvider({ children, service }) {
|
||||
getNumViewportPanes,
|
||||
]);
|
||||
|
||||
// run many of the calls through the service itself since we want to publish events
|
||||
const api = {
|
||||
getState,
|
||||
setActiveViewportIndex: index => service.setActiveViewportIndex(index), // run it through the service itself since we want to publish events
|
||||
setDisplaySetsForViewports,
|
||||
setLayout: layout => service.setLayout(layout), // run it through the service itself since we want to publish events
|
||||
reset,
|
||||
setActiveViewportIndex: index => service.setActiveViewportIndex(index),
|
||||
setDisplaySetsForViewport: props =>
|
||||
service.setDisplaySetsForViewports([props]),
|
||||
setDisplaySetsForViewports: props =>
|
||||
service.setDisplaySetsForViewports(props),
|
||||
setLayout: layout => service.setLayout(layout),
|
||||
reset: () => service.reset(),
|
||||
set: gridLayoutState => service.setState(gridLayoutState), // run it through the service itself since we want to publish events
|
||||
getNumViewportPanes,
|
||||
};
|
||||
@ -422,9 +426,7 @@ export function ViewportGridProvider({ children, service }) {
|
||||
|
||||
ViewportGridProvider.propTypes = {
|
||||
children: PropTypes.any,
|
||||
service: PropTypes.shape({
|
||||
setServiceImplementation: PropTypes.func,
|
||||
}).isRequired,
|
||||
service: PropTypes.instanceOf(ViewportGridService).isRequired,
|
||||
};
|
||||
|
||||
export const useViewportGrid = () => useContext(ViewportGridContext);
|
||||
|
||||
@ -18,4 +18,4 @@ const StringNumber = PropTypes.oneOfType([PropTypes.string, PropTypes.number]);
|
||||
*/
|
||||
const StringArray = PropTypes.oneOfType([PropTypes.string, PropTypes.array]);
|
||||
|
||||
export { StringNumber, StringArray, ThumbnailType, PresentationIds };
|
||||
export { StringNumber, StringArray, ThumbnailType };
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import React, { useEffect, useCallback } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { ServicesManager, Types } from '@ohif/core';
|
||||
import { ServicesManager, Types, MeasurementService } from '@ohif/core';
|
||||
import { ViewportGrid, ViewportPane, useViewportGrid } from '@ohif/ui';
|
||||
import { utils } from '@ohif/core';
|
||||
import EmptyViewport from './EmptyViewport';
|
||||
@ -23,13 +23,6 @@ const ORIENTATION_MAP = {
|
||||
},
|
||||
};
|
||||
|
||||
const compareViewportOptions = (opts1, opts2) => {
|
||||
if ((opts1.viewportType || 'stack') != opts2.viewportType) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
function ViewerViewportGrid(props) {
|
||||
const { servicesManager, viewportComponents, dataSource } = props;
|
||||
const [viewportGrid, viewportGridService] = useViewportGrid();
|
||||
@ -160,77 +153,48 @@ function ViewerViewportGrid(props) {
|
||||
|
||||
useEffect(() => {
|
||||
const { unsubscribe } = measurementService.subscribe(
|
||||
measurementService.EVENTS.JUMP_TO_MEASUREMENT,
|
||||
({ viewportIndex, measurement }) => {
|
||||
const {
|
||||
displaySetInstanceUID: referencedDisplaySetInstanceUID,
|
||||
metadata: { viewPlaneNormal },
|
||||
} = measurement;
|
||||
|
||||
// if we already have the displaySet in one of the viewports
|
||||
// Todo: handle fusion display sets?
|
||||
for (const viewport of viewports) {
|
||||
const isMatch = viewport.displaySetInstanceUIDs.includes(
|
||||
referencedDisplaySetInstanceUID
|
||||
);
|
||||
if (isMatch) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const displaySet = displaySetService.getDisplaySetByUID(
|
||||
referencedDisplaySetInstanceUID
|
||||
);
|
||||
|
||||
let imageIndex;
|
||||
// jump straight to the initial image index if we can
|
||||
if (displaySet.images && measurement.SOPInstanceUID) {
|
||||
imageIndex = displaySet.images.findIndex(
|
||||
image => image.SOPInstanceUID === measurement.SOPInstanceUID
|
||||
);
|
||||
}
|
||||
MeasurementService.EVENTS.JUMP_TO_MEASUREMENT_LAYOUT,
|
||||
({ viewportIndex, measurement, isConsumed }) => {
|
||||
if (isConsumed) return;
|
||||
// This occurs when no viewport has elected to consume the event
|
||||
// so we need to change layouts into a layout which can consume
|
||||
// the event.
|
||||
const { displaySetInstanceUID: referencedDisplaySetInstanceUID } =
|
||||
measurement;
|
||||
|
||||
const updatedViewports = _getUpdatedViewports(
|
||||
viewportIndex,
|
||||
referencedDisplaySetInstanceUID
|
||||
);
|
||||
// Arbitrarily assign the viewport to element 0
|
||||
const viewport = updatedViewports?.[0];
|
||||
|
||||
if (!updatedViewports || !updatedViewports.length) {
|
||||
if (!viewport) {
|
||||
console.warn(
|
||||
'ViewportGrid::Unable to navigate to viewport containing',
|
||||
referencedDisplaySetInstanceUID
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
updatedViewports.forEach(vp => {
|
||||
vp.viewportOptions ||= {};
|
||||
const { orientation, viewportType } = vp.viewportOptions;
|
||||
let initialImageOptions;
|
||||
viewport.viewportOptions ||= {};
|
||||
viewport.viewportOptions.orientation = 'acquisition';
|
||||
|
||||
// For initial imageIndex to hang be careful for the volume viewport
|
||||
if (viewportType === 'stack' || !viewportType) {
|
||||
initialImageOptions = {
|
||||
index: imageIndex,
|
||||
};
|
||||
} else if (viewportType === 'volume') {
|
||||
// For the volume viewports, be careful to not jump in the viewports
|
||||
// that are not in the same orientation.
|
||||
// Todo: this doesn't work for viewports that have custom orientation
|
||||
// vectors specified
|
||||
if (
|
||||
orientation &&
|
||||
viewPlaneNormal &&
|
||||
isEqualWithin(
|
||||
ORIENTATION_MAP[orientation]?.viewPlaneNormal,
|
||||
viewPlaneNormal
|
||||
)
|
||||
) {
|
||||
initialImageOptions = {
|
||||
index: imageIndex,
|
||||
const displaySet = displaySetService.getDisplaySetByUID(
|
||||
referencedDisplaySetInstanceUID
|
||||
);
|
||||
// jump straight to the initial image index if we can
|
||||
if (displaySet.images && measurement.SOPInstanceUID) {
|
||||
for (let index = 0; index < displaySet.images.length; index++) {
|
||||
const image = displaySet.images[index];
|
||||
if (image.SOPInstanceUID === measurement.SOPInstanceUID) {
|
||||
viewport.viewportOptions.initialImageOptions = {
|
||||
index,
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
vp.viewportOptions.initialImageOptions = initialImageOptions;
|
||||
});
|
||||
|
||||
}
|
||||
viewportGridService.setDisplaySetsForViewports(updatedViewports);
|
||||
}
|
||||
);
|
||||
|
||||
298
yarn.lock
298
yarn.lock
@ -1272,7 +1272,7 @@
|
||||
core-js-pure "^3.25.1"
|
||||
regenerator-runtime "^0.13.11"
|
||||
|
||||
"@babel/runtime@7.17.9", "@babel/runtime@7.7.6", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.6", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.6", "@babel/runtime@^7.20.13", "@babel/runtime@^7.20.7", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.4", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
|
||||
"@babel/runtime@7.17.9", "@babel/runtime@7.7.6", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.14.6", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.6", "@babel/runtime@^7.20.13", "@babel/runtime@^7.20.7", "@babel/runtime@^7.21.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.4", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
|
||||
version "7.21.0"
|
||||
resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673"
|
||||
integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==
|
||||
@ -1387,16 +1387,31 @@
|
||||
resolved "https://registry.npmjs.org/@cornerstonejs/calculate-suv/-/calculate-suv-1.0.3.tgz#6d99a72032c0f90cebf44dc6f0b12a5f1102e884"
|
||||
integrity sha512-2SwVJKzC1DzyxdxJtCht9dhTND2GFjLwhhkDyyC7vJq5tIgbhxgPk1CSwovO1pxmoybAXzjOxnaubllxLgoT+w==
|
||||
|
||||
"@cornerstonejs/codec-charls@^0.1.1":
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@cornerstonejs/codec-charls/-/codec-charls-0.1.1.tgz#e55d4aa908732d0cc902888b7f3856c5a996df7f"
|
||||
integrity sha512-Y250DGVzmownJ7WgpHxNqWvfTnv4/malaKm/tWm0xE1FxhQE8iErMWFpKxpNDk3MdfXO4/98piVsUwmJMiWoDQ==
|
||||
|
||||
"@cornerstonejs/codec-charls@^1.2.3":
|
||||
version "1.2.3"
|
||||
resolved "https://registry.npmjs.org/@cornerstonejs/codec-charls/-/codec-charls-1.2.3.tgz#6952c420486822ac8404409ae0ed5a559aff6e25"
|
||||
integrity sha512-qKUe6DN0dnGzhhfZLYhH9UZacMcudjxcaLXCrpxJImT/M/PQvZCT2rllu6VGJbWKJWG+dMVV2zmmleZcdJ7/cA==
|
||||
|
||||
"@cornerstonejs/codec-libjpeg-turbo-8bit@^0.0.7":
|
||||
version "0.0.7"
|
||||
resolved "https://registry.yarnpkg.com/@cornerstonejs/codec-libjpeg-turbo-8bit/-/codec-libjpeg-turbo-8bit-0.0.7.tgz#2ea9b575eed19e6e7e3701b7a50a4ae0ffbef0c4"
|
||||
integrity sha512-qgm6BuVAy5mNP8SJ+A6+VbmPnqgj8jPvJrw4HbUoAzndmf9/VHjTYwawn3kmZWya5ErFAsXQ6c0U0noB1LKAiA==
|
||||
|
||||
"@cornerstonejs/codec-libjpeg-turbo-8bit@^1.2.2":
|
||||
version "1.2.2"
|
||||
resolved "https://registry.npmjs.org/@cornerstonejs/codec-libjpeg-turbo-8bit/-/codec-libjpeg-turbo-8bit-1.2.2.tgz#ae384b149d6655e3dd6e18b9891fab479ab5e144"
|
||||
integrity sha512-aAUMK2958YNpOb/7G6e2/aG7hExTiFTASlMt/v90XA0pRHdWiNg5ny4S5SAju0FbIw4zcMnR0qfY+yW3VG2ivg==
|
||||
|
||||
"@cornerstonejs/codec-openjpeg@^0.1.1":
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@cornerstonejs/codec-openjpeg/-/codec-openjpeg-0.1.1.tgz#5bd1c52a33a425299299e970312731fa0cc2711b"
|
||||
integrity sha512-HOMMOLV6xy8O/agNGGvrl0a8DwShpBvWxAzEzv2pqq12d3r5z/3MyIgNA3Oj/8bIBVvvVXxh9RX7rMDRHJdowg==
|
||||
|
||||
"@cornerstonejs/codec-openjpeg@^1.2.2":
|
||||
version "1.2.2"
|
||||
resolved "https://registry.npmjs.org/@cornerstonejs/codec-openjpeg/-/codec-openjpeg-1.2.2.tgz#f0b524235b5551426b46db197a37b06f8ac805d7"
|
||||
@ -3408,6 +3423,35 @@
|
||||
npmlog "^4.1.2"
|
||||
write-file-atomic "^2.3.0"
|
||||
|
||||
"@mapbox/jsonlint-lines-primitives@~2.0.2":
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz#ce56e539f83552b58d10d672ea4d6fc9adc7b234"
|
||||
integrity sha512-rY0o9A5ECsTQRVhv7tL/OyDpGAoUB4tTvLiW1DSzQGq4bvTPhNw1VpSNjDJc5GFZ2XuyOtSWSVN05qOtcD71qQ==
|
||||
|
||||
"@mapbox/mapbox-gl-style-spec@^13.23.1":
|
||||
version "13.28.0"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/mapbox-gl-style-spec/-/mapbox-gl-style-spec-13.28.0.tgz#2ec226320a0f77856046e000df9b419303a56458"
|
||||
integrity sha512-B8xM7Fp1nh5kejfIl4SWeY0gtIeewbuRencqO3cJDrCHZpaPg7uY+V8abuR+esMeuOjRl5cLhVTP40v+1ywxbg==
|
||||
dependencies:
|
||||
"@mapbox/jsonlint-lines-primitives" "~2.0.2"
|
||||
"@mapbox/point-geometry" "^0.1.0"
|
||||
"@mapbox/unitbezier" "^0.0.0"
|
||||
csscolorparser "~1.0.2"
|
||||
json-stringify-pretty-compact "^2.0.0"
|
||||
minimist "^1.2.6"
|
||||
rw "^1.3.3"
|
||||
sort-object "^0.3.2"
|
||||
|
||||
"@mapbox/point-geometry@^0.1.0":
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz#8a83f9335c7860effa2eeeca254332aa0aeed8f2"
|
||||
integrity sha512-6j56HdLTwWGO0fJPlrZtdU/B13q8Uwmo18Ck2GnGgN9PCFyKTZ3UbXeEdRFh18i9XQ92eH2VdtpJHpBD3aripQ==
|
||||
|
||||
"@mapbox/unitbezier@^0.0.0":
|
||||
version "0.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@mapbox/unitbezier/-/unitbezier-0.0.0.tgz#15651bd553a67b8581fb398810c98ad86a34524e"
|
||||
integrity sha512-HPnRdYO0WjFjRTSwO3frz1wKaU649OBFPX3Zo/2WZvuRi6zMiRGui8SnPQiQABgqCf8YikDe5t3HViTVw1WUzA==
|
||||
|
||||
"@mdx-js/mdx@^1.6.22":
|
||||
version "1.6.22"
|
||||
resolved "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-1.6.22.tgz#8a723157bf90e78f17dc0f27995398e6c731f1ba"
|
||||
@ -3669,6 +3713,11 @@
|
||||
resolved "https://registry.npmjs.org/@percy/sdk-utils/-/sdk-utils-1.24.0.tgz#b6e83333c437ac106386e10a776dc823c1a90f33"
|
||||
integrity sha512-kfYxX0rHP5N2Da6HyfjRCVaeNahAO9XV5WD4SKWKKjdKVkV/Z5/XjVgSKlTBLSYxnWDzYJJ4UHZV43Mw+facMA==
|
||||
|
||||
"@petamoriken/float16@^3.4.7":
|
||||
version "3.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@petamoriken/float16/-/float16-3.8.0.tgz#3a48b7938e1a62188a61ec02d5b12630f671401f"
|
||||
integrity sha512-AhVAm6SQ+zgxIiOzwVdUcDmKlu/qU39FiYD2UD6kQQaVenrn0dGZewIghWAENGQsvC+1avLCuT+T2/3Gsp/W3w==
|
||||
|
||||
"@philpl/buble@^0.19.7":
|
||||
version "0.19.7"
|
||||
resolved "https://registry.npmjs.org/@philpl/buble/-/buble-0.19.7.tgz#27231e6391393793b64bc1c982fc7b593198b893"
|
||||
@ -7614,6 +7663,13 @@ colorette@^2.0.10, colorette@^2.0.14, colorette@^2.0.16, colorette@^2.0.19:
|
||||
resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a"
|
||||
integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==
|
||||
|
||||
colormap@^2.3:
|
||||
version "2.3.2"
|
||||
resolved "https://registry.yarnpkg.com/colormap/-/colormap-2.3.2.tgz#4422c1178ce563806e265b96782737be85815abf"
|
||||
integrity sha512-jDOjaoEEmA9AgA11B/jCSAvYE95r3wRoAyTf3LEHGiUVlNHJaL1mRkf5AyLSpQBVGfTEPwGEqCIzL+kgr2WgNA==
|
||||
dependencies:
|
||||
lerp "^1.0.3"
|
||||
|
||||
colors@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63"
|
||||
@ -7697,6 +7753,11 @@ compare-func@^2.0.0:
|
||||
array-ify "^1.0.0"
|
||||
dot-prop "^5.1.0"
|
||||
|
||||
complex.js@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/complex.js/-/complex.js-2.1.1.tgz#0675dac8e464ec431fb2ab7d30f41d889fb25c31"
|
||||
integrity sha512-8njCHOTtFFLtegk6zQo0kkVX1rngygb/KQI6z1qZxlFI3scluC+LVTCFbrkWjBv4vvLlbQ9t88IPMC6k95VTTg==
|
||||
|
||||
component-emitter@^1.2.1:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0"
|
||||
@ -8332,6 +8393,11 @@ css-what@^6.0.1, css-what@^6.1.0:
|
||||
resolved "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4"
|
||||
integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==
|
||||
|
||||
csscolorparser@~1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/csscolorparser/-/csscolorparser-1.0.3.tgz#b34f391eea4da8f3e98231e2ccd8df9c041f171b"
|
||||
integrity sha512-umPSgYwZkdFoUrH5hIq5kf0wPSXiro51nPw0j2K/c83KflkPSTBGMz6NJvMB+07VlL0y7VPo6QJcDjcgKTTm3w==
|
||||
|
||||
cssdb@^7.1.0:
|
||||
version "7.5.4"
|
||||
resolved "https://registry.npmjs.org/cssdb/-/cssdb-7.5.4.tgz#e34dafee5184d67634604e345e389ca79ac179ea"
|
||||
@ -8680,6 +8746,17 @@ dayjs@^1.10.4:
|
||||
resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz#4b296922642f70999544d1144a2c25730fce63e2"
|
||||
integrity sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ==
|
||||
|
||||
dcmjs@^0.27:
|
||||
version "0.27.0"
|
||||
resolved "https://registry.yarnpkg.com/dcmjs/-/dcmjs-0.27.0.tgz#2662818c8b20494e366583e6dd3577c20d04d6ff"
|
||||
integrity sha512-26wtatOLh+0b0aFy9iOg7PdOLG9EHevn9nEOn7Aoo5l7P9aFAMZ3XAa9Q+NULzLE2Q7DcIf2TQvfyVtdzhQzeg==
|
||||
dependencies:
|
||||
"@babel/runtime-corejs2" "^7.17.8"
|
||||
gl-matrix "^3.1.0"
|
||||
lodash.clonedeep "^4.5.0"
|
||||
loglevelnext "^3.0.1"
|
||||
ndarray "^1.0.19"
|
||||
|
||||
dcmjs@^0.29.5:
|
||||
version "0.29.6"
|
||||
resolved "https://registry.npmjs.org/dcmjs/-/dcmjs-0.29.6.tgz#6ca1543e74bae29657d1f7f2273407e23266c011"
|
||||
@ -8743,6 +8820,11 @@ decamelize@^1.1.0, decamelize@^1.1.2, decamelize@^1.2.0:
|
||||
resolved "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
|
||||
integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==
|
||||
|
||||
decimal.js@^10.4.3:
|
||||
version "10.4.3"
|
||||
resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23"
|
||||
integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==
|
||||
|
||||
decode-named-character-reference@^1.0.0:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz#daabac9690874c394c81e4162a0304b35d824f0e"
|
||||
@ -9068,16 +9150,43 @@ dezalgo@^1.0.0:
|
||||
asap "^2.0.0"
|
||||
wrappy "1"
|
||||
|
||||
dicom-microscopy-viewer@^0.44.0:
|
||||
version "0.44.0"
|
||||
resolved "https://registry.yarnpkg.com/dicom-microscopy-viewer/-/dicom-microscopy-viewer-0.44.0.tgz#d4a9e985acb23c5b82a9aedbe379b39198b8fd55"
|
||||
integrity sha512-7rcm8bXTcOLsXrhBPwWe5gf4Sj1Rz1lRh+ECcaznOEr/uvX6BTAYLqNJNmeAUMoKcadboEeDrmLihCwCteRSJQ==
|
||||
dependencies:
|
||||
"@cornerstonejs/codec-charls" "^0.1.1"
|
||||
"@cornerstonejs/codec-libjpeg-turbo-8bit" "^0.0.7"
|
||||
"@cornerstonejs/codec-openjpeg" "^0.1.1"
|
||||
colormap "^2.3"
|
||||
dcmjs "^0.27"
|
||||
dicomicc "^0.1"
|
||||
dicomweb-client "^0.8"
|
||||
image-type "^4.1"
|
||||
mathjs "^11.2"
|
||||
ol "^7.1"
|
||||
uuid "^9.0"
|
||||
|
||||
dicom-parser@^1.8.9:
|
||||
version "1.8.21"
|
||||
resolved "https://registry.npmjs.org/dicom-parser/-/dicom-parser-1.8.21.tgz#916fdc77776367976b8457cad462b5b7cf74eaea"
|
||||
integrity sha512-lYCweHQDsC8UFpXErPlg86Px2A8bay0HiUY+wzoG3xv5GzgqVHU3lziwSc/Gzn7VV7y2KeP072SzCviuOoU02w==
|
||||
|
||||
dicomicc@^0.1:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/dicomicc/-/dicomicc-0.1.0.tgz#c73acc60a8e2d73a20f462c8c7d0e1e0d977c486"
|
||||
integrity sha512-kZejPGjLQ9NsgovSyVsiAuCpq6LofNR9Erc8Tt/vQAYGYCoQnTyWDlg5D0TJJQATKul7cSr9k/q0TF8G9qdDkQ==
|
||||
|
||||
dicomweb-client@^0.10.2:
|
||||
version "0.10.2"
|
||||
resolved "https://registry.yarnpkg.com/dicomweb-client/-/dicomweb-client-0.10.2.tgz#9c2e466264a5d3b56c18edaafd360e89912cac13"
|
||||
integrity sha512-sGjq3TxM7jgbe7cBpqddT1VlfOlwXmE7Q12qCSGDOkEL7fgn+Ak/5oW/LiRP2FzmfYzcbpO32r+hC8i4ITXQLw==
|
||||
|
||||
dicomweb-client@^0.8:
|
||||
version "0.8.4"
|
||||
resolved "https://registry.yarnpkg.com/dicomweb-client/-/dicomweb-client-0.8.4.tgz#3da814cedb9415facb50bc5f43af8d961a991c74"
|
||||
integrity sha512-/6oY3/Fg9JyAlbTWuJOYbVqici3+nlZt43+Z/Y47RNiqLc028JcxNlY28u4VQqksxfB59f1hhNbsqsHyDT4vhw==
|
||||
|
||||
didyoumean@^1.2.2:
|
||||
version "1.2.2"
|
||||
resolved "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037"
|
||||
@ -9391,6 +9500,11 @@ duplexify@^3.4.2, duplexify@^3.5.0, duplexify@^3.6.0:
|
||||
readable-stream "^2.0.0"
|
||||
stream-shift "^1.0.0"
|
||||
|
||||
earcut@^2.2.3:
|
||||
version "2.2.4"
|
||||
resolved "https://registry.yarnpkg.com/earcut/-/earcut-2.2.4.tgz#6d02fd4d68160c114825d06890a92ecaae60343a"
|
||||
integrity sha512-/pjZsA1b4RPHbeWZQn66SWS8nZZWLQQ23oE3Eam7aroEFGEvwKAsJfZ9ytiEMycfzXWpca4FA9QIOehf7PocBQ==
|
||||
|
||||
eastasianwidth@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb"
|
||||
@ -9703,6 +9817,11 @@ escape-html@^1.0.3, escape-html@~1.0.3:
|
||||
resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988"
|
||||
integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==
|
||||
|
||||
escape-latex@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/escape-latex/-/escape-latex-1.2.0.tgz#07c03818cf7dac250cce517f4fda1b001ef2bca1"
|
||||
integrity sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==
|
||||
|
||||
escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
@ -10666,6 +10785,11 @@ file-system-cache@^2.0.0:
|
||||
fs-extra "^11.1.0"
|
||||
ramda "^0.28.0"
|
||||
|
||||
file-type@^10.10.0:
|
||||
version "10.11.0"
|
||||
resolved "https://registry.yarnpkg.com/file-type/-/file-type-10.11.0.tgz#2961d09e4675b9fb9a3ee6b69e9cd23f43fd1890"
|
||||
integrity sha512-uzk64HRpUZyTGZtVuvrjP0FYxzQrBf4rojot6J65YMEbwBLB0CWm0CLojVpwpmFmxcE/lkvYICgfcGozbBq6rw==
|
||||
|
||||
file-uri-to-path@1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd"
|
||||
@ -11133,6 +11257,19 @@ gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2:
|
||||
resolved "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
|
||||
integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
|
||||
|
||||
geotiff@^2.0.7:
|
||||
version "2.0.7"
|
||||
resolved "https://registry.yarnpkg.com/geotiff/-/geotiff-2.0.7.tgz#358e578233af70bfb0b4dee62d599ad78fc5cfca"
|
||||
integrity sha512-FKvFTNowMU5K6lHYY2f83d4lS2rsCNdpUC28AX61x9ZzzqPNaWFElWv93xj0eJFaNyOYA63ic5OzJ88dHpoA5Q==
|
||||
dependencies:
|
||||
"@petamoriken/float16" "^3.4.7"
|
||||
lerc "^3.0.0"
|
||||
pako "^2.0.4"
|
||||
parse-headers "^2.0.2"
|
||||
quick-lru "^6.1.1"
|
||||
web-worker "^1.2.0"
|
||||
xml-utils "^1.0.2"
|
||||
|
||||
get-caller-file@^2.0.1, get-caller-file@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
|
||||
@ -12151,7 +12288,7 @@ identity-obj-proxy@3.0.x:
|
||||
dependencies:
|
||||
harmony-reflect "^1.4.6"
|
||||
|
||||
ieee754@^1.1.13:
|
||||
ieee754@^1.1.12, ieee754@^1.1.13:
|
||||
version "1.2.1"
|
||||
resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352"
|
||||
integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==
|
||||
@ -12185,6 +12322,13 @@ image-size@^1.0.1:
|
||||
dependencies:
|
||||
queue "6.0.2"
|
||||
|
||||
image-type@^4.1:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/image-type/-/image-type-4.1.0.tgz#72a88d64ff5021371ed67b9a466442100be57cd1"
|
||||
integrity sha512-CFJMJ8QK8lJvRlTCEgarL4ro6hfDQKif2HjSvYCdQZESaIPV4v9imrf7BQHK+sQeTeNeMpWciR9hyC/g8ybXEg==
|
||||
dependencies:
|
||||
file-type "^10.10.0"
|
||||
|
||||
immer@^9.0.7:
|
||||
version "9.0.21"
|
||||
resolved "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz#1e025ea31a40f24fb064f1fef23e931496330176"
|
||||
@ -13127,6 +13271,11 @@ jake@^10.8.5:
|
||||
filelist "^1.0.1"
|
||||
minimatch "^3.0.4"
|
||||
|
||||
javascript-natural-sort@^0.7.1:
|
||||
version "0.7.1"
|
||||
resolved "https://registry.yarnpkg.com/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz#f9e2303d4507f6d74355a73664d1440fb5a0ef59"
|
||||
integrity sha512-nO6jcEfZWQXDhOiBtG2KvKyEptz7RVbpGP4vTD2hLBdmNQSsCiicO2Ioinv6UI4y9ukqnBpy+XZ9H6uLNgJTlw==
|
||||
|
||||
jest-canvas-mock@^2.1.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.npmjs.org/jest-canvas-mock/-/jest-canvas-mock-2.5.0.tgz#3e60f87f77ddfa273cf8e7e4ea5f86fa827c7117"
|
||||
@ -13752,6 +13901,11 @@ json-stable-stringify-without-jsonify@^1.0.1:
|
||||
resolved "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651"
|
||||
integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==
|
||||
|
||||
json-stringify-pretty-compact@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/json-stringify-pretty-compact/-/json-stringify-pretty-compact-2.0.0.tgz#e77c419f52ff00c45a31f07f4c820c2433143885"
|
||||
integrity sha512-WRitRfs6BGq4q8gTgOy4ek7iPFXjbra0H3PmDLKm2xnZ+Gh1HUhiKGgCZkSPNULlP7mvfu6FV/mOLhCarspADQ==
|
||||
|
||||
json-stringify-safe@^5.0.1, json-stringify-safe@~5.0.1:
|
||||
version "5.0.1"
|
||||
resolved "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
|
||||
@ -13928,6 +14082,11 @@ left-pad@^1.3.0:
|
||||
resolved "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e"
|
||||
integrity sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==
|
||||
|
||||
lerc@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/lerc/-/lerc-3.0.0.tgz#36f36fbd4ba46f0abf4833799fff2e7d6865f5cb"
|
||||
integrity sha512-Rm4J/WaHhRa93nCN2mwWDZFoRVF18G1f47C+kvQWyHGEZxFpTUi73p7lMVSAndyxGt6lJ2/CFbOcf9ra5p8aww==
|
||||
|
||||
lerna@^3.15.0:
|
||||
version "3.22.1"
|
||||
resolved "https://registry.npmjs.org/lerna/-/lerna-3.22.1.tgz#82027ac3da9c627fd8bf02ccfeff806a98e65b62"
|
||||
@ -13952,6 +14111,11 @@ lerna@^3.15.0:
|
||||
import-local "^2.0.0"
|
||||
npmlog "^4.1.2"
|
||||
|
||||
lerp@^1.0.3:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/lerp/-/lerp-1.0.3.tgz#a18c8968f917896de15ccfcc28d55a6b731e776e"
|
||||
integrity sha512-70Rh4rCkJDvwWiTsyZ1HmJGvnyfFah4m6iTux29XmasRiZPDBpT9Cfa4ai73+uLZxnlKruUS62jj2lb11wURiA==
|
||||
|
||||
leven@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2"
|
||||
@ -14476,6 +14640,11 @@ map-visit@^1.0.0:
|
||||
dependencies:
|
||||
object-visit "^1.0.0"
|
||||
|
||||
mapbox-to-css-font@^2.4.1:
|
||||
version "2.4.2"
|
||||
resolved "https://registry.yarnpkg.com/mapbox-to-css-font/-/mapbox-to-css-font-2.4.2.tgz#a9e31b363ad8ca881cd339ca99f2d2a6b02ea5dd"
|
||||
integrity sha512-f+NBjJJY4T3dHtlEz1wCG7YFlkODEjFIYlxDdLIDMNpkSksqTt+l/d4rjuwItxuzkuMFvPyrjzV2lxRM4ePcIA==
|
||||
|
||||
markdown-escapes@^1.0.0:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535"
|
||||
@ -14496,6 +14665,21 @@ material-colors@^1.2.1:
|
||||
resolved "https://registry.npmjs.org/material-colors/-/material-colors-1.2.6.tgz#6d1958871126992ceecc72f4bcc4d8f010865f46"
|
||||
integrity sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg==
|
||||
|
||||
mathjs@^11.2:
|
||||
version "11.8.0"
|
||||
resolved "https://registry.yarnpkg.com/mathjs/-/mathjs-11.8.0.tgz#b02e66461ec068fadf1e90c221121704dc14d8f5"
|
||||
integrity sha512-I7r8HCoqUGyEiHQdeOCF2m2k9N+tcOHO3cZQ3tyJkMMBQMFqMR7dMQEboBMJAiFW2Um3PEItGPwcOc4P6KRqwg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.21.0"
|
||||
complex.js "^2.1.1"
|
||||
decimal.js "^10.4.3"
|
||||
escape-latex "^1.2.0"
|
||||
fraction.js "^4.2.0"
|
||||
javascript-natural-sort "^0.7.1"
|
||||
seedrandom "^3.0.5"
|
||||
tiny-emitter "^2.1.0"
|
||||
typed-function "^4.1.0"
|
||||
|
||||
mdast-squeeze-paragraphs@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.npmjs.org/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-4.0.0.tgz#7c4c114679c3bee27ef10b58e2e015be79f1ef97"
|
||||
@ -15956,6 +16140,25 @@ oidc-client@1.11.5:
|
||||
crypto-js "^4.0.0"
|
||||
serialize-javascript "^4.0.0"
|
||||
|
||||
ol-mapbox-style@^9.2.0:
|
||||
version "9.7.0"
|
||||
resolved "https://registry.yarnpkg.com/ol-mapbox-style/-/ol-mapbox-style-9.7.0.tgz#38a4f7abc8f0a94f378dcdb7cefdcc69ca3f6287"
|
||||
integrity sha512-YX3u8FBJHsRHaoGxmd724Mp5WPTuV7wLQW6zZhcihMuInsSdCX1EiZfU+8IAL7jG0pbgl5YgC0aWE/MXJcUXxg==
|
||||
dependencies:
|
||||
"@mapbox/mapbox-gl-style-spec" "^13.23.1"
|
||||
mapbox-to-css-font "^2.4.1"
|
||||
|
||||
ol@^7.1:
|
||||
version "7.3.0"
|
||||
resolved "https://registry.yarnpkg.com/ol/-/ol-7.3.0.tgz#7ffb5f258dafa4a3e218208aad9054d61f6fe786"
|
||||
integrity sha512-08vJE4xITKPazQ9qJjeqYjRngnM9s+1eSv219Pdlrjj3LpLqjEH386ncq+76Dw1oGPGR8eLVEePk7FEd9XqqMw==
|
||||
dependencies:
|
||||
earcut "^2.2.3"
|
||||
geotiff "^2.0.7"
|
||||
ol-mapbox-style "^9.2.0"
|
||||
pbf "3.2.1"
|
||||
rbush "^3.0.1"
|
||||
|
||||
on-finished@2.4.1:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f"
|
||||
@ -16301,6 +16504,11 @@ parse-github-repo-url@^1.3.0:
|
||||
resolved "https://registry.npmjs.org/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz#9e7d8bb252a6cb6ba42595060b7bf6df3dbc1f50"
|
||||
integrity sha512-bSWyzBKqcSL4RrncTpGsEKoJ7H8a4L3++ifTAbTFeMHyq2wRV+42DGmQcHIrJIvdcacjIOxEuKH/w4tthF17gg==
|
||||
|
||||
parse-headers@^2.0.2:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/parse-headers/-/parse-headers-2.0.5.tgz#069793f9356a54008571eb7f9761153e6c770da9"
|
||||
integrity sha512-ft3iAoLOB/MlwbNXgzy43SWGP6sQki2jQvAyBg/zDFAgr9bfNWZIUj42Kw2eJIl8kEi4PbgE6U1Zau/HwI75HA==
|
||||
|
||||
parse-json@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9"
|
||||
@ -16501,6 +16709,14 @@ pause-stream@0.0.11:
|
||||
dependencies:
|
||||
through "~2.3"
|
||||
|
||||
pbf@3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/pbf/-/pbf-3.2.1.tgz#b4c1b9e72af966cd82c6531691115cc0409ffe2a"
|
||||
integrity sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==
|
||||
dependencies:
|
||||
ieee754 "^1.1.12"
|
||||
resolve-protobuf-schema "^2.1.0"
|
||||
|
||||
peek-stream@^1.1.0:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.npmjs.org/peek-stream/-/peek-stream-1.1.3.tgz#3b35d84b7ccbbd262fff31dc10da56856ead6d67"
|
||||
@ -17588,7 +17804,7 @@ prettier@^1.18.2:
|
||||
|
||||
prettier@^2.8.0:
|
||||
version "2.8.8"
|
||||
resolved "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da"
|
||||
resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da"
|
||||
integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==
|
||||
|
||||
pretty-bytes@^5.3.0, pretty-bytes@^5.4.1, pretty-bytes@^5.6.0:
|
||||
@ -17728,6 +17944,11 @@ proto-list@~1.2.1:
|
||||
resolved "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz#212d5bfe1318306a420f6402b8e26ff39647a849"
|
||||
integrity sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==
|
||||
|
||||
protocol-buffers-schema@^3.3.1:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz#77bc75a48b2ff142c1ad5b5b90c94cd0fa2efd03"
|
||||
integrity sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==
|
||||
|
||||
protocols@^1.4.0:
|
||||
version "1.4.8"
|
||||
resolved "https://registry.npmjs.org/protocols/-/protocols-1.4.8.tgz#48eea2d8f58d9644a4a32caae5d5db290a075ce8"
|
||||
@ -17919,6 +18140,16 @@ quick-lru@^5.1.1:
|
||||
resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz#366493e6b3e42a3a6885e2e99d18f80fb7a8c932"
|
||||
integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==
|
||||
|
||||
quick-lru@^6.1.1:
|
||||
version "6.1.1"
|
||||
resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-6.1.1.tgz#f8e5bf9010376c126c80c1a62827a526c0e60adf"
|
||||
integrity sha512-S27GBT+F0NTRiehtbrgaSE1idUAJ5bX8dPAQTdylEyNlrdcH5X4Lz7Edz3DYzecbsCluD5zO8ZNEe04z3D3u6Q==
|
||||
|
||||
quickselect@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/quickselect/-/quickselect-2.0.0.tgz#f19680a486a5eefb581303e023e98faaf25dd018"
|
||||
integrity sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw==
|
||||
|
||||
raf@^3.4.1:
|
||||
version "3.4.1"
|
||||
resolved "https://registry.npmjs.org/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39"
|
||||
@ -17958,6 +18189,13 @@ raw-body@2.5.1:
|
||||
iconv-lite "0.4.24"
|
||||
unpipe "1.0.0"
|
||||
|
||||
rbush@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/rbush/-/rbush-3.0.1.tgz#5fafa8a79b3b9afdfe5008403a720cc1de882ecf"
|
||||
integrity sha512-XRaVO0YecOpEuIvbhbpTrZgoiI6xBlz6hnlr6EHhd+0x9ase6EmeN+hdwwUaJvLcsFFQ8iWVF1GAK1yB0BWi0w==
|
||||
dependencies:
|
||||
quickselect "^2.0.0"
|
||||
|
||||
rc@1.2.8, rc@^1.0.1, rc@^1.1.6, rc@^1.2.7, rc@^1.2.8:
|
||||
version "1.2.8"
|
||||
resolved "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
|
||||
@ -19043,6 +19281,13 @@ resolve-pathname@^3.0.0:
|
||||
resolved "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz#99d02224d3cf263689becbb393bc560313025dcd"
|
||||
integrity sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==
|
||||
|
||||
resolve-protobuf-schema@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz#9ca9a9e69cf192bbdaf1006ec1973948aa4a3758"
|
||||
integrity sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==
|
||||
dependencies:
|
||||
protocol-buffers-schema "^3.3.1"
|
||||
|
||||
resolve-url@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a"
|
||||
@ -19219,6 +19464,11 @@ run-queue@^1.0.0, run-queue@^1.0.3:
|
||||
dependencies:
|
||||
aproba "^1.1.1"
|
||||
|
||||
rw@^1.3.3:
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4"
|
||||
integrity sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==
|
||||
|
||||
rxjs@^6.3.3, rxjs@^6.4.0:
|
||||
version "6.6.7"
|
||||
resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9"
|
||||
@ -19368,7 +19618,7 @@ section-matter@^1.0.0:
|
||||
extend-shallow "^2.0.1"
|
||||
kind-of "^6.0.0"
|
||||
|
||||
seedrandom@3.0.5:
|
||||
seedrandom@3.0.5, seedrandom@^3.0.5:
|
||||
version "3.0.5"
|
||||
resolved "https://registry.npmjs.org/seedrandom/-/seedrandom-3.0.5.tgz#54edc85c95222525b0c7a6f6b3543d8e0b3aa0a7"
|
||||
integrity sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==
|
||||
@ -19813,11 +20063,21 @@ socks@~2.3.2:
|
||||
ip "1.1.5"
|
||||
smart-buffer "^4.1.0"
|
||||
|
||||
sort-asc@^0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/sort-asc/-/sort-asc-0.1.0.tgz#ab799df61fc73ea0956c79c4b531ed1e9e7727e9"
|
||||
integrity sha512-jBgdDd+rQ+HkZF2/OHCmace5dvpos/aWQpcxuyRs9QUbPRnkEJmYVo81PIGpjIdpOcsnJ4rGjStfDHsbn+UVyw==
|
||||
|
||||
sort-css-media-queries@2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.npmjs.org/sort-css-media-queries/-/sort-css-media-queries-2.1.0.tgz#7c85e06f79826baabb232f5560e9745d7a78c4ce"
|
||||
integrity sha512-IeWvo8NkNiY2vVYdPa27MCQiR0MN0M80johAYFVxWWXQ44KU84WNxjslwBHmc/7ZL2ccwkM7/e6S5aiKZXm7jA==
|
||||
|
||||
sort-desc@^0.1.1:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/sort-desc/-/sort-desc-0.1.1.tgz#198b8c0cdeb095c463341861e3925d4ee359a9ee"
|
||||
integrity sha512-jfZacW5SKOP97BF5rX5kQfJmRVZP5/adDUTY8fCSPvNcXDVpUEe2pr/iKGlcyZzchRJZrswnp68fgk3qBXgkJw==
|
||||
|
||||
sort-keys@^1.0.0:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad"
|
||||
@ -19832,6 +20092,14 @@ sort-keys@^2.0.0:
|
||||
dependencies:
|
||||
is-plain-obj "^1.0.0"
|
||||
|
||||
sort-object@^0.3.2:
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/sort-object/-/sort-object-0.3.2.tgz#98e0d199ede40e07c61a84403c61d6c3b290f9e2"
|
||||
integrity sha512-aAQiEdqFTTdsvUFxXm3umdo04J7MRljoVGbBlkH7BgNsMvVNAJyGj7C/wV1A8wHWAJj/YikeZbfuCKqhggNWGA==
|
||||
dependencies:
|
||||
sort-asc "^0.1.0"
|
||||
sort-desc "^0.1.1"
|
||||
|
||||
source-list-map@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
|
||||
@ -20823,6 +21091,11 @@ timsort@^0.3.0:
|
||||
resolved "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
|
||||
integrity sha512-qsdtZH+vMoCARQtyod4imc2nIJwg9Cc7lPRrw9CzF8ZKR0khdr8+2nX80PBhET3tcyTtJDxAffGh2rXH4tyU8A==
|
||||
|
||||
tiny-emitter@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
|
||||
integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==
|
||||
|
||||
tiny-invariant@^1.0.2:
|
||||
version "1.3.1"
|
||||
resolved "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642"
|
||||
@ -21084,6 +21357,11 @@ typed-array-length@^1.0.4:
|
||||
for-each "^0.3.3"
|
||||
is-typed-array "^1.1.9"
|
||||
|
||||
typed-function@^4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/typed-function/-/typed-function-4.1.0.tgz#da4bdd8a6d19a89e22732f75e4a410860aaf9712"
|
||||
integrity sha512-DGwUl6cioBW5gw2L+6SMupGwH/kZOqivy17E4nsh1JI9fKF87orMmlQx3KISQPmg3sfnOUGlwVkroosvgddrlg==
|
||||
|
||||
typedarray-to-buffer@^3.1.5:
|
||||
version "3.1.5"
|
||||
resolved "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
|
||||
@ -21580,7 +21858,7 @@ uuid@^8.3.2:
|
||||
resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
|
||||
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
|
||||
|
||||
uuid@^9.0.0:
|
||||
uuid@^9.0, uuid@^9.0.0:
|
||||
version "9.0.0"
|
||||
resolved "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5"
|
||||
integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==
|
||||
@ -21779,6 +22057,11 @@ web-streams-polyfill@^3.0.3:
|
||||
resolved "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6"
|
||||
integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==
|
||||
|
||||
web-worker@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/web-worker/-/web-worker-1.2.0.tgz#5d85a04a7fbc1e7db58f66595d7a3ac7c9c180da"
|
||||
integrity sha512-PgF341avzqyx60neE9DD+XS26MMNMoUQRz9NOZwW32nPQrF6p77f1htcnjBSEV8BGMKZ16choqUG4hyI0Hx7mA==
|
||||
|
||||
webgl-constants@^1.1.1:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.npmjs.org/webgl-constants/-/webgl-constants-1.1.1.tgz#f9633ee87fea56647a60b9ce735cbdfb891c6855"
|
||||
@ -22499,6 +22782,11 @@ xml-name-validator@^3.0.0:
|
||||
resolved "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a"
|
||||
integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==
|
||||
|
||||
xml-utils@^1.0.2:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/xml-utils/-/xml-utils-1.7.0.tgz#333ce391d8918f872aaf98d2cf90f9ef9b82bd0f"
|
||||
integrity sha512-bWB489+RQQclC7A9OW8e5BzbT8Tu//jtAOvkYwewFr+Q9T9KDGvfzC1lp0pYPEQPEoPQLDkmxkepSC/2gIAZGw==
|
||||
|
||||
xml@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmjs.org/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user